[comp.mail.sendmail] UK-2.1part3

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