0
|
1 /* m_update.c - update the profile */
|
|
2 #ifndef lint
|
|
3 static char ident[] = "@(#)$Id$";
|
|
4 #endif /* lint */
|
|
5
|
|
6 #include "../h/mh.h"
|
|
7 #include <stdio.h>
|
|
8 #include <signal.h>
|
|
9 #ifndef sigmask
|
|
10 #define sigmask(s) (1 << ((s) - 1))
|
|
11 #endif /* not sigmask */
|
|
12
|
|
13 static int m_chkids();
|
|
14
|
|
15 void m_update () {
|
|
16 int action;
|
|
17 #ifndef BSD42
|
|
18 TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
|
|
19 #else /* BSD42 */
|
|
20 int smask;
|
|
21 #endif /* BSD42 */
|
|
22 register struct node *np;
|
|
23 FILE * out;
|
|
24
|
|
25 if (!(ctxflags & CTXMOD))
|
|
26 return;
|
|
27 ctxflags &= ~CTXMOD;
|
|
28
|
|
29 if ((action = m_chkids ()) > OK)
|
|
30 return; /* child did it for us */
|
|
31
|
|
32 #ifndef BSD42
|
|
33 hstat = signal (SIGHUP, SIG_IGN);
|
|
34 istat = signal (SIGINT, SIG_IGN);
|
|
35 qstat = signal (SIGQUIT, SIG_IGN);
|
|
36 tstat = signal (SIGTERM, SIG_IGN);
|
|
37 #else /* BSD42 */
|
|
38 smask = sigblock (sigmask (SIGHUP) | sigmask (SIGINT)
|
|
39 | sigmask (SIGQUIT) | sigmask (SIGTERM));
|
|
40 #endif /* BSD42 */
|
|
41
|
|
42 if ((out = fopen (ctxpath, "w")) == NULL)
|
|
43 adios (ctxpath, "unable to write");
|
|
44 for (np = m_defs; np; np = np -> n_next)
|
|
45 if (np -> n_context)
|
|
46 fprintf (out, "%s: %s\n", np -> n_name, np -> n_field);
|
|
47 (void) fclose (out);
|
|
48
|
|
49 #ifndef BSD42
|
|
50 (void) signal (SIGHUP, hstat);
|
|
51 (void) signal (SIGINT, istat);
|
|
52 (void) signal (SIGQUIT, qstat);
|
|
53 (void) signal (SIGTERM, tstat);
|
|
54 #else /* BSD42 */
|
|
55 (void) sigsetmask (smask);
|
|
56 #endif /* BSD42 */
|
|
57 if (action == OK)
|
|
58 _exit (0); /* we are child, time to die */
|
|
59 }
|
|
60
|
|
61 /* */
|
|
62
|
|
63 /* This hack brought to you so we can handle set[ug]id MH programs. If we
|
|
64 return NOTOK, then no fork is made, we update .mh_profile normally, and
|
|
65 return to the caller normally. If we return 0, then the child is
|
|
66 executing, .mh_profile is modified after we set our [ug]ids to the norm.
|
|
67 If we return > 0, then the parent is executed and .mh_profile has
|
|
68 already be modified. We can just return to the caller immediately. */
|
|
69
|
|
70
|
|
71 static int m_chkids () {
|
|
72 int i,
|
|
73 child_id;
|
|
74
|
|
75 if (getuid () == geteuid ())
|
|
76 return (NOTOK);
|
|
77
|
|
78 for (i = 0; (child_id = fork ()) == -1 && i < 5; i++)
|
|
79 sleep (5);
|
|
80 switch (child_id) {
|
|
81 case NOTOK:
|
|
82 break;
|
|
83
|
|
84 case OK:
|
|
85 (void) setgid (getgid ());
|
|
86 (void) setuid (getuid ());
|
|
87 break;
|
|
88
|
|
89 default:
|
|
90 (void) pidwait (child_id, NOTOK);
|
|
91 break;
|
|
92 }
|
|
93
|
|
94 return child_id;
|
|
95 }
|