]> andersk Git - moira.git/blob - update/exec_002.c
Read it and weep.
[moira.git] / update / exec_002.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5 /*  (c) Copyright 1988 by the Massachusetts Institute of Technology. */
6 /*  For copying and distribution information, please see the file */
7 /*  <mit-copyright.h>. */
8
9 #ifndef lint
10 static char *rcsid_exec_002_c = "$Header$";
11 #endif
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <errno.h>
16 #include <sys/types.h>
17 #ifdef _AIX
18 #undef _BSD
19 #endif
20 #include <sys/wait.h>
21 #ifdef _AIX
22 #define _BSD 44
23 #endif
24 #include <signal.h>
25 #include <gdb.h>
26 #include <moira.h>
27 #include "update.h"
28
29 extern CONNECTION conn;
30 extern int code, errno, uid, log_priority, have_authorization;
31 extern char *whoami;
32
33 #if defined(vax) || defined(ibm032)
34 #define WEXITSTATUS(waitb) ((waitb).w_retcode)
35 #endif
36
37
38 int
39 exec_002(str)
40     char *str;
41 {
42 #ifdef POSIX
43     int waitb;
44     sigset_t mask,oldmask;
45 #else
46     union wait waitb;
47     int mask;
48 #endif
49     int n, pid;
50
51     if (!have_authorization) {
52         reject_call(MR_PERM);
53         return(0);
54     }
55     if (config_lookup("noexec")) {
56         code = EPERM;
57         code = send_object(conn, (char *)&code, INTEGER_T);
58         com_err(whoami, code, "Not allowed to execute");
59         return(0);
60     }
61     str += 8;
62     while (*str == ' ')
63         str++;
64 #ifdef POSIX
65     sigemptyset(&mask);
66     sigaddset(&mask,SIGCHLD);
67     sigprocmask(SIG_BLOCK,&mask,&oldmask);
68 #else
69     mask = sigblock(sigmask(SIGCHLD));
70 #endif
71     pid = fork();
72     switch (pid) {
73     case -1:
74         n = errno;
75 #ifdef POSIX
76         sigprocmask(SIG_UNBLOCK,&oldmask,&mask);
77 #else
78         sigsetmask(mask);
79 #endif
80         log_priority = log_ERROR;
81         com_err(whoami, errno, ": can't fork to run install script");
82         code = send_object(conn, (char *)&n, INTEGER_T);
83         if (code)
84             exit(1);
85         return(0);
86     case 0:
87         if (setuid(uid) < 0) {
88             com_err(whoami, errno, "Unable to setuid to %d\n", uid);
89             exit(1);
90         }
91 #ifdef POSIX
92         sigprocmask(SIG_UNBLOCK,&oldmask,&mask);
93 #else
94         sigsetmask(mask);
95 #endif
96         execlp(str, str, (char *)NULL);
97         n = errno;
98 #ifdef POSIX
99         sigprocmask(SIG_UNBLOCK,&oldmask,&mask);
100 #else
101         sigsetmask(mask);
102 #endif
103         log_priority = log_ERROR;
104         com_err(whoami, n, ": %s", str);
105         (void) send_object(conn, (char *)&n, INTEGER_T);
106         exit(1);
107     default:
108         do {
109             n = wait(&waitb);
110         } while (n != -1 && n != pid);
111 #ifdef POSIX
112         sigprocmask(SIG_UNBLOCK,&oldmask,&mask);
113 #else
114         sigsetmask(mask);
115 #endif
116 #ifdef POSIX
117         if ( (WIFEXITED(waitb) && (WEXITSTATUS(waitb)!=0)) || WIFSIGNALED(waitb)  ) {
118             /* This is not really correct.  It will cause teh moira server to
119                report a bogus error message if the script died on a signal.
120                However this is the same thing that occurs in the non-POSIX
121                case, and I don't know how to come up with a useful error based
122                on the signal recieved.
123             */
124             n = WEXITSTATUS(waitb) + ERROR_TABLE_BASE_sms;
125             log_priority = log_ERROR;
126             com_err(whoami, n, " child exited with status %d",
127                     WEXITSTATUS(waitb));
128 #else
129         if (waitb.w_status) {
130             n = waitb.w_retcode + ERROR_TABLE_BASE_sms;
131             log_priority = log_ERROR;
132             com_err(whoami, n, " child exited with status %d",
133                     waitb.w_retcode);
134 #endif
135             code = send_object(conn, (char *)&n, INTEGER_T);
136             if (code) {
137                 exit(1);
138             }
139         } else {
140             code = send_ok();
141             if (code)
142               exit(1);
143         }
144     }
145 }
This page took 0.045268 seconds and 5 git commands to generate.