Mercurial > hg > Applications > mh
comparison uip/spost.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | 441a2190cfae |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 #ifndef lint | |
2 static char sccsid[] = "@(#)spost.c 1.6 (Berkeley) 11/2/85"; | |
3 #endif | |
4 #ifndef lint | |
5 static char ident[] = "@(#)$Id$"; | |
6 #endif /* lint */ | |
7 | |
8 /* spost.c - feed messages to sendmail */ | |
9 /* | |
10 * (This is a simpler, faster, replacement for "post" for use when "sendmail" | |
11 * is the transport system) | |
12 */ | |
13 | |
14 #include <ctype.h> | |
15 #include <stdio.h> | |
16 #include <signal.h> | |
17 #include "../h/mh.h" | |
18 #include "../h/addrsbr.h" | |
19 #include "../h/aliasbr.h" | |
20 #include "../h/dropsbr.h" | |
21 #include "../zotnet/tws.h" | |
22 #ifdef LOCALE | |
23 #include <locale.h> | |
24 #endif | |
25 #ifdef UNISTD | |
26 #include <unistd.h> | |
27 #endif | |
28 | |
29 extern char *getfullname (), *getusr (); | |
30 extern char *sendmail; | |
31 | |
32 | |
33 #define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : c) | |
34 | |
35 #define MAX_SM_FIELD 1476 /* < largest hdr field sendmail will accept */ | |
36 #define FCCS 10 /* max number of fccs allowed */ | |
37 | |
38 /* */ | |
39 | |
40 struct swit switches[] = { | |
41 #define FILTSW 0 | |
42 "filter filterfile", 0, | |
43 #define NFILTSW 1 | |
44 "nofilter", 0, | |
45 | |
46 #define FRMTSW 2 | |
47 "format", 0, | |
48 #define NFRMTSW 3 | |
49 "noformat", 0, | |
50 | |
51 #define REMVSW 4 | |
52 "remove", 0, | |
53 #define NREMVSW 5 | |
54 "noremove", 0, | |
55 | |
56 #define VERBSW 6 | |
57 "verbose", 0, | |
58 #define NVERBSW 7 | |
59 "noverbose", 0, | |
60 | |
61 #define WATCSW 8 | |
62 "watch", 0, | |
63 #define NWATCSW 9 | |
64 "nowatch", 0, | |
65 | |
66 #define HELPSW 10 | |
67 "help", 4, | |
68 | |
69 #define DEBUGSW 11 | |
70 "debug", -5, | |
71 | |
72 #define DISTSW 12 | |
73 "dist", -4, /* interface from dist */ | |
74 | |
75 #define BACKSW 13 | |
76 "backup", 0, | |
77 #define NBACKSW 14 | |
78 "nobackup", 0, | |
79 | |
80 #define CHKSW 15 | |
81 "check", -5, /* interface from whom */ | |
82 #define NCHKSW 16 | |
83 "nocheck", -7, /* interface from whom */ | |
84 #define WHOMSW 17 | |
85 "whom", -4, /* interface from whom */ | |
86 | |
87 #define PUSHSW 18 /* fork to sendmail then exit */ | |
88 "push", -4, | |
89 #define NPUSHSW 19 /* exec sendmail */ | |
90 "nopush", -6, | |
91 | |
92 #define ALIASW 20 | |
93 "alias aliasfile", 0, | |
94 #define NALIASW 21 | |
95 "noalias", 0, | |
96 | |
97 #define WIDTHSW 22 | |
98 "width columns", 0, | |
99 | |
100 #define LIBSW 23 | |
101 "library directory", -7, | |
102 | |
103 #define ANNOSW 24 | |
104 "idanno number", -6, | |
105 | |
106 #ifdef MIME_HEADERS | |
107 #define HENCDSW 25 | |
108 "hencode", 0, | |
109 #define NHENCDSW 26 | |
110 "nohencode", 0, | |
111 #endif /* MIME_HEADERS */ | |
112 | |
113 NULL, 0 | |
114 }; | |
115 | |
116 /* */ | |
117 | |
118 struct headers { | |
119 char *value; | |
120 | |
121 unsigned int flags; | |
122 #define HNOP 0x0000 /* just used to keep .set around */ | |
123 #define HBAD 0x0001 /* bad header - don't let it through */ | |
124 #define HADR 0x0002 /* header has an address field */ | |
125 #define HSUB 0x0004 /* Subject: header */ | |
126 #define HTRY 0x0008 /* try to send to addrs on header */ | |
127 #define HBCC 0x0010 /* don't output this header */ | |
128 #define HMNG 0x0020 /* mung this header */ | |
129 #define HNGR 0x0040 /* no groups allowed in this header */ | |
130 #define HFCC 0x0080 /* FCC: type header */ | |
131 #define HNIL 0x0100 /* okay for this header not to have addrs */ | |
132 #define HIGN 0x0200 /* ignore this header */ | |
133 | |
134 unsigned int set; | |
135 #define MFRM 0x0001 /* we've seen a From: */ | |
136 #define MDAT 0x0002 /* we've seen a Date: */ | |
137 #define MRFM 0x0004 /* we've seen a Resent-From: */ | |
138 #define MVIS 0x0008 /* we've seen sighted addrs */ | |
139 #define MINV 0x0010 /* we've seen blind addrs */ | |
140 #define MRDT 0x0020 /* we've seen a Resent-Date: */ | |
141 }; | |
142 | |
143 /* */ | |
144 | |
145 static struct headers NHeaders[] = { | |
146 "Return-Path", HBAD, 0, | |
147 "Received", HBAD, 0, | |
148 "Reply-To", HADR | HNGR, 0, | |
149 "From", HADR | HNGR, MFRM, | |
150 "Sender", HADR | HBAD, 0, | |
151 "Date", HNOP, MDAT, | |
152 "Subject", HSUB, 0, | |
153 "To", HADR | HTRY, MVIS, | |
154 "cc", HADR | HTRY, MVIS, | |
155 "Bcc", HADR | HTRY | HBCC | HNIL, MINV, | |
156 "Message-Id", HBAD, 0, | |
157 "Fcc", HFCC, 0, | |
158 | |
159 NULL | |
160 }; | |
161 | |
162 static struct headers RHeaders[] = { | |
163 "Resent-Reply-To", HADR | HNGR, 0, | |
164 "Resent-From", HADR | HNGR, MRFM, | |
165 "Resent-Sender", HADR | HBAD, 0, | |
166 "Resent-Date", HNOP, MRDT, | |
167 "Resent-Subject", HSUB, 0, | |
168 "Resent-To", HADR | HTRY, MVIS, | |
169 "Resent-cc", HADR | HTRY, MVIS, | |
170 "Resent-Bcc", HADR | HTRY | HBCC, MINV, | |
171 "Resent-Message-Id", HBAD, 0, | |
172 "Resent-Fcc", HFCC, 0, | |
173 "Reply-To", HADR, 0, | |
174 "Fcc", HIGN, 0, | |
175 | |
176 NULL | |
177 }; | |
178 | |
179 /* */ | |
180 | |
181 | |
182 static short fccind = 0; /* index into fccfold[] */ | |
183 | |
184 static int badmsg = 0; /* message has bad semantics */ | |
185 static int verbose = 0; /* spell it out */ | |
186 static int debug = 0; /* debugging post */ | |
187 static int rmflg = 1; /* remove temporary file when done */ | |
188 static int watch = 0; /* watch the delivery process */ | |
189 static int backflg = 0; /* rename input file as *.bak when done */ | |
190 static int whomflg = 0; /* if just checking addresses */ | |
191 static int pushflg = 0; /* if going to fork to sendmail */ | |
192 static int aliasflg = -1; /* if going to process aliases */ | |
193 static int outputlinelen=72; | |
194 #ifdef MIME_HEADERS | |
195 static int hencode = -1; /* encode header in RFC-2047 style */ | |
196 #endif /* MIME_HEADERS */ | |
197 | |
198 static unsigned msgflags = 0; /* what we've seen */ | |
199 | |
200 static enum { | |
201 normal, resent | |
202 } msgstate = normal; | |
203 | |
204 static char tmpfil[] = "/tmp/pstXXXXXX"; | |
205 | |
206 static char from[BUFSIZ]; /* my network address */ | |
207 static char signature[BUFSIZ]; /* my signature */ | |
208 static char *filter = NULL; /* the filter for BCC'ing */ | |
209 static char *subject = NULL; /* the subject field for BCC'ing */ | |
210 static char *fccfold[FCCS]; /* foldernames for FCC'ing */ | |
211 | |
212 static struct headers *hdrtab; /* table for the message we're doing */ | |
213 static FILE *out; /* output (temp) file */ | |
214 | |
215 static putfmt(), start_headers(), finish_headers(), putadr(), | |
216 insert_fcc(); | |
217 static file(), fcc(); | |
218 static int get_header(), putone(); | |
219 /* MAIN */ | |
220 | |
221 /* ARGSUSED */ | |
222 | |
223 main (argc, argv) | |
224 int argc; | |
225 char *argv[]; | |
226 { | |
227 int state, | |
228 i, | |
229 pid, | |
230 compnum; | |
231 char *cp, | |
232 *msg = NULL, | |
233 **argp = argv + 1, | |
234 *sargv[16], | |
235 buf[BUFSIZ], | |
236 name[NAMESZ], | |
237 *arguments[MAXARGS]; | |
238 FILE * in; | |
239 | |
240 #ifdef LOCALE | |
241 setlocale(LC_ALL, ""); | |
242 #endif | |
243 #ifdef JAPAN | |
244 ml_init(); | |
245 #endif /* JAPAN */ | |
246 invo_name = r1bindex (argv[0], '/'); | |
247 mts_init (invo_name); | |
248 if ((cp = m_find (invo_name)) != NULL) { | |
249 argp = copyip (brkstring (cp, " ", "\n"), arguments); | |
250 (void) copyip (argv+1, argp); | |
251 argp = arguments; | |
252 } | |
253 | |
254 /* */ | |
255 | |
256 while (cp = *argp++) { | |
257 if (*cp == '-') | |
258 switch (smatch (++cp, switches)) { | |
259 case AMBIGSW: | |
260 ambigsw (cp, switches); | |
261 done (1); | |
262 case UNKWNSW: | |
263 adios (NULLCP, "-%s unknown", cp); | |
264 case HELPSW: | |
265 (void)sprintf (buf, "%s [switches] file", invo_name); | |
266 help (buf, switches); | |
267 done (1); | |
268 | |
269 case DEBUGSW: | |
270 debug++; | |
271 continue; | |
272 | |
273 case DISTSW: | |
274 msgstate = resent; | |
275 continue; | |
276 | |
277 case WHOMSW: | |
278 whomflg++; | |
279 continue; | |
280 | |
281 case FILTSW: | |
282 if (!(filter = *argp++) || *filter == '-') | |
283 adios (NULLCP, "missing argument to %s", argp[-2]); | |
284 continue; | |
285 case NFILTSW: | |
286 filter = NULL; | |
287 continue; | |
288 | |
289 case REMVSW: | |
290 rmflg++; | |
291 continue; | |
292 case NREMVSW: | |
293 rmflg = 0; | |
294 continue; | |
295 | |
296 case BACKSW: | |
297 backflg++; | |
298 continue; | |
299 case NBACKSW: | |
300 backflg = 0; | |
301 continue; | |
302 | |
303 case VERBSW: | |
304 verbose++; | |
305 continue; | |
306 case NVERBSW: | |
307 verbose = 0; | |
308 continue; | |
309 | |
310 case WATCSW: | |
311 watch++; | |
312 continue; | |
313 case NWATCSW: | |
314 watch = 0; | |
315 continue; | |
316 | |
317 case PUSHSW: | |
318 pushflg++; | |
319 continue; | |
320 case NPUSHSW: | |
321 pushflg = 0; | |
322 continue; | |
323 | |
324 case ALIASW: | |
325 if (!(cp = *argp++) || *cp == '-') | |
326 adios (NULLCP, "missing argument to %s", argp[-2]); | |
327 if (aliasflg < 0) | |
328 (void) alias (AliasFile);/* load default aka's */ | |
329 aliasflg = 1; | |
330 if ((state = alias(cp)) != AK_OK) | |
331 adios (NULLCP, "aliasing error in file %s - %s", | |
332 cp, akerror(state) ); | |
333 continue; | |
334 case NALIASW: | |
335 aliasflg = 0; | |
336 continue; | |
337 | |
338 case WIDTHSW: | |
339 if (!(cp = *argp++) || *cp == '-') | |
340 adios (NULLCP, "missing argument to %s", argp[-2]); | |
341 outputlinelen = atoi (cp); | |
342 if (outputlinelen <= 10) | |
343 outputlinelen = 72; | |
344 continue; | |
345 | |
346 case LIBSW: | |
347 case ANNOSW: | |
348 /* -library & -idanno switch ignored */ | |
349 if (!(cp = *argp++) || *cp == '-') | |
350 adios (NULLCP, "missing argument to %s", argp[-2]); | |
351 continue; | |
352 #ifdef MIME_HEADERS | |
353 case HENCDSW: | |
354 hencode = 1; | |
355 continue; | |
356 case NHENCDSW: | |
357 hencode = 0; | |
358 continue; | |
359 #endif /* MIME_HEADERS */ | |
360 } | |
361 if (msg) | |
362 adios (NULLCP, "only one message at a time!"); | |
363 else | |
364 msg = cp; | |
365 } | |
366 | |
367 /* */ | |
368 | |
369 if (aliasflg < 0) | |
370 (void) alias (AliasFile); /* load default aka's */ | |
371 | |
372 if (!msg) | |
373 adios (NULLCP, "usage: %s [switches] file", invo_name); | |
374 | |
375 if ((in = fopen (msg, "r")) == NULL) | |
376 adios (msg, "unable to open"); | |
377 | |
378 #ifdef MIME_HEADERS | |
379 if (hencode == -1) { | |
380 hencode = 0; | |
381 for (state = FLD;;) { | |
382 switch (state = m_getfld (state, name, buf, sizeof buf, in)) { | |
383 case FLD: | |
384 case FLDEOF: | |
385 case FLDPLUS: | |
386 if (uleq (name, "MIME-Version")) { | |
387 hencode = 1; | |
388 break; | |
389 } | |
390 continue; | |
391 | |
392 default: | |
393 break; | |
394 } | |
395 break; | |
396 } | |
397 (void) fseek (in, 0L, 0); | |
398 } | |
399 #endif /* MIME_HEADERS */ | |
400 | |
401 start_headers (); | |
402 if (debug) { | |
403 verbose++; | |
404 out = stdout; | |
405 } | |
406 else { | |
407 (void)mktemp (tmpfil); | |
408 if ((out = fopen (tmpfil, "w")) == NULL) | |
409 adios (tmpfil, "unable to create"); | |
410 (void)chmod (tmpfil, 0600); | |
411 } | |
412 | |
413 hdrtab = (msgstate == normal) ? NHeaders : RHeaders; | |
414 | |
415 for (compnum = 1, state = FLD;;) { | |
416 switch (state = m_getfld (state, name, buf, sizeof buf, in)) { | |
417 #if defined(JAPAN) || defined(MIME_HEADERS) | |
418 case FLD: | |
419 case FLDEOF: | |
420 case FLDPLUS: | |
421 compnum++; | |
422 cp = add (buf, NULLCP); | |
423 while (state == FLDPLUS) { | |
424 state = m_getfld (state, name, buf, sizeof buf, in); | |
425 cp = add (buf, cp); | |
426 } | |
427 putfmt (name, cp, out); | |
428 free (cp); | |
429 continue; | |
430 #else /* JAPAN || MIME_HEADERS */ | |
431 case FLD: | |
432 compnum++; | |
433 putfmt (name, buf, out); | |
434 continue; | |
435 | |
436 case FLDPLUS: | |
437 compnum++; | |
438 cp = add (buf, cp); | |
439 while (state == FLDPLUS) { | |
440 state = m_getfld (state, name, buf, sizeof buf, in); | |
441 cp = add (buf, cp); | |
442 } | |
443 putfmt (name, cp, out); | |
444 free (cp); | |
445 continue; | |
446 #endif /* JAPAN || MIME_HEADERS */ | |
447 | |
448 case BODY: | |
449 finish_headers (out); | |
450 fprintf (out, "\n%s", buf); | |
451 if(whomflg == 0) | |
452 while (state == BODY) { | |
453 state = m_getfld (state, name, buf, sizeof buf, in); | |
454 fputs (buf, out); | |
455 } | |
456 break; | |
457 | |
458 case FILEEOF: | |
459 finish_headers (out); | |
460 break; | |
461 | |
462 case LENERR: | |
463 case FMTERR: | |
464 adios (NULLCP, "message format error in component #%d", | |
465 compnum); | |
466 | |
467 default: | |
468 adios (NULLCP, "getfld() returned %d", state); | |
469 } | |
470 break; | |
471 } | |
472 | |
473 /* */ | |
474 | |
475 (void)fclose (in); | |
476 if (backflg && !whomflg) { | |
477 (void) strcpy (buf, m_backup (msg)); | |
478 if (rename (msg, buf) == NOTOK) | |
479 advise (buf, "unable to rename %s to", msg); | |
480 } | |
481 | |
482 if (debug) { | |
483 done (0); | |
484 } | |
485 else | |
486 (void)fclose (out); | |
487 | |
488 file (tmpfil); | |
489 | |
490 /* | |
491 * re-open the temp file, unlink it and exec sendmail, giving it | |
492 * the msg temp file as std in. | |
493 */ | |
494 if ( freopen( tmpfil, "r", stdin) == NULL) | |
495 adios (tmpfil, "can't reopen for sendmail"); | |
496 if (rmflg) | |
497 (void)unlink (tmpfil); | |
498 | |
499 argp = sargv; | |
500 *argp++ = "send-mail"; | |
501 *argp++ = "-m"; /* send to me too */ | |
502 *argp++ = "-t"; /* read msg for recipients */ | |
503 *argp++ = "-i"; /* don't stop on "." */ | |
504 if (whomflg) | |
505 *argp++ = "-bv"; | |
506 if (watch || verbose) | |
507 *argp++ = "-v"; | |
508 *argp = NULL; | |
509 | |
510 if (pushflg && !(watch || verbose)) { | |
511 /* fork to a child to run sendmail */ | |
512 for (i=0; (pid = vfork()) == NOTOK && i < 5; i++) | |
513 sleep(5); | |
514 switch (pid) { | |
515 case NOTOK: | |
516 fprintf (verbose ? stdout : stderr, "%s: can't fork to %s\n", | |
517 invo_name, sendmail); | |
518 exit(-1); | |
519 case OK: | |
520 /* we're the child .. */ | |
521 break; | |
522 default: | |
523 exit(0); | |
524 } | |
525 } | |
526 execv ( sendmail, sargv); | |
527 adios ( sendmail, "can't exec"); | |
528 } | |
529 | |
530 /* DRAFT GENERATION */ | |
531 | |
532 static putfmt (name, str, out) | |
533 char *name, | |
534 *str; | |
535 FILE * out; | |
536 { | |
537 int count, | |
538 grp, | |
539 i, | |
540 keep; | |
541 char *cp, | |
542 *pp, | |
543 *qp, | |
544 #ifdef MIME_HEADERS | |
545 *origstr, | |
546 #endif /* MIME_HEADERS */ | |
547 namep[BUFSIZ]; | |
548 struct mailname *mp, | |
549 *np; | |
550 struct headers *hdr; | |
551 | |
552 while (*str == ' ' || *str == '\t') | |
553 str++; | |
554 | |
555 #ifdef MIME_HEADERS | |
556 if (hencode) { | |
557 char *ep; | |
558 if ((ep = malloc((unsigned)strlen(str)*10+1)) == NULL) | |
559 adios(NULLCP, "out of memory"); | |
560 #ifdef JAPAN | |
561 (void) ml_conv(str); | |
562 #endif /* JAPAN */ | |
563 (void) exthdr_encode(str, ep, strlen(name)+2, name); | |
564 origstr = str; | |
565 str = ep; | |
566 } | |
567 #endif /* MIME_HEADERS */ | |
568 | |
569 if ((i = get_header (name, hdrtab)) == NOTOK) { | |
570 fprintf (out, "%s: %s", name, str); | |
571 return; | |
572 } | |
573 | |
574 hdr = &hdrtab[i]; | |
575 if (hdr -> flags & HIGN) | |
576 return; | |
577 if (hdr -> flags & HBAD) { | |
578 advise (NULLCP, "illegal header line -- %s:", name); | |
579 badmsg++; | |
580 return; | |
581 } | |
582 msgflags |= hdr -> set; | |
583 | |
584 if (hdr -> flags & HSUB) | |
585 subject = subject ? add (str, add ("\t", subject)) : getcpy (str); | |
586 | |
587 if (hdr -> flags & HFCC) { | |
588 if (cp = rindex (str, '\n')) | |
589 *cp = 0; | |
590 for (cp = pp = str; cp = index (pp, ','); pp = cp) { | |
591 *cp++ = 0; | |
592 insert_fcc (hdr, pp); | |
593 } | |
594 insert_fcc (hdr, pp); | |
595 return; | |
596 } | |
597 | |
598 #ifdef notdef | |
599 if (hdr -> flags & HBCC) { | |
600 insert_bcc(str); | |
601 return; | |
602 } | |
603 #endif /* notdef */ | |
604 | |
605 if (*str != '\n' && *str != '\0') | |
606 if (aliasflg && hdr->flags & HTRY) { | |
607 /* this header contains address(es) that we have to do | |
608 * alias expansion on. Because of the saved state in | |
609 * getname we have to put all the addresses into a list. | |
610 * We then let putadr munch on that list, possibly | |
611 * expanding aliases. | |
612 */ | |
613 register struct mailname *f = 0; | |
614 register struct mailname *mp = 0; | |
615 | |
616 #ifdef MIME_HEADERS | |
617 if (hencode) | |
618 /* encode again after format */ | |
619 (void) exthdr_decode(origstr, str); | |
620 #endif /* MIME_HEADERS */ | |
621 | |
622 while (cp = getname( str ) ) { | |
623 mp = getm( cp, NULLCP, 0, AD_HOST, NULLCP); | |
624 if (f == 0) { | |
625 f = mp; | |
626 mp->m_next = mp; | |
627 } else { | |
628 mp->m_next = f->m_next; | |
629 f->m_next = mp; | |
630 f = mp; | |
631 } | |
632 } | |
633 f = mp->m_next; mp->m_next = 0; | |
634 putadr( name, f ); | |
635 } else { | |
636 fprintf (out, "%s: %s", name, str ); | |
637 } | |
638 } | |
639 | |
640 /* */ | |
641 | |
642 static | |
643 start_headers () | |
644 { | |
645 char *cp; | |
646 char sigbuf[BUFSIZ]; | |
647 | |
648 (void)strcpy( from, getusr() ); | |
649 | |
650 if ((cp = getfullname ()) && *cp) { | |
651 (void)strcpy (sigbuf, cp); | |
652 (void)sprintf (signature, "%s <%s>", sigbuf, from); | |
653 #ifdef MIME_HEADERS | |
654 if (hencode) { | |
655 char *ep; | |
656 #ifdef JAPAN | |
657 (void) ml_conv(signature); | |
658 #endif /* JAPAN */ | |
659 ep = getcpy (signature); | |
660 (void) exthdr_encode (ep, signature, 5, "From"); | |
661 free(ep); | |
662 } | |
663 #endif /* MIME_HEADERS */ | |
664 } | |
665 else | |
666 (void)sprintf (signature, "%s", from); | |
667 } | |
668 | |
669 /* */ | |
670 | |
671 static | |
672 finish_headers (out) | |
673 FILE * out; | |
674 { | |
675 switch (msgstate) { | |
676 case normal: | |
677 if (!(msgflags & MDAT)) | |
678 fprintf (out, "Date: %s\n", dtimenow ()); | |
679 if (msgflags & MFRM) | |
680 fprintf (out, "Sender: %s\n", from); | |
681 else | |
682 fprintf (out, "From: %s\n", signature); | |
683 #ifdef notdef | |
684 if (!(msgflags & MVIS)) | |
685 fprintf (out, "Bcc: Blind Distribution List: ;\n"); | |
686 #endif /* notdef */ | |
687 break; | |
688 | |
689 case resent: | |
690 if (!(msgflags & MRDT)) | |
691 fprintf (out, "Resent-Date: %s\n", dtimenow()); | |
692 if (msgflags & MRFM) | |
693 fprintf (out, "Resent-Sender: %s\n", from); | |
694 else | |
695 fprintf (out, "Resent-From: %s\n", signature); | |
696 #ifdef notdef | |
697 if (!(msgflags & MVIS)) | |
698 fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n"); | |
699 #endif /* notdef */ | |
700 break; | |
701 } | |
702 | |
703 if (badmsg) | |
704 adios (NULLCP, "re-format message and try again"); | |
705 } | |
706 | |
707 /* */ | |
708 | |
709 static int | |
710 get_header (header, table) | |
711 char *header; | |
712 struct headers *table; | |
713 { | |
714 struct headers *h; | |
715 | |
716 for (h = table; h -> value; h++) | |
717 if (uleq (header, h -> value)) | |
718 return (h - table); | |
719 | |
720 return NOTOK; | |
721 } | |
722 | |
723 /* */ | |
724 | |
725 /* output the address list for header "name". The address list | |
726 * is a linked list of mailname structs. "nl" points to the head | |
727 * of the list. Alias substitution should be done on nl. | |
728 */ | |
729 static putadr (name, nl) | |
730 char *name; | |
731 struct mailname *nl; | |
732 { | |
733 register struct mailname *mp, *mp2; | |
734 register int linepos; | |
735 register char *cp; | |
736 int namelen; | |
737 | |
738 fprintf (out, "%s: ", name); | |
739 namelen = strlen(name) + 2; | |
740 linepos = namelen; | |
741 | |
742 for (mp = nl; mp; ) { | |
743 if (linepos > MAX_SM_FIELD) { | |
744 fprintf (out, "\n%s: ", name); | |
745 linepos = namelen; | |
746 } | |
747 if (mp->m_nohost) { | |
748 /* a local name - see if it's an alias */ | |
749 cp = akvalue(mp->m_mbox); | |
750 if (strcmp(cp, mp->m_mbox) == 0) | |
751 /* wasn't an alias - use what the user typed */ | |
752 linepos = putone( mp->m_text, linepos, namelen ); | |
753 else { | |
754 /* an alias - expand it */ | |
755 while (cp = getname(cp) ) { | |
756 if (linepos > MAX_SM_FIELD) { | |
757 fprintf (out, "\n%s: ", name); | |
758 linepos = namelen; | |
759 } | |
760 mp2 = getm( cp, NULLCP, 0, AD_HOST, NULLCP); | |
761 if (akvisible()) { | |
762 mp2->m_pers = getcpy(mp->m_mbox); | |
763 linepos = putone( adrformat(mp2), linepos, namelen ); | |
764 } else { | |
765 linepos = putone( mp2->m_text, linepos, namelen ); | |
766 } | |
767 mnfree( mp2 ); | |
768 } | |
769 } | |
770 } else { | |
771 /* not a local name - use what the user typed */ | |
772 linepos = putone( mp->m_text, linepos, namelen ); | |
773 } | |
774 mp2 = mp; | |
775 mp = mp->m_next; | |
776 mnfree( mp2 ); | |
777 } | |
778 putc( '\n', out ); | |
779 } | |
780 | |
781 static int putone ( adr, pos, indent ) | |
782 register char *adr; | |
783 register int pos; | |
784 int indent; | |
785 { | |
786 register int len; | |
787 static int linepos; | |
788 #ifdef MIME_HEADERS | |
789 char name[BUFSIZ], *ep; | |
790 | |
791 if (hencode) { | |
792 if ((ep = malloc((unsigned)strlen(adr)*10+1)) == NULL) | |
793 adios(NULLCP, "out of memory"); | |
794 sprintf(name, "%*s", indent, ""); /* dummy */ | |
795 (void) exthdr_encode(adr, ep, pos, name); | |
796 len = strlen(ep); | |
797 } else | |
798 #endif /* MIME_HEADERS */ | |
799 len = strlen( adr ); | |
800 if (pos == indent) | |
801 linepos = pos; | |
802 else if ( linepos+len > outputlinelen ) { | |
803 fprintf ( out, ",\n%*s", indent, ""); | |
804 #ifdef MIME_HEADERS | |
805 if (hencode) { | |
806 (void) exthdr_encode(adr, ep, linepos, name); | |
807 len = strlen(ep); | |
808 } | |
809 #endif /* MIME_HEADERS */ | |
810 linepos = indent; | |
811 pos += indent + 2; | |
812 } | |
813 else { | |
814 fputs( ", ", out ); | |
815 linepos += 2; | |
816 pos += 2; | |
817 } | |
818 #ifdef MIME_HEADERS | |
819 if (hencode) { | |
820 char *p; | |
821 fputs(ep, out); | |
822 linepos = (p = rindex(ep, '\n')) ? (ep + len) - (p+1) : linepos + len; | |
823 free(ep); | |
824 } else { | |
825 fputs(adr, out); | |
826 linepos += len; | |
827 } | |
828 #else /* MIME_HEADERS */ | |
829 fputs( adr, out ); | |
830 | |
831 linepos += len; | |
832 #endif /* MIME_HEADERS */ | |
833 return (pos+len); | |
834 } | |
835 | |
836 /* */ | |
837 | |
838 static insert_fcc (hdr, pp) | |
839 struct headers *hdr; | |
840 char *pp; | |
841 { | |
842 char *cp; | |
843 | |
844 for (cp = pp; isspace (*cp); cp++) | |
845 continue; | |
846 for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--) | |
847 continue; | |
848 if (pp >= cp) | |
849 *++pp = 0; | |
850 if (*cp == 0) | |
851 return; | |
852 | |
853 if (fccind >= FCCS) | |
854 adios (NULLCP, "too many %ss", hdr -> value); | |
855 fccfold[fccind++] = getcpy (cp); | |
856 } | |
857 | |
858 #ifdef notdef | |
859 /* BCC GENERATION */ | |
860 | |
861 static make_bcc_file () { | |
862 int fd, | |
863 i, | |
864 child_id, | |
865 status; | |
866 char *vec[6]; | |
867 FILE * in, *out; | |
868 | |
869 (void)mktemp (bccfil); | |
870 if ((out = fopen (bccfil, "w")) == NULL) | |
871 adios (bccfil, "unable to create"); | |
872 (void)chmod (bccfil, 0600); | |
873 | |
874 fprintf (out, "Date: %s\n", dtimenow ()); | |
875 fprintf (out, "From: %s\n", signature); | |
876 if (subject) | |
877 fprintf (out, "Subject: %s", subject); | |
878 fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n"); | |
879 (void)fflush (out); | |
880 | |
881 if (filter == NULL) { | |
882 if ((fd = open (tmpfil, 0)) == NOTOK) | |
883 adios (NULLCP, "unable to re-open"); | |
884 cpydgst (fd, fileno (out), tmpfil, bccfil); | |
885 close (fd); | |
886 } | |
887 else { | |
888 vec[0] = r1bindex (mhlproc, '/'); | |
889 | |
890 for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++) | |
891 sleep (5); | |
892 switch (child_id) { | |
893 case NOTOK: | |
894 adios ("vfork", "unable to"); | |
895 | |
896 case OK: | |
897 dup2 (fileno (out), 1); | |
898 | |
899 i = 1; | |
900 vec[i++] = "-forward"; | |
901 vec[i++] = "-form"; | |
902 vec[i++] = filter; | |
903 vec[i++] = tmpfil; | |
904 vec[i] = NULL; | |
905 | |
906 execvp (mhlproc, vec); | |
907 adios (mhlproc, "unable to exec"); | |
908 | |
909 default: | |
910 if (status = pidwait (child_id, OK)) | |
911 admonish (NULL, "%s lost (status=0%o)", vec[0], status); | |
912 break; | |
913 } | |
914 } | |
915 | |
916 fseek (out, 0L, 2); | |
917 fprintf (out, "\n------- End of Blind-Carbon-Copy\n"); | |
918 (void)fclose (out); | |
919 } | |
920 #endif /* notdef */ | |
921 | |
922 /* FCC INTERACTION */ | |
923 | |
924 static file (path) | |
925 char *path; | |
926 { | |
927 int i; | |
928 | |
929 if (fccind == 0) | |
930 return; | |
931 | |
932 for (i = 0; i < fccind; i++) | |
933 if (whomflg) | |
934 printf ("Fcc: %s\n", fccfold[i]); | |
935 else | |
936 fcc (path, fccfold[i]); | |
937 } | |
938 | |
939 | |
940 static fcc (file, folder) | |
941 char *file, | |
942 *folder; | |
943 { | |
944 int i, | |
945 child_id, | |
946 status; | |
947 char fold[BUFSIZ]; | |
948 | |
949 if (verbose) | |
950 printf ("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", folder); | |
951 (void)fflush (stdout); | |
952 | |
953 for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++) | |
954 sleep (5); | |
955 switch (child_id) { | |
956 case NOTOK: | |
957 if (!verbose) | |
958 fprintf (stderr, " %sFcc %s: ", | |
959 msgstate == resent ? "Resent-" : "", folder); | |
960 fprintf (verbose ? stdout : stderr, "no forks, so not ok\n"); | |
961 break; | |
962 | |
963 case OK: | |
964 (void)sprintf (fold, "%s%s", | |
965 *folder == '+' || *folder == '@' ? "" : "+", folder); | |
966 execlp (fileproc, r1bindex (fileproc, '/'), | |
967 "-link", "-file", file, fold, NULL); | |
968 _exit (-1); | |
969 | |
970 default: | |
971 if (status = pidwait (child_id, OK)) { | |
972 if (!verbose) | |
973 fprintf (stderr, " %sFcc %s: ", | |
974 msgstate == resent ? "Resent-" : "", folder); | |
975 fprintf (verbose ? stdout : stderr, | |
976 " errored (0%o)\n", status); | |
977 } | |
978 } | |
979 | |
980 (void)fflush (stdout); | |
981 } | |
982 | |
983 /* TERMINATION */ | |
984 | |
985 /* VARARGS2 */ | |
986 | |
987 static die (what, fmt, a, b, c, d) | |
988 char *what, | |
989 *fmt, | |
990 *a, | |
991 *b, | |
992 *c, | |
993 *d; | |
994 { | |
995 adios (what, fmt, a, b, c, d); | |
996 } |