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