]> andersk Git - moira.git/blame - server/mr_scall.c
Fixes to build with `gcc' instead of `gcc -traditional' on suns. (Needed
[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>
03c05291 20#include <fcntl.h>
21#include <string.h>
98a7b0ee 22#include <netinet/in.h>
960b073b 23#include <arpa/inet.h>
a3cf6921 24#include <krb.h>
78849033 25#include <errno.h>
d548a4e7 26#include "mr_server.h"
03c05291 27#include "query.h"
a3cf6921 28extern char buf1[];
29extern int nclients;
30extern char *whoami;
8165c536 31extern int errno;
a3cf6921 32
33extern void clist_delete(), do_auth(), do_shutdown();
34void do_call();
03c05291 35extern int dbms_errno, mr_errcode;
78543660 36static int row_count;
37
38/* Put this in a variable so that we can patch it if necessary */
50e114e1 39int max_row_count = 4096;
a3cf6921 40
41/*
42 * Welcome to the (finite state) machine (highest level).
43 */
44void
45do_client(cp)
46 client *cp;
47{
57c08162 48 struct stat stbuf;
49
ed31e0d1 50 free_rtn_tuples(cp);
a3cf6921 51 if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
a36b5bd7 52 com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
f17535a4 53 nclients-1,
a36b5bd7 54 nclients!=2?"s":"",
55 newqueries,
56 oldqueries);
a3cf6921 57 clist_delete(cp);
57c08162 58 /* if we no longer have any clients, and we're supposed to
59 * go down, then go down now.
60 */
61 if ((dormant == AWAKE) && (nclients == 0) &&
d548a4e7 62 (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) {
57c08162 63 com_err(whoami, 0, "motd file exists, slumbertime");
64 dormant = SLEEPY;
65 }
a3cf6921 66 return;
67 }
68 switch (cp->action) {
69 case CL_ACCEPT:
70 case CL_SEND:
71 /* Start recieving next request */
d548a4e7 72 initialize_operation(cp->pending_op, mr_start_recv,
5dbd09a0 73 (char *)&cp->args, (int (*)())NULL);
a3cf6921 74 queue_operation(cp->con, CON_INPUT, cp->pending_op);
75 cp->action = CL_RECEIVE;
76 break;
77 case CL_RECEIVE:
78 /* Data is here. Process it & start it heading back */
79 do_call(cp); /* This may block for a while. */
d548a4e7 80 mr_destroy_reply(cp->args);
de24f12d 81 cp->args = NULL;
d548a4e7 82 initialize_operation(cp->pending_op, mr_start_send,
5dbd09a0 83 (char *)&cp->reply, (int (*)())NULL);
a3cf6921 84 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
85 cp->action = CL_SEND;
86 break;
87 }
88}
89
a3cf6921 90char *procnames[] = {
91 "noop",
92 "auth",
93 "shutdown",
78849033 94 "query",
630e8323 95 "access",
57c08162 96 "dcm",
97 "motd",
630e8323 98};
99
a3cf6921 100
101void
102do_call(cl)
103 client *cl;
104{
105 int pn;
d548a4e7 106 cl->reply.mr_argc = 0;
107 cl->reply.mr_status = 0;
108 cl->reply.mr_version_no = cl->args->mr_version_no;
109 if (((pn = cl->args->mr_procno) < 0) ||
110 (pn > MR_MAX_PROC)) {
a3cf6921 111 com_err(whoami, 0, "procno out of range");
d548a4e7 112 cl->reply.mr_status = MR_UNKNOWN_PROC;
a3cf6921 113 return;
114 }
630e8323 115 if (log_flags & LOG_ARGS)
d548a4e7 116 log_args(procnames[pn], cl->args->mr_version_no,
117 cl->args->mr_argc, cl->args->mr_argv);
630e8323 118 else if (log_flags & LOG_REQUESTS)
f17535a4 119 com_err(whoami, 0, "%s", procnames[pn]);
a3cf6921 120
57c08162 121 if ((dormant == ASLEEP || dormant == GROGGY) &&
d548a4e7 122 pn != MR_NOOP && pn != MR_MOTD) {
123 cl->reply.mr_status = MR_DOWN;
57c08162 124 if (log_flags & LOG_RES)
d548a4e7 125 com_err(whoami, MR_DOWN, "(query refused)");
57c08162 126 return;
127 }
128
4ce8321c 129 /* make sure this gets cleared before every operation */
03c05291 130 dbms_errno = 0;
4ce8321c 131
a3cf6921 132 switch(pn) {
d548a4e7 133 case MR_NOOP:
134 cl->reply.mr_status = 0;
a3cf6921 135 return;
3630192b 136
d548a4e7 137 case MR_AUTH:
a3cf6921 138 do_auth(cl);
139 return;
78849033 140
d548a4e7 141 case MR_QUERY:
a3cf6921 142 do_retr(cl);
143 return;
a3cf6921 144
d548a4e7 145 case MR_ACCESS:
3630192b 146 do_access(cl);
147 return;
148
d548a4e7 149 case MR_SHUTDOWN:
a3cf6921 150 do_shutdown(cl);
151 return;
8165c536 152
d548a4e7 153 case MR_DO_UPDATE:
a36b5bd7 154 trigger_dcm(0, 0, cl);
8165c536 155 return;
57c08162 156
d548a4e7 157 case MR_MOTD:
57c08162 158 get_motd(cl);
159 return;
a3cf6921 160 }
161}
162
ed31e0d1 163free_rtn_tuples(cp)
164 client *cp;
165{
166 register returned_tuples *temp;
167 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
168 register returned_tuples *t1=temp;
169 temp = t1->next;
170 if (t1 == cp->last) cp->last = NULL;
28222705 171
d548a4e7 172 mr_destroy_reply(t1->retval);
ed31e0d1 173 delete_operation(t1->op);
174 free(t1);
175 }
176 cp->first = temp;
177}
178
78849033 179retr_callback(argc, argv, p_cp)
28222705 180 register int argc;
181 register char **argv;
78849033 182 char *p_cp;
183{
184 register client *cp = (client *)p_cp;
78543660 185 mr_params *arg_tmp;
186 returned_tuples *tp;
187 OPERATION op_tmp;
188 register char **nargv;
189 register int i;
190
191 if (row_count++ >= max_row_count) {
03c05291 192 dbms_errno = mr_errcode = MR_NO_MEM;
78543660 193 return;
194 }
195
78849033 196 /*
197 * This takes too much advantage of the fact that
198 * serialization of the data happens during the queue operation.
199 */
78543660 200 arg_tmp = (mr_params *)db_alloc(sizeof(mr_params));
201 tp = (returned_tuples *)db_alloc(sizeof(returned_tuples));
202 nargv = (char **)malloc(argc * sizeof(char *));
ed31e0d1 203
78543660 204 op_tmp = create_operation();
78849033 205
d548a4e7 206 if (mr_trim_args(argc, argv) == MR_NO_MEM) {
207 com_err(whoami, MR_NO_MEM, "while trimming args");
a36b5bd7 208 }
630e8323 209 if (log_flags & LOG_RESP)
d548a4e7 210 log_args("return: ", cp->args->mr_version_no, argc, argv);
630e8323 211
ed31e0d1 212 tp->op = op_tmp;
213 tp->retval = arg_tmp;
214 tp->next = NULL;
78849033 215
d548a4e7 216 arg_tmp->mr_status = MR_MORE_DATA;
217 arg_tmp->mr_version_no = cp->args->mr_version_no;
218 arg_tmp->mr_argc = argc;
219 arg_tmp->mr_argv = nargv;
28222705 220 for (i = 0; i < argc; i++) {
221 register int len = strlen(argv[i]) + 1;
222 nargv[i] = malloc(len);
03c05291 223 memcpy(nargv[i], argv[i], len);
28222705 224 }
d548a4e7 225 arg_tmp->mr_flattened = (char *)NULL;
226 arg_tmp->mr_argl = (int *)NULL;
ed31e0d1 227
228 if (cp->last) {
229 cp->last->next = tp;
230 cp->last = tp;
231 } else {
232 cp->last = cp->first = tp;
233 }
234
78849033 235 reset_operation(op_tmp);
d548a4e7 236 initialize_operation(op_tmp, mr_start_send, (char *)arg_tmp,
78849033 237 (int (*)())NULL);
238 queue_operation(cp->con, CON_OUTPUT, op_tmp);
239}
240
de24f12d 241list_users(callbk, callarg)
242 int (*callbk)();
243 char *callarg;
244{
245 char *argv[6];
246 char buf[30];
247 char buf1[30];
248 int i;
249 extern client **clients;
de24f12d 250 char *cp;
de24f12d 251 char *ctime();
252
253 for (i = 0; i < nclients; i++) {
254 register client *cl = clients[i];
255 if (cl->clname)
256 argv[0] = cl->clname;
257 else argv[0] = "unauthenticated";
258
259 argv[1] = inet_ntoa(cl->haddr.sin_addr);
260 argv[2] = buf;
261 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
262 argv[3] = ctime(&cl->last_time_used);
03c05291 263 cp = strchr(argv[3], '\n');
de24f12d 264 if (cp) *cp = '\0';
265 argv[4] = buf1;
266 sprintf(buf1, "[#%d]", cl->id);
267 (*callbk)(5, argv, callarg);
268 }
269 return 0;
270}
78849033 271
a3cf6921 272do_retr(cl)
de24f12d 273 register client *cl;
a3cf6921 274{
de24f12d 275 register char *queryname;
276
d548a4e7 277 cl->reply.mr_argc = 0;
278 cl->reply.mr_status = 0;
78543660 279 row_count = 0;
630e8323 280
c473dda1 281 if (cl->args->mr_argc < 1) {
282 cl->reply.mr_status = MR_ARGS;
283 com_err(whoami, MR_ARGS, "got nameless query");
284 return;
285 }
d548a4e7 286 queryname = cl->args->mr_argv[0];
de24f12d 287
d548a4e7 288 if (cl->args->mr_version_no == MR_VERSION_2)
a36b5bd7 289 newqueries++;
290 else
291 oldqueries++;
292
de24f12d 293 if (strcmp(queryname, "_list_users") == 0)
d548a4e7 294 cl->reply.mr_status = list_users(retr_callback, (char *)cl);
de24f12d 295 else {
d548a4e7 296 cl->reply.mr_status =
297 mr_process_query(cl,
c473dda1 298 queryname,
d548a4e7 299 cl->args->mr_argc-1,
300 cl->args->mr_argv+1,
de24f12d 301 retr_callback,
302 (char *)cl);
303 }
78543660 304 if (row_count >= max_row_count) {
305 critical_alert("moirad", "attempted query %s with %d rows\n",
306 queryname, row_count);
307 }
308
630e8323 309 if (log_flags & LOG_RES)
310 com_err(whoami, 0, "Query complete.");
a3cf6921 311}
78849033 312
3630192b 313do_access(cl)
314 client *cl;
315{
c473dda1 316 if (cl->args->mr_argc < 1) {
317 cl->reply.mr_status = MR_ARGS;
318 com_err(whoami, MR_ARGS, "got nameless access");
319 return;
320 }
d548a4e7 321 cl->reply.mr_argc = 0;
630e8323 322
d548a4e7 323 cl->reply.mr_status =
324 mr_check_access(cl,
325 cl->args->mr_argv[0],
326 cl->args->mr_argc-1,
327 cl->args->mr_argv+1);
3630192b 328
329 com_err(whoami, 0, "Access check complete.");
330}
8165c536 331
a36b5bd7 332
333/* trigger_dcm is also used as a followup routine to the
334 * set_server_host_override query, hence the two dummy arguments.
335 */
336
8165c536 337struct query pseudo_query = {
338 "trigger_dcm",
339 "tdcm",
340};
341
a36b5bd7 342trigger_dcm(dummy0, dummy1, cl)
343 int dummy0, dummy1;
8165c536 344 client *cl;
345{
346 register int pid;
185f76ce 347 char prog[128];
348
d548a4e7 349 cl->reply.mr_argc = 0;
8165c536 350
d548a4e7 351 if (cl->reply.mr_status = check_query_access(&pseudo_query, 0, cl) )
352 return(cl->reply.mr_status);
8165c536 353
185f76ce 354 sprintf(prog, "%s/startdcm", BIN_DIR);
8165c536 355 pid = vfork();
356 switch (pid) {
357 case 0:
185f76ce 358 execl(prog, "startdcm", 0);
8165c536 359 exit(1);
360
361 case -1:
d548a4e7 362 cl->reply.mr_status = errno;
a36b5bd7 363 return(0);
8165c536 364
365 default:
a36b5bd7 366 return(0);
8165c536 367 }
368}
369
57c08162 370
371get_motd(cl)
372client *cl;
373{
9cad7c8f 374 int motd, len;
57c08162 375 char buffer[1024];
376 char *arg[1];
377
378 arg[0] = buffer;
d548a4e7 379 cl->reply.mr_status = 0;
380 motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
9cad7c8f 381 if (motd < 0) return;
382 len = read(motd, buffer, sizeof(buffer) - 1);
383 close(motd);
384 buffer[len] = 0;
78543660 385 row_count = 0;
57c08162 386 retr_callback(1, arg, cl);
d548a4e7 387 cl->reply.mr_status = 0;
57c08162 388}
This page took 0.171446 seconds and 5 git commands to generate.