home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume35 / procmail / part08 < prev    next >
Text File  |  1993-02-05  |  42KB  |  1,162 lines

  1. Newsgroups: comp.sources.misc
  2. From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
  3. Subject: v35i029:  procmail - mail processing package v2.80, Part08/11
  4. Message-ID: <1993Feb5.020605.16770@sparky.imd.sterling.com>
  5. X-Md4-Signature: baac7b9d80b9b8c0157faca798219198
  6. Date: Fri, 5 Feb 1993 02:06:05 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 29
  11. Archive-name: procmail/part08
  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 8 (of 11)."
  22. # Contents:  procmail280/config.h procmail280/man/procmail.man
  23. #   procmail280/src/regexp.c
  24. # Wrapped by berg@hathi on Thu Feb  4 15:28:00 1993
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'procmail280/config.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'procmail280/config.h'\"
  28. else
  29. echo shar: Extracting \"'procmail280/config.h'\" \(11315 characters\)
  30. sed "s/^X//" >'procmail280/config.h' <<'END_OF_FILE'
  31. X/*$Id: config.h,v 1.17 1993/02/02 15:26:42 berg Exp $*/
  32. X
  33. X/*#define sMAILBOX_SEPARATOR    "\1\1\1\1\n"    /* sTART- and eNDing separ.  */
  34. X/*#define eMAILBOX_SEPARATOR    "\1\1\1\1\n"    /* uncomment (one or both)
  35. X                           if your mail system uses
  36. X    nonstandard mail separators (non sendmail or smail compatible mailers
  37. X    like MMDF), if yours is even different, uncomment and change the
  38. X    value of course */
  39. X
  40. X/* KEEPENV and PRESTENV should be defined as a comma-separated null-terminated
  41. X   list of strings */
  42. X
  43. X/* every environment variable appearing in KEEPENV will not be thrown away
  44. X * upon startup of procmail, e.g. you could define KEEPENV as follows:
  45. X * #define KEEPENV    {"TZ","LANG",0}
  46. X * environment variables ending in an _ will designate the whole group starting
  47. X * with this prefix (e.g. "LC_").
  48. X */
  49. X#define KEEPENV        {"TZ",0}
  50. X
  51. X/* every environment variable appearing in PRESTENV will be set or wiped
  52. X * out of the environment (variables without an '=' sign will be thrown
  53. X * out), e.g. you could define PRESTENV as follows:
  54. X * #define PRESTENV    {"IFS","PATH=$HOME/bin:/bin:/usr/bin",0}
  55. X * any side effects (like setting the umask after an assignment to UMASK) will
  56. X * *not* take place
  57. X */
  58. X#define PRESTENV    {"IFS","PATH=$HOME/bin:/bin:/usr/bin", \
  59. X             "USER=$LOGNAME",0}
  60. X
  61. X/************************************************************************
  62. X * Only edit below this line if you have viewed/edited this file before *
  63. X ************************************************************************/
  64. X
  65. X/* every user & group appearing in TRUSTED_IDS is allowed to use the -f option
  66. X   if the list is empty (just a terminating 0), everyone can use it
  67. X   TRUSTED_IDS should be defined as a comma-separated null-terminated
  68. X   list of strings */
  69. X
  70. X#define TRUSTED_IDS    {"root","daemon","uucp","mail","x400",0}
  71. X
  72. X/*#define NO_USER_TO_LOWERCASE_HACK    /* uncomment if your getpwnam() is
  73. X                       case insensitive or if procmail
  74. X    will always be supplied with the correct case in the explicit
  75. X    delivery mode argument(s) */
  76. X
  77. X/*#define NO_fcntl_LOCK        /* uncomment any of these three if you         */
  78. X/*#define NO_lockf_LOCK        /* definitely do not want procmail to make   */
  79. X/*#define NO_flock_LOCK        /* use of those kernel-locking methods         */
  80. X
  81. X/*#define NO_NFS_ATIME_HACK    /* uncomment if you're definitely not using
  82. X                   NFS mounted filesystems and can't afford
  83. X    procmail to sleep for 1 sec. before writing a mailbox */
  84. X
  85. X/*#define SYSTEM_MBOX    "$HOME/.mail"    /* uncomment and/or change if the
  86. X                       preset default mailbox is *not*
  87. X    suitable or if you want standard mail delivery to take place in a
  88. X    different file from the normal mail-spool-file.
  89. X    (it will supersede the value of SYSTEM_MAILBOX in autoconf.h) */
  90. X
  91. X/*#define DEFsendmail    "/bin/mail"    /* uncomment and/or change if the
  92. X                       preset default SENDMAIL is not
  93. X    suitable */
  94. X
  95. X/*#define console    "/dev/console"    /* uncomment if you want procmail to
  96. X                       use the console (or any other
  97. X    terminal or file) to print any error messages that could not be dumped
  98. X    in the "logfile"; only recommended for debugging purposes, if you have
  99. X    trouble creating a "logfile" or suspect that the trouble starts before
  100. X    procmail can interpret any rcfile or arguments. */
  101. X
  102. X/************************************************************************
  103. X * Only edit below this line if you *think* you know what you are doing *
  104. X ************************************************************************/
  105. X
  106. X#define NOBODY_uid    0xfffe          /* default uid when no valid recipient */
  107. X#define NOBODY_gid    0xfffe          /* default gid when no valid recipient */
  108. X#define ROOT_uid    0
  109. X
  110. X#define INIT_UMASK    (S_IRWXG|S_IRWXO)               /* == 077 */
  111. X#define NORMperm    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
  112. X         /* == 0666, normal mode bits used to create files, before umask */
  113. X#define LOCKperm    0      /* mode bits used while creating lockfiles */
  114. X#define MAX_LOCK_SIZE    0      /* lockfiles are expected not to be longer */
  115. X#ifndef SMALLHEAP
  116. X#define DEFlinebuf    2048         /* default max expanded line length */
  117. X#define BLKSIZ        16384          /* blocksize while reading/writing */
  118. X#define STDBUF        1024             /* blocksize for emulated stdio */
  119. X#else           /* and some lower defaults for the unfortunate amongst us */
  120. X#define DEFlinebuf    512
  121. X#define BLKSIZ        1024
  122. X#define STDBUF        128
  123. X#endif /* SMALLHEAP */
  124. X#define HOSTNAMElen    9      /* nr of significant chararacters for HOST */
  125. X#define BOGUSprefix    "BOGUS."         /* prepended to bogus mailboxes */
  126. X#define PROCMAILRC    ".procmailrc"
  127. X#define DEFsuspend    16         /* multi-purpose 'idle loop' period */
  128. X#define DEFlocksleep    8
  129. X#define TOkey        "^TO"
  130. X#define TOsubstitute    \
  131. X "^((Resent-)?(To|Cc|Bcc)|(X-Envelope|Apparently)-To):(.*[^a-zA-Z])?"
  132. X#define FROMDkey    "^FROM_DAEMON"
  133. X#define FROMDsubstitute "^(Precedence:.*(junk|bulk|list)|\
  134. X(((Resent-)?(From|Sender)|X-Envelope-From):|From )(.*[^.a-z])?(\
  135. XPost(ma(st(er)?|n)|office)|Mailer|daemon|mmdf|root|uucp|LISTSERV|owner|\
  136. Xrequest|bounce|serv(ices?|er))([^.a-z]|$))" /* matches most kinds of daemons */
  137. X#define DEFshellmetas    "&|<>~;?*[]"            /* never put '$' in here */
  138. X#define DEFmaildir    "$HOME"
  139. X#define DEFdefault    "$ORGMAIL"
  140. X#define DEFdefaultlock    "LOCKFILE=$DEFAULT$LOCKEXT"
  141. X#define DEFmsgprefix    "msg."
  142. X#define DEFlockext    ".lock"
  143. X#define DEFshellflags    "-c"
  144. X#define DEFlocktimeout    1024             /* defaults to about 17 minutes */
  145. X#define DEFtimeout    (DEFlocktimeout-64)       /* 64 seconds to clean up */
  146. X#define DEFnoresretry    4      /* default nr of retries if no resources left */
  147. X#define nfsTRY        2     /* nr of times-1 to ignore spurious NFS errors */
  148. X#define COMSAThost    "localhost"    /* where the biff/comsat daemon lives */
  149. X#define COMSATservice    "biff"        /* the service name of the comsat daemon */
  150. X#define COMSATprotocol    "udp" /* if you change this, comsat() needs patching */
  151. X#define COMSATxtrsep    ":"         /* mailbox-spec extension separator */
  152. X#define SERV_ADDRsep    '@'          /* when overriding in COMSAT=serv@addr */
  153. X#define DEFcomsat    "no"              /* when an rcfile is specified */
  154. X
  155. X#define BinSh        "/bin/sh"
  156. X#define RootDir        "/"
  157. X#define DevNull        "/dev/null"
  158. X#define chCURDIR    '.'                /* the current directory */
  159. X#define chPARDIR    ".."                 /* the parent directory */
  160. X#define DIRSEP        "/"         /* directory separator symbols, the */
  161. X                   /* last one should be the most common one */
  162. X
  163. X#define EOFName        " \t\n#`'\");"
  164. X
  165. X#define HELPOPT1    'h'         /* options to get command line help */
  166. X#define HELPOPT2    '?'
  167. X
  168. X#define VERSIONOPT    'v'            /* option to display version */
  169. X#define PRESERVOPT    'p'                 /* preserve environment */
  170. X#define TEMPFAILOPT    't'              /* return EX_TEMPFAIL on error */
  171. X#define FROMWHOPT    'f'               /* set name on From_ line */
  172. X#define ALTFROMWHOPT    'r'        /* alternate and obsolete form of -f */
  173. X#define DELIVEROPT    'd'          /* deliver mail to named recipient */
  174. X#define PM_USAGE    \
  175. X "Usage: procmail [-vpt] [-f fromwhom] [parameter=value | rcfile] ...\
  176. X\n   Or: procmail [-vpt] [-f fromwhom] -d recipient ...\n"
  177. X#define PM_HELP        \
  178. X "\t-v\t\tdisplay the version number and exit\
  179. X\n\t-p\t\tpreserve (most of) the environment upon startup\
  180. X\n\t-t\t\tfail softly if mail is undeliverable\
  181. X\n\t-f fromwhom\t(re)generate the leading 'From ' line\
  182. X\n\t-d recipient\texplicit delivery mode\n"
  183. X#define PM_QREFERENCE    \
  184. X "\nRecipe flag quick reference:\
  185. X\n\tH\tegrep the header (default)\
  186. X\n\tB\tegrep the body\
  187. X\n\tD\tdistinguish case\
  188. X\n\tA\talso execute this recipe if the common condition matched\
  189. X\n\ta\tsame as 'A', but only if the previous recipe was successful\
  190. X\n\th\tfeed the header to the pipe (default)\
  191. X\n\tb\tfeed the body to the pipe (default)\
  192. X\n\tf\tfilter\
  193. X\n\tc\tcontinue with the next recipe in any case\
  194. X\n\tw\twait for a filter or program\
  195. X\n\tW\tsame as 'w', but suppress 'Program failure' messages\
  196. X\n\ti\tignore write errors\n"
  197. X
  198. X#define MINlinebuf    128    /* minimal LINEBUF length (don't change this) */
  199. X#define FROM_EXPR    "\nFrom "
  200. X#define FROM        "From "
  201. X#define SHFROM        "From"
  202. X#define NSUBJECT    "^Subject:.*$"
  203. X#define MAXSUBJECTSHOW    78
  204. X#define FOLDER        "  Folder: "
  205. X#define LENtSTOP    9 /* tab stop at which message length will be logged */
  206. X
  207. X#define TABCHAR        "\t"
  208. X#define TABWIDTH    8
  209. X
  210. X#define RECFLAGS    "HBDAahbfcwWi"
  211. X#define HEAD_GREP     0
  212. X#define BODY_GREP      1
  213. X#define DISTINGUISH_CASE   2
  214. X#define ALSO_NEXT_RECIPE    3
  215. X#define ALSO_N_IF_SUCC         4
  216. X#define PASS_HEAD          5
  217. X#define PASS_BODY           6
  218. X#define FILTER            7
  219. X#define CONTINUE         8
  220. X#define WAIT_EXIT          9
  221. X#define WAIT_EXIT_QUIET           10
  222. X#define IGNORE_WRITERR            11
  223. X
  224. X#define UNIQ_PREFIX    '_'      /* prepended to temporary unique filenames */
  225. X#define ESCAP        '>'
  226. X
  227. X        /* some formail-specific configuration options: */
  228. X
  229. X#define UNKNOWN        "foo@bar"      /* formail default originator name */
  230. X#define OLD_PREFIX    "Old-"             /* formail field-Old-prefix */
  231. X
  232. X#define FM_SKIP        '+'              /* skip the first nnn messages */
  233. X#define FM_TOTAL    '-'        /* only spit out a total of nnn messages */
  234. X#define FM_BOGUS    'b'             /* leave bogus Froms intact */
  235. X#define FM_CONCATENATE    'c'          /* concatenate continued header-fields */
  236. X#define FM_FORCE    'f'   /* force formail to accept an arbitrary format */
  237. X#define FM_REPLY    'r'            /* generate an auto-reply header */
  238. X#define FM_KEEPB    'k'           /* keep the header, when replying */
  239. X#define FM_TRUST    't'    /* trust the sender to supply a valid header */
  240. X#define FM_LOGSUMMARY    'l'    /* generate a procmail-compatible log summary */
  241. X#define FM_SPLIT    's'                      /* split it up */
  242. X#define FM_NOWAIT    'n'              /* don't wait for the programs */
  243. X#define FM_EVERY    'e'    /* don't require empty lines leading headers */
  244. X#define FM_MINFIELDS    'm'    /* the number of fields that have to be found */
  245. X#define DEFminfields    2        /* before a header is recognised as such */
  246. X#define FM_DIGEST    'd'                 /* split up digests */
  247. X#define FM_QUIET    'q'            /* ignore write errors on stdout */
  248. X#define FM_EXTRACT    'x'               /* extract field contents */
  249. X#define FM_EXTRC_KEEP    'X'                    /* extract field */
  250. X#define FM_ADD_IFNOT    'a'         /* add a field if not already there */
  251. X#define FM_ADD_ALWAYS    'A'               /* add this field in any case */
  252. X#define FM_REN_INSERT    'i'            /* rename and insert a field */
  253. X#define FM_DEL_INSERT    'I'            /* delete and insert a field */
  254. X#define FM_ReNAME    'R'                   /* rename a field */
  255. X#define FM_USAGE    "\
  256. XUsage: formail [+nnn] [-nnn] [-bcfrktnedq] [-m nnn] [-l folder]\
  257. X [-xXaAiI field]\n\t[-R ofield nfield] [-s prg arg ...]\n"
  258. X#define FM_HELP        \
  259. X "\t-b\tdon't escape bogus mailbox headers\
  260. X\n\t-c\tconcatenate continued header-fields\
  261. X\n\t-f\tforce formail to pass along any non-mailbox format\
  262. X\n\t-r\tgenerate an auto-reply header, preserve fields with -i\
  263. X\n\t-k\ton auto-reply keep the body, prevent escaping with -b\
  264. X\n\t-t\ttrust the sender for his return address\
  265. X\n\t-l folder\tgenerate a procmail-compatible log summary\
  266. X\n\t-q\tbe quiet about write errors on stdout\
  267. X\n\t-s prg arg\tsplit the mail, startup prg for every message\
  268. X\n\t-n\tdon't wait for every prg while splitting\
  269. X\n\t-e\tdon't require empty lines to precede a header\
  270. X\n\t-d\taccept digest format\
  271. X\n\t-m nnn\tmin fields threshold (default 2) for start of message\
  272. X\n\t+nnn\tskip the first nnn messages while splitting\
  273. X\n\t-nnn\toutput at most nnn messages while splitting\
  274. X\n\t-x field   extract contents\t-X field   extract fully\
  275. X\n\t-a field   add if not present\t-A field   add in any case\
  276. X\n\t-i field   rename and insert\t-I field   delete and insert\
  277. X\n\t-R oldfield newfield\trename\n"
  278. END_OF_FILE
  279. if test 11315 -ne `wc -c <'procmail280/config.h'`; then
  280.     echo shar: \"'procmail280/config.h'\" unpacked with wrong size!
  281. fi
  282. # end of 'procmail280/config.h'
  283. fi
  284. if test -f 'procmail280/man/procmail.man' -a "${1}" != "-c" ; then 
  285.   echo shar: Will not clobber existing file \"'procmail280/man/procmail.man'\"
  286. else
  287. echo shar: Extracting \"'procmail280/man/procmail.man'\" \(14857 characters\)
  288. sed "s/^X//" >'procmail280/man/procmail.man' <<'END_OF_FILE'
  289. X.Id $Id: procmail.man,v 1.13 1993/01/28 14:22:05 berg Exp $
  290. X.TH PROCMAIL 1 \*(Dt BuGless
  291. X.na
  292. X.SH NAME
  293. Xprocmail \- autonomous mail processor
  294. X.SH SYNOPSIS
  295. X.B procmail
  296. X.RB [ \-+PRESERVOPT++TEMPFAILOPT+ ]
  297. X.RB [ "\-+FROMWHOPT+ \fIfromwhom\fP" ]
  298. X.RI [ "parameter\fB=\fPvalue " | " rcfile" ]
  299. X\&.\|.\|.
  300. X.br
  301. X.B procmail
  302. X.RB [ \-+PRESERVOPT++TEMPFAILOPT+ ]
  303. X.RB [ "\-+FROMWHOPT+ \fIfromwhom\fP" ]
  304. X.B \-+DELIVEROPT+
  305. X.I recipient
  306. X\&.\|.\|.
  307. X.br
  308. X.B procmail
  309. X.B \-+VERSIONOPT+
  310. X.ad
  311. X.Sh DESCRIPTION
  312. XFor a quick start, see
  313. X.B NOTES
  314. Xat the end.
  315. X.PP
  316. X.B Procmail
  317. Xshould be invoked automatically over the
  318. X.B +DOT_FORWARD+
  319. Xfile mechanism as soon as mail arrives.  Alternatively, when installed by
  320. Xa system administrator, it can be invoked from within the mailer immediately.
  321. XWhen invoked, it first sets some environment variables to default values,
  322. Xreads the mail message from stdin until an EOF, separates the body from the
  323. Xheader, and then, if no command line arguments are present, it starts to look
  324. Xfor a file named
  325. X.B +PROCMAILRC+
  326. Xin your home directory.  According to the processing recipes in this file,
  327. Xthe mail message that just arrived gets distributed into the right folder
  328. X(and more).
  329. X.PP
  330. XIf running suid root or with root privileges, procmail will be able to
  331. Xperform as a functionally enhanced, backwards compatible mail delivery agent.
  332. X.PP
  333. XThe rcfile format is described in detail in the
  334. X.BR procmailrc (5)
  335. Xman page.
  336. X.PP
  337. XExamples for rcfile recipes can be looked up in the
  338. X.BR procmailex (5)
  339. Xman page.
  340. X.Ss Signals
  341. X.Tp 1.2i
  342. X.B TERMINATE
  343. XTerminate prematurely and requeue the mail.
  344. X.Tp
  345. X.B HANGUP
  346. XTerminate prematurely and bounce the mail.
  347. X.Tp
  348. X.B INTERRUPT
  349. XTerminate prematurely and bounce the mail.
  350. X.Tp
  351. X.B QUIT
  352. XTerminate prematurely and silently lose the mail.
  353. X.Tp
  354. X.B ALARM
  355. XForce a timeout (see
  356. X.BR TIMEOUT).
  357. X.Sh OPTIONS
  358. X.Tp 0.5i
  359. X.B \-+VERSIONOPT+
  360. XProcmail will print its version number and exit.
  361. X.Tp
  362. X.B \-+PRESERVOPT+
  363. XPreserve any old environment.  Normally procmail clears the environment
  364. Xupon startup+KEEPENV+.  However, in any case: any default values will override
  365. Xany preexisting environment variables, i.e. procmail will not pay any attention
  366. Xto any predefined environment variables, it will happily overwrite them
  367. Xwith its own defaults.
  368. X.Tp
  369. X.B \-+TEMPFAILOPT+
  370. XMake procmail fail softly, i.e. if procmail cannot deliver the mail to
  371. Xany of the destinations you gave, the mail will not bounce, but will return
  372. Xto the mailqueue.  Another delivery-attempt will be made at some time in
  373. Xthe future.
  374. X.Tp
  375. X.I "\fB\-+FROMWHOPT+\fP fromwhom"
  376. XCauses procmail to regenerate the leading `+FROM+' line with
  377. X.I fromwhom
  378. Xas the sender (instead of \-+FROMWHOPT+ one could use the alternate and
  379. Xobsolete \-+ALTFROMWHOPT+).
  380. X.Tp
  381. X.I "\fB\-+DELIVEROPT+\fP recipient .\|.\|."
  382. XThis turns on explicit delivery mode, delivery will be to the local user
  383. X.IR recipient .
  384. XThis, of course, only is possible if procmail has root privileges.
  385. XProcmail will setuid to the intended recipients and shall
  386. X.I only
  387. Xread the recipient's +PROCMAILRC+ file (if present, if not, delivery is like
  388. Xordinary mail).
  389. X.Sh ARGUMENTS
  390. XAny arguments containing an '=' are considered to be environment variable
  391. Xassignments, they will
  392. X.I all
  393. Xbe evaluated after the default values have been
  394. Xassigned and before the first rcfile is opened.
  395. X.PP
  396. XAny other arguments are presumed to be rcfile paths (either absolute,
  397. Xor if they start with `+chCURDIR++MCDIRSEP+' relative to the current
  398. Xdirectory;
  399. X.B any other relative
  400. Xpath is relative to $HOME); procmail will start with the first one it finds
  401. Xon the command line.  The following ones will only be parsed if the preceding
  402. Xones have a not matching HOST-directive entry, or in case they should not
  403. Xexist.
  404. X.PP
  405. XIf no rcfiles are specified, it looks for
  406. X.BR $HOME/+PROCMAILRC+ .
  407. XIf not even that can be found, processing will continue according to
  408. Xthe default settings of the environment variables and the ones specified
  409. Xon the command line.
  410. X.Sh CAVEATS
  411. XAny default values that procmail has for some environment variables will
  412. X.B always
  413. Xoverride the ones that were already defined.  If you really want to
  414. Xoverride the defaults, you either have to put them in the
  415. X.B rcfile
  416. Xor in the command line as arguments.
  417. X.Sh FILES
  418. X.Tp 2.3i
  419. X.B /etc/passwd
  420. Xto set the recipient's LOGNAME, HOME and SHELL variable defaults
  421. X.Tp
  422. X.B +SYSTEM_MBOX+
  423. Xsystem mailbox
  424. X.Tp
  425. X.B $HOME/+PROCMAILRC+
  426. Xdefault rcfile
  427. X.Tp
  428. X.B +SYSTEM_MBOX++DEFlockext+
  429. Xlockfile for the system mailbox (not used by procmail automatically, unless
  430. X$DEFAULT equals +SYSTEM_MBOX+ and procmail is delivering to $DEFAULT)
  431. X.Tp
  432. X.B +DEFsendmail+
  433. Xdefault mail forwarder
  434. X.Tp
  435. X.B +UNIQ_PREFIX+????`hostname`
  436. Xtemporary `unique' zero-length files created by procmail
  437. X.Sh "SEE ALSO"
  438. X.na
  439. X.nh
  440. X.BR procmailrc (5),
  441. X.BR procmailex (5),
  442. X.BR sh (1),
  443. X.BR csh (1),
  444. X.BR mail (1),
  445. X.BR mailx (1),
  446. X.BR binmail (1),
  447. X.BR uucp (1),
  448. X.BR aliases (5),
  449. X.BR sendmail (8),
  450. X.BR egrep (1),
  451. X.BR grep (1),
  452. X.BR biff (1),
  453. X.BR comsat (8),
  454. X.BR lockfile (1),
  455. X.BR formail (1),
  456. X.BR cron (1)
  457. X.hy
  458. X.ad
  459. X.Sh DIAGNOSTICS
  460. X.Tp 2.3i
  461. XAutoforwarding mailbox found
  462. XThe system mailbox had its suid or sgid bit set, procmail terminates with
  463. XEX_NOUSER assuming that this mailbox must not be delivered to.
  464. X.Tp
  465. XBad substitution of "x"
  466. XNot a valid environment variable name specified.
  467. X.Tp
  468. XCouldn't create "x"
  469. XThe system mailbox was missing and could not/will not be created.
  470. X.Tp
  471. XCouldn't determine implicit lockfile from "x"
  472. XThere were no `>>' redirectors to be found, using simply `$LOCKEXT' as
  473. Xlocallockfile.
  474. X.Tp
  475. XCouldn't unlock "x"
  476. XLockfile was already gone, or write permission to the directory were the
  477. Xlockfile is has been denied.
  478. X.Tp
  479. XDeadlock attempted on "x"
  480. XThe locallockfile specified on this recipe is equal to a still active
  481. X$LOCKFILE.
  482. X.Tp
  483. XError while writing to "x"
  484. XNonexistent subdirectory, no write permission, pipe died or disk full.
  485. X.Tp
  486. XExceeded LINEBUF
  487. XBuffer overflow detected, LINEBUF was too small, memory might be corrupted.
  488. X.Tp
  489. XExcessive output quenched from "x"
  490. XThe program or filter "x" tried to produce too much output for the current
  491. XLINEBUF, discarded the rest.
  492. X.Tp
  493. XExtraneous filter-flag ignored
  494. XYou specified the `+FILTER+'-flag on a recipe with a filename as the
  495. Xdestination, or where stdout is captured.
  496. X.Tp
  497. XFailed forking "x"
  498. XProcess table is full (and NORESRETRY has been exhausted).
  499. X.Tp
  500. XFailed to execute "x"
  501. XProgram not in path, or not executable.
  502. X.Tp
  503. XForced unlock denied on "x"
  504. XNo write permission in the directory where
  505. X.B lockfile
  506. X"x" resides, or more than one procmail trying to force a lock at exactly the
  507. Xsame time.
  508. X.Tp
  509. XForcing lock on "x"
  510. X.B Lockfile
  511. X"x" is going to be removed by force because of a timeout (see also:
  512. X.BR LOCKTIMEOUT ).
  513. X.Tp
  514. XKernel-lock failed
  515. XWhile trying to use the kernel-supported locking calls, one of them failed
  516. X(usually indicates an OS error), procmail ignores this error and proceeds.
  517. X.Tp
  518. XKernel-unlock failed
  519. XSee above.
  520. X.Tp
  521. XLock failure on "x"
  522. XCan only occur if you specify some real weird (and illegal) lockfilenames
  523. Xor if the
  524. X.B lockfile
  525. Xcould not be created because of insufficient permissions or noexistent
  526. Xsubdirectories.
  527. X.Tp
  528. XMissing name
  529. XThe \-+FROMWHOPT+ option needs an extra argument
  530. X.Tp
  531. XMissing recipient
  532. XYou specified the \-+DELIVEROPT+ option or called procmail under a different
  533. Xname, it expects one or more recipients as arguments
  534. X.Tp
  535. XOut of memory
  536. XThe system is out of swap space (and NORESRETRY has been exhausted).
  537. X.Tp
  538. XProcessing continued
  539. XThe unrecognised options on the command line are ignored, proceeding as
  540. Xusual.
  541. X.Tp
  542. XProgram failure of "x"
  543. XProgram that was started by procmail didn't return EX_OK (=+EX_OK+).
  544. X.Tp
  545. XSkipped: "x"
  546. XCouldn't do anything with "x" in the rcfile (syntax error), ignoring it.
  547. X.Tp
  548. XSuspicious rcfile
  549. XThe owner of the rcfile was not the recipient, or the directory that contained
  550. Xit was world writeable (the rcfile was not used)
  551. X.Tp
  552. XTerminating prematurely whilst waiting for .\|.\|.
  553. XProcmail received a signal while it was waiting for .\|.\|.
  554. X.Tp
  555. XTimeout, terminating "x"
  556. XTimeout has occurred on program/filter "x".
  557. X.Tp
  558. XTruncating "x" and retrying lock
  559. X"x" does not seem to be a valid filename or the file is not empty.
  560. X.Tp
  561. XReiterating kernel-lock
  562. XWhile attempting several locking methods, one of these failed.  Procmail will
  563. Xreiterate untill they all succeed in rapid succession.
  564. X.Tp
  565. XRescue of unfiltered data succeeded/failed
  566. XA filter returned unsuccessfully, procmail tried to get back the original text.
  567. X.Tp
  568. XUnexpected EOL
  569. XMissing closing quote, or trying to escape EOF.
  570. X.Tp
  571. XUnknown user "x"
  572. XThe specified recipient does not have a corresponding uid.
  573. X.Sh "EXTENDED DIAGNOSTICS"
  574. X.Tp 2.3i
  575. XAssigning "x"
  576. XEnvironment variable assignment.
  577. X.Tp
  578. XExecuting "x"
  579. XStarting program "x".  If it is started by procmail directly (without an
  580. Xintermediate shell), procmail will show where it separated the arguments
  581. Xby inserting commas.
  582. X.Tp
  583. XHOST mismatched "x"
  584. XThis host was called "x", HOST contained something else.
  585. X.Tp
  586. XLocking "x"
  587. XCreating lockfile "x".
  588. X.Tp
  589. XMatch on "x"
  590. XCondition matched.
  591. X.Tp
  592. XNo match on "x"
  593. XCondition didn't match, recipe skipped.
  594. X.Tp
  595. XNotified comsat: "$LOGNAME@offset:file"
  596. XSent comsat/biff a notice that mail arrived for user $LOGNAME at `offset'
  597. Xin `file'.
  598. X.Tp
  599. XOpening "x"
  600. XOpening file "x" for appending.
  601. X.Tp
  602. XOpening directory "x"
  603. XOpening a directory for finding the highest file number.
  604. X.Tp
  605. XRcfile: "x"
  606. XRcfile changed to "x".
  607. X.Tp
  608. XUnlocking "x"
  609. XRemoving lockfile "x" again.
  610. X.Sh WARNINGS
  611. XYou should create a shell script that uses
  612. X.BR lockfile (1)
  613. Xbefore invoking your mail shell on any mailbox file other than the system
  614. Xmailbox (unless of course, your mail shell uses the same lockfiles (local
  615. Xor global) you specified in your rcfile).
  616. X.PP
  617. XIn the unlikely event that you absolutely need to kill procmail before it has
  618. Xfinished, first try and use the regular kill command (i.e.
  619. X.I not
  620. Xkill -9, see the subsection
  621. X.I Signals
  622. Xfor suggestions), otherwise some
  623. X.I lockfiles
  624. Xmight not get removed.
  625. X.PP
  626. XBeware when using the
  627. X.B \-+TEMPFAILOPT+
  628. Xoption, if procmail repeatedly is unable to deliver the mail (e.g. due to
  629. Xan incorrect rcfile), the system mailqueue could fill up.  This could
  630. Xaggravate both the local postmaster and other users.
  631. X.Sh BUGS
  632. XAfter removing a lockfile by force, procmail waits $SUSPEND seconds before
  633. Xcreating a new lockfile so that another process that decides to remove the
  634. Xstale lockfile will not remove the newly created lock by mistake.
  635. X.PP
  636. XProcmail uses the regular TERMINATE signal to terminate any runaway filter,
  637. Xbut it does not check if the filter responds to that signal and it only sends
  638. Xit to the filter itself, not to any of the filter's children.
  639. X.Sh MISCELLANEOUS
  640. XWhen appending to regular mailfolders any lines in the body of the message that
  641. Xlook like postmarks are prepended with `+ESCAP+' (disarms bogus mailheaders).
  642. XThe regular expression that is used to search for these postmarks is:
  643. X.Rs
  644. X`+FROM_EXPR+'
  645. X.Re
  646. X.PP
  647. XIf the destination name used in explicit delivery mode is not in /etc/passwd,
  648. Xprocmail will proceed as if explicit delivery mode was not in effect.
  649. XIf not in explicit delivery mode and
  650. Xshould the uid procmail is running under, have no corresponding /etc/passwd
  651. Xentry, then HOME will default to +RootDir+, LOGNAME will default to #uid and
  652. XSHELL will default to +BinSh+.
  653. X.PP
  654. XWhen in explicit delivery mode, procmail will generate a leading `+FROM+'
  655. Xline if none is present.  If one is already present+TRUSTED_IDS+ procmail will
  656. Xleave it intact.
  657. X.PP
  658. XFor security reasons procmail will only use an rcfile if it is owned by the
  659. Xrecipient or if the directory it is contained in, is not world writeable.
  660. X.PP
  661. XIf +SYSTEM_MBOX+ is a bogus mailbox (i.e. does not belong to the recipient,
  662. Xis unwritable, is a symbolic link or is a hard link), procmail will upon
  663. Xstartup try to rename it into a file starting with `+BOGUSprefix+' and
  664. Xending in an inode-sequence-code.  If this turns out to be impossible,
  665. X.B ORGMAIL
  666. Xwill have
  667. X.I no
  668. Xinitial value, and hence will inhibit delivery without a proper rcfile.
  669. X.PP
  670. XWhen delivering to directories (or to MH folders) you
  671. X.B don't
  672. Xneed to use lockfiles to prevent several concurrently running procmail
  673. Xprograms from messing up.
  674. X.PP
  675. XDelivering to MH folders is slightly more time consuming than delivering
  676. Xto normal directories or mailboxes, because procmail has to search for
  677. Xthe next available number (instead of having the filename immediately
  678. Xavailable).
  679. X.PP
  680. XOn general failure procmail will return EX_CANTCREAT, unless option
  681. X.B \-+TEMPFAILOPT+
  682. Xis specified, in which case it will return EX_TEMPFAIL.
  683. X.PP
  684. XTo make `egrepping' of headers more consistent, procmail concatenates all
  685. Xcontinued header fields; but only internally.  When delivering the mail, line
  686. Xbreaks will appear as before.
  687. X.PP
  688. XIf procmail is called under a different name than `procmail' (i.e. if it
  689. Xis linked to another name and invoked as such), it comes up in explicit
  690. Xdelivery mode, and expects the recipients' names as command line arguments
  691. X(as if \-+DELIVEROPT+ had been specified).
  692. X.PP
  693. XComsat/biff notifications are done using +COMSATprotocol+.  They are sent off
  694. Xonce when procmail generates the regular logfile entry.  The notification
  695. Xmessages have the following extended format (or as close as you can get when
  696. Xfinal delivery was not to a file):
  697. X.Rs
  698. X$LOGNAME@offset_of_message_in_mailbox+COMSATxtrsep+absolute_path_to_mailbox
  699. X.Re
  700. X.PP
  701. XWhenever procmail itself opens a file to deliver to, it
  702. X+KERNEL_LOCKING+.
  703. X.PP
  704. XProcmail is NFS-resistant and eight-bit clean.
  705. X.br
  706. X.ne 11
  707. X.Sh NOTES
  708. XCalling up procmail with the \-+HELPOPT1+ or \-+HELPOPT2+ options will cause
  709. Xit to display a command-line help and recipe flag quick-reference page.
  710. X.PP
  711. X+CF_procmail+
  712. XIn this case your $HOME/+DOT_FORWARD+ (beware, it
  713. X.B has
  714. Xto be world readable) file should contain the line below.  Be sure to include
  715. Xthe single and double quotes, and it
  716. X.I must
  717. Xbe an
  718. X.I absolute
  719. Xpath.  The `#YOUR_LOGIN_NAME' is not actually a parameter that is required by
  720. Xprocmail, in fact, it will be discarded by sh before procmail ever sees it;
  721. Xit is however a necessary kludge against overoptimising sendmail programs:
  722. X.PP
  723. X.na
  724. X.nf
  725. X+FW_content+
  726. X.fi
  727. X.ad
  728. X.PP
  729. XProcmail can also be invoked to postprocess an already filled system
  730. Xmailbox.  This can be useful if you don't want to or can't use a
  731. X$HOME/+DOT_FORWARD+ file (in which case the following script could
  732. Xperiodically be called from within
  733. X.BR cron (1),
  734. Xor whenever you start reading mail):
  735. X.Rs
  736. X#!/bin/sh
  737. Xumask 077
  738. Xlockfile \-l3600 $HOME/.newmail.lock
  739. Xlockfile \-l3600 \-ml
  740. Xcat +SYSTEM_MBOX+ >>$HOME/.newmail &&
  741. X cp /dev/null >+SYSTEM_MBOX+
  742. Xlockfile \-mu
  743. Xformail \-+FM_SPLIT+ procmail <$HOME/.newmail
  744. Xrm \-f $HOME/.newmail $HOME/.newmail.lock
  745. Xexit 0
  746. X.Re
  747. X.br
  748. X.ne 14
  749. X.Ss "A sample small +PROCMAILRC+:"
  750. X.na
  751. X.nf
  752. XPATH=/bin:/usr/bin:/usr/local/bin
  753. XMAILDIR=$HOME/Mail      #you'd better make sure it exists
  754. XDEFAULT=$MAILDIR/mbox
  755. XLOGFILE=$MAILDIR/from
  756. X::
  757. X^From.*berg
  758. Xfrom_me
  759. X:
  760. X^Subject:.*Flame
  761. X/dev/null
  762. X.fi
  763. X.ad
  764. END_OF_FILE
  765. if test 14857 -ne `wc -c <'procmail280/man/procmail.man'`; then
  766.     echo shar: \"'procmail280/man/procmail.man'\" unpacked with wrong size!
  767. fi
  768. # end of 'procmail280/man/procmail.man'
  769. fi
  770. if test -f 'procmail280/src/regexp.c' -a "${1}" != "-c" ; then 
  771.   echo shar: Will not clobber existing file \"'procmail280/src/regexp.c'\"
  772. else
  773. echo shar: Extracting \"'procmail280/src/regexp.c'\" \(11082 characters\)
  774. sed "s/^X//" >'procmail280/src/regexp.c' <<'END_OF_FILE'
  775. X/************************************************************************
  776. X *    Custom regular expression library, *fully* egrep compatible    *
  777. X *                                    *
  778. X *    Seems to be perfect.                        *
  779. X *                                    *
  780. X *    Copyright (c) 1991-1992, S.R. van den Berg, The Netherlands    *
  781. X *    #include "README"                        *
  782. X ************************************************************************/
  783. X#ifdef RCS
  784. Xstatic /*const*/char rcsid[]=
  785. X "$Id: regexp.c,v 1.15 1993/01/13 20:18:03 berg Exp $";
  786. X#endif
  787. X#include "procmail.h"
  788. X#include "robust.h"
  789. X#include "shell.h"
  790. X#include "regexp.h"
  791. X
  792. X#define R_BEG_GROUP    '('
  793. X#define R_OR        '|'
  794. X#define R_END_GROUP    ')'
  795. X#define R_0_OR_MORE    '*'
  796. X#define R_0_OR_1    '?'
  797. X#define R_1_OR_MORE    '+'
  798. X#define R_DOT        '.'
  799. X#define R_SOL        '^'
  800. X#define R_EOL        '$'
  801. X#define R_BEG_CLASS    '['
  802. X#define R_NOT_CLASS    '^'
  803. X#define R_RANGE        '-'
  804. X#define R_END_CLASS    ']'
  805. X#define R_ESCAPE    '\\'
  806. X
  807. X#define BITS_P_CHAR        8
  808. X#define OPB            (1<<BITS_P_CHAR)
  809. X#define OPC_EPS            OPB
  810. X#define OPC_CLASS        (OPB+1)
  811. X#define OPC_DOT            (OPB+2)
  812. X#define OPC_BOTEXT        (OPB+3)
  813. X#define OPC_FIN            (OPB+4)
  814. X
  815. X#define bit_type        unsigned
  816. X#define bit_bits        (sizeof(bit_type)*8)
  817. X#define bit_index(which)    ((unsigned)(which)/bit_bits)
  818. X#define bit_mask(which)        ((unsigned)1<<(unsigned)(which)%bit_bits)
  819. X#define bit_toggle(name,which)    (name[bit_index(which)]^=bit_mask(which))
  820. X#define bit_test(name,which)    (!!(name[bit_index(which)]&bit_mask(which)))
  821. X#define bit_set(name,which,value)    \
  822. X (value?(name[bit_index(which)]|=bit_mask(which)):\
  823. X (name[bit_index(which)]&=~bit_mask(which)))
  824. X#define bit_field(name,size)    bit_type name[((size)+bit_bits-1)/bit_bits]
  825. X
  826. X#define SZ(x)        (sizeof(struct x))
  827. X#define Ceps        (struct eps*)
  828. X#define epso(to,add)    (Ceps((char*)(to)+(add)))
  829. X#define ii        (aleps.topc)
  830. X#define jjp        (aleps.tnext)
  831. X
  832. X/* the spawn and stack members are reused in the normal opcodes as pc fields */
  833. Xstatic struct eps*r;
  834. Xstatic struct{unsigned topc;struct eps*tnext;}aleps;
  835. Xstatic uchar*p,*cachea,*cachep;
  836. Xstatic size_t cacher;
  837. Xstatic ignore_case;
  838. X
  839. Xstruct chclass {unsigned opc_;struct eps*stack_,*spawn_,*next_;
  840. X bit_field(c,OPB);};
  841. X
  842. Xstatic void puteps(spot,to,aswell)struct eps*const spot;  /* epsilon transit */
  843. X const struct eps*const to,*const aswell;
  844. X{ spot->opc=OPC_EPS;spot->next=to!=spot?Ceps to:Ceps aswell;
  845. X  spot->spawn=aswell!=spot?Ceps aswell:Ceps to;spot->stack=0;
  846. X}
  847. X
  848. Xstatic void putneps(spot,to)struct eps*const spot;const struct eps*const to;
  849. X{ puteps(spot,to,spot+1);
  850. X}
  851. X
  852. X#define rAc    (((struct chclass*)r)->c)
  853. X
  854. Xstatic void bseti(i,j)unsigned i;const int j;
  855. X{ bit_set(rAc,i,j);               /* mark 'i' as being in the class */
  856. X  if(ignore_case)                  /* mark the other case too */
  857. X   { if(i-'A'<'Z'-'A')                        /* uppercase */
  858. X    i+='a'-'A';
  859. X     else if(i-'a'<'z'-'a')                    /* lowercase */
  860. X    i-='a'-'A';
  861. X     else return;                          /* no case */
  862. X     bit_set(rAc,i,j);
  863. X   }
  864. X}
  865. X
  866. Xstatic void por P((const struct eps*const e));
  867. X
  868. Xstatic void psimp(e)const struct eps*const e;
  869. X{ switch(*p)
  870. X   { case R_BEG_GROUP:p++;por(e);return;      /* not so simple after all */
  871. X     case R_BEG_CLASS:                       /* a simple class */
  872. X      { unsigned i,j=R_NOT_CLASS==*++p;
  873. X    if(e)
  874. X     { r->opc=OPC_CLASS;r->next=Ceps e;r->spawn=r->stack=0;
  875. X       i=maxindex(rAc);
  876. X       do rAc[i]=j?~0:0;                 /* preset the bit field */
  877. X       while(i--);
  878. X     }
  879. X    if(j)                      /* skip the 'not' modifier */
  880. X     { p++;
  881. X       if(e)
  882. X          bit_toggle(rAc,'\n');
  883. X     }
  884. X    if(*p==R_END_CLASS)      /* right at the start, cannot mean the end */
  885. X     { p++;
  886. X       if(e)
  887. X          i=R_END_CLASS,bit_toggle(rAc,R_END_CLASS);
  888. X     }
  889. X    else if(*p==R_RANGE)                /* take it literally */
  890. X     { p++;
  891. X       if(e)
  892. X          i=R_RANGE,bit_toggle(rAc,R_RANGE);
  893. X     }
  894. X    for(;;p++)
  895. X     { switch(*p)
  896. X        { case R_END_CLASS:p++;
  897. X          case '\0':r=epso(r,SZ(chclass));return;
  898. X          case R_RANGE:
  899. X         switch(*++p)
  900. X          { default:
  901. X               if(e)
  902. X              while(++i<*p)            /* mark all in the range */
  903. X                 bseti(i,!j);
  904. X               break;
  905. X            case '\0':case R_END_CLASS:p--;        /* literally */
  906. X          }
  907. X        }
  908. X       if(e)
  909. X          bseti(i= *p,!j);              /* a normal character, mark it */
  910. X     }
  911. X      }
  912. X     case '\0':return;
  913. X     case R_DOT:             /* matches everything but a newline */
  914. X    if(e)
  915. X     { r->opc=OPC_DOT;goto fine;
  916. X     }
  917. X    goto fine2;
  918. X     case R_EOL:case R_SOL:              /* match a newline (in effect) */
  919. X    if(p[1]==R_SOL)
  920. X     { p++;
  921. X       if(e)
  922. X        {  r->opc=OPC_BOTEXT;goto fine;
  923. X        }
  924. X     }
  925. X    else if(e)
  926. X     { r->opc='\n';goto fine;
  927. X     }
  928. X    goto fine2;
  929. X     case R_ESCAPE:                      /* quote something */
  930. X    if(!*++p)                     /* nothing to quote */
  931. X       p--;
  932. X   }
  933. X  if(e)                              /* a regular character */
  934. X   { r->opc=ignore_case&&(unsigned)*p-'A'<'Z'-'A'?*p+'a'-'A':*p;
  935. Xfine:
  936. X     r->next=Ceps e;r->spawn=r->stack=0;
  937. X   }
  938. Xfine2:
  939. X  p++;r++;
  940. X}
  941. X
  942. X#define EOS(x)    (jjp?jjp:(x))
  943. X
  944. Xstatic void pnorm(e)const struct eps*const e;
  945. X{ void*pold;struct eps*rold;
  946. X  for(;;)
  947. X   { pold=p;rold=r;psimp(Ceps 0);ii= *p;            /* skip it first */
  948. X     jjp=p[1]==R_OR||p[1]==R_END_GROUP||!p[1]?Ceps e:Ceps 0;
  949. X     if(e)
  950. X    p=pold,pold=r;
  951. X     switch(ii)               /* check for any of the postfix operators */
  952. X      { case R_0_OR_MORE:r++;
  953. X       if(e)              /* first an epsilon, then the rest */
  954. X          putneps(rold,EOS(r)),r=rold+1,psimp(rold);
  955. X       goto incagoon;
  956. X    case R_1_OR_MORE:                   /* first the rest */
  957. X       if(e)                      /* and then an epsilon */
  958. X          puteps(r,rold,EOS(r+1)),r=rold,psimp(Ceps pold);
  959. X       r++;goto incagoon;
  960. X    case R_0_OR_1:r++;
  961. X       if(e)              /* first an epsilon, then the rest */
  962. X          putneps(rold,r=EOS(r)),pold=r,r=rold+1,psimp(Ceps pold);
  963. Xincagoon:  switch(*++p)            /* at the end of this group already? */
  964. X        { case R_OR:case R_END_GROUP:case '\0':return;
  965. X        }
  966. X       continue;                 /* regular end of the group */
  967. X    case R_OR:case R_END_GROUP:case '\0':
  968. X       if(e)
  969. X          r=rold,psimp(e);
  970. X       return;
  971. X      }
  972. X     if(e)            /* no fancy postfix operators, plain vanilla */
  973. X    r=rold,psimp(Ceps pold);
  974. X   }
  975. X}
  976. X
  977. Xstatic void por(e)const struct eps*const e;
  978. X{ uchar*pvold;struct eps*rvold;
  979. X  if(!e)
  980. X   { rvold=r;
  981. X     if(cachea==(pvold=p))
  982. X      { p=cachep;r=epso(rvold,cacher);return;
  983. X      }
  984. X   }
  985. X  for(;;)
  986. X   { uchar*pold;struct eps*rold;
  987. X     for(pold=p,rold=r;;)
  988. X      { switch(*p)
  989. X     { default:pnorm(Ceps 0);r=rold;continue;     /* still in this group */
  990. X       case '\0':case R_END_GROUP:           /* found the end of the group */
  991. X          if(p==pold)                 /* empty 'or' group */
  992. X           { if(e)
  993. X            puteps(r,e,e);           /* misused epsilon as branch, */
  994. X         r++;        /* let the optimiser (fillout()) take it out */
  995. X           }
  996. X          else
  997. X         p=pold,pnorm(e);            /* normal last group */
  998. X          if(*p)
  999. X         p++;
  1000. X          if(!e)
  1001. X         cachea=pvold,cachep=p,cacher=(char*)r-(char*)rvold;
  1002. X          return;
  1003. X       case R_OR:r++;
  1004. X          if(p==pold)                 /* empty 'or' group */
  1005. X           { if(e)
  1006. X            putneps(rold,e);              /* special epsilon */
  1007. X           }
  1008. X          else
  1009. X           { p=pold;pnorm(e);          /* normal 'or' group, first an */
  1010. X         if(e)                   /* epsilon, then the rest */
  1011. X            putneps(rold,r);
  1012. X           }
  1013. X          p++;
  1014. X     }
  1015. X    break;
  1016. X      }
  1017. X   }
  1018. X}
  1019. X
  1020. Xstatic void findandrep(old,newv)register struct eps**const old;
  1021. X struct eps*const newv;
  1022. X{ register struct eps*i,*t= *old;               /* save the value */
  1023. X  for(i=r;i->opc!=OPC_FIN;)         /* change all pointers from *old to new */
  1024. X   { if(i->next==t)
  1025. X    i->next=newv;
  1026. X     if(i->spawn==t)
  1027. X    i->spawn=newv;
  1028. X     switch(i->opc)
  1029. X      { case OPC_CLASS:i=epso(i,SZ(chclass));break;
  1030. X    default:i++;
  1031. X      }
  1032. X   }
  1033. X  *old=t;
  1034. X}
  1035. X
  1036. X#define drs(m)    (*(struct eps**)((char*)*stack+(ioffsetof(struct eps,m)^ofs)))
  1037. X
  1038. Xstatic cstack(stack,ofs)struct eps**const stack;
  1039. X{ if(drs(next)->stack==Ceps p)
  1040. X   { findandrep(*stack,drs(next));*stack=drs(spawn);return 1;
  1041. X   }
  1042. X  return 0;
  1043. X}
  1044. X    /* break up any closed epsilon circles, otherwise they can't be executed */
  1045. Xstatic fillout(stack)struct eps**const stack;
  1046. X{ if((*stack)->opc!=OPC_EPS||(*stack)->stack)
  1047. X     return 0;
  1048. X  (*stack)->stack=Ceps p;                /* mark this one as used */
  1049. X#define RECURS(nxt)    \
  1050. X  do\
  1051. X     if(cstack(stack,ioffsetof(struct eps,nxt)^ioffsetof(struct eps,next)))\
  1052. X    return 1;\
  1053. X  while(fillout(&(*stack)->nxt))
  1054. X  RECURS(next);RECURS(spawn);return 0;                  /* recurse */
  1055. X}
  1056. X
  1057. Xstruct eps*bregcomp(a,ign_case)const char*a;
  1058. X{ struct eps*st;size_t i;      /* first a trial run, determine memory needed */
  1059. X  p=(uchar*)a;ignore_case=ign_case;r=Ceps&aleps;cachea=0;por(Ceps 0);
  1060. X  st=r=
  1061. X   malloc((i=(char*)r-(char*)&aleps)+ioffsetof(struct eps,stack)+sizeof r);
  1062. X  p=(uchar*)a;por(epso(st,i));r->opc=OPC_FIN;r->stack=0;      /* compile */
  1063. X  for(r=st;;)                 /* simplify the compiled code (i.e. */
  1064. X     switch(st->opc)              /* take out cyclic epsilon references) */
  1065. X      { case OPC_FIN:return r;                     /* finished */
  1066. X    case OPC_CLASS:st=epso(st,SZ(chclass));break;             /* skip */
  1067. X    case OPC_EPS:p=(uchar*)st;fillout(&st);               /* check tree */
  1068. X    default:st++;                         /* skip too */
  1069. X      }
  1070. X}
  1071. X
  1072. X#define XOR1        \
  1073. X (ioffsetof(struct eps,spawn)^ioffsetof(struct eps,stack))
  1074. X#define PC(this,t)    (*(struct eps**)((char*)(this)+(t)))
  1075. X
  1076. Xchar*bregexec(code,text,len,ign_case)struct eps*code;const uchar*const text;
  1077. X size_t len;
  1078. X{ register struct eps*reg,*stack,*other,*thiss;unsigned i,th1,ot1;
  1079. X  const uchar*str;struct eps*initstack,*initcode;
  1080. X  initstack=0;
  1081. X  if((initcode=code)->opc==OPC_EPS)
  1082. X     initcode=(initstack=code)->next,code->stack=0;
  1083. X  thiss= --code;th1=ioffsetof(struct eps,spawn);
  1084. X  ot1=ioffsetof(struct eps,stack);str=text-1;len++;i='\n';goto setups;
  1085. X  do                  /* make sure any beginning-of-line-hooks catch */
  1086. X   { i= *++str;                 /* get the next real-text character */
  1087. X     if(ign_case&&i-'A'<'Z'-'A')
  1088. X    i+='a'-'A';                 /* transmogrify it to lowercase */
  1089. Xlastrun:                     /* switch this & other pc-stack */
  1090. X     th1^=XOR1;ot1^=XOR1;thiss=other;
  1091. Xsetups:
  1092. X     other=code;stack=initstack;reg=initcode;goto nostack;
  1093. X     do                     /* pop next entry off this pc-stack */
  1094. X      { thiss=PC(reg=thiss,th1);PC(reg,th1)=0;reg=reg->next;goto nostack;
  1095. X    do                /* pop next entry off the work-stack */
  1096. X     { for(reg=stack->spawn,stack=stack->stack;;)
  1097. Xnostack:    { switch(reg->opc-OPB)  /* push spawned branch on the work-stack */
  1098. X           { default:
  1099. X            if(i==reg->opc)          /* regular character match */
  1100. X               goto yep;
  1101. X            break;
  1102. X         case OPC_EPS-OPB:reg->stack=stack;reg=(stack=reg)->next;
  1103. X            continue;
  1104. X         case OPC_FIN-OPB:       /* hurray!  complete regexp match */
  1105. X            return(char*)str;        /* return one past the match */
  1106. X         case OPC_BOTEXT-OPB:
  1107. X            if(str<text)           /* only at the very beginning */
  1108. X               goto yep;
  1109. X            break;
  1110. X         case OPC_CLASS-OPB:
  1111. X            if(bit_test(((struct chclass*)reg)->c,i))
  1112. X               goto yep;               /* character in class */
  1113. X            break;
  1114. X         case OPC_DOT-OPB:                 /* dot-wildcard */
  1115. X            if(i!='\n')
  1116. Xyep:               if(!PC(reg,ot1))             /* state not yet pushed */
  1117. X              PC(reg,ot1)=other,other=reg; /* push location onto */
  1118. X           }                       /* other pc-stack */
  1119. X          break;
  1120. X        }
  1121. X     }
  1122. X    while(stack);                  /* the work-stack is not empty */
  1123. X      }
  1124. X     while(thiss!=code);               /* this pc-stack is not empty */
  1125. X   }
  1126. X  while(--len);                         /* still text to search */
  1127. X  if(ign_case!=2)                          /* out of text */
  1128. X   { ign_case=2;len=1;str++;goto lastrun;     /* check if we just matched */
  1129. X   }
  1130. X  return 0;                             /* no match */
  1131. X}
  1132. END_OF_FILE
  1133. if test 11082 -ne `wc -c <'procmail280/src/regexp.c'`; then
  1134.     echo shar: \"'procmail280/src/regexp.c'\" unpacked with wrong size!
  1135. fi
  1136. # end of 'procmail280/src/regexp.c'
  1137. fi
  1138. echo shar: End of archive 8 \(of 11\).
  1139. cp /dev/null ark8isdone
  1140. MISSING=""
  1141. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1142.     if test ! -f ark${I}isdone ; then
  1143.     MISSING="${MISSING} ${I}"
  1144.     fi
  1145. done
  1146. if test "${MISSING}" = "" ; then
  1147.     echo You have unpacked all 11 archives.
  1148.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1149. else
  1150.     echo You still need to unpack the following archives:
  1151.     echo "        " ${MISSING}
  1152. fi
  1153. ##  End of shell archive.
  1154. exit 0
  1155. -- 
  1156. Sincerely,                                  berg@pool.informatik.rwth-aachen.de
  1157.            Stephen R. van den Berg (AKA BuGless).    berg@physik.tu-muenchen.de
  1158.  
  1159. "Be spontaneous!"
  1160.  
  1161. exit 0 # Just in case...
  1162.