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