|
|
1.1 root 1: /* inc.c - incorporate messages from a maildrop into a folder */
2:
3: #include "../h/mh.h"
4: #ifdef POP
5: #include "../h/dropsbr.h"
6: #endif POP
7: #include "../h/formatsbr.h"
8: #include "../h/scansbr.h"
9: #include "../zotnet/tws.h"
10: #include <stdio.h>
11: #include "../zotnet/mts.h"
12: #include <errno.h>
13: #include <signal.h>
14: #include <sys/types.h>
15: #include <sys/stat.h>
16:
17: /* */
18:
19: static struct swit switches[] = {
20: #define AUDSW 0
21: "audit audit-file", 0,
22: #define NAUDSW 1
23: "noaudit", 0,
24:
25: #define CHGSW 2
26: "changecur", 0,
27: #define NCHGSW 3
28: "nochangecur", 0,
29:
30: #define DECRSW 4
31: "decrypt",
32: #ifndef TMA
33: -7,
34: #else TMA
35: 0,
36: #endif TMA
37: #define NDECRSW 5
38: "nodecrypt",
39: #ifndef TMA
40: -9,
41: #else TMA
42: 0,
43: #endif TMA
44:
45: #define MSW 6
46: "file name", 0,
47:
48: #define FORMSW 7
49: "form formatfile", 0,
50: #define FMTSW 8
51: "format string", 5,
52:
53: #define HOSTSW 9
54: "host host",
55: #ifndef POP
56: -4,
57: #else POP
58: 0,
59: #endif POP
60: #define USERSW 10
61: "user user",
62: #ifndef POP
63: -4,
64: #else POP
65: 0,
66: #endif POP
67: #define PACKSW 11
68: "pack file",
69: #ifndef POP
70: -4,
71: #else POP
72: 0,
73: #endif POP
74: #define NPACKSW 12
75: "nopack",
76: #ifndef POP
77: -6,
78: #else POP
79: 0,
80: #endif POP
81: #define RPOPSW 13
82: "rpop",
83: #ifndef RPOP
84: -4,
85: #else RPOP
86: 0,
87: #endif RPOP
88: #define NRPOPSW 14
89: "norpop",
90: #ifndef RPOP
91: -6,
92: #else RPOP
93: 0,
94: #endif RPOP
95:
96: #define SILSW 15
97: "silent", 0,
98: #define NSILSW 16
99: "nosilent", 0,
100:
101: #define TRNCSW 17
102: "truncate", 0,
103: #define NTRNCSW 18
104: "notruncate", 0,
105:
106: #define UUCPSW 19
107: "uucp",
108: #ifndef MF
109: -4,
110: #else MF
111: 0,
112: #endif MF
113: #define NUUCPSW 20
114: "nouucp",
115: #ifndef MF
116: -6,
117: #else MF
118: 0,
119: #endif MF
120:
121: #define WIDSW 21
122: "width columns", 0,
123:
124: #define HELPSW 22
125: "help", 4,
126:
127: NULL, NULL
128: };
129:
130: /* */
131:
132: extern int errno;
133:
134: #ifdef POP
135: int snoop = 0;
136: extern char response[];
137:
138: static char *file = NULL;
139: static int size;
140: static long pos;
141: static long start;
142: static long stop;
143:
144: static int pd = NOTOK;
145: static FILE *pf = NULL;
146:
147: int pop_action (), pop_pack ();
148: #endif POP
149:
150: /* * /
151:
152: /* ARGSUSED */
153:
154: main (argc, argv)
155: int argc;
156: char *argv[];
157: {
158: int chgflag = 1,
159: trnflag = 1,
160: decflag = 1,
161: noisy = 1,
162: width = 0,
163: uucp = 1,
164: locked = 0,
165: #ifdef POP
166: nmsgs,
167: nbytes,
168: p,
169: #endif POP
170: rpop = 1,
171: i,
172: hghnum,
173: msgnum;
174: char *cp,
175: *maildir,
176: *folder = NULL,
177: *form = NULL,
178: *format = NULL,
179: *audfile = NULL,
180: *from = NULL,
181: *host = NULL,
182: *user = NULL,
183: #ifdef POP
184: *pass = NULL,
185: #endif POP
186: *newmail,
187: buf[100],
188: **ap,
189: **argp,
190: *nfs,
191: *arguments[MAXARGS];
192: struct msgs *mp;
193: struct stat st,
194: s1;
195: FILE *in, *aud;
196: #ifdef MHE
197: FILE *mhe;
198: #endif MHE
199:
200: invo_name = r1bindex (argv[0], '/');
201: mts_init (invo_name);
202: #ifdef POP
203: if (pophost && *pophost)
204: host = pophost;
205: if ((cp = getenv ("MHPOPDEBUG")) && *cp)
206: snoop++;
207: #endif POP
208: if ((cp = m_find (invo_name)) != NULL) {
209: ap = brkstring (cp = getcpy (cp), " ", "\n");
210: ap = copyip (ap, arguments);
211: }
212: else
213: ap = arguments;
214: (void) copyip (argv + 1, ap);
215: argp = arguments;
216:
217: /* */
218:
219: while (cp = *argp++) {
220: if (*cp == '-')
221: switch (smatch (++cp, switches)) {
222: case AMBIGSW:
223: ambigsw (cp, switches);
224: done (1);
225: case UNKWNSW:
226: adios (NULLCP, "-%s unknown", cp);
227: case HELPSW:
228: (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
229: help (buf, switches);
230: done (1);
231:
232: case AUDSW:
233: if (!(cp = *argp++) || *cp == '-')
234: adios (NULLCP, "missing argument to %s", argp[-2]);
235: audfile = getcpy (m_maildir (cp));
236: continue;
237: case NAUDSW:
238: audfile = NULL;
239: continue;
240:
241: case CHGSW:
242: chgflag++;
243: continue;
244: case NCHGSW:
245: chgflag = 0;
246: continue;
247:
248: case TRNCSW:
249: trnflag++;
250: continue;
251: case MSW:
252: if (!(cp = *argp++) || *cp == '-')
253: adios (NULLCP, "missing argument to %s", argp[-2]);
254: from = path (cp, TFILE);/* fall */
255: case NTRNCSW:
256: trnflag = 0;
257: continue;
258:
259: case SILSW:
260: noisy = 0;
261: continue;
262: case NSILSW:
263: noisy++;
264: continue;
265:
266: case FORMSW:
267: if (!(form = *argp++) || *form == '-')
268: adios (NULLCP, "missing argument to %s", argp[-2]);
269: format = NULL;
270: continue;
271: case FMTSW:
272: if (!(format = *argp++) || *format == '-')
273: adios (NULLCP, "missing argument to %s", argp[-2]);
274: form = NULL;
275: continue;
276:
277: case WIDSW:
278: if (!(cp = *argp++) || *cp == '-')
279: adios (NULLCP, "missing argument to %s", argp[-2]);
280: width = atoi (cp);
281: continue;
282:
283: case DECRSW:
284: decflag++;
285: continue;
286: case NDECRSW:
287: decflag = 0;
288: continue;
289:
290: case UUCPSW:
291: uucp++;
292: continue;
293: case NUUCPSW:
294: uucp = 0;
295: continue;
296:
297: case HOSTSW:
298: if (!(host = *argp++) || *host == '-')
299: adios (NULLCP, "missing argument to %s", argp[-2]);
300: continue;
301: case USERSW:
302: if (!(user = *argp++) || *user == '-')
303: adios (NULLCP, "missing argument to %s", argp[-2]);
304: continue;
305: case PACKSW:
306: #ifndef POP
307: if (!(cp = *argp++) || *cp == '-')
308: adios (NULLCP, "missing argument to %s", argp[-2]);
309: #else POP
310: if (!(file = *argp++) || *file == '-')
311: adios (NULLCP, "missing argument to %s", argp[-2]);
312: #endif POP
313: continue;
314: case NPACKSW:
315: #ifdef POP
316: file = NULLCP;
317: #endif POP
318: continue;
319: case RPOPSW:
320: rpop++;
321: continue;
322: case NRPOPSW:
323: rpop = 0;
324: continue;
325: }
326: if (*cp == '+' || *cp == '@') {
327: if (folder)
328: adios (NULLCP, "only one folder at a time!");
329: else
330: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
331: }
332: else
333: adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
334: }
335:
336: /* */
337:
338: #ifdef POP
339: if (host && !*host)
340: host = NULL;
341: if (from || !host || !rpop)
342: (void) setuid (getuid ());
343: #endif POP
344: if (from) {
345: newmail = from;
346: #ifdef POP
347: host = NULL;
348: #endif POP
349: if (stat (newmail, &s1) == NOTOK || s1.st_size == 0)
350: adios (NULLCP, "no mail to incorporate");
351: }
352: #ifdef POP
353: else if (host) {
354: if (rpop) {
355: if (user == NULL)
356: user = getusr ();
357: pass = getusr ();
358: }
359: else
360: ruserpass (host, &user, &pass);
361:
362: if (pop_init (host, user, pass, snoop, rpop) == NOTOK
363: || pop_stat (&nmsgs, &nbytes) == NOTOK)
364: adios (NULLCP, "%s", response);
365: if (rpop)
366: (void) setuid (getuid ());
367: if (nmsgs == 0) {
368: (void) pop_quit ();
369: adios (NULLCP, "no mail to incorporate");
370: }
371: }
372: #endif POP
373: else {
374: if (((newmail = getenv ("MAILDROP")) && *newmail)
375: || ((newmail = m_find ("maildrop")) && *newmail))
376: newmail = m_mailpath (newmail);
377: else {
378: #ifdef MF
379: if (uucp && umincproc && *umincproc)
380: get_uucp_mail ();
381: #endif MF
382: newmail = concat (MAILDIR, "/", MAILFIL, NULLCP);
383: }
384: if (stat (newmail, &s1) == NOTOK || s1.st_size == 0)
385: adios (NULLCP, "no mail to incorporate");
386: }
387:
388: #ifdef POP
389: if (host && file)
390: goto go_to_it;
391: #endif POP
392: if (!m_find ("path"))
393: free (path ("./", TFOLDER));
394: if (!folder)
395: folder = defalt;
396: maildir = m_maildir (folder);
397:
398: if (stat (maildir, &st) == NOTOK) {
399: if (errno != ENOENT)
400: adios (maildir, "error on folder");
401: cp = concat ("Create folder \"", maildir, "\"? ", NULLCP);
402: if (noisy && !getanswer (cp))
403: done (1);
404: free (cp);
405: if (!makedir (maildir))
406: adios (NULLCP, "unable to create folder %s", maildir);
407: }
408:
409: if (chdir (maildir) == NOTOK)
410: adios (maildir, "unable to change directory to");
411: if (!(mp = m_gmsg (folder)))
412: adios (NULLCP, "unable to read folder %s", folder);
413:
414: /* */
415:
416: #ifdef POP
417: go_to_it: ;
418: if (host == NULL)
419: #endif POP
420: if (access (newmail, 02) == NOTOK) {
421: trnflag = 0;
422: if ((in = fopen (newmail, "r")) == NULL)
423: adios (newmail, "unable to read");
424: }
425: else {
426: locked++;
427: if (trnflag) {
428: (void) signal (SIGHUP, SIG_IGN);
429: (void) signal (SIGINT, SIG_IGN);
430: (void) signal (SIGQUIT, SIG_IGN);
431: (void) signal (SIGTERM, SIG_IGN);
432: }
433: if ((in = lkfopen (newmail, "r")) == NULL)
434: adios (NULLCP, "unable to lock and fopen %s", newmail);
435: (void) fstat (fileno(in), &s1);
436: }
437:
438: if (audfile) {
439: if ((i = stat (audfile, &st)) == NOTOK)
440: advise (NULLCP, "Creating Receive-Audit: %s", audfile);
441: if ((aud = fopen (audfile, "a")) == NULL)
442: adios (audfile, "unable to append to");
443: else
444: if (i == NOTOK)
445: (void) chmod (audfile, m_gmprot ());
446: #ifndef POP
447: fprintf (aud, from ? "<<inc>> %s -ms %s\n" : "<<inc>> %s\n",
448: dtimenow (), from);
449: #else POP
450: fprintf (aud, from ? "<<inc>> %s -ms %s\n"
451: : host ? "<<inc>> %s -host %s -user %s%s\n"
452: : "<<inc>> %s\n",
453: dtimenow (), from ? from : host, user, rpop ? " -rpop" : "");
454: #endif POP
455: }
456:
457: #ifdef MHE
458: if (m_find ("mhe")) {
459: cp = concat (maildir, "/++", NULLCP);
460: i = stat (cp, &st);
461: if ((mhe = fopen (cp, "a")) == NULL)
462: admonish (cp, "unable to append to");
463: else
464: if (i == NOTOK)
465: (void) chmod (cp, m_gmprot ());
466: free (cp);
467: }
468: #endif MHE
469:
470: nfs = new_fs (form, format, FORMAT);
471:
472: if (noisy) {
473: printf ("Incorporating new mail into %s...\n\n", folder);
474: (void) fflush (stdout);
475: }
476:
477: /* */
478:
479: #ifdef POP
480: if (host) {
481: if (file) {
482: file = path (file, TFILE);
483: if (stat (file, &st) == NOTOK) {
484: if (errno != ENOENT)
485: adios (file, "error on file");
486: cp = concat ("Create file \"", file, "\"? ", NULLCP);
487: if (noisy && !getanswer (cp))
488: done (1);
489: free (cp);
490: }
491: msgnum = map_count ();
492: if ((pd = mbx_open (file, getuid (), getgid (), m_gmprot ()))
493: == NOTOK)
494: adios (file, "unable to open");
495: if ((pf = fdopen (pd, "w+")) == NULL)
496: adios (NULLCP, "unable to fdopen %s", file);
497: }
498: else {
499: hghnum = msgnum = mp -> hghmsg;
500: if ((mp = m_remsg (mp, 0, mp -> hghmsg + nmsgs)) == NULL)
501: adios (NULLCP, "unable to allocate folder storage");
502: }
503:
504: for (i = 1; i <= nmsgs; i++) {
505: msgnum++;
506: if (file) {
507: (void) fseek (pf, 0L, 1);
508: pos = ftell (pf);
509: size = 0;
510: (void) fwrite (mmdlm1, 1, strlen (mmdlm1), pf);
511: start = ftell (pf);
512:
513: if (pop_retr (i, pop_pack) == NOTOK)
514: adios (NULLCP, "%s", response);
515:
516: (void) fseek (pf, 0L, 1);
517: stop = ftell (pf);
518: if (fflush (pf))
519: adios (file, "write error on");
520: (void) fseek (pf, start, 0);
521: }
522: else {
523: cp = getcpy (m_name (msgnum));
524: if ((pf = fopen (cp, "w+")) == NULL)
525: adios (cp, "unable to write");
526: (void) chmod (cp, m_gmprot ());
527: start = stop = 0L;
528:
529: if (pop_retr (i, pop_action) == NOTOK)
530: adios (NULLCP, "%s", response);
531:
532: if (fflush (pf))
533: adios (cp, "write error on");
534: (void) fseek (pf, 0L, 0);
535: }
536: switch (p = scan (pf, msgnum, 0, nfs, width,
537: file ? 0 : msgnum == mp -> hghmsg + 1 && chgflag,
538: 0, stop - start, noisy)) {
539: case SCNEOF:
540: printf ("%*d empty\n", DMAXFOLDER, msgnum);
541: break;
542:
543: case SCNERR:
544: case SCNNUM:
545: break;
546:
547: case SCNMSG:
548: case SCNENC:
549: default:
550: if (aud)
551: fputs (scanl, aud);
552: #ifdef MHE
553: if (mhe)
554: fputs (scanl, mhe);
555: #endif MHE
556: if (noisy)
557: (void) fflush (stdout);
558: if (!file) {
559: mp -> msgstats[msgnum] = EXISTS;
560: #ifdef TMA
561: if (p == SCNENC) {
562: if (mp -> lowsel == 0 || msgnum < mp -> lowsel)
563: mp -> lowsel = msgnum;
564: if (mp -> hghsel == 0 || msgnum > mp -> hghsel)
565: mp -> hghsel = msgnum;
566: mp -> numsel++;
567: mp -> msgstats[msgnum] |= SELECTED;
568: }
569: #endif TMA
570: mp -> msgstats[msgnum] |= UNSEEN;
571: mp -> msgflags |= SEQMOD;
572: }
573: break;
574: }
575: if (file) {
576: (void) fseek (pf, stop, 0);
577: (void) fwrite (mmdlm2, 1, strlen (mmdlm2), pf);
578: if (fflush (pf))
579: adios (file, "write error on");
580: (void) map_write (file, pd, 0, start, stop, pos, size, noisy);
581: }
582: else {
583: (void) fclose (pf);
584: free (cp);
585: }
586:
587: if (trnflag && pop_dele (i) == NOTOK)
588: adios (NULLCP, "%s", response);
589: }
590: if (pop_quit () == NOTOK)
591: adios (NULLCP, "%s", response);
592: if (file) {
593: (void) mbx_close (file, pd);
594: pd = NOTOK;
595: }
596: }
597: else {
598: #endif POP
599:
600: /* */
601:
602: m_unknown (in); /* the MAGIC invocation... */
603: hghnum = msgnum = mp -> hghmsg;
604: for (;;) {
605: if (msgnum >= mp -> hghoff)
606: if ((mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER)) == NULL)
607: adios (NULLCP, "unable to allocate folder storage");
608:
609: switch (i = scan (in, msgnum + 1, msgnum + 1, nfs, width,
610: msgnum == hghnum && chgflag,
611: 0,
612: 0L,
613: noisy)) {
614: case SCNEOF:
615: break;
616:
617: case SCNERR:
618: if (aud)
619: fputs ("inc aborted!\n", aud);
620: adios (NULLCP, "aborted!");
621:
622: case SCNNUM:
623: adios (NULLCP, "more than %d messages in folder %s, %s not zero'd",
624: MAXFOLDER, folder, newmail);
625:
626: default:
627: adios (NULLCP, "scan() botch (%d)", i);
628:
629: case SCNMSG:
630: case SCNENC:
631: if (aud)
632: fputs (scanl, aud);
633: #ifdef MHE
634: if (mhe)
635: fputs (scanl, mhe);
636: #endif MHE
637: if (noisy)
638: (void) fflush (stdout);
639:
640: msgnum++, mp -> hghmsg++;
641: mp -> msgstats[msgnum] = EXISTS;
642: #ifdef TMA
643: if (i == SCNENC) {
644: if (mp -> lowsel == 0 || mp -> lowsel > msgnum)
645: mp -> lowsel = msgnum;
646: if (mp -> hghsel == 0 || mp -> hghsel < msgnum)
647: mp -> hghsel = msgnum;
648: mp -> numsel++;
649: mp -> msgstats[msgnum] |= SELECTED;
650: }
651: #endif TMA
652: mp -> msgstats[msgnum] |= UNSEEN;
653: mp -> msgflags |= SEQMOD;
654: continue;
655: }
656: break;
657: }
658: #ifdef POP
659: }
660: #endif POP
661:
662: if (aud)
663: (void) fclose (aud);
664: #ifdef MHE
665: if (mhe)
666: (void) fclose (mhe);
667: #endif MHE
668: if (noisy)
669: (void) fflush (stdout);
670: #ifdef POP
671: if (host && file)
672: done (0);
673: #endif POP
674:
675: /* */
676:
677: #ifdef POP
678: if (host == NULL)
679: #endif POP
680: if (trnflag) {
681: if (stat (newmail, &st) != NOTOK && s1.st_mtime != st.st_mtime)
682: advise (NULLCP, "new messages have arrived!\007");
683: else {
684: if ((i = creat (newmail, 0600)) != NOTOK)
685: (void) close (i);
686: else
687: admonish (newmail, "error zero'ing");
688: (void) unlink (map_name (newmail));
689: }
690: }
691: else
692: if (noisy)
693: printf ("%s not zero'd\n", newmail);
694:
695: if (msgnum == hghnum)
696: admonish (NULLCP, "no messages incorporated");
697: else {
698: m_replace (pfolder, folder);
699: if (chgflag)
700: mp -> curmsg = hghnum + 1;
701: mp -> hghmsg = msgnum;
702: if (mp -> lowmsg == 0)
703: mp -> lowmsg = 1;
704: if (chgflag) /* sigh... */
705: m_setcur (mp, mp -> curmsg);
706: }
707:
708: #ifdef POP
709: if (host == NULL)
710: #endif POP
711: if (locked)
712: (void) lkfclose (in, newmail);
713: else
714: (void) fclose (in);
715:
716: m_setvis (mp, 0);
717: m_sync (mp);
718: m_update ();
719:
720: #ifdef TMA
721: if (decflag && mp -> numsel > 0) {
722: if (noisy) {
723: printf ("\nIncorporating encrypted mail into %s...\n\n", folder);
724: (void) fflush (stdout);
725: }
726:
727: tmastart ();
728: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
729: if (mp -> msgstats[msgnum] & SELECTED && decipher (msgnum) == OK) {
730: if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
731: admonish (cp, "unable to open message");
732: free (cp);
733: continue;
734: }
735: switch (scan (in, msgnum, 0, nfs, width,
736: msgnum == mp -> curmsg,
737: 0,
738: fstat (fileno (in), &st) != NOTOK ? (long) st.st_size
739: : 0L,
740: noisy)) {
741: case SCNEOF:
742: printf ("%*d empty\n", DMAXFOLDER, msgnum);
743: break;
744:
745: default:
746: break;
747: }
748: (void) fclose (in);
749: free (cp);
750: }
751: tmastop ();
752:
753: if (noisy)
754: (void) fflush (stdout);
755: }
756: #endif TMA
757:
758: done (0);
759: }
760:
761: /* */
762:
763: #ifdef POP
764: void done (status)
765: int status;
766: {
767: if (file && pd != NOTOK)
768: (void) mbx_close (file, pd);
769:
770: exit (status);
771: }
772: #endif POP
773: /* */
774:
775: #ifdef MF
776: get_uucp_mail () {
777: int child_id;
778: char buffer[BUFSIZ];
779: struct stat st;
780:
781: (void) sprintf (buffer, "%s/%s", UUCPDIR, UUCPFIL);
782: if (stat (buffer, &st) == NOTOK || st.st_size == 0)
783: return;
784:
785: switch (child_id = vfork ()) {
786: case NOTOK:
787: admonish ("fork", "unable to");
788: break;
789:
790: case OK:
791: execlp (umincproc, r1bindex (umincproc, '/'), NULLCP);
792: fprintf (stderr, "unable to exec ");
793: perror (umincproc);
794: _exit (-1);
795:
796: default:
797: (void) pidXwait (child_id, umincproc);
798: break;
799: }
800: }
801: #endif MF
802:
803: /* */
804:
805: #ifdef POP
806: static int pop_action (s)
807: register char *s;
808: {
809: fprintf (pf, "%s\n", s);
810: stop += strlen (s) + 1;
811: }
812:
813:
814: static int pop_pack (s)
815: register char *s;
816: {
817: register int j;
818: char buffer[BUFSIZ];
819:
820: (void) sprintf (buffer, "%s\n", s);
821: for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
822: continue;
823: for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
824: continue;
825: fputs (buffer, pf);
826: size += strlen (buffer) + 1;
827: }
828:
829: static int map_count () {
830: int md;
831: char *cp;
832: struct drop d;
833: struct stat st;
834:
835: if (stat (file, &st) == NOTOK)
836: return 0;
837: if ((md = open (cp = map_name (file), 0)) == NOTOK
838: || map_chk (cp, md, &d, (long) st.st_size, 1)) {
839: if (md != NOTOK)
840: (void) close (md);
841: return 0;
842: }
843: (void) close (md);
844: return (d.d_id);
845: }
846: #endif POP
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.