]>
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" |
5df6ee25 | 28 | #include "des.h" |
de56407f | 29 | |
5df6ee25 | 30 | extern int auth_002(), 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; |
de56407f | 37 | |
38 | CONNECTION conn; | |
7da203a3 | 39 | int code, log_priority; |
de56407f | 40 | char *whoami; |
41 | ||
45c91bf7 | 42 | int have_authorization = 0; |
5df6ee25 | 43 | C_Block session; |
45c91bf7 | 44 | int have_file = 0; |
45c91bf7 | 45 | int done = 0; |
529a5b0d | 46 | int uid = 0; |
45c91bf7 | 47 | |
de56407f | 48 | #define send_int(n) \ |
5eaef520 | 49 | (_send_int = (n), send_object(conn, (char *)&_send_int, INTEGER_T)) |
de56407f | 50 | int _send_int; |
51 | ||
52 | struct _dt { | |
5eaef520 | 53 | char *str; |
54 | int (*proc)(); | |
de56407f | 55 | } dispatch_table[] = { |
5eaef520 | 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 } | |
de56407f | 62 | }; |
63 | ||
529a5b0d | 64 | /* general scratch space -- useful for building error messages et al... */ |
de56407f | 65 | char buf[BUFSIZ]; |
529a5b0d | 66 | |
5eaef520 | 67 | int main(int argc, char **argv) |
de56407f | 68 | { |
5eaef520 | 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 | |
59ec8dae | 104 | * will listen on the named port rather than SERVICE_NAME "moira_update" |
5eaef520 | 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); | |
de56407f | 120 | exit(1); |
5eaef520 | 121 | } |
122 | uid = pw->pw_uid; | |
123 | } | |
de56407f | 124 | |
5eaef520 | 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 | } | |
45c91bf7 | 136 | |
5eaef520 | 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 | { | |
44d12d58 | 152 | char *cp; |
5eaef520 | 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 | } | |
de56407f | 181 | } |
182 | ||
5eaef520 | 183 | int send_ok(void) |
de56407f | 184 | { |
5eaef520 | 185 | static int zero = 0; |
186 | return code = send_object(conn, (char *)&zero, INTEGER_T); | |
de56407f | 187 | } |
45c91bf7 | 188 | |
189 | ||
5eaef520 | 190 | initialize(void) |
45c91bf7 | 191 | { |
5eaef520 | 192 | /* keep have_authorization around */ |
193 | have_file = 0; | |
194 | done = 0; | |
45c91bf7 | 195 | } |
196 | ||
197 | ||
198 | /* | |
199 | * quit request: | |
200 | * | |
201 | * syntax: | |
202 | * >>> quit | |
203 | * <<< (int)0 | |
204 | * any arguments are ignored | |
205 | * | |
206 | * function: | |
2ad0a777 | 207 | * closes connection from MR |
45c91bf7 | 208 | */ |
5eaef520 | 209 | int quit(char *str) |
45c91bf7 | 210 | { |
5eaef520 | 211 | send_ok(); |
212 | sever_connection(conn); | |
213 | mr_log_info("Closing connection."); | |
214 | exit(0); | |
45c91bf7 | 215 | } |
216 | ||
217 | ||
218 | /* | |
219 | * lose(msg) | |
220 | * | |
221 | * put <msg> to log as error, break connection, and exit | |
222 | */ | |
223 | ||
5eaef520 | 224 | lose(char *msg) |
45c91bf7 | 225 | { |
5eaef520 | 226 | com_err(whoami, code, msg); |
227 | if (conn) | |
228 | sever_connection(conn); | |
229 | exit(1); | |
45c91bf7 | 230 | } |
231 | ||
232 | /* | |
233 | * report_error(msg) | |
234 | * | |
235 | * send back (external) <code>; if error, punt big with <lose(msg)> | |
236 | */ | |
237 | ||
5eaef520 | 238 | report_error(char *msg) |
45c91bf7 | 239 | { |
5eaef520 | 240 | code = send_object(conn, (char *)&code, INTEGER_T); |
241 | if (code) | |
242 | { | |
243 | code = connection_errno(conn); | |
244 | lose(msg); | |
45c91bf7 | 245 | } |
246 | } | |
247 | ||
248 | /* | |
249 | * reject_call(c) | |
250 | * | |
251 | * set (external) <code> to <c> and call <report_error> | |
252 | */ | |
253 | ||
5eaef520 | 254 | reject_call(int c) |
45c91bf7 | 255 | { |
5eaef520 | 256 | code = c; |
257 | report_error("call rejected"); | |
45c91bf7 | 258 | } |