]> andersk Git - moira.git/blob - update/update_server.c
Read it and weep.
[moira.git] / update / update_server.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_dispatch_c = "$Header$";
11 #endif
12
13 #include <mit-copyright.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <gdb.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <pwd.h>
20 #include <moira.h>
21 #include <sys/file.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #ifdef POSIX
25 #include <termios.h>
26 #endif
27 #include "update.h"
28 #include "des.h"
29
30 extern int auth_002(), xfer_002(), xfer_003(), exec_002();
31
32 extern int sync_proc(), quit();
33 extern char *config_lookup();
34
35 extern void gdb_debug();
36 extern int errno;
37
38 CONNECTION conn;
39 int code, log_priority;
40 char *whoami;
41
42 int have_authorization = 0;
43 C_Block session;
44 int have_file = 0;
45 int done = 0;
46 int uid = 0;
47
48 #define send_int(n) \
49      (_send_int=(n),send_object(conn,(char *)&_send_int,INTEGER_T))
50 int _send_int;
51
52 struct _dt {
53      char *str;
54      int (*proc)();
55 } dispatch_table[] = {
56      { "AUTH_002", auth_002 },
57      { "XFER_002", xfer_002 },
58      { "XFER_003", xfer_003 },
59      { "EXEC_002", exec_002 },
60      { "quit", quit },
61      { (char *)NULL, (int (*)())abort }
62 };
63
64 /* general scratch space -- useful for building error messages et al... */
65 char buf[BUFSIZ];
66
67
68 main(argc, argv)
69      int argc;
70      char **argv;
71 {
72      STRING str;
73      struct _dt *d;
74      char *p;
75      int n;
76
77 #ifdef DEBUG
78      gdb_debug(GDB_NOFORK);
79 #endif /* DEBUG */
80
81      whoami = strrchr(argv[0], '/');
82      if (whoami)
83          whoami++;
84      else
85          whoami = argv[0];
86
87      /* interpret arguments here */
88      if (argc != 1) {
89           fprintf(stderr, "Usage:  %s\n", whoami);
90           exit(1);
91      }
92
93 #ifndef DEBUG
94      if (!config_lookup("nofork")) {
95          if (fork())
96            exit(0);
97 #ifdef POSIX
98          setsid();
99 #else
100          n = open("/dev/tty", O_RDWR|FNDELAY);
101          if (n > 0) {
102              (void) ioctl(n, TIOCNOTTY, (char *)NULL);
103              (void) close(n);
104          }
105 #endif
106      } else
107        gdb_debug(GDB_NOFORK);
108 #endif
109
110      umask(0022);
111      initialize_sms_error_table();
112      initialize_krb_error_table();
113      mr_update_initialize();
114
115      /* wait for connection */
116      gdb_init();
117      /* If the config file contains a line "port portname", the daemon
118       * will listen on the named port rather than SERVICE_NAME "sms_update"
119       */
120      if ((p = config_lookup("port")) == NULL)
121        p = SERVICE_NAME;
122      conn = create_forking_server(p, 0);
123
124      /* If the config file contains a line "user username", the
125       * daemon will run with that user's UID.
126       */
127      if (p = config_lookup("user")) {
128          struct passwd *pw;
129          pw = getpwnam(p);
130          if (pw == 0) {
131              com_err(whoami, errno, "Unable to find user %s\n", p);
132              exit(1);
133          }
134          uid = pw->pw_uid;
135      }
136
137      /* If the config file contains a line "chroot /dir/name", the
138       * daemon will run chrooted to that directory.
139       */
140      if (p = config_lookup("chroot")) {
141          if (chroot(p) < 0) {
142              com_err(whoami, errno, "unable to chroot to %s", p);
143              exit(1);
144          }
145      }
146
147      if (!conn) {
148          com_err(whoami, errno, "can't get connection");
149          exit(1);
150      }
151      if (connection_status(conn) == CON_STOPPED) {
152          com_err(whoami, connection_errno(conn), ": can't get connection");
153          exit(1);
154      }
155
156      mr_log_info("got connection");
157      /* got a connection; loop forever */
158      while (1) {
159           register char *cp;
160           code = receive_object(conn, (char *)&str, STRING_T);
161           if (code) {
162               com_err(whoami, connection_errno(conn), "receiving command");
163               sever_connection(conn);
164               exit(1);
165           }
166           cp = strchr(STRING_DATA(str), ' ');
167           if (cp)
168                *cp = '\0';
169           for (d = dispatch_table; d->str; d++) {
170               if (!strcmp(d->str, STRING_DATA(str))) {
171                   if (cp)
172                       *cp = ' ';
173 #ifdef  DEBUG
174                   printf("got request: %s\n", STRING_DATA(str));
175 #endif  /* DEBUG */
176                   (void)(d->proc)(STRING_DATA(str));
177                   goto ok;
178               }
179           }
180           sprintf(buf, "unknown request received: %s\n", STRING_DATA(str));
181           mr_log_error(buf);
182           code = send_int(MR_UNKNOWN_PROC);
183           if (code) {
184               com_err(whoami, connection_errno(conn), "sending UNKNOWN_PROC");
185           }
186      ok:
187           string_free(&str);
188      }
189 }
190
191 int
192 send_ok()
193 {
194      static int zero = 0;
195      return((code = send_object(conn, (char *)&zero, INTEGER_T)));
196 }
197
198
199 initialize()
200 {
201      /* keep have_authorization around */
202      have_file = 0;
203      done = 0;
204 }
205
206
207 /*
208  * quit request:
209  *
210  * syntax:
211  * >>> quit
212  * <<< (int)0
213  * any arguments are ignored
214  *
215  * function:
216  *      closes connection from MR
217  */
218 int
219 quit(str)
220      char *str;
221 {
222 #ifdef lint
223      str = (char *)NULL;
224 #endif /* lint */
225      (void) send_ok();
226      sever_connection(conn);
227      mr_log_info("Closing connection.");
228      exit(0);
229 }
230
231
232 /*
233  * lose(msg)
234  *
235  * put <msg> to log as error, break connection, and exit
236  */
237
238 lose(msg)
239     char *msg;
240 {
241     com_err(whoami, code, msg);
242     if (conn)
243         sever_connection(conn);
244     exit(1);
245 }
246
247 /*
248  * report_error(msg)
249  *
250  * send back (external) <code>; if error, punt big with <lose(msg)>
251  */
252
253 report_error(msg)
254     char *msg;
255 {
256     code = send_object(conn, (char *)&code, INTEGER_T);
257     if (code) {
258         code = connection_errno(conn);
259         lose(msg);
260     }
261 }
262
263 /*
264  * reject_call(c)
265  *
266  * set (external) <code> to <c> and call <report_error>
267  */
268
269 reject_call(c)
270     int c;
271 {
272     code = c;
273     report_error("call rejected");
274 }
This page took 0.055863 seconds and 5 git commands to generate.