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