The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: 'Phage List' - Archives (1988 - 1989)
DOCUMENT: phage #276 [Pyramid's version of rmail.c] (1 message, 3243 bytes)
SOURCE: http://securitydigest.org/exec/display?f=phage/archive/276.txt&t=text/plain
NOTICE: securitydigest.org recognises the rights of all third-party works.

START OF DOCUMENT

From: ames!pyramid.pyramid.com!csg@ea.ecn.purdue.edu (Carl S. Gutekunst)
To: phage
Date: Fri 15:00:16 18/11/1988 EST
Subject: Pyramid's version of rmail.c
References: [Thread Prev: 274] [Thread Next: 277] [Message Prev: 274] [Message Next: 275]

[This is a repost. Mail to phage doesn't seem to be getting through.]

I started out modifying rmail.c; I ended up throwing it out. This version is
not quite as clever as Rick's (no lseek), although it does do a better parse
of the From_ line. It also inserts 'hostname!uucp' when it cannot find any
From_ line, instead of /dev/null. Of course, it eliminates the popen() call,
and returns an error if it finds an argument beginning with a '-'.

And it comes with a man page. :-)

I like the lseek trick. I may modify this to use it....

<csg>

: ------ CUT HERE ------ CUT HERE ------ CUT HERE ------ CUT HERE ------
: This is a shell archive.
: To unpack it, feed it to /bin/sh, NOT to /bin/csh.
:
: This archive includes the following files:
:	rmail.1
:	rmail.c
:
echo x - rmail.1
sed 's/^X//' >rmail.1 <<'*-*-END-of-rmail.1-*-*'
X.TH RMAIL 1-ucb
X.SH NAME
Xrmail \- accept remote mail received via \s-1UUCP\s0
X.SH SYNOPSIS
X.B rmail
X.I user1
X[
X.I user2
X] ... [
X.I usern
X]
X.SH DESCRIPTION
X.I Rmail
Xis a simple interface utility that accepts mail from
X.IR uux (1C)
Xand pipes it into
X.IR sendmail (8).
XIt reads a mail message from stdin, and collapses multiple \s-1UUCP\s0-style
X``From\ '' lines into a single '!' path.
XThe mail message is then piped to
X.IR sendmail ,
Xwhich is invoked with the following command line:
X.IP
X\fB/usr/lib/sendmail\ -ee\ -i\ -f\fP\ \fIbangpath\fP\fB!\fP\fIuser\ user1\ user2\ ...\ usern\fP
X.PP
Xwhere \fIbangpath\fP\fB!\fP\fIuser\fP is the collapsed path,
Xand \fIusern\fP is the list of arguments from the
X.B /bin/rmail
Xcommand line (the list of recipients).
XTo prevent any surreptitious manipulation of sendmail options,
Xany
X.I rmail
Xarguments that begin with a hyphen will cause the entire message to be
Xdiscarded.
X.PP
XThree forms of ``From\ '' lines are recognized.
XThe old /bin/mail style, still used in System VR3.2:
X.IP
XFrom\ uucp\ Sat\ Nov\ 12\ 21:53\ PST\ 1988\ remote\ from\ pyr3b2
X.br
X>From\ csg\ Sat\ Nov\ 12\ 21:23\ PST\ 1988\ remote\ from\ pyramid
X.PP
Xthe RFC-976 style ``envelope'' line:
X.IP
XFrom\ pyr3b2!pyramid!csg\ Sat\ Nov\ 12\ 19:53:44\ 1988
X.PP
Xand the invalid but not-unheard-of '@' line:
X.IP
XFrom\ csg@pyramid\ Sat\ Nov\ 12\ 19:53:44\ 1988
X.PP
XMixed formats will produce mixed results.
X``remote from'' has the highest precedence
X(that is, it is assumed to refer to the nearest host), then `@', and
Xthen `!'.
XSo the blasphemous:
X.IP
XFrom\ pyramid!csg@pyrvax\ Sat\ Nov\ 12\ 19:53:44\ 1988\ remote\ from\ pyr3b2
X.PP
Xwill be turned into:
X.IP
Xpyr3b2!pyrvax!pyramid!csg
X.PP
XIf no ``From\ '' lines can be found, then
X\fIhostname\fP\fB!uucp\fP
Xis substituted, where
X.I hostname
Xis the name of the local host.
X(Note that if
X.I sendmail
Xaccepts a message with no ``From\ '' line and no \fB\-f\fP option,
Xit uses \fIuser\fP@\fIhostname\fP, with \fIuser\fP taken from the effective
XUID that invoked
X.IR rmail .
XThis is inelegant.)
XIf
X.I rmail
Xabsolutely cannot determine a hostname for a particular line,
Xthen the magic word
X.B somewhere
Xis substituted.
X.PP
XNote that no ``From\ '' lines are passed to
X.IR sendmail ;
Xall are discarded by
X.IR rmail .
X.I Sendmail
Xforms a new ``From\ '' line from the \fB\-f\fP option field.
X.SH "SEE ALSO"
Xbinmail(1),
Xuux(1C),
Xuuxqt(8C),
Xsendmail(8)
*-*-END-of-rmail.1-*-*
echo x - rmail.c
sed 's/^X//' >rmail.c <<'*-*-END-of-rmail.c-*-*'
X#ifndef lint
Xstatic char *RcsId = "@(#)rmail.c $Revision: 1.1 $ $Date: 2003/02/04 10:07:18 $";
X#endif
X
X/*
X *  rmail.c -- UUCP mail server.
X *
X * This utility is intended as a simple preprocessor for sendmail. It accepts
X * a mail message on stdin, and collapses multiple UUCP-style "From " lines
X * into a single '!' path.
X *
X * For more details, see the rmail(1) man page.
X *
X * By Carl S. Gutekunst, Pyramid Technology Corporation <csg@pyramid.com>
X * Released into the public domain, unrestricted distribution
X */
X
X#include <stdio.h>
X#include <sysexits.h>
X
X#define TRUE	(1)
X#define FALSE	(0)
X#define SAME	(0)
X
XFILE	*popen();
Xchar	*index();
Xchar	*rindex();
X
Xchar	Debug;
X
X#define MAILER	"/usr/lib/sendmail"
X#define USER	"uucp"
X#define NCMDS	256
X
Xchar *cmd[NCMDS] =
X{
X	MAILER,
X	"-ee",
X	"-i",
X	"-f",
X};
X#define CMD_START 4
X
Xmain(argc, argv)
X	char **argv;
X{
X	char lbuf[1024], *lp;		/* one line of the message */
X	char path[1024];		/* accumulated path of sender */
X	char user[512], *up = NULL;	/* user on remote system */
X	FILE *out;			/* output to sendmail */
X	char **cargp;			/* Outgoing argument list pointer */
X	int foundit;
X	int err;
X
X# ifdef DEBUG
X	if (argc > 1 && strcmp(argv[1], "-T") == SAME)
X	{
X		Debug = TRUE;
X		argc--;
X		argv++;
X	}
X# endif DEBUG
X
X	if (argc < 2)
X	{
X		fprintf(stderr, "Usage: rmail user ...\n");
X		exit(EX_USAGE);
X	}
X
X	path[0] = '\0';
X
X	while (fgets(lbuf, sizeof lbuf, stdin) != NULL)
X	{
X		foundit = FALSE;
X		if (strncmp(lbuf, "From ", 5) == SAME)
X			lp = &lbuf[5];
X		else if (strncmp(lbuf, ">From ", 6) == SAME)
X			lp = &lbuf[6];
X		else
X			break;
X
X		(void) sscanf(lp, "%s", user);
X
X		while ((lp = index(lp+1, 'r')) != NULL)
X		{
X			if (strncmp(lp, "remote from ", 12) == SAME)
X			{
X				sscanf(lp + 12, "%s", index(path, '\0'));
X				foundit = TRUE;
X				(void) strcat(path, "!");
X				break;
X			}
X		}
X
X		if ((up = rindex(user, '@')) != NULL)
X		{
X			*up++ = '\0';
X			(void) strcat(path, up);
X			(void) strcat(path, "!");
X			foundit = TRUE;
X		}
X		if ((up = rindex(user, '!')) != NULL)
X		{
X			*up++ = '\0';
X			(void) strcat(path, user);
X			(void) strcat(path, "!");
X			foundit = TRUE;
X		}
X		else
X			up = user;
X		if (!foundit)
X			(void) strcat(path, "somewhere!");
X	}
X
X	if (path[0] == '\0')
X	{
X		(void) gethostname(path, sizeof path);
X		(void) strcat(path, "!");
X	}
X	if (up == NULL)
X		up = USER;
X	(void) strcat(path, up);
X
X	cargp = &cmd[CMD_START];
X	*cargp++ = path;
X
X	while (*++argv != NULL)
X	{
X		if (**argv == '-')
X			exit(EX_USAGE);
X		*cargp++ = *argv;
X	}
X	*cargp = NULL;
X#ifdef DEBUG
X	if (Debug)
X	{
X		printf("cmd=");
X		cargp = cmd;
X		while (*cargp != NULL)
X			printf(" %s", *cargp++);
X		putchar('\n');
X	}
X#endif
X
X#ifdef DEBUG
X	if (Debug)
X		out = stdout;
X	else
X#endif DEBUG
X	if ((out = popen(cmd)) == NULL)
X		exit(EX_OSERR);
X	fputs(lbuf, out);
X	while (fgets(lbuf, sizeof lbuf, stdin))
X		fputs(lbuf, out);
X#ifdef DEBUG
X	if (Debug)
X	{
X		fclose(out);
X		err = 0;
X	}
X	else
X#endif DEBUG
X	err = pclose(out);
X	if ((err & 0377) != 0)
X	{
X		fprintf(stderr, "pclose: status 0%o\n", err);
X		exit(EX_OSERR);
X	}
X
X	exit((err >> 8) & 0377);
X}
X
X#define PIPE_WRITE 1
X#define PIPE_READ  0
Xint childpid;
X
XFILE *
Xpopen(cmd)
Xchar **cmd;
X{
X	int pfd[2];
X
X	if (pipe(pfd) == -1)
X		return NULL;
X
X	if ((childpid = fork()) == -1)
X		return NULL;
X	else if (childpid == 0)
X	{
X		(void) close(pfd[PIPE_WRITE]);
X		(void) dup2(pfd[PIPE_READ], 0);
X		(void) close(pfd[PIPE_READ]);
X		execv(cmd[0], cmd);
X		return NULL;
X	}
X	(void) close(pfd[PIPE_READ]);
X	return fdopen(pfd[PIPE_WRITE], "w");
X}
X
Xpclose(fp)
XFILE *fp;
X{
X	int retval, status;
X
X	fclose(fp);
X	while ((retval = wait(&status)) != childpid && retval != -1)
X		;
X	return status;
X}
*-*-END-of-rmail.c-*-*
exit

END OF DOCUMENT