]>
Commit | Line | Data |
---|---|---|
de56407f | 1 | /* |
2 | * $Source$ | |
3 | * $Header$ | |
4 | */ | |
546bc43b | 5 | /* (c) Copyright 1988 by the Massachusetts Institute of Technology. */ |
6 | /* For copying and distribution information, please see the file */ | |
7 | /* <mit-copyright.h>. */ | |
de56407f | 8 | |
9 | #ifndef lint | |
10 | static char *rcsid_dispatch_c = "$Header$"; | |
7da203a3 | 11 | #endif |
de56407f | 12 | |
546bc43b | 13 | #include <mit-copyright.h> |
de56407f | 14 | #include <stdio.h> |
7da203a3 | 15 | #include <stdlib.h> |
45c91bf7 | 16 | #include <gdb.h> |
de56407f | 17 | #include <errno.h> |
698271c7 | 18 | #include <string.h> |
529a5b0d | 19 | #include <pwd.h> |
2ad0a777 | 20 | #include <moira.h> |
45c91bf7 | 21 | #include <sys/file.h> |
4691347d | 22 | #include <fcntl.h> |
45c91bf7 | 23 | #include <sys/ioctl.h> |
698271c7 | 24 | #ifdef POSIX |
4691347d | 25 | #include <termios.h> |
26 | #endif | |
de56407f | 27 | #include "update.h" |
de56407f | 28 | |
45c91bf7 | 29 | extern int auth_001(), inst_001(); |
b0a35414 | 30 | extern int xfer_002(), xfer_003(), exec_002(); |
de56407f | 31 | |
32 | extern int sync_proc(), quit(); | |
529a5b0d | 33 | extern char *config_lookup(); |
de56407f | 34 | |
35 | extern void gdb_debug(); | |
7da203a3 | 36 | extern int errno; |
45c91bf7 | 37 | extern STRING instructions; |
de56407f | 38 | |
39 | CONNECTION conn; | |
7da203a3 | 40 | int code, log_priority; |
de56407f | 41 | char *whoami; |
42 | ||
45c91bf7 | 43 | int have_authorization = 0; |
44 | int have_file = 0; | |
45 | int have_instructions = 0; | |
46 | int done = 0; | |
529a5b0d | 47 | int uid = 0; |
45c91bf7 | 48 | |
de56407f | 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 }, | |
de56407f | 59 | { "XFER_002", xfer_002 }, |
b0a35414 | 60 | { "XFER_003", xfer_003 }, |
de56407f | 61 | { "EXEC_002", exec_002 }, |
62 | { "quit", quit }, | |
7da203a3 | 63 | { (char *)NULL, (int (*)())abort } |
de56407f | 64 | }; |
65 | ||
529a5b0d | 66 | /* general scratch space -- useful for building error messages et al... */ |
de56407f | 67 | char buf[BUFSIZ]; |
529a5b0d | 68 | |
de56407f | 69 | |
70 | main(argc, argv) | |
71 | int argc; | |
72 | char **argv; | |
73 | { | |
74 | STRING str; | |
75 | struct _dt *d; | |
529a5b0d | 76 | char *p; |
45c91bf7 | 77 | int n; |
de56407f | 78 | |
79 | #ifdef DEBUG | |
80 | gdb_debug(GDB_NOFORK); | |
81 | #endif /* DEBUG */ | |
82 | ||
698271c7 | 83 | whoami = strrchr(argv[0], '/'); |
de56407f | 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 | } | |
de56407f | 94 | |
45c91bf7 | 95 | #ifndef DEBUG |
529a5b0d | 96 | if (!config_lookup("nofork")) { |
97 | if (fork()) | |
98 | exit(0); | |
698271c7 | 99 | #ifdef POSIX |
100 | setsid(); | |
101 | #else | |
529a5b0d | 102 | n = open("/dev/tty", O_RDWR|FNDELAY); |
103 | if (n > 0) { | |
104 | (void) ioctl(n, TIOCNOTTY, (char *)NULL); | |
105 | (void) close(n); | |
106 | } | |
698271c7 | 107 | #endif |
529a5b0d | 108 | } else |
109 | gdb_debug(GDB_NOFORK); | |
45c91bf7 | 110 | #endif |
111 | ||
112 | umask(0022); | |
0dac1a73 | 113 | initialize_sms_error_table(); |
114 | initialize_krb_error_table(); | |
2ad0a777 | 115 | mr_update_initialize(); |
de56407f | 116 | |
117 | /* wait for connection */ | |
118 | gdb_init(); | |
529a5b0d | 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 | ||
de56407f | 149 | if (!conn) { |
529a5b0d | 150 | com_err(whoami, errno, "can't get connection"); |
151 | exit(1); | |
de56407f | 152 | } |
153 | if (connection_status(conn) == CON_STOPPED) { | |
154 | com_err(whoami, connection_errno(conn), ": can't get connection"); | |
155 | exit(1); | |
156 | } | |
157 | ||
2ad0a777 | 158 | mr_log_info("got connection"); |
de56407f | 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) { | |
529a5b0d | 164 | com_err(whoami, connection_errno(conn), "receiving command"); |
165 | sever_connection(conn); | |
166 | exit(1); | |
de56407f | 167 | } |
698271c7 | 168 | cp = strchr(STRING_DATA(str), ' '); |
de56407f | 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)); | |
2ad0a777 | 183 | mr_log_error(buf); |
184 | code = send_int(MR_UNKNOWN_PROC); | |
de56407f | 185 | if (code) { |
529a5b0d | 186 | com_err(whoami, connection_errno(conn), "sending UNKNOWN_PROC"); |
de56407f | 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 | } | |
45c91bf7 | 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: | |
2ad0a777 | 221 | * closes connection from MR |
45c91bf7 | 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); | |
2ad0a777 | 232 | mr_log_info("Closing connection."); |
7da203a3 | 233 | exit(0); |
45c91bf7 | 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 | { | |
529a5b0d | 246 | com_err(whoami, code, msg); |
45c91bf7 | 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 | } |