version 1.1.1.37, 2007/03/17 21:52:33 |
version 4.17, 2019/11/11 13:28:36 |
|
|
#!/usr/bin/perl -T |
#!/usr/bin/perl |
|
# $Id$ |
|
# $knu: cvsweb.cgi,v 1.299 2010/11/13 16:37:18 simon |
# |
# |
# cvsweb - a CGI interface to CVS trees. |
# cvsweb - a CGI interface to CVS trees. |
# |
# |
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# 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.295 2005/09/25 20:28:51 scop 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 $ |
|
# |
|
### |
|
|
|
require 5.006; |
require 5.006; |
|
|
use strict; |
use strict; |
|
|
use warnings; |
use warnings; |
use filetest qw(access); |
use filetest qw(access); |
|
|
|
|
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi |
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi |
$doCheckout $scriptname $scriptwhere |
$doCheckout $scriptname $scriptwhere |
$where $Browser $nofilelinks $maycompress @stickyvars %funcline_regexp |
$where $Browser $nofilelinks $maycompress @stickyvars |
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased |
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased |
%input $query $barequery $sortby $bydate $byrev $byauthor |
%input $query $barequery $sortby $bydate $byrev $byauthor |
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot |
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot |
|
|
$tablepadding $hr_breakable $showfunc $hr_ignwhite $hr_ignkeysubst |
$tablepadding $hr_breakable $showfunc $hr_ignwhite $hr_ignkeysubst |
$inputTextSize $mime_types $allow_annotate $allow_markup $allow_mailtos |
$inputTextSize $mime_types $allow_annotate $allow_markup $allow_mailtos |
$allow_log_extra $allow_dir_extra $allow_source_extra |
$allow_log_extra $allow_dir_extra $allow_source_extra |
$allow_cvsgraph $cvsgraph_config $use_java_script $edit_option_form |
$allow_cvsgraph $cvsgraph_config $edit_option_form |
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup |
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup |
$tabstop $state $annTable $sel @ForbiddenFiles |
$tabstop $state $annTable $sel @ForbiddenFiles |
$use_descriptions %descriptions @mytz $dwhere |
$use_descriptions %descriptions @mytz $dwhere |
|
|
$allow_enscript @enscript_options %enscript_types |
$allow_enscript @enscript_options %enscript_types |
); |
); |
|
|
|
require Compress::Zlib; |
use Cwd qw(abs_path); |
use Cwd qw(abs_path); |
use File::Basename qw(dirname); |
|
use File::Path qw(rmtree); |
use File::Path qw(rmtree); |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
tmpdir updir); |
tmpdir updir); |
Line 108 use constant CVSWEBMARKUP => qr{^text/(x-cvsweb|vnd\.v |
|
Line 103 use constant CVSWEBMARKUP => qr{^text/(x-cvsweb|vnd\.v |
|
use constant LOG_FILESEPR => qr/^={77}$/o; |
use constant LOG_FILESEPR => qr/^={77}$/o; |
use constant LOG_REVSEPR => qr/^-{28}$/o; |
use constant LOG_REVSEPR => qr/^-{28}$/o; |
|
|
use constant HAS_ZLIB => eval { require Compress::Zlib; }; |
|
use constant HAS_EDIFF => eval { require String::Ediff; }; |
|
|
|
# ----------------------------------------------------------------------------- |
# ----------------------------------------------------------------------------- |
|
|
# All global initialization that can be done in compile time should go to |
# All global initialization that can be done in compile time should go to |
Line 119 use constant HAS_EDIFF => eval { require String::Ed |
|
Line 111 use constant HAS_EDIFF => eval { require String::Ed |
|
|
|
BEGIN |
BEGIN |
{ |
{ |
$VERSION = '3.0.6'; |
$VERSION = '3.1'; |
|
|
$HTML_DOCTYPE = |
$HTML_DOCTYPE = |
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' . |
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' . |
|
|
|
|
$HTML_META = <<EOM; |
$HTML_META = <<EOM; |
<meta name="robots" content="nofollow" /> |
<meta name="robots" content="nofollow" /> |
<meta name="generator" content="FreeBSD-CVSweb $VERSION" /> |
<meta name="generator" content="CVSweb $VERSION" /> |
<meta http-equiv="Content-Script-Type" content="text/javascript" /> |
|
<meta http-equiv="Content-Style-Type" content="text/css" /> |
<meta http-equiv="Content-Style-Type" content="text/css" /> |
EOM |
EOM |
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
# ----------------------------------------------------------------------------- |
|
|
sub printDiffSelect($); |
sub printDiffSelect(); |
sub printDiffSelectStickyVars(); |
sub printDiffSelectStickyVars(); |
sub getDiffLinks($$$); |
sub getDiffLinks($$$); |
sub printLogSortSelect($); |
sub printLogSortSelect(); |
sub findLastModifiedSubdirs(@); |
sub findLastModifiedSubdirs(@); |
sub htmlify_sub(&$); |
sub htmlify_sub(&$); |
sub htmlify($;$); |
sub htmlify($;$); |
Line 208 sub checkout_to_temp($$$); |
|
Line 199 sub checkout_to_temp($$$); |
|
# (think mod_perl)... |
# (think mod_perl)... |
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}); |
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}); |
|
|
my ($mydir) = (dirname($0) =~ /(.*)/); # untaint |
# Location of the configuration file inside the web server chroot: |
|
$config = '/conf/cvsweb/cvsweb.conf'; |
|
|
##### Start of Configuration Area ######## |
|
|
|
# == EDIT this == |
|
# Locations to search for user configuration, in order: |
|
for (catfile($mydir, 'cvsweb.conf'), '/usr/local/etc/cvsweb/cvsweb.conf') { |
|
if (-r $_) { |
|
$config = $_; |
|
last; |
|
} |
|
} |
|
|
|
##### End of Configuration Area ######## |
|
|
|
undef $mydir; |
|
|
|
######## Configuration parameters ######### |
######## Configuration parameters ######### |
|
|
@CVSrepositories = @CVSROOT = %CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = |
@CVSrepositories = @CVSROOT = %CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = |
Line 234 $cvstreedefault = $logo = $defaulttitle = |
|
Line 211 $cvstreedefault = $logo = $defaulttitle = |
|
$address = $long_intro = $short_instruction = $shortLogLen = $show_author = |
$address = $long_intro = $short_instruction = $shortLogLen = $show_author = |
$tablepadding = $hr_breakable = $showfunc = $hr_ignwhite = |
$tablepadding = $hr_breakable = $showfunc = $hr_ignwhite = |
$hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate = |
$hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate = |
$allow_markup = $allow_compress = $use_java_script = $edit_option_form = |
$allow_markup = $allow_compress = $edit_option_form = |
$show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup = |
$show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup = |
$tabstop = $use_moddate = $gzip_open = $DEBUG = $allow_cvsgraph = |
$tabstop = $use_moddate = $gzip_open = $DEBUG = $allow_cvsgraph = |
$cvsgraph_config = $cvshistory_url = $allow_tar = undef; |
$cvsgraph_config = $cvshistory_url = $allow_tar = undef; |
|
|
$allow_version_select = $allow_mailtos = $allow_log_extra = 1; |
$allow_version_select = $allow_mailtos = $allow_log_extra = 1; |
|
|
@DIFFTYPES = qw(h H u c s); |
@DIFFTYPES = qw(h H u c); |
@DIFFTYPES{@DIFFTYPES} = ( |
@DIFFTYPES{@DIFFTYPES} = ( |
{ |
{ |
'descr' => 'colored', |
'descr' => 'colored', |
Line 263 $allow_version_select = $allow_mailtos = $allow_log_ex |
|
Line 240 $allow_version_select = $allow_mailtos = $allow_log_ex |
|
'opts' => ['-c'], |
'opts' => ['-c'], |
'colored' => 0, |
'colored' => 0, |
}, |
}, |
{ |
|
'descr' => 'side by side', |
|
# width=168 should be enough to support 80 character line lengths |
|
'opts' => ['--side-by-side', '--width=168'], |
|
'colored' => 0, |
|
}, |
|
); |
); |
|
|
@LOGSORTKEYS = qw(cvs date rev); |
@LOGSORTKEYS = qw(cvs date rev); |
Line 343 $maycompress = ( |
|
Line 314 $maycompress = ( |
|
&& $ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) |
&& $ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) |
|| $is_mozilla3) |
|| $is_mozilla3) |
&& !$is_msie |
&& !$is_msie |
&& !(defined($ENV{MOD_PERL}) && !HAS_ZLIB) |
&& !(defined($ENV{MOD_PERL})) |
); |
); |
|
|
# Parameters that will be sticky in all constructed links/query strings. |
# Parameters that will be sticky in all constructed links/query strings. |
Line 384 if (defined($ENV{QUERY_STRING})) { |
|
Line 355 if (defined($ENV{QUERY_STRING})) { |
|
$p =~ y/+/ /; |
$p =~ y/+/ /; |
my ($key, $val) = split(/=/, $p, 2); |
my ($key, $val) = split(/=/, $p, 2); |
next unless defined($key); |
next unless defined($key); |
$val = 1 unless defined($val); |
$key = uri_unescape($key); |
($key = uri_unescape($key)) =~ /[[:graph:]]/ or next; |
$key =~ /([^a-z_12-])/ and fatal('404 Not Found', |
($val = uri_unescape($val)) =~ /[[:graph:]]/ or next; |
'Invalid character "%s" in query parameter "%s"', $1, $key); |
|
if (defined $val) { |
|
$val = uri_unescape($val); |
|
$val =~ /([^a-zA-Z_01-9.\/-])/ and fatal('404 Not Found', |
|
'Invalid character "%s" in the value "%s" of the query parameter "%s"', |
|
$1, $val, $key); |
|
} else { |
|
$val = 1; |
|
} |
$query{$key} = $val; |
$query{$key} = $val; |
} |
} |
} |
} |
Line 559 foreach (@stickyvars) { |
|
Line 538 foreach (@stickyvars) { |
|
} |
} |
|
|
if ($allow_enscript) { |
if ($allow_enscript) { |
push(@DIFFTYPES, qw(uc cc sc)); |
push(@DIFFTYPES, qw(uc cc)); |
@DIFFTYPES{qw(uc cc sc)} = ( |
@DIFFTYPES{qw(uc cc)} = ( |
{ |
{ |
'descr' => 'unified, colored', |
'descr' => 'unified, colored', |
'opts' => ['-u'], |
'opts' => ['-u'], |
Line 571 if ($allow_enscript) { |
|
Line 550 if ($allow_enscript) { |
|
'opts' => ['-c'], |
'opts' => ['-c'], |
'colored' => 0, |
'colored' => 0, |
}, |
}, |
{ |
|
'descr' => 'side by side, colored', |
|
# width=168 should be enough to support 80 character line lengths |
|
'opts' => ['--side-by-side', '--width=168'], |
|
'colored' => 0, |
|
}, |
|
); |
); |
} else { |
} else { |
# No Enscript -> respect difftype, but don't offer colorization. |
# No Enscript -> respect difftype, but don't offer colorization. |
Line 789 if ($input{tarball}) { |
|
Line 762 if ($input{tarball}) { |
|
} |
} |
|
|
# Clean up. |
# Clean up. |
|
chdir(".."); |
rmtree($tmpexportdir); |
rmtree($tmpexportdir); |
|
|
&fatal(@fatal) if @fatal; |
&fatal(@fatal) if @fatal; |
Line 883 if (-d $fullname) { |
|
Line 857 if (-d $fullname) { |
|
|
|
my $infocols = 1; |
my $infocols = 1; |
|
|
printf(<<EOF, 'Directory index of ' . htmlquote($where)); |
printf(<<EOF, $tablepadding, 'Directory index of ' . htmlquote($where)); |
<table class="dir" width="100%%" cellspacing="0" cellpadding="$tablepadding" summary="%s"> |
<table class="dir" width="100%%" cellspacing="0" cellpadding="%s" summary="%s"> |
<tr> |
<tr> |
EOF |
EOF |
printf('<th colspan="2"%s>', ($byfile ? ' class="sorted"' : '')); |
printf('<th colspan="2"%s>', ($byfile ? ' class="sorted"' : '')); |
|
|
|
|
# Show last change in dir |
# Show last change in dir |
if ($filename) { |
if ($filename) { |
print "</td>\n<td> </td>\n<td class=\"age\">"; |
my $ageclass = 'age'; |
print readableTime(time() - $date, 0) if $date; |
my $age = ''; |
|
if ($date) { |
|
$age = readableTime(time() - $date, 0); |
|
$ageclass .= " $1" if ($age =~ /^\d+ ([a-z]+)/); |
|
} |
|
print "</td>\n<td> </td>\n<td class=\"$ageclass\">$age"; |
print "</td>\n<td class=\"author\">", htmlquote($author) |
print "</td>\n<td class=\"author\">", htmlquote($author) |
if $show_author; |
if $show_author; |
print "</td>\n<td class=\"log\">"; |
print "</td>\n<td class=\"log\">"; |
|
|
print ' ', &link(htmlquote($file), $url), $attic; |
print ' ', &link(htmlquote($file), $url), $attic; |
print '</td><td class="graph">', graph_link($fileurl) if $allow_cvsgraph; |
print '</td><td class="graph">', graph_link($fileurl) if $allow_cvsgraph; |
print "</td>\n<td width=\"30\">", display_link($fileurl, $rev); |
print "</td>\n<td width=\"30\">", display_link($fileurl, $rev); |
print "</td>\n<td class=\"age\">"; |
my $ageclass = 'age'; |
print readableTime(time() - $date, 0) if $date; |
my $age = ''; |
|
if ($date) { |
|
$age = readableTime(time() - $date, 0); |
|
$ageclass .= " $1" if ($age =~ /^\d+ ([a-z]+)/); |
|
} |
|
print "</td>\n<td class=\"$ageclass\">$age"; |
print "</td>\n<td class=\"author\">", htmlquote($author) if $show_author; |
print "</td>\n<td class=\"author\">", htmlquote($author) if $show_author; |
print "</td>\n<td class=\"log\">"; |
print "</td>\n<td class=\"log\">"; |
|
|
|
|
if (scalar %tags || $input{only_with_tag}) { |
if (scalar %tags || $input{only_with_tag}) { |
print "<form method=\"get\" action=\"./\">\n<p>\n"; |
print "<form method=\"get\" action=\"./\">\n<p>\n"; |
foreach my $var (@stickyvars) { |
foreach my $var (@stickyvars) { |
printf("<input type=\"hidden\" name=\"$var\" value=\"%s\" />\n", |
printf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n", |
htmlquote($input{$var})) |
$var, htmlquote($input{$var})) |
if (defined($input{$var}) |
if (defined($input{$var}) |
&& (!defined($DEFAULTVALUE{$var}) |
&& (!defined($DEFAULTVALUE{$var}) |
|| $input{$var} ne $DEFAULTVALUE{$var}) |
|| $input{$var} ne $DEFAULTVALUE{$var}) |
&& $var ne 'only_with_tag'); |
&& $var ne 'only_with_tag'); |
} |
} |
printf(<<EOF, ($use_java_script ? ' onchange="this.form.submit()"' : '')); |
print <<EOF; |
<span class="nowrap"> |
<span class="nowrap"> |
<label for="only_with_tag" accesskey="T">Show only files with tag: |
<label for="only_with_tag" accesskey="T">Show only files with tag: |
<select id="only_with_tag" name="only_with_tag"%s> |
<select id="only_with_tag" name="only_with_tag"> |
<option value="">All tags / default branch</option> |
<option value="">All tags / default branch</option> |
EOF |
EOF |
foreach my $tag (reverse sort { lc $a cmp lc $b } keys %tags) { |
foreach my $tag (reverse sort { lc $a cmp lc $b } keys %tags) { |
|
|
<legend>General options</legend> |
<legend>General options</legend> |
<input type="hidden" name="copt" value="1" /> |
<input type="hidden" name="copt" value="1" /> |
EOF |
EOF |
for my $v qw(hidecvsroot hidenonreadable) { |
for my $v (qw(hidecvsroot hidenonreadable)) { |
printf(qq{<input type="hidden" name="%s" value="%s" />\n}, |
printf(qq{<input type="hidden" name="%s" value="%s" />\n}, |
$v, $input{$v} || 0); |
$v, $input{$v} || 0); |
} |
} |
|
|
</td> |
</td> |
<td class="opt-value"> |
<td class="opt-value"> |
EOF |
EOF |
printLogSortSelect(0); |
printLogSortSelect(); |
print <<EOF; |
print <<EOF; |
</td> |
</td> |
<td class="opt-label"> |
<td class="opt-label"> |
|
|
</td> |
</td> |
<td> |
<td> |
EOF |
EOF |
printDiffSelect(0); |
printDiffSelect(); |
print <<EOF; |
print <<EOF; |
</td> |
</td> |
<td colspan="2" class="opt-label"> |
<td colspan="2" class="opt-label"> |
|
|
## End MAIN |
## End MAIN |
|
|
|
|
sub printDiffSelect($) |
sub printDiffSelect() |
{ |
{ |
my ($use_java_script) = @_; |
|
|
|
print '<select id="f" name="f"'; |
print '<select id="f" name="f"'; |
print ' onchange="this.form.submit()"' if $use_java_script; |
|
print ">\n"; |
print ">\n"; |
|
|
for my $difftype (@DIFFTYPES) { |
for my $difftype (@DIFFTYPES) { |
Line 1415 sub printDiffSelectStickyVars() |
|
Line 1396 sub printDiffSelectStickyVars() |
|
} |
} |
|
|
|
|
sub printLogSortSelect($) |
sub printLogSortSelect() |
{ |
{ |
my ($use_java_script) = @_; |
|
|
|
print '<select id="logsort" name="logsort"'; |
print '<select id="logsort" name="logsort"'; |
print ' onchange="this.form.submit()"' if $use_java_script; |
|
print ">\n"; |
print ">\n"; |
|
|
for my $sortkey (@LOGSORTKEYS) { |
for my $sortkey (@LOGSORTKEYS) { |
Line 1521 sub htmlify($;$) |
|
Line 1499 sub htmlify($;$) |
|
|
|
do { |
do { |
$prev = $_; |
$prev = $_; |
|
|
$_ = htmlify_sub { |
$_ = htmlify_sub { |
s{ |
s{ |
(\b$re_prkeyword[:\#]?\s* |
(\b$re_prkeyword[:\#]?\s* |
Line 1563 sub htmlify($;$) |
|
Line 1540 sub htmlify($;$) |
|
}{ |
}{ |
my($text, $name, $section) = ($1, $2, defined($3) ? $3 : $4); |
my($text, $name, $section) = ($1, $2, defined($3) ? $3 : $4); |
($name =~ /[A-Za-z]/ && $name !~ /\.(:|$)/) |
($name =~ /[A-Za-z]/ && $name !~ /\.(:|$)/) |
? &link($text, sprintf($mancgi, $section, uri_escape($name))) |
? &link($text, sprintf($mancgi, uri_escape($name), $section)) |
: $text; |
: $text; |
}egx; |
}egx; |
} $_; |
} $_; |
Line 2314 sub doDiff($$$$$$) |
|
Line 2291 sub doDiff($$$$$$) |
|
my @difftype = @{$difftype->{opts}}; |
my @difftype = @{$difftype->{opts}}; |
my $human_readable = $difftype->{colored}; |
my $human_readable = $difftype->{colored}; |
|
|
# Apply special diff options. -p and -F are not available with side by side |
# Apply special diff options. |
# diffs and may cause problems with older (< 2.8) versions of diffutils if |
push @difftype, '-p' if $showfunc; |
# used with --side-by-side. |
|
if ($showfunc && $f !~ /^s/) { |
|
push(@difftype, '-p'); |
|
while (my ($re1, $re2) = each %funcline_regexp) { |
|
if ($fullname =~ $re1) { |
|
push(@difftype, '-F', $re2); |
|
last; |
|
} |
|
} |
|
} |
|
|
|
if ($human_readable) { |
if ($human_readable) { |
push(@difftype, '-w') if $hr_ignwhite; |
push(@difftype, '-w') if $hr_ignwhite; |
|
|
EOF |
EOF |
printDiffSelectStickyVars(); |
printDiffSelectStickyVars(); |
print 'Diff format: '; |
print 'Diff format: '; |
printDiffSelect($use_java_script); |
printDiffSelect(); |
print "<input type=\"submit\" value=\"Show\" />\n</form>\n"; |
print "<input type=\"submit\" value=\"Show\" />\n</form>\n"; |
html_footer(); |
html_footer(); |
gzipclose(); |
gzipclose(); |
Line 2951 sub printLog($$$;$$) |
|
Line 2918 sub printLog($$$;$$) |
|
print "<br />\n"; |
print "<br />\n"; |
|
|
print '<i>'; |
print '<i>'; |
if (defined @mytz) { |
if (@mytz) { |
my ($est) = $mytz[(localtime($date{$_}))[8]]; |
my ($est) = $mytz[(localtime($date{$_}))[8]]; |
print scalar localtime($date{$_}), " $est</i> ("; |
print scalar localtime($date{$_}), " $est</i> ("; |
} else { |
} else { |
|
|
</td> |
</td> |
<td class="opt-value"> |
<td class="opt-value"> |
EOF |
EOF |
printDiffSelect($use_java_script); |
printDiffSelect(); |
print <<EOF; |
print <<EOF; |
</td> |
</td> |
<td></td> |
<td></td> |
|
|
|
|
if (@branchnames) { |
if (@branchnames) { |
|
|
printf(<<EOF, $use_java_script ? ' onchange="this.form.submit()"' : ''); |
print <<EOF; |
<tr> |
<tr> |
<td class="opt-label"> |
<td class="opt-label"> |
<label for="only_with_tag" accesskey="B">View only branch:</label> |
<label for="only_with_tag" accesskey="B">View only branch:</label> |
</td> |
</td> |
<td class="opt-value"> |
<td class="opt-value"> |
<a name="branch"> |
<a name="branch"> |
<select id="only_with_tag" name="only_with_tag"%s> |
<select id="only_with_tag" name="only_with_tag"> |
EOF |
EOF |
|
|
my @tmp = (); |
my @tmp = (); |
|
|
</td> |
</td> |
<td> |
<td> |
EOF |
EOF |
printLogSortSelect($use_java_script); |
printLogSortSelect(); |
print <<EOF; |
print <<EOF; |
</td> |
</td> |
<td><input type="submit" value="Set" accesskey="S" /></td> |
<td><input type="submit" value="Set" accesskey="S" /></td> |
|
|
next if ($_ eq "f"); |
next if ($_ eq "f"); |
next if ($_ eq "only_with_tag"); |
next if ($_ eq "only_with_tag"); |
next if ($_ eq "logsort"); |
next if ($_ eq "logsort"); |
printf("<input type=\"hidden\" name=\"$_\" value=\"%s\" />\n", |
printf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n", |
htmlquote($input{$_})) |
$_, htmlquote($input{$_})) |
if (defined($input{$_}) |
if (defined($input{$_}) |
&& (!defined($DEFAULTVALUE{$_}) || $input{$_} ne $DEFAULTVALUE{$_})); |
&& (!defined($DEFAULTVALUE{$_}) || $input{$_} ne $DEFAULTVALUE{$_})); |
} |
} |
|
|
} |
} |
} elsif ($state eq "PreChange") { # state eq "PreChange" |
} elsif ($state eq "PreChange") { # state eq "PreChange" |
# we got removes with subsequent adds |
# we got removes with subsequent adds |
if (HAS_EDIFF) { |
|
# construct the suffix tree |
|
my $left_diff = join("\n", @$leftColRef[0..$leftRow-1]); |
|
my $right_diff = join("\n", @$rightColRef[0..$rightRow-1]); |
|
my $diff_str = String::Ediff::ediff($left_diff, $right_diff); |
|
|
|
my @diff_str = split(/ /, $diff_str); |
|
my $INFINITY = 10000000; |
|
push(@diff_str, ($INFINITY) x 8); |
|
my ($idx, $b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
(0, @diff_str[0..7]); |
|
my ($l_cul, $r_cul) = (0, 0); |
|
my ($ldx, $rdx) = (0, 0); |
|
my (@left_html, @right_html); |
|
for (my $j = 0; $j < $leftRow; $j++) { |
|
my $line_len = length(@$leftColRef[$j]); |
|
my $line = @$leftColRef[$j]; |
|
$l_cul += length($line) + 1; # includes "\n" |
|
my $l_culx = $l_cul - 1; # not includes "\n" |
|
if ($j < $lb1) { |
|
$line = spacedHtmlText($line); |
|
push(@left_html, "<td class=\"diff diff-changed\">$line</td>"); |
|
} elsif ($lb1 == $j) { |
|
my $html_line; |
|
while ($lb1 == $j) { |
|
my $begin_char = $l_culx - $b1; |
|
|
|
$line =~ /^(.*)(.{$begin_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-unchanged">'; |
|
$line = $2; |
|
last if ($j != $le1); |
|
|
|
my $end_char = $l_culx - $e1; |
|
$line =~ /^(.*)(.{$end_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-changed">'; |
|
$line = $2; |
|
|
|
$idx++; |
|
my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
@diff_str[$idx*8..($idx+1)*8-1]; |
|
$lb1 = $INFINITY if ($lb1 < 0); |
|
$lb2 = $INFINITY if ($lb2 < 0); |
|
$le1 = $INFINITY if ($le1 < 0); |
|
$le2 = $INFINITY if ($le2 < 0); |
|
if ($te1 > $b1) { |
|
($b1, $lb1) = ($te1, $tle1); |
|
} |
|
if ($te2 > $b2) { |
|
($b2, $lb2) = ($te2, $tle2); |
|
} |
|
} |
|
push(@left_html, |
|
sprintf('<td><span class="diff diff-changed">%s%s</span></td>', |
|
$html_line, spacedHtmlText($line))); |
|
} elsif ($le1 == $j) { |
|
my $html_line; |
|
while ($le1 == $j) { |
|
my $end_char = $l_culx - $e1; |
|
$line =~ /^(.*)(.{$end_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-changed">'; |
|
$line = $2; |
|
|
|
$idx++; |
|
my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
@diff_str[$idx*8..($idx+1)*8-1]; |
|
$lb1 = $INFINITY if ($lb1 < 0); |
|
$lb2 = $INFINITY if ($lb2 < 0); |
|
$le1 = $INFINITY if ($le1 < 0); |
|
$le2 = $INFINITY if ($le2 < 0); |
|
if ($te1 > $b1) { |
|
($b1, $lb1) = ($te1, $tle1); |
|
} |
|
if ($te2 > $b2) { |
|
($b2, $lb2) = ($te2, $tle2); |
|
} |
|
|
|
last if ($lb1 != $j); |
|
|
|
my $begin_char = $l_culx - $b1; |
|
|
|
$line =~ /^(.*)(.{$begin_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-unchanged">'; |
|
$line = $2; |
|
} |
|
push(@left_html, |
|
sprintf('<td><span class="diff diff-unchanged">%s%s</span></td>', |
|
$html_line, spacedHtmlText($line))); |
|
} else { |
|
$line = spacedHtmlText($line); |
|
push(@left_html, "<td class=\"diff diff-unchanged\">$line</td>"); |
|
} |
|
} |
|
($idx, $b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
(0, @diff_str[0..7]); |
|
$lb1 = $INFINITY if ($lb1 < 0); |
|
$lb2 = $INFINITY if ($lb2 < 0); |
|
$le1 = $INFINITY if ($le1 < 0); |
|
$le2 = $INFINITY if ($le2 < 0); |
|
for (my $j = 0; $j < $rightRow; $j++) { |
|
my $line_len = length(@$rightColRef[$j]); |
|
my $line = @$rightColRef[$j]; |
|
$r_cul += length($line) + 1; # includes "\n" |
|
my $r_culx = $r_cul - 1; # not includes "\n" |
|
if ($j < $lb2) { |
|
$line = spacedHtmlText($line); |
|
push(@right_html, "<td class=\"diff diff-changed\">$line</td>"); |
|
} elsif ($lb2 == $j) { |
|
my $html_line; |
|
while ($lb2 == $j) { |
|
my $begin_char = $r_culx - $b2; |
|
|
|
$line =~ /^(.*)(.{$begin_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-unchanged">'; |
|
$line = $2; |
|
|
|
last if ($j != $le2); |
|
|
|
my $end_char = $r_culx - $e2; |
|
$line =~ /^(.*)(.{$end_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-changed">'; |
|
$line = $2; |
|
|
|
$idx++; |
|
my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
@diff_str[$idx*8..($idx+1)*8-1]; |
|
$lb1 = $INFINITY if ($lb1 < 0); |
|
$lb2 = $INFINITY if ($lb2 < 0); |
|
$le1 = $INFINITY if ($le1 < 0); |
|
$le2 = $INFINITY if ($le2 < 0); |
|
if ($te1 > $b1) { |
|
($b1, $lb1) = ($te1, $tle1); |
|
} |
|
if ($te2 > $b2) { |
|
($b2, $lb2) = ($te2, $tle2); |
|
} |
|
} |
|
push(@right_html, |
|
sprintf('<td><span class="diff diff-changed">%s%s</span></td>', |
|
$html_line, spacedHtmlText($line))); |
|
} elsif ($le2 == $j) { |
|
my $html_line; |
|
while ($le2 == $j) { |
|
my $end_char = $r_culx - $e2; |
|
$line =~ /^(.*)(.{$end_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-changed">'; |
|
$line = $2; |
|
|
|
$idx++; |
|
my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); |
|
($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = |
|
@diff_str[$idx*8..($idx+1)*8-1]; |
|
$lb1 = $INFINITY if ($lb1 < 0); |
|
$lb2 = $INFINITY if ($lb2 < 0); |
|
$le1 = $INFINITY if ($le1 < 0); |
|
$le2 = $INFINITY if ($le2 < 0); |
|
if ($te1 > $b1) { |
|
($b1, $lb1) = ($te1, $tle1); |
|
} |
|
if ($te2 > $b2) { |
|
($b2, $lb2) = ($te2, $tle2); |
|
} |
|
|
|
last if ($lb2 != $j); |
|
|
|
my $begin_char = $r_culx - $b2; |
|
$line =~ /^(.*)(.{$begin_char})$/; |
|
$html_line .= spacedHtmlText($1) . |
|
'</span><span class="diff diff-unchanged">'; |
|
$line = $2; |
|
} |
|
push(@right_html, |
|
sprintf('<td nowrap="nowrap"><span class="diff diff-unchanged"'. |
|
'>%s%s</span></td>', |
|
$html_line, spacedHtmlText($line))); |
|
} else { |
|
$line = spacedHtmlText ($line); |
|
push @right_html, "<td class=\"diff diff-unchanged\">$line</td>"; |
|
} |
|
} |
|
for (my $j = 0; $j < $leftRow || $j < $rightRow ; $j++) { # dump out both cols |
|
print '<tr>'; |
|
if ($j < $leftRow) { |
|
print $left_html[$j]; |
|
} else { |
|
print '<td class="diff diff-changed-missing"> </td>'; |
|
} |
|
if ($j < $rightRow) { |
|
print $right_html[$j]; |
|
} else { |
|
print '<td class="diff diff-changed-missing"> </td>'; |
|
} |
|
print "</tr>\n"; |
|
} |
|
} else { |
|
for (my $j = 0; $j < $leftRow || $j < $rightRow; $j++) { # dump both cols |
for (my $j = 0; $j < $leftRow || $j < $rightRow; $j++) { # dump both cols |
print "<tr>\n"; |
print "<tr>\n"; |
if ($j < $leftRow) { |
if ($j < $leftRow) { |
|
|
} |
} |
print "\n</tr>\n"; |
print "\n</tr>\n"; |
} |
} |
} |
|
} |
} |
} |
} |
|
|
|
|
<label for="f">Diff format:<br /> |
<label for="f">Diff format:<br /> |
EOF |
EOF |
printDiffSelectStickyVars(); |
printDiffSelectStickyVars(); |
printDiffSelect($use_java_script); |
printDiffSelect(); |
printf(<<EOF, $rev1, $rev2); |
printf(<<EOF, $rev1, $rev2); |
</label> |
</label> |
<input type="submit" value="Show" /> |
<input type="submit" value="Show" /> |
Line 3840 sub navigateHeader($$$$$;$) |
|
Line 3598 sub navigateHeader($$$$$;$) |
|
my $qpath = htmlquote($path); |
my $qpath = htmlquote($path); |
my $trev = $rev ? " - " . htmlquote($rev) : ''; |
my $trev = $rev ? " - " . htmlquote($rev) : ''; |
|
|
http_header('', $moddate); |
http_header('text/html', $moddate); |
|
|
print <<EOF; |
print <<EOF; |
$HTML_DOCTYPE |
$HTML_DOCTYPE |
Line 3984 sub chooseCVSRoot() |
|
Line 3742 sub chooseCVSRoot() |
|
if ($input{$k} && $k ne 'cvsroot'); |
if ($input{$k} && $k ne 'cvsroot'); |
} |
} |
|
|
printf(<<EOF, $use_java_script ? ' onchange="this.form.submit()"' : ''); |
print <<EOF; |
<label for="cvsroot" accesskey="C">CVS Root: |
<label for="cvsroot" accesskey="C">CVS Root: |
<select id="cvsroot" name="cvsroot"%s> |
<select id="cvsroot" name="cvsroot"> |
EOF |
EOF |
|
|
foreach my $k (@CVSROOT) { |
foreach my $k (@CVSROOT) { |
Line 4227 sub htmlquote($) |
|
Line 3985 sub htmlquote($) |
|
# Special Characters; RFC 1866 |
# Special Characters; RFC 1866 |
s/&/&/g; |
s/&/&/g; |
s/\"/"/g; |
s/\"/"/g; |
|
s/"/"/g; |
s/</</g; |
s/</</g; |
s/>/>/g; |
s/>/>/g; |
return $_; |
return $_; |
Line 4266 sub http_header(;$$) |
|
Line 4025 sub http_header(;$$) |
|
push(@headers, 'Last-Modified: ' . scalar gmtime($moddate) . ' GMT') |
push(@headers, 'Last-Modified: ' . scalar gmtime($moddate) . ' GMT') |
if $moddate; |
if $moddate; |
push(@headers, 'Content-Type: ' . $content_type); |
push(@headers, 'Content-Type: ' . $content_type); |
|
push(@headers, "Content-Security-Policy: default-src 'none'; " . |
|
"img-src 'self'; style-src 'unsafe-inline'"); |
|
|
if ($allow_compress && $maycompress) { |
if ($allow_compress && $maycompress) { |
if (HAS_ZLIB |
push(@headers, 'Content-Encoding: gzip'); |
|| (defined($CMD{gzip}) && open(GZIP, "| $CMD{gzip} -1 -c"))) |
|
{ |
|
|
|
push(@headers, 'Content-Encoding: x-gzip'); |
|
push(@headers, 'Vary: Accept-Encoding'); # RFC 2616, 14.44 |
push(@headers, 'Vary: Accept-Encoding'); # RFC 2616, 14.44 |
print join("\r\n", @headers) . "\r\n\r\n"; |
print join("\r\n", @headers) . "\r\n\r\n"; |
|
|
$| = 1; |
$| = 1; |
$| = 0; # Flush header output. |
$| = 0; # Flush header output. |
|
|
tie(*GZIP, __PACKAGE__, \*STDOUT) if HAS_ZLIB; |
tie(*GZIP, __PACKAGE__, \*STDOUT); |
select(GZIP); |
select(GZIP); |
$gzip_open = 1; |
$gzip_open = 1; |
|
|
} else { |
|
|
|
print join("\r\n", @headers) . "\r\n\r\n"; |
|
printf |
|
'<span style="font-size: smaller">Unable to find gzip binary in the <b>$command_path</b> (<code>%s</code>) to compress output</span><br />', |
|
htmlquote(join(':', @command_path)); |
|
} |
|
|
|
} else { |
} else { |
print join("\r\n", @headers) . "\r\n\r\n"; |
print join("\r\n", @headers) . "\r\n\r\n"; |
} |
} |
|
|
crc => 0, |
crc => 0, |
len => 0, |
len => 0, |
}; |
}; |
my ($header) = pack("c10", |
my ($header) = pack("C10", |
MAGIC1, MAGIC2, Compress::Zlib::Z_DEFLATED(), |
MAGIC1, MAGIC2, Compress::Zlib::Z_DEFLATED(), |
0, 0, 0, 0, 0, 0, OSCODE); |
0, 0, 0, 0, 0, 0, OSCODE); |
print {$o->{handle}} $header; |
print {$o->{handle}} $header; |