From: Don Armstrong Date: Thu, 18 Sep 2008 02:59:16 +0000 (-0700) Subject: support search, show, stop, and daemon options in local-debbugs X-Git-Tag: release/2.6.0~472^2~3 X-Git-Url: https://git.donarmstrong.com/?p=debbugs.git;a=commitdiff_plain;h=de4779cf60c52ae4881250b2a7b4e560d35b8d37 support search, show, stop, and daemon options in local-debbugs --- diff --git a/bin/local-debbugs b/bin/local-debbugs index bb93783..86f83a9 100755 --- a/bin/local-debbugs +++ b/bin/local-debbugs @@ -89,12 +89,17 @@ use User; use Config::Simple; use File::Temp qw(tempdir); use Params::Validate qw(validate_with :types); +use POSIX 'setsid'; +use Debbugs::Common qw(checkpid lockpid); my %options = (debug => 0, help => 0, man => 0, verbose => 0, quiet => 0, + detach => 1, + cgi_bin => '/var/lib/debbugs/www/cgi-bin', + css => '/var/lib/debbugs/www/bugs.css', ); my %option_defaults = (port => 8080, @@ -104,7 +109,9 @@ my %option_defaults = (port => 8080, ); GetOptions(\%options, - 'daemon|D','show|s','search|select|S','mirror|M', + 'daemon|D','show|s','search|select|S','mirror|M', 'stop', + 'detach!', + 'css=s','cgi_bin|cgi-bin|cgi=s', 'verbose|v+','quiet|q+', 'debug|d+','help|h|?','man|m'); @@ -114,7 +121,7 @@ pod2usage({verbose=>2}) if $options{man}; $DEBUG = $options{debug}; my @USAGE_ERRORS; -if (1 != scalar @options{qw(daemon show search mirror)}) { +if (1 != grep {exists $options{$_}} qw(daemon show search mirror stop)) { push @USAGE_ERRORS,"You must pass one (and only one) of --daemon --show --search or --mirror"; } $options{verbose} = $options{verbose} - $options{quiet}; @@ -128,6 +135,131 @@ local_config(\%options); if ($options{daemon}) { # daemonize, do stuff + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (defined $pid and $pid != 0) { + print STDERR "Unable to start daemon; it's already running\n"; + exit 1; + } + if (-e $options{mirror_location}.'/local-debbugs.pid' and + not defined $pid) { + print STDERR "Unable to determine if daemon is running: $!\n"; + exit 1; + } + # ok, now lets daemonize + + # XXX make sure that all paths have been turned into absolute + # paths + chdir '/' or die "Can't chdir to /: $!"; + # allow us not to detach for debugging + if ($options{detach}) { + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, '>/dev/null' + or die "Can't write to /dev/null: $!"; + defined(my $pid = fork) or die "Can't fork: $!"; + exit if $pid; + setsid or die "Can't start a new session: $!"; + open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; + } + lockpid($options{mirror_location}.'/local-debbugs.pid') or + die "Unable to deal with the pidfile"; + # this is the subclass of HTTP::Server::Simple::CGI which handles + # the "hard" bits of actually running a tiny webserver for us + { + package local_debbugs::server; + use IO::File; + use HTTP::Server::Simple; + use base qw(HTTP::Server::Simple::CGI); + + sub net_server { + return 'Net::Server::Fork'; + } + + sub redirect { + my ($cgi,$url) = @_; + print "HTTP/1.1 302 Found\r\n"; + print "Location: $url\r\n"; + } + + # here we want to call cgi-bin/pkgreport or cgi-bin/bugreport + sub handle_request { + my ($self,$cgi) = @_; + + my $base_uri = 'http://'.$cgi->virtual_host; + if ($cgi->virtual_port ne 80) { + $base_uri .= ':'.$cgi->virtual_port; + } + my $path = $cgi->path_info(); + # RewriteRule ^/[[:space:]]*#?([[:digit:]][[:digit:]][[:digit:]]+)([;&].+)?$ /cgi-bin/bugreport.cgi?bug=$1$2 [L,R,NE] + if ($path =~ m{^/?\s*\#?(\d+)((?:[;&].+)?)$}) { + redirect($cgi,$base_uri."/cgi-bin/bugreport.cgi?bug=$1$2"); + } + # RewriteRule ^/[Ff][Rr][Oo][Mm]:([^/]+\@.+)$ /cgi-bin/pkgreport.cgi?submitter=$1 [L,R,NE] + elsif ($path =~ m{^/?\s*from:([^/]+\@.+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?submitter=$1"); + } + # RewriteRule ^/([^/]+\@.+)$ /cgi-bin/pkgreport.cgi?maint=$1 [L,R,NE] + elsif ($path =~ m{^/?\s*([^/]+\@.+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?maint=$1"); + } + # RewriteRule ^/mbox:([[:digit:]][[:digit:]][[:digit:]]+)([;&].+)?$ /cgi-bin/bugreport.cgi?mbox=yes&bug=$1$2 [L,R,NE] + elsif ($path =~ m{^/?\s*mbox:\#?(\d+)((?:[;&].+)?)$}i) { + redirect($cgi,$base_uri."/cgi-bin/bugreport.cgi?mbox=yes;bug=$1$2"); + } + # RewriteRule ^/src:([^/]+)$ /cgi-bin/pkgreport.cgi?src=$1 [L,R,NE] + elsif ($path =~ m{^/?src:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?src=$1"); + } + # RewriteRule ^/severity:([^/]+)$ /cgi-bin/pkgreport.cgi?severity=$1 [L,R,NE] + elsif ($path =~ m{^/?severity:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?severity=$1"); + } + # RewriteRule ^/tag:([^/]+)$ /cgi-bin/pkgreport.cgi?tag=$1 [L,R,NE] + elsif ($path =~ m{^/?tag:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?tag=$1"); + } + # RewriteRule ^/([^/]+)$ /cgi-bin/pkgreport.cgi?pkg=$1 [L,R,NE] + elsif ($path =~ m{^/?([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?pkg=$1"); + } + elsif ($path =~ m{^/?cgi(?:-bin)?/((?:(?:bug|pkg)report|version)\.cgi)}) { + # dispatch to pkgreport.cgi + print "HTTP/1.1 200 OK\n"; + exec("$options{cgi_bin}/$1") or + die "Unable to execute $options{cgi_bin}/$1"; + } + elsif ($path =~ m{^/?css/bugs.css}) { + my $fh = IO::File->new($options{css},'r') or + die "Unable to open $options{css} for reading: $!"; + print "HTTP/1.1 200 OK\n"; + print "Content-type: text/css\n"; + print "\n"; + print <$fh>; + } + elsif ($path =~ m{^/?$}) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?package=put%20package%20here"); + } + else { + print "HTTP/1.1 404 Not Found\n"; + print "Content-Type: text/html\n"; + print "\n"; + print "

That which you were seeking, found I have not.

\n"; + } + # RewriteRule ^/$ /Bugs/ [L,R,NE] + } + } + my $debbugs_server = local_debbugs::server->new($options{port}) or + die "Unable to create debbugs server"; + $debbugs_server->run() or + die 'Unable to run debbugs server'; +} +elsif ($options{stop}) { + # stop the daemon + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + exit 1; + } + exit !(kill(15,$pid) == 1); } elsif ($options{mirror}) { # run the mirror jobies @@ -180,6 +312,7 @@ elsif ($options{mirror}) { options => [@common_rsync_options, '--exclude','*old', '--exclude','*.bak', + '--exclude','by-reverse*', 'rsync://'.$options{bug_mirror}.'/bts-spool-index/', $options{mirror_location}.'/', ], @@ -197,9 +330,33 @@ elsif ($options{mirror}) { ); } elsif ($options{show}) { - + # figure out the url + # see if the daemon is running + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + print STDERR qq(Mr. T: "I pity da fool who tries to show a bug without a running daemon"\n); + print STDERR "Hint: try the --daemon option first\n"; + exit 1; + } + # twist and shout + my $url = qq(http://localhost:$options{port}/$ARGV[0]); + exec('/usr/bin/sensible-browser',$url) or + die "Unable to run sensible-browser (try feeding me cheetos?)"; } elsif ($options{search}) { + my $url = qq(http://localhost:$options{port}/cgi-bin/pkgreport.cgi?). + join(';',map {if (/:/) {s/:/=/; $_;} else {qq(pkg=$_);}} @ARGV); + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + print STDERR qq(Mr. T: "I pity da fool who tries to show a bug without a running daemon"\n); + print STDERR "Hint: try the --daemon option first\n"; + exit 1; + } + # twist and shout + exec('/usr/bin/sensible-browser',$url) or + die "Unable to run sensible-browser (Maybe chorizo is required?)"; } else { # you get here, you were an idiot in checking for @USAGE_ERRORS