home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume20 / procmail2.10 / part03 < prev    next >
Encoding:
Text File  |  1991-07-11  |  50.7 KB  |  1,430 lines

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