New changes: Sender: cannot be blank, Sender: always overrides From:
[mmh] / sbr / context_save.c
1
2 /*
3  * context_save.c -- write out the updated context file
4  *
5  * This code is Copyright (c) 2002, by the authors of nmh.  See the
6  * COPYRIGHT file in the root directory of the nmh distribution for
7  * complete copyright information.
8  */
9
10 #include <h/mh.h>
11 #include <h/signals.h>
12
13 /*
14  * static prototypes
15  */
16 static int m_chkids(void);
17
18
19 void
20 context_save (void)
21 {
22     int action;
23     register struct node *np;
24     FILE *out;
25     sigset_t set, oset;
26     
27     /* No context in use -- silently ignore any changes! */
28     if (!ctxpath)
29        return;
30
31     if (!(ctxflags & CTXMOD))
32         return;
33     ctxflags &= ~CTXMOD;
34
35     if ((action = m_chkids ()) > 0)
36         return;                 /* child did it for us */
37
38     /* block a few signals */
39     sigemptyset (&set);
40     sigaddset (&set, SIGHUP);
41     sigaddset (&set, SIGINT);
42     sigaddset (&set, SIGQUIT);
43     sigaddset (&set, SIGTERM);
44     sigprocmask (SIG_BLOCK, &set, &oset);
45
46     if (!(out = lkfopen (ctxpath, "w")))
47         adios (ctxpath, "unable to write");
48     for (np = m_defs; np; np = np->n_next)
49         if (np->n_context)
50             fprintf (out, "%s: %s\n", np->n_name, np->n_field);
51     lkfclose (out, ctxpath);
52
53     sigprocmask (SIG_SETMASK, &oset, &set); /* reset the signal mask */
54
55     if (action == 0)
56         _exit (0);              /* we are child, time to die */
57 }
58
59 /*
60  * This hack brought to you so we can handle set[ug]id MH programs.
61  * If we return -1, then no fork is made, we update .mh_profile
62  * normally, and return to the caller normally.  If we return 0,
63  * then the child is executing, .mh_profile is modified after
64  * we set our [ug]ids to the norm.  If we return > 0, then the
65  * parent is executed and .mh_profile has already be modified.
66  * We can just return to the caller immediately.
67  */
68
69 static int
70 m_chkids (void)
71 {
72     int i;
73     pid_t pid;
74
75     if (getuid () == geteuid ())
76         return (-1);
77
78     for (i = 0; (pid = fork ()) == -1 && i < 5; i++)
79         sleep (5);
80
81     switch (pid) {
82         case -1:
83             break;
84
85         case 0:
86             setgid (getgid ());
87             setuid (getuid ());
88             break;
89
90         default:
91             pidwait (pid, -1);
92             break;
93     }
94
95     return pid;
96 }