===================================================================
RCS file: /cvs/cvsweb/cvsweb.cgi,v
retrieving revision 4.28
retrieving revision 4.39
diff -u -p -r4.28 -r4.39
--- cvsweb/cvsweb.cgi 2019/11/26 12:14:38 4.28
+++ cvsweb/cvsweb.cgi 2019/11/29 23:42:40 4.39
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $Id: cvsweb.cgi,v 4.28 2019/11/26 12:14:38 schwarze Exp $
+# $Id: cvsweb.cgi,v 4.39 2019/11/29 23:42:40 schwarze Exp $
# $knu: cvsweb.cgi,v 1.299 2010/11/13 16:37:18 simon
#
# cvsweb - a CGI interface to CVS trees.
@@ -55,10 +55,8 @@ use filetest qw(access);
use vars qw (
$VERSION $CheckoutMagic $MimeTypes $DEBUG
- $config $allow_version_select
- @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr
- %DEFAULTVALUE %ICONS %MTYPES
- %DIFF_COMMANDS @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
+ @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr %DEFAULTVALUE %MTYPES
+ @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
%alltags %fileinfo %tags @branchnames %nameprinted
%symrev %revsym @allrevisions %date %author @revdisplayorder
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution
@@ -67,19 +65,17 @@ use vars qw (
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased
%input $query $barequery $sortby $bydate $byrev $byauthor
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot
- $charset $output_filter
- @command_path %CMD $allow_compress $backicon $diricon $fileicon
- $fullname $logo $defaulttitle $address $binfileicon
- $long_intro $short_instruction $shortLogLen $show_author
- $tablepadding $hr_breakable $showfunc $hr_ignwhite $hr_ignkeysubst
- $inputTextSize $mime_types $allow_annotate $allow_markup $allow_mailtos
+ %CMD $allow_compress $backicon $diricon $fileicon
+ $fullname $logo $defaulttitle $address $binfileicon $iconsdir
+ $shortLogLen $show_author $hr_breakable $hr_ignwhite $hr_ignkeysubst
+ $mime_types $allow_annotate $allow_markup $allow_mailtos
$allow_log_extra $allow_dir_extra $allow_source_extra
$edit_option_form
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup
$tabstop $state $annTable $sel @ForbiddenFiles
$use_descriptions %descriptions $dwhere
$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
$HTML_DOCTYPE $HTML_META $cssurl $CSS
);
@@ -89,7 +85,7 @@ use Cwd qw(abs_path);
use File::Path qw(rmtree);
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir
tmpdir updir);
-use File::Temp qw(tempdir tempfile);
+use File::Temp qw(tempdir);
use IPC::Run qw();
use Time::Local qw(timegm);
use URI::Escape qw(uri_escape uri_unescape);
@@ -150,7 +146,6 @@ sub search_path($);
sub getMimeType($;$);
sub head($;$);
sub scan_directives(@);
-sub openOutputFilter();
sub doAnnotate($$);
sub doCheckout($$$);
sub cvswebMarkup($$$$$$;$);
@@ -183,31 +178,99 @@ sub link_tags($);
sub forbidden($);
sub startproc(@);
sub runproc(@);
-sub checkout_to_temp($$$);
# Get rid of unsafe environment vars. Don't do this in the BEGIN block
# (think mod_perl)...
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)});
-# Location of the configuration file inside the web server chroot:
-$config = '/conf/cvsweb/cvsweb.conf';
+# Helps to achieve read only access to the repositories
+# with cvs >= 1.12.1 and doesn't hurt other versions.
+$ENV{CVSREADONLYFS} = 1;
-######## Configuration parameters #########
+######## configuration defaults #########
-@CVSrepositories = @CVSROOT = %CVSROOT = %DEFAULTVALUE = %ICONS =
- %MTYPES = %tags = %alltags = %fileinfo = %DIFF_COMMANDS = ();
+%CMD = (
+ cvs => '/usr/bin/cvs',
+ rcsdiff => '/usr/bin/rcsdiff',
+ rlog => '/usr/bin/rlog',
+ tar => '/bin/tar',
+);
-$logo = $defaulttitle =
- $address = $long_intro = $short_instruction = $shortLogLen = $show_author =
- $tablepadding = $hr_breakable = $showfunc = $hr_ignwhite =
- $hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate =
- $allow_markup = $allow_compress = $edit_option_form =
- $show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup =
- $tabstop = $use_moddate = $gzip_open = $DEBUG =
- $allow_tar = undef;
+%DEFAULTVALUE = (
+ f => 'u',
+ hideattic => 1,
+ hidecvsroot => 0,
+ hidenonreadable => 1,
+ ignorecase => 0,
+ ln => 0,
+ 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 "%s
":
%s', + $config, $@; + fatal '500 Internal Error', + 'Cannot read configuration file "
%s
": %s',
+ $config, $! || 'unknown error';
+}
+
+######## other global variables #########
+
@DIFFTYPES = qw(h H u c);
@DIFFTYPES{@DIFFTYPES} = (
{
@@ -239,8 +302,16 @@ $allow_version_select = $allow_mailtos = $allow_log_ex
{ descr => 'Revision', },
);
-##### End of configuration parameters #####
+%alltags = ();
+@CVSROOT = ();
+%CVSROOT = ();
+%CVSROOTdescr = ();
+%fileinfo = ();
+$gzip_open = 0;
+%tags = ();
+######## end of global variables #########
+
my $pathinfo = '';
if (defined($ENV{PATH_INFO}) && $ENV{PATH_INFO} ne '') {
($pathinfo) = ($ENV{PATH_INFO} =~ VALID_PATH)
@@ -313,20 +384,6 @@ $maycompress = (
qw(cvsroot hideattic ignorecase sortby logsort f only_with_tag ln
hidecvsroot hidenonreadable);
-# Load configuration.
-{
- $config =~ m|^/| or fatal '500 Internal Error',
- 'Configuration file name "%s
" is not an absolute path.',
- $config;
- defined do $config and last;
- $@ and fatal '500 Internal Error',
- 'Error loading configuration file "%s
": %s', - $config, $@; - fatal '500 Internal Error', - 'Cannot read configuration file "
%s
": %s',
- $config, $! || 'unknown error';
-}
-
# 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
# work properly.
@@ -476,10 +533,7 @@ for (my $i = 0; $i < scalar(@CVSrepositories); $i += 2
push(@CVSROOT, $key);
}
unless ($rootfound) {
- fatal('500 Internal Error',
- 'No valid CVS roots found! See @CVSrepositories
in ' .
- 'the configuration file (%s
).',
- $config);
+ fatal('500 Internal Error', 'no valid CVS roots found');
}
undef $rootfound;
@@ -567,30 +621,22 @@ if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) {
$cvsroot = $CVSROOT{$cvstree};
-# create icons out of description
-foreach my $k (keys %ICONS) {
- my ($itxt, $ipath, $iwidth, $iheight) = @{$ICONS{$k}};
- no strict 'refs';
- if ($ipath) {
- ${"${k}icon"} =
- sprintf('',
- htmlquote($ipath), htmlquote($itxt), $iwidth, $iheight);
- } else {
- ${"${k}icon"} = $itxt;
- }
+if ($iconsdir) {
+ $backicon = '';
+ $diricon = '';
+ $fileicon = '';
+ $binfileicon = '';
+} 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%s', $errcode, $err || $export_err); - } else { - $| = 1; # Essential to get the buffering right. local (*TAR_OUT); - - my (@cmd, $ctype); - 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); + my ($h, $err) = startproc($CMD{tar}, @tar_options, '-czf', '-', + $basedir, '>pipe', \*TAR_OUT); if ($h) { - print "Content-Type: $ctype\r\n\r\n"; + print "Content-Type: application/x-gzip\r\n\r\n"; local $/ = undef; print
%s
" in ' .
- '%%DIFF_COMMANDS
.',
- $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: %s', - $? >> 8 || -1, $err); - } - - http_header($diffcmd->{type} || 'text/plain'); - local $/ = undef; - print
@command_path
in your configuration file correctly? (Currently: "%s
")',
- htmlquote(join(', ', @files)), join(':', @command_path));
+ 'Failed to spawn rlog on "%s"',
+ htmlquote(join(', ', @files)));
}
-
return @unreadable;
}
@@ -2449,7 +2393,6 @@ sub readLog($;$)
my $fh = do { local (*FH); };
if (!open($fh, "-|")) { # child
- openOutputFilter();
$revision = defined($revision) ? "-r$revision" : '';
if ($revision =~ /\./) {
# Normal revision, not a branch/tag name.
@@ -2675,13 +2618,6 @@ sub getDiffLinks($$$)
&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;
}
@@ -2733,7 +2669,7 @@ sub printLog($$$;$$)
print ' - view: ', join(', ', @vlinks) if @vlinks;
undef @vlinks;
- if (!$isbin && $allow_version_select) {
+ unless ($isbin) {
print ' - ';
if ($isSelected) {
print '[selected for diffs]';
@@ -2957,8 +2893,8 @@ EOF
my $diffrev = defined($input{r1}) ?
$input{r1} : $revdisplayorder[$#revdisplayorder];
- printf(<%s', - $? >> 8 || -1, $err); - } - - return $temp_fn; } #