diff -Nur procmail-3.22-orig/src/mailfold.c procmail-3.22/src/mailfold.c --- procmail-3.22-orig/src/mailfold.c 2001-09-11 06:58:34.000000000 +0200 +++ procmail-3.22/src/mailfold.c 2006-07-05 20:32:22.000000000 +0200 @@ -191,9 +191,107 @@ return opena(buf); } -int writefolder(boxname,linkfolder,source,len,ignwerr,dolock) - char*boxname,*linkfolder;const char*source;long len;const int ignwerr,dolock; +int isyes(const char* s) +{ + int result = 0; + char* env = getenv(s); + if (env) + { + result = !strcmp(env, "yes"); + } + return result; +} + +int writefolder(boxname,linkfolder,source,len,ignwerr,dolock, trydeliver) + char*boxname,*linkfolder;const char*source;long len;const int ignwerr,dolock, trydeliver; { char*chp,*chp2;mode_t mode;int fd,type; + +// GW: + char* program = getenv("DELIVER_PROGRAM"); + char* s_org_mail = getenv("ORGMAIL"); + + int deliver_inbox = isyes("DELIVER_INBOX"); + int deliver_absolute_path = isyes("DELIVER_ABSOLUTE_PATH"); + int isabsolute = boxname[0] == '/'; + int isinbox = 0; + if (s_org_mail) isinbox = !strcmp(s_org_mail, boxname); + + if (trydeliver && program && ((!isinbox && !isabsolute) || (isinbox && deliver_inbox) || (isabsolute && deliver_absolute_path)) ) + { + char slen[16]; + int oldrawnonl; + int retval; + size_t str_len; + char* tmp; + + int deliver_raw_mode = isyes("DELIVER_RAW_MODE"); + int deliver_remove_from = isyes("DELIVER_REMOVE_FROM"); + int deliver_replace_inbox_name = isyes("DELIVER_REPLACE_INBOX_NAME"); + + char* s_deliver_new_inbox_name = getenv("DELIVER_NEW_INBOX_NAME"); + char* recipient = getenv("RECIPIENT"); + char* inbox_name = "INBOX"; + + if (!recipient) + { + yell("NO RECIPIENT", ""); + } + else + { + yell("RECIPIENT", recipient); + } + + if (isinbox && deliver_replace_inbox_name) + { + if (s_deliver_new_inbox_name) + { + inbox_name = s_deliver_new_inbox_name; + } + boxname = inbox_name; + } + + yell("boxname=", boxname); + yell("deliver through external program before expansion", program); + +#define BOXNAME "BOXNAME" + // put it into environment + str_len = STRLEN(BOXNAME) + 2 + strlen(boxname); + strcpy(tmp=malloc(str_len),BOXNAME); + strlcat(tmp, "=", str_len); + strlcat(tmp, boxname, str_len); + sputenv(tmp); + free(tmp); + + // sprintf(slen, "len=%i", (int)len); + // yell("slen=", slen); + + if (deliver_remove_from) + { + if(source==themail.p) + source=skipFrom_(source,&len); /* skip leading From_? */ + } + + // sprintf(slen, "len=%i", (int)len); + // yell("slen=", slen); + + metaparse(program); + + // Remove environment + sputenv(BOXNAME); + + inittmout(buf); + oldrawnonl = rawnonl; + + if (deliver_raw_mode) + { + rawnonl = 1; /* raw mode */ + } + retval = !pipin(buf, source, len, 1); /* regular program */ + rawnonl = oldrawnonl; + + return retval; + } + if(*boxname=='|'&&(!linkfolder||linkfolder==Tmnate)) { setlastfolder(boxname); fd=rdup(Deliverymode==2?STDOUT:savstdout); diff -Nur procmail-3.22-orig/src/mailfold.h procmail-3.22/src/mailfold.h --- procmail-3.22-orig/src/mailfold.h 2000-12-31 07:08:34.000000000 +0100 +++ procmail-3.22/src/mailfold.h 2006-07-03 22:56:24.000000000 +0200 @@ -4,7 +4,7 @@ dump P((const int s,const int type,const char*source,long len)); int writefolder P((char*boxname,char*linkfolder,const char*source,long len, - const int ignwerr,const int dolock)); + const int ignwerr,const int dolock, const int trydeliver)); void logabstract P((const char*const lstfolder)), concon P((const int ch)), diff -Nur procmail-3.22-orig/src/procmail.c procmail-3.22/src/procmail.c --- procmail-3.22-orig/src/procmail.c 2001-09-11 06:59:14.000000000 +0200 +++ procmail-3.22/src/procmail.c 2006-07-04 20:12:35.000000000 +0200 @@ -306,7 +306,22 @@ } gargv=argv+argc; /* save it for nextrcfile() */ if(Deliverymode) /* try recipient without changing case first */ - { if(!(pass=auth_finduser(chp2,-1))) /* chp2 is the recipient */ + { + // GW + size_t str_len; + char* tmp; + +#define RECIPIENT "RECIPIENT" + + // put it into environment + str_len = STRLEN(RECIPIENT) + 2 + strlen(chp2); + strcpy(tmp=malloc(str_len),RECIPIENT); + strlcat(tmp, "=", str_len); + strlcat(tmp, chp2, str_len); + sputenv(tmp); + free(tmp); + + if(!(pass=auth_finduser(chp2,-1))) /* chp2 is the recipient */ { static const char unkuser[]="Unknown user"; nlog(unkuser);logqnl(chp2);syslog(LOG_ERR,slogstr,unkuser,chp2); return EX_NOUSER; /* we don't handle strangers */ @@ -498,12 +513,12 @@ setuid(uid); /* make sure we have enough space */ if(linebuf<(len=strlen(chp)+strlen(lockext)+UNIQnamelen)) allocbuffers(linebuf=len,1); /* to perform the lock & delivery */ - if(writefolder(chp,(char*)0,themail.p,filled,0,1)) /* default */ + if(writefolder(chp,(char*)0,themail.p,filled,0,1,1)) /* default */ succeed=1; } /* if all else failed */ if(!succeed&&*(chp2=(char*)tgetenv(orgmail))&&strcmp(chp2,chp)) { rawnonl=0; - if(writefolder(chp2,(char*)0,themail.p,filled,0,0)) /* don't panic */ + if(writefolder(chp2,(char*)0,themail.p,filled,0,0,0)) /* don't panic */ succeed=1; /* try the last resort */ } if(succeed) /* should we panic now? */ @@ -876,14 +891,29 @@ goto setlsucc; } if(i) - { if(ofiltflag) /* protect who use bogus filter-flags */ + { + char* deliver_pipe_no_lock = 0; + int dolock = 1; + + if(ofiltflag) /* protect who use bogus filter-flags */ startchar=themail.p,tobesent=filled; /* whole message */ tostdout: rawnonl=flags[RAW_NONL]; - if(locknext) /* write to a file or directory */ + // GW + deliver_pipe_no_lock = getenv("DELIVER_PIPE_NO_LOCK"); + if (deliver_pipe_no_lock) + { + if (!strcmp(deliver_pipe_no_lock, "yes")) + { + yell("disable deliver locking", "DELIVER_PIPE_NO_LOCK=yes"); + dolock = 0; + } + } + + if(locknext && dolock) /* write to a file or directory */ lcllock(tolock,buf); inittmout(buf); /* to break messed-up kernel locks */ if(writefolder(buf,strchr(buf,'\0')+1,startchar,tobesent, - ignwerr,0)&& + ignwerr,0,1)&& (succeed=1,!flags[CONTINUE])) frmailed: { if(ifstack.vals) free(ifstack.vals);