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