2004-04-30 05:40:40 +04:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
|
|
package Doctor;
|
|
|
|
require Exporter;
|
|
|
|
@ISA = qw(Exporter);
|
2006-05-02 21:46:07 +04:00
|
|
|
@EXPORT_OK = qw(%CONFIG); # symbols to export on request
|
2004-04-30 05:40:40 +04:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
use File::Temp qw(tempfile tempdir);
|
|
|
|
use Template;
|
|
|
|
use AppConfig qw(:expand :argcount);
|
2006-05-02 21:46:07 +04:00
|
|
|
use CGI;
|
2006-05-03 02:34:11 +04:00
|
|
|
use Cwd qw(getcwd);
|
2004-04-30 05:40:40 +04:00
|
|
|
|
|
|
|
# Create an AppConfig object and populate it with parameters defined
|
|
|
|
# in the configuration file.
|
|
|
|
# Note: Look in the configuration file for descriptions of each parameter.
|
2004-05-07 06:30:25 +04:00
|
|
|
our $config = AppConfig->new({
|
2004-04-30 05:40:40 +04:00
|
|
|
CASE => 1,
|
|
|
|
CREATE => 1 ,
|
2004-05-07 06:30:25 +04:00
|
|
|
GLOBAL => { ARGCOUNT => ARGCOUNT_ONE }
|
|
|
|
});
|
2004-04-30 05:40:40 +04:00
|
|
|
$config->file("doctor.conf");
|
|
|
|
our %CONFIG = $config->varlist(".*");
|
|
|
|
|
2006-05-02 21:46:07 +04:00
|
|
|
# Create the global template object that processes templates and specify
|
|
|
|
# configuration parameters that apply to templates processed in this script.
|
|
|
|
my $_template;
|
|
|
|
sub template {
|
|
|
|
my $class = shift;
|
|
|
|
# INCLUDE_PATH is a colon-separated list of directories containing templates.
|
2006-05-03 02:34:11 +04:00
|
|
|
$_template ||= Template->new({INCLUDE_PATH => getcwd() . "/templates",
|
2006-05-02 21:46:07 +04:00
|
|
|
PRE_CHOMP => 1,
|
|
|
|
POST_CHOMP => 1});
|
|
|
|
return $_template;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $_cgi;
|
|
|
|
sub cgi {
|
|
|
|
my $class = shift;
|
|
|
|
$_cgi ||= new CGI();
|
|
|
|
return $_cgi;
|
|
|
|
}
|
2004-04-30 05:40:40 +04:00
|
|
|
|
|
|
|
sub system_capture {
|
2004-05-07 06:30:25 +04:00
|
|
|
# Runs a command and captures its output and errors. This should be using
|
|
|
|
# in-memory files, but they require that we close STDOUT and STDERR
|
|
|
|
# before reopening them on the in-memory files, and closing and reopening
|
|
|
|
# STDERR causes CVS to choke with return value 256.
|
|
|
|
|
|
|
|
my ($command, @args) = @_;
|
|
|
|
|
|
|
|
my ($rv, $output, $errors);
|
|
|
|
|
|
|
|
# Back up the original STDOUT and STDERR so we can restore them later.
|
|
|
|
open(OLDOUT, ">&STDOUT") or die "Can't back up STDOUT to OLDOUT: $!";
|
|
|
|
open(OLDERR, ">&STDERR") or die "Can't back up STDERR to OLDERR: $!";
|
2004-05-07 07:50:56 +04:00
|
|
|
use vars qw( *OLDOUT *OLDERR ); # suppress "used only once" warnings
|
2004-05-07 06:30:25 +04:00
|
|
|
|
|
|
|
# Close and reopen STDOUT and STDERR to in-memory files, which are just
|
|
|
|
# scalars that take output and append it to their value.
|
|
|
|
# XXX Disabled in-memory files in favor of temp files until in-memory issues
|
|
|
|
# can be worked out.
|
2004-05-07 07:50:56 +04:00
|
|
|
#close(STDOUT);
|
|
|
|
#close(STDERR);
|
|
|
|
#open(STDOUT, ">", \$output) or die "Can't open STDOUT to output var: $!";
|
|
|
|
#open(STDERR, ">", \$errors) or die "Can't open STDERR to errors var: $!";
|
2004-05-07 06:30:25 +04:00
|
|
|
my $outfile = tempfile();
|
|
|
|
my $errfile = tempfile();
|
2004-05-07 07:50:56 +04:00
|
|
|
# Perl 5.6.1 filehandle duplication doesn't support the three-argument form
|
|
|
|
# of open, so we can't just open(STDOUT, ">&", $outfile); instead we have to
|
|
|
|
# create an alias OUTFILE and then do open(STDOUT, ">&OUTFILE").
|
2004-05-07 08:08:28 +04:00
|
|
|
local *OUTFILE = *$outfile;
|
|
|
|
local *ERRFILE = *$errfile;
|
2004-05-07 07:50:56 +04:00
|
|
|
use vars qw( *OUTFILE *ERRFILE ); # suppress "used only once" warnings
|
|
|
|
open(STDOUT, ">&OUTFILE") or open(STDOUT, ">&OLDOUT")
|
|
|
|
and die "Can't dupe STDOUT to output file: $!";
|
|
|
|
open(STDERR, ">&ERRFILE") or open(STDOUT, ">&OLDOUT")
|
|
|
|
and open(STDERR, ">&OLDERR")
|
|
|
|
and die "Can't dupe STDERR to errors file: $!";
|
2004-05-07 06:30:25 +04:00
|
|
|
|
|
|
|
# Run the command.
|
|
|
|
$rv = system($command, @args);
|
|
|
|
|
|
|
|
# Grab output and errors from the temp files. In a block to localize $/.
|
|
|
|
# XXX None of this would be necessary if in-memory files was working.
|
|
|
|
{
|
|
|
|
local $/ = undef;
|
|
|
|
seek($outfile, 0, 0);
|
|
|
|
seek($errfile, 0, 0);
|
|
|
|
$output = <$outfile>;
|
|
|
|
$errors = <$errfile>;
|
|
|
|
}
|
2004-05-07 07:50:56 +04:00
|
|
|
|
2004-05-07 06:30:25 +04:00
|
|
|
# Restore original STDOUT and STDERR.
|
|
|
|
close(STDOUT);
|
|
|
|
close(STDERR);
|
|
|
|
open(STDOUT, ">&OLDOUT") or die "Can't restore STDOUT from OLDOUT: $!";
|
|
|
|
open(STDERR, ">&OLDERR") or die "Can't restore STDERR from OLDERR: $!";
|
2004-05-07 07:50:56 +04:00
|
|
|
|
2004-05-07 06:30:25 +04:00
|
|
|
return ($rv, $output, $errors);
|
2004-04-30 05:40:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
1; # so the require or use succeeds
|