--- vpopmail-5.4.17/vdelivermail.c	2006-06-29 21:36:43.000000000 +0200
+++ vpopmail-5.4.17.patched/vdelivermail.c	2006-10-20 20:48:02.000000000 +0200
@@ -20,6 +20,11 @@
 /* code review/cleanup/rewrite October 2004 through March, 2005
  * by Tom Collins <tom@tomlogic.com>
  *
+ * maildrop mailfilter support added
+ * by Andre Beckedorf <eviljazz@katastrophos.net> 2003-2006
+ * http://www.katastrophos.net/andre/blog
+ * (some parts based on some other code which source I forgot)
+ * 
  */
 
 /* include files */
@@ -44,7 +49,7 @@
 #endif
 
 /* Globals */
-#define AUTH_SIZE 300
+#define AUTH_SIZE 600
 char TheUser[AUTH_SIZE];
 char TheUserFull[AUTH_SIZE];
 char TheDomain[AUTH_SIZE];
@@ -52,6 +57,8 @@
 uid_t TheDomainUid;
 gid_t TheDomainGid;
 char TheDir[AUTH_SIZE];
+char Cmd[AUTH_SIZE];
+char Dir[AUTH_SIZE];
 char CurrentDir[AUTH_SIZE];
 char DeliveredTo[AUTH_SIZE];
 struct vqpasswd *vpw;
@@ -78,6 +85,8 @@
 #define EXIT_OK 0
 #define EXIT_OVERQUOTA EXIT_BOUNCE
 
+#define MAILDROP "/usr/local/bin/maildrop"
+
 /* from qmail's wait.h for run_command() */
 #define wait_exitcode(w) ((w) >> 8)
 
@@ -91,6 +100,9 @@
 void run_command(char *prog);
 void checkuser(void);
 void usernotfound(void);
+int domain_has_mailfilter(void);
+void usemaildrop(void);
+void postprocess(void);
 int is_loop_match( const char *dt, const char *address);
 int deliver_quota_warning(const char *dir, const char *q);
 
@@ -126,7 +138,9 @@
 
     /* get the user from vpopmail database */
     if ((vpw=vauth_getpw(TheUser, TheDomain)) != NULL ) {
-        checkuser();
+	    if (domain_has_mailfilter()) {
+	        usemaildrop();
+        } else checkuser();
     } 
 
 #ifdef QMAIL_EXT
@@ -136,7 +150,9 @@
     else if ( strcmp(TheUser, TheUserExt) != 0 ) {
         /* get the user from vpopmail database */
         if ((vpw=vauth_getpw(TheUserExt, TheDomain)) != NULL ) {
-            checkuser();
+            if (domain_has_mailfilter()) {  
+                usemaildrop();
+            } else checkuser();
         } else {
             usernotfound();
         }
@@ -170,9 +186,6 @@
  */
 void get_arguments(int argc, char **argv)
 {
-#ifdef QMAIL_EXT
- int i;
-#endif
  char *tmpstr; 
 
     if (argc != 3) {
@@ -192,6 +205,15 @@
         vexiterr (EXIT_BOUNCE, "vdelivermail: no HOST environment varilable");
     }
     snprintf (TheDomain, sizeof(TheDomain), "%s", tmpstr);
+    
+    postprocess();
+}
+
+void postprocess(void)
+{
+#ifdef QMAIL_EXT
+ int i;
+#endif
 
     lowerit(TheUser);
     lowerit(TheDomain);
@@ -334,6 +356,28 @@
     return(pid);
 }
 
+int domain_has_mailfilter(void)
+{
+    FILE *fs;
+    snprintf(Dir, AUTH_SIZE, "%s/mailfilter", TheDomainDir);
+    if ( (fs = fopen(Dir,"r")) == NULL ) {
+        return(0);
+    }
+    fclose(fs);
+    return(1);
+}
+
+void usemaildrop(void)
+{
+    /* printf("using mailfilter at %s/mailfilter \n", TheDomainDir); */
+    snprintf(Cmd, AUTH_SIZE, "| /usr/bin/env HOME=%s VDOMAINDIR=%s VUSERDIR=%s VUSER=%s VDOMAIN=%s preline \"%s\" -V 2 %s/mailfilter",
+      TheDomainDir, TheDomainDir, vpw->pw_dir, TheUser, TheDomain, MAILDROP, TheDomainDir);
+
+    printf(Cmd);
+        
+    deliver_mail(Cmd, "");
+} 
+
 int fdcopy (int write_fd, int read_fd, const char *extra_headers, size_t headerlen)
 {
   char msgbuf[4096];
@@ -932,6 +976,11 @@
  */
 void usernotfound() 
 {
+ char DomainsDir[AUTH_SIZE] = "";
+ char *pbegin;
+ char *pend;
+ int already_processed = 0;
+
     /* read the full message to avoid SIGPIPE if maildrop is calling us */
     if (message_size == 0) message_size = get_message_size();
 
@@ -975,10 +1024,71 @@
         if( check_forward_deliver(bounce) == 1 )
             vexit(EXIT_OK);
         else
-            strcat( bounce, "Maildir/");
+		{
+            strcat(DomainsDir, VPOPMAILDIR);
+            strcat(DomainsDir, "/" DOMAINS_DIR "/");
+
+            /* check if directory is subdirectory of VPOPMAILDIR/domains/ */
+            pbegin = strstr(bounce, DomainsDir);
+            if (pbegin != NULL) {
+                pbegin = pbegin + strlen(DomainsDir);
+                pend = strchr(pbegin, '/');
+                
+                if (pend != NULL) {
+                    strncpy(TheDomain, pbegin, pend - pbegin);
+                    TheDomain[pend - pbegin] = 0;
+                                       
+                    pbegin = pend + 1;
+                    pend = strchr(pbegin, '/');
+                    
+                    if (pend != NULL) {
+                        strncpy(TheUser, pbegin, pend - pbegin);
+                        TheUser[pend - pbegin] = 0;
+			/*
+                        printf("TheUser: %s\n", TheUser);
+                        printf("TheDomain: %s\n", TheDomain);
+			*/
+                        strcpy(bounce, BOUNCE_ALL);
+                        bounce[strlen(BOUNCE_ALL)] = 0;
+                        /*
+			printf("bounce: %s \n", bounce);
+			*/
+                        
+                        /* validate new TheUser and TheDomain data and
+                           get additional data */
+                        postprocess();
+
+                        /* get the user from vpopmail database */
+                        if ((vpw=vauth_getpw(TheUser, TheDomain)) != NULL ) {
+                            if (domain_has_mailfilter()) {
+                                usemaildrop();
+                                already_processed = 1;                                
+                            } else {
+                                strcat( bounce, "Maildir/");                            
+                            }
+                        } 
+                        /*
+                        printf("TheUser: %s\n", TheUser);
+                        printf("TheDomain: %s\n", TheDomain);
+                        printf("TheDomainDir: %s\n", TheDomainDir);
+                        printf("vpw->pw_dir: %s\n", vpw->pw_dir);
+                        printf("TheUserFull: %s\n", TheUserFull);
+			*/
+                    } else { /* on failure fallback */
+                        strcat( bounce, "Maildir/");
+                    }
+                } else { /* on failure fallback */
+                    strcat( bounce, "Maildir/");                
+                }
+            } else {
+                strcat( bounce, "Maildir/");
+            }
+            
+		}
     }
 
-    deliver_mail(bounce, "");
+    if (!already_processed)
+	    deliver_mail(bounce, "");
 }
 
 /* 
