11392Seric # include <stdio.h>
21392Seric # include <ctype.h>
31392Seric # include "dlvrmail.h"
41392Seric 
5*1397Seric static char	SccsId[] = "@(#)collect.c	1.3	10/11/80";
61392Seric 
71392Seric /*
81392Seric **  MAKETEMP -- read & parse message header & make temp file.
91392Seric **
101392Seric **	Creates a temporary file name and copies the standard
111392Seric **	input to that file.  While it is doing it, it looks for
121392Seric **	"From:" and "Sender:" fields to use as the from-person
131392Seric **	(but only if the -a flag is specified).  It prefers to
141392Seric **	to use the "Sender:" field.
151392Seric **
161392Seric **	MIT seems to like to produce "Sent-By:" fields instead
171392Seric **	of "Sender:" fields.  We used to catch this, but it turns
181392Seric **	out that the "Sent-By:" field doesn't always correspond
191392Seric **	to someone real ("___057", for instance), as required by
201392Seric **	the protocol.  So we limp by.....
211392Seric **
221392Seric **	Parameters:
231392Seric **		none
241392Seric **
251392Seric **	Returns:
261392Seric **		Name of temp file.
271392Seric **
281392Seric **	Side Effects:
291392Seric **		Temp file is created and filled.
301392Seric **
311392Seric **	Called By:
321392Seric **		main
331392Seric **
341392Seric **	Notes:
351392Seric **		This is broken off from main largely so that the
361392Seric **		temp buffer can be deallocated.
371392Seric */
381392Seric 
39*1397Seric char	MsgId[MAXNAME];
40*1397Seric 
411392Seric char *
421392Seric maketemp()
431392Seric {
441392Seric 	register FILE *tf;
451392Seric 	char buf[MAXFIELD+1];
461392Seric 	static char fbuf[sizeof buf];
471392Seric 	extern char *prescan();
481392Seric 	extern char *matchhdr();
491392Seric 	register char *p;
501392Seric 	register bool inheader;
511392Seric 	bool firstline;
521392Seric 	char c;
531392Seric 
541392Seric 	/*
551392Seric 	**  Create the temp file name and create the file.
561392Seric 	*/
571392Seric 
581392Seric 	mktemp(InFileName);
591392Seric 	close(creat(InFileName, 0600));
601392Seric 	if ((tf = fopen(InFileName, "w")) == NULL)
611392Seric 	{
621392Seric 		syserr("Cannot create %s", InFileName);
631392Seric 		return (NULL);
641392Seric 	}
651392Seric 
661392Seric 	/*
671392Seric 	**  Copy stdin to temp file & do message editting.
681392Seric 	**	From person gets copied into fbuf.  At the end of
691392Seric 	**	this loop, if fbuf[0] == '\0' then there was no
701392Seric 	**	recognized from person in the message.  We also
711392Seric 	**	save the message id in MsgId.  The
721392Seric 	**	flag 'inheader' keeps track of whether we are
731392Seric 	**	in the header or in the body of the message.
741392Seric 	**	The flag 'firstline' is only true on the first
751392Seric 	**	line of a message.
761392Seric 	**	To keep certain mailers from getting confused,
771392Seric 	**	and to keep the output clean, lines that look
781392Seric 	**	like UNIX "From" lines are deleted in the header,
791392Seric 	**	and prepended with ">" in the body.
801392Seric 	*/
811392Seric 
821392Seric 	inheader = TRUE;
831392Seric 	firstline = TRUE;
841392Seric 	fbuf[0] = '\0';
851392Seric 	while (fgets(buf, sizeof buf, stdin) != NULL)
861392Seric 	{
871392Seric 		if (inheader && isalnum(buf[0]))
881392Seric 		{
891392Seric 			/* get the rest of this field */
901392Seric 			while ((c = getc(stdin)) == ' ' || c == '\t')
911392Seric 			{
921392Seric 				p = &buf[strlen(buf)];
931392Seric 				*p++ = c;
941392Seric 				if (fgets(p, sizeof buf - (p - buf), stdin) == NULL)
951392Seric 					break;
961392Seric 			}
971392Seric 			ungetc(c, stdin);
981392Seric 		}
991392Seric 
1001392Seric 		if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0'))
1011392Seric 			break;
1021392Seric 
1031392Seric 		/* are we still in the header? */
1041392Seric 		if ((buf[0] == '\n' || buf[0] == '\0') && inheader)
1051392Seric 		{
1061392Seric 			inheader = FALSE;
1071392Seric 			if (MsgId[0] == '\0')
1081392Seric 			{
1091392Seric 				makemsgid();
1101392Seric 				if (UseMsgId)
1111392Seric 					fprintf(tf, "Message-Id: <%s>\n", MsgId);
1121392Seric 			}
1131392Seric # ifdef DEBUG
1141392Seric 			if (Debug)
1151392Seric 				printf("EOH\n");
1161392Seric # endif DEBUG
1171392Seric 		}
1181392Seric 
1191392Seric 		/* Hide UNIX-like From lines */
1201392Seric 		if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' &&
1211392Seric 		    buf[3] == 'm' && buf[4] == ' ')
1221392Seric 		{
1231392Seric 			if (firstline && !SaveFrom)
1241392Seric 				continue;
1251392Seric 			fputs(">", tf);
1261392Seric 		}
1271392Seric 
1281392Seric 		if (inheader && !isspace(buf[0]))
1291392Seric 		{
1301392Seric 			/* find out if this is really a header */
1311392Seric 			for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++)
1321392Seric 				continue;
1331392Seric 			while (*p != ':' && isspace(*p))
1341392Seric 				p++;
1351392Seric 			if (*p != ':')
1361392Seric 			{
1371392Seric 				inheader = FALSE;
1381392Seric # ifdef DEBUG
1391392Seric 				if (Debug)
1401392Seric 					printf("EOH?\n");
1411392Seric # endif DEBUG
1421392Seric 			}
1431392Seric 		}
1441392Seric 
1451392Seric 		if (inheader)
1461392Seric 		{
1471392Seric 			/* find the sender */
1481392Seric 			p = matchhdr(buf, "sender");
1491392Seric 			if (p == NULL && fbuf[0] == '\0')
1501392Seric 				p = matchhdr(buf, "from");
1511392Seric 			if (p != NULL)
1521392Seric 				prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0');
1531392Seric 
1541392Seric 			/* find the message id */
1551392Seric 			p = matchhdr(buf, "message-id");
1561392Seric 			if (p != NULL && MsgId[0] == '\0')
1571392Seric 				prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0');
1581392Seric 		}
1591392Seric 		fputs(buf, tf);
1601392Seric 		firstline = FALSE;
1611392Seric 		if (ferror(tf))
1621392Seric 		{
1631392Seric 			syserr("Cannot write %s", InFileName);
1641392Seric 			clearerr(tf);
1651392Seric 			break;
1661392Seric 		}
1671392Seric 	}
1681392Seric 	fclose(tf);
1691392Seric 	if (MsgId[0] == '\0')
1701392Seric 		makemsgid();
1711392Seric 	if (freopen(InFileName, "r", stdin) == NULL)
1721392Seric 		syserr("Cannot reopen %s", InFileName);
1731392Seric 	return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL);
1741392Seric }
1751392Seric /*
1761392Seric **  MAKEMSGID -- Compute a message id for this process.
1771392Seric **
1781392Seric **	This routine creates a message id for a message if
1791392Seric **	it did not have one already.  If the MESSAGEID compile
1801392Seric **	flag is set, the messageid will be added to any message
1811392Seric **	that does not already have one.  Currently it is more
1821392Seric **	of an artifact, but I suggest that if you are hacking,
1831392Seric **	you leave it in -- I may want to use it someday if
1841392Seric **	duplicate messages turn out to be a problem.
1851392Seric **
1861392Seric **	Parameters:
1871392Seric **		none.
1881392Seric **
1891392Seric **	Returns:
1901392Seric **		none.
1911392Seric **
1921392Seric **	Side Effects:
1931392Seric **		Stores a message-id into MsgId.
1941392Seric **
1951392Seric **	Called By:
1961392Seric **		maketemp
1971392Seric */
1981392Seric 
1991392Seric makemsgid()
2001392Seric {
2011392Seric 	auto long t;
2021392Seric 	extern char *MyLocName;
2031392Seric 	extern char *ArpaHost;
2041392Seric 
2051392Seric 	time(&t);
2061392Seric 	sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost);
2071392Seric }
208