=head1 SYNOPSIS
- [options]
+ local-debbugs [options]
Options:
--mirror, -M update local mirror
use User;
use Config::Simple;
+use File::Basename qw(dirname);
use File::Temp qw(tempdir);
use Params::Validate qw(validate_with :types);
use POSIX 'setsid';
-use Debbugs::Common qw(checkpid lockpid get_hashname);
-use Debbugs::Mail qw(get_addresses);
use SOAP::Lite;
use IPC::Run;
use IO::File;
use File::Path;
-
+use File::Spec;
my %options = (debug => 0,
help => 0,
verbose => 0,
quiet => 0,
detach => 1,
- cgi_bin => '/var/lib/debbugs/www/cgi',
- css => '/var/lib/debbugs/www/bugs.css',
+ git_mode => -d (dirname(__FILE__).'/../.git') ? 1 : 0,
bug_site => 'bugs.debian.org',
bug_mirror => 'bugs-mirror.debian.org',
);
);
GetOptions(\%options,
- 'daemon|D','show|s','search|select|S','mirror|M', 'stop',
+ 'daemon|D','show|s','search|select|S','mirror|M', 'stop|exit|quit',
'detach!',
'css=s','cgi_bin|cgi-bin|cgi=s',
'verbose|v+','quiet|q+',
'bug_mirror|bug-mirror=s',
'debug|d+','help|h|?','man|m');
+if ($options{git_mode}) {
+ my $base_dir = dirname(File::Spec->rel2abs(dirname(__FILE__)));
+ $options{cgi_bin} = "$base_dir/cgi" unless defined $options{cgi_bin};
+ $options{css} = "$base_dir/html/bugs.css" unless defined $options{css};
+ $options{template_dir} = "$base_dir/templates";
+ $options{base_dir} = $base_dir;
+ eval "use lib '$options{base_dir}'";
+} else {
+ $options{cgi_bin} = '/var/lib/debbugs/www/cgi';
+ $options{css} = '/var/lib/debbugs/www/bugs.css';
+ $options{template_dir} = "/usr/share/debbugs/templates";
+}
+
+eval "use Debbugs::Common qw(checkpid lockpid get_hashname)";
+eval "use Debbugs::Mail qw(get_addresses)";
+
pod2usage() if $options{help};
pod2usage({verbose=>2}) if $options{man};
my @USAGE_ERRORS;
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";
+ push @USAGE_ERRORS,"You must pass one (and only one) of --daemon --show --search --mirror or --stop";
}
$options{verbose} = $options{verbose} - $options{quiet};
print STDERR "Unable to determine if daemon is running: $!\n";
exit 1;
}
+ my $conf = IO::File->new($options{mirror_location}.'/debbugs_config_local','w') or
+ die "Unable to open $options{mirror_location}/debbugs_config_local for writing: $!";
+ print {$conf} <<"EOF";
+\$gConfigDir = "$options{mirror_location}";
+\$gSpoolDir = "$options{mirror_location}";
+\$gTemplateDir = "$options{template_dir}";
+\$gWebHost = 'localhost:$options{port}';
+\$gPackageSource = '$options{mirror_location}/sources';
+\$gPseudoDescFile = '';
+\$gPseudoMaintFile = '';
+\$gMaintainerFile = '$options{mirror_location}/Maintainers';
+\$gMaintainerFileOverride = '';
+\$config{source_maintainer_file} = '$options{mirror_location}/Source_maintainers';
+\$config{source_maintainer_file_override} = '';
+\$gProject = 'Local Debbugs';
+1;
+EOF
+ close $conf;
+ $ENV{DEBBUGS_CONFIG_FILE} = $options{mirror_location}.'/debbugs_config_local';
# ok, now lets daemonize
# XXX make sure that all paths have been turned into absolute
package local_debbugs::server;
use IO::File;
use HTTP::Server::Simple;
- use base qw(HTTP::Server::Simple::CGI);
+ use File::Basename qw(dirname);
+ use base qw(HTTP::Server::Simple::CGI HTTP::Server::Simple::CGI::Environment);
sub net_server {
return 'Net::Server::Fork';
sub handle_request {
my ($self,$cgi) = @_;
+ $ENV{DEBBUGS_CONFIG_FILE} = $options{mirror_location}.'/debbugs_config_local';
my $base_uri = 'http://'.$cgi->virtual_host;
if ($cgi->virtual_port ne 80) {
$base_uri .= ':'.$cgi->virtual_port;
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";
- }
+ my @exec_options = "$options{cgi_bin}/$1";
+ if ($options{git_mode}) {
+ unshift @exec_options,
+ 'perl','-I',$options{base_dir},'-T';
+ }
+ open(my $fh,'-|',@exec_options) or
+ die "Unable to execute $options{cgi_bin}/$1";
+ my $status;
+ my $cache = '';
+ while (<$fh>) {
+ if (/Status: (\d+\s+.+?)\n?$/) {
+ $status = $1;
+ print "HTTP/1.1 $status\n";
+ print STDERR "'$status'\n";
+ last;
+ }
+ $cache .= $_;
+ if (/^$/) {
+ print "HTTP/1.1 200 OK\n";
+ last;
+ }
+ }
+ print $cache;
+ print <$fh>;
+ close($fh) or die "Unable to close";
+ }
elsif ($path =~ m{^/?css/bugs.css}) {
my $fh = IO::File->new($options{css},'r') or
die "Unable to open $options{css} for reading: $!";
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 qq(Mr. T: "I pity da fool who tries to search for bugs without a running daemon"\n);
print STDERR "Hint: try the --daemon option first\n";
exit 1;
}
);
my ($output,$error) = ('','');
my $h = IPC::Run::start(['rsync',@{$param{options}}],
- \undef,\$output,\$error);
+ \undef,$param{log},$param{log});
while ($h->pump) {
- print {$param{log}} $output,$error;
#print {$param{debug}} $error if defined $param{debug};
}
$h->finish();
elsif (/\s\w+\:/) {
push @bug_selections, $_;
}
- }
+ }
}
# Split archive:both into archive:1 and archive:0
@bug_selections =
$bugs{$archived_bugs}{$_} = 1 for @{$bugs};
}
}
+ for my $bug (@bugs) {
+ $bugs{archived}{$bug} = 1;
+ $bugs{unarchived}{$bug} = 1;
+ }
return \%bugs;
}
__END__
+# Local Variables:
+# cperl-indent-level: 4
+# indent-tabs-mode: nil
+# End: