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