source: trunk/third/moira/update/update_server.c @ 23882

Revision 23882, 4.8 KB checked in by broder, 16 years ago (diff)
In moira: * New upstream release * Build and install libmoira as a shared library. (Trac: #70) * Drop most of the krb4 patch - it's been incorporated upstream. * Install the Moira development headers by patching the relevant Makefiles, instead of in the debian/rules file.
Line 
1/* $Id: update_server.c,v 1.27 2009-05-04 20:49:13 zacheiss Exp $
2 *
3 * Copyright 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
12#include <sys/stat.h>
13#include <sys/utsname.h>
14#include <sys/wait.h>
15
16#include <netinet/in.h>
17#include <arpa/inet.h>
18
19#include <errno.h>
20#include <pwd.h>
21#include <signal.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <syslog.h>
27
28#ifdef HAVE_KRB4
29#include <des.h>
30#endif
31#include "update.h"
32
33RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/update/update_server.c,v 1.27 2009-05-04 20:49:13 zacheiss Exp $");
34
35char *whoami, *hostname;
36
37int have_authorization = 0;
38#ifdef HAVE_KRB4
39des_cblock session;
40#endif
41int uid = 0;
42
43void child_handler(int signal);
44static void syslog_com_err_proc(const char *progname, long code,
45                                const char *fmt, va_list args);
46
47struct _dt {
48  char *str;
49  void (*proc)(int, char *);
50} dispatch_table[] = {
51#ifdef HAVE_KRB4
52  { "AUTH_002", auth_002 },
53#endif
54  { "AUTH_003", auth_003 },
55  { "XFER_002", xfer_002 },
56  { "XFER_003", xfer_003 },
57  { "EXEC_002", exec_002 },
58  { "quit", quit },
59  { NULL, (void (*)(int, char *))abort }
60};
61
62int main(int argc, char **argv)
63{
64  char *str, *p;
65  size_t len;
66  struct _dt *d;
67  struct utsname name;
68  int s, conn;
69  struct sigaction sa;
70
71  whoami = strrchr(argv[0], '/');
72  if (whoami)
73    whoami++;
74  else
75    whoami = argv[0];
76
77  /* interpret arguments here */
78  if (argc != 1)
79    {
80      fprintf(stderr, "Usage:  %s\n", whoami);
81      exit(1);
82    }
83
84  if (!config_lookup("nofork"))
85    {
86      if (fork())
87        exit(0);
88      setsid();
89    }
90
91  uname(&name);
92  hostname = name.nodename;
93
94  umask(0022);
95  mr_init();
96
97  sigemptyset(&sa.sa_mask);
98  sa.sa_flags = SA_RESTART;
99  sa.sa_handler = child_handler;
100  sigaction(SIGCHLD, &sa, NULL);
101
102  /* If the config file contains a line "user username", the
103   * daemon will run with that user's UID.
104   */
105  if ((p = config_lookup("user")))
106    {
107      struct passwd *pw;
108      pw = getpwnam(p);
109      if (!pw)
110        {
111          com_err(whoami, errno, "Unable to find user %s\n", p);
112          exit(1);
113        }
114      uid = pw->pw_uid;
115    }
116
117  /* If the config file contains a line "port portname", the daemon
118   * will listen on the named port rather than SERVICE_NAME ("moira_update")
119   */
120  if (!(p = config_lookup("port")))
121    p = SERVICE_NAME;
122
123  s = mr_listen(p);
124  if (s == -1)
125    {
126      com_err(whoami, errno, "creating listening socket");
127      exit(1);
128    }
129
130  set_com_err_hook(syslog_com_err_proc);
131  openlog(whoami, LOG_PID, LOG_DAEMON);
132
133  /* now loop waiting for connections */
134  while (1)
135    {
136      struct sockaddr_in client;
137      long len;
138      char *buf;
139
140      conn = mr_accept(s, &client);
141      if (conn == -1)
142        {
143          com_err(whoami, errno, "accepting on listening socket");
144          exit(1);
145        }
146      else if (conn == 0)
147        continue;
148
149      if (config_lookup("nofork") || (fork() <= 0))
150        break;
151
152      close(conn);
153    }
154
155  /* If the config file contains a line "chroot /dir/name", the
156   * daemon will run chrooted to that directory.
157   */
158  if ((p = config_lookup("chroot")))
159    {
160      if (chroot(p) < 0)
161        {
162          com_err(whoami, errno, "unable to chroot to %s", p);
163          exit(1);
164        }
165    }
166
167  com_err(whoami, 0, "got connection");
168
169  while (1)
170    {
171      char *cp, *str;
172      size_t len;
173      int code;
174
175      code = recv_string(conn, &str, &len);
176      if (code)
177        {
178          com_err(whoami, code, "receiving command");
179          close(conn);
180          exit(1);
181        }
182
183      cp = strchr(str, ' ');
184      if (cp)
185        *cp = '\0';
186      for (d = dispatch_table; d->str; d++)
187        {
188          if (!strcmp(d->str, str))
189            {
190              if (cp)
191                *cp = ' ';
192              (d->proc)(conn, str);
193              goto ok;
194            }
195        }
196      com_err(whoami, 0, "unknown request received: %s", str);
197      code = send_int(conn, MR_UNKNOWN_PROC);
198      if (code)
199        com_err(whoami, code, "sending UNKNOWN_PROC");
200    ok:
201      free(str);
202    }
203}
204
205int send_ok(int conn)
206{
207  return send_int(conn, 0);
208}
209
210/*
211 * quit request:
212 *
213 * syntax:
214 * >>> quit
215 * <<< (int)0
216 * any arguments are ignored
217 *
218 * function:
219 *      closes connection from MR
220 */
221
222void quit(int conn, char *str)
223{
224  send_ok(conn);
225  close(conn);
226  com_err(whoami, 0, "Closing connection.");
227  exit(0);
228}
229
230void fail(int conn, int err, char *msg)
231{
232  com_err(whoami, err, msg);
233  close(conn);
234  exit(1);
235}
236
237void child_handler(int signal)
238{
239  int status;
240
241  while (waitpid(-1, &status, WNOHANG) > 0)
242    ;
243}
244
245static void syslog_com_err_proc(const char *progname, long code,
246                                const char *fmt, va_list args)
247{
248  char buf[BUFSIZ + 1];
249
250  buf[BUFSIZ] = '\0';
251
252  vsnprintf(buf, BUFSIZ, fmt, args);
253  syslog(LOG_NOTICE, "%s: %s %s", progname ? progname : "",
254         code ? error_message(code) : "", buf);
255}
Note: See TracBrowser for help on using the repository browser.