--- ./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 <fmode>    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);
