]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/rmail.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / rmail.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 static char *sccsid = "@(#)from rmail.c 4.1 (Berkeley) 10/1/80";
9 /*
10 * rmail: front end for mail to stack up those stupid >From ... remote from ...
11 * lines and make a correct return address. This works with the -f option
12 * to /etc/delivermail so it won't work on systems without delivermail.
13 * However, it ought to be easy to modify a standard /bin/mail to do the
14 * same thing.
15 *
16 * NOTE: Rmail is SPECIFICALLY INTENDED for ERNIE COVAX because of its
17 * physical position as a gateway between the uucp net and the arpanet.
18 * By default, other sites will probably want /bin/rmail to be a link
19 * to /bin/mail, as it was intended by BTL. However, other than the
20 * (somewhat annoying) loss of information about when the mail was
21 * originally sent, rmail should work OK on other systems running uucp.
22 * If you don't run uucp you don't even need any rmail.
23 *
24 * This version revised around New Year's Day 1981 to interface with
25 * Rand's MH system. The nature of the revision is to (1) do nothing
26 * if the destination is uucp-remote (note the assumption of single
27 * destination) and (2) to call "/etc/mh/deliver" to do the deed.
28 *
29 * Revised Aug 1981 to add NOGATEWAY screen. Also fixed a few bugs.
30 * PK.
31 *
32 * 5/8/82: Tack on uu-Date: if msg has no date. PK.
33 */
34
35 /*#define DEBUG 1*/
36
37 #include "../mh.h"
38 #include <whoami.h>
39 #include <stdio.h>
40
41 #define MATCH 0
42 #define PARSE 1
43 #define NOPARSE 0
44
45
46 char *index();
47
48 FILE *out; /* output to delivermail */
49 char *tmpfil; /* file name of same */
50 char tmpfila[24]; /* array for tmpfil */
51 char *to; /* argv[1] */
52 char from[512]; /* accumulated path of sender */
53 char lbuf[512]; /* one line of the message */
54
55 char d1[10], d2[10], d3[10], d4[10], d5[10]; /*** ctime() fields ***/
56
57 #ifdef ARPANET
58 int netaddr; /* set if "to" contains an arpanet address */
59 #endif
60
61 main(argc, argv)
62 char **argv;
63 {
64 char ufrom[64]; /* user on remote system */
65 char sys[64]; /* a system in path */
66 char junk[512]; /* scratchpad */
67 char *cp;
68 int badhdr; /***/
69
70 to = argv[1];
71 if (argc != 2) {
72 fprintf(stderr, "Usage: rmail user\n");
73 exit(1);
74 }
75 #ifdef DEBUG
76 out=stdout;
77 tmpfil = "/dev/tty";
78 #else
79 tmpfil = tmpfila;
80 sprintf (tmpfil, "/tmp/%s", makename ("mail",".tmp"));
81 if ((out=fopen(tmpfil, "w")) == NULL) {
82 fprintf(stderr, "Can't create %s\n", tmpfil);
83 exit(1);
84 }
85 #endif
86 for (;;) {
87 fgets(lbuf, sizeof lbuf, stdin);
88 if (strncmp(lbuf, "From ", 5) && strncmp(lbuf, ">From ", 6))
89 break;
90 fputs(lbuf, out); /* Save--in case we are just forwarding */
91 /***/ sscanf(lbuf, "%s %s %s %s %s %s %s remote from %s",
92 junk, ufrom, d1, d2, d3, d4, d5, sys);
93 /* sscanf(lbuf, "%s %s", junk, ufrom); */
94 cp = lbuf;
95 for (;;) {
96 cp = index(cp+1, 'r');
97 if (cp == NULL)
98 cp = "remote from somewhere";
99 #ifdef DEBUG
100 printf("cp='%s'\n", cp);
101 #endif
102 if (strncmp(cp, "remote from ", 12) == MATCH)
103 break;
104 }
105 sscanf(cp, "remote from %s", sys);
106 strcat(from, sys);
107 strcat(from, "!");
108 #ifdef DEBUG
109 printf("ufrom='%s', sys='%s', from now '%s'\n", ufrom, sys, from);
110 #endif
111 }
112 strcat(from, ufrom);
113
114 #ifdef DEBUG
115 printf("from now '%s'\n", from);
116 #endif
117
118
119 #ifdef ARPANET
120 netaddr = isarpa(to); /* Arpanet destination? */
121
122 #ifdef NOGATEWAY
123 if(netaddr && !okhost(sys))
124 {
125 truncate();
126 returnmail("Sorry, not an Arpanet gateway!");
127 exit(0);
128 }
129 #endif
130
131 if (index (to, '!') && !netaddr) {
132 #else
133 if (index (to, '!')) {
134 #endif
135 /* Just forwarding! */
136 putmsg(NOPARSE);
137 deliver(to);
138 exit(0);
139 }
140
141 truncate();
142 /* fprintf(out, "To: %s\n",to); */
143 putfrom();
144
145 if( !((cp = index(lbuf, ':')) && (cp - lbuf < NAMESZ ))) {
146 fputs("\n",out);/* Doesn't look good; terminate hdr */
147 badhdr++;
148 }
149 putmsg(badhdr?NOPARSE:PARSE);
150 deliver(to);
151
152 }
153
154
155 deliver(to)
156 char *to;
157 {
158 int sts,pid,waitid;
159
160 #ifdef DEBUG
161 printf("%s would get called here; Delivery to: %s \n", mh_deliver,to);
162 exit(0);
163 #endif
164 fclose(out);
165
166 if ((pid=fork()) == -1) {
167 fprintf(stderr, "Cannot fork Deliver!\n");
168
169 #ifndef DEBUG /* Extra precaution */
170 unlink(tmpfil);
171 #endif
172 exit(1);
173 }
174 if(pid) {
175 while(((waitid = wait(&sts)) != pid) && (waitid != -1));
176
177 #ifndef DEBUG /* Extra precaution */
178 unlink(tmpfil);
179 #endif
180 exit(0);
181 }
182 execl(mh_deliver, "deliver", "-deliver", to, tmpfil, 0);
183
184 perror( "Cannot exec Deliver ");
185
186 exit(1);
187
188 }
189
190 #ifdef ARPANET
191
192 isarpa(str) /* Gateway to Arpanet? */
193 char *str;
194 {
195 char *cp;
196
197 if (index (str, '@'))
198 return(1);
199
200 for (cp = str; ;) {
201 if((cp = index(cp, ' ')) == NULL)
202 return(0);
203 while(*cp == ' ')
204 cp++;
205 if ((strncmp(cp, "at ", 3) == MATCH) ||
206 (strncmp(cp, "AT ", 3) == MATCH) ||
207 (strncmp(cp, "At ", 3) == MATCH))
208
209 return(1);
210 }
211 }
212
213
214 okhost(str) /* Host permitted to use us as an arpanet gateway? */
215 char *str;
216 {
217 register short i;
218
219 for (i=0; rhosts[i]; i++)
220 if (strcmp (str, rhosts[i]) == MATCH)
221 return(1);
222 return(0);
223 }
224 #endif
225
226 returnmail(message)
227 char *message;
228 {
229
230 #ifdef DEBUG
231 printf("returnmail()\n");
232 #endif
233 if(!from) return;
234
235 putdate();
236 fprintf(out, "To: %s\n", from);
237 fputs("\n",out);
238 fputs (message, out);
239 fputs("\n\n\n*--------------RETURNED MESSAGE---------------*\n\n",
240 out);
241
242 putmsg(NOPARSE);
243 deliver(from);
244
245 }
246
247
248 #include <sys/types.h>
249 #include <sys/timeb.h>
250 #include <time.h>
251
252 putdate()
253 {
254 long now;
255 register char *t, *p;
256 char *timezone();
257 struct timeb tb;
258 struct tm *tmp;
259 static char *wday[] = {
260 "Sun",
261 "Mon",
262 "Tues",
263 "Wednes",
264 "Thurs",
265 "Fri",
266 "Satur"
267 };
268
269 now = time((long *)0);
270 t = ctime(&now);
271 ftime(&tb);
272 tmp = localtime(&now);
273 p = timezone(tb.timezone, tmp->tm_isdst);
274
275 /* day 13 Apr 1981 20 :38 -PST */
276 fprintf(out, "Date: %sday, %.2s %.3s %.4s %.2s:%.2s-%.3s\n",
277 wday[tmp->tm_wday], t+8, t+4, t+20, t+11, t+14, p);
278 }
279
280
281 putfrom()
282 {
283 if (strlen(from))
284 #ifdef ARPANET
285 if (netaddr)
286 fprintf(out, "From: %s at %s\n",from, HOSTNAME);
287 else
288 fprintf(out, "From: %s\n", from);
289 #else
290 fprintf(out, "From: %s\n",from);
291 #endif
292
293 }
294
295
296 putmsg(parse)
297 int parse;
298 {
299 int dateseen = 0;
300
301 if(!parse)
302 putall();
303 else {
304 if (uleqn(lbuf, "date:", 5) == 0)
305 dateseen++;
306 fputs(lbuf, out);
307 while (fgets(lbuf, sizeof lbuf, stdin)) {
308 if(lbuf[0] == '\n' ) { /* end of hdrs */
309 if(!dateseen)
310 uudate();
311 putall();
312 } else {
313 if (uleqn(lbuf, "date:", 5) == 0)
314 dateseen++;
315 fputs(lbuf, out);
316 }
317 }
318 }
319 }
320
321
322 putall()
323 {
324 fputs(lbuf, out);
325 while (fgets(lbuf, sizeof lbuf, stdin))
326 fputs(lbuf, out);
327 }
328
329
330 truncate()
331 {
332 /* Truncate those "...remote from..." header lines. */
333 /* They're kept only if the message is to be uucp-forwarded */
334
335 #ifndef DEBUG
336 fclose (out); out=fopen(tmpfil, "w");
337 #endif
338
339 }
340
341
342 /*
343 * Compare strings (at most n bytes) without regard to case.
344 * Returns: s1>s2: >0, s1==s2: 0, s1<s2: <0.
345 */
346
347 uleqn(s1, s2, n)
348 register char *s1, *s2;
349 register n;
350 {
351
352 while (--n >= 0 && (*s1|040) == (*s2|040)) {
353 s2++;
354 if (*s1++ == '\0')
355 return(0);
356 }
357 return(n<0 ? 0 : (*s1|040) - (*s2|040));
358 }
359
360
361 uudate()
362 {
363 char *prefix();
364
365 /* day 13 Apr 1981 20 :38 -PST */
366 fprintf(out, "Date: %sday, %.2s %.3s %.4s %.2s:%.2s-%.3s\n",
367 prefix(d1), d3, d2, d5, d4, d4+3, "???");
368 }
369
370 char *
371 prefix(str)
372 char *str;
373 {
374 static char *wday[] = {
375 "Sun",
376 "Mon",
377 "Tues",
378 "Wednes",
379 "Thurs",
380 "Fri",
381 "Satur",
382 0
383 };
384
385 register char **wp;
386
387 for(wp=wday; wp; wp++)
388 if(uleqn(str, *wp, 3) == 0)
389 return(*wp);
390 return("???");
391 }