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