version 4.27, 2019/11/26 12:09:02 |
version 4.40, 2019/11/30 13:08:41 |
Line 55 use filetest qw(access); |
|
Line 55 use filetest qw(access); |
|
|
|
use vars qw ( |
use vars qw ( |
$VERSION $CheckoutMagic $MimeTypes $DEBUG |
$VERSION $CheckoutMagic $MimeTypes $DEBUG |
$config $allow_version_select |
@CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr %DEFAULTVALUE %MTYPES |
@CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr |
@DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS |
%DEFAULTVALUE %ICONS %MTYPES |
|
%DIFF_COMMANDS @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS |
|
%alltags %fileinfo %tags @branchnames %nameprinted |
%alltags %fileinfo %tags @branchnames %nameprinted |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
|
|
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased |
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased |
%input $query $barequery $sortby $bydate $byrev $byauthor |
%input $query $barequery $sortby $bydate $byrev $byauthor |
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot |
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot |
$charset $output_filter |
%CMD $allow_compress $backicon $diricon $fileicon |
@command_path %CMD $allow_compress $backicon $diricon $fileicon |
$fullname $logo $defaulttitle $address $binfileicon $iconsdir |
$fullname $logo $defaulttitle $address $binfileicon |
$shortLogLen $show_author $hr_breakable $hr_ignwhite $hr_ignkeysubst |
$long_intro $short_instruction $shortLogLen $show_author |
$mime_types $allow_annotate $allow_markup $allow_mailtos |
$tablepadding $hr_breakable $showfunc $hr_ignwhite $hr_ignkeysubst |
|
$inputTextSize $mime_types $allow_annotate $allow_markup $allow_mailtos |
|
$allow_log_extra $allow_dir_extra $allow_source_extra |
$allow_log_extra $allow_dir_extra $allow_source_extra |
$edit_option_form |
$edit_option_form |
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup |
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup |
$tabstop $state $annTable $sel @ForbiddenFiles |
$tabstop $state $annTable $sel @ForbiddenFiles |
$use_descriptions %descriptions $dwhere |
$use_descriptions %descriptions $dwhere |
$use_moddate $gzip_open $file_list_len |
$use_moddate $gzip_open $file_list_len |
$allow_tar @tar_options @gzip_options @cvs_options |
$allow_tar @tar_options @cvs_options |
@annotate_options @rcsdiff_options |
@annotate_options @rcsdiff_options |
$HTML_DOCTYPE $HTML_META $cssurl $CSS |
$HTML_DOCTYPE $HTML_META $cssurl $CSS |
); |
); |
Line 89 use Cwd qw(abs_path); |
|
Line 85 use Cwd qw(abs_path); |
|
use File::Path qw(rmtree); |
use File::Path qw(rmtree); |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
tmpdir updir); |
tmpdir updir); |
use File::Temp qw(tempdir tempfile); |
use File::Temp qw(tempdir); |
use IPC::Run qw(); |
use IPC::Run qw(); |
use Time::Local qw(timegm); |
use Time::Local qw(timegm); |
use URI::Escape qw(uri_escape uri_unescape); |
use URI::Escape qw(uri_escape uri_unescape); |
Line 150 sub search_path($); |
|
Line 146 sub search_path($); |
|
sub getMimeType($;$); |
sub getMimeType($;$); |
sub head($;$); |
sub head($;$); |
sub scan_directives(@); |
sub scan_directives(@); |
sub openOutputFilter(); |
|
sub doAnnotate($$); |
sub doAnnotate($$); |
sub doCheckout($$$); |
sub doCheckout($$$); |
sub cvswebMarkup($$$$$$;$); |
sub cvswebMarkup($$$$$$;$); |
Line 183 sub link_tags($); |
|
Line 178 sub link_tags($); |
|
sub forbidden($); |
sub forbidden($); |
sub startproc(@); |
sub startproc(@); |
sub runproc(@); |
sub runproc(@); |
sub checkout_to_temp($$$); |
|
|
|
# Get rid of unsafe environment vars. Don't do this in the BEGIN block |
# Get rid of unsafe environment vars. Don't do this in the BEGIN block |
# (think mod_perl)... |
# (think mod_perl)... |
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}); |
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}); |
|
|
# Location of the configuration file inside the web server chroot: |
# Helps to achieve read only access to the repositories |
$config = '/conf/cvsweb/cvsweb.conf'; |
# with cvs >= 1.12.1 and doesn't hurt other versions. |
|
$ENV{CVSREADONLYFS} = 1; |
|
|
######## Configuration parameters ######### |
######## configuration defaults ######### |
|
|
@CVSrepositories = @CVSROOT = %CVSROOT = %DEFAULTVALUE = %ICONS = |
%CMD = ( |
%MTYPES = %tags = %alltags = %fileinfo = %DIFF_COMMANDS = (); |
cvs => '/usr/bin/cvs', |
|
rcsdiff => '/usr/bin/rcsdiff', |
|
rlog => '/usr/bin/rlog', |
|
tar => '/bin/tar', |
|
); |
|
|
$logo = $defaulttitle = |
%DEFAULTVALUE = ( |
$address = $long_intro = $short_instruction = $shortLogLen = $show_author = |
f => 'u', |
$tablepadding = $hr_breakable = $showfunc = $hr_ignwhite = |
hideattic => 1, |
$hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate = |
hidecvsroot => 0, |
$allow_markup = $allow_compress = $edit_option_form = |
hidenonreadable => 1, |
$show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup = |
ignorecase => 0, |
$tabstop = $use_moddate = $gzip_open = $DEBUG = |
ln => 0, |
$allow_tar = undef; |
logsort => 'date', |
|
sortby => 'file', |
|
); |
|
|
$allow_version_select = $allow_mailtos = $allow_log_extra = 1; |
@ForbiddenFiles = ( |
|
qr|^CVSROOT/+passwd$|o, # CVSROOT/passwd should not be 'cvs add'ed though. |
|
qr|/\.cvspass$|o, # Ditto. Just in case. |
|
); |
|
|
|
%MTYPES = ( |
|
gif => 'image/gif', |
|
html => 'text/html', |
|
jpeg => 'image/jpeg', |
|
jpg => 'image/jpeg', |
|
png => 'image/png', |
|
); |
|
|
|
$address = 'CVSweb'; |
|
$allow_annotate = 1; |
|
$allow_compress = 0; |
|
$allow_dir_extra = 1; |
|
$allow_log_extra = 1; |
|
$allow_mailtos = 1; |
|
$allow_markup = 1; |
|
$allow_source_extra = 1; |
|
$allow_tar = 0; |
|
@annotate_options = qw(-f -R); |
|
$cssurl = '/css/cvsweb.css'; |
|
@cvs_options = qw(-f -R); |
|
@CVSrepositories = ('local', ['Local Repository', '/cvs']); |
|
$DEBUG = 0; |
|
$defaulttitle = 'CVS Repository'; |
|
$edit_option_form = 1; |
|
$file_list_len = 0; |
|
$hr_breakable = 1; |
|
$hr_ignkeysubst = 1; |
|
$hr_ignwhite = 0; |
|
$iconsdir = '/icons'; |
|
$logo = undef; |
|
$mancgi = 'https://man.openbsd.org/%s.%s'; |
|
$mime_types = '/conf/mime.types'; |
|
$preformat_in_markup = 0; |
|
@rcsdiff_options = qw(-q); |
|
$shortLogLen = 80; |
|
$show_author = 1; |
|
$show_log_in_markup = 1; |
|
$show_subdir_lastmod = 0; |
|
$tabstop = 8; |
|
@tar_options = qw(); |
|
$use_descriptions = 0; |
|
$use_moddate = 1; |
|
|
|
######## load configuration ######### |
|
|
|
{ |
|
my $config = '/conf/cvsweb/cvsweb.conf'; |
|
last unless -e $config; |
|
defined do $config and last; |
|
$@ and fatal '500 Internal Error', |
|
'Error loading configuration file "<code>%s</code>": <pre>%s</pre>', |
|
$config, $@; |
|
fatal '500 Internal Error', |
|
'Cannot read configuration file "<code>%s</code>": %s', |
|
$config, $! || 'unknown error'; |
|
} |
|
|
|
######## other global variables ######### |
|
|
@DIFFTYPES = qw(h H u c); |
@DIFFTYPES = qw(h H u c); |
@DIFFTYPES{@DIFFTYPES} = ( |
@DIFFTYPES{@DIFFTYPES} = ( |
{ |
{ |
Line 239 $allow_version_select = $allow_mailtos = $allow_log_ex |
|
Line 302 $allow_version_select = $allow_mailtos = $allow_log_ex |
|
{ descr => 'Revision', }, |
{ descr => 'Revision', }, |
); |
); |
|
|
##### End of configuration parameters ##### |
%alltags = (); |
|
@CVSROOT = (); |
|
%CVSROOT = (); |
|
%CVSROOTdescr = (); |
|
%fileinfo = (); |
|
$gzip_open = 0; |
|
%tags = (); |
|
|
|
######## end of global variables ######### |
|
|
my $pathinfo = ''; |
my $pathinfo = ''; |
if (defined($ENV{PATH_INFO}) && $ENV{PATH_INFO} ne '') { |
if (defined($ENV{PATH_INFO}) && $ENV{PATH_INFO} ne '') { |
($pathinfo) = ($ENV{PATH_INFO} =~ VALID_PATH) |
($pathinfo) = ($ENV{PATH_INFO} =~ VALID_PATH) |
Line 313 $maycompress = ( |
|
Line 384 $maycompress = ( |
|
qw(cvsroot hideattic ignorecase sortby logsort f only_with_tag ln |
qw(cvsroot hideattic ignorecase sortby logsort f only_with_tag ln |
hidecvsroot hidenonreadable); |
hidecvsroot hidenonreadable); |
|
|
# Load configuration. |
|
{ |
|
$config =~ m|^/| or fatal '500 Internal Error', |
|
'Configuration file name "<code>%s</code>" is not an absolute path.', |
|
$config; |
|
defined do $config and last; |
|
$@ and fatal '500 Internal Error', |
|
'Error loading configuration file "<code>%s</code>": <pre>%s</pre>', |
|
$config, $@; |
|
fatal '500 Internal Error', |
|
'Cannot read configuration file "<code>%s</code>": %s', |
|
$config, $! || 'unknown error'; |
|
} |
|
|
|
# Try to find a readable dir where we can cd into. Some abs_path() |
# Try to find a readable dir where we can cd into. Some abs_path() |
# implementations as well as various cvs operations require such a dir to |
# implementations as well as various cvs operations require such a dir to |
# work properly. |
# work properly. |
Line 476 for (my $i = 0; $i < scalar(@CVSrepositories); $i += 2 |
|
Line 533 for (my $i = 0; $i < scalar(@CVSrepositories); $i += 2 |
|
push(@CVSROOT, $key); |
push(@CVSROOT, $key); |
} |
} |
unless ($rootfound) { |
unless ($rootfound) { |
fatal('500 Internal Error', |
fatal('500 Internal Error', 'no valid CVS roots found'); |
'No valid CVS roots found! See <code>@CVSrepositories</code> in ' . |
|
'the configuration file (<code>%s</code>).', |
|
$config); |
|
} |
} |
undef $rootfound; |
undef $rootfound; |
|
|
Line 567 if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) { |
|
Line 621 if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) { |
|
|
|
$cvsroot = $CVSROOT{$cvstree}; |
$cvsroot = $CVSROOT{$cvstree}; |
|
|
# create icons out of description |
if ($iconsdir) { |
foreach my $k (keys %ICONS) { |
$backicon = '<img src="' . $iconsdir . '/back.gif" alt="[BACK]"' . |
my ($itxt, $ipath, $iwidth, $iheight) = @{$ICONS{$k}}; |
' border="0" width="20" height="22"/>'; |
no strict 'refs'; |
$diricon = '<img src="' . $iconsdir . '/dir.gif" alt="[DIR]"' . |
if ($ipath) { |
' border="0" width="20" height="22"/>'; |
${"${k}icon"} = |
$fileicon = '<img src="' . $iconsdir . '/text.gif" alt="[TXT]"' . |
sprintf('<img src="%s" alt="%s" border="0" width="%d" height="%d" />', |
' border="0" width="20" height="22"/>'; |
htmlquote($ipath), htmlquote($itxt), $iwidth, $iheight); |
$binfileicon = '<img src="' . $iconsdir . '/binary.gif" alt="[BIN]"' . |
} else { |
' border="0" width="20" height="22"/>'; |
${"${k}icon"} = $itxt; |
} else { |
} |
$backicon = 'back'; |
|
$diricon = 'dir'; |
|
$fileicon = 'file'; |
|
$binfileicon = 'binfile'; |
} |
} |
|
|
my $config_cvstree = "$config-$cvstree"; |
|
|
|
# Do some special configuration for cvstrees |
|
if (-f $config_cvstree) { |
|
do "$config_cvstree" |
|
or fatal("500 Internal Error", |
|
'Error in loading configuration file: %s<br /><br />%s<br />', |
|
$config_cvstree, $@); |
|
} |
|
undef $config_cvstree; |
|
|
|
$fullname = catfile($cvsroot, $where); |
$fullname = catfile($cvsroot, $where); |
|
|
my $rewrite = 0; |
my $rewrite = 0; |
Line 644 if ($input{tarball}) { |
|
Line 690 if ($input{tarball}) { |
|
'You cannot download the top level directory.'); |
'You cannot download the top level directory.'); |
} |
} |
|
|
my $istar = $ext eq '.tar.gz' || $ext eq '.tgz'; |
unless ($ext eq '.tar.gz' || $ext eq '.tgz') { |
if ($istar) { |
fatal('404 Not Found', 'Unsupported archive type.'); |
fatal('500 Internal Error', 'tar command not found.') unless $CMD{tar}; |
|
fatal('500 Internal Error', 'gzip command not found.') unless $CMD{gzip}; |
|
} else { |
|
fatal('500 Internal Error', 'Unsupported archive type.'); |
|
} |
} |
|
|
my $tmpexportdir; |
my $tmpexportdir; |
Line 681 if ($input{tarball}) { |
|
Line 723 if ($input{tarball}) { |
|
('500 Internal Error', |
('500 Internal Error', |
'Export failure (exit status %s), output: <pre>%s</pre>', |
'Export failure (exit status %s), output: <pre>%s</pre>', |
$errcode, $err || $export_err); |
$errcode, $err || $export_err); |
|
|
} else { |
} else { |
|
|
$| = 1; # Essential to get the buffering right. |
$| = 1; # Essential to get the buffering right. |
local (*TAR_OUT); |
local (*TAR_OUT); |
|
my ($h, $err) = startproc($CMD{tar}, @tar_options, '-czf', '-', |
my (@cmd, $ctype); |
$basedir, '>pipe', \*TAR_OUT); |
if ($istar) { |
|
my @tar = ($CMD{tar}, @tar_options, '-cf', '-', $basedir); |
|
my @gzip = ($CMD{gzip}, @gzip_options, '-c'); |
|
push(@cmd, \@tar, '|', \@gzip); |
|
$ctype = 'application/x-gzip'; |
|
} |
|
push(@cmd, '>pipe', \*TAR_OUT); |
|
|
|
my ($h, $err) = startproc(@cmd); |
|
if ($h) { |
if ($h) { |
print "Content-Type: $ctype\r\n\r\n"; |
print "Content-Type: application/x-gzip\r\n\r\n"; |
local $/ = undef; |
local $/ = undef; |
print <TAR_OUT>; |
print <TAR_OUT>; |
$h->finish(); |
$h->finish(); |
Line 732 if (-d $fullname) { |
|
Line 763 if (-d $fullname) { |
|
|
|
if ($where eq '/') { |
if ($where eq '/') { |
html_header($defaulttitle); |
html_header($defaulttitle); |
$long_intro =~ s/!!CVSROOTdescr!!/$CVSROOTdescr{$cvstree}/g; |
|
print $long_intro; |
|
} else { |
} else { |
html_header($where); |
html_header($where); |
my $html = (-f catfile($fullname, 'README.cvs.html,v') || |
my $html = (-f catfile($fullname, 'README.cvs.html,v') || |
Line 770 if (-d $fullname) { |
|
Line 799 if (-d $fullname) { |
|
} |
} |
$h->finish(); |
$h->finish(); |
} |
} |
print $short_instruction; |
|
} |
} |
|
|
if ($use_descriptions && |
if ($use_descriptions && |
Line 799 if (-d $fullname) { |
|
Line 827 if (-d $fullname) { |
|
|
|
my $infocols = 1; |
my $infocols = 1; |
|
|
printf(<<EOF, $tablepadding, 'Directory index of ' . htmlquote($where)); |
printf(<<EOF, 'Directory index of ' . htmlquote($where)); |
<table class="dir" width="100%%" cellspacing="0" cellpadding="%s" summary="%s"> |
<table class="dir" width="100%%" cellspacing="0" cellpadding="2" summary="%s"> |
<tr> |
<tr> |
EOF |
EOF |
printf('<th colspan="2"%s>', ($byfile ? ' class="sorted"' : '')); |
printf('<th colspan="2"%s>', ($byfile ? ' class="sorted"' : '')); |
|
|
|
|
if ($allow_tar && $filesfound) { |
if ($allow_tar && $filesfound) { |
my ($basefile) = ($where =~ m,(?:.*/)?([^/]+),); |
my ($basefile) = ($where =~ m,(?:.*/)?([^/]+),); |
my $havetar = $CMD{tar} && $CMD{gzip}; |
if (defined($basefile) && $basefile ne '') { |
if (defined($basefile) && $basefile ne '' && $havetar) { |
|
my $q = ($query ? "$query;" : '?') . 'tarball=1'; |
my $q = ($query ? "$query;" : '?') . 'tarball=1'; |
print "<hr />\n", |
print "<hr />\n", |
'<div style="text-align: center">Download this directory in '; |
'<div style="text-align: center">Download this directory in '; |
Line 1260 elsif (do { (my $tmp = $fullname) =~ s|/([^/]+)$|/Atti |
|
Line 1287 elsif (do { (my $tmp = $fullname) =~ s|/([^/]+)$|/Atti |
|
|
|
} |
} |
|
|
elsif (0 && (my @files = &safeglob($fullname . ",v"))) { |
|
http_header("text/plain"); |
|
print "You matched the following files:\n"; |
|
print join ("\n", @files); |
|
|
|
# TODO: |
|
# Find the tags from each file |
|
# Display a form offering diffs between said tags |
|
} |
|
|
|
else { |
else { |
# Assume it's a module name with a potential path following it. |
# Assume it's a module name with a potential path following it. |
my $module; |
my $module; |
Line 1572 sub safeglob($) |
|
Line 1589 sub safeglob($) |
|
|
|
|
|
# |
# |
# Searches @command_path for the given executable file. |
|
# |
|
sub search_path($) |
|
{ |
|
my ($command) = @_; |
|
for my $d (@command_path) { |
|
my $cmd = catfile($d, $command); |
|
return $cmd if (-x $cmd && !-d _); |
|
} |
|
return ''; |
|
} |
|
|
|
|
|
# |
|
# Gets the MIME type for the given file name. |
# Gets the MIME type for the given file name. |
# |
# |
sub getMimeType($;$) |
sub getMimeType($;$) |
Line 1658 sub scan_directives(@) |
|
Line 1661 sub scan_directives(@) |
|
} |
} |
|
|
|
|
sub openOutputFilter() |
|
{ |
|
return unless $output_filter; |
|
|
|
open(STDOUT, "|-") and return; |
|
|
|
# child of child |
|
open(STDERR, '>', devnull()) unless $DEBUG; |
|
exec($output_filter) or exit -1; |
|
} |
|
|
|
|
|
############################### |
############################### |
# show Annotation |
# show Annotation |
############################### |
############################### |
Line 2089 sub doDiff($$$$$$) |
|
Line 2080 sub doDiff($$$$$$) |
|
|
|
my $mimetype = getMimeType($fullname); |
my $mimetype = getMimeType($fullname); |
|
|
# |
|
# Check for per-MIME type diff commands. |
|
# |
|
my $diffcmd = undef; |
|
if (my $diffcmds = $DIFF_COMMANDS{lc($mimetype)}) { |
|
if ($f =~ /^ext(\d*)$/) { |
|
my $n = $1 || 0; |
|
$diffcmd = $diffcmds->[$n]; |
|
} |
|
} |
|
if ($diffcmd && $diffcmd->{cmd} && $diffcmd->{name}) { |
|
|
|
if ($diffcmd->{args} && ref($diffcmd->{args}) ne 'ARRAY') { |
|
fatal('500 Internal Error', |
|
'Configuration error: arguments to external diff tools must ' . |
|
'be given as array refs. See "<code>%s</code>" in ' . |
|
'<code>%%DIFF_COMMANDS</code>.', |
|
$diffcmd->{name}); |
|
} |
|
|
|
(my $cvsname = $where) =~ s/\.diff$//; |
|
|
|
# Create two temporary files with the two revisions |
|
my $temp_fn1 = checkout_to_temp($cvsroot, $cvsname, $rev1); |
|
my $temp_fn2 = checkout_to_temp($cvsroot, $cvsname, $rev2); |
|
|
|
# Execute chosen diff binary. |
|
local (*DIFF_OUT); |
|
my @cmd = ($diffcmd->{cmd}); |
|
push(@cmd, @{$diffcmd->{args}}) if $diffcmd->{args}; |
|
push(@cmd, $temp_fn1, $temp_fn2); |
|
my ($h, $err) = startproc(\@cmd, \"", '>pipe', \*DIFF_OUT); |
|
if (!$h) { |
|
unlink($temp_fn1); |
|
unlink($temp_fn2); |
|
fatal('500 Internal Error', |
|
'Diff failure (exit status %s), output: <pre>%s</pre>', |
|
$? >> 8 || -1, $err); |
|
} |
|
|
|
http_header($diffcmd->{type} || 'text/plain'); |
|
local $/ = undef; |
|
print <DIFF_OUT>; |
|
$h->finish(); |
|
unlink($temp_fn1); |
|
unlink($temp_fn2); |
|
|
|
exit; |
|
} |
|
|
|
# |
|
# Normal CVS diff. |
|
# |
|
|
|
$f = $DEFAULTVALUE{f} || 'u' if ($f =~ /^ext\d*$/); |
$f = $DEFAULTVALUE{f} || 'u' if ($f =~ /^ext\d*$/); |
my $difftype = $DIFFTYPES{$f}; |
my $difftype = $DIFFTYPES{$f}; |
if (!$difftype) { |
if (!$difftype) { |
Line 2153 sub doDiff($$$$$$) |
|
Line 2090 sub doDiff($$$$$$) |
|
my $human_readable = $difftype->{colored}; |
my $human_readable = $difftype->{colored}; |
|
|
# Apply special diff options. |
# Apply special diff options. |
push @difftype, '-p' if $showfunc; |
push @difftype, '-p'; |
|
|
if ($human_readable) { |
if ($human_readable) { |
push(@difftype, '-w') if $hr_ignwhite; |
push(@difftype, '-w') if $hr_ignwhite; |
Line 2163 sub doDiff($$$$$$) |
|
Line 2100 sub doDiff($$$$$$) |
|
my $fh = do { local (*FH); }; |
my $fh = do { local (*FH); }; |
if (!open($fh, "-|")) { # child |
if (!open($fh, "-|")) { # child |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
openOutputFilter(); |
|
exec($CMD{rcsdiff}, @rcsdiff_options, @difftype, "-r$rev1", "-r$rev2", |
exec($CMD{rcsdiff}, @rcsdiff_options, @difftype, "-r$rev1", "-r$rev2", |
$fullname) or exit -1; |
$fullname) or exit -1; |
} |
} |
Line 2270 sub getDirLogs($$@) |
|
Line 2206 sub getDirLogs($$@) |
|
my $fh = do { local (*FH); }; |
my $fh = do { local (*FH); }; |
if (!open($fh, '-|')) { # Child |
if (!open($fh, '-|')) { # Child |
open(STDERR, '>', devnull()) unless $DEBUG; # Ignore rlog's complaints. |
open(STDERR, '>', devnull()) unless $DEBUG; # Ignore rlog's complaints. |
openOutputFilter(); |
|
if ($file_list_len && $file_list_len > 1) { |
if ($file_list_len && $file_list_len > 1) { |
while (scalar(@files) > $file_list_len) { # Process files in chunks. |
while (scalar(@files) > $file_list_len) { # Process files in chunks. |
system(@cmd, splice(@files, 0, $file_list_len)) == 0 or exit -1; |
system(@cmd, splice(@files, 0, $file_list_len)) == 0 or exit -1; |
Line 2424 sub getDirLogs($$@) |
|
Line 2359 sub getDirLogs($$@) |
|
|
|
if ($linesread == 0) { |
if ($linesread == 0) { |
fatal('500 Internal Error', |
fatal('500 Internal Error', |
'Failed to spawn GNU rlog on <em>"%s"</em>.<br /><br />Did you set the <b><code>@command_path</code></b> in your configuration file correctly? (Currently: "<code>%s</code>")', |
'Failed to spawn rlog on <em>"%s"</em>', |
htmlquote(join(', ', @files)), join(':', @command_path)); |
htmlquote(join(', ', @files))); |
} |
} |
|
|
return @unreadable; |
return @unreadable; |
} |
} |
|
|
Line 2449 sub readLog($;$) |
|
Line 2383 sub readLog($;$) |
|
|
|
my $fh = do { local (*FH); }; |
my $fh = do { local (*FH); }; |
if (!open($fh, "-|")) { # child |
if (!open($fh, "-|")) { # child |
openOutputFilter(); |
|
$revision = defined($revision) ? "-r$revision" : ''; |
$revision = defined($revision) ? "-r$revision" : ''; |
if ($revision =~ /\./) { |
if ($revision =~ /\./) { |
# Normal revision, not a branch/tag name. |
# Normal revision, not a branch/tag name. |
Line 2675 sub getDiffLinks($$$) |
|
Line 2608 sub getDiffLinks($$$) |
|
&link(htmlquote(lc($DIFFTYPES{$difftype}{descr})), "$url;f=$f")); |
&link(htmlquote(lc($DIFFTYPES{$difftype}{descr})), "$url;f=$f")); |
} |
} |
} |
} |
if (my $extdiffs = $DIFF_COMMANDS{lc($mimetype)}) { |
|
for my $i (0 .. scalar(@$extdiffs)-1) { |
|
my $extdiff = $extdiffs->[$i]; |
|
push(@links, &link(htmlquote($extdiff->{name}), "$url;f=ext$i")) |
|
if ($extdiff->{cmd} && $extdiff->{name}); |
|
} |
|
} |
|
return @links; |
return @links; |
} |
} |
|
|
Line 2733 sub printLog($$$;$$) |
|
Line 2659 sub printLog($$$;$$) |
|
print ' - view: ', join(', ', @vlinks) if @vlinks; |
print ' - view: ', join(', ', @vlinks) if @vlinks; |
undef @vlinks; |
undef @vlinks; |
|
|
if (!$isbin && $allow_version_select) { |
unless ($isbin) { |
print ' - '; |
print ' - '; |
if ($isSelected) { |
if ($isSelected) { |
print '<b>[selected for diffs]</b>'; |
print '<b>[selected for diffs]</b>'; |
|
|
my $diffrev = defined($input{r1}) ? |
my $diffrev = defined($input{r1}) ? |
$input{r1} : $revdisplayorder[$#revdisplayorder]; |
$input{r1} : $revdisplayorder[$#revdisplayorder]; |
|
|
printf(<<EOF, $inputTextSize, $diffrev); |
printf(<<EOF, $diffrev); |
<input type="text" size="%s" name="tr1" value="%s" onchange="this.form.r1.selectedIndex=0" /> |
<input type="text" size="12" name="tr1" value="%s" onchange="this.form.r1.selectedIndex=0" /> |
</td> |
</td> |
<td></td> |
<td></td> |
</tr> |
</tr> |
|
|
|
|
$diffrev = defined($input{r2}) ? $input{r2} : $revdisplayorder[0]; |
$diffrev = defined($input{r2}) ? $input{r2} : $revdisplayorder[0]; |
|
|
printf(<<EOF, $inputTextSize, $diffrev, $scriptwhere); |
printf(<<EOF, $diffrev, $scriptwhere); |
<input type="text" size="%s" name="tr2" value="%s" onchange="this.form.r2.selectedIndex=0" /> |
<input type="text" size="12" name="tr2" value="%s" onchange="this.form.r2.selectedIndex=0" /> |
</td> |
</td> |
<td><input type="submit" value="Get Diffs" accesskey="G" /></td> |
<td><input type="submit" value="Get Diffs" accesskey="G" /></td> |
</tr> |
</tr> |
Line 3669 sub http_header(;$$) |
|
Line 3595 sub http_header(;$$) |
|
{ |
{ |
my ($content_type, $moddate) = @_; |
my ($content_type, $moddate) = @_; |
$content_type ||= 'text/html'; |
$content_type ||= 'text/html'; |
|
$content_type .= '; charset="UTF-8"' if $content_type =~ /^text\//; |
|
|
$content_type .= "; charset=$charset" |
|
if ($charset && $content_type =~ m,^text/,); |
|
|
|
# Note that in the following, we explicitly join() and concatenate the |
# Note that in the following, we explicitly join() and concatenate the |
# headers instead of printing them as an array. This is because some |
# headers instead of printing them as an array. This is because some |
# systems, eg. early versions of mod_perl 2 don't quite get it if the |
# systems, eg. early versions of mod_perl 2 don't quite get it if the |
|
|
$errormsg = "'@{$_[0]}' failed: $@"; |
$errormsg = "'@{$_[0]}' failed: $@"; |
} |
} |
return ($exitcode, $errormsg); |
return ($exitcode, $errormsg); |
} |
|
|
|
# |
|
# Check out a file to a temporary file. |
|
# |
|
sub checkout_to_temp($$$) |
|
{ |
|
my ($cvsroot, $cvsname, $rev) = @_; |
|
|
|
# Pipe given cvs file into a temporary place. |
|
my ($temp_fh, $temp_fn) = tempfile('.cvsweb.XXXXXXXX', DIR => tmpdir()); |
|
|
|
my @cmd = ($CMD{cvs}, @cvs_options, '-Qd', $cvsroot, |
|
'co', '-p', "-r$rev", $cvsname); |
|
|
|
local (*DIFF_OUT); |
|
my ($h, $err) = startproc(\@cmd, \"", '>pipe', \*DIFF_OUT); |
|
if ($h) { |
|
local $/ = undef; |
|
print $temp_fh <DIFF_OUT>; |
|
$h->finish(); |
|
close($temp_fh); |
|
} else { |
|
close($temp_fh); |
|
unlink($temp_fn); |
|
fatal('500 Internal Error', |
|
'Checkout failure (exit status %s), output: <pre>%s</pre>', |
|
$? >> 8 || -1, $err); |
|
} |
|
|
|
return $temp_fn; |
|
} |
} |
|
|
# |
# |