1*1392Seric # include <stdio.h>
2*1392Seric # include <ctype.h>
3*1392Seric # include "dlvrmail.h"
4*1392Seric 
5*1392Seric static char	SccsId[] = "@(#)collect.c	1.2	10/11/80";
6*1392Seric 
7*1392Seric /*
8*1392Seric **  MAKETEMP -- read & parse message header & make temp file.
9*1392Seric **
10*1392Seric **	Creates a temporary file name and copies the standard
11*1392Seric **	input to that file.  While it is doing it, it looks for
12*1392Seric **	"From:" and "Sender:" fields to use as the from-person
13*1392Seric **	(but only if the -a flag is specified).  It prefers to
14*1392Seric **	to use the "Sender:" field.
15*1392Seric **
16*1392Seric **	MIT seems to like to produce "Sent-By:" fields instead
17*1392Seric **	of "Sender:" fields.  We used to catch this, but it turns
18*1392Seric **	out that the "Sent-By:" field doesn't always correspond
19*1392Seric **	to someone real ("___057", for instance), as required by
20*1392Seric **	the protocol.  So we limp by.....
21*1392Seric **
22*1392Seric **	Parameters:
23*1392Seric **		none
24*1392Seric **
25*1392Seric **	Returns:
26*1392Seric **		Name of temp file.
27*1392Seric **
28*1392Seric **	Side Effects:
29*1392Seric **		Temp file is created and filled.
30*1392Seric **
31*1392Seric **	Called By:
32*1392Seric **		main
33*1392Seric **
34*1392Seric **	Notes:
35*1392Seric **		This is broken off from main largely so that the
36*1392Seric **		temp buffer can be deallocated.
37*1392Seric */
38*1392Seric 
39*1392Seric char *
40*1392Seric maketemp()
41*1392Seric {
42*1392Seric 	register FILE *tf;
43*1392Seric 	char buf[MAXFIELD+1];
44*1392Seric 	static char fbuf[sizeof buf];
45*1392Seric 	extern char *prescan();
46*1392Seric 	extern char *matchhdr();
47*1392Seric 	register char *p;
48*1392Seric 	register bool inheader;
49*1392Seric 	bool firstline;
50*1392Seric 	char c;
51*1392Seric 
52*1392Seric 	/*
53*1392Seric 	**  Create the temp file name and create the file.
54*1392Seric 	*/
55*1392Seric 
56*1392Seric 	mktemp(InFileName);
57*1392Seric 	close(creat(InFileName, 0600));
58*1392Seric 	if ((tf = fopen(InFileName, "w")) == NULL)
59*1392Seric 	{
60*1392Seric 		syserr("Cannot create %s", InFileName);
61*1392Seric 		return (NULL);
62*1392Seric 	}
63*1392Seric 
64*1392Seric 	/*
65*1392Seric 	**  Copy stdin to temp file & do message editting.
66*1392Seric 	**	From person gets copied into fbuf.  At the end of
67*1392Seric 	**	this loop, if fbuf[0] == '\0' then there was no
68*1392Seric 	**	recognized from person in the message.  We also
69*1392Seric 	**	save the message id in MsgId.  The
70*1392Seric 	**	flag 'inheader' keeps track of whether we are
71*1392Seric 	**	in the header or in the body of the message.
72*1392Seric 	**	The flag 'firstline' is only true on the first
73*1392Seric 	**	line of a message.
74*1392Seric 	**	To keep certain mailers from getting confused,
75*1392Seric 	**	and to keep the output clean, lines that look
76*1392Seric 	**	like UNIX "From" lines are deleted in the header,
77*1392Seric 	**	and prepended with ">" in the body.
78*1392Seric 	*/
79*1392Seric 
80*1392Seric 	inheader = TRUE;
81*1392Seric 	firstline = TRUE;
82*1392Seric 	fbuf[0] = '\0';
83*1392Seric 	while (fgets(buf, sizeof buf, stdin) != NULL)
84*1392Seric 	{
85*1392Seric 		if (inheader && isalnum(buf[0]))
86*1392Seric 		{
87*1392Seric 			/* get the rest of this field */
88*1392Seric 			while ((c = getc(stdin)) == ' ' || c == '\t')
89*1392Seric 			{
90*1392Seric 				p = &buf[strlen(buf)];
91*1392Seric 				*p++ = c;
92*1392Seric 				if (fgets(p, sizeof buf - (p - buf), stdin) == NULL)
93*1392Seric 					break;
94*1392Seric 			}
95*1392Seric 			ungetc(c, stdin);
96*1392Seric 		}
97*1392Seric 
98*1392Seric 		if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0'))
99*1392Seric 			break;
100*1392Seric 
101*1392Seric 		/* are we still in the header? */
102*1392Seric 		if ((buf[0] == '\n' || buf[0] == '\0') && inheader)
103*1392Seric 		{
104*1392Seric 			inheader = FALSE;
105*1392Seric 			if (MsgId[0] == '\0')
106*1392Seric 			{
107*1392Seric 				makemsgid();
108*1392Seric 				if (UseMsgId)
109*1392Seric 					fprintf(tf, "Message-Id: <%s>\n", MsgId);
110*1392Seric 			}
111*1392Seric # ifdef DEBUG
112*1392Seric 			if (Debug)
113*1392Seric 				printf("EOH\n");
114*1392Seric # endif DEBUG
115*1392Seric 		}
116*1392Seric 
117*1392Seric 		/* Hide UNIX-like From lines */
118*1392Seric 		if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' &&
119*1392Seric 		    buf[3] == 'm' && buf[4] == ' ')
120*1392Seric 		{
121*1392Seric 			if (firstline && !SaveFrom)
122*1392Seric 				continue;
123*1392Seric 			fputs(">", tf);
124*1392Seric 		}
125*1392Seric 
126*1392Seric 		if (inheader && !isspace(buf[0]))
127*1392Seric 		{
128*1392Seric 			/* find out if this is really a header */
129*1392Seric 			for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++)
130*1392Seric 				continue;
131*1392Seric 			while (*p != ':' && isspace(*p))
132*1392Seric 				p++;
133*1392Seric 			if (*p != ':')
134*1392Seric 			{
135*1392Seric 				inheader = FALSE;
136*1392Seric # ifdef DEBUG
137*1392Seric 				if (Debug)
138*1392Seric 					printf("EOH?\n");
139*1392Seric # endif DEBUG
140*1392Seric 			}
141*1392Seric 		}
142*1392Seric 
143*1392Seric 		if (inheader)
144*1392Seric 		{
145*1392Seric 			/* find the sender */
146*1392Seric 			p = matchhdr(buf, "sender");
147*1392Seric 			if (p == NULL && fbuf[0] == '\0')
148*1392Seric 				p = matchhdr(buf, "from");
149*1392Seric 			if (p != NULL)
150*1392Seric 				prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0');
151*1392Seric 
152*1392Seric 			/* find the message id */
153*1392Seric 			p = matchhdr(buf, "message-id");
154*1392Seric 			if (p != NULL && MsgId[0] == '\0')
155*1392Seric 				prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0');
156*1392Seric 		}
157*1392Seric 		fputs(buf, tf);
158*1392Seric 		firstline = FALSE;
159*1392Seric 		if (ferror(tf))
160*1392Seric 		{
161*1392Seric 			syserr("Cannot write %s", InFileName);
162*1392Seric 			clearerr(tf);
163*1392Seric 			break;
164*1392Seric 		}
165*1392Seric 	}
166*1392Seric 	fclose(tf);
167*1392Seric 	if (MsgId[0] == '\0')
168*1392Seric 		makemsgid();
169*1392Seric 	if (freopen(InFileName, "r", stdin) == NULL)
170*1392Seric 		syserr("Cannot reopen %s", InFileName);
171*1392Seric 	return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL);
172*1392Seric }
173*1392Seric /*
174*1392Seric **  MAKEMSGID -- Compute a message id for this process.
175*1392Seric **
176*1392Seric **	This routine creates a message id for a message if
177*1392Seric **	it did not have one already.  If the MESSAGEID compile
178*1392Seric **	flag is set, the messageid will be added to any message
179*1392Seric **	that does not already have one.  Currently it is more
180*1392Seric **	of an artifact, but I suggest that if you are hacking,
181*1392Seric **	you leave it in -- I may want to use it someday if
182*1392Seric **	duplicate messages turn out to be a problem.
183*1392Seric **
184*1392Seric **	Parameters:
185*1392Seric **		none.
186*1392Seric **
187*1392Seric **	Returns:
188*1392Seric **		none.
189*1392Seric **
190*1392Seric **	Side Effects:
191*1392Seric **		Stores a message-id into MsgId.
192*1392Seric **
193*1392Seric **	Called By:
194*1392Seric **		maketemp
195*1392Seric */
196*1392Seric 
197*1392Seric makemsgid()
198*1392Seric {
199*1392Seric 	auto long t;
200*1392Seric 	extern char *MyLocName;
201*1392Seric 	extern char *ArpaHost;
202*1392Seric 
203*1392Seric 	time(&t);
204*1392Seric 	sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost);
205*1392Seric }
206