version 1.1.1.30, 2002/05/22 07:00:03 |
version 1.1.1.35, 2002/09/30 19:43:49 |
|
|
# 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> |
# Jens-Uwe Mager <jum@helios.de> |
# Ville Skyttä <ville.skytta@iki.fi> (html cleanup) |
# Ville Skyttä <scop@FreeBSD.org> |
|
# Vassilii Khachaturov <vassilii@tarunz.org> |
# |
# |
# Based on: |
# Based on: |
# * Bill Fenners cvsweb.cgi revision 1.28 available from: |
# * Bill Fenners cvsweb.cgi revision 1.28 available from: |
|
|
# |
# |
# Copyright (c) 1996-1998 Bill Fenner |
# Copyright (c) 1996-1998 Bill Fenner |
# (c) 1998-1999 Henner Zeller |
# (c) 1998-1999 Henner Zeller |
# (c) 1999 Henrik Nordstrom |
# (c) 1999 Henrik Nordstrom |
# (c) 2000-2002 Akinori MUSHA |
# (c) 2000-2002 Akinori MUSHA |
|
# (c) 2002 Ville Skyttä |
# All rights reserved. |
# All rights reserved. |
# |
# |
# Redistribution and use in source and binary forms, with or without |
# Redistribution and use in source and binary forms, with or without |
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# SUCH DAMAGE. |
# |
# |
# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.102 2002/05/22 06:51:59 knu Exp $ |
# FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.119 2002/07/23 13:58:32 scop Exp |
# $zId: cvsweb.cgi,v 1.112 2001/07/24 13:03:16 hzeller Exp $ |
# $zId: cvsweb.cgi,v 1.112 2001/07/24 13:03:16 hzeller Exp $ |
# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.84 2001/10/07 20:50:10 knu Exp $ |
# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.84 2001/10/07 20:50:10 knu Exp $ |
|
# $FreeBSD: www/en/cgi/cvsweb.cgi,v 1.86 2002/09/26 22:18:25 scop Exp $ |
# |
# |
### |
### |
|
|
|
|
$use_moddate $has_zlib $gzip_open |
$use_moddate $has_zlib $gzip_open |
$allow_tar @tar_options @gzip_options @zip_options @cvs_options |
$allow_tar @tar_options @gzip_options @zip_options @cvs_options |
$LOG_FILESEPARATOR $LOG_REVSEPARATOR |
$LOG_FILESEPARATOR $LOG_REVSEPARATOR |
$tmpdir $HTML_DOCTYPE |
$tmpdir $HTML_DOCTYPE $HTML_META |
); |
); |
|
|
sub printDiffSelect($); |
sub printDiffSelect($); |
Line 104 sub htmlify($;$); |
|
Line 107 sub htmlify($;$); |
|
sub spacedHtmlText($;$); |
sub spacedHtmlText($;$); |
sub link($$); |
sub link($$); |
sub revcmp($$); |
sub revcmp($$); |
sub fatal($$); |
sub fatal($$@); |
sub redirect($); |
sub redirect($); |
sub safeglob($); |
sub safeglob($); |
sub search_path($); |
sub search_path($); |
Line 147 sub forbidden_module($); |
|
Line 150 sub forbidden_module($); |
|
##### Start of Configuration Area ######## |
##### Start of Configuration Area ######## |
delete $ENV{PATH}; |
delete $ENV{PATH}; |
|
|
$cvsweb_revision = '2.0.2'; |
$cvsweb_revision = '2.0.5'; |
|
|
use File::Basename (); |
use File::Basename (); |
|
|
Line 185 $cvstreedefault = $body_tag = $body_tag_for_src = $log |
|
Line 188 $cvstreedefault = $body_tag = $body_tag_for_src = $log |
|
$extern_window_width = $extern_window_height = $edit_option_form = |
$extern_window_width = $extern_window_height = $edit_option_form = |
$show_subdir_lastmod = $show_log_in_markup = $v = $navigationHeaderColor = |
$show_subdir_lastmod = $show_log_in_markup = $v = $navigationHeaderColor = |
$tableBorderColor = $markupLogColor = $tabstop = $use_moddate = $moddate = |
$tableBorderColor = $markupLogColor = $tabstop = $use_moddate = $moddate = |
$gzip_open = $HTML_DOCTYPE = undef; |
$gzip_open = $HTML_DOCTYPE = $HTML_META = undef; |
$tmpdir = defined($ENV{TMPDIR}) ? $ENV{TMPDIR} : "/var/tmp"; |
$tmpdir = defined($ENV{TMPDIR}) ? $ENV{TMPDIR} : "/var/tmp"; |
|
|
$LOG_FILESEPARATOR = q/^={77}$/; |
$LOG_FILESEPARATOR = q/^={77}$/; |
Line 233 $LOG_REVSEPARATOR = q/^-{28}$/; |
|
Line 236 $LOG_REVSEPARATOR = q/^-{28}$/; |
|
}, |
}, |
); |
); |
|
|
|
$cgi_style::hsty_base = 'http://www.FreeBSD.org'; |
|
$_ = q$FreeBSD: www/en/cgi/cvsweb.cgi,v 1.86 2002/09/26 22:18:25 scop Exp $; |
|
@_ = split; |
|
$cgi_style::hsty_date = "@_[3,4]"; |
|
|
|
# warningproof |
|
0 if $cgi_style::hsty_base ne $cgi_style::hsty_date; |
|
|
|
package cgi_style; |
|
require "$main::mydir/cgi-style.pl"; |
|
package main; |
|
|
$HTML_DOCTYPE = |
$HTML_DOCTYPE = |
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'; |
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'; |
|
|
|
$HTML_META = <<EOM; |
|
<meta name="robots" content="nofollow"> |
|
<meta name="generator" content="FreeBSD-CVSweb $cvsweb_revision"> |
|
<meta http-equiv="Content-Script-Type" content="text/javascript"> |
|
<meta http-equiv="Content-Style-Type" content="text/css"> |
|
EOM |
|
|
##### End of configuration variables ##### |
##### End of configuration variables ##### |
|
|
use Time::Local (); |
use Time::Local (); |
|
|
@unsafevars = qw(logsort only_with_tag r1 r2 rev sortby tr1 tr2); |
@unsafevars = qw(logsort only_with_tag r1 r2 rev sortby tr1 tr2); |
|
|
if (-f $config) { |
if (-f $config) { |
do "$config" or &fatal( |
do "$config" or fatal("500 Internal Error", |
"500 Internal Error", |
'Error in loading configuration file: %s<br><br>%s<br>', |
sprintf( |
$config, $@); |
'Error in loading configuration file: %s<br><br>%s<br>', |
|
$config, |
|
&htmlify($@) |
|
) |
|
); |
|
} else { |
} else { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
'Configuration not found. Set the variable <code>$config</code> ' |
'Configuration not found. Set the variable <code>$config</code> in cvsweb.cgi to your <b>cvsweb.conf</b> configuration file first.' |
. 'in cvsweb.cgi to your <b>cvsweb.conf</b> configuration file first.' |
); |
); |
|
} |
} |
|
|
undef %input; |
undef %input; |
Line 341 $input{only_with_tag} = $input{only_on_branch} |
|
Line 357 $input{only_with_tag} = $input{only_on_branch} |
|
|
|
# Prevent cross-site scripting |
# Prevent cross-site scripting |
foreach (@unsafevars) { |
foreach (@unsafevars) { |
if (defined($input{$_}) && $input{$_} =~ /[^\w\-.]/) { |
# Colons are needed in diffs between tags. |
fatal("500 Internal Error", "Malformed query string ($_)"); |
if (defined($input{$_}) && $input{$_} =~ /[^\w\-.:]/) { |
} |
fatal("500 Internal Error", |
|
'Malformed query (%s=%s)', |
|
$_, $input{$_}); |
|
} |
} |
} |
|
|
if (defined($input{"content-type"})) { |
if (defined($input{"content-type"})) { |
Line 447 $logsort = $input{'logsort'}; |
|
Line 466 $logsort = $input{'logsort'}; |
|
|
|
## Default CVS-Tree |
## Default CVS-Tree |
if (!defined($CVSROOT{$cvstreedefault})) { |
if (!defined($CVSROOT{$cvstreedefault})) { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
"<code>\$cvstreedefault</code> points to a repository ($cvstreedefault) " |
'<code>$cvstreedefault</code> points to a repository (%s) not defined in <code>%%CVSROOT</code> (edit your configuration file %s)', |
. "not defined in <code>%CVSROOT</code> " |
$cvstreedefault, $config); |
. "(edit your configuration file $config)"); |
|
} |
} |
|
|
# alternate CVS-Tree, configured in cvsweb.conf |
# alternate CVS-Tree, configured in cvsweb.conf |
Line 482 my $config_cvstree = "$config-$cvstree"; |
|
Line 500 my $config_cvstree = "$config-$cvstree"; |
|
|
|
# Do some special configuration for cvstrees |
# Do some special configuration for cvstrees |
if (-f $config_cvstree) { |
if (-f $config_cvstree) { |
do "$config_cvstree" or &fatal( |
do "$config_cvstree" or |
"500 Internal Error", |
fatal("500 Internal Error", |
sprintf( |
'Error in loading configuration file: %s<br><br>%s<br>', |
'Error in loading configuration file: %s<br><br>%s<br>', |
$config_cvstree, $@); |
$config_cvstree, |
|
&htmlify($@) |
|
) |
|
); |
|
} |
} |
undef $config_cvstree; |
undef $config_cvstree; |
|
|
|
|
undef $rewrite; |
undef $rewrite; |
|
|
if (!-d $cvsroot) { |
if (!-d $cvsroot) { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
'$CVSROOT not found!<p>The server on which the CVS tree lives is probably down. Please try again in a few minutes.' |
'$CVSROOT not found!<p>The server on which the CVS tree lives is probably down. Please try again in a few minutes.'); |
); |
|
} |
} |
|
|
# |
# |
Line 537 if (!-d $cvsroot) { |
|
Line 550 if (!-d $cvsroot) { |
|
$where =~ m:([^/]*):; |
$where =~ m:([^/]*):; |
$module = $1; |
$module = $1; |
if ($module && &forbidden_module($module)) { |
if ($module && &forbidden_module($module)) { |
&fatal("403 Forbidden", "Access to $where forbidden."); |
fatal("403 Forbidden", |
|
'Access to %s forbidden.', |
|
$where); |
} |
} |
|
|
# |
# |
# Handle tarball downloads before any headers are output. |
# Handle tarball downloads before any headers are output. |
# |
# |
if ($input{tarball}) { |
if ($input{tarball}) { |
&fatal("403 Forbidden", "Downloading tarballs is prohibited.") |
fatal("403 Forbidden", |
|
'Downloading tarballs is prohibited.') |
unless $allow_tar; |
unless $allow_tar; |
my ($module) = ($where =~ m,^/?(.*),); # untaint |
my ($module) = ($where =~ m,^/?(.*),); # untaint |
$module =~ s,/([^/]*)$,,; |
$module =~ s,/([^/]*)$,,; |
Line 552 if ($input{tarball}) { |
|
Line 568 if ($input{tarball}) { |
|
my ($basedir) = ($module =~ m,([^/]+)$,); |
my ($basedir) = ($module =~ m,([^/]+)$,); |
|
|
if ($basedir eq '' || $module eq '') { |
if ($basedir eq '' || $module eq '') { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
"You cannot download the top level directory."); |
'You cannot download the top level directory.'); |
} |
} |
|
|
my $tmpexportdir = "$tmpdir/.cvsweb.$$." . int(time); |
my $tmpexportdir = "$tmpdir/.cvsweb.$$." . int(time); |
|
|
mkdir($tmpexportdir, 0700) |
mkdir($tmpexportdir, 0700) |
or &fatal("500 Internal Error", |
or fatal("500 Internal Error", |
"Unable to make temporary directory: $!"); |
'Unable to make temporary directory: %s', |
|
$!); |
|
|
my @fatal; |
my @fatal; |
|
|
Line 575 if ($input{tarball}) { |
|
Line 592 if ($input{tarball}) { |
|
if (system $CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'export', '-r', |
if (system $CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'export', '-r', |
$tag, '-d', "$tmpexportdir/$basedir", $module) |
$tag, '-d', "$tmpexportdir/$basedir", $module) |
{ |
{ |
@fatal = ("500 Internal Error", "cvs co failure: $!: $module"); |
@fatal = ("500 Internal Error", |
|
'cvs co failure: %s: %s', |
|
$!, $module); |
} else { |
} else { |
$| = 1; # Essential to get the buffering right. |
$| = 1; # Essential to get the buffering right. |
|
|
Line 585 if ($input{tarball}) { |
|
Line 604 if ($input{tarball}) { |
|
system |
system |
"$CMD{tar} @tar_options -cf - -C $tmpexportdir $basedir | $CMD{gzip} @gzip_options -c" |
"$CMD{tar} @tar_options -cf - -C $tmpexportdir $basedir | $CMD{gzip} @gzip_options -c" |
and @fatal = |
and @fatal = |
("500 Internal Error", |
("500 Internal Error", |
"tar zc failure: $!: $basedir"); |
'tar zc failure: %s: %s', |
|
$!, $basedir); |
} elsif ($ext eq '.zip' && $CMD{zip}) { |
} elsif ($ext eq '.zip' && $CMD{zip}) { |
print "Content-Type: application/zip\r\n\r\n"; |
print "Content-Type: application/zip\r\n\r\n"; |
|
|
system |
system |
"cd $tmpexportdir && $CMD{zip} @zip_options -r - $basedir" |
"cd $tmpexportdir && $CMD{zip} @zip_options -r - $basedir" |
and @fatal = |
and @fatal = |
("500 Internal Error", "zip failure: $!: $basedir"); |
("500 Internal Error", |
|
'zip failure: %s: %s', |
|
$!, $basedir); |
} else { |
} else { |
@fatal = |
@fatal = |
("500 Internal Error", "unsupported file type"); |
("500 Internal Error", |
|
'unsupported file type'); |
} |
} |
} |
} |
|
|
Line 612 if ($input{tarball}) { |
|
Line 635 if ($input{tarball}) { |
|
############################### |
############################### |
if (-d $fullname) { |
if (-d $fullname) { |
my $dh = do { local (*DH); }; |
my $dh = do { local (*DH); }; |
opendir($dh, $fullname) or &fatal("404 Not Found", "$where: $!"); |
opendir($dh, $fullname) or fatal("404 Not Found", |
|
'%s: %s', |
|
$where, $!); |
my @dir = readdir($dh); |
my @dir = readdir($dh); |
closedir($dh); |
closedir($dh); |
my @subLevelFiles = findLastModifiedSubdirs(@dir) |
my @subLevelFiles = findLastModifiedSubdirs(@dir) |
Line 628 if (-d $fullname) { |
|
Line 653 if (-d $fullname) { |
|
print $short_instruction; |
print $short_instruction; |
} |
} |
|
|
my $descriptions; |
if ($use_descriptions && open(DESC, "<$cvsroot/CVSROOT/descriptions")) |
if (($use_descriptions) && open(DESC, "<$cvsroot/CVSROOT/descriptions")) |
|
{ |
{ |
while (<DESC>) { |
while (<DESC>) { |
chomp; |
chomp; |
my ($dir, $description) = /(\S+)\s+(.*)/; |
my ($dir, $description) = /(\S+)\s+(.*)/; |
$descriptions{$dir} = $description; |
$descriptions{$dir} = $description; |
} |
} |
|
close(DESC); |
} |
} |
|
|
print "<p><a name=\"dirlist\"></a></p>\n"; |
print "<p><a name=\"dirlist\"></a></p>\n"; |
Line 922 if (-d $fullname) { |
|
Line 947 if (-d $fullname) { |
|
} |
} |
$dirrow++; |
$dirrow++; |
} elsif (s/,v$//) { |
} elsif (s/,v$//) { |
|
|
|
# Skip forbidden files now so we'll give no hint |
|
# about their existence. This should probably have |
|
# been done earlier, but it's straightforward here. |
|
next if forbidden_file("$fullname/$_"); |
|
|
$fileurl = ($attic ? "Attic/" : "") . urlencode($_); |
$fileurl = ($attic ? "Attic/" : "") . urlencode($_); |
$url = './' . $fileurl . $query; |
$url = './' . $fileurl . $query; |
my $rev = ''; |
my $rev = ''; |
Line 1000 if (-d $fullname) { |
|
Line 1031 if (-d $fullname) { |
|
|| $input{$var} ne $DEFAULTVALUE{$var}) |
|| $input{$var} ne $DEFAULTVALUE{$var}) |
&& $input{$var} ne "" && $var ne "only_with_tag"); |
&& $input{$var} ne "" && $var ne "only_with_tag"); |
} |
} |
print "<p>Show only files with tag:\n"; |
print "<p><label for=\"only_with_tag\" accesskey=\"T\">"; |
print "<select name=\"only_with_tag\""; |
print "Show only files with tag:</label>\n"; |
|
print "<select id=\"only_with_tag\" name=\"only_with_tag\""; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print ">"; |
print ">"; |
print "<option value=\"\">All tags / default branch</option>\n"; |
print "<option value=\"\">All tags / default branch</option>\n"; |
Line 1013 if (-d $fullname) { |
|
Line 1045 if (-d $fullname) { |
|
">$tag</option>\n"; |
">$tag</option>\n"; |
} |
} |
print "</select>\n"; |
print "</select>\n"; |
print " Module path or alias:\n"; |
print " <label for=\"path\" accesskey=\"P\">"; |
printf "<input type=\"text\" name=\"path\" value=\"%s\" size=\"15\">\n", |
print "Module path or alias:</label>\n"; |
|
printf "<input type=\"text\" id=\"path\" name=\"path\" value=\"%s\" size=\"15\">\n", |
htmlquote($where); |
htmlquote($where); |
print "<input type=\"submit\" value=\"Go\"></p>\n"; |
print "<input type=\"submit\" value=\"Go\" accesskey=\"G\"></p>\n"; |
print "</form>\n"; |
print "</form>\n"; |
} |
} |
|
|
Line 1054 if (-d $fullname) { |
|
Line 1087 if (-d $fullname) { |
|
print "<center>\n<table cellpadding=\"0\" cellspacing=\"0\">"; |
print "<center>\n<table cellpadding=\"0\" cellspacing=\"0\">"; |
print "\n<tr style=\"background-color: $columnHeaderColorDefault\">\n"; |
print "\n<tr style=\"background-color: $columnHeaderColorDefault\">\n"; |
print "<th colspan=\"2\">Preferences</th>\n</tr>\n"; |
print "<th colspan=\"2\">Preferences</th>\n</tr>\n"; |
print "<tr>\n<td>Sort files by <select name=\"sortby\">\n"; |
print "<tr>\n<td>"; |
|
print "<label for=\"sortby\" accesskey=\"F\">Sort files by "; |
|
print "</label><select id=\"sortby\" name=\"sortby\">\n"; |
print "<option value=\"\">File</option>\n"; |
print "<option value=\"\">File</option>\n"; |
print "<option", $bydate ? " selected" : "", |
print "<option", $bydate ? " selected" : "", |
" value=\"date\">Age</option>\n"; |
" value=\"date\">Age</option>\n"; |
Line 1066 if (-d $fullname) { |
|
Line 1101 if (-d $fullname) { |
|
print "<option", $bylog ? " selected" : "", |
print "<option", $bylog ? " selected" : "", |
" value=\"log\">Log message</option>\n"; |
" value=\"log\">Log message</option>\n"; |
print "</select>\n</td>\n"; |
print "</select>\n</td>\n"; |
print "<td>Sort log by: "; |
print "<td><label for=\"logsort\" accesskey=\"L\">"; |
|
print "Sort log by: </label>"; |
printLogSortSelect(0); |
printLogSortSelect(0); |
print "</td>\n</tr>\n"; |
print "</td>\n</tr>\n"; |
print "<tr>\n<td>Diff format: "; |
print "<tr>\n<td><label for=\"f\" accesskey=\"D\">"; |
|
print "Diff format: </label>"; |
printDiffSelect(0); |
printDiffSelect(0); |
print "</td>\n"; |
print "</td>\n"; |
print "<td><label>Show Attic files: "; |
print "<td><label for=\"hideattic\" accesskey=\"A\">"; |
print "<input name=\"hideattic\" type=\"checkbox\"", |
print "Show Attic files: </label>"; |
|
print "<input id=\"hideattic\" name=\"hideattic\" type=\"checkbox\"", |
$input{'hideattic'} ? " checked" : "", |
$input{'hideattic'} ? " checked" : "", |
"></label></td>\n</tr>\n"; |
"></td>\n</tr>\n"; |
print "<tr>\n<td align=\"center\" colspan=\"2\">"; |
print "<tr>\n<td align=\"center\" colspan=\"2\">"; |
print "<input type=\"submit\" value=\"Change Options\">"; |
print "<input type=\"submit\" value=\"Change Options\" accesskey=\"C\">"; |
print "</td>\n</tr>\n</table>\n</center>\n</form>\n"; |
print "</td>\n</tr>\n</table>\n</center>\n</form>\n"; |
} |
} |
html_footer(); |
html_footer(); |
Line 1087 if (-d $fullname) { |
|
Line 1125 if (-d $fullname) { |
|
# View Files |
# View Files |
############################### |
############################### |
elsif (-f $fullname . ',v') { |
elsif (-f $fullname . ',v') { |
|
|
|
if (forbidden_file($fullname)) { |
|
fatal('403 Forbidden', |
|
'Access forbidden. This file is mentioned in @ForbiddenFiles'); |
|
return; |
|
} |
|
|
if (defined($input{'rev'}) || $doCheckout) { |
if (defined($input{'rev'}) || $doCheckout) { |
&doCheckout($fullname, $input{'rev'}); |
&doCheckout($fullname, $input{'rev'}); |
gzipclose(); |
gzipclose(); |
Line 1169 elsif (-f $fullname . ',v') { |
|
Line 1214 elsif (-f $fullname . ',v') { |
|
} |
} |
} |
} |
} |
} |
&fatal("404 Not Found", "$where: no such file or directory"); |
fatal("404 Not Found", |
|
'%s: no such file or directory', |
|
$where); |
} |
} |
|
|
gzipclose(); |
gzipclose(); |
Line 1180 sub printDiffSelect($) { |
|
Line 1227 sub printDiffSelect($) { |
|
my ($use_java_script) = @_; |
my ($use_java_script) = @_; |
my $f = $input{'f'}; |
my $f = $input{'f'}; |
|
|
print '<select name="f"'; |
print '<select id="f" name="f"'; |
print ' onchange="this.form.submit()"' if $use_java_script; |
print ' onchange="this.form.submit()"' if $use_java_script; |
print ">\n"; |
print ">\n"; |
|
|
Line 1196 sub printDiffSelect($) { |
|
Line 1243 sub printDiffSelect($) { |
|
sub printLogSortSelect($) { |
sub printLogSortSelect($) { |
my ($use_java_script) = @_; |
my ($use_java_script) = @_; |
|
|
print '<select name="logsort"'; |
print '<select id="logsort" name="logsort"'; |
print ' onchange="this.form.submit()"' if $use_java_script; |
print ' onchange="this.form.submit()"' if $use_java_script; |
print ">\n"; |
print ">\n"; |
|
|
Line 1232 sub findLastModifiedSubdirs(@) { |
|
Line 1279 sub findLastModifiedSubdirs(@) { |
|
$filename = "$dirname/$filename"; |
$filename = "$dirname/$filename"; |
my ($file) = "$fullname/$filename"; |
my ($file) = "$fullname/$filename"; |
next if ($filename !~ /,v$/ || !-f $file); |
next if ($filename !~ /,v$/ || !-f $file); |
|
|
|
# Skip forbidden files. |
|
(my $f = $file) =~ s/,v$//; |
|
next if forbidden_file($f); |
|
|
$filename =~ s/,v$//; |
$filename =~ s/,v$//; |
my $modtime = -M $file; |
my $modtime = -M $file; |
|
|
Line 1403 sub revcmp($$) { |
|
Line 1455 sub revcmp($$) { |
|
return 0; |
return 0; |
} |
} |
|
|
sub fatal($$) { |
sub fatal($$@) { |
my ($errcode, $errmsg) = @_; |
my ($errcode, $format, @args) = @_; |
if ($is_mod_perl) { |
if ($is_mod_perl) { |
Apache->request->status((split (/ /, $errcode))[0]); |
Apache->request->status((split (/ /, $errcode))[0]); |
} else { |
} else { |
print "Status: $errcode\r\n"; |
print "Status: $errcode\r\n"; |
} |
} |
html_header("Error"); |
html_header("Error"); |
print "<p>Error: ", htmlquote($errmsg), "</p>\n"; |
print "<p>Error: ", |
|
sprintf($format, map(htmlquote($_), @args)), |
|
"</p>\n"; |
html_footer(); |
html_footer(); |
exit(1); |
exit(1); |
} |
} |
Line 1561 sub doAnnotate($$) { |
|
Line 1615 sub doAnnotate($$) { |
|
# make sure the revisions are wellformed, for security |
# make sure the revisions are wellformed, for security |
# reasons .. |
# reasons .. |
if ($rev =~ /[^\w.]/) { |
if ($rev =~ /[^\w.]/) { |
&fatal("404 Not Found", |
fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
'Malformed query "%s"', |
|
$ENV{QUERY_STRING}); |
} |
} |
|
|
if (&forbidden_file($fullname)) { |
|
&fatal("403 Forbidden", |
|
"Access forbidden. This file is mentioned in \@ForbiddenFiles" |
|
); |
|
return; |
|
} |
|
|
|
($pathname = $where) =~ s/(Attic\/)?[^\/]*$//; |
($pathname = $where) =~ s/(Attic\/)?[^\/]*$//; |
($filename = $where) =~ s/^.*\///; |
($filename = $where) =~ s/^.*\///; |
|
|
Line 1587 sub doAnnotate($$) { |
|
Line 1635 sub doAnnotate($$) { |
|
# the cvsserver in a similiar way one day (..after rewrite) |
# the cvsserver in a similiar way one day (..after rewrite) |
$pid = open2($reader, $writer, $CMD{cvs}, @cvs_options, "server") |
$pid = open2($reader, $writer, $CMD{cvs}, @cvs_options, "server") |
or fatal("500 Internal Error", |
or fatal("500 Internal Error", |
"Fatal Error - unable to open cvs for annotation"); |
'Fatal Error - unable to open cvs for annotation'); |
|
|
# OK, first send the request to the server. A simplified example is: |
# OK, first send the request to the server. A simplified example is: |
# Root /home/kingdon/zwork/cvsroot |
# Root /home/kingdon/zwork/cvsroot |
Line 1722 sub doAnnotate($$) { |
|
Line 1770 sub doAnnotate($$) { |
|
# CVS command line client. But for simplicity, we don't. |
# CVS command line client. But for simplicity, we don't. |
} elsif ($words[0] eq "error") { |
} elsif ($words[0] eq "error") { |
fatal("500 Internal Error", |
fatal("500 Internal Error", |
"Error occured during annotate: <b>$_</b>"); |
'Error occured during annotate: <b>%s</b>', |
|
$_); |
} |
} |
} |
} |
|
|
Line 1750 sub doCheckout($$) { |
|
Line 1799 sub doCheckout($$) { |
|
# make sure the revisions a wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if (defined($rev) && $rev =~ /[^\w.]/) { |
if (defined($rev) && $rev =~ /[^\w.]/) { |
&fatal("404 Not Found", |
fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
'Malformed query "%s"', |
|
$ENV{QUERY_STRING}); |
} |
} |
|
|
if (&forbidden_file($fullname)) { |
|
&fatal("403 Forbidden", |
|
"Access forbidden. This file is mentioned in \@ForbiddenFiles" |
|
); |
|
return; |
|
} |
|
|
|
# get mimetype |
# get mimetype |
if (defined($input{"content-type"}) |
if (defined($input{"content-type"}) |
&& ($input{"content-type"} =~ /\S\/\S/)) |
&& ($input{"content-type"} =~ /\S\/\S/)) |
Line 1805 sub doCheckout($$) { |
|
Line 1848 sub doCheckout($$) { |
|
} |
} |
|
|
if (eof($fh)) { |
if (eof($fh)) { |
&fatal("404 Not Found", "$where is not (any longer) pertinent"); |
fatal("404 Not Found", |
|
'%s is not (any longer) pertinent', |
|
$where); |
} |
} |
|
|
#=================================================================== |
#=================================================================== |
Line 1829 sub doCheckout($$) { |
|
Line 1874 sub doCheckout($$) { |
|
} |
} |
|
|
if ($filename ne $where) { |
if ($filename ne $where) { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
"Unexpected output from cvs co: $cvsheader"); |
'Unexpected output from cvs co: %s', |
|
$cvsheader); |
} |
} |
$| = 1; |
$| = 1; |
|
|
Line 1924 sub doDiff($$$$$$) { |
|
Line 1970 sub doDiff($$$$$$) { |
|
my ($rev1, $rev2, $sym1, $sym2, $f1, $f2); |
my ($rev1, $rev2, $sym1, $sym2, $f1, $f2); |
|
|
if (&forbidden_file($fullname)) { |
if (&forbidden_file($fullname)) { |
&fatal("403 Forbidden", |
fatal("403 Forbidden", |
"Access forbidden. This file is mentioned in \@ForbiddenFiles" |
'Access forbidden. This file is mentioned in @ForbiddenFiles'); |
); |
|
return; |
return; |
} |
} |
|
|
Line 1951 sub doDiff($$$$$$) { |
|
Line 1996 sub doDiff($$$$$$) { |
|
# make sure the revisions a wellformed, for security |
# make sure the revisions a wellformed, for security |
# reasons .. |
# reasons .. |
if ($rev1 =~ /[^\w.]/ || $rev2 =~ /[^\w.]/) { |
if ($rev1 =~ /[^\w.]/ || $rev2 =~ /[^\w.]/) { |
&fatal("404 Not Found", |
fatal("404 Not Found", |
"Malformed query \"$ENV{QUERY_STRING}\""); |
'Malformed query "%s"', |
|
$ENV{QUERY_STRING}); |
} |
} |
|
|
# |
# |
Line 1967 sub doDiff($$$$$$) { |
|
Line 2013 sub doDiff($$$$$$) { |
|
my $difftype = $DIFFTYPES{$f}; |
my $difftype = $DIFFTYPES{$f}; |
|
|
if (!$difftype) { |
if (!$difftype) { |
fatal("400 Bad arguments", "Diff format $f not understood"); |
fatal("400 Bad arguments", |
|
'Diff format %s not understood', |
|
$f); |
} |
} |
|
|
my @difftype = @{$difftype->{'opts'}}; |
my @difftype = @{$difftype->{'opts'}}; |
Line 2261 sub getDirLogs($$@) { |
|
Line 2309 sub getDirLogs($$@) { |
|
} |
} |
|
|
if ($. == 0) { |
if ($. == 0) { |
fatal("500 Internal Error", "Failed to spawn GNU rlog on <em>'" |
fatal("500 Internal Error", |
. join (", ", @files) |
'Failed to spawn GNU rlog on <em>"%s"</em>. <p>Did you set the <b>$command_path</b> in your configuration file correctly ? (Currently "%s"', |
. "'</em><p>Did you set the <b>\$command_path</b> in your configuration file correctly ? (Currently '$command_path'" |
join (", ", @files), $command_path); |
); |
|
} |
} |
close($fh); |
close($fh); |
} |
} |
Line 2352 sub readLog($;$) { |
|
Line 2399 sub readLog($;$) { |
|
# these lines since we don't know what revision they go with |
# these lines since we don't know what revision they go with |
# any more. |
# any more. |
next logentry; |
next logentry; |
|
|
# &fatal("500 Internal Error","Error parsing RCS output: $_"); |
|
} |
} |
$_ = <$fh>; |
$_ = <$fh>; |
print "D:", $_ if ($verbose); |
print "D:", $_ if ($verbose); |
Line 2373 sub readLog($;$) { |
|
Line 2418 sub readLog($;$) { |
|
$state{$rev} = $8; |
$state{$rev} = $8; |
$difflines{$rev} = $10; |
$difflines{$rev} = $10; |
} else { |
} else { |
&fatal("500 Internal Error", |
fatal("500 Internal Error", |
"Error parsing RCS output: $_"); |
'Error parsing RCS output: %s', |
|
$_); |
} |
} |
line: |
line: |
|
|
Line 2481 sub readLog($;$) { |
|
Line 2527 sub readLog($;$) { |
|
|
|
if (!defined($onlyonbranch) || $onlybranchpoint eq "") { |
if (!defined($onlyonbranch) || $onlybranchpoint eq "") { |
fatal("404 Tag not found", |
fatal("404 Tag not found", |
"Tag $input{'only_with_tag'} not defined"); |
'Tag %s not defined', |
|
$input{'only_with_tag'}); |
} |
} |
} |
} |
|
|
Line 2752 sub printLog($;$) { |
|
Line 2799 sub printLog($;$) { |
|
printDiffLinks($input{'r1'}, $url); |
printDiffLinks($input{'r1'}, $url); |
} |
} |
|
|
print '<br>' if $diff; |
|
} |
} |
print "\n</p>\n<pre>\n"; |
print "\n</p>\n<pre>\n"; |
print &htmlify($log{$_}, $allow_log_extra); |
print &htmlify($log{$_}, $allow_log_extra); |
|
|
|| $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne "")); |
|| $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne "")); |
} |
} |
print "<table style=\"border: none\">\n<tr>\n"; |
print "<table style=\"border: none\">\n<tr>\n"; |
print "<td align=\"right\">Diffs between \n"; |
print "<td align=\"right\">"; |
print "<select name=\"r1\">\n"; |
print "<label for=\"r1\" accesskey=\"1\">Diffs between </label>\n"; |
|
print "<select id=\"r1\" name=\"r1\">\n"; |
print "<option value=\"text\" selected>Use Text Field</option>\n"; |
print "<option value=\"text\" selected>Use Text Field</option>\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 |
print |
"<input type=\"text\" size=\"$inputTextSize\" name=\"tr1\" value=\"$diffrev\" onchange=\"document.diff_select.r1.selectedIndex=0\"></td>\n"; |
"<input type=\"text\" size=\"$inputTextSize\" name=\"tr1\" value=\"$diffrev\" onchange=\"this.form.r1.selectedIndex=0\"></td>\n"; |
print "<td><br></td>\n</tr>\n"; |
print "<td><br></td>\n</tr>\n"; |
print "<tr>\n<td align=\"right\">and \n"; |
print "<tr>\n<td align=\"right\">"; |
print "<select name=\"r2\">\n"; |
print "<label for=\"r2\" accesskey=\"2\">and </label>\n"; |
|
print "<select id=\"r2\" name=\"r2\">\n"; |
print "<option value=\"text\" selected>Use Text Field</option>\n"; |
print "<option value=\"text\" selected>Use Text Field</option>\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 |
print |
"<input type=\"text\" size=\"$inputTextSize\" name=\"tr2\" value=\"$diffrev\" onchange=\"document.diff_select.r2.selectedIndex=0\"></td>\n"; |
"<input type=\"text\" size=\"$inputTextSize\" name=\"tr2\" value=\"$diffrev\" onchange=\"this.form.r2.selectedIndex=0\"></td>\n"; |
print "<td><input type=\"submit\" value=\" Get Diffs \"></td>\n"; |
print "<td><input type=\"submit\" value=\" Get Diffs \" accesskey=\"G\"></td>\n"; |
print "</tr>\n</table>\n"; |
print "</tr>\n</table>\n"; |
print "</form>\n"; |
print "</form>\n"; |
print "<hr noshade>\n"; |
print "<hr noshade>\n"; |
print "<form method=\"get\" action=\"$scriptwhere\">\n"; |
print "<form method=\"get\" action=\"$scriptwhere\">\n"; |
print "<table style=\"border: none\">\n"; |
print "<table style=\"border: none\">\n"; |
print "<tr>\n<td align=\"right\">Preferred Diff type:</td>\n"; |
print "<tr>\n<td align=\"right\">"; |
|
print "<label for=\"f\" accesskey=\"D\">Preferred Diff type:"; |
|
print "</label></td>\n"; |
print "<td>"; |
print "<td>"; |
printDiffSelect($use_java_script); |
printDiffSelect($use_java_script); |
print "</td>\n<td></td>\n</tr>\n"; |
print "</td>\n<td></td>\n</tr>\n"; |
|
|
if (@branchnames) { |
if (@branchnames) { |
print "<tr>\n<td align=\"right\">View only Branch:</td>\n"; |
print "<tr>\n<td align=\"right\">"; |
|
print "<label for=\"only_with_tag\" accesskey=\"B\">"; |
|
print "View only Branch:</label></td>\n"; |
print "<td>"; |
print "<td>"; |
print "<a name=\"branch\"></a>\n"; |
print "<a name=\"branch\"></a>\n"; |
print "<select name=\"only_with_tag\""; |
print "<select id=\"only_with_tag\" name=\"only_with_tag\""; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print ">\n"; |
print ">\n"; |
print "<option value=\"\""; |
print "<option value=\"\""; |
|
|
} |
} |
print "<tr>\n<td align=\"right\">"; |
print "<tr>\n<td align=\"right\">"; |
print "<a name=\"logsort\"></a>\n"; |
print "<a name=\"logsort\"></a>\n"; |
print "Sort log by:</td>\n"; |
print "<label for=\"logsort\" accesskey=\"L\">Sort log by:"; |
print "<td>"; |
print "</label></td>\n<td>"; |
printLogSortSelect($use_java_script); |
printLogSortSelect($use_java_script); |
print "</td>\n"; |
print "</td>\n"; |
print "<td><input type=\"submit\" value=\" Set \"></td>\n"; |
print "<td><input type=\"submit\" value=\" Set \" accesskey=\"S\"></td>\n"; |
print "</tr>\n</table>\n"; |
print "</tr>\n</table>\n"; |
print "</form>\n"; |
print "</form>\n"; |
html_footer(); |
html_footer(); |
Line 3135 sub navigateHeader($$$$$) { |
|
Line 3187 sub navigateHeader($$$$$) { |
|
$HTML_DOCTYPE |
$HTML_DOCTYPE |
<html> |
<html> |
<head> |
<head> |
<meta name="robots" content="nofollow"> |
|
<meta http-equiv="Content-Script-Type" content="application/x-javascript"> |
|
<meta http-equiv="Content-Style-Type" content="text/css"> |
|
<!-- FreeBSD-cvsweb $cvsweb_revision --> |
|
<title>$path$filename - $title - $rev</title>$css |
<title>$path$filename - $title - $rev</title>$css |
</head> |
$HTML_META</head> |
$body_tag_for_src |
$body_tag_for_src |
<table width="100%" style="border: none; background-color: $navigationHeaderColor" cellspacing="0" cellpadding="1"> |
<table width="100%" style="border: none; background-color: $navigationHeaderColor" cellspacing="0" cellpadding="1"> |
<tr valign="bottom"><td> |
<tr valign="bottom"><td> |
Line 3270 sub chooseCVSRoot() { |
|
Line 3318 sub chooseCVSRoot() { |
|
# isn't gray and the form elements are not placed |
# isn't gray and the form elements are not placed |
# within a table ... |
# within a table ... |
print "<table style=\"border: none\">\n<tr>\n"; |
print "<table style=\"border: none\">\n<tr>\n"; |
print "<td>CVS Root:</td>\n"; |
print "<td><label for=\"cvsroot\" accesskey=\"C\">CVS Root:</label></td>\n"; |
print "<td>\n<select name=\"cvsroot\""; |
print "<td>\n<select id=\"cvsroot\" name=\"cvsroot\""; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print " onchange=\"this.form.submit()\"" if $use_java_script; |
print ">\n"; |
print ">\n"; |
|
|
Line 3290 sub chooseCVSRoot() { |
|
Line 3338 sub chooseCVSRoot() { |
|
print "CVS Root: <b>[$cvstree]</b>"; |
print "CVS Root: <b>[$cvstree]</b>"; |
} |
} |
|
|
print " Module path or alias:\n"; |
print " <label for=\"mpath\" accesskey=\"M\">Module path or alias:"; |
print "<input type=\"text\" name=\"path\" value=\"\" size=\"15\">\n"; |
print "</label>\n"; |
print "<input type=\"submit\" value=\"Go\">"; |
print "<input type=\"text\" id=\"mpath\" name=\"path\" value=\"\" size=\"15\">\n"; |
|
print "<input type=\"submit\" value=\"Go\" accesskey=\"O\">"; |
|
|
if (2 <= @CVSROOT) { |
if (2 <= @CVSROOT) { |
print "</td>\n</tr>\n</table>"; |
print "</td>\n</tr>\n</table>"; |
Line 3303 sub chooseCVSRoot() { |
|
Line 3352 sub chooseCVSRoot() { |
|
} |
} |
|
|
sub chooseMirror() { |
sub chooseMirror() { |
my ($mirror, $moremirrors); |
|
$moremirrors = 0; |
|
|
|
# This code comes from the original BSD-cvsweb |
# This code comes from the original BSD-cvsweb |
# 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. |
# |
scalar(%MIRRORS) or return; |
# Should perhaps exlude the current site somehow.. |
|
if (keys %MIRRORS) { |
|
print "\nThis cvsweb is mirrored in:\n"; |
|
|
|
foreach $mirror (keys %MIRRORS) { |
# Should perhaps exclude the current site somehow... |
print ", " if ($moremirrors); |
print "\n<p>\nThis CVSweb is mirrored in\n"; |
print &link(htmlquote($mirror), $MIRRORS{$mirror}); |
|
$moremirrors = 1; |
my @tmp = map(&link(htmlquote($_), $MIRRORS{$_}), |
} |
sort keys %MIRRORS); |
print "<p>\n"; |
my $tmp = pop(@tmp); |
|
|
|
if (scalar(@tmp)) { |
|
print join(', ', @tmp), ' and '; |
} |
} |
|
|
|
print "$tmp.\n</p>\n"; |
} |
} |
|
|
sub fileSortCmp() { |
sub fileSortCmp() { |
Line 3348 sub fileSortCmp() { |
|
Line 3397 sub fileSortCmp() { |
|
|
|
if ($comp == 0) { |
if ($comp == 0) { |
|
|
# Directories first, then sorted on name if no other sort critera |
# Directories first, then files under version control, |
# available. |
# then other, "rogue" files. |
my $ad = ((-d "$fullname/$a") ? "D" : "F"); |
# Sort by filename if no other criteria available. |
my $bd = ((-d "$fullname/$b") ? "D" : "F"); |
|
|
my $ad = ((-d "$fullname/$a") ? 'D' |
|
: (defined($fileinfo{$af}) ? 'F' : 'R')); |
|
my $bd = ((-d "$fullname/$b") ? 'D' |
|
: (defined($fileinfo{$bf}) ? 'F' : 'R')); |
($c = $a) =~ s|.*/||; |
($c = $a) =~ s|.*/||; |
($d = $b) =~ s|.*/||; |
($d = $b) =~ s|.*/||; |
$comp = ("$ad$c" cmp "$bd$d"); |
$comp = ("$ad$c" cmp "$bd$d"); |
Line 3411 sub download_link($$$;$) { |
|
Line 3464 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) { |
my @attr = qw(resizeable scrollbars); |
my @attr = qw(resizable scrollbars); |
|
|
push @attr, qw(status toolbar) |
push @attr, qw(status toolbar) |
if (defined($mimetype) && $mimetype eq "text/html"); |
if (defined($mimetype) && $mimetype eq "text/html"); |
Line 3428 sub download_link($$$;$) { |
|
Line 3481 sub download_link($$$;$) { |
|
# the same window *twice*. |
# the same window *twice*. |
printf |
printf |
q` onclick="window.open('%s','cvs_checkout','%s');return false"`, |
q` onclick="window.open('%s','cvs_checkout','%s');return false"`, |
hrefquote($fullurl), join (',', @attr); |
hrefquote("$fullurl$barequery"), join (',', @attr); |
} |
} |
} |
} |
print "><b>$textlink</b></a>"; |
print "><b>$textlink</b></a>"; |
Line 3579 sub http_header(;$) { |
|
Line 3632 sub http_header(;$) { |
|
sub html_header($) { |
sub html_header($) { |
my ($title) = @_; |
my ($title) = @_; |
http_header("text/html"); |
http_header("text/html"); |
|
|
|
(my $header = &cgi_style::html_header) =~ s,\A.*</head>\n,,s; |
|
|
print <<EOH; |
print <<EOH; |
$HTML_DOCTYPE |
$HTML_DOCTYPE |
<html> |
<html> |
<head> |
<head> |
<meta name="robots" content="nofollow"> |
|
<meta http-equiv="Content-Script-Type" content="application/x-javascript"> |
|
<meta http-equiv="Content-Style-Type" content="text/css"> |
|
<title>$title</title> |
<title>$title</title> |
<!-- FreeBSD-cvsweb $cvsweb_revision --> |
$HTML_META</head> |
</head> |
$header |
$body_tag |
|
$logo <h1 align="center">$title</h1> |
|
EOH |
EOH |
} |
} |
|
|
sub html_footer() { |
sub html_footer() { |
print "<hr noshade>\n<address>$address</address>\n</body>\n</html>\n"; |
return &cgi_style::html_footer; |
} |
} |
|
|
sub link_tags($) { |
sub link_tags($) { |