simscan是配合qmail进行扫毒和垃圾邮件处理的接口程序,在扫毒和垃圾邮件处理之前,需要对经过编码的邮件解码,分离出附件等再进行扫描,这个事情就是由ripmime解决的。

而在simscan 1.4.0调用ripmime时,有个小问题.

先看代码,代码在simscan.c内的do_ripmime():

int run_ripmime()
{
int pid;
int rmstat;

/* fork ripmime */
switch(pid = vfork()) {
    case -1:
      return(-1);
    case 0:
     close(1);
     close(2);
     execl(RIPMIME, "ripmime", "–disable-qmail-bounce",
           "-i", message_name, "-d", NULL );
     _exit(-1);
}

   /* wait for ripmime to finish */
if (waitpid(pid,&rmstat, 0) == -1) {
     return(-1);
}

/* check if the child died on a signal */
if ( WIFSIGNALED(rmstat) ) {
     return(-1);
}

/* if it exited okay, return the status */
if ( WIFEXITED(rmstat) ) {
    return(WEXITSTATUS(rmstat));
}

/* should not reach here */
return(-1);
}

上面代码内的execl(RIPMIME, "ripmime", "–disable-qmail-bounce", "-i", message_name, "-d", NULL );就是调用ripmime的地方,这名相当于:
/usr/bin/ripmime –disable-qmail-bounce -i message_name -d

真正跑的时候会发现其实是错的,-d后面还需要加一个目录。
[root@fortelchina ~]# /usr/bin/ripmime –disable-qmail-bounce -i mail.eml -d            
ERROR: insufficient parameters after ‘-d’

调用代码改成:execl(RIPMIME, "ripmime", "–disable-qmail-bounce", "-i", message_name, "-d", workdir, NULL );

就好了。

完整函数如下,我加了些debug信息,以方便邮件出问题时追踪:

int run_ripmime()
{
int pid;
int rmstat;

if ( DebugFlag > 0 ) {
    fprintf(stderr, "simscan: calling ripmime.n");
}

/* fork ripmime */
switch(pid = vfork()) {
    case -1:
      if ( DebugFlag > 0 ) {
        fprintf(stderr, "simscan:vfork ripmime error.n");
      }
      return(-1);
    case 0:
     close(1);
     close(2);
     execl(RIPMIME, "ripmime", "–disable-qmail-bounce",
           "-i", message_name, "-d", workdir, NULL );
     _exit(-1);
}

   /* wait for ripmime to finish */
if (waitpid(pid,&rmstat, 0) == -1) {
     if ( DebugFlag > 0 ) {
       fprintf(stderr, "simscan: wait for ripmime to finish –error!n");
     }
     return(-1);
}

/* check if the child died on a signal */
if ( WIFSIGNALED(rmstat) ) {
     if ( DebugFlag > 0 ) {
       fprintf(stderr, "simscan: check if the child died on a signal,rmstat:%d,–error!n", WIFSIGNALED(rmstat));
     }
     return(-1);
}

/* if it exited okay, return the status */
if ( WIFEXITED(rmstat) ) {
     if ( DebugFlag > 0 ) {
       fprintf(stderr, "simscan: ripmime is done,return to simscan.n");
     }
    return(WEXITSTATUS(rmstat));
}

if ( DebugFlag > 0 ) {
     fprintf(stderr, "simscan: ripmime return -1!n");
}

/* should not reach here */
return(-1);
}

toaster包的更新方法:

先安装源码包:
rpm -ivh simscan-toaster-1.4.0-1.3.0.src.rpm

cd /usr/src/redhat/SOURCES/

tar -xvzf simscan-1.4.0.tar.gz

cd simscan-1.4.0

按上面的方法更改simscan.c文件。保存。

cd ..

rm simscan-1.4.0.tar.gz

tar -czf simscan-1.4.0.tar.gz simscan

编译:

rpmbuild -ba ../SPECS/simscan-toaster.spec

安装编译好的程序:

rpm -ivh /usr/src/redhat/RPMS/i386/simscan-toaster-1.4.0-1.3.0.i386.rpm