home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume20 / procmail / part03 < prev    next >
Encoding:
Text File  |  1991-06-18  |  44.1 KB  |  1,264 lines

  1. Newsgroups: comp.sources.misc
  2. From: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
  3. Subject:  v20i051:  procmail - mail processing program v2.02, Part03/03
  4. Message-ID: <1991Jun17.043158.1962@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 21263b7c7bb2b8f7e24ffb5258793db8
  6. Date: Mon, 17 Jun 1991 04:31:58 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Stephen R. van den Berg <berg@messua.informatik.rwth-aachen.de>
  10. Posting-number: Volume 20, Issue 51
  11. Archive-name: procmail/part03
  12. Environment: UNIX, sendmail
  13. Supersedes: procmail: Volume 17, Issue 31-32
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. #!/bin/sh
  17. # This is part 03 of procmail
  18. # ============= procmail/retint.c ==============
  19. if test ! -d 'procmail'; then
  20.     echo 'x - creating directory procmail'
  21.     mkdir 'procmail'
  22. fi
  23. if test -f 'procmail/retint.c' -a X"$1" != X"-c"; then
  24.     echo 'x - skipping procmail/retint.c (File already exists)'
  25. else
  26. echo 'x - extracting procmail/retint.c (Text)'
  27. sed 's/^X//' << 'SHAR_EOF' > 'procmail/retint.c' &&
  28. X/************************************************************************
  29. X *    Collection of routines that return an int (sort of anyway :-)    *
  30. X *                                    *
  31. X *    Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands    *
  32. X *    The sources can be freely copied for non-commercial use.    *
  33. X *    #include "README"                        *
  34. X *                                    *
  35. X *    #include "STYLE"                        *
  36. X *                                    *
  37. X ************************************************************************/
  38. X#ifdef    RCS
  39. Xstatic char rcsid[]="$Id: retint.c,v 2.0 1991/06/10 14:35:35 berg Rel $";
  40. X#endif
  41. X#include "config.h"
  42. X#include "procmail.h"
  43. X#include "shell.h"
  44. X
  45. Xsetdef(name,contents)const char*const name,*const contents;{
  46. X strcat(strcat(strcpy(sgetcp=buf2,name),"="),contents);
  47. X readparse(buf,sgetc,0);sputenv(buf);}
  48. X
  49. Xchar*backblock;        /* what is to be recovered in case of filter failure */
  50. Xlong backlen;                               /* its length */
  51. Xpid_t pidfilt,pidchild;
  52. Xint pbackfd[2];                       /* the emergency backpipe :-) */
  53. X
  54. Xpipthrough(line,source,len)char*line,*source;const long len;{
  55. X int pinfd[2],poutfd[2];
  56. X rpipe(pbackfd);rpipe(pinfd);flaggerd=0;         /* main pipes setup */
  57. X if(!(pidchild=fork())){            /* create a sending procmail */
  58. X   backblock=source;backlen=len;signal(SIGTERM,stermchild);
  59. X   signal(SIGINT,stermchild);signal(SIGHUP,stermchild);
  60. X   signal(SIGQUIT,stermchild);rclose(rc);rclose(PRDI);rclose(PRDB);
  61. X   rpipe(poutfd);rclose(STDOUT);
  62. X   if(!(pidfilt=fork())){                /* create the filter */
  63. X      rclose(PWRO);rclose(PWRB);rdup(PWRI);rclose(PWRI);getstdin(PRDO);
  64. X      callnewprog(line);}
  65. X   rclose(PWRI);rclose(PRDO);
  66. X   if(forkerr(pidfilt,line)){
  67. X      rclose(PWRO);stermchild();}
  68. X   if(dump(PWRO,source,len)){          /* send in the text to be filtered */
  69. X      writeerr(line);stermchild();}
  70. X   if(pwait&&waitfor(pidfilt)!=EX_OK){     /* check the exitcode of the filter */
  71. X      progerr(line);stermchild();}
  72. X   rclose(PWRB);kill(thepid,SIGQUIT);exit(EX_OK);} /* tell parent to proceed */
  73. X rclose(PWRI);rclose(PWRB);getstdin(PRDI);
  74. X if(forkerr(pidchild,"procmail"))
  75. X    return 1;
  76. X return 0;}            /* we stay behind to read back the filtered text */
  77. X
  78. Xwaitflagger(){                      /* wait for SIGQUIT from child */
  79. X while(!flaggerd)
  80. X   suspend();}                           /* to prevent polling */
  81. X
  82. Xgrepin(expr,source,len,casesens)const char*const expr,*const source;long len;{
  83. X pid_t pid;int poutfd[2];static const char*newargv[5]={0,"-e"};
  84. X newargv[3]=casesens?(char*)0:"-i";*newargv=tgetenv(grep);newargv[2]=expr;
  85. X rpipe(poutfd);
  86. X if(!(pid=sfork())){                           /* start grep */
  87. X   rclose(PWRO);rclose(rc);getstdin(PRDO);shexec(newargv);}
  88. X rclose(PRDO);len=dump(PWRO,source,len);
  89. X if(!forkerr(pid,*newargv)){
  90. X    if(len)
  91. X       writeerr(*newargv);
  92. X    else
  93. X       return waitfor(pid)!=EX_OK;}                 /* did it grep? */
  94. X return EX_UNAVAILABLE;}
  95. X
  96. Xwaitfor(pid)const pid_t pid;{int i;          /* wait for a specific process */
  97. X while(pid!=wait(&i)||(i&127)==127);
  98. X return i>>8&255;}
  99. X
  100. Xgetstdin(pip)const int pip;{
  101. X rclose(STDIN);rdup(pip);rclose(pip);}
  102. X
  103. Xcallnewprog(newname)const char*const newname;{
  104. X if(sh){const char*newargv[4];             /* should we start a shell? */
  105. X   yell(executing,newname);newargv[3]=0;newargv[2]=newname;
  106. X   newargv[1]=tgetenv(shellflags);*newargv=tgetenv(shell);shexec(newargv);}
  107. X {register const char*p;int argc;const char**newargv;
  108. X argc=1;p=newname;         /* If no shell, chop up the arguments ourselves */
  109. X if(verbose){
  110. X    log(executing);log(oquote);goto no_1st_comma;}
  111. X do{                         /* show chopped up command line */
  112. X   if(verbose){
  113. X      log(",");
  114. Xno_1st_comma:
  115. X      log(p);}
  116. X   while(*p++);}
  117. X while(argc++,*p!=TMNATE);
  118. X if(verbose)
  119. X   log(cquote);
  120. X newargv=malloc(argc*sizeof*newargv);p=newname;argc=0;     /* alloc argv array */
  121. X do{
  122. X   newargv[argc++]=p;
  123. X   while(*p++);}
  124. X while(*p!=TMNATE);
  125. X newargv[argc]=0;shexec(newargv);}}
  126. X
  127. Xwriteerr(line)const char*const line;{
  128. X log("Error while writing to");logqnl(line);}
  129. X
  130. Xforkerr(pid,a)const pid_t pid;const char*const a;{
  131. X if(pid==-1){
  132. X   log("Failed forking");logqnl(a);return 1;}
  133. X return 0;}
  134. X
  135. Xprogerr(line)const char*const line;{
  136. X log("Program failure of");logqnl(line);}
  137. X
  138. Xopena(a)const char*const a;{
  139. X lastfolder=cstr(lastfolder,a);yell("Opening",a);
  140. X return ropen(a,O_WRONLY|O_APPEND|O_CREAT,0666);}
  141. X
  142. Xyell(a,b)const char*const a,*const b;{             /* log if -d option set */
  143. X if(verbose){
  144. X   log(a);logqnl(b);}}
  145. X
  146. Xunlock(lockp)const char**const lockp;{
  147. X lcking=1;
  148. X if(*lockp){
  149. X   yell("Unlocking",*lockp);
  150. X   if(unlink(*lockp)){
  151. X      log("Couldn't unlock");logqnl(*lockp);}
  152. X   free(*lockp);*lockp=0;}
  153. X if(nextexit==1){        /* make sure we are not inside terminate already */
  154. X   log(newline);terminate();}
  155. X lcking=0;}
  156. X
  157. Xnomemerr(){
  158. X log("Out of memory\nbuffer 0: \"");buf[linebuf-1]=buf2[linebuf-1]='\0';
  159. X log(buf);log("\"\nbuffer 1:");logqnl(buf2);retval=EX_OSERR;terminate();}
  160. X
  161. Xlogqnl(a)const char*const a;{
  162. X log(oquote);log(a);log(cquote);}
  163. X
  164. Xnextrcfile(){const char*p;    /* next rcfile specified on the command line */
  165. X while(p= *gargv){
  166. X   gargv++;
  167. X   if(!strchr(p,'=')){
  168. X      rcfile=p;return 1;}}
  169. X return 0;}
  170. X
  171. Xrclose(fd)const int fd;{int i;          /* a sysV secure close (signal immune) */
  172. X while((i=close(fd))&&errno==EINTR);
  173. X return i;}
  174. X
  175. Xrwrite(fd,a,len)const int fd,len;void*const a;{int i; /* a sysV secure write */
  176. X while(0>(i=write(fd,a,(size_t)len))&&errno==EINTR);
  177. X return i;}
  178. X
  179. Xrread(fd,a,len)const int fd,len;void*const a;{int i;   /* a sysV secure read */
  180. X while(0>(i=read(fd,a,(size_t)len))&&errno==EINTR);
  181. X return i;}
  182. X
  183. Xropen(name,mode,mask)const char*const name;const mode_t mask;{int i,r;
  184. X for(r=noresretry;0>(i=open(name,mode,mask));)           /* a sysV secure open */
  185. X   if(errno!=EINTR)
  186. X      if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
  187. X     break;         /* survives a temporary "file table full" condition */
  188. X return i;}
  189. X
  190. Xrdup(p)const int p;{int i,r;
  191. X for(r=noresretry;0>(i=dup(p));)          /* catch "file table full" */
  192. X    if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
  193. X       break;
  194. X return i;}
  195. X
  196. Xrpipe(fd)int fd[2];{int i,r;
  197. X for(r=noresretry;0>(i=pipe(fd));)          /* catch "file table full" */
  198. X    if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--))){
  199. X       *fd=fd[1]= -1;break;}
  200. X return i;}
  201. X
  202. Xlockit(name,lockp)char*name;const char**const lockp;{int i;struct stat stbuf;
  203. X unlock(lockp);                   /* unlock any previous lockfile FIRST */
  204. X if(!*name)
  205. X   return;
  206. X for(lcking=1;;){          /* to prevent deadlocks (I hate deadlocks) */
  207. X   yell("Locking",name);
  208. X   if(!NFSxopen(name)){
  209. X      *lockp=tstrdup(name);               /* lock acquired, hurray! */
  210. Xterm: if(nextexit){
  211. X     log(whilstwfor);log("lockfile");logqnl(name);terminate();}
  212. X      lcking=0;return;}           /* check if it's time for a lock override */
  213. X   if(errno==EEXIST&&!stat(name,&stbuf)&&!stbuf.st_size){time_t t;
  214. X      if(locktimeout&&(t=time((time_t*)0),!stat(name,&stbuf)))    /* from stat */
  215. X     if(locktimeout<t-stbuf.st_mtime){   /* till unlink should be atomic */
  216. X     if(unlink(name)){             /* but can't guarantee that */
  217. X        log("Forced unlock denied on");logqnl(name);}
  218. X     else{
  219. X        log("Forcing lock on");logqnl(name);suspend();}}}
  220. X   else{               /* maybe filename too long, shorten and retry */
  221. X      if(0<(i=strlen(name)-1)&&!strchr(dirsep,(name[i-1]))){
  222. X     name[i]='\0';continue;}
  223. X      log("Lockfailure on");logqnl(name);return;}
  224. X   sleep(DEFlocksleep,locksleep);
  225. X   if(nextexit)
  226. X      goto term;}}
  227. X
  228. Xlcllock(){                   /* lock a local file (if need be) */
  229. X if(locknext)
  230. X   if(tolock)
  231. X      lockit(tolock,&loclock);
  232. X   else
  233. X      lockit(strcat(buf2,tgetenv(lockext)),&loclock);}
  234. X
  235. Xterminate(){
  236. X nextexit=2;            /* prevent multiple invocations of terminate */
  237. X if(retval!=EX_OK)
  238. X   log("Mail bounced\n");
  239. X unlock(&loclock);unlock(&globlock);exit(retval);}
  240. X
  241. Xsuspend(){
  242. X sleep((unsigned)suspendv);}
  243. X
  244. Xskipspace(){
  245. X while(testb(' ')||testb('\t'));}
  246. X
  247. Xsgetc(){                    /* a fake fgetc for a string */
  248. X return *sgetcp?*(uchar*)sgetcp++:EOF;}
  249. X
  250. Xskipped(x)const char*const x;{
  251. X log("Skipped");logqnl(x);}
  252. X
  253. Xstatic uchar rcbuf[STDBUF],*rcbufp,*rcbufend;     /* buffers for custom stdio */
  254. Xstatic ungetb;                         /* pushed back char */
  255. X
  256. Xbopen(name)const char*const name;{                 /* my fopen */
  257. X rcbufp=rcbufend=0;ungetb= -1;yell("Rcfile:",name);
  258. X return rc=ropen(name,O_RDONLY);}
  259. X
  260. Xgetbl(p)char*p;{int i;char*q;                      /* my gets */
  261. X for(q=p;;){
  262. X   switch(i=getb()){
  263. X      case '\n':case EOF:
  264. X     *p='\0';return p!=q;}             /* did we read anything at all? */
  265. X   *p++=i;}}
  266. X
  267. Xgetb(){                                 /* my fgetc */
  268. X if(ungetb>=0){int i;                    /* anything pushed back? */
  269. X   i=ungetb;ungetb= -1;return i;}
  270. X if(rcbufp==rcbufend){
  271. X   rcbufend=rcbuf+rread(rc,rcbufp=rcbuf,STDBUF);}           /* refill */
  272. X return rcbufp<rcbufend?*rcbufp++:EOF;}
  273. X
  274. Xtestb(x)const int x;{int i;       /* fgetc that only succeeds if it matches */
  275. X if((i=getb())==x)
  276. X   return 1;
  277. X ungetb=i;return 0;}
  278. X
  279. Xalphanum(c)const int c;{
  280. X return c>='0'&&c<='9'||c>='a'&&c<='z'||c>='A'&&c<='Z'||c=='_';}
  281. X                       /* open file or new file in directory */
  282. Xdeliver(boxname)char*const boxname;{struct stat stbuf;
  283. X strcpy(buf,boxname);             /* boxname can be found back in buf */
  284. X return stat(buf,&stbuf)||!S_ISDIR(stbuf.st_mode)?opena(buf):dirmail();}
  285. X
  286. X#include "exopen.h"
  287. X                    /* an NFS secure exclusive file open */
  288. XNFSxopen(name)char*name;{char*p,*q;int j= -1,i;
  289. X for(q=name;p=strpbrk(q,dirsep);q=p+1);             /* find last DIRSEP */
  290. X i=q-name;strncpy(p=malloc(i+UNIQnamelen),name,i);
  291. X if(unique(p,p+i,0))
  292. X   j=myrename(p,name);         /* try and rename it, fails if nonexclusive */
  293. X free(p);return j;}
  294. SHAR_EOF
  295. chmod 0644 procmail/retint.c ||
  296. echo 'restore of procmail/retint.c failed'
  297. Wc_c="`wc -c < 'procmail/retint.c'`"
  298. test 9348 -eq "$Wc_c" ||
  299.     echo 'procmail/retint.c: original size 9348, current size' "$Wc_c"
  300. fi
  301. # ============= procmail/shell.h ==============
  302. if test -f 'procmail/shell.h' -a X"$1" != X"-c"; then
  303.     echo 'x - skipping procmail/shell.h (File already exists)'
  304. else
  305. echo 'x - extracting procmail/shell.h (Text)'
  306. sed 's/^X//' << 'SHAR_EOF' > 'procmail/shell.h' &&
  307. X/*$Id: shell.h,v 2.0 1991/06/10 14:39:08 berg Rel $*/
  308. X
  309. X#define malloc(n)    tmalloc((size_t)(n))
  310. X#define realloc(p,n)    trealloc(p,(size_t)(n))
  311. X#define tmemmove(t,f,n) memmove(t,f,(size_t)(n))
  312. SHAR_EOF
  313. chmod 0644 procmail/shell.h ||
  314. echo 'restore of procmail/shell.h failed'
  315. Wc_c="`wc -c < 'procmail/shell.h'`"
  316. test 188 -eq "$Wc_c" ||
  317.     echo 'procmail/shell.h: original size 188, current size' "$Wc_c"
  318. fi
  319. # ============= procmail/INSTALL ==============
  320. if test -f 'procmail/INSTALL' -a X"$1" != X"-c"; then
  321.     echo 'x - skipping procmail/INSTALL (File already exists)'
  322. else
  323. echo 'x - extracting procmail/INSTALL (Text)'
  324. sed 's/^X//' << 'SHAR_EOF' > 'procmail/INSTALL' &&
  325. XTo install procmail, lockfile and formail: edit Makefile accordingly (if need
  326. Xbe, config.h as well) and type 'make install'.
  327. X
  328. X'make install' will:
  329. X      - execute autoconf (a shell script that repeatedly calls the C compiler
  330. X    to determine if certain features/symbols are supported), which will
  331. X    create a file named autoconf.h
  332. X      - compile the *.c files, create the three binaries: procmail, lockfile,
  333. X    formail
  334. X      - copy these binaries to $(BINDIR)
  335. X      - copy the man pages to $(MANDIR)
  336. X
  337. X
  338. XMinimal requirements:
  339. X
  340. Xprocmail must be installed.
  341. Xlockfile needs only to be installed if you plan to read several mailboxes
  342. X    with one of the standard mailers.
  343. Xformail needs only to be installed if mail sometimes arrives in nonstandard
  344. X    mailbox format (or if you want to generate auto replies, split up
  345. X    mailboxes/digests etc., see the man page of formail for more info).
  346. X
  347. X
  348. XIf things don't compile automagically, I suggest you take a look at:
  349. Xautoconf, autoconf.h, config.h, includes.h
  350. X
  351. XThe program is supposed to be fully ANSI and K&R compliant.
  352. X
  353. XIf you run procmail by hand and pipe in some sample mail, then make
  354. Xsure that if you kill procmail, you use "kill pid" and NOT "kill -9 pid".
  355. XShould procmail seem to hang, check if the $LOCKFILE is still present.
  356. XIf you kill procmail with "kill pid" it will clean up the $LOCKFILE
  357. Xitself.
  358. X
  359. XSuggested command line for a test run: "procmail -d LOGFILE=/dev/tty"
  360. X(now type in a mail message).
  361. X
  362. XEvery user that wants to use procmail should have a .forward and a
  363. X.procmailrc file in his HOME directory.     For starters, you can look
  364. Xat the supplied example files in "examples".
  365. X(BTW, be sure to make .forward *world* readable).
  366. X
  367. XFor more info about the program, see the man page.
  368. X
  369. X------------------------------------------------------------------------------
  370. X-----------------------Frequently Asked Questions-----------------------------
  371. X------------------------------------------------------------------------------
  372. X
  373. X1. Why does the logfile have lines containing "file -i not found"?
  374. X
  375. X    Your egrep doesn't understand the -i option (ignore case).  Either
  376. X    use a different grep (e.g. set GREP to /bin/grep), or be sure
  377. X    to specify the 'D' option on every recipe.
  378. X
  379. X2. I installed procmail (i.e. typed 'make install'), but how am I supposed to
  380. X   use it?  When I type procmail on the command line it simply does nothing.
  381. X
  382. X    You're not supposed to start procmail from the command line.
  383. X    Be sure to have a .forward and a .procmailrc file in your home
  384. X    directory (see the examples subdirectory or the man page).
  385. SHAR_EOF
  386. chmod 0644 procmail/INSTALL ||
  387. echo 'restore of procmail/INSTALL failed'
  388. Wc_c="`wc -c < 'procmail/INSTALL'`"
  389. test 2542 -eq "$Wc_c" ||
  390.     echo 'procmail/INSTALL: original size 2542, current size' "$Wc_c"
  391. fi
  392. # ============= procmail/Makefile ==============
  393. if test -f 'procmail/Makefile' -a X"$1" != X"-c"; then
  394.     echo 'x - skipping procmail/Makefile (File already exists)'
  395. else
  396. echo 'x - extracting procmail/Makefile (Text)'
  397. sed 's/^X//' << 'SHAR_EOF' > 'procmail/Makefile' &&
  398. X#$Id: Makefile,v 2.0 1991/06/10 14:39:08 berg Rel $
  399. X
  400. X# change BASENAME to your home directory if need be
  401. XBASENAME = /usr/local
  402. X
  403. XBINDIR     = $(BASENAME)/bin
  404. XMANDIR     = $(BASENAME)/man/man1
  405. X
  406. X########################################################################
  407. X# Only edit below this line if you *think* you know what you are doing #
  408. X########################################################################
  409. X
  410. X# Directory for the standard include files
  411. XUSRINCLUDE = /usr/include
  412. X
  413. XOCFLAGS     = -O
  414. XOLDFLAGS = -s
  415. X
  416. XCFLAGS    = $(OCFLAGS) -I$(USRINCLUDE) -I./include
  417. XLDFLAGS = $(OLDFLAGS)
  418. X
  419. XCC = cc
  420. XO = o
  421. XRM= rm -f
  422. X
  423. XBINS=procmail lockfile formail
  424. X
  425. XOBJ=procmail.$(O) nonint.$(O) goodies.$(O)
  426. X
  427. XDEP=shell.h procmail.h config.h
  428. X
  429. Xall:    autoconf.h $(BINS)
  430. X
  431. Xprocmail: $(OBJ) exopen.$(O) common.$(O) retint.$(O)
  432. X    $(CC) $(CFLAGS) -o procmail $(OBJ) exopen.$(O) common.$(O) \
  433. Xretint.$(O) $(LDFLAGS)
  434. X
  435. Xlockfile: lockfile.$(O) exopen.$(O)
  436. X    $(CC) $(CFLAGS) -o lockfile lockfile.$(O) exopen.$(O) ${LDFLAGS}
  437. X
  438. Xformail: formail.$(O) common.$(O)
  439. X    $(CC) $(CFLAGS) -o formail formail.$(O) common.$(O) ${LDFLAGS}
  440. X
  441. X_autotst: _autotst.c
  442. X    $(CC) $(CFLAGS) -o _autotst _autotst.c $(LDFLAGS)
  443. X
  444. Xautoconf.h: autoconf Makefile
  445. X    /bin/sh autoconf
  446. X
  447. X$(OBJ): $(DEP)
  448. X
  449. Xretint.$(O): $(DEP) exopen.h
  450. X
  451. Xexopen.$(O): config.h includes.h exopen.h
  452. X
  453. Xformail.$(O): config.h includes.h shell.h
  454. X
  455. Xlockfile.$(O): config.h includes.h
  456. X
  457. Xcommon.$(O): includes.h shell.h
  458. X
  459. Xprocmail.h: includes.h
  460. X    touch procmail.h
  461. X
  462. Xincludes.h: autoconf.h
  463. X    touch includes.h
  464. X
  465. X.c.$(O):
  466. X    $(CC) $(CFLAGS) -c $*.c
  467. X
  468. Xinstall: all
  469. X    chmod 755 $(BINS)
  470. X    cp $(BINS) $(BINDIR)
  471. X    chmod 644 man/procmail.1 man/lockfile.1 man/formail.1
  472. X    cp man/procmail.1 man/lockfile.1 man/formail.1 $(MANDIR)
  473. X
  474. Xclean:
  475. X    $(RM) $(OBJ) common.$(O) lockfile.$(O) exopen.$(O) retint.$(O) \
  476. Xformail.$(O) $(BINS) autoconf.h _autotst*
  477. SHAR_EOF
  478. chmod 0644 procmail/Makefile ||
  479. echo 'restore of procmail/Makefile failed'
  480. Wc_c="`wc -c < 'procmail/Makefile'`"
  481. test 1801 -eq "$Wc_c" ||
  482.     echo 'procmail/Makefile: original size 1801, current size' "$Wc_c"
  483. fi
  484. # ============= procmail/autoconf ==============
  485. if test -f 'procmail/autoconf' -a X"$1" != X"-c"; then
  486.     echo 'x - skipping procmail/autoconf (File already exists)'
  487. else
  488. echo 'x - extracting procmail/autoconf (Text)'
  489. sed 's/^X//' << 'SHAR_EOF' > 'procmail/autoconf' &&
  490. X#!/bin/sh
  491. X#$Id: autoconf,v 2.1 1991/06/11 12:59:16 berg Rel $
  492. X
  493. XSHELL=/bin/sh || exec /bin/sh <autoconf # we're in a csh, feed myself to sh
  494. X
  495. XACONF=autoconf.h
  496. Xtrap "rm $ACONF;exit 1" 1 2 3 15
  497. Xcat >$ACONF <<HERE
  498. X/* This file was automagically generated by autoconf */
  499. X
  500. XHERE
  501. X
  502. X# WARNING: in ./include/stdlib.h the const keyword is already used!
  503. X#       hence the const test has to precede all others.
  504. X
  505. Xcat >_autotst.c <<HERE
  506. Xmain(){const int i;return 0;}
  507. XHERE
  508. X
  509. Xecho 'Testing for const'
  510. Xif make _autotst >/dev/null 2>&1
  511. Xthen
  512. X:
  513. Xelse
  514. X echo '#define const' >>$ACONF
  515. Xfi
  516. Xrm -f _autotst _autotst.o
  517. X
  518. Xcat >_autotst.c <<HERE
  519. Xmain(){volatile int i;return 0;}
  520. XHERE
  521. Xecho 'Testing for volatile'
  522. Xif make _autotst >/dev/null 2>&1
  523. Xthen
  524. X:
  525. Xelse
  526. X echo '#define volatile' >>$ACONF
  527. Xfi
  528. Xrm -f _autotst _autotst.o
  529. X
  530. Xcat >_autotst.c <<HERE
  531. Xmain(){int i;i= -1;return i=-i;}
  532. XHERE
  533. X
  534. Xecho 'Testing for compiler age'
  535. Xmake _autotst >_autotst.rrr 2>&1
  536. X
  537. Xif _autotst
  538. Xthen
  539. X echo 'Aha, this one is genuine antique!'
  540. X echo '#define void char' >>$ACONF
  541. Xfi
  542. Xrm -f _autotst _autotst.o
  543. X
  544. X
  545. Xcat >_autotst.c <<HERE
  546. X#include "includes.h"
  547. Xmain(){int i;
  548. X void*p;
  549. X i=(size_t)1;
  550. X i+=(pid_t)1;
  551. X i+=(time_t)1;
  552. X i+=(mode_t)1;
  553. X return 0;}
  554. XHERE
  555. X
  556. Xecho 'Testing for void*,size_t,pid_t,time_t,mode_t'
  557. Xmake _autotst >_autotst.rrr 2>&1
  558. Xrm -f _autotst _autotst.o
  559. X
  560. Xgrepfor(){
  561. Xif fgrep "$1" _autotst.rrr >/dev/null
  562. Xthen
  563. X echo "$2" >>$ACONF
  564. Xfi
  565. X}
  566. X
  567. Xgrepfor void '#define void char'
  568. Xgrepfor size_t 'typedef unsigned size_t;'
  569. Xgrepfor pid_t 'typedef int pid_t;'
  570. Xgrepfor time_t 'typedef long time_t;'
  571. Xgrepfor mode_t 'typedef int mode_t;'
  572. X
  573. Xcat >_autotst.c <<HERE
  574. X#include "includes.h"
  575. Xmain(){char a[1];
  576. X setpwent();endpwent();memmove(a,"t",1);bcopy("t",a,1);strstr(a,"t");return 0;}
  577. XHERE
  578. X
  579. Xecho 'Testing for memmove & strstr'
  580. Xmake _autotst >_autotst.rrr 2>&1
  581. Xrm -f _autotst _autotst.o
  582. X
  583. Xif fgrep memmove _autotst.rrr >/dev/null
  584. Xthen
  585. X echo '#define NOmemmove' >>$ACONF
  586. X grepfor bcopy '#define NObcopy'
  587. Xfi
  588. Xgrepfor strstr '#define NOstrstr'
  589. Xgrepfor setpwent '#define setpwent()'
  590. Xgrepfor endpwent '#define endpwent()'
  591. X
  592. Xrm -f _autotst*
  593. X
  594. Xecho -----------------------------autoconf.h-----------------------------------
  595. Xcat autoconf.h
  596. Xecho --------------------------------------------------------------------------
  597. SHAR_EOF
  598. chmod 0644 procmail/autoconf ||
  599. echo 'restore of procmail/autoconf failed'
  600. Wc_c="`wc -c < 'procmail/autoconf'`"
  601. test 2224 -eq "$Wc_c" ||
  602.     echo 'procmail/autoconf: original size 2224, current size' "$Wc_c"
  603. fi
  604. # ============= procmail/exopen.h ==============
  605. if test -f 'procmail/exopen.h' -a X"$1" != X"-c"; then
  606.     echo 'x - skipping procmail/exopen.h (File already exists)'
  607. else
  608. echo 'x - extracting procmail/exopen.h (Text)'
  609. sed 's/^X//' << 'SHAR_EOF' > 'procmail/exopen.h' &&
  610. X/*$Id: exopen.h,v 2.0 1991/06/10 14:39:08 berg Rel $*/
  611. X#define SERIALchars    3
  612. X#define UNIQnamelen    (1+SERIALchars+HOSTNAMElen+1)
  613. X#define SERIALmask    ((1L<<6*SERIALchars)-1)
  614. SHAR_EOF
  615. chmod 0644 procmail/exopen.h ||
  616. echo 'restore of procmail/exopen.h failed'
  617. Wc_c="`wc -c < 'procmail/exopen.h'`"
  618. test 170 -eq "$Wc_c" ||
  619.     echo 'procmail/exopen.h: original size 170, current size' "$Wc_c"
  620. fi
  621. # ============= procmail/formail.c ==============
  622. if test -f 'procmail/formail.c' -a X"$1" != X"-c"; then
  623.     echo 'x - skipping procmail/formail.c (File already exists)'
  624. else
  625. echo 'x - extracting procmail/formail.c (Text)'
  626. sed 's/^X//' << 'SHAR_EOF' > 'procmail/formail.c' &&
  627. X/************************************************************************
  628. X *    formail.c    a mail (re)formatter                *
  629. X *                                    *
  630. X *    Seems to be relatively bug free.                *
  631. X *                                    *
  632. X *    Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands    *
  633. X *    The sources can be freely copied for non-commercial use.    *
  634. X *    #include "README"                        *
  635. X *                                    *
  636. X *    #include "STYLE"                        *
  637. X *                                    *
  638. X ************************************************************************/
  639. X#ifdef    RCS
  640. Xstatic char rcsid[]="$Id: formail.c,v 2.3 1991/06/12 10:50:21 berg Rel $";
  641. X#endif
  642. Xstatic char rcsdate[]="$Date: 1991/06/12 10:50:21 $";
  643. X#include "config.h"            /* I know, overkill, only need BinSh */
  644. X#include "includes.h"
  645. X
  646. X#define BSIZE    4096
  647. X
  648. X#define FROM        "From "
  649. X#define UNKNOWN        "foo@bar"
  650. X
  651. X#define Re        (re+1)
  652. X#define Nextchar(x)    do{x=getchar();if(feof(stdin))goto foundeof;}while(0)
  653. X#define putssn(a,l)    tputssn(a,(size_t)(l))
  654. X#define putcs(a)    (errout=putc(a,mystdout))
  655. X#define PRDO        poutfd[0]
  656. X#define PWRO        poutfd[1]
  657. X
  658. Xstatic const char From[]=FROM,replyto[]="Reply-To:",Fromm[]="From:",
  659. X returnpath[]="Return-Path",sender[]="Sender:",outofmem[]="Out of memory\n",
  660. X subject[]="Subject:",re[]=" Re:",couldntw[]="Couldn't write to stdout",
  661. X references[]="References:",messageid[]="Message-ID:",Date[]="Date:";
  662. Xconst char binsh[]=BinSh;
  663. Xstatic struct {const char*const head;const int len,wrepl;}sest[]={
  664. X {sender,STRLEN(sender),0},{replyto,STRLEN(replyto),4},
  665. X {Fromm,STRLEN(Fromm),2},{returnpath,STRLEN(returnpath),1}};
  666. Xstatic struct {const char*const headr;const int lenr;size_t offset;}rex[]={
  667. X {subject,STRLEN(subject)},{references,STRLEN(references)},
  668. X {messageid,STRLEN(messageid)}};
  669. X#define subj    rex[0]
  670. X#define refr    rex[1]
  671. X#define msid    rex[2]
  672. Xstatic struct {const char*const hedr;const int lnr;}cdigest[]={
  673. X {Fromm,STRLEN(Fromm)},{Date,STRLEN(Date)},{subject,STRLEN(subject)}};
  674. X#define mxl(a,b)    mx(STRLEN(a),STRLEN(b))
  675. X#define dig_HDR_LEN    mx(mxl(From,Fromm),mxl(Date,subject))
  676. Xstatic errout,oldstdout;
  677. Xstatic pid_t child= -1;
  678. Xstatic FILE*mystdout;
  679. Xstatic size_t nrskip,nrtotal= -1;
  680. X
  681. X#ifdef    NOstrstr
  682. Xchar*strstr(whole,part)const char*whole,*const part;{size_t len;
  683. X if(!(len=strlen(part)))
  684. X   return(char*)whole;
  685. X while(*whole&&strncmp(whole,part,len))
  686. X   ++whole;
  687. X return *whole?(char*)whole:(char*)0;}
  688. X#endif
  689. X
  690. Xvoid*tmalloc(len)const size_t len;{void*p;
  691. X if(p=malloc(len))
  692. X   return p;
  693. X log(outofmem);exit(EX_OSERR);}
  694. X
  695. Xvoid*trealloc(old,len)void*old;const size_t len;{
  696. X if(old=realloc(old,len))
  697. X   return old;
  698. X log(outofmem);exit(EX_OSERR);}
  699. X
  700. X#include "shell.h"
  701. X
  702. Xmain(argc,argv)const char*const argv[];{time_t t;
  703. X int i,lastm,nowm,thelen=0,split=0,force=0,bogus=1,every=0,areply=0,
  704. X   trust=0,digest=0,nowait=0;
  705. X size_t buflen,p=0,lnl=0,thename,ll;
  706. X char*buf,*chp;
  707. X while(*++argv){
  708. X   if((lastm= **argv)=='+')
  709. X      goto number;
  710. X   else if(lastm!='-')
  711. X      goto usg;
  712. X   for(i=1;;){
  713. X      switch((*argv)[i++]){
  714. X     case 't':trust=1;continue;    /* trust the sender for valid headers */
  715. X     case 'r':areply=1;continue;             /* generate a reply */
  716. X     case 'f':force=1;continue;          /* accept arbitrary format */
  717. X     case 'e':every=1;continue;              /* split on every From */
  718. X     case 'd':digest=1;continue;             /* split up digests */
  719. X     case 'n':nowait=1;continue;          /* don't wait for the programs */
  720. X     case 's':split=1;bogus=0;
  721. X        if(!(*argv++)[i])
  722. X           goto parsedoptions;
  723. X        goto usg;
  724. Xnumber:     default:
  725. X        if((*argv)[1]-'0'>(unsigned)9){
  726. Xusg:           log("Usage: formail [+nnn] [-nnn] [-bfrtned] \
  727. X[-s command argument ...]\n");return EX_USAGE;}
  728. X        ll=strtol((*argv)+1,(char**)0,10);
  729. X        if(lastm=='+')
  730. X           nrskip=ll;
  731. X        else
  732. X           nrtotal=ll;
  733. X        break;
  734. X     case 'b':bogus=0;continue;         /* leave bogus Froms intact */
  735. X     case '\0':;}
  736. X      break;}}
  737. Xparsedoptions:
  738. X mystdout=stdout;
  739. X if(split){
  740. X   oldstdout=dup(STDOUT);fclose(stdout);startprog(argv);}
  741. X while('\n'==(i=getchar()));
  742. X buf=malloc(buflen=BSIZE);t=time((time_t*)0);
  743. X for(;;){                     /* start parsing the header */
  744. X   if((buf[p++]=i)=='\n'){
  745. X      chp=buf+lnl;i=maxindex(rex);
  746. X      while(strnicmp(rex[i].headr,chp,rex[i].lenr)&&i--);
  747. X      if(i>=0)                      /* found anything already? */
  748. X     rex[i].offset=lnl+rex[i].lenr;
  749. X      else if(!strncmp(From,chp,STRLEN(From))){
  750. X     if(!lnl){                /* was the real "From " line */
  751. X        if(!areply)
  752. X           goto endofheader;
  753. X        nowm=trust?1:3/*wreply*/;ll=lnl+STRLEN(From);goto foundfrom;}
  754. X     if(bogus){
  755. X        tmemmove(chp+1,chp,p++-lnl);*chp='>';}}           /* disarm */
  756. X      else{
  757. X     i=maxindex(sest);
  758. X     do
  759. X        if(!strnicmp(sest[i].head,chp,sest[i].len)){
  760. X           nowm=areply?sest[i].wrepl:i;ll=lnl+sest[i].len;
  761. Xfoundfrom:     buf[p]='\0';
  762. X           if(chp=strchr(buf+ll,'<'))          /* extract the address */
  763. X          ll=chp-buf+1;
  764. X           chp=buf+(ll+=strspn(buf+ll," \t"));
  765. X           if((i=strcspn(chp,">(\n \t"))&&(!thelen||nowm>lastm)){
  766. X          thename=ll;thelen=i;
  767. X          lastm=strstr(chp,".UUCP")?nowm-maxindex(sest)-1:nowm;}
  768. X           break;}
  769. X     while(i--);
  770. X     if(lnl==p-1)
  771. X        break;}                    /* end of header reached */
  772. X      lnl=p;}
  773. X   if(p>=buflen-2)
  774. X      buf=realloc(buf,buflen+=BSIZE);
  775. Xredigest:
  776. X   i=getchar();
  777. X   if(feof(stdin))
  778. X      i='\n';}            /* make sure the header ends with 2 newlines */
  779. X if(areply||!force){
  780. X   putss(areply?"To: ":From);
  781. X   if(thelen)                    /* found any sender address? */
  782. X      putssn(buf+thename,thelen);
  783. X   else
  784. X      putss(UNKNOWN);
  785. X   if(areply){
  786. X      putcs('\n');
  787. X      if(subj.offset){                       /* any Subject: ? */
  788. X     putss(subject);chp=buf+subj.offset;
  789. X     if(strnicmp(chp+strspn(chp," "),Re,STRLEN(Re)))
  790. X        putss(re);                   /* no Re: , add one ourselves */
  791. X     nlputss(chp);}
  792. X      if(refr.offset||msid.offset){     /* any Message-ID: or References: ? */
  793. X     putss(references);
  794. X     if(refr.offset){
  795. X        chp=buf+refr.offset;
  796. X        putssn(chp,strchr(chp,'\n')-chp+!msid.offset);}
  797. X     if(msid.offset){
  798. X        nlputss(buf+msid.offset);putss("In-Reply-To:");
  799. X        nlputss(buf+msid.offset);}}
  800. X      putcs('\n');
  801. X      while(getchar(),!feof(stdin));return EX_OK;}
  802. X   putcs(' ');putss(ctime(&t));}
  803. Xendofheader:
  804. X putssn(buf,p);p=0;lnl=1;
  805. X if(!bogus&&!split)
  806. X   for(;;putcs(i))
  807. X      Nextchar(i);
  808. X for(;;){                           /* continue the quest */
  809. X   do{                         /* read line until not From */
  810. X      if(p==buflen-1)
  811. X     buf=realloc(buf,++buflen);
  812. X      Nextchar(i=buf[p]);
  813. X      if(++p==STRLEN(From))
  814. X     if(!strncmp(From,buf,STRLEN(From))){
  815. X        if(bogus){
  816. X           putcs('>');break;}                   /* disarm */
  817. X        else if(every)
  818. X           goto splitit;
  819. X        else if(split&&lnl)
  820. X           lnl=2;}               /* mark line as possible postmark */
  821. X      if(lnl==1&&digest){
  822. X     thelen=maxindex(cdigest);
  823. X     do                      /* check for new digest header */
  824. X        if(p==cdigest[thelen].lnr&&!strncmp(buf,cdigest[thelen].hedr,p)){
  825. X           lnl=thelen=0;goto splitit;}      /* pretend we started over */
  826. X     while(thelen--);}}
  827. X   while(i!='\n'&&(lnl==2||p<dig_HDR_LEN));
  828. X   if(lnl==2){
  829. X      buf[p]='\0';         /* perform more thorough check for postmark */
  830. X      for(i=STRLEN(From)-1;buf[++i]==' ';);
  831. X      if(ll=strcspn(buf+i,"\n \t")){
  832. X     i+=ll;
  833. X     if(ll=strspn(buf+i," ")&&(ll=buf[i+ll])!='\t'&&ll!='\n'){
  834. Xsplitit:    if(fclose(mystdout)==EOF||errout==EOF){
  835. X           log(couldntw);log(", continuing...\n");split= -1;}
  836. X        if(!nowait)
  837. X           waitforit();
  838. X        startprog(argv);
  839. X        if(!lnl)                        /* digest split? */
  840. X           goto redigest;
  841. X        i='\n';}}}
  842. X   lnl=p==1;putssn(buf,p);p=0;
  843. X   if(i!='\n')
  844. X      do Nextchar(i);
  845. X      while(putcs(i),i!='\n');}
  846. Xfoundeof:
  847. X putssn(buf,p);
  848. X if(fclose(mystdout)==EOF||errout==EOF){
  849. X   log(couldntw);return EX_IOERR;}
  850. X child= -1;waitforit();return split<0?EX_IOERR:EX_OK;}    /* wait for everyone */
  851. X
  852. Xstrnicmp(a,b,l)register const char*a,*b;register unsigned l;{int i,j;
  853. X if(l)                         /* case insensitive strncmp */
  854. X   do{
  855. X      while(*a&&*a==*b&&--l)
  856. X     ++a,++b;
  857. X      if(!l)
  858. X     break;
  859. X      if((i= *a++)>='A'&&i<='Z')
  860. X     i+='a'-'A';
  861. X      if((j= *b++)>='A'&&j<='Z')
  862. X     j+='a'-'A';
  863. X      if(j!=i)
  864. X     return i>j?1:-1;}
  865. X   while(i&&j&&--l);
  866. X return 0;}
  867. X
  868. Xlog(a)const char*const a;{
  869. X fputs(a,stderr);}
  870. X
  871. Xlogqnl(a)const char*a;{
  872. X log(" \"");log(a);log("\"\n");}
  873. X
  874. Xnlputss(a)const char*const a;{
  875. X putssn(a,strchr(a,'\n')+1-a);}
  876. X
  877. Xputss(a)const char*a;{
  878. X while(*a)
  879. X   putcs(*a++);}
  880. X
  881. Xtputssn(a,l)const char*a;size_t l;{
  882. X while(l--)
  883. X   putcs(*a++);}
  884. X
  885. Xstartprog(argv)const char*const*const argv;{int poutfd[2];
  886. X if(!nrtotal)
  887. X   goto squelch;
  888. X if(nrskip){
  889. X   --nrskip;
  890. Xsquelch:
  891. X   if(!(mystdout=fopen(DevNull,"a")))
  892. X      goto nofild;
  893. X   return;}
  894. X if(nrtotal>0)
  895. X   --nrtotal;
  896. X dup(oldstdout);pipe(poutfd);
  897. X if(!(child=fork())){
  898. X   close(oldstdout);close(PWRO);fclose(stdin);dup(PRDO);close(PRDO);
  899. X   shexec(argv);}
  900. X close(STDOUT);close(PRDO);
  901. X if(STDOUT!=dup(PWRO)||!(mystdout=fdopen(STDOUT,"a"))){
  902. Xnofild:
  903. X   log("File table full\n");exit(EX_OSERR);}
  904. X close(PWRO);
  905. X if(0>child){
  906. X   log("Can't fork\n");exit(EX_OSERR);}}
  907. X
  908. Xwaitforit(){int i;
  909. X while(child!=wait(&i)||(i&127)==127);}
  910. SHAR_EOF
  911. chmod 0644 procmail/formail.c ||
  912. echo 'restore of procmail/formail.c failed'
  913. Wc_c="`wc -c < 'procmail/formail.c'`"
  914. test 8833 -eq "$Wc_c" ||
  915.     echo 'procmail/formail.c: original size 8833, current size' "$Wc_c"
  916. fi
  917. # ============= procmail/config.h ==============
  918. if test -f 'procmail/config.h' -a X"$1" != X"-c"; then
  919.     echo 'x - skipping procmail/config.h (File already exists)'
  920. else
  921. echo 'x - extracting procmail/config.h (Text)'
  922. sed 's/^X//' << 'SHAR_EOF' > 'procmail/config.h' &&
  923. X/*$Id: config.h,v 2.0 1991/06/10 14:35:35 berg Rel $*/
  924. X
  925. X/*#define console    "/dev/console"    /* uncomment if you want procmail to
  926. X                       use the console (or any other
  927. X    terminal) to print any error messages that could not be dumped in the
  928. X    "logfile".  (Only recommended for debugging purposes, if you have
  929. X    trouble creating a "logfile") */
  930. X
  931. X/************************************************************************
  932. X * Only edit below this line if you *think* you know what you are doing *
  933. X ************************************************************************/
  934. X
  935. X#define DEFlinebuf    2048         /* default max expanded line length */
  936. X#define BLKSIZ        16384          /* blocksize while reading/writing */
  937. X#define STDBUF        1024             /* blocksize for emulated stdio */
  938. X#define HOSTNAMElen    8      /* nr of significant chararacters for HOST */
  939. X#define PROCMAILRC    ".procmailrc"
  940. X#define DEFsuspend    16         /* multi-purpose 'idle loop' period */
  941. X#define DEFlocksleep    8
  942. X#define TOkey        "^TO"
  943. X#define TOsubstitute    "^(To|Cc|Apparently-To):.*"
  944. X#define DEFshellmetas    "&()[]*?|<>~;:"            /* never put '$' in here */
  945. X#define DEFmaildir    "$HOME"
  946. X#define DEFdefault    "$MAILDIR/.mailbox"
  947. X#define DEFmsgprefix    "msg."
  948. X#define DEForgmail    "/usr/spool/mail/$USER"
  949. X#define DEFgrep        "/usr/bin/egrep"
  950. X#define DEFsendmail    "/usr/lib/sendmail"
  951. X#define DEFlockext    ".lock"
  952. X#define DEFshellflags    "-c"
  953. X#define DEFlocktimeout    3600                 /* defaults to one hour */
  954. X#define DEFnoresretry    2      /* default nr of retries if no resources left */
  955. X
  956. X#define NRRECFLAGS    (9+1)
  957. X#define RECFLAGS    " %9[HBDIhbfcws] %[^\n]" /* 'I' and 's' are obsolete */
  958. X#define BinSh        "/bin/sh"
  959. X#define Tmp        "/tmp"
  960. X#define DevNull        "/dev/null"
  961. X#define DIRSEP        "/"         /* directory separator symbols, the */
  962. X                   /* last one should be the most common one */
  963. X
  964. X/* the regular expression we use to look for bogus headers
  965. X    (which I took from /usr/ucb/mail) is:
  966. X                          "\n\nFrom +[^\t\n ]+ +[^\n\t]" */
  967. X
  968. X#define FromSCAN    "From%*[ ]%*[^\t\n ]%*[ ]%1[^\n\t]"
  969. X#define EOFName        "%[^ \t\n#'\")};]"
  970. X
  971. X#define VERSIONOPT    'v'            /* option to display version */
  972. X#define PRESERVOPT    'p'
  973. X#define DEBUGOPT    'd'
  974. X
  975. X#define MINlinebuf    128    /* minimal LINEBUF length (don't change this) */
  976. X#define SFROM        "From "
  977. X#define SFROM_S        "From%*[ ]%74[^\n]"
  978. X#define SSUBJECT    " Subject:"
  979. X#define SSUBJECT_S    \
  980. X        "%*1[Ss]%*1[Uu]%*1[Bb]%*1[Jj]%*1[Ee]%*1[Cc]%*1[Tt]:%70[^\n]"
  981. X#define FOLDER        "  Folder: "
  982. X#define LENtSTOP    9 /* tab stop at which message length will be logged */
  983. X
  984. X#define TABCHAR        "\t"
  985. X#define TABWIDTH    8
  986. SHAR_EOF
  987. chmod 0644 procmail/config.h ||
  988. echo 'restore of procmail/config.h failed'
  989. Wc_c="`wc -c < 'procmail/config.h'`"
  990. test 2501 -eq "$Wc_c" ||
  991.     echo 'procmail/config.h: original size 2501, current size' "$Wc_c"
  992. fi
  993. # ============= procmail/procmail.h ==============
  994. if test -f 'procmail/procmail.h' -a X"$1" != X"-c"; then
  995.     echo 'x - skipping procmail/procmail.h (File already exists)'
  996. else
  997. echo 'x - extracting procmail/procmail.h (Text)'
  998. sed 's/^X//' << 'SHAR_EOF' > 'procmail/procmail.h' &&
  999. X/*$Id: procmail.h,v 2.0 1991/06/10 14:35:35 berg Rel $*/
  1000. X
  1001. X#include "includes.h"
  1002. X
  1003. Xtypedef unsigned char uchar;
  1004. X
  1005. X#ifndef console
  1006. X#define console devnull
  1007. X#endif
  1008. X
  1009. X#define XTRAlinebuf    2         /* surplus of LINEBUF (see readparse()) */
  1010. X#define TMNATE        '\377'             /* terminator (see readoarse()) */
  1011. X
  1012. X#define PRDO    poutfd[0]
  1013. X#define PWRO    poutfd[1]
  1014. X#define PRDI    pinfd[0]
  1015. X#define PWRI    pinfd[1]
  1016. X#define PRDB    pbackfd[0]
  1017. X#define PWRB    pbackfd[1]
  1018. X#define LENoffset    (TABWIDTH*LENtSTOP)
  1019. X#define MAXfoldlen    (LENoffset-STRLEN(sfolder)-1)
  1020. X#define MCDIRSEP    (dirsep+STRLEN(dirsep)-1)      /* most common DIRSEP */
  1021. X
  1022. Xstruct varval{const char*const name;long val;};
  1023. X#define locksleep    (strenvvar[0].val)
  1024. X#define locktimeout    (strenvvar[1].val)
  1025. X#define suspendv    (strenvvar[2].val)
  1026. X#define noresretry    (strenvvar[3].val)
  1027. X#define MAXvarvals    maxindex(strenvvar)
  1028. X
  1029. X#ifndef MAIN
  1030. Xextern char*buf,*buf2,*globlock,*loclock,*tolock,*lastfolder;
  1031. Xextern const char grep[],shellflags[],shell[],lockext[],newline[],binsh[],
  1032. X unexpeof[],shellmetas[],*const*gargv,*sgetcp,*rcfile,dirsep[],msgprefix[],
  1033. X devnull[],executing[],oquote[],cquote[],whilstwfor[];
  1034. Xextern struct varval strenvvar[];
  1035. Xextern long lastdump;
  1036. Xextern sh,pwait,retval,lcking,locknext,verbose,linebuf,rc;
  1037. Xextern volatile flaggerd,nextexit;
  1038. Xextern pid_t thepid;
  1039. X#endif
  1040. X
  1041. X#ifdef NOmemmove
  1042. Xvoid*memmove();
  1043. X#endif
  1044. X
  1045. Xvoid*tmalloc(),*trealloc();
  1046. Xpid_t sfork();
  1047. Xvoid sterminate(),stermchild(),flagger(),errgrandchild();
  1048. Xlong dump(),pipin(),renvint();
  1049. Xchar*readdyn(),*fromprog(),*cat(),*findnl(),*tstrdup(),*cstr();
  1050. Xconst char*tgetenv(),*hostname();
  1051. Xint sgetc(),getb();
  1052. SHAR_EOF
  1053. chmod 0644 procmail/procmail.h ||
  1054. echo 'restore of procmail/procmail.h failed'
  1055. Wc_c="`wc -c < 'procmail/procmail.h'`"
  1056. test 1582 -eq "$Wc_c" ||
  1057.     echo 'procmail/procmail.h: original size 1582, current size' "$Wc_c"
  1058. fi
  1059. # ============= procmail/HISTORY ==============
  1060. if test -f 'procmail/HISTORY' -a X"$1" != X"-c"; then
  1061.     echo 'x - skipping procmail/HISTORY (File already exists)'
  1062. else
  1063. echo 'x - extracting procmail/HISTORY (Text)'
  1064. sed 's/^X//' << 'SHAR_EOF' > 'procmail/HISTORY' &&
  1065. X1990/12/07: v1.00
  1066. X        First release (after 2 weeks of coding and testing)
  1067. X1990/12/12: v1.01
  1068. X        Added fsync to procmail.c
  1069. X        Removed longjmp in lockfile.c out of the signal handler
  1070. X        (not portable, so I'm told)
  1071. X1991/02/04: v1.02
  1072. X        Changes to procmail.c:
  1073. X           Added physical-write-error check
  1074. X           Altered egrep invocation (left out the -s flag, not supported
  1075. X          on all machines; this didn't change functionality though)
  1076. X           Avoided the 'dirty' allocation of one more byte than needed by
  1077. X          rewriting the bogus_header_replace routine
  1078. X           Made the search for bogus headers more robust
  1079. X        Added sysV lines in Makefile
  1080. X1991/02/13: v1.10
  1081. X        Changes to procmail.c:
  1082. X           Fixed slight error in parsing the recipe when 'h' and 'b' where
  1083. X          specified
  1084. X           Started using the official exit codes
  1085. X           Made sure that the procmail is not influenced by falsely
  1086. X          set environment variables like LOCKSLEEP
  1087. X1991/02/21: v1.20
  1088. X        Changes to procmail.c:
  1089. X           Removed library conflict on some machines for 'locking'
  1090. X           Added uname call as alternative for gethostname
  1091. X           Changed name of SHELLMETA to SHELLMETAS (for conformance
  1092. X          with dmake)
  1093. X           Added LOCKTIMEOUT to learn procmail to decide wether or not
  1094. X          a certain lockfile is still 'valid'
  1095. X           Added the function sputenv (smart-putenv) to avoid library
  1096. X          problems and to finally have a putenv that works the
  1097. X          way it was supposed to work all along (you wouldn't believe
  1098. X          how brain damaged this library function is :-)
  1099. X           Changed environment variable assignment to skip trailing blanks
  1100. X          only, and allow intermediate blanks (parsing like make)
  1101. X1991/02/22: v1.21
  1102. X        Split up procmail.c in procmail.c, nonint.c, retint.c, procmail.h,
  1103. X           config.h, sysexits.h, shell.h
  1104. X        Changes to lockfile.c:
  1105. X           Added -l option (locktimeout)
  1106. X        Moved virtually all configuration stuff from Makefile into
  1107. X           config.h
  1108. X        Added -v option to procmail
  1109. X1991/03/01: v1.30
  1110. X        Added out of memory/swap space immunity  (NOMEMRETRY)
  1111. X        Made forced terminations of procmail more reliable and verbose
  1112. X           (previously, procmail would display erroneous error messages
  1113. X           if an attempt was made to kill procmail more than once in
  1114. X           rapid succession)
  1115. X        Fixed up man pages and comments
  1116. X        Included more example files
  1117. X        Made sure that variable substitution works in locallockfile-
  1118. X           specifications too
  1119. X1991/03/15: v1.35
  1120. X        Fixed the problem when no rcfile was found (rc!=NULL)
  1121. X        Made my memmove replacement ANSI compatible
  1122. X        Fixed up the Makefile (include file dependencies were incorrect)
  1123. X        Started using RCS to manage the source
  1124. X1991/06/04: v1.99
  1125. X        Changed NOMEMRETRY into NORESRETRY, now all machine limitations
  1126. X           are caught
  1127. X        Beefed up the parsing routine, now supports virtually complete
  1128. X           /bin/sh syntax (*all* quotes and escapes are understood)
  1129. X        Cleaned up the code, arranged for all remotely configuration-
  1130. X           dependent looking values to be in config.h
  1131. X        Created an include directory to catch missing include files
  1132. X        Created an autoconf script that determines all installation
  1133. X           specifics (all the user has to do now is make)
  1134. X        Threw out (the last?) BSD specific library routines
  1135. X        ANSI'fied the code, it's now as close as you can get to 'native'
  1136. X           ANSI while maintaining compatibility with K&R
  1137. X        Stopped using the %i identifier from sscanf
  1138. X        Improved the diagnostic messages when procmail is killed (tells
  1139. X           you what it was waiting for)
  1140. X        Made the file locking mechanism RELIABLE over NFS
  1141. X        Procmail now is able to deliver to directories too (AMS --
  1142. X           Andrew Mail System), it creates a uniquely named new file for
  1143. X           every new mail
  1144. X        Threw out the 's' and 'I' options in rcfiles, introduced 'D'
  1145. X        Completely rewrote the filter code, made sure that the pid number
  1146. X           off procmail does not change anymore while filtering
  1147. X        Threw out the stdio library (out of procmail) to avoid the hidden
  1148. X           malloc on fopen (I want to catch all mallocs), reliability
  1149. X           was improved, binary size did not shrink because the getpwent
  1150. X           library links in the stdio library (aargh!)
  1151. X        Procmail ditches the environment completely now upon startup
  1152. X        Provided a -p flag to preserve the environment
  1153. X        Provided a -d flag for debugging purposes (debugging rc scripts)
  1154. X        Improved logfile format, now logs a third entry on mail arrival:
  1155. X           which folder the mail finally went to and how long it was
  1156. X        Made logfile output line buffered to get a cleaner logfile if
  1157. X           several programs write it concurrently
  1158. X        Changes to lockfile.c:
  1159. X           Added -s flag to maintain step with procmail
  1160. X        Created formail.c:
  1161. X           A new (the third) program
  1162. X        Rearranged the routines a bit, so that two object files could be
  1163. X           shared between the three programs
  1164. X1991/06/10: v2.00
  1165. X        Changed all "ambiguous assignments" to have a space inserted
  1166. X           (preserves compatibility with older compilers)
  1167. X        Made some more entries in the config.h file
  1168. X        Changes to formail.c:
  1169. X           Added strstr library replacement
  1170. X           Added the option to split digests
  1171. X        Updated the manual files (I hate doing this)
  1172. X        Updated the example files
  1173. X1991/06/11: v2.01
  1174. X        Fixed up includes.h and autoconf to be more POSIX compliant
  1175. X        Fixed up small bug in readparse() (goodies.c) that caused trouble
  1176. X           with recursively nested backquotes (nobody will probably ever
  1177. X           use this, but I was testing worst case behaviour)
  1178. X        Documented the $$ environment variable in procmail.1
  1179. X1991/06/12: v2.02
  1180. X        Fixed typo in strstr replacement
  1181. X        Fixed runaway line while logging long folder names
  1182. SHAR_EOF
  1183. chmod 0644 procmail/HISTORY ||
  1184. echo 'restore of procmail/HISTORY failed'
  1185. Wc_c="`wc -c < 'procmail/HISTORY'`"
  1186. test 5739 -eq "$Wc_c" ||
  1187.     echo 'procmail/HISTORY: original size 5739, current size' "$Wc_c"
  1188. fi
  1189. # ============= procmail/FEATURES ==============
  1190. if test -f 'procmail/FEATURES' -a X"$1" != X"-c"; then
  1191.     echo 'x - skipping procmail/FEATURES (File already exists)'
  1192. else
  1193. echo 'x - extracting procmail/FEATURES (Text)'
  1194. sed 's/^X//' << 'SHAR_EOF' > 'procmail/FEATURES' &&
  1195. XFeature summary for procmail:
  1196. X    + Easy to install
  1197. X    + Simple to maintain and configure because
  1198. X      all you need is actually only ONE executable (procmail)
  1199. X      and ONE configuration file (.procmailrc)
  1200. X    + Uses *your* (i.e. easily configurable) favourite regular expression
  1201. X      syntax
  1202. X    + Allows for very-easy-to-use yes-no decisions on where the mail
  1203. X      should go
  1204. X    + Filters, delivers and forwards mail *reliably*
  1205. X    + Provides a stable and guaranteed environment for any programs or
  1206. X      shell scripts you may wish to start upon mail arrival
  1207. X    + Is designed for reliability, once procmail gets hold of your mail
  1208. X      you can consider it delivered
  1209. X    + Is event driven (i.e. gets invoked automagically when mail arrives)
  1210. X    + Performs heroically under even the worst conditions
  1211. X      (file system full, out of swap space, process table full,
  1212. X      file table full, missing support files, unavailable executables,
  1213. X      denied permissions) and tries to deliver the mail somehow anyway
  1214. X      (it usually succeeds were other programs would have given up)
  1215. X    + procmail is the closest you can get to a program that outlives
  1216. X      the swapper :-)
  1217. X    + Absolutely undeliverable mail (after trying every trick in the book)
  1218. X      will bounce back to the sender
  1219. X    + Does not use *any* temporary files
  1220. X    + Is explicitly designed to work under NFS as well
  1221. X    + Performs more reliable mailbox locking than most other mailers
  1222. X      (especially across NFS, DON'T use NFS mounted mailboxes WITHOUT
  1223. X      installing procmail, you may use valuable mail one day)
  1224. X    + Supports both mailfolder standards (single file folders (standard
  1225. X      *NIX format) as well as directory folders (AMS -- Andrew Mail System)
  1226. X      that contain one file per message)
  1227. X    + Variable assignment and substitution is a subset of the standard
  1228. X      /bin/sh syntax
  1229. X    + Provides a mail log file, which logs all mail arrival, shows
  1230. X      in summary whence it came from, what it was about, where it went
  1231. X      (what folder) and how long (in bytes) it was
  1232. X    + Uses this log file to display a wide range of diagnostic and error
  1233. X      messages (if something went wrong)
  1234. X    + Processed mail can contain arbitrary 8-bit characters (including
  1235. X      '\0'); i.e. binary mailings can be processed if the rest of the
  1236. X      mailing system knew how to handle them too
  1237. X    + It has a man page (boy, does *it* have a man page)
  1238. X    + It can be used as a local delivery agent (substitute for /bin/mail)
  1239. X
  1240. XFeature summary for formail:
  1241. X    + Can generate auto-reply headers
  1242. X    + Can force mail into mailbox format (so that you can process it with
  1243. X      standard mail programs)
  1244. X    + Can split up mailboxes into the individual messages
  1245. X    + Can split up digests into the individual messages
  1246. X
  1247. XFeature summary for lockfile:
  1248. X    + Provides NFS-secure lockfiles to shell script programmers
  1249. SHAR_EOF
  1250. chmod 0644 procmail/FEATURES ||
  1251. echo 'restore of procmail/FEATURES failed'
  1252. Wc_c="`wc -c < 'procmail/FEATURES'`"
  1253. test 2717 -eq "$Wc_c" ||
  1254.     echo 'procmail/FEATURES: original size 2717, current size' "$Wc_c"
  1255. fi
  1256. exit 0
  1257. exit 0 # Just in case...
  1258. -- 
  1259. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1260. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1261. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1262. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1263.