home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume35
/
procmail
/
part05
< prev
next >
Wrap
Text File
|
1993-02-05
|
43KB
|
1,325 lines
Newsgroups: comp.sources.misc
From: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
Subject: v35i026: procmail - mail processing package v2.80, Part05/11
Message-ID: <1993Feb5.020428.16527@sparky.imd.sterling.com>
X-Md4-Signature: 036de9ceec6c4d9abd9091886ddb041e
Date: Fri, 5 Feb 1993 02:04:28 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 26
Archive-name: procmail/part05
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 5 (of 11)."
# Contents: procmail280/mailinglist/Manual procmail280/man/formail.man
# procmail280/src/includes.h procmail280/src/manconf.c
# procmail280/src/pipes.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/mailinglist/Manual' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'procmail280/mailinglist/Manual'\"
else
echo shar: Extracting \"'procmail280/mailinglist/Manual'\" \(8524 characters\)
sed "s/^X//" >'procmail280/mailinglist/Manual' <<'END_OF_FILE'
X$Id: Manual,v 1.4 1993/01/29 13:32:44 berg Exp $
X
X Written by Stephen R. van den Berg.
X berg@pool.informatik.rwth-aachen.de
X berg@physik.tu-muenchen.de
X
XContents:
X--------- 1. Creating and removing mailinglists
X 2. Remote maintenance of mailinglists
X 3. Customisation
X 4. The archive server
X 5. The format of the dist file
X
X
X1. Creating and removing mailinglists
X ----------------------------------
X
XMake sure that the .bin directory is in your PATH. Now you can issue
Xcommands like:
X
X createlist testing
X createlist testing joe@somewhere.edu
X removelist testing
X
XThe first command creates a mailinglist with two useful addresses:
X
X testing
X testing-request
X
XThe second command does the same, but it also specifies joe@somewhere.edu
Xto be the responsible contact person for this list.
X
XThe third command removes all traces of the "testing" mailinglist again.
X
XThere is one other convenience-utility that can be used: "delink"
XIt will unlink a file from its hardlinked counterpart(s).
X
X
X2. Remote maintenance of mailinglists
X ----------------------------------
X
XTo facilitate remote maintenance of some mailinglists by their maintainers
XI have created the .bin/x_command script. It parses mails sent to the
X-request address and can execute some administrative commands.
X
XThe mail should be sent to the -request address of a mailinglist and
Xshould contain a field in the header looking like this:
X
XX-Command: joe@somewhere.edu password command
X
X"command" can be anything of the following:
X
X subscribe mailaddress
X unsubscribe mailaddress
X showdist To list the distfile
X showlog To list the log
X wipelog To clear the log
X help To show this command summary
X info Ditto
X
XThe exact fieldname defaults to "X-Command", but can be customised to
Xwhatever you want.
X
XThe password defaults to "password", but can/should be changed.
X
XThe "joe@somewhere.edu" is always the mail address of the maintainer. Note
Xthat this has to match what was specified on the command line of
X"createlist" when the list was created.
X
XNote that the X-Command: field has to be part of the header, when it's
Xin the body of the mail, it has no effect.
X
XAnytime an X-Command: mail has been processed, the results will be
Xmailed back to the maintainer of the list, and the X-Command: field
Xwill have been renamed to X-Processed:.
X
XAlthough this remote-facility is convenient, some might argue that it
Xpresents a security hole. Well, in order to make this hole as small as
Xpossible, you can keep the password secret. Also, the exact mailaddress
Xof the maintainer might not be publicly known. You can simply change
Xthe X-Command field into something else like X-MyCommand. Above all, since
Xfaking mail is a well known possibility it would be ridiculous to take
Xmore precautions than these.
X
X
X3. Customisation
X -------------
X
XThe mailinglists can be customised in several ways:
X
X- For all the lists:
X - Since all the lists share the same help.txt, subscibe.txt, rc.init,
X rc.submit and rc.request files (hardlinked), any change to them
X will affect all lists.
X - Since all the lists have the .bin directory in their PATH, any
X change to one of the Bourne shell scripts in there will affect
X them all.
X- Per list:
X - Every list directory contains an "rc.custom" rcfile which can
X be edited to your hearts content to customise certain parameters
X for this list only.
X - For graver customisation you can remove the hardlink (using
X .bin/delink for example) to any of the files in a list directory and
X provide that list with its own copy in order to edit that to taste.
X - Since the current directory is in the PATH before the .bin
X directory you can create per-list copies of any of the Bourne shell
X scripts in .bin which can then be changed without affecting the
X other lists.
X- Per group of lists:
X - The same applies as when customising per list, but you should
X then hardlink the appropriate files among the group of list
X directories.
X
XIf you are not using the remote-maintenance facility and you start editing
Xor customising scripts/files by hand, then you should make sure that there
Xdoesn't arrive any mail to those lists that are affected by your changes.
X
XIf you are editing while the system is running you can temporarily put
Xincoming mails on hold; you can do this:
X
X- for all the lists by creating the file: .etc/rc.lock
X- only for one list by creating the file: rc.lock
X in the list directory of that list.
X
XThe .bin/flist command checks to see if these rc.lock files exist AND are
Xnot older than 17 minutes before delivering the mail. So, if you create
Xan rc.lock file, mails to that (or all) lists will stall for the next
X17 minutes. If you need more time, touch the file every so often.
XYou should remove the rc.lock files again after finishing your editing.
X
X
X4. The archive server
X ------------------
X
XAll mail (except mail being forwarded from another mailinglist) sent to any
Xof the lists is archived. The archiving is fairly straightforward.
XE.g. if you have a list called "scuba", then all submissions are archived
Xin scuba/archive/latest/. The mails will be stored one-mail-per-file each.
XThe files will be numbered.
X
XNow, normally, only the last two mails will be kept around, the others
Xare periodically removed. This in order to keep down the archiving costs
Xfor people with limited diskspace. To disable archiving completely,
Xedit the rc.submit file. To simply make the archive-history longer,
Xedit the rc.custom file. To get more sophisticated archiving, like grouping
Xsubmissions monthly, you should either create a cron job or edit the
X.bin/arch_trunc file.
X
XThe archive server can be accessed per mailinglist by sending mail
Xto the -request address with the following Subject:
X
X Subject: archive
X
XThe body of the mail or the rest of the subject line can then be
Xfiled with requests to the archive server. It basically understands
Xthree commands:
X
X get file ...
X ls directory ...
X help
X
XThe archive server does a thorough check on the commands and the files
Xthat are requested. This to ensure that it does not access any files
Xoutside the "scuba/archive" directory. Any text-file that you put below
Xthe "scuba/archive" directory can now be retrieved by the archive commands.
X
XThe whole archive server can be found in the .bin/arch_retrieve script.
X
X
X5. The format of the dist file
X ---------------------------
X
XYou do not need to know this, unless you edit the dist file by hand or want
Xto incorporate an existing list of addresses.
X
XIn order to distribute incoming submissions the dist file is fed to sendmail
Xwith the regular :include: alias. So the format of this file must
Xbe in accordance with what sendmail would expect. In addition to that
Xthis file is searched and edited by multigram in order to find particular
Xsubscribers. The format which multigram expects is a bit more rigid than
Xwhat sendmail allows.
X
XThe following conditions apply:
X- One subscriber per line.
X- Empty lines are allowed.
X- The mail address of the subscriber must be the first word on the line.
X- Comments may follow the address (but separated from the address by
X at least one whitespace character).
X- Everything preceding the line containing:
X (Only addresses below this line can be automatically removed)
X is write protected from changes by multigram (i.e. these addresses can
X never be automatically/accidentally unsubscribed).
X- If the line:
X (Only addresses below this line can be automatically removed)
X is not present at all, automatic unsubscriptions to this list are impossible.
X- Whenever multigram automatically removes an address from the list, it
X rewrites the dist file `in situ'. This means that the dist file will be
X contracted at that point, any excess slack at the end will be overwritten
X by newlines (i.e. the dist file never shrinks, this because ANSI-C does not
X provide a truncate() command of some kind). I choose to write in situ in
X order to avoid copying the dist file every time it changes (a real life
X saver if the list grows too big).
X- Multigram always adds new subscribers on the line immediately following the
X last filled entry in the dist file.
X
XSome sample entries (the preferred format):
X joe@some.where
X joe@some.where (some comment)
X joe@some.where (some comment) (some more comment)
X
XDepreciated, but allowed:
X <joe@some.where>
X <joe@some.where> some comment
X <joe@some.where> (some comment)
X
XNot allowed by multigram (although sendmail doesn't mind):
X (some comment) joe@some.where
X some comment <joe@some.where>
END_OF_FILE
if test 8524 -ne `wc -c <'procmail280/mailinglist/Manual'`; then
echo shar: \"'procmail280/mailinglist/Manual'\" unpacked with wrong size!
fi
# end of 'procmail280/mailinglist/Manual'
fi
if test -f 'procmail280/man/formail.man' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'procmail280/man/formail.man'\"
else
echo shar: Extracting \"'procmail280/man/formail.man'\" \(7358 characters\)
sed "s/^X//" >'procmail280/man/formail.man' <<'END_OF_FILE'
X.Id $Id: formail.man,v 1.8 1993/01/22 13:42:11 berg Exp $
X.TH FORMAIL 1 \*(Dt BuGless
X.na
X.SH NAME
Xformail \- mail (re)formatter
X.SH SYNOPSIS
X.B formail
X.RI [ "\fB\+FM_SKIP+\fPskip" ]
X.RI [ "\fB\+FM_TOTAL+\fPtotal" ]
X.RB [ \-+FM_BOGUS++FM_CONCATENATE++FM_FORCE++FM_REPLY++FM_KEEPB++FM_TRUST++FM_NOWAIT++FM_EVERY++FM_DIGEST++FM_QUIET+ ]
X.RB [ \-+FM_MINFIELDS+
X.IR "min fields" ]
X.if n .ti +0.5i
X.RB [ \-+FM_EXTRACT+
X.IR "header field" ]
X.RB [ \-+FM_EXTRC_KEEP+
X.IR "header field" ]
X.if n .ti +0.5i
X.RB [ \-+FM_ADD_IFNOT+
X.IR "header field" ]
X.RB [ \-+FM_ADD_ALWAYS+
X.IR "header field" ]
X.if n .ti +0.5i
X.RB [ \-+FM_REN_INSERT+
X.IR "header field" ]
X.RB [ \-+FM_DEL_INSERT+
X.IR "header field" ]
X.if n .ti +0.5i
X.RB [ \-+FM_ReNAME+
X.I "oldfield"
X.IR "newfield" ]
X.RB [ \-+FM_SPLIT+
X.I command
X.I arg
X\&.\|.\|.\|]
X.ad
X.Sh DESCRIPTION
X.B formail
Xis a filter that can be used to force mail into mailbox format, perform
X`+FROM+' escaping, generate auto-replying headers, do simple
Xheader munging/extracting or split up a
Xmailbox/digest/articles file. The mail/mailbox/article contents will be
Xexpected on stdin.
X.PP
XIf formail is supposed to determine the sender of the mail, but is unable
Xto find any, it will substitute `+UNKNOWN+'.
X.PP
XIf formail is started without any command line options, it will force any
Xmail coming from stdin into mailbox format and will escape
X.B all
Xbogus `+FROM+' lines with a `+ESCAP+'.
X.Sh OPTIONS
X.Tp 0.5i
X.B \-+FM_BOGUS+
XDon't escape any bogus mailbox headers (i.e. lines starting with `+FROM+').
X.Tp
X.B \-+FM_CONCATENATE+
XConcatenate continued fields in the header. Might be convenient when
Xpostprocessing mail with standard (line oriented) text utilities.
X.Tp
X.B \-+FM_FORCE+
XForce formail to simply pass along any non-mailbox format (i.e. don't
Xgenerate a `+FROM+' line as the first line).
X.Tp
X.B \-+FM_REPLY+
XGenerate an auto-reply header. This will normally throw away all the existing
Xfields in the original message, fields you wish to preserve need to be named
Xusing the
X.B \-+FM_REN_INSERT+
Xoption.
X.Tp
X.B \-+FM_KEEPB+
XWhen generating the auto-reply header, keep the body as well. If used
Xtogether with the
X.B \-+FM_BOGUS+
Xoption then the body will not be escaped.
X.Tp
X.B \-+FM_TRUST+
XTrust the sender to have used a valid return address in his header. This
Xoption will be most useful when generating auto-reply headers from news
Xarticles. If this option is not turned on, formail tends to favour
Xmachine-generated addresses in the header.
X.Tp
X.B \-+FM_SPLIT+
XThe input will be split up into separate mail messages, and piped into
Xa program one by one (a new program is started for every part).
X.B \-+FM_SPLIT+
Xhas to be the last option specified, the first argument following it
Xis expected to be the name of a program, any other arguments will be passed
Xalong to it.
X.Tp
X.B \-+FM_NOWAIT+
XTell formail not to wait for every program to finish before starting the next.
X.Tp
X.B \-+FM_EVERY+
XDo not require empty lines preceding the header of a new message (i.e. the
Xmessages could start on every line).
X.Tp
X.B \-+FM_DIGEST+
XTell formail that the messages it is supposed to split need not be in strict
Xmailbox format (i.e. allows you to split digests/articles or non-standard
Xmailbox formats).
X.Tp
X.I "\fB\-+FM_MINFIELDS+\fP min fields"
XAllows you to specify the number of consecutive fields formail needs to find
Xbefore it decides it found the start of a new message, it defaults to
X+DEFminfields+.
X.Tp
X.B \-+FM_QUIET+
XTells formail to ignore any write errors on stdout.
X.Tp
X.I "\fB\-+FM_EXTRACT+\fP header field"
XExtract the contents of this
X.I header field
Xfrom the header, display it as a single line.
X.Tp
X.I "\fB\-+FM_EXTRC_KEEP+\fP header field"
XSame as
X.BR \-+FM_EXTRACT+ ,
Xbut also preserves the field name.
X.Tp
X.I "\fB\-+FM_ADD_IFNOT+\fP header field"
XAppend a custom
X.I header field
Xonto the header; but only if a similar field does not exist yet.
X.Tp
X.I "\fB\-+FM_ADD_ALWAYS+\fP header field"
XAppend a custom
X.I header field
Xonto the header in any case.
X.Tp
X.I "\fB\-+FM_REN_INSERT+\fP header field"
XSame as
X.BR \-+FM_ADD_IFNOT+ ,
Xexcept that any existing similar fields are renamed by prepending
Xan ``+OLD_PREFIX+'' prefix. If
X.I header field
Xconsists only of a field-name, it will not be appended.
X.Tp
X.I "\fB\-+FM_DEL_INSERT+\fP header field"
XSame as
X.BR \-+FM_REN_INSERT+ ,
Xexcept that any existing similar fields are simply removed.
X.Tp
X.I "\fB\-+FM_ReNAME+\fP oldfield newfield"
XRenames all occurrences of the fieldname
X.I oldfield
Xinto
X.IR newfield .
X.Tp
X.I "\fB\+FM_SKIP+\fPskip"
XSkip the first
X.I skip
Xmessages while splitting.
X.Tp
X.I "\fB\+FM_TOTAL+\fPtotal"
XOutput at most
X.I total
Xmessages while splitting.
X.Sh EXAMPLES
XTo split up a digest one usually uses:
X.Rs
Xformail +FM_SKIP+1 \-+FM_DIGEST++FM_SPLIT+ cat >>the_mailbox_of_your_choice
X.Re
Xor
X.Rs
Xformail +FM_SKIP+1 \-+FM_DIGEST++FM_SPLIT+ procmail
X.Re
X.PP
XTo supersede the Reply-To: field in a header you could use:
X.Rs
Xformail \-+FM_REN_INSERT+ "Reply-To: foo@bar"
X.Re
X.PP
XTo convert a non-standard mailbox file into a standard mailbox file you can
Xuse:
X.Rs
Xformail \-+FM_DIGEST++FM_SPLIT+ cat <old_mailbox >>new_mailbox
X.Re
X.PP
XOr, alternatively, if you have a very tolerant mailer:
X.Rs
Xformail \-+FM_ADD_IFNOT+ Date: \-+FM_DIGEST++FM_SPLIT+ cat <old_mailbox >>new_mailbox
X.Re
X.Sh MISCELLANEOUS
XThe regular expression that is used to find `real' postmarks is:
X.Rs
X"\en\en+FROM+[\et ]*[^\et\en ]+[\et ]+[^\en\et ]"
X.Re
X.Sh "SEE ALSO"
X.na
X.nh
X.BR mail (1),
X.BR binmail (1),
X.BR sendmail (8),
X.BR procmail (1),
X.BR sh (1)
X.hy
X.ad
X.Sh DIAGNOSTICS
X.Tp 2.3i
XCan't fork
XToo many processes on this machine.
X.Tp
XCouldn't write to stdout
XThe program that formail was trying to pipe into didn't accept all the data
Xformail sent to it; this diagnostic can be disabled by the
X.B \-+FM_QUIET+
Xoption.
X.Tp
XFailed to execute "x"
XProgram not in path, or not executable.
X.Tp
XFile table full
XToo many open files on this machine.
X.Tp
XInvalid field-name: "x"
XThe specified field-name "x" does not contain a colon or contains control
Xcharacters.
X.Sh WARNINGS
XYou can save yourself and others a lot of mischief if you try to avoid using
Xthis autoreply feature on mails coming through mailinglists. Depending
Xon the format of the incoming mail (which in turn depends on both the
Xoriginal sender's mail agent and the mailinglist setup) formail could
Xdecide to generate an autoreply header that replies to the list (if
Xthe original sender was careful enough though, formail will be able to pick
Xhis/her address, instead of the list's). Now if the list is not intelligent
Xenough (most aren't) this autoreply will be widely distributed.
X.Sh BUGS
XWhen formail has to generate a leading `+FROM+' line it normally will contain
Xthe current date. If formail is given the option `\-+FM_ADD_IFNOT+ Date:',
Xit will use the date from the `Date:' field in the header (if present).
XHowever, since formail copies it verbatim, the format will differ from that
Xexpected by most mail readers.
X.Sh MISCELLANEOUS
XFormail is eight-bit clean.
X.PP
XWhen formail has to determine the sender's address, every RFC 822 conforming
Xmail address is allowed. Formail will always strip down the address to
Xits minimal form (deleting excessive comments and whitespace).
X.Sh NOTES
XCalling up formail with the \-+HELPOPT1+ or \-+HELPOPT2+ options will cause
Xit to display a command-line help page.
END_OF_FILE
if test 7358 -ne `wc -c <'procmail280/man/formail.man'`; then
echo shar: \"'procmail280/man/formail.man'\" unpacked with wrong size!
fi
# end of 'procmail280/man/formail.man'
fi
if test -f 'procmail280/src/includes.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'procmail280/src/includes.h'\"
else
echo shar: Extracting \"'procmail280/src/includes.h'\" \(6896 characters\)
sed "s/^X//" >'procmail280/src/includes.h' <<'END_OF_FILE'
X/*$Id: includes.h,v 1.17 1993/02/04 12:44:52 berg Exp $*/
X
X#include "../autoconf.h"
X#include "../config.h"
X /* not all the "library identifiers" specified here need to be
X available for all programs in this package; some have substitutes
X as well (see autoconf); this is just an informal list */
X
X#ifndef _HPUX_SOURCE
X#define _HPUX_SOURCE /* sad, but needed on HP-UX when compiling -Aa */
X#endif
X#ifndef _CONVEX_SOURCE
X#define _CONVEX_SOURCE /* same story with Convex and -std */
X#endif
X
X#include <sys/types.h> /* pid_t mode_t uid_t gid_t */
X#ifndef UNISTD_H_MISSING
X#include <unistd.h> /* open() read() write() close() dup() pipe()
X /* fork() getuid() getpid() execve()
X execvp() sleep() */
X#endif
X#include <stdio.h> /* setbuf() fclose() stdin stdout stderr
X /* fopen() fread() fwrite() fgetc() getc()
X fdopen() putc() fputs() FILE EOF */
X#ifndef STDDEF_H_MISSING
X#include <stddef.h> /* ptrdiff_t size_t */
X#endif
X#ifndef STDLIB_H_MISSING
X#include <stdlib.h> /* getenv() malloc() realloc() free()
X /* strtol() exit() */
X#endif
X#include <time.h> /* time() ctime() time_t */
X#include <fcntl.h> /* fcntl() struct flock O_RDONLY O_WRONLY
X /* O_APPEND O_CREAT O_EXCL */
X#include <grp.h> /* getgrgid() struct group */
X#include <pwd.h> /* getpwuid() getpwnam() struct passwd */
X#ifndef DIRENT_H_MISSING
X#include <dirent.h> /* opendir() readdir() closedir() DIR
X /* struct dirent */
X#endif
X#ifndef SYS_WAIT_H_MISSING
X#include <sys/wait.h> /* wait() WIFEXITED() WIFSTOPPED()
X /* WEXITSTATUS() */
X#endif
X#ifndef SYS_UTSNAME_H_MISSING
X#include <sys/utsname.h> /* uname() utsname */
X#endif
X#include <sys/stat.h> /* stat() S_ISDIR() S_ISREG() struct stat */
X#include <signal.h> /* signal() kill() alarm() SIG_IGN SIGHUP
X /* SIGINT SIGQUIT SIGALRM SIGTERM */
X#ifndef STRING_H_MISSING
X#include <string.h> /* strcpy() strncpy() strcat() strlen()
X /* strspn() strcspn() strchr() strcmp()
X strncmp() strpbrk() strstr() memmove() */
X#endif
X#include <errno.h> /* EINTR EEXIST ENFILE EACCES EAGAIN */
X#ifndef SYSEXITS_H_MISSING
X#include <sysexits.h> /* EX_OK EX_USAGE EX_NOUSER EX_UNAVAILABLE
X /* EX_OSERR EX_OSFILE EX_CANTCREAT EX_IOERR
X EX_TEMPFAIL EX_NOPERM */
X#endif
X
X#ifdef STDLIB_H_MISSING
Xvoid*malloc(),*realloc();
Xconst char*getenv();
X#endif
X#ifdef DIRENT_H_MISSING
X#ifndef NDIR_H_MISSING
X#include <ndir.h>
X#define dirent direct
X#else
X#ifndef SYS_NDIR_H_MISSING
X#include <sys/ndir.h>
X#define dirent direct
X#else
X#ifndef SYS_DIR_H_MISSING
X#include <sys/dir.h>
X#define dirent direct
X#else /* due to brain-damaged NeXT sys/dirent.h contents */
X#ifndef SYS_DIRENT_H_MISSING /* sys/dirent.h must be moved down here */
X#include <sys/dirent.h>
X#else
X/* I give up, I can only hope that your system defines DIR and struct dirent */
X#endif
X#endif
X#endif
X#endif
X#endif /* DIRENT_H_MISSING */
X#ifdef STRING_H_MISSING
X#include <strings.h>
X#ifndef strchr
Xchar*strchr();
X#endif
Xchar*strpbrk();
X#endif
X#ifdef SYS_UTSNAME_H_MISSING
X#define NOuname
X#endif
X#ifdef SYSEXITS_H_MISSING
X /* Standard exit codes, original list maintained
X by Eric Allman (eric@berkeley, ucbvax!eric) */
X#define EX_OK 0
X#define EX_USAGE 64
X#define EX_NOUSER 67
X#define EX_UNAVAILABLE 69
X#define EX_OSERR 71
X#define EX_OSFILE 72
X#define EX_CANTCREAT 73
X#define EX_IOERR 74
X#define EX_TEMPFAIL 75
X#define EX_NOPERM 77
X#endif
X
X#if O_SYNC
X#else
X#undef O_SYNC
X#define O_SYNC 0
X#endif
X#ifndef O_RDONLY
X#define O_RDONLY 0
X#define O_WRONLY 1
X#endif
X#ifndef SEEK_SET
X#define SEEK_SET 0
X#define SEEK_CUR 1
X#define SEEK_END 2
X#endif
X#ifndef tell
X#define tell(fd) lseek(fd,0L,SEEK_CUR)
X#endif
X
X#ifndef EWOULDBLOCK
X#define EWOULDBLOCK EACCES
X#endif
X#ifndef EAGAIN
X#define EAGAIN EINTR
X#endif
X
X#ifndef EOF
X#define EOF (-1)
X#endif
X
X#ifndef S_ISDIR
X#define S_ISDIR(mode) (((mode)&S_IFMT)==S_IFDIR)
X#ifndef S_IFDIR
X#define S_IFDIR 0040000
X#endif
X#endif
X
X#ifndef S_ISREG
X#define S_ISREG(mode) (((mode)&S_IFMT)==S_IFREG)
X#ifndef S_IFREG
X#define S_IFREG 0100000
X#endif
X#endif
X
X#ifndef S_ISLNK
X#ifndef S_IFLNK
X#define lstat(path,stbuf) stat(path,stbuf)
X#define S_ISLNK(mode) 0
X#else
X#define S_ISLNK(mode) (((mode)&S_IFMT)==S_IFLNK)
X#endif
X#endif
X
X#ifndef S_IFMT
X#define S_IFMT 0170000
X#endif
X
X#ifndef S_IRWXU
X#define S_IRWXU 00700
X#define S_IRWXG 00070
X#define S_IRWXO 00007
X#endif
X#ifndef S_IWUSR
X#ifdef S_IREAD
X#define S_IRUSR S_IREAD
X#define S_IWUSR S_IWRITE
X#define S_IXUSR S_IEXEC
X#else
X#define S_IRUSR 0400
X#define S_IWUSR 0200
X#define S_IXUSR 0100
X#endif /* S_IREAD */
X#define S_IRGRP 0040
X#define S_IWGRP 0020
X#define S_IXGRP 0010
X#define S_IROTH 0004
X#define S_IWOTH 0002
X#define S_IXOTH 0001
X#endif /* S_IWUSR */
X#ifndef S_ISGID
X#define S_ISUID 04000
X#define S_ISGID 02000
X#endif
X
X#ifdef WMACROS_NON_POSIX
X#ifdef WIFEXITED
X#undef WIFEXITED
X#endif
X#ifdef WIFSTOPPED
X#undef WIFSTOPPED
X#endif
X#ifdef WEXITSTATUS
X#undef WEXITSTATUS
X#endif
X#endif /* WMACROS_NON_POSIX */
X
X#ifndef WIFEXITED
X#define WIFEXITED(waitval) (!((waitval)&255))
X#endif
X#ifndef WIFSTOPPED
X#define WIFSTOPPED(waitval) (((waitval)&255)==127)
X#endif
X#ifndef WEXITSTATUS
X#define WEXITSTATUS(waitval) ((waitval)>>8&255)
X#endif
X
Xextern /*const*/char**environ;
Xextern errno;
X
X#ifndef STDIN_FILENO
X#define STDIN 0
X#define STDOUT 1
X#define STDERR 2
X#else
X#define STDIN STDIN_FILENO
X#define STDOUT STDOUT_FILENO
X#define STDERR STDERR_FILENO
X#endif
X
X#ifdef NO_fcntl_LOCK
X#ifndef NOfcntl_lock
X#define NOfcntl_lock
X#endif
X#endif
X#ifdef NO_lockf_LOCK
X#ifdef USElockf
X#undef USElockf
X#endif
X#endif
X#ifdef NO_flock_LOCK
X#ifdef USEflock
X#undef USEflock
X#endif
X#endif
X
X#ifndef NOuname
X#ifndef P /* SINIX V5.23 has the wrong prototype for uname() */
Xextern int uname(); /* so we fix it :-) */
X#define Uname(name) ((int(*)(struct utsname*))uname)(name)
X#else
X#define Uname(name) uname(name) /* no fix needed */
X#endif /* P */
X#endif /* NOuname */
X /* NEWS OS 5.X has the wrong prototype here */
X#define Fdopen(fd,type) ((FILE*)fdopen(fd,type))
X
X#ifndef strchr /* for very old K&R compatible include files with */
X#ifdef P /* new K&R libraries */
X#ifdef const
Xextern char*strchr();
Xextern char*strpbrk();
Xextern char*strstr();
Xextern void*memmove();
X#endif
X#endif
X#endif
X
X#define Const /*const*/ /* Convex cc doesn't grok this */
X
X#ifdef NOrename
X#define rename(old,new) (-(link(old,new)||unlink(old)))
X#endif
X
X#ifdef NOmemmove
X#define memmove(to,from,count) smemmove(to,from,count)
X#endif
X
X#ifndef P
X#define P(args) args
X#endif
X#define Q(args) () /* needed until function definitions are ANSI too */
X
X#ifdef oBRAIN_DAMAGE
X#undef offsetof
X#endif
X#ifndef offsetof
X#define offsetof(s,m) ((char*)&(((s*)sizeof(s))->m)-(char*)sizeof(s))
X#endif
X
X#define PROGID const char progid[]="Stephen R. van den Berg"
X#define maxindex(x) (sizeof(x)/sizeof((x)[0])-1)
X#define STRLEN(x) (sizeof(x)-1)
X#define ioffsetof(s,m) ((int)offsetof(s,m))
X
X#define mx(a,b) ((a)>(b)?(a):(b))
END_OF_FILE
if test 6896 -ne `wc -c <'procmail280/src/includes.h'`; then
echo shar: \"'procmail280/src/includes.h'\" unpacked with wrong size!
fi
# end of 'procmail280/src/includes.h'
fi
if test -f 'procmail280/src/manconf.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'procmail280/src/manconf.c'\"
else
echo shar: Extracting \"'procmail280/src/manconf.c'\" \(7000 characters\)
sed "s/^X//" >'procmail280/src/manconf.c' <<'END_OF_FILE'
X/* A sed script generator (for transmogrifying the man pages automagically) */
X
X/*$Id: manconf.c,v 1.14 1993/01/28 15:18:33 berg Exp $*/
X
X#include "../patchlevel.h"
X#include "procmail.h"
X
X#define pn(name,val) pnr(name,(long)(val))
X
Xstatic char pm_version[]=VERSION;
Xconst char dirsep[]=DIRSEP;
Xstatic const char*const keepenv[]=KEEPENV,*const prestenv[]=PRESTENV,
X *const trusted_ids[]=TRUSTED_IDS,
X *const krnllocks[]={
X#ifndef NOfcntl_lock
X "fcntl(2)",
X#endif
X#ifdef USElockf
X "lockf(3)",
X#endif
X#ifdef USEflock
X "flock(2)",
X#endif
X 0};
X
Xstatic char*skltmark(nl,current)char**current;
X{ char*from= *current,*p;
X while(nl--) /* skip some newlines first */
X from=strchr(from,'\n')+1;
X while(*from=='\t')
X from++;
X *(p=strchr(from,'\n'))='\0';*current=p+1;return from;
X}
X
Xstatic void putcesc(i)
X{ switch(i)
X { case '|':printf("\\\\h'-\\\\w' 'u' ");break;
X case '\\':i='e';goto twoesc;
X case '\1':i='\n';goto singesc;
X case '\t':i='t';goto fin;
X case '\n':i='n';
Xfin: putchar('\\');putchar('\\');
Xtwoesc: putchar('\\');
Xsingesc:
X case '&':case '/':putchar('\\');
X }
X putchar(i);
X}
X
Xstatic void putsesc(a)const char*a;
X{ while(*a)
X putcesc(*a++);
X}
X
Xstatic void pname(name)const char*const name;
X{ putchar('s');putchar('/');putchar('\\');putchar('+');putsesc(name);
X putchar('\\');putchar('+');putchar('/');
X}
X
Xstatic void pnr(name,value)const char*const name;const long value;
X{ pname(name);printf("%ld/g\n",value);
X}
X
Xstatic void plist(name,preamble,list,postamble,ifno,andor)
X const char*const name,*const preamble,*const postamble,*const ifno,
X *const andor;const char*const*list;
X{ pname(name);
X if(!*list)
X putsesc(ifno);
X else
X { putsesc(preamble);goto jin;
X do
X { putsesc(list[1]?", ":andor);
Xjin: putsesc(*list);
X }
X while(*++list);
X putsesc(postamble);
X }
X puts("/g");
X}
X
Xstatic void ps(name,value)const char*const name,*const value;
X{ pname(name);putsesc(value);puts("/g");
X}
X
Xstatic void pc(name,value)const char*const name;const int value;
X{ pname(name);putcesc(value);puts("/g");
X}
X
Xmain P((void))
X{ char*p,*q;
X#ifdef CF_no_procmail_yet
X ps("CF_procmail","If procmail is\1\
X.I not\1\
Xinstalled globally as the default mail delivery agent (ask your system \
Xadministrator), you have to make sure it is invoked when your mail arrives.");
X#else
X ps("CF_procmail","Instead of using the system provided invocation of \
Xprocmail when mail arrives, you can control the invokation of procmail \
Xyourself.");
X#endif
X#ifndef MAILBOX_SEPARATOR
X ps("DOT_FORWARD",".forward");
X ps("FW_content",
X "\"|IFS=' ';exec /usr/local/bin/procmail #YOUR_LOGIN_NAME\"");
X#else
X ps("DOT_FORWARD",".maildelivery");
X ps("FW_content",
X "* - | ? \"IFS=' ';exec /usr/local/bin/procmail #YOUR_LOGIN_NAME\"");
X#endif
X plist("PRESTENV","\1.PP\1Other preset environment variables are "
X ,prestenv,".",""," and ");
X plist("KEEPENV",", except for the values of ",keepenv,"",""," and ");
X plist("TRUSTED_IDS",
X ", and procmail is invoked with one of the following user or group ids: ",
X trusted_ids,",",""," or ");
X plist("KERNEL_LOCKING",
X "consistenly uses the following kernel locking strategies: ",krnllocks,"",
X "doesn't use any additional kernel locking strategies"," and ");
X#ifdef LD_ENV_FIX
X ps("LD_ENV_FIX","\1.PP\1For security reasons, procmail will wipe out all\
X environment variables starting with LD_ upon startup.");
X#else
X ps("LD_ENV_FIX","");
X#endif
X#ifdef NO_USER_TO_LOWERCASE_HACK
X ps("UPPERCASE_USERNAMES","\1.PP\1If the standard\1.BR getpwnam() (3)\1\
Xis case sensitive, and some users have login names with uppercase letters in\
X them, procmail will be unable to deliver mail to them, unless started with\
X their uid.");
X#else
X ps("UPPERCASE_USERNAMES","");
X#endif
X ps("SYSTEM_MBOX",SYSTEM_MBOX);
X#ifdef console
X ps("pconsole","appear on\1.BR ");
X ps("console",console);
X ps("aconsole"," .");
X#else
X ps("pconsole","be mailed back to the ");
X ps("console","sender");
X ps("aconsole",".");
X#endif
X pname("INIT_UMASK");printf("0%lo/g\n",INIT_UMASK);
X pn("DEFlinebuf",DEFlinebuf);
X ps("BOGUSprefix",BOGUSprefix);
X ps("PROCMAILRC",PROCMAILRC);
X pn("HOSTNAMElen",HOSTNAMElen);
X pn("DEFsuspend",DEFsuspend);
X pn("DEFlocksleep",DEFlocksleep);
X ps("TOkey",TOkey);
X ps("TOsubstitute",TOsubstitute);
X ps("FROMDkey",FROMDkey);
X ps("FROMDsubstitute",FROMDsubstitute);
X ps("DEFshellmetas",DEFshellmetas);
X ps("DEFmaildir",DEFmaildir);
X ps("DEFdefault",DEFdefault);
X ps("DEFdefaultlock",strchr(DEFdefaultlock,'=')+1);
X ps("DEFmsgprefix",DEFmsgprefix);
X ps("DEFsendmail",DEFsendmail);
X ps("DEFlockext",DEFlockext);
X ps("DEFshellflags",DEFshellflags);
X pn("DEFlocktimeout",DEFlocktimeout);
X pn("DEFtimeout",DEFtimeout);
X pn("DEFnoresretry",DEFnoresretry);
X ps("COMSAThost",COMSAThost);
X ps("COMSATservice",COMSATservice);
X ps("COMSATprotocol",COMSATprotocol);
X ps("COMSATxtrsep",COMSATxtrsep);
X pc("SERV_ADDRsep",SERV_ADDRsep);
X ps("DEFcomsat",DEFcomsat);
X ps("BinSh",BinSh);
X ps("RootDir",RootDir);
X pc("MCDIRSEP",*MCDIRSEP);
X pc("chCURDIR",chCURDIR);
X pc("HELPOPT1",HELPOPT1);
X pc("HELPOPT2",HELPOPT2);
X pc("VERSIONOPT",VERSIONOPT);
X pc("PRESERVOPT",PRESERVOPT);
X pc("TEMPFAILOPT",TEMPFAILOPT);
X pc("FROMWHOPT",FROMWHOPT);
X pc("ALTFROMWHOPT",ALTFROMWHOPT);
X pc("DELIVEROPT",DELIVEROPT);
X pn("MINlinebuf",MINlinebuf);
X ps("FROM",FROM);
X pc("HEAD_GREP",RECFLAGS[HEAD_GREP]);
X pc("BODY_GREP",RECFLAGS[BODY_GREP]);
X pc("DISTINGUISH_CASE",RECFLAGS[DISTINGUISH_CASE]);
X pc("ALSO_NEXT_RECIPE",RECFLAGS[ALSO_NEXT_RECIPE]);
X pc("ALSO_N_IF_SUCC",RECFLAGS[ALSO_N_IF_SUCC]);
X pc("PASS_HEAD",RECFLAGS[PASS_HEAD]);
X pc("PASS_BODY",RECFLAGS[PASS_BODY]);
X pc("FILTER",RECFLAGS[FILTER]);
X pc("CONTINUE",RECFLAGS[CONTINUE]);
X pc("WAIT_EXIT",RECFLAGS[WAIT_EXIT]);
X pc("WAIT_EXIT_QUIET",RECFLAGS[WAIT_EXIT_QUIET]);
X pc("IGNORE_WRITERR",RECFLAGS[IGNORE_WRITERR]);
X ps("FROM_EXPR",FROM_EXPR);
X pc("UNIQ_PREFIX",UNIQ_PREFIX);
X pc("ESCAP",ESCAP);
X ps("UNKNOWN",UNKNOWN);
X ps("OLD_PREFIX",OLD_PREFIX);
X pc("FM_SKIP",FM_SKIP);
X pc("FM_TOTAL",FM_TOTAL);
X pc("FM_BOGUS",FM_BOGUS);
X pc("FM_CONCATENATE",FM_CONCATENATE);
X pc("FM_FORCE",FM_FORCE);
X pc("FM_REPLY",FM_REPLY);
X pc("FM_KEEPB",FM_KEEPB);
X pc("FM_TRUST",FM_TRUST);
X pc("FM_SPLIT",FM_SPLIT);
X pc("FM_NOWAIT",FM_NOWAIT);
X pc("FM_EVERY",FM_EVERY);
X pc("FM_MINFIELDS",FM_MINFIELDS);
X pn("DEFminfields",DEFminfields);
X pc("FM_DIGEST",FM_DIGEST);
X pc("FM_QUIET",FM_QUIET);
X pc("FM_EXTRACT",FM_EXTRACT);
X pc("FM_EXTRC_KEEP",FM_EXTRC_KEEP);
X pc("FM_ADD_IFNOT",FM_ADD_IFNOT);
X pc("FM_ADD_ALWAYS",FM_ADD_ALWAYS);
X pc("FM_REN_INSERT",FM_REN_INSERT);
X pc("FM_DEL_INSERT",FM_DEL_INSERT);
X pc("FM_ReNAME",FM_ReNAME);
X pn("EX_OK",EX_OK);
X *(p=strchr(strchr(q=strchr(pm_version,' ')+1,' ')+1,' '))='\0';p++;
X ps("PM_VERSION",q);
X ps("MY_MAIL_ADDR",skltmark(1,&p));
X ps("MY_ALT_MAIL_ADDR",skltmark(0,&p));
X ps("PM_MAILINGLIST",skltmark(2,&p));
X ps("PM_MAILINGLISTR",skltmark(2,&p));
X return EX_OK;
X}
END_OF_FILE
if test 7000 -ne `wc -c <'procmail280/src/manconf.c'`; then
echo shar: \"'procmail280/src/manconf.c'\" unpacked with wrong size!
fi
# end of 'procmail280/src/manconf.c'
fi
if test -f 'procmail280/src/pipes.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'procmail280/src/pipes.c'\"
else
echo shar: Extracting \"'procmail280/src/pipes.c'\" \(7343 characters\)
sed "s/^X//" >'procmail280/src/pipes.c' <<'END_OF_FILE'
X/************************************************************************
X * Routines related to setting up pipes and filters *
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: pipes.c,v 1.12 1993/01/19 11:55:20 berg Exp $";
X#endif
X#include "procmail.h"
X#include "robust.h"
X#include "shell.h"
X#include "misc.h"
X#include "pipes.h"
X#include "common.h"
X#include "cstdio.h"
X#include "goodies.h"
X#include "mailfold.h"
X
Xpid_t pidchild;
Xvolatile time_t alrmtime;
Xstatic char*lastexec,*backblock;
Xstatic long backlen; /* length of backblock, filter recovery block */
Xstatic pid_t pidfilt;
Xstatic pipw,pbackfd[2]; /* the emergency backpipe :-) */
X
Xvoid inittmout(progname)const char*const progname;
X{ lastexec=cstr(lastexec,progname);
X alrmtime=timeoutv?time((time_t*)0)+(unsigned)timeoutv:0;
X alarm((unsigned)timeoutv);
X}
X
Xvoid ftimeout P((void))
X{ alarm(0);alrmtime=0;
X if(pidchild>0&&!kill(pidchild,SIGTERM)) /* careful, killing again */
X nlog("Timeout, terminating"),logqnl(lastexec);
X signal(SIGALRM,(void(*)())ftimeout);
X}
X
Xstatic void stermchild P((void))
X{ if(pidfilt>0) /* don't kill what is not ours, we might be root */
X kill(pidfilt,SIGTERM);
X if(!Stdout)
X { nlog("Rescue of unfiltered data ");
X if(dump(PWRB,backblock,backlen)) /* pump data back via the backpipe */
X elog("failed\n");
X else
X elog("succeeded\n");
X }
X exit(lexitcode);
X}
X
Xstatic void childsetup P((void))
X{ lexitcode=EX_UNAVAILABLE;signal(SIGTERM,(void(*)())stermchild);
X signal(SIGINT,(void(*)())stermchild);signal(SIGHUP,(void(*)())stermchild);
X signal(SIGQUIT,(void(*)())stermchild);closerc();
X}
X
Xstatic void getstdin(pip)const int pip;
X{ rclose(STDIN);rdup(pip);rclose(pip);
X}
X
Xstatic void callnewprog(newname)const char*const newname;
X{ if(sh) /* should we start a shell? */
X { const char*newargv[4];
X yell(executing,newname);newargv[3]=0;newargv[2]=newname;
X newargv[1]=tgetenv(shellflags);*newargv=tgetenv(shell);shexec(newargv);
X }
X ;{ register const char*p;int argc;const char**newargv;
X argc=1;p=newname; /* If no shell, chop up the arguments ourselves */
X if(verbose)
X { nlog(executing);elog(oquote);goto no_1st_comma;
X }
X do /* show chopped up command line */
X { if(verbose)
X { elog(",");
Xno_1st_comma:
X elog(p);
X }
X while(*p++);
X }
X while(argc++,*p!=TMNATE);
X if(verbose)
X elog(cquote); /* allocate argv array */
X newargv=malloc(argc*sizeof*newargv);p=newname;argc=0;
X do
X { newargv[argc++]=p;
X while(*p++);
X }
X while(*p!=TMNATE);
X newargv[argc]=0;shexec(newargv);
X }
X}
X
Xpipthrough(line,source,len)char*line,*source;const long len;
X{ int pinfd[2],poutfd[2];
X if(Stdout)
X PWRB=PRDB= -1;
X else
X rpipe(pbackfd);
X rpipe(pinfd); /* main pipes setup */
X if(!(pidchild=sfork())) /* create a sending procmail */
X { backblock=source;backlen=len;childsetup();rclose(PRDI);rclose(PRDB);
X rpipe(poutfd);rclose(STDOUT);
X if(!(pidfilt=sfork())) /* create the filter */
X { rclose(PWRB);rclose(PWRO);rdup(PWRI);rclose(PWRI);getstdin(PRDO);
X callnewprog(line);
X }
X rclose(PWRI);rclose(PRDO);
X if(forkerr(pidfilt,line))
X rclose(PWRO),stermchild();
X if(dump(PWRO,source,len)&&!ignwerr) /* send in the text to be filtered */
X writeerr(line),lexitcode=EX_IOERR,stermchild();
X if(pwait&&waitfor(pidfilt)!=EX_OK) /* check the exitcode of the filter */
X { pidfilt=0;
X if(!(pwait&2)) /* do we put it on report? */
X progerr(line);
X stermchild();
X }
X rclose(PWRB);exit(EX_OK); /* allow parent to proceed */
X }
X rclose(PWRB);rclose(PWRI);getstdin(PRDI);
X if(forkerr(pidchild,procmailn))
X return 1;
X if(Stdout)
X { retStdout(readdyn(Stdout,&Stdfilled));
X if(pwait)
X return pipw;
X }
X return 0; /* we stay behind to read back the filtered text */
X}
X
Xlong pipin(line,source,len)char*const line;char*source;long len;
X{ int poutfd[2];
X rpipe(poutfd);
X if(!(pidchild=sfork())) /* spawn program */
X rclose(PWRO),closerc(),getstdin(PRDO),callnewprog(line);
X rclose(PRDO);
X if(forkerr(pidchild,line))
X return 1; /* dump mail in the pipe */
X if((len=dump(PWRO,source,len))&&(!ignwerr||(len=0)))
X writeerr(line); /* pipe was shut in our face, get mad */
X if(pwait&&waitfor(pidchild)!=EX_OK) /* optionally check the exitcode */
X { if(!(pwait&2)) /* do we put it on report? */
X progerr(line);
X len=1;
X }
X pidchild=0;
X if(!sh)
X concatenate(line);
X if(asgnlastf)
X asgnlastf=0,lastfolder=cstr(lastfolder,line);
X return len;
X}
X
Xchar*readdyn(bf,filled)char*bf;long*const filled;
X{ int i;long oldsize;
X oldsize= *filled;goto jumpin;
X do
X { *filled+=i; /* change listed buffer size */
Xjumpin:
X#ifdef SMALLHEAP
X if((size_t)*filled>=(size_t)(*filled+BLKSIZ))
X lcking|=lck_MEMORY,nomemerr();
X#endif
X bf=realloc(bf,*filled+BLKSIZ); /* dynamically adjust the buffer size */
Xjumpback:;
X }
X while(0<(i=rread(STDIN,bf+*filled,BLKSIZ))); /* read mail */
X if(pidchild>0)
X { if(!Stdout)
X { getstdin(PRDB); /* filter ready, get backpipe */
X if(1==rread(STDIN,buf,1)) /* backup pipe closed? */
X { bf=realloc(bf,(*filled=oldsize+1)+BLKSIZ);bf[oldsize]= *buf;
X if(pwait)
X waitfor(pidchild);
X pidchild=0;goto jumpback; /* filter goofed, rescue data */
X }
X }
X if(pwait)
X pipw=waitfor(pidchild); /* reap your child in any case */
X }
X pidchild=0; /* child must be gone by now */
X if(!*filled)
X return realloc(bf,1); /* +1 for housekeeping purposes */
X return realloc(bf,*filled+1); /* minimise the buffer space */
X}
X
Xchar*fromprog(name,dest,max)char*name;char*const dest;size_t max;
X{ int pinfd[2],poutfd[2];int i;char*p;
X concon('\n');rpipe(pinfd);inittmout(name);
X if(!(pidchild=sfork())) /* create a sending procmail */
X { Stdout=name;childsetup();rclose(PRDI);rpipe(poutfd);rclose(STDOUT);
X if(!(pidfilt=sfork())) /* spawn program/filter */
X rclose(PWRO),rdup(PWRI),rclose(PWRI),getstdin(PRDO),callnewprog(name);
X rclose(PWRI);rclose(PRDO);
X if(forkerr(pidfilt,name))
X rclose(PWRO),stermchild();
X dump(PWRO,themail,filled);waitfor(pidfilt);exit(lexitcode);
X }
X rclose(PWRI);p=dest;
X if(!forkerr(pidchild,name))
X { name=tstrdup(name);
X while(0<(i=rread(PRDI,p,max))&&(p+=i,max-=i)); /* read its lips */
X if(0<rread(PRDI,p,1))
X nlog("Excessive output quenched from"),logqnl(name);
X rclose(PRDI);free(name);
X while(--p>=dest&&*p=='\n'); /* trailing newlines should be discarded */
X p++;waitfor(pidchild);
X }
X else
X rclose(PRDI);
X pidchild=0;*p='\0';return p;
X}
X
Xvoid exectrap(tp)const char*const tp;
X{ if(*tp)
X { int newret;
X metaparse(tp);inittmout(buf);
X if(!(pidchild=sfork())) /* connect stdout to stderr before exec */
X { signal(SIGTERM,SIG_DFL);signal(SIGINT,SIG_DFL);signal(SIGHUP,SIG_DFL);
X signal(SIGQUIT,SIG_DFL);rclose(STDOUT);rdup(STDERR);callnewprog(buf);
X }
X if(!forkerr(pidchild,buf)&&(newret=waitfor(pidchild))!=EX_OK)
X retval=newret; /* supersede the return value */
X }
X}
END_OF_FILE
if test 7343 -ne `wc -c <'procmail280/src/pipes.c'`; then
echo shar: \"'procmail280/src/pipes.c'\" unpacked with wrong size!
fi
# end of 'procmail280/src/pipes.c'
fi
echo shar: End of archive 5 \(of 11\).
cp /dev/null ark5isdone
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...