--- ./bin/incm.c.org 2005-10-19 13:58:21.000000000 +0900 +++ ./bin/incm.c 2005-12-16 13:53:10.000000000 +0900 @@ -77,6 +77,7 @@ private int PreserveUnixFrom; private int CreateMTime = TRUE; private int FileMode = S_IRUSR | S_IWUSR; +private char *CommandInboxFile = NULL; private int Exit = 0; /**************************************************************** @@ -98,6 +99,7 @@ private int maildir_names(const char *, char **, char **, char **); private int new_inbox_file(int, char[]); private FILE *open_new_inbox_file(int *, char[]); +private int process_inbox_file(char inboxfile[]); private int get_from_dir(int, char *, char *, int); private int process_maildir(int); private int lock_mbox(char *); @@ -207,9 +209,24 @@ #define MAILDIR_CUR "cur" #define MAILDIR_TMP "tmp" +#ifndef AV_COMMAND +#define AV_COMMAND "/opt/local/clamav/bin/clamdscan" +#endif + +#ifndef AV_COMMAND_NOMAIL +#define AV_COMMAND_NOMAIL "exec cat \"%1$s\" | "AV_COMMAND" --quiet -; test $? = 1 && rm -f \"%1$s\"" +#endif +#ifndef AV_COMMAND_NOBODY +#define AV_COMMAND_NOBODY "exec cat \"%1$s\" | "AV_COMMAND" --quiet -; test $? = 1 && (mv \"%1$s\" \"%1$s\".bak && sed -e '/^$/q' \"%1$s\".bak > \"%1$s\" && rm -f \"%1$s\".bak)" +#endif +#ifndef AV_COMMAND_AVBODY +#define AV_COMMAND_AVBODY "exec cat \"%1$s\" | "AV_COMMAND" --quiet --no-summary --log=\"%1$s\".log -; test $? = 1 && (mv \"%1$s\" \"%1$s\".bak && sed -e '/^$/{\nr%1$s.log\nq\n}' \"%1$s\".bak > \"%1$s\" && rm -f \"%1$s\".bak \"%1$s\".log)" +#endif + + private void usage(const char *progname) { - fprintf(stderr, "Usage: %s [-abchsv] [-d maildir] [-i inboxdir]\n", progname); + fprintf(stderr, "Usage: %s [-abchsvZz] [-d maildir] [-i inboxdir]\n", progname); } private const char * @@ -229,6 +246,7 @@ " -u Don't create inboxdir/.mew-mtime file.", " -f Preserve Unix From (Envelope Sender). (for mbox)", " -p Specify file permission. (for mbox)", + " -z|-Z Scan viral mail, and truncate body|delete the whole", NULL }; @@ -545,6 +563,27 @@ } private int +process_inbox_file(char inboxfile[]) +{ + char *command_f, command_s[PATH_MAX*10]; + int pid, status; + + if (!CommandInboxFile || !*CommandInboxFile) + return -1; + command_f = CommandInboxFile; + snprintf(command_s, sizeof(command_s), command_f, inboxfile); + if ((pid = fork()) < 0) + return -1; + else if (!pid) { + setsid(); + exit(execl("/bin/sh", "/bin/sh", "-c", command_s, NULL)); + } + if (waitpid(pid, &status, 0) < 0) + return -1; + return WIFEXITED(status) ? (WEXITSTATUS(status)==0?1:-1) : -1; +} + +private int get_from_dir(int seq, char *fromdir, char *backupdir, int backup) { struct stat sb; @@ -600,6 +639,7 @@ else movefile(mailfile, inboxfile, NULL, backup); printf("%d\n", seq); + process_inbox_file(inboxfile); } return seq; } @@ -721,6 +761,7 @@ if (bytes < 0 && strncmp(ln, "From ", 5) == 0) { if (fclose(dstfp)) goto rerr; + process_inbox_file(inboxfile); printf("%d\n", seq); dstfp = open_new_inbox_file(&seq, inboxfile); @@ -753,6 +794,7 @@ if (bytes <= 0) { if (fclose(dstfp)) goto rerr; + process_inbox_file(inboxfile); dstfp = NULL; printf("%d\n", seq); state = ST_UNKNOWN; @@ -767,6 +809,7 @@ if (dstfp) { if (fclose(dstfp)) goto rerr; + process_inbox_file(inboxfile); printf("%d\n", seq); } if (!Backup && ftruncate(srcfd, 0)) { @@ -811,6 +854,7 @@ if (dstfp) { fclose(dstfp); + process_inbox_file(inboxfile); printf("%d\n", seq); } return seq; @@ -892,7 +936,7 @@ warn_prog = progname; init_env(argc, argv); - while ((ch = Getopt(argc, argv, "abcd:fhi:m:p:suv")) != EOF) { + while ((ch = Getopt(argc, argv, "abcd:fhi:m:p:suvZz")) != EOF) { switch (ch) { case 'a': GetCur = TRUE; @@ -926,6 +970,12 @@ case 'u': CreateMTime = FALSE; break; + case 'Z': + CommandInboxFile = AV_COMMAND_NOMAIL; + break; + case 'z': + CommandInboxFile = AV_COMMAND_NOBODY; + break; case 'v': version(progname); exit(EXIT_SUCCESS);