Beta release 4.39.4
Julian Field
MailScanner at ecs.soton.ac.uk
Thu Mar 3 08:52:36 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. ]
Rick Cooper wrote:
>>-----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;
> }
> }
>
That looks great thanks. Now how do I tell which files were the result
of the unrar expansion?
------------------------ 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