Commit | Line | Data |
---|---|---|
cb590f52 EA |
1 | # include <stdio.h> |
2 | # include <ctype.h> | |
b8020f57 | 3 | # include <errno.h> |
cb590f52 EA |
4 | # include "dlvrmail.h" |
5 | ||
1faf68d2 | 6 | static char SccsId[] = "@(#)collect.c 2.1 %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 | ||
afcbcc6e EA |
40 | char MsgId[MAXNAME]; /* message-id, determined or created */ |
41 | long MsgSize; /* size of message in bytes */ | |
628ac6c6 | 42 | |
cb590f52 EA |
43 | char * |
44 | maketemp() | |
45 | { | |
46 | register FILE *tf; | |
47 | char buf[MAXFIELD+1]; | |
48 | static char fbuf[sizeof buf]; | |
49 | extern char *prescan(); | |
50 | extern char *matchhdr(); | |
51 | register char *p; | |
52 | register bool inheader; | |
53 | bool firstline; | |
54 | char c; | |
b8020f57 | 55 | extern int errno; |
cb590f52 EA |
56 | |
57 | /* | |
58 | ** Create the temp file name and create the file. | |
59 | */ | |
60 | ||
61 | mktemp(InFileName); | |
62 | close(creat(InFileName, 0600)); | |
63 | if ((tf = fopen(InFileName, "w")) == NULL) | |
64 | { | |
65 | syserr("Cannot create %s", InFileName); | |
66 | return (NULL); | |
67 | } | |
68 | ||
69 | /* | |
70 | ** Copy stdin to temp file & do message editting. | |
71 | ** From person gets copied into fbuf. At the end of | |
72 | ** this loop, if fbuf[0] == '\0' then there was no | |
73 | ** recognized from person in the message. We also | |
74 | ** save the message id in MsgId. The | |
75 | ** flag 'inheader' keeps track of whether we are | |
76 | ** in the header or in the body of the message. | |
77 | ** The flag 'firstline' is only true on the first | |
78 | ** line of a message. | |
79 | ** To keep certain mailers from getting confused, | |
80 | ** and to keep the output clean, lines that look | |
81 | ** like UNIX "From" lines are deleted in the header, | |
82 | ** and prepended with ">" in the body. | |
83 | */ | |
84 | ||
85 | inheader = TRUE; | |
86 | firstline = TRUE; | |
87 | fbuf[0] = '\0'; | |
88 | while (fgets(buf, sizeof buf, stdin) != NULL) | |
89 | { | |
90 | if (inheader && isalnum(buf[0])) | |
91 | { | |
92 | /* get the rest of this field */ | |
93 | while ((c = getc(stdin)) == ' ' || c == '\t') | |
94 | { | |
95 | p = &buf[strlen(buf)]; | |
96 | *p++ = c; | |
97 | if (fgets(p, sizeof buf - (p - buf), stdin) == NULL) | |
98 | break; | |
99 | } | |
0982b655 EA |
100 | if (c != EOF) |
101 | ungetc(c, stdin); | |
cb590f52 EA |
102 | } |
103 | ||
104 | if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0')) | |
105 | break; | |
106 | ||
107 | /* are we still in the header? */ | |
108 | if ((buf[0] == '\n' || buf[0] == '\0') && inheader) | |
109 | { | |
110 | inheader = FALSE; | |
111 | if (MsgId[0] == '\0') | |
112 | { | |
113 | makemsgid(); | |
114 | if (UseMsgId) | |
115 | fprintf(tf, "Message-Id: <%s>\n", MsgId); | |
116 | } | |
117 | # ifdef DEBUG | |
118 | if (Debug) | |
119 | printf("EOH\n"); | |
120 | # endif DEBUG | |
121 | } | |
122 | ||
123 | /* Hide UNIX-like From lines */ | |
124 | if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && | |
125 | buf[3] == 'm' && buf[4] == ' ') | |
126 | { | |
127 | if (firstline && !SaveFrom) | |
128 | continue; | |
129 | fputs(">", tf); | |
afcbcc6e | 130 | MsgSize++; |
cb590f52 EA |
131 | } |
132 | ||
133 | if (inheader && !isspace(buf[0])) | |
134 | { | |
135 | /* find out if this is really a header */ | |
136 | for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++) | |
137 | continue; | |
138 | while (*p != ':' && isspace(*p)) | |
139 | p++; | |
140 | if (*p != ':') | |
141 | { | |
142 | inheader = FALSE; | |
143 | # ifdef DEBUG | |
144 | if (Debug) | |
145 | printf("EOH?\n"); | |
146 | # endif DEBUG | |
147 | } | |
148 | } | |
149 | ||
150 | if (inheader) | |
151 | { | |
152 | /* find the sender */ | |
153 | p = matchhdr(buf, "sender"); | |
154 | if (p == NULL && fbuf[0] == '\0') | |
155 | p = matchhdr(buf, "from"); | |
156 | if (p != NULL) | |
157 | prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0'); | |
158 | ||
159 | /* find the message id */ | |
160 | p = matchhdr(buf, "message-id"); | |
161 | if (p != NULL && MsgId[0] == '\0') | |
162 | prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0'); | |
163 | } | |
afcbcc6e | 164 | MsgSize += strlen(buf); |
cb590f52 EA |
165 | fputs(buf, tf); |
166 | firstline = FALSE; | |
167 | if (ferror(tf)) | |
168 | { | |
b8020f57 EA |
169 | if (errno == ENOSPC) |
170 | { | |
171 | freopen(InFileName, "w", tf); | |
172 | fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf); | |
173 | syserr("Out of disk space for temp file"); | |
174 | } | |
175 | else | |
176 | syserr("Cannot write %s", InFileName); | |
177 | freopen("/dev/null", "w", tf); | |
cb590f52 EA |
178 | } |
179 | } | |
180 | fclose(tf); | |
181 | if (MsgId[0] == '\0') | |
182 | makemsgid(); | |
183 | if (freopen(InFileName, "r", stdin) == NULL) | |
184 | syserr("Cannot reopen %s", InFileName); | |
185 | return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL); | |
186 | } | |
187 | \f/* | |
188 | ** MAKEMSGID -- Compute a message id for this process. | |
189 | ** | |
190 | ** This routine creates a message id for a message if | |
191 | ** it did not have one already. If the MESSAGEID compile | |
192 | ** flag is set, the messageid will be added to any message | |
193 | ** that does not already have one. Currently it is more | |
194 | ** of an artifact, but I suggest that if you are hacking, | |
195 | ** you leave it in -- I may want to use it someday if | |
196 | ** duplicate messages turn out to be a problem. | |
197 | ** | |
198 | ** Parameters: | |
199 | ** none. | |
200 | ** | |
201 | ** Returns: | |
202 | ** none. | |
203 | ** | |
204 | ** Side Effects: | |
205 | ** Stores a message-id into MsgId. | |
206 | ** | |
207 | ** Called By: | |
208 | ** maketemp | |
209 | */ | |
210 | ||
211 | makemsgid() | |
212 | { | |
213 | auto long t; | |
214 | extern char *MyLocName; | |
215 | extern char *ArpaHost; | |
216 | ||
217 | time(&t); | |
218 | sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost); | |
219 | } |