patch for vpopmail to make it working with maildrop and mailman automatically. Apply the patch to vdelivermail.c and replace your existing /home/vpopmail/bin/vdelivermail, your virtual domain is ready for mailman based lists and maildrop based filters (except autoreply does not work and I do not know why). My mailman is installed in /home/mailman/$domain version 2.1 My maildrop has WITHCOURIER defined so that it checks the $HOME env variable. My vpopmail version is 4.10.35 ================================================= --- vpopmail-4.10.35/vdelivermail.org Sun Sep 16 18:48:42 2001 +++ vpopmail-4.10.35/vdelivermail.c Mon Sep 17 19:36:31 2001 @@ -42,6 +42,8 @@ char TheUserFull[AUTH_SIZE]; char TheDomain[AUTH_SIZE]; char TheDir[AUTH_SIZE]; +char ListDir[AUTH_SIZE]; +char ListCmd[AUTH_SIZE]; char CurrentDir[AUTH_SIZE]; char DeliveredTo[AUTH_SIZE]; struct vqpasswd *vpw; @@ -49,8 +51,13 @@ char bounce[AUTH_SIZE]; int CurrentQuotaSizeFd; + +#define QMAIL_EXT + #ifdef QMAIL_EXT char TheUserExt[AUTH_SIZE]; /* the User with '-' and following chars out if any */ +char TheExt[AUTH_SIZE]; /* Ext after the User with and '-' */ +char TheLastExt[AUTH_SIZE]; /* The last ext after the User with and '-' */ #endif #define FILE_SIZE 156 @@ -79,6 +86,10 @@ void run_command(char *prog); void checkuser(void); void usernotfound(void); +int islistaddr(void); +int processlistcmd(void); +int havemailfilter(void); +int usemaildrop(void); static char local_file[156]; static char local_file_new[156]; @@ -90,6 +101,7 @@ */ int main(int argc, char **argv) { + /* get the arguments to the program and setup things */ get_arguments(argc, argv); @@ -101,9 +113,19 @@ } #endif + /* List management addresses */ + if ( islistaddr() == 1 ) { + (void) processlistcmd(); + /* printf("ListDir=%s\n",ListDir); */ + } + /* get the user from vpopmail database */ - if ((vpw=vauth_getpw(TheUser, TheDomain)) != NULL ) { - checkuser(); + else if ((vpw=vauth_getpw(TheUser, TheDomain)) != NULL ) { + if ( havemailfilter() == 1 ) { + (void) usemaildrop(); + /* printf("MailCmd=%s\n",ListCmd); */ + } + else checkuser(); } #ifdef QMAIL_EXT /* try and find user that matches the QmailEXT address if: no user found, */ @@ -111,7 +133,11 @@ else if ( strncmp(TheUser, TheUserExt, AUTH_SIZE) != 0 ) { /* get the user from vpopmail database */ if ((vpw=vauth_getpw(TheUserExt, TheDomain)) != NULL ) { - checkuser(); + if ( havemailfilter() == 1 ) { + (void) usemaildrop(); + printf("MailCmd=%s\n",ListCmd); + } + else checkuser(); } else { usernotfound(); @@ -130,12 +156,13 @@ /* * Get the command line arguments and the environment variables. * Force addresses to be lower case and set the default domain + * Default: vdelivermail '' bounce-no-mailbox */ void get_arguments(int argc, char **argv) { char *tmpstr; #ifdef QMAIL_EXT - int i; + int i,j; #endif if (argc != 3) { @@ -176,15 +203,106 @@ if (TheUser[i] == '-' ) { break; } - TheUserExt[i] = TheUser[i]; } - TheUserExt[i] = 0; + + /* Now i is either at the end of string or points to the 1st - */ + for(j = i; TheUser[j] != 0; j++) { + if (j>i) TheExt[j-i-1] = TheUser[j]; + } + TheExt[j-i] = 0; + + /* Now j is either at the end of string */ + for(i = j; i >= 0; i--) { + if (TheUser[i] == '-' ) break; + } + + /* Now i is either at the beginning of string or points to the last - */ + if (i>0) { + for (j = i; TheUser[j] != 0; j++) { + if (j>i) TheLastExt[j-i-1] = TheUser[j]; + } + TheLastExt[j-i] = 0; + } + else TheLastExt[0] = 0; + #endif vget_real_domain(TheDomain,AUTH_SIZE); + /*printf("TheDomain=%s TheUser=%s TheUserExt=%s TheExt=%s TheLastExt=%s\n", + TheDomain, TheUser, TheUserExt, TheExt, TheLastExt); + */ +} + + +int islistaddr(void) +{ + DIR *mydir; + + /* snprintf(ListDir, AUTH_SIZE, "%s/Maildir/", vpw->pw_dir); */ + snprintf(ListDir, AUTH_SIZE, "/home/mailman/%s/lists/%s", TheDomain, TheUserExt); + + if ( (mydir = opendir(ListDir)) == NULL ) { + return(0); + } + closedir(mydir); + /* printf("ListDir=%s\n",ListDir); */ + + return(1); +} + +int processlistcmd(void) +{ + if ( strncmp(TheLastExt, "", AUTH_SIZE) == 0 ) { + snprintf(ListCmd, AUTH_SIZE, "| /home/mailman/%s/mail/wrapper %s %s", TheDomain, "post", TheUserExt); + return deliver_mail(ListCmd, "NOQUOTA"); + } + else if ( strncmp(TheLastExt, "request", AUTH_SIZE) == 0 ) { + snprintf(ListCmd, AUTH_SIZE, "| /home/mailman/%s/mail/wrapper %s %s", TheDomain, "mailcmd", TheUserExt); + return deliver_mail(ListCmd, "NOQUOTA"); + } + else if (( strncmp(TheLastExt, "admin", AUTH_SIZE) == 0 ) || + ( strncmp(TheLastExt, "owner", AUTH_SIZE) == 0 )) { + snprintf(ListCmd, AUTH_SIZE, "| /home/mailman/%s/mail/wrapper %s %s", TheDomain, "mailowner", TheUserExt); + return deliver_mail(ListCmd, "NOQUOTA"); + } + else if (( strncmp(TheLastExt, "join", AUTH_SIZE) == 0 ) || + ( strncmp(TheLastExt, "subscribe", AUTH_SIZE) == 0 )) { + snprintf(ListCmd, AUTH_SIZE, "| /home/mailman/%s/mail/wrapper %s %s", TheDomain, "join", TheUserExt); + return deliver_mail(ListCmd, "NOQUOTA"); + } + else if (( strncmp(TheLastExt, "leave", AUTH_SIZE) == 0 ) || + ( strncmp(TheLastExt, "unsubscribe", AUTH_SIZE) == 0 )) { + snprintf(ListCmd, AUTH_SIZE, "| /home/mailman/%s/mail/wrapper %s %s", TheDomain, "leave", TheUserExt); + return deliver_mail(ListCmd, "NOQUOTA"); + } + else { + printf("Sorry, invalid list command\n"); + printf("TheUser=%s TheUserExt=%s TheExt=%s TheLastExt=%s\n", + TheUser, TheUserExt, TheExt, TheLastExt); + /* exit 100 causes the email to be bounced back */ + vexit(100); + return 100; + } +} + +int havemailfilter(void) +{ + FILE *fs; + snprintf(ListDir, AUTH_SIZE, "%s/.mailfilter", vpw->pw_dir); + if ( (fs = fopen(ListDir,"r")) == NULL ) { + return(0); + } + fclose(fs); + return(1); +} + +int usemaildrop(void) +{ + snprintf(ListCmd, AUTH_SIZE, "| /usr/bin/env HOME=%s DEFAULT=./Maildir /usr/local/bin/maildrop -V 1", vpw->pw_dir); + return deliver_mail(ListCmd, "NOQUOTA"); } #ifdef VALIAS @@ -401,6 +519,7 @@ return(-3); } + /* This is a directory/Maildir location */ if ( *address == '/' ) { @@ -472,8 +591,8 @@ "%sDelivered-To: %s\n", getenv("RPLINE"), dtline); } - if ( lseek(0, SEEK_SET, 0L) < 0 ) { - printf("lseek errno=%d\n", errno); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("DeliverMail: lseek errno=%d\n", errno); return(errno); } @@ -648,8 +767,8 @@ while (*prog==' ') ++prog; while (*prog=='|') ++prog; - if ( lseek(0, SEEK_SET, 0L) < 0 ) { - printf("lseek errno=%d\n", errno); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("RunCmd: lseek errno=%d\n", errno); return; } @@ -698,7 +817,10 @@ return(1); } - lseek(0,SEEK_SET,0L); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("IsLooping: lseek errno=%d\n", errno); + } + while(fgets(loop_buf,sizeof(loop_buf),stdin)!=NULL){ /* if we find the line, return error (looping) */ @@ -765,8 +887,9 @@ - printf("lseek errno=%d\n", errno); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("DeliverMail: lseek errno=%d\n", errno); return(errno); } @@ -648,8 +767,8 @@ while (*prog==' ') ++prog; while (*prog=='|') ++prog; - if ( lseek(0, SEEK_SET, 0L) < 0 ) { - printf("lseek errno=%d\n", errno); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("RunCmd: lseek errno=%d\n", errno); return; } @@ -698,7 +817,10 @@ return(1); } - lseek(0,SEEK_SET,0L); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("IsLooping: lseek errno=%d\n", errno); + } + while(fgets(loop_buf,sizeof(loop_buf),stdin)!=NULL){ /* if we find the line, return error (looping) */ @@ -765,8 +887,9 @@ ssize_t message_size; ssize_t bytes; - if ( lseek(0, SEEK_SET, 0L) < 0 ) { - printf("lseek error %d\n", errno); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { + printf("GetMsgSize lseek errno=%d\n", errno); + printf(" Errno EBADF=%i ESPIPE=%i EINVAL=%i\n",EBADF, ESPIPE, EINVAL); return(-1); } ================================================ >>>>>>>> Visit http://www.acosmo.com <<<<<<<<< ------------------------------------------------------ Mailman-Users maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/mailman-users