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