diff --git a/en/cgi/Makefile b/en/cgi/Makefile index 06a07d2fcb..bde0a27bb9 100644 --- a/en/cgi/Makefile +++ b/en/cgi/Makefile @@ -1,46 +1,47 @@ -# $FreeBSD: www/en/cgi/Makefile,v 1.25 2005/10/06 15:44:08 remko Exp $ +# $FreeBSD: www/en/cgi/Makefile,v 1.26 2005/11/06 20:28:56 ceri Exp $ .if exists(../Makefile.conf) .include "../Makefile.conf" .endif .if exists(../Makefile.inc) .include "../Makefile.inc" .endif DATA= DATA+= Gnats.pm DATA+= cgi-lib.pl DATA+= cgi-style.pl DATA+= cvsweb.conf DATA+= cvsweb.conf-freebsd DATA+= cvsweb.conf-netbsd DATA+= cvsweb.conf-openbsd DATA+= ftp.mirrors DATA+= html.pl CGI= CGI+= cvsweb.cgi CGI+= dosendpr.cgi CGI+= ftp.cgi CGI+= gallery.cgi CGI+= getmsg.cgi CGI+= mailindex.cgi CGI+= man.cgi CGI+= mid.cgi CGI+= mirror.cgi CGI+= missing_handler.cgi CGI+= monthly.cgi CGI+= pds.cgi CGI+= ports.cgi CGI+= query-pr.cgi CGI+= query-pr-summary.cgi +CGI+= querypr-code.cgi CGI+= search.cgi CGI+= sendpr-code.cgi CGI+= url.cgi .SUFFIXES: .C .cgi .C.cgi: ${CXX} ${CFLAGS} -o ${.TARGET} ${.IMPSRC} .include "${WEB_PREFIX}/share/mk/web.site.mk" diff --git a/en/cgi/query-pr.cgi b/en/cgi/query-pr.cgi index 07b948f928..2ff101cf59 100755 --- a/en/cgi/query-pr.cgi +++ b/en/cgi/query-pr.cgi @@ -1,243 +1,330 @@ #!/usr/bin/perl -T # $FreeBSD: www/en/cgi/query-pr.cgi,v 1.46 2005/11/04 10:25:42 ceri Exp $ $ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin"; +use DB_File; +use Fcntl qw(:DEFAULT :flock); + require "./cgi-lib.pl"; require "./cgi-style.pl"; require "getopts.pl"; require "./Gnats.pm"; import Gnats; -&Getopts('p:'); +my $expiretime = 2700; +$dbpath = "/tmp/querypr-code.db"; + +&Getopts('cp:'); + +if ($opt_c) { + $codeentered = $opt_c; +} if ($opt_p) { $input{'pr'} = $opt_p; } else { if (! &ReadParse(*input)) { print &html_header("PR Query Interface"); print "

Please enter the PR number you wish to query:

\n"; ($scriptname = $ENV{'SCRIPT_NAME'}) =~ s|^/?|/|; $scriptname =~ s|/$||; ($summary = $scriptname) =~ s/query-pr/query-pr-summary/; - print "
\n"; + print "\n"; print "\n"; + print "

To view the PR with email addresses, copy the code "; + print " from the image below: \n"; + print "

\n"; print "\n
\n"; print "

See also the PR summary

\n"; print &html_footer; exit 0; } } # allow query-pr.cgi? queries if (!($pr = $input{'pr'}) && &MethGet) { $pr = $ENV{'QUERY_STRING'}; } +# Get the confirmation code if it exists +# (and wasn't specified with -c). +$codeentered ||= $input{'code-confirm'}; + +# Verify the data ... + +$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644) + or die "dbcreate $dbpath $!"; +$fd = $db_obj->fd; +open(DB_FH, "+<&=$fd") or die "fdopen $!"; + +unless (flock (DB_FH, LOCK_EX | LOCK_NB)) { + unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" } +} + +# Sweep for and remove expired codes. +foreach $randomcode (keys %db_hash) { + if ( ($currenttime - $expiretime) >= $db_hash{$randomcode}) { + delete $db_hash{"$randomcode"}; + } +} + +$currenttime = time(); +if (defined($codeentered) && $codeentered && $db_hash{$codeentered} && + (($currenttime - $expiretime) <= $db_hash{$codeentered})) { + # This code is good. Set the flag and remove the code. + $codeok++; + delete $db_hash{"$codeentered"}; +} else { + # Fail silently. + if ($db_hash{$codeentered}) { + print "code was in db\n"; + print "time in db is $db_hash{$codeentered}\n"; + } else { + print "code not in db\n"; + } + print "code entered was $codeentered\n"; + print "current time is $currenttime\n"; + print "expire time is $expiretime\n"; + + die ("shit: $@"); + undef; +} + +$db_obj->sync(); # to flush +flock(DB_FH, LOCK_UN); +undef $db_obj; # removing the last reference to the DB + # closes it. Closing DB_FH is implicit. +untie %db_hash; + # be tolerant to / queries $pr =~ s%^.+/%%; # remove / part if ($pr =~ /(\d+)/) { $pr = $1; } else { $pr = 0; } $pr = int($pr); # numeralize: "0123" -> 123 if ($pr < 1 || $pr > 499999) { print &html_header("FreeBSD Problem Report"); print "

Invalid problem report number: $pr

\n"; print &summary_link; print &html_footer; exit 0; } unless (open(Q, "$query_pr -F $pr 2>&1 |")) { print &html_header("Server error"); print "

Unable to open PR database.

\n"; print &summary_link; print &html_footer; die "Unable to query PR's"; } if ($input{'f'} eq 'raw') { print "Content-Type: text/plain\r\n\r\n"; print ; close(Q); exit 0; } $inhdr = 1; $multiline = 0; $from = ""; $replyto = ""; while() { chop; $html_fixup = 1; if (/^query-pr(:?\.(:?real|web))?: /) { print &html_header("FreeBSD problem report"); if ($_ !~ /^query-pr(:?\.(:?real|web))?: no PRs matched$/) { print "

query-pr said:\n"; print "

$_\n";
 	    print ;
 	    print "
\n"; } else { print "

No PR found matching $pr

\n"; } print &summary_link; print &html_footer; exit; } elsif (/^lockf: /) { print &html_header("FreeBSD problem report"); print "

The PR database is currently busy; please try ", "your query again.

"; print &summary_link; print &html_footer; exit; } # In e-mail header if ($inhdr && /^From:\s*(.*)$/i) { $from = $1; $from =~ s/.*<(.*)>.*/$1/; $from =~ s/\s*\(.*\)\s*//; } if ($inhdr && /^Reply-to:\s*(.*)$/i) { $replyto = $1; $replyto =~ s/.*<(.*)>.*/$1/; $replyto =~ s/\s*\(.*\)\s*//; } # End of e-mail header if ($inhdr && /^$/) { $from = $replyto if ($replyto); $email = $from; $email .= '@FreeBSD.org' unless ($email =~ /@/); $inhdr = 0; } if (/^>Responsible:/) { $_ = &getline($_); s/\(.*\)//; # remove personal name s/\s+//g; $_ = $_ . '@FreeBSD.org' if !/@/; $_ = ">Responsible:$_"; $html_fixup = 0; } s/^>Last-Modified:\s*$/>Last-Modified: never/; if (/^>Number:/) { $number = &getline($_); } elsif (/^>Category:/) { $cat = &getline($_); } elsif (/^>Synopsis:/) { $syn = &getline($_); $syn =~ s/[\t]+/ /g; $origsyn = $syn; $syn = &fixline($syn); print &html_header("Problem Report $cat/$number : $syn"); + if (! $codeok ) { + print "

View PR with email + addresses

\n"; + } print "

$syn

\n
\n"; } else { next if $inhdr; if (/^>(\S+):\s*(.*)/) { print $trailer . "\n" unless ($blank); $trailer = "
$1
\n"; if ($html_fixup) { $trailer .= &fixline($2); } else { $trailer .= $2; } - if ($1 eq "Originator" && $from ne "") { # add email address + if ($1 eq "Originator" && $from ne "" && $codeok) { # add email address $trailer .= " <" . &fixline($from) . ">"; } $trailer .= '
'; $blank = !($2); $multiline = 0; } else { unless ($multiline) { next if /^\s*$/; print $trailer . "\n
\n";
 	    }
 	    $multiline = 1;
 	    $blank = 0;
 	    print $html_fixup ? &fixline($_) : $_ , "\n";
 	    $trailer = "
"; } } } close(Q); print "$trailer\n" unless ($blank); print "
"; $origsyn =~ s/[^a-zA-Z+.@-]/"%" . sprintf("%02X", unpack("C", $&))/eg; $email =~ s/[^a-zA-Z+.@-]/"%" . sprintf("%02X", unpack("C", $&))/eg; print qq`Submit Followup | Raw PR | Find Another PR\n`; +if (! $codeok ) { + print ""; + print "

To see this PR with email addresses "; + print " displayed, enter the code from the image and submit: \n"; + print "

\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "

\n"; +} + print &html_footer; # Sleep 0.35 seconds to avoid DoS attacks from broken robots select undef, undef, undef, 0.35; exit 0; sub getline { local($_) = @_; ($tag,$remainder) = split(/\s+/, $_, 2); return $remainder; } sub summary_link { return qq`

Search for Another PR

\n`; } sub cvsweb { local($file) = shift; $file =~ s/[,.;]$//; return 'http://cvsweb.FreeBSD.org/' . $file; } sub srcref { local($_) = shift; local($rev) = '(rev\.?|revision):?\s+[0-9]\.[0-9.]+(\s+of)?'; local($src) = '((src|www|doc|ports)/[^\s]+)'; if (m%$rev\s*$src%oi || m%$src\s*$rev%) { s#$src#sprintf("%s", 34, &cvsweb($1), 34, $1)#ge; } return $_; } sub fixline { local(@splitline) = split(/((?:https?|ftp):\/\/[^\s"\(\)<>,;]+)/, shift); local($isurl) = 0; foreach (@splitline) { if ($isurl) { local($href) = local($html) = $_; $href =~ s/&/%26/g; $html =~ s/&/&/g; $_ = "$html"; } else { s/&/&/g; s//>/g; s%(\WPR[:s# \t]+)([a-z3486]+\/)?([0-9]+)%$1$2$3%ig; } $isurl = ! $isurl; } return &srcref(join('', @splitline)); } diff --git a/en/cgi/querypr-code.cgi b/en/cgi/querypr-code.cgi new file mode 100755 index 0000000000..671183b172 --- /dev/null +++ b/en/cgi/querypr-code.cgi @@ -0,0 +1,84 @@ +#!/usr/bin/perl -T +# +# $FreeBSD$ +# +# Cribbed from sendpr-code.cgi, which is: +# Copyright (c) 2003 Eric Anderson + +use DB_File; +use Fcntl qw(:DEFAULT :flock); +use strict; + +$ENV{"PATH"} = "/bin:/usr/bin"; +$ENV{"TMPDIR"} = "/tmp"; + +my($fd, $db_obj, %db_hash, $currenttime, $randomcode, $pngbindata, $randompick, $pnmlist, $i); +my($expiretime, $pnmcat, $pnmtopng, $pnmdatadir, $dbpath); + +############################################ +# generate 8 character code from A-Z0-9 (no I,O,0,1 for clarity) +my @availchars = qw(A B C D E F G H J K L M N P Q R S T U V W X Y Z + 2 3 4 5 6 7 8 9); + +$pnmcat = "/usr/local/bin/pnmcat"; +$pnmtopng = "/usr/local/bin/pnmtopng"; +$pnmdatadir = "../gifs/"; +$dbpath = "/tmp/querypr-code.db"; +$expiretime = 2700; # seconds until code expires +############################################ + +$currenttime = time(); + +# DB stuff here +$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644) + or die "dbcreate $dbpath $!"; +$fd = $db_obj->fd; +open(DB_FH, "+<&=$fd") or die "fdopen $!"; + +unless (flock (DB_FH, LOCK_EX | LOCK_NB)) { + unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" } +} + +&gencode; + +while ($db_hash{$randomcode}) { + # it already exists so: + # we check age (over x seconds old?) + # if it is, override with new date + # if not, generate a new code + if ( ($currenttime - $expiretime) <= $db_hash{$randomcode}) { + &gencode; + } else { + delete $db_hash{"$randomcode"}; + } +} + +$db_hash{$randomcode} = $currenttime; + +$db_obj->sync(); # to flush +flock(DB_FH, LOCK_UN); +undef $db_obj; # removing the last reference to the DB + # closes it. Closing DB_FH is implicit. +untie %db_hash; + +$/ = ""; + +open(BUILDPNG, "$pnmcat -lr $pnmlist | $pnmtopng 2>/dev/null |"); +$pngbindata = ; +print "Pragma: no-cache\n"; +print "Content-type: image/png\n\n"; +print "$pngbindata"; +close(BUILDPNG); + +############################################ +sub gencode { + srand( time() ^ ($$ + ($$ << 15)) ); + + for ($i = 0; $i < 8; $i++) { + $randompick = $availchars[int(rand(@availchars))]; + $randomcode .= "$randompick"; + $pnmlist .= "$pnmdatadir$randompick\.pnm "; + } +} + +