source: trunk/third/moira/update/exec_002.c @ 24319

Revision 24319, 2.2 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: exec_002.c 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
5 * <mit-copyright.h>.
6 */
7
8#include <mit-copyright.h>
9#include <moira.h>
10#include "update_server.h"
11#include "update.h"
12
13#include <sys/wait.h>
14
15#include <errno.h>
16#include <signal.h>
17#include <stdio.h>
18#include <unistd.h>
19
20RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/update/exec_002.c $ $Id: exec_002.c 3956 2010-01-05 20:56:56Z zacheiss $");
21
22void exec_002(int conn, char *str)
23{
24  int waitb, n;
25  sigset_t mask, oldmask;
26  pid_t pid;
27  long code;
28
29  if (!have_authorization)
30    {
31      send_int(conn, MR_PERM);
32      return;
33    }
34  if (config_lookup("noexec"))
35    {
36      send_int(conn, EPERM);
37      com_err(whoami, EPERM, "Not allowed to execute");
38      return;
39    }
40
41  str += 8;
42  while (*str == ' ')
43    str++;
44  sigemptyset(&mask);
45  sigaddset(&mask, SIGCHLD);
46  sigprocmask(SIG_BLOCK, &mask, &oldmask);
47  pid = fork();
48  switch (pid)
49    {
50    case -1:
51      n = errno;
52      sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
53      com_err(whoami, n, ": can't fork to run install script");
54      code = send_int(conn, n);
55      if (code)
56        exit(1);
57      return;
58
59    case 0:
60      if (setuid(uid) < 0)
61        {
62          com_err(whoami, errno, "Unable to setuid to %d\n", uid);
63          exit(1);
64        }
65      sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
66      execlp(str, str, NULL);
67      n = errno;
68      sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
69      com_err(whoami, n, ": %s", str);
70      send_int(conn, n);
71      exit(1);
72
73    default:
74      do
75        n = wait(&waitb);
76      while (n != -1 && n != pid);
77
78      sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
79      if ((WIFEXITED(waitb) && (WEXITSTATUS(waitb) != 0)) ||
80          WIFSIGNALED(waitb))
81        {
82          if (WIFSIGNALED(waitb))
83            {
84              n = MR_COREDUMP;
85              com_err(whoami, n, " child exited on signal %d",
86                      WTERMSIG(waitb));
87            }
88          else
89            {
90              n = WEXITSTATUS(waitb) + ERROR_TABLE_BASE_sms;
91              com_err(whoami, n, " child exited with status %d",
92                      WEXITSTATUS(waitb));
93            }
94          code = send_int(conn, n);
95          if (code)
96            exit(1);
97        }
98      else
99        {
100          code = send_ok(conn);
101          if (code)
102            exit(1);
103        }
104    }
105  return;
106}
Note: See TracBrowser for help on using the repository browser.