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