]>
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$"; | |
11 | #endif lint | |
12 | ||
546bc43b | 13 | #include <mit-copyright.h> |
de56407f | 14 | #include <stdio.h> |
45c91bf7 | 15 | #include <gdb.h> |
de56407f | 16 | #include <errno.h> |
17 | #include <strings.h> | |
45c91bf7 | 18 | #include <sms.h> |
19 | #include <sys/file.h> | |
20 | #include <sys/ioctl.h> | |
de56407f | 21 | #include "update.h" |
de56407f | 22 | |
23 | /* XXX */ | |
24 | #include "kludge.h" | |
25 | /* XXX */ | |
26 | ||
45c91bf7 | 27 | extern int auth_001(), inst_001(); |
de56407f | 28 | extern int xfer_002(), exec_002(); |
29 | ||
30 | extern int sync_proc(), quit(); | |
31 | ||
32 | extern void gdb_debug(); | |
33 | extern int exit(), abort(), errno; | |
45c91bf7 | 34 | extern STRING instructions; |
de56407f | 35 | |
36 | CONNECTION conn; | |
37 | int code; | |
38 | char *whoami; | |
39 | ||
45c91bf7 | 40 | int have_authorization = 0; |
41 | int have_file = 0; | |
42 | int have_instructions = 0; | |
43 | int done = 0; | |
44 | ||
45 | ||
de56407f | 46 | #define send_int(n) \ |
47 | (_send_int=(n),send_object(conn,(char *)&_send_int,INTEGER_T)) | |
48 | int _send_int; | |
49 | ||
50 | struct _dt { | |
51 | char *str; | |
52 | int (*proc)(); | |
53 | } dispatch_table[] = { | |
54 | { "INST_001", inst_001 }, | |
55 | { "AUTH_001", auth_001 }, | |
de56407f | 56 | { "XFER_002", xfer_002 }, |
57 | { "EXEC_002", exec_002 }, | |
58 | { "quit", quit }, | |
59 | { (char *)NULL, abort } | |
60 | }; | |
61 | ||
62 | /* | |
63 | * general scratch space -- useful for building | |
64 | * error messages et al... | |
65 | */ | |
66 | char buf[BUFSIZ]; | |
67 | err(code, fmt) | |
68 | int code; | |
69 | char *fmt; | |
70 | { | |
71 | sprintf(buf, fmt, error_message(code)); | |
72 | sms_log_error(buf); | |
73 | } | |
74 | ||
75 | main(argc, argv) | |
76 | int argc; | |
77 | char **argv; | |
78 | { | |
79 | STRING str; | |
80 | struct _dt *d; | |
45c91bf7 | 81 | int n; |
de56407f | 82 | |
83 | #ifdef DEBUG | |
84 | gdb_debug(GDB_NOFORK); | |
85 | #endif /* DEBUG */ | |
86 | ||
87 | whoami = rindex(argv[0], '/'); | |
88 | if (whoami) | |
89 | whoami++; | |
90 | else | |
91 | whoami = argv[0]; | |
92 | ||
93 | /* interpret arguments here */ | |
94 | if (argc != 1) { | |
95 | fprintf(stderr, "Usage: %s\n", whoami); | |
96 | exit(1); | |
97 | } | |
98 | /* well, sort of... */ | |
99 | ||
45c91bf7 | 100 | #ifndef DEBUG |
101 | if (fork()) | |
102 | exit(0); | |
103 | n = open("/dev/tty", O_RDWR|O_NDELAY); | |
104 | if (n > 0) { | |
105 | (void) ioctl(n, TIOCNOTTY, (char *)NULL); | |
106 | (void) close(n); | |
107 | } | |
108 | #endif | |
109 | ||
110 | umask(0022); | |
0dac1a73 | 111 | initialize_sms_error_table(); |
112 | initialize_krb_error_table(); | |
de56407f | 113 | sms_update_initialize(); |
de56407f | 114 | |
115 | /* wait for connection */ | |
116 | gdb_init(); | |
117 | conn = create_forking_server(SERVICE_NAME, 0); | |
118 | if (!conn) { | |
119 | err(errno, "%s: can't get connection"); | |
120 | exit(1); | |
121 | } | |
122 | if (connection_status(conn) == CON_STOPPED) { | |
123 | com_err(whoami, connection_errno(conn), ": can't get connection"); | |
124 | exit(1); | |
125 | } | |
126 | ||
127 | sms_log_info("got connection"); | |
128 | /* got a connection; loop forever */ | |
129 | while (1) { | |
130 | register char *cp; | |
131 | code = receive_object(conn, (char *)&str, STRING_T); | |
132 | if (code) { | |
133 | err(connection_errno(conn), "%s: receiving command"); | |
134 | sever_connection(conn); | |
135 | exit(1); | |
136 | } | |
137 | cp = index(STRING_DATA(str), ' '); | |
138 | if (cp) | |
139 | *cp = '\0'; | |
140 | for (d = dispatch_table; d->str; d++) { | |
141 | if (!strcmp(d->str, STRING_DATA(str))) { | |
142 | if (cp) | |
143 | *cp = ' '; | |
144 | #ifdef DEBUG | |
145 | printf("got request: %s\n", STRING_DATA(str)); | |
146 | #endif /* DEBUG */ | |
147 | (void)(d->proc)(STRING_DATA(str)); | |
148 | goto ok; | |
149 | } | |
150 | } | |
151 | sprintf(buf, "unknown request received: %s\n", STRING_DATA(str)); | |
152 | sms_log_error(buf); | |
45c91bf7 | 153 | code = send_int(SMS_UNKNOWN_PROC); |
de56407f | 154 | if (code) { |
155 | err(connection_errno(conn), "%s: sending UNKNOWN_PROC"); | |
156 | } | |
157 | ok: | |
158 | string_free(&str); | |
159 | } | |
160 | } | |
161 | ||
162 | int | |
163 | send_ok() | |
164 | { | |
165 | static int zero = 0; | |
166 | return((code = send_object(conn, (char *)&zero, INTEGER_T))); | |
167 | } | |
45c91bf7 | 168 | |
169 | ||
170 | initialize() | |
171 | { | |
172 | /* keep have_authorization around */ | |
173 | have_file = 0; | |
174 | have_instructions = 0; | |
175 | done = 0; | |
176 | if (STRING_DATA(instructions) != (char *)NULL) | |
177 | string_free(&instructions); | |
178 | } | |
179 | ||
180 | ||
181 | /* | |
182 | * quit request: | |
183 | * | |
184 | * syntax: | |
185 | * >>> quit | |
186 | * <<< (int)0 | |
187 | * any arguments are ignored | |
188 | * | |
189 | * function: | |
190 | * closes connection from SMS | |
191 | */ | |
192 | int | |
193 | quit(str) | |
194 | char *str; | |
195 | { | |
196 | #ifdef lint | |
197 | str = (char *)NULL; | |
198 | #endif /* lint */ | |
199 | (void) send_ok(); | |
200 | sever_connection(conn); | |
201 | sms_log_info("Closing connection."); | |
202 | exit(0); | |
203 | } | |
204 | ||
205 | ||
206 | /* | |
207 | * lose(msg) | |
208 | * | |
209 | * put <msg> to log as error, break connection, and exit | |
210 | */ | |
211 | ||
212 | lose(msg) | |
213 | char *msg; | |
214 | { | |
215 | sprintf(buf, "%s: %s", error_message(code), msg); | |
216 | sms_log_error(buf); | |
217 | if (conn) | |
218 | sever_connection(conn); | |
219 | exit(1); | |
220 | } | |
221 | ||
222 | /* | |
223 | * report_error(msg) | |
224 | * | |
225 | * send back (external) <code>; if error, punt big with <lose(msg)> | |
226 | */ | |
227 | ||
228 | report_error(msg) | |
229 | char *msg; | |
230 | { | |
231 | code = send_object(conn, (char *)&code, INTEGER_T); | |
232 | if (code) { | |
233 | code = connection_errno(conn); | |
234 | lose(msg); | |
235 | } | |
236 | } | |
237 | ||
238 | /* | |
239 | * reject_call(c) | |
240 | * | |
241 | * set (external) <code> to <c> and call <report_error> | |
242 | */ | |
243 | ||
244 | reject_call(c) | |
245 | int c; | |
246 | { | |
247 | code = c; | |
248 | report_error("call rejected"); | |
249 | } |