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