diff -u --recursive procmail-3.11pre7/src/mailfold.c procmail/src/mailfold.c --- procmail-3.11pre7/src/mailfold.c Wed Apr 2 19:58:45 1997 +++ procmail/src/mailfold.c Wed Oct 8 22:52:02 1997 @@ -152,6 +152,86 @@ return -1; } +static int ckmaildir(dir,statbuf)const char*dir;struct stat*statbuf; +{ int tmplen; + char*tmpstr; + tmplen=strlen(dir)+5; + tmpstr=(char*)malloc(tmplen); + if(S_ISDIR(statbuf->st_mode)) + { snprintf(tmpstr,tmplen,"%s/new",dir); + if((lstat(tmpstr,statbuf)==0)&&(S_ISDIR(statbuf->st_mode))) + { snprintf(tmpstr,tmplen,"%s/cur",dir); + if((lstat(tmpstr,statbuf)==0)&&(S_ISDIR(statbuf->st_mode))) + { snprintf( tmpstr,tmplen,"%s/tmp",dir); + if((lstat(tmpstr,statbuf)==0)&&(S_ISDIR(statbuf->st_mode))) + { free(tmpstr); + return 1; /* Woohoo. */ + } + } + } + } + /* Something is missing or screwed up. */ + free(tmpstr); + return 0; +} + +static int mkmaildir(dir)const char* dir; +{ char *tmpstr; + int tmplen; + tmplen=strlen(dir)+5; + tmpstr=(char *)malloc(tmplen); + if(mkdir(dir,0700)==0) + { snprintf(tmpstr,tmplen,"%s/new",dir); + if(mkdir(tmpstr,0700)==0) + { snprintf(tmpstr,tmplen,"%s/cur",dir); + if(mkdir(tmpstr,0700)==0) + { snprintf(tmpstr,tmplen,"%s/tmp",dir); + if(mkdir(tmpstr,0700)==0) + { free(tmpstr); + return 1; + } + } + } + } + free(tmpstr); + return 0; +} + +static int ismaildir(chp,buf)char*const chp;char*const buf; +{ int err; + struct stat statbuf; + if(!(chp>buf&&*chp==*MCDIRSEP_)) + return 0; + err=lstat(buf,&statbuf); + if(err==-1) + return (errno==ENOENT)?mkmaildir(buf):0; + else + return ckmaildir(buf,&statbuf); +} + +static int deliver_maildir(source,len) + const char*source;const long len; +{ char path_tmp[1024];char hostname[1024];char path_new[1024];int iteration; + pid_t pid;int fd; + gethostname(hostname,1024); + pid=getpid(); + for(iteration=0; iteration<100; iteration++,sleep(2)) + {struct stat statbuf;time_t currtime; + currtime=time(NULL); + snprintf(path_tmp,1024,"%s/tmp/%d.%d.%s",buf,currtime,pid,hostname); + snprintf(path_new,1024,"%s/new/%d.%d.%s",buf,currtime,pid,hostname); + if(lstat(path_tmp, &statbuf)==0 || errno!=ENOENT) continue; + fflush(NULL); + fd=opena(path_tmp); + if(fd>0) break; + } + strcpy(buf,path_tmp); + strcpy(buf2,path_tmp); + if(dump(fd,source,len)) + return 1; + return link(path_tmp,path_new)||unlink(path_tmp); +} + static int ismhdir(chp)char*const chp; { if(chp-1>=buf&&chp[-1]==*MCDIRSEP_&&*chp==chCURDIR) { chp[-1]='\0'; @@ -160,19 +240,25 @@ return 0; } /* open file or new file in directory */ -static int deliver(boxname,linkfolder)char*boxname,*linkfolder; -{ struct stat stbuf;char*chp;int mhdir;mode_t numask; +static int deliver(boxname,linkfolder,source,len)char*boxname,*linkfolder; + const char*source;const long len; +{ struct stat stbuf;char*chp;int mhdir;mode_t numask;int maildir; asgnlastf=1; if(*boxname=='|'&&(!linkfolder||linkfolder==Tmnate)) { setlastfolder(boxname); - return rdup(savstdout); + return dump(rdup(savstdout),source,len); } numask=UPDATE_MASK&~cumask;tofile=to_FILE; if(boxname!=buf) strcpy(buf,boxname); /* boxname can be found back in buf */ if(*(chp=buf)) /* not null length target? */ chp=strchr(buf,'\0')-1; /* point to just before the end */ + maildir=ismaildir(chp,buf); mhdir=ismhdir(chp); /* is it an MH folder? */ + if(maildir) + return deliver_maildir(source,len); + else if(!mhdir && *chp=='/') + *chp='\0'; if(!stat(boxname,&stbuf)) /* it exists */ { if(numask&&!(stbuf.st_mode&UPDATE_MASK)) chmod(boxname,stbuf.st_mode|UPDATE_MASK); @@ -184,7 +270,7 @@ { if(linkfolder) /* any leftovers? Now is the time to display them */ concatenate(linkfolder),skipped(linkfolder); tofile=strcmp(devnull,buf)?to_FOLDER:(rawnonl=1,0); - return opena(boxname); + return dump(opena(boxname),source,len); } if(linkfolder) /* any additional directories specified? */ { size_t blen; @@ -218,13 +304,13 @@ } if(linkfolder) /* free our cache */ free(linkfolder); - return fd; /* return the file descriptor we saved */ + return dump(fd,source,len); } } int writefolder(boxname,linkfolder,source,len,ignwerr)char*boxname,*linkfolder; const char*source;const long len;const int ignwerr; -{ if(dump(deliver(boxname,linkfolder),source,len)&&!ignwerr) +{ if(deliver(boxname,linkfolder,source,len)&&!ignwerr) { switch(errno) { case ENOSPC:nlog("No space left to finish writing"),logqnl(buf); break;