]> andersk Git - moira.git/blame - server/mr_scall.c
use read(), not streams to read motd file
[moira.git] / server / mr_scall.c
CommitLineData
a3cf6921 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
a3cf6921 9 *
a3cf6921 10 */
11
12#ifndef lint
13static char *rcsid_sms_scall_c = "$Header$";
14#endif lint
15
c801de4c 16#include <mit-copyright.h>
57c08162 17#include <sys/types.h>
18#include <sys/stat.h>
9cad7c8f 19#include <sys/file.h>
a3cf6921 20#include <krb.h>
78849033 21#include <errno.h>
8165c536 22#include "query.h"
a3cf6921 23#include "sms_server.h"
24extern char buf1[];
25extern int nclients;
26extern char *whoami;
28222705 27extern char *malloc();
8165c536 28extern int errno;
a3cf6921 29
30extern void clist_delete(), do_auth(), do_shutdown();
31void do_call();
32
33/*
34 * Welcome to the (finite state) machine (highest level).
35 */
36void
37do_client(cp)
38 client *cp;
39{
57c08162 40 struct stat stbuf;
41
ed31e0d1 42 free_rtn_tuples(cp);
a3cf6921 43 if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
a36b5bd7 44 com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
f17535a4 45 nclients-1,
a36b5bd7 46 nclients!=2?"s":"",
47 newqueries,
48 oldqueries);
a3cf6921 49 clist_delete(cp);
57c08162 50 /* if we no longer have any clients, and we're supposed to
51 * go down, then go down now.
52 */
53 if ((dormant == AWAKE) && (nclients == 0) &&
54 (stat(SMS_MOTD_FILE, &stbuf) == 0)) {
55 com_err(whoami, 0, "motd file exists, slumbertime");
56 dormant = SLEEPY;
57 }
a3cf6921 58 return;
59 }
60 switch (cp->action) {
61 case CL_ACCEPT:
62 case CL_SEND:
63 /* Start recieving next request */
64 initialize_operation(cp->pending_op, sms_start_recv,
5dbd09a0 65 (char *)&cp->args, (int (*)())NULL);
a3cf6921 66 queue_operation(cp->con, CON_INPUT, cp->pending_op);
67 cp->action = CL_RECEIVE;
68 break;
69 case CL_RECEIVE:
70 /* Data is here. Process it & start it heading back */
71 do_call(cp); /* This may block for a while. */
de24f12d 72 sms_destroy_reply(cp->args);
73 cp->args = NULL;
a3cf6921 74 initialize_operation(cp->pending_op, sms_start_send,
5dbd09a0 75 (char *)&cp->reply, (int (*)())NULL);
a3cf6921 76 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
77 cp->action = CL_SEND;
78 break;
79 }
80}
81
a3cf6921 82char *procnames[] = {
83 "noop",
84 "auth",
85 "shutdown",
78849033 86 "query",
630e8323 87 "access",
57c08162 88 "dcm",
89 "motd",
630e8323 90};
91
a3cf6921 92
93void
94do_call(cl)
95 client *cl;
96{
97 int pn;
98 cl->reply.sms_argc = 0;
99 cl->reply.sms_status = 0;
a36b5bd7 100 cl->reply.sms_version_no = cl->args->sms_version_no;
a3cf6921 101 if (((pn = cl->args->sms_procno) < 0) ||
102 (pn > SMS_MAX_PROC)) {
103 com_err(whoami, 0, "procno out of range");
104 cl->reply.sms_status = SMS_UNKNOWN_PROC;
105 return;
106 }
630e8323 107 if (log_flags & LOG_ARGS)
a36b5bd7 108 log_args(procnames[pn], cl->args->sms_version_no,
109 cl->args->sms_argc, cl->args->sms_argv);
630e8323 110 else if (log_flags & LOG_REQUESTS)
f17535a4 111 com_err(whoami, 0, "%s", procnames[pn]);
a3cf6921 112
57c08162 113 if ((dormant == ASLEEP || dormant == GROGGY) &&
114 pn != SMS_NOOP && pn != SMS_MOTD) {
115 cl->reply.sms_status = SMS_DOWN;
116 if (log_flags & LOG_RES)
117 com_err(whoami, SMS_DOWN, "(query refused)");
118 return;
119 }
120
a3cf6921 121 switch(pn) {
122 case SMS_NOOP:
123 cl->reply.sms_status = 0;
a3cf6921 124 return;
3630192b 125
a3cf6921 126 case SMS_AUTH:
127 do_auth(cl);
128 return;
78849033 129
130 case SMS_QUERY:
a3cf6921 131 do_retr(cl);
132 return;
a3cf6921 133
3630192b 134 case SMS_ACCESS:
135 do_access(cl);
136 return;
137
a3cf6921 138 case SMS_SHUTDOWN:
139 do_shutdown(cl);
140 return;
8165c536 141
142 case SMS_DO_UPDATE:
a36b5bd7 143 trigger_dcm(0, 0, cl);
8165c536 144 return;
57c08162 145
146 case SMS_MOTD:
147 get_motd(cl);
148 return;
a3cf6921 149 }
150}
151
ed31e0d1 152free_rtn_tuples(cp)
153 client *cp;
154{
155 register returned_tuples *temp;
156 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
157 register returned_tuples *t1=temp;
158 temp = t1->next;
159 if (t1 == cp->last) cp->last = NULL;
28222705 160
ed31e0d1 161 sms_destroy_reply(t1->retval);
ed31e0d1 162 delete_operation(t1->op);
163 free(t1);
164 }
165 cp->first = temp;
166}
167
78849033 168retr_callback(argc, argv, p_cp)
28222705 169 register int argc;
170 register char **argv;
78849033 171 char *p_cp;
172{
173 register client *cp = (client *)p_cp;
78849033 174 /*
175 * This takes too much advantage of the fact that
176 * serialization of the data happens during the queue operation.
177 */
178 sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
ed31e0d1 179 returned_tuples *tp = (returned_tuples *)
180 db_alloc(sizeof(returned_tuples));
28222705 181 register char **nargv = (char **)malloc(argc * sizeof(char *));
182 register int i;
ed31e0d1 183
78849033 184 OPERATION op_tmp = create_operation();
78849033 185
a36b5bd7 186 if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
187 com_err(whoami, SMS_NO_MEM, "while trimming args");
188 }
630e8323 189 if (log_flags & LOG_RESP)
a36b5bd7 190 log_args("return: ", cp->args->sms_version_no, argc, argv);
630e8323 191
ed31e0d1 192 tp->op = op_tmp;
193 tp->retval = arg_tmp;
194 tp->next = NULL;
78849033 195
196 arg_tmp->sms_status = SMS_MORE_DATA;
a36b5bd7 197 arg_tmp->sms_version_no = cp->args->sms_version_no;
78849033 198 arg_tmp->sms_argc = argc;
28222705 199 arg_tmp->sms_argv = nargv;
200 for (i = 0; i < argc; i++) {
201 register int len = strlen(argv[i]) + 1;
202 nargv[i] = malloc(len);
203 bcopy(argv[i], nargv[i], len);
204 }
78849033 205 arg_tmp->sms_flattened = (char *)NULL;
206 arg_tmp->sms_argl = (int *)NULL;
ed31e0d1 207
208 if (cp->last) {
209 cp->last->next = tp;
210 cp->last = tp;
211 } else {
212 cp->last = cp->first = tp;
213 }
214
78849033 215 reset_operation(op_tmp);
216 initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
217 (int (*)())NULL);
218 queue_operation(cp->con, CON_OUTPUT, op_tmp);
219}
220
de24f12d 221list_users(callbk, callarg)
222 int (*callbk)();
223 char *callarg;
224{
225 char *argv[6];
226 char buf[30];
227 char buf1[30];
228 int i;
229 extern client **clients;
230 extern char *inet_ntoa();
231 char *cp;
232 char *index();
233 char *ctime();
234
235 for (i = 0; i < nclients; i++) {
236 register client *cl = clients[i];
237 if (cl->clname)
238 argv[0] = cl->clname;
239 else argv[0] = "unauthenticated";
240
241 argv[1] = inet_ntoa(cl->haddr.sin_addr);
242 argv[2] = buf;
243 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
244 argv[3] = ctime(&cl->last_time_used);
245 cp = index(argv[3], '\n');
246 if (cp) *cp = '\0';
247 argv[4] = buf1;
248 sprintf(buf1, "[#%d]", cl->id);
249 (*callbk)(5, argv, callarg);
250 }
251 return 0;
252}
78849033 253
a3cf6921 254do_retr(cl)
de24f12d 255 register client *cl;
a3cf6921 256{
de24f12d 257 register char *queryname;
258
78849033 259 cl->reply.sms_argc = 0;
260 cl->reply.sms_status = 0;
630e8323 261
de24f12d 262 queryname = cl->args->sms_argv[0];
263
a36b5bd7 264 if (cl->args->sms_version_no == SMS_VERSION_2)
265 newqueries++;
266 else
267 oldqueries++;
268
de24f12d 269 if (strcmp(queryname, "_list_users") == 0)
270 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
271 else {
272 cl->reply.sms_status =
273 sms_process_query(cl,
274 cl->args->sms_argv[0],
275 cl->args->sms_argc-1,
276 cl->args->sms_argv+1,
277 retr_callback,
278 (char *)cl);
279 }
630e8323 280 if (log_flags & LOG_RES)
281 com_err(whoami, 0, "Query complete.");
a3cf6921 282}
78849033 283
3630192b 284do_access(cl)
285 client *cl;
286{
287 cl->reply.sms_argc = 0;
630e8323 288
3630192b 289 cl->reply.sms_status =
290 sms_check_access(cl,
291 cl->args->sms_argv[0],
292 cl->args->sms_argc-1,
293 cl->args->sms_argv+1);
294
295 com_err(whoami, 0, "Access check complete.");
296}
8165c536 297
a36b5bd7 298
299/* trigger_dcm is also used as a followup routine to the
300 * set_server_host_override query, hence the two dummy arguments.
301 */
302
8165c536 303struct query pseudo_query = {
304 "trigger_dcm",
305 "tdcm",
306};
307
a36b5bd7 308trigger_dcm(dummy0, dummy1, cl)
309 int dummy0, dummy1;
8165c536 310 client *cl;
311{
312 register int pid;
313
314 cl->reply.sms_argc = 0;
315
316 if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
a36b5bd7 317 return(cl->reply.sms_status);
8165c536 318
319 pid = vfork();
320 switch (pid) {
321 case 0:
9ddf3daa 322 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
323 close(dummy0);
a36b5bd7 324 execl("/u1/sms/bin/startdcm", "startdcm", 0);
8165c536 325 exit(1);
326
327 case -1:
328 cl->reply.sms_status = errno;
a36b5bd7 329 return(0);
8165c536 330
331 default:
a36b5bd7 332 return(0);
8165c536 333 }
334}
335
57c08162 336
337get_motd(cl)
338client *cl;
339{
9cad7c8f 340 int motd, len;
57c08162 341 char buffer[1024];
342 char *arg[1];
343
344 arg[0] = buffer;
345 cl->reply.sms_status = 0;
9cad7c8f 346 motd = open(SMS_MOTD_FILE, 0, O_RDONLY);
347 if (motd < 0) return;
348 len = read(motd, buffer, sizeof(buffer) - 1);
349 close(motd);
350 buffer[len] = 0;
57c08162 351 retr_callback(1, arg, cl);
352 cl->reply.sms_status = 0;
353}
This page took 0.114073 seconds and 5 git commands to generate.