home *** CD-ROM | disk | FTP | other *** search
- From: berg@marvin.e17.physik.tu-muenchen.de (Stephen R. van den Berg)
- Newsgroups: comp.sources.misc
- Subject: v17i031: procmail - mail processing package, Part01/02
- Message-ID: <1991Mar2.004704.16888@sparky.IMD.Sterling.COM>
- Date: 2 Mar 91 00:47:04 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: dcfc8213 ea1ac849 f50ab45d 529eca40
- X-Checksum-Snefru: 4e1f6733 2be9cdad 47f71b72 337a3d19
-
- Submitted-by: Stephen R. van den Berg <berg@marvin.e17.physik.tu-muenchen.de>
- Posting-number: Volume 17, Issue 31
- Archive-name: procmail/part01
- Supersedes: procmail: Volume 16, Issue 103
-
- The Procmail mail processing package. (v1.30 1991-01-03)
-
- Can be used to create mail-servers, mailing lists, sort your incoming mail
- (real convenient when subscribing to one or more mailing lists),
- preprocess your mail, or selectively forward certain incoming mail
- automatically to someone, etc...
-
- Procmail was designed to deliver the mail under the worst conditions
- (file system full, out of swap space (**NEW**), process table full,
- missing support files, unavailable executables; it all doesn't matter).
- Should (in the unlikely event) procmail be unable to deliver your mail
- somewhere, the mail will bounce back to the sender.
-
- Advantages: This package is small (boils down to one executable)
- and therefore robust, but still doesn't lack any mayor
- features you would want.
-
- Cheers,
- Stephen R. van den Berg at RWTH-Aachen, Germany.
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is procmail, a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 03/01/1991 11:56 UTC by berg@marvin.e17.physik.tu-muenchen.de
- # Source directory /tmp_mnt/tmp/.am/baghira/berg
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 2428 -rw-r--r-- procmail/HISTORY
- # 729 -rw-r--r-- procmail/Makefile
- # 999 -rw-r--r-- procmail/Manifest
- # 3420 -rw-r--r-- procmail/README
- # 2474 -rw-r--r-- procmail/lockfile.1
- # 1908 -rw-r--r-- procmail/lockfile.c
- # 15169 -rw-r--r-- procmail/procmail.1
- # 9798 -rw-r--r-- procmail/procmail.c
- # 3914 -rw-r--r-- procmail/nonint.c
- # 1929 -rw-r--r-- procmail/config.h
- # 279 -rw-r--r-- procmail/sysexits.h
- # 1158 -rw-r--r-- procmail/procmail.h
- # 130 -rw-r--r-- procmail/shell.h
- # 9549 -rw-r--r-- procmail/retint.c
- # 29 -rw-r--r-- procmail/examples/forward
- # 381 -rw-r--r-- procmail/examples/1rmail
- # 1587 -rw-r--r-- procmail/examples/2procmailrc
- # 1255 -rw-r--r-- procmail/examples/3procmailrc
- # 373 -rw-r--r-- procmail/examples/2rmail
- # 738 -rw-r--r-- procmail/examples/3rmail
- # 638 -rw-r--r-- procmail/examples/1procmailrc
- # 589 -rw-r--r-- procmail/includes.h
- #
- # ============= procmail/HISTORY ==============
- if test ! -d 'procmail'; then
- echo 'x - creating directory procmail'
- mkdir 'procmail'
- fi
- if test -f 'procmail/HISTORY' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/HISTORY (File already exists)'
- else
- echo 'x - extracting procmail/HISTORY (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/HISTORY' &&
- X1990-12-07: v1.00
- X First release (after 2 weeks of coding and testing)
- X1990-12-12: v1.01
- X Added fsync to procmail.c
- X Removed longjmp in lockfile.c out of the signal handler
- X (not portable, so I'm told)
- X1991-02-04: v1.02
- X Changes to procmail.c:
- X Added physical-write-error check
- X Altered egrep invocation (left out the -s flag, not supported
- X on all machines; this didn't change functionality though)
- X Avoided the 'dirty' allocation of one more byte than needed by
- X rewriting the bogus_header_replace routine
- X Made the finding bogus headers more robust
- X Added sysV lines in Makefile
- X1991-02-13: v1.10
- X Changes to procmail.c:
- X Fixed slight error in parsing the recipe when 'h' and 'b' where
- X specified
- X Started using the official exit codes
- X Made sure that the procmail is not influenced by falsely
- X set environment variables like LOCKSLEEP
- X1991-02-21: v1.20
- X Changes to procmail.c:
- X Removed library conflict on some machines for 'locking'
- X Added uname call as alternative for gethostname
- X Changed name of SHELLMETA to SHELLMETAS (for conformance
- X with dmake)
- X Added LOCKTIMEOUT to learn procmail to decide wether or not
- X a certain lockfile is still 'valid'
- X Added the function sputenv (smart-putenv) to avoid library
- X problems and to finally have a putenv that works the
- X way it was supposed to work all along (you wouldn't believe
- X how brain damaged this library function is :-)
- X Changed environment variable assignment to skip trailing blanks
- X only, and allow intermediate blanks (parsing like make)
- X1991-02-22: v1.21
- X Split up procmail.c in procmail.c, nonint.c, retint.c, procmail.h,
- X config.h, sysexits.h, shell.h
- X Changes to lockfile.c:
- X Added -l option (locktimeout)
- X Moved virtually all configuration stuff from Makefile into
- X config.h
- X Added -v option to procmail
- X1991-03-01: v1.30
- X Added out of memory/swap space immunity (NOMEMRETRY)
- X Made forced terminations of procmail more reliable and verbose
- X (previously, procmail would display erroneous error messages
- X if an attempt was made to kill procmail more than once in
- X rapid succession)
- X Fixed up man pages and comments
- X Included more example files
- X Made sure that variable substitution works in locallockfile-
- X specifications too
- SHAR_EOF
- chmod 0644 procmail/HISTORY ||
- echo 'restore of procmail/HISTORY failed'
- Wc_c="`wc -c < 'procmail/HISTORY'`"
- test 2428 -eq "$Wc_c" ||
- echo 'procmail/HISTORY: original size 2428, current size' "$Wc_c"
- fi
- # ============= procmail/Makefile ==============
- if test -f 'procmail/Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/Makefile (File already exists)'
- else
- echo 'x - extracting procmail/Makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/Makefile' &&
- X# change BASENAME to your home directory if need be
- XBASENAME = /global
- X
- XBINDIR = ${BASENAME}/bin
- XMANDIR = ${BASENAME}/man/man1
- X
- XOCFLAGS = -O
- XOLDFLAGS = -s
- X
- X# Uncomment appropiately (for sysV and the like):
- XCFLAGS = ${OCFLAGS} #-DSYSV
- XLDFLAGS = ${OLDFLAGS} #-lbsd
- X
- XCC = cc
- XINSTALL= mv
- XRM= rm -f
- X
- XOBJ=procmail.o nonint.o retint.o
- X
- Xall: procmail lockfile
- X
- Xprocmail: ${OBJ}
- X ${CC} ${CFLAGS} -o procmail ${OBJ} ${LDFLAGS}
- X
- Xlockfile: lockfile.o
- X ${CC} ${CFLAGS} -o lockfile lockfile.o ${LDFLAGS}
- X
- X.c.o:
- X ${CC} ${CFLAGS} -c $*.c
- X
- Xinstall: all
- X chmod 755 procmail lockfile
- X ${INSTALL} procmail lockfile ${BINDIR}
- X chmod 644 procmail.1 lockfile.1
- X cp procmail.1 lockfile.1 ${MANDIR}
- X
- Xclean:
- X ${RM} ${OBJ} lockfile.o procmail lockfile
- SHAR_EOF
- chmod 0644 procmail/Makefile ||
- echo 'restore of procmail/Makefile failed'
- Wc_c="`wc -c < 'procmail/Makefile'`"
- test 729 -eq "$Wc_c" ||
- echo 'procmail/Makefile: original size 729, current size' "$Wc_c"
- fi
- # ============= procmail/Manifest ==============
- if test -f 'procmail/Manifest' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/Manifest (File already exists)'
- else
- echo 'x - extracting procmail/Manifest (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/Manifest' &&
- XMakefile We all know what that is.
- XREADME Important, read it.
- XHISTORY Recent and ancient changes (or bugs) documented.
- Xlockfile.1 Man page for lockfile.
- Xlockfile.c You guessed it.
- XManifest Right again.
- Xprocmail.1 Yes, the man page for procmail (writing man pages gobbles up
- X sooo much time, here you can see why :-).
- Xprocmail.c main program for procmail.
- Xnonint.c Collection of routines that don't return ints.
- Xretint.c Collection of routines that return ints.
- Xprocmail.h Include file with all declarations.
- X
- Xincludes.h System include files are all referenced here.
- Xconfig.h The file to edit if you want to change, yes, the configuration.
- X
- Xshell.h Defines a few 'shell' macros for malloc and the like.
- Xsysexits.h Standard exit codes.
- Xexamples/?procmailrc
- X Sample .procmailrc files.
- Xexamples/?rmail
- X Sample shell scripts that demonstrate how to use
- X lockfiles while reading the mail (to ensure mail integrity
- X as soon as you exit the mail program).
- Xexamples/forward
- X A sample .forward file.
- SHAR_EOF
- chmod 0644 procmail/Manifest ||
- echo 'restore of procmail/Manifest failed'
- Wc_c="`wc -c < 'procmail/Manifest'`"
- test 999 -eq "$Wc_c" ||
- echo 'procmail/Manifest: original size 999, current size' "$Wc_c"
- fi
- # ============= procmail/README ==============
- if test -f 'procmail/README' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/README (File already exists)'
- else
- echo 'x - extracting procmail/README (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/README' &&
- XSome legal stuff:
- X
- XUse this software package at your own risk. The programmer can not
- Xbe held liable for any incurred damages due to the use of this software.
- X
- XYou are encouraged to distribute this package freely. This package is
- Xhowever not to be not sold (minor transfer costs excepted) or included in
- Xany commercially sold software package (if you want to do this anyway,
- Xcontact me (address below), and we'll work something out).
- X
- XIf you distribute it, please leave the package in tact. If you have some
- Ximportant changes that might be usefull to the rest of the world, contact
- Xme instead.
- X
- X----------------------
- X
- XThe Procmail mail processing package. (v1.30 1991-01-03)
- X
- XCan be used to create mail-servers, mailing lists, sort your incoming mail
- X(real convenient when subscribing to one or more mailing lists),
- Xpreprocess your mail, or selectively forward certain incoming mail
- Xautomatically to someone.
- X
- XTo install it, edit config.h (!) and Makefile accordingly (if it doesn't
- Xcompile at first, check if some extra header files (in includes.h) should
- Xbe included (or left out) in order to make any used types/defines/declarations
- Xfor the library compatible).
- X
- XBTW, the warnings you get about 'loop not entered at top': they're normal :-).
- XSome older compilers could complain about ambiguous assignments, if they
- Xassume normal assigns, you're safe.
- X
- XIf you run procmail by hand and pipe in some sample mail, then make
- Xsure that if you kill procmail, you use "kill pid" and NOT "kill -9 pid".
- XShould procmail seem to hang, check if the $LOCKFILE is still present.
- XIf you kill procmail with "kill pid" it will clean up the $LOCKFILE
- Xitself.
- X
- XThough be sure to skim through config.h and in particular check out
- Xthe t_buf declaration.
- X
- XEvery user that wants to use procmail should have a .forward and a
- X.procmailrc file in his HOME directory. For starters, you can look
- Xat the supplied example files in "examples".
- X(BTW, be sure to make .forward *world* readable).
- X
- XFor more info about the program, see the man page.
- X
- X----------------------
- X
- XAlthough I can't guarantee that the procmail (or lockfile) program
- Xwill perform as required, I must say that I made the utmost effort
- Xto make procmail as robust as any program can be.
- X
- XProcmail was designed to deliver the mail under the worst conditions
- X(file system full, out of swap space, process table full,
- Xmissing support files, unavailable executables; it all doesn't matter).
- XShould (in the unlikely event) procmail be unable to deliver your mail
- Xsomewhere, the mail will bounce back to the sender.
- X
- XHowever, as with any program, bugs can not be completely ruled out.
- XI tested the program extensively, and believe it should be relatively
- Xbug free (no known bug at the time). Should, however, anyone
- Xfind any bugs (highly unlikely :-), I would be pleased (well, sort of :-)
- Xto hear about it. Please send me the patches or bug report.
- XI'll look at them and will try to fix it in a future release.
- X(BTW, if you should find any spelling or grammar errors in these files,
- Xit's not priority one, but if you were sending me mail anyway, I don't
- Xmind if you point them out to me; I like correct English just as much
- Xas you do).
- X
- XCheers,
- X Stephen R. van den Berg at RWTH-Aachen, Germany.
- X
- XInternet E-mail: berg@marvin.e17.physik.tu-muenchen.de
- Xor if the above bounces: berg@cip-s01.informatik.rwth-aachen.de
- X
- XOr: P.O.Box 21074
- X 6369 ZG Simpelveld
- X The Netherlands
- SHAR_EOF
- chmod 0644 procmail/README ||
- echo 'restore of procmail/README failed'
- Wc_c="`wc -c < 'procmail/README'`"
- test 3420 -eq "$Wc_c" ||
- echo 'procmail/README: original size 3420, current size' "$Wc_c"
- fi
- # ============= procmail/lockfile.1 ==============
- if test -f 'procmail/lockfile.1' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/lockfile.1 (File already exists)'
- else
- echo 'x - extracting procmail/lockfile.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/lockfile.1' &&
- X.\" @(#)lockfile.1 1.29 91/03/01 SMI;
- X.de Sh
- X.br
- X.ne 6
- X.SH \\$1
- X..
- X.de Ss
- X.br
- X.ne 6
- X.SS \\$1
- X..
- X.de Tp
- X.br
- X.ne 6
- X.TP \\$1
- X..
- X.TH LOCKFILE 1 "1 March 1991"
- X.SH NAME
- Xlockfile \- conditional semaphore-file creator
- X.SH SYNOPSIS
- X.B lockfile
- X.RI [ " \fB\-\fPsleeptime " ]
- X.RI [ " \fB\-r\fPretries " ]
- X.RB [ " \-! ]
- X.if n .ti +0.5i
- X.RI [ " \fB\-l\fPlocktimeout " ]
- X.I filename
- X\&.\|.\|.
- X.Sh "DESCRIPTION"
- X.B lockfile
- Xcan be used to create one or more
- X.I semaphore
- X.IR files .
- XIf
- X.B lockfile
- Xcan't create all the specified files (in the specified order), it waits
- X.I sleeptime
- X(defaults to 8) seconds and retries the last file that didn't succeed.
- XYou can specify the number of
- X.I retries
- Xto do until failure is returned.
- XIf the number of
- X.I retries
- Xis 0 (default)
- X.B lockfile
- Xwill retry forever.
- X.LP
- XIf the number of
- X.I retries
- Xexpires before all files have been created,
- X.B lockfile
- Xreturns failure and removes all the files it created up till that point.
- X.LP
- XThe return value of
- X.B lockfile
- Xcan be easily inverted by specifying
- X.B \-!
- Xas an argument (handy in shell scripts).
- X.LP
- XAll flags can be specified anywhere on the command line, they will be
- Xprocessed when encountered. The command line is simply parsed from
- Xleft to right.
- X.LP
- XAll files created by
- X.B lockfile
- Xwill have access permission 0, and therefore will have to be removed
- Xwith
- X.B rm
- X.BR \-f .
- X.LP
- XIf you specify a
- X.I locktimeout
- Xthen a
- X.B lockfile
- Xwill be removed by force after
- X.I locktimeout
- Xseconds have passed since the
- X.B lockfile
- Xwas last modified/created.
- X.Sh "SEE ALSO"
- X.LP
- X.BR rm (1),
- X.BR mail (1),
- X.BR binmail (1),
- X.BR sendmail (8),
- X.BR procmail (1)
- X.Sh "DIAGNOSTICS"
- X.Tp 23
- XForcing lock on "x"
- Xspecified
- X.B lockfile
- Xis going to be removed by force because of a timeout (compare
- X.BR LOCKTIMEOUT
- Xin
- X.BR procmail (1))
- X.Sh "BUGS & SPECIAL FEATURES"
- X.LP
- X.B lockfile
- Xis only a simple program and can't process concatenated options.
- X.LP
- XMultiple
- X.B \-!
- Xflags will not toggle the return status.
- X.Sh "NOTES"
- X.LP
- XSince flags can occur anywhere on the command line, any filename starting
- Xwith an '-' has to be preceded by another '-'.
- X.LP
- XThe number of
- X.I retries
- Xis global. That is, it is not reset when a new file is being created.
- XIt can, however, be reset by specifying
- X.RI \-r newretries
- Xafter every file on the command line.
- X.Sh "AUTHOR"
- X.LP
- XStephen R. van den Berg at RWTH-Aachen, Germany
- X.RS
- Xberg@marvin.e17.physik.tu-muenchen.de (preferred)
- X.br
- Xberg@cip-s01.informatik.rwth-aachen.de (alternative)
- X.RE
- SHAR_EOF
- chmod 0644 procmail/lockfile.1 ||
- echo 'restore of procmail/lockfile.1 failed'
- Wc_c="`wc -c < 'procmail/lockfile.1'`"
- test 2474 -eq "$Wc_c" ||
- echo 'procmail/lockfile.1: original size 2474, current size' "$Wc_c"
- fi
- # ============= procmail/lockfile.c ==============
- if test -f 'procmail/lockfile.c' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/lockfile.c (File already exists)'
- else
- echo 'x - extracting procmail/lockfile.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/lockfile.c' &&
- X/************************************************************************
- X * lockfile.c a conditional semaphore-file creator *
- X * *
- X * Version 1.30 1991-01-03 *
- X * Is relatively bug free. *
- X * *
- X * Created by S.R.van den Berg, The Netherlands *
- X * This file can be freely copied for any use. *
- X * *
- X * If you have had to make major changes in order to get it *
- X * running on a different machine, please send me the patches. *
- X * That way I might include them in a future version. *
- X ************************************************************************/
- X#include "config.h" /* I know, a bit overkill, need NO_ANSI_PROT */
- X#include "includes.h"
- X
- Xint exitflag;
- X
- Xvoid failure(){
- X exitflag=1;}
- X
- Xmain(argc,argv)char*argv[];{int sleepsec,retries,i,invert,force;char**p,*cp;
- X sleepsec=8;force=retries=invert=0;
- X if(argc<2){
- X putse("Usage: lockfile [-nnn] [-rnnn] [-!] [-lnnn] file ...\n");return 2;}
- Xagain:
- X p=argv+1;signal(SIGHUP,failure);signal(SIGINT,failure);
- X signal(SIGQUIT,failure);signal(SIGTERM,failure);
- X do
- X if(*(cp=*p)=='-')
- X switch(cp[1]){
- X case'!':invert=1;break;
- X case'r':retries=strtol(cp+2,NULL,10);break;
- X case'l':force=strtol(cp+2,NULL,10);break;
- X case'-':cp++;goto filename;
- X default:
- X if(sleepsec>=0)
- X sleepsec=strtol(cp+1,NULL,10);}
- X else
- Xfilename:
- X if(sleepsec<0)
- X unlink(cp);
- X else{
- X while(0>(i=open(cp,O_WRONLY|O_CREAT|O_EXCL|O_SYNC,0))){
- X struct stat buf;
- X if(exitflag||retries==1){
- X sleepsec=-1;*p=0;goto again;}
- X if(force&&!stat(cp,&buf)&&force<time((time_t*)0)-buf.st_mtime){
- X putse("Forcing lock on \"");putse(cp);putse("\"\n");
- X unlink(cp);}
- X sleep(sleepsec);
- X if(retries)
- X retries--;}
- X close(i);}
- X while(*++p);
- Xreturn invert^(sleepsec<0);}
- X
- X#define STDERR 2
- X
- Xputse(a)char*a;{char*b;
- X b=a-1;
- X while(*++b);
- X write(STDERR,a,b-a);}
- SHAR_EOF
- chmod 0644 procmail/lockfile.c ||
- echo 'restore of procmail/lockfile.c failed'
- Wc_c="`wc -c < 'procmail/lockfile.c'`"
- test 1908 -eq "$Wc_c" ||
- echo 'procmail/lockfile.c: original size 1908, current size' "$Wc_c"
- fi
- # ============= procmail/procmail.1 ==============
- if test -f 'procmail/procmail.1' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/procmail.1 (File already exists)'
- else
- echo 'x - extracting procmail/procmail.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/procmail.1' &&
- X.\" @(#)procmail.1 1.29 91/03/01 SMI;
- X.de Sh
- X.br
- X.ne 6
- X.SH \\$1
- X..
- X.de Ss
- X.br
- X.ne 6
- X.SS \\$1
- X..
- X.de Tp
- X.br
- X.ne 6
- X.TP \\$1
- X..
- X.TH PROCMAIL 1 "1 March 1991"
- X.SH NAME
- Xprocmail \- autonomous mail processor
- X.SH SYNOPSIS
- X.B procmail
- X.RB [ " \-v " ]
- X.RI [ " parameter\fB=\fPvalue " | " rcfile " ]
- X\&.\|.\|.
- X.Sh "DESCRIPTION"
- X.LP
- XFor a quick start, see
- X.B NOTES
- Xat the end.
- X.LP
- X.B procmail
- Xfirst sets some environment variables to default values, then, if no
- Xarguments are specified, it reads the mail message from stdin until an
- XEOF, separates
- Xthe body from the header and starts to look for a file named
- X.B .procmailrc
- Xin your home directory.
- X.LP
- X.Ss "Defaults"
- X.Tp 22
- X.B "USER, HOME and SHELL"
- XYour (the recipient's) defaults
- X.Tp
- X.B SHELLMETAS
- X"'`{}()[]*?|<>~;!\\
- X.Tp
- X.B SHELLFLAGS
- X-c
- X.Tp
- X.B MAILDIR
- X$HOME
- X.Tp
- X.BR DEFAULT
- X$MAILDIR/.mailbox
- X.Tp
- X.B ORGMAIL
- X/var/spool/mail/$USER
- X.Tp
- X.B GREP
- X/usr/bin/egrep
- X.Tp
- X.B SENDMAIL
- X/usr/lib/sendmail
- X.Tp
- X.B LOCKEXT
- X\&.lock
- X.Tp
- X.B LOCKSLEEP
- X8
- X.Tp
- X.B LOCKTIMEOUT
- X3600
- X.Tp
- X.B NOMEMRETRY
- X2
- X.Ss "Environment"
- X.Tp 12
- X.B MAILDIR
- XDefault 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 file)
- X.Tp
- X.B LOGFILE
- XAll incoming messages will be logged here with their 'From' and 'Subject'
- Xlines in the header. This file will also contain any error or diagnostic
- Xmessages from procmail.
- X(Normally none :-). If this file is not specified it defaults to
- X.BR /dev/null .
- 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 file 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.
- 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).
- 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. This variable is usefull to prevent indefinite
- Xhangups of
- X.BR sendmail /procmail.
- 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).
- 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 077.
- X.Tp
- X.B GREP
- XThe program that gets called for parsing regular expressions.
- X.br
- XIt is called as: $GREP -e "$*" [-i];
- 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 NOMEMRETRY
- XNumber of retries that are to be made if any "\fBout of memory\fP" or
- X"\fBout of swap space\fP" error should occur. If this number is negative,
- Xthen procmail will retry indefinitely. The retries occur with a 16
- Xsecond interval. The idea behind this is, that if the
- X.I swap
- X.I space
- Xhas been exhausted, usually several other programs will either detect this
- Xand abort or crash 8-), and thereby freeing valuable swap space for procmail.
- X.Sh "OPTIONS"
- X.LP
- XIf you specify the
- X.B \-v
- Xoption as the first argument, all
- X.B procmail
- Xdoes is print the version number and exit.
- X.Sh "ARGUMENTS"
- X.LP
- 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
- X.I first
- Xrcfile is parsed.
- X.LP
- XAny other arguments are presumed to be rcfiles; procmail
- Xwill start with the first one it finds on the command line. The following
- Xones will only be parsed if the preceding ones have a not matching
- XHOST-directive entry.
- X.LP
- 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 "RCFILE FORMAT"
- X.LP
- XEnvironment 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 default directory whenever you
- Xwant by specifying a new
- X.BR MAILDIR ,
- Xswitch lockfiles by specifying a new
- X.B LOCKFILE
- X(usually one won't need this particular application though), change
- Xthe umask at any time, etc., the possibilities are endless :-).
- X.LP
- XValues being assigned to environment variables (in the rcfile) can not
- Xcontain any tab, newline or '#' characters. Spaces will be stripped
- Xon both ends. Anything on a line from the first '#' till EOL is
- Xconsidered comment.
- X.Ss "Recipes"
- X.LP
- XA line starting with ':' marks the beginning of a recipe. It has the
- Xfollowing format:
- X.LP
- X:
- X.RI [ " number " ]
- X.RI [ " options " ]
- X.RI "[ : [" " locallockfile " "] ]"
- X.LP
- XThe
- X.I number
- Xis optional (defaults to 1) and specifies the number of conditionals
- Xfollowing this line. Conditionals are complete lines that are passed onto
- X$GREP
- X.BR literally ,
- Xconditionals are anded; if
- X.I number
- Xis zero, then the condition is always true and no conditionals are expected
- Xnext.
- X.LP
- X.I Options
- Xcan be any of the following (don't insert spaces in between, from the first
- Xcharacter that is not a valid option, on till EOL will be skipped without notice):
- X.Tp 5
- X.B H
- XFeed the header to $GREP (default)
- X.Tp
- X.B B
- XFeed the body to $GREP
- X.Tp
- X.B I
- XTell $GREP to ignore case
- X.Tp
- X.B h
- XFeed the header to the pipe (default)
- X.Tp
- X.B b
- XFeed the body to the pipe (default)
- X.Tp
- X.B f
- XConsider the pipe as a filter (ignored if a file)
- X.Tp
- X.B c
- XContinue processing rcfile even if this recipe matches (not needed if 'f'
- Xspecified)
- X.Tp
- X.B w
- XWait for the pipe or program to finish (and check if it was successfull,
- Xnormally ignored). If you specify 'f' and it matches, then the original mailer
- Xwill be told that the mail has already been delivered. If you want
- Xprocmail to stall telling the mailer that the mail has been delivered, until
- Xit really has been delivered, you'll have to specify 'w' together with
- Xevery 'f'. If you don't, the mailer will be told that the mail has been
- Xdelivered
- Xsuccesfully as soon as the first 'f' without a 'w' has been processed.
- XThis option is also advisable if you specified any
- X.I locallockfile
- Xon this recipe.
- X.Tp
- X.B s
- XMake procmail secure. If any fork fails in the current recipe, retry
- Xuntil it succeeds (usefull when running on machines that occasionally have
- Xa full process tables, to ensure normal delivery in any case). If a fork
- Xfails and 's' is not specified, it simply is logged in $LOGFILE and parsing
- Xof the rcfile continues (eventually delivering to $DEFAULT if no more
- Xrecipes match).
- X.Ss "Local lockfile"
- X.LP
- XIf you put a second ':' on the first recipe line, then procmail will use a
- X.I locallockfile
- X(for this recipe only). You optionally can specify the locallockfile
- Xto use; if you don't however, procmail
- Xwill use the filename specified as the destination (or the filename
- Xfollowing the first '>>') and will append $LOCKEXT to it.
- X.Ss "Recipe destination"
- X.LP
- XThe next line can start with the following characters:
- X.Tp
- X.B !
- XForwards to all the specified mail addresses (comments are
- X.B not
- Xignored on this line).
- X.Tp
- X.B |
- XStarts the specified program, possibly in $SHELL if any
- Xof the $METASHELL characters are found (that means comments are normally
- Xprocessed by the shell on
- X.B this
- Xline).
- X.LP
- XAnything else will be taken as a filename (relative to the last specified
- X$MAILDIR). After the filename everything will be ignored till EOL.
- X.Sh "EXAMPLES"
- X.LP
- XSome example recipes are listed below:
- X.LP
- XSort out all mail to mailling list scuba-dive.
- X.RS
- X.LP
- X:
- X.PD 0
- X.LP
- X^TOscuba
- X.LP
- Xscubafile
- X.PD
- X.LP
- X.RE
- XForward all mail from peter about compilers to william (and keep a copy
- Xof it here in petcompil).
- X.RS
- X.LP
- X:2 bc
- X.PD 0
- X.LP
- X^From.*peter
- X.LP
- X^Subject:.*compilers
- X.LP
- X! william@somewhere.edu
- X.LP
- X:2
- X.LP
- X^From.*peter
- X.LP
- X^Subject:.*compilers
- X.LP
- Xpetcompil
- X.PD
- X.RE
- X.LP
- XAdd the headers of all messages to your private header collection (for
- Xstatistics or mail debugging); and use the lockfile "headc.lock". In order
- Xto make sure the lockfile is not removed until the pipe has finished,
- Xyou have to specify option 'w'; otherwise the lockfile would be removed as
- Xsoon as the pipe had accepted the mail.
- X.RS
- X.LP
- X:0hwc:
- X.PD 0
- X.LP
- X| uncompress headc.Z; cat >>headc; compress headc
- X.RE
- X.PD
- X.LP
- XPrepend a linecount at the beginning of all multi part messages
- X(and don't allow
- X.B procmail
- Xto terminate early if the filter succeeds). Use "templock" as lockfile.
- X.RS
- X.LP
- X:wbf:templock
- X.PD 0
- X.LP
- X^Subject:.*\\(.*(/|of).*\\)
- X.LP
- X|echo "wc output:";tee tempf|wc;cat tempf;rm tempf
- X.PD
- X.RE
- X.LP
- XDump all mail from at jobs into one file, filter out the interesting
- Xparts of the header first.
- X.LP
- X.RS
- X:2fh
- X.PD 0
- X.LP
- X^From root
- X.LP
- X^Subject: Output from "at" job
- X.LP
- X|echo "From at job";echo;egrep "^Date:"
- X.LP
- X:b
- X.LP
- X^From at job
- X.LP
- Xatjunk
- X.RE
- X.PD
- X.Sh "FILES"
- X.PD 0
- X.Tp 22
- X.B /etc/passwd
- Xto get the recipients USER, HOME and SHELL variable defaults
- X.Tp
- X.B /var/spool/mail/$USER
- Xdefault last resort to put mail
- X.Tp
- X.B $HOME/.procmailrc
- Xdefault rc file
- X.Tp
- X.B $HOME/.mailbox
- Xdefault mailbox
- X.Tp
- X.B /var/spool/mail/$USER.lock
- Xlockfile for standard system mail directory (not used by
- X.B procmail
- Xunless you explicitly tell it to)
- X.Tp
- X.B /lib/sendmail
- Xdefault mail forwarder
- X.Tp
- X.B /usr/bin/egrep
- Xdefault regular expression parser
- X.PD
- X.Sh "SEE ALSO"
- X.LP
- 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.Sh "DIAGNOSTICS"
- X.Tp 23
- XError while writing to "x"
- Xnonexistent subdirectory, no write permission, or disk full
- X.Tp
- XFailed forking "x"
- Xnot possible if 's' flag specified on the recipe
- X.Tp
- XProgram failure of "x"
- Xsome pipe or program that was started by procmail returned a non-null value
- X.Tp
- XFailed to execute "x"
- Xprogram not in path, or not executable
- X.Tp
- XCouldn't unlink "x"
- Xlockfile was already gone, or write permission to the directory were the
- Xlockfile is has been denied
- X.Tp
- XOut of memory
- Xprobably a runaway filter that dumps junk into procmail,
- Xor the system could be out of swap space
- X.Tp
- XLockfailure 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
- 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
- XForced unlock denied on "x"
- Xno write permission in the directory where
- X.B lockfile
- Xresides
- X.Tp
- XTerminating prematurely
- Xprocmail received a signal and is bailing out
- X.Tp
- XTerminating prematurely whilst waiting for lockfile "x"
- Xprocmail received a signal while it was waiting for a lockfile to
- Xdisappear
- X.PD
- X.Sh "BUGS & SPECIAL FEATURES"
- X.LP
- XIf you don't explicitly tell procmail
- Xto wait (option 'w') for the pipe or program to finish, it won't wait
- Xand will terminate early (not knowing if the pipe or program returns
- Xsuccess).
- X.LP
- XThe only substitutions of environment variables that can be handled by
- Xprocmail itself are of the type $name.
- X.LP
- XA line buffer of 2048 bytes is used when processing the
- X.IR rcfile ,
- Xany environment variable expansions
- X.B have
- Xto fit within this limit.
- X.LP
- XDon't put comments on the lines in a recipe that get fed to $GREP,
- Xthese lines are fed to $GREP
- X.IR literally .
- X.LP
- XRace conditions sometimes result in a failure to remove a lock file
- X(e.g. forwarding mail to yourself (on the same account) could (not
- Xnecessarily) be a problem).
- X.LP
- XIn the unlikely event that you absolutely need to kill
- Xprocmail before it has finished, then first try and use
- Xthe regular kill command
- X.RB ( SIGTERM ),
- Xotherwise some
- X.I lockfiles
- Xmight not get removed.
- X.LP
- XYou should create a shell script that uses
- X.BR lockfile (1)
- Xbefore invoking
- Xthe mail program on any mailbox file other than the system mailbox.
- X.LP
- 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
- X.B override
- Xthe
- X.BR defaults ,
- Xyou either have to put them in the
- X.B .procmailrc
- Xor on the command line.
- X.LP
- XThe values of
- X.BR LOCKSLEEP ,
- X.B LOCKTIMEOUT
- Xand
- X.B NOMEMRETRY
- Xare parsed as if they were C constants (octal, decimal and hexadecimal format
- Xare understood).
- X.Sh "NOTES"
- X.LP
- XAny program executed from within procmail will be searched for in the PATH
- Xvariable (you have to specify it though). It is advisable however, to
- Xspecify an absolute path for $GREP, because it gets executed fairly often.
- X.LP
- XIf the regular expression starts with "\fB^TO\fP" it will be substituted by
- X"\fB^(To|Cc|Apparently-To):.*\fP", which should catch all destination
- Xspecifications.
- X.LP
- XAny lines in the body of the message that look like postmarks are prepended
- Xwith '>' (disarms bogus mailheaders). The regular expression that is used
- Xto search for these postmarks is:
- X.RS
- X\\n\\nFrom +[^\\t\\n ]+ +[^\\n\\t]
- X.RE
- X.LP
- 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.LP
- XFor
- X.I really
- Xcomplicated processing you can even consider calling
- X.B procmail
- Xrecursively.
- X.LP
- XYour $HOME/.forward (beware, it
- X.B has
- Xto be world readable) file should contain (include the quotes,
- X.I must
- Xbe an
- X.I absolute
- Xpath):
- X.LP
- X"|exec /global/bin/procmail"
- X.Ss "A sample small .procmailrc:"
- X.PD 0
- X.LP
- XPATH=/bin:/usr/bin:/global/bin:/usr/local/bin
- X.LP
- XMAILDIR=$HOME/Mail #you'd better make sure it exists
- X.LP
- XDEFAULT=$MAILDIR/mbox
- X.LP
- XLOGFILE=$MAILDIR/from
- X.LP
- XLOCKFILE=$HOME/.lockmail
- X.LP
- X:
- X.LP
- X^From.*berg
- X.LP
- Xfrom_me
- X.LP
- X:
- X.LP
- X^Subject:.*Flame
- X.LP
- X/dev/null
- X.PD
- X.Sh "AUTHOR"
- X.LP
- XStephen R. van den Berg at RWTH-Aachen, Germany
- X.RS
- Xberg@marvin.e17.physik.tu-muenchen.de (preferred)
- X.br
- Xberg@cip-s01.informatik.rwth-aachen.de (alternative)
- X.RE
- SHAR_EOF
- chmod 0644 procmail/procmail.1 ||
- echo 'restore of procmail/procmail.1 failed'
- Wc_c="`wc -c < 'procmail/procmail.1'`"
- test 15169 -eq "$Wc_c" ||
- echo 'procmail/procmail.1: original size 15169, current size' "$Wc_c"
- fi
- # ============= procmail/procmail.c ==============
- if test -f 'procmail/procmail.c' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/procmail.c (File already exists)'
- else
- echo 'x - extracting procmail/procmail.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/procmail.c' &&
- X/************************************************************************
- X * procmail.c an autonomous mail processor *
- X * *
- X * Version 1.30 1991-03-01 *
- X * Seems to be relatively bug free. *
- X * *
- X * Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands *
- X * The sources can be freely copied for non-commercial use. *
- X * See the accompanying README file for more info. *
- X * *
- X * Don't complain about the formatting, I know it's *
- X * unconventional, but it's my standard format (I have my *
- X * reasons). If you don't like it, feed it through your *
- X * favourite C beautifier. The program has been tested on *
- X * SUN's, but should work on almost every *NIX system that *
- X * has a fork() and execvp() command. The only things that *
- X * might need some changes are the include files. *
- X * There might be one problem if your system doesn't know *
- X * fsync(fd). Define NOfsync in that case. *
- X * *
- X * If you have had to make major changes in order to get it *
- X * running on a different machine, please send me the patches. *
- X * That way I might include them in a future version. *
- X * *
- X * Please note that this program essentially is supposed to be *
- X * static, that means no extra features (IMHO no more are *
- X * needed) are supposed to be added (though any usefull *
- X * suggestions will be appreciated and evaluated if time permits). *
- X ************************************************************************/
- X#include "config.h"
- X#define MAIN
- X#include "procmail.h"
- X#include "sysexits.h"
- X#include "shell.h"
- X
- X#define VERSION "Procmail v1.30 1991-03-01 written by Stephen R.van den Berg\n"
- X#define VERSIONOPT "-v" /* option to display version */
- X
- Xchar buf[BFSIZ],buf2[BFSIZ],maildir[]="MAILDIR",defaultf[]="DEFAULT",
- X logfile[]="LOGFILE",lockfile[]="LOCKFILE",grep[]="GREP",host[]="HOST",
- X locksleep[]="LOCKSLEEP",orgmail[]="ORGMAIL",eumask[]="UMASK",
- X shellmetas[]="SHELLMETAS",shellflags[]="SHELLFLAGS",shell[]="SHELL",
- X sendmail[]="SENDMAIL",lockext[]="LOCKEXT",locktimeout[]="LOCKTIMEOUT",
- X devnull[]="/dev/null",newline[]="\n",binsh[]="/bin/sh",home[]="HOME",
- X tmp[]="/tmp",user[]="USER",nomemretry[]="NOMEMRETRY",*rcfile=PROCMAILRC,
- X **gargv,*globlock,*loclock,*tolock;
- Xint retval=EX_CANTCREAT,flaggerd=1,verrgrandchild,sh,pwait,secur,lcking,
- X nextexit,locknext;
- Xpid_t mother;
- XFILE*rc;
- X
- Xmain(argc,argv)char*argv[];{static char flags[10];int i;
- X char*themail,*thebody,*chp,*startchar,*chp2;long tobesent,filled,rcoffset;
- X if((chp=argv[1])&&!strcmp(chp,VERSIONOPT)){
- X log(VERSION);return EX_OK;}
- X mother=getpid();setbuf(stdin,(void*)0);umask(077);
- X sprintf(buf,"%u",i=getuid());setpwent();
- X {struct passwd*pass;
- X if(pass=getpwuid(i)){ /* find user defaults in /etc/passwd */
- X setdef(home,pass->pw_dir);chdir(pass->pw_dir);
- X setdef(user,pass->pw_name?pass->pw_name:buf);setdef(shell,pass->pw_shell);}
- X else{ /* user could not be found, set reasonable defaults */
- X setdef(home,tmp);chdir(tmp);setdef(user,buf);setdef(shell,binsh);}}
- X endpwent();setdef(shellmetas,DEFshellmetas);setdef(shellflags,DEFshellflags);
- X setdef(maildir,DEFmaildir);setdef(defaultf,DEFdefault);
- X setdef(orgmail,DEForgmail);setdef(grep,DEFgrep);setdef(sendmail,DEFsendmail);
- X setdef(lockext,DEFlockext);setdef(locksleep,DEFlocksleeps);
- X setdef(locktimeout,DEFlocktimeout);setdef(nomemretry,DEFnomemretry);
- X chdir(getenv(maildir));fdreopena(devnull,STDERR);fdreopena(devnull,STDOUT);
- X gargv=argv+1;nextrcfile();
- X thebody=themail=malloc(argc=1);filled=rcoffset=0;
- Xchangedmail:
- X themail=readdyn(themail,&filled); /* read in the mail */
- Xonlyhead:
- X startchar=filled+(thebody=themail);
- X while(thebody<startchar&&*thebody++=='\n'); /* skip leading garbage */
- X thebody=findel(thebody,startchar); /* find the end of the header */
- X chp=thebody;
- X do{ /* search for bogus headers */
- X if(startchar-chp<8) /* we're looking for: */
- X break; /* "\n\nFrom +[^\t\n ]+ +[^\n\t]" */
- X if(0>=sscanf(chp,"From%1[ ]",buf)) /* thats the regular expression */
- X continue; /* that defines the start of a mail */
- X chp2=chp;chp+=5; /* message. */
- X#define SKIPWHILE(x) while(x){ if(++chp>=startchar) break;}
- X SKIPWHILE(*chp==' ')
- X SKIPWHILE((i=*chp)&&i!=' '&&i!='\t'&&i!='\n')
- X SKIPWHILE(*chp==' ')
- X if((i=*chp)&&i!='\n'&&i!='\t'){ /* insert '>' before bogus header */
- X i=startchar[-1];tmemmove(chp2+1,chp2,(startchar-chp2)-1);
- X *chp2='>';themail=realloc(chp2=themail,++filled);
- X#define ADJUST(x) ((x)=themail+((x)-chp2))
- X ADJUST(thebody);ADJUST(startchar);ADJUST(chp);*startchar++=i;}}
- X while(startchar>(chp=findel(chp,startchar)));
- X waitflagger(); /* if we're a child, wait for the parental guidance */
- Xchangerc:
- X rc=fopen(strcat(cat(getenv(home),"/"),rcfile),"r");
- X fseek(rc,rcoffset,SEEK_SET);signal(SIGINT,sterminate);
- X signal(SIGQUIT,sterminate);signal(SIGTERM,sterminate);signal(SIGHUP,SIG_IGN);
- Xgoon:
- X while(unlock(&loclock),!feof(rc)||argv[argc]){
- X while(chp=argv[argc]){ /* interpret command line specs first */
- X argc++;strcpy(buf2,chp);
- X if(chp=strchr(buf2,'=')){
- X chp++;goto argenv;}}
- X if(tscrc(" %1[:]",flags)){ /* check for a recipe */
- X skipblanks();i=sh=1;
- X if(tscrc("%[0-9]",buf2)){
- X sscanf(buf2,"%d",&sh);skipblanks();}
- X *flags='\0';scrc("%9[HBIhbfcws]",flags);skipblanks();
- X if(tolock) /* clear temporary buffer for lockfile name */
- X free(tolock);
- X tolock=0;
- X if((locknext=(tscrc("%1[:]",buf)))&&
- X (skipblanks(),tscrc("%[^ \t\n#]",buf2))){
- X parse();tolock=tstrdup(buf);}
- X startchar=themail;tobesent=thebody-themail;
- X if(strchr(flags,'B')) /* what needs to be piped into grep? */
- X if(strchr(flags,'H'))
- X tobesent=filled;
- X else{
- X startchar=thebody;tobesent=filled-tobesent;}
- X while(sh--){ /* any conditions (left) */
- X skiptoeol();scrc("%[^\n]",buf2);
- X if(!strncmp(buf2,TOkey,TOkeylen))
- X cat(TOsubstitute,buf2+TOkeylen);
- X else
- X strcpy(buf,buf2);
- X if(i) /* check out all conditions */
- X i=!grepin(buf,startchar,tobesent,!strchr(flags,'I'));}
- X startchar=themail;tobesent=filled; /* body, header or both? */
- X if(strchr(flags,'h')){
- X if(!strchr(flags,'b'))
- X tobesent=thebody-themail;}
- X else if(strchr(flags,'b'))
- X tobesent-=(startchar=thebody)-themail;
- X chp=buf+strlen(cat(getenv(sendmail)," "));sh=0;
- X pwait=!!strchr(flags,'w');secur=!!strchr(flags,'s');
- X if(tscrc(" ! %[^\n]",chp)){ /* forward the mail */
- X if(i)
- X goto forward;}
- X else if(tscrc("| %[^\n]",buf2)){ /* pipe the mail */
- X if(i){
- X if(sh=!!strpbrk(buf2,getenv(shellmetas)))
- X strcpy(buf,buf2);
- X else
- X parse();
- X chp=buf;*buf2='\0';
- X while(i=*chp) /* find the implicit lockfile name ('>>name') */
- X if(chp++,i=='>'&&*chp=='>'){
- X while((i=*++chp)==' '||i=='\t');
- X sscanf(chp,"%[^ \t\n#'\");|<>]",buf2);break;}
- X lcllock();
- X if(strchr(flags,'f')){
- X if(startchar==themail&&tobesent!=filled){ /* if only 'h' */
- X char*dest;long dfilled=0;
- X if(pipthrough(buf,startchar,tobesent))
- X goto goon;
- X dest=readdyn(malloc(1),&dfilled);filled-=tobesent;
- X if(tobesent<dfilled) /* adjust buffer size (only bigger) */
- X themail=realloc(themail,dfilled+filled);
- X tmemmove(themail+dfilled,themail+tobesent,filled);
- X tmemmove(themail,dest,dfilled);free(dest);
- X themail=realloc(themail,filled+=dfilled);
- X goto onlyhead;} /* and determine the header again */
- X rcoffset=ftell(rc); /* needed because we have to fclose it */
- X if(pipthrough(buf,startchar,tobesent))
- X goto goon;
- X filled=startchar-themail;goto changedmail;}
- Xforward: if(!pipin(buf,startchar,tobesent)&&!strchr(flags,'c'))
- X goto mailed;}}
- X else{ /* append the mail to a file */
- X scrc("%s",buf2);skipcomment();
- X if(i){
- X parse();strcpy(buf2,buf);lcllock();
- X if(!dump(opena(buf),startchar,tobesent)&&!strchr(flags,'c'))
- X goto mailed;}}}
- X else if(tscrc("%[A-Z_a-z0-9] = ",buf)){ /* then it must be an assignment */
- X *(chp=buf+strlen(buf))='=';*++chp='\0';scrc("%[^\t\n#]",chp);
- X for(chp2=chp+strlen(chp);*--chp2==' ';); /* skip trailing blanks */
- X chp2[1]='\0';skipcomment();strcpy(buf2,buf);
- Xargenv:
- X parse();sputenv(buf);chp[-1]='\0';
- X if(!strcmp(buf,maildir))
- X chdir(chp);
- X else if(!strcmp(buf,logfile))
- X fdreopena(chp,STDERR);
- X else if(!strcmp(buf,lockfile))
- X lockit(chp,&globlock);
- X else if(!strcmp(buf,eumask)){
- X sscanf(chp,"%o",&i);umask(i);}
- X else if(!strcmp(buf,host)){
- X#ifndef NOuname
- X struct utsname name;
- X uname(&name);
- X if(strcmp(chp,name.nodename)){
- X#else
- X *buf2='\0';gethostname(buf2,BFSIZ);
- X if(strcmp(chp,buf2)){
- X#endif
- X if(nextrcfile()){
- X fclose(rc);rcoffset=0;goto changerc;}
- X retval=EX_OK;terminate();}}}
- X else if(!skipcomment()){ /* either comment or garbage */
- X scrc("%[^\n] ",buf);log("Skipped:");logqnl(buf);}}
- X if(dump(opena(chp=getenv(defaultf)),themail,filled)){ /* default maildest */
- X writeerr(chp); /* if it fails, don't panic, try the last resort */
- X if(dump(opena(chp=getenv(orgmail)),themail,filled))
- X writeerr(chp);goto mailerr;} /* now you can panic */
- Xmailed:
- X retval=EX_OK; /* we're home free, mail delivered */
- Xmailerr:
- X unlock(&loclock); /* any local lock file still around? */
- X do{
- X chp=buf-1;
- X while(themail<thebody&&chp<buf+BFSIZ-1&&(*++chp=*themail++)!='\n');
- X if(chp<buf)
- X chp++;
- X *chp='\0';
- X if(0<sscanf(buf,"From%*1[^:]%[^\n]",buf2)){
- X log("From ");goto foundsorf;}
- X else if(0<sscanf(buf,"Subject:%[^\n]",buf2)){
- X log(" Subject:");
- Xfoundsorf:
- X log(buf2);log(newline);}} /* log it's arrival */
- X while(themail<thebody);
- X terminate();}
- SHAR_EOF
- chmod 0644 procmail/procmail.c ||
- echo 'restore of procmail/procmail.c failed'
- Wc_c="`wc -c < 'procmail/procmail.c'`"
- test 9798 -eq "$Wc_c" ||
- echo 'procmail/procmail.c: original size 9798, current size' "$Wc_c"
- fi
- # ============= procmail/nonint.c ==============
- if test -f 'procmail/nonint.c' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/nonint.c (File already exists)'
- else
- echo 'x - extracting procmail/nonint.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/nonint.c' &&
- X/************************************************************************
- X * Collection of routines that don't return int *
- X * *
- X * Copyright (c) 1990-1991, S.R.van den Berg, The Netherlands *
- X * The sources can be freely copied for non-commercial use. *
- X * See the accompanying README file for more info. *
- X * *
- X * Don't complain about the formatting, I know it's *
- X * unconventional, but it's my standard format (I have my *
- X * reasons). If you don't like it, feed it through your *
- X * favourite C beautifier. *
- X ************************************************************************/
- X
- X#include "config.h"
- X#include "procmail.h"
- X#include "sysexits.h"
- X
- X#ifdef NOmemmove
- Xvoid*memmove(to,from,count)register void*to,*from;register t_buf count;{
- X void*old;
- X old=to;count++;--(char*)to;--(char*)from;
- X if(to<=from){
- X goto jiasc;
- X do{
- X *++(char*)to=*++(char*)from;
- Xjiasc:;}
- X while(--count);}
- X else{
- X (char*)to+=count;(char*)from+=count;
- X goto jidesc;
- X do{
- X *--(char*)to=*--(char*)from;
- Xjidesc:;}
- X while(--count);}
- X return old;}
- X#endif
- X
- Xvoid*tmalloc(len)t_buf len;{void*p;int i; /* this malloc can survive */
- X if(p=malloc(len)) /* a temporary "out of swap space" condition */
- X return p;
- X for(i=renvint(iDEFnomemretry,nomemretry);i<0||i--;){
- X sleep(SUSPENSION); /* problems? don't panic, wait a few secs till */
- X if(p=malloc(len)) /* some other process has paniced (and died 8-) */
- X return p;}
- X nomemerr();}
- X
- Xvoid*trealloc(old,len)void*old;t_buf len;{int i; /* this realloc can survive */
- X if(old=realloc(old,len)) /* a temporary "out of swap space" condition */
- X return old;
- X for(i=renvint(iDEFnomemretry,nomemretry);i<0||i--;){
- X sleep(SUSPENSION); /* problems? don't panic, wait a few secs till */
- X if(old=realloc(old,len)) /* some other process has paniced (and died 8-) */
- X return old;}
- X nomemerr();}
- X
- X#include "shell.h"
- X
- Xpid_t sfork(){pid_t i; /* if secur is set, it doesn't return */
- X while((i=fork())&&secur&&i==-1) /* until the fork was successfull */
- X sleep(SUSPENSION);
- X return i;}
- X
- Xvoid sterminate(){
- X if(!nextexit){
- X log("Terminating prematurely");
- X if(!lcking){
- X log(newline);terminate();}}
- X nextexit=1;}
- X
- Xvoid flagger(){ /* hey, we received a SIGHUP */
- X flaggerd=1;}
- X
- Xvoid errgrandchild(){ /* my grandchildren scream in despair */
- X verrgrandchild=1;}
- X
- Xlong dump(s,source,len)int s;char*source;long len;{int i;long ol;
- X if(s>=0){
- X ol=len;
- X while(i=rwrite(s,source,BLKSIZ<len?BLKSIZ:(int)len)){
- X if(i<0){
- X i=0;goto writefin;}
- X len-=i;source+=i;}
- X if(!len&&(ol<2||!(source[-1]=='\n'&&source[-2]=='\n')))
- X rwrite(s,newline,1); /* message always ends with a newline */
- Xwritefin:
- X if(fsync(s)&&errno!=EINVAL)
- X len++; /* if there is a physical write error */
- X rclose(s);return len-i;}
- X return len?len:-1;} /* return an error even if nothing was to be sent */
- X
- Xlong pipin(line,source,len)char*line,*source;long len;{pid_t pid;
- X int poutfd[2];
- X pipe(poutfd);
- X if(!(pid=sfork())){
- X rclose(PWRITE);redirect(PREAD);callnewprog(line);}
- X rclose(PREAD);forkerr(pid,line);
- X if(len=dump(PWRITE,source,len))
- X writeerr(line);
- X if(pwait&&waitfor(pid)!=EX_OK){
- X progerr(line);len=1;}
- X return len;}
- X
- Xchar*readdyn(bf,filled)char*bf;long*filled;{int i;
- X goto jumpin;
- X do{
- X *filled+=i;
- Xjumpin:
- X bf=realloc(bf,*filled+BLKSIZ);} /* dynamic adjust */
- X while(0<(i=read(STDIN,bf+*filled,BLKSIZ)));
- X if(!*filled)
- X return realloc(bf,1);
- X return realloc(bf,*filled);} /* minimize the buffer space */
- X
- Xchar*cat(a,b)char*a,*b;{
- X return strcat(strcpy(buf,a),b);}
- X
- Xchar*findel(start,end)register char*start,*end;{/* find the first empty line */
- X while(start<end)
- X if(*start++=='\n'&&start<end&&*start=='\n')
- X return start+1;
- X return end;}
- X
- Xchar*tstrdup(a)char*a;{int i;
- X i=strlen(a)+1;return tmemmove(malloc(i),a,i);}
- SHAR_EOF
- chmod 0644 procmail/nonint.c ||
- echo 'restore of procmail/nonint.c failed'
- Wc_c="`wc -c < 'procmail/nonint.c'`"
- test 3914 -eq "$Wc_c" ||
- echo 'procmail/nonint.c: original size 3914, current size' "$Wc_c"
- fi
- # ============= procmail/config.h ==============
- if test -f 'procmail/config.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/config.h (File already exists)'
- else
- echo 'x - extracting procmail/config.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/config.h' &&
- X/*#define SYSV /* you guessed it, uncomment if sysV machine */
- X
- X#define NOmemmove /* if your library has it, comment this line */
- X
- X/*#define NO_ANSI_PROT /* uncomment if you don't have ANSI headers */
- X
- X/*#define void char /* uncomment if your compiler is brain damaged */
- X
- X#ifdef SYSV
- X# define NOfsync /* in my experience no sysV machine has it */
- X#else
- X# define NOuname /* some BSD machines seem to have it anyway */
- X#endif
- X
- X/*#define NOfsync /* if you don't want to use it or don't have it */
- X
- X#ifndef t_buf /* should not be a macro anyway */
- Xtypedef unsigned t_buf; /* comment out if already defined */
- X /* when in doubt, please check if this is the */
- X /* correct type for your library as the size */
- X /* argument to malloc, realloc and memmove */
- X /* this is important, since it determines the */
- X /* maximum message length that can be processed */
- X /* by procmail */
- X#endif
- X
- X/* If need be, you can change some of the defines below, for most
- X people these defaults should do however */
- X
- X#define BFSIZ 2048 /* max expanded line length */
- X#define BLKSIZ (1<<14) /* blocksize while reading/writing */
- X#define PROCMAILRC ".procmailrc"
- X#define SUSPENSION 16 /* multi-purpose 'idle loop' period */
- X#define DEFlocksleep 8
- X#define DEFlocksleeps "8"
- X#define TOkey "^TO"
- X#define TOkeylen 3 /* should be length of TOkey */
- X#define TOsubstitute "^(To|Cc|Apparently-To):.*"
- X#define DEFshellmetas "\"'`{}()[]*?|<>~;!\\" /* never put '$' in here */
- X#define DEFmaildir "$HOME"
- X#define DEFdefault "$MAILDIR/.mailbox"
- X#define DEForgmail "/var/spool/mail/$USER"
- X#define DEFgrep "/usr/bin/egrep"
- X#define DEFsendmail "/usr/lib/sendmail"
- X#define DEFlockext ".lock"
- X#define DEFshellflags "-c"
- X#define DEFlocktimeout "3600" /* defaults to one hour */
- X#define iDEFnomemretry 2 /* standard nr of retries if no mem left */
- X /* valid as soon as procmail runs */
- X#define DEFnomemretry "2"
- SHAR_EOF
- chmod 0644 procmail/config.h ||
- echo 'restore of procmail/config.h failed'
- Wc_c="`wc -c < 'procmail/config.h'`"
- test 1929 -eq "$Wc_c" ||
- echo 'procmail/config.h: original size 1929, current size' "$Wc_c"
- fi
- # ============= procmail/sysexits.h ==============
- if test -f 'procmail/sysexits.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/sysexits.h (File already exists)'
- else
- echo 'x - extracting procmail/sysexits.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/sysexits.h' &&
- X/*#include <sysexits.h> /* uncomment if your system has it */
- X
- X#ifndef EX_OK
- X /* Standard exit codes, original list maintained
- X by Eric Allman (eric@berkeley, ucbvax!eric) */
- X# define EX_OK 0
- X# define EX_UNAVAILABLE 69
- X# define EX_OSERR 71
- X# define EX_CANTCREAT 73
- X#endif
- SHAR_EOF
- chmod 0644 procmail/sysexits.h ||
- echo 'restore of procmail/sysexits.h failed'
- Wc_c="`wc -c < 'procmail/sysexits.h'`"
- test 279 -eq "$Wc_c" ||
- echo 'procmail/sysexits.h: original size 279, current size' "$Wc_c"
- fi
- # ============= procmail/procmail.h ==============
- if test -f 'procmail/procmail.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/procmail.h (File already exists)'
- else
- echo 'x - extracting procmail/procmail.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/procmail.h' &&
- X#include "includes.h"
- X
- X#ifdef NOsync /* If you don't want syncs at all define */
- X# define fsync(fd) 0 /* NOsync. Only recommended if procmail */
- X# define sync() 0 /* isn't used in a networked environment */
- X#else
- X# ifdef NOfsync /* If you don't have fsync, define NOfsync */
- X# define fsync(fd) 0 /* sync will be used instead. Is a bit */
- X# endif /* slower, but works nevertheless */
- X#endif
- X
- X#define PREAD (poutfd[0])
- X#define PWRITE (poutfd[1])
- X#define tscrc(a,b) (0<fscanf(rc,a,b))
- X#define scrc(a,b) fscanf(rc,a,b)
- X
- X#ifndef MAIN
- Xextern char buf[],buf2[],maildir[],defaultf[],logfile[],lockfile[],grep[],
- X host[],locksleep[],orgmail[],eumask[],shellmetas[],shellflags[],shell[],
- X sendmail[],lockext[],locktimeout[],devnull[],newline[],binsh[],home[],
- X tmp[],user[],nomemretry[],*rcfile,**gargv,*globlock,*loclock,*tolock;
- Xextern retval,flaggerd,verrgrandchild,sh,pwait,secur,lcking,nextexit,locknext;
- Xextern pid_t mother;
- Xextern FILE*rc;
- X#endif
- X
- X#ifdef NOmemmove
- Xvoid*memmove();
- X#endif
- X
- Xvoid*tmalloc(),*trealloc();
- Xpid_t sfork();
- Xvoid sterminate(),flagger(),errgrandchild();
- Xlong dump(),pipin();
- Xchar*readdyn(),*cat(),*findel(),*tstrdup();
- SHAR_EOF
- chmod 0644 procmail/procmail.h ||
- echo 'restore of procmail/procmail.h failed'
- Wc_c="`wc -c < 'procmail/procmail.h'`"
- test 1158 -eq "$Wc_c" ||
- echo 'procmail/procmail.h: original size 1158, current size' "$Wc_c"
- fi
- # ============= procmail/shell.h ==============
- if test -f 'procmail/shell.h' -a X"$1" != X"-c"; then
- echo 'x - skipping procmail/shell.h (File already exists)'
- else
- echo 'x - extracting procmail/shell.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'procmail/shell.h' &&
- X#define malloc(n) tmalloc((t_buf)(n))
- X#define realloc(p,n) trealloc(p,(t_buf)(n))
- X#define tmemmove(t,f,n) memmove(t,f,(t_buf)(n))
- SHAR_EOF
- chmod 0644 procmail/shell.h ||
- echo 'restore of procmail/shell.h failed'
- Wc_c="`wc -c < 'procmail/shell.h'`"
- test 130 -eq "$Wc_c" ||
- echo 'procmail/shell.h: original size 130, current size' "$Wc_c"
- fi
- true || echo 'restore of procmail/retint.c failed'
- echo End of part 1, continue with part 2
- exit 0
- --
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-