]> andersk Git - moira.git/blob - update/update_server.c
Change `SMS' to `Moira' where possible.
[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   { NULL, (int (*)())abort }
62 };
63
64 /* general scratch space -- useful for building error messages et al... */
65 char buf[BUFSIZ];
66
67 int main(int argc, char **argv)
68 {
69   STRING str;
70   struct _dt *d;
71   char *p;
72   int n;
73
74   whoami = strrchr(argv[0], '/');
75   if (whoami)
76     whoami++;
77   else
78     whoami = argv[0];
79
80   /* interpret arguments here */
81   if (argc != 1)
82     {
83       fprintf(stderr, "Usage:  %s\n", whoami);
84       exit(1);
85     }
86
87   if (!config_lookup("nofork"))
88     {
89       if (fork())
90         exit(0);
91       setsid();
92     }
93   else
94     gdb_debug(GDB_NOFORK);
95
96   umask(0022);
97   initialize_sms_error_table();
98   initialize_krb_error_table();
99   mr_update_initialize();
100
101   /* wait for connection */
102   gdb_init();
103   /* If the config file contains a line "port portname", the daemon
104    * will listen on the named port rather than SERVICE_NAME "moira_update"
105    */
106   if (!(p = config_lookup("port")))
107     p = SERVICE_NAME;
108   conn = create_forking_server(p, 0);
109
110   /* If the config file contains a line "user username", the
111    * daemon will run with that user's UID.
112    */
113   if ((p = config_lookup("user")))
114     {
115       struct passwd *pw;
116       pw = getpwnam(p);
117       if (!pw)
118         {
119           com_err(whoami, errno, "Unable to find user %s\n", p);
120           exit(1);
121         }
122       uid = pw->pw_uid;
123     }
124
125   /* If the config file contains a line "chroot /dir/name", the
126    * daemon will run chrooted to that directory.
127    */
128   if ((p = config_lookup("chroot")))
129     {
130       if (chroot(p) < 0)
131         {
132           com_err(whoami, errno, "unable to chroot to %s", p);
133           exit(1);
134         }
135     }
136
137   if (!conn)
138     {
139       com_err(whoami, errno, "can't get connection");
140       exit(1);
141     }
142   if (connection_status(conn) == CON_STOPPED)
143     {
144       com_err(whoami, connection_errno(conn), ": can't get connection");
145       exit(1);
146     }
147
148   mr_log_info("got connection");
149   /* got a connection; loop forever */
150   while (1)
151     {
152       char *cp;
153       code = receive_object(conn, (char *)&str, STRING_T);
154       if (code)
155         {
156           com_err(whoami, connection_errno(conn), "receiving command");
157           sever_connection(conn);
158           exit(1);
159         }
160       cp = strchr(STRING_DATA(str), ' ');
161       if (cp)
162         *cp = '\0';
163       for (d = dispatch_table; d->str; d++)
164         {
165           if (!strcmp(d->str, STRING_DATA(str)))
166             {
167               if (cp)
168                 *cp = ' ';
169               (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     ok:
179       string_free(&str);
180     }
181 }
182
183 int send_ok(void)
184 {
185   static int zero = 0;
186   return code = send_object(conn, (char *)&zero, INTEGER_T);
187 }
188
189
190 initialize(void)
191 {
192   /* keep have_authorization around */
193   have_file = 0;
194   done = 0;
195 }
196
197
198 /*
199  * quit request:
200  *
201  * syntax:
202  * >>> quit
203  * <<< (int)0
204  * any arguments are ignored
205  *
206  * function:
207  *      closes connection from MR
208  */
209 int quit(char *str)
210 {
211   send_ok();
212   sever_connection(conn);
213   mr_log_info("Closing connection.");
214   exit(0);
215 }
216
217
218 /*
219  * lose(msg)
220  *
221  * put <msg> to log as error, break connection, and exit
222  */
223
224 lose(char *msg)
225 {
226   com_err(whoami, code, msg);
227   if (conn)
228     sever_connection(conn);
229   exit(1);
230 }
231
232 /*
233  * report_error(msg)
234  *
235  * send back (external) <code>; if error, punt big with <lose(msg)>
236  */
237
238 report_error(char *msg)
239 {
240   code = send_object(conn, (char *)&code, INTEGER_T);
241   if (code)
242     {
243       code = connection_errno(conn);
244       lose(msg);
245     }
246 }
247
248 /*
249  * reject_call(c)
250  *
251  * set (external) <code> to <c> and call <report_error>
252  */
253
254 reject_call(int c)
255 {
256   code = c;
257   report_error("call rejected");
258 }
This page took 0.354868 seconds and 5 git commands to generate.