]>
Commit | Line | Data |
---|---|---|
7ac48069 | 1 | /* $Id$ |
2 | * | |
3 | * Copyright 1988-1998 by the Massachusetts Institute of Technology. | |
4 | * For copying and distribution information, please see the file | |
5 | * <mit-copyright.h>. | |
de56407f | 6 | */ |
de56407f | 7 | |
546bc43b | 8 | #include <mit-copyright.h> |
7ac48069 | 9 | #include <moira.h> |
10 | #include "update_server.h" | |
11 | ||
12 | #include <sys/stat.h> | |
13 | ||
14 | #include <pwd.h> | |
de56407f | 15 | #include <stdio.h> |
7da203a3 | 16 | #include <stdlib.h> |
698271c7 | 17 | #include <string.h> |
7ac48069 | 18 | #include <unistd.h> |
de56407f | 19 | |
7ac48069 | 20 | #include <des.h> |
21 | #include <gdb.h> | |
22 | #include "update.h" | |
de56407f | 23 | |
7ac48069 | 24 | RCSID("$Header$"); |
de56407f | 25 | |
7da203a3 | 26 | extern int errno; |
de56407f | 27 | |
28 | CONNECTION conn; | |
7da203a3 | 29 | int code, log_priority; |
de56407f | 30 | char *whoami; |
31 | ||
45c91bf7 | 32 | int have_authorization = 0; |
5df6ee25 | 33 | C_Block session; |
45c91bf7 | 34 | int have_file = 0; |
45c91bf7 | 35 | int done = 0; |
529a5b0d | 36 | int uid = 0; |
45c91bf7 | 37 | |
de56407f | 38 | #define send_int(n) \ |
5eaef520 | 39 | (_send_int = (n), send_object(conn, (char *)&_send_int, INTEGER_T)) |
de56407f | 40 | int _send_int; |
41 | ||
42 | struct _dt { | |
5eaef520 | 43 | char *str; |
7ac48069 | 44 | int (*proc)(char *); |
de56407f | 45 | } dispatch_table[] = { |
5eaef520 | 46 | { "AUTH_002", auth_002 }, |
47 | { "XFER_002", xfer_002 }, | |
48 | { "XFER_003", xfer_003 }, | |
49 | { "EXEC_002", exec_002 }, | |
50 | { "quit", quit }, | |
7ac48069 | 51 | { NULL, (int (*)(char *))abort } |
de56407f | 52 | }; |
53 | ||
529a5b0d | 54 | /* general scratch space -- useful for building error messages et al... */ |
de56407f | 55 | char buf[BUFSIZ]; |
529a5b0d | 56 | |
5eaef520 | 57 | int main(int argc, char **argv) |
de56407f | 58 | { |
5eaef520 | 59 | STRING str; |
60 | struct _dt *d; | |
61 | char *p; | |
5eaef520 | 62 | |
63 | whoami = strrchr(argv[0], '/'); | |
64 | if (whoami) | |
65 | whoami++; | |
66 | else | |
67 | whoami = argv[0]; | |
68 | ||
69 | /* interpret arguments here */ | |
70 | if (argc != 1) | |
71 | { | |
72 | fprintf(stderr, "Usage: %s\n", whoami); | |
73 | exit(1); | |
74 | } | |
75 | ||
76 | if (!config_lookup("nofork")) | |
77 | { | |
78 | if (fork()) | |
79 | exit(0); | |
80 | setsid(); | |
81 | } | |
82 | else | |
83 | gdb_debug(GDB_NOFORK); | |
84 | ||
85 | umask(0022); | |
86 | initialize_sms_error_table(); | |
87 | initialize_krb_error_table(); | |
88 | mr_update_initialize(); | |
89 | ||
90 | /* wait for connection */ | |
91 | gdb_init(); | |
92 | /* If the config file contains a line "port portname", the daemon | |
59ec8dae | 93 | * will listen on the named port rather than SERVICE_NAME "moira_update" |
5eaef520 | 94 | */ |
95 | if (!(p = config_lookup("port"))) | |
96 | p = SERVICE_NAME; | |
97 | conn = create_forking_server(p, 0); | |
98 | ||
99 | /* If the config file contains a line "user username", the | |
100 | * daemon will run with that user's UID. | |
101 | */ | |
102 | if ((p = config_lookup("user"))) | |
103 | { | |
104 | struct passwd *pw; | |
105 | pw = getpwnam(p); | |
106 | if (!pw) | |
107 | { | |
108 | com_err(whoami, errno, "Unable to find user %s\n", p); | |
de56407f | 109 | exit(1); |
5eaef520 | 110 | } |
111 | uid = pw->pw_uid; | |
112 | } | |
de56407f | 113 | |
5eaef520 | 114 | /* If the config file contains a line "chroot /dir/name", the |
115 | * daemon will run chrooted to that directory. | |
116 | */ | |
117 | if ((p = config_lookup("chroot"))) | |
118 | { | |
119 | if (chroot(p) < 0) | |
120 | { | |
121 | com_err(whoami, errno, "unable to chroot to %s", p); | |
122 | exit(1); | |
123 | } | |
124 | } | |
45c91bf7 | 125 | |
5eaef520 | 126 | if (!conn) |
127 | { | |
128 | com_err(whoami, errno, "can't get connection"); | |
129 | exit(1); | |
130 | } | |
131 | if (connection_status(conn) == CON_STOPPED) | |
132 | { | |
133 | com_err(whoami, connection_errno(conn), ": can't get connection"); | |
134 | exit(1); | |
135 | } | |
136 | ||
137 | mr_log_info("got connection"); | |
138 | /* got a connection; loop forever */ | |
139 | while (1) | |
140 | { | |
44d12d58 | 141 | char *cp; |
5eaef520 | 142 | code = receive_object(conn, (char *)&str, STRING_T); |
143 | if (code) | |
144 | { | |
145 | com_err(whoami, connection_errno(conn), "receiving command"); | |
146 | sever_connection(conn); | |
147 | exit(1); | |
148 | } | |
149 | cp = strchr(STRING_DATA(str), ' '); | |
150 | if (cp) | |
151 | *cp = '\0'; | |
152 | for (d = dispatch_table; d->str; d++) | |
153 | { | |
154 | if (!strcmp(d->str, STRING_DATA(str))) | |
155 | { | |
156 | if (cp) | |
157 | *cp = ' '; | |
158 | (d->proc)(STRING_DATA(str)); | |
159 | goto ok; | |
160 | } | |
161 | } | |
162 | sprintf(buf, "unknown request received: %s\n", STRING_DATA(str)); | |
163 | mr_log_error(buf); | |
164 | code = send_int(MR_UNKNOWN_PROC); | |
165 | if (code) | |
166 | com_err(whoami, connection_errno(conn), "sending UNKNOWN_PROC"); | |
167 | ok: | |
168 | string_free(&str); | |
169 | } | |
de56407f | 170 | } |
171 | ||
5eaef520 | 172 | int send_ok(void) |
de56407f | 173 | { |
5eaef520 | 174 | static int zero = 0; |
175 | return code = send_object(conn, (char *)&zero, INTEGER_T); | |
de56407f | 176 | } |
45c91bf7 | 177 | |
178 | ||
7ac48069 | 179 | void initialize(void) |
45c91bf7 | 180 | { |
5eaef520 | 181 | /* keep have_authorization around */ |
182 | have_file = 0; | |
183 | done = 0; | |
45c91bf7 | 184 | } |
185 | ||
186 | ||
187 | /* | |
188 | * quit request: | |
189 | * | |
190 | * syntax: | |
191 | * >>> quit | |
192 | * <<< (int)0 | |
193 | * any arguments are ignored | |
194 | * | |
195 | * function: | |
2ad0a777 | 196 | * closes connection from MR |
45c91bf7 | 197 | */ |
5eaef520 | 198 | int quit(char *str) |
45c91bf7 | 199 | { |
5eaef520 | 200 | send_ok(); |
201 | sever_connection(conn); | |
202 | mr_log_info("Closing connection."); | |
203 | exit(0); | |
45c91bf7 | 204 | } |
205 | ||
206 | ||
207 | /* | |
208 | * lose(msg) | |
209 | * | |
210 | * put <msg> to log as error, break connection, and exit | |
211 | */ | |
212 | ||
7ac48069 | 213 | void lose(char *msg) |
45c91bf7 | 214 | { |
5eaef520 | 215 | com_err(whoami, code, msg); |
216 | if (conn) | |
217 | sever_connection(conn); | |
218 | exit(1); | |
45c91bf7 | 219 | } |
220 | ||
221 | /* | |
222 | * report_error(msg) | |
223 | * | |
224 | * send back (external) <code>; if error, punt big with <lose(msg)> | |
225 | */ | |
226 | ||
7ac48069 | 227 | void report_error(char *msg) |
45c91bf7 | 228 | { |
5eaef520 | 229 | code = send_object(conn, (char *)&code, INTEGER_T); |
230 | if (code) | |
231 | { | |
232 | code = connection_errno(conn); | |
233 | lose(msg); | |
45c91bf7 | 234 | } |
235 | } | |
236 | ||
237 | /* | |
238 | * reject_call(c) | |
239 | * | |
240 | * set (external) <code> to <c> and call <report_error> | |
241 | */ | |
242 | ||
7ac48069 | 243 | void reject_call(int c) |
45c91bf7 | 244 | { |
5eaef520 | 245 | code = c; |
246 | report_error("call rejected"); | |
45c91bf7 | 247 | } |