Operating System - HP-UX
1754836 Members
4496 Online
108825 Solutions
New Discussion

webmin / perl cgi scripts

 
SOLVED
Go to solution
John de Villiers
Frequent Advisor

webmin / perl cgi scripts

Im trying to call an OS command from within a cgi ( PERL ) script and then output the result to the browser.

If i run via the commandline it works and i get the result, but it takes a while ( approx 30 secs ).

When i call the same command from within the script i never see the result. I can see the command being executed though, but i think a timeout is preventing the thing from showing me the result.

the command looks like follows
local $out = system("/opt/ssh/bin/ssh -t sshuser@hostname '/opt/sudo/bin/sudo /opt/omni/lbin/statd /dev/scsi/ESL9000'");
print $out;


The command gets a list of the drive contents.
SSH has been setup for keyed logins and works just fine.
The script "statd" does a call to uma and passes the command "stat d" via STDIN.

Like i said, if i take that command and run it manually i get the result i want.

Any Ideas on how to increase the timeout ?
1 REPLY 1
Ralph Grothe
Honored Contributor
Solution

Re: webmin / perl cgi scripts

Perl's system() call ideed will pass the command for execution to either the shell, or the OS (depending on context of its args).
But it won't dump the command's output.
Instead what you get is the exit value of the intrinsic wait() call (you can get the command's exit value by an 8 byte right shift).
What you need to dump the command's output in the HTML markup of your CGI script would be to open a pipe and read from this pipe.
This can be accomplished in many ways (following Perl's TIMTOWTDI; another method could be using backticks which set up the pipe implicitly for you, but gives less control and thus less security).
The easiest way to set up the pipe is an open() call with a trailing pipe character.

e.g.

my $cmdstr = '/opt/ssh/bin/ssh ...';
open MYPIPE, "$cmd |" or die "cannot pipe from ssh: $!";
while () {
# parse output here
}
close MYPIPE;

Be careful if the content of $cmd above is derirved from user input.
Then it is called to be "tainted", and can pose a security hazard because $cmd is parsed and executed through the shell.

To avoid this you could fork() and exec() and set up your pipe manually.
But there is a nice feature of the open() call that even relieves you from setting up the pipe while giving you the liberty of forking.

e.g.

my $pid = open MYPIPE, '-|';
die "cannot fork: $!" unless defined $pid;
if ($pid) { # parent's block
while () {
# parse output from child here
} else { # child's block
# do some untainting here, e.g. setting up %ENV
exec '/opt/ssh/bin/ssh', qw(other args to command);
die "oops, exec failed";
}
close MYPIPE; # parent will block until it closes the pipe


All this IPC stuff is much better explained in
"perldoc perlipc"
"perldoc perlopentut"
Madness, thy name is system administration