home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-18 | 44.1 KB | 1,264 lines |
- Newsgroups: comp.sources.misc
- From: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
- Subject: v20i051: procmail - mail processing program v2.02, Part03/03
- Message-ID: <1991Jun17.043158.1962@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 21263b7c7bb2b8f7e24ffb5258793db8
- Date: Mon, 17 Jun 1991 04:31:58 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
- Posting-number: Volume 20, Issue 51
- Archive-name: procmail/part03
- Environment: UNIX, sendmail
- Supersedes: procmail: Volume 17, Issue 31-32
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is part 03 of procmail
- # ============= procmail/retint.c ==============
- if test ! -d 'procmail'; then
- echo 'x - creating directory procmail'
- mkdir 'procmail'
- fi
- if test -f 'procmail/retint.c' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/retint.c (File already exists)'
- else
- echo 'x - extracting procmail/retint.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/retint.c' &&
- X/************************************************************************
- X * Collection of routines that return an int (sort of anyway :-) *
- X * *
- X * Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands *
- X * The sources can be freely copied for non-commercial use. *
- X * #include "README" *
- X * *
- X * #include "STYLE" *
- X * *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic char rcsid[]="$Id: retint.c,v 2.0 1991/06/10 14:35:35 berg Rel $";
- X#endif
- X#include "config.h"
- X#include "procmail.h"
- X#include "shell.h"
- X
- Xsetdef(name,contents)const char*const name,*const contents;{
- X strcat(strcat(strcpy(sgetcp=buf2,name),"="),contents);
- X readparse(buf,sgetc,0);sputenv(buf);}
- X
- Xchar*backblock; /* what is to be recovered in case of filter failure */
- Xlong backlen; /* its length */
- Xpid_t pidfilt,pidchild;
- Xint pbackfd[2]; /* the emergency backpipe :-) */
- X
- Xpipthrough(line,source,len)char*line,*source;const long len;{
- X int pinfd[2],poutfd[2];
- X rpipe(pbackfd);rpipe(pinfd);flaggerd=0; /* main pipes setup */
- X if(!(pidchild=fork())){ /* create a sending procmail */
- X backblock=source;backlen=len;signal(SIGTERM,stermchild);
- X signal(SIGINT,stermchild);signal(SIGHUP,stermchild);
- X signal(SIGQUIT,stermchild);rclose(rc);rclose(PRDI);rclose(PRDB);
- X rpipe(poutfd);rclose(STDOUT);
- X if(!(pidfilt=fork())){ /* create the filter */
- X rclose(PWRO);rclose(PWRB);rdup(PWRI);rclose(PWRI);getstdin(PRDO);
- X callnewprog(line);}
- X rclose(PWRI);rclose(PRDO);
- X if(forkerr(pidfilt,line)){
- X rclose(PWRO);stermchild();}
- X if(dump(PWRO,source,len)){ /* send in the text to be filtered */
- X writeerr(line);stermchild();}
- X if(pwait&&waitfor(pidfilt)!=EX_OK){ /* check the exitcode of the filter */
- X progerr(line);stermchild();}
- X rclose(PWRB);kill(thepid,SIGQUIT);exit(EX_OK);} /* tell parent to proceed */
- X rclose(PWRI);rclose(PWRB);getstdin(PRDI);
- X if(forkerr(pidchild,"procmail"))
- X return 1;
- X return 0;} /* we stay behind to read back the filtered text */
- X
- Xwaitflagger(){ /* wait for SIGQUIT from child */
- X while(!flaggerd)
- X suspend();} /* to prevent polling */
- X
- Xgrepin(expr,source,len,casesens)const char*const expr,*const source;long len;{
- X pid_t pid;int poutfd[2];static const char*newargv[5]={0,"-e"};
- X newargv[3]=casesens?(char*)0:"-i";*newargv=tgetenv(grep);newargv[2]=expr;
- X rpipe(poutfd);
- X if(!(pid=sfork())){ /* start grep */
- X rclose(PWRO);rclose(rc);getstdin(PRDO);shexec(newargv);}
- X rclose(PRDO);len=dump(PWRO,source,len);
- X if(!forkerr(pid,*newargv)){
- X if(len)
- X writeerr(*newargv);
- X else
- X return waitfor(pid)!=EX_OK;} /* did it grep? */
- X return EX_UNAVAILABLE;}
- X
- Xwaitfor(pid)const pid_t pid;{int i; /* wait for a specific process */
- X while(pid!=wait(&i)||(i&127)==127);
- X return i>>8&255;}
- X
- Xgetstdin(pip)const int pip;{
- X rclose(STDIN);rdup(pip);rclose(pip);}
- X
- Xcallnewprog(newname)const char*const newname;{
- X if(sh){const char*newargv[4]; /* should we start a shell? */
- X yell(executing,newname);newargv[3]=0;newargv[2]=newname;
- X newargv[1]=tgetenv(shellflags);*newargv=tgetenv(shell);shexec(newargv);}
- X {register const char*p;int argc;const char**newargv;
- X argc=1;p=newname; /* If no shell, chop up the arguments ourselves */
- X if(verbose){
- X log(executing);log(oquote);goto no_1st_comma;}
- X do{ /* show chopped up command line */
- X if(verbose){
- X log(",");
- Xno_1st_comma:
- X log(p);}
- X while(*p++);}
- X while(argc++,*p!=TMNATE);
- X if(verbose)
- X log(cquote);
- X newargv=malloc(argc*sizeof*newargv);p=newname;argc=0; /* alloc argv array */
- X do{
- X newargv[argc++]=p;
- X while(*p++);}
- X while(*p!=TMNATE);
- X newargv[argc]=0;shexec(newargv);}}
- X
- Xwriteerr(line)const char*const line;{
- X log("Error while writing to");logqnl(line);}
- X
- Xforkerr(pid,a)const pid_t pid;const char*const a;{
- X if(pid==-1){
- X log("Failed forking");logqnl(a);return 1;}
- X return 0;}
- X
- Xprogerr(line)const char*const line;{
- X log("Program failure of");logqnl(line);}
- X
- Xopena(a)const char*const a;{
- X lastfolder=cstr(lastfolder,a);yell("Opening",a);
- X return ropen(a,O_WRONLY|O_APPEND|O_CREAT,0666);}
- X
- Xyell(a,b)const char*const a,*const b;{ /* log if -d option set */
- X if(verbose){
- X log(a);logqnl(b);}}
- X
- Xunlock(lockp)const char**const lockp;{
- X lcking=1;
- X if(*lockp){
- X yell("Unlocking",*lockp);
- X if(unlink(*lockp)){
- X log("Couldn't unlock");logqnl(*lockp);}
- X free(*lockp);*lockp=0;}
- X if(nextexit==1){ /* make sure we are not inside terminate already */
- X log(newline);terminate();}
- X lcking=0;}
- X
- Xnomemerr(){
- X log("Out of memory\nbuffer 0: \"");buf[linebuf-1]=buf2[linebuf-1]='\0';
- X log(buf);log("\"\nbuffer 1:");logqnl(buf2);retval=EX_OSERR;terminate();}
- X
- Xlogqnl(a)const char*const a;{
- X log(oquote);log(a);log(cquote);}
- X
- Xnextrcfile(){const char*p; /* next rcfile specified on the command line */
- X while(p= *gargv){
- X gargv++;
- X if(!strchr(p,'=')){
- X rcfile=p;return 1;}}
- X return 0;}
- X
- Xrclose(fd)const int fd;{int i; /* a sysV secure close (signal immune) */
- X while((i=close(fd))&&errno==EINTR);
- X return i;}
- X
- Xrwrite(fd,a,len)const int fd,len;void*const a;{int i; /* a sysV secure write */
- X while(0>(i=write(fd,a,(size_t)len))&&errno==EINTR);
- X return i;}
- X
- Xrread(fd,a,len)const int fd,len;void*const a;{int i; /* a sysV secure read */
- X while(0>(i=read(fd,a,(size_t)len))&&errno==EINTR);
- X return i;}
- X
- Xropen(name,mode,mask)const char*const name;const mode_t mask;{int i,r;
- X for(r=noresretry;0>(i=open(name,mode,mask));) /* a sysV secure open */
- X if(errno!=EINTR)
- X if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
- X break; /* survives a temporary "file table full" condition */
- X return i;}
- X
- Xrdup(p)const int p;{int i,r;
- X for(r=noresretry;0>(i=dup(p));) /* catch "file table full" */
- X if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
- X break;
- X return i;}
- X
- Xrpipe(fd)int fd[2];{int i,r;
- X for(r=noresretry;0>(i=pipe(fd));) /* catch "file table full" */
- X if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--))){
- X *fd=fd[1]= -1;break;}
- X return i;}
- X
- Xlockit(name,lockp)char*name;const char**const lockp;{int i;struct stat stbuf;
- X unlock(lockp); /* unlock any previous lockfile FIRST */
- X if(!*name)
- X return;
- X for(lcking=1;;){ /* to prevent deadlocks (I hate deadlocks) */
- X yell("Locking",name);
- X if(!NFSxopen(name)){
- X *lockp=tstrdup(name); /* lock acquired, hurray! */
- Xterm: if(nextexit){
- X log(whilstwfor);log("lockfile");logqnl(name);terminate();}
- X lcking=0;return;} /* check if it's time for a lock override */
- X if(errno==EEXIST&&!stat(name,&stbuf)&&!stbuf.st_size){time_t t;
- X if(locktimeout&&(t=time((time_t*)0),!stat(name,&stbuf))) /* from stat */
- X if(locktimeout<t-stbuf.st_mtime){ /* till unlink should be atomic */
- X if(unlink(name)){ /* but can't guarantee that */
- X log("Forced unlock denied on");logqnl(name);}
- X else{
- X log("Forcing lock on");logqnl(name);suspend();}}}
- X else{ /* maybe filename too long, shorten and retry */
- X if(0<(i=strlen(name)-1)&&!strchr(dirsep,(name[i-1]))){
- X name[i]='\0';continue;}
- X log("Lockfailure on");logqnl(name);return;}
- X sleep(DEFlocksleep,locksleep);
- X if(nextexit)
- X goto term;}}
- X
- Xlcllock(){ /* lock a local file (if need be) */
- X if(locknext)
- X if(tolock)
- X lockit(tolock,&loclock);
- X else
- X lockit(strcat(buf2,tgetenv(lockext)),&loclock);}
- X
- Xterminate(){
- X nextexit=2; /* prevent multiple invocations of terminate */
- X if(retval!=EX_OK)
- X log("Mail bounced\n");
- X unlock(&loclock);unlock(&globlock);exit(retval);}
- X
- Xsuspend(){
- X sleep((unsigned)suspendv);}
- X
- Xskipspace(){
- X while(testb(' ')||testb('\t'));}
- X
- Xsgetc(){ /* a fake fgetc for a string */
- X return *sgetcp?*(uchar*)sgetcp++:EOF;}
- X
- Xskipped(x)const char*const x;{
- X log("Skipped");logqnl(x);}
- X
- Xstatic uchar rcbuf[STDBUF],*rcbufp,*rcbufend; /* buffers for custom stdio */
- Xstatic ungetb; /* pushed back char */
- X
- Xbopen(name)const char*const name;{ /* my fopen */
- X rcbufp=rcbufend=0;ungetb= -1;yell("Rcfile:",name);
- X return rc=ropen(name,O_RDONLY);}
- X
- Xgetbl(p)char*p;{int i;char*q; /* my gets */
- X for(q=p;;){
- X switch(i=getb()){
- X case '\n':case EOF:
- X *p='\0';return p!=q;} /* did we read anything at all? */
- X *p++=i;}}
- X
- Xgetb(){ /* my fgetc */
- X if(ungetb>=0){int i; /* anything pushed back? */
- X i=ungetb;ungetb= -1;return i;}
- X if(rcbufp==rcbufend){
- X rcbufend=rcbuf+rread(rc,rcbufp=rcbuf,STDBUF);} /* refill */
- X return rcbufp<rcbufend?*rcbufp++:EOF;}
- X
- Xtestb(x)const int x;{int i; /* fgetc that only succeeds if it matches */
- X if((i=getb())==x)
- X return 1;
- X ungetb=i;return 0;}
- X
- Xalphanum(c)const int c;{
- X return c>='0'&&c<='9'||c>='a'&&c<='z'||c>='A'&&c<='Z'||c=='_';}
- X /* open file or new file in directory */
- Xdeliver(boxname)char*const boxname;{struct stat stbuf;
- X strcpy(buf,boxname); /* boxname can be found back in buf */
- X return stat(buf,&stbuf)||!S_ISDIR(stbuf.st_mode)?opena(buf):dirmail();}
- X
- X#include "exopen.h"
- X /* an NFS secure exclusive file open */
- XNFSxopen(name)char*name;{char*p,*q;int j= -1,i;
- X for(q=name;p=strpbrk(q,dirsep);q=p+1); /* find last DIRSEP */
- X i=q-name;strncpy(p=malloc(i+UNIQnamelen),name,i);
- X if(unique(p,p+i,0))
- X j=myrename(p,name); /* try and rename it, fails if nonexclusive */
- X free(p);return j;}
- SHAR_EOF
- chmod 0644 procmail/retint.c ||
- echo 'restore of procmail/retint.c failed'
- Wc_c="`wc -c < 'procmail/retint.c'`"
- test 9348 -eq "$Wc_c" ||
- echo 'procmail/retint.c: original size 9348, current size' "$Wc_c"
- fi
- # ============= procmail/shell.h ==============
- if test -f 'procmail/shell.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/shell.h (File already exists)'
- else
- echo 'x - extracting procmail/shell.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/shell.h' &&
- X/*$Id: shell.h,v 2.0 1991/06/10 14:39:08 berg Rel $*/
- X
- X#define malloc(n) tmalloc((size_t)(n))
- X#define realloc(p,n) trealloc(p,(size_t)(n))
- X#define tmemmove(t,f,n) memmove(t,f,(size_t)(n))
- SHAR_EOF
- chmod 0644 procmail/shell.h ||
- echo 'restore of procmail/shell.h failed'
- Wc_c="`wc -c < 'procmail/shell.h'`"
- test 188 -eq "$Wc_c" ||
- echo 'procmail/shell.h: original size 188, current size' "$Wc_c"
- fi
- # ============= procmail/INSTALL ==============
- if test -f 'procmail/INSTALL' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/INSTALL (File already exists)'
- else
- echo 'x - extracting procmail/INSTALL (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/INSTALL' &&
- XTo install procmail, lockfile and formail: edit Makefile accordingly (if need
- Xbe, config.h as well) and type 'make install'.
- X
- X'make install' will:
- X - execute autoconf (a shell script that repeatedly calls the C compiler
- X to determine if certain features/symbols are supported), which will
- X create a file named autoconf.h
- X - compile the *.c files, create the three binaries: procmail, lockfile,
- X formail
- X - copy these binaries to $(BINDIR)
- X - copy the man pages to $(MANDIR)
- X
- X
- XMinimal requirements:
- X
- Xprocmail must be installed.
- Xlockfile needs only to be installed if you plan to read several mailboxes
- X with one of the standard mailers.
- Xformail needs only to be installed if mail sometimes arrives in nonstandard
- X mailbox format (or if you want to generate auto replies, split up
- X mailboxes/digests etc., see the man page of formail for more info).
- X
- X
- XIf things don't compile automagically, I suggest you take a look at:
- Xautoconf, autoconf.h, config.h, includes.h
- X
- XThe program is supposed to be fully ANSI and K&R compliant.
- X
- XIf you run procmail by hand and pipe in some sample mail, then make
- Xsure that if you kill procmail, you use "kill pid" and NOT "kill -9 pid".
- XShould procmail seem to hang, check if the $LOCKFILE is still present.
- XIf you kill procmail with "kill pid" it will clean up the $LOCKFILE
- Xitself.
- X
- XSuggested command line for a test run: "procmail -d LOGFILE=/dev/tty"
- X(now type in a mail message).
- X
- XEvery user that wants to use procmail should have a .forward and a
- X.procmailrc file in his HOME directory. For starters, you can look
- Xat the supplied example files in "examples".
- X(BTW, be sure to make .forward *world* readable).
- X
- XFor more info about the program, see the man page.
- X
- X------------------------------------------------------------------------------
- X-----------------------Frequently Asked Questions-----------------------------
- X------------------------------------------------------------------------------
- X
- X1. Why does the logfile have lines containing "file -i not found"?
- X
- X Your egrep doesn't understand the -i option (ignore case). Either
- X use a different grep (e.g. set GREP to /bin/grep), or be sure
- X to specify the 'D' option on every recipe.
- X
- X2. I installed procmail (i.e. typed 'make install'), but how am I supposed to
- X use it? When I type procmail on the command line it simply does nothing.
- X
- X You're not supposed to start procmail from the command line.
- X Be sure to have a .forward and a .procmailrc file in your home
- X directory (see the examples subdirectory or the man page).
- SHAR_EOF
- chmod 0644 procmail/INSTALL ||
- echo 'restore of procmail/INSTALL failed'
- Wc_c="`wc -c < 'procmail/INSTALL'`"
- test 2542 -eq "$Wc_c" ||
- echo 'procmail/INSTALL: original size 2542, current size' "$Wc_c"
- fi
- # ============= procmail/Makefile ==============
- if test -f 'procmail/Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/Makefile (File already exists)'
- else
- echo 'x - extracting procmail/Makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/Makefile' &&
- X#$Id: Makefile,v 2.0 1991/06/10 14:39:08 berg Rel $
- X
- X# change BASENAME to your home directory if need be
- XBASENAME = /usr/local
- X
- XBINDIR = $(BASENAME)/bin
- XMANDIR = $(BASENAME)/man/man1
- X
- X########################################################################
- X# Only edit below this line if you *think* you know what you are doing #
- X########################################################################
- X
- X# Directory for the standard include files
- XUSRINCLUDE = /usr/include
- X
- XOCFLAGS = -O
- XOLDFLAGS = -s
- X
- XCFLAGS = $(OCFLAGS) -I$(USRINCLUDE) -I./include
- XLDFLAGS = $(OLDFLAGS)
- X
- XCC = cc
- XO = o
- XRM= rm -f
- X
- XBINS=procmail lockfile formail
- X
- XOBJ=procmail.$(O) nonint.$(O) goodies.$(O)
- X
- XDEP=shell.h procmail.h config.h
- X
- Xall: autoconf.h $(BINS)
- X
- Xprocmail: $(OBJ) exopen.$(O) common.$(O) retint.$(O)
- X $(CC) $(CFLAGS) -o procmail $(OBJ) exopen.$(O) common.$(O) \
- Xretint.$(O) $(LDFLAGS)
- X
- Xlockfile: lockfile.$(O) exopen.$(O)
- X $(CC) $(CFLAGS) -o lockfile lockfile.$(O) exopen.$(O) ${LDFLAGS}
- X
- Xformail: formail.$(O) common.$(O)
- X $(CC) $(CFLAGS) -o formail formail.$(O) common.$(O) ${LDFLAGS}
- X
- X_autotst: _autotst.c
- X $(CC) $(CFLAGS) -o _autotst _autotst.c $(LDFLAGS)
- X
- Xautoconf.h: autoconf Makefile
- X /bin/sh autoconf
- X
- X$(OBJ): $(DEP)
- X
- Xretint.$(O): $(DEP) exopen.h
- X
- Xexopen.$(O): config.h includes.h exopen.h
- X
- Xformail.$(O): config.h includes.h shell.h
- X
- Xlockfile.$(O): config.h includes.h
- X
- Xcommon.$(O): includes.h shell.h
- X
- Xprocmail.h: includes.h
- X touch procmail.h
- X
- Xincludes.h: autoconf.h
- X touch includes.h
- X
- X.c.$(O):
- X $(CC) $(CFLAGS) -c $*.c
- X
- Xinstall: all
- X chmod 755 $(BINS)
- X cp $(BINS) $(BINDIR)
- X chmod 644 man/procmail.1 man/lockfile.1 man/formail.1
- X cp man/procmail.1 man/lockfile.1 man/formail.1 $(MANDIR)
- X
- Xclean:
- X $(RM) $(OBJ) common.$(O) lockfile.$(O) exopen.$(O) retint.$(O) \
- Xformail.$(O) $(BINS) autoconf.h _autotst*
- SHAR_EOF
- chmod 0644 procmail/Makefile ||
- echo 'restore of procmail/Makefile failed'
- Wc_c="`wc -c < 'procmail/Makefile'`"
- test 1801 -eq "$Wc_c" ||
- echo 'procmail/Makefile: original size 1801, current size' "$Wc_c"
- fi
- # ============= procmail/autoconf ==============
- if test -f 'procmail/autoconf' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/autoconf (File already exists)'
- else
- echo 'x - extracting procmail/autoconf (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/autoconf' &&
- X#!/bin/sh
- X#$Id: autoconf,v 2.1 1991/06/11 12:59:16 berg Rel $
- X
- XSHELL=/bin/sh || exec /bin/sh <autoconf # we're in a csh, feed myself to sh
- X
- XACONF=autoconf.h
- Xtrap "rm $ACONF;exit 1" 1 2 3 15
- Xcat >$ACONF <<HERE
- X/* This file was automagically generated by autoconf */
- X
- XHERE
- X
- X# WARNING: in ./include/stdlib.h the const keyword is already used!
- X# hence the const test has to precede all others.
- X
- Xcat >_autotst.c <<HERE
- Xmain(){const int i;return 0;}
- XHERE
- X
- Xecho 'Testing for const'
- Xif make _autotst >/dev/null 2>&1
- Xthen
- X:
- Xelse
- X echo '#define const' >>$ACONF
- Xfi
- Xrm -f _autotst _autotst.o
- X
- Xcat >_autotst.c <<HERE
- Xmain(){volatile int i;return 0;}
- XHERE
- X
- Xecho 'Testing for volatile'
- Xif make _autotst >/dev/null 2>&1
- Xthen
- X:
- Xelse
- X echo '#define volatile' >>$ACONF
- Xfi
- Xrm -f _autotst _autotst.o
- X
- Xcat >_autotst.c <<HERE
- Xmain(){int i;i= -1;return i=-i;}
- XHERE
- X
- Xecho 'Testing for compiler age'
- Xmake _autotst >_autotst.rrr 2>&1
- X
- Xif _autotst
- Xthen
- X echo 'Aha, this one is genuine antique!'
- X echo '#define void char' >>$ACONF
- Xfi
- Xrm -f _autotst _autotst.o
- X
- X
- Xcat >_autotst.c <<HERE
- X#include "includes.h"
- Xmain(){int i;
- X void*p;
- X i=(size_t)1;
- X i+=(pid_t)1;
- X i+=(time_t)1;
- X i+=(mode_t)1;
- X return 0;}
- XHERE
- X
- Xecho 'Testing for void*,size_t,pid_t,time_t,mode_t'
- Xmake _autotst >_autotst.rrr 2>&1
- Xrm -f _autotst _autotst.o
- X
- Xgrepfor(){
- Xif fgrep "$1" _autotst.rrr >/dev/null
- Xthen
- X echo "$2" >>$ACONF
- Xfi
- X}
- X
- Xgrepfor void '#define void char'
- Xgrepfor size_t 'typedef unsigned size_t;'
- Xgrepfor pid_t 'typedef int pid_t;'
- Xgrepfor time_t 'typedef long time_t;'
- Xgrepfor mode_t 'typedef int mode_t;'
- X
- Xcat >_autotst.c <<HERE
- X#include "includes.h"
- Xmain(){char a[1];
- X setpwent();endpwent();memmove(a,"t",1);bcopy("t",a,1);strstr(a,"t");return 0;}
- XHERE
- X
- Xecho 'Testing for memmove & strstr'
- Xmake _autotst >_autotst.rrr 2>&1
- Xrm -f _autotst _autotst.o
- X
- Xif fgrep memmove _autotst.rrr >/dev/null
- Xthen
- X echo '#define NOmemmove' >>$ACONF
- X grepfor bcopy '#define NObcopy'
- Xfi
- Xgrepfor strstr '#define NOstrstr'
- Xgrepfor setpwent '#define setpwent()'
- Xgrepfor endpwent '#define endpwent()'
- X
- Xrm -f _autotst*
- X
- Xecho -----------------------------autoconf.h-----------------------------------
- Xcat autoconf.h
- Xecho --------------------------------------------------------------------------
- SHAR_EOF
- chmod 0644 procmail/autoconf ||
- echo 'restore of procmail/autoconf failed'
- Wc_c="`wc -c < 'procmail/autoconf'`"
- test 2224 -eq "$Wc_c" ||
- echo 'procmail/autoconf: original size 2224, current size' "$Wc_c"
- fi
- # ============= procmail/exopen.h ==============
- if test -f 'procmail/exopen.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/exopen.h (File already exists)'
- else
- echo 'x - extracting procmail/exopen.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/exopen.h' &&
- X/*$Id: exopen.h,v 2.0 1991/06/10 14:39:08 berg Rel $*/
- X#define SERIALchars 3
- X#define UNIQnamelen (1+SERIALchars+HOSTNAMElen+1)
- X#define SERIALmask ((1L<<6*SERIALchars)-1)
- SHAR_EOF
- chmod 0644 procmail/exopen.h ||
- echo 'restore of procmail/exopen.h failed'
- Wc_c="`wc -c < 'procmail/exopen.h'`"
- test 170 -eq "$Wc_c" ||
- echo 'procmail/exopen.h: original size 170, current size' "$Wc_c"
- fi
- # ============= procmail/formail.c ==============
- if test -f 'procmail/formail.c' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/formail.c (File already exists)'
- else
- echo 'x - extracting procmail/formail.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/formail.c' &&
- X/************************************************************************
- X * formail.c a mail (re)formatter *
- X * *
- X * Seems to be relatively bug free. *
- X * *
- X * Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands *
- X * The sources can be freely copied for non-commercial use. *
- X * #include "README" *
- X * *
- X * #include "STYLE" *
- X * *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic char rcsid[]="$Id: formail.c,v 2.3 1991/06/12 10:50:21 berg Rel $";
- X#endif
- Xstatic char rcsdate[]="$Date: 1991/06/12 10:50:21 $";
- X#include "config.h" /* I know, overkill, only need BinSh */
- X#include "includes.h"
- X
- X#define BSIZE 4096
- X
- X#define FROM "From "
- X#define UNKNOWN "foo@bar"
- X
- X#define Re (re+1)
- X#define Nextchar(x) do{x=getchar();if(feof(stdin))goto foundeof;}while(0)
- X#define putssn(a,l) tputssn(a,(size_t)(l))
- X#define putcs(a) (errout=putc(a,mystdout))
- X#define PRDO poutfd[0]
- X#define PWRO poutfd[1]
- X
- Xstatic const char From[]=FROM,replyto[]="Reply-To:",Fromm[]="From:",
- X returnpath[]="Return-Path",sender[]="Sender:",outofmem[]="Out of memory\n",
- X subject[]="Subject:",re[]=" Re:",couldntw[]="Couldn't write to stdout",
- X references[]="References:",messageid[]="Message-ID:",Date[]="Date:";
- Xconst char binsh[]=BinSh;
- Xstatic struct {const char*const head;const int len,wrepl;}sest[]={
- X {sender,STRLEN(sender),0},{replyto,STRLEN(replyto),4},
- X {Fromm,STRLEN(Fromm),2},{returnpath,STRLEN(returnpath),1}};
- Xstatic struct {const char*const headr;const int lenr;size_t offset;}rex[]={
- X {subject,STRLEN(subject)},{references,STRLEN(references)},
- X {messageid,STRLEN(messageid)}};
- X#define subj rex[0]
- X#define refr rex[1]
- X#define msid rex[2]
- Xstatic struct {const char*const hedr;const int lnr;}cdigest[]={
- X {Fromm,STRLEN(Fromm)},{Date,STRLEN(Date)},{subject,STRLEN(subject)}};
- X#define mxl(a,b) mx(STRLEN(a),STRLEN(b))
- X#define dig_HDR_LEN mx(mxl(From,Fromm),mxl(Date,subject))
- Xstatic errout,oldstdout;
- Xstatic pid_t child= -1;
- Xstatic FILE*mystdout;
- Xstatic size_t nrskip,nrtotal= -1;
- X
- X#ifdef NOstrstr
- Xchar*strstr(whole,part)const char*whole,*const part;{size_t len;
- X if(!(len=strlen(part)))
- X return(char*)whole;
- X while(*whole&&strncmp(whole,part,len))
- X ++whole;
- X return *whole?(char*)whole:(char*)0;}
- X#endif
- X
- Xvoid*tmalloc(len)const size_t len;{void*p;
- X if(p=malloc(len))
- X return p;
- X log(outofmem);exit(EX_OSERR);}
- X
- Xvoid*trealloc(old,len)void*old;const size_t len;{
- X if(old=realloc(old,len))
- X return old;
- X log(outofmem);exit(EX_OSERR);}
- X
- X#include "shell.h"
- X
- Xmain(argc,argv)const char*const argv[];{time_t t;
- X int i,lastm,nowm,thelen=0,split=0,force=0,bogus=1,every=0,areply=0,
- X trust=0,digest=0,nowait=0;
- X size_t buflen,p=0,lnl=0,thename,ll;
- X char*buf,*chp;
- X while(*++argv){
- X if((lastm= **argv)=='+')
- X goto number;
- X else if(lastm!='-')
- X goto usg;
- X for(i=1;;){
- X switch((*argv)[i++]){
- X case 't':trust=1;continue; /* trust the sender for valid headers */
- X case 'r':areply=1;continue; /* generate a reply */
- X case 'f':force=1;continue; /* accept arbitrary format */
- X case 'e':every=1;continue; /* split on every From */
- X case 'd':digest=1;continue; /* split up digests */
- X case 'n':nowait=1;continue; /* don't wait for the programs */
- X case 's':split=1;bogus=0;
- X if(!(*argv++)[i])
- X goto parsedoptions;
- X goto usg;
- Xnumber: default:
- X if((*argv)[1]-'0'>(unsigned)9){
- Xusg: log("Usage: formail [+nnn] [-nnn] [-bfrtned] \
- X[-s command argument ...]\n");return EX_USAGE;}
- X ll=strtol((*argv)+1,(char**)0,10);
- X if(lastm=='+')
- X nrskip=ll;
- X else
- X nrtotal=ll;
- X break;
- X case 'b':bogus=0;continue; /* leave bogus Froms intact */
- X case '\0':;}
- X break;}}
- Xparsedoptions:
- X mystdout=stdout;
- X if(split){
- X oldstdout=dup(STDOUT);fclose(stdout);startprog(argv);}
- X while('\n'==(i=getchar()));
- X buf=malloc(buflen=BSIZE);t=time((time_t*)0);
- X for(;;){ /* start parsing the header */
- X if((buf[p++]=i)=='\n'){
- X chp=buf+lnl;i=maxindex(rex);
- X while(strnicmp(rex[i].headr,chp,rex[i].lenr)&&i--);
- X if(i>=0) /* found anything already? */
- X rex[i].offset=lnl+rex[i].lenr;
- X else if(!strncmp(From,chp,STRLEN(From))){
- X if(!lnl){ /* was the real "From " line */
- X if(!areply)
- X goto endofheader;
- X nowm=trust?1:3/*wreply*/;ll=lnl+STRLEN(From);goto foundfrom;}
- X if(bogus){
- X tmemmove(chp+1,chp,p++-lnl);*chp='>';}} /* disarm */
- X else{
- X i=maxindex(sest);
- X do
- X if(!strnicmp(sest[i].head,chp,sest[i].len)){
- X nowm=areply?sest[i].wrepl:i;ll=lnl+sest[i].len;
- Xfoundfrom: buf[p]='\0';
- X if(chp=strchr(buf+ll,'<')) /* extract the address */
- X ll=chp-buf+1;
- X chp=buf+(ll+=strspn(buf+ll," \t"));
- X if((i=strcspn(chp,">(\n \t"))&&(!thelen||nowm>lastm)){
- X thename=ll;thelen=i;
- X lastm=strstr(chp,".UUCP")?nowm-maxindex(sest)-1:nowm;}
- X break;}
- X while(i--);
- X if(lnl==p-1)
- X break;} /* end of header reached */
- X lnl=p;}
- X if(p>=buflen-2)
- X buf=realloc(buf,buflen+=BSIZE);
- Xredigest:
- X i=getchar();
- X if(feof(stdin))
- X i='\n';} /* make sure the header ends with 2 newlines */
- X if(areply||!force){
- X putss(areply?"To: ":From);
- X if(thelen) /* found any sender address? */
- X putssn(buf+thename,thelen);
- X else
- X putss(UNKNOWN);
- X if(areply){
- X putcs('\n');
- X if(subj.offset){ /* any Subject: ? */
- X putss(subject);chp=buf+subj.offset;
- X if(strnicmp(chp+strspn(chp," "),Re,STRLEN(Re)))
- X putss(re); /* no Re: , add one ourselves */
- X nlputss(chp);}
- X if(refr.offset||msid.offset){ /* any Message-ID: or References: ? */
- X putss(references);
- X if(refr.offset){
- X chp=buf+refr.offset;
- X putssn(chp,strchr(chp,'\n')-chp+!msid.offset);}
- X if(msid.offset){
- X nlputss(buf+msid.offset);putss("In-Reply-To:");
- X nlputss(buf+msid.offset);}}
- X putcs('\n');
- X while(getchar(),!feof(stdin));return EX_OK;}
- X putcs(' ');putss(ctime(&t));}
- Xendofheader:
- X putssn(buf,p);p=0;lnl=1;
- X if(!bogus&&!split)
- X for(;;putcs(i))
- X Nextchar(i);
- X for(;;){ /* continue the quest */
- X do{ /* read line until not From */
- X if(p==buflen-1)
- X buf=realloc(buf,++buflen);
- X Nextchar(i=buf[p]);
- X if(++p==STRLEN(From))
- X if(!strncmp(From,buf,STRLEN(From))){
- X if(bogus){
- X putcs('>');break;} /* disarm */
- X else if(every)
- X goto splitit;
- X else if(split&&lnl)
- X lnl=2;} /* mark line as possible postmark */
- X if(lnl==1&&digest){
- X thelen=maxindex(cdigest);
- X do /* check for new digest header */
- X if(p==cdigest[thelen].lnr&&!strncmp(buf,cdigest[thelen].hedr,p)){
- X lnl=thelen=0;goto splitit;} /* pretend we started over */
- X while(thelen--);}}
- X while(i!='\n'&&(lnl==2||p<dig_HDR_LEN));
- X if(lnl==2){
- X buf[p]='\0'; /* perform more thorough check for postmark */
- X for(i=STRLEN(From)-1;buf[++i]==' ';);
- X if(ll=strcspn(buf+i,"\n \t")){
- X i+=ll;
- X if(ll=strspn(buf+i," ")&&(ll=buf[i+ll])!='\t'&&ll!='\n'){
- Xsplitit: if(fclose(mystdout)==EOF||errout==EOF){
- X log(couldntw);log(", continuing...\n");split= -1;}
- X if(!nowait)
- X waitforit();
- X startprog(argv);
- X if(!lnl) /* digest split? */
- X goto redigest;
- X i='\n';}}}
- X lnl=p==1;putssn(buf,p);p=0;
- X if(i!='\n')
- X do Nextchar(i);
- X while(putcs(i),i!='\n');}
- Xfoundeof:
- X putssn(buf,p);
- X if(fclose(mystdout)==EOF||errout==EOF){
- X log(couldntw);return EX_IOERR;}
- X child= -1;waitforit();return split<0?EX_IOERR:EX_OK;} /* wait for everyone */
- X
- Xstrnicmp(a,b,l)register const char*a,*b;register unsigned l;{int i,j;
- X if(l) /* case insensitive strncmp */
- X do{
- X while(*a&&*a==*b&&--l)
- X ++a,++b;
- X if(!l)
- X break;
- X if((i= *a++)>='A'&&i<='Z')
- X i+='a'-'A';
- X if((j= *b++)>='A'&&j<='Z')
- X j+='a'-'A';
- X if(j!=i)
- X return i>j?1:-1;}
- X while(i&&j&&--l);
- X return 0;}
- X
- Xlog(a)const char*const a;{
- X fputs(a,stderr);}
- X
- Xlogqnl(a)const char*a;{
- X log(" \"");log(a);log("\"\n");}
- X
- Xnlputss(a)const char*const a;{
- X putssn(a,strchr(a,'\n')+1-a);}
- X
- Xputss(a)const char*a;{
- X while(*a)
- X putcs(*a++);}
- X
- Xtputssn(a,l)const char*a;size_t l;{
- X while(l--)
- X putcs(*a++);}
- X
- Xstartprog(argv)const char*const*const argv;{int poutfd[2];
- X if(!nrtotal)
- X goto squelch;
- X if(nrskip){
- X --nrskip;
- Xsquelch:
- X if(!(mystdout=fopen(DevNull,"a")))
- X goto nofild;
- X return;}
- X if(nrtotal>0)
- X --nrtotal;
- X dup(oldstdout);pipe(poutfd);
- X if(!(child=fork())){
- X close(oldstdout);close(PWRO);fclose(stdin);dup(PRDO);close(PRDO);
- X shexec(argv);}
- X close(STDOUT);close(PRDO);
- X if(STDOUT!=dup(PWRO)||!(mystdout=fdopen(STDOUT,"a"))){
- Xnofild:
- X log("File table full\n");exit(EX_OSERR);}
- X close(PWRO);
- X if(0>child){
- X log("Can't fork\n");exit(EX_OSERR);}}
- X
- Xwaitforit(){int i;
- X while(child!=wait(&i)||(i&127)==127);}
- SHAR_EOF
- chmod 0644 procmail/formail.c ||
- echo 'restore of procmail/formail.c failed'
- Wc_c="`wc -c < 'procmail/formail.c'`"
- test 8833 -eq "$Wc_c" ||
- echo 'procmail/formail.c: original size 8833, current size' "$Wc_c"
- fi
- # ============= procmail/config.h ==============
- if test -f 'procmail/config.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/config.h (File already exists)'
- else
- echo 'x - extracting procmail/config.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/config.h' &&
- X/*$Id: config.h,v 2.0 1991/06/10 14:35:35 berg Rel $*/
- X
- X/*#define console "/dev/console" /* uncomment if you want procmail to
- X use the console (or any other
- X terminal) to print any error messages that could not be dumped in the
- X "logfile". (Only recommended for debugging purposes, if you have
- X trouble creating a "logfile") */
- X
- X/************************************************************************
- X * Only edit below this line if you *think* you know what you are doing *
- X ************************************************************************/
- X
- X#define DEFlinebuf 2048 /* default max expanded line length */
- X#define BLKSIZ 16384 /* blocksize while reading/writing */
- X#define STDBUF 1024 /* blocksize for emulated stdio */
- X#define HOSTNAMElen 8 /* nr of significant chararacters for HOST */
- X#define PROCMAILRC ".procmailrc"
- X#define DEFsuspend 16 /* multi-purpose 'idle loop' period */
- X#define DEFlocksleep 8
- X#define TOkey "^TO"
- X#define TOsubstitute "^(To|Cc|Apparently-To):.*"
- X#define DEFshellmetas "&()[]*?|<>~;:" /* never put '$' in here */
- X#define DEFmaildir "$HOME"
- X#define DEFdefault "$MAILDIR/.mailbox"
- X#define DEFmsgprefix "msg."
- X#define DEForgmail "/usr/spool/mail/$USER"
- X#define DEFgrep "/usr/bin/egrep"
- X#define DEFsendmail "/usr/lib/sendmail"
- X#define DEFlockext ".lock"
- X#define DEFshellflags "-c"
- X#define DEFlocktimeout 3600 /* defaults to one hour */
- X#define DEFnoresretry 2 /* default nr of retries if no resources left */
- X
- X#define NRRECFLAGS (9+1)
- X#define RECFLAGS " %9[HBDIhbfcws] %[^\n]" /* 'I' and 's' are obsolete */
- X#define BinSh "/bin/sh"
- X#define Tmp "/tmp"
- X#define DevNull "/dev/null"
- X#define DIRSEP "/" /* directory separator symbols, the */
- X /* last one should be the most common one */
- X
- X/* the regular expression we use to look for bogus headers
- X (which I took from /usr/ucb/mail) is:
- X "\n\nFrom +[^\t\n ]+ +[^\n\t]" */
- X
- X#define FromSCAN "From%*[ ]%*[^\t\n ]%*[ ]%1[^\n\t]"
- X#define EOFName "%[^ \t\n#'\")};]"
- X
- X#define VERSIONOPT 'v' /* option to display version */
- X#define PRESERVOPT 'p'
- X#define DEBUGOPT 'd'
- X
- X#define MINlinebuf 128 /* minimal LINEBUF length (don't change this) */
- X#define SFROM "From "
- X#define SFROM_S "From%*[ ]%74[^\n]"
- X#define SSUBJECT " Subject:"
- X#define SSUBJECT_S \
- X "%*1[Ss]%*1[Uu]%*1[Bb]%*1[Jj]%*1[Ee]%*1[Cc]%*1[Tt]:%70[^\n]"
- X#define FOLDER " Folder: "
- X#define LENtSTOP 9 /* tab stop at which message length will be logged */
- X
- X#define TABCHAR "\t"
- X#define TABWIDTH 8
- SHAR_EOF
- chmod 0644 procmail/config.h ||
- echo 'restore of procmail/config.h failed'
- Wc_c="`wc -c < 'procmail/config.h'`"
- test 2501 -eq "$Wc_c" ||
- echo 'procmail/config.h: original size 2501, current size' "$Wc_c"
- fi
- # ============= procmail/procmail.h ==============
- if test -f 'procmail/procmail.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/procmail.h (File already exists)'
- else
- echo 'x - extracting procmail/procmail.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/procmail.h' &&
- X/*$Id: procmail.h,v 2.0 1991/06/10 14:35:35 berg Rel $*/
- X
- X#include "includes.h"
- X
- Xtypedef unsigned char uchar;
- X
- X#ifndef console
- X#define console devnull
- X#endif
- X
- X#define XTRAlinebuf 2 /* surplus of LINEBUF (see readparse()) */
- X#define TMNATE '\377' /* terminator (see readoarse()) */
- X
- X#define PRDO poutfd[0]
- X#define PWRO poutfd[1]
- X#define PRDI pinfd[0]
- X#define PWRI pinfd[1]
- X#define PRDB pbackfd[0]
- X#define PWRB pbackfd[1]
- X#define LENoffset (TABWIDTH*LENtSTOP)
- X#define MAXfoldlen (LENoffset-STRLEN(sfolder)-1)
- X#define MCDIRSEP (dirsep+STRLEN(dirsep)-1) /* most common DIRSEP */
- X
- Xstruct varval{const char*const name;long val;};
- X#define locksleep (strenvvar[0].val)
- X#define locktimeout (strenvvar[1].val)
- X#define suspendv (strenvvar[2].val)
- X#define noresretry (strenvvar[3].val)
- X#define MAXvarvals maxindex(strenvvar)
- X
- X#ifndef MAIN
- Xextern char*buf,*buf2,*globlock,*loclock,*tolock,*lastfolder;
- Xextern const char grep[],shellflags[],shell[],lockext[],newline[],binsh[],
- X unexpeof[],shellmetas[],*const*gargv,*sgetcp,*rcfile,dirsep[],msgprefix[],
- X devnull[],executing[],oquote[],cquote[],whilstwfor[];
- Xextern struct varval strenvvar[];
- Xextern long lastdump;
- Xextern sh,pwait,retval,lcking,locknext,verbose,linebuf,rc;
- Xextern volatile flaggerd,nextexit;
- Xextern pid_t thepid;
- X#endif
- X
- X#ifdef NOmemmove
- Xvoid*memmove();
- X#endif
- X
- Xvoid*tmalloc(),*trealloc();
- Xpid_t sfork();
- Xvoid sterminate(),stermchild(),flagger(),errgrandchild();
- Xlong dump(),pipin(),renvint();
- Xchar*readdyn(),*fromprog(),*cat(),*findnl(),*tstrdup(),*cstr();
- Xconst char*tgetenv(),*hostname();
- Xint sgetc(),getb();
- SHAR_EOF
- chmod 0644 procmail/procmail.h ||
- echo 'restore of procmail/procmail.h failed'
- Wc_c="`wc -c < 'procmail/procmail.h'`"
- test 1582 -eq "$Wc_c" ||
- echo 'procmail/procmail.h: original size 1582, current size' "$Wc_c"
- fi
- # ============= procmail/HISTORY ==============
- if test -f 'procmail/HISTORY' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/HISTORY (File already exists)'
- else
- echo 'x - extracting procmail/HISTORY (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/HISTORY' &&
- X1990/12/07: v1.00
- X First release (after 2 weeks of coding and testing)
- X1990/12/12: v1.01
- X Added fsync to procmail.c
- X Removed longjmp in lockfile.c out of the signal handler
- X (not portable, so I'm told)
- X1991/02/04: v1.02
- X Changes to procmail.c:
- X Added physical-write-error check
- X Altered egrep invocation (left out the -s flag, not supported
- X on all machines; this didn't change functionality though)
- X Avoided the 'dirty' allocation of one more byte than needed by
- X rewriting the bogus_header_replace routine
- X Made the search for bogus headers more robust
- X Added sysV lines in Makefile
- X1991/02/13: v1.10
- X Changes to procmail.c:
- X Fixed slight error in parsing the recipe when 'h' and 'b' where
- X specified
- X Started using the official exit codes
- X Made sure that the procmail is not influenced by falsely
- X set environment variables like LOCKSLEEP
- X1991/02/21: v1.20
- X Changes to procmail.c:
- X Removed library conflict on some machines for 'locking'
- X Added uname call as alternative for gethostname
- X Changed name of SHELLMETA to SHELLMETAS (for conformance
- X with dmake)
- X Added LOCKTIMEOUT to learn procmail to decide wether or not
- X a certain lockfile is still 'valid'
- X Added the function sputenv (smart-putenv) to avoid library
- X problems and to finally have a putenv that works the
- X way it was supposed to work all along (you wouldn't believe
- X how brain damaged this library function is :-)
- X Changed environment variable assignment to skip trailing blanks
- X only, and allow intermediate blanks (parsing like make)
- X1991/02/22: v1.21
- X Split up procmail.c in procmail.c, nonint.c, retint.c, procmail.h,
- X config.h, sysexits.h, shell.h
- X Changes to lockfile.c:
- X Added -l option (locktimeout)
- X Moved virtually all configuration stuff from Makefile into
- X config.h
- X Added -v option to procmail
- X1991/03/01: v1.30
- X Added out of memory/swap space immunity (NOMEMRETRY)
- X Made forced terminations of procmail more reliable and verbose
- X (previously, procmail would display erroneous error messages
- X if an attempt was made to kill procmail more than once in
- X rapid succession)
- X Fixed up man pages and comments
- X Included more example files
- X Made sure that variable substitution works in locallockfile-
- X specifications too
- X1991/03/15: v1.35
- X Fixed the problem when no rcfile was found (rc!=NULL)
- X Made my memmove replacement ANSI compatible
- X Fixed up the Makefile (include file dependencies were incorrect)
- X Started using RCS to manage the source
- X1991/06/04: v1.99
- X Changed NOMEMRETRY into NORESRETRY, now all machine limitations
- X are caught
- X Beefed up the parsing routine, now supports virtually complete
- X /bin/sh syntax (*all* quotes and escapes are understood)
- X Cleaned up the code, arranged for all remotely configuration-
- X dependent looking values to be in config.h
- X Created an include directory to catch missing include files
- X Created an autoconf script that determines all installation
- X specifics (all the user has to do now is make)
- X Threw out (the last?) BSD specific library routines
- X ANSI'fied the code, it's now as close as you can get to 'native'
- X ANSI while maintaining compatibility with K&R
- X Stopped using the %i identifier from sscanf
- X Improved the diagnostic messages when procmail is killed (tells
- X you what it was waiting for)
- X Made the file locking mechanism RELIABLE over NFS
- X Procmail now is able to deliver to directories too (AMS --
- X Andrew Mail System), it creates a uniquely named new file for
- X every new mail
- X Threw out the 's' and 'I' options in rcfiles, introduced 'D'
- X Completely rewrote the filter code, made sure that the pid number
- X off procmail does not change anymore while filtering
- X Threw out the stdio library (out of procmail) to avoid the hidden
- X malloc on fopen (I want to catch all mallocs), reliability
- X was improved, binary size did not shrink because the getpwent
- X library links in the stdio library (aargh!)
- X Procmail ditches the environment completely now upon startup
- X Provided a -p flag to preserve the environment
- X Provided a -d flag for debugging purposes (debugging rc scripts)
- X Improved logfile format, now logs a third entry on mail arrival:
- X which folder the mail finally went to and how long it was
- X Made logfile output line buffered to get a cleaner logfile if
- X several programs write it concurrently
- X Changes to lockfile.c:
- X Added -s flag to maintain step with procmail
- X Created formail.c:
- X A new (the third) program
- X Rearranged the routines a bit, so that two object files could be
- X shared between the three programs
- X1991/06/10: v2.00
- X Changed all "ambiguous assignments" to have a space inserted
- X (preserves compatibility with older compilers)
- X Made some more entries in the config.h file
- X Changes to formail.c:
- X Added strstr library replacement
- X Added the option to split digests
- X Updated the manual files (I hate doing this)
- X Updated the example files
- X1991/06/11: v2.01
- X Fixed up includes.h and autoconf to be more POSIX compliant
- X Fixed up small bug in readparse() (goodies.c) that caused trouble
- X with recursively nested backquotes (nobody will probably ever
- X use this, but I was testing worst case behaviour)
- X Documented the $$ environment variable in procmail.1
- X1991/06/12: v2.02
- X Fixed typo in strstr replacement
- X Fixed runaway line while logging long folder names
- SHAR_EOF
- chmod 0644 procmail/HISTORY ||
- echo 'restore of procmail/HISTORY failed'
- Wc_c="`wc -c < 'procmail/HISTORY'`"
- test 5739 -eq "$Wc_c" ||
- echo 'procmail/HISTORY: original size 5739, current size' "$Wc_c"
- fi
- # ============= procmail/FEATURES ==============
- if test -f 'procmail/FEATURES' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/FEATURES (File already exists)'
- else
- echo 'x - extracting procmail/FEATURES (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/FEATURES' &&
- XFeature summary for procmail:
- X + Easy to install
- X + Simple to maintain and configure because
- X all you need is actually only ONE executable (procmail)
- X and ONE configuration file (.procmailrc)
- X + Uses *your* (i.e. easily configurable) favourite regular expression
- X syntax
- X + Allows for very-easy-to-use yes-no decisions on where the mail
- X should go
- X + Filters, delivers and forwards mail *reliably*
- X + Provides a stable and guaranteed environment for any programs or
- X shell scripts you may wish to start upon mail arrival
- X + Is designed for reliability, once procmail gets hold of your mail
- X you can consider it delivered
- X + Is event driven (i.e. gets invoked automagically when mail arrives)
- X + Performs heroically under even the worst conditions
- X (file system full, out of swap space, process table full,
- X file table full, missing support files, unavailable executables,
- X denied permissions) and tries to deliver the mail somehow anyway
- X (it usually succeeds were other programs would have given up)
- X + procmail is the closest you can get to a program that outlives
- X the swapper :-)
- X + Absolutely undeliverable mail (after trying every trick in the book)
- X will bounce back to the sender
- X + Does not use *any* temporary files
- X + Is explicitly designed to work under NFS as well
- X + Performs more reliable mailbox locking than most other mailers
- X (especially across NFS, DON'T use NFS mounted mailboxes WITHOUT
- X installing procmail, you may use valuable mail one day)
- X + Supports both mailfolder standards (single file folders (standard
- X *NIX format) as well as directory folders (AMS -- Andrew Mail System)
- X that contain one file per message)
- X + Variable assignment and substitution is a subset of the standard
- X /bin/sh syntax
- X + Provides a mail log file, which logs all mail arrival, shows
- X in summary whence it came from, what it was about, where it went
- X (what folder) and how long (in bytes) it was
- X + Uses this log file to display a wide range of diagnostic and error
- X messages (if something went wrong)
- X + Processed mail can contain arbitrary 8-bit characters (including
- X '\0'); i.e. binary mailings can be processed if the rest of the
- X mailing system knew how to handle them too
- X + It has a man page (boy, does *it* have a man page)
- X + It can be used as a local delivery agent (substitute for /bin/mail)
- X
- XFeature summary for formail:
- X + Can generate auto-reply headers
- X + Can force mail into mailbox format (so that you can process it with
- X standard mail programs)
- X + Can split up mailboxes into the individual messages
- X + Can split up digests into the individual messages
- X
- XFeature summary for lockfile:
- X + Provides NFS-secure lockfiles to shell script programmers
- SHAR_EOF
- chmod 0644 procmail/FEATURES ||
- echo 'restore of procmail/FEATURES failed'
- Wc_c="`wc -c < 'procmail/FEATURES'`"
- test 2717 -eq "$Wc_c" ||
- echo 'procmail/FEATURES: original size 2717, current size' "$Wc_c"
- fi
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-