home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume38 / procmail / part07 < prev    next >
Text File  |  1993-07-05  |  49KB  |  1,350 lines

  1. Newsgroups: comp.sources.misc
  2. From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
  3. Subject: v38i026:  procmail - mail processing package v2.90, Part07/11
  4. Message-ID: <1993Jul1.151226.21582@sparky.imd.sterling.com>
  5. X-Md4-Signature: ea8005409a460f2b671fc61f971440fe
  6. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Thu, 1 Jul 1993 15:12:26 GMT
  9. Approved: kent@sparky.imd.sterling.com
  10.  
  11. Submitted-by: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
  12. Posting-number: Volume 38, Issue 26
  13. Archive-name: procmail/part07
  14. Environment: sendmail, smail, MMDF, mailsurr, UNIX, POSIX
  15. Supersedes: procmail: Volume 35, Issue 21-32,124,125
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 7 (of 11)."
  24. # Contents:  procmail/config.h procmail/examples/advanced
  25. #   procmail/man/procmailex.man procmail/src/misc.c
  26. #   procmail/src/regexp.h
  27. # Wrapped by berg@tubastos on Thu Jul  1 14:06:17 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'procmail/config.h' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'procmail/config.h'\"
  31. else
  32. echo shar: Extracting \"'procmail/config.h'\" \(12187 characters\)
  33. sed "s/^X//" >'procmail/config.h' <<'END_OF_FILE'
  34. X/*$Id: config.h,v 1.27 1993/07/01 11:58:23 berg Exp $*/
  35. X
  36. X/*#define sMAILBOX_SEPARATOR    "\1\1\1\1\n"    /* sTART- and eNDing separ.  */
  37. X/*#define eMAILBOX_SEPARATOR    "\1\1\1\1\n"    /* uncomment (one or both)
  38. X                           if your mail system uses
  39. X    nonstandard mail separators (non sendmail or smail compatible mailers
  40. X    like MMDF), if yours is even different, uncomment and change the
  41. X    value of course */
  42. X
  43. X/* KEEPENV and PRESTENV should be defined as a comma-separated null-terminated
  44. X   list of strings */
  45. X
  46. X/* every environment variable appearing in KEEPENV will not be thrown away
  47. X * upon startup of procmail, e.g. you could define KEEPENV as follows:
  48. X * #define KEEPENV    {"TZ","LANG",0}
  49. X * environment variables ending in an _ will designate the whole group starting
  50. X * with this prefix (e.g. "LC_").
  51. X */
  52. X#define KEEPENV        {"TZ",0}
  53. X
  54. X/* every environment variable appearing in PRESTENV will be set or wiped
  55. X * out of the environment (variables without an '=' sign will be thrown
  56. X * out), e.g. you could define PRESTENV as follows:
  57. X * #define PRESTENV    {"IFS","PATH=$HOME/bin:/bin:/usr/bin",0}
  58. X * any side effects (like setting the umask after an assignment to UMASK) will
  59. X * *not* take place
  60. X */
  61. X#define PRESTENV    {"IFS","PATH=$HOME/bin:/bin:/usr/bin", \
  62. X             "USER=$LOGNAME",0}
  63. X
  64. X/************************************************************************
  65. X * Only edit below this line if you have viewed/edited this file before *
  66. X ************************************************************************/
  67. X
  68. X/* every user & group appearing in TRUSTED_IDS is allowed to use the -f option
  69. X   if the list is empty (just a terminating 0), everyone can use it
  70. X   TRUSTED_IDS should be defined as a comma-separated null-terminated
  71. X   list of strings */
  72. X
  73. X#define TRUSTED_IDS    {"root","daemon","uucp","mail","x400",\
  74. X             "list","lists",0}
  75. X
  76. X/*#define NO_USER_TO_LOWERCASE_HACK    /* uncomment if your getpwnam() is
  77. X                       case insensitive or if procmail
  78. X    will always be supplied with the correct case in the explicit
  79. X    delivery mode argument(s) */
  80. X
  81. X/*#define NO_fcntl_LOCK        /* uncomment any of these three if you         */
  82. X/*#define NO_lockf_LOCK        /* definitely do not want procmail to make   */
  83. X/*#define NO_flock_LOCK        /* use of those kernel-locking methods         */
  84. X
  85. X/*#define NO_NFS_ATIME_HACK    /* uncomment if you're definitely not using
  86. X                   NFS mounted filesystems and can't afford
  87. X    procmail to sleep for 1 sec. before writing a mailbox */
  88. X
  89. X/*#define SYSTEM_MBOX    "$HOME/.mail"    /* uncomment and/or change if the
  90. X                       preset default mailbox is *not*
  91. X    suitable or if you want standard mail delivery to take place in a
  92. X    different file from the normal mail-spool-file.
  93. X    (it will supersede the value of SYSTEM_MAILBOX in autoconf.h) */
  94. X
  95. X/*#define DEFsendmail    "/bin/mail"    /* uncomment and/or change if the
  96. X                       preset default SENDMAIL is not
  97. X    suitable */
  98. X
  99. X/*#define console    "/dev/console"    /* uncomment if you want procmail to
  100. X                       use the console (or any other
  101. X    terminal or file) to print any error messages that could not be dumped
  102. X    in the "logfile"; only recommended for debugging purposes, if you have
  103. X    trouble creating a "logfile" or suspect that the trouble starts before
  104. X    procmail can interpret any rcfile or arguments. */
  105. X
  106. X/************************************************************************
  107. X * Only edit below this line if you *think* you know what you are doing *
  108. X ************************************************************************/
  109. X
  110. X#define NOBODY_uid    0xfffe          /* default uid when no valid recipient */
  111. X#define NOBODY_gid    0xfffe          /* default gid when no valid recipient */
  112. X#define ROOT_uid    0
  113. X
  114. X#define UPDATE_MASK    S_IXOTH
  115. X#define INIT_UMASK    (S_IRWXG|S_IRWXO)               /* == 077 */
  116. X#define NORMperm    \
  117. X (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH|UPDATE_MASK)
  118. X         /* == 0667, normal mode bits used to create files, before umask */
  119. X#define NORMdirperm    (S_IRWXU|S_IRWXG|S_IRWXO)          /* == 0777 */
  120. X#define LOCKperm    0      /* mode bits used while creating lockfiles */
  121. X#define MAX_LOCK_SIZE    16      /* lockfiles are expected not to be longer */
  122. X#ifndef SMALLHEAP
  123. X#define DEFlinebuf    2048         /* default max expanded line length */
  124. X#define BLKSIZ        16384          /* blocksize while reading/writing */
  125. X#define STDBUF        1024             /* blocksize for emulated stdio */
  126. X#else           /* and some lower defaults for the unfortunate amongst us */
  127. X#define DEFlinebuf    512
  128. X#define BLKSIZ        1024
  129. X#define STDBUF        128
  130. X#endif /* SMALLHEAP */
  131. X#define HOSTNAMElen    9      /* nr of significant chararacters for HOST */
  132. X#define BOGUSprefix    "BOGUS."         /* prepended to bogus mailboxes */
  133. X#define PROCMAILRC    ".procmailrc"
  134. X#define DEFsuspend    16         /* multi-purpose 'idle loop' period */
  135. X#define DEFlocksleep    8
  136. X#define TOkey        "^TO"
  137. X#define TOsubstitute    \
  138. X "^((Resent-)?(To|Cc|Bcc)|(X-Envelope|Apparently)-To):(.*[^a-zA-Z])?"
  139. X#define FROMDkey    "^FROM_DAEMON"
  140. X#define FROMDsubstitute "^(Precedence:.*(junk|bulk|list)|\
  141. X(((Resent-)?(From|Sender)|X-Envelope-From):|From )(.*[^.%@a-z0-9])?(\
  142. XPost(ma?(st(e?r)?|n)|office)|Mailer|daemon|mmdf|root|uucp|LISTSERV|owner|\
  143. Xrequest|bounce|serv(ices?|er))([^.!:a-z0-9]|$))"     /* matches most daemons */
  144. X#define FROMMkey    "^FROM_MAILER"
  145. X#define FROMMsubstitute "^(((Resent-)?(From|Sender)|X-Envelope-From):|From )\
  146. X(.*[^.%@a-z0-9])?(\
  147. XPost(ma(st(er)?|n)|office)|Mailer|daemon|mmdf|root|uucp|serv(ices?|er))\
  148. X([^.!:a-z0-9]|$)"                  /* matches most mailer-daemons */
  149. X#define DEFshellmetas    "&|<>~;?*[]"            /* never put '$' in here */
  150. X#define DEFmaildir    "$HOME"
  151. X#define DEFdefault    "$ORGMAIL"
  152. X#define DEFdefaultlock    "LOCKFILE=$DEFAULT$LOCKEXT"
  153. X#define DEFmsgprefix    "msg."
  154. X#define DEFlockext    ".lock"
  155. X#define DEFshellflags    "-c"
  156. X#define DEFlocktimeout    1024             /* defaults to about 17 minutes */
  157. X#define DEFtimeout    (DEFlocktimeout-64)       /* 64 seconds to clean up */
  158. X#define DEFnoresretry    4      /* default nr of retries if no resources left */
  159. X#define nfsTRY        2     /* nr of times-1 to ignore spurious NFS errors */
  160. X#define DEFlogabstract    -1    /* abstract by default, but don't mail it back */
  161. X#define COMSAThost    "localhost"    /* where the biff/comsat daemon lives */
  162. X#define COMSATservice    "biff"        /* the service name of the comsat daemon */
  163. X#define COMSATprotocol    "udp" /* if you change this, comsat() needs patching */
  164. X#define COMSATxtrsep    ":"         /* mailbox-spec extension separator */
  165. X#define SERV_ADDRsep    '@'          /* when overriding in COMSAT=serv@addr */
  166. X#define DEFcomsat    "no"        /* when an rcfile has been specified */
  167. X
  168. X#define BinSh        "/bin/sh"
  169. X#define RootDir        "/"
  170. X#define DevNull        "/dev/null"
  171. X#define chCURDIR    '.'                /* the current directory */
  172. X#define chPARDIR    ".."                 /* the parent directory */
  173. X#define DIRSEP        "/"         /* directory separator symbols, the */
  174. X                   /* last one should be the most common one */
  175. X
  176. X#define EOFName        " \t\n#`'\");"
  177. X
  178. X#define HELPOPT1    'h'         /* options to get command line help */
  179. X#define HELPOPT2    '?'
  180. X
  181. X#define VERSIONOPT    'v'            /* option to display version */
  182. X#define PRESERVOPT    'p'                 /* preserve environment */
  183. X#define TEMPFAILOPT    't'              /* return EX_TEMPFAIL on error */
  184. X#define MAILFILTOPT    'm'         /* act as a general purpose mail filter */
  185. X#define FROMWHOPT    'f'               /* set name on From_ line */
  186. X#define ALTFROMWHOPT    'r'        /* alternate and obsolete form of -f */
  187. X#define ARGUMENTOPT    'a'                       /* set $1 */
  188. X#define DELIVEROPT    'd'          /* deliver mail to named recipient */
  189. X#define PM_USAGE    \
  190. X "Usage: procmail [-vpt] [-f fromwhom] [parameter=value | rcfile] ...\
  191. X\n   Or: procmail [-pt] [-f fromwhom] [-a argument] -d recipient ...\
  192. X\n   Or: procmail [-pt] -m [parameter=value] ... rcfile mail_from rcpt_to ...\
  193. X\n"
  194. X#define PM_HELP        \
  195. X "\t-v\t\tdisplay the version number and exit\
  196. X\n\t-p\t\tpreserve (most of) the environment upon startup\
  197. X\n\t-t\t\tfail softly if mail is undeliverable\
  198. X\n\t-f fromwhom\t(re)generate the leading 'From ' line\
  199. X\n\t-a argument\twill set $1\
  200. X\n\t-d recipient\texplicit delivery mode\
  201. X\n\t-m\t\tact as a general purpose mail filter\n"
  202. X#define PM_QREFERENCE    \
  203. X "Recipe flag quick reference:\
  204. X\n\tH\tegrep the header (default)\
  205. X\n\tB\tegrep the body\
  206. X\n\tD\tdistinguish case\
  207. X\n\tA\talso execute this recipe if the common condition matched\
  208. X\n\ta\tsame as 'A', but only if the previous recipe was successful\
  209. X\n\th\tfeed the header to the pipe (default)\
  210. X\n\tb\tfeed the body to the pipe (default)\
  211. X\n\tf\tfilter\
  212. X\n\tc\tcontinue with the next recipe in any case\
  213. X\n\tw\twait for a filter or program\
  214. X\n\tW\tsame as 'w', but suppress 'Program failure' messages\
  215. X\n\ti\tignore write errors\n"
  216. X
  217. X#define MINlinebuf    128    /* minimal LINEBUF length (don't change this) */
  218. X#define FROM_EXPR    "\nFrom "
  219. X#define FROM        "From "
  220. X#define SHFROM        "From"
  221. X#define NSUBJECT    "^Subject:.*$"
  222. X#define MAXSUBJECTSHOW    78
  223. X#define FOLDER        "  Folder: "
  224. X#define LENtSTOP    9 /* tab stop at which message length will be logged */
  225. X
  226. X#define TABCHAR        "\t"
  227. X#define TABWIDTH    8
  228. X
  229. X#define RECFLAGS    "HBDAahbfcwWi"
  230. X#define HEAD_GREP     0
  231. X#define BODY_GREP      1
  232. X#define DISTINGUISH_CASE   2
  233. X#define ALSO_NEXT_RECIPE    3
  234. X#define ALSO_N_IF_SUCC         4
  235. X#define PASS_HEAD          5
  236. X#define PASS_BODY           6
  237. X#define FILTER            7
  238. X#define CONTINUE         8
  239. X#define WAIT_EXIT          9
  240. X#define WAIT_EXIT_QUIET           10
  241. X#define IGNORE_WRITERR            11
  242. X
  243. X#define UNIQ_PREFIX    '_'      /* prepended to temporary unique filenames */
  244. X#define ESCAP        ">"
  245. X
  246. X        /* some formail-specific configuration options: */
  247. X
  248. X#define UNKNOWN        "foo@bar"      /* formail default originator name */
  249. X#define OLD_PREFIX    "Old-"             /* formail field-Old-prefix */
  250. X
  251. X#define FM_SKIP        '+'              /* skip the first nnn messages */
  252. X#define FM_TOTAL    '-'        /* only spit out a total of nnn messages */
  253. X#define FM_BOGUS    'b'             /* leave bogus Froms intact */
  254. X#define FM_QPREFIX    'p'              /* define quotation prefix */
  255. X#define FM_CONCATENATE    'c'          /* concatenate continued header-fields */
  256. X#define FM_FORCE    'f'   /* force formail to accept an arbitrary format */
  257. X#define FM_REPLY    'r'            /* generate an auto-reply header */
  258. X#define FM_KEEPB    'k'           /* keep the header, when replying */
  259. X#define FM_TRUST    't'    /* trust the sender to supply a valid header */
  260. X#define FM_LOGSUMMARY    'l'    /* generate a procmail-compatible log summary */
  261. X#define FM_SPLIT    's'                      /* split it up */
  262. X#define FM_NOWAIT    'n'              /* don't wait for the programs */
  263. X#define FM_EVERY    'e'    /* don't require empty lines leading headers */
  264. X#define FM_MINFIELDS    'm'    /* the number of fields that have to be found */
  265. X#define DEFminfields    2        /* before a header is recognised as such */
  266. X#define FM_DIGEST    'd'                 /* split up digests */
  267. X#define FM_QUIET    'q'            /* ignore write errors on stdout */
  268. X#define FM_EXTRACT    'x'               /* extract field contents */
  269. X#define FM_EXTRC_KEEP    'X'                    /* extract field */
  270. X#define FM_ADD_IFNOT    'a'         /* add a field if not already there */
  271. X#define FM_ADD_ALWAYS    'A'               /* add this field in any case */
  272. X#define FM_REN_INSERT    'i'            /* rename and insert a field */
  273. X#define FM_DEL_INSERT    'I'            /* delete and insert a field */
  274. X#define FM_ReNAME    'R'                   /* rename a field */
  275. X#define FM_USAGE    "\
  276. XUsage: formail [+nnn] [-nnn] [-bcfrktnedq] [-p prefix] [-m nnn] [-l folder]\n\
  277. X\t[-xXaAiI field] [-R ofield nfield] [-s prg arg ...]\n"
  278. X#define FM_HELP        \
  279. X "\t-b\tdon't escape bogus mailbox headers\
  280. X\n\t-p prefix\tdefine quotation prefix\
  281. X\n\t-c\tconcatenate continued header-fields\
  282. X\n\t-f\tforce formail to pass along any non-mailbox format\
  283. X\n\t-r\tgenerate an auto-reply header, preserve fields with -i\
  284. X\n\t-k\ton auto-reply keep the body, prevent escaping with -b\
  285. X\n\t-t\ttrust the sender for his return address\
  286. X\n\t-l folder\tgenerate a procmail-compatible log summary\
  287. X\n\t-q\tbe quiet about write errors on stdout\
  288. X\n\t-s prg arg\tsplit the mail, startup prg for every message\
  289. X\n\t-n\tdon't wait for every prg while splitting\
  290. X\n\t-e\tdon't require empty lines to precede a header\
  291. X\n\t-d\taccept digest format\
  292. X\n\t-m nnn\tmin fields threshold (default 2) for start of message\
  293. X\n\t+nnn\tskip the first nnn messages while splitting\
  294. X\n\t-nnn\toutput at most nnn messages while splitting\
  295. X\n\t-x field   extract contents\t-X field   extract fully\
  296. X\n\t-a field   add if not present\t-A field   add in any case\
  297. X\n\t-i field   rename and insert\t-I field   delete and insert\
  298. X\n\t-R oldfield newfield\trename\n"
  299. END_OF_FILE
  300. if test 12187 -ne `wc -c <'procmail/config.h'`; then
  301.     echo shar: \"'procmail/config.h'\" unpacked with wrong size!
  302. fi
  303. # end of 'procmail/config.h'
  304. fi
  305. if test -f 'procmail/examples/advanced' -a "${1}" != "-c" ; then 
  306.   echo shar: Will not clobber existing file \"'procmail/examples/advanced'\"
  307. else
  308. echo shar: Extracting \"'procmail/examples/advanced'\" \(10907 characters\)
  309. sed "s/^X//" >'procmail/examples/advanced' <<'END_OF_FILE'
  310. X
  311. XDiscusses:
  312. X        1. One home directory, several machine architectures
  313. X        2. Procmail as an integrated local mail delivery agent
  314. X        2a.Special directions for sites with sendmail
  315. X        2b.Special directions for sites with smail
  316. X        2c.Special directions for sites with SysV /etc/mail/mailsurr
  317. X        3. Changing the mail spool directory to $HOME for all users
  318. X        4. Security considerations (when installing procmail suid root)
  319. X        5. Some exorbitant examples of rcfile formats
  320. X        6. Some advanced examples of the use of the 'A' flag
  321. X
  322. X                ---
  323. X
  324. X1. One home directory, several machine architectures
  325. X   -------------------------------------------------
  326. X
  327. XFor users that have the very same home directory on machines with differing
  328. Xarchitectures (i.e. you need different executables), and they
  329. Xhave to explicitly use (i.e. the system administrator did not arrange,
  330. Xfor example, /usr/local/bin/procmail to have exactly the right contents
  331. Xdepending on from which machine it is called) two executables of procmail,
  332. XI have the following suggestion to use as a .forward file (examples are for
  333. Xsparc and sun3 architectures):
  334. X
  335. X"|IFS=' ';if /usr/bin/sparc;then exec /home/berg/bin.sun4/procmail;else exec /home/berg/bin.sun3/procmail;fi #YOUR_LOGIN_NAME"
  336. X
  337. Xor alternatively:
  338. X
  339. X"|IFS=' ';exec /home/berg/bin.`/usr/bin/arch`/procmail #YOUR_LOGIN_NAME"
  340. X
  341. XPlease note, in the .forward file there can NOT be any newlines between
  342. Xthe doublequotes, i.e. the former example *has* to be typed in as one long
  343. Xline.
  344. X
  345. XIf, on the other hand, you have to log in to every machine to read mail
  346. Xarrived for you on that machine, a different solution might be more
  347. Xappropriate; in that case put something like the following two lines in your
  348. X.forward file:
  349. X
  350. XYOUR_LOGIN_NAME@your.favourite.machine
  351. X"|IFS=' ';test .`/bin/uname -n` != .your.favourite.machine || exec /usr/local/bin/procmail #YOUR_LOGIN_NAME"
  352. X
  353. XThe leading dots are important.     Check what `/bin/uname -n` returns on
  354. Xyour.favourite.machine, and substitute that for your.favourite.machine in the
  355. Xsample .forward file.  If your system does not have /bin/uname, check if there
  356. Xis a /bin/hostname.
  357. X
  358. X                ---
  359. X
  360. X2. Procmail as an integrated local mail delivery agent
  361. X   ---------------------------------------------------
  362. X
  363. XCompletely integrating procmail in the mail delivery means that mail is
  364. Xdelivered as normal, unless a .procmailrc file is present in the home
  365. Xdirectory of the recipient.  This will be completely independent of the
  366. Xfact if a .forward file is present.  This will not break anything, it
  367. Xjust makes the use of procmail easier because people are not required to
  368. Xstart up procmail from within their .forward files.  Creation of a .procmailrc
  369. Xfile will suffice.
  370. X
  371. XThe generic way to accomplish this (works with sendmail, smail and any other
  372. Xmail system that uses a local mail delivery program that takes the mail-
  373. Xto-be-delivered on stdin and the recipient(s) on the command line, with or
  374. Xwithout the "-d" option) is this:
  375. X
  376. XMove your current local mail delivery agent (e.g. /bin/mail, /bin/lmail,
  377. X/usr/lib/mail/mail.local, etc.) out of the way, and create a (symbolic or hard)
  378. Xlink from there to procmail, as in "ln /usr/local/bin/procmail /bin/lmail".
  379. X
  380. XBeware, however, that if you are using this method, /bin/mail can *only* be
  381. Xused to deliver mail.  On many systems /bin/mail has several uses (also to
  382. Xread mail or check for mail).  So, it would definitely be preferred if you
  383. Xcould edit the invocation of /bin/mail from within your mail transport agent
  384. Xto invoke procmail instead (with appropriate flags, if needed).     Special
  385. Xdirections detailing this process for some of the more popular MTAs are
  386. Xincluded in sections (2a) and (2b) below.
  387. X
  388. XIn addition to needing root privileges upon startup, on some systems procmail
  389. Xneeds to be sgid to daemon or mail.  One way to check is by looking at the
  390. Xcurrent mail delivery agent (usually /bin/mail) and to mimic its permissions,
  391. Xowner and group.  If you're not quite sure, just type "make recommend" and some
  392. Xsuitable recommendations will be made for your particular environment.
  393. X
  394. XThe same might apply to the "lockfile" program, in order for it to be able to
  395. Xcreate and unlink lockfiles in the mail spool directory it might need to be
  396. Xsgid to daemon or mail, not to worry however, "lockfile" will not enable users
  397. Xto abuse the sgid/suid-ness.
  398. X
  399. X                ---
  400. X
  401. X2a.Special directions for sites with sendmail
  402. X   ------------------------------------------
  403. X
  404. XThe following lines should take the place of the standard Mlocal definition in
  405. Xyour sendmail.cf:
  406. X
  407. XMlocal, P=/usr/local/bin/procmail, F=lsSDFMhPfn, S=10, R=20,
  408. X    A=procmail -a $h -d $u
  409. X
  410. XThe `f' and the `n' flags can be omitted (if your sendmail generates correct
  411. XFrom_ lines).  As for the options "S=10, R=20": if your system uses others or
  412. Xnone on the current Mlocal definition, use those instead of "S=10, R=20".
  413. X
  414. XIn order to take advantage of the meta argument that can be passed to
  415. Xprocmail you'd have to change to $#local mailer rule to set the $@ host name
  416. X(which will be substituted for $h in the mailer definition).
  417. X
  418. XSince you are editing the sendmail.cf file now anyway, you might as well setup
  419. Xan extra `procmail' mailer.  This Mprocmail can then be used as a general mail
  420. Xfilter.     For more information, see EXAMPLES section the procmail(1) man page.
  421. X
  422. X                ---
  423. X
  424. X2b.Special directions for sites with smail
  425. X   ---------------------------------------
  426. X
  427. XFor smail 2.x users there are two options:
  428. X i. Move the current local-mail-delivery program (probably /bin/lmail) out of
  429. X    the way, make a symbolic or hard link from procmail to the name of that
  430. X    program (e.g. "ln /usr/local/bin/procmail /bin/lmail")
  431. X ii.Make sure the following macro is defined in src/defs.h:
  432. X    #define LMAIL(frm,sys) "/usr/local/bin/procmail -d"
  433. X
  434. XFor smail 3.x users there are also two options:
  435. X i. The same solution as for smail 2.x (however, method ii is preferred)
  436. X ii.Replace any existing "local"-entry in the /usr/lib/smail/transports file
  437. X    (create one, if need be) with the following two lines:
  438. X
  439. Xlocal: return_path, local, from, driver=pipe; user=root,
  440. X    cmd="/usr/local/bin/procmail -d $($user$)"
  441. X
  442. X                ---
  443. X
  444. X2c.Special directions for sites with SysV /etc/mail/mailsurr
  445. X   ---------------------------------------------------------
  446. X
  447. XSome systems use a SysV /bin/mail that supports mailsurr.  To interface
  448. Xprocmail with mailsurr the following two lines should be inserted in the
  449. X/etc/mail/mailsurr file (preferably at the bottom):
  450. X
  451. X'(.+)' '([^@!]+)' '<S=0;C=67,75;F=*;
  452. X    /usr/local/bin/procmail -f \\1 -d \\2'
  453. X
  454. X                ---
  455. X
  456. X3. Changing the mail spool directory to $HOME for all users
  457. X   --------------------------------------------------------
  458. X
  459. XThere are many different reasons why more and more sites decide not to
  460. Xstore mail in /usr/spool/mail or /usr/mail anymore.
  461. XSome of the obvious advantages when storing mail in the recipient's home
  462. Xdirectory are:
  463. X    - Mail is automatically subject to his quota limitations.
  464. X    - Often there is more room on the home partitions than on that
  465. X      one /usr/mail partition.
  466. X
  467. XThe quota limitations also apply to /usr/spool/mail or /usr/mail if procmail
  468. Xdoes the delivery.  This quota limitation often does not work with the
  469. Xregular /bin/mail since it often writes the mailbox with root permissions
  470. X(eluding the quota restrictions).
  471. X
  472. XHowever, if you are going to install procmail as the integrated local
  473. Xdelivery agent, and you want mail to be delivered to, say, $HOME/.mail
  474. Xby default, this is what you have to do:
  475. X
  476. X    Edit the procmail*/config.h file.   Uncomment and possibly change
  477. X    the SYSTEM_MBOX define.     Procmail now delivers there by default.
  478. X
  479. X    In order to make sure that normal mailtools can find the new
  480. X    system mailboxes, you should make sure that every user has the
  481. X    MAIL environment variable set to be equal to whatever you
  482. X    defined SYSTEM_MBOX to be.  Some braindamaged mail programs
  483. X    do not pick up the MAIL environment variable, these either
  484. X    have to be patched/recompiled or you have to create symbolic
  485. X    links in /usr/mail to every person's new mailbox.
  486. X
  487. X                ---
  488. X
  489. X4. Security considerations (when installing procmail suid root)
  490. X   -------------------------------------------------------------
  491. X
  492. XIf in EXPLICIT DELIVERY mode (typically when called from within sendmail)
  493. Xprocmail will ALWAYS change UID and gid to the RECIPIENT's defaults as soon as
  494. Xit starts reading the recipient's $HOME/.procmailrc file.
  495. X
  496. XIf NOT in explicit delivery mode (typically when called from within the
  497. Xrecipient's $HOME/.forward file) procmail will ALWAYS change UID and gid to
  498. Xthe real uid and gid of the INVOKER (effectively losing any suid or sgid
  499. Xprivileges).
  500. X
  501. XThese two precautions should effectively eliminate any security holes because
  502. Xprocmail will always have the uid of the person whose commands it is executing.
  503. X
  504. XTo summarise, procmail will only behave better if made suid/sgid something, in
  505. Xfact, making procmail suid/sgid something will *improve* security on systems
  506. Xwhich have dynamically linked libraries.
  507. X
  508. X                ---
  509. X
  510. X5. Some exorbitant examples of rcfile formats
  511. X   ------------------------------------------
  512. X
  513. X# Now follows an example of what you can do in a procmailrc file
  514. XHELLO=oneword
  515. XHELLO="two words"
  516. XHELLO='two words'    HELLO  =    one\
  517. Xword
  518. XHELLO=two\ words
  519. XHELLO=two\ `echo words`
  520. XHELLO=            # empty
  521. XHELLO            # This will wipe "HELLO" from the environment
  522. XHELLO     =    "three words"\ yes
  523. XHELLO    =    "$HELLO `cat somefile`    "    # Trailing blanks
  524. XHELLO = "wheeee`date`${HELLO} this works too"     HELLO = 'But so does this!'
  525. X
  526. X# As you can see, every trick in the book of /bin/sh programming can be used
  527. X# (and more).
  528. X
  529. XLOCALLOCKFILE = llf
  530. X
  531. X  :0:$LOCALLOCKFILE
  532. X  * grep for this
  533. X |$HELLO        # calls up a program named "But" with 3 arguments
  534. X
  535. X:0: "test ing"        # lockfilename with a space in it
  536. X  * grep for this
  537. X  |$HELLO
  538. X
  539. X:0
  540. X* or for this
  541. X|"$HELLO"        # tries to call up a program named "But so does this!"
  542. X
  543. X:0
  544. X* and this
  545. X|$HELLO \
  546. Xthere        # action lines can be continued
  547. X
  548. X                ---
  549. X
  550. X6. Some advanced examples of the use of the 'A' flag
  551. X   -------------------------------------------------
  552. X
  553. X:0c        # Specify the 'c' otherwise we never arrive at the next recipe
  554. X* ^From Myfriend
  555. Xevery_message_from_my_friend        # Mailbox for everything he/she writes
  556. X
  557. X:0 Ac            # Note the 'c' again
  558. X! my_other_friend      # Forward everything Myfriend writes to my_other_friend
  559. X
  560. X:0 Ac
  561. X* ^Subject:.*jokes
  562. X! my_third_friend    # Forward everything Myfriend writes about jokes
  563. X            # to my_third_friend
  564. X
  565. X:0 A
  566. X* ^Subject:.*parties
  567. X* !beach
  568. X! my_fourth_friend    # Forward everything Myfriend writes about parties,
  569. X            # except beach parties, to my_fourth_friend
  570. X
  571. X:0 A            # Provide a mail sink, in order to fake procmail into
  572. X/dev/null        # believing that the mail was absorbed/delivered,
  573. X            # even if the mail was about beach parties :-).
  574. X        # This is not the best solution though, better would be to
  575. X        # rearrange these last five recipes so that the current
  576. X        # number one or two is last, the current number five can be
  577. X        # omitted then.
  578. X
  579. X                ---
  580. END_OF_FILE
  581. if test 10907 -ne `wc -c <'procmail/examples/advanced'`; then
  582.     echo shar: \"'procmail/examples/advanced'\" unpacked with wrong size!
  583. fi
  584. # end of 'procmail/examples/advanced'
  585. fi
  586. if test -f 'procmail/man/procmailex.man' -a "${1}" != "-c" ; then 
  587.   echo shar: Will not clobber existing file \"'procmail/man/procmailex.man'\"
  588. else
  589. echo shar: Extracting \"'procmail/man/procmailex.man'\" \(9942 characters\)
  590. sed "s/^X//" >'procmail/man/procmailex.man' <<'END_OF_FILE'
  591. X.Id $Id: procmailex.man,v 1.16 1993/06/21 14:24:06 berg Exp $
  592. X.TH PROCMAILEX 5 \*(Dt BuGless
  593. X.na
  594. X.SH NAME
  595. Xprocmailex \- procmail rcfile examples
  596. X.SH SYNOPSIS
  597. X.B $HOME/@PROCMAILRC@ examples
  598. X.ad
  599. X.Sh DESCRIPTION
  600. XFor a description of the rcfile format see
  601. X.BR procmailrc (5).
  602. X.PP
  603. XThis man page shows several example recipes.  For examples of complete rcfiles
  604. Xyou can check the NOTES section in
  605. X.BR procmail (1),
  606. Xor look at the example rcfiles part of the procmail source distribution
  607. X(procmail*/examples/?procmailrc).
  608. X.Sh EXAMPLES
  609. XSort out all mail coming from the scuba-dive mailing list into the mailfolder
  610. Xscubafile (uses the locallockfile scubafile.lock).
  611. X.Sx 3
  612. X:0:
  613. X* ^TOscuba
  614. Xscubafile
  615. X.Ex
  616. XForward all mail from peter about compilers to william (and keep a copy
  617. Xof it here in petcompil).
  618. X.Sx 7
  619. X:0 @CONTINUE@
  620. X* ^From.*peter
  621. X* ^Subject:.*compilers
  622. X! william@somewhere.edu
  623. X
  624. X   :0 @ALSO_NEXT_RECIPE@
  625. X   petcompil
  626. X.Ex
  627. XAn equivalent, but slightly slower solution that accomplishes the same:
  628. X.Sx 9
  629. X:0 @CONTINUE@
  630. X* ^From.*peter
  631. X* ^Subject:.*compilers
  632. X! william@somewhere.edu
  633. X
  634. X   :0
  635. X   * ^From.*peter
  636. X   * ^Subject:.*compilers
  637. X   petcompil
  638. X.Ex
  639. XAdd the headers of all messages that didn't come from the postmaster
  640. Xto your private header collection (for
  641. Xstatistics or mail debugging); and use the lockfile `headc.lock'.  In order
  642. Xto make sure the lockfile is not removed until the pipe has finished,
  643. Xyou have to specify option `@WAIT_EXIT@'; otherwise the lockfile would be
  644. Xremoved as soon as the pipe has accepted the mail.
  645. X.Sx 3
  646. X:0 @PASS_HEAD@@WAIT_EXIT@@CONTINUE@:
  647. X* !@FROMMkey@
  648. X| uncompress headc.Z; cat >>headc; compress headc
  649. X.Ex
  650. XForward all mails shorter than 1000 bytes to my home address (no lockfile
  651. Xneeded on this recipe).
  652. X.Sx 3
  653. X:0
  654. X* < 1000
  655. X! myname@home
  656. X.Ex
  657. XSplit up incoming digests from the surfing mailing list into their individual
  658. Xmessages, and store them into surfing, using surfing.lock as the locallockfile.
  659. X.Sx 3
  660. X:0:
  661. X* ^Subject:.*surfing.*Digest
  662. X| formail @FM_SKIP@1 \-@FM_DIGEST@@FM_SPLIT@ cat >>surfing
  663. X.Ex
  664. XStore everything coming from the postmaster or mailer-daemon (like bounced
  665. Xmail) into the file postm, using postm.lock as the locallockfile.
  666. X.Sx 3
  667. X:0:
  668. X* @FROMMkey@
  669. Xpostm
  670. X.Ex
  671. XA simple autoreply recipe.  It makes sure that neither mail from any daemon
  672. X(like bouncing mail or mail from mailing-lists), nor mail coming from yourself
  673. Xwill be autoreplied.  If this precaution would not be taken, disaster could
  674. Xresult (`ringing' mail).  In order for this recipe to autoreply to all the
  675. Xincoming mail, you should of course insert it before all other recipes in your
  676. Xrcfile.  However, it is advisable to put it
  677. X.I after
  678. Xany recipes that process the mails from subscribed mailinglists; it generally
  679. Xis not a good idea to generate autoreplies to mailinglists (yes, the
  680. X!^FROM_DAEMON regexp should already catch those, but if the mailinglist
  681. Xdoesn't follow accepted conventions, this might not be enough).
  682. X.Sx 4
  683. X:0 @PASS_HEAD@ @CONTINUE@
  684. X* !^FROM_DAEMON
  685. X* !^From +YOUR_LOGIN_NAME
  686. X| (formail \-@FM_REPLY@ \-@FM_ADD_ALWAYS@"Precedence: junk";\e
  687. X   echo "Mail received.") | $SENDMAIL \-t
  688. X.Ex
  689. XA more complicated autoreply recipe that implements the functional equivalent
  690. Xof the well known
  691. X.BR vacation (1)
  692. Xprogram.  This recipe is based on the same principles as the last one (prevent
  693. X`ringing' mail).  In addition to that however, it maintains a vacation database
  694. Xby extracting the name of the sender and appending it to the file
  695. X$ALREADYSENT, if the name is
  696. X.B not
  697. Xalready in there.  If the name was new, an autoreply will be sent (using the
  698. X`@ALSO_N_IF_SUCC@' flag functionality).  To reliably extract the name of the
  699. Xsender, I let formail generate an autoreply header (thereby making it figure
  700. Xout the most appropriate sender address), and then telling it to extract the
  701. Xvalue of the `To:' field.
  702. X.Sx 14
  703. XSHELL=/bin/sh    # for other shells, this might need adjustment
  704. XALREADYSENT=$HOME/vacation     # the vacation database
  705. X
  706. X:0 @PASS_HEAD@@WAIT_EXIT_QUIET@@CONTINUE@:                       # the lockfile is important
  707. X* !^FROM_DAEMON
  708. X* !^From +YOUR_LOGIN_NAME
  709. X| FROM="`formail \-@FM_REPLY@@FM_EXTRACT@ To:`" ;\e
  710. X  if fgrep \-e "$FROM" <$ALREADYSENT ;\e
  711. X  then exit 1 ;\e
  712. X  else echo "$FROM" >>$ALREADYSENT ;\e
  713. X  fi
  714. X
  715. X   :0 @ALSO_N_IF_SUCC@@PASS_HEAD@@CONTINUE@
  716. X   | (formail \-@FM_REPLY@@FM_ADD_ALWAYS@"Precedence: junk";\e
  717. X      echo "Mail received.") | $SENDMAIL \-t
  718. X.Ex
  719. XStore all messages concerning TeX in separate, unique filenames, in a directory
  720. Xnamed texmail (this directory has to exist); there is no need to use lockfiles
  721. Xin this case, so we won't.
  722. X.Sx 3
  723. X:0
  724. X* (^TO|^Subject:.*)TeX[^t]
  725. Xtexmail
  726. X.Ex
  727. XThe same as above, except now we store the mails in numbered files (MH mail
  728. Xfolder), again the texmail directory should exist already.
  729. X.Sx 3
  730. X:0
  731. X* (^TO|^Subject:.*)TeX[^t]
  732. Xtexmail/.
  733. X.Ex
  734. XOr you could file the mail in several directory folders at the same time.
  735. XThe following recipe will deliver the mail to two MH-folders and one
  736. Xdirectory folder.  It is actually only one file with two extra hardlinks.
  737. X.Sx 3
  738. X:0
  739. X* (^TO|^Subject:.*)TeX[^t]
  740. Xtexmail/. wordprocessing dtp/.
  741. X.Ex
  742. XStore all the messages about meetings in a folder that is in a directory
  743. Xthat changes every month.  E.g. if it were January 1994, the folder
  744. Xwould have the name `94-01/meeting' and the locallockfile would be
  745. X`94-01/meeting.lock'.
  746. X.Sx 3
  747. X:0:
  748. X* meeting
  749. X`date +%y-%m`/meeting
  750. X.Ex
  751. XThe same as above, but, if the `94-01' directory wouldn't have existed, it
  752. Xis created automatically:
  753. X.Sx 9
  754. XMONTHFOLDER=`date +%y-%m`
  755. X
  756. X:0 @IGNORE_WRITERR@
  757. X* ? test ! \-d $MONTHFOLDER
  758. X| mkdir $MONTHFOLDER
  759. X
  760. X:0:
  761. X* meeting
  762. X${MONTHFOLDER}/meeting
  763. X.Ex
  764. XThe same as above, but now by slightly different means:
  765. X.Sx 6
  766. XMONTHFOLDER=`date +%y-%m`
  767. XDUMMY=`test \-d $MONTHFOLDER || mkdir $MONTHFOLDER`
  768. X
  769. X:0:
  770. X* meeting
  771. X${MONTHFOLDER}/meeting
  772. X.Ex
  773. XWhen delivering to emacs folders (i.e. mailfolders managed by any emacs
  774. Xmail package, e.g. RMAIL or VM) directly, you should use emacs-compatible
  775. Xlockfiles.  The emacs mailers are a bit braindamaged in that respect, they get
  776. Xvery upset if someone delivers to mailfolders which they already have in their
  777. Xinternal buffers.  The following recipe assumes that $HOME equals /home/john.
  778. X.Sx 5
  779. XMAILDIR=Mail
  780. X
  781. X:0:/usr/local/lib/emacs/lock/!home!john!Mail!mailbox
  782. X* ^Subject:.*whatever
  783. Xmailbox
  784. X.Ex
  785. XTo extract certain headers from a mail and put them into environment
  786. Xvariables you can use any of the following constructs:
  787. X.Sx 5
  788. XSUBJECT=`formail \-@FM_EXTRACT@Subject:`    # regular field
  789. XFROM=`formail \-@FM_REPLY@@FM_TRUST@ \-@FM_EXTRACT@To:`        # special case
  790. X
  791. X:0 @PASS_HEAD@                            # alternate method
  792. XKEYWORDS=| formail \-@FM_EXTRACT@Keywords:
  793. X.Ex
  794. XIf you are using temporary files in a procmailrc file, and want to make
  795. Xsure that they are removed just before procmail exits, you could use
  796. Xsomething along the lines of:
  797. X.Sx 2
  798. XTEMPORARY=/tmp/pmail.$$
  799. XTRAP="/bin/rm \-f $TEMPORARY"
  800. X.Ex
  801. XThe TRAP keyword can also be used to change the exitcode of procmail.
  802. XI.e. if you want procmail to return an exitcode of `1' instead of its
  803. Xregular exitcodes, you could simply use:
  804. X.Sx 2
  805. XTRAP="exit 1;"   # The trailing semi-colon is important
  806. X                 # since exit is not a standalone program
  807. X.Ex
  808. XThe following recipe prints every incoming mail that looks like a postscript
  809. Xfile.
  810. X.Sx 3
  811. X:0 @BODY_GREP@@PASS_BODY@
  812. X* ^^%!
  813. X| lpr
  814. X.Ex
  815. XThe following recipe does the same, but is a bit more selective.  It only
  816. Xprints the postscript file if it comes from the print-server.  The first
  817. Xcondition matches only if it is found in the header (i.e. no preceding empty
  818. Xline).  The second condition only matches at the start of the body (i.e.
  819. Xright after the
  820. X.B first
  821. Xempty line).
  822. X.Sx
  823. X:0 @HEAD_GREP@@BODY_GREP@ @PASS_BODY@
  824. X* ^^(.+$)*From[ :].*print-server
  825. X* ^^(.+$)*^%!
  826. X| lpr
  827. X.Ex
  828. XSuppose you have two accounts, you use both accounts regularly, but they are
  829. Xin very distinct places (i.e. you can only read mail that arrived at either one
  830. Xof the accounts).  You would like to forward mail arriving at account one to
  831. Xaccount two, and the other way around.  The first thing that comes to mind is
  832. Xusing .forward files at both sites; this won't work of course, since you will
  833. Xbe creating a mail loop.  This mail loop can be avoided by inserting the
  834. Xfollowing recipe in front of all other recipes in the @PROCMAILRC@ files on
  835. Xboth sites.  If you make sure that you add the same X-Loop: field at both
  836. Xsites, mail can now safely be forwarded to the other account from either of
  837. Xthem.
  838. X.Sx 4
  839. X:0 @CONTINUE@
  840. X* !^X-Loop: yourname@your.main.mail.address
  841. X| formail \-@FM_ADD_ALWAYS@ "X-Loop: yourname@your.main.mail.address" | \e
  842. X   $SENDMAIL \-oi yourname@the.other.account
  843. X.Ex
  844. XIf someone sends you a mail with the word `retrieve' in the subject, the
  845. Xfollowing will automatically send back the contents of info_file to the
  846. Xsender.  Like in all recipes where we send mail, we watch out for mail
  847. Xloops.
  848. X.Sx 7
  849. X:0 @CONTINUE@@FILTER@@PASS_HEAD@
  850. X* !^X-Loop: yourname@your.main.mail.address
  851. X* ^Subject:.*retrieve
  852. X| formail -r -A"X-Loop: yourname@your.main.mail.address"
  853. X
  854. X  :0 A
  855. X  | (cat ; cat info_file ) | $SENDMAIL -oi -t
  856. X.Ex
  857. XThe following one is rather exotic, but it only serves to demonstrate a
  858. Xfeature.  Suppose you have a file in your HOME directory called ".urgent",
  859. Xand the (one) person named in that file is the sender of an incoming mail,
  860. Xyou'd like that mail to be stored in $MAILDIR/urgent instead of in any of the
  861. Xnormal mailfolders it would have been sorted in.  Then this is what you could
  862. Xdo (beware, the filelength of $HOME/.urgent should be well below $LINEBUF,
  863. Xincrease LINEBUF if necessary):
  864. X.Sx 5
  865. XURGMATCH=`cat $HOME/.urgent`
  866. X
  867. X:0 @BODY_GREP@:
  868. X* $^From.*${URGMATCH}.*
  869. Xurgent
  870. X.Re
  871. X.Sh "SEE ALSO"
  872. X.na
  873. X.nh
  874. X.BR procmail (1),
  875. X.BR procmailrc (5),
  876. X.BR sh (1),
  877. X.BR csh (1),
  878. X.BR mail (1),
  879. X.BR mailx (1),
  880. X.BR binmail (1),
  881. X.BR uucp (1),
  882. X.BR aliases (5),
  883. X.BR sendmail (8),
  884. X.BR egrep (1),
  885. X.BR grep (1),
  886. X.BR biff (1),
  887. X.BR comsat (8),
  888. X.BR lockfile (1),
  889. X.BR formail (1)
  890. X.hy
  891. X.ad
  892. END_OF_FILE
  893. if test 9942 -ne `wc -c <'procmail/man/procmailex.man'`; then
  894.     echo shar: \"'procmail/man/procmailex.man'\" unpacked with wrong size!
  895. fi
  896. # end of 'procmail/man/procmailex.man'
  897. fi
  898. if test -f 'procmail/src/misc.c' -a "${1}" != "-c" ; then 
  899.   echo shar: Will not clobber existing file \"'procmail/src/misc.c'\"
  900. else
  901. echo shar: Extracting \"'procmail/src/misc.c'\" \(10665 characters\)
  902. sed "s/^X//" >'procmail/src/misc.c' <<'END_OF_FILE'
  903. X/************************************************************************
  904. X *    Miscellaneous routines used by procmail                *
  905. X *                                    *
  906. X *    Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands    *
  907. X *    #include "README"                        *
  908. X ************************************************************************/
  909. X#ifdef RCS
  910. Xstatic /*const*/char rcsid[]=
  911. X "$Id: misc.c,v 1.26 1993/06/21 14:24:41 berg Exp $";
  912. X#endif
  913. X#include "procmail.h"
  914. X#include "sublib.h"
  915. X#include "robust.h"
  916. X#include "misc.h"
  917. X#include "pipes.h"
  918. X#include "common.h"
  919. X#include "cstdio.h"
  920. X#include "exopen.h"
  921. X#include "regexp.h"
  922. X#include "goodies.h"
  923. X#include "locking.h"
  924. X#include "mailfold.h"
  925. X
  926. Xconst char lastfolder[]="LASTFOLDER";
  927. Xstruct varval strenvvar[]={{"LOCKSLEEP",DEFlocksleep},
  928. X {"LOCKTIMEOUT",DEFlocktimeout},{"SUSPEND",DEFsuspend},
  929. X {"NORESRETRY",DEFnoresretry},{"TIMEOUT",DEFtimeout},{"VERBOSE",DEFverbose},
  930. X {"LOGABSTRACT",DEFlogabstract}};
  931. Xint didchd;
  932. Xstatic fakedelivery;
  933. X               /* line buffered to keep concurrent entries untangled */
  934. Xvoid elog(newt)const char*const newt;
  935. X{ int lnew,i;static lold;static char*old;char*p;
  936. X#ifndef O_CREAT
  937. X  lseek(STDERR,(off_t)0,SEEK_END);      /* locking should be done actually */
  938. X#endif
  939. X  if(!(lnew=strlen(newt))||nextexit)                 /* force flush? */
  940. X     goto flush;
  941. X  i=lold+lnew;
  942. X  if(p=lold?realloc(old,i):malloc(i))             /* unshelled malloc */
  943. X   { memmove((old=p)+lold,newt,(size_t)lnew);               /* append */
  944. X     if(p[(lold=i)-1]=='\n')                         /* EOL? */
  945. X    rwrite(STDERR,p,i),lold=0,free(p);        /* flush the line(s) */
  946. X   }
  947. X  else                           /* no memory, force flush */
  948. Xflush:
  949. X   { if(lold)
  950. X      { rwrite(STDERR,old,lold);lold=0;
  951. X    if(!nextexit)
  952. X       free(old);            /* don't use free in signal handlers */
  953. X      }
  954. X     if(lnew)
  955. X    rwrite(STDERR,newt,lnew);
  956. X   }
  957. X}
  958. X
  959. X#include "shell.h"
  960. X
  961. Xvoid ignoreterm P((void))
  962. X{ signal(SIGTERM,SIG_IGN);signal(SIGHUP,SIG_IGN);signal(SIGINT,SIG_IGN);
  963. X  signal(SIGQUIT,SIG_IGN);
  964. X}
  965. X
  966. Xvoid setids(uid,gid)const uid_t uid;const gid_t gid;
  967. X{ if(setrgid(gid))    /* due to these !@#$%^&*() POSIX semantics, setgid() */
  968. X     setgid(gid);       /* sets the saved gid as well; we can't use that! */
  969. X  setuid(uid);setgid(gid);
  970. X}
  971. X
  972. Xvoid writeerr(line)const char*const line;
  973. X{ nlog("Error while writing to");logqnl(line);
  974. X}
  975. X
  976. Xforkerr(pid,a)const pid_t pid;const char*const a;
  977. X{ if(pid==-1)
  978. X   { nlog("Failed forking");logqnl(a);return 1;
  979. X   }
  980. X  return 0;
  981. X}
  982. X
  983. Xvoid progerr(line)const char*const line;
  984. X{ nlog("Program failure of");logqnl(line);
  985. X}
  986. X
  987. Xvoid chderr(dir)const char*const dir;
  988. X{ nlog("Couldn't chdir to");logqnl(dir);
  989. X}
  990. X
  991. Xvoid readerr(file)const char*const file;
  992. X{ nlog("Couldn't read");logqnl(file);
  993. X}
  994. X
  995. Xvoid yell(a,b)const char*const a,*const b;        /* log if VERBOSE=on */
  996. X{ if(verbose)
  997. X     nlog(a),logqnl(b);
  998. X}
  999. X
  1000. Xvoid nlog(a)const char*const a;
  1001. X{ elog(procmailn);elog(": ");elog(a);
  1002. X}
  1003. X
  1004. Xvoid logqnl(a)const char*const a;
  1005. X{ elog(oquote);elog(a);elog(cquote);
  1006. X}
  1007. X
  1008. Xvoid skipped(x)const char*const x;
  1009. X{ if(*x)
  1010. X     nlog("Skipped"),logqnl(x);
  1011. X}
  1012. X
  1013. Xnextrcfile P((void))        /* next rcfile specified on the command line */
  1014. X{ const char*p;
  1015. X  while(p= *gargv)
  1016. X   { gargv++;
  1017. X     if(!strchr(p,'='))
  1018. X      { rcfile=p;return 1;
  1019. X      }
  1020. X   }
  1021. X  return 0;
  1022. X}
  1023. X
  1024. Xvoid sterminate P((void))
  1025. X{ static const char*const msg[]={"memory","fork",      /* crosscheck with */
  1026. X   "a file descriptor","a kernel-lock"};      /* lck_ defs in procmail.h */
  1027. X  ignoreterm();
  1028. X  if(pidchild>0)        /* don't kill what is not ours, we might be root */
  1029. X     kill(pidchild,SIGTERM);
  1030. X  if(!nextexit)
  1031. X   { nextexit=1;nlog("Terminating prematurely");
  1032. X     if(!(lcking&lck_LOCKFILE))
  1033. X      { register unsigned i,j;
  1034. X    if(i=(lcking&~(lck_ALLOCLIB|lck_LOCKFILE))>>1)
  1035. X     { elog(whilstwfor);
  1036. X       for(j=0;!((i>>=1)&1);j++);
  1037. X       elog(msg[j]);
  1038. X     }
  1039. X    elog(newline);terminate();
  1040. X      }
  1041. X   }
  1042. X}
  1043. X
  1044. Xvoid terminate P((void))
  1045. X{ ignoreterm();
  1046. X  if(retvl2!=EX_OK)
  1047. X     fakedelivery=0,retval=retvl2;
  1048. X  if(getpid()==thepid)
  1049. X   { if(retval!=EX_OK)
  1050. X      { tofile=0;lasttell= -1;              /* mark it for logabstract */
  1051. X    logabstract(fakedelivery?"**Lost**":
  1052. X     retval==EX_TEMPFAIL?"**Requeued**":"**Bounced**");
  1053. X      }
  1054. X     else
  1055. X    logabstract(tgetenv(lastfolder));
  1056. X     closerc();
  1057. X     if(!(lcking&lck_ALLOCLIB))            /* don't reenter malloc/free */
  1058. X    exectrap(tgetenv("TRAP"));
  1059. X     nextexit=2;unlock(&loclock);unlock(&globlock);fdunlock();
  1060. X   }
  1061. X  exit(fakedelivery==2?EX_OK:retval);
  1062. X}
  1063. X
  1064. Xvoid suspend P((void))
  1065. X{ long t;
  1066. X  sleep((unsigned)suspendv);
  1067. X  if(alrmtime)
  1068. X     if((t=alrmtime-time((time_t*)0))<=1)      /* if less than 1s timeout */
  1069. X    ftimeout();                  /* activate it by hand now */
  1070. X     else            /* set it manually again, to avoid problems with */
  1071. X    alarm((unsigned)t);    /* badly implemented sleep library functions */
  1072. X}
  1073. X
  1074. Xvoid app_val(sp,val)struct dyna_long*const sp;const off_t val;
  1075. X{ if(sp->filled==sp->tspace)                /* growth limit reached? */
  1076. X   { if(!sp->offs)
  1077. X    sp->offs=malloc(1);
  1078. X     sp->offs=realloc(sp->offs,(sp->tspace+=4)*sizeof sp->offs);   /* expand */
  1079. X   }
  1080. X  sp->offs[sp->filled++]=val;                     /* append to it */
  1081. X}
  1082. X
  1083. Xalphanum(c)const unsigned c;
  1084. X{ return numeric(c)||c-'a'<='z'-'a'||c-'A'<='Z'-'A'||c=='_';
  1085. X}
  1086. X
  1087. Xvoid firstchd P((void))
  1088. X{ if(!didchd)                       /* have we been here already? */
  1089. X   { const char*p;
  1090. X     didchd=1;                  /* no, well, then try an initial chdir */
  1091. X     if(chdir(p=tgetenv(maildir)))
  1092. X      { chderr(p);
  1093. X    if(chdir(p=tgetenv(home)))
  1094. X       chderr(p);
  1095. X      }
  1096. X   }
  1097. X}
  1098. X
  1099. Xvoid srequeue P((void))
  1100. X{ retval=EX_TEMPFAIL;sterminate();
  1101. X}
  1102. X
  1103. Xvoid slose P((void))
  1104. X{ fakedelivery=2;sterminate();
  1105. X}
  1106. X
  1107. Xvoid sbounce P((void))
  1108. X{ retval=EX_CANTCREAT;sterminate();
  1109. X}
  1110. X
  1111. Xvoid catlim(src)register const char*src;
  1112. X{ register char*dest=buf;register size_t lim=linebuf;
  1113. X  while(lim&&*dest)
  1114. X     dest++,lim--;
  1115. X  if(lim)
  1116. X   { while(--lim&&(*dest++= *src++));
  1117. X     *dest='\0';
  1118. X   }
  1119. X}
  1120. X
  1121. Xvoid setdef(name,contents)const char*const name,*const contents;
  1122. X{ strcat(strcat(strcpy((char*)(sgetcp=buf2),name),"="),contents);
  1123. X  readparse(buf,sgetc,2);sputenv(buf);
  1124. X}
  1125. X
  1126. Xvoid metaparse(p)const char*p;                    /* result in buf */
  1127. X{ if(sh=!!strpbrk(p,tgetenv(shellmetas)))
  1128. X     strcpy(buf,p);             /* copy literally, shell will parse */
  1129. X  else
  1130. X#ifndef GOT_bin_test
  1131. X   { sgetcp=p=tstrdup(p);
  1132. X     readparse(buf,sgetc,0);                /* parse it yourself */
  1133. X     if(!strcmp(test,buf))
  1134. X    strcpy(buf,p),sh=1;                   /* oops, `test' found */
  1135. X     free((char*)p);
  1136. X   }
  1137. X#else
  1138. X     sgetcp=p,readparse(buf,sgetc,0);
  1139. X#endif
  1140. X}
  1141. X
  1142. Xvoid concatenate(p)register char*p;
  1143. X{ while(p!=Tmnate)              /* concatenate all other arguments */
  1144. X   { while(*p++);
  1145. X     p[-1]=' ';
  1146. X   }
  1147. X  *p=p[-1]='\0';
  1148. X}
  1149. X
  1150. Xchar*lastdirsep(filename)const char*filename;     /* finds the next character */
  1151. X{ const char*p;                    /* following the last DIRSEP */
  1152. X  while(p=strpbrk(filename,dirsep))
  1153. X     filename=p+1;
  1154. X  return(char*)filename;
  1155. X}
  1156. X
  1157. Xchar*cat(a,b)const char*const a,*const b;
  1158. X{ return strcat(strcpy(buf,a),b);
  1159. X}
  1160. X
  1161. Xchar*tstrdup(a)const char*const a;
  1162. X{ int i;
  1163. X  i=strlen(a)+1;return tmemmove(malloc(i),a,i);
  1164. X}
  1165. X
  1166. Xconst char*tgetenv(a)const char*const a;
  1167. X{ const char*b;
  1168. X  return(b=getenv(a))?b:"";
  1169. X}
  1170. X
  1171. Xchar*cstr(a,b)char*const a;const char*const b;    /* dynamic buffer management */
  1172. X{ if(a)
  1173. X     free(a);
  1174. X  return tstrdup(b);
  1175. X}
  1176. X
  1177. Xvoid setlastfolder(folder)const char*const folder;
  1178. X{ if(asgnlastf)
  1179. X   { char*chp;
  1180. X     asgnlastf=0;
  1181. X     strcpy(chp=malloc(STRLEN(lastfolder)+1+strlen(folder)+1),lastfolder);
  1182. X     chp[STRLEN(lastfolder)]='=';strcpy(chp+STRLEN(lastfolder)+1,folder);
  1183. X     sputenv(chp);free(chp);
  1184. X   }
  1185. X}
  1186. X
  1187. Xchar*skpspace(chp)const char*chp;
  1188. X{ for(;;chp++)
  1189. X     switch(*chp)
  1190. X      { case ' ':case '\t':continue;
  1191. X    default:return(char*)chp;
  1192. X      }
  1193. X}
  1194. X
  1195. Xchar*gobenv(chp)char*chp;
  1196. X{ int found,i;
  1197. X  found=0;
  1198. X  if(alphanum(i=getb())&&!numeric(i))
  1199. X     for(found=1;*chp++=i,alphanum(i=getb()););
  1200. X  *chp='\0';ungetb(i);
  1201. X  switch(i)
  1202. X   { case ' ':case '\t':case '\n':case '=':
  1203. X    if(found)
  1204. X       return chp;
  1205. X   }
  1206. X  return 0;
  1207. X}
  1208. X
  1209. Xasenvcpy(src)char*src;
  1210. X{ strcpy(buf,src);
  1211. X  if(src=strchr(buf,'='))                 /* is it an assignment? */
  1212. X   { strcpy((char*)(sgetcp=buf2),++src);readparse(src,sgetc,2);sputenv(buf);
  1213. X     src[-1]='\0';asenv(src);return 1;
  1214. X   }
  1215. X  return 0;
  1216. X}
  1217. X
  1218. Xvoid asenv(chp)const char*const chp;
  1219. X{ static const char slinebuf[]="LINEBUF",logfile[]="LOGFILE",Log[]="LOG",
  1220. X   sdelivered[]="DELIVERED",includerc[]="INCLUDERC",eumask[]="UMASK",
  1221. X   host[]="HOST";
  1222. X  if(!strcmp(buf,slinebuf))
  1223. X   { if((linebuf=renvint(0L,chp)+XTRAlinebuf)<MINlinebuf+XTRAlinebuf)
  1224. X    linebuf=MINlinebuf+XTRAlinebuf;               /* check minimum size */
  1225. X     free(buf);free(buf2);buf=malloc(linebuf);buf2=malloc(linebuf);
  1226. X   }
  1227. X  else if(!strcmp(buf,maildir))
  1228. X     if(chdir(chp))
  1229. X    chderr(chp);
  1230. X     else
  1231. X    didchd=1;
  1232. X  else if(!strcmp(buf,logfile))
  1233. X     opnlog(chp);
  1234. X  else if(!strcmp(buf,Log))
  1235. X     elog(chp);
  1236. X  else if(!strcmp(buf,sdelivered))                /* fake delivery */
  1237. X   { if(renvint(0L,chp))                    /* is it really? */
  1238. X      { lcking|=lck_LOCKFILE;            /* just to prevent interruptions */
  1239. X    if((thepid=sfork())>0)
  1240. X     { nextexit=2;lcking&=~lck_LOCKFILE;exit(retvl2);
  1241. X     }                    /* signals may cause trouble */
  1242. X    if(!forkerr(thepid,procmailn))
  1243. X       fakedelivery=1;
  1244. X    thepid=getpid();lcking&=~lck_LOCKFILE;
  1245. X    if(nextexit)                 /* signals occurred so far? */
  1246. X       elog(newline),terminate();
  1247. X      }
  1248. X   }
  1249. X  else if(!strcmp(buf,lockfile))
  1250. X     lockit((char*)chp,&globlock);
  1251. X  else if(!strcmp(buf,eumask))
  1252. X     umask((mode_t)strtol(chp,(char**)0,8));
  1253. X  else if(!strcmp(buf,includerc))
  1254. X     pushrc(chp);
  1255. X  else if(!strcmp(buf,host))
  1256. X   { const char*name;
  1257. X     if(strncmp(chp,name=hostname(),HOSTNAMElen))
  1258. X      { yell("HOST mismatched",name);
  1259. X    if(rc<0||!nextrcfile())              /* if no rcfile opened yet */
  1260. X       retval=EX_OK,terminate();          /* exit gracefully as well */
  1261. X    closerc();rc=rc_NOFILE;
  1262. X      }
  1263. X   }
  1264. X  else
  1265. X   { int i=MAXvarvals;
  1266. X     do                          /* several numeric assignments */
  1267. X    if(!strcmp(buf,strenvvar[i].name))
  1268. X     { strenvvar[i].val=renvint(strenvvar[i].val,chp);break;
  1269. X     }
  1270. X     while(i--);
  1271. X   }
  1272. X}
  1273. X
  1274. Xlong renvint(i,env)const long i;const char*const env;
  1275. X{ const char*p;long t;
  1276. X  t=strtol(env,(char**)&p,10);              /* parse like a decimal nr */
  1277. X  if(p==env)
  1278. X   { for(;;p++)                      /* skip leading whitespace */
  1279. X      { switch(*p)
  1280. X     { case '\t':case ' ':continue;
  1281. X     }
  1282. X    break;
  1283. X      }
  1284. X     t=i;
  1285. X     if(!strnIcmp(p,"on",(size_t)2)||!strnIcmp(p,"y",(size_t)1)||
  1286. X      !strnIcmp(p,"t",(size_t)1)||!strnIcmp(p,"e",(size_t)1))
  1287. X    t=1;
  1288. X     else if(!strnIcmp(p,"off",(size_t)3)||!strnIcmp(p,"n",(size_t)1)||
  1289. X      !strnIcmp(p,"f",(size_t)1)||!strnIcmp(p,"d",(size_t)1))
  1290. X    t=0;
  1291. X   }
  1292. X  return t;
  1293. X}
  1294. X
  1295. Xchar*egrepin(expr,source,len,casesens)char*expr;const char*source;
  1296. X const long len;
  1297. X{ source=(const char*)bregexec((struct eps*)(expr=(char*)
  1298. X   bregcomp(expr,!casesens)),(const uchar*)source,len>0?
  1299. X   (size_t)len:(size_t)0,!casesens);
  1300. X  free(expr);return(char*)source;
  1301. X}
  1302. END_OF_FILE
  1303. if test 10665 -ne `wc -c <'procmail/src/misc.c'`; then
  1304.     echo shar: \"'procmail/src/misc.c'\" unpacked with wrong size!
  1305. fi
  1306. # end of 'procmail/src/misc.c'
  1307. fi
  1308. if test -f 'procmail/src/regexp.h' -a "${1}" != "-c" ; then 
  1309.   echo shar: Will not clobber existing file \"'procmail/src/regexp.h'\"
  1310. else
  1311. echo shar: Extracting \"'procmail/src/regexp.h'\" \(270 characters\)
  1312. sed "s/^X//" >'procmail/src/regexp.h' <<'END_OF_FILE'
  1313. X/*$Id: regexp.h,v 1.7 1993/05/28 14:40:16 berg Exp $*/
  1314. X
  1315. Xstruct eps{unsigned opc;struct eps*next;
  1316. X union {struct eps*awn;int sopc;} sp;}*
  1317. X bregcomp P((const char*const a,int ign_case));
  1318. Xchar*
  1319. X bregexec Q((struct eps*code,const uchar*const text,size_t len,int ign_case));
  1320. END_OF_FILE
  1321. if test 270 -ne `wc -c <'procmail/src/regexp.h'`; then
  1322.     echo shar: \"'procmail/src/regexp.h'\" unpacked with wrong size!
  1323. fi
  1324. # end of 'procmail/src/regexp.h'
  1325. fi
  1326. echo shar: End of archive 7 \(of 11\).
  1327. cp /dev/null ark7isdone
  1328. MISSING=""
  1329. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1330.     if test ! -f ark${I}isdone ; then
  1331.     MISSING="${MISSING} ${I}"
  1332.     fi
  1333. done
  1334. if test "${MISSING}" = "" ; then
  1335.     echo You have unpacked all 11 archives.
  1336.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1337. else
  1338.     echo You still need to unpack the following archives:
  1339.     echo "        " ${MISSING}
  1340. fi
  1341. ##  End of shell archive.
  1342. exit 0
  1343. -- 
  1344. Sincerely,                                  berg@pool.informatik.rwth-aachen.de
  1345.            Stephen R. van den Berg (AKA BuGless).    berg@physik.tu-muenchen.de
  1346.  
  1347. "Always look on the bright side of life!"
  1348.  
  1349. exit 0 # Just in case...
  1350.