Mercurial > hg > Applications > mh
comparison sbr/m_update.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | 441a2190cfae |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
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 } |