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