version 1.1.1.27, 2001/07/06 09:54:57 |
version 3.35, 2000/10/10 21:14:05 |
|
|
#!/usr/bin/perl -wT |
#!/usr/bin/perl5 -ws |
# |
# |
# cvsweb - a CGI interface to CVS trees. |
# cvsweb - a CGI interface to CVS trees. |
# |
# |
|
|
# Copyright (c) 1996-1998 Bill Fenner |
# Copyright (c) 1996-1998 Bill Fenner |
# (c) 1998-1999 Henner Zeller |
# (c) 1998-1999 Henner Zeller |
# (c) 1999 Henrik Nordstrom |
# (c) 1999 Henrik Nordstrom |
# (c) 2000-2001 Akinori MUSHA |
# (c) 2000 Akinori MUSHA |
# All rights reserved. |
# All rights reserved. |
# |
# |
# Redistribution and use in source and binary forms, with or without |
# Redistribution and use in source and binary forms, with or without |
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# SUCH DAMAGE. |
# |
# |
# $zId: cvsweb.cgi,v 1.110 2001/06/29 09:29:36 hnordstrom Exp $ |
# $zId: cvsweb.cgi,v 1.103 2000/09/20 17:02:29 jumager Exp $ |
# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.78 2001/07/06 09:49:01 knu Exp $ |
# $Id$ |
# |
# |
### |
### |
|
|
require 5.000; |
|
|
|
use strict; |
use strict; |
|
|
use vars qw ( |
use vars qw ( |
$cvsweb_revision |
$config $allow_version_select $verbose |
$mydir $uname $config $allow_version_select $verbose |
%CVSROOT %CVSROOTdescr %MIRRORS %DEFAULTVALUE %ICONS %MTYPES |
@CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr |
|
%MIRRORS %DEFAULTVALUE %ICONS %MTYPES |
|
@DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS |
|
%alltags @tabcolors %fileinfo %tags @branchnames %nameprinted |
%alltags @tabcolors %fileinfo %tags @branchnames %nameprinted |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
@revisions %state %difflines %log %branchpoint @revorder |
@revisions %state %difflines %log %branchpoint @revorder |
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi |
$prcgi @prcategories $prcategories $mancgi |
$checkoutMagic $doCheckout $scriptname $scriptwhere |
$checkoutMagic $doCheckout $scriptname $scriptwhere |
$where $pathinfo $Browser $nofilelinks $maycompress @stickyvars |
$where $pathinfo $Browser $nofilelinks $maycompress @stickyvars |
%funcline_regexp $is_mod_perl |
%funcline_regexp $is_mod_perl |
$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 $hr_default $logsort $cvstree $cvsroot |
$mimetype $charset $defaultTextPlain $defaultViewable |
$mimetype $defaultTextPlain $defaultViewable $allow_compress |
$command_path %CMD $allow_compress |
$GZIPBIN $backicon $diricon $fileicon $fullname $newname |
$backicon $diricon $fileicon |
$cvstreedefault $body_tag $body_tag_for_src |
$fullname $newname $cvstreedefault |
$logo $defaulttitle $address |
$body_tag $body_tag_for_src $logo $defaulttitle $address |
|
$long_intro $short_instruction $shortLogLen |
$long_intro $short_instruction $shortLogLen |
$show_author $dirtable $tablepadding $columnHeaderColorDefault |
$show_author $dirtable $tablepadding $columnHeaderColorDefault |
$columnHeaderColorSorted $hr_breakable $showfunc $hr_ignwhite |
$columnHeaderColorSorted $hr_breakable $showfunc $hr_ignwhite |
|
|
$difffontsize $inputTextSize $mime_types $allow_annotate |
$difffontsize $inputTextSize $mime_types $allow_annotate |
$allow_markup $use_java_script $open_extern_window |
$allow_markup $use_java_script $open_extern_window |
$extern_window_width $extern_window_height $edit_option_form |
$extern_window_width $extern_window_height $edit_option_form |
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup $v |
$show_subdir_lastmod $show_log_in_markup $v |
$navigationHeaderColor $tableBorderColor $markupLogColor |
$navigationHeaderColor $tableBorderColor $markupLogColor |
$tabstop $state $annTable $sel $curbranch @HideModules |
$tabstop $state $annTable $sel $curbranch @HideModules |
$module $use_descriptions %descriptions @mytz $dwhere $moddate |
$module $use_descriptions %descriptions @mytz $dwhere $moddate |
$use_moddate $has_zlib $gzip_open |
$use_moddate $has_zlib $gzip_open |
$allow_tar @tar_options @gzip_options @zip_options @cvs_options |
|
$LOG_FILESEPARATOR $LOG_REVSEPARATOR |
$LOG_FILESEPARATOR $LOG_REVSEPARATOR |
); |
); |
|
|
sub printDiffSelect($); |
sub printDiffSelect($); |
sub printDiffLinks($$); |
|
sub printLogSortSelect($); |
|
sub findLastModifiedSubdirs(@); |
sub findLastModifiedSubdirs(@); |
sub htmlify_sub(&$); |
|
sub htmlify($;$); |
sub htmlify($;$); |
sub spacedHtmlText($;$); |
sub spacedHtmlText($;$); |
sub link($$); |
sub link($$); |
|
|
sub fatal($$); |
sub fatal($$); |
sub redirect($); |
sub redirect($); |
sub safeglob($); |
sub safeglob($); |
sub search_path($); |
|
sub getMimeTypeFromSuffix($); |
sub getMimeTypeFromSuffix($); |
sub head($;$); |
sub head($;$); |
sub scan_directives(@); |
sub scan_directives(@); |
Line 128 sub download_link($$$;$); |
|
Line 117 sub download_link($$$;$); |
|
sub toggleQuery($$); |
sub toggleQuery($$); |
sub urlencode($); |
sub urlencode($); |
sub htmlquote($); |
sub htmlquote($); |
sub htmlunquote($); |
|
sub hrefquote($); |
|
sub http_header(;$); |
sub http_header(;$); |
sub html_header($); |
sub html_header($); |
sub html_footer(); |
sub html_footer(); |
Line 137 sub link_tags($); |
|
Line 124 sub link_tags($); |
|
sub forbidden_module($); |
sub forbidden_module($); |
|
|
##### Start of Configuration Area ######## |
##### Start of Configuration Area ######## |
delete $ENV{PATH}; |
use Cwd; |
|
|
$cvsweb_revision = '1.110' . '.' . (split(/ /, |
|
q$Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.78 2001/07/06 09:49:01 knu Exp $ |
|
))[2]; |
|
|
|
use File::Basename; |
|
|
|
($mydir) = (dirname($0) =~ /(.*)/); # untaint |
|
|
|
# == EDIT this == |
# == EDIT this == |
# Locations to search for user configuration, in order: |
# Locations to search for user configuration, in order: |
for ( |
for ( |
"$mydir/cvsweb.conf", |
$ENV{CVSWEB_CONFIG}, |
'/usr/local/etc/cvsweb/cvsweb.conf' |
'/usr/local/etc/cvsweb.conf', |
|
getcwd() . '/cvsweb.conf' |
) { |
) { |
if (defined($_) && -r $_) { |
$config = $_ if defined($_) && -r $_; |
$config = $_; |
|
last; |
|
} |
|
} |
} |
|
|
# == Configuration defaults == |
# == Configuration defaults == |
Line 168 $allow_version_select = 1; |
|
Line 145 $allow_version_select = 1; |
|
|
|
######## Configuration variables ######### |
######## Configuration variables ######### |
# These are defined to allow checking with perl -cw |
# These are defined to allow checking with perl -cw |
@CVSrepositories = @CVSROOT = %CVSROOT = |
%CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = %MTYPES = |
%MIRRORS = %DEFAULTVALUE = %ICONS = %MTYPES = |
%tags = %alltags = @tabcolors = (); |
%tags = %alltags = @tabcolors = %fileinfo = (); |
|
$cvstreedefault = $body_tag = $body_tag_for_src = |
$cvstreedefault = $body_tag = $body_tag_for_src = |
$logo = $defaulttitle = $address = |
$logo = $defaulttitle = $address = |
$long_intro = $short_instruction = $shortLogLen = |
$long_intro = $short_instruction = $shortLogLen = |
Line 188 $tabstop = $use_moddate = $moddate = $gzip_open = unde |
|
Line 164 $tabstop = $use_moddate = $moddate = $gzip_open = unde |
|
$LOG_FILESEPARATOR = q/^={77}$/; |
$LOG_FILESEPARATOR = q/^={77}$/; |
$LOG_REVSEPARATOR = q/^-{28}$/; |
$LOG_REVSEPARATOR = q/^-{28}$/; |
|
|
@DIFFTYPES = qw(h H u c s); |
|
@DIFFTYPES{@DIFFTYPES} = ( |
|
{ |
|
'descr' => 'colored', |
|
'opts' => [ '-u' ], |
|
'colored' => 1, |
|
}, |
|
{ |
|
'descr' => 'long colored', |
|
'opts' => [ '--unified=15' ], |
|
'colored' => 1, |
|
}, |
|
{ |
|
'descr' => 'unified', |
|
'opts' => [ '-u' ], |
|
'colored' => 0, |
|
}, |
|
{ |
|
'descr' => 'context', |
|
'opts' => [ '-c' ], |
|
'colored' => 0, |
|
}, |
|
{ |
|
'descr' => 'side by side', |
|
'opts' => [ '--side-by-side', '--width=164' ], |
|
'colored' => 0, |
|
}, |
|
); |
|
|
|
@LOGSORTKEYS = qw(cvs date rev); |
|
@LOGSORTKEYS{@LOGSORTKEYS} = ( |
|
{ |
|
'descr' => 'Not sorted', |
|
}, |
|
{ |
|
'descr' => 'Commit date', |
|
}, |
|
{ |
|
'descr' => 'Revision', |
|
}, |
|
); |
|
|
|
|
|
##### End of configuration variables ##### |
##### End of configuration variables ##### |
|
|
use Time::Local; |
use Time::Local; |
|
|
$checkoutMagic = "~checkout~"; |
$checkoutMagic = "~checkout~"; |
$pathinfo = defined($ENV{PATH_INFO}) ? $ENV{PATH_INFO} : ''; |
$pathinfo = defined($ENV{PATH_INFO}) ? $ENV{PATH_INFO} : ''; |
$where = $pathinfo; |
$where = $pathinfo; |
$doCheckout = ($where =~ m|^/$checkoutMagic/|); |
$doCheckout = ($where =~ /^\/$checkoutMagic/); |
$where =~ s|^/$checkoutMagic/|/|; |
$where =~ s|^/($checkoutMagic)?||; |
$where =~ s|^/||; |
$where =~ s|/+$||; |
$scriptname = defined($ENV{SCRIPT_NAME}) ? $ENV{SCRIPT_NAME} : ''; |
$scriptname = defined($ENV{SCRIPT_NAME}) ? $ENV{SCRIPT_NAME} : ''; |
$scriptname =~ s|^/*|/|; |
$scriptname =~ s|^/?|/|; |
|
$scriptname =~ s|/+$||; |
# Let's workaround thttpd's stupidity.. |
$scriptwhere = $scriptname; |
if ($scriptname =~ m|/$|) { |
if ($where) { |
$pathinfo .= '/'; |
$scriptwhere .= '/' . urlencode($where); |
my $re = quotemeta $pathinfo; |
|
$scriptname =~ s/$re$//; |
|
} |
} |
|
|
$scriptwhere = $scriptname; |
|
$scriptwhere .= '/' . urlencode($where); |
|
$where = '/' if ($where eq ''); |
|
|
|
$is_mod_perl = defined($ENV{MOD_PERL}); |
$is_mod_perl = defined($ENV{MOD_PERL}); |
|
|
# in lynx, it it very annoying to have two links |
# in lynx, it it very annoying to have two links |
# per file, so disable the link at the icon |
# per file, so disable the link at the icon |
# in this case: |
# in this case: |
$Browser = $ENV{HTTP_USER_AGENT} || ''; |
$Browser = $ENV{HTTP_USER_AGENT}; |
$is_links = ($Browser =~ m`^Links `); |
$is_links = ($Browser =~ m`^Links `); |
$is_lynx = ($Browser =~ m`^Lynx/`i); |
$is_lynx = ($Browser =~ m`^Lynx/`i); |
$is_w3m = ($Browser =~ m`^w3m/`i); |
$is_w3m = ($Browser =~ m`^w3m/`i); |
Line 302 $maycompress = (((defined($ENV{HTTP_ACCEPT_ENCODING}) |
|
Line 229 $maycompress = (((defined($ENV{HTTP_ACCEPT_ENCODING}) |
|
@stickyvars = qw(cvsroot hideattic sortby logsort f only_with_tag); |
@stickyvars = qw(cvsroot hideattic sortby logsort f only_with_tag); |
|
|
if (-f $config) { |
if (-f $config) { |
require $config |
do $config |
|| &fatal("500 Internal Error", |
|| &fatal("500 Internal Error", |
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
$config, &htmlify($@))); |
$config, &htmlify($@))); |
} else { |
} else { |
&fatal("500 Internal Error", |
&fatal("500 Internal Error", |
'Configuration not found. Set the variable <code>$config</code> ' |
'Configuration not found. Set the variable <code>$config</code> ' |
. 'in cvsweb.cgi to your <b>cvsweb.conf</b> configuration file first.'); |
. 'in cvsweb.cgi, or the environment variable ' |
|
. '<code>CVSWEB_CONFIG</code>, to your <b>cvsweb.conf</b> ' |
|
. 'configuration file first.'); |
} |
} |
|
|
undef %input; |
undef %input; |
Line 317 $query = $ENV{QUERY_STRING}; |
|
Line 246 $query = $ENV{QUERY_STRING}; |
|
|
|
if (defined($query) && $query ne '') { |
if (defined($query) && $query ne '') { |
foreach (split(/&/, $query)) { |
foreach (split(/&/, $query)) { |
y/+/ /; |
|
s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted |
s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted |
if (/(\S+)=(.*)/) { |
if (/(\S+)=(.*)/) { |
$input{$1} = $2 if ($2 ne ""); |
$input{$1} = $2 if ($2 ne ""); |
|
|
} |
} |
undef @barequery; |
undef @barequery; |
|
|
if (defined($input{path})) { |
|
redirect("$scriptname/$input{path}$query"); |
|
} |
|
|
|
# get actual parameters |
# get actual parameters |
$sortby = $input{"sortby"}; |
$sortby = $input{"sortby"}; |
$bydate = 0; |
$bydate = 0; |
|
|
$byfile = 1; |
$byfile = 1; |
} |
} |
|
|
$defaultDiffType = $input{'f'}; |
$hr_default = $input{'f'} eq 'h'; |
|
|
$logsort = $input{'logsort'}; |
$logsort = $input{'logsort'}; |
|
|
my @tmp = @CVSrepositories; |
|
my @pair; |
|
|
|
while (@pair = splice(@tmp, 0, 2)) { |
|
my($key, $val) = @pair; |
|
my($descr, $cvsroot) = @$val; |
|
|
|
next if !-d $cvsroot; |
|
|
|
$CVSROOTdescr{$key} = $descr; |
|
$CVSROOT{$key} = $cvsroot; |
|
push @CVSROOT, $key; |
|
} |
|
undef @tmp; |
|
undef @pair; |
|
|
|
## Default CVS-Tree |
## Default CVS-Tree |
if (!defined($CVSROOT{$cvstreedefault})) { |
if (!defined($CVSROOT{$cvstreedefault})) { |
&fatal("500 Internal Error", |
&fatal("500 Internal Error", |
Line 447 foreach $k (keys %ICONS) { |
|
Line 356 foreach $k (keys %ICONS) { |
|
my ($itxt,$ipath,$iwidth,$iheight) = @{$ICONS{$k}}; |
my ($itxt,$ipath,$iwidth,$iheight) = @{$ICONS{$k}}; |
if ($ipath) { |
if ($ipath) { |
${"${k}icon"} = sprintf('<IMG SRC="%s" ALT="%s" BORDER="0" WIDTH="%d" HEIGHT="%d">', |
${"${k}icon"} = sprintf('<IMG SRC="%s" ALT="%s" BORDER="0" WIDTH="%d" HEIGHT="%d">', |
hrefquote($ipath), htmlquote($itxt), $iwidth, $iheight) |
htmlquote($ipath), htmlquote($itxt), $iwidth, $iheight) |
} |
} |
else { |
else { |
${"${k}icon"} = $itxt; |
${"${k}icon"} = $itxt; |
Line 459 my $config_cvstree = "$config-$cvstree"; |
|
Line 368 my $config_cvstree = "$config-$cvstree"; |
|
|
|
# Do some special configuration for cvstrees |
# Do some special configuration for cvstrees |
if (-f $config_cvstree) { |
if (-f $config_cvstree) { |
require $config_cvstree |
do $config_cvstree |
|| &fatal("500 Internal Error", |
|| &fatal("500 Internal Error", |
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
$config_cvstree, &htmlify($@))); |
$config_cvstree, &htmlify($@))); |
} |
} |
undef $config_cvstree; |
undef $config_cvstree; |
|
|
$re_prcategories = '(?:' . join('|', @prcategories) . ')' if @prcategories; |
$prcategories = '(?:' . join('|', @prcategories) . ')'; |
$re_prkeyword = quotemeta($prkeyword) if defined($prkeyword); |
|
$prcgi .= '%s' if defined($prcgi) && $prcgi !~ /%s/; |
$prcgi .= '%s' if defined($prcgi) && $prcgi !~ /%s/; |
|
|
$fullname = "$cvsroot/$where"; |
$fullname = $cvsroot . '/' . $where; |
$mimetype = &getMimeTypeFromSuffix ($fullname); |
$mimetype = &getMimeTypeFromSuffix ($fullname); |
$defaultTextPlain = ($mimetype eq "text/plain"); |
$defaultTextPlain = ($mimetype eq "text/plain"); |
$defaultViewable = $allow_markup && viewable($mimetype); |
$defaultViewable = $allow_markup && viewable($mimetype); |
|
|
my $rewrite = 0; |
# search for GZIP if compression allowed |
|
# We've to find out if the GZIP-binary exists .. otherwise |
if ($pathinfo =~ m|//|) { |
# ge get an Internal Server Error if we try to pipe the |
$pathinfo =~ y|/|/|s; |
# output through the nonexistent gzip .. |
$rewrite = 1; |
# any more elegant ways to prevent this are welcome! |
|
if ($allow_compress && $maycompress && !$has_zlib) { |
|
foreach (split(/:/, $ENV{PATH})) { |
|
if (-x "$_/gzip") { |
|
$GZIPBIN = "$_/gzip"; |
|
last; |
|
} |
|
} |
} |
} |
|
|
if (-d $fullname && $pathinfo !~ m|/$|) { |
if (-d $fullname) { |
$pathinfo .= '/'; |
# |
$rewrite = 1; |
# ensure, that directories always end with (exactly) one '/' |
|
# to allow relative URL's. If they're not, make a redirect. |
|
## |
|
if (!($pathinfo =~ m|/$|) || ($pathinfo =~ m |/{2,}$|)) { |
|
redirect ($scriptwhere . '/' . $query); |
|
} |
|
else { |
|
$where .= '/'; |
|
$scriptwhere .= '/'; |
|
} |
} |
} |
|
|
if (!-d $fullname && $pathinfo =~ m|/$|) { |
|
chop $pathinfo; |
|
$rewrite = 1; |
|
} |
|
|
|
if ($rewrite) { |
|
redirect($scriptname . urlencode($pathinfo) . $query); |
|
} |
|
|
|
undef $rewrite; |
|
|
|
if (!-d $cvsroot) { |
if (!-d $cvsroot) { |
&fatal("500 Internal Error",'$CVSROOT not found!<P>The server on which the CVS tree lives is probably down. Please try again in a few minutes.'); |
&fatal("500 Internal Error",'$CVSROOT not found!<P>The server on which the CVS tree lives is probably down. Please try again in a few minutes.'); |
} |
} |
|
|
if ($module && &forbidden_module($module)) { |
if ($module && &forbidden_module($module)) { |
&fatal("403 Forbidden", "Access to $where forbidden."); |
&fatal("403 Forbidden", "Access to $where forbidden."); |
} |
} |
|
|
# |
|
# Handle tarball downloads before any headers are output. |
|
# |
|
if ($input{tarball}) { |
|
&fatal("403 Forbidden", "Downloading tarballs is prohibited.") |
|
unless $allow_tar; |
|
my($module) = ($where =~ m,^/?(.*),); # untaint |
|
$module =~ s,/([^/]*)$,,; |
|
my($ext) = ($1 =~ /(\.tar\.gz|\.zip)$/); |
|
my($basedir) = ($module =~ m,([^/]+)$,); |
|
|
|
if ($basedir eq '' || $module eq '') { |
|
&fatal("500 Internal Error", "You cannot download the top level directory."); |
|
} |
|
|
|
my $tmpdir = "/tmp/.cvsweb.$$." . int(time); |
|
|
|
mkdir($tmpdir, 0700) |
|
or &fatal("500 Internal Error", "Unable to make temporary directory: $!"); |
|
|
|
my @fatal; |
|
|
|
my $tag = (exists $input{only_with_tag} && length $input{only_with_tag}) |
|
? $input{only_with_tag} : "HEAD"; |
|
|
|
if (system $CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'export', '-r', $tag, '-d', "$tmpdir/$basedir", $module) { |
|
@fatal = ("500 Internal Error", "cvs co failure: $!: $module"); |
|
} else { |
|
$| = 1; # Essential to get the buffering right. |
|
|
|
if ($ext eq '.tar.gz') { |
|
print "Content-type: application/x-gzip\r\n\r\n"; |
|
|
|
system "$CMD{tar} @tar_options -cf - -C $tmpdir $basedir | $CMD{gzip} @gzip_options -c" |
|
and @fatal = ("500 Internal Error", "tar zc failure: $!: $basedir"); |
|
} elsif ($ext eq '.zip' && $CMD{zip}) { |
|
print "Content-type: application/zip\r\n\r\n"; |
|
|
|
system "cd $tmpdir && $CMD{zip} @zip_options -r - $basedir" |
|
and @fatal = ("500 Internal Error", "zip failure: $!: $basedir"); |
|
} else { |
|
@fatal = ("500 Internal Error", "unsupported file type"); |
|
} |
|
} |
|
|
|
system $CMD{rm}, '-rf', $tmpdir if -d $tmpdir; |
|
|
|
&fatal(@fatal) if @fatal; |
|
|
|
exit; |
|
} |
|
|
|
############################## |
############################## |
# View a directory |
# View a directory |
############################### |
############################### |
if (-d $fullname) { |
elsif (-d $fullname) { |
my $dh = do {local(*DH);}; |
my $dh = do {local(*DH);}; |
opendir($dh, $fullname) || &fatal("404 Not Found","$where: $!"); |
opendir($dh, $fullname) || &fatal("404 Not Found","$where: $!"); |
my @dir = readdir($dh); |
my @dir = readdir($dh); |
Line 622 if (-d $fullname) { |
|
Line 482 if (-d $fullname) { |
|
} |
} |
print "<table width=\"100%\" border=0 cellspacing=1 cellpadding=$tablepadding>\n"; |
print "<table width=\"100%\" border=0 cellspacing=1 cellpadding=$tablepadding>\n"; |
$infocols++; |
$infocols++; |
printf '<tr><th align=left bgcolor="%s">', |
print "<tr><th align=left bgcolor=\"" . (($byfile) ? |
$byfile ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorSorted : |
|
$columnHeaderColorDefault) . "\">"; |
if ($byfile) { |
if ($byfile) { |
print 'File'; |
print 'File'; |
} else { |
} else { |
Line 635 if (-d $fullname) { |
|
Line 496 if (-d $fullname) { |
|
# with revision information: |
# with revision information: |
if (scalar(%fileinfo)) { |
if (scalar(%fileinfo)) { |
$infocols++; |
$infocols++; |
printf '<th align=left bgcolor="%s">', |
print "<th align=left bgcolor=\"" . (($byrev) ? |
$byrev ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorSorted : |
|
$columnHeaderColorDefault) . "\">"; |
if ($byrev) { |
if ($byrev) { |
print 'Rev.'; |
print 'Rev.'; |
} else { |
} else { |
Line 645 if (-d $fullname) { |
|
Line 507 if (-d $fullname) { |
|
} |
} |
print "</th>"; |
print "</th>"; |
$infocols++; |
$infocols++; |
printf '<th align=left bgcolor="%s">', |
print "<th align=left bgcolor=\"" . (($bydate) ? |
$bydate ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorSorted : |
|
$columnHeaderColorDefault) . "\">"; |
if ($bydate) { |
if ($bydate) { |
print 'Age'; |
print 'Age'; |
} else { |
} else { |
print &link('Age', sprintf('./%s#dirlist', |
print &link('Age', sprintf('./%s#dirlist', |
&toggleQuery("sortby", "date"))); |
&toggleQuery("sortby", "date"))); |
} |
} |
print "</th>"; |
print "</th>"; |
if ($show_author) { |
if ($show_author) { |
$infocols++; |
$infocols++; |
printf '<th align=left bgcolor="%s">', |
print "<th align=left bgcolor=\"" . (($byauthor) ? |
$byauthor ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorSorted : |
|
$columnHeaderColorDefault) . "\">"; |
if ($byauthor) { |
if ($byauthor) { |
print 'Author'; |
print 'Author'; |
} else { |
} else { |
Line 667 if (-d $fullname) { |
|
Line 531 if (-d $fullname) { |
|
print "</th>"; |
print "</th>"; |
} |
} |
$infocols++; |
$infocols++; |
printf '<th align=left bgcolor="%s">', |
print "<th align=left bgcolor=\"" . (($bylog) ? |
$bylog ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorSorted : |
|
$columnHeaderColorDefault) . "\">"; |
if ($bylog) { |
if ($bylog) { |
print 'Last log entry'; |
print 'Last log entry'; |
} else { |
} else { |
print &link('Last log entry', sprintf('./%s#dirlist', |
print &link('Last log entry', sprintf('./%s#dirlist', |
&toggleQuery("sortby", "log"))); |
&toggleQuery("sortby", "log"))); |
} |
} |
print "</th>"; |
print "</th>"; |
} |
} |
elsif ($use_descriptions) { |
elsif ($use_descriptions) { |
printf '<th align=left bgcolor="%s">', $columnHeaderColorDefault; |
print "<th align=left bgcolor=\"". $columnHeaderColorDefault . "\">"; |
print "Description"; |
print "Description"; |
$infocols++; |
$infocols++; |
} |
} |
Line 741 if (-d $fullname) { |
|
Line 606 if (-d $fullname) { |
|
|
|
if ($_ eq '..' || -d "$fullname/$_") { |
if ($_ eq '..' || -d "$fullname/$_") { |
next if ($_ eq '..' && $where eq '/'); |
next if ($_ eq '..' && $where eq '/'); |
my ($rev,$date,$log,$author,$filename); |
my ($rev,$date,$log,$author,$filename) = @{$fileinfo{$_}} |
($rev,$date,$log,$author,$filename) = @{$fileinfo{$_}} |
|
if (defined($fileinfo{$_})); |
if (defined($fileinfo{$_})); |
printf '<tr bgcolor="%s"><td>', $tabcolors[$dirrow % 2] if $dirtable; |
print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable); |
if ($_ eq '..') { |
if ($_ eq '..') { |
$url = "../$query"; |
$url = "../" . $query; |
if ($nofilelinks) { |
if ($nofilelinks) { |
print $backicon; |
print $backicon; |
} |
} |
else { |
else { |
print &link($backicon, $url); |
print &link($backicon, $url); |
} |
} |
print " ", &link("Parent Directory", $url); |
print " ", &link("Previous Directory", $url); |
} |
} |
else { |
else { |
$url = './' . urlencode($_) . "/$query"; |
$url = urlencode($_) . '/' . $query; |
print "<A NAME=\"$_\"></A>"; |
print "<A NAME=\"$_\"></A>"; |
if ($nofilelinks) { |
if ($nofilelinks) { |
print $diricon; |
print $diricon; |
Line 775 if (-d $fullname) { |
|
Line 639 if (-d $fullname) { |
|
if ($filename) { |
if ($filename) { |
print "</td><td> </td><td> " if ($dirtable); |
print "</td><td> </td><td> " if ($dirtable); |
if ($date) { |
if ($date) { |
print " <i>", readableTime(time() - $date,0), "</i>"; |
print " <i>" . readableTime(time() - $date,0) . "</i>"; |
} |
} |
if ($show_author) { |
if ($show_author) { |
print "</td><td> " if ($dirtable); |
print "</td><td> " if ($dirtable); |
Line 786 if (-d $fullname) { |
|
Line 650 if (-d $fullname) { |
|
print "$filename/$rev"; |
print "$filename/$rev"; |
print "<BR>" if ($dirtable); |
print "<BR>" if ($dirtable); |
if ($log) { |
if ($log) { |
print " <font size=-1>", |
print " <font size=-1>" |
&htmlify(substr($log,0,$shortLogLen)); |
. &htmlify(substr($log,0,$shortLogLen)); |
if (length $log > 80) { |
if (length $log > 80) { |
print "..."; |
print "..."; |
} |
} |
Line 797 if (-d $fullname) { |
|
Line 661 if (-d $fullname) { |
|
else { |
else { |
my ($dwhere) = ($where ne "/" ? $where : "") . $_; |
my ($dwhere) = ($where ne "/" ? $where : "") . $_; |
if ($use_descriptions && defined $descriptions{$dwhere}) { |
if ($use_descriptions && defined $descriptions{$dwhere}) { |
print "<TD COLSPAN=", ($infocols-1), "> " if $dirtable; |
print "<TD COLSPAN=" . ($infocols-1) . "> " if $dirtable; |
print $descriptions{$dwhere}; |
print $descriptions{$dwhere}; |
} elsif ($dirtable && $infocols > 1) { |
} elsif ($dirtable && $infocols > 1) { |
# close the row with the appropriate number of |
# close the row with the appropriate number of |
Line 819 if (-d $fullname) { |
|
Line 683 if (-d $fullname) { |
|
} |
} |
elsif (s/,v$//) { |
elsif (s/,v$//) { |
$fileurl = ($attic ? "Attic/" : "") . urlencode($_); |
$fileurl = ($attic ? "Attic/" : "") . urlencode($_); |
$url = './' . $fileurl . $query; |
$url = $fileurl . $query; |
my $rev = ''; |
my $rev = ''; |
my $date = ''; |
my $date = ''; |
my $log = ''; |
my $log = ''; |
Line 828 if (-d $fullname) { |
|
Line 692 if (-d $fullname) { |
|
next if (!defined($fileinfo{$_})); |
next if (!defined($fileinfo{$_})); |
($rev,$date,$log,$author) = @{$fileinfo{$_}}; |
($rev,$date,$log,$author) = @{$fileinfo{$_}}; |
$filesfound++; |
$filesfound++; |
printf '<tr bgcolor="%s"><td>', $tabcolors[$dirrow % 2] if $dirtable; |
print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable); |
print "<A NAME=\"$_\"></A>"; |
print "<A NAME=\"$_\"></A>"; |
if ($nofilelinks) { |
if ($nofilelinks) { |
print $fileicon; |
print $fileicon; |
Line 843 if (-d $fullname) { |
|
Line 707 if (-d $fullname) { |
|
$defaultViewable ? "text/x-cvsweb-markup" : undef); |
$defaultViewable ? "text/x-cvsweb-markup" : undef); |
print "</td><td> " if ($dirtable); |
print "</td><td> " if ($dirtable); |
if ($date) { |
if ($date) { |
print " <i>", readableTime(time() - $date,0), "</i>"; |
print " <i>" . readableTime(time() - $date,0) . "</i>"; |
} |
} |
if ($show_author) { |
if ($show_author) { |
print "</td><td> " if ($dirtable); |
print "</td><td> " if ($dirtable); |
Line 851 if (-d $fullname) { |
|
Line 715 if (-d $fullname) { |
|
} |
} |
print "</td><td> " if ($dirtable); |
print "</td><td> " if ($dirtable); |
if ($log) { |
if ($log) { |
print " <font size=-1>", &htmlify(substr($log,0,$shortLogLen)); |
print " <font size=-1>" . &htmlify(substr($log,0,$shortLogLen)); |
if (length $log > 80) { |
if (length $log > 80) { |
print "..."; |
print "..."; |
} |
} |
Line 866 if (-d $fullname) { |
|
Line 730 if (-d $fullname) { |
|
if ($dirtable && defined($tableBorderColor)) { |
if ($dirtable && defined($tableBorderColor)) { |
print "</td></tr></table>"; |
print "</td></tr></table>"; |
} |
} |
print( $dirtable == 1 ? "</table>\n" : "</menu>\n" ); |
print "". ($dirtable == 1) ? "</table>" : "</menu>" . "\n"; |
|
|
if ($filesexists && !$filesfound) { |
if ($filesexists && !$filesfound) { |
print "<P><B>NOTE:</B> There are $filesexists files, but none matches the current tag ($input{only_with_tag})\n"; |
print "<P><B>NOTE:</B> There are $filesexists files, but none matches the current tag ($input{only_with_tag})\n"; |
Line 902 if (-d $fullname) { |
|
Line 766 if (-d $fullname) { |
|
">$tag\n"; |
">$tag\n"; |
} |
} |
print "</SELECT>\n"; |
print "</SELECT>\n"; |
print " Module path or alias:\n"; |
|
printf "<INPUT TYPE=TEXT NAME=\"path\" VALUE=\"%s\" SIZE=15>\n", htmlquote($where); |
|
print "<INPUT TYPE=SUBMIT VALUE=\"Go\">\n"; |
print "<INPUT TYPE=SUBMIT VALUE=\"Go\">\n"; |
print "</FORM>\n"; |
print "</FORM>\n"; |
} |
} |
|
|
if ($allow_tar) { |
|
my($basefile) = ($where =~ m,(?:.*/)?([^/]+),); |
|
|
|
if (defined($basefile) && $basefile ne '') { |
|
print "<HR NOSHADE>\n", |
|
"<DIV align=center>Download this directory in "; |
|
# Mangle the filename so browsers show a reasonable |
|
# filename to download. |
|
print &link("tarball", |
|
"./$basefile.tar.gz$query". |
|
($query ? "&" : "?")."tarball=1"); |
|
if ($CMD{zip}) { |
|
print " or ", |
|
&link("zip archive", |
|
"./$basefile.zip$query". |
|
($query ? "&" : "?")."tarball=1"); |
|
} |
|
print "</DIV>"; |
|
} |
|
} |
|
|
|
my $formwhere = $scriptwhere; |
my $formwhere = $scriptwhere; |
$formwhere =~ s|Attic/?$|| if ($input{'hideattic'}); |
$formwhere =~ s|Attic/?$|| if ($input{'hideattic'}); |
|
|
Line 948 if (-d $fullname) { |
|
Line 788 if (-d $fullname) { |
|
print "<OPTION",$byrev ? " SELECTED" : ""," VALUE=rev>Revision"; |
print "<OPTION",$byrev ? " SELECTED" : ""," VALUE=rev>Revision"; |
print "<OPTION",$bylog ? " SELECTED" : ""," VALUE=log>Log message"; |
print "<OPTION",$bylog ? " SELECTED" : ""," VALUE=log>Log message"; |
print "</SELECT></td>"; |
print "</SELECT></td>"; |
print "<td>Sort log by: "; |
print "<td>revisions by: \n"; |
printLogSortSelect(0); |
print "<SELECT NAME=logsort>\n"; |
print "</td></tr>"; |
print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted"; |
|
print "<OPTION VALUE=date",$logsort eq "date" ? " SELECTED" : "", ">Commit date"; |
|
print "<OPTION VALUE=rev",$logsort eq "rev" ? " SELECTED" : "", ">Revision"; |
|
print "</SELECT></td></tr>"; |
print "<tr><td>Diff format: "; |
print "<tr><td>Diff format: "; |
printDiffSelect(0); |
printDiffSelect(0); |
print "</td>"; |
print "</td>"; |
Line 1012 if (-d $fullname) { |
|
Line 855 if (-d $fullname) { |
|
# The file has been removed and is in the Attic. |
# The file has been removed and is in the Attic. |
# Send a redirect pointing to the file in the Attic. |
# Send a redirect pointing to the file in the Attic. |
(my $newplace = $scriptwhere) =~ s|/([^/]+)$|/Attic/$1|; |
(my $newplace = $scriptwhere) =~ s|/([^/]+)$|/Attic/$1|; |
redirect("$newplace$query"); |
&redirect($newplace); |
exit; |
exit; |
} |
} |
elsif (0 && (my @files = &safeglob($fullname . ",v"))) { |
elsif (0 && (my @files = &safeglob($fullname . ",v"))) { |
Line 1026 if (-d $fullname) { |
|
Line 869 if (-d $fullname) { |
|
my $fh = do {local(*FH);}; |
my $fh = do {local(*FH);}; |
my ($xtra, $module); |
my ($xtra, $module); |
# Assume it's a module name with a potential path following it. |
# Assume it's a module name with a potential path following it. |
$xtra = (($module = $where) =~ s|/.*||) ? $& : ''; |
$xtra = $& if (($module = $where) =~ s|/.*||); |
# Is there an indexed version of modules? |
# Is there an indexed version of modules? |
if (open($fh, "< $cvsroot/CVSROOT/modules")) { |
if (open($fh, "$cvsroot/CVSROOT/modules")) { |
while (<$fh>) { |
while (<$fh>) { |
if (/^(\S+)\s+(\S+)/o && $module eq $1 |
if (/^(\S+)\s+(\S+)/o && $module eq $1 |
&& -d "$cvsroot/$2" && $module ne $2) { |
&& -d "${cvsroot}/$2" && $module ne $2) { |
redirect("$scriptname/$2$xtra$query"); |
&redirect($scriptname . '/' . $2 . $xtra); |
} |
} |
} |
} |
} |
} |
|
|
|
|
sub printDiffSelect($) { |
sub printDiffSelect($) { |
my ($use_java_script) = @_; |
my ($use_java_script) = @_; |
my $f = $input{'f'}; |
my ($f) = $input{'f'}; |
|
print "<SELECT NAME=\"f\""; |
print '<SELECT NAME="f"'; |
print " onchange=\"submit()\"" if ($use_java_script); |
print ' onchange="submit()"' if $use_java_script; |
print ">\n"; |
print '>'; |
print "<OPTION VALUE=h",$f eq "h" ? " SELECTED" : "", ">Colored Diff"; |
|
print "<OPTION VALUE=H",$f eq "H" ? " SELECTED" : "", ">Long Colored Diff"; |
local $_; |
print "<OPTION VALUE=u",$f eq "u" ? " SELECTED" : "", ">Unidiff"; |
for (@DIFFTYPES) { |
print "<OPTION VALUE=c",$f eq "c" ? " SELECTED" : "", ">Context Diff"; |
printf('<OPTION VALUE="%s"%s>%s', |
print "<OPTION VALUE=s",$f eq "s" ? " SELECTED" : "", ">Side by Side"; |
$_, |
|
$f eq $_ ? ' SELECTED' : '', |
|
"\u$DIFFTYPES{$_}{'descr'}" |
|
); |
|
} |
|
|
|
print "</SELECT>"; |
print "</SELECT>"; |
} |
} |
|
|
sub printLogSortSelect($) { |
|
my ($use_java_script) = @_; |
|
|
|
print '<SELECT NAME="logsort"'; |
|
print ' onchange="submit()"' if $use_java_script; |
|
print '>'; |
|
|
|
local $_; |
|
for (@LOGSORTKEYS) { |
|
printf('<OPTION VALUE="%s"%s>%s', |
|
$_, |
|
$logsort eq $_ ? ' SELECTED' : '', |
|
"\u$LOGSORTKEYS{$_}{'descr'}" |
|
); |
|
} |
|
|
|
print "</SELECT>"; |
|
} |
|
|
|
sub findLastModifiedSubdirs(@) { |
sub findLastModifiedSubdirs(@) { |
my (@dirs) = @_; |
my (@dirs) = @_; |
my ($dirname, @files); |
my ($dirname, @files); |
Line 1115 sub findLastModifiedSubdirs(@) { |
|
Line 933 sub findLastModifiedSubdirs(@) { |
|
return @files; |
return @files; |
} |
} |
|
|
sub htmlify_sub(&$) { |
|
(my $proc, local $_) = @_; |
|
my @a = split(m`(<a [^>]+>[^<]*</a>)`i); |
|
my $linked; |
|
my $result = ''; |
|
|
|
while (($_, $linked) = splice(@a, 0, 2)) { |
|
&$proc(); |
|
$result .= $_ if defined($_); |
|
$result .= $linked if defined($linked); |
|
} |
|
|
|
$result; |
|
} |
|
|
|
sub htmlify($;$) { |
sub htmlify($;$) { |
(local $_, my $extra) = @_; |
(local $_, my $extra) = @_; |
|
|
$_ = htmlquote($_); |
$_ = htmlquote($_); |
|
|
# get URL's as link |
# get URL's as link |
s{ |
s`(http|ftp|https)(://[-a-zA-Z0-9%.~:_/]+)([?&]([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*`&link("$1$2$3", "$1$2$3")`ge; # ` |
(http|ftp|https)://\S+ |
# get e-mails as link |
}{ |
s`[-a-zA-Z0-9_.]+@([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4}`&link($&, "mailto:$&")`ge; # ` |
&link($&, htmlunquote($&)) |
|
}egx; |
|
|
|
# get e-mails as link |
if ($extra) { |
$_ = htmlify_sub { |
# get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" |
s< |
if (defined($prcgi)) { |
[\w+=\-.!]+@[\w\-]+(\.[\w\-]+)+ |
1 while s`\b(pr[:#]?\s*(?:#?\d+[,\s]\s*)*#?)(\d+)\b`$1 . &link($2, sprintf($prcgi, $2))`ie; # `; |
>< |
s`\b${prcategories}/(\d+)\b`&link($&, sprintf($prcgi, $1))`igeo; # `; |
&link($&, "mailto:$&") |
} |
>egix; |
|
} $_; |
|
|
|
if ($extra) { |
# get manpage specs as link: "foo.1" "foo(1)" |
# get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" |
if (defined($mancgi)) { |
if (defined($prcgi) && defined($re_prcategories) && defined($re_prkeyword)) { |
s`\b([a-zA-Z]\w+)(?:\(([0-9n])\)\B|\.([0-9n])\b)`&link($&, sprintf($mancgi, $2 ne '' ? $2 : $3, $1))`ge; # `x; |
my $prev; |
} |
|
|
do { |
|
$prev = $_; |
|
|
|
$_ = htmlify_sub { |
|
s{ |
|
(\b$re_prkeyword[:\#]?\s* |
|
(?: |
|
\#? |
|
\d+[,\s]\s* |
|
)* |
|
\#?) |
|
(\d+)\b |
|
}{ |
|
$1 . &link($2, sprintf($prcgi, $2)) |
|
}egix; |
|
} $_; |
|
} while ($_ ne $prev); |
|
|
|
$_ = htmlify_sub { |
|
s{ |
|
(\b$re_prcategories/(\d+)\b) |
|
}{ |
|
&link($1, sprintf($prcgi, $2)) |
|
}egox; |
|
} $_; |
|
} |
} |
|
|
# get manpage specs as link: "foo.1" "foo(1)" |
$_; |
if (defined($mancgi)) { |
|
$_ = htmlify_sub { |
|
s{ |
|
(\b([a-zA-Z][\w.]+) |
|
(?: |
|
\( ([0-9n]) \)\B |
|
| |
|
\.([0-9n])\b |
|
) |
|
) |
|
}{ |
|
&link($1, sprintf($mancgi, defined($3) ? $3 : $4, $2)) |
|
}egx; |
|
} $_; |
|
} |
|
} |
|
|
|
$_; |
|
} |
} |
|
|
sub spacedHtmlText($;$) { |
sub spacedHtmlText($;$) { |
Line 1235 sub spacedHtmlText($;$) { |
|
Line 990 sub spacedHtmlText($;$) { |
|
} |
} |
|
|
sub link($$) { |
sub link($$) { |
my($name, $url) = @_; |
my($name, $where) = @_; |
|
|
$url =~ s/:/sprintf("%%%02x", ord($&))/eg if $url =~ /^[^a-z]/; # relative |
sprintf '<A HREF="%s">%s</A>', htmlquote($where), $name; |
|
|
sprintf '<A HREF="%s">%s</A>', hrefquote($url), $name; |
|
} |
} |
|
|
sub revcmp($$) { |
sub revcmp($$) { |
Line 1313 sub safeglob($) { |
|
Line 1066 sub safeglob($) { |
|
$glob =~ s/{([^}]+)}/($t = $1) =~ s-,-|-g; "($t)"/eg; |
$glob =~ s/{([^}]+)}/($t = $1) =~ s-,-|-g; "($t)"/eg; |
foreach (readdir($dh)) { |
foreach (readdir($dh)) { |
if (/^${glob}$/) { |
if (/^${glob}$/) { |
push(@results, "$dirname/" .$_); |
push(@results, $dirname . "/" .$_); |
} |
} |
} |
} |
closedir($dh); |
|
} |
} |
|
|
@results; |
@results; |
} |
} |
|
|
sub search_path($) { |
|
my($command) = @_; |
|
my $d; |
|
|
|
for $d (split(/:/, $command_path)) { |
|
return "$d/$command" if -x "$d/$command"; |
|
} |
|
|
|
''; |
|
} |
|
|
|
sub getMimeTypeFromSuffix($) { |
sub getMimeTypeFromSuffix($) { |
my ($fullname) = @_; |
my ($fullname) = @_; |
my ($mimetype, $suffix); |
my ($mimetype, $suffix); |
Line 1406 sub doAnnotate($$) { |
|
Line 1147 sub doAnnotate($$) { |
|
my $reader = do {local(*FH);}; |
my $reader = do {local(*FH);}; |
my $writer = do {local(*FH);}; |
my $writer = do {local(*FH);}; |
|
|
# make sure the revisions are wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if ($rev =~ /[^\w.]/) { |
if ($rev =~ /[^\w.]/) { |
&fatal("404 Not Found", |
&fatal("404 Not Found", |
Line 1425 sub doAnnotate($$) { |
|
Line 1166 sub doAnnotate($$) { |
|
# the public domain. |
# the public domain. |
# we could abandon the use of rlog, rcsdiff and co using |
# we could abandon the use of rlog, rcsdiff and co using |
# the cvsserver in a similiar way one day (..after rewrite) |
# the cvsserver in a similiar way one day (..after rewrite) |
$pid = open2($reader, $writer, $CMD{cvs}, @cvs_options, "server") |
$pid = open2($reader, $writer, "cvs -Rl server") || fatal ("500 Internal Error", |
|| fatal ("500 Internal Error", "Fatal Error - unable to open cvs for annotation"); |
"Fatal Error - unable to open cvs for annotation"); |
|
|
# OK, first send the request to the server. A simplified example is: |
# OK, first send the request to the server. A simplified example is: |
# Root /home/kingdon/zwork/cvsroot |
# Root /home/kingdon/zwork/cvsroot |
Line 1524 sub doAnnotate($$) { |
|
Line 1265 sub doAnnotate($$) { |
|
} |
} |
else { |
else { |
$revprint = sprintf('%-8s', $lrev); |
$revprint = sprintf('%-8s', $lrev); |
$revprint =~ s`\S+`&link($&, "$scriptwhere$query#rev$&")`e; # ` |
$revprint =~ s`\S+`&link($&, "$scriptwhere$barequery#rev$&")`e; # ` |
$oldLusr = ''; |
$oldLusr = ''; |
} |
} |
if ($lusr eq $oldLusr) { |
if ($lusr eq $oldLusr) { |
Line 1555 sub doAnnotate($$) { |
|
Line 1296 sub doAnnotate($$) { |
|
# CVS command line client. But for simplicity, we don't. |
# CVS command line client. But for simplicity, we don't. |
} |
} |
elsif ($words[0] eq "error") { |
elsif ($words[0] eq "error") { |
fatal("500 Internal Error", "Error occured during annotate: <b>$_</b>"); |
fatal ("500 Internal Error", "Error occured during annotate: <b>$_</b>"); |
} |
} |
} |
} |
if ($annTable) { |
if ($annTable) { |
Line 1617 sub doCheckout($$) { |
|
Line 1358 sub doCheckout($$) { |
|
# |
# |
# Safely for a child process to read from. |
# Safely for a child process to read from. |
if (! open($fh, "-|")) { # child |
if (! open($fh, "-|")) { # child |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
exec($CMD{cvs}, @cvs_options, '-d', $cvsroot, 'co', '-p', $revopt, $where); |
exec("cvs", "-Rld", $cvsroot, "co", "-p", $revopt, $where); |
} |
} |
|
|
if (eof($fh)) { |
|
&fatal("404 Not Found", |
|
"$where is not (any longer) pertinent"); |
|
} |
|
#=================================================================== |
#=================================================================== |
#Checking out squid/src/ftp.c |
#Checking out squid/src/ftp.c |
#RCS: /usr/src/CVS/squid/src/ftp.c,v |
#RCS: /usr/src/CVS/squid/src/ftp.c,v |
Line 1633 sub doCheckout($$) { |
|
Line 1369 sub doCheckout($$) { |
|
|
|
# Parse CVS header |
# Parse CVS header |
my ($revision, $filename, $cvsheader); |
my ($revision, $filename, $cvsheader); |
$filename = ""; |
|
while(<$fh>) { |
while(<$fh>) { |
last if (/^\*\*\*\*/); |
last if (/^\*\*\*\*/); |
$revision = $1 if (/^VERS: (.*)$/); |
$revision = $1 if (/^VERS: (.*)$/); |
Line 1645 sub doCheckout($$) { |
|
Line 1380 sub doCheckout($$) { |
|
} |
} |
if ($filename ne $where) { |
if ($filename ne $where) { |
&fatal("500 Internal Error", |
&fatal("500 Internal Error", |
"Unexpected output from cvs co: $cvsheader"); |
"Unexpected output from cvs co: $cvsheader" |
|
. "<p><b>Check whether the directory $cvsroot/CVSROOT exists " |
|
. "and the script has write-access to the CVSROOT/history " |
|
. "file if it exists." |
|
. "<br>The script needs to place lock files in the " |
|
. "directory the file is in as well.</b>"); |
} |
} |
$| = 1; |
$| = 1; |
|
|
Line 1696 sub cvswebMarkup($$$) { |
|
Line 1436 sub cvswebMarkup($$$) { |
|
my $url = download_url($fileurl, $revision, $mimetype); |
my $url = download_url($fileurl, $revision, $mimetype); |
print "<HR noshade>"; |
print "<HR noshade>"; |
if ($mimetype =~ /^image/) { |
if ($mimetype =~ /^image/) { |
printf '<IMG SRC="%s"><BR>', hrefquote("$url$barequery"); |
printf '<IMG SRC="%s"><BR>', htmlquote("$url$barequery"); |
} |
} |
elsif ($mimetype =~ m%^application/pdf%) { |
elsif ($mimetype =~ m%^application/pdf%) { |
printf '<EMBED SRC="%s" WIDTH="100%"><BR>', hrefquote("$url$barequery"); |
printf '<EMBED SRC="%s" WIDTH="100%"><BR>', htmlquote("$url$barequery"); |
} |
} |
elsif ($preformat_in_markup) { |
else { |
print "<PRE>"; |
print "<PRE>"; |
|
|
# prefetch several lines |
# prefetch several lines |
Line 1716 sub cvswebMarkup($$$) { |
|
Line 1456 sub cvswebMarkup($$$) { |
|
} |
} |
print "</PRE>"; |
print "</PRE>"; |
} |
} |
else { |
|
print "<PRE>"; |
|
while (<$filehandle>) { |
|
print htmlquote($_); |
|
} |
|
print "</PRE>"; |
|
} |
|
} |
} |
|
|
sub viewable($) { |
sub viewable($) { |
Line 1737 sub viewable($) { |
|
Line 1470 sub viewable($) { |
|
sub doDiff($$$$$$) { |
sub doDiff($$$$$$) { |
my($fullname, $r1, $tr1, $r2, $tr2, $f) = @_; |
my($fullname, $r1, $tr1, $r2, $tr2, $f) = @_; |
my $fh = do {local(*FH);}; |
my $fh = do {local(*FH);}; |
my ($rev1, $rev2, $sym1, $sym2, $f1, $f2); |
my ($rev1, $rev2, $sym1, $sym2, @difftype, $diffname, $f1, $f2); |
|
|
if ($r1 =~ /([^:]+)(:(.+))?/) { |
if ($r1 =~ /([^:]+)(:(.+))?/) { |
$rev1 = $1; |
$rev1 = $1; |
Line 1771 sub doDiff($$$$$$) { |
|
Line 1504 sub doDiff($$$$$$) { |
|
($rev1, $sym1) = ($rev2, $sym2); |
($rev1, $sym1) = ($rev2, $sym2); |
($rev2, $sym2) = ($tmp1, $tmp2); |
($rev2, $sym2) = ($tmp1, $tmp2); |
} |
} |
my $difftype = $DIFFTYPES{$f}; |
my $human_readable = 0; |
|
if ($f eq 'c') { |
if (!$difftype) { |
@difftype = qw{-c}; |
|
$diffname = "Context diff"; |
|
} |
|
elsif ($f eq 's') { |
|
@difftype = qw{--side-by-side --width=164}; |
|
$diffname = "Side by Side"; |
|
} |
|
elsif ($f eq 'H') { |
|
$human_readable = 1; |
|
@difftype = qw{--unified=15}; |
|
$diffname = "Long Human readable"; |
|
} |
|
elsif ($f eq 'h') { |
|
@difftype =qw{-u}; |
|
$human_readable = 1; |
|
$diffname = "Human readable"; |
|
} |
|
elsif ($f eq 'u') { |
|
@difftype = qw{-u}; |
|
$diffname = "Unidiff"; |
|
} |
|
else { |
fatal ("400 Bad arguments", "Diff format $f not understood"); |
fatal ("400 Bad arguments", "Diff format $f not understood"); |
} |
} |
|
|
my @difftype = @{$difftype->{'opts'}}; |
|
my $human_readable = $difftype->{'colored'}; |
|
|
|
# apply special options |
# apply special options |
if ($showfunc) { |
if ($showfunc) { |
push @difftype, '-p' if $f ne 's'; |
push @difftype, '-p' if $f =~ /^[cHhu]$/; |
|
|
my($re1, $re2); |
my($re1, $re2); |
|
|
while (($re1, $re2) = each %funcline_regexp) { |
while (($re1, $re2) = each %funcline_regexp) { |
if ($fullname =~ /$re1/) { |
if ($fullname =~ /$re1/) { |
push @difftype, '-F', $re2; |
push @difftype, '-F', '$re2'; |
last; |
last; |
} |
} |
} |
} |
Line 1803 sub doDiff($$$$$$) { |
|
Line 1554 sub doDiff($$$$$$) { |
|
} |
} |
if (! open($fh, "-|")) { # child |
if (! open($fh, "-|")) { # child |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
open(STDERR, ">&STDOUT"); # Redirect stderr to stdout |
exec($CMD{rcsdiff}, @difftype, "-r$rev1", "-r$rev2", $fullname); |
exec("rcsdiff",@difftype,"-r$rev1","-r$rev2",$fullname); |
} |
} |
if ($human_readable) { |
if ($human_readable) { |
http_header(); |
http_header(); |
Line 1844 sub doDiff($$$$$$) { |
|
Line 1595 sub doDiff($$$$$$) { |
|
s|$cvsroot/||o; |
s|$cvsroot/||o; |
if ($sym1) { |
if ($sym1) { |
chop; |
chop; |
$_ .= " $sym1\n"; |
$_ .= " " . $sym1 . "\n"; |
} |
} |
} |
} |
elsif (m|^$f2 $cvsroot|o) { |
elsif (m|^$f2 $cvsroot|o) { |
s|$cvsroot/||o; |
s|$cvsroot/||o; |
if ($sym2) { |
if ($sym2) { |
chop; |
chop; |
$_ .= " $sym2\n"; |
$_ .= " " . $sym2 . "\n"; |
} |
} |
} |
} |
print $_; |
print $_; |
Line 1884 sub getDirLogs($$@) { |
|
Line 1635 sub getDirLogs($$@) { |
|
return; |
return; |
} |
} |
|
|
if (defined($tag)) { |
if ($tag) { |
#can't use -r<tag> as - is allowed in tagnames, but misinterpreated by rlog.. |
#can't use -r<tag> as - is allowed in tagnames, but misinterpreated by rlog.. |
if (! open($fh, "-|")) { |
if (! open($fh, "-|")) { |
open(STDERR, '>/dev/null'); # rlog may complain; ignore. |
open(STDERR, '>/dev/null'); # rlog may complain; ignore. |
exec($CMD{rlog}, @files); |
exec('rlog', @files); |
} |
} |
} |
} |
else { |
else { |
if (! open($fh, "-|")) { |
my $kidpid = open($fh, "-|"); |
open(STDERR, '>/dev/null'); # rlog may complain; ignore. |
if (! $kidpid) { |
exec($CMD{rlog}, '-r', @files); |
open(STDERR, '>/dev/null'); # rlog may complain; ignore. |
|
exec('rlog', '-r', @files); |
} |
} |
} |
} |
$state = "start"; |
$state = "start"; |
while (<$fh>) { |
while (<$fh>) { |
if ($state eq "start") { |
if ($state eq "start") { |
#Next file. Initialize file variables |
#Next file. Initialize file variables |
$rev = ''; |
$rev = undef; |
$revwanted = ''; |
$revwanted = undef; |
$branch = ''; |
$branch = undef; |
$branchpoint = ''; |
$branchpoint = undef; |
$filename = ''; |
$filename = undef; |
$log = ''; |
$log = undef; |
$revision = ''; |
$revision = undef; |
|
$branch = undef; |
%symrev = (); |
%symrev = (); |
@filetags = (); |
@filetags = (); |
#jump to head state |
#jump to head state |
Line 1917 sub getDirLogs($$@) { |
|
Line 1670 sub getDirLogs($$@) { |
|
again: |
again: |
if ($state eq "head") { |
if ($state eq "head") { |
#$rcsfile = $1 if (/^RCS file: (.+)$/); #not used (yet) |
#$rcsfile = $1 if (/^RCS file: (.+)$/); #not used (yet) |
|
$filename = $1 if (/^Working file: (.+)$/); |
if (/^Working file: (.+)$/) { |
$head = $1 if (/^head: (.+)$/); |
$filename = $1; |
$branch = $1 if (/^branch: (.+)$/); |
} elsif (/^head: (.+)$/) { |
} |
$head = $1; |
if ($state eq "head" && /^symbolic names/) { |
} elsif (/^branch: (.+)$/) { |
$state = "tags"; |
$branch = $1 |
($branch = $head) =~ s/\.\d+$// if (!defined($branch)); |
} elsif (/^symbolic names:/) { |
$branch =~ s/(\.?)(\d+)$/${1}0.$2/; |
$state = "tags"; |
$symrev{MAIN} = $branch; |
($branch = $head) =~ s/\.\d+$// if $branch eq ''; |
$symrev{HEAD} = $branch; |
$branch =~ s/(\d+)$/0.$1/; |
$alltags{MAIN} = 1; |
$symrev{MAIN} = $branch; |
$alltags{HEAD} = 1; |
$symrev{HEAD} = $branch; |
push (@filetags, "MAIN", "HEAD"); |
$alltags{MAIN} = 1; |
|
$alltags{HEAD} = 1; |
|
push (@filetags, "MAIN", "HEAD"); |
|
} elsif (/$LOG_REVSEPARATOR/o) { |
|
$state = "log"; |
|
$rev = ''; |
|
$date = ''; |
|
$log = ''; |
|
# Try to reconstruct the relative filename if RCS spits out a full path |
|
$filename =~ s%^\Q$DirName\E/%%; |
|
} |
|
next; |
next; |
} |
} |
if ($state eq "tags") { |
if ($state eq "tags" && |
if (/^\s+(.+):\s+([\d\.]+)\s+$/) { |
/^\s+(.+):\s+([\d\.]+)\s+$/) { |
push (@filetags, $1); |
push (@filetags, $1); |
$symrev{$1} = $2; |
$symrev{$1} = $2; |
$alltags{$1} = 1; |
$alltags{$1} = 1; |
|
next; |
|
} |
|
if ($state eq "tags" && /^\S/) { |
|
if (defined($tag) && (defined($symrev{$tag}) || $tag eq "HEAD")) { |
|
$revwanted = $tag eq "HEAD" ? $symrev{"MAIN"} : $symrev{$tag}; |
|
($branch = $revwanted) =~ s/\b0\.//; |
|
($branchpoint = $branch) =~ s/\.?\d+$//; |
|
$revwanted = undef if ($revwanted ne $branch); |
|
} |
|
elsif (defined($tag) && $tag ne "HEAD") { |
|
print "Tag not found, skip this file" if ($verbose); |
|
$state = "skip"; |
next; |
next; |
} elsif (/^\S/) { |
|
if (defined($tag)) { |
|
if(defined($symrev{$tag}) || $tag eq "HEAD") { |
|
$revwanted = $symrev{$tag eq "HEAD" ? "MAIN" : $tag}; |
|
($branch = $revwanted) =~ s/\b0\.//; |
|
($branchpoint = $branch) =~ s/\.?\d+$//; |
|
$revwanted = '' if ($revwanted ne $branch); |
|
} elsif ($tag ne "HEAD") { |
|
print "Tag not found, skip this file" if ($verbose); |
|
$state = "skip"; |
|
next; |
|
} |
|
} |
|
foreach my $tagfound (@filetags) { |
|
$tags{$tagfound} = 1; |
|
} |
|
$state = "head"; |
|
goto again; |
|
} |
} |
|
foreach my $tagfound (@filetags) { |
|
$tags{$tagfound} = 1; |
|
} |
|
$state = "head"; |
|
goto again; |
} |
} |
|
if ($state eq "head" && /$LOG_REVSEPARATOR/o) { |
|
$state = "log"; |
|
$rev = undef; |
|
$date = undef; |
|
$log = ""; |
|
# Try to reconstruct the relative filename if RCS spits out a full path |
|
$filename =~ s%^\Q$DirName\E/%%; |
|
next; |
|
} |
if ($state eq "log") { |
if ($state eq "log") { |
if (/$LOG_REVSEPARATOR/o || /$LOG_FILESEPARATOR/o) { |
if (/$LOG_REVSEPARATOR/o || /$LOG_FILESEPARATOR/o) { |
# End of a log entry. |
# End of a log entry. |
my $revbranch = $rev; |
my $revbranch; |
$revbranch =~ s/\.\d+$//; |
($revbranch = $rev) =~ s/\.\d+$//; |
print "$filename $rev Wanted: $revwanted ", |
print "$filename $rev Wanted: $revwanted " |
"Revbranch: $revbranch Branch: $branch ", |
. "Revbranch: $revbranch Branch: $branch " |
"Branchpoint: $branchpoint\n" if ($verbose); |
. "Branchpoint: $branchpoint\n" if ($verbose); |
if ($revwanted eq '' && $branch ne '' |
if (!defined($revwanted) && defined($branch) |
&& $branch eq $revbranch || !defined($tag)) { |
&& $branch eq $revbranch || !defined($tag)) { |
print "File revision $rev found for branch $branch\n" |
print "File revision $rev found for branch $branch\n" |
if ($verbose); |
if ($verbose); |
$revwanted = $rev; |
$revwanted = $rev; |
} |
} |
if ($revwanted ne '' ? $rev eq $revwanted : |
if (defined($revwanted) ? $rev eq $revwanted : |
$branchpoint ne '' ? $rev eq $branchpoint : |
defined($branchpoint) ? $rev eq $branchpoint : |
0 && ($rev eq $head)) { # Don't think head is needed here.. |
0 && ($rev eq $head)) { # Don't think head is needed here.. |
print "File info $rev found for $filename\n" if ($verbose); |
print "File info $rev found for $filename\n" if ($verbose); |
my @finfo = ($rev,$date,$log,$author,$filename); |
my @finfo = ($rev,$date,$log,$author,$filename); |
|
|
$fileinfo{$name} = [ @finfo ]; |
$fileinfo{$name} = [ @finfo ]; |
$state = "done" if ($rev eq $revwanted); |
$state = "done" if ($rev eq $revwanted); |
} |
} |
$rev = ''; |
$rev = undef; |
$date = ''; |
$date = undef; |
$log = ''; |
$log = ""; |
} |
} |
elsif ($date eq '' && m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);|) { |
elsif (!defined($date) && m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);|) { |
my $yr = $1; |
my $yr = $1; |
# damn 2-digit year routines :-) |
# damn 2-digit year routines :-) |
if ($yr > 100) { |
if ($yr > 100) { |
|
|
$log = ''; |
$log = ''; |
next; |
next; |
} |
} |
elsif ($rev eq '' && /^revision (.*)$/) { |
elsif (!defined($rev) && m/^revision (.*)$/) { |
$rev = $1; |
$rev = $1; |
next; |
next; |
} |
} |
else { |
else { |
$log .= $_; |
$log = $log . $_; |
} |
} |
} |
} |
if (/$LOG_FILESEPARATOR/o) { |
if (/$LOG_FILESEPARATOR/o) { |
|
|
} |
} |
if ($. == 0) { |
if ($. == 0) { |
fatal("500 Internal Error", |
fatal("500 Internal Error", |
"Failed to spawn GNU rlog on <em>'".join(", ", @files)."'</em><p>Did you set the <b>\$command_path</b> in your configuration file correctly ? (Currently '$command_path'"); |
"Failed to spawn GNU rlog on <em>'".join(", ", @files)."'</em><p>did you set the <b>\$ENV{PATH}</b> in your configuration file correctly ?"); |
} |
} |
close($fh); |
close($fh); |
} |
} |
Line 2052 sub readLog($;$) { |
|
Line 1802 sub readLog($;$) { |
|
|
|
print("Going to rlog '$fullname'\n") if ($verbose); |
print("Going to rlog '$fullname'\n") if ($verbose); |
if (! open($fh, "-|")) { # child |
if (! open($fh, "-|")) { # child |
if ($revision ne '') { |
if ($revision ne '') { |
exec($CMD{rlog}, $revision, $fullname); |
exec("rlog",$revision,$fullname); |
} |
} |
else { |
else { |
exec($CMD{rlog}, $fullname); |
exec("rlog",$fullname); |
} |
} |
} |
} |
while (<$fh>) { |
while (<$fh>) { |
print if ($verbose); |
print if ($verbose); |
Line 2151 sub readLog($;$) { |
|
Line 1901 sub readLog($;$) { |
|
# is the first commit listed on the appropriate branch. |
# is the first commit listed on the appropriate branch. |
# This is not neccesary the same revision as marked as head in the RCS file. |
# This is not neccesary the same revision as marked as head in the RCS file. |
my $headrev = $curbranch || "1"; |
my $headrev = $curbranch || "1"; |
($symrev{"MAIN"} = $headrev) =~ s/(\d+)$/0.$1/; |
($symrev{"MAIN"} = $headrev) =~ s/(\.?)(\d+)$/${1}0.$2/; |
|
revision: |
foreach $rev (@revorder) { |
foreach $rev (@revorder) { |
if ($rev =~ /^(\S*)\.\d+$/ && $headrev eq $1) { |
if ($rev =~ /^(\S*)\.\d+$/ && $headrev eq $1) { |
$symrev{"HEAD"} = $rev; |
$symrev{"HEAD"} = $rev; |
last; |
last revision; |
} |
} |
} |
} |
($symrev{"HEAD"} = $headrev) =~ s/\.\d+$// |
($symrev{"HEAD"} = $headrev) =~ s/\.\d+$// |
Line 2186 sub readLog($;$) { |
|
Line 1937 sub readLog($;$) { |
|
# with the branch number 0.A, with the exception that |
# with the branch number 0.A, with the exception that |
# it has no head to translate to if there is nothing on |
# it has no head to translate to if there is nothing on |
# the branch, but I guess this can never happen? |
# the branch, but I guess this can never happen? |
# |
|
# (the code below gracefully forgets about the branch |
# (the code below gracefully forgets about the branch |
# if it should happen) |
# if it should happen) |
# |
# |
Line 2194 sub readLog($;$) { |
|
Line 1944 sub readLog($;$) { |
|
$branch = $3; |
$branch = $3; |
$branchrev = $head . ($head ne "" ? "." : "") . $branch; |
$branchrev = $head . ($head ne "" ? "." : "") . $branch; |
my $regex; |
my $regex; |
$regex = quotemeta $branchrev; |
($regex = $branchrev) =~ s/\./\\./g; |
$rev = $head; |
$rev = $head; |
|
|
|
revision: |
foreach my $r (@revorder) { |
foreach my $r (@revorder) { |
if ($r =~ /^${regex}\b/) { |
if ($r =~ /^${regex}\b/) { |
$rev = $branchrev; |
$rev = $branchrev; |
last; |
last revision; |
} |
} |
} |
} |
next if ($rev eq ""); |
next if ($rev eq ""); |
Line 2256 sub readLog($;$) { |
|
Line 2007 sub readLog($;$) { |
|
|
|
} |
} |
|
|
sub printDiffLinks($$) { |
|
my($text, $url) = @_; |
|
my @extra; |
|
|
|
local $_; |
|
for ($DIFFTYPES{$defaultDiffType}{'colored'} ? qw(u) : qw(h)) { |
|
my $f = $_ eq $defaultDiffType ? '' : $_; |
|
|
|
push @extra, &link(lc $DIFFTYPES{$_}{'descr'}, "$url&f=$f"); |
|
} |
|
|
|
print &link($text, $url), ' (', join(', ', @extra), ')'; |
|
} |
|
|
|
sub printLog($;$) { |
sub printLog($;$) { |
my ($link, $br, $brp); |
my ($link, $br, $brp); |
($_,$link) = @_; |
($_,$link) = @_; |
Line 2346 sub printLog($;$) { |
|
Line 2083 sub printLog($;$) { |
|
} |
} |
if (defined @mytz) { |
if (defined @mytz) { |
my ($est) = $mytz[(localtime($date{$_}))[8]]; |
my ($est) = $mytz[(localtime($date{$_}))[8]]; |
print ", <i>", scalar localtime($date{$_}), " $est</i> ("; |
print ", <i>" . scalar localtime($date{$_}) . " $est</i> ("; |
} else { |
} else { |
print ", <i>", scalar gmtime($date{$_}), " UTC</i> ("; |
print ", <i>" . scalar gmtime($date{$_}) . " UTC</i> ("; |
} |
} |
print readableTime(time() - $date{$_},1), " ago)"; |
print readableTime(time() - $date{$_},1) . " ago)"; |
print " by "; |
print " by "; |
print "<i>", $author{$_}, "</i>\n"; |
print "<i>" . $author{$_} . "</i>\n"; |
print "<BR>Branch: <b>",$link?link_tags($revsym{$br}):$revsym{$br},"</b>\n" |
print "<BR>Branch: <b>",$link?link_tags($revsym{$br}):$revsym{$br},"</b>\n" |
if ($revsym{$br}); |
if ($revsym{$br}); |
print "<BR>CVS Tags: <b>",$link?link_tags($revsym{$_}):$revsym{$_},"</b>" |
print "<BR>CVS Tags: <b>",$link?link_tags($revsym{$_}):$revsym{$_},"</b>" |
Line 2394 sub printLog($;$) { |
|
Line 2131 sub printLog($;$) { |
|
$barequery); |
$barequery); |
|
|
print " to previous "; |
print " to previous "; |
printDiffLinks($prev, $url); |
print &link($prev, $url); |
|
if (!$hr_default) { # offer a human readable version if not default |
|
print &link('colored', "$url&f=h"); |
|
} |
} |
} |
# |
# |
# Plus, if it's on a branch, and it's not a vendor branch, |
# Plus, if it's on a branch, and it's not a vendor branch, |
Line 2407 sub printLog($;$) { |
|
Line 2147 sub printLog($;$) { |
|
$barequery); |
$barequery); |
|
|
print " to branchpoint "; |
print " to branchpoint "; |
printDiffLinks($brp, $url); |
print &link($brp, $url); |
|
if (!$hr_default) { # offer a human readable version if not default |
|
print &link('colored', "$url&f=h"); |
|
} |
} |
} |
# |
# |
# Plus, if it's on a branch, and it's not a vendor branch, |
# Plus, if it's on a branch, and it's not a vendor branch, |
Line 2417 sub printLog($;$) { |
|
Line 2160 sub printLog($;$) { |
|
if (/^\d+\.\d+\.\d+/ && !/^1\.1\.1\.\d+$/) { |
if (/^\d+\.\d+\.\d+/ && !/^1\.1\.1\.\d+$/) { |
my ($i,$nextmain); |
my ($i,$nextmain); |
for ($i = 0; $i < $#revorder && $revorder[$i] ne $_; $i++){} |
for ($i = 0; $i < $#revorder && $revorder[$i] ne $_; $i++){} |
my @tmp2 = split(/\./, $_); |
my (@tmp2) = split(/\./, $_); |
for ($nextmain = ""; $i > 0; $i--) { |
for ($nextmain = ""; $i > 0; $i--) { |
my $next = $revorder[$i-1]; |
my ($next) = $revorder[$i-1]; |
my @tmp1 = split(/\./, $next); |
my (@tmp1) = split(/\./, $next); |
if (@tmp1 < @tmp2) { |
if ($#tmp1 < $#tmp2) { |
$nextmain = $next; |
$nextmain = $next; |
last; |
last; |
} |
} |
# Only the highest version on a branch should have |
# Only the highest version on a branch should have |
# a diff for the "next main". |
# a diff for the "next main". |
last if (@tmp1 - 1 <= @tmp2 && |
last if (join(".",@tmp1[0..$#tmp1-1]) |
join(".",@tmp1[0..$#tmp1-1]) eq join(".",@tmp2[0..$#tmp1-1])); |
eq join(".",@tmp2[0..$#tmp1-1])); |
} |
} |
if (!defined($diffrev{$nextmain})) { |
if (!defined($diffrev{$nextmain})) { |
$diffrev{$nextmain} = 1; |
$diffrev{$nextmain} = 1; |
Line 2440 sub printLog($;$) { |
|
Line 2183 sub printLog($;$) { |
|
$barequery); |
$barequery); |
|
|
print " next main "; |
print " next main "; |
printDiffLinks($nextmain, $url); |
print &link($nextmain, $url); |
|
if (!$hr_default) { # offer a human readable version if not default |
|
print &link('colored', "$url&f=h"); |
|
} |
} |
} |
} |
} |
# Plus if user has selected only r1, then present a link |
# Plus if user has selected only r1, then present a link |
Line 2455 sub printLog($;$) { |
|
Line 2201 sub printLog($;$) { |
|
$barequery); |
$barequery); |
|
|
print " to selected "; |
print " to selected "; |
printDiffLinks($input{'r1'}, $url); |
print &link($input{'r1'}, $url); |
|
if (!$hr_default) { # offer a human readable version if not default |
|
print &link('colored', "$url&f=h"); |
|
} |
} |
} |
} |
} |
print "<PRE>\n"; |
print "<PRE>\n"; |
|
|
print "<HR noshade>\n"; |
print "<HR noshade>\n"; |
print "<TABLE>"; |
print "<TABLE>"; |
print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n"; |
print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n"; |
print "<TR><TD align=right>Preferred Diff type:</TD>"; |
print "<TR><TD align=right>Preferred Diff type:</TD>"; |
print "<TD>"; |
print "<TD>"; |
printDiffSelect($use_java_script); |
printDiffSelect($use_java_script); |
print "</TD><TD></TD></TR>\n"; |
print "</TD><TD></TD></TR>\n"; |
if (@branchnames) { |
if (@branchnames) { |
|
|
print "<TR><TD align=right>"; |
print "<TR><TD align=right>"; |
print "<A name=logsort></A>\n"; |
print "<A name=logsort></A>\n"; |
print "Sort log by:</TD>"; |
print "Sort log by:</TD>"; |
print "<TD>"; |
print "<TD><SELECT NAME=\"logsort\""; |
printLogSortSelect($use_java_script); |
print " onchange=\"submit()\"" if ($use_java_script); |
print "</TD>"; |
print ">\n"; |
|
print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted"; |
|
print "<OPTION VALUE=date",$logsort eq "date" ? " SELECTED" : "", ">Commit date"; |
|
print "<OPTION VALUE=rev",$logsort eq "rev" ? " SELECTED" : "", ">Revision"; |
|
print "</SELECT></TD>"; |
print "<TD><INPUT TYPE=SUBMIT VALUE=\" Set \"></TD>"; |
print "<TD><INPUT TYPE=SUBMIT VALUE=\" Set \"></TD>"; |
print "</FORM>\n"; |
print "</FORM>\n"; |
print "</TR></TABLE>"; |
print "</TR></TABLE>"; |
Line 2643 sub human_readable_diff($){ |
|
Line 2396 sub human_readable_diff($){ |
|
$date2 = $r2d; |
$date2 = $r2d; |
} |
} |
|
|
print "<h3 align=center>Diff for /$where_nd between version $rev1 and $rev2</h3>\n", |
print "<h3 align=center>Diff for /$where_nd between version $rev1 and $rev2</h3>\n"; |
"<table border=0 cellspacing=0 cellpadding=0 width=\"100%\">\n", |
|
"<tr bgcolor=\"#ffffff\">\n", |
print "<table border=0 cellspacing=0 cellpadding=0 width=\"100%\">\n"; |
"<th width=\"50%\" valign=TOP>", |
print "<tr bgcolor=\"#ffffff\">\n"; |
"version $rev1"; |
print "<th width=\"50%\" valign=TOP>"; |
|
print "version $rev1"; |
print ", $date1" if (defined($date1)); |
print ", $date1" if (defined($date1)); |
print "<br>Tag: $sym1\n" if ($sym1); |
print "<br>Tag: $sym1\n" if ($sym1); |
print "</th>\n", |
print "</th>\n"; |
"<th width=\"50%\" valign=TOP>", |
print "<th width=\"50%\" valign=TOP>"; |
"version $rev2"; |
print "version $rev2"; |
print ", $date2" if (defined($date2)); |
print ", $date2" if (defined($date2)); |
print "<br>Tag: $sym2\n" if ($sym1); |
print "<br>Tag: $sym2\n" if ($sym1); |
print "</th>\n"; |
print "</th>\n"; |
|
|
my $fs = "<font face=\"$difffontface\" size=\"$difffontsize\"><tt>"; |
my $fs = "<font face=\"$difffontface\" size=\"$difffontsize\">"; |
my $fe = "</tt></font>"; |
my $fe = "</font>"; |
|
|
my $leftRow = 0; |
my $leftRow = 0; |
my $rightRow = 0; |
my $rightRow = 0; |
Line 2680 sub human_readable_diff($){ |
|
Line 2434 sub human_readable_diff($){ |
|
|
|
if ($difftxt =~ /^@@/) { |
if ($difftxt =~ /^@@/) { |
($oldline,$newline,$funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/; |
($oldline,$newline,$funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/; |
$funname = htmlquote($funname); |
|
print "<tr bgcolor=\"$diffcolorHeading\"><td width=\"50%\">"; |
print "<tr bgcolor=\"$diffcolorHeading\"><td width=\"50%\">"; |
print "<table width=\"100%\" border=1 cellpadding=5><tr><td><b>Line $oldline</b>"; |
print "<table width=\"100%\" border=1 cellpadding=5><tr><td><b>Line $oldline</b>"; |
print " <font size=-1>$funname</font></td></tr></table>"; |
print " <font size=-1>$funname</font></td></tr></table>"; |
Line 2775 sub human_readable_diff($){ |
|
Line 2528 sub human_readable_diff($){ |
|
sub navigateHeader($$$$$) { |
sub navigateHeader($$$$$) { |
my ($swhere,$path,$filename,$rev,$title) = @_; |
my ($swhere,$path,$filename,$rev,$title) = @_; |
$swhere = "" if ($swhere eq $scriptwhere); |
$swhere = "" if ($swhere eq $scriptwhere); |
$swhere = './' . urlencode($filename) if ($swhere eq ""); |
$swhere = urlencode($filename) if ($swhere eq ""); |
|
print "<\!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"; |
print <<EOF; |
print "<HTML>\n<HEAD>\n"; |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
print '<!-- CVSweb $zRevision: 1.103 $ $Revision$ -->'; |
<HTML> |
print "\n<TITLE>$path$filename - $title - $rev</TITLE></HEAD>\n"; |
<HEAD> |
print "$body_tag_for_src\n"; |
<META name="robots" content="nofollow"> |
print "<table width=\"100%\" border=0 cellspacing=0 cellpadding=1 bgcolor=\"$navigationHeaderColor\">"; |
<!-- knu-cvsweb $cvsweb_revision --> |
print "<tr valign=bottom><td>"; |
<TITLE>$path$filename - $title - $rev</TITLE></HEAD> |
|
$body_tag_for_src |
|
<table width="100%" border=0 cellspacing=0 cellpadding=1 bgcolor="$navigationHeaderColor"> |
|
<tr valign=bottom><td> |
|
EOF |
|
|
|
print &link($backicon, "$swhere$query#rev$rev"); |
print &link($backicon, "$swhere$query#rev$rev"); |
print "<b>Return to ", &link($filename,"$swhere$query#rev$rev")," CVS log"; |
print "</a> <b>Return to ", &link("$filename","$swhere$query#rev$rev")," CVS log"; |
print "</b> $fileicon</td>"; |
print "</b> $fileicon</td>"; |
|
|
print "<td align=right>$diricon <b>Up to ", &clickablePath($path, 1), "</b></td>"; |
print "<td align=right>$diricon <b>Up to ", &clickablePath($path, 1), "</b></td>"; |
|
|
sub plural_write($$) { |
sub plural_write($$) { |
my ($num,$text) = @_; |
my ($num,$text) = @_; |
if ($num != 1) { |
if ($num != 1) { |
$text .= "s"; |
$text = $text . "s"; |
} |
} |
if ($num > 0) { |
if ($num > 0) { |
return join(' ', $num, $text); |
return $num . " " . $text; |
} |
} |
else { |
else { |
return ""; |
return ""; |
Line 2847 sub readableTime($$) { |
|
Line 2594 sub readableTime($$) { |
|
my $resttime = plural_write(int ($rest / $break), |
my $resttime = plural_write(int ($rest / $break), |
$desc{$break}); |
$desc{$break}); |
if ($resttime) { |
if ($resttime) { |
$retval .= ", $resttime"; |
$retval = $retval . ", " . $resttime; |
} |
} |
} |
} |
|
|
Line 2877 sub clickablePath($$) { |
|
Line 2624 sub clickablePath($$) { |
|
my $wherepath = ''; |
my $wherepath = ''; |
my ($lastslash) = $pathname =~ m|/$|; |
my ($lastslash) = $pathname =~ m|/$|; |
foreach (split(/\//, $pathname)) { |
foreach (split(/\//, $pathname)) { |
$retval .= " / "; |
$retval = $retval . " / "; |
$wherepath .= "/$_"; |
$wherepath = $wherepath . '/' . $_; |
my ($last) = "$wherepath/" eq "/$pathname" |
my ($last) = "$wherepath/" eq "/$pathname" |
|| $wherepath eq "/$pathname"; |
|| $wherepath eq "/$pathname"; |
if ($clickLast || !$last) { |
if ($clickLast || !$last) { |
Line 2898 sub clickablePath($$) { |
|
Line 2645 sub clickablePath($$) { |
|
} |
} |
|
|
sub chooseCVSRoot() { |
sub chooseCVSRoot() { |
if (2 <= @CVSROOT) { |
my @foo; |
|
foreach (sort keys %CVSROOT) { |
|
if (-d $CVSROOT{$_}) { |
|
push(@foo, $_); |
|
} |
|
} |
|
if (@foo > 1) { |
my ($k); |
my ($k); |
print "<form method=\"GET\" action=\"${scriptwhere}\">\n"; |
print "<form method=\"GET\" action=\"${scriptwhere}\">\n"; |
foreach $k (keys %input) { |
foreach $k (keys %input) { |
Line 2913 sub chooseCVSRoot() { |
|
Line 2666 sub chooseCVSRoot() { |
|
print "<td>\n<select name=\"cvsroot\""; |
print "<td>\n<select name=\"cvsroot\""; |
print " onchange=\"submit()\"" if ($use_java_script); |
print " onchange=\"submit()\"" if ($use_java_script); |
print ">\n"; |
print ">\n"; |
foreach $k (@CVSROOT) { |
foreach $k (@foo) { |
print "<option value=\"$k\""; |
print "<option value=\"$k\""; |
print " selected" if ($k eq $cvstree); |
print " selected" if ($k eq $cvstree); |
print ">", ($CVSROOTdescr{$k} ? $CVSROOTdescr{$k} : $k), "</option>\n"; |
print ">" . ($CVSROOTdescr{$k} ? $CVSROOTdescr{$k} : |
|
$k). "</option>\n"; |
} |
} |
print "</select>\n</td>"; |
print "</select>\n</td>"; |
print "<td>"; |
print "<td><input type=submit value=\"Go\"></td>"; |
|
print "</tr></table></form>"; |
} |
} |
else { |
else { |
# no choice .. |
# no choice .. |
print "CVS Root: <b>[$cvstree]</b>"; |
print "CVS Root: <b>[$cvstree]</b>"; |
} |
} |
|
|
print " Module path or alias:\n"; |
|
print "<INPUT TYPE=TEXT NAME=\"path\" VALUE=\"\" SIZE=15>\n"; |
|
print "<input type=submit value=\"Go\">"; |
|
|
|
if (2 <= @CVSROOT) { |
|
print "</td></tr></table></form>"; |
|
} |
|
} |
} |
|
|
sub chooseMirror() { |
sub chooseMirror() { |
Line 3008 sub download_link($$$;$) { |
|
Line 2755 sub download_link($$$;$) { |
|
my ($url, $revision, $textlink, $mimetype) = @_; |
my ($url, $revision, $textlink, $mimetype) = @_; |
my ($fullurl) = download_url($url, $revision, $mimetype); |
my ($fullurl) = download_url($url, $revision, $mimetype); |
|
|
$fullurl =~ s/:/sprintf("%%%02x", ord($&))/eg; |
printf '<A HREF="%s"', htmlquote("$fullurl$barequery"); |
|
|
printf '<A HREF="%s"', hrefquote("$fullurl$barequery"); |
|
|
|
if ($open_extern_window && (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) { |
if ($open_extern_window && (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) { |
print ' target="cvs_checkout"'; |
print ' target="cvs_checkout"'; |
# we should have |
# we should have |
Line 3044 sub download_link($$$;$) { |
|
Line 2789 sub download_link($$$;$) { |
|
if (defined($extern_window_height)); |
if (defined($extern_window_height)); |
|
|
printf q` onClick="window.open('%s','cvs_checkout','%s');"`, |
printf q` onClick="window.open('%s','cvs_checkout','%s');"`, |
hrefquote($fullurl), join(',', @attr); |
htmlquote($fullurl), join(',', @attr); |
} |
} |
} |
} |
print "><b>$textlink</b></A>"; |
print "><b>$textlink</b></A>"; |
Line 3084 sub urlencode($) { |
|
Line 2829 sub urlencode($) { |
|
|
|
s/[\000-+{-\377]/sprintf("%%%02x", ord($&))/ge; |
s/[\000-+{-\377]/sprintf("%%%02x", ord($&))/ge; |
|
|
$_; |
|
|
$_; |
} |
} |
|
|
sub htmlquote($) { |
sub htmlquote($) { |
Line 3099 sub htmlquote($) { |
|
Line 2845 sub htmlquote($) { |
|
$_; |
$_; |
} |
} |
|
|
sub htmlunquote($) { |
|
local($_) = @_; |
|
|
|
# Special Characters; RFC 1866 |
|
s/"/\"/g; |
|
s/</</g; |
|
s/>/>/g; |
|
s/&/&/g; |
|
|
|
$_; |
|
} |
|
|
|
sub hrefquote($) { |
|
local($_) = @_; |
|
|
|
y/ /+/; |
|
|
|
htmlquote($_) |
|
} |
|
|
|
sub http_header(;$) { |
sub http_header(;$) { |
my $content_type = shift || "text/html"; |
my $content_type = shift || "text/html"; |
|
|
$content_type .= "; charset=$charset" |
|
if $content_type =~ m,^text/, && defined($charset) && $charset; |
|
|
|
if (defined($moddate)) { |
if (defined($moddate)) { |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Apache->request->header_out("Last-Modified" => scalar gmtime($moddate) . " GMT"); |
Apache->request->header_out("Last-Modified" => scalar gmtime($moddate) . " GMT"); |
} |
} |
else { |
else { |
print "Last-Modified: ", scalar gmtime($moddate), " GMT\r\n"; |
print "Last-Modified: " . scalar gmtime($moddate) . " GMT\r\n"; |
} |
} |
} |
} |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Line 3140 sub http_header(;$) { |
|
Line 2862 sub http_header(;$) { |
|
print "Content-type: $content_type\r\n"; |
print "Content-type: $content_type\r\n"; |
} |
} |
if ($allow_compress && $maycompress) { |
if ($allow_compress && $maycompress) { |
if ($has_zlib || (defined($CMD{gzip}) && open(GZIP, "| $CMD{gzip} -1 -c"))) { |
if ($has_zlib || (defined($GZIPBIN) && open(GZIP, "|$GZIPBIN -1 -c"))) { |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Apache->request->content_encoding("x-gzip"); |
Apache->request->content_encoding("x-gzip"); |
Apache->request->header_out(Vary => "Accept-Encoding"); |
Apache->request->header_out(Vary => "Accept-Encoding"); |
Line 3157 sub http_header(;$) { |
|
Line 2879 sub http_header(;$) { |
|
} |
} |
select(GZIP); |
select(GZIP); |
$gzip_open = 1; |
$gzip_open = 1; |
# print "<!-- gzipped -->" if ($content_type =~ m|^text/html\b|); |
# print "<!-- gzipped -->" if ($content_type eq "text/html"); |
} |
} |
else { |
else { |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Line 3166 sub http_header(;$) { |
|
Line 2888 sub http_header(;$) { |
|
else { |
else { |
print "\r\n"; # Close headers |
print "\r\n"; # Close headers |
} |
} |
print "<font size=-1>Unable to find gzip binary in the <b>\$command_path</b> ($command_path) to compress output</font><br>"; |
print "<font size=-1>Unable to find gzip binary in the \$PATH to compress output</font><br>"; |
} |
} |
} |
} |
else { |
else { |
Line 3181 sub http_header(;$) { |
|
Line 2903 sub http_header(;$) { |
|
|
|
sub html_header($) { |
sub html_header($) { |
my ($title) = @_; |
my ($title) = @_; |
http_header("text/html"); |
my $version = '$zRevision: 1.103 $ $Revision$'; #' |
|
http_header(); |
print <<EOH; |
print <<EOH; |
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" |
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" |
"http://www.w3.org/TR/REC-html40/loose.dtd"> |
"http://www.w3.org/TR/REC-html40/loose.dtd"> |
<html> |
<html> |
<head> |
|
<meta name="robots" content="nofollow"> |
|
<title>$title</title> |
<title>$title</title> |
<!-- knu-cvsweb $cvsweb_revision --> |
<!-- CVSweb $version --> |
</head> |
</head> |
$body_tag |
$body_tag |
$logo <h1 align="center">$title</h1> |
$logo <h1 align="center">$title</h1> |
Line 3206 sub link_tags($) { |
|
Line 2927 sub link_tags($) { |
|
my ($fileurl,$filename); |
my ($fileurl,$filename); |
|
|
($filename = $where) =~ s/^.*\///; |
($filename = $where) =~ s/^.*\///; |
$fileurl = './' . urlencode($filename); |
$fileurl = urlencode($filename); |
|
|
foreach my $sym (split(", ", $tags)) { |
foreach my $sym (split(", ", $tags)) { |
$ret .= ",\n" if ($ret ne ""); |
$ret .= ",\n" if ($ret ne ""); |