home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-04 | 41.6 KB | 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...
-