[BACK]Return to cvsweb.cgi CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / cvsweb

Diff for /cvsweb/cvsweb.cgi between version 4.26 and 4.37

version 4.26, 2019/11/26 12:04:55 version 4.37, 2019/11/29 18:50:15
Line 56  use filetest qw(access);
Line 56  use filetest qw(access);
 use vars qw (  use vars qw (
   $VERSION $CheckoutMagic $MimeTypes $DEBUG    $VERSION $CheckoutMagic $MimeTypes $DEBUG
   $config $allow_version_select    $config $allow_version_select
   @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr    @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr %DEFAULTVALUE %MTYPES
   %MIRRORS %DEFAULTVALUE %ICONS %MTYPES    @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
   %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
Line 67  use vars qw (
Line 66  use vars qw (
   $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    $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 86  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 129  EOM
Line 126  EOM
   $MimeTypes = undef if $@;    $MimeTypes = undef if $@;
   
   $CheckoutMagic = '~checkout~';    $CheckoutMagic = '~checkout~';
     $CMD{$_} = "/usr/bin/$_" for (qw(cvs rcsdiff rlog));
     $CMD{tar} = "/bin/tar";
 }  }
   
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
Line 167  sub plural_write($$);
Line 166  sub plural_write($$);
 sub readableTime($$);  sub readableTime($$);
 sub clickablePath($$);  sub clickablePath($$);
 sub chooseCVSRoot();  sub chooseCVSRoot();
 sub chooseMirror();  
 sub fileSortCmp();  sub fileSortCmp();
 sub download_url($$;$);  sub download_url($$;$);
 sub download_link($$$;$);  sub download_link($$$;$);
Line 184  sub link_tags($);
Line 182  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)});
   
   # Helps to achieve read only access to the repositories
   # with cvs >= 1.12.1 and doesn't hurt other versions.
   $ENV{CVSREADONLYFS} = 1;
   
 # Location of the configuration file inside the web server chroot:  # Location of the configuration file inside the web server chroot:
 $config = '/conf/cvsweb/cvsweb.conf';  $config = '/conf/cvsweb/cvsweb.conf';
   
 ######## Configuration parameters #########  ######## Configuration parameters #########
   
 @CVSrepositories = @CVSROOT = %CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS =  @CVSrepositories = @CVSROOT = %CVSROOT = %DEFAULTVALUE =
   %MTYPES = %tags = %alltags = %fileinfo = %DIFF_COMMANDS = ();    %MTYPES = %tags = %alltags = %fileinfo = ();
   
 $logo = $defaulttitle =  $logo = $defaulttitle =
   $address = $long_intro = $short_instruction = $shortLogLen = $show_author =    $address = $shortLogLen = $show_author =
   $tablepadding = $hr_breakable = $showfunc = $hr_ignwhite =    $hr_breakable = $hr_ignwhite =
   $hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate =    $hr_ignkeysubst = $mime_types = $allow_annotate =
   $allow_markup = $allow_compress = $edit_option_form =    $allow_markup = $allow_compress = $edit_option_form =
   $show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup =    $show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup =
   $tabstop = $use_moddate = $gzip_open = $DEBUG =    $tabstop = $use_moddate = $gzip_open = $DEBUG =
Line 568  if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) {
Line 569  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";  my $config_cvstree = "$config-$cvstree";
Line 645  if ($input{tarball}) {
Line 649  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 682  if ($input{tarball}) {
Line 682  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 733  if (-d $fullname) {
Line 722  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 771  if (-d $fullname) {
Line 758  if (-d $fullname) {
       }        }
       $h->finish();        $h->finish();
     }      }
     print $short_instruction;  
   }    }
   
   if ($use_descriptions &&    if ($use_descriptions &&
Line 788  if (-d $fullname) {
Line 774  if (-d $fullname) {
   
   # give direct access to dirs    # give direct access to dirs
   if ($where eq '/') {    if ($where eq '/') {
     chooseMirror();  
     chooseCVSRoot();      chooseCVSRoot();
   
   } else {    } else {
     print '<p>Current directory: <b>', clickablePath($where, 0), '</b>';      print '<p>Current directory: <b>', clickablePath($where, 0), '</b>';
     print "</p>\n";      print "</p>\n";
Line 802  if (-d $fullname) {
Line 786  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"' : ''));
Line 1097  EOF
Line 1081  EOF
   
   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 1575  sub safeglob($)
Line 1558  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 2092  sub doDiff($$$$$$)
Line 2061  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 2156  sub doDiff($$$$$$)
Line 2071  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 2427  sub getDirLogs($$@)
Line 2342  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 2678  sub getDiffLinks($$$)
Line 2592  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 2960  EOF
Line 2867  EOF
   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>
Line 2977  EOF
Line 2884  EOF
   
   $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 3482  EOF
Line 3389  EOF
 }  }
   
   
 sub chooseMirror()  
 {  
   # This code comes from the original BSD-cvsweb  
   # and may not be useful for your site; If you don't  
   # set %MIRRORS this won't show up, anyway.  
   scalar(%MIRRORS) or return;  
   
   # Should perhaps exclude the current site somehow...  
   print "\n<p>\nThis CVSweb is mirrored in\n";  
   
   my @tmp = map(&link(htmlquote($_), $MIRRORS{$_}), sort keys %MIRRORS);  
   my $tmp = pop (@tmp);  
   
   if (scalar(@tmp)) {  
     print join (', ', @tmp), ' and ';  
   }  
   
   print "$tmp.\n</p>\n";  
 }  
   
   
 sub fileSortCmp()  sub fileSortCmp()
 {  {
   (my $af = $a) =~ s/,v$//;    (my $af = $a) =~ s/,v$//;
Line 3822  sub runproc(@)
Line 3708  sub runproc(@)
     $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;  
 }  }
   
 #  #

Legend:
Removed from v.4.26  
changed lines
  Added in v.4.37

CVSweb