version 3.9, 2000/07/29 12:41:25 |
version 3.37, 2000/10/20 15:46:01 |
|
|
#!/usr/bin/perl -ws |
#!/usr/bin/perl5 -ws |
# |
# |
# cvsweb - a CGI interface to CVS trees. |
# cvsweb - a CGI interface to CVS trees. |
# |
# |
# Written in their spare time by |
# Written in their spare time by |
# Bill Fenner <fenner@FreeBSD.org> (original work) |
# Bill Fenner <fenner@FreeBSD.org> (original work) |
# extended by Henner Zeller <zeller@think.de>, |
# extended by Henner Zeller <zeller@think.de>, |
# Henrik Nordstrom <hno@hem.passagen.se> |
# Henrik Nordstrom <hno@hem.passagen.se> |
# Ken Coar <coar@Apache.Org> |
# Ken Coar <coar@Apache.Org> |
# Dick Balaska <dick@buckosoft.com> |
# Dick Balaska <dick@buckosoft.com> |
# Akinori MUSHA <knu@FreeBSD.org> |
# Akinori MUSHA <knu@FreeBSD.org> |
|
# Jens-Uwe Mager <jum@helios.de> |
# |
# |
# Based on: |
# Based on: |
# * Bill Fenners cvsweb.cgi revision 1.28 available from: |
# * Bill Fenners cvsweb.cgi revision 1.28 available from: |
|
|
# 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.93 2000/07/27 17:42:28 hzeller Exp $ |
# $zId: cvsweb.cgi,v 1.103 2000/09/20 17:02:29 jumager Exp $ |
# $Id$ |
# $Id$ |
# |
# |
### |
### |
|
|
use vars qw ( |
use vars qw ( |
$config $allow_version_select $verbose |
$config $allow_version_select $verbose |
%CVSROOT %CVSROOTdescr %MIRRORS %DEFAULTVALUE %ICONS %MTYPES |
%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 $prcgi |
@revisions %state %difflines %log %branchpoint @revorder |
@prcategories $prcategories |
$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_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 $hr_default $logsort $cvstree $cvsroot |
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot |
$mimetype $defaultTextPlain $defaultViewable $allow_compress |
$mimetype $defaultTextPlain $defaultViewable $allow_compress |
$GZIPBIN $backicon $diricon $fileicon $fullname $newname |
$GZIPBIN $backicon $diricon $fileicon $fullname $newname |
$cvstreedefault $body_tag $logo $defaulttitle $address |
$cvstreedefault $body_tag $body_tag_for_src |
$backcolor $long_intro $short_instruction $shortLogLen |
$logo $defaulttitle $address |
|
$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 |
$hr_ignkeysubst $diffcolorHeading $diffcolorEmpty $diffcolorRemove |
$hr_ignkeysubst $diffcolorHeading $diffcolorEmpty $diffcolorRemove |
|
|
$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 |
$checkout_magic $show_subdir_lastmod $show_log_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 |
$use_moddate $has_zlib $gzip_open |
|
$LOG_FILESEPARATOR $LOG_REVSEPARATOR |
); |
); |
|
|
|
sub printDiffSelect($); |
|
sub printDiffLinks($$); |
|
sub printLogSortSelect($); |
|
sub findLastModifiedSubdirs(@); |
|
sub htmlify_sub(&$); |
|
sub htmlify($;$); |
|
sub spacedHtmlText($;$); |
|
sub link($$); |
|
sub revcmp($$); |
|
sub fatal($$); |
|
sub redirect($); |
|
sub safeglob($); |
|
sub getMimeTypeFromSuffix($); |
|
sub head($;$); |
|
sub scan_directives(@); |
|
sub doAnnotate($$); |
|
sub doCheckout($$); |
|
sub cvswebMarkup($$$); |
|
sub viewable($); |
|
sub doDiff($$$$$$); |
|
sub getDirLogs($$@); |
|
sub readLog($;$); |
|
sub printLog($;$); |
|
sub doLog($); |
|
sub flush_diff_rows($$$$); |
|
sub human_readable_diff($); |
|
sub navigateHeader($$$$$); |
|
sub plural_write($$); |
|
sub readableTime($$); |
|
sub clickablePath($$); |
|
sub chooseCVSRoot(); |
|
sub chooseMirror(); |
|
sub fileSortCmp(); |
|
sub download_url($$;$); |
|
sub download_link($$$;$); |
|
sub toggleQuery($$); |
|
sub urlencode($); |
|
sub htmlquote($); |
|
sub htmlunquote($); |
|
sub http_header(;$); |
|
sub html_header($); |
|
sub html_footer(); |
|
sub link_tags($); |
|
sub forbidden_module($); |
|
|
##### Start of Configuration Area ######## |
##### Start of Configuration Area ######## |
# == EDIT this == |
use Cwd; |
# User configuration is stored in |
|
$config = defined($ENV{CVSWEB_CONFIG}) ? $ENV{CVSWEB_CONFIG} : '/usr/local/etc/cvsweb.conf'; |
|
|
|
|
# == EDIT this == |
|
# Locations to search for user configuration, in order: |
|
for ( |
|
$ENV{CVSWEB_CONFIG}, |
|
'/usr/local/etc/cvsweb.conf', |
|
getcwd() . '/cvsweb.conf' |
|
) { |
|
$config = $_ if defined($_) && -r $_; |
|
} |
|
|
# == Configuration defaults == |
# == Configuration defaults == |
# Defaults for configuration variables that shouldn't need |
# Defaults for configuration variables that shouldn't need |
# to be configured.. |
# to be configured.. |
Line 95 $allow_version_select = 1; |
|
Line 152 $allow_version_select = 1; |
|
# These are defined to allow checking with perl -cw |
# These are defined to allow checking with perl -cw |
%CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = %MTYPES = |
%CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = %MTYPES = |
%tags = %alltags = @tabcolors = (); |
%tags = %alltags = @tabcolors = (); |
$cvstreedefault = $body_tag = $logo = $defaulttitle = $address = |
$cvstreedefault = $body_tag = $body_tag_for_src = |
$backcolor = $long_intro = $short_instruction = $shortLogLen = |
$logo = $defaulttitle = $address = |
|
$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 = |
$hr_ignkeysubst = $diffcolorHeading = $diffcolorEmpty = $diffcolorRemove = |
$hr_ignkeysubst = $diffcolorHeading = $diffcolorEmpty = $diffcolorRemove = |
Line 104 $diffcolorChange = $diffcolorAdd = $diffcolorDarkChang |
|
Line 162 $diffcolorChange = $diffcolorAdd = $diffcolorDarkChang |
|
$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 = |
$checkout_magic = $show_subdir_lastmod = $show_log_in_markup = $v = |
$show_subdir_lastmod = $show_log_in_markup = $v = |
$navigationHeaderColor = $tableBorderColor = $markupLogColor = |
$navigationHeaderColor = $tableBorderColor = $markupLogColor = |
$tabstop = $use_moddate = $moddate = undef; |
$tabstop = $use_moddate = $moddate = $gzip_open = undef; |
|
|
|
$LOG_FILESEPARATOR = q/^={77}$/; |
|
$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; |
use IPC::Open2; |
use IPC::Open2; |
|
|
|
# Check if the zlib C library interface is installed, and if yes |
|
# we can avoid using the extra gzip process. |
|
eval { |
|
require Compress::Zlib; |
|
}; |
|
$has_zlib = !$@; |
|
|
$verbose = $v; |
$verbose = $v; |
$checkoutMagic = "~checkout~"; |
$checkoutMagic = "~checkout~"; |
$pathinfo = defined($ENV{PATH_INFO}) ? $ENV{PATH_INFO} : ''; |
$pathinfo = defined($ENV{PATH_INFO}) ? $ENV{PATH_INFO} : ''; |
Line 133 $is_mod_perl = defined($ENV{MOD_PERL}); |
|
Line 244 $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_lynx = ($Browser =~ m`^Lynx/`i); |
$is_lynx = ($Browser =~ m`^Lynx/`i); |
$is_w3m = ($Browser =~ m`^w3m/`i); |
$is_w3m = ($Browser =~ m`^w3m/`i); |
$is_msie = ($Browser =~ m`MSIE`); |
$is_msie = ($Browser =~ m`MSIE`); |
$is_mozilla3 = ($Browser =~ m`^Mozilla/[3-9]`); |
$is_mozilla3 = ($Browser =~ m`^Mozilla/[3-9]`); |
|
|
$is_textbased = ($is_lynx || $is_w3m); |
$is_textbased = ($is_links || $is_lynx || $is_w3m); |
|
|
$nofilelinks = $is_textbased; |
$nofilelinks = $is_textbased; |
|
|
Line 150 $nofilelinks = $is_textbased; |
|
Line 262 $nofilelinks = $is_textbased; |
|
# braindamaged MS-Internet Exploders claim that they |
# braindamaged MS-Internet Exploders claim that they |
# accept gzip .. but don't in fact and |
# accept gzip .. but don't in fact and |
# display garbage then :-/ |
# display garbage then :-/ |
# Turn off gzip if running under mod_perl. piping does |
# Turn off gzip if running under mod_perl and no zlib is available, |
# not work as expected inside the server. One can probably |
# piping does not work as expected inside the server. |
# achieve the same result using Apache::GZIPFilter. |
$maycompress = (((defined($ENV{HTTP_ACCEPT_ENCODING}) |
$maycompress =(($ENV{HTTP_ACCEPT_ENCODING} =~ m`gzip` |
&& $ENV{HTTP_ACCEPT_ENCODING} =~ m`gzip`) |
|| $is_mozilla3) |
|| $is_mozilla3) |
&& !$is_msie |
&& !$is_msie |
&& !$is_mod_perl); |
&& !($is_mod_perl && !$has_zlib)); |
|
|
# put here the variables we need in order |
# put here the variables we need in order |
# to hold our state - they will be added (with |
# to hold our state - they will be added (with |
# their current value) to any link/query string |
# their current value) to any link/query string |
# you construct |
# you construct |
@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) { |
do $config; |
do $config |
} |
|| &fatal("500 Internal Error", |
else { |
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
|
$config, &htmlify($@))); |
|
} 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, or the environment variable ' |
. 'in cvsweb.cgi, or the environment variable ' |
|
|
undef %input; |
undef %input; |
$query = $ENV{QUERY_STRING}; |
$query = $ENV{QUERY_STRING}; |
|
|
if ($query ne '') { |
if (defined($query) && $query ne '') { |
foreach (split(/&/, $query)) { |
foreach (split(/&/, $query)) { |
s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted |
s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted |
if (/(\S+)=(.*)/) { |
if (/(\S+)=(.*)/) { |
Line 190 if ($query ne '') { |
|
Line 304 if ($query ne '') { |
|
} |
} |
} |
} |
|
|
# For backwards compability, set only_with_tag to only_on_branch if set. |
# For backwards compability, set only_with_tag to only_on_branch if set. |
$input{only_with_tag} = $input{only_on_branch} |
$input{only_with_tag} = $input{only_on_branch} |
if (defined($input{only_on_branch})); |
if (defined($input{only_on_branch})); |
|
|
Line 217 foreach (keys %DEFAULTVALUE) |
|
Line 331 foreach (keys %DEFAULTVALUE) |
|
} |
} |
} |
} |
} |
} |
|
|
$barequery = ""; |
$barequery = ""; |
|
my @barequery; |
foreach (@stickyvars) { |
foreach (@stickyvars) { |
# construct a query string with the sticky non default parameters set |
# construct a query string with the sticky non default parameters set |
if (defined($input{$_}) && $input{$_} ne '' && |
if (defined($input{$_}) && $input{$_} ne '' && |
!(defined($DEFAULTVALUE{$_}) && $input{$_} eq $DEFAULTVALUE{$_})) { |
!(defined($DEFAULTVALUE{$_}) && $input{$_} eq $DEFAULTVALUE{$_})) { |
if ($barequery) { |
push @barequery, join('=', urlencode($_), urlencode($input{$_})); |
$barequery = $barequery . "&"; |
|
} |
|
my $thisval = urlencode($_) . "=" . urlencode($input{$_}); |
|
$barequery .= $thisval; |
|
} |
} |
} |
} |
# is there any query ? |
# is there any query ? |
if ($barequery) { |
if (@barequery) { |
|
$barequery = join('&', @barequery); |
$query = "?$barequery"; |
$query = "?$barequery"; |
$barequery = "&" . $barequery; |
$barequery = "&$barequery"; |
} |
} |
else { |
else { |
$query = ""; |
$query = ""; |
} |
} |
|
undef @barequery; |
|
|
# get actual parameters |
# get actual parameters |
$sortby = $input{"sortby"}; |
$sortby = $input{"sortby"}; |
|
|
$byfile = 1; |
$byfile = 1; |
} |
} |
|
|
$hr_default = $input{'f'} eq 'h'; |
$defaultDiffType = $input{'f'}; |
|
|
$logsort = $input{'logsort'}; |
$logsort = $input{'logsort'}; |
|
|
Line 285 if ($input{'cvsroot'} && $CVSROOT{$input{'cvsroot'}}) |
|
Line 398 if ($input{'cvsroot'} && $CVSROOT{$input{'cvsroot'}}) |
|
$cvsroot = $CVSROOT{$cvstree}; |
$cvsroot = $CVSROOT{$cvstree}; |
|
|
# create icons out of description |
# create icons out of description |
foreach my $k (keys %ICONS) { |
my $k; |
|
foreach $k (keys %ICONS) { |
no strict 'refs'; |
no strict 'refs'; |
my ($itxt,$ipath,$iwidth,$iheight) = @{$ICONS{$k}}; |
my ($itxt,$ipath,$iwidth,$iheight) = @{$ICONS{$k}}; |
if ($ipath) { |
if ($ipath) { |
${"${k}icon"} = "<IMG SRC=\"$ipath\" ALT=\"$itxt\" BORDER=\"0\" WIDTH=\"$iwidth\" HEIGHT=\"$iheight\">"; |
${"${k}icon"} = sprintf('<IMG SRC="%s" ALT="%s" BORDER="0" WIDTH="%d" HEIGHT="%d">', |
|
htmlquote($ipath), htmlquote($itxt), $iwidth, $iheight) |
} |
} |
else { |
else { |
${"${k}icon"} = $itxt; |
${"${k}icon"} = $itxt; |
} |
} |
} |
} |
|
undef $k; |
|
|
|
my $config_cvstree = "$config-$cvstree"; |
|
|
# Do some special configuration for cvstrees |
# Do some special configuration for cvstrees |
do "$config-$cvstree" if (-f "$config-$cvstree"); |
if (-f $config_cvstree) { |
|
do $config_cvstree |
|
|| &fatal("500 Internal Error", |
|
sprintf('Error in loading configuration file: %s<BR><BR>%s<BR>', |
|
$config_cvstree, &htmlify($@))); |
|
} |
|
undef $config_cvstree; |
|
|
$prcategories = '(?:' . join('|', @prcategories) . ')'; |
$prcategories = '(?:' . join('|', @prcategories) . ')'; |
|
$prcgi .= '%s' if defined($prcgi) && $prcgi !~ /%s/; |
|
|
$fullname = $cvsroot . '/' . $where; |
$fullname = $cvsroot . '/' . $where; |
$mimetype = &getMimeTypeFromSuffix ($fullname); |
$mimetype = &getMimeTypeFromSuffix ($fullname); |
Line 309 $defaultViewable = $allow_markup && viewable($mimetype |
|
Line 434 $defaultViewable = $allow_markup && viewable($mimetype |
|
# search for GZIP if compression allowed |
# search for GZIP if compression allowed |
# We've to find out if the GZIP-binary exists .. otherwise |
# We've to find out if the GZIP-binary exists .. otherwise |
# ge get an Internal Server Error if we try to pipe the |
# ge get an Internal Server Error if we try to pipe the |
# output through the nonexistent gzip .. |
# output through the nonexistent gzip .. |
# any more elegant ways to prevent this are welcome! |
# any more elegant ways to prevent this are welcome! |
if ($allow_compress && $maycompress) { |
if ($allow_compress && $maycompress && !$has_zlib) { |
foreach (split(/:/, $ENV{PATH})) { |
foreach (split(/:/, $ENV{PATH})) { |
if (-x "$_/gzip") { |
if (-x "$_/gzip") { |
$GZIPBIN = "$_/gzip"; |
$GZIPBIN = "$_/gzip"; |
Line 390 elsif (-d $fullname) { |
|
Line 515 elsif (-d $fullname) { |
|
$input{only_with_tag}; |
$input{only_with_tag}; |
|
|
} |
} |
|
|
|
|
|
|
print "<HR NOSHADE>\n"; |
print "<HR NOSHADE>\n"; |
# Using <MENU> in this manner violates the HTML2.0 spec but |
# Using <MENU> in this manner violates the HTML2.0 spec but |
# provides the results that I want in most browsers. Another |
# provides the results that I want in most browsers. Another |
# case of layout spooging up HTML. |
# case of layout spooging up HTML. |
|
|
my $infocols = 0; |
my $infocols = 0; |
if ($dirtable) { |
if ($dirtable) { |
if (defined($tableBorderColor)) { |
if (defined($tableBorderColor)) { |
Line 405 elsif (-d $fullname) { |
|
Line 530 elsif (-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++; |
print "<tr><th align=left bgcolor=\"" . (($byfile) ? |
printf '<tr><th align=left bgcolor="%s">', |
$columnHeaderColorSorted : |
$byfile ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorDefault) . "\">"; |
if ($byfile) { |
print "<a href=\"./" . &toggleQuery("sortby","file") . |
print 'File'; |
"#dirlist\">" if (!$byfile); |
} else { |
print "File"; |
print &link('File', sprintf('./%s#dirlist', |
print "</a>" if (!$byfile); |
&toggleQuery("sortby", "file"))); |
|
} |
print "</th>"; |
print "</th>"; |
# do not display the other column-headers, if we do not have any files |
# do not display the other column-headers, if we do not have any files |
# with revision information: |
# with revision information: |
if (scalar(%fileinfo)) { |
if (scalar(%fileinfo)) { |
$infocols++; |
$infocols++; |
print "<th align=left bgcolor=\"" . (($byrev) ? |
printf '<th align=left bgcolor="%s">', |
$columnHeaderColorSorted : |
$byrev ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorDefault) . "\">"; |
if ($byrev) { |
print "<a href=\"./" . &toggleQuery ("sortby","rev") . |
print 'Rev.'; |
"#dirlist\">" if (!$byrev); |
} else { |
print "Rev."; |
print &link('Rev.', sprintf('./%s#dirlist', |
print "</a>" if (!$byrev); |
&toggleQuery("sortby", "rev"))); |
|
} |
print "</th>"; |
print "</th>"; |
$infocols++; |
$infocols++; |
print "<th align=left bgcolor=\"" . (($bydate) ? |
printf '<th align=left bgcolor="%s">', |
$columnHeaderColorSorted : |
$bydate ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorDefault) . "\">"; |
if ($bydate) { |
print "<a href=\"./" . &toggleQuery ("sortby","date") . |
print 'Age'; |
"#dirlist\">" if (!$bydate); |
} else { |
print "Age"; |
print &link('Age', sprintf('./%s#dirlist', |
print "</a>" if (!$bydate); |
&toggleQuery("sortby", "date"))); |
|
} |
print "</th>"; |
print "</th>"; |
if ($show_author) { |
if ($show_author) { |
$infocols++; |
$infocols++; |
print "<th align=left bgcolor=\"" . (($byauthor) ? |
printf '<th align=left bgcolor="%s">', |
$columnHeaderColorSorted : |
$byauthor ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorDefault) . "\">"; |
if ($byauthor) { |
print "<a href=\"./" . &toggleQuery ("sortby","author") . |
print 'Author'; |
"#dirlist\">" if (!$byauthor); |
} else { |
print "Author"; |
print &link('Author', sprintf('./%s#dirlist', |
print "</a>" if (!$byauthor); |
&toggleQuery("sortby", "author"))); |
|
} |
print "</th>"; |
print "</th>"; |
} |
} |
$infocols++; |
$infocols++; |
print "<th align=left bgcolor=\"" . (($bylog) ? |
printf '<th align=left bgcolor="%s">', |
$columnHeaderColorSorted : |
$bylog ? $columnHeaderColorSorted : $columnHeaderColorDefault; |
$columnHeaderColorDefault) . "\">"; |
if ($bylog) { |
print "<a href=\"./", toggleQuery("sortby","log"), "#dirlist\">" if (!$bylog); |
print 'Last log entry'; |
print "Last log entry"; |
} else { |
print "</a>" if (!$bylog); |
print &link('Last log entry', sprintf('./%s#dirlist', |
|
&toggleQuery("sortby", "log"))); |
|
} |
print "</th>"; |
print "</th>"; |
} |
} |
elsif ($use_descriptions) { |
elsif ($use_descriptions) { |
print "<th align=left bgcolor=\"". $columnHeaderColorDefault . "\">"; |
printf '<th align=left bgcolor="%s">', $columnHeaderColorDefault; |
print "Description"; |
print "Description"; |
$infocols++; |
$infocols++; |
} |
} |
Line 465 elsif (-d $fullname) { |
|
Line 596 elsif (-d $fullname) { |
|
print "<menu>\n"; |
print "<menu>\n"; |
} |
} |
my $dirrow = 0; |
my $dirrow = 0; |
|
|
my $i; |
my $i; |
lookingforattic: |
lookingforattic: |
for ($i = 0; $i <= $#dir; $i++) { |
for ($i = 0; $i <= $#dir; $i++) { |
Line 480 elsif (-d $fullname) { |
|
Line 611 elsif (-d $fullname) { |
|
closedir($dh); |
closedir($dh); |
} |
} |
|
|
my $hideAtticToggleLink = "<a href=\"./" . |
my $hideAtticToggleLink = $input{'hideattic'} ? '' : |
&toggleQuery ("hideattic") . |
&link('[Hide]', sprintf('./%s#dirlist', |
"#dirlist\">[Hide]</a>" if (!$input{'hideattic'}); |
&toggleQuery ("hideattic"))); |
|
|
# Sort without the Attic/ pathname. |
# Sort without the Attic/ pathname. |
# place directories first |
# place directories first |
Line 520 elsif (-d $fullname) { |
|
Line 651 elsif (-d $fullname) { |
|
next if ($_ eq '..' && $where eq '/'); |
next if ($_ eq '..' && $where eq '/'); |
my ($rev,$date,$log,$author,$filename) = @{$fileinfo{$_}} |
my ($rev,$date,$log,$author,$filename) = @{$fileinfo{$_}} |
if (defined($fileinfo{$_})); |
if (defined($fileinfo{$_})); |
print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable); |
printf '<tr bgcolor="%s"><td>', $tabcolors[$dirrow % 2] 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("Previous 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; |
} |
} |
else { |
else { |
print &link($diricon,$url); |
print &link($diricon, $url); |
} |
} |
print " ", &link($_ . "/", $url), $attic; |
print " ", &link("$_/", $url), $attic; |
if ($_ eq "Attic") { |
if ($_ eq "Attic") { |
print " <a href=\"./" . |
print " "; |
&toggleQuery ("hideattic") . |
print &link("[Don't hide]", sprintf('./%s#dirlist', |
"#dirlist\">[Don't hide]</a>"; |
&toggleQuery ("hideattic"))); |
} |
} |
} |
} |
# Show last change in dir |
# Show last change in dir |
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 562 elsif (-d $fullname) { |
|
Line 693 elsif (-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 573 elsif (-d $fullname) { |
|
Line 704 elsif (-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 604 elsif (-d $fullname) { |
|
Line 735 elsif (-d $fullname) { |
|
next if (!defined($fileinfo{$_})); |
next if (!defined($fileinfo{$_})); |
($rev,$date,$log,$author) = @{$fileinfo{$_}}; |
($rev,$date,$log,$author) = @{$fileinfo{$_}}; |
$filesfound++; |
$filesfound++; |
print "<tr bgcolor=\"" . @tabcolors[$dirrow%2] . "\"><td>" if ($dirtable); |
printf '<tr bgcolor="%s"><td>', $tabcolors[$dirrow % 2] if $dirtable; |
print "<A NAME=\"$_\"></A>"; |
print "<A NAME=\"$_\"></A>"; |
if ($nofilelinks) { |
if ($nofilelinks) { |
print $fileicon; |
print $fileicon; |
Line 615 elsif (-d $fullname) { |
|
Line 746 elsif (-d $fullname) { |
|
print " ", &link($_, $url), $attic; |
print " ", &link($_, $url), $attic; |
print "</td><td> " if ($dirtable); |
print "</td><td> " if ($dirtable); |
download_link($fileurl, |
download_link($fileurl, |
$rev, $rev, |
$rev, $rev, |
$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 627 elsif (-d $fullname) { |
|
Line 758 elsif (-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 642 elsif (-d $fullname) { |
|
Line 773 elsif (-d $fullname) { |
|
if ($dirtable && defined($tableBorderColor)) { |
if ($dirtable && defined($tableBorderColor)) { |
print "</td></tr></table>"; |
print "</td></tr></table>"; |
} |
} |
print "". ($dirtable == 1) ? "</table>" : "</menu>" . "\n"; |
print( $dirtable == 1 ? "</table>\n" : "</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"; |
} |
} |
if ($input{only_with_tag} && (!%tags || !$tags{$input{only_with_tag}})) { |
if ($input{only_with_tag} && (!%tags || !$tags{$input{only_with_tag}})) { |
%tags = %alltags |
%tags = %alltags |
} |
} |
if (scalar %tags |
if (scalar %tags |
|| $input{only_with_tag} |
|| $input{only_with_tag} |
|| $edit_option_form |
|| $edit_option_form |
|| defined($input{"options"})) { |
|| defined($input{"options"})) { |
print "<hr size=1 NOSHADE>"; |
print "<hr size=1 NOSHADE>"; |
Line 662 elsif (-d $fullname) { |
|
Line 793 elsif (-d $fullname) { |
|
foreach my $var (@stickyvars) { |
foreach my $var (@stickyvars) { |
print "<INPUT TYPE=HIDDEN NAME=\"$var\" VALUE=\"$input{$var}\">\n" |
print "<INPUT TYPE=HIDDEN NAME=\"$var\" VALUE=\"$input{$var}\">\n" |
if (defined($input{$var}) |
if (defined($input{$var}) |
&& $input{$var} ne $DEFAULTVALUE{$var} |
&& (!defined($DEFAULTVALUE{$var}) |
|
|| $input{$var} ne $DEFAULTVALUE{$var}) |
&& $input{$var} ne "" |
&& $input{$var} ne "" |
&& $var ne "only_with_tag"); |
&& $var ne "only_with_tag"); |
} |
} |
Line 672 elsif (-d $fullname) { |
|
Line 804 elsif (-d $fullname) { |
|
print ">"; |
print ">"; |
print "<OPTION VALUE=\"\">All tags / default branch\n"; |
print "<OPTION VALUE=\"\">All tags / default branch\n"; |
foreach my $tag (reverse sort { lc $a cmp lc $b } keys %tags) { |
foreach my $tag (reverse sort { lc $a cmp lc $b } keys %tags) { |
print "<OPTION",defined($input{only_with_tag}) && |
print "<OPTION",defined($input{only_with_tag}) && |
$input{only_with_tag} eq $tag ? " SELECTED":"", |
$input{only_with_tag} eq $tag ? " SELECTED" : "", |
">$tag\n"; |
">$tag\n"; |
} |
} |
print "</SELECT>\n"; |
print "</SELECT>\n"; |
Line 699 elsif (-d $fullname) { |
|
Line 831 elsif (-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>revisions by: \n"; |
print "<td>Sort log by: "; |
print "<SELECT NAME=logsort>\n"; |
printLogSortSelect(0); |
print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted"; |
print "</td></tr>"; |
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(); |
printDiffSelect(0); |
print "</td>"; |
print "</td>"; |
print "<td>Show Attic files: "; |
print "<td>Show Attic files: "; |
print "<INPUT NAME=hideattic TYPE=CHECKBOX", $input{'hideattic'}?" CHECKED":"", |
print "<INPUT NAME=hideattic TYPE=CHECKBOX", $input{'hideattic'} ? " CHECKED" : "", |
"></td></tr>\n"; |
"></td></tr>\n"; |
print "<tr><td align=center colspan=2><input type=submit value=\"Change Options\">"; |
print "<tr><td align=center colspan=2><input type=submit value=\"Change Options\">"; |
print "</td></tr></table></center></FORM>\n"; |
print "</td></tr></table></center></FORM>\n"; |
} |
} |
print &html_footer; |
print &html_footer; |
print "</BODY></HTML>\n"; |
print "</BODY></HTML>\n"; |
} |
} |
|
|
############################### |
############################### |
# View Files |
# View Files |
Line 724 elsif (-d $fullname) { |
|
Line 853 elsif (-d $fullname) { |
|
elsif (-f $fullname . ',v') { |
elsif (-f $fullname . ',v') { |
if (defined($input{'rev'}) || $doCheckout) { |
if (defined($input{'rev'}) || $doCheckout) { |
&doCheckout($fullname, $input{'rev'}); |
&doCheckout($fullname, $input{'rev'}); |
|
gzipclose(); |
exit; |
exit; |
} |
} |
if (defined($input{'annotate'}) && $allow_annotate) { |
if (defined($input{'annotate'}) && $allow_annotate) { |
&doAnnotate($input{'annotate'}); |
&doAnnotate($input{'annotate'}); |
|
gzipclose(); |
exit; |
exit; |
} |
} |
if (defined($input{'r1'}) && defined($input{'r2'})) { |
if (defined($input{'r1'}) && defined($input{'r2'})) { |
&doDiff($fullname, $input{'r1'}, $input{'tr1'}, |
&doDiff($fullname, $input{'r1'}, $input{'tr1'}, |
$input{'r2'}, $input{'tr2'}, $input{'f'}); |
$input{'r2'}, $input{'tr2'}, $input{'f'}); |
|
gzipclose(); |
exit; |
exit; |
} |
} |
print("going to dolog($fullname)\n") if ($verbose); |
print("going to dolog($fullname)\n") if ($verbose); |
Line 755 elsif (-d $fullname) { |
|
Line 887 elsif (-d $fullname) { |
|
# e.g. foo.c |
# e.g. foo.c |
&doDiff($fullname, $input{'r1'}, $input{'tr1'}, |
&doDiff($fullname, $input{'r1'}, $input{'tr1'}, |
$input{'r2'}, $input{'tr2'}, $input{'f'}); |
$input{'r2'}, $input{'tr2'}, $input{'f'}); |
|
gzipclose(); |
exit; |
exit; |
} |
} |
elsif (($newname = $fullname) =~ s|/([^/]+)$|/Attic/$1| && |
elsif (($newname = $fullname) =~ s|/([^/]+)$|/Attic/$1| && |
Line 788 elsif (-d $fullname) { |
|
Line 921 elsif (-d $fullname) { |
|
} |
} |
&fatal("404 Not Found","$where: no such file or directory"); |
&fatal("404 Not Found","$where: no such file or directory"); |
} |
} |
|
|
|
gzipclose(); |
## End MAIN |
## End MAIN |
|
|
sub printDiffSelect { |
sub printDiffSelect($) { |
my ($use_java_script) = @_; |
my ($use_java_script) = @_; |
$use_java_script = 0 if (!defined($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 findLastModifiedSubdirs { |
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(@) { |
my (@dirs) = @_; |
my (@dirs) = @_; |
my ($dirname, @files); |
my ($dirname, @files); |
|
|
Line 839 sub findLastModifiedSubdirs { |
|
Line 998 sub findLastModifiedSubdirs { |
|
return @files; |
return @files; |
} |
} |
|
|
sub htmlify { |
sub htmlify_sub(&$) { |
my($string, $pr) = @_; |
(my $proc, local $_) = @_; |
|
local @_ = split(m`(<a [^>]+>[^<]*</a>)`i); |
|
my ($linked, $result); |
|
|
# Special Characters; RFC 1866 |
while (($_, $linked) = splice(@_, 0, 2)) { |
$string =~ s/&/&/g; |
&$proc(); |
$string =~ s/\"/"/g; |
$result .= $_; |
$string =~ s/</</g; |
$result .= $linked; |
$string =~ s/>/>/g; |
} |
|
|
# get URL's as link .. |
$result; |
$string =~ s`(http|ftp|https)(://[-a-zA-Z0-9%.~:_/]+)([?&]([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*`<A HREF="$1$2$3">$1$2$3</A>`; |
} |
# get e-mails as link |
|
$string =~ s`([-a-zA-Z0-9_.]+@([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})`<A HREF="mailto:$1">$1</A>`; |
|
|
|
# get #PR as link .. |
sub htmlify($;$) { |
if ($pr && defined($prcgi)) { |
(local $_, my $extra) = @_; |
1 while $string =~ s`\b(pr[:#]?\s*(?:#?\d+[,\s]\s*)*#?)(\d+)\b`$1<A HREF="$prcgi$2">$2</A>`i; |
|
$string =~ s`\b${prcategories}/(\d+)\b`<A HREF="$prcgi$1">$&</A>`igo; |
$_ = htmlquote($_); |
|
|
|
# get URL's as link |
|
s{ |
|
(http|ftp|https)://\S+ |
|
}{ |
|
&link($&, htmlunquote($&)) |
|
}egx; |
|
|
|
# get e-mails as link |
|
$_ = htmlify_sub { |
|
s< |
|
[\w+=\-.!]+@[\w\-]+(\.[\w\-]+)+ |
|
>< |
|
&link($&, "mailto:$&") |
|
>egix; |
|
} $_; |
|
|
|
if ($extra) { |
|
# get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" |
|
if (defined($prcgi)) { |
|
my $prev; |
|
|
|
do { |
|
$prev = $_; |
|
|
|
$_ = htmlify_sub { |
|
s{ |
|
(\bPR[:\#]?\s* |
|
(?: |
|
\#? |
|
\d+[,\s]\s* |
|
)* |
|
\#?) |
|
(\d+)\b |
|
}{ |
|
$1 . &link($2, sprintf($prcgi, $2)) . $3 |
|
}egix; |
|
} $_; |
|
} while ($_ ne $prev); |
|
|
|
$_ = htmlify_sub { |
|
s{ |
|
(\b$prcategories/(\d+)\b) |
|
}{ |
|
&link($1, sprintf($prcgi, $2)) . $3 |
|
}egox; |
|
} $_; |
} |
} |
|
|
return $string; |
# 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, $3 ne '' ? $3 : $4, $2)) . $5 |
|
}egx; |
|
} $_; |
|
} |
|
} |
|
|
|
$_; |
} |
} |
|
|
sub spacedHtmlText { |
sub spacedHtmlText($;$) { |
my($string, $pr) = @_; |
local $_ = $_[0]; |
|
my $ts = $_[1] || $tabstop; |
|
|
# Cut trailing spaces |
# Cut trailing spaces and tabs |
s/\s+$//; |
s/[ \t]+$//; |
|
|
# Expand tabs |
if (defined($ts)) { |
$string =~ s/\t+/' ' x (length($&) * $tabstop - length($`) % $tabstop)/e |
# Expand tabs |
if (defined($tabstop)); |
1 while s/\t+/' ' x (length($&) * $ts - length($`) % $ts)/e |
|
} |
|
|
# replace <tab> and <space> (\001 is to protect us from htmlify) |
# replace <tab> and <space> (\001 is to protect us from htmlify) |
# gzip can make excellent use of this repeating pattern :-) |
# gzip can make excellent use of this repeating pattern :-) |
$string =~ s/\001/\001%/g; #protect our & substitute |
|
if ($hr_breakable) { |
if ($hr_breakable) { |
# make every other space 'breakable' |
# make every other space 'breakable' |
$string =~ s/ / \001nbsp; \001nbsp; \001nbsp; \001nbsp;/g; # <tab> |
s/ / \001nbsp;/g; # 2 * <space> |
$string =~ s/ / \001nbsp;/g; # 2 * <space> |
|
# leave single space as it is |
# leave single space as it is |
|
} else { |
|
s/ /\001nbsp;/g; |
} |
} |
else { |
|
$string =~ s/ /\001nbsp;\001nbsp;\001nbsp;\001nbsp;\001nbsp;\001nbsp;\001nbsp;\001nbsp;/g; |
|
$string =~ s/ /\001nbsp;/g; |
|
} |
|
|
|
$string = htmlify($string); |
$_ = htmlify($_); |
|
|
# unescape |
# unescape |
$string =~ s/\001([^%])/&$1/g; |
y/\001/&/; |
$string =~ s/\001%/\001/g; |
|
|
|
return $string; |
return $_; |
} |
} |
|
|
sub link { |
sub link($$) { |
my($name, $where) = @_; |
my($name, $where) = @_; |
|
|
return "<A HREF=\"$where\">$name</A>\n"; |
sprintf '<A HREF="%s">%s</A>', htmlquote($where), $name; |
} |
} |
|
|
sub revcmp { |
sub revcmp($$) { |
my($rev1, $rev2) = @_; |
my($rev1, $rev2) = @_; |
|
|
|
# make no comparison for a tag or a branch |
|
return 0 if $rev1 =~ /[^\d.]/ || $rev2 =~ /[^\d.]/; |
|
|
my(@r1) = split(/\./, $rev1); |
my(@r1) = split(/\./, $rev1); |
my(@r2) = split(/\./, $rev2); |
my(@r2) = split(/\./, $rev2); |
my($a,$b); |
my($a,$b); |
|
|
return 0; |
return 0; |
} |
} |
|
|
sub fatal { |
sub fatal($$) { |
my($errcode, $errmsg) = @_; |
my($errcode, $errmsg) = @_; |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Apache->request->status((split(/ /, $errcode))[0]); |
Apache->request->status((split(/ /, $errcode))[0]); |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
sub redirect { |
sub redirect($) { |
my($url) = @_; |
my($url) = @_; |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Apache->request->status(301); |
Apache->request->status(301); |
|
|
print "Location: $url\r\n"; |
print "Location: $url\r\n"; |
} |
} |
html_header("Moved"); |
html_header("Moved"); |
print "This document is located <A HREF=$url>here</A>.\n"; |
print "This document is located ", &link('here', $url), "\n"; |
print &html_footer; |
print &html_footer; |
exit(1); |
exit(1); |
} |
} |
|
|
sub safeglob { |
sub safeglob($) { |
my ($filename) = @_; |
my ($filename) = @_; |
my ($dirname); |
my ($dirname); |
my (@results); |
my (@results); |
|
|
$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/" .$_); |
} |
} |
} |
} |
} |
} |
|
|
@results; |
@results; |
} |
} |
|
|
sub getMimeTypeFromSuffix { |
sub getMimeTypeFromSuffix($) { |
my ($fullname) = @_; |
my ($fullname) = @_; |
my ($mimetype, $suffix); |
my ($mimetype, $suffix); |
my $fh = do {local(*FH);}; |
my $fh = do {local(*FH);}; |
Line 984 sub getMimeTypeFromSuffix { |
|
Line 1209 sub getMimeTypeFromSuffix { |
|
($suffix = $fullname) =~ s/^.*\.([^.]*)$/$1/; |
($suffix = $fullname) =~ s/^.*\.([^.]*)$/$1/; |
$mimetype = $MTYPES{$suffix}; |
$mimetype = $MTYPES{$suffix}; |
$mimetype = $MTYPES{'*'} if (!$mimetype); |
$mimetype = $MTYPES{'*'} if (!$mimetype); |
|
|
if (!$mimetype && -f $mime_types) { |
if (!$mimetype && -f $mime_types) { |
# okey, this is something special - search the |
# okey, this is something special - search the |
# mime.types database |
# mime.types database |
Line 997 sub getMimeTypeFromSuffix { |
|
Line 1222 sub getMimeTypeFromSuffix { |
|
} |
} |
close ($fh); |
close ($fh); |
} |
} |
|
|
# okey, didn't find anything useful .. |
# okey, didn't find anything useful .. |
if (!($mimetype =~ /\S\/\S/)) { |
if (!($mimetype =~ /\S\/\S/)) { |
$mimetype = "text/plain"; |
$mimetype = "text/plain"; |
Line 1006 sub getMimeTypeFromSuffix { |
|
Line 1231 sub getMimeTypeFromSuffix { |
|
} |
} |
|
|
############################### |
############################### |
|
# read first lines like head(1) |
|
############################### |
|
sub head($;$) { |
|
my $fh = $_[0]; |
|
my $linecount = $_[1] || 10; |
|
|
|
my @buf; |
|
|
|
if ($linecount > 0) { |
|
my $i; |
|
for ($i = 0; !eof($fh) && $i < $linecount; $i++) { |
|
push @buf, scalar <$fh>; |
|
} |
|
} else { |
|
@buf = <$fh>; |
|
} |
|
|
|
@buf; |
|
} |
|
|
|
############################### |
|
# scan vim and Emacs directives |
|
############################### |
|
sub scan_directives(@) { |
|
my $ts = undef; |
|
|
|
for (@_) { |
|
$ts = $1 if /\b(?:ts|tabstop|tab-width)[:=]\s*([1-9]\d*)\b/; |
|
} |
|
|
|
('tabstop' => $ts); |
|
} |
|
|
|
############################### |
# show Annotation |
# show Annotation |
############################### |
############################### |
sub doAnnotate ($$) { |
sub doAnnotate($$) { |
my ($rev) = @_; |
my ($rev) = @_; |
my ($pid); |
my ($pid); |
my ($pathname, $filename); |
my ($pathname, $filename); |
Line 1017 sub doAnnotate ($$) { |
|
Line 1276 sub doAnnotate ($$) { |
|
|
|
# make sure the revisions a wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if (!($rev =~ /^[\d\.]+$/)) { |
if ($rev =~ /[^\w.]/) { |
&fatal("404 Not Found", |
&fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
"Malformed query \"$ENV{QUERY_STRING}\""); |
} |
} |
Line 1025 sub doAnnotate ($$) { |
|
Line 1284 sub doAnnotate ($$) { |
|
($pathname = $where) =~ s/(Attic\/)?[^\/]*$//; |
($pathname = $where) =~ s/(Attic\/)?[^\/]*$//; |
($filename = $where) =~ s/^.*\///; |
($filename = $where) =~ s/^.*\///; |
|
|
http_header(); |
|
|
|
navigateHeader ($scriptwhere,$pathname,$filename,$rev, "annotate"); |
|
print "<h3 align=center>Annotation of $pathname$filename, Revision $rev</h3>\n"; |
|
|
|
# this seems to be necessary |
# this seems to be necessary |
$| = 1; $| = 0; # Flush |
$| = 1; $| = 0; # Flush |
|
|
Line 1039 sub doAnnotate ($$) { |
|
Line 1293 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, "cvs server") || fatal ("500 Internal Error", |
$pid = open2($reader, $writer, "cvs -Rl server") || 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 |
# Argument foo/xx |
# Argument foo/xx |
Line 1051 sub doAnnotate ($$) { |
|
Line 1305 sub doAnnotate ($$) { |
|
# /home/kingdon/zwork/cvsroot |
# /home/kingdon/zwork/cvsroot |
# annotate |
# annotate |
# although as you can see there are a few more details. |
# although as you can see there are a few more details. |
|
|
print $writer "Root $cvsroot\n"; |
print $writer "Root $cvsroot\n"; |
print $writer "Valid-responses ok error Valid-requests Checked-in Updated Merged Removed M E\n"; |
print $writer "Valid-responses ok error Valid-requests Checked-in Updated Merged Removed M E\n"; |
# Don't worry about sending valid-requests, the server just needs to |
# Don't worry about sending valid-requests, the server just needs to |
Line 1071 sub doAnnotate ($$) { |
|
Line 1325 sub doAnnotate ($$) { |
|
if ($path eq "") { |
if ($path eq "") { |
# In our example, $_ is "dir". |
# In our example, $_ is "dir". |
$path = $_; |
$path = $_; |
} |
} |
else { |
else { |
print $writer "Directory $path\n"; |
print $writer "Directory $path\n"; |
print $writer "$cvsroot/$path\n"; |
print $writer "$cvsroot/$path\n"; |
Line 1084 sub doAnnotate ($$) { |
|
Line 1338 sub doAnnotate ($$) { |
|
# And the last "Directory" before "annotate" is the top level. |
# And the last "Directory" before "annotate" is the top level. |
print $writer "Directory .\n"; |
print $writer "Directory .\n"; |
print $writer "$cvsroot\n"; |
print $writer "$cvsroot\n"; |
|
|
print $writer "annotate\n"; |
print $writer "annotate\n"; |
# OK, we've sent our command to the server. Thing to do is to |
# OK, we've sent our command to the server. Thing to do is to |
# close the writer side and get all the responses. If "cvs server" |
# close the writer side and get all the responses. If "cvs server" |
# were nicer about buffering, then we could just leave it open, I think. |
# were nicer about buffering, then we could just leave it open, I think. |
close ($writer) || die "cannot close: $!"; |
close ($writer) || die "cannot close: $!"; |
|
|
|
http_header(); |
|
|
|
navigateHeader($scriptwhere,$pathname,$filename,$rev, "annotate"); |
|
print "<h3 align=center>Annotation of $pathname$filename, Revision $rev</h3>\n"; |
|
|
# Ready to get the responses from the server. |
# Ready to get the responses from the server. |
# For example: |
# For example: |
# E Annotations for foo/xx |
# E Annotations for foo/xx |
# E *************** |
# E *************** |
# M 1.3 (kingdon 06-Sep-97): hello |
# M 1.3 (kingdon 06-Sep-97): hello |
# ok |
# ok |
my ($lineNr) = 0; |
my ($lineNr) = 0; |
my ($oldLrev, $oldLusr) = ("", ""); |
my ($oldLrev, $oldLusr) = ("", ""); |
Line 1106 sub doAnnotate ($$) { |
|
Line 1365 sub doAnnotate ($$) { |
|
else { |
else { |
print "<pre>"; |
print "<pre>"; |
} |
} |
while (<$reader>) { |
|
|
# prefetch several lines |
|
my @buf = head($reader); |
|
|
|
my %d = scan_directives(@buf); |
|
|
|
while (@buf || !eof($reader)) { |
|
$_ = @buf ? shift @buf : <$reader>; |
|
|
my @words = split; |
my @words = split; |
# Adding one is for the (single) space which follows $words[0]. |
# Adding one is for the (single) space which follows $words[0]. |
my $rest = substr ($_, length ($words[0]) + 1); |
my $rest = substr ($_, length ($words[0]) + 1); |
Line 1115 sub doAnnotate ($$) { |
|
Line 1382 sub doAnnotate ($$) { |
|
} |
} |
elsif ($words[0] eq "M") { |
elsif ($words[0] eq "M") { |
$lineNr++; |
$lineNr++; |
my $lrev = substr ($_, 2, 13); |
(my $lrev = substr($_, 2, 13)) =~ y/ //d; |
my $lusr = substr ($_, 16, 9); |
(my $lusr = substr($_, 16, 9)) =~ y/ //d; |
my $line = substr ($_, 36); |
my $line = substr($_, 36); |
|
my $isCurrentRev = ($rev eq $lrev); |
# we should parse the date here .. |
# we should parse the date here .. |
if ($lrev eq $oldLrev) { |
if ($lrev eq $oldLrev) { |
$revprint = " "; |
$revprint = sprintf('%-8s', ''); |
} |
} |
else { |
else { |
$revprint = $lrev; $oldLusr = ""; |
$revprint = sprintf('%-8s', $lrev); |
|
$revprint =~ s`\S+`&link($&, "$scriptwhere$query#rev$&")`e; # ` |
|
$oldLusr = ''; |
} |
} |
if ($lusr eq $oldLusr) { |
if ($lusr eq $oldLusr) { |
$usrprint = " "; |
$usrprint = ''; |
} |
} |
else { |
else { |
$usrprint = $lusr; |
$usrprint = $lusr; |
} |
} |
$oldLrev = $lrev; |
$oldLrev = $lrev; |
$oldLusr = $lusr; |
$oldLusr = $lusr; |
# is there a less timeconsuming way to strip spaces ? |
|
($lrev = $lrev) =~ s/\s+//g; |
# Set bold for text-based browsers only - graphical |
my $isCurrentRev = ($rev eq $lrev); |
# browsers show bold fonts a bit wider than regular fonts, |
|
# so it looks irregular. |
print "<b>" if ($isCurrentRev); |
print "<b>" if ($isCurrentRev && $is_textbased); |
printf ("%8s%s%8s %4d:", $revprint, ($isCurrentRev ? "|" : " "), $usrprint, $lineNr); |
|
print spacedHtmlText($line); |
printf "%s%s %-8s %4d:", |
print "</b>" if ($isCurrentRev); |
$revprint, |
|
$isCurrentRev ? '!' : ' ', |
|
$usrprint, |
|
$lineNr; |
|
print spacedHtmlText($line, $d{'tabstop'}); |
|
|
|
print "</b>" if ($isCurrentRev && $is_textbased); |
} |
} |
elsif ($words[0] eq "ok") { |
elsif ($words[0] eq "ok") { |
# We could complain about any text received after this, like the |
# We could complain about any text received after this, like the |
# 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 1163 sub doAnnotate ($$) { |
|
Line 1439 sub doAnnotate ($$) { |
|
############################### |
############################### |
# make Checkout |
# make Checkout |
############################### |
############################### |
sub doCheckout { |
sub doCheckout($$) { |
my ($fullname, $rev) = @_; |
my ($fullname, $rev) = @_; |
my ($mimetype,$revopt); |
my ($mimetype,$revopt); |
my $fh = do {local(*FH);}; |
my $fh = do {local(*FH);}; |
|
|
|
if ($rev eq 'HEAD' || $rev eq '.') { |
|
$rev = undef; |
|
} |
|
|
# make sure the revisions a wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if (defined($rev) && !($rev =~ /^[\d\.]+$/)) { |
if (defined($rev) && $rev =~ /[^\w.]/) { |
&fatal("404 Not Found", |
&fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
"Malformed query \"$ENV{QUERY_STRING}\""); |
} |
} |
Line 1197 sub doCheckout { |
|
Line 1477 sub doCheckout { |
|
$moddate=$date{$symrev{HEAD}}; |
$moddate=$date{$symrev{HEAD}}; |
} |
} |
} |
} |
|
|
### just for the record: |
### just for the record: |
### 'cvs co' seems to have a bug regarding single checkout of |
### 'cvs co' seems to have a bug regarding single checkout of |
### directories/files having spaces in it; |
### directories/files having spaces in it; |
Line 1206 sub doCheckout { |
|
Line 1486 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("cvs", "-d", $cvsroot, "co", "-p", $revopt, $where); |
exec("cvs", "-Rld", $cvsroot, "co", "-p", $revopt, $where); |
} |
} |
#=================================================================== |
#=================================================================== |
#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 1246 sub doCheckout { |
|
Line 1526 sub doCheckout { |
|
close($fh); |
close($fh); |
} |
} |
|
|
sub cvswebMarkup { |
sub cvswebMarkup($$$) { |
my ($filehandle,$fullname,$revision) = @_; |
my ($filehandle,$fullname,$revision) = @_; |
my ($pathname, $filename); |
my ($pathname, $filename); |
|
|
Line 1256 sub cvswebMarkup { |
|
Line 1536 sub cvswebMarkup { |
|
|
|
http_header(); |
http_header(); |
|
|
navigateHeader ($scriptwhere, $pathname, $filename, $revision, "view"); |
navigateHeader($scriptwhere, $pathname, $filename, $revision, "view"); |
print "<HR noshade>"; |
print "<HR noshade>"; |
print "<table width=\"100%\"><tr><td bgcolor=\"$markupLogColor\">"; |
print "<table width=\"100%\"><tr><td bgcolor=\"$markupLogColor\">"; |
print "File: ", &clickablePath($where, 1); |
print "File: ", &clickablePath($where, 1); |
print " "; |
print " ("; |
&download_link(urlencode($fileurl), $revision, "(download)"); |
&download_link($fileurl, $revision, "download"); |
|
print ")"; |
if (!$defaultTextPlain) { |
if (!$defaultTextPlain) { |
print " "; |
print " ("; |
&download_link(urlencode($fileurl), $revision, "(as text)", |
&download_link($fileurl, $revision, "as text", |
"text/plain"); |
"text/plain"); |
|
print ")"; |
} |
} |
print "<BR>\n"; |
print "<BR>\n"; |
if ($show_log_in_markup) { |
if ($show_log_in_markup) { |
Line 1278 sub cvswebMarkup { |
|
Line 1560 sub cvswebMarkup { |
|
$input{only_with_tag}; |
$input{only_with_tag}; |
} |
} |
print "</td></tr></table>"; |
print "</td></tr></table>"; |
my @content = <$filehandle>; |
|
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/) { |
print "<IMG SRC=\"$url$barequery\"><BR>"; |
printf '<IMG SRC="%s"><BR>', htmlquote("$url$barequery"); |
} |
} |
|
elsif ($mimetype =~ m%^application/pdf%) { |
|
printf '<EMBED SRC="%s" WIDTH="100%"><BR>', htmlquote("$url$barequery"); |
|
} |
else { |
else { |
print "<PRE>"; |
print "<PRE>"; |
foreach (@content) { |
|
print spacedHtmlText($_); |
# prefetch several lines |
|
my @buf = head($filehandle); |
|
|
|
my %d = scan_directives(@buf); |
|
|
|
while (@buf || !eof($filehandle)) { |
|
$_ = @buf ? shift @buf : <$filehandle>; |
|
|
|
print spacedHtmlText($_, $d{'tabstop'}); |
} |
} |
print "</PRE>"; |
print "</PRE>"; |
} |
} |
Line 1296 sub cvswebMarkup { |
|
Line 1588 sub cvswebMarkup { |
|
sub viewable($) { |
sub viewable($) { |
my ($mimetype) = @_; |
my ($mimetype) = @_; |
|
|
$mimetype =~ m%^text/% || |
$mimetype =~ m%^((text|image)/|application/pdf)% ; |
$mimetype =~ m%^image/% || |
|
0; |
|
} |
} |
|
|
############################### |
############################### |
# Show Colored Diff |
# Show Colored Diff |
############################### |
############################### |
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, @difftype, $diffname, $f1, $f2); |
my ($rev1, $rev2, $sym1, $sym2, $f1, $f2); |
|
|
if ($r1 =~ /([^:]+)(:(.+))?/) { |
if ($r1 =~ /([^:]+)(:(.+))?/) { |
$rev1 = $1; |
$rev1 = $1; |
|
|
$rev2 = $tr2; |
$rev2 = $tr2; |
$sym2 = ""; |
$sym2 = ""; |
} |
} |
|
|
# make sure the revisions a wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if (!($rev1 =~ /^[\d\.]+$/) || !($rev2 =~ /^[\d\.]+$/)) { |
if ($rev1 =~ /[^\w.]/ || $rev2 =~ /[^\w.]/) { |
&fatal("404 Not Found", |
&fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
"Malformed query \"$ENV{QUERY_STRING}\""); |
} |
} |
|
|
($rev1, $sym1) = ($rev2, $sym2); |
($rev1, $sym1) = ($rev2, $sym2); |
($rev2, $sym2) = ($tmp1, $tmp2); |
($rev2, $sym2) = ($tmp1, $tmp2); |
} |
} |
my $human_readable = 0; |
my $difftype = $DIFFTYPES{$f}; |
if ($f eq 'c') { |
|
@difftype = qw{-c}; |
if (!$difftype) { |
$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'; |
push @difftype, '-p' if $f ne 's'; |
|
|
my($re1, $re2); |
my($re1, $re2); |
|
|
|
|
if ($human_readable) { |
if ($human_readable) { |
http_header(); |
http_header(); |
&human_readable_diff($fh, $rev2); |
&human_readable_diff($fh, $rev2); |
|
gzipclose(); |
exit; |
exit; |
} |
} |
else { |
else { |
|
|
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 $_; |
|
|
############################### |
############################### |
# Show Logs .. |
# Show Logs .. |
############################### |
############################### |
sub getDirLogs { |
sub getDirLogs($$@) { |
my ($cvsroot,$dirname,@otherFiles) = @_; |
my ($cvsroot,$dirname,@otherFiles) = @_; |
my ($state,$otherFiles,$tag, $file, $date, $branchpoint, $branch, $log); |
my ($state,$otherFiles,$tag, $file, $date, $branchpoint, $branch, $log); |
my ($rev, $revision, $revwanted, $filename, $head, $author); |
my ($rev, $revision, $revwanted, $filename, $head, $author); |
Line 1466 sub getDirLogs { |
|
Line 1740 sub getDirLogs { |
|
} |
} |
|
|
# just execute rlog if there are any files |
# just execute rlog if there are any files |
if ($#files < 0) { |
if ($#files < 0) { |
return; |
return; |
} |
} |
|
|
|
|
} |
} |
if ($state eq "head" && /^symbolic names/) { |
if ($state eq "head" && /^symbolic names/) { |
$state = "tags"; |
$state = "tags"; |
($branch = $head) =~ s/\.\d+$// if (!defined($branch)); |
($branch = $head) =~ s/\.\d+$// if (!defined($branch)); |
$branch =~ s/(\.?)(\d+)$/${1}0.$2/; |
$branch =~ s/(\.?)(\d+)$/${1}0.$2/; |
$symrev{MAIN} = $branch; |
$symrev{MAIN} = $branch; |
$symrev{HEAD} = $branch; |
$symrev{HEAD} = $branch; |
|
|
$state = "head"; |
$state = "head"; |
goto again; |
goto again; |
} |
} |
if ($state eq "head" && /^----------------------------$/) { |
if ($state eq "head" && /$LOG_REVSEPARATOR/o) { |
$state = "log"; |
$state = "log"; |
$rev = undef; |
$rev = undef; |
$date = undef; |
$date = undef; |
|
|
next; |
next; |
} |
} |
if ($state eq "log") { |
if ($state eq "log") { |
if (/^----------------------------$/ |
if (/$LOG_REVSEPARATOR/o || /$LOG_FILESEPARATOR/o) { |
|| /^=============================/) { |
|
# End of a log entry. |
# End of a log entry. |
my $revbranch; |
my $revbranch; |
($revbranch = $rev) =~ 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 (!defined($revwanted) && defined($branch) |
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" |
|
|
next; |
next; |
} |
} |
else { |
else { |
$log = $log . $_; |
$log .= $_; |
} |
} |
} |
} |
if (/^===============/) { |
if (/$LOG_FILESEPARATOR/o) { |
$state = "start"; |
$state = "start"; |
next; |
next; |
} |
} |
} |
} |
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>\$ENV{PATH}</b> in your configuration file correctly ?"); |
"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); |
} |
} |
|
|
sub readLog { |
sub readLog($;$) { |
my($fullname,$revision) = @_; |
my($fullname,$revision) = @_; |
my ($symnames, $head, $rev, $br, $brp, $branch, $branchrev); |
my ($symnames, $head, $rev, $br, $brp, $branch, $branchrev); |
my $fh = do {local(*FH);}; |
my $fh = do {local(*FH);}; |
|
|
# log info |
# log info |
# ---------------------------- |
# ---------------------------- |
logentry: |
logentry: |
while (!/^=========/) { |
while (!/$LOG_FILESEPARATOR/o) { |
$_ = <$fh>; |
$_ = <$fh>; |
last logentry if (!defined($_)); # EOF |
last logentry if (!defined($_)); # EOF |
print "R:", $_ if ($verbose); |
print "R:", $_ if ($verbose); |
|
|
$rev = $1; |
$rev = $1; |
unshift(@allrevisions,$rev); |
unshift(@allrevisions,$rev); |
} |
} |
elsif (/^========/ || /^----------------------------$/) { |
elsif (/$LOG_FILESEPARATOR/o || /$LOG_REVSEPARATOR/o) { |
next logentry; |
next logentry; |
} |
} |
else { |
else { |
|
|
while (<$fh>) { |
while (<$fh>) { |
print "L:", $_ if ($verbose); |
print "L:", $_ if ($verbose); |
next line if (/^branches:\s/); |
next line if (/^branches:\s/); |
last line if (/^----------------------------$/ || /^=========/); |
last line if (/$LOG_FILESEPARATOR/o || /$LOG_REVSEPARATOR/o); |
$log{$rev} .= $_; |
$log{$rev} .= $_; |
} |
} |
print "E:", $_ if ($verbose); |
print "E:", $_ if ($verbose); |
|
|
|
|
} |
} |
|
|
|
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 1871 sub printLog($;$) { |
|
Line 2158 sub printLog($;$) { |
|
} |
} |
print "\n Revision "; |
print "\n Revision "; |
&download_link($fileurl, $_, $_, |
&download_link($fileurl, $_, $_, |
$defaultViewable ? "text/x-cvsweb-markup" : undef); |
$defaultViewable ? "text/x-cvsweb-markup" : undef); |
if ($defaultViewable) { |
if ($defaultViewable) { |
print " / "; |
print " / ("; |
&download_link($fileurl, $_, "(download)", $mimetype); |
&download_link($fileurl, $_, "download", $mimetype); |
|
print ")"; |
} |
} |
if (not $defaultTextPlain) { |
if (not $defaultTextPlain) { |
print " / "; |
print " / ("; |
&download_link($fileurl, $_, "(as text)", |
&download_link($fileurl, $_, "as text", "text/plain"); |
"text/plain"); |
print ")"; |
} |
} |
if (!$defaultViewable) { |
if (!$defaultViewable) { |
print " / "; |
print " / ("; |
&download_link($fileurl, $_, "(view)", "text/x-cvsweb-markup"); |
&download_link($fileurl, $_, "view", "text/x-cvsweb-markup"); |
|
print ")"; |
} |
} |
if ($allow_annotate) { |
if ($allow_annotate) { |
print " - <a href=\"" . $scriptname . "/" . urlencode($where) . "?annotate=$_$barequery\">"; |
print " - "; |
print "annotate</a>"; |
print &link('annotate', |
|
sprintf('%s/%s?annotate=%s%s', |
|
$scriptname, |
|
urlencode($where), |
|
$_, |
|
$barequery)); |
} |
} |
# Plus a select link if enabled, and this version isn't selected |
# Plus a select link if enabled, and this version isn't selected |
if ($allow_version_select) { |
if ($allow_version_select) { |
if ((!defined($input{"r1"}) || $input{"r1"} ne $_)) { |
if ((!defined($input{"r1"}) || $input{"r1"} ne $_)) { |
print " - <A HREF=\"${scriptwhere}?r1=$_$barequery" . |
print " - "; |
"\">[select for diffs]</A>\n"; |
print &link('[select for diffs]', |
|
sprintf('%s?r1=%s%s', |
|
$scriptwhere, |
|
$_, |
|
$barequery)); |
} |
} |
else { |
else { |
print " - <b>[selected]</b>"; |
print " - <b>[selected]</b>"; |
Line 1908 sub printLog($;$) { |
|
Line 2206 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 1948 sub printLog($;$) { |
|
Line 2246 sub printLog($;$) { |
|
# Offer diff to previous revision |
# Offer diff to previous revision |
if ($prev) { |
if ($prev) { |
$diffrev{$prev} = 1; |
$diffrev{$prev} = 1; |
print " to previous <A HREF=\"${scriptwhere}.diff?r1=$prev"; |
|
print "&r2=$_" . $barequery . "\">$prev</A>\n"; |
my $url = sprintf('%s.diff?r1=%s&r2=%s%s', |
if (!$hr_default) { # offer a human readable version if not default |
$scriptwhere, |
print "(<A HREF=\"${scriptwhere}.diff?r1=$prev"; |
$prev, |
print "&r2=$_" . $barequery . "&f=h\">colored</A>)\n"; |
$_, |
} |
$barequery); |
|
|
|
print " to previous "; |
|
printDiffLinks($prev, $url); |
} |
} |
# |
# |
# 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, |
# offer a diff with the branch point. |
# offer a diff with the branch point. |
if ($revsym{$brp} && !/^1\.1\.1\.\d+$/ && !defined($diffrev{$brp})) { |
if ($revsym{$brp} && !/^1\.1\.1\.\d+$/ && !defined($diffrev{$brp})) { |
print " to branchpoint <A HREF=\"${scriptwhere}.diff?r1=$brp"; |
my $url = sprintf('%s.diff?r1=%s&r2=%s%s', |
print "&r2=$_" . $barequery . "\">$brp</A>\n"; |
$scriptwhere, |
if (!$hr_default) { # offer a human readable version if not default |
$brp, |
print "(<A HREF=\"${scriptwhere}.diff?r1=$brp"; |
$_, |
print "&r2=$_" . $barequery . "&f=h\">colored</A>)\n"; |
$barequery); |
} |
|
|
print " to branchpoint "; |
|
printDiffLinks($brp, $url); |
} |
} |
# |
# |
# 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 1989 sub printLog($;$) { |
|
Line 2292 sub printLog($;$) { |
|
} |
} |
if (!defined($diffrev{$nextmain})) { |
if (!defined($diffrev{$nextmain})) { |
$diffrev{$nextmain} = 1; |
$diffrev{$nextmain} = 1; |
print " next main <A HREF=\"${scriptwhere}.diff?r1=$nextmain"; |
|
print "&r2=$_" . $barequery . |
my $url = sprintf('%s.diff?r1=%s&r2=%s%s', |
"\">$nextmain</A>\n"; |
$scriptwhere, |
if (!$hr_default) { # offer a human readable version if not default |
$nextmain, |
print "(<A HREF=\"${scriptwhere}.diff?r1=$nextmain"; |
$_, |
print "&r2=$_" . $barequery . |
$barequery); |
"&f=h\">colored</A>)\n"; |
|
} |
print " next main "; |
|
printDiffLinks($nextmain, $url); |
} |
} |
} |
} |
# Plus if user has selected only r1, then present a link |
# Plus if user has selected only r1, then present a link |
# to make a diff to that revision |
# to make a diff to that revision |
if (defined($input{"r1"}) && !defined($diffrev{$input{"r1"}})) { |
if (defined($input{"r1"}) && !defined($diffrev{$input{"r1"}})) { |
$diffrev{$input{"r1"}} = 1; |
$diffrev{$input{"r1"}} = 1; |
print " to selected <A HREF=\"${scriptwhere}.diff?" |
|
. "r1=$input{'r1'}&r2=$_" . $barequery |
|
. "\">$input{'r1'}</A>\n"; |
|
if (!$hr_default) { # offer a human readable version if not default |
|
print "(<A HREF=\"${scriptwhere}.diff?r1=$input{'r1'}"; |
|
print "&r2=$_" . $barequery . |
|
"&f=h\">colored</A>)\n"; |
|
|
|
} |
my $url = sprintf('%s.diff?r1=%s&r2=%s%s', |
|
$scriptwhere, |
|
$input{'r1'}, |
|
$_, |
|
$barequery); |
|
|
|
print " to selected "; |
|
printDiffLinks($input{'r1'}, $url); |
} |
} |
} |
} |
print "<PRE>\n"; |
print "<PRE>\n"; |
Line 2019 sub printLog($;$) { |
|
Line 2323 sub printLog($;$) { |
|
print "</PRE>\n"; |
print "</PRE>\n"; |
} |
} |
|
|
sub doLog { |
sub doLog($) { |
my($fullname) = @_; |
my($fullname) = @_; |
my ($diffrev, $upwhere, $filename, $backurl); |
my ($diffrev, $upwhere, $filename, $backurl); |
|
|
readLog($fullname); |
readLog($fullname); |
|
|
html_header("CVS log for $where"); |
html_header("CVS log for $where"); |
|
|
($filename = $where) =~ s|^.*/||; |
($filename = $where) =~ s|^.*/||; |
$backurl = $scriptname . "/" . urlencode($upwhere) . $query; |
$backurl = $scriptname . "/" . urlencode($upwhere) . $query; |
print &link($backicon, "$backurl#$filename"), |
print &link($backicon, "$backurl#$filename"), |
" <b>Up to ", &clickablePath($upwhere, 1), "</b><p>\n"; |
" <b>Up to ", &clickablePath($upwhere, 1), "</b><p>\n"; |
print <<EOF; |
print &link('Request diff between arbitrary revisions', '#diff'); |
<A HREF="#diff">Request diff between arbitrary revisions</A> |
print '<HR NOSHADE>'; |
<HR NOSHADE> |
|
EOF |
|
if ($curbranch) { |
if ($curbranch) { |
print "Default branch: ", ($revsym{$curbranch} || $curbranch); |
print "Default branch: ", ($revsym{$curbranch} || $curbranch); |
} |
} |
|
|
print "</A><P>\n"; |
print "</A><P>\n"; |
print "<FORM METHOD=\"GET\" ACTION=\"${scriptwhere}.diff\" NAME=\"diff_select\">\n"; |
print "<FORM METHOD=\"GET\" ACTION=\"${scriptwhere}.diff\" NAME=\"diff_select\">\n"; |
foreach (@stickyvars) { |
foreach (@stickyvars) { |
print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n" |
printf('<INPUT TYPE=HIDDEN NAME="%s" VALUE="%s">', $_, $input{$_}) |
if (defined($input{$_}) |
if (defined($input{$_}) |
&& ($input{$_} ne $DEFAULTVALUE{$_} && $input{$_} ne "")); |
&& ((!defined($DEFAULTVALUE{$_}) |
|
|| $input{$_} ne $DEFAULTVALUE{$_}) |
|
&& $input{$_} ne "")); |
} |
} |
print "Diffs between \n"; |
print "<TABLE><TR>\n"; |
|
print "<TD align=right>Diffs between \n"; |
print "<SELECT NAME=\"r1\">\n"; |
print "<SELECT NAME=\"r1\">\n"; |
print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n"; |
print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n"; |
print $sel; |
print $sel; |
print "</SELECT>\n"; |
print "</SELECT>\n"; |
$diffrev = $revdisplayorder[$#revdisplayorder]; |
$diffrev = $revdisplayorder[$#revdisplayorder]; |
$diffrev = $input{"r1"} if (defined($input{"r1"})); |
$diffrev = $input{"r1"} if (defined($input{"r1"})); |
print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr1\" VALUE=\"$diffrev\" onChange='document.diff_select.r1.selectedIndex=0'>\n"; |
print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr1\" VALUE=\"$diffrev\" onChange='document.diff_select.r1.selectedIndex=0'></TD>"; |
print " and \n"; |
print "<TD><BR></TD></TR>\n"; |
|
print "<TR><TD align=right>and \n"; |
print "<SELECT NAME=\"r2\">\n"; |
print "<SELECT NAME=\"r2\">\n"; |
print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n"; |
print "<OPTION VALUE=\"text\" SELECTED>Use Text Field\n"; |
print $sel; |
print $sel; |
print "</SELECT>\n"; |
print "</SELECT>\n"; |
$diffrev = $revdisplayorder[0]; |
$diffrev = $revdisplayorder[0]; |
$diffrev = $input{"r2"} if (defined($input{"r2"})); |
$diffrev = $input{"r2"} if (defined($input{"r2"})); |
print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr2\" VALUE=\"$diffrev\" onChange='docuement.diff_select.r2.selectedIndex=0'>\n"; |
print "<INPUT TYPE=\"TEXT\" SIZE=\"$inputTextSize\" NAME=\"tr2\" VALUE=\"$diffrev\" onChange='document.diff_select.r2.selectedIndex=0'></TD>"; |
print "<BR>Type of Diff should be a "; |
print "<TD><INPUT TYPE=SUBMIT VALUE=\" Get Diffs \"></TD>\n"; |
printDiffSelect(); |
|
print "<INPUT TYPE=SUBMIT VALUE=\" Get Diffs \">\n"; |
|
print "</FORM>\n"; |
print "</FORM>\n"; |
|
print "</TR></TABLE>\n"; |
print "<HR noshade>\n"; |
print "<HR noshade>\n"; |
|
print "<TABLE>"; |
|
print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n"; |
|
print "<TR><TD align=right>Preferred Diff type:</TD>"; |
|
print "<TD>"; |
|
printDiffSelect($use_java_script); |
|
print "</TD><TD></TD></TR>\n"; |
if (@branchnames) { |
if (@branchnames) { |
|
print "<TR><TD align=right>View only Branch:</TD>"; |
|
print "<TD>"; |
print "<A name=branch></A>\n"; |
print "<A name=branch></A>\n"; |
print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n"; |
|
foreach (@stickyvars) { |
|
next if ($_ eq "only_with_tag"); |
|
next if ($_ eq "logsort"); |
|
print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n" |
|
if (defined($input{$_}) && $input{$_} ne $DEFAULTVALUE{$_} |
|
&& $input{$_} ne ""); |
|
} |
|
print "View only Branch: \n"; |
|
print "<SELECT NAME=\"only_with_tag\""; |
print "<SELECT NAME=\"only_with_tag\""; |
print " onchange=\"submit()\"" if ($use_java_script); |
print " onchange=\"submit()\"" if ($use_java_script); |
print ">\n"; |
print ">\n"; |
|
|
&& $input{"only_with_tag"} eq $_); |
&& $input{"only_with_tag"} eq $_); |
print ">${_}\n"; |
print ">${_}\n"; |
} |
} |
print "</SELECT>\n"; |
print "</SELECT></TD><TD></TD></TR>\n"; |
print "<INPUT TYPE=SUBMIT VALUE=\" View Branch \">\n"; |
|
print "</FORM>\n"; |
|
} |
} |
print "<A name=logsort></A>\n"; |
|
print "<FORM METHOD=\"GET\" ACTION=\"$scriptwhere\">\n"; |
|
foreach (@stickyvars) { |
foreach (@stickyvars) { |
|
next if ($_ eq "f"); |
next if ($_ eq "only_with_tag"); |
next if ($_ eq "only_with_tag"); |
next if ($_ eq "logsort"); |
next if ($_ eq "logsort"); |
print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n" |
print "<INPUT TYPE=HIDDEN NAME=\"$_\" VALUE=\"$input{$_}\">\n" |
if (defined($input{$_}) && $input{$_} ne $DEFAULTVALUE{$_} |
if (defined($input{$_}) |
|
&& (!defined($DEFAULTVALUE{$_}) |
|
|| $input{$_} ne $DEFAULTVALUE{$_}) |
&& $input{$_} ne ""); |
&& $input{$_} ne ""); |
} |
} |
print "Sort log by: \n"; |
print "<TR><TD align=right>"; |
print "<SELECT NAME=\"logsort\""; |
print "<A name=logsort></A>\n"; |
print " onchange=\"submit()\"" if ($use_java_script); |
print "Sort log by:</TD>"; |
print ">\n"; |
print "<TD>"; |
print "<OPTION VALUE=cvs",$logsort eq "cvs" ? " SELECTED" : "", ">Not sorted"; |
printLogSortSelect($use_java_script); |
print "<OPTION VALUE=date",$logsort eq "date" ? " SELECTED" : "", ">Commit date"; |
print "</TD>"; |
print "<OPTION VALUE=rev",$logsort eq "rev" ? " SELECTED" : "", ">Revision"; |
print "<TD><INPUT TYPE=SUBMIT VALUE=\" Set \"></TD>"; |
print "</SELECT>\n"; |
|
print "<INPUT TYPE=SUBMIT VALUE=\" Sort \">\n"; |
|
print "</FORM>\n"; |
print "</FORM>\n"; |
|
print "</TR></TABLE>"; |
print &html_footer; |
print &html_footer; |
print "</BODY></HTML>\n"; |
print "</BODY></HTML>\n"; |
} |
} |
|
|
sub flush_diff_rows ($$$$) |
sub flush_diff_rows($$$$) { |
{ |
|
my $j; |
my $j; |
my ($leftColRef,$rightColRef,$leftRow,$rightRow) = @_; |
my ($leftColRef,$rightColRef,$leftRow,$rightRow) = @_; |
if ($state eq "PreChangeRemove") { # we just got remove-lines before |
if ($state eq "PreChangeRemove") { # we just got remove-lines before |
Line 2174 sub flush_diff_rows ($$$$) |
|
Line 2476 sub flush_diff_rows ($$$$) |
|
# human_readable_diff(String revision_to_return_to); |
# human_readable_diff(String revision_to_return_to); |
## |
## |
sub human_readable_diff($){ |
sub human_readable_diff($){ |
my ($i,$difftxt, $where_nd, $filename, $pathname, $scriptwhere_nd); |
my ($difftxt, $where_nd, $filename, $pathname, $scriptwhere_nd); |
my ($fh, $rev) = @_; |
my ($fh, $rev) = @_; |
my ($date1, $date2, $r1d, $r2d, $r1r, $r2r, $rev1, $rev2, $sym1, $sym2); |
my ($date1, $date2, $r1d, $r2d, $r1r, $r2r, $rev1, $rev2, $sym1, $sym2); |
my (@rightCol, @leftCol); |
my (@rightCol, @leftCol); |
Line 2184 sub human_readable_diff($){ |
|
Line 2486 sub human_readable_diff($){ |
|
($pathname = $where_nd) =~ s/(Attic\/)?[^\/]*$//; |
($pathname = $where_nd) =~ s/(Attic\/)?[^\/]*$//; |
($scriptwhere_nd = $scriptwhere) =~ s/.diff$//; |
($scriptwhere_nd = $scriptwhere) =~ s/.diff$//; |
|
|
navigateHeader ($scriptwhere_nd, $pathname, $filename, $rev, "diff"); |
navigateHeader($scriptwhere_nd, $pathname, $filename, $rev, "diff"); |
|
|
# Read header to pick up read revision and date, if possible |
# Read header to pick up read revision and date, if possible |
while (<$fh>) { |
while (<$fh>) { |
Line 2200 sub human_readable_diff($){ |
|
Line 2502 sub human_readable_diff($){ |
|
$rev2 = $r2r; |
$rev2 = $r2r; |
$date2 = $r2d; |
$date2 = $r2d; |
} |
} |
|
|
print "<h3 align=center>Diff for /$where_nd between version $rev1 and $rev2</h3>\n"; |
|
|
|
print "<table border=0 cellspacing=0 cellpadding=0 width=\"100%\">\n"; |
print "<h3 align=center>Diff for /$where_nd between version $rev1 and $rev2</h3>\n", |
print "<tr bgcolor=\"#ffffff\">\n"; |
"<table border=0 cellspacing=0 cellpadding=0 width=\"100%\">\n", |
print "<th width=\"50%\" valign=TOP>"; |
"<tr bgcolor=\"#ffffff\">\n", |
print "version $rev1"; |
"<th width=\"50%\" valign=TOP>", |
|
"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", |
print "<th width=\"50%\" valign=TOP>"; |
"<th width=\"50%\" valign=TOP>", |
print "version $rev2"; |
"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"; |
Line 2228 sub human_readable_diff($){ |
|
Line 2529 sub human_readable_diff($){ |
|
# cascading style sheets because we've to set the |
# cascading style sheets because we've to set the |
# font and color for each row. anyone ...? |
# font and color for each row. anyone ...? |
#### |
#### |
while (<$fh>) { |
|
$difftxt = $_; |
# prefetch several lines |
|
my @buf = head($fh); |
|
|
|
my %d = scan_directives(@buf); |
|
|
|
while (@buf || !eof($fh)) { |
|
$difftxt = @buf ? shift @buf : <$fh>; |
|
|
if ($difftxt =~ /^@@/) { |
if ($difftxt =~ /^@@/) { |
($oldline,$newline,$funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/; |
($oldline,$newline,$funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/; |
print "<tr bgcolor=\"$diffcolorHeading\"><td width=\"50%\">"; |
print "<tr bgcolor=\"$diffcolorHeading\"><td width=\"50%\">"; |
Line 2246 sub human_readable_diff($){ |
|
Line 2553 sub human_readable_diff($){ |
|
} |
} |
else { |
else { |
($diffcode,$rest) = $difftxt =~ /^([-+ ])(.*)/; |
($diffcode,$rest) = $difftxt =~ /^([-+ ])(.*)/; |
$_ = spacedHtmlText ($rest); |
$_ = spacedHtmlText($rest, $d{'tabstop'}); |
|
|
# Add fontface, size |
# Add fontface, size |
$_ = "$fs $_$fe"; |
$_ = "$fs $_$fe"; |
|
|
######### |
######### |
# little state machine to parse unified-diff output (Hen, zeller@think.de) |
# little state machine to parse unified-diff output (Hen, zeller@think.de) |
# in order to get some nice 'ediff'-mode output |
# in order to get some nice 'ediff'-mode output |
Line 2268 sub human_readable_diff($){ |
|
Line 2575 sub human_readable_diff($){ |
|
$state = "PreChange"; |
$state = "PreChange"; |
$rightCol[$rightRow++] = $_; |
$rightCol[$rightRow++] = $_; |
} |
} |
} |
} |
elsif ($diffcode eq '-') { |
elsif ($diffcode eq '-') { |
$state = "PreChangeRemove"; |
$state = "PreChangeRemove"; |
$leftCol[$leftRow++] = $_; |
$leftCol[$leftRow++] = $_; |
Line 2324 sub human_readable_diff($){ |
|
Line 2631 sub human_readable_diff($){ |
|
print "</tr></table>"; |
print "</tr></table>"; |
} |
} |
|
|
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 "<\!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"; |
print "<HTML>\n<HEAD>\n"; |
print "<HTML>\n<HEAD>\n"; |
print '<!-- CVSweb $zRevision: 1.93 $ $Revision$ -->'; |
print '<!-- CVSweb $zRevision: 1.103 $ $Revision$ -->'; |
print "\n<TITLE>$path$filename - $title - $rev</TITLE></HEAD>\n"; |
print "\n<TITLE>$path$filename - $title - $rev</TITLE></HEAD>\n"; |
print "<BODY BGCOLOR=\"$backcolor\">\n"; |
print "$body_tag_for_src\n"; |
print "<table width=\"100%\" border=0 cellspacing=0 cellpadding=1 bgcolor=\"$navigationHeaderColor\">"; |
print "<table width=\"100%\" border=0 cellspacing=0 cellpadding=1 bgcolor=\"$navigationHeaderColor\">"; |
print "<tr valign=bottom><td>"; |
print "<tr valign=bottom><td>"; |
print "<a href=\"$swhere$query#rev$rev\">$backicon"; |
print &link($backicon, "$swhere$query#rev$rev"); |
print "</a> <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>"; |
print "</tr></table>"; |
print "</tr></table>"; |
} |
} |
|
|
sub plural_write ($$) |
sub plural_write($$) { |
{ |
|
my ($num,$text) = @_; |
my ($num,$text) = @_; |
if ($num != 1) { |
if ($num != 1) { |
$text = $text . "s"; |
$text .= "s"; |
} |
} |
if ($num > 0) { |
if ($num > 0) { |
return $num . " " . $text; |
return join(' ', $num, $text); |
} |
} |
else { |
else { |
return ""; |
return ""; |
Line 2362 sub plural_write ($$) |
|
Line 2668 sub plural_write ($$) |
|
# '..time ago' |
# '..time ago' |
# H. Zeller <zeller@think.de> |
# H. Zeller <zeller@think.de> |
## |
## |
sub readableTime ($$) |
sub readableTime($$) { |
{ |
|
my ($i, $break, $retval); |
my ($i, $break, $retval); |
my ($secs,$long) = @_; |
my ($secs,$long) = @_; |
|
|
Line 2381 sub readableTime ($$) |
|
Line 2686 sub readableTime ($$) |
|
31536000, 'year'); |
31536000, 'year'); |
my @breaks = sort {$a <=> $b} keys %desc; |
my @breaks = sort {$a <=> $b} keys %desc; |
$i = 0; |
$i = 0; |
while ($i <= $#breaks && $secs >= 2 * $breaks[$i]) { |
while ($i <= $#breaks && $secs >= 2 * $breaks[$i]) { |
$i++; |
$i++; |
} |
} |
$i--; |
$i--; |
Line 2392 sub readableTime ($$) |
|
Line 2697 sub readableTime ($$) |
|
my $rest = $secs % $break; |
my $rest = $secs % $break; |
$i--; |
$i--; |
$break = $breaks[$i]; |
$break = $breaks[$i]; |
my $resttime = plural_write(int ($rest / $break), |
my $resttime = plural_write(int ($rest / $break), |
$desc{$break}); |
$desc{$break}); |
if ($resttime) { |
if ($resttime) { |
$retval = $retval . ", " . $resttime; |
$retval .= ", $resttime"; |
} |
} |
} |
} |
|
|
Line 2410 sub readableTime ($$) |
|
Line 2715 sub readableTime ($$) |
|
# basename (last directory/file) is a link as well |
# basename (last directory/file) is a link as well |
## |
## |
sub clickablePath($$) { |
sub clickablePath($$) { |
my ($pathname,$clickLast) = @_; |
my ($pathname,$clickLast) = @_; |
my $retval = ''; |
my $retval = ''; |
|
|
if ($pathname eq '/') { |
if ($pathname eq '/') { |
# this should never happen - chooseCVSRoot() is |
# this should never happen - chooseCVSRoot() is |
# intended to do this |
# intended to do this |
$retval = "[$cvstree]"; |
$retval = "[$cvstree]"; |
} |
} |
else { |
else { |
$retval = $retval . " <a href=\"${scriptname}/${query}#dirlist\">[$cvstree]</a>"; |
$retval .= ' ' . &link("[$cvstree]", sprintf('%s/%s#dirlist', |
|
$scriptname, |
|
$query)); |
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) { |
$retval = $retval . "<a href=\"${scriptname}" |
$retval .= &link($_, join('', |
. urlencode($wherepath) |
$scriptname, |
. (!$last || $lastslash ? '/' : '') |
urlencode($wherepath), |
. ${query} |
(!$last || $lastslash ? '/' : ''), |
. (!$last || $lastslash ? "#dirlist" : "") |
$query, |
. "\">$_</a>"; |
(!$last || $lastslash ? "#dirlist" : ""))); |
} |
} |
else { # do not make a link to the current dir |
else { # do not make a link to the current dir |
$retval = $retval . $_; |
$retval .= $_; |
} |
} |
} |
} |
} |
} |
Line 2454 sub chooseCVSRoot() { |
|
Line 2761 sub chooseCVSRoot() { |
|
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) { |
print "<input type=hidden NAME=$k VALUE=$input{$k}>\n" |
print "<input type=hidden NAME=$k VALUE=$input{$k}>\n" |
if ($input{$k}) && ($k ne "cvsroot"); |
if ($input{$k}) && ($k ne "cvsroot"); |
} |
} |
# Form-Elements look wierd in Netscape if the background |
# Form-Elements look wierd in Netscape if the background |
Line 2468 sub chooseCVSRoot() { |
|
Line 2775 sub chooseCVSRoot() { |
|
foreach $k (@foo) { |
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} : |
print ">", ($CVSROOTdescr{$k} ? $CVSROOTdescr{$k} : $k), "</option>\n"; |
$k). "</option>\n"; |
|
} |
} |
print "</select>\n</td>"; |
print "</select>\n</td>"; |
print "<td><input type=submit value=\"Go\"></td>"; |
print "<td><input type=submit value=\"Go\"></td>"; |
Line 2488 sub chooseMirror() { |
|
Line 2794 sub chooseMirror() { |
|
# and may not be useful for your site; If you don't |
# and may not be useful for your site; If you don't |
# set %MIRRORS this won't show up, anyway |
# set %MIRRORS this won't show up, anyway |
# |
# |
# Should perhaps exlude the current site somehow.. |
# Should perhaps exlude the current site somehow.. |
if (keys %MIRRORS) { |
if (keys %MIRRORS) { |
print "\nThis cvsweb is mirrored in:\n"; |
print "\nThis cvsweb is mirrored in:\n"; |
foreach $mirror (keys %MIRRORS) { |
foreach $mirror (keys %MIRRORS) { |
print ", " if ($moremirrors); |
print ", " if ($moremirrors); |
print qq(<a href="$MIRRORS{$mirror}">$mirror</A>\n); |
print &link(htmlquote($mirror),$MIRRORS{$mirror}); |
$moremirrors = 1; |
$moremirrors = 1; |
} |
} |
print "<p>\n"; |
print "<p>\n"; |
} |
} |
} |
} |
|
|
sub fileSortCmp { |
sub fileSortCmp() { |
my ($comp) = 0; |
my ($comp) = 0; |
my ($c,$d,$af,$bf); |
my ($c,$d,$af,$bf); |
|
|
Line 2531 sub fileSortCmp { |
|
Line 2837 sub fileSortCmp { |
|
} |
} |
|
|
# make A url for downloading |
# make A url for downloading |
sub download_url { |
sub download_url($$;$) { |
my ($url,$revision,$mimetype) = @_; |
my ($url,$revision,$mimetype) = @_; |
|
|
$revision =~ s/\b0\.//; |
$revision =~ s/\b0\.//; |
|
|
if (defined($checkout_magic) |
if (defined($checkoutMagic) |
&& (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) { |
&& (!defined($mimetype) || $mimetype ne "text/x-cvsweb-markup")) { |
my ($path); |
my $path = $where; |
($path = $where) =~ s|/[^/]*$|/|; |
$path =~ s|/[^/]*$|/|; |
$url = "$scriptname/$checkoutMagic/${path}$url"; |
$url = "$scriptname/$checkoutMagic/${path}$url"; |
} |
} |
$url .= "?rev=$revision"; |
$url .= "?rev=$revision"; |
$url .= "&content-type=$mimetype" if (defined($mimetype)); |
$url .= '&content-type=' . urlencode($mimetype) if (defined($mimetype)); |
|
|
return $url; |
$url; |
} |
} |
|
|
# Presents a link to download the |
# Presents a link to download the |
# selected revision |
# selected revision |
sub download_link { |
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); |
my ($paren) = $textlink =~ /^\(/; |
|
$textlink =~ s/^\(// if ($paren); |
printf '<A HREF="%s"', htmlquote("$fullurl$barequery"); |
$textlink =~ s/\)$// if ($paren); |
|
print "(" if ($paren); |
|
print "<A HREF=\"$fullurl"; |
|
print $barequery; |
|
print "\""; |
|
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 |
# 'if (document.cvswin==null) document.cvswin=window.open(...' |
# 'if (document.cvswin==null) document.cvswin=window.open(...' |
# in order to allow the user to resize the window; otherwise |
# in order to allow the user to resize the window; otherwise |
Line 2580 sub download_link { |
|
Line 2882 sub download_link { |
|
# currently, the best way is to comment out the size parameters |
# currently, the best way is to comment out the size parameters |
# ($extern_window...) in cvsweb.conf. |
# ($extern_window...) in cvsweb.conf. |
if ($use_java_script) { |
if ($use_java_script) { |
print " onClick=\"window.open('$fullurl','cvs_checkout',"; |
my @attr = qw(resizeable scrollbars); |
print "'resizeable,scrollbars"; |
|
print ",status,toolbar" if (defined($mimetype) |
push @attr, qw(status toolbar) |
&& $mimetype eq "text/html"); |
if (defined($mimetype) && $mimetype eq "text/html"); |
print ",width=$extern_window_width" if (defined($extern_window_width)); |
|
print ",height=$extern_window_height" if (defined($extern_window_height)); |
push @attr, "width=$extern_window_width" |
print"');\""; |
if (defined($extern_window_width)); |
|
|
|
push @attr, "height=$extern_window_height" |
|
if (defined($extern_window_height)); |
|
|
|
printf q` onClick="window.open('%s','cvs_checkout','%s');"`, |
|
htmlquote($fullurl), join(',', @attr); |
} |
} |
} |
} |
print "><b>$textlink</b></A>"; |
print "><b>$textlink</b></A>"; |
print ")" if ($paren); |
|
} |
} |
|
|
# Returns a Query string with the |
# Returns a Query string with the |
Line 2612 sub toggleQuery($$) { |
|
Line 2919 sub toggleQuery($$) { |
|
my ($value) = defined($vars{$var}) ? $vars{$var} : ""; |
my ($value) = defined($vars{$var}) ? $vars{$var} : ""; |
my ($default) = defined($DEFAULTVALUE{$var}) ? $DEFAULTVALUE{$var} : ""; |
my ($default) = defined($DEFAULTVALUE{$var}) ? $DEFAULTVALUE{$var} : ""; |
if ($value ne $default) { |
if ($value ne $default) { |
$newquery .= "&" if ($newquery ne ""); |
$newquery .= "&" if ($newquery ne ""); |
$newquery .= urlencode($var) . "=" . urlencode($value); |
$newquery .= urlencode($var) . "=" . urlencode($value); |
} |
} |
} |
} |
Line 2622 sub toggleQuery($$) { |
|
Line 2929 sub toggleQuery($$) { |
|
return ""; |
return ""; |
} |
} |
|
|
sub urlencode { |
sub urlencode($) { |
my ($in) = @_; |
local($_) = @_; |
my ($out); |
|
($out = $in) =~ s/([\000-+{-\377])/sprintf("%%%02x", ord($1))/ge; |
s/[\000-+{-\377]/sprintf("%%%02x", ord($&))/ge; |
return $out; |
|
|
|
|
$_; |
} |
} |
|
|
sub http_header { |
sub htmlquote($) { |
|
local($_) = @_; |
|
|
|
# Special Characters; RFC 1866 |
|
s/&/&/g; |
|
s/\"/"/g; |
|
s/</</g; |
|
s/>/>/g; |
|
|
|
$_; |
|
} |
|
|
|
sub htmlunquote($) { |
|
local($_) = @_; |
|
|
|
# Special Characters; RFC 1866 |
|
s/"/\"/g; |
|
s/</</g; |
|
s/>/>/g; |
|
s/&/&/g; |
|
|
|
$_; |
|
} |
|
|
|
sub http_header(;$) { |
my $content_type = shift || "text/html"; |
my $content_type = shift || "text/html"; |
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 2646 sub http_header { |
|
Line 2979 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) { |
my $fh = do {local(*FH);}; |
if ($has_zlib || (defined($GZIPBIN) && open(GZIP, "|$GZIPBIN -1 -c"))) { |
if (defined($GZIPBIN) && open($fh, "|$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 2659 sub http_header { |
|
Line 2991 sub http_header { |
|
print "\r\n"; # Close headers |
print "\r\n"; # Close headers |
} |
} |
$| = 1; $| = 0; # Flush header output |
$| = 1; $| = 0; # Flush header output |
select ($fh); |
if ($has_zlib) { |
|
tie *GZIP, __PACKAGE__, \*STDOUT; |
|
} |
|
select(GZIP); |
|
$gzip_open = 1; |
# print "<!-- gzipped -->" if ($content_type eq "text/html"); |
# print "<!-- gzipped -->" if ($content_type eq "text/html"); |
} |
} |
else { |
else { |
Line 2684 sub http_header { |
|
Line 3020 sub http_header { |
|
|
|
sub html_header($) { |
sub html_header($) { |
my ($title) = @_; |
my ($title) = @_; |
my $version = '$zRevision: 1.93 $ $Revision$'; |
my $version = '$zRevision: 1.103 $ $Revision$'; #' |
http_header(); |
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" |
Line 2698 $logo <h1 align="center">$title</h1> |
|
Line 3034 $logo <h1 align="center">$title</h1> |
|
EOH |
EOH |
} |
} |
|
|
sub html_footer { |
sub html_footer() { |
return "<hr noshade><address>$address</address>\n"; |
return "<hr noshade><address>$address</address>\n"; |
} |
} |
|
|
sub link_tags |
sub link_tags($) { |
{ |
|
my ($tags) = @_; |
my ($tags) = @_; |
my ($ret) = ""; |
my ($ret) = ""; |
my ($fileurl,$filename); |
my ($fileurl,$filename); |
|
|
|
|
foreach my $sym (split(", ", $tags)) { |
foreach my $sym (split(", ", $tags)) { |
$ret .= ",\n" if ($ret ne ""); |
$ret .= ",\n" if ($ret ne ""); |
$ret .= "<A HREF=\"$fileurl" |
$ret .= &link($sym, $fileurl . toggleQuery('only_with_tag',$sym)); |
. toggleQuery('only_with_tag',$sym) . "\">$sym</A>"; |
|
} |
} |
return $ret."\n"; |
return "$ret\n"; |
} |
} |
|
|
# |
# |
# See if a module is listed in the config file's @HideModule list. |
# See if a module is listed in the config file's @HideModule list. |
# |
# |
sub forbidden_module { |
sub forbidden_module($) { |
my($module) = @_; |
my($module) = @_; |
|
|
for (my $i=0; $i < @HideModules; $i++) { |
for (my $i=0; $i < @HideModules; $i++) { |
return 1 if $module eq $HideModules[$i]; |
return 1 if $module eq $HideModules[$i]; |
} |
} |
|
|
return 0; |
return 0; |
|
} |
|
|
|
# Close the GZIP handle remove the tie. |
|
|
|
sub gzipclose { |
|
if ($gzip_open) { |
|
select(STDOUT); |
|
close(GZIP); |
|
untie *GZIP; |
|
$gzip_open = 0; |
|
} |
|
} |
|
|
|
# implement a gzipped file handle via the Compress:Zlib compression |
|
# library. |
|
|
|
sub MAGIC1() { 0x1f } |
|
sub MAGIC2() { 0x8b } |
|
sub OSCODE() { 3 } |
|
|
|
sub TIEHANDLE { |
|
my ($class, $out) = @_; |
|
my ($d) = Compress::Zlib::deflateInit(-Level => Compress::Zlib::Z_BEST_COMPRESSION(), |
|
-WindowBits => -Compress::Zlib::MAX_WBITS()) or return undef; |
|
my ($o) = { |
|
handle => $out, |
|
dh => $d, |
|
crc => 0, |
|
len => 0, |
|
}; |
|
my ($header) = pack("c10", MAGIC1, MAGIC2, Compress::Zlib::Z_DEFLATED(), 0,0,0,0,0,0, OSCODE); |
|
print {$o->{handle}} $header; |
|
return bless($o, $class); |
|
} |
|
|
|
sub PRINT { |
|
my ($o) = shift; |
|
my ($buf) = join(defined $, ? $, : "",@_); |
|
my ($len) = length($buf); |
|
my ($compressed, $status) = $o->{dh}->deflate($buf); |
|
print {$o->{handle}} $compressed if defined($compressed); |
|
$o->{crc} = Compress::Zlib::crc32($buf, $o->{crc}); |
|
$o->{len} += $len; |
|
return $len; |
|
} |
|
|
|
sub PRINTF { |
|
my ($o) = shift; |
|
my ($fmt) = shift; |
|
my ($buf) = sprintf($fmt, @_); |
|
my ($len) = length($buf); |
|
my ($compressed, $status) = $o->{dh}->deflate($buf); |
|
print {$o->{handle}} $compressed if defined($compressed); |
|
$o->{crc} = Compress::Zlib::crc32($buf, $o->{crc}); |
|
$o->{len} += $len; |
|
return $len; |
|
} |
|
|
|
sub WRITE { |
|
my ($o, $buf, $len, $off) = @_; |
|
my ($compressed, $status) = $o->{dh}->deflate(substr($buf, 0, $len)); |
|
print {$o->{handle}} $compressed if defined($compressed); |
|
$o->{crc} = Compress::Zlib::crc32(substr($buf, 0, $len), $o->{crc}); |
|
$o->{len} += $len; |
|
return $len; |
|
} |
|
|
|
sub CLOSE { |
|
my ($o) = @_; |
|
return if !defined( $o->{dh}); |
|
my ($buf) = $o->{dh}->flush(); |
|
$buf .= pack("V V", $o->{crc}, $o->{len}); |
|
print {$o->{handle}} $buf; |
|
undef $o->{dh}; |
|
} |
|
|
|
sub DESTROY { |
|
my ($o) = @_; |
|
CLOSE($o); |
} |
} |