home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 56.2 KB | 1,757 lines |
- Newsgroups: comp.sources.misc
- From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
- Subject: v31i043: procmail - mail processing program v2.71, Part04/05
- Message-ID: <1992Jul16.204846.20976@sparky.imd.sterling.com>
- X-Md4-Signature: acc6ce8d82c525fa8b729ab10109d6bc
- Date: Thu, 16 Jul 1992 20:48:46 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
- Posting-number: Volume 31, Issue 43
- Archive-name: procmail/part04
- Environment: UNIX, sendmail, smail, MMDF
- Supersedes: procmail: Volume 29, Issue 90-94
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 5)."
- # Contents: procmail/examples/advanced procmail/man/procmail.man
- # procmail/man/procmailrc.man procmail/retint.c
- # Wrapped by berg@minipicc on Thu Jul 16 14:34:21 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'procmail/examples/advanced' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail/examples/advanced'\"
- else
- echo shar: Extracting \"'procmail/examples/advanced'\" \(11463 characters\)
- sed "s/^X//" >'procmail/examples/advanced' <<'END_OF_FILE'
- XDiscusses:
- X 1. One home directory, several machine architectures
- X 2. Procmail as an integrated local mail delivery agent
- X 2a.Special directions for sites with sendmail
- X 2b.Special directions for sites with smail
- X 3. Security considerations (when installing procmail suid root)
- X 4. How to generate autoreplies
- X 4a.`Vacation' functionality
- X 5. Some exorbitant examples of rcfile formats
- X 6. Some advanced examples of the use of the 'A' flag
- X
- X ---
- X
- X1. One home directory, several machine architectures
- X -------------------------------------------------
- X
- XFor users that have the very same home directory on machines with differing
- Xarchitectures (i.e. you need different executables), and they
- Xhave to explicitly use (i.e. the system administrator did not arrange,
- Xfor example, /usr/local/bin/procmail to have exactly the right contents
- Xdepending on from which machine it is called) two executables of procmail,
- XI have the following suggestion to use as a .forward file (examples are for
- Xsparc and sun3 architectures):
- X
- X"|IFS=' ';if /usr/bin/sparc;then exec /home/berg/bin.sun4/procmail;else exec /home/berg/bin.sun3/procmail;fi #YOUR_LOGIN_NAME"
- X
- Xor alternatively:
- X
- X"|IFS=' ';exec /home/berg/bin.`/usr/bin/arch`/procmail #YOUR_LOGIN_NAME"
- X
- XPlease note, in the .forward file there can NOT be any newlines between
- Xthe doublequotes, i.e. the former example *has* to be typed in as one long
- Xline.
- X
- XIf, on the other hand, you have to log in to every machine to read mail
- Xarrived for you on that machine, a different solution might be more
- Xappropriate; in that case put something like the following two lines in your
- X.forward file:
- X
- XYOUR_LOGIN_NAME@your.favourite.machine
- X"|IFS=' ';if test .`/bin/uname -n` = .your.favourite.machine; then /exec /home/berg/bin/procmail; else exit 0; fi #YOUR_LOGIN_NAME"
- X
- XThe leading dots are important. Check what `/bin/uname -n` returns on
- Xyour.favourite.machine, and substitute that for your.favourite.machine in the
- Xsample .forward file. If your system does not have /bin/uname, /bin/hostname
- Xwill do too.
- X
- X ---
- X
- X2. Procmail as an integrated local mail delivery agent
- X ---------------------------------------------------
- X
- XCompletely integrating procmail in the mail delivery means that mail is
- Xdelivered as normal, unless a .procmailrc file is present in the home
- Xdirectory of the recipient. This will be completely independent of the
- Xfact if a .forward file is present. This will not break anything, it
- Xjust makes the use of procmail easier because people are not required to
- Xstart up procmail from within their .forward files. Creation of a .procmailrc
- Xfile will suffice.
- X
- XThe generic way to accomplish this (works with sendmail, smail and any other
- Xmail system that uses a local mail delivery program that takes the mail-
- Xto-be-delivered on stdin and the recipient(s) on the command line, with or
- Xwithout the "-d" option) is this:
- X
- XMove your current local mail delivery agent (e.g. /bin/mail, /bin/lmail,
- X/usr/lib/mail/mail.local, etc.) out of the way, and create a (symbolic or hard)
- Xlink from there to procmail, as in "ln /usr/local/bin/procmail /bin/lmail".
- X
- XIn addition to needing root priviliges upon startup, on some systems procmail
- Xneeds to be sgid to daemon or mail. One way to check is by looking at the
- Xcurrent mail delivery agent (usually /bin/mail) and to mimic its permissions,
- Xowner and group. If you're not quite sure, just type "make recommend" and some
- Xsuitable recommendations will be made for your particular environment.
- X
- XThe same might apply to the "lockfile" program, in order for it to be able to
- Xcreate and unlink lockfiles in the mail spool directory it might need to be
- Xsgid to daemon or mail, not to worry however, "lockfile" will not enable users
- Xto abuse the sgid/suid-ness.
- X
- X ---
- X
- X2a.Special directions for sites with sendmail
- X ------------------------------------------
- X
- XHere you have two options:
- X i. Procmail *not* being suid root
- X ii.Procmail suid root (actually preferred and recommended)
- X
- X)Ad i.
- XThe following line should take the place of the standard
- XMlocal rule in your sendmail.cf (this way sendmail will start up procmail with
- Xroot priv, procmail will immediately setuid itself to the recipient's uid):
- X
- XMlocal, P=/usr/local/bin/procmail, F=lsSDFMuhP, S=10, R=20, A=procmail -d $u
- X
- X)Ad ii.
- XIf your sendmail does not allow starting programs with root privs (the
- X'S' flag), you can instead make procmail suid root (this is actually the
- Xpreferred way to go, it closes a security hole which actually sendmail should
- Xhave closed). This will not create a security hole, procmail will normally
- Xsetuid immediately to the real uid (effectively losing root privs), or will
- Ximmediately setuid to the recipient's uid (and be completely loyal to the
- Xrecipient's absent or present .procmailrc file). Actually installing procmail
- Xsuid root is a slightly more flexible approach (not at all more dangerous).
- X
- XIf using the suid root version of procmail, you only need to insert the
- Xfollowing line in your sendmail.cf:
- X
- XMlocal, P=/usr/local/bin/procmail, F=lsDFMuhP, S=10, R=20, A=procmail -d $u
- X
- XSo, to summarise, if you install procmail not-suid-root you should use the
- Xfirst rule (with the 'S' flag), and if you install it suid-root you should
- Xuse the second rule (without the 'S' flag). If you install procmail
- Xnot-suid-root you cannot use the second rule, since procmail will not be
- Xable to change uid to the recipient, and therefore it cannot read/write
- Xthe recipient's files (including any .procmailrc). The alternative would
- Xbe that procmail already has the recipient's uid upon startup, this is not
- Xpossible in sendmail without changing some configuration options.
- X
- XAs for the remaining flags "S=10, R=20", if your system uses others or
- Xnone on the current Mlocal rule, use those instead of "S=10, R=20".
- X
- X ---
- X
- X2b.Special directions for sites with smail
- X ---------------------------------------
- X
- XFor smail 2.x users there are two options:
- X i. Move the current local-mail-delivery program (probably /bin/lmail) out of
- X the way, make a symbolic or hard link from procmail to the name of that
- X program (e.g. "ln /usr/local/bin/procmail /bin/lmail")
- X ii.Make sure the following macro is defined in src/defs.h:
- X #define LMAIL(frm,sys) "/usr/local/bin/procmail -d"
- X
- XFor smail 3.x users there are also two options:
- X i. The same solution as for smail 2.x (however, method ii is preferred)
- X ii.Replace any existing "local"-entry in the /usr/lib/smail/transports file
- X (create one, if need be) with the following two lines:
- X
- Xlocal: return_path, local, from, driver=pipe;
- X cmd="/usr/local/bin/procmail -d $($user$)"
- X
- XFor any ideas on suid/sgid modes which *might* be needed, see the previous
- Xparagraph (2).
- X
- X ---
- X
- X3. Security considerations (when installing procmail suid root)
- X -------------------------------------------------------------
- X
- XIf in EXPLICIT DELIVERY mode (typically when called from within sendmail)
- Xprocmail will ALWAYS change UID and gid to the RECIPIENT's defaults as soon as
- Xit starts reading the recipient's $HOME/.procmailrc file.
- X
- XIf NOT in explicit delivery mode (typically when called from within the
- Xrecipient's $HOME/.forward file) procmail will ALWAYS change UID and gid to
- Xthe real uid and gid of the INVOKER (effectively losing any suid or sgid
- Xpriviliges).
- X
- XThese two precautions should effectively eliminate any security holes because
- Xprocmail will always have the uid of the person whose commands it is executing.
- X
- XTo summarise, procmail will only behave better if made suid/sgid something, in
- Xfact, making procmail suid/sgid something will *improve* security on systems
- Xwhich have dynamically linked libraries.
- X
- X ---
- X
- X4. How to generate autoreplies
- X ---------------------------
- X
- XUsing a recipe like the following, you can generate autoreplies to mail
- Xreceived by you:
- X
- X: 2 h c
- X!^From +[^ ]*(postmaster|Mailer)
- X!^From +YOUR_LOGIN_NAME
- X| (formail -r ; echo "Mail received.") | $SENDMAIL -t
- X
- XAs you can see, I made sure that neither bouncing mail (from postmaster or the
- Xmailer-daemon), nor mail coming from yourself will be autoreplied. If this
- Xprecaution would not be taken, disaster could result ("ringing" mail).
- XThe abovementioned recipe should be inserted before all other recipes in
- Xyour rcfile, however, it is advisable to put it *after* any recipes that
- Xprocess mailinglist subscriptions; it generally is not a good idea to
- Xgenerate autoreplies to mailinglists.
- X
- X ---
- X
- X4a.`Vacation' functionality
- X ------------------------
- X
- XSHELL=/bin/sh # for other shells, this might need adjustment
- XALREADYSENT=$MAILDIR/vacation # the vacation database
- X
- X: 2 hWc: # the lockfile is important
- X!^From +[^ ]*(postmaster|Mailer)
- X!^From +YOUR_LOGIN_NAME
- X| FROM="`formail -rx To:`" ;\
- X if fgrep -e "$FROM" <$ALREADYSENT ;\
- X then exit 1 ;\
- X else echo "$FROM" >>$ALREADYSENT ;\
- X fi
- X
- X :ahc
- X | (formail -r ; echo "Mail received.") | $SENDMAIL -t
- X
- XThis example is based on the same principles as before (sort out bounced mail
- Xand mail coming from oneself). In addition to that however, it maintains a
- Xvacation database by extracting the name of the sender and appending it
- Xto $ALREADYSENT if the name is *not* already in there. If the name was new,
- Xan autoreply will be sent (using the "a" flag functionality, see the man
- Xpage of procmail for more info). To reliably extract the name of the sender,
- XI let formail generate an autoreply header (thereby making it figure out the
- Xmost appropriate sender address), and then telling it to extract the value
- Xof the "To:" field.
- X
- X ---
- X
- X5. Some exorbitant examples of rcfile formats
- X ------------------------------------------
- X
- X# Now follows an example of what you can do in a procmailrc file
- XHELLO=oneword
- XHELLO="two words"
- XHELLO='two words' HELLO = one\
- Xword
- XHELLO=two\ words
- XHELLO=two\ `echo words`
- XHELLO= # empty
- XHELLO # This will wipe "HELLO" from the environment
- XHELLO = "three words"\ yes
- XHELLO = "$HELLO `cat somefile` " # Trailing blanks
- XHELLO = "wheeee`date`${HELLO} this works too" HELLO = 'But so does this!'
- X
- X# As you can see, every trick in the book of /bin/sh programming can be used
- X# (and more).
- X
- XLOCALLOCKFILE = llf
- X
- X ::$LOCALLOCKFILE
- Xgrep for this
- X |$HELLO # calls up a program named "But" with 3 arguments
- X
- X:: "test ing" # lockfilename with a space in it
- Xgrep for this
- X |$HELLO
- X
- X:
- Xor for this
- X|"$HELLO" # tries to call up a program named "But so does this!"
- X
- X:
- Xand this
- X|$HELLO \
- Xthere # action lines can be continued
- X
- X ---
- X
- X6. Some advanced examples of the use of the 'A' flag
- X -------------------------------------------------
- X
- X:c # Specify the 'c' otherwise we never arrive at the next recipe
- X^From Myfriend
- Xevery_message_from_my_friend # Mailbox for everything he/she writes
- X
- X:Ac # Note the 'c' again
- X! my_other_friend # Forward everything Myfriend writes to my_other_friend
- X
- X:1Ac
- X^Subject:.*jokes
- X! my_third_friend # Forward everything Myfriend writes about jokes
- X # to my_third_friend
- X
- X:2A
- X^Subject:.*parties
- X!beach
- X! my_third_friend # Forward everything Myfriend writes about parties,
- X # except beach parties, to my_third_friend
- X
- X:A # Provide a mail sink, in order to fake procmail into
- X/dev/null # believing that the mail was absorbed/delivered,
- X # even if the mail was about beach parties :-).
- X # This is not the best solution though, better would be to
- X # rearrange these last five recipes so that the current
- X # number one or two is last, the current number five can be
- X # omitted then.
- X
- X ---
- END_OF_FILE
- if test 11463 -ne `wc -c <'procmail/examples/advanced'`; then
- echo shar: \"'procmail/examples/advanced'\" unpacked with wrong size!
- fi
- # end of 'procmail/examples/advanced'
- fi
- if test -f 'procmail/man/procmail.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail/man/procmail.man'\"
- else
- echo shar: Extracting \"'procmail/man/procmail.man'\" \(12373 characters\)
- sed "s/^X//" >'procmail/man/procmail.man' <<'END_OF_FILE'
- X.de Id
- X.ds Rv \\$3
- X.ds Dt \\$4
- X..
- X.Id $Id: procmail.man,v 2.27 1992/06/03 14:40:24 berg Rel $
- X.de Sh
- X.br
- X.ne 11
- X.SH "\\$1"
- X..
- X.de Ss
- X.br
- X.ne 10
- X.SS "\\$1"
- X..
- X.de Tp
- X.br
- X.ne 9
- X.TP \\$1
- X..
- X.de Rs
- X.na
- X.nf
- X.RS
- X..
- X.de Re
- X.RE
- X.fi
- X.ad
- X..
- X.TH PROCMAIL 1 \*(Dt BuGless
- X.SH NAME
- X.na
- Xprocmail \- autonomous mail processor
- X.SH SYNOPSIS
- X.B procmail
- X.RB [ \-+PRESERVOPT++TEMPFAILOPT+ ]
- X.RB [ "\-+FROMWHOPT+ \fIfromwhom\fP" ]
- X.RI [ "parameter\fB=\fPvalue " | " rcfile" ]
- X\&.\|.\|.
- X.br
- X.B procmail
- X.RB [ \-+PRESERVOPT++TEMPFAILOPT+ ]
- X.RB [ "\-+FROMWHOPT+ \fIfromwhom\fP" ]
- X.B \-+DELIVEROPT+
- X.I recipient
- X\&.\|.\|.
- X.br
- X.B procmail
- X.B \-+VERSIONOPT+
- X.ad
- X.Sh DESCRIPTION
- XFor a quick start, see
- X.B NOTES
- Xat the end.
- X.PP
- X.B Procmail
- Xshould be invoked automatically over the
- X.B +DOT_FORWARD+
- Xfile mechanism as soon as mail arrives. Alternatively, when installed by
- Xa system administrator, it can be invoked from within the mailer immediately.
- XWhen invoked, it first sets some environment variables to default values,
- Xreads the mail message from stdin until an EOF, separates the body from the
- Xheader, and then, if no command line arguments are present, it starts to look
- Xfor a file named
- X.B +PROCMAILRC+
- Xin your home directory. According to the processing recipes in this file,
- Xthe mail message that just arrived gets distributed into the right folder
- X(and more).
- X.PP
- XIf running suid root or with root priviliges, procmail will be able to
- Xperform as a functionally enhanced, backwards compatible mail delivery agent.
- X.PP
- XThe rcfile format is described in detail in the
- X.BR procmailrc (5)
- Xman page.
- X.PP
- XExamples for rcfile recipes can be looked up in the
- X.BR procmailex (5)
- Xman page.
- X.Ss Signals
- X.Tp 1.2i
- X.B TERMINATE
- XTerminate prematurely and requeue the mail.
- X.Tp
- X.B HANGUP
- XTerminate prematurely and bounce the mail.
- X.Tp
- X.B INTERRUPT
- XTerminate prematurely and bounce the mail.
- X.Tp
- X.B QUIT
- XTerminate prematurely and silently lose the mail.
- X.Tp
- X.B ALARM
- XForce a timeout (see
- X.BR TIMEOUT).
- X.Sh OPTIONS
- X.Tp 0.5i
- X.B \-+VERSIONOPT+
- XProcmail will print its version number and exit.
- X.Tp
- X.B \-+PRESERVOPT+
- XPreserve any old environment. Normally procmail clears the environment
- Xupon startup+KEEPENV+. However, in any case: any default values will override
- Xany preexisting environment variables, i.e. procmail will not pay any attention
- Xto any predefined environment variables, it will happily overwrite them
- Xwith its own defaults.
- X.Tp
- X.B \-+TEMPFAILOPT+
- XMake procmail fail softly, i.e. if procmail cannot deliver the mail to
- Xany of the destinations you gave, the mail will not bounce, but will return
- Xto the mailqueue. Another delivery-attempt will be made at some time in
- Xthe future.
- X.Tp
- X.I "\fB\-+FROMWHOPT+\fP fromwhom"
- XCauses procmail to regenerate the leading `+FROM+' line with
- X.I fromwhom
- Xas the sender (instead of \-+FROMWHOPT+ one could use the alternate and
- Xobsolete \-+ALTFROMWHOPT+).
- X.Tp
- X.I "\fB\-+DELIVEROPT+\fP recipient .\|.\|."
- XThis turns on explicit delivery mode, delivery will be to the local user
- X.IR recipient .
- XThis, of course, only is possible if procmail has root priviliges.
- XProcmail will setuid to the intended recipients and shall
- X.I only
- Xread the recipient's +PROCMAILRC+ file (if present, if not, delivery is like
- Xordinary mail).
- X.Sh ARGUMENTS
- XAny arguments containing an '=' are considered to be environment variable
- Xassignments, they will
- X.I all
- Xbe evaluated after the default values have been
- Xassigned and before the first rcfile is opened.
- X.PP
- XAny other arguments are presumed to be rcfile paths (absolute or relative to
- X$HOME); procmail will start with the first one it finds on the command line.
- XThe following ones will only be parsed if the preceding ones have a not
- Xmatching HOST-directive entry, or in case they should not exist.
- X.PP
- XIf no rcfiles are specified, it looks for
- X.BR $HOME/+PROCMAILRC+ .
- XIf not even that can be found, processing will continue according to
- Xthe default settings of the environment variables and the ones specified
- Xon the command line.
- X.Sh CAVEATS
- XAny default values that procmail has for some environment variables will
- X.B always
- Xoverride the ones that were already defined. If you really want to
- Xoverride the defaults, you either have to put them in the
- X.B rcfile
- Xor in the command line as arguments.
- X.Sh FILES
- X.Tp 2.3i
- X.B /etc/passwd
- Xto get the recipient's USER, HOME and SHELL variable defaults
- X.Tp
- X.B +SYSTEM_MBOX+
- Xsystem mailbox
- X.Tp
- X.B $HOME/+PROCMAILRC+
- Xdefault rcfile
- X.Tp
- X.B +SYSTEM_MBOX++DEFlockext+
- Xlockfile for the system mailbox (not used by procmail automatically, unless
- X$DEFAULT equals +SYSTEM_MBOX+ and procmail is delivering to $DEFAULT)
- X.Tp
- X.B +DEFsendmail+
- Xdefault mail forwarder
- X.Tp
- X.B +UNIQ_PREFIX+????`hostname`
- Xtemporary `unique' zero-length files created by procmail
- X.Sh "SEE ALSO"
- X.na
- X.BR procmailrc (5),
- X.BR procmailex (5),
- X.BR sh (1),
- X.BR csh (1),
- X.BR mail (1),
- X.BR binmail (1),
- X.BR uucp (1C),
- X.BR aliases (5),
- X.BR sendmail (8),
- X.BR egrep (1V),
- X.BR lockfile (1),
- X.BR formail (1)
- X.ad
- X.Sh DIAGNOSTICS
- X.Tp 2.3i
- XBad substitution of "x"
- XNot a valid environment variable name specified.
- X.Tp
- XCouldn't unlock "x"
- XLockfile was already gone, or write permission to the directory were the
- Xlockfile is has been denied.
- X.Tp
- XError while writing to "x"
- XNonexistent subdirectory, no write permission, pipe died or disk full.
- X.Tp
- XExceeded LINEBUF
- XBuffer overflow detected, LINEBUF was too small, memory might be corrupted.
- X.Tp
- XFailed forking "x"
- XProcess table is full (and NORESRETRY has been exhausted).
- X.Tp
- XFailed to execute "x"
- XProgram not in path, or not executable.
- X.Tp
- XForced unlock denied on "x"
- XNo write permission in the directory where
- X.B lockfile
- Xresides, or more than one procmail trying to force a lock at exactly the same
- Xtime.
- X.Tp
- XForcing lock on "x"
- XSpecified
- X.B lockfile
- Xis going to be removed by force because of a timeout (see also:
- X.BR LOCKTIMEOUT ).
- X.Tp
- XLock failure on "x"
- XCan only occur if you specify some real weird (and illegal) lockfilenames
- Xor if the
- X.B lockfile
- Xcould not be created because of insufficient permissions or noexistent
- Xsubdirectories.
- X.Tp
- XMissing name
- XThe \-+FROMWHOPT+ option needs an extra argument
- X.Tp
- XMissing recipient
- XYou specified the \-+DELIVEROPT+ option or called procmail under a different
- Xname, it expects one or more recipients as arguments
- X.Tp
- XOut of memory
- XThe system is out of swap space (and NORESRETRY has been exhausted).
- X.Tp
- XProcessing continued
- XThe unrecognised options on the command line are ignored, proceeding as
- Xusual.
- X.Tp
- XProgram failure of "x"
- XProgram that was started by procmail didn't return EX_OK (=+EX_OK+).
- X.Tp
- XSkipped: "x"
- XCouldn't do anything with "x" in the rcfile (syntax error), ignoring it.
- X.Tp
- XSuspicious rcfile
- XThe owner of the rcfile was not the recipient, or the directory that contained
- Xit was world writeable (the rcfile was not used)
- X.Tp
- XTerminating prematurely whilst waiting for .\|.\|.
- XProcmail received a signal while it was waiting for .\|.\|.
- X.Tp
- XTimeout, terminating "x"
- XTimeout has occurred on program/filter "x".
- X.Tp
- XTruncating "x" and retrying lock
- X"x" does not seem to be a valid filename or the file is not empty.
- X.Tp
- XRescue of unfiltered data succeeded/failed
- XA filter returned unsuccessfully, procmail tried to get back the original text.
- X.Tp
- XUnexpected EOL
- XMissing closing quote, or trying to escape EOF.
- X.Sh "EXTENDED DIAGNOSTICS"
- X.Tp 2.3i
- XAssigning "x"
- XEnvironment variable assignment
- X.Tp
- XExecuting "x"
- XStarting program "x"
- X.Tp
- XHOST mismatched "x"
- XThis host was called "x", HOST contained something else
- X.Tp
- XLocking "x"
- XCreating lockfile "x"
- X.Tp
- XMatch on "x"
- XCondition matched
- X.Tp
- XNo match on "x"
- XCondition didn't match, recipe skipped
- X.Tp
- XOpening "x"
- XOpening file "x" for appending
- X.Tp
- XOpening directory "x"
- XOpening a directory for finding the highest file number
- X.Tp
- XRcfile: "x"
- XRcfile changed to "x"
- X.Tp
- XUnlocking "x"
- XRemoving lockfile "x" again
- X.Sh WARNINGS
- XYou should create a shell script that uses
- X.BR lockfile (1)
- Xbefore invoking your mail shell on any mailbox file other than the system
- Xmailbox (unless of course, your mail shell uses the same lockfiles (local
- Xor global) you specified in your rcfile).
- X.PP
- XIn the unlikely event that you absolutely need to kill procmail before it has
- Xfinished, first try and use the regular kill command (i.e.
- X.I not
- Xkill -9, see the subsection
- X.I Signals
- Xfor suggestions), otherwise some
- X.I lockfiles
- Xmight not get removed.
- X.PP
- XBeware when using the
- X.B \-+TEMPFAILOPT+
- Xoption, if procmail repeatedly is unable to deliver the mail (e.g. due to
- Xan incorrect rcfile), the system mailqueue could fill up. This could
- Xaggravate both the local postmaster and other users.
- X.Sh BUGS
- XAfter a lockfile is removed by force, a suspension of $SUSPEND seconds
- Xis taken into account, in order to prevent the inadvertent immediate removal
- Xof any newly created lockfile by another program.
- X.PP
- XProcmail uses the regular TERMINATE signal to terminate any runaway filter,
- Xbut it does not check if the filter responds to that signal and it only sends
- Xit to the filter itself, not to any of the filter's children.
- X.Sh MISCELLANEOUS
- XAny lines in the body of the message that look like postmarks are prepended
- Xwith `+ESCAP+' (disarms bogus mailheaders). The regular expression that is
- Xused to search for these postmarks is:
- X.Rs
- X"+FROM_EXPR+"
- X.Re
- X.PP
- XIf the destination name used in explicit delivery mode is not in /etc/passwd,
- Xprocmail will proceed as if explicit delivery mode was not in effect.
- XIf not in explicit delivery mode and
- Xshould the uid procmail is running under, have no corresponding /etc/passwd
- Xentry, then HOME will default to +Tmp+, USER will default to #uid.
- X.PP
- XWhen in explicit delivery mode, procmail will generate a leading `+FROM+'
- Xline if none is present. If one is already present+TRUSTED_IDS+ procmail will
- Xleave it intact.
- X.PP
- XFor security reasons procmail will only use an rcfile if it is owned by the
- Xrecipient or if the directory it is contained in, is not world writeable.
- X.PP
- XIf +SYSTEM_MBOX+ is a bogus mailbox (i.e. does not belong to the recipient,
- Xis unwritable, is a symbolic link or is a hard link), procmail will upon
- Xstartup try to rename it into a file starting with `+BOGUSprefix+' and
- Xending in an inode-sequence-code. If this turns out to be impossible,
- X.B ORGMAIL
- Xwill have
- X.I no
- Xinitial value.
- X.PP
- XWhen delivering to directories (or to MH folders) you
- X.B don't
- Xneed to use lockfiles to prevent several concurrently running procmail
- Xprograms from messing up.
- X.PP
- XDelivering to MH folders is slightly more time consuming than delivering
- Xto normal directories or mailboxes, because procmail has to search for
- Xthe next available number (instead of having the filename immediately
- Xavailable).
- X.PP
- XOn general failure procmail will return EX_CANTCREAT, unless option
- X.B \-+TEMPFAILOPT+
- Xis specified, in which case it will return EX_TEMPFAIL.
- X.PP
- XTo make `egrepping' of headers more consistent, procmail concatenates all
- Xcontinued header fields.
- X.PP
- XIf procmail is called under a different name than `procmail' (i.e. if it
- Xis linked to another name and invoked as such), it comes up in explicit
- Xdelivery mode, and expects the recipients' names as command line arguments
- X(as if \-+DELIVEROPT+ had been specified).
- X.PP
- XProcmail performs the locking in an NFS-secure way.
- X.br
- X.ne 11
- X.Sh NOTES
- XCalling up procmail with the \-+HELPOPT1+ or \-+HELPOPT2+ options will cause
- Xit to display a command-line help and flags quick-reference page.
- X.PP
- XIf procmail is
- X.I not
- Xinstalled globally as the default mail delivery agent (ask your system
- Xadministrator), you have to make sure it is invoked when your mail arrives.
- XIn this case your $HOME/+DOT_FORWARD+ (beware, it
- X.B has
- Xto be world readable) file should contain the line below. Be sure to include
- Xthe single and double quotes, and it
- X.I must
- Xbe an
- X.I absolute
- Xpath. The `#YOUR_LOGIN_NAME' is not actually a parameter that is required by
- Xprocmail, actually, it will be discarded by /bin/sh before procmail ever
- Xsees it; it is however a necessary bug fix against overoptimising sendmail
- Xprograms:
- X.PP
- X.na
- X.nf
- X+FW_content+
- X.fi
- X.ad
- X.br
- X.ne 14
- X.Ss "A sample small +PROCMAILRC+:"
- X.na
- X.nf
- XPATH=/bin:/usr/bin:/usr/local/bin
- XMAILDIR=$HOME/Mail #you'd better make sure it exists
- XDEFAULT=$MAILDIR/mbox
- XLOGFILE=$MAILDIR/from
- X::
- X^From.*berg
- Xfrom_me
- X:
- X^Subject:.*Flame
- X/dev/null
- X.fi
- X.ad
- X.Sh AUTHOR
- XStephen R. van den Berg at RWTH-Aachen, Germany
- X.Rs
- Xberg@pool.informatik.rwth-aachen.de
- Xberg@physik.tu-muenchen.de
- X.Re
- END_OF_FILE
- if test 12373 -ne `wc -c <'procmail/man/procmail.man'`; then
- echo shar: \"'procmail/man/procmail.man'\" unpacked with wrong size!
- fi
- # end of 'procmail/man/procmail.man'
- fi
- if test -f 'procmail/man/procmailrc.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail/man/procmailrc.man'\"
- else
- echo shar: Extracting \"'procmail/man/procmailrc.man'\" \(15197 characters\)
- sed "s/^X//" >'procmail/man/procmailrc.man' <<'END_OF_FILE'
- X.de Id
- X.ds Rv \\$3
- X.ds Dt \\$4
- X..
- X.Id $Id: procmailrc.man,v 2.6 1992/06/03 12:58:50 berg Rel $
- X.de Sh
- X.br
- X.ne 11
- X.SH "\\$1"
- X..
- X.de Ss
- X.br
- X.ne 10
- X.SS "\\$1"
- X..
- X.de Tp
- X.br
- X.ne 9
- X.TP \\$1
- X..
- X.de Rs
- X.na
- X.nf
- X.RS
- X..
- X.de Re
- X.RE
- X.fi
- X.ad
- X..
- X.TH PROCMAILRC 5 \*(Dt BuGless
- X.SH NAME
- X.na
- Xprocmailrc \- procmail rcfile
- X.SH SYNOPSIS
- X.B $HOME/+PROCMAILRC+
- X.ad
- X.Sh DESCRIPTION
- XFor a quick start, see
- X.B NOTES
- Xat the end of the
- X.BR procmail (1)
- Xman page.
- X.PP
- XThe rcfile can contain a mixture of environment variable assignments (some
- Xof which have special meanings to procmail), and recipes. In their most
- Xsimple appearance, the recipes are simply one line regular expressions
- Xthat are searched for in the header of the arriving mail, the first recipe
- Xthat matches is used to determine where the mail has to go (usually a file).
- X.PP
- XIf a matching recipe does not specify any special flags (like `+FILTER+' or
- X`+CONTINUE+') and the recipe is successful (i.e. no write failures or other
- Xcalamities), then processing of the rcfile will cease at this point, and
- Xprocmail will consider the mail to have been delivered.
- X.PP
- XThis enables you to presort your mail extremely straightforward into several
- Xmailfolders. Bear in mind though that the mail can arrive concurrently in
- Xthese mailfolders (if several procmail programs happen to run at the same time,
- Xnot unlikely if a lot of mail arrives), to make sure this does not result in a
- Xmess, proper use of lockfiles is highly recommended.
- X.PP
- XThe environment variable
- X.B assignments
- Xand
- X.B recipes
- Xcan be freely intermixed in the rcfile. If any environment variable has
- Xa special meaning to procmail, it will be used appropiately the moment
- Xit is parsed. (i.e. you can change the current directory whenever you
- Xwant by specifying a new
- X.BR MAILDIR ,
- Xswitch lockfiles by specifying a new
- X.BR LOCKFILE ,
- Xchange the umask at any time, etc., the possibilities are endless :-).
- X.PP
- XThe assignments and substitutions of these environment variables are handled
- Xexactly like in
- X.BR sh (1)
- X(that includes all possible quotes and escapes),
- Xwith the added bonus that blanks around the '=' sign are ignored and that,
- Xif an environment variable appears without a trailing '=', it will be
- Xremoved from the environment.
- X.PP
- X.Ss Comments
- XA word beginning with # and all the following characters up to a NEWLINE
- Xare ignored.
- X.Ss Recipes
- X.PP
- XA line starting with ':' marks the beginning of a recipe. It has the
- Xfollowing format:
- X.PP
- X.Rs
- X: [\fInumber\fP] [\fIflags\fP] [ : [\fIlocallockfile\fP] ]
- X<zero or more conditions (one per line)>
- X<exactly one action line>
- X.Re
- X.PP
- XThe
- X.I number
- Xis optional (defaults to 1) and specifies the number of conditions that
- Xfollow the first line of the recipe. Conditions are complete lines that are
- Xpassed on to the internal egrep
- X.BR literally ,
- Xexcept for leading blanks.
- XIf a condition starts with an '!', the condition is inverted. If you really
- Xwant the condition to start with an '!', precede the '!' by a '\\'.
- XThese conditions are
- X.B completely
- Xcompatible to the normal
- X.BR egrep (1)
- Xregular expressions.
- X.PP
- XA special case condition is one starting with either '<' or '>', this
- Xcondition is true only if the total length of the mail is shorter,
- Xrespectively longer than the specified (in decimal) number of bytes.
- X.PP
- XAnother special case condition is one starting with a '$'. This condition
- Xwill be evaluated according to
- X.BR sh (1)
- Xsubtitution rules inside double quotes, i.e. environment variable
- Xsubstitutions take place here, prior to being interpreted as a condition.
- X.PP
- XConditions are anded; if
- X.I number
- Xis zero, then the condition is always true and no conditions are expected
- Xnext.
- X.PP
- X.I Flags
- Xcan be any of the following:
- X.Tp 0.5i
- X.B +HEAD_GREP+
- XEgrep the header (default).
- X.Tp
- X.B +BODY_GREP+
- XEgrep the body.
- X.Tp
- X.B +DISTINGUISH_CASE+
- XTell the internal egrep to distinguish between upper and lower case (defaults
- Xto ignoring case).
- X.Tp
- X.B +ALSO_NEXT_RECIPE+
- XThis recipe will depend on the last preceding recipe without the
- X`+ALSO_NEXT_RECIPE+' or `+ALSO_N_IF_SUCC+' flag. This allows you to chain
- Xactions that depend on a common condition. The number of conditions that
- Xare expected to follow default to none.
- X.Tp
- X.B +ALSO_N_IF_SUCC+
- XHas the same meaning as the `+ALSO_NEXT_RECIPE+' flag, but will depend on the
- X.I successful
- Xcompletion of the immediately preceding recipe as well.
- X.Tp
- X.B +PASS_HEAD+
- XFeed the header to the pipe (default).
- X.Tp
- X.B +PASS_BODY+
- XFeed the body to the pipe (default).
- X.Tp
- X.B +FILTER+
- XConsider the pipe as a filter (ignored if a file).
- X.Tp
- X.B +CONTINUE+
- XContinue processing rcfile even if this recipe matches (not needed when 'f'
- Xspecified).
- X.Tp
- X.B +WAIT_EXIT+
- XWait for the filter or program to finish and check its exitcode (normally
- Xignored); if the filter is unsuccessful, then the text will
- Xnot have been filtered. This flag is also recommended if you specified any
- X.I locallockfile
- Xon this recipe.
- X.Tp
- X.B +WAIT_EXIT_QUIET+
- XHas the same meaning as the `+WAIT_EXIT+' flag, but will suppress any
- X`Program failure' message.
- X.Tp
- X.B +IGNORE_WRITERR+
- XIgnore any write errors on this recipe (i.e. usually due to an early closed
- Xpipe).
- X.Ss "Local lockfile"
- X.PP
- XIf you put a second ':' on the first recipe line, then procmail will use a
- X.I locallockfile
- X(for this recipe only). You can optionally specify the locallockfile
- Xto use; if you don't however, procmail will use the destination filename
- X(or the filename following the first '>>') and will append $LOCKEXT to it.
- X.Ss "Recipe action line"
- X.PP
- XThe action line can start with the following characters:
- X.Tp
- X.B !
- XForwards to all the specified mail addresses.
- X.Tp
- X.B |
- XStarts the specified program, possibly in $SHELL if any
- Xof the characters $SHELLMETAS are found.
- X.PP
- XAnything else will be taken as a mailbox name (either a filename or a
- Xdirectory, absolute or relative to the current directory (see MAILDIR)).
- XIf it is a filename (or nonexistent), the mail will be appended to it.
- X.PP
- XIf it is a directory, the mail will be delivered to a newly created, guaranteed
- Xto be unique file named $MSGPREFIX* in the specified directory. If the
- Xdirectory name ends in "/.", then this directory is presumed to be an MH
- Xfolder; i.e. procmail will use the next number it finds available.
- X.Ss "Environment variable defaults"
- X.Tp 2.2i
- X.B "USER, HOME and SHELL"
- XYour (the recipient's) defaults
- X.Tp
- X.B SHELLMETAS
- X\&+DEFshellmetas+
- X.Tp
- X.B SHELLFLAGS
- X\&+DEFshellflags+
- X.Tp
- X.BR ORGMAIL
- X\&+SYSTEM_MBOX+
- X.Tp
- X.B MAILDIR
- X\&+DEFmaildir+
- X.Tp
- X.B DEFAULT
- X\&+DEFdefault+
- X.Tp
- X.B MSGPREFIX
- X\&+DEFmsgprefix+
- X.Tp
- X.B SENDMAIL
- X\&+DEFsendmail+
- X.Tp
- X.B LOCKEXT
- X\&+DEFlockext+
- X.Tp
- X.B LOCKFILE
- X\&+DEFdefaultlock+
- X.br
- X(after procmail closed the last rcfile)+PRESTENV++LD_ENV_FIX+
- X.Ss Environment
- X.PP
- XBefore you get lost in the multitude of environment variables, keep in mind
- Xthat all of them have reasonable defaults.
- X.Tp 1.2i
- X.B MAILDIR
- XCurrent directory while procmail is executing (that means that all paths
- Xare relative to $MAILDIR).
- X.Tp
- X.B DEFAULT
- XDefault
- X.B mailbox
- Xfile (if not told otherwise, procmail will dump mail in this mailbox).
- XProcmail will automatically use LOCKFILE=$DEFAULT$LOCKEXT prior to writing
- Xto this mailbox.
- X.Tp
- X.B MSGPREFIX
- XFilename prefix that is used when delivering to a directory (not used when
- Xdelivering to an MH directory).
- X.Tp
- X.B LOGFILE
- XAll incoming messages will be logged here with their `+FROM+' and `Subject:'
- Xlines in the header, and an additional line specifying what folder it
- Xfinally went to and how long (in bytes) the message was. This file will
- Xalso contain any error or diagnostic messages from procmail
- X(normally none :-) or any other programs started by procmail. If this file
- Xis not specified it defaults to
- X.BR +console+ .
- XYou can turn on
- X.I extended diagnostics
- Xby prepending a `+DEBUGPREFIX+' to the desired pathname.
- X.Tp
- X.B LOG
- XAnything assigned to this variable will be echoed in $LOGFILE.
- X.Tp
- X.B ORGMAIL
- XUsually the system mailbox (\fBOR\fPi\fBG\fPinal \fBMAIL\fPbox). If, for
- Xsome obscure reason (like `\fBfilesystem full\fP') the mail could not be
- Xdelivered, then this mailbox will be the last resort. If procmail
- Xfails to save the mail in here (deep, deep trouble :-), then the mail
- Xwill bounce back to the sender.
- X.Tp
- X.B LOCKFILE
- XGlobal semaphore file. If this file already exists, procmail
- Xwill wait until it has gone before proceeding, and will create it itself
- X(cleaning it up when ready, of course). If more than one
- X.I lockfile
- Xare specified, then the previous one will be removed before trying to create
- Xthe new one. The use of a global lockfile is discouraged, use locallockfiles
- X(on a per recipe basis) instead.
- X.Tp
- X.B LOCKEXT
- XDefault extension that is appended to a destination file to determine
- Xwhat local
- X.I lockfile
- Xto use (only if turned on, on a per-recipe basis).
- X.Tp
- X.B LOCKSLEEP
- XNumber of seconds procmail will sleep before retrying on a
- X.I lockfile
- X(if it already existed); if not specified, it defaults to +DEFlocksleep+
- Xseconds.
- X.Tp
- X.B LOCKTIMEOUT
- XNumber of seconds that have to have passed since a
- X.I lockfile
- Xwas last modified/created before procmail decides that this must be an
- Xerroneously leftover lockfile that can be removed by force now. If zero,
- Xthen no timeout will be used and procmail will wait forever until the
- Xlockfile is removed; if not specified, it defaults to +DEFlocktimeout+ seconds.
- XThis variable is useful to prevent indefinite hangups of
- X.BR sendmail /procmail.
- XProcmail is immune to clock skews.
- X.Tp
- X.B TIMEOUT
- XNumber of seconds that have to have passed before procmail decides that
- Xsome child it started must be hanging. The offending program will receive
- Xa TERMINATE signal from procmail, and processing of the rcfile will continue.
- XIf zero, then no timeout will be used and procmail will wait forever until the
- Xchild has terminated; if not specified, it defaults to +DEFtimeout+ seconds.
- X.Tp
- X.B HOST
- XIf this is not the
- X.I hostname
- Xof the machine, processing of the current
- X.I rcfile
- Xwill immediately cease. If other rcfiles were specified on the
- Xcommand line, processing will continue with the next one. If all rcfiles
- Xare exhausted, the program will terminate, but will not generate an error
- X(i.e. to the mailer it will seem that the mail has been delivered). Only the
- Xfirst +HOSTNAMElen+ characters of the HOST are significant.
- X.Tp
- X.B UMASK
- XThe name says it all (if it doesn't, then forget about this one :-). It
- Xis taken as an
- X.B octal
- Xnumber. If not specified, it defaults to +INIT_UMASK+.
- X.Tp
- X.B SHELLMETAS
- XIf any of the characters in SHELLMETAS appears in the line specifying
- Xa filter or program, the line will be fed to $SHELL
- Xinstead of being executed directly.
- X.Tp
- X.B SHELLFLAGS
- XAny invocation of $SHELL will be like:
- X.br
- X"$SHELL" "$SHELLFLAGS" "$*";
- X.Tp
- X.B SENDMAIL
- XIf you're not using the
- X.I forwarding
- Xfacility don't worry about this one. It specifies the program being
- Xcalled to forward any mail.
- X.br
- XIt gets invoked as: "$SENDMAIL" "$@";
- X.Tp
- X.B NORESRETRY
- XNumber of retries that are to be made if any `\fBprocess table full\fP',
- X`\fBfile table full\fP', `\fBout of memory\fP' or
- X`\fBout of swap space\fP' error should occur. If this number is negative,
- Xthen procmail will retry indefinitely; if not specified, it defaults to two
- Xtimes. The retries occur with a $SUSPEND second interval. The idea behind
- Xthis is, that if the
- X.I swap
- X.I space
- Xhas been exhausted or the
- X.I process
- X.I table
- Xis full, usually several other programs will either detect this
- Xand abort or crash 8-), and thereby freeing valuable
- X.I resources
- Xfor procmail.
- X.Tp
- X.B SUSPEND
- XNumber of seconds that procmail will pause if it has to wait for something
- Xthat is currently unavailable (memory, fork, etc.); if not specified, it will
- Xdefault to +DEFsuspend+ seconds. See also:
- X.BR LOCKSLEEP .
- X.Tp
- X.B LINEBUF
- XLength of the internal line buffers, cannot be set smaller than +MINlinebuf+.
- XAll lines read from the rcfile
- X.RI ( not
- Xthe mail itself, which can have arbitrary line lengths, or could be a binary
- Xfile for that matter) should not exceed $LINEBUF characters before and after
- Xexpansion. If not specified, it defaults to +DEFlinebuf+.
- X.Tp
- X.B DELIVERED
- XIf set (to a dummy value) procmail will pretend (to the mail agent) the mail
- Xhas been delivered. If mail cannot be delivered after meeting this
- Xassignment, the mail will be lost (i.e. it will not bounce).
- X.Sh EXAMPLES
- XLook in the
- X.BR procmailex (5)
- Xman page.
- X.Sh CAVEATS
- XIf you don't explicitly tell procmail to wait (recipe flag `+WAIT_EXIT+' or
- X`+WAIT_EXIT_QUIET+') for a program to finish, it won't wait and will terminate
- Xearly (not knowing if the program returns success). That also means that any
- Xlocallockfile on this recipe might get removed
- X.I before
- Xthe program has terminated.
- X.PP
- XContinued lines in a recipe that are to be executed are concatenated
- X.I before
- Xbeing parsed, hence
- X.I any
- Xbackslash-newline combinations in them are removed regardless.
- X.PP
- XDon't put comments on the condition lines (the regular expressions) in a recipe,
- Xthese lines are fed to the internal egrep
- X.IR literally .
- X(Except for any
- X.I leading
- Xwhitespace, `!' or `\\', it will be stripped.
- XPrecede it by a `\\' if you want it to be taken literally too.)
- X.PP
- XOn a related note, watch out for trailing whitespace on condition lines, you
- Xdon't see it, but procmail will try to match it; enabling extended diagnostics
- X(see LOGFILE) will reveal this.
- X.PP
- XWatch out for deadlocks when doing unhealthy things like forwarding mail
- Xto your own account. Deadlocks can be broken by proper use of
- X.BR LOCKTIMEOUT .
- X.PP
- XAny default values that procmail has for some environment variables will
- X.B always
- Xoverride the ones that were already defined. If you really want to
- Xoverride the defaults, you either have to put them in the
- X.B rcfile
- Xor on the command line as arguments.
- X.Sh "SEE ALSO"
- X.na
- X.BR procmail (1),
- X.BR procmailex (5),
- X.BR sh (1),
- X.BR csh (1),
- X.BR mail (1),
- X.BR binmail (1),
- X.BR uucp (1C),
- X.BR aliases (5),
- X.BR sendmail (8),
- X.BR egrep (1V),
- X.BR lockfile (1),
- X.BR formail (1)
- X.ad
- X.Sh BUGS
- XThe only substitutions of environment variables that can be handled by
- Xprocmail itself are of the type $name, ${name}, $$ and $\-; whereas $\- will
- Xbe substituted by the name of the last folder delivered to.+UPPERCASE_USERNAMES+
- X.PP
- XA line buffer of length $LINEBUF is used when processing the
- X.IR rcfile ,
- Xany expansions
- X.B have
- Xto fit within this limit; if they don't, behaviour is undefined.
- X.PP
- XIf the global lockfile has a
- X.I relative
- Xpath, and the current directory
- Xis not the same as when the global lockfile was created, then the global
- Xlockfile will not be removed if procmail exits at that point (remedy:
- Xuse
- X.I absolute
- Xpaths to specify global lockfiles).
- X.Sh MISCELLANEOUS
- XWhitespace is ignored in the rcfile, except on the
- Xlines that are fed to the internal egrep where only leading whitespace is
- Xignored; i.e. you can indent everything.
- X.PP
- XIf the regular expression starts with `\fB+TOkey+\fP' it will be substituted by
- X`\fB+TOsubstitute+\fP', which should catch all destination
- Xspecifications.
- X.Sh NOTES
- XFor
- X.I really
- Xcomplicated processing you can even consider calling
- X.B procmail
- Xrecursively.
- X.Sh AUTHOR
- XStephen R. van den Berg at RWTH-Aachen, Germany
- X.Rs
- Xberg@pool.informatik.rwth-aachen.de
- Xberg@physik.tu-muenchen.de
- X.Re
- END_OF_FILE
- if test 15197 -ne `wc -c <'procmail/man/procmailrc.man'`; then
- echo shar: \"'procmail/man/procmailrc.man'\" unpacked with wrong size!
- fi
- # end of 'procmail/man/procmailrc.man'
- fi
- if test -f 'procmail/retint.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail/retint.c'\"
- else
- echo shar: Extracting \"'procmail/retint.c'\" \(13188 characters\)
- sed "s/^X//" >'procmail/retint.c' <<'END_OF_FILE'
- X/************************************************************************
- X * Collection of routines that return an int (sort of anyway :-) *
- X * *
- X * Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands *
- X * The sources can be freely copied for non-commercial use. *
- X * #include "README" *
- X * *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic char rcsid[]="$Id: retint.c,v 2.27 1992/06/30 16:42:26 berg Rel $";
- X#endif
- X#include "config.h"
- X#include "procmail.h"
- X#include "shell.h"
- X
- Xsetdef(name,contents)const char*const name,*const contents;
- X{ strcat(strcat(strcpy((char*)(sgetcp=buf2),name),"="),contents);
- X readparse(buf,sgetc,2);sputenv(buf);
- X}
- X
- Xchar*lastexec,*backblock;
- Xlong backlen; /* length of backblock, filter recovery block */
- Xpid_t pidfilt;
- Xint pbackfd[2]; /* the emergency backpipe :-) */
- X
- Xpipthrough(line,source,len)char*line,*source;const long len;
- X{ int pinfd[2],poutfd[2];
- X rpipe(pbackfd);rpipe(pinfd); /* main pipes setup */
- X if(!(pidchild=sfork())) /* create a sending procmail */
- X { backblock=source;backlen=len;signal(SIGTERM,stermchild);
- X signal(SIGINT,stermchild);signal(SIGHUP,stermchild);
- X signal(SIGQUIT,stermchild);rclose(rc);rclose(PRDI);rclose(PRDB);
- X rpipe(poutfd);rclose(STDOUT);
- X if(!(pidfilt=sfork())) /* create the filter */
- X { rclose(PWRO);rclose(PWRB);rdup(PWRI);rclose(PWRI);getstdin(PRDO);
- X callnewprog(line);
- X }
- X rclose(PWRI);rclose(PRDO);
- X if(forkerr(pidfilt,line))
- X rclose(PWRO),stermchild();
- X if(dump(PWRO,source,len)) /* send in the text to be filtered */
- X writeerr(line),stermchild();
- X if(pwait&&waitfor(pidfilt)!=EX_OK) /* check the exitcode of the filter */
- X { if(!(pwait&2)) /* do we put it on report? */
- X progerr(line);
- X stermchild();
- X }
- X rclose(PWRB);exit(EX_OK); /* allow parent to proceed */
- X }
- X rclose(PWRI);rclose(PWRB);getstdin(PRDI);
- X if(forkerr(pidchild,procmailn))
- X return 1;
- X return 0; /* we stay behind to read back the filtered text */
- X}
- X
- Xwaitfor(pid)const pid_t pid; /* wait for a specific process */
- X{ int i;pid_t j;
- X while(pid!=(j=wait(&i))||WIFSTOPPED(i))
- X if(-1==j)
- X return -1;
- X return WIFEXITED(i)?WEXITSTATUS(i):-1;
- X}
- X
- Xgetstdin(pip)const int pip;
- X{ rclose(STDIN);rdup(pip);rclose(pip);
- X}
- X
- Xcallnewprog(newname)const char*const newname;
- X{ if(sh) /* should we start a shell? */
- X { const char*newargv[4];
- X yell(executing,newname);newargv[3]=0;newargv[2]=newname;
- X newargv[1]=tgetenv(shellflags);*newargv=tgetenv(shell);shexec(newargv);
- X }
- X {register const char*p;int argc;const char**newargv;
- X argc=1;p=newname; /* If no shell, chop up the arguments ourselves */
- X if(verbose)
- X { log(executing);log(oquote);goto no_1st_comma;
- X }
- X do /* show chopped up command line */
- X { if(verbose)
- X { log(",");
- Xno_1st_comma:
- X log(p);
- X }
- X while(*p++);
- X }
- X while(argc++,*p!=TMNATE);
- X if(verbose)
- X log(cquote);
- X newargv=malloc(argc*sizeof*newargv);p=newname;argc=0; /* alloc argv array */
- X do
- X { newargv[argc++]=p;
- X while(*p++);
- X }
- X while(*p!=TMNATE);
- X newargv[argc]=0;shexec(newargv);
- X }
- X}
- X
- Xwriteerr(line)const char*const line;
- X{ log("Error while writing to");logqnl(line);
- X}
- X
- Xforkerr(pid,a)const pid_t pid;const char*const a;
- X{ if(pid==-1)
- X { log("Failed forking");logqnl(a);return 1;
- X }
- X return 0;
- X}
- X
- Xprogerr(line)const char*const line;
- X{ log("Program failure of");logqnl(line);
- X}
- X
- Xopena(a)const char*const a;
- X{ lastfolder=cstr(lastfolder,a);yell("Opening",a);
- X#ifdef O_CREAT
- X return ropen(a,O_WRONLY|O_APPEND|O_CREAT,NORMperm);
- X#else
- X {int fd;
- X return(fd=ropen(a,O_WRONLY,0))<0?creat(a,NORMperm):fd;
- X }
- X#endif
- X}
- X
- Xyell(a,b)const char*const a,*const b; /* log if -d option set */
- X{ if(verbose)
- X log(a),logqnl(b);
- X}
- X
- Xunlock(lockp)char**const lockp;
- X{ lcking|=lck_LOCKFILE;
- X if(*lockp)
- X { yell("Unlocking",*lockp);
- X if(unlink(*lockp))
- X log("Couldn't unlock"),logqnl(*lockp);
- X if(!nextexit) /* if not inside a signal handler */
- X free(*lockp);
- X *lockp=0;
- X }
- X lcking&=~lck_LOCKFILE;
- X if(nextexit==1) /* make sure we are not inside terminate already */
- X log(newline),terminate();
- X}
- X
- Xnomemerr() /* set nextexit to prevent log from using malloc() */
- X{ nextexit=2;log("Out of memory\n");
- X if(buf2)
- X { buf[linebuf-1]=buf2[linebuf-1]='\0';log("buffer 0:");logqnl(buf);
- X log("buffer 1:");logqnl(buf2);
- X }
- X if(retval!=EX_TEMPFAIL)
- X retval=EX_OSERR;
- X terminate();
- X}
- X
- Xlogqnl(a)const char*const a;
- X{ log(oquote);log(a);log(cquote);
- X}
- X
- Xnextrcfile() /* next rcfile specified on the command line */
- X{ const char*p;
- X while(p= *gargv)
- X { gargv++;
- X if(!strchr(p,'='))
- X { rcfile=p;return 1;
- X }
- X }
- X return 0;
- X}
- X
- Xrclose(fd)const int fd; /* a SysV secure close (signal immune) */
- X{ int i;
- X while((i=close(fd))&&errno==EINTR);
- X return i;
- X}
- X
- Xrwrite(fd,a,len)const int fd,len;void*const a; /* a SysV secure write */
- X{ int i;
- X while(0>(i=write(fd,a,(size_t)len))&&errno==EINTR);
- X return i;
- X}
- X
- Xrread(fd,a,len)const int fd,len;void*const a; /* a SysV secure read */
- X{ int i;
- X while(0>(i=read(fd,a,(size_t)len))&&errno==EINTR);
- X return i;
- X}
- X
- Xropen(name,mode,mask)const char*const name;const int mode;const mode_t mask;
- X{ int i,r; /* a SysV secure open */
- X for(r=noresretry,lcking|=lck_FILDES;0>(i=open(name,mode,mask));)
- X if(errno!=EINTR&&!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
- X break; /* survives a temporary "file table full" condition */
- X lcking&=~lck_FILDES;return i;
- X}
- X
- Xrdup(p)const int p;
- X{ int i,r; /* catch "file table full" */
- X for(r=noresretry,lcking|=lck_FILDES;0>(i=dup(p));)
- X if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
- X break;
- X lcking&=~lck_FILDES;return i;
- X}
- X
- Xrpipe(fd)int fd[2];
- X{ int i,r; /* catch "file table full" */
- X for(r=noresretry,lcking|=lck_FILDES;0>(i=pipe(fd));)
- X if(!((errno==EMFILE||errno==ENFILE)&&(r<0||r--)))
- X { *fd=fd[1]= -1;break;
- X }
- X lcking&=~lck_FILDES;return i;
- X}
- X
- Xlockit(name,lockp)char*name;const char**const lockp;
- X{ int i,permanent=2,triedforce=0;struct stat stbuf;time_t t;
- X if(*lockp)
- X { if(!strcmp(name,*lockp)) /* compare the previous lockfile to this one */
- X return; /* they're equal, save yourself some effort */
- X unlock(lockp); /* unlock any previous lockfile FIRST */
- X } /* to prevent deadlocks (I hate deadlocks) */
- X if(!*name)
- X return;
- X name=tstrdup(name); /* allocate now, so we won't hang on memory *and* lock */
- X for(lcking|=lck_LOCKFILE;;)
- X { yell("Locking",name); /* in order to cater for clock skew: */
- X if(!NFSxopen(name,LOCKperm,&t)) /* get time t from filesystem */
- X { *lockp=name;break; /* lock acquired, hurray! */
- X }
- X switch(errno)
- X { case EEXIST: /* check if it's time for a lock override */
- X if(!lstat(name,&stbuf)&&stbuf.st_size<=MAX_LOCK_SIZE&&locktimeout
- X &&!lstat(name,&stbuf)&&locktimeout<t-stbuf.st_mtime)
- X /*
- X * stat() till unlink() should be atomic, but can't guarantee that
- X */
- X { if(triedforce) /* already tried, not trying */
- X goto faillock; /* again */
- X if(S_ISDIR(stbuf.st_mode)||unlink(name))
- X triedforce=1,log("Forced unlock denied on"),logqnl(name);
- X else
- X { log("Forcing lock on");logqnl(name);suspend();goto ce;
- X }
- X }
- X else
- X triedforce=0; /* legitimate iteration, clear flag */
- X break;
- X#ifdef ENAMETOOLONG
- X case ENAMETOOLONG: /* maybe filename too long, shorten and retry */
- X if(0<(i=strlen(name)-1)&&!strchr(dirsep,name[i-1]))
- X { log("Truncating");logqnl(name);log(" and retrying lock\n");
- X name[i]='\0';continue;
- X }
- X#endif
- X default:
- Xfaillock: log("Lock failure on");logqnl(name);goto term;
- X case ENOENT:case ENOTDIR:case EIO:case EACCES:
- X if(!--permanent)
- X goto faillock;
- X case ENOSPC:;
- X#ifdef EDQUOT
- X case EDQUOT:;
- X#endif
- X }
- X sleep((unsigned)locksleep);
- Xce: if(nextexit)
- Xterm: { free(name);break; /* drop the preallocated buffer */
- X }
- X }
- X lcking&=~lck_LOCKFILE;
- X if(nextexit)
- X { log(whilstwfor);log("lockfile");logqnl(name);terminate();
- X }
- X}
- X
- Xlcllock() /* lock a local file (if need be) */
- X{ if(locknext)
- X if(tolock)
- X lockit(tolock,&loclock);
- X else
- X lockit(strcat(buf2,tgetenv(lockext)),&loclock);
- X}
- X
- Xsterminate()
- X{ static const char*const msg[]={"memory","fork", /* crosscheck with */
- X "a file descriptor","a kernel lock"}; /* lck_ defs in procmail.h */
- X ignoreterm();
- X if(pidchild>0) /* don't kill what is not ours, we might be root */
- X kill(pidchild,SIGTERM);
- X if(!nextexit)
- X { nextexit=1;log("Terminating prematurely");
- X if(!(lcking&lck_LOCKFILE))
- X { register unsigned i,j;
- X if(i=(lcking&~(lck_ALLOCLIB|lck_LOCKFILE))>>1)
- X { log(whilstwfor);
- X for(j=0;(i>>=1)&1;++j);
- X log(msg[j]);
- X }
- X log(newline);terminate();
- X }
- X }
- X}
- X
- Xterminate()
- X{ ignoreterm();
- X if(retvl2!=EX_OK)
- X fakedelivery=0,retval=retvl2;
- X if(getpid()==thepid)
- X { if(retval!=EX_OK)
- X { lastfolder=fakedelivery?"**Lost**": /* don't free() here */
- X retval==EX_TEMPFAIL?"**Requeued**":"**Bounced**";
- X }
- X logabstract();nextexit=2;unlock(&loclock);unlock(&globlock);fdunlock();
- X }
- X exit(fakedelivery==2?EX_OK:retval);
- X}
- X
- Xignoreterm()
- X{ signal(SIGTERM,SIG_IGN);signal(SIGHUP,SIG_IGN);signal(SIGINT,SIG_IGN);
- X signal(SIGQUIT,SIG_IGN);
- X}
- X
- Xsuspend()
- X{ long t;
- X sleep((unsigned)suspendv);
- X if(alrmtime)
- X if((t=alrmtime-time((time_t*)0))<=1) /* if less than 1s timeout */
- X ftimeout(); /* activate it by hand now */
- X else /* set it manually again, to avoid problems with */
- X alarm((unsigned)t); /* badly implemented sleep library functions */
- X}
- X
- Xinittmout(progname)const char*const progname;
- X{ lastexec=cstr(lastexec,progname);
- X alrmtime=timeoutv?time((time_t*)0)+(unsigned)timeoutv:0;
- X alarm((unsigned)timeoutv);
- X}
- X
- Xskipspace()
- X{ while(testb(' ')||testb('\t'));
- X}
- X
- Xsgetc() /* a fake fgetc for a string */
- X{ return *sgetcp?*(uchar*)sgetcp++:EOF;
- X}
- X
- Xskipped(x)const char*const x;
- X{ log("Skipped");logqnl(x);
- X}
- X
- Xconcatenate(old)char*const old;
- X{ register char*p=old;
- X while(*p!=TMNATE) /* concatenate all other arguments */
- X { while(*p++);
- X p[-1]=' ';
- X }
- X *p=p[-1]='\0';return*old;
- X}
- X
- Xdetab(p)char*p;
- X{ while(p=strchr(p,'\t'))
- X *p=' '; /* take out all tabs */
- X}
- X
- Xstatic uchar rcbuf[STDBUF],*rcbufp,*rcbufend; /* buffers for custom stdio */
- Xstatic ungetb; /* pushed back char */
- X
- Xbopen(name)const char*const name; /* my fopen */
- X{ rcbufp=rcbufend=0;ungetb= -1;yell("Rcfile:",name);
- X return rc=ropen(name,O_RDONLY,0);
- X}
- X
- Xgetbl(p)char*p; /* my gets */
- X{ int i;char*q;
- X for(q=p;;)
- X { switch(i=getb())
- X { case '\n':case EOF:
- X *p='\0';return p!=q; /* did we read anything at all? */
- X }
- X *p++=i;
- X }
- X}
- X
- Xgetb() /* my fgetc */
- X{ if(ungetb>=0) /* anything pushed back? */
- X { int i;
- X i=ungetb;ungetb= -1;return i;
- X }
- X if(rcbufp==rcbufend)
- X rcbufend=rcbuf+rread(rc,rcbufp=rcbuf,STDBUF); /* refill */
- X return rcbufp<rcbufend?*rcbufp++:EOF;
- X}
- X
- Xtestb(x)const int x; /* fgetc that only succeeds if it matches */
- X{ int i;
- X if((i=getb())==x)
- X return 1;
- X ungetb=i;return 0;
- X}
- X
- Xalphanum(c)const int c;
- X{ return c>='0'&&c<='9'||c>='a'&&c<='z'||c>='A'&&c<='Z'||c=='_';
- X}
- X /* open file or new file in directory */
- Xdeliver(boxname)char*const boxname;
- X{ struct stat stbuf;
- X strcpy(buf,boxname); /* boxname can be found back in buf */
- X return stat(buf,&stbuf)||!S_ISDIR(stbuf.st_mode)?
- X (tofolder=1,opena(buf)):dirmail();
- X}
- X
- X#ifdef KERNEL_LOCKS
- Xstatic oldfdlock; /* the fd we locked last */
- X#ifdef F_SETLKW
- Xstatic struct flock flck; /* why can't it be a local variable? */
- X
- Xfdlock(fd) /* the POSIX-fcntl() lock */
- X{ flck.l_type=F_WRLCK;flck.l_whence=SEEK_SET;flck.l_len=0;
- X flck.l_start=tell(fd);lcking|=lck_KERNELL;
- X fd=fcntl(oldfdlock=fd,F_SETLKW,&flck);lcking&=~lck_KERNELL;return fd;
- X}
- X
- Xfdunlock()
- X{ flck.l_type=F_UNLCK;return fcntl(oldfdlock,F_SETLK,&flck);
- X}
- X#else /* F_SETLKW */
- X#ifdef F_LOCK
- Xstatic long oldlockoffset;
- X
- Xfdlock(fd) /* the SysV-lockf() */
- X{ oldlockoffset=tell(fd);lcking|=lck_KERNELL;fd=lockf(oldfdlock=fd,F_LOCK,0L);
- X lcking&=~lck_KERNELL;return fd;
- X}
- X
- Xfdunlock()
- X{ lseek(oldfdlock,oldlockoffset,SEEK_SET);return lockf(oldfdlock,F_ULOCK,0L);
- X}
- X#else /* F_LOCK */
- X#ifdef LOCK_EX
- Xfdlock(fd) /* the BSD-flock() */
- X{ lcking|=lck_KERNELL;fd=flock(oldfdlock=fd,LOCK_EX);lcking&=~lck_KERNELL;
- X return fd;
- X}
- X
- Xfdunlock()
- X{ return flock(oldfdlock,LOCK_UN);
- X}
- X#endif /* LOCK_EX */
- X#endif /* F_LOCK */
- X#endif /* F_SETLKW */
- X#endif /* KERNEL_LOCKS */
- X /* an NFS secure exclusive file open */
- XNFSxopen(name,mode,tim)char*name;const mode_t mode;time_t*const tim;
- X{ char*p;int j= -2,i;struct stat stbuf;
- X i=lastdirsep(name)-name;strncpy(p=malloc(i+UNIQnamelen),name,i);
- X if(unique(p,p+i,mode)) /* try and rename the unique filename */
- X { stat(p,&stbuf);
- X if(tim)
- X *tim=stbuf.st_mtime; /* return the filesystem time to the caller */
- X j=myrename(p,name);
- X }
- X free(p);return j;
- X}
- END_OF_FILE
- if test 13188 -ne `wc -c <'procmail/retint.c'`; then
- echo shar: \"'procmail/retint.c'\" unpacked with wrong size!
- fi
- # end of 'procmail/retint.c'
- fi
- echo shar: End of archive 4 \(of 5\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Sincerely, berg@pool.informatik.rwth-aachen.de
- Stephen R. van den Berg (AKA BuGless). berg@physik.tu-muenchen.de
-
- He did a quarter of the work in *half* the time!
-
- exit 0 # Just in case...
-