Beta release 4.39.4
Rick Cooper
rcooper at DWFORD.COM
Wed Mar 2 23:07:55 GMT 2005
[ The following text is in the "iso-8859-1" character set. ]
[ Your display is set for the "US-ASCII" character set. ]
[ Some characters may be displayed incorrectly. ]
> -----Original Message-----
> From: MailScanner mailing list [mailto:MAILSCANNER at JISCMAIL.AC.UK]On
> Behalf Of Julian Field
> Sent: Wednesday, March 02, 2005 9:18 AM
> To: MAILSCANNER at JISCMAIL.AC.UK
> Subject: Re: Beta release 4.39.4
>
>
> I always try to at least reply, but good ideas do get lost sometimes.
> The unrar code would require another timeout wrapper round it, which I
> would have to copy from elsewhere, so it isn't trivial.
> I can't remember if I came up with a solution to the duplicated
> filenames problem or not, it was quite a long time ago.
>
<snip>
How about this for a timeout wrapper. It should work as a general purpose
wrapper for commands that use system or backticks. I put it together from
code you use eleswhere. So a line like:
$unrar =`which unrar`;
return 0 unless $unrar !~ /no unrar in)/i && $unrar ne "";
would be $unrar = SafePipe("which unrar",30,"ST");
return 0 unless $unrar !~ /(no unrar in|^COMMAND_TIMED_OUT$)/i &&
$unrar ne "";
and
system("$unrar e -p- -idp $safename 2>&1");
unless ("$?" == 0 && !$IsEncrypted) {
would be
unless (RcSafePipe("$unrar e -p- -idp $safename 2>&1",30,"EC") == 0 &&
!$IsEncrypted) {
It appears to work fine, and handles the time out fine as well.
Rick
sub SafePipe{
# Modified Julian's code from SweepOther.pm
# Changed to allow execution of a given command line with a time
# control
#
# $Cmd = command line to execute
# $timeout = max time in seconds to allow execution
# $ReturnType = ST For String or Anything else for error code
#
# Replaces backtick or system calls that are looking for both
# string output or an error code
my ($Cmd, $TimeOut,$ReturnType) = @_;
my($Kid, $pid, $TimedOut, $PipeReturn, $Str);
$Kid = new FileHandle;
$TimedOut = 0;
eval {
die "Can't fork: $!" unless defined($pid = open($Kid, '-|'));
if ($pid) {
# In the parent
local $SIG{ALRM} = sub { $TimedOut = 1; die "Command Timed Out" };
alarm $TimeOut;
# Only process the output if we are scanning, not disinfecting
while(<$Kid>) {
$Str .= $_;
#print STDERR "Processing line \"$_\"\n";
}
close $Kid;
$PipeReturn = $?;
$pid = 0; # 2.54
alarm 0;
# Workaround for bug in perl shipped with Solaris 9,
# it doesn't unblock the SIGALRM after handling it.
eval {
my $unblockset = POSIX::SigSet->new(SIGALRM);
sigprocmask(SIG_UNBLOCK, $unblockset)
or die "Could not unblock alarm: $!\n";
};
} else {
# In the child
POSIX::setsid();
# for testing time out
# sleep 40; exec $Cmd;
MailScanner::Log::WarnLog("Can't run $Cmd command! ");
exit 1;
}
};
alarm 0; # 2.53
# Note to self: I only close the KID in the parent, not in the child.
MailScanner::Log::DebugLog("Completed $Cmd");
# Catch failures other than the alarm
MailScanner::Log::DieLog("$Cmd failed with real error: $@")
if $@ and $@ !~ /Command Timed Out/;
#print STDERR "pid = $pid and \@ = $@\n";
# In which case any failures must be the alarm
if ($@ or $pid>0) {
# Kill the running child process
my($i);
kill -15, $pid;
# Wait for up to 5 seconds for it to die
for ($i=0; $i<5; $i++) {
sleep 1;
waitpid($pid, &POSIX::WNOHANG);
($pid=0),last unless kill(0, $pid);
kill -15, $pid;
}
# And if it didn't respond to 11 nice kills, we kill -9 it
if ($pid) {
kill -9, $pid;
waitpid $pid, 0; # 2.53
}
}
# Return failure if the command timed out, otherwise return success
if ($TimedOut){
MailScanner::Log::WarnLog("$Cmd timed out!");
return "COMMAND_TIMED_OUT";
}
if($ReturnType eq "ST"){
return $Str;
}else{
return $PipeReturn;
}
}
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
------------------------ MailScanner list ------------------------
To unsubscribe, email jiscmail at jiscmail.ac.uk with the words:
'leave mailscanner' in the body of the email.
Before posting, read the MAQ (http://www.mailscanner.biz/maq/) and
the archives (http://www.jiscmail.ac.uk/lists/mailscanner.html).
Support MailScanner development - buy the book off the website!
More information about the MailScanner
mailing list