*** src/lmtp.c 30 Jun 2002 06:40:38 -0000 --- src/lmtp.c 30 Dec 2003 09:18:35 -0000 *************** *** 50,55 **** --- 50,56 ---- static int lreaddyn P((void)); int childserverpid; + char detaildelim='\0'; static ctopfd; static char*overread; *************** *** 234,246 **** wrong, and it can't do the necessary calls to lmtpresponse(), then it should exit with some non-zero status. The parent will then syslog it, and exit with EX_SOFTWARE. (See getL() in cstdio.c) */ ! struct auth_identity **lmtp(lrout,invoker) ! struct auth_identity***lrout;char*invoker; { static const char cLHLO[]="LHLO ",cMAIL[]="MAIL FROM:",cRCPT[]="RCPT TO:", cDATA[]="DATA",cBDAT[]="BDAT",cRSET[]="RSET",cVRFY[]="VRFY ",cQUIT[]="QUIT", cNOOP[]="NOOP"; const char*msg,*msgcmd;int flush=0,c,lmtp_state=S_START;long size=0; ! auth_identity**rcpts,**lastrcpt,**currcpt; pushfd(STDIN);overread=0;overlen=0;nliseol=1; bufinit;ctopfd=-1; /* setup our output */ --- 235,247 ---- wrong, and it can't do the necessary calls to lmtpresponse(), then it should exit with some non-zero status. The parent will then syslog it, and exit with EX_SOFTWARE. (See getL() in cstdio.c) */ ! struct lmtp_rcpt *lmtp(lrout,invoker) ! struct lmtp_rcpt**lrout;char*invoker; { static const char cLHLO[]="LHLO ",cMAIL[]="MAIL FROM:",cRCPT[]="RCPT TO:", cDATA[]="DATA",cBDAT[]="BDAT",cRSET[]="RSET",cVRFY[]="VRFY ",cQUIT[]="QUIT", cNOOP[]="NOOP"; const char*msg,*msgcmd;int flush=0,c,lmtp_state=S_START;long size=0; ! struct lmtp_rcpt*rcpts,*lastrcpt,*currcpt; pushfd(STDIN);overread=0;overlen=0;nliseol=1; bufinit;ctopfd=-1; /* setup our output */ *************** *** 375,381 **** rcpts=realloc(rcpts,(num+INCR_RCPTS)*sizeof*rcpts); currcpt=rcpts+num;lastrcpt=currcpt+INCR_RCPTS; } ! ;{ char *path,*mailbox;auth_identity*temp; /* if it errors, extractaddress() will free its argument */ if(!(path=slurpaddress())||!(mailbox=extractaddress(path))) { msg="550 5.1.3 address syntax error\r\n"; --- 376,382 ---- rcpts=realloc(rcpts,(num+INCR_RCPTS)*sizeof*rcpts); currcpt=rcpts+num;lastrcpt=currcpt+INCR_RCPTS; } ! ;{ char *path,*mailbox,*detail;auth_identity*temp; /* if it errors, extractaddress() will free its argument */ if(!(path=slurpaddress())||!(mailbox=extractaddress(path))) { msg="550 5.1.3 address syntax error\r\n"; *************** *** 383,394 **** } /* if we were to handle ESMTP params on the RCPT verb, we would do so here */ skiptoeol; if(!(temp=auth_finduser(mailbox,0))) { msg="550 5.1.1 mailbox unknown\r\n"; free(path); goto message; } ! auth_copyid(*currcpt=auth_newid(),temp); free(path); currcpt++; msg="250 2.1.5 ok\r\n"; --- 384,398 ---- } /* if we were to handle ESMTP params on the RCPT verb, we would do so here */ skiptoeol; + if(detail=strchr(mailbox,detaildelim)) + *detail++='\0'; if(!(temp=auth_finduser(mailbox,0))) { msg="550 5.1.1 mailbox unknown\r\n"; free(path); goto message; } ! auth_copyid(currcpt->id=auth_newid(),temp); ! currcpt->detail=detail&&detaildelim?tstrdup(detail):0; free(path); currcpt++; msg="250 2.1.5 ok\r\n"; *************** *** 517,529 **** if(NOTcommand(cVRFY,1)) goto unknown_command; flush=1; ! ;{ char *path,*mailbox; ! auth_identity *temp; if(!(path=slurpaddress())||!(mailbox=extractaddress(path))) { msg="501 5.1.3 address syntax error\r\n"; goto message; } skiptoeol; if(!(temp=auth_finduser(mailbox,0))) { msg="550 5.1.1 user unknown\r\n"; free(path); --- 521,534 ---- if(NOTcommand(cVRFY,1)) goto unknown_command; flush=1; ! ;{ char *path,*mailbox,*detail;auth_identity *temp; if(!(path=slurpaddress())||!(mailbox=extractaddress(path))) { msg="501 5.1.3 address syntax error\r\n"; goto message; } skiptoeol; + if(detail=strchr(mailbox,detaildelim)) + *detail='\0'; if(!(temp=auth_finduser(mailbox,0))) { msg="550 5.1.1 user unknown\r\n"; free(path); *** src/lmtp.h 30 Jun 2002 05:22:09 -0000 --- src/lmtp.h 30 Dec 2003 09:18:35 -0000 *************** *** 2,9 **** extern int childserverpid; ! struct auth_identity ! **lmtp P((struct auth_identity***lrout,char*invoker)); void flushoverread P((void)), freeoverread P((void)), --- 2,12 ---- extern int childserverpid; + extern char detaildelim; ! struct lmtp_rcpt{struct auth_identity*id;char*detail;}; ! ! struct lmtp_rcpt ! *lmtp P((struct lmtp_rcpt**lrout,char*invoker)); void flushoverread P((void)), freeoverread P((void)), *** src/procmail.c 30 Jun 2002 07:12:51 -0000 --- src/procmail.c 30 Dec 2003 09:18:35 -0000 *************** *** 161,166 **** --- 161,173 ---- case LMTPOPT: #ifdef LMTP Deliverymode=2; + if(*(chp= ++chp2)||((chp=(char*)argv[++argc])&&*chp)) + { detaildelim= *chp++; + if(*chp) + { nlog("LMTP delimiter must be a single character"); + return EX_USAGE; + } + } goto last_option; #else nlog("LMTP support not enabled in this binary\n"); *************** *** 193,204 **** case 2: if(fromwhom) { fromwhom=0; /* -z disables -f, */ ! goto confldopt; /* -p and -m */ } #endif case 1: if(presenviron||mailfilter) ! confldopt: { presenviron=mailfilter=0; /* -d disables -p and -m */ goto conflopt; } break; --- 200,216 ---- case 2: if(fromwhom) { fromwhom=0; /* -z disables -f, */ ! presenviron=1; /* -p and -m */ ! } ! if(detaildelim&&crestarg) /* -z delim disables -a */ ! { crestarg=0; ! restargv=&nullp; ! presenviron=1; } #endif case 1: if(presenviron||mailfilter) ! { presenviron=mailfilter=0; /* -d disables -p and -m */ goto conflopt; } break; *************** *** 249,255 **** chp2=buf; #ifdef LMTP if(Deliverymode==2) ! { auth_identity**rcpts,**lastrcpt,**currcpt; currcpt=rcpts=lmtp(&lastrcpt,chp2); if(currcpt+1!=lastrcpt) /* if there's more than one recipient */ lockblock(&themail); /* then no one can write to the block */ --- 261,267 ---- chp2=buf; #ifdef LMTP if(Deliverymode==2) ! { struct lmtp_rcpt*rcpts,*lastrcpt,*currcpt; currcpt=rcpts=lmtp(&lastrcpt,chp2); if(currcpt+1!=lastrcpt) /* if there's more than one recipient */ lockblock(&themail); /* then no one can write to the block */ *************** *** 258,266 **** while(currcptdetail) ! { char**a=malloc(2*sizeof*a); ! *a=currcpt->detail;a[1]=0; ! restargv=(const char**)a; ! crestarg++; ! } ! pass= currcpt++->id; while(currcptdetail)free(currcpt->detail); ! auth_freeid(currcpt++->id); ! } freeoverread(); free(rcpts);newid();gargv=&nullp; goto dorcpt; *************** *** 271,277 **** waitfor(pidchild); lmtpresponse(lexitcode); pidchild=0; ! auth_freeid(*currcpt++); } free(rcpts); flushoverread(); /* pass upwards the extra LMTP data */ --- 291,298 ---- waitfor(pidchild); lmtpresponse(lexitcode); pidchild=0; ! if(currcpt->detail)free(currcpt->detail); ! auth_freeid(currcpt++->id); } free(rcpts); flushoverread(); /* pass upwards the extra LMTP data */