# -------------------------------------------------------------------------------------
# lib::util::Command
# -------------------------------------------------------------------------------------
#
#       Author : Jean-Michel Hiver (jhiver@cisedi.com).
#    Copyright : (c) Jean-Michel Hiver, 2001.
# 
#      Unauthorized modification, use, reuse, distribution or redistribution
#      of this module is stricly forbidden.
#
#    Description:
#
#      A horrible hack that allows to execute unix commands, pass them some
#      input, and grab the output and error data. Well, at least it's less
#      hassle to use compared with IPC::Open3
#
# -------------------------------------------------------------------------------------
package lib::util::Command;
use lib::Exception;
use Exporter;
use strict;
use vars qw /@ISA @EXPORT/;
@ISA = qw/Exporter/;
@EXPORT = qw /sysexec/;


sub sysexec($$$)
{
    my $cmd = shift;
    my $tmp_dir = shift;
    my $in  = shift;
    
    my $out = undef;
    my $err = undef;
    
    my $tmp = $$ . '.' . time . '.' . int (rand (10000));
    my $tmp_out = $tmp_dir . '/' . $tmp . '.out';
    my $tmp_err = $tmp_dir . '/' . $tmp . '.err';
    
    if (defined $in)
    {
	# executes the command and writes to temp files
	open FP, "|$cmd 2>$tmp_err >$tmp_out" or
	    throw (new lib::Exception (code => 'CANNOT_OPEN_PIPE',
				       info => "Cannot open pipe to $cmd: $!"));
	print FP $in;
	close FP;
    }
    else
    {
	# executes the command and writes to temp files
	system ("$cmd 2>$tmp_err >$tmp_out") or
	    throw (new lib::Exception (code => 'CANNOT_EXEC',
				       info => "Cannot exec $cmd: $!"));
	print FP $in;
	close FP;
    }
    
    # reads the command standard output
    open FP, "<$tmp_out" or
	throw (new lib::Exception (code => 'CANNOT_OPEN_FILE',
				   info => "Cannot open file $tmp_out: $!"));
    $out = join '', <FP>;
    close FP;
    
    # reads the command error output
    open FP, "<$tmp_err" or
	throw (new lib::Exception (code => 'CANNOT_OPEN_FILE',
				   info => "Cannot open file $tmp_err: $!"));
    $err = join '', <FP>;
    close FP;
    
    # tidy all the mess and returns $out and $err
    unlink $tmp_out;
    unlink $tmp_err;
    return ($out, $err);
}


1;
