home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / procmail / part06 < prev    next >
Encoding:
Text File  |  1993-02-04  |  40.0 KB  |  1,040 lines

  1. Newsgroups: comp.sources.misc
  2. From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
  3. Subject: v35i027:  procmail - mail processing package v2.80, Part06/11
  4. Message-ID: <1993Feb5.020459.16607@sparky.imd.sterling.com>
  5. X-Md4-Signature: 570d6b94a6b1da31e9495ca6f644f790
  6. Date: Fri, 5 Feb 1993 02:04:59 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
  10. Posting-number: Volume 35, Issue 27
  11. Archive-name: procmail/part06
  12. Environment: sendmail, smail, MMDF, mailsurr, UNIX, POSIX
  13. Supersedes: procmail: Volume 31, Issue 40-44
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 6 (of 11)."
  22. # Contents:  procmail280/HISTORY procmail280/mailinglist/INTRO
  23. #   procmail280/man/procmailex.man procmail280/src/goodies.c
  24. # Wrapped by berg@hathi on Thu Feb  4 15:27:59 1993
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'procmail280/HISTORY' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'procmail280/HISTORY'\"
  28. else
  29. echo shar: Extracting \"'procmail280/HISTORY'\" \(9070 characters\)
  30. sed "s/^X//" >'procmail280/HISTORY' <<'END_OF_FILE'
  31. X    Only the last entry is complete, the others might have been condensed.
  32. X
  33. X1990/12/07: v1.00
  34. X1990/12/12: v1.01
  35. X1991/02/04: v1.02
  36. X1991/02/13: v1.10
  37. X1991/02/21: v1.20
  38. X1991/02/22: v1.21
  39. X1991/03/01: v1.30
  40. X1991/03/15: v1.35
  41. X        Started using RCS to manage the source
  42. X1991/06/04: v1.99
  43. X1991/06/10: v2.00
  44. X1991/06/11: v2.01
  45. X1991/06/12: v2.02
  46. X1991/06/20: v2.03
  47. X1991/07/04: v2.10
  48. X1991/07/12: v2.11
  49. X1991/10/02: v2.20 (never released)
  50. X1991/10/18: v2.30
  51. X        Implemented a custom regular expression library (fully egrep
  52. X           compatible), should eliminate the annoyances with incompatible
  53. X           egreps
  54. X        Accomplished the doubtful milestone of having a source file
  55. X           (regexp.c) which provokes a compiler error on an old compiler
  56. X           (if using the optimiser)
  57. X        Ignoring leading spaces on condition lines now (means that
  58. X           everything can be indented in the rcfile)
  59. X1991/10/22: v2.31
  60. X1991/12/05: v2.40
  61. X        Made procmail capable of healing the recipient's mail spool file
  62. X        Tricked NFS into supplying an access_time<modification_time for the
  63. X           folders written
  64. X1991/12/13: v2.50
  65. X1992/01/22: v2.60
  66. X1992/01/31: v2.61
  67. X1992/04/30: v2.70
  68. X        Made procmail & lockfile clock skew independent (important during
  69. X           LOCKTIMEOUT)
  70. X        Made procmail accept multiple recipients (this was not as trivial
  71. X           as it sounds!), in order for complete compatibility with mailers
  72. X           like smail 2.x
  73. X        Expanded the mail-delivery-agent instructions in examples/advanced,
  74. X           this includes specific intstructions for smail 2.x
  75. X        Made special entries in config.h for semi-permanent environment-
  76. X           variable overrides
  77. X        Made formail more intelligent, it can now parse full-fledged
  78. X           RFC822 addresses (quoting et al)
  79. X        A complete rewrite of formail, the code got bigger, the runtime
  80. X           requirement got bigger, it got slower, but, it's more structured
  81. X           (so much for structured programming :-)
  82. X        Made procmail check the permissions of its invoker, generate
  83. X           an overriding From_ line if necessary, and consequently made it
  84. X           accept the -f option (fromwhom), and also the alternate obsolete
  85. X           -r option of course
  86. X        Wiped out the ./include tree, made autoconf check it instead (the
  87. X           compile line looks so terribly clean now :-)
  88. X        Procmail makes an additional security check on the rcfiles before
  89. X           accepting them (owner and permissions, see man page)
  90. X1992/07/01: v2.71
  91. X        Sharpened the autoconf "const" check, to catch buggy AIX compilers
  92. X        Made the MAILBOX_SEPARATORS more orthogonal (i.e. you can define
  93. X           one or both now)
  94. X        Added the -A option to formail, the only option that was missing
  95. X           (to be able to boldly add header fields)
  96. X        Fixed some typos and extended the procmailex man page by a popular
  97. X           example
  98. X        Enhanced the MH directory delivery mode, procmail uses the MH
  99. X           method of finding the next number now (this requires procmail
  100. X           to read the directory)
  101. X        Fixed a typo in the WIFEXITED substitute macro (for non-POSIX
  102. X           systems), should fix all erroneous "program failed" messages
  103. X        Fixed a problem on byte-aligned machines with the 'i' flag
  104. X        Now throwing away all environment variables starting with LD_
  105. X           (not just LD_LIBRARY_PATH), but only on those machines that
  106. X           have the security hole (i.e. SunOS)
  107. X        Created logfile summariser (in shell-script form), by popular
  108. X           demand (examples/mailstat)
  109. X        Gave procmail, formail, lockfile and mailstat a more verbose
  110. X           command line help (called up by -h or -?)
  111. X1993/02/04: v2.80
  112. X        Started using CVS to manage the source (god's gift to programmers)
  113. X        In procmail, lockfile and formail I built in a sanity check now,
  114. X           in case they would be called with argc==0
  115. X        Provided an *extensive* generic mailinglist example (well, it's
  116. X           more than an example really :-)
  117. X        Created the mailinglist swiss-army-knife utility "multigram"
  118. X        Extended the man pages (including more examples)
  119. X        Substantially changed the examples/advanced mailer integration
  120. X           instructions (especially for smail)
  121. X        Provided for brain damaged compilers that misparse #include lines
  122. X        Enhanced lockfile a lot:
  123. X           - the -r option really specifies *re*tries now
  124. X           - concatenated and/or seperate options are allowed now
  125. X           - fixed an inconsistency with removing lockfiles by force
  126. X           - lockfile is more intelligent about locks which are impossible
  127. X         to acquire (it sees it now and displays an appropriate error
  128. X         message)
  129. X           - related to this, lockfile now can return a whole range of
  130. X         standard exitcodes to describe the error
  131. X           - dropped the suid support for lockfile, sgid support however
  132. X         was consolidated (with more descriptive error messages)
  133. X        Changes to formail:
  134. X           - formail does *NOT* CONCATENATE continued header-fields by
  135. X         default now anymore, specify the -c option for this
  136. X           - fixed the sender-determination-code, v2.71 didn't comply
  137. X         with RFC-822 on some points
  138. X           - the sender-determination-code now minimises the mailaddress
  139. X           - taught formail about some more headers, previously formail
  140. X         would refuse to split some mail-articles because it didn't
  141. X         recognise the second field
  142. X           - made it strip the <> on generated mail addresses
  143. X           - reorganised the known header-fields into the header.h file
  144. X         (to allow convenient additions)
  145. X           - introduced the -l option, for generating procmail-alike
  146. X         summaries
  147. X           - introduced the -R option for renaming header-fields
  148. X           - taught it about the Resent- fields when looking for a reply
  149. X         address
  150. X           - made sure that it does not generate an extra empty line at
  151. X         the end of a mail with no body
  152. X           - fixed the '-nnn' option, somehow this got broken
  153. X           - added the -X option for extracting complete fields (to make
  154. X         the toolset complete)
  155. X           - defined away one const, for buggy Convex "ANSI" C compilers
  156. X        Changes to procmail:
  157. X           - procmail does *NOT* CONCATENATE continued header-fields
  158. X         anymore, filter through "formail -c" for this
  159. X           - procmail only escapes bogus From_ lines now when writing a
  160. X         regular mailfolder (otherwise it's unchanged)
  161. X           - changed the method for turning on extended diagnostics, the
  162. X         preceding colon is not supported anymore, use VERBOSE=on
  163. X           - worked over the mailbox-healing code, some changes were
  164. X         needed to ensure complete functionality when the system
  165. X         mailbox is in the user's home directory
  166. X           - taught procmail about $? (see sh(1))
  167. X           - added the INCLUDERC keyword, to permit unlimited nesting
  168. X         of included rcfiles
  169. X           - any program started in backquotes by procmail now has the
  170. X         complete mail on its stdin
  171. X           - all diagnostics logged by procmail will now be preceded by
  172. X         a "procmail: " for easy identification
  173. X           - as long as no LOGFILE has been specified, all diagnostics
  174. X         will be mailed back to the sender (instead of /dev/null)
  175. X           - when a program is specified on an action line, you can
  176. X         precede the line by an environment variable name and an
  177. X         equal sign;  this will read in the (unlimited length) text
  178. X         from stdout into this variable
  179. X           - backslash-newline pairs on continued program-action lines
  180. X         will be simply passed on now;    unless the backslash-newline
  181. X         pair is on an otherwise empty line, in which case only the
  182. X         newline remains
  183. X           - comsat/biff is fully supported now
  184. X           - added the TRAP keyword, to allow for temporary file cleanup
  185. X           - in explicit delivery mode, unknown users are now rejected
  186. X           - system mailboxes with their suid or sgid bits set will not
  187. X         be delivered to anymore, they are presumed to contain SysV
  188. X         autoforwarding information
  189. X           - a condition line of a recipe can now start with '?' in order
  190. X         to use the exitcode of a program as true or false
  191. X           - the ^TO and ^FROM_DAEMON special keywords can now be used
  192. X         anywhere in the regular expression (^TO has been extended
  193. X         as well)
  194. X           - taught the ^^ special token to the internal egrep
  195. X           - more than doubled the speed of the builtin regexp library
  196. X         (which was already fast :-)
  197. X           - procmail uses and defines LOGNAME instead of USER
  198. X        Changes to the installation scripts:
  199. X           - preset values for $(MAKE), $(CC) and $(SHELL) are respected
  200. X         in Makefiles now
  201. X           - a POSIX conforming grep is recognised and used
  202. X           - the need for any -D_POSIX_SOURCE is recognised automatically
  203. X           - to make sure that all this is possible, the Makefiles are
  204. X         created in a two step-process now (make init)
  205. X           - missing libraries for network/socket and opendir support
  206. X         are searched for (you won't believe what names people picked
  207. X         for network support libraries, not in your wildest dreams :-)
  208. X           - the autoconf script now performs a reliability test on kernel
  209. X         locking support
  210. X           - also, network support for comsat tries to build up a compile
  211. X         time cache for trivial get*byname() calls
  212. END_OF_FILE
  213. if test 9070 -ne `wc -c <'procmail280/HISTORY'`; then
  214.     echo shar: \"'procmail280/HISTORY'\" unpacked with wrong size!
  215. fi
  216. # end of 'procmail280/HISTORY'
  217. fi
  218. if test -f 'procmail280/mailinglist/INTRO' -a "${1}" != "-c" ; then 
  219.   echo shar: Will not clobber existing file \"'procmail280/mailinglist/INTRO'\"
  220. else
  221. echo shar: Extracting \"'procmail280/mailinglist/INTRO'\" \(9350 characters\)
  222. sed "s/^X//" >'procmail280/mailinglist/INTRO' <<'END_OF_FILE'
  223. X$Id: INTRO,v 1.5 1993/01/28 14:21:56 berg Exp $
  224. X
  225. X            How to set up mailing lists
  226. X            ---------------------------
  227. X
  228. X        Written by Stephen R. van den Berg.
  229. X                    berg@pool.informatik.rwth-aachen.de
  230. X                    berg@physik.tu-muenchen.de
  231. X
  232. XThis document mainly describes a sendmail environment, much of it applies
  233. Xto non-sendmail mail agents as well.
  234. X
  235. X
  236. XContents:
  237. X---------    1. Intro
  238. X        2. Bouncing mail
  239. X        3. The disadvantages
  240. X        4. How to circumvent these disadvantages
  241. X        5. Why use procmail to filter the mailinglist mail?
  242. X        6. How do I use procmail to filter the mailinglist mail?
  243. X
  244. X1. Intro
  245. X   -----
  246. X
  247. XThe simplest and most direct way to setup a mailinglist is by inserting a line
  248. Xin the /usr/lib/aliases file looking like:
  249. X
  250. Xmylist: fred,john, wilma, barney@bedrock, pebbles
  251. X
  252. XNow all the mail arriving at your machine for "mylist" (either local or
  253. Xmylist@your.domain) will be automatically forwarded to all the mentioned
  254. Xaddresses (fred, john, etc.).
  255. X
  256. XThe address mylist@your.domain is intended for submissions to the list that
  257. Xare supposed to be forwarded to all the subscribers.  For the administrative
  258. Xtasks like removals from the list, new subscriptions to the list, or address
  259. Xchanges of subscribers, it is common practice to create a second entry in the
  260. X/usr/lib/aliases file:
  261. X
  262. Xmylist-request: your_login_name@your.domain
  263. X
  264. X
  265. X2. Bouncing mail
  266. X   -------------
  267. X
  268. XIn order to deal with bouncing mail gracefully, an extra precaution should
  269. Xbe taken.  If for example mail to wilma bounces (user non-existent, mail
  270. Xfilesystem full, etc.), it will bounce back to the original sender.
  271. XNow, the only person that should be concerned with distribution failures
  272. Xshould be the mylist-request holder.  Therefore you should be using a
  273. Xsendmail special alias like:
  274. X
  275. Xowner-mylist: mylist-request@your.domain
  276. X
  277. XThis way local mail will bounce back to mylist-request@your.domain.
  278. X
  279. X
  280. X3. The disadvantages
  281. X   -----------------
  282. X
  283. XIf you are using the above methods, some obvious disadvantages come to mind
  284. Xhowever:
  285. X
  286. Xa. The subscriber list cannot exceed 1000 bytes (on many sendmails).
  287. Xb. The subscriber list cannot be changed on-the-fly (/usr/lib/aliases needs
  288. X   to be edited, and newaliases has to be run).
  289. Xc. People cannot be prevented from submitting messages like "Please remove
  290. X   me from this mailinglist" to mylist (and thereby annoying all subscribers).
  291. Xd. People cannot be guarded from themselves in case they insert
  292. X   "Return-Receipt-To:" fields in their headers (if they are particularly
  293. X   unlucky, they will receive an acknowledge mail from *every* subscriber's
  294. X   sendmail).
  295. Xe. People including "Errors-To:" or "Sender:" fields can cause the bounce
  296. X   messages to bypass owner-mylist anyway.
  297. Xf. There is no way of limiting the number of submitters, i.e. every person
  298. X   who knows the name of the mailing list and who can send mail to your.domain
  299. X   is able to submit messages to the list.  This means, for example, that you
  300. X   cannot limit a mailing list to local users (i.e. only local users can
  301. X   submit).
  302. Xg. You are unable to insert a "Reply-To: mylist@your.domain" in case you
  303. X   would want to (this makes replying to the list easier, too easy as some
  304. X   people say).
  305. X
  306. X
  307. X4. How to circumvent these disadvantages
  308. X   -------------------------------------
  309. X
  310. Xa. Can be circumvented by using nested aliases like:
  311. X    mylist: mylist1, mylist2
  312. X    mylist1: fred,john
  313. X    mylist2: wilma,barney@bedrock,pebbles
  314. X   This can however, become extremely messy to maintain.
  315. X
  316. Xb. This can be avoided if you use aliases like:
  317. X    mylist: :include:/path/to/the/memberfile
  318. X   The memberfile should contain:
  319. X    fred,john,wilma,barney@bedrock,pebbles
  320. X   This will also take care of the upper limit on aliases expansions and
  321. X   newaliases need not be run again every time you change the file.
  322. X
  323. Xc. Can only be taken care of by using a mailfilter like procmail.
  324. X
  325. Xd. Can only be taken care of by using a mailfilter like procmail.
  326. X
  327. Xe. Can only be taken care of by using a mailfilter like procmail.
  328. X
  329. Xf. Can only be taken care of by using a mailfilter like procmail.
  330. X
  331. Xg. Can only be taken care of by using a mailfilter like procmail.
  332. X
  333. X
  334. X5. Why use procmail to filter the mailinglist mail?
  335. X   ------------------------------------------------
  336. X
  337. XInstead of using a mailfilter you could also take care of most of the problems
  338. Xthree till seven by editing the sendmail.cf file.  I would strongly recommend
  339. Xagainst this approach however, since this will be too much of a customising
  340. Xoperation and surely will not be a trivial task (in all cases).     As a general
  341. Xrule: don't mess with a sendmail.cf file once it works :-).
  342. X
  343. XNow, you could, instead of procmail, simply use immediate VNIX commands
  344. Xlike grep, sed or awk to do the mail filtering.     Again, there are some obvious
  345. Xdisadvantages with this approach:
  346. X
  347. XA. In case any system resources go out (no more file descriptors, no more
  348. X   swap space, process table full, file system full (for temporary files))
  349. X   your awk or shell script will fail generously (i.e. several bad things
  350. X   could happen: mail munged, truncated, lost, hanging awk or sh programs,
  351. X   etc., you get the picture).
  352. X
  353. XB. All mail headers (including From: and Reply-To:) could very well be
  354. X   multi-line headers; it will be very difficult to make it understandable
  355. X   to awk that somehow the header line could continue on the next line
  356. X   (in case you want to remove a header, or do some complicated substitution).
  357. X
  358. XC. Another hairy problem will be determining the end of the header, of course
  359. X   that is solvable, but you have to make some extra precautions in your
  360. X   awk script to ensure that any substitutions/changes will not occur in
  361. X   the body of the message (further degrading performance and increasing the
  362. X   load on your machine).
  363. X
  364. XD. Starting programs directly from within aliases or .forward files can get
  365. X   extremely messy, since the environment the program starts in is
  366. X   potentially hostile.
  367. X
  368. XProcmail does not *directly* allow you to change any headers, but that
  369. Xfeature is not really necessary since you can tell procmail to send ONLY the
  370. Xheader through some filter of your choice.
  371. X
  372. XTo comment on the previously mentioned three disadvantages:
  373. X
  374. XA. Procmail takes care of that.     Should the filter have problems anyway,
  375. X   procmail will graciously notice that the filter was in some kind of
  376. X   trouble, and will try something else with the original unmunged mail
  377. X   (you can specify what it should do of course, obvious choices: try
  378. X   the same filter again, drop the mail in a file and send you a notice,
  379. X   forward the mail to you instead (unfiltered), etc.)
  380. X
  381. XB. In order to make consistent scanning of the header possible using the
  382. X   egrep regular expressions built in to procmail, procmail will internally
  383. X   concatenate any headers that were continued according to the RCF 822
  384. X   recommendations, in order for external filters to benefit from this, you
  385. X   would use the formail program to pre-filter the mail.
  386. X
  387. XC. Procmail can be told to send the header, the body or both through the
  388. X   filter, hence your filter need not watch out to avoid doing any
  389. X   substitutions in the body, and the filter can therefore be a lot simpler.
  390. X
  391. XD. Procmail makes no assumptions about the environment it is started in, it
  392. X   assumes that everything is hostile and fights its way back to the
  393. X   civilised world by initialising *everything* to sane and expected default
  394. X   values.  Thereby providing a warm bed for any program started from within
  395. X   procmail.
  396. X
  397. XBut procmail has some additional advantages as well:
  398. X
  399. X -- It will probably all go a bit faster, since only the header of the mail
  400. X    is being piped through the filter.    Also, procmail reads in the mail in
  401. X    16KB chunks, not line by line as sed does.
  402. X
  403. X -- You could use procmail to filter out any messages to the normal mailing
  404. X    list that should have gone to the mylist-request and remail them to
  405. X    mylist-request.
  406. X
  407. XWell, anyway, as you see, procmail does not give you everything you would want,
  408. Xbut this was intentional in accordance to the true VNIX spirit (modularity).
  409. XWhat procmail does provide is a *very* reliable hook (you might say it
  410. Xprovides an anchor :-) for any mail processing you might do.  For the more
  411. Xcomplex things you still have to use shell scripts or call other programs
  412. Xfrom within procmail, but then again, that saves you from learning any
  413. Xparticular syntax procmail would have had to do the same.
  414. X
  415. XAs it happens, the accompanying formail program is able to cater to most
  416. X(if not all) of your needs regarding mail munging.
  417. X
  418. X
  419. X6. How do I use procmail to filter the mailinglist mail?
  420. X   -----------------------------------------------------
  421. X
  422. XIn order to cater for most wishes regarding mailinglist setup, I took the
  423. Xliberty to write some rcfiles for procmail that can readily be used to create
  424. Xany number of mailinglists in a comfortable and simple way.
  425. X
  426. XSee the FEATURES file in this directory for more information on what
  427. Xthese mailinglist scripts will do for you.
  428. X
  429. XIf the scripts do not exactly do what you would have liked, you are invited to
  430. Xedit them to taste.  Perhaps you could send your changes to the procmail
  431. Xmailinglist if you feel that they could be useful to others.
  432. X
  433. XTo get started I suggest you read the INSTALL file in this directory.
  434. X
  435. XFor operating instructions you should read the Manual file in this directory.
  436. X
  437. X
  438. XP.S. Any suggestions/corrections/improvements on this document are welcome.
  439. END_OF_FILE
  440. if test 9350 -ne `wc -c <'procmail280/mailinglist/INTRO'`; then
  441.     echo shar: \"'procmail280/mailinglist/INTRO'\" unpacked with wrong size!
  442. fi
  443. # end of 'procmail280/mailinglist/INTRO'
  444. fi
  445. if test -f 'procmail280/man/procmailex.man' -a "${1}" != "-c" ; then 
  446.   echo shar: Will not clobber existing file \"'procmail280/man/procmailex.man'\"
  447. else
  448. echo shar: Extracting \"'procmail280/man/procmailex.man'\" \(8735 characters\)
  449. sed "s/^X//" >'procmail280/man/procmailex.man' <<'END_OF_FILE'
  450. X.Id $Id: procmailex.man,v 1.10 1993/01/29 13:32:49 berg Exp $
  451. X.de Sx
  452. X.PP
  453. X.ne \\$1
  454. X.Rs
  455. X..
  456. X.de Ex
  457. X.Re
  458. X.PP
  459. X..
  460. X.TH PROCMAILEX 5 \*(Dt BuGless
  461. X.na
  462. X.SH NAME
  463. Xprocmailex \- procmail rcfile examples
  464. X.SH SYNOPSIS
  465. X.B $HOME/+PROCMAILRC+ examples
  466. X.ad
  467. X.Sh DESCRIPTION
  468. XFor a description of the rcfile format see
  469. X.BR procmailrc (5).
  470. X.PP
  471. XThis man page shows several example recipes.  For examples of complete rcfiles
  472. Xyou can check the NOTES section in
  473. X.BR procmail (1),
  474. Xor look at the example rcfiles part of the procmail source distribution
  475. X(procmail*/examples/?procmailrc).
  476. X.Sh EXAMPLES
  477. XSort out all mail coming from the scuba-dive mailling list into the mailfolder
  478. Xscubafile (uses the locallockfile scubafile.lock).
  479. X.Sx 3
  480. X::
  481. X^TOscuba
  482. Xscubafile
  483. X.Ex
  484. XForward all mail from peter about compilers to william (and keep a copy
  485. Xof it here in petcompil).
  486. X.Sx 7
  487. X:2 +CONTINUE+
  488. X^From.*peter
  489. X^Subject:.*compilers
  490. X! william@somewhere.edu
  491. X
  492. X   :+ALSO_NEXT_RECIPE+
  493. X   petcompil
  494. X.Ex
  495. XAn equivalent, but slightly slower solution that accomplishes the same:
  496. X.Sx 9
  497. X:2 +CONTINUE+
  498. X^From.*peter
  499. X^Subject:.*compilers
  500. X! william@somewhere.edu
  501. X
  502. X   :2
  503. X   ^From.*peter
  504. X   ^Subject:.*compilers
  505. X   petcompil
  506. X.Ex
  507. XAdd the headers of all messages that didn't come from the postmaster
  508. Xto your private header collection (for
  509. Xstatistics or mail debugging); and use the lockfile `headc.lock'.  In order
  510. Xto make sure the lockfile is not removed until the pipe has finished,
  511. Xyou have to specify option `+WAIT_EXIT+'; otherwise the lockfile would be
  512. Xremoved as soon as the pipe has accepted the mail.
  513. X.Sx 3
  514. X:+PASS_HEAD++WAIT_EXIT++CONTINUE+:
  515. X!From +[^ ]*(postmaster|Mailer)
  516. X| uncompress headc.Z; cat >>headc; compress headc
  517. X.Ex
  518. XForward all mails shorter than 1000 bytes to my home address (no lockfile
  519. Xneeded on this recipe).
  520. X.Sx 3
  521. X:
  522. X< 1000
  523. X! myname@home
  524. X.Ex
  525. XSplit up incoming digests from the surfing mailing list into their individual
  526. Xmessages, and store them into surfing, using surfing.lock as the locallockfile.
  527. X.Sx 3
  528. X::
  529. X^Subject:.*surfing.*Digest
  530. X| formail +FM_SKIP+1 \-+FM_DIGEST++FM_SPLIT+ cat >>surfing
  531. X.Ex
  532. XStore everything coming from the postmaster or mailer-daemon (like bounced
  533. Xmail) into the file postm, using postm.lock as the locallockfile.
  534. X.Sx 3
  535. X::
  536. X^From[ :].*(postmaster|Mailer)
  537. Xpostm
  538. X.Ex
  539. XA simple autoreply recipe.  It makes sure that neither mail from any daemon
  540. X(like bouncing mail or mail from mailing-lists), nor mail coming from yourself
  541. Xwill be autoreplied.  If this precaution would not be taken, disaster could
  542. Xresult (`ringing' mail).  In order for this recipe to autoreply to all the
  543. Xincoming mail, you should of course insert it before all other recipes in your
  544. Xrcfile.  However, it is advisable to put it
  545. X.I after
  546. Xany recipes that process the mails from subscribed mailinglists; it generally
  547. Xis not a good idea to generate autoreplies to mailinglists (yes, the
  548. X!^FROM_DAEMON regexp should already catch those, but if the mailinglist
  549. Xdoesn't follow accepted conventions, this might not be enough).
  550. X.Sx 4
  551. X: 2 +PASS_HEAD+ +CONTINUE+
  552. X!^FROM_DAEMON
  553. X!^From +YOUR_LOGIN_NAME
  554. X| (formail \-+FM_REPLY+ \-+FM_ADD_ALWAYS+"Precedence: junk";\e
  555. X   echo "Mail received.") | $SENDMAIL \-t
  556. X.Ex
  557. XA more complicated autoreply recipe that implements the functional equivalent
  558. Xof the well known
  559. X.BR vacation (1)
  560. Xprogram.  This recipe is based on the same principles as the last one (prevent
  561. X`ringing' mail).  In addition to that however, it maintains a vacation database
  562. Xby extracting the name of the sender and appending it to the file
  563. X$ALREADYSENT, if the name is
  564. X.B not
  565. Xalready in there.  If the name was new, an autoreply will be sent (using the
  566. X`+ALSO_N_IF_SUCC+' flag functionality).  To reliably extract the name of the
  567. Xsender, I let formail generate an autoreply header (thereby making it figure
  568. Xout the most appropriate sender address), and then telling it to extract the
  569. Xvalue of the `To:' field.
  570. X.Sx 14
  571. XSHELL=/bin/sh    # for other shells, this might need adjustment
  572. XALREADYSENT=$HOME/vacation     # the vacation database
  573. X
  574. X: 2 +PASS_HEAD++WAIT_EXIT_QUIET++CONTINUE+:                       # the lockfile is important
  575. X!^FROM_DAEMON
  576. X!^From +YOUR_LOGIN_NAME
  577. X| FROM="`formail \-+FM_REPLY++FM_EXTRACT+ To:`" ;\e
  578. X  if fgrep \-e "$FROM" <$ALREADYSENT ;\e
  579. X  then exit 1 ;\e
  580. X  else echo "$FROM" >>$ALREADYSENT ;\e
  581. X  fi
  582. X
  583. X   :+ALSO_N_IF_SUCC++PASS_HEAD++CONTINUE+
  584. X   | (formail \-+FM_REPLY++FM_ADD_ALWAYS+"Precedence: junk";\e
  585. X      echo "Mail received.") | $SENDMAIL \-t
  586. X.Ex
  587. XStore all messages concerning TeX in separate, unique filenames, in a directory
  588. Xnamed texmail (this directory has to exist); there is no need to use lockfiles
  589. Xin this case, so we won't.
  590. X.Sx 3
  591. X:
  592. X(^TO|^Subject:.*)TeX[^t]
  593. Xtexmail
  594. X.Ex
  595. XThe same as above, except now we store the mails in numbered files (MH mail
  596. Xfolder), again the texmail directory has to exist already.
  597. X.Sx 3
  598. X:
  599. X(^TO|^Subject:.*)TeX[^t]
  600. Xtexmail/.
  601. X.Ex
  602. XStore all the messages about meetings in a folder that is in a directory
  603. Xthat changes every month.  E.g. if it were January 1994, the folder
  604. Xwould have the name `94-01/meeting' and the locallockfile would be
  605. X`94-01/meeting.lock'.
  606. X.Sx 3
  607. X::
  608. Xmeeting
  609. X`date +%y-%m`/meeting
  610. X.Ex
  611. XThe same as above, but, if the `94-01' directory wouldn't have existed, it
  612. Xis created automatically:
  613. X.Sx 9
  614. XMONTHFOLDER=`date +%y-%m`
  615. X
  616. X:+IGNORE_WRITERR+
  617. X? test ! \-d $MONTHFOLDER
  618. X| mkdir $MONTHFOLDER
  619. X
  620. X::
  621. Xmeeting
  622. X${MONTHFOLDER}/meeting
  623. X.Ex
  624. XThe same as above, but now by slightly different means:
  625. X.Sx 6
  626. XMONTHFOLDER=`date +%y-%m`
  627. XDUMMY=`test \-d $MONTHFOLDER || mkdir $MONTHFOLDER`
  628. X
  629. X::
  630. Xmeeting
  631. X${MONTHFOLDER}/meeting
  632. X.Ex
  633. XTo extract certain headers from a mail and put them into environment
  634. Xvariables you can use any of the following constructs:
  635. X.Sx 5
  636. XSUBJECT=`formail \-+FM_EXTRACT+Subject:`    # regular field
  637. XFROM=`formail \-+FM_REPLY++FM_TRUST+ \-+FM_EXTRACT+To:`        # special case
  638. X
  639. X:0+PASS_HEAD+                             # alternate method
  640. XKEYWORDS=| formail \-+FM_EXTRACT+Keywords:
  641. X.Ex
  642. XIf you are using temporary files in a procmailrc file, and want to make
  643. Xsure that they are removed just before procmail exits, you could use
  644. Xsomething along the lines of:
  645. X.Sx 2
  646. XTEMPORARY=/tmp/pmail.$$
  647. XTRAP="/bin/rm \-f $TEMPORARY"
  648. X.Ex
  649. XThe TRAP keyword can also be used to change the exitcode of procmail.
  650. XI.e. if you want procmail to return an exitcode of `1' instead of its
  651. Xregular exitcodes, you could simply use:
  652. X.Sx 2
  653. XTRAP="exit 1;"   # The trailing semi-colon is important
  654. X                 # since exit is not a standalone program
  655. X.Ex
  656. XThe following recipe prints every incoming mail that looks like a postscript
  657. Xfile.
  658. X.Sx 3
  659. X:+BODY_GREP++PASS_BODY+
  660. X^^%!
  661. X| lpr
  662. X.Ex
  663. XThe following recipe does the same, but is a bit more selective.  It only
  664. Xprints the postscript file if it comes from the print-server.  The first
  665. Xcondition matches only if it is found in the header (i.e. no preceding empty
  666. Xline).  The second condition only matches at the start of the body (i.e.
  667. Xright after the
  668. X.B first
  669. Xempty line).
  670. X.Sx
  671. X:2 +HEAD_GREP++BODY_GREP+ +PASS_BODY+
  672. X^^(.+$)*From[ :].*print-server
  673. X^^(.+$)*^%!
  674. X| lpr
  675. X.Ex
  676. XSuppose you have two accounts, you use both accounts regularly, but they are
  677. Xin very distinct places (i.e. you can only read mail that arrived at either one
  678. Xof the accounts).  You would like to forward mail arriving at account one to
  679. Xaccount two, and the other way around.  The first thing that comes to mind is
  680. Xusing .forward files at both sites; this won't work of course, since you will
  681. Xbe creating a mail loop.  This mail loop can be avoided by inserting the
  682. Xfollowing recipe in front of all other recipes in the +PROCMAILRC+ files on
  683. Xboth sites.  If you make sure that you add the same X-Loop: field at both
  684. Xsites, mail can now safely be forwarded to the other account from either of
  685. Xthem.
  686. X.Sx 4
  687. X:+CONTINUE+
  688. X!^X-Loop: yourname@your.main.mail.address
  689. X| formail \-+FM_ADD_ALWAYS+ "X-Loop: yourname@your.main.mail.address" | \e
  690. X   $SENDMAIL \-oi yourname@the.other.account
  691. X.Ex
  692. XThe following one is rather exotic, but it only serves to demonstrate a
  693. Xfeature.  Suppose you have a file in your HOME directory called ".urgent",
  694. Xand the (one) person named in that file is the sender of an incoming mail,
  695. Xyou'd like that mail to be stored in $MAILDIR/urgent instead of in any of the
  696. Xnormal mailfolders it would have been sorted in.  Then this is what you could
  697. Xdo (beware, the filelength of $HOME/.urgent should be well below $LINEBUF,
  698. Xincrease LINEBUF if necessary):
  699. X.Sx 5
  700. XURGMATCH=`cat $HOME/.urgent`
  701. X
  702. X:+BODY_GREP+:
  703. X$^From.*${URGMATCH}.*
  704. Xurgent
  705. X.Re
  706. X.Sh "SEE ALSO"
  707. X.na
  708. X.nh
  709. X.BR procmail (1),
  710. X.BR procmailrc (5),
  711. X.BR sh (1),
  712. X.BR csh (1),
  713. X.BR mail (1),
  714. X.BR mailx (1),
  715. X.BR binmail (1),
  716. X.BR uucp (1),
  717. X.BR aliases (5),
  718. X.BR sendmail (8),
  719. X.BR egrep (1),
  720. X.BR grep (1),
  721. X.BR biff (1),
  722. X.BR comsat (8),
  723. X.BR lockfile (1),
  724. X.BR formail (1)
  725. X.hy
  726. X.ad
  727. END_OF_FILE
  728. if test 8735 -ne `wc -c <'procmail280/man/procmailex.man'`; then
  729.     echo shar: \"'procmail280/man/procmailex.man'\" unpacked with wrong size!
  730. fi
  731. # end of 'procmail280/man/procmailex.man'
  732. fi
  733. if test -f 'procmail280/src/goodies.c' -a "${1}" != "-c" ; then 
  734.   echo shar: Will not clobber existing file \"'procmail280/src/goodies.c'\"
  735. else
  736. echo shar: Extracting \"'procmail280/src/goodies.c'\" \(9142 characters\)
  737. sed "s/^X//" >'procmail280/src/goodies.c' <<'END_OF_FILE'
  738. X/************************************************************************
  739. X *    Collection of library-worthy routines                *
  740. X *                                    *
  741. X *    Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands    *
  742. X *    #include "README"                        *
  743. X ************************************************************************/
  744. X#ifdef RCS
  745. Xstatic /*const*/char rcsid[]=
  746. X "$Id: goodies.c,v 1.13 1993/01/13 15:20:55 berg Exp $";
  747. X#endif
  748. X#include "procmail.h"
  749. X#include "sublib.h"
  750. X#include "robust.h"
  751. X#include "shell.h"
  752. X#include "misc.h"
  753. X#include "pipes.h"
  754. X#include "common.h"
  755. X#include "cstdio.h"
  756. X#include "goodies.h"
  757. X
  758. Xlong Stdfilled;
  759. X#ifndef GOT_bin_test
  760. Xconst char test[]="test";
  761. X#endif
  762. X
  763. X#define NOTHING_YET    (-1)     /* readparse understands a very complete    */
  764. X#define SKIPPING_SPACE    0     /* subset of the standard /bin/sh syntax    */
  765. X#define NORMAL_TEXT    1     /* that includes single-, double- and back- */
  766. X#define DOUBLE_QUOTED    2     /* quotes, backslashes and $subtitutions    */
  767. X#define SINGLE_QUOTED    3
  768. X
  769. X#define fgetc() (*fpgetc)()       /* some compilers previously choked on it */
  770. X
  771. X/* sarg==0 : normal parsing, split up arguments like in /bin/sh
  772. X * sarg==1 : environment assignment parsing, parse up till first whitespace
  773. X * sarg==2 : normal parsing, split up arguments by single spaces
  774. X */
  775. Xvoid readparse(p,fpgetc,sarg)register char*p;int(*const fpgetc)();
  776. X const int sarg;
  777. X{ static i;int got;char*startb;
  778. X  for(got=NOTHING_YET;;)            /* buf2 is used as scratch space */
  779. Xloop:
  780. X   { i=fgetc();
  781. X     if(buf+linebuf-3<p)        /* doesn't catch everything, just a hint */
  782. X      { nlog("Exceeded LINEBUF\n");p=buf+linebuf-3;goto ready;
  783. X      }
  784. Xnewchar:
  785. X     switch(i)
  786. X      { case EOF:    /* check sarg too to prevent warnings in the recipe- */
  787. X       if(sarg!=2&&got>NORMAL_TEXT)         /* condition expansion code */
  788. Xearly_eof:    nlog(unexpeof);
  789. Xready:       if(got!=SKIPPING_SPACE||sarg)  /* not terminated yet or sarg==2 ? */
  790. X          *p++='\0';
  791. X       *p=TMNATE;return;
  792. X    case '\\':
  793. X       if(got==SINGLE_QUOTED)
  794. X          break;
  795. X       switch(i=fgetc())
  796. X        { case EOF:goto early_eof;              /* can't quote EOF */
  797. X          case '\n':continue;            /* concatenate lines */
  798. X          case '#':
  799. X         if(got>SKIPPING_SPACE) /* escaped comment at start of word? */
  800. X            goto noesc;            /* apparently not, literally */
  801. X          case ' ':case '\t':case '\'':
  802. X         if(got==DOUBLE_QUOTED)
  803. X            goto noesc;
  804. X          case '"':case '\\':case '$':case '`':goto nodelim;
  805. X        }
  806. X       if(got>NORMAL_TEXT)
  807. Xnoesc:          *p++='\\';        /* nothing to escape, just echo both */
  808. X       break;
  809. X    case '`':
  810. X       if(got==SINGLE_QUOTED)
  811. X          goto nodelim;
  812. X       for(startb=p;;)                   /* mark your position */
  813. X        { switch(i=fgetc())             /* copy till next backquote */
  814. X           { case '\\':
  815. X            switch(i=fgetc())
  816. X             { case EOF:nlog(unexpeof);goto forcebquote;
  817. X               case '\n':continue;
  818. X               case '"':
  819. X              if(got!=DOUBLE_QUOTED)
  820. X                 break;
  821. X               case '\\':case '$':case '`':goto escaped;
  822. X             }
  823. X            *p++='\\';break;
  824. X         case '"':
  825. X            if(got!=DOUBLE_QUOTED)     /* missing closing backquote? */
  826. X               break;
  827. Xforcebquote:     case EOF:case '`':
  828. X          { int osh=sh;
  829. X            *p='\0';
  830. X            if(!(sh=!!strpbrk(startb,tgetenv(shellmetas))))
  831. X             { const char*save=sgetcp;
  832. X               sgetcp=p=tstrdup(startb);readparse(startb,sgetc,0);
  833. X#ifndef GOT_bin_test
  834. X               if(!strcmp(test,startb))
  835. X              strcpy(startb,p),sh=1;       /* oops, `test' found */
  836. X#endif
  837. X               free(p);sgetcp=save;               /* chopped up */
  838. X             }            /* drop source buffer, read from program */
  839. X            startb=
  840. X             fromprog(p=startb,startb,(size_t)(buf-startb+linebuf-3));
  841. X            sh=osh;                       /* restore sh */
  842. X            if(got!=DOUBLE_QUOTED)
  843. X             { i=0;startb=p;goto simplsplit;          /* split it up */
  844. X             }
  845. X            if(i=='"'||got<=SKIPPING_SPACE)   /* missing closing ` ? */
  846. X               got=NORMAL_TEXT;                 /* or sarg!=0 ? */
  847. X            p=startb;goto loop;
  848. X          }
  849. X         case '\n':i=';';           /* newlines separate commands */
  850. X           }
  851. Xescaped:      *p++=i;
  852. X        }
  853. X    case '"':
  854. X       switch(got)
  855. X        { case DOUBLE_QUOTED:got=NORMAL_TEXT;continue;    /* closing " */
  856. X          case SINGLE_QUOTED:goto nodelim;
  857. X        }
  858. X       got=DOUBLE_QUOTED;continue;                /* opening " */
  859. X    case '\'':
  860. X       switch(got)
  861. X        { case DOUBLE_QUOTED:goto nodelim;
  862. X          case SINGLE_QUOTED:got=NORMAL_TEXT;continue;}    /* closing ' */
  863. X       got=SINGLE_QUOTED;continue;                /* opening ' */
  864. X    case '#':
  865. X       if(got>SKIPPING_SPACE)        /* comment at start of word? */
  866. X          break;
  867. X       while((i=fgetc())!=EOF&&i!='\n');            /* skip till EOL */
  868. X       goto ready;
  869. X    case '$':
  870. X       if(got==SINGLE_QUOTED)
  871. X          break;
  872. X       if(EOF==(i=fgetc()))
  873. X        { *p++='$';goto ready;
  874. X        }
  875. X       startb=buf2;
  876. X       if(i=='{')                          /* ${name} */
  877. X        { while(EOF!=(i=fgetc())&&alphanum(i))
  878. X         *startb++=i;
  879. X          *startb='\0';
  880. X          if(i!='}')
  881. X           { nlog("Bad substitution of");logqnl(buf2);continue;
  882. X           }
  883. X          i='\0';
  884. X        }
  885. X       else if(alphanum(i))                        /* $name */
  886. X        { do *startb++=i;
  887. X          while(EOF!=(i=fgetc())&&alphanum(i));
  888. X          if(i==EOF)
  889. X         i='\0';
  890. X          *startb='\0';
  891. X        }
  892. X       else if(i=='$')                      /* $$ =pid */
  893. X        { ultstr(0,(unsigned long)thepid,p);goto ieofstr;
  894. X        }
  895. X       else if(i=='?')       /* $? =exitcode from last started program */
  896. X        { strcpy(p,"-1");
  897. X          if(lexitcode>=0)
  898. X         ultstr(0,(unsigned long)lexitcode,p);
  899. X          goto ieofstr;
  900. X        }
  901. X       else if(i=='-')                   /* $- =lastfolder */
  902. X        { strcpy(p,lastfolder);
  903. Xieofstr:      i='\0';goto eofstr;
  904. X        }
  905. X       else
  906. X        { *p++='$';goto newchar;               /* not a substitution */
  907. X        }
  908. X       startb=(char*)tgetenv(buf2);
  909. X       if(got!=DOUBLE_QUOTED)
  910. Xsimplsplit:   for(;;startb++)          /* simply split it up in arguments */
  911. X           { switch(*startb)
  912. X          { case ' ':case '\t':case '\n':
  913. X               if(got<=SKIPPING_SPACE)
  914. X              continue;
  915. X               *p++=sarg?' ':'\0';got=SKIPPING_SPACE;continue;
  916. X            case '\0':goto eeofstr;
  917. X          }
  918. X         *p++= *startb;got=NORMAL_TEXT;
  919. X           }
  920. X       else
  921. X        { strcpy(p,startb);                   /* simply copy it */
  922. Xeofstr:          if(got<=SKIPPING_SPACE)        /* can only occur if sarg!=0 */
  923. X         got=NORMAL_TEXT;
  924. X          p=strchr(p,'\0');
  925. X        }
  926. Xeeofstr:   if(i)                 /* already read next character? */
  927. X          goto newchar;
  928. X       continue;
  929. X    case ' ':case '\t':
  930. X       switch(got)
  931. X        { case NORMAL_TEXT:
  932. X         if(sarg==1)
  933. X            goto ready;        /* already fetched a single argument */
  934. X         got=SKIPPING_SPACE;*p++=sarg?' ':'\0';     /* space or \0 sep. */
  935. X          case NOTHING_YET:case SKIPPING_SPACE:continue;   /* skip space */
  936. X        }
  937. X    case '\n':
  938. X       if(got<=NORMAL_TEXT)
  939. X          goto ready;                /* EOL means we're ready */
  940. X      }
  941. Xnodelim:
  942. X     *p++=i;                       /* ah, a normal character */
  943. X     if(got<=SKIPPING_SPACE)         /* should we bother to change mode? */
  944. X    got=NORMAL_TEXT;
  945. X   }
  946. X}
  947. X
  948. Xwaitfor(pid)const pid_t pid;              /* wait for a specific process */
  949. X{ int i;pid_t j;
  950. X  while(pid!=(j=wait(&i))||WIFSTOPPED(i))
  951. X     if(-1==j)
  952. X    return -1;
  953. X  return lexitcode=WIFEXITED(i)?WEXITSTATUS(i):-1;
  954. X}
  955. X
  956. Xstatic struct lienv{struct lienv*enext;char ename[255];}*myenv;
  957. Xstatic char**lastenv;
  958. X                  /* smart putenv, the way it was supposed to be */
  959. Xvoid sputenv(a)const char*const a;
  960. X{ static alloced;int i,remove;char*split,**preenv;struct lienv*curr,**last;
  961. X  yell("Assigning",a);remove=0;
  962. X  if(!(split=strchr(a,'=')))               /* assignment or removal? */
  963. X     remove=1,split=strchr(a,'\0');
  964. X  i=split-a;
  965. X  for(curr= *(last= &myenv);curr;curr= *(last= &curr->enext))    /* is it one */
  966. X     if(!strncmp(a,curr->ename,i)&&curr->ename[i]=='=')      /* I made earlier? */
  967. X      { split=curr->ename;*last=curr->enext;free(curr);
  968. X    for(preenv=environ;*preenv!=split;preenv++);
  969. X    goto wipenv;
  970. X      }
  971. X  for(preenv=environ;*preenv;preenv++)            /* is it in the standard */
  972. X     if(!strncmp(a,*preenv,i)&&(*preenv)[i]=='=')         /* environment? */
  973. Xwipenv:
  974. X      { while(*preenv=preenv[1])   /* wipe this entry out of the environment */
  975. X       preenv++;
  976. X    break;
  977. X      }
  978. X  i=(preenv-environ+2)*sizeof*environ;
  979. X  if(alloced)           /* have we ever alloced the environ array before? */
  980. X     environ=realloc(environ,i);
  981. X  else
  982. X     alloced=1,environ=tmemmove(malloc(i),environ,i-sizeof*environ);
  983. X  if(!remove)          /* if not remove, then add it to both environments */
  984. X   { for(preenv=environ;*preenv;preenv++);
  985. X     curr=malloc(ioffsetof(struct lienv,ename[0])+(i=strlen(a)+1));
  986. X     tmemmove(*(lastenv=preenv)=curr->ename,a,i);preenv[1]=0;curr->enext=myenv;
  987. X     myenv=curr;
  988. X   }
  989. X}
  990. X                /* between calling primeStdout() and retStdout() */
  991. Xvoid primeStdout P((void))        /* *no* environment changes are allowed! */
  992. X{ char*p;
  993. X  if((p=strchr(buf,'\0'))[-1]!='=')           /* does it end in an '='? */
  994. X     *p='=',p[1]='\0';                    /* make sure it does */
  995. X  sputenv(buf);Stdout=(char*)myenv;
  996. X  Stdfilled=ioffsetof(struct lienv,ename[0])+strlen(myenv->ename);
  997. X}
  998. X
  999. Xvoid retStdout(newmyenv)char*const newmyenv;    /* see note on primeStdout() */
  1000. X{ if(newmyenv[Stdfilled-1]=='\n')           /* strip one trailing newline */
  1001. X     Stdfilled--;
  1002. X  newmyenv[Stdfilled]='\0';*lastenv=(myenv=(struct lienv*)newmyenv)->ename;
  1003. X  Stdout=0;
  1004. X}
  1005. X
  1006. Xvoid postStdout P((void))         /* throw it into the keyword parser */
  1007. X{ const char*p;size_t i;
  1008. X  p= *lastenv;tmemmove(buf,p,i=strchr(p,'=')-p);buf[i]='\0';asenv(p+i+1);
  1009. X}
  1010. END_OF_FILE
  1011. if test 9142 -ne `wc -c <'procmail280/src/goodies.c'`; then
  1012.     echo shar: \"'procmail280/src/goodies.c'\" unpacked with wrong size!
  1013. fi
  1014. # end of 'procmail280/src/goodies.c'
  1015. fi
  1016. echo shar: End of archive 6 \(of 11\).
  1017. cp /dev/null ark6isdone
  1018. MISSING=""
  1019. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1020.     if test ! -f ark${I}isdone ; then
  1021.     MISSING="${MISSING} ${I}"
  1022.     fi
  1023. done
  1024. if test "${MISSING}" = "" ; then
  1025.     echo You have unpacked all 11 archives.
  1026.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1027. else
  1028.     echo You still need to unpack the following archives:
  1029.     echo "        " ${MISSING}
  1030. fi
  1031. ##  End of shell archive.
  1032. exit 0
  1033. -- 
  1034. Sincerely,                                  berg@pool.informatik.rwth-aachen.de
  1035.            Stephen R. van den Berg (AKA BuGless).    berg@physik.tu-muenchen.de
  1036.  
  1037. "Be spontaneous!"
  1038.  
  1039. exit 0 # Just in case...
  1040.