]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/inc.c
1 /* inc.c - incorporate messages from a maildrop into a folder */
3 static char ident
[] = "@(#)$Id: inc.c,v 1.24 1994/04/21 18:22:06 jromine Exp shettich $";
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.
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.
20 #include "../h/dropsbr.h"
28 #include "../h/formatsbr.h"
29 #include "../h/scansbr.h"
30 #include "../zotnet/tws.h"
32 #include "../zotnet/mts.h"
35 #include <sys/types.h>
50 #define POPminc(a) (a)
55 #define RPOPminc(a) (a)
58 #define APOPminc(a) (a)
64 #define TMAminc(a) (a)
69 static struct swit switches
[] = {
71 "audit audit-file", 0,
81 "decrypt", TMAminc (-7),
83 "nodecrypt", TMAminc (-9),
94 "host host", POPminc (-4),
96 "user user", POPminc (-4),
98 "pack file", POPminc (-4),
100 "nopack", POPminc (-6),
103 "apop", APOPminc (-4),
105 "noapop", APOPminc (-6),
121 "nouucp", MFminc (-6),
138 extern char response
[];
140 static char *file
= NULL
;
146 static int pd
= NOTOK
;
147 static FILE *pf
= NULL
;
149 static int pop_action (), pop_pack ();
150 static int map_count();
157 #ifdef MAILGROUP /* For setting and returning to "mail" gid */
158 static int return_gid
;
159 #endif /* MAILGROUP */
205 FILE *in
, *aud
= NULL
;
210 struct hes_postoffice
*po
;
215 setlocale(LC_ALL
, "");
217 invo_name
= r1bindex (argv
[0], '/');
218 mts_init (invo_name
);
224 * use MAILHOST environment variable if present,
226 * If that fails, use the default (if any)
227 * provided by mtstailor in mts_init()
229 if ((tmphost
= getenv("MAILHOST")) != NULL
)
231 else if ((po
= hes_getmailhost(getusr())) != NULL
&&
232 strcmp(po
->po_type
, "POP") == 0)
233 pophost
= po
->po_host
;
235 if (pophost
&& *pophost
)
238 if ((cp
= getenv ("MHPOPDEBUG")) && *cp
)
242 if ((cp
= m_find (invo_name
)) != NULL
) {
243 ap
= brkstring (cp
= getcpy (cp
), " ", "\n");
244 ap
= copyip (ap
, arguments
);
248 (void) copyip (argv
+ 1, ap
);
253 while (cp
= *argp
++) {
255 switch (smatch (++cp
, switches
)) {
257 ambigsw (cp
, switches
);
260 adios (NULLCP
, "-%s unknown", cp
);
262 (void) sprintf (buf
, "%s [+folder] [switches]", invo_name
);
263 help (buf
, switches
);
267 if (!(cp
= *argp
++) || *cp
== '-')
268 adios (NULLCP
, "missing argument to %s", argp
[-2]);
269 audfile
= getcpy (m_maildir (cp
));
286 if (!(cp
= *argp
++) || *cp
== '-')
287 adios (NULLCP
, "missing argument to %s", argp
[-2]);
288 from
= path (cp
, TFILE
);/* fall */
301 if (!(form
= *argp
++) || *form
== '-')
302 adios (NULLCP
, "missing argument to %s", argp
[-2]);
306 if (!(format
= *argp
++) || *format
== '-')
307 adios (NULLCP
, "missing argument to %s", argp
[-2]);
312 if (!(cp
= *argp
++) || *cp
== '-')
313 adios (NULLCP
, "missing argument to %s", argp
[-2]);
336 if (!(host
= *argp
++) || *host
== '-')
337 adios (NULLCP
, "missing argument to %s", argp
[-2]);
340 if (!(user
= *argp
++) || *user
== '-')
341 adios (NULLCP
, "missing argument to %s", argp
[-2]);
345 if (!(cp
= *argp
++) || *cp
== '-')
346 adios (NULLCP
, "missing argument to %s", argp
[-2]);
348 if (!(file
= *argp
++) || *file
== '-')
349 adios (NULLCP
, "missing argument to %s", argp
[-2]);
363 if (*cp
== '+' || *cp
== '@') {
365 adios (NULLCP
, "only one folder at a time!");
367 folder
= path (cp
+ 1, *cp
== '+' ? TFOLDER
: TSUBCWF
);
370 adios (NULLCP
, "usage: %s [+folder] [switches]", invo_name
);
376 return_gid
= getegid(); /* Save effective gid, assuming we'll use it */
377 setgid(getgid()); /* Turn off extraordinary privileges */
378 #endif /* MAILGROUP */
389 if (stat (newmail
, &s1
) == NOTOK
|| s1
.st_size
== 0)
390 adios (NULLCP
, "no mail to incorporate");
396 ruserpass (host
, &user
, &pass
);
398 if (pop_init (host
, user
, pass
, snoop
, rpop
) == NOTOK
399 || pop_stat (&nmsgs
, &nbytes
) == NOTOK
)
400 adios (NULLCP
, "%s", response
);
403 adios (NULLCP
, "no mail to incorporate");
408 if (((newmail
= getenv ("MAILDROP")) && *newmail
)
409 || ((newmail
= m_find ("maildrop")) && *newmail
))
410 newmail
= m_mailpath (newmail
);
413 if (uucp
&& umincproc
&& *umincproc
)
416 newmail
= concat (MAILDIR
, "/", MAILFIL
, NULLCP
);
418 if (stat (newmail
, &s1
) == NOTOK
|| s1
.st_size
== 0)
419 adios (NULLCP
, "no mail to incorporate");
426 if (!m_find ("path"))
427 free (path ("./", TFOLDER
));
428 if (!folder
&& !(folder
= m_find (inbox
)))
430 maildir
= m_maildir (folder
);
432 if (stat (maildir
, &st
) == NOTOK
) {
434 adios (maildir
, "error on folder");
435 cp
= concat ("Create folder \"", maildir
, "\"? ", NULLCP
);
436 if (noisy
&& !getanswer (cp
))
439 if (!makedir (maildir
))
440 adios (NULLCP
, "unable to create folder %s", maildir
);
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
);
454 if (access (newmail
, 02) == NOTOK
) {
456 if ((in
= fopen (newmail
, "r")) == NULL
)
457 adios (newmail
, "unable to read");
462 (void) signal (SIGHUP
, SIG_IGN
);
463 (void) signal (SIGINT
, SIG_IGN
);
464 (void) signal (SIGQUIT
, SIG_IGN
);
465 (void) signal (SIGTERM
, SIG_IGN
);
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
);
474 setgid(getgid()); /* Return us to normal privileges */
475 #endif /* MAILGROUP */
476 (void) fstat (fileno(in
), &s1
);
480 setgid(getgid()); /* Return us to normal privileges */
481 #endif /* MAILGROUP */
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");
490 (void) chmod (audfile
, m_gmprot ());
492 fprintf (aud
, from
? "<<inc>> %s -ms %s\n" : "<<inc>> %s\n",
495 fprintf (aud
, from
? "<<inc>> %s -ms %s\n"
496 : host
? "<<inc>> %s -host %s -user %s%s\n"
498 dtimenow (), from
? from
: host
, user
,
499 apop
== 1 ? " -apop" : "");
504 if (m_find ("mhe")) {
505 cp
= concat (maildir
, "/++", NULLCP
);
507 if ((mhe
= fopen (cp
, "a")) == NULL
)
508 admonish (cp
, "unable to append to");
511 (void) chmod (cp
, m_gmprot ());
516 nfs
= new_fs (form
, format
, FORMAT
);
519 printf ("Incorporating new mail into %s...\n\n", folder
);
520 (void) fflush (stdout
);
528 file
= path (file
, TFILE
);
529 if (stat (file
, &st
) == NOTOK
) {
531 adios (file
, "error on file");
532 cp
= concat ("Create file \"", file
, "\"? ", NULLCP
);
533 if (noisy
&& !getanswer (cp
))
537 msgnum
= map_count ();
538 if ((pd
= mbx_open (file
, getuid (), getgid (), m_gmprot ()))
540 adios (file
, "unable to open");
541 if ((pf
= fdopen (pd
, "w+")) == NULL
)
542 adios (NULLCP
, "unable to fdopen %s", file
);
545 hghnum
= msgnum
= mp
-> hghmsg
;
546 if ((mp
= m_remsg (mp
, 0, mp
-> hghmsg
+ nmsgs
)) == NULL
)
547 adios (NULLCP
, "unable to allocate folder storage");
550 for (i
= 1; i
<= nmsgs
; i
++) {
553 (void) fseek (pf
, 0L, 1);
556 (void) fwrite (mmdlm1
, 1, strlen (mmdlm1
), pf
);
559 if (pop_retr (i
, pop_pack
) == NOTOK
)
560 adios (NULLCP
, "%s", response
);
562 (void) fseek (pf
, 0L, 1);
565 adios (file
, "write error on");
566 (void) fseek (pf
, start
, 0);
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 ());
575 if (pop_retr (i
, pop_action
) == NOTOK
)
576 adios (NULLCP
, "%s", response
);
579 adios (cp
, "write error on");
580 (void) fseek (pf
, 0L, 0);
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
)) {
587 printf ("%*d empty\n", DMAXFOLDER
, msgnum
);
593 /* advise (cp, "unable to read"); already advised */
610 (void) fflush (stdout
);
612 mp
-> msgstats
[msgnum
] = EXISTS
;
615 if (mp
-> lowsel
== 0 || msgnum
< mp
-> lowsel
)
616 mp
-> lowsel
= msgnum
;
617 if (mp
-> hghsel
== 0 || msgnum
> mp
-> hghsel
)
618 mp
-> hghsel
= msgnum
;
620 mp
-> msgstats
[msgnum
] |= SELECTED
;
623 mp
-> msgstats
[msgnum
] |= UNSEEN
;
624 mp
-> msgflags
|= SEQMOD
;
629 (void) fseek (pf
, stop
, 0);
630 (void) fwrite (mmdlm2
, 1, strlen (mmdlm2
), pf
);
631 if (fflush (pf
) || ferror (pf
)) {
635 adios (file
, "write error on");
637 (void) map_write (file
, pd
, 0, 0L, start
, stop
, pos
, size
,
641 if (ferror(pf
) || fclose (pf
)) {
646 adios (cp
, "write error on");
651 if (trnflag
&& pop_dele (i
) == NOTOK
)
652 adios (NULLCP
, "%s", response
);
654 if (pop_quit () == NOTOK
)
655 adios (NULLCP
, "%s", response
);
657 (void) mbx_close (file
, pd
);
666 m_unknown (in
); /* the MAGIC invocation... */
667 hghnum
= msgnum
= mp
-> hghmsg
;
669 if (msgnum
>= mp
-> hghoff
)
670 if ((mp
= m_remsg (mp
, 0, mp
-> hghoff
+ MAXFOLDER
)) == NULL
) {
671 advise (NULLCP
, "unable to allocate folder storage");
676 switch (i
= scan (in
, msgnum
+ 1, msgnum
+ 1, nfs
, width
,
677 msgnum
== hghnum
&& chgflag
,
678 1, /* check UNSEEN? */
686 fputs ("inc aborted!\n", aud
);
687 advise (NULLCP
, "aborted!"); /* doesn't clean up locks! */
692 "more than %d messages in folder %s, %s not zero'd",
693 MAXFOLDER
, folder
, newmail
);
697 advise (NULLCP
, "scan() botch (%d)", i
);
709 (void) fflush (stdout
);
711 msgnum
++, mp
-> hghmsg
++;
712 mp
-> msgstats
[msgnum
] = EXISTS
;
715 if (mp
-> lowsel
== 0 || mp
-> lowsel
> msgnum
)
716 mp
-> lowsel
= msgnum
;
717 if (mp
-> hghsel
== 0 || mp
-> hghsel
< msgnum
)
718 mp
-> hghsel
= msgnum
;
720 mp
-> msgstats
[msgnum
] |= SELECTED
;
723 mp
-> msgstats
[msgnum
] |= UNSEEN
;
724 mp
-> msgflags
|= SEQMOD
;
733 if (i
< 0) { /* error } */
735 if (p
< 0) { /* error */
740 setgid(return_gid
); /* Be sure we can unlock mail file */
741 #endif /* MAILGROUP */
743 (void) lkfclose (in
, newmail
);
745 setgid(getgid()); /* And then return us to normal privileges */
747 #endif /* MAILGROUP */
750 adios (NULLCP
, "failed");
760 (void) fflush (stdout
);
772 if (stat (newmail
, &st
) != NOTOK
&& s1
.st_mtime
!= st
.st_mtime
)
773 advise (NULLCP
, "new messages have arrived!\007");
775 if ((i
= creat (newmail
, 0600)) != NOTOK
)
778 admonish (newmail
, "error zero'ing");
779 (void) unlink (map_name (newmail
));
784 printf ("%s not zero'd\n", newmail
);
786 if (msgnum
== hghnum
)
787 admonish (NULLCP
, "no messages incorporated");
789 m_replace (pfolder
, folder
);
791 mp
-> curmsg
= hghnum
+ 1;
792 mp
-> hghmsg
= msgnum
;
793 if (mp
-> lowmsg
== 0)
795 if (chgflag
) /* sigh... */
796 m_setcur (mp
, mp
-> curmsg
);
805 setgid(return_gid
); /* Be sure we can unlock mail file */
806 #endif /* MAILGROUP */
808 (void) lkfclose (in
, newmail
);
810 setgid(getgid()); /* And then return us to normal privileges */
812 #endif /* MAILGROUP */
821 if (decflag
&& mp
-> numsel
> 0) {
823 printf ("\nIncorporating encrypted mail into %s...\n\n", folder
);
824 (void) fflush (stdout
);
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");
835 switch (scan (in
, msgnum
, 0, nfs
, width
,
836 msgnum
== mp
-> curmsg
,
837 1, /* check UNSEEN? */
839 fstat (fileno (in
), &st
) != NOTOK
? (long) st
.st_size
843 printf ("%*d empty\n", DMAXFOLDER
, msgnum
);
855 (void) fflush (stdout
);
868 if (file
&& pd
!= NOTOK
)
869 (void) mbx_close (file
, pd
);
882 (void) sprintf (buffer
, "%s/%s", UUCPDIR
, UUCPFIL
);
883 if (stat (buffer
, &st
) == NOTOK
|| st
.st_size
== 0)
886 switch (child_id
= vfork ()) {
888 admonish ("fork", "unable to");
892 execlp (umincproc
, r1bindex (umincproc
, '/'), NULLCP
);
893 fprintf (stderr
, "unable to exec ");
898 (void) pidXwait (child_id
, umincproc
);
907 static int pop_action (s
)
910 fprintf (pf
, "%s\n", s
);
911 stop
+= strlen (s
) + 1;
915 static int pop_pack (s
)
921 (void) sprintf (buffer
, "%s\n", s
);
922 for (j
= 0; (j
= stringdex (mmdlm1
, buffer
)) >= 0; buffer
[j
]++)
924 for (j
= 0; (j
= stringdex (mmdlm2
, buffer
)) >= 0; buffer
[j
]++)
927 size
+= strlen (buffer
) + 1;
930 static int map_count () {
936 if (stat (file
, &st
) == NOTOK
)
938 if ((md
= open (cp
= map_name (file
), 0)) == NOTOK
939 || map_chk (cp
, md
, &d
, (long) st
.st_size
, 1)) {