|
|
1.1 root 1: # include <stdio.h>
2: # include <ctype.h>
3: # include <errno.h>
4: # include "dlvrmail.h"
5:
6: static char SccsId[] = "@(#)maketemp.c 1.6 10/27/80";
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:
40: char MsgId[MAXNAME]; /* message-id, determined or created */
41: long MsgSize; /* size of message in bytes */
42:
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;
55: extern int errno;
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: }
100: if (c != EOF)
101: ungetc(c, stdin);
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);
130: MsgSize++;
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: }
164: MsgSize += strlen(buf);
165: fputs(buf, tf);
166: firstline = FALSE;
167: if (ferror(tf))
168: {
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);
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: /*
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.