=================================================================== RCS file: /cvs/cvsweb/cvsweb.cgi,v retrieving revision 1.1 retrieving revision 1.14 diff -u -p -r1.1 -r1.14 --- cvsweb/cvsweb.cgi 1996/09/28 23:31:06 1.1 +++ cvsweb/cvsweb.cgi 1998/01/12 16:27:14 1.14 @@ -28,7 +28,21 @@ require 'timelocal.pl'; require 'ctime.pl'; -$cvsroot = '/home/ncvs'; +$hsty_base = ""; +require 'cgi-style.pl'; +#&get_the_source; + +%CVSROOT = ( + 'freebsd', '/home/ncvs', + 'openbsd', '/home/OpenBSD/cvs', + 'learn', '/c/learncvs', + ); + +$cvstreedefault = 'freebsd'; +$cvstree = $cvstreedefault; +$cvsroot = $CVSROOT{"$cvstree"} || "/home/ncvs"; + + $intro = " This is a WWW interface to the FreeBSD CVS tree. You can browse the file hierarchy by picking directories @@ -41,8 +55,12 @@ diffs between that revision and the previous one, and a form at the bottom of the page that allows you to display diffs between arbitrary revisions.
+If you would like to use this CGI script on your own web server and +CVS tree, see +the CVSWeb distribution site. +
Please send any suggestions, comments, etc. to -Bill Fenner <fenner@freebsd.org> +Bill Fenner <fenner\@freebsd.org> "; $shortinstr = " Click on a directory to enter that directory. Click on a file to display @@ -53,152 +71,343 @@ chance to display diffs between revisions. $verbose = $v; ($where = $ENV{'PATH_INFO'}) =~ s|^/||; $where =~ s|/$||; -$fullname = $cvsroot . '/' . $where; ($scriptname = $ENV{'SCRIPT_NAME'}) =~ s|^/?|/|; $scriptname =~ s|/$||; $scriptwhere = $scriptname . '/' . $where; $scriptwhere =~ s|/$||; +if ($query = $ENV{'QUERY_STRING'}) { + foreach (split(/&/, $query)) { + s/%(..)/sprintf("%c", hex($1))/ge; # unquote %-quoted + if (/(\S+)=(.*)/) { + $input{$1} = $2; + } else { + $input{$_}++; + } + } + $query = "?" . $query; +} + + +$config = '/usr/local/etc/cvsweb'; +do "$config" if -f $config; + +if ($input{'cvsroot'}) { + if ($CVSROOT{$input{'cvsroot'}}) { + $cvstree = $input{'cvsroot'}; + $cvsroot = $CVSROOT{"$cvstree"}; + } +} +do "$config-$cvstree" if -f "$config-$cvstree"; + +$fullname = $cvsroot . '/' . $where; + if (!-d $cvsroot) { - &fatal("500 Internal Error",'$CVSROOT not found!'); + &fatal("500 Internal Error",'$CVSROOT not found!
The server on which the CVS tree lives is probably down. Please try again in a few minutes.'); } + + if (-d $fullname) { -# Something that would be nice to support, although I have no real -# good idea of how, would be to get full directory diff's, using -# symbolic names (revision numbers would be meaningless). -# The problem is finding a list of symbolic names that is common -# to all the files in the directory. -# opendir(DIR, $fullname) || &fatal("404 Not Found","$where: $!"); @dir = readdir(DIR); closedir(DIR); - print "Content-type: text/html\n\n"; - print "
Current directory: /$where\n"; - print "
- print "Content-type: text/plain\n\n"; - open(RCSDIFF, "rcsdiff $difftype -r$rev1 -r$rev2 '$fullname' 2>&1 |") || - &fail("500 Internal Error", "Couldn't rcsdiff: $!"); + print "Content-type: text/plain\n\n"; + open(RCSDIFF, "rcsdiff $difftype -r$rev1 -r$rev2 '$fullname' 2>&1 |") || + &fail("500 Internal Error", "Couldn't rcsdiff: $!"); # #=================================================================== #RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v @@ -216,36 +425,44 @@ print "
#--- src/sys/netinet/tcp_output.c 1995/12/05 17:46:35 1.17 RELENG_2_1_0 # (bogus example, but...) # - if ($difftype eq '-u') { - $f1 = '---'; - $f2 = '\+\+\+'; - } else { - $f1 = '\*\*\*'; - $f2 = '---'; - } - while () { - if (m|^$f1 $cvsroot|o) { - s|$cvsroot/||o; - if ($sym1) { - chop; - $_ .= " " . $sym1 . "\n"; - } - } elsif (m|^$f2 $cvsroot|o) { - s|$cvsroot/||o; - if ($sym2) { - chop; - $_ .= " " . $sym2 . "\n"; - } + if ($difftype eq '-u') { + $f1 = '---'; + $f2 = '\+\+\+'; + } else { + $f1 = '\*\*\*'; + $f2 = '---'; + } + while ( ) { + if (m|^$f1 $cvsroot|o) { + s|$cvsroot/||o; + if ($sym1) { + chop; + $_ .= " " . $sym1 . "\n"; } - print $_; + } elsif (m|^$f2 $cvsroot|o) { + s|$cvsroot/||o; + if ($sym2) { + chop; + $_ .= " " . $sym2 . "\n"; + } } - close(RCSDIFF); - exit; + print $_; } + close(RCSDIFF); +} + +sub dolog { + local($fullname) = @_; + local($curbranch,$symnames); #... + + print("Going to rlog '$fullname'\n") if ($verbose); open(RCS, "rlog '$fullname'|") || &fatal("500 Internal Error", "Failed to spawn rlog"); while ( ) { print if ($verbose); + if (/^branch:\s+([\d\.]+)/) { + $curbranch = $1; + } if ($symnames) { if (/^\s+([^:]+):\s+([\d\.]+)/) { $symrev{$1} = $2; @@ -262,6 +479,12 @@ print "
last; } } + + if ($onlyonbranch = $input{'only_on_branch'}) { + ($onlyonbranch = $symrev{$onlyonbranch}) =~ s/\.0\././; + ($onlybranchpoint = $onlyonbranch) =~ s/\.\d+$//; + } + # each log entry is of the form: # ---------------------------- # revision 3.7.1.1 @@ -271,17 +494,26 @@ print "
logentry: while (!/^=========/) { $_ =; + last logentry if (!defined($_)); # EOF print "R:", $_ if ($verbose); if (/^revision ([\d\.]+)/) { $rev = $1; } elsif (/^========/ || /^----------------------------$/) { next logentry; } else { - &fatal("500 Internal Error","Error parsing RCS output: $_"); + # The rlog output is syntactically ambiguous. We must + # have guessed wrong about where the end of the last log + # message was. + # Since this is likely to happen when people put rlog output + # in their commit messages, don't even bother keeping + # these lines since we don't know what revision they go with + # any more. + next logentry; +# &fatal("500 Internal Error","Error parsing RCS output: $_"); } $_ = ; print "D:", $_ if ($verbose); - if (m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+author:\s+(\S+);|) { + if (m|^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+author:\s+(\S+);\s+state:\s+(\S+);|) { $yr = $1; # damn 2-digit year routines if ($yr > 100) { @@ -289,6 +521,7 @@ print "
} $date{$rev} = &timelocal($6,$5,$4,$3,$2 - 1,$yr); $author{$rev} = $7; + $state{$rev} = $8; } else { &fatal("500 Internal Error", "Error parsing RCS output: $_"); } @@ -309,12 +542,13 @@ print "
print "Done sorting revisions\n" if ($verbose); # # HEAD is an artificial tag which is simply the highest tag number on the main -# branch (I think!). Find it by looking through @revorder; it should at least -# be near the beginning (In fact, it *should* be the first commit listed on -# the main branch.) +# branch, unless there is a branch tag in the RCS file in which case it's the +# highest revision on that branch. Find it by looking through @revorder; it +# is the first commit listed on the appropriate branch. + $headrev = $curbranch || "1"; revision: for ($i = 0; $i <= $#revorder; $i++) { - if ($revorder[$i] =~ /^\d+\.\d+$/) { + if ($revorder[$i] =~ /^(\S*)\.\d+$/ && $headrev eq $1) { if ($revsym{$revorder[$i]}) { $revsym{$revorder[$i]} .= ", "; } @@ -334,6 +568,7 @@ print "
foreach (sort keys %symrev) { $rev = $symrev{$_}; if ($rev =~ /^(\d+(\.\d+)+)\.0\.(\d+)$/) { + push(@branchnames, $_); # # A revision number of A.B.0.D really translates into # "the highest current revision on branch A.B.D". @@ -341,8 +576,6 @@ print "
# If there is no branch A.B.D, then it translates into # the head A.B . # - # This is pure speculation. - # $head = $1; $branch = $3; $regex = $head . "." . $branch; @@ -360,19 +593,27 @@ print "
} $revsym{$rev} .= ", " if ($revsym{$rev}); $revsym{$rev} .= $_; + if ($rev ne $head) { + $branchpoint{$head} .= ", " if ($branchpoint{$head}); + $branchpoint{$head} .= $_; + } } $sel .= "
\n"; - print "
\n"; -print "\n"; + print "
\n"; + print &html_footer; print "\n"; -} else { - &fatal("404 Not Found","$where: no such file or directory"); } -sub htmlify { - local($string) = @_; - - $string =~ s/</g; - $string =~ s/>/>/g; - - $string; -} - -sub link { - local($name, $where) = @_; - - "$name\n"; -} - -sub revcmp { - local($rev1, $rev2) = @_; - local(@r1) = split(/\./, $rev1); - local(@r2) = split(/\./, $rev2); - local($a,$b); - - while (($a = pop(@r1)) && ($b = pop(@r2))) { - if ($a != $b) { - return $a <=> $b; - } - } - if (@r1) { return 1; } - if (@r2) { return -1; } - return 0; -} - -sub fatal { - local($errcode, $errmsg) = @_; - print "Status: $errcode\n"; - print "Content-type: text/html\n"; - print "\n"; - print "