home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-04 | 43.4 KB | 1,244 lines |
- Newsgroups: comp.sources.misc
- From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
- Subject: v35i028: procmail - mail processing package v2.80, Part07/11
- Message-ID: <1993Feb5.020525.16689@sparky.imd.sterling.com>
- X-Md4-Signature: 131eae9bcc289b0d78b907312d466809
- Date: Fri, 5 Feb 1993 02:05:25 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
- Posting-number: Volume 35, Issue 28
- Archive-name: procmail/part07
- Environment: sendmail, smail, MMDF, mailsurr, UNIX, POSIX
- Supersedes: procmail: Volume 31, Issue 40-44
-
- #! /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 7 (of 11)."
- # Contents: procmail280/examples/advanced procmail280/src/lockfile.c
- # procmail280/src/mailfold.c procmail280/src/misc.c
- # Wrapped by berg@hathi on Thu Feb 4 15:27:59 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'procmail280/examples/advanced' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail280/examples/advanced'\"
- else
- echo shar: Extracting \"'procmail280/examples/advanced'\" \(10469 characters\)
- sed "s/^X//" >'procmail280/examples/advanced' <<'END_OF_FILE'
- X
- 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 2c.Special directions for sites with SysV /etc/mail/mailsurr
- X 3. Changing the mail spool directory to $HOME for all users
- X 4. Security considerations (when installing procmail suid root)
- 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, check if there
- Xis a /bin/hostname.
- 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
- XBeware, however, that if you are using this method, /bin/mail can *only* be
- Xused to deliver mail. On many systems /bin/mail has several uses (also to
- Xread mail or check for mail). So, it would definitely be preferred if you
- Xcould edit the invocation of /bin/mail from within your mail transport agent
- Xto invoke procmail instead (with appropriate flags, if needed). Special
- Xdirections detailing this process for some of the more popular MTAs are
- Xincluded in sections (2a) and (2b) below.
- X
- XIn addition to needing root privileges 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
- 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=lsSDFMhP, S=10, R=20, A=procmail -d $u
- 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; user=root,
- X cmd="/usr/local/bin/procmail -d $($user$)"
- X
- X ---
- X
- X2c.Special directions for sites with SysV /etc/mail/mailsurr
- X ---------------------------------------------------------
- X
- XSome systems use a SysV /bin/mail that supports mailsurr. To interface
- Xprocmail with mailsurr the following two lines should be inserted in the
- X/etc/mail/mailsurr file (preferably at the bottom):
- X
- X'(.+)' '([^@!]+)' '<S=0;C=67,75;F=*;
- X /usr/local/bin/procmail -f \\1 -d \\2'
- X
- X ---
- X
- X3. Changing the mail spool directory to $HOME for all users
- X --------------------------------------------------------
- X
- XThere are many different reasons why more and more sites decide not to
- Xstore mail in /usr/spool/mail or /usr/mail anymore.
- XSome of the obvious advantages when storing mail in the recipient's home
- Xdirectory are:
- X - Mail is automatically subject to his quota limitations.
- X - Often there is more room on the home partitions than on that
- X one /usr/mail partition.
- X
- XThe quota limitations also apply to /usr/spool/mail or /usr/mail if procmail
- Xdoes the delivery. This quota limitation often does not work with the
- Xregular /bin/mail since it often writes the mailbox with root permissions
- X(eluding the quota restrictions).
- X
- XHowever, if you are going to install procmail as the integrated local
- Xdelivery agent, and you want mail to be delivered to, say, $HOME/.mail
- Xby default, this is what you have to do:
- X
- X Edit the procmail*/config.h file. Uncomment and possibly change
- X the SYSTEM_MBOX define. Procmail now delivers there by default.
- X
- X In order to make sure that normal mailtools can find the new
- X system mailboxes, you should make sure that every user has the
- X MAIL environment variable set to be equal to whatever you
- X defined SYSTEM_MBOX to be. Some braindamaged mail programs
- X do not pick up the MAIL environment variable, these either
- X have to be patched/recompiled or you have to create symbolic
- X links in /usr/mail to every person's new mailbox.
- X
- X ---
- X
- X4. 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
- Xprivileges).
- 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
- 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_fourth_friend # Forward everything Myfriend writes about parties,
- X # except beach parties, to my_fourth_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 10469 -ne `wc -c <'procmail280/examples/advanced'`; then
- echo shar: \"'procmail280/examples/advanced'\" unpacked with wrong size!
- fi
- # end of 'procmail280/examples/advanced'
- fi
- if test -f 'procmail280/src/lockfile.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail280/src/lockfile.c'\"
- else
- echo shar: Extracting \"'procmail280/src/lockfile.c'\" \(9425 characters\)
- sed "s/^X//" >'procmail280/src/lockfile.c' <<'END_OF_FILE'
- X/************************************************************************
- X * lockfile - The conditional semaphore-file creator *
- X * *
- X * It has been designed to be able to be run sgid mail or *
- X * any gid you see fit (in case your mail spool area is *not* *
- X * world writeable, but group writeable), without creating *
- X * security holes. *
- X * *
- X * Seems to be relatively bug free. *
- X * *
- X * Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands *
- X * #include "README" *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic /*const*/char rcsid[]=
- X "$Id: lockfile.c,v 1.13 1993/01/19 18:30:36 berg Exp $";
- X#endif
- Xstatic /*const*/char rcsdate[]="$Date: 1993/01/19 18:30:36 $";
- X#include "includes.h"
- X#include "sublib.h"
- X#include "exopen.h"
- X
- X#ifndef SYSTEM_MBOX
- X#define SYSTEM_MBOX SYSTEM_MAILBOX
- X#endif
- X
- Xstatic volatile exitflag;
- Xpid_t thepid;
- Xstatic char systm_mbox[]=SYSTEM_MBOX;
- Xstatic const char dirsep[]=DIRSEP,lockext[]=DEFlockext,
- X nameprefix[]="lockfile: ",lgname[]="LOGNAME",home[]="HOME";
- X
- Xstatic void failure P((void)) /* signal trap */
- X{ exitflag=2; /* merely sets a flag */
- X}
- X /* see locking.c for comment on xcreat() */
- Xstatic xcreat(name,tim)const char*const name;time_t*const tim;
- X{ char*p,*q;int j= -1,i;struct stat stbuf;
- X for(q=(char*)name;p=strpbrk(q,dirsep);q=p+1);
- X i=q-name;
- X if(!(p=malloc(i+UNIQnamelen)))
- X return exitflag=1;
- X strncpy(p,name,i);
- X if(unique(p,p+i,0,0))
- X stat(p,&stbuf),*tim=stbuf.st_mtime,j=myrename(p,name);
- X free(p);return j;
- X}
- X
- Xvoid elog(a)const char*const a;
- X{ write(STDERR,a,strlen(a));
- X}
- X
- Xvoid nlog(a)const char*const a;
- X{ elog(nameprefix);elog(a); /* decent error messages should start with this */
- X}
- X
- Xstatic size_t parsecopy(dest,org,pass)char*const dest;const char*org;
- X const struct passwd*const pass; /* try and digest the mailbox-lockfile name */
- X{ size_t len;const char*chp;char*p;unsigned i;
- X for(p=dest,len=STRLEN(lockext)+1;;)
- X { switch(*org)
- X { case '$': /* we substitute */
- X if(!strncmp(++org,lgname,STRLEN(lgname)))
- X org+=STRLEN(lgname),chp=pass->pw_name; /* $LOGNAME and */
- X else if(!strncmp(org,home,STRLEN(home)))
- X org+=STRLEN(home),chp=pass->pw_dir; /* $HOME */
- X else
- X goto capac; /* no other fancy stuff */
- X if((i= *org)-'a'<='z'-'a'||i-'A'<='Z'-'A'||i-'0'<='9'-'0'||i=='_')
- X goto capac;
- X if(p)
- X p+=strlen(strcpy(p,chp)); /* paste it in */
- X len+=strlen(chp);continue;
- X default:
- X if(p)
- X *p++= *org; /* simply copy everything else */
- X len++;org++;continue; /* except suspicous looking characters */
- X case '\'':case '`':case '"':case '\\':case '{':goto capac;
- X case '\0':;
- X }
- X if(p)
- X { if(p==dest||!strchr(dirsep,*dest)) /* absolute path wanted */
- Xcapac: { nlog("Sorry, but turning this mess into a useable mailbox \
- Xexceeds my humble\ncapacities");return 0;
- X }
- X strcpy(p,lockext);
- X }
- X return len;
- X }
- X}
- X
- Xstatic PROGID;
- X
- Xmain(argc,argv)const char*const argv[];
- X{ const char*const*p,*const*lastf;char*cp;uid_t uid;
- X int sleepsec,retries,invert,force,suspend,retval=EX_OK,virgin=1;
- X static const char usage[]="Usage: lockfile -nnn | -r nnn | -l nnn | -s nnn \
- X| -! | -ml | -mu | file ...\n";
- X if(argc<=1) /* sanity check, any argument at all? */
- X goto usg;
- X sleepsec=DEFlocksleep;force=invert=(char*)progid-(char*)progid;retries= -1;
- X suspend=DEFsuspend;thepid=getpid();uid=getuid();signal(SIGPIPE,SIG_IGN);
- Xagain:
- X signal(SIGHUP,(void(*)())failure);signal(SIGINT,(void(*)())failure);
- X signal(SIGQUIT,(void(*)())failure);signal(SIGTERM,(void(*)())failure);
- X for(lastf=p=argv;--argc;)
- X if(*(cp=(char*)*++p)=='-')
- X for(cp++;;)
- X { char*cp2=cp+1;int i;
- X switch(*cp++)
- X { case '!':invert^=1;continue; /* invert the exitcode */
- X case 'r':case 'l':case 's':
- X if(!*cp&&(cp=(char*)*++p,!--argc)) /* concatenated/seperate */
- X goto eusg;
- X i=strtol(cp,&cp,10);
- X switch(cp2[-1])
- X { case 'r':retries=i;goto checkrdec;
- X case 'l':force=i;goto checkrdec;
- X default:
- X if(i<0) /* suspend should be >=0 */
- X goto eusg;
- X suspend=i;goto checkrdec;
- X }
- X case HELPOPT1:case HELPOPT2:elog(usage);
- X elog(
- X "\t-nnn\twait nnn seconds between locking attempts\
- X\n\t-r nnn\tmake at most nnn retries before giving up on a lock\
- X\n\t-l nnn\tset locktimeout to nnn seconds\
- X\n\t-s nnn\tsuspend nnn seconds after a locktimeout occurred\
- X\n\t-!\tinvert the exit code of lockfile\
- X\n\t-ml\tlock your system mail-spool file\
- X\n\t-mu\tunlock your system mail-spool file\n");goto xusg;
- X default:
- X if(sleepsec>=0) /* is this still the first pass? */
- X { if((sleepsec=strtol(cp,&cp,10))<0)
- X goto eusg;
- Xcheckrdec: if(cp2==cp)
- Xeusg: { elog(usage); /* regular usage message */
- Xxusg: retval=EX_USAGE;goto nfailure;
- X }
- X }
- X else /* no second pass, so leave sleepsec<0 */
- X strtol(cp,&cp,10); /* and discard the number */
- X continue;
- X case 'm': /* take $LOGNAME as a hint, check if valid */
- X { struct passwd*pass;static char*ma;size_t alen;
- X if(*cp&&cp[1]||ma&&sleepsec>=0) /* second pass? */
- X goto eusg;
- X if(!ma) /* ma initialised last time? */
- X { if(!((ma=(char*)getenv(lgname))&&(pass=getpwnam(ma))&&
- X pass->pw_uid==uid||(pass=getpwuid(uid))))
- X { nlog("Can't determine your mailbox, who are you?\n");
- X goto nfailure; /* panic, you're not in /etc/passwd */
- X }
- X if(!(alen=parsecopy((char*)0,systm_mbox,pass)))
- X { cp=systm_mbox;goto lfailure; /* couldn't digest */
- X } /* mailbox */
- X if(!(ma=malloc(alen))) /* ok, make some room */
- X goto outofmem;
- X parsecopy(ma,systm_mbox,pass); /* and fill her up */
- X }
- X switch(*cp)
- X { default:goto eusg; /* somebody goofed again */
- X case 'l': /* lock the mailbox */
- X if(sleepsec>=0) /* first pass? */
- X { cp=ma;goto stilv; /* yes, lock it! */
- X }
- X case 'u': /* unlock the mailbox */
- X if(unlink(ma))
- X { nlog("Can't unlock \"");elog(ma);elog("\"");
- X if(*cp=='l') /* they messed up, give them a hint */
- X elog(" again,\n already dropped my privileges");
- X elog("\n");
- X }
- X else
- X virgin=0;
- X }
- X }
- X case '\0':;
- X }
- X break;
- X }
- X else if(sleepsec<0) /* second pass, release everything we acquired */
- X unlink(cp);
- X else
- X { time_t t;int permanent;
- X setgid(getgid()); /* just to be on the safe side */
- Xstilv: virgin=0;permanent=nfsTRY;
- X while(0>xcreat(cp,&t)) /* try and lock */
- X { struct stat stbuf;
- X if(exitflag) /* time to stop? */
- X { if(exitflag==1) /* was it failure() or malloc() */
- Xoutofmem: retval=EX_OSERR,nlog("Out of memory");
- X else
- X retval=EX_TEMPFAIL,nlog("Signal received");
- X goto lfailure;
- X }
- X switch(errno) /* why did the lock not succeed? */
- X { case EEXIST: /* hmmm..., by force then? */
- X if(force&&!lstat(cp,&stbuf)&&force<t-stbuf.st_mtime)
- X { nlog(unlink(cp)?"Forced unlock denied on \"":
- X "Forcing lock on \"");
- X elog(cp);elog("\"\n");sleep(suspend); /* important */
- X }
- X else /* no forcing now */
- X case ENOSPC:
- X#ifdef EDQUOT
- X case EDQUOT:
- X#endif
- X switch(retries) /* await your turn like everyone else */
- X { case 0:nlog("Sorry");retval=EX_CANTCREAT;
- X goto lfailure; /* patience exhausted, give up */
- X default:retries--; /* count sheep */
- X case -1:sleep(sleepsec); /* wait and see */
- X }
- X break;
- X case ENOENT:case ENOTDIR:case EIO:case EACCES:
- X if(!--permanent) /* NFS sporadically generates these */
- X { sleep(sleepsec);continue; /* unwarranted */
- X } /* so ignore them first */
- X default: /* but, it seems to persist, so give up */
- X nlog("Try praying");retval=EX_UNAVAILABLE;
- X#ifdef ENAMETOOLONG
- X goto lfailure;
- X case ENAMETOOLONG:
- X if(0<(permanent=strlen(cp)-1)&& /* can we truncate it? */
- X !strchr(dirsep,cp[permanent-1]))
- X { nlog("Truncating \"");elog(cp); /* then try it */
- X elog("\" and retrying lock\n");cp[permanent]='\0';break;
- X } /* otherwise, forget it */
- X nlog("Filename too long");retval=EX_UNAVAILABLE;
- X#endif
- Xlfailure: elog(", giving up on \"");elog(cp);elog("\"\n");
- Xnfailure: sleepsec= -1;argc=lastf-argv+1;goto again; /* mark sleepsec */
- X } /* for second pass, and adjust argc to the no. of args parsed */
- X permanent=nfsTRY; /* refresh the NFS-error-ignore count */
- X }
- X lastf=p; /* last valid file */
- X }
- X if(retval==EX_OK&&virgin) /* any errors? did we do anything? */
- Xusg:
- X { elog(usage);return EX_USAGE;
- X }
- X if(invert)
- X switch(retval) /* we only invert the regular cases */
- X { case EX_OK:return EX_CANTCREAT;
- X case EX_CANTCREAT:return EX_OK;
- X }
- X return retval; /* all other exitcodes remain */
- X}
- X
- Xvoid*tmalloc(len)const size_t len; /* stub */
- X{ return malloc(len);
- X}
- X
- Xropen(name,mode,mask)const char*const name;const int mode;const mode_t mask;
- X{ return open(name,mode,mask); /* stub */
- X}
- X
- Xrclose(fd)const int fd; /* stub */
- X{ return close(fd);
- X}
- X
- Xvoid writeerr(a)const char*const a; /* stub */
- X{
- X}
- END_OF_FILE
- if test 9425 -ne `wc -c <'procmail280/src/lockfile.c'`; then
- echo shar: \"'procmail280/src/lockfile.c'\" unpacked with wrong size!
- fi
- # end of 'procmail280/src/lockfile.c'
- fi
- if test -f 'procmail280/src/mailfold.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail280/src/mailfold.c'\"
- else
- echo shar: Extracting \"'procmail280/src/mailfold.c'\" \(9757 characters\)
- sed "s/^X//" >'procmail280/src/mailfold.c' <<'END_OF_FILE'
- X/************************************************************************
- X * Routines that deal with the mailfolder(format) *
- X * *
- X * Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands *
- X * #include "README" *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic /*const*/char rcsid[]=
- X "$Id: mailfold.c,v 1.19 1993/02/04 12:44:55 berg Exp $";
- X#endif
- X#include "procmail.h"
- X#include "sublib.h"
- X#include "robust.h"
- X#include "shell.h"
- X#include "misc.h"
- X#include "pipes.h"
- X#include "common.h"
- X#include "exopen.h"
- X#include "locking.h"
- X#include "mailfold.h"
- X#ifndef NO_COMSAT
- X#include "network.h"
- X
- Xconst char scomsat[]="COMSAT";
- X#endif
- Xint logopened,tofile;
- Xlong lasttell;
- Xstatic long lastdump;
- Xstatic volatile mailread; /* if the mail is completely read in already */
- Xstatic struct dyna_long escFrom_,confield; /* escapes, concatenations */
- X /* inserts escape characters on outgoing mail */
- Xstatic long getchunk(s,fromw,len)const int s;const char*fromw;const long len;
- X{ long dist,dif;int i;static char esc[]={ESCAP};
- X dist=fromw-themail; /* where are we now in transmitting? */
- X for(dif=len,i=0;i<escFrom_.filled;) /* let's see if we can find this */
- X if(!(dif=escFrom_.offs[i++]-dist)) /* this exact spot? */
- X { rwrite(s,esc,sizeof esc);lastdump++; /* escape it */
- X if(i>=escFrom_.filled) /* last block? */
- X return len; /* yes, give all what's left */
- X dif=escFrom_.offs[i]-dist;break; /* the whole next block */
- X }
- X else if(dif>0) /* passed this spot already? */
- X break;
- X return dif<len?dif:len;
- X}
- X
- Xlong dump(s,source,len)const int s;const char*source;long len;
- X{ int i;long part;
- X lasttell=i= -1;
- X if(s>=0)
- X { if(tofile&&(lseek(s,0L,SEEK_END),fdlock(s)))
- X nlog("Kernel-lock failed\n");
- X lastdump=len;part=tofile==to_FOLDER?getchunk(s,source,len):len;
- X lasttell=lseek(s,0L,SEEK_END);smboxseparator(s); /* optional separator */
- X#ifndef NO_NFS_ATIME_HACK
- X if(part&&tofile) /* if it is a file, trick NFS into an */
- X len--,part--,rwrite(s,source++,1),sleep(1); /* a_time<m_time */
- X#endif
- X goto jin;
- X do
- X { part=getchunk(s,source,len);
- Xjin: while(part&&(i=rwrite(s,source,BLKSIZ<part?BLKSIZ:(int)part)))
- X { if(i<0)
- X { i=0;goto writefin;
- X }
- X part-=i;len-=i;source+=i;
- X }
- X }
- X while(len);
- X if(!len&&(lastdump<2||!(source[-1]=='\n'&&source[-2]=='\n')))
- X lastdump++,rwrite(s,newline,1); /* message always ends with a */
- X emboxseparator(s); /* newline and an optional custom separator */
- Xwritefin:
- X if(tofile&&fdunlock())
- X nlog("Kernel-unlock failed\n");
- X i=rclose(s);
- X } /* return an error even if nothing was to be sent */
- X tofile=0;return i&&!len?-1:len;
- X}
- X /* open file or new file in directory */
- Xdeliver(boxname)char*const boxname;
- X{ struct stat stbuf;
- X tofile=to_FILE;strcpy(buf,boxname); /* boxname can be found back in buf */
- X return stat(buf,&stbuf)||!S_ISDIR(stbuf.st_mode)?
- X (tofile=strcmp(devnull,buf)?to_FOLDER:0,opena(buf)):dirmail();
- X}
- X
- Xvoid logabstract P((void))
- X{ if(logopened) /* make sure that this doesn't get mailed back */
- X { char*chp,*chp2;int i;static const char sfolder[]=FOLDER;
- X if(mailread) /* is the mail completely read in? */
- X { *thebody='\0'; /* terminate the header, just in case */
- X if(eqFrom_(chp=themail)) /* any "From " header */
- X { if(chp=strchr(themail,'\n'))
- X *chp++='\0';
- X else
- X chp=thebody; /* preserve mailbox format */
- X elog(themail);elog(newline); /* (any length) */
- X }
- X if(!(lcking&lck_ALLOCLIB)&& /* don't reenter malloc/free */
- X (chp=egrepin(NSUBJECT,chp,(long)(thebody-chp),0)))
- X { for(chp2= --chp;*--chp2!='\n'&&*chp2;);
- X if(chp-++chp2>MAXSUBJECTSHOW) /* keep it within bounds */
- X chp2[MAXSUBJECTSHOW]='\0';
- X *chp='\0';detab(chp2);elog(" ");elog(chp2);elog(newline);
- X }
- X }
- X elog(sfolder);
- X i=strlen(strncpy(buf,lastfolder,MAXfoldlen))+STRLEN(sfolder);
- X buf[MAXfoldlen]='\0';detab(buf);elog(buf);i-=i%TABWIDTH; /* last dump */
- X do elog(TABCHAR);
- X while((i+=TABWIDTH)<LENoffset);
- X ultstr(7,lastdump,buf);elog(buf);elog(newline);
- X }
- X#ifndef NO_COMSAT
- X ;{ int s;struct sockaddr_in addr;char*chp,*chad; /* @ seperator? */
- X if(chad=strchr(chp=(char*)tgetenv(scomsat),SERV_ADDRsep))
- X *chad++='\0'; /* split it up in service and hostname */
- X else if(!renvint(-1L,scomsat)) /* or is it a false boolean? */
- X return; /* ok, no comsat then */
- X if(!chad||!*chad) /* no host */
- X#ifndef IP_localhost
- X chad=COMSAThost; /* use default */
- X#else /* IP_localhost */
- X { static const unsigned char ip_localhost[]=IP_localhost;
- X addr.sin_family=AF_INET;
- X tmemmove(&addr.sin_addr,ip_localhost,sizeof ip_localhost);
- X }
- X else
- X#endif /* IP_localhost */
- X { const struct hostent*host; /* what host? paranoid checks */
- X if(!(host=gethostbyname(chad))||!host->h_0addr_list)
- X { endhostent();return; /* host can't be found, too bad */
- X }
- X addr.sin_family=host->h_addrtype; /* address number found */
- X tmemmove(&addr.sin_addr,host->h_0addr_list,host->h_length);
- X endhostent();
- X }
- X if(!*chp) /* no service */
- X chp=BIFF_serviceport; /* use default */
- X s=strtol(chp,&chad,10);
- X if(chp==chad) /* the service is not numeric */
- X { const struct servent*serv;
- X if(!(serv=getservbyname(chp,COMSATprotocol))) /* so get its no. */
- X { endservent();return;
- X }
- X addr.sin_port=serv->s_port;endservent();
- X }
- X else
- X addr.sin_port=htons((short)s); /* network order */
- X cat(tgetenv(lgname),"@"); /* should always fit in buf */
- X if(lasttell>=0) /* was it a file? */
- X ultstr(0,lasttell,buf2),catlim(buf2); /* yep */
- X catlim(COMSATxtrsep); /* custom seperator */
- X if(lasttell>=0&&!strchr(dirsep,*lastfolder)) /* relative filename? */
- X catlim(tgetenv(maildir)),catlim(_MCDIRSEP); /* prepend current dir */
- X catlim(lastfolder);s=socket(AF_INET,SOCK_DGRAM,UDP_protocolno);
- X sendto(s,buf,strlen(buf),0,(const void*)&addr,sizeof(addr));rclose(s);
- X yell("Notified comsat:",buf);
- X }
- X#endif /* NO_COMSAT */
- X}
- X
- Xstatic concnd; /* last concatenation value */
- X
- Xvoid concon(ch)const int ch; /* flip between concatenated and split fields */
- X{ size_t i;
- X if(concnd!=ch) /* is this run redundant? */
- X { concnd=ch; /* no, but note this one for next time */
- X for(i=confield.filled;i;) /* step through the saved offsets */
- X themail[confield.offs[--i]]=ch; /* and flip every one */
- X }
- X}
- X
- Xvoid readmail(rhead,tobesent)const long tobesent;
- X{ char*chp,*pastend,*realstart;
- X ;{ long dfilled;
- X if(rhead) /* only read in a new header */
- X { dfilled=mailread=0;chp=readdyn(malloc(1),&dfilled);filled-=tobesent;
- X if(tobesent<dfilled) /* adjust buffer size (grow only) */
- X themail=realloc(themail,dfilled+filled);
- X tmemmove(themail+dfilled,thebody,filled);tmemmove(themail,chp,dfilled);
- X free(chp);themail=realloc(themail,1+(filled+=dfilled));
- X }
- X else
- X { if(!mailread||!filled)
- X rhead=1; /* yup, we read in a new header as well as new mail */
- X mailread=0;dfilled=thebody-themail;themail=readdyn(themail,&filled);
- X }
- X pastend=filled+(thebody=themail);
- X while(thebody<pastend&&*thebody++=='\n'); /* skip leading garbage */
- X realstart=thebody;
- X if(rhead) /* did we read in a new header anyway? */
- X { confield.filled=0;concnd='\n';
- X while(thebody=
- X egrepin("[^\n]\n[\n\t ]",thebody,(long)(pastend-thebody),1))
- X if(thebody[-1]!='\n') /* mark continuated fields */
- X app_val(&confield,(long)(--thebody-1-themail));
- X else
- X goto eofheader; /* empty line marks end of header */
- X thebody=pastend; /* provide a default, in case there is no body */
- Xeofheader:;
- X }
- X else /* no new header read, keep it simple */
- X thebody=themail+dfilled; /* that means we know where the body starts */
- X }
- X ;{ int f1stchar; /* to make sure that the first From_ line is uninjured */
- X f1stchar= *realstart;*(chp=realstart)='\0';escFrom_.filled=0;
- X while(chp=egrepin(FROM_EXPR,chp,(long)(pastend-chp),1))
- X { while(*--chp!='\n'); /* where did this line start? */
- X app_val(&escFrom_,(long)(++chp-themail));chp++; /* bogus! */
- X }
- X *realstart=f1stchar;mailread=1;
- X }
- X}
- X
- Xdirmail P((void)) /* buf should contain directory name */
- X{ char*chp;struct stat stbuf;
- X if((chp=strchr(buf,'\0')-1)-1>=buf&&chp[-1]==*_MCDIRSEP&&*chp==chCURDIR)
- X *chp='\0',strcpy(buf2,buf); /* it ended in /. */
- X else
- X chp=0,strcpy(buf2,strcat(buf,_MCDIRSEP));
- X if(unique(buf2,strchr(buf2,'\0'),NORMperm,verbose))
- X { if(chp)
- X { long i=0; /* first let us try to prime i with the */
- X#ifndef NOopendir /* highest MH folder number we can find */
- X long j;DIR*dirp;struct dirent*dp;char*chp2;
- X *chp='\0';yell("Opening directory",buf);
- X if(dirp=opendir(buf))
- X { while(dp=readdir(dirp)) /* there still are directory entries */
- X if((j=strtol(dp->d_name,&chp2,10))>i&&!*chp2)
- X i=j; /* yep, we found a higher number */
- X closedir(dirp); /* aren't we neat today */
- X }
- X else
- X readerr(buf);
- X#endif /* NOopendir */
- X do ultstr(0,++i,chp); /* find first empty MH folder */
- X while(link(buf2,buf)&&errno==EEXIST);
- X unlink(buf2);goto opn;
- X }
- X stat(buf2,&stbuf);
- X ultoan((unsigned long)stbuf.st_ino, /* filename with i-node number */
- X strchr(strcat(buf,tgetenv(msgprefix)),'\0'));
- X if(!myrename(buf2,buf)) /* rename it, we need the same i-node */
- Xopn: return opena(buf);
- X }
- X return -1;
- X}
- END_OF_FILE
- if test 9757 -ne `wc -c <'procmail280/src/mailfold.c'`; then
- echo shar: \"'procmail280/src/mailfold.c'\" unpacked with wrong size!
- fi
- # end of 'procmail280/src/mailfold.c'
- fi
- if test -f 'procmail280/src/misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'procmail280/src/misc.c'\"
- else
- echo shar: Extracting \"'procmail280/src/misc.c'\" \(9939 characters\)
- sed "s/^X//" >'procmail280/src/misc.c' <<'END_OF_FILE'
- X/************************************************************************
- X * Miscellaneous routines used by procmail *
- X * *
- X * Copyright (c) 1990-1992, S.R. van den Berg, The Netherlands *
- X * #include "README" *
- X ************************************************************************/
- X#ifdef RCS
- Xstatic /*const*/char rcsid[]=
- X "$Id: misc.c,v 1.18 1993/02/02 15:27:13 berg Exp $";
- X#endif
- X#include "procmail.h"
- X#include "sublib.h"
- X#include "robust.h"
- X#include "misc.h"
- X#include "pipes.h"
- X#include "common.h"
- X#include "cstdio.h"
- X#include "exopen.h"
- X#include "regexp.h"
- X#include "goodies.h"
- X#include "locking.h"
- X#include "mailfold.h"
- X
- Xstruct varval strenvvar[]={{"LOCKSLEEP",DEFlocksleep},
- X {"LOCKTIMEOUT",DEFlocktimeout},{"SUSPEND",DEFsuspend},
- X {"NORESRETRY",DEFnoresretry},{"TIMEOUT",DEFtimeout},{"VERBOSE",DEFverbose}};
- Xint didchd;
- Xstatic fakedelivery;
- X /* line buffered to keep concurrent entries untangled */
- Xvoid elog(newt)const char*const newt;
- X{ int lnew,i;static lold;static char*old;char*p;
- X#ifndef O_CREAT
- X lseek(STDERR,0L,SEEK_END); /* locking should be done actually */
- X#endif
- X if(!(lnew=strlen(newt))||nextexit) /* force flush? */
- X goto flush;
- X i=lold+lnew;
- X if(p=lold?realloc(old,i):malloc(i)) /* unshelled malloc */
- X { memmove((old=p)+lold,newt,(size_t)lnew); /* append */
- X if(p[(lold=i)-1]=='\n') /* EOL? */
- X rwrite(STDERR,p,i),lold=0,free(p); /* flush the line(s) */
- X }
- X else /* no memory, force flush */
- Xflush:
- X { if(lold)
- X { rwrite(STDERR,old,lold);lold=0;
- X if(!nextexit)
- X free(old); /* don't use free in signal handlers */
- X }
- X if(lnew)
- X rwrite(STDERR,newt,lnew);
- X }
- X}
- X
- X#include "shell.h"
- X
- Xvoid ignoreterm P((void))
- X{ signal(SIGTERM,SIG_IGN);signal(SIGHUP,SIG_IGN);signal(SIGINT,SIG_IGN);
- X signal(SIGQUIT,SIG_IGN);
- X}
- X
- Xvoid writeerr(line)const char*const line;
- X{ nlog("Error while writing to");logqnl(line);
- X}
- X
- Xforkerr(pid,a)const pid_t pid;const char*const a;
- X{ if(pid==-1)
- X { nlog("Failed forking");logqnl(a);return 1;
- X }
- X return 0;
- X}
- X
- Xvoid progerr(line)const char*const line;
- X{ nlog("Program failure of");logqnl(line);
- X}
- X
- Xvoid chderr(dir)const char*const dir;
- X{ nlog("Couldn't chdir to");logqnl(dir);
- X}
- X
- Xvoid readerr(file)const char*const file;
- X{ nlog("Couldn't read");logqnl(file);
- X}
- X
- Xvoid yell(a,b)const char*const a,*const b; /* log if VERBOSE=on */
- X{ if(verbose)
- X nlog(a),logqnl(b);
- X}
- X
- Xvoid nlog(a)const char*const a;
- X{ elog(procmailn);elog(": ");elog(a);
- X}
- X
- Xvoid logqnl(a)const char*const a;
- X{ elog(oquote);elog(a);elog(cquote);
- X}
- X
- Xvoid skipped(x)const char*const x;
- X{ if(*x)
- X nlog("Skipped"),logqnl(x);
- X}
- X
- Xnextrcfile P((void)) /* 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
- Xvoid sterminate P((void))
- 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;nlog("Terminating prematurely");
- X if(!(lcking&lck_LOCKFILE))
- X { register unsigned i,j;
- X if(i=(lcking&~(lck_ALLOCLIB|lck_LOCKFILE))>>1)
- X { elog(whilstwfor);
- X for(j=0;!((i>>=1)&1);j++);
- X elog(msg[j]);
- X }
- X elog(newline);terminate();
- X }
- X }
- X}
- X
- Xvoid terminate P((void))
- X{ ignoreterm();
- X if(retvl2!=EX_OK)
- X fakedelivery=0,retval=retvl2;
- X if(getpid()==thepid)
- X { if(retval!=EX_OK)
- X { tofile=0;lasttell= -1; /* make sure that logabstract knows */
- X lastfolder=fakedelivery?"**Lost**": /* don't free() here */
- X retval==EX_TEMPFAIL?"**Requeued**":"**Bounced**";
- X }
- X logabstract();closerc();
- X if(!(lcking&lck_ALLOCLIB)) /* don't reenter malloc/free */
- X exectrap(tgetenv("TRAP"));
- X nextexit=2;unlock(&loclock);unlock(&globlock);fdunlock();
- X }
- X exit(fakedelivery==2?EX_OK:retval);
- X}
- X
- Xvoid suspend P((void))
- 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
- Xvoid app_val(sp,val)struct dyna_long*const sp;const long val;
- X{ if(sp->filled==sp->tspace) /* growth limit reached? */
- X { if(!sp->offs)
- X sp->offs=malloc(1);
- X sp->offs=realloc(sp->offs,(sp->tspace+=4)*sizeof sp->offs); /* expand */
- X }
- X sp->offs[sp->filled++]=val; /* append to it */
- X}
- X
- Xalphanum(c)const unsigned c;
- X{ return c-'0'<='9'-'0'||c-'a'<='z'-'a'||c-'A'<='Z'-'A'||c=='_';
- X}
- X
- Xvoid firstchd P((void))
- X{ if(!didchd) /* have we been here already? */
- X { const char*p;
- X didchd=1; /* no, well, then try an initial chdir */
- X if(chdir(p=tgetenv(maildir)))
- X { chderr(p);
- X if(chdir(p=tgetenv(home)))
- X chderr(p);
- X }
- X }
- X}
- X
- Xvoid srequeue P((void))
- X{ retval=EX_TEMPFAIL;sterminate();
- X}
- X
- Xvoid slose P((void))
- X{ fakedelivery=2;sterminate();
- X}
- X
- Xvoid sbounce P((void))
- X{ retval=EX_CANTCREAT;sterminate();
- X}
- X
- Xvoid catlim(src)register const char*src;
- X{ register char*dest=buf;register size_t lim=linebuf;
- X while(lim&&*dest)
- X dest++,lim--;
- X if(lim)
- X { while(--lim&&(*dest++= *src++));
- X *dest='\0';
- X }
- X}
- X
- Xvoid setdef(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
- Xvoid metaparse(p)const char*p; /* result in buf */
- X{ if(sh=!!strpbrk(p,tgetenv(shellmetas)))
- X strcpy(buf,p); /* copy literally, shell will parse */
- X else
- X#ifndef GOT_bin_test
- X { sgetcp=p=tstrdup(p);
- X readparse(buf,sgetc,0); /* parse it yourself */
- X if(!strcmp(test,buf))
- X strcpy(buf,p),sh=1; /* oops, `test' found */
- X free((char*)p);
- X }
- X#else
- X sgetcp=p,readparse(buf,sgetc,0);
- X#endif
- X}
- X
- Xvoid concatenate(p)register char*p;
- X{ while(*p!=TMNATE) /* concatenate all other arguments */
- X { while(*p++);
- X p[-1]=' ';
- X }
- X *p=p[-1]='\0';
- X}
- X
- Xchar*lastdirsep(filename)const char*filename; /* finds the next character */
- X{ const char*p; /* following the last DIRSEP */
- X while(p=strpbrk(filename,dirsep))
- X filename=p+1;
- X return(char*)filename;
- X}
- X
- Xchar*cat(a,b)const char*const a,*const b;
- X{ return strcat(strcpy(buf,a),b);
- X}
- X
- Xchar*tstrdup(a)const char*const a;
- X{ int i;
- X i=strlen(a)+1;return tmemmove(malloc(i),a,i);
- X}
- X
- Xconst char*tgetenv(a)const char*const a;
- X{ const char*b;
- X return(b=getenv(a))?b:"";
- X}
- X
- Xchar*cstr(a,b)char*const a;const char*const b; /* dynamic buffer management */
- X{ if(a)
- X free(a);
- X return tstrdup(b);
- X}
- X
- Xchar*skpspace(chp)const char*chp;
- X{ for(;;chp++)
- X switch(*chp)
- X { case ' ':case '\t':continue;
- X default:return(char*)chp;
- X }
- X}
- X
- Xchar*gobenv(chp)char*chp;
- X{ int found,i;
- X for(found=0;alphanum(i=getb());found=1,*chp++=i);
- X *chp='\0';ungetb(i);
- X switch(i)
- X { case ' ':case '\t':case '\n':case '=':return chp;
- X }
- X return 0;
- X}
- X
- Xvoid asenvcpy(src)char*src;
- X{ strcpy(buf,src);
- X if(src=strchr(buf,'=')) /* is it an assignment? */
- X { strcpy((char*)(sgetcp=buf2),++src);readparse(src,sgetc,2);sputenv(buf);
- X src[-1]='\0';asenv(src);
- X }
- X}
- X
- Xvoid asenv(chp)const char*const chp;
- X{ static const char slinebuf[]="LINEBUF",logfile[]="LOGFILE",Log[]="LOG",
- X sdelivered[]="DELIVERED",includerc[]="INCLUDERC",eumask[]="UMASK",
- X host[]="HOST";
- X if(!strcmp(buf,slinebuf))
- X { if((linebuf=renvint(0L,chp)+XTRAlinebuf)<MINlinebuf+XTRAlinebuf)
- X linebuf=MINlinebuf+XTRAlinebuf; /* check minimum size */
- X free(buf);free(buf2);buf=malloc(linebuf);buf2=malloc(linebuf);
- X }
- X else if(!strcmp(buf,maildir))
- X if(chdir(chp))
- X chderr(chp);
- X else
- X didchd=1;
- X else if(!strcmp(buf,logfile))
- X openlog(chp);
- X else if(!strcmp(buf,Log))
- X elog(chp);
- X else if(!strcmp(buf,sdelivered)) /* fake delivery */
- X { if(renvint(0L,chp)) /* is it really? */
- X { lcking|=lck_LOCKFILE; /* just to prevent interruptions */
- X if((thepid=sfork())>0)
- X { nextexit=2;lcking&=~lck_LOCKFILE;exit(retvl2);
- X } /* signals may cause trouble */
- X if(!forkerr(thepid,procmailn))
- X fakedelivery=1;
- X thepid=getpid();lcking&=~lck_LOCKFILE;
- X if(nextexit) /* signals occurred so far? */
- X elog(newline),terminate();
- X }
- X }
- X else if(!strcmp(buf,lockfile))
- X lockit((char*)chp,&globlock);
- X else if(!strcmp(buf,eumask))
- X umask((int)strtol(chp,(char**)0,8));
- X else if(!strcmp(buf,includerc))
- X pushrc(chp);
- X else if(!strcmp(buf,host))
- X { const char*name;
- X if(strncmp(chp,name=hostname(),HOSTNAMElen))
- X { yell("HOST mismatched",name);
- X if(rc<0||!nextrcfile()) /* if no rcfile opened yet */
- X retval=EX_OK,terminate(); /* exit gracefully as well */
- X closerc();rc=rc_NOFILE;
- X }
- X }
- X else
- X { int i=MAXvarvals;
- X do /* several numeric assignments */
- X if(!strcmp(buf,strenvvar[i].name))
- X { strenvvar[i].val=renvint(strenvvar[i].val,chp);break;
- X }
- X while(i--);
- X }
- X}
- X
- Xlong renvint(i,env)const long i;const char*const env;
- X{ const char*p;long t;
- X t=strtol(env,(char**)&p,10); /* parse like a decimal nr */
- X if(p==env)
- X { for(;;p++) /* skip leading whitespace */
- X { switch(*p)
- X { case '\t':case ' ':continue;
- X }
- X break;
- X }
- X t=i;
- X if(!strnIcmp(p,"on",(size_t)2)||!strnIcmp(p,"y",(size_t)1)||
- X !strnIcmp(p,"t",(size_t)1))
- X t=1;
- X else if(!strnIcmp(p,"off",(size_t)3)||!strnIcmp(p,"n",(size_t)1)||
- X !strnIcmp(p,"f",(size_t)1))
- X t=0;
- X }
- X return t;
- X}
- X
- Xchar*egrepin(expr,source,len,casesens)char*expr;const char*source;
- X const long len;
- X{ source=(const char*)bregexec((struct eps*)(expr=(char*)
- X bregcomp(expr,!casesens)),(const uchar*)source,len>0?
- X (size_t)len:(size_t)0,!casesens);
- X free(expr);return(char*)source;
- X}
- END_OF_FILE
- if test 9939 -ne `wc -c <'procmail280/src/misc.c'`; then
- echo shar: \"'procmail280/src/misc.c'\" unpacked with wrong size!
- fi
- # end of 'procmail280/src/misc.c'
- fi
- echo shar: End of archive 7 \(of 11\).
- cp /dev/null ark7isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-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
-
- "Be spontaneous!"
-
- exit 0 # Just in case...
-