rmail revisited

utzoo!decvax!ucbvax!ihnss!cbosg!cbosgd!mark utzoo!decvax!ucbvax!ihnss!cbosg!cbosgd!mark
Sun Feb 28 11:38:00 AEST 1982


From: mark (Mark Horton)
It has been pointed out to me that the 4.1BSD rmail program, as distributed,
does NOT handle multiple addresses correctly after all.  I seem to have
been running a more current version.  So I'm enclosing an rmail which
will do it right.
	Mark
static char *sccsid = "@(#)rmail.c	4.1 (Berkeley) 10/1/80";
static char *mrhid  = "@(#)rmail.c	1.5	(MRH)	2/28/82";
/*
 * rmail: front end for mail to stack up those stupid >From ... remote from ...
 * lines and make a correct return address.  This works with the -f option
 * to /etc/delivermail so it won't work on systems without delivermail.
 * However, it ought to be easy to modify a standard /bin/mail to do the
 * same thing.
 *
 * Via and Date lines added by Steve Bellovin of UNC.
 */

#include <stdio.h>
#include <ctype.h>
FILE *popen();
char *index();

#define MAILER	"/etc/delivermail"

main(argc, argv)
char **argv;
{
	FILE *out;		/* output to delivermail */
	char lbuf[1024];	/* one line of the message */
	char from[1024];	/* accumulated path of sender */
	char via[1024];		/* uucp path of ARPA sender */
	char date[1024]; 	/* date of original letter */
	char ufrom[128];	/* user on remote system */
	char sys[128];		/* a system in path */
	char junk[1024];	/* scratchpad */
	char cmd[1024];
	register char *cp, *p;
	char *arpa, *uucp;
	register char **to;

	if (argc < 2) {
		fprintf(stderr, "Usage: rmail user...\n");
		exit(1);
	}

	from[0] = date[0] = via[0] = '\0';
	for (;;) {
		fgets(lbuf, sizeof lbuf, stdin);
		if (strncmp(lbuf, "From ", 5) && strncmp(lbuf, ">From ", 6))
			break;
		/* sscanf(lbuf, "%s %s %s %s %s %s %s remote from %s", junk, ufrom, junk, junk, junk, junk, junk, sys); */
		p = index(lbuf, ' ');	/* note -- cannot be NULL */
		while (isspace(*p)) p++;	/* find start of name */
		for (cp = p; !isspace(*cp); cp++)	/* find end of name */
			if (*cp == '\0') break;
		strncpy(ufrom, p, cp-p);
		ufrom[cp-p] = '\0';
		while(isspace(*cp)) cp++;
		p = cp;
		for (;;) {
			cp = index(cp+1, 'r');
			if (cp == NULL)
				goto nsys;
#ifdef DEBUG
			printf("cp='%s'\n", cp);
#endif
			if (strncmp(cp, "remote from ", 12)==0)
				break;
		}
		sscanf(cp, "remote from %s", sys);
		strcat(from, sys);
		strcat(from, "!");
		while (--cp > p && isspace(*cp))
			;
		if (++cp > p) {
			*cp = '\0';
			strcpy(date, p);
		}
nsys:;
#ifdef DEBUG
		printf("ufrom='%s', sys='%s', from now '%s' date=%s\n", ufrom, sys, from, date);
#endif
	}
	strcat(from, ufrom);

	arpa = index(from, '@');
	if (arpa == NULL) arpa = index(from, '%');
	if (arpa) {
		for (uucp = arpa-1; uucp >= from; uucp--)
			if (*uucp == '!') break;
		if (uucp >= from) {
			*uucp = '\0';
			strcpy(via, from);
			strcpy(from, uucp+1);
		}
	}

	sprintf(cmd, "%s -r%s -em", MAILER, from);
	for (to = &argv[1]; *to; to++) {
		strcat(cmd, " ");
		strcat(cmd, *to);
	}
#ifdef DEBUG
	printf("cmd='%s'\n", cmd);
#endif
	setuid(0);
	out = popen(cmd, "w");
	if (via[0]) {
		if (strncmp(lbuf, "Via:", 4) == 0) {
			lbuf[strlen(lbuf)-1] = '!';
			strcat(lbuf, via);
			fprintf(out, "%s\n", lbuf);
			fgets(lbuf, sizeof lbuf, stdin);
		}
		else fprintf(out, "Via: %s\n", via);
	}
	if (date[0] && strncmp(lbuf, "Date", 4))
		fprintf(out, "Date: %s\n", date);
	fputs(lbuf, out);
	while (fgets(lbuf, sizeof lbuf, stdin))
		fputs(lbuf, out);
	pclose(out);
}

/*
 * Return the ptr in sp at which the character c appears;
 * NULL if not found
 */

char *
index(sp, c)
register char *sp, c;
{
	do {
		if (*sp == c)
			return(sp);
	} while (*sp++);
	return(NULL);
}



More information about the Comp.bugs.4bsd.ucb-fixes mailing list