--- /dev/null
+#! /usr/bin/perl
+# local-debbugs is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later version, at your
+# option. See the file README and COPYING for more information.
+# Copyright 2008 by Don Armstrong <don@donarmstrong.com>.
+
+
+use warnings;
+use strict;
+
+use Getopt::Long;
+use Pod::Usage;
+
+=head1 NAME
+
+local-debbugs - use a local mirror of debbugs
+
+=head1 SYNOPSIS
+
+ [options]
+
+ Options:
+ --mirror, -M update local mirror
+ --daemon, -D start the daemon
+ --search, -S run a search
+ --show, -s show a bug
+ --debug, -d debugging level (Default 0)
+ --help, -h display this help
+ --man, -m display manual
+
+=head1 OPTIONS
+
+=over
+
+=item B<--mirror, -M>
+
+Update the local mirror of debbugs bugs
+
+=item B<--daemon, -D>
+
+Start up the daemon on the configured local port to serve bugs which
+have been previously retried
+
+=item B<--search, -S>
+
+Cause the running daemon to show the pkgreport.cgi page corresponding
+to the search by invoking sensible-browser and an appropriate url
+
+=item B<--show, -s>
+
+Cause the running daemon to show the bugreport.cgi page corresponding
+to the bug by invoking sensible-browser and an appropriate url
+
+=item B<--port,-p>
+
+The port that the daemon is running on (or will be running on.)
+
+Defaults to the value of the currently running daemon, the value in
+the configuration file, or 8080 if nothing is set.
+
+=item B<--bugs-to-get>
+
+File which contains the set of bugs to get.
+Defaults to ~/.debbugs/bugs_to_get
+
+=item B<--debug, -d>
+
+Debug verbosity. (Default 0)
+
+=item B<--help, -h>
+
+Display brief useage information.
+
+=item B<--man, -m>
+
+Display this manual.
+
+=back
+
+=head1 EXAMPLES
+
+
+=cut
+
+
+use vars qw($DEBUG);
+
+use User;
+use Config::Simple;
+use File::Temp qw(tempdir);
+
+my %options = (debug => 0,
+ help => 0,
+ man => 0,
+ );
+
+my %option_defaults = (port => 8080,
+ debbugs_config => User->Home.'/.debbugs/debbugs_config',
+ mirror_location => User->Home.'/.debbugs/mirror/',
+ bugs_to_get => User->Home.'/.debbugs/bugs_to_get',
+ );
+
+GetOptions(\%options,
+ 'daemon|D','show|s','search|select|S','mirror|M',
+ 'debug|d+','help|h|?','man|m');
+
+pod2usage() if $options{help};
+pod2usage({verbose=>2}) if $options{man};
+
+$DEBUG = $options{debug};
+
+my @USAGE_ERRORS;
+if (1 != scalar @options{qw(daemon show search mirror)}) {
+ push @USAGE_ERRORS,"You must pass one (and only one) of --daemon --show --search or --mirror";
+}
+
+pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
+
+
+# munge in local configuration
+
+local_config(\%options);
+
+if ($options{daemon}) {
+ # daemonize, do stuff
+}
+elsif ($options{mirror}) {
+ # run the mirror jobies
+ # figure out which bugs we need
+ my @bugs = select_bugs();
+ # get them
+ my $tempdir = tempdir(CLEANUP => 1);
+ my $mirror_log = IO::File->new($options{mirror_location}.'/mirror.log') or
+ die "Unable to open $options{mirror_location}/mirror.log for writing: $!";
+ my $inc_fh = IO::File->new("$tempdir/include_list",'w') or
+ die "Unable to open $tempdir/include_list for writing: $!";
+ foreach my $bug (@bugs) {
+ print {$inc_fh} "*/${bugs}.*\n" or
+ die "Unable to write to $tempdir/include_list: $!";
+ }
+ close $inc_fh or
+ die "Unable to close $tempdir/include_list: $!";
+ my ($wrf,$rfh);
+ run_rsync(log => $mirror_log,
+ ($options{debug}?(debug => \*STDERR):()),
+ options => ['-avz','--partial',
+ '--delete',
+ '--include-from',"$tempdir/include_list",
+ # skip things not specifically included
+ '--exclude','*/*',
+ # skip the -1,-2,-3.log files
+ '--exclude','*.log',
+ 'rsync://'.$options{bug_mirror}.'/bts-spool-db/',
+ $options{mirror_location}.'/db-h/']
+ );
+
+
+
+
+}
+elsif ($options{show}) {
+
+}
+elsif ($options{search}) {
+}
+else {
+ # you get here, you were an idiot in checking for @USAGE_ERRORS
+ # above
+ die "No option that we understand was passed (the first check for this is now buggy, so shoot your maintainer)"
+}
+
+
+# determine the local configuration
+sub local_config{
+ my ($options) = @_;
+ my $config = {};
+ if (-e '/etc/debbugs/local_debbugs.conf') {
+ Config::Simple->import_from('/etc/debbugs/local_debbugs.conf', $config) or
+ die "Unable to read configuration from /etc/debbugs/local_debbugs.conf: $!";
+ }
+ if (-e User->Home.'/.debbugs/local_debbugs.conf') {
+ Config::Simple->import_from(User->Home.'/.debbugs/local_debbugs.conf', $config) or
+ die "Unable to read configuration from ".User->Home.'/.debbugs/local_debbugs.conf: '.$!;
+ }
+ for (keys %default_options) {
+ if (exists $config->{$_} and not defined $options->{$_}) {
+ $options->{$_} = $config->{$_};
+ }
+ if (not defined $options->{$_}) {
+ $options->{$_} = $default_options{$_};
+ }
+ }
+}
+
+sub run_rsync{
+ my ($output_fh,@rsync_options) = @_;
+ my ($wfh,$rfh);
+ my $pid = open3($wfh,$rfh,
+ 'rsync',
+ @rsync_options,
+ ) or die "Unable to start rsync: $!";
+ close $wfh or die "Unable to close the writer filehandle $?";
+ print {$output_fh}
+
+
+}
+
+
+__END__