version 4.8, 2019/11/09 09:41:07 |
version 4.21, 2019/11/12 09:28:15 |
|
|
%alltags %fileinfo %tags @branchnames %nameprinted |
%alltags %fileinfo %tags @branchnames %nameprinted |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
%symrev %revsym @allrevisions %date %author @revdisplayorder |
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution |
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi |
$mancgi $doCheckout $scriptname $scriptwhere |
$doCheckout $scriptname $scriptwhere |
|
$where $Browser $nofilelinks $maycompress @stickyvars |
$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 |
$charset $output_filter |
$charset $output_filter |
@command_path %CMD $allow_compress $backicon $diricon $fileicon $graphicon |
@command_path %CMD $allow_compress $backicon $diricon $fileicon |
$fullname $cvstreedefault $logo $defaulttitle $address $binfileicon |
$fullname $cvstreedefault $logo $defaulttitle $address $binfileicon |
$long_intro $short_instruction $shortLogLen $show_author |
$long_intro $short_instruction $shortLogLen $show_author |
$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 |
$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_tar @tar_options @gzip_options @zip_options @cvs_options |
$allow_tar @tar_options @gzip_options @zip_options @cvs_options |
@annotate_options @rcsdiff_options |
@annotate_options @rcsdiff_options |
$HTML_DOCTYPE $HTML_META $cssurl $CSS $cvshistory_url |
$HTML_DOCTYPE $HTML_META $cssurl $CSS $cvshistory_url |
$allow_enscript @enscript_options %enscript_types |
|
); |
); |
|
|
|
require Compress::Zlib; |
use Cwd qw(abs_path); |
use Cwd qw(abs_path); |
use File::Path qw(rmtree); |
use File::Path qw(rmtree); |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir |
Line 102 use constant CVSWEBMARKUP => qr{^text/(x-cvsweb|vnd\.v |
|
Line 101 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 |
|
|
|
|
$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 153 sub config_error($$); |
|
Line 148 sub config_error($$); |
|
sub redirect($;$); |
sub redirect($;$); |
sub safeglob($); |
sub safeglob($); |
sub search_path($); |
sub search_path($); |
sub getEnscriptHL($); |
|
sub getMimeType($;$); |
sub getMimeType($;$); |
sub head($;$); |
sub head($;$); |
sub scan_directives(@); |
sub scan_directives(@); |
sub openOutputFilter(); |
sub openOutputFilter(); |
sub doAnnotate($$); |
sub doAnnotate($$); |
sub doCheckout($$$); |
sub doCheckout($$$); |
sub doEnscript($$$;$); |
|
sub doGraph(); |
|
sub doGraphView(); |
|
sub cvswebMarkup($$$$$$;$); |
sub cvswebMarkup($$$$$$;$); |
sub viewable($); |
sub viewable($); |
sub doDiff($$$$$$); |
sub doDiff($$$$$$); |
Line 183 sub download_url($$;$); |
|
Line 174 sub download_url($$;$); |
|
sub download_link($$$;$); |
sub download_link($$$;$); |
sub display_url($$;$); |
sub display_url($$;$); |
sub display_link($$;$$); |
sub display_link($$;$$); |
sub graph_link($;$); |
|
sub history_link($$;$); |
sub history_link($$;$); |
sub toggleQuery($;$); |
sub toggleQuery($;$); |
sub htmlquote($); |
sub htmlquote($); |
Line 214 $cvstreedefault = $logo = $defaulttitle = |
|
Line 204 $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 = |
$cvsgraph_config = $cvshistory_url = $allow_tar = undef; |
$cvshistory_url = $allow_tar = undef; |
|
|
$allow_version_select = $allow_mailtos = $allow_log_extra = 1; |
$allow_version_select = $allow_mailtos = $allow_log_extra = 1; |
|
|
Line 273 $scriptname = '' unless defined($scriptname); |
|
Line 263 $scriptname = '' unless defined($scriptname); |
|
$where = $pathinfo; |
$where = $pathinfo; |
$doCheckout = $where =~ s|^/$CheckoutMagic/|/|o; |
$doCheckout = $where =~ s|^/$CheckoutMagic/|/|o; |
$where =~ s|^/||; |
$where =~ s|^/||; |
$scriptname =~ s|^/*|/|; |
$scriptname =~ s|^/+||; |
|
|
# Let's workaround thttpd's stupidity.. |
# Let's workaround thttpd's stupidity.. |
if ($scriptname =~ m|/$|) { |
if ($scriptname =~ m|/$|) { |
Line 281 if ($scriptname =~ m|/$|) { |
|
Line 271 if ($scriptname =~ m|/$|) { |
|
my $re = quotemeta $pathinfo; |
my $re = quotemeta $pathinfo; |
$scriptname =~ s/$re$//; |
$scriptname =~ s/$re$//; |
} |
} |
|
$scriptname = "/$scriptname" if $scriptname; |
|
|
# $scriptname : the URI escaped path to this script |
# $scriptname : the URI escaped path to this script |
# $where : the path in the CVS repository (without leading /, or only /) |
# $where : the path in the CVS repository (without leading /, or only /) |
Line 317 $maycompress = ( |
|
Line 308 $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 358 if (defined($ENV{QUERY_STRING})) { |
|
Line 349 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 368 if (defined($ENV{QUERY_STRING})) { |
|
Line 367 if (defined($ENV{QUERY_STRING})) { |
|
undef %input; |
undef %input; |
|
|
my $t; |
my $t; |
for my $p (qw(graph hideattic hidecvsroot hidenonreadable ignorecase ln copt |
for my $p (qw(hideattic hidecvsroot hidenonreadable ignorecase ln copt |
makeimage options tarball)) { |
options tarball)) { |
$t = $query{$p}; |
$t = $query{$p}; |
if (defined($t)) { |
if (defined($t)) { |
($input{$p}) = ($t =~ /^([01]|on)$/) |
($input{$p}) = ($t =~ /^([01]|on)$/) |
Line 532 foreach (@stickyvars) { |
|
Line 531 foreach (@stickyvars) { |
|
} |
} |
} |
} |
|
|
if ($allow_enscript) { |
|
push(@DIFFTYPES, qw(uc cc)); |
|
@DIFFTYPES{qw(uc cc)} = ( |
|
{ |
|
'descr' => 'unified, colored', |
|
'opts' => ['-u'], |
|
'colored' => 0, |
|
}, |
|
{ |
|
'descr' => 'context, colored', |
|
'opts' => ['-c'], |
|
'colored' => 0, |
|
}, |
|
); |
|
} else { |
|
# No Enscript -> respect difftype, but don't offer colorization. |
|
if ($input{f} && $input{f} =~ /^([ucs])c$/) { |
|
$input{f} = $1; |
|
} |
|
} |
|
|
|
# is there any query ? |
# is there any query ? |
if (@barequery) { |
if (@barequery) { |
$barequery = join (';', @barequery); |
$barequery = join (';', @barequery); |
Line 625 if (-f $config_cvstree) { |
|
Line 603 if (-f $config_cvstree) { |
|
} |
} |
undef $config_cvstree; |
undef $config_cvstree; |
|
|
$re_prcategories = '(?:' . join ('|', @prcategories) . ')' if @prcategories; |
|
$re_prkeyword = quotemeta($prkeyword) if defined($prkeyword); |
|
$prcgi .= '%s' if defined($prcgi) && $prcgi !~ /%s/; |
|
|
|
$fullname = catfile($cvsroot, $where); |
$fullname = catfile($cvsroot, $where); |
|
|
my $rewrite = 0; |
my $rewrite = 0; |
Line 757 if ($input{tarball}) { |
|
Line 731 if ($input{tarball}) { |
|
} |
} |
|
|
# Clean up. |
# Clean up. |
|
chdir(".."); |
rmtree($tmpexportdir); |
rmtree($tmpexportdir); |
|
|
&fatal(@fatal) if @fatal; |
&fatal(@fatal) if @fatal; |
|
|
$filesfound++; |
$filesfound++; |
|
|
printf "<tr class=\"%s\">\n", ($dirrow % 2) ? 'even' : 'odd'; |
printf "<tr class=\"%s\">\n", ($dirrow % 2) ? 'even' : 'odd'; |
printf '<td class="file"%s>', $allow_cvsgraph ? '' : ' colspan="2"'; |
printf '<td class="file" colspan="2">'; |
|
|
my $icon = $isbinary ? $binfileicon : $fileicon; |
my $icon = $isbinary ? $binfileicon : $fileicon; |
print $nofilelinks ? $icon : &link($icon, $url); |
print $nofilelinks ? $icon : &link($icon, $url); |
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>\n<td width=\"30\">", display_link($fileurl, $rev); |
print "</td>\n<td width=\"30\">", display_link($fileurl, $rev); |
my $ageclass = 'age'; |
my $ageclass = 'age'; |
my $age = ''; |
my $age = ''; |
|
|
|| $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"> |
Line 1279 elsif (-f $fullname . ',v') { |
|
Line 1253 elsif (-f $fullname . ',v') { |
|
exit; |
exit; |
} |
} |
|
|
if ($allow_cvsgraph && $input{graph}) { |
|
if ($input{makeimage}) { |
|
doGraph(); |
|
} else { |
|
doGraphView(); |
|
} |
|
gzipclose(); |
|
exit; |
|
} |
|
|
|
&doLog($fullname); |
&doLog($fullname); |
} |
} |
|
|
|
|
## 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 1393 sub printDiffSelectStickyVars() |
|
Line 1354 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 1492 sub htmlify($;$) |
|
Line 1450 sub htmlify($;$) |
|
} |
} |
|
|
if ($extra) { |
if ($extra) { |
|
|
# get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" |
|
if (defined($prcgi) && defined($re_prkeyword)) { |
|
my $prev; |
|
|
|
do { |
|
$prev = $_; |
|
$_ = htmlify_sub { |
|
s{ |
|
(\b$re_prkeyword[:\#]?\s* |
|
(?: |
|
\#? |
|
\d+[,\s]\s* |
|
)* |
|
\#?) |
|
(\d+)\b |
|
}{ |
|
$1 . &link($2, sprintf($prcgi, $2)) |
|
}egix; |
|
} $_; |
|
} while ($_ ne $prev); |
|
|
|
if (defined($re_prcategories)) { |
|
$_ = htmlify_sub { |
|
s{ |
|
(\b$re_prcategories/(\d+)\b) |
|
}{ |
|
&link($1, sprintf($prcgi, $2)) |
|
}egox; |
|
} $_; |
|
} |
|
} |
|
|
|
# get manpage specs as link: "foo.1" "foo(1)" |
# get manpage specs as link: "foo.1" "foo(1)" |
if (defined($mancgi)) { |
if (defined($mancgi)) { |
$_ = htmlify_sub { |
$_ = htmlify_sub { |
Line 1702 sub search_path($) |
|
Line 1627 sub search_path($) |
|
|
|
|
|
# |
# |
# Gets the enscript(1) highlight mode corresponding to the given filename, |
|
# or undef if unsupported. |
|
# |
|
sub getEnscriptHL($) |
|
{ |
|
return undef unless $allow_enscript; |
|
my ($filename) = @_; |
|
while (my ($hl, $regex) = each %enscript_types) { |
|
return $hl if ($filename =~ $regex); |
|
} |
|
return undef; |
|
} |
|
|
|
|
|
# |
|
# Gets the MIME type for the given file name. |
# Gets the MIME type for the given file name. |
# |
# |
sub getMimeType($;$) |
sub getMimeType($;$) |
|
|
printf '<embed src="%s" width="100%%" height="100%%" /><br />', |
printf '<embed src="%s" width="100%%" height="100%%" /><br />', |
$url . $barequery; |
$url . $barequery; |
} else { |
} else { |
|
|
print "<pre>\n"; |
print "<pre>\n"; |
my $linenumbers = $input{ln} || 0; |
my $linenumbers = $input{ln} || 0; |
|
|
if (my $enscript_hl = getEnscriptHL($filename)) { |
|
doEnscript($filehandle, $enscript_hl, $linenumbers); |
|
|
|
} else { |
|
my $ln = 0; |
my $ln = 0; |
my @buf = (); |
my @buf = (); |
my $ts = undef; |
my $ts = undef; |
|
|
} |
} |
print $preformat_in_markup ? spacedHtmlText($_, $ts) : htmlquote($_); |
print $preformat_in_markup ? spacedHtmlText($_, $ts) : htmlquote($_); |
} |
} |
} |
|
|
|
print "</pre>\n"; |
print "</pre>\n"; |
} |
} |
html_footer(); |
html_footer(); |
Line 2315 sub doDiff($$$$$$) |
|
Line 2217 sub doDiff($$$$$$) |
|
html_footer(); |
html_footer(); |
gzipclose(); |
gzipclose(); |
exit; |
exit; |
|
|
} elsif ($f =~ /^([ucs])c$/) { |
|
# |
|
# Enscript colored diff. |
|
# |
|
my $hl = 'diff'; |
|
$hl .= $1 if ($1 eq 'u' || $1 eq 's'); |
|
(my $where_nd = $where) =~ s/\.diff$//; |
|
(my $pathname = $where_nd) =~ s|((?<=/)Attic/)?[^/]*$||; |
|
(my $filename = $where_nd) =~ s|^.*/||; |
|
(my $swhere = $scriptwhere) =~ s|\.diff$||; |
|
navigateHeader($swhere, $pathname, $filename, $rev2, 'diff'); |
|
printf(<<EOF, $where_nd, $rev1, $rev2); |
|
<h3 style="text-align: center">Diff for /%s between versions %s and %s</h3> |
|
<pre> |
|
EOF |
|
doEnscript(\$fh, $hl, 0, 'cvsweb_diff'); |
|
print <<EOF; |
|
</pre> |
|
<hr style="width: 100%" /> |
|
<form method="get" action="$scriptwhere"> |
|
EOF |
|
printDiffSelectStickyVars(); |
|
print 'Diff format: '; |
|
printDiffSelect($use_java_script); |
|
print "<input type=\"submit\" value=\"Show\" />\n</form>\n"; |
|
html_footer(); |
|
gzipclose(); |
|
exit; |
|
|
|
} else { |
} else { |
# |
# |
# Plain diff. |
# Plain diff. |
Line 2912 sub printLog($$$;$$) |
|
Line 2784 sub printLog($$$;$$) |
|
$fileurl, $_, $barequery, $_)); |
$fileurl, $_, $barequery, $_)); |
} |
} |
} |
} |
print ' - ', graph_link('', 'revision graph') |
|
if (!$inlogview && $allow_cvsgraph); |
|
} |
} |
print "<br />\n"; |
print "<br />\n"; |
|
|
Line 3046 sub printLog($$$;$$) |
|
Line 2916 sub printLog($$$;$$) |
|
} |
} |
|
|
|
|
# |
|
# Generates the HTML view for CvsGraph. |
|
# |
|
sub doGraphView() |
|
{ |
|
(my $pathname = $where) =~ s|[^/]*$||; |
|
(my $filename = $where) =~ s|^.*/||; |
|
|
|
navigateHeader($scriptwhere, $pathname, $filename, undef, 'graph'); |
|
|
|
my $title = 'Revision graph of ' . htmlquote($pathname . $filename); |
|
my $mapname = 'CvsGraphMap'; |
|
|
|
printf(<<EOF, $title, $mapname, $cvstree, $title); |
|
<h3 style="text-align: center">%s</h3> |
|
<div style="text-align: center"><img border="0" usemap="#%s" src="?cvsroot=%s;graph=1;makeimage=1" alt="%s" /> |
|
EOF |
|
|
|
# Remove any pre-existing tag/branch names from branch links. |
|
(my $notag_query = $barequery) =~ s/;+only_with_tag=.*?(?=;|$)//g; |
|
|
|
my @graph_cmd = |
|
($CMD{cvsgraph}, |
|
'-r', $cvsroot, |
|
'-m', $pathname, |
|
'-i', |
|
'-M', $mapname, |
|
'-x', 'x', |
|
"-Omap_branch_href=\"href=\\\"./?only_with_tag=%(%t%)$notag_query\\\"\"", |
|
"-Omap_rev_href=\"href=\\\"?rev=%(%R%)$barequery\\\"\"", |
|
"-Omap_diff_href=\"href=\\\"%(%F%).diff" . |
|
"?r1=%(%P%);r2=%(%R%)$barequery\\\"\"", |
|
); |
|
push(@graph_cmd, '-c', $cvsgraph_config) if $cvsgraph_config; |
|
push(@graph_cmd, $filename . ',v'); |
|
|
|
local *CVSGRAPH_OUT; |
|
my ($h, $err) = |
|
startproc(\@graph_cmd, \"", '>pipe', \*CVSGRAPH_OUT); |
|
fatal('500 Internal Error', $err) unless $h; |
|
|
|
# Browser compatibility kludge: many browsers do not support client side |
|
# image maps where the <map> element contains only the id attribute. Let's |
|
# add the corresponding name attribute to it on the fly. |
|
while (<CVSGRAPH_OUT>) { |
|
s/(<map\s+id="([^"]+)")\s*>/$1 name="$2">/; |
|
print; |
|
} |
|
|
|
$h->finish(); |
|
print "</div>\n"; |
|
|
|
html_footer(); |
|
} |
|
|
|
|
|
# |
|
# Generates a graph using CvsGraph. |
|
# |
|
sub doGraph() |
|
{ |
|
(my $pathname = $where) =~ s|[^/]*$||; |
|
(my $filename = $where) =~ s|^.*/||; |
|
|
|
http_header('image/png'); |
|
|
|
my @graph_cmd = ($CMD{cvsgraph}, '-r', $cvsroot, '-m', $pathname); |
|
push(@graph_cmd, '-c', $cvsgraph_config) if $cvsgraph_config; |
|
push(@graph_cmd, $filename . ',v'); |
|
|
|
local *CVSGRAPH_OUT; |
|
my ($h, $err) = |
|
startproc(\@graph_cmd, \"", '>pipe', \*CVSGRAPH_OUT); |
|
fatal('500 Internal Error', $err) unless $h; |
|
{ |
|
local $/ = undef; |
|
binmode(\*STDOUT); |
|
print <CVSGRAPH_OUT>; |
|
} |
|
$h->finish(); |
|
} |
|
|
|
|
|
sub doLog($) |
sub doLog($) |
{ |
{ |
my ($fullname) = @_; |
my ($fullname) = @_; |
|
|
&clickablePath($upwhere, 1), "</b>\n</p>\n"; |
&clickablePath($upwhere, 1), "</b>\n</p>\n"; |
print "<p>\n "; |
print "<p>\n "; |
print &link('Request diff between arbitrary revisions', '#diff'); |
print &link('Request diff between arbitrary revisions', '#diff'); |
print ' - ', &graph_link('', 'Display revisions graphically') |
|
if $allow_cvsgraph; |
|
if ($cvshistory_url) { |
if ($cvshistory_url) { |
(my $d = $upwhere) =~ s|/+$||; |
(my $d = $upwhere) =~ s|/+$||; |
print ' - ', history_link($d, $filename); |
print ' - ', history_link($d, $filename); |
|
|
</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> |
|
|
} |
} |
} 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" /> |
|
|
} |
} |
|
|
|
|
sub doEnscript($$$;$) |
|
{ |
|
my ($filehandle, $highlight, $linenumbers, $lang) = @_; |
|
$lang ||= 'cvsweb'; |
|
|
|
my @cmd = ($CMD{enscript}, |
|
@enscript_options, |
|
'-q', "--language=$lang", '-o', '-', "--highlight=$highlight"); |
|
|
|
local *ENSCRIPT_OUT; |
|
my ($h, $err) = |
|
startproc(\@cmd, $filehandle, '>pipe', \*ENSCRIPT_OUT); |
|
fatal('500 Internal Error', $err) unless $h; |
|
|
|
# We could short-circuit and have enscript output directly to STDOUT above, |
|
# but that doesn't work with mod_perl (at least some 1.99 versions). |
|
if ($linenumbers) { |
|
my $ln = 0; |
|
while (<ENSCRIPT_OUT>) { |
|
printf '<a id="l%d" class="src">%5d: </a>', (++$ln) x 2; |
|
print $_; |
|
} |
|
} else { |
|
local $/ = undef; |
|
print <ENSCRIPT_OUT>; |
|
} |
|
$h->finish(); |
|
} |
|
|
|
|
|
# |
# |
# The passed in $path and $filename should not be URI escaped, and $swhere |
# The passed in $path and $filename should not be URI escaped, and $swhere |
# *should* be. |
# *should* be. |
Line 3951 sub chooseCVSRoot() |
|
Line 3497 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 4131 sub display_link($$;$$) |
|
Line 3677 sub display_link($$;$$) |
|
} |
} |
|
|
# |
# |
# Expects the passed in URL to be URI escaped, and without a query string. |
|
# The passed in link text should be already HTML escaped as appropriate. |
|
# |
|
sub graph_link($;$) |
|
{ |
|
my ($url, $text) = @_; |
|
$text ||= $graphicon; |
|
return sprintf('<a href="%s?graph=1%s">%s</a>', $url, $barequery, $text); |
|
} |
|
|
|
# |
|
# Returns a link to CVSHistory for the given directory and filename. |
# Returns a link to CVSHistory for the given directory and filename. |
# |
# |
sub history_link($$;$) |
sub history_link($$;$) |
Line 4234 sub http_header(;$$) |
|
Line 3769 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 |
|
|| (defined($CMD{gzip}) && open(GZIP, "| $CMD{gzip} -1 -c"))) |
|
{ |
|
|
|
push(@headers, 'Content-Encoding: gzip'); |
push(@headers, 'Content-Encoding: 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"; |
Line 4247 sub http_header(;$$) |
|
Line 3780 sub http_header(;$$) |
|
$| = 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; |