idc@cs.hw.ac.uk (Ian Crorie) (01/25/89)
Sorry for the delay in getting UK-2.1 out but our pad has been
performing its yoyo impersonation.
---------- cut here ----------
#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./Support`
then
mkdir ./Support
echo "mkdir ./Support"
fi
if `test ! -s ./Support/Makefile`
then
echo "Writing ./Support/Makefile"
cat > ./Support/Makefile << '\Rogue\Monster\'
# Support programs for UK-Sendmail 2.1
SRCS = authorise.c muucp.c rmail.c uumailclean.c warn.c \
distribute mail-news checkaddr SysV.sh
BINS = authorise muucp rmail uumailclean
DESTS = /usr/local/lib/authorise /usr/lib/uucp/muucp /bin/rmail \
/usr/lib/uucp/uumailclean /usr/local/lib/distribute \
/usr/lib/news/mail-news
BINMODE=755
SHMODE =755
support: $(BINS)
install: $(DESTS)
/usr/lib/uucp/muucp: muucp
cp muucp $@ && chmod $(BINMODE) $@
/usr/lib/uucp/uumailclean: uumailclean
cp uumailclean $@ && chmod $(BINMODE) $@
/bin/rmail: rmail
cp rmail $@ && chmod $(BINMODE) $@
/usr/local/lib/authorise: authorise
cp authorise $@ && chmod $(SHMODE) $@
/usr/local/lib/distribute: distribute
cp distribute $@ && chmod $(SHMODE) $@
/usr/lib/news/mail-news: mail-news
cp mail-news $@ && chmod $(SHMODE) $@
uumailclean: uumailclean.c warn.o
$(CC) $@.c warn.o -o $@ $(CFLAGS) $(LDFLAGS)
convert: SysV.sh
cd ..; sh Support/SysV.sh
clean:
rm -f *.o $(BINS)
\Rogue\Monster\
else
echo "Will not over-write ./Support/Makefile"
fi
chmod 444 ./Support/Makefile
if [ `wc -c < ./Support/Makefile` -ne 976 ]
then
echo 'Got' `wc -c < ./Support/Makefile` ', Expected ' 976
fi
if `test ! -s ./Support/SysV.sh`
then
echo "Writing ./Support/SysV.sh"
cat > ./Support/SysV.sh << '\Rogue\Monster\'
#!/bin/sh
#
# This shell script converts the BSD dependent parts of the main shell
# scripts into something suitable for SystemV.
#
# This must be run in the top level directory of the sendmail package.
#
for i in Config Dombuild Chnbuild
do
if [ ! -f $i ]
then
echo $i non-existent
exit 1
fi
if [ ! -f $i.bsd ]
then
mv $i $i.bsd
fi
done
# The top level make file
sed -e 's/echo -n/echo/' -e 's/\.\.\."/...\\c"/' Config.bsd > Config
# The channel make file
sed -e "s;fmt | sed;nroff | sed -e '/^$/d' -e;" Chnbuild.bsd > Chnbuild
# The domain make file
sed -e "s;tail -r \(...S12\);pr -t -n \1 | sort -r | sed 's/^......//';" \
-e "s;fmt | sed;nroff | sed -e '/^$/d' -e;" Dombuild.bsd > Dombuild
\Rogue\Monster\
else
echo "Will not over-write ./Support/SysV.sh"
fi
chmod 444 ./Support/SysV.sh
if [ `wc -c < ./Support/SysV.sh` -ne 723 ]
then
echo 'Got' `wc -c < ./Support/SysV.sh` ', Expected ' 723
fi
if `test ! -s ./Support/authorise.c`
then
echo "Writing ./Support/authorise.c"
cat > ./Support/authorise.c << '\Rogue\Monster\'
/*
* authorise - sendmail authorisation program
*
* Given a channel name, sender address and recipient address or
* host, it matches these against entries in an authorisation
* file to see if permission is granted to send the mail.
*
* If successful, the mailer interface is called; else the
* appropriate error status is returned to sendmail.
*
* Written by Jim Crammond. <jac@ic.doc> 5/87
*/
#include <stdio.h>
#include <sysexits.h>
#define AUTHFILE "/usr/lib/authorisations"
#define CHANSIZE 64
#define ADDRSIZE 256
#define LINESIZE 1024
char a_chan[CHANSIZE];
char a_from[ADDRSIZE];
char a_to[ADDRSIZE];
char *authfile = AUTHFILE;
int negative = 0;
main(argc, argv)
int argc;
char *argv[];
{
char *progname, *channel;
char *from_addr, *to_addr;
FILE *afp, *fopen();
char line[LINESIZE];
int cnt, nfields;
register char *p;
char *index();
int gotmatch = 0;
progname = *argv++;
if (argv[0][0] == '-' && argv[0][1] == 'f')
{ authfile = argv[1];
argc -= 2;
argv += 2;
}
if (argc < 4)
{ printf("usage: %s [-f authfile] channel from to command [args]\n", progname);
exit(EX_USAGE);
}
channel = *argv++;
from_addr = *argv++;
to_addr = *argv++;
if ((afp = fopen(authfile, "r")) == NULL)
{ printf("warning: cannot open authorisation file\n");
gotmatch = 1;
}
while (!gotmatch && fgets(line, sizeof(line), afp))
{ cnt++;
if ((p = index(line, '\n')) != NULL)
*p = '\0';
if ((p = index(line, '#')) != NULL)
*p = '\0';
for (p=line; *p == ' ' && *p == '\t'; p++)
;
if (*p == '\0')
continue;
nfields = sscanf(p, "%s %s %s", a_chan, a_from, a_to);
if (nfields != 3)
{ printf("warning: line %d ignored: \"%s\"\n", cnt, line);
continue;
}
negative = 0;
if (strcmp(channel, a_chan) == 0 &&
match(from_addr, a_from) && match(to_addr, a_to))
{ if (negative > 0)
gotmatch = -1;
else
gotmatch = 1;
}
#ifdef DEBUG
printf("%d: %s - %s\n", cnt, line,
gotmatch ? "matched" : "no match");
#endif DEBUG
}
if (gotmatch <= 0)
{ printf("%s: %s is not authorised to send to host/address %s\n",
progname, from_addr, to_addr);
exit(EX_NOPERM);
}
execv(argv[0], argv);
printf("%s: cannot exec %s\n", progname, argv[0]);
exit(EX_UNAVAILABLE);
}
/*
* MATCH -- match the strings s1 and s2.
* s2 can contain wildcards and lists
*/
match(s1, s2)
char *s1, *s2;
{
char lbuf[ADDRSIZE];
char *rest, *lp;
char *index();
if (*s2 == '\\') /* escape */
{ if (*s1 == *(s2+1) && match(s1+1, s2+2))
return(1);
}
else if (*s2 == '*') /* wildcard */
{ if (match(s1, ++s2))
return(1);
while (*s1++)
{ if (match(s1, s2))
return(1);
}
}
else if (*s2 == '{' && (rest = index(++s2, '}'))) /* list */
{ rest++;
lp = lbuf;
while (s2 != rest)
{ while (*s2 && *s2 != ',' && *s2 != '}')
*lp++ = *s2++;
strcpy(lp, rest);
if (match(s1, lbuf))
return(1);
lp = lbuf;
s2++;
}
}
else if (*s2 == '^') /* negative match */
{ if (match(s1, ++s2))
{ negative++;
return(1);
}
}
else if (*s1 == *s2) /* literal */
{ if (*s1 == '\0')
return(1);
if (match(++s1, ++s2))
return(1);
}
return(0);
}
\Rogue\Monster\
else
echo "Will not over-write ./Support/authorise.c"
fi
chmod 444 ./Support/authorise.c
if [ `wc -c < ./Support/authorise.c` -ne 3194 ]
then
echo 'Got' `wc -c < ./Support/authorise.c` ', Expected ' 3194
fi
if `test ! -s ./Support/checkaddr`
then
echo "Writing ./Support/checkaddr"
cat > ./Support/checkaddr << '\Rogue\Monster\'
#!/bin/sh
# shell script to verify what sendmail would do with given addresses
# this version works for sendmail versions 4.40 and above
verbose=false
if [ $1 = "-v" ]
then
verbose=true
shift
fi
trap "/bin/rm /tmp/ver.$$; exit" 1 2 3 15
while [ $# -ge 1 ]
do
echo -n "$1: "
/usr/lib/sendmail -bt > /tmp/ver.$$ <<EOF
0 $1
EOF
if grep -s 'ruleset 0 returns: "^V" "local"' /tmp/ver.$$
then
if /usr/lib/sendmail -bv $1 > /tmp/ver.$$
then
echo addr OK
else
sed -n -e '/deliverable/d' \
-e 's/\(.*\)\.\.\. \(.*\)/\2 (\1)/p' /tmp/ver.$$
fi
if $verbose
then
aliases=""
for a in `sed -n 's/\.\.\. deliverable//p' /tmp/ver.$$`
do
if [ "$a" = "$1" ]
then
echo "Routed to: channel=local, addr=$a"
else
aliases="$aliases $a"
fi
done
if [ -n "$aliases" ]
then
echo "Aliased to:$aliases"
$0 $aliases
fi
fi
elif grep -s 'ruleset 0 returns: "^V" "error"' /tmp/ver.$$
then
sed -n -e 's/"\([^"]*\)"/\1/g' \
-e '/ruleset 0 returns:/s/.*^X //p' /tmp/ver.$$
else
echo addr OK
if $verbose
then
sed -n '/ruleset 3 returns:/s/.*returns: //p' /tmp/ver.$$ |
sed -n -e '$s/"\([^"]*\)"/\1/g' \
-e '$s/ \([!.@%]\) /\1/g' \
-e '$s/^/Normalised to: /p'
sed -n '/ruleset 0 returns:/s/.*^V" //p' /tmp/ver.$$ |
sed -e 's/"\([^"]*\)"/\1/g' \
-e 's/\(.*\) ^W \(.*\) ^X \(.*\)/Routed to: channel=\1, host=\2, addr=\3/'\
-e 's/\(.*\) ^X \(.*\)/Routed to: channel=\1, addr=\2/' \
-e 's/ \([!.@%]\) /\1/g'
fi
fi
/bin/rm /tmp/ver.$$
shift
done
\Rogue\Monster\
else
echo "Will not over-write ./Support/checkaddr"
fi
chmod 444 ./Support/checkaddr
if [ `wc -c < ./Support/checkaddr` -ne 1605 ]
then
echo 'Got' `wc -c < ./Support/checkaddr` ', Expected ' 1605
fi
if `test ! -s ./Support/distribute`
then
echo "Writing ./Support/distribute"
cat > ./Support/distribute << '\Rogue\Monster\'
#!/bin/sh
#
# Send a mail message to users on a distribution list. The message header is
# altered mainly to allow error messages to be returned to the list maintainer.
# This script should be setuid to one of sendmail's trusted users.
#
# Usage: put an entry into /usr/lib/aliases in one of the following forms:
#
# list-name: "|/usr/local/lib/distribute list-name user1 user2 ..."
# list-name: "|/usr/local/lib/distribute list-name :include:pathname"
#
if [ $# -lt 2 ]
then
echo Usage: $0 list-name user1 user2 ...
exit 64
fi
dlist=$1
dusers=""
shift
# gather distribution list usernames
for i in $*
do
case $i in
:include:*)
file=`expr $i : ':include:\(.*\)'`
if [ -f $file ]
then
dusers="$dusers `cat $file`"
else
echo $i: No such file or directory
exit 64
fi
;;
*) dusers="$dusers $i"
;;
esac
done
# adjust headers of incoming message
sed -e '1,/^$/s/^$/EOH\
/' |
sed -e '/^$/,$b' \
-e '/^From /d' \
-e '/^Via:/s//Original-Via:/' \
-e '/^Sender:/s//Original-Sender:/' \
-e '/^Acknowledge-To:/d' \
-e '/^Return-Receipt-To:/d' \
-e "/^EOH$/s//Sender: $dlist-request/" |
/usr/lib/sendmail -f$dlist-request $dusers
\Rogue\Monster\
else
echo "Will not over-write ./Support/distribute"
fi
chmod 444 ./Support/distribute
if [ `wc -c < ./Support/distribute` -ne 1189 ]
then
echo 'Got' `wc -c < ./Support/distribute` ', Expected ' 1189
fi
if `test ! -s ./Support/mail-news`
then
echo "Writing ./Support/mail-news"
cat > ./Support/mail-news << '\Rogue\Monster\'
#!/bin/sh
#
# mail-news release 2.0 Copyright Jem Taylor 1988
#
# Remove To: Cc: Received: and Via: fields,
# ensure that there is a Subject: line or make Subject: (none),
# re-order header lines to give
# From:
# Subject:
# Message-ID:
# Date:
# Sender:
# and move any other header lines to after these
#
/bin/awk '
BEGIN { true=1; false=0; head=true; subject="Subject: (none)"
gateway="X-Mailer: mail-news 2.0.3"
}
# From: and Sender: lines must be login@host (real name)
# instead of real name <login@host>
# assume that <username> is one word - no quoted space - and at end of line
/^From:.*>$/ { if (head==true)
{ user=substr ( $NF, 2, length($NF) -2 )
real = $2
for ( i=3; i<NF; i++ ) real = real " " $i
from = "From: " user " (" real ")"
next
}
}
/^Sender:.*>$/ { if (head==true)
{ user=substr ( $NF, 2, length($NF) -2 )
real = $2
for ( i=3; i<NF; i++ ) real = real " " $i
sender = "Sender: " user " (" real ")"
next
}
}
/^From:/ { if (head==true) { from = $0 ; next } }
/^Sender:/ { if (head==true) { sender = $0 ; next } }
/^Message-ID:/ { if (head==true) { messageid = $0 ; next } }
/^Date:/ { if (head==true) { date = $0 ; next } }
##insist Subject: has something in it!
/^Subject:.*[-=:)a-zA-Z@#!]/ {
if (head==true) { subject=$0; next } }
## discard these and header continuation lines
/^Received:/||/^Via:/|| \
/^To:/||/^Cc:/||\
/^ /||/^ / { if (head==true) next }
## move any other header lines to end of header
/^.*:/ { if (head==true) { others[++ocnt]=$0; next } }
## break between head and body - ensure subject in head
/^$/ { if (head==true)
{ head=false;
if (from!="") print from
print subject
if (messageid!="") print messageid
if (date!="") print date
if (sender!="") print sender
for (i=1;i<=ocnt;i++) print others[i]
print gateway
print ""
next
}
}
## change inclusion mark since sender is not on hand ...
/^>/ { if (head==false)
{ print "|" substr( $0, 2, length - 1 )
next
}
}
## all lines including body - unless explicitly skipped above
{ print $0 }
' | /usr/lib/news/inews $@
\Rogue\Monster\
else
echo "Will not over-write ./Support/mail-news"
fi
chmod 444 ./Support/mail-news
if [ `wc -c < ./Support/mail-news` -ne 2071 ]
then
echo 'Got' `wc -c < ./Support/mail-news` ', Expected ' 2071
fi
if `test ! -s ./Support/muucp.c`
then
echo "Writing ./Support/muucp.c"
cat > ./Support/muucp.c << '\Rogue\Monster\'
/*
* MUUCP -- Send mail over uucp, using the UUCP Transmission Format
*
* This simply prepends a unix from line of the appropriate form to the
* message which is then passed on the uux. -Jim Crammond 12/88.
*
* usage: muucp [-r] [-gA] -f<from_addr> -H<uucpname> host user1 user2...
*/
#include <stdio.h>
#include <sysexits.h>
#include <sys/types.h>
char uuxcmd[1024] = "/usr/bin/uux -";
char *perc_to_uucp();
char *tidy_addr();
char *index();
char *rindex();
FILE *popen();
main(argc, argv)
int argc;
char *argv[];
{
FILE *out;
char lbuf[BUFSIZ];
char *From = NULL;
char *sysname = NULL;
int i;
time_t now;
while (argc > 1 && argv[1][0] == '-')
{ switch(argv[1][1])
{
case 'f':
From = &argv[1][2];
break;
case 'H':
sysname = &argv[1][2];
break;
case 'r':
case 'g':
case 'O':
case 'x':
strcat(uuxcmd, " ");
strcat(uuxcmd, argv[1]);
break;
default:
fprintf(stderr, "unknown flag %s\n", argv[1]);
break;
}
argc--;
argv++;
}
if (argc < 3 || From == NULL || sysname == NULL)
{ fprintf(stderr, "usage: muucp -f<From> -H<sysname> host users...\n");
exit(EX_USAGE);
}
/* add host!rmail (users) to cmd line */
strcat(uuxcmd, " ");
strcat(uuxcmd, argv[1]);
strcat(uuxcmd, "!rmail '(");
argc--;
argv++;
while (--argc > 1)
{ strcat(uuxcmd, argv[1]);
strcat(uuxcmd, " ");
argv++;
}
strcat(uuxcmd, argv[1]);
strcat(uuxcmd, ")'");
/* open pipe to uux */
out = popen(uuxcmd, "w");
/* generate the UUCP From line */
From = perc_to_uucp(From);
From = tidy_addr(From);
time(&now);
fprintf(out, "From %s %.24s remote from %s\n", From, ctime(&now), sysname);
/* pass stdin (mail message) to uux */
while (fgets(lbuf, sizeof lbuf, stdin))
fputs(lbuf, out);
/* close pipe */
i = pclose(out);
if ((i & 0377) != 0)
{ fprintf(stderr, "pclose: status 0%o\n", i);
exit(EX_OSERR);
}
exit((i >> 8) & 0377);
}
/*
** PERC_TO_UUCP -- converts an address in Percent style into uucp style
**
** e.g. user%c.bitnet%b.arpa@a.uucp -> a.uucp!b.arpa!c.bitnet!user
*/
char *
perc_to_uucp(addr)
char *addr;
{
static char buf[512];
char *bp = buf;
char *p;
while ((p = rindex(addr,'@')) != NULL || (p = rindex(addr,'%')) != NULL)
{
*p++ = '\0';
while (*p)
*bp++ = *p++;
*bp++ = '!';
}
strcpy(bp, addr);
return(buf);
}
/*
** TIDY_ADDR -- strips duplicate domain names from start of address
**
** e.g. cs.hw.AC.UK!cs.hw.AC.UK!jim -> cs.hw.AC.UK!jim
*/
char *
tidy_addr(addr)
char *addr;
{
register char *p, *q;
p = addr;
while ((q = index(p, '!')) != NULL)
{ ++q;
while (*p != '!' && *p == *q)
{ p++;
q++;
}
if (*p != '!' && *q != '!')
break;
addr = ++p;
}
return(addr);
}
\Rogue\Monster\
else
echo "Will not over-write ./Support/muucp.c"
fi
chmod 444 ./Support/muucp.c
if [ `wc -c < ./Support/muucp.c` -ne 2720 ]
then
echo 'Got' `wc -c < ./Support/muucp.c` ', Expected ' 2720
fi
if `test ! -s ./Support/rmail.c`
then
echo "Writing ./Support/rmail.c"
cat > ./Support/rmail.c << '\Rogue\Monster\'
#ifndef lint
static char sccsid[] = "@(#)rmail.c 4.4 (Berkeley) 8/11/83";
#endif
/*
** RMAIL -- UUCP mail server.
**
** This program reads the >From ... remote from ... lines that
** UUCP is so fond of and turns them into something reasonable.
** It calls sendmail giving it a -f option built from these
** lines.
**
** Modified to set the sender's hostname (deduced from first
** "remote from host" line) and convert the final "user" part
** from an address with '@' and '%' (which mmdf is so fond of)
** in to a 'pure' uucp address. -Jim Crammond, (hwcs!jim) 29/11/84
*/
# include <stdio.h>
# include <sysexits.h>
typedef char bool;
#define TRUE 1
#define FALSE 0
extern FILE *popen();
extern char *index();
extern char *rindex();
char *perc_to_uucp();
bool Debug;
# define MAILER "/usr/lib/sendmail"
main(argc, argv)
char **argv;
{
FILE *out; /* output to sendmail */
char lbuf[512]; /* one line of the message */
char from[512]; /* accumulated path of sender */
char ufrom[128]; /* user on remote system */
char sys[64]; /* a system in path */
char sysname[64]; /* system received from */
char cmd[2000];
register char *cp;
register char *uf; /* ptr into ufrom */
int linecount;
int i;
# ifdef DEBUG
if (argc > 1 && strcmp(argv[1], "-T") == 0)
{
Debug = TRUE;
argc--;
argv++;
}
# endif DEBUG
if (argc < 2)
{
fprintf(stderr, "Usage: rmail user ...\n");
exit(EX_USAGE);
}
(void) strcpy(from, "");
(void) strcpy(sysname, "");
(void) strcpy(ufrom, "/dev/null");
linecount = 0;
while (fgets(lbuf, sizeof lbuf, stdin) != NULL)
{
if (strncmp(lbuf, "From ", 5) != 0 && strncmp(lbuf, ">From ", 6) != 0)
break;
linecount++;
(void) sscanf(lbuf, "%*s %s", ufrom);
cp = lbuf;
uf = ufrom;
while ((cp = index(cp, 'r')) != NULL)
{
#ifdef DEBUG
if (Debug)
printf("cp='%s'\n", cp);
#endif
if (sscanf(cp, "remote from %s", sys) == 1)
{ (void) strcat(from, sys);
(void) strcat(from, "!");
if (linecount == 1)
(void) strcpy(sysname, sys);
break;
}
cp++;
}
#ifdef DEBUG
if (Debug)
printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
#endif
}
/*
* check for percent style addresses in user field
*/
if (index(uf, '@') != NULL || index(uf, '%') != NULL)
uf = perc_to_uucp(uf);
/*
* if this is a new style "From domain!user .. remote from system"
* header then don't prepend the system name to the from person
*/
if (linecount == 1 && (cp = index(uf, '!')) != NULL)
{ char *p = index(uf, '.');
if (p != NULL && p < cp)
(void) strcpy(from, uf);
else
(void) strcat(from, uf);
}
else
(void) strcat(from, uf);
(void) sprintf(cmd, "%s -em -oi -f%s", MAILER, from);
if (*sysname != '\0')
{ (void) strcat(cmd, " -oMs");
(void) strcat(cmd, sysname);
}
while (*++argv != NULL)
{
(void) strcat(cmd, " '");
if (**argv == '(')
(void) strncat(cmd, *argv + 1, strlen(*argv) - 2);
else
(void) strcat(cmd, *argv);
(void) strcat(cmd, "'");
}
#ifdef DEBUG
if (Debug)
printf("cmd='%s'\n", cmd);
#endif
out = popen(cmd, "w");
fputs(lbuf, out);
while (fgets(lbuf, sizeof lbuf, stdin))
fputs(lbuf, out);
i = pclose(out);
if ((i & 0377) != 0)
{
fprintf(stderr, "pclose: status 0%o\n", i);
exit(EX_OSERR);
}
exit((i >> 8) & 0377);
}
/*
** PERC_TO_UUCP -- converts an address in Percent style into uucp style
**
** e.g. user%c.bitnet%b.arpa@a.uucp -> a.uucp!b.arpa!c.bitnet!user
*/
char *
perc_to_uucp(addr)
char *addr;
{
static char buf[512];
char *bp = buf;
char *p;
#ifdef DEBUG
if (Debug)
printf("perc_to_uucp(%s) ", addr);
#endif
while ((p = rindex(addr,'@')) != NULL || (p = rindex(addr,'%')) != NULL)
{
*p++ = '\0';
while (*p)
*bp++ = *p++;
*bp++ = '!';
}
strcpy(bp, addr);
#ifdef DEBUG
printf("returns %s\n", buf);
#endif
return(buf);
}
\Rogue\Monster\
else
echo "Will not over-write ./Support/rmail.c"
fi
chmod 444 ./Support/rmail.c
if [ `wc -c < ./Support/rmail.c` -ne 3835 ]
then
echo 'Got' `wc -c < ./Support/rmail.c` ', Expected ' 3835
fi
if `test ! -s ./Support/uumailclean.c`
then
echo "Writing ./Support/uumailclean.c"
cat > ./Support/uumailclean.c << '\Rogue\Monster\'
#include "uucp.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifdef BSD42
#include <sys/dir.h>
#endif BSD42
#ifdef NDIR
#include <ndir.h>
#endif NDIR
#ifdef LIBNDIR
#include "LIBNDIR/ndir.h"
#endif LIBNDIR
/*
* uumailclean - this program searches through the uucp spool directory
* looking for mail files. Files which have been around for longer
* than "failtime" hours will be returned to the sender. If a file
* has been around longer than "warntime" hours, then a warning
* message is sent (once) to the sender.
*
* If you use L.dirs to specify subdirectories, then failtime and
* warntime can be specified as 3rd and 4th arguments to the directory
* entries respectively: e.g. "C. 336 168 72"
* By default, these times are 1 week and 3 days.
*
* Written by Jim Crammond <jim@cs.hw.ac.uk> 3/86
*/
#define FAILTIME 168 /* default hours before returning the mail */
#define WARNTIME 72 /* default hours before sending a warning */
#define WARNFILE UUCPDIR/uucp/warnlist.mail"
int warntime, failtime;
main(argc, argv)
char *argv[];
{
#ifdef SUBCS
FILE *fdirs;
#endif SUBCS
char file[NAMESIZE];
char cdir[ MAXFULLNAME ];
char *flds[10];
int nflds, ret;
int orig_uid = getuid();
strcpy(Progname, "uumailclean");
uucpname(Myname);
chkdebug(orig_uid);
/* cd to spool */
ASSERT(subchdir(Spool) != -1, "cannot chdir to ", Spool, 0 );
init_warnedlist(WARNFILE);
#ifdef SUBCS
fdirs=fopen(DIRFILE,"r");
ASSERT(fdirs != NULL, "uumailclean cannot open", DIRFILE, 0);
while (cfgets(cdir, sizeof(cdir), fdirs) != NULL)
{ nflds = getargs( cdir, flds );
ASSERT(nflds >= 1, "BAD entry in", DIRFILE, 0);
/* only interested in command files */
if (flds[0][0] != CMDPRE)
continue;
failtime = (nflds > 2) ? atoi(flds[2]) : FAILTIME;
warntime = (nflds > 3) ? atoi(flds[3]) : WARNTIME;
checkfiles(flds[0]);
}
#else SUBCS
failtime = FAILTIME;
warntime = WARNTIME;
checkfiles(".");
#endif SUBCS
exit(0);
}
/*
* checkfiles - scan a directory looking for "old" control files.
* For each one found, call fail or warn as appropriate.
*/
checkfiles(dir)
char *dir;
{
DIR *dirp;
char file[NAMESIZE];
struct stat stbuf;
time_t now;
int hours;
time(&now);
DEBUG(5, "checkfiles(%s)\n", dir);
if ((dirp = opendir(dir)) == NULL)
{ printf("directory unreadable\n");
return;
}
while (gnamef(dirp, file))
{ if (file[0] != CMDPRE)
continue;
if (stat(subfile(file), &stbuf) == -1)
{ DEBUG(4, "stat on %s failed\n", file);
continue;
}
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
continue;
hours = (int) (now - stbuf.st_mtime) / 3600;
if (hours >= failtime)
fail(file, hours);
else if (hours >= warntime)
warn(file, hours);
}
}
/*
* fail - send a failure message to the sender and delete the mail.
*/
fail(cmdfile, hours)
char *cmdfile;
int hours;
{
char dfile[NAMESIZE], xfile[NAMESIZE];
char host[NAMESIZE];
char *from, **to;
char *sender(), **recipients();
DEBUG(4, "fail called on %s\n", cmdfile);
getfnames(cmdfile, dfile, xfile);
if ((to = recipients(xfile)) == NULL)
return;
if ((from = sender(dfile)) == NULL)
return;
strcpy(host, &cmdfile[2]);
host[ strlen(cmdfile)-7 ] = '\0';
sendfailure(from, to, host, hours, dfile);
unlink(subfile(cmdfile));
unlink(subfile(dfile));
unlink(subfile(xfile));
return;
}
/*
* warn - send a warning message to the sender and add the control file
* to the list of files for which warnings have been sent.
*/
warn(cmdfile, hours)
char *cmdfile;
int hours;
{
char dfile[NAMESIZE], xfile[NAMESIZE];
char host[NAMESIZE];
char *from, **to;
char *sender(), **recipients();
if (in_warnedlist(cmdfile))
return;
DEBUG(4, "warn called on %s\n", cmdfile);
getfnames(cmdfile, dfile, xfile);
if ((to = recipients(xfile)) == NULL)
return;
if ((from = sender(dfile)) == NULL)
return;
strcpy(host, &cmdfile[2]);
host[ strlen(cmdfile)-7 ] = '\0';
sendwarning(from, to, host, hours, failtime, dfile);
add_warnedlist(cmdfile);
return;
}
/*
* getfnames - read the control file to find the data and execute files
* which contain the message and list of recipients.
* dfile is set to the datafile, xfile to the execute file.
*/
getfnames(cmdfile, dfile, xfile)
char *cmdfile;
char *dfile;
char *xfile;
{
FILE *fp;
char dline[100], xline[100];
char *wrkvec[10];
if ((fp = fopen(subfile(cmdfile), "r")) == NULL)
return;
if (fgets(dline, 100, fp) == NULL || fgets(xline, 100, fp) == NULL)
{ fclose(fp);
return;
}
if (getargs(dline, wrkvec) <= QF_INDEX)
{ fclose(fp);
return;
}
strcpy(dfile, wrkvec[ QF_INDEX ]);
if (getargs(xline, wrkvec) < QF_INDEX)
{ fclose(fp);
return;
}
strcpy(xfile, wrkvec[ QF_INDEX ]);
fclose(fp);
}
/*
* recipients - returns a list of recipients that the mail was intended
* for, or NULL if the execute file is not a mail file.
*/
char **
recipients(xfile)
char *xfile;
{
static char rbuf[BUFSIZ];
static char *tobuf[1000]; /* see uuxqt */
FILE *fp;
char *p, **t;
if ((fp = fopen(subfile(xfile), "r")) == NULL)
return(NULL);
while (fgets(rbuf, BUFSIZ, fp) != NULL)
{ if (rbuf[0] == X_CMD)
{ if (strncmp(rbuf, "C rmail ", 8) == SAME)
{ fclose(fp);
/* turn into an array of addresses */
for (p = &rbuf[8], t=tobuf; *p;)
{ while (*p == ' ' || *p == '\n')
*p++ = '\0';
*t = p;
while (*p && *p != ' ' && *p != '\n')
p++;
if (*t != p)
t++;
}
*t = NULL;
return(tobuf);
}
}
}
fclose(fp);
return(NULL);
}
/*
* sender - returns the sender address from the uucp from line,
* or NULL if not found.
*/
char *
sender(dfile)
char *dfile;
{
static char sender[BUFSIZ];
char buf[BUFSIZ];
FILE *fp;
if ((fp = fopen(subfile(dfile), "r")) == NULL)
return(NULL);
if (fgets(buf, BUFSIZ, fp) == NULL)
return(NULL);
if (sscanf(buf, "From %s", sender) == 1)
{ fclose(fp);
return(sender);
}
fclose(fp);
return(NULL);
}
/*
* exists - returns 1 if "file" exists, else 0.
*/
exists(file)
char *file;
{
return( access(subfile(file),0) == 0 );
}
/*
* print_message - print the message in "dfile" on the stream "outp".
* If the edited flag is set, then only print some
* interesting headers and the first few lines of the body.
*/
print_message(dfile, outp, edited)
char *dfile;
FILE *outp;
int edited;
{
FILE *dfp;
char buf[BUFSIZ];
int iflg, linecount;
if ((dfp = fopen(subfile(dfile), "r")) == NULL)
return;
/* skip unix from line */
fgets(buf, BUFSIZ, dfp);
/* print header */
iflg = 0;
while (fgets(buf, BUFSIZ, dfp) != NULL && buf[0] != '\n')
{ if (edited)
{ if (buf[0] == '\t' || buf[0] == ' ')
{ if (iflg)
fputs(buf, outp);
continue;
}
if (!interested(buf))
{ iflg = 0;
continue;
}
iflg = 1;
}
fputs(buf, outp);
}
putc('\n', outp);
/* print body */
linecount = 0;
while (fgets(buf, BUFSIZ, dfp) != NULL)
{ if (edited && ++linecount > 5)
{ fprintf(outp, ".....\n");
break;
}
fputs(buf, outp);
}
fclose(dfp);
}
static char *headers[] = { "From:", "Date:", "To:", "Cc:", "Subject:", 0 };
/*
* interested - determine whether "hdr" is considered interesting
* and thus should be printed in edited mode.
*/
interested(hdr)
char *hdr;
{
char **hp = headers;
while (*hp)
{ if (strncmp(hdr, *hp, strlen(*hp)) == SAME)
return(1);
hp++;
}
return(0);
}
cleanup(code)
int code;
{
exit(code);
}
\Rogue\Monster\
else
echo "Will not over-write ./Support/uumailclean.c"
fi
chmod 444 ./Support/uumailclean.c
if [ `wc -c < ./Support/uumailclean.c` -ne 7456 ]
then
echo 'Got' `wc -c < ./Support/uumailclean.c` ', Expected ' 7456
fi
if `test ! -s ./Support/warn.c`
then
echo "Writing ./Support/warn.c"
cat > ./Support/warn.c << '\Rogue\Monster\'
#include <stdio.h>
/*
* routines to maintain a list of mailfiles for which warning messages have
* been sent out, plus routines to send out warning and failure messages.
*
* Written by Jim Crammond <jim@cs.hw.ac.uk> 3/86
*/
#define SENDMAIL "/usr/lib/sendmail"
#define NAMESIZE 15
#define BLKSIZE ((BUFSIZ/NAMESIZE) - 1)
struct flist
{ char fname[BLKSIZE][NAMESIZE];
int nused;
struct flist *next;
};
struct flist warnlist;
FILE *warnfp;
/*
* Initialise list of files for which warning messages have already been sent.
* This involves reading the warnfile into a table, removing files which
* no longer exist (i.e. been sent or deleted), and writing this out again.
*/
init_warnedlist(warnfile)
char *warnfile;
{
struct flist *wp;
char warned[NAMESIZE], *p;
int i;
char *index();
wp = &warnlist;
wp->next = NULL;
wp->nused = 0;
if ((warnfp = fopen(warnfile, "r")) != NULL)
{ while (fgets(warned, NAMESIZE, warnfp) != NULL)
{ if ((p = index(warned, '\n')) != NULL)
*p = '\0';
if (exists(warned))
{ if (wp->nused >= BLKSIZE)
{ wp->next = (struct flist *) malloc(sizeof(warnlist));
wp = wp->next;
wp->next = (struct flist *) NULL;
wp->nused = 0;
}
strcpy(wp->fname[wp->nused], warned);
wp->nused++;
}
}
fclose(warnfp);
}
/*
* Rewrite warnedlist removing files that no longer exist.
* Could be really paranoid here and create a temporary file
* first, rather than overwrite; in case of crashed
*/
if ((warnfp = fopen(warnfile, "w")) != NULL)
{ wp = &warnlist;
while (wp)
{ for (i=0; i < wp->nused; i++)
fprintf(warnfp, "%s\n", wp->fname[i]);
wp = wp->next;
}
fflush(warnfp);
}
}
/*
* Determine whether the given filename is in the warn list.
* Returns 1 if found, 0 otherwise.
*/
in_warnedlist(file)
char *file;
{
struct flist *wp = &warnlist;
int i;
while (wp)
{ for (i=0; i < wp->nused; i++)
{ if (strcmp(file, wp->fname[i]) == 0)
return(1);
}
wp = wp->next;
}
return(0);
}
/*
* Add a filename to the warn list.
*/
add_warnedlist(file)
char *file;
{
fprintf(warnfp, "%s\n", file);
}
/*
* Send a Failed Mail message back to the sender, containing the whole
* of the failed message.
*/
sendfailure(sender, rcpts, host, hours, msgfile)
char *sender;
char **rcpts;
char *host;
int hours;
char *msgfile;
{
FILE *out, *popen();
char cmd[50];
sprintf(cmd, "%s -t", SENDMAIL);
out = popen(cmd, "w");
fprintf(out, "From: MAILER-DAEMON\nSubject:Failed Mail\nTo: %s\n\n", sender);
fprintf(out, "After %d days (%d hours), your message to the following people:\n\n", hours/24, hours);
/* put out recipents */
while (*rcpts)
{ fprintf(out, "\t%s (host=%s)\n", *rcpts, host);
rcpts++;
}
fprintf(out, "\ncould not be delivered.\n\n");
fprintf(out, " ----- Unsent message follows ----- \n");
/* print all of the message */
print_message(msgfile, out, 0);
pclose(out);
return;
}
/*
* Send a Waiting Mail message back to the sender, containing a summary
* of the delayed message (to remind him/her what it was about!).
*/
sendwarning(sender, rcpts, host, hours, failtime, msgfile)
char *sender;
char **rcpts;
char *host;
int hours;
int failtime;
char *msgfile;
{
FILE *out, *popen();
char cmd[50];
sprintf(cmd, "%s -t", SENDMAIL);
out = popen(cmd, "w");
fprintf(out, "From: MAILER-DAEMON\nSubject:Waiting Mail\nTo: %s\n\n",
sender);
fprintf(out, "After %d days (%d hours), your message to the following people:\n\n", hours/24, hours);
/* put out recipents */
while (*rcpts)
{ fprintf(out, "\t%s (host=%s)\n", *rcpts, host);
rcpts++;
}
fprintf(out, "\nhas not yet been delivered. Attempts to deliver the message will\n");
fprintf(out, "continue for %d more days. No further action is required by you.\n\n", (failtime-hours)/24);
fprintf(out, " ----- Queued message begins ----- \n");
/* print a summary of the message */
print_message(msgfile, out, 1);
pclose(out);
return;
}
\Rogue\Monster\
else
echo "Will not over-write ./Support/warn.c"
fi
chmod 444 ./Support/warn.c
if [ `wc -c < ./Support/warn.c` -ne 3988 ]
then
echo 'Got' `wc -c < ./Support/warn.c` ', Expected ' 3988
fi
if `test ! -d ./Manuals`
then
mkdir ./Manuals
echo "mkdir ./Manuals"
fi
if `test ! -s ./Manuals/authorise.1`
then
echo "Writing ./Manuals/authorise.1"
cat > ./Manuals/authorise.1 << '\Rogue\Monster\'
.TH AUTHORISE 1 "UK-sendmail"
.UC 4
.SH NAME
authorise - sendmail authorisation program
.SH SYNOPSIS
.B authorise
[-f authorisation_file ]
.B channel
.B sender
.B recipient
.B command
[args]
.SH DESCRIPTION
.I Authorise
allows outgoing mail to be subjected to authorisation
on certain channels, based on sender address and recipient
address or relay host.
.PP
Permission is based on entries contained in an authorisation file (
.I /usr/lib/authorisations
by default).
Each line has three entries:
.I "channel name",
.I "sender address",
.I "relay host/recipient address".
The channel name is a string indicating the name of the outgoing channel.
The sender and recipient addresses are pattern strings in which wildcards,
lists of alternatives and negative matches
(i.e. matches which force authorisation to fail) can be specified.
.PP
Wildcards are specified by a "*" and will match zero or more characters.
Lists are specified by a comma separated list enclosed in brackets, e.g.
{a,b,c}. Negative matches are specified by a preceding "^".
Lists can contain wildcards and
negative matches, thus producing a reasonably powerful pattern matching
system. These special characters can be escaped by preceding them with a "\e".
Finally, if a "#" is encountered then the rest of the line is treated as
comment.
.PP
.I Authorise
will stop searching the authorisation file once a match has been found,
so the order of the entries in the file is important when negative matches
are used.
.SH EXAMPLES
Here are some examples of authorisation on
.I "sender address" and
.I "relay host"
(i.e. the host sendmail is about to send the mail to).
.in +5
.nf
.ta 1i 4i 4.5i
# simple per-user sender authorisation
csnet jim@cs.hw.ac.uk * # single user
csnet {alex,ian,paul}@cs.hw.ac.uk * # a list of users
# simple per-host sender authorisation
csnet *@cs.hw.ac.uk * # single domain
csnet *@*.cs.hw.ac.uk * # and all subdomains
# preventing users from using this channel
csnet ^{jim,ian}@cs.hw.ac.uk * # jim & ian are banned
csnet * * # everyone else is okay
.ta 1i 3.5i 4i
# more complex example - users on hw.ga and hw.hci
# can only send to ukc and ed sites; users at other hw
# sites send to anywhere.
janet *@uk.ac.hw.{ga,hci} uk.ac.{ukc,ed}*
janet ^*@uk.ac.hw.{ga,hci} *
janet *@uk.ac.hw* *
# only allow local users to use that link to the USA!
# anyone can use the other uucp links
uucp *@cs.hw.cs.uk ucbvax
uucp * {aimmi,spider,zen}
.fi
.in
.PP
Note that the syntax of the addresses are in the form appropriate for that
mailer and that when authorising on recipient address, it is the
.I "transport address"
which is actually used (i.e. the one given to the mailer interface
in the command line). Thus, an entry using
.I "recipient address"
on the local uucp channel might be:
.in +5
.nf
# uucp link to "service" is only for error reports..
luucp * service!bug-reports
.ta 0.5i 1.5i 2.5i
.fi
.in
.SH "SENDMAIL INTERFACE"
The interface to sendmail is quite simple. For relay host based authorisation
two changes need to be made to mailer specification for the channel
requiring authorisation in the sendmail configuration.
.IP 1.
change the pathname of the mailer interface to the path of the
authorise program.
.IP 2.
change the command arguments specification to:
.nf
A=authorise <channel> $g $h <pathname> <args>
.fi
where:
.RS 0.5i
.IP <channel> 12
is the name of the channel (e.g. uucp, janet, csnet);
.IP <pathname> 12
is the path of the mailer interface
.IP <args> 12
are the arguments to the mailer interface
(not including the command name itself).
.RE
.IP
$g is the sender address and $h is the relay host.
.PP
This is done automatically for you by the UK-2.1 Sendmail Configuration
Package when you specify the
.I auth
option to the channel specification in the configuration description file.
.PP
For recipient address based authorisation, $u should be given
instead of $h as the third argument to authorise (for uucp channels
use $h!$u). Further, the 'm' flag must be removed from the mailer flags.
.PP
This is needed because
.I authorise
does not allow multiple recipients to be specified.
For this reason, authorisation on relay-host is much preferred.
.SH EXAMPLE
The janet channel, normally specified as :-
.nf
Mniftp, P=/usr/lib/niftp/ni_send, F=nsmFDMSxu, S=24, R=24, M=100000,
A=ni_send -f $g $h $u
for relay host authorisation, becomes :-
Mniftp, P=/usr/lib/authorise, F=nsmFDMSxu, S=24, R=24, M=100000,
A=authorise janet $g $h /usr/lib/niftp/ni_send -f $g $h $u
and for recipient address authorisation, becomes :-
Mniftp, P=/usr/lib/authorise, F=nsFDMSxu, S=24, R=24, M=100000,
A=authorise janet $g $u /usr/lib/niftp/ni_send -f $g $h $u
.fi
.SH FILES
/usr/lib/authorisations - default authorisation file
.SH "SEE ALSO"
sendmail(8)
.SH AUTHOR
Jim Crammond
.SH BUGS
.IP 1.
Authorisation cannot be placed on the ethernet or tcp channels as
sendmail does the delivery itself, using sockets.
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/authorise.1"
fi
chmod 444 ./Manuals/authorise.1
if [ `wc -c < ./Manuals/authorise.1` -ne 4927 ]
then
echo 'Got' `wc -c < ./Manuals/authorise.1` ', Expected ' 4927
fi
if `test ! -s ./Manuals/checkaddr.1`
then
echo "Writing ./Manuals/checkaddr.1"
cat > ./Manuals/checkaddr.1 << '\Rogue\Monster\'
.TH CHECKADDR 1 "UK-sendmail"
.UC 4
.SH NAME
checkaddr - sendmail address verification program
.SH SYNOPSIS
.B checkaddr
[-v]
.B addresses...
.SH DESCRIPTION
The
.I checkaddr
program is used to check the validity of any address with
the local mail system (sendmail).
A list of addresses is given on the command line,
checkaddr will then announce each
address on a separate line and follow the address with its status
(normally ``addr OK'').
.PP
By specifying the -v flag, checkaddr will print additional information
about how it
.I normalises
the address and
what routing it then does.
.SH "SEE ALSO"
sendmail(8)
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/checkaddr.1"
fi
chmod 444 ./Manuals/checkaddr.1
if [ `wc -c < ./Manuals/checkaddr.1` -ne 622 ]
then
echo 'Got' `wc -c < ./Manuals/checkaddr.1` ', Expected ' 622
fi
if `test ! -s ./Manuals/distribute.1`
then
echo "Writing ./Manuals/distribute.1"
cat > ./Manuals/distribute.1 << '\Rogue\Monster\'
.TH DISTRIBUTE 8 "UK-sendmail"
.UC 4
.SH NAME
distribute - send mail to a distribution list
.SH SYNOPSIS
.B /usr/local/lib/distribute
.B list-name
.B addresses...
.SH DESCRIPTION
.I Distribute
sends a mail message to users on a distribution list.
It alters the message header received from a contributor
mainly to arrange for any error messages to be
returned to the list maintainer.
.PP
.I Distribute
is normally invoked by sendmail from an alias entry in
/usr/lib/aliases of the form:
.PP
.DT
list-name: "|/usr/local/lib/distribute list-name users..."
.PP
With lists containing many names, which maybe subject to frequent
alteration, it is best to store the usernames in a file and specify
the path name of the file with the syntax
.I ":include:file",
i.e.
.PP
.nf
list-name: "|/usr/local/lib/distribute list-name :include:file"
.fi
.PP
There should be a second entry in /usr/lib/aliases for the list maintainer.
This is the name of the list with "\-request" appended. This should be
aliased to the person who is responsible for maintaining the distribution
list.
e.g.
.PP
.DT
list-name-request: postman-pat
.PP
.I Distribute
should be setuid to one of sendmail's trusted users, so that
it will set the sender address to that of the list maintainer.
.SH FILES
/usr/lib/aliases
.SH "SEE ALSO"
sendmail(8), aliases(5), newaliases(1)
.br
"Recommendations for implementors of the
JNT Mail Protocol Specifications (MG.B)"
by Steve Kille, April 1985
.SH AUTHOR
Jim Crammond
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/distribute.1"
fi
chmod 444 ./Manuals/distribute.1
if [ `wc -c < ./Manuals/distribute.1` -ne 1471 ]
then
echo 'Got' `wc -c < ./Manuals/distribute.1` ', Expected ' 1471
fi
if `test ! -s ./Manuals/mail-news.8`
then
echo "Writing ./Manuals/mail-news.8"
cat > ./Manuals/mail-news.8 << '\Rogue\Monster\'
.TH MAIL-NEWS 8 "UK-sendmail"
.UC 4
.SH NAME
mail-news - send mail to newsgroups
.SH SYNOPSIS
.B /usr/lib/news/mail-news
.B <arguments for inews>
.SH DESCRIPTION
.I Mail-news
sends a mail message to one or more newsgroups.
It alters the message header to ensure that it satisfies certain
constraints imposed by inews version B.2.11, mainly to insure that
there is a subject and that included text does not cause rejections.
.PP
.I Mail-news
is normally invoked by sendmail from a mailer channel; it may also be invoked
by an alias entry (in /usr/lib/aliases) of the form:
.PP
.DT
list-name: "|/usr/lib/news/mail-news [inews argument list]"
.SH "SEE ALSO"
sendmail(8), inews(8) recnews(1)
.SH AUTHOR
Jem Taylor
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/mail-news.8"
fi
chmod 444 ./Manuals/mail-news.8
if [ `wc -c < ./Manuals/mail-news.8` -ne 711 ]
then
echo 'Got' `wc -c < ./Manuals/mail-news.8` ', Expected ' 711
fi
if `test ! -s ./Manuals/muucp.8c`
then
echo "Writing ./Manuals/muucp.8c"
cat > ./Manuals/muucp.8c << '\Rogue\Monster\'
.TH MUUCP 8 "UK-sendmail"
.SH NAME
muucp \- send mail over uucp, using the UUCP transmission format
.SH SYNOPSIS
.B muucp
[uux options]
.B -f<from_address>
.B -H<uucpname>
host user1 user2 ...
.SH DESCRIPTION
.I Muucp
simply prepends a unix From line to the message received from
.IR sendmail (8)
which is then passed on to
.IR uux (1C).
.PP
The from address passed by sendmail is expected in "percent form"
and is converted to uucp path address ("bang format"). Muucp also removes
any duplicate domains which are detected in the resulting path.
.SH "SEE ALSO"
sendmail(8)
uux(1C)
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/muucp.8c"
fi
chmod 444 ./Manuals/muucp.8c
if [ `wc -c < ./Manuals/muucp.8c` -ne 581 ]
then
echo 'Got' `wc -c < ./Manuals/muucp.8c` ', Expected ' 581
fi
if `test ! -s ./Manuals/uumailclean.8c`
then
echo "Writing ./Manuals/uumailclean.8c"
cat > ./Manuals/uumailclean.8c << '\Rogue\Monster\'
.TH UUMAILCLEAN 8C "UK-Sendmail"
.UC 4
.SH NAME
uumailclean \- uucp spool directory mail clean-up
.SH SYNOPSIS
.B /usr/lib/uucp/uumailclean
.SH DESCRIPTION
.I Uumailclean
scans the uucp spool directory for mail files and checks to see how long
they have been queued.
If a mail message is found to have been queued for longer than
.I failtime
hours, then it is returned to the sender and deleted from the queue.
If a mail message is found to have been queued for longer than
.I warntime
hours (but less than failtime), then
a warning message is sent to the sender to inform them that the mail
has yet to be delivered.
.PP
By default, failtime is set to 168 hours (1 week) and warntime to 72 hours
(3 days). With the subdirectories option of UKUUCP,
.I uumailclean
will override these defaults if times are specified in the
.I L.dirs
file as 3rd and 4th arguments to the subdirectory entries. For example,
.nf
C.hwcs 336 96 48
.fi
specifies a failtime of 96 hours and a warntime of 48 hours.
.PP
.I uumailclean
maintains a list of mail files for which warning messages
have already been sent out, so that the sender will only receive one
warning message. This is normally the file
.I warnlist.mail
in the uucp spool directory.
.PP
.I Uumailclean
will typically be started by
.IR cron (8).
.SH FILES
/usr/spool/uucp uucp spool directory
.br
/usr/spool/uucp/warnlist.mail list of warned mail files
.br
/usr/lib/uucp/L.dirs list of subdirectories of spool
.br
/usr/spool/uucp/warnlist.mail list of warned mail files
.SH "SEE ALSO"
sendmail(8), uuclean(8C)
.SH AUTHOR
Jim Crammond
\Rogue\Monster\
else
echo "Will not over-write ./Manuals/uumailclean.8c"
fi
chmod 444 ./Manuals/uumailclean.8c
if [ `wc -c < ./Manuals/uumailclean.8c` -ne 1582 ]
then
echo 'Got' `wc -c < ./Manuals/uumailclean.8c` ', Expected ' 1582
fi
echo "Finished archive 3 of 4"
exit