]> andersk Git - moira.git/blame - server/mr_scall.c
changed user relation; add FS type MUL
[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;
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) &&
d548a4e7 54 (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) {
57c08162 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 */
d548a4e7 64 initialize_operation(cp->pending_op, mr_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. */
d548a4e7 72 mr_destroy_reply(cp->args);
de24f12d 73 cp->args = NULL;
d548a4e7 74 initialize_operation(cp->pending_op, mr_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;
4ce8321c 98 extern int ingres_errno;
d548a4e7 99 cl->reply.mr_argc = 0;
100 cl->reply.mr_status = 0;
101 cl->reply.mr_version_no = cl->args->mr_version_no;
102 if (((pn = cl->args->mr_procno) < 0) ||
103 (pn > MR_MAX_PROC)) {
a3cf6921 104 com_err(whoami, 0, "procno out of range");
d548a4e7 105 cl->reply.mr_status = MR_UNKNOWN_PROC;
a3cf6921 106 return;
107 }
630e8323 108 if (log_flags & LOG_ARGS)
d548a4e7 109 log_args(procnames[pn], cl->args->mr_version_no,
110 cl->args->mr_argc, cl->args->mr_argv);
630e8323 111 else if (log_flags & LOG_REQUESTS)
f17535a4 112 com_err(whoami, 0, "%s", procnames[pn]);
a3cf6921 113
57c08162 114 if ((dormant == ASLEEP || dormant == GROGGY) &&
d548a4e7 115 pn != MR_NOOP && pn != MR_MOTD) {
116 cl->reply.mr_status = MR_DOWN;
57c08162 117 if (log_flags & LOG_RES)
d548a4e7 118 com_err(whoami, MR_DOWN, "(query refused)");
57c08162 119 return;
120 }
121
4ce8321c 122 /* make sure this gets cleared before every operation */
123 ingres_errno = 0;
124
a3cf6921 125 switch(pn) {
d548a4e7 126 case MR_NOOP:
127 cl->reply.mr_status = 0;
a3cf6921 128 return;
3630192b 129
d548a4e7 130 case MR_AUTH:
a3cf6921 131 do_auth(cl);
132 return;
78849033 133
d548a4e7 134 case MR_QUERY:
a3cf6921 135 do_retr(cl);
136 return;
a3cf6921 137
d548a4e7 138 case MR_ACCESS:
3630192b 139 do_access(cl);
140 return;
141
d548a4e7 142 case MR_SHUTDOWN:
a3cf6921 143 do_shutdown(cl);
144 return;
8165c536 145
d548a4e7 146 case MR_DO_UPDATE:
a36b5bd7 147 trigger_dcm(0, 0, cl);
8165c536 148 return;
57c08162 149
d548a4e7 150 case MR_MOTD:
57c08162 151 get_motd(cl);
152 return;
a3cf6921 153 }
154}
155
ed31e0d1 156free_rtn_tuples(cp)
157 client *cp;
158{
159 register returned_tuples *temp;
160 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
161 register returned_tuples *t1=temp;
162 temp = t1->next;
163 if (t1 == cp->last) cp->last = NULL;
28222705 164
d548a4e7 165 mr_destroy_reply(t1->retval);
ed31e0d1 166 delete_operation(t1->op);
167 free(t1);
168 }
169 cp->first = temp;
170}
171
78849033 172retr_callback(argc, argv, p_cp)
28222705 173 register int argc;
174 register char **argv;
78849033 175 char *p_cp;
176{
177 register client *cp = (client *)p_cp;
78849033 178 /*
179 * This takes too much advantage of the fact that
180 * serialization of the data happens during the queue operation.
181 */
d548a4e7 182 mr_params *arg_tmp = (mr_params *)db_alloc(sizeof(mr_params));
ed31e0d1 183 returned_tuples *tp = (returned_tuples *)
184 db_alloc(sizeof(returned_tuples));
28222705 185 register char **nargv = (char **)malloc(argc * sizeof(char *));
186 register int i;
ed31e0d1 187
78849033 188 OPERATION op_tmp = create_operation();
78849033 189
d548a4e7 190 if (mr_trim_args(argc, argv) == MR_NO_MEM) {
191 com_err(whoami, MR_NO_MEM, "while trimming args");
a36b5bd7 192 }
630e8323 193 if (log_flags & LOG_RESP)
d548a4e7 194 log_args("return: ", cp->args->mr_version_no, argc, argv);
630e8323 195
ed31e0d1 196 tp->op = op_tmp;
197 tp->retval = arg_tmp;
198 tp->next = NULL;
78849033 199
d548a4e7 200 arg_tmp->mr_status = MR_MORE_DATA;
201 arg_tmp->mr_version_no = cp->args->mr_version_no;
202 arg_tmp->mr_argc = argc;
203 arg_tmp->mr_argv = nargv;
28222705 204 for (i = 0; i < argc; i++) {
205 register int len = strlen(argv[i]) + 1;
206 nargv[i] = malloc(len);
207 bcopy(argv[i], nargv[i], len);
208 }
d548a4e7 209 arg_tmp->mr_flattened = (char *)NULL;
210 arg_tmp->mr_argl = (int *)NULL;
ed31e0d1 211
212 if (cp->last) {
213 cp->last->next = tp;
214 cp->last = tp;
215 } else {
216 cp->last = cp->first = tp;
217 }
218
78849033 219 reset_operation(op_tmp);
d548a4e7 220 initialize_operation(op_tmp, mr_start_send, (char *)arg_tmp,
78849033 221 (int (*)())NULL);
222 queue_operation(cp->con, CON_OUTPUT, op_tmp);
223}
224
de24f12d 225list_users(callbk, callarg)
226 int (*callbk)();
227 char *callarg;
228{
229 char *argv[6];
230 char buf[30];
231 char buf1[30];
232 int i;
233 extern client **clients;
234 extern char *inet_ntoa();
235 char *cp;
236 char *index();
237 char *ctime();
238
239 for (i = 0; i < nclients; i++) {
240 register client *cl = clients[i];
241 if (cl->clname)
242 argv[0] = cl->clname;
243 else argv[0] = "unauthenticated";
244
245 argv[1] = inet_ntoa(cl->haddr.sin_addr);
246 argv[2] = buf;
247 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
248 argv[3] = ctime(&cl->last_time_used);
249 cp = index(argv[3], '\n');
250 if (cp) *cp = '\0';
251 argv[4] = buf1;
252 sprintf(buf1, "[#%d]", cl->id);
253 (*callbk)(5, argv, callarg);
254 }
255 return 0;
256}
78849033 257
a3cf6921 258do_retr(cl)
de24f12d 259 register client *cl;
a3cf6921 260{
de24f12d 261 register char *queryname;
262
d548a4e7 263 cl->reply.mr_argc = 0;
264 cl->reply.mr_status = 0;
630e8323 265
d548a4e7 266 queryname = cl->args->mr_argv[0];
de24f12d 267
d548a4e7 268 if (cl->args->mr_version_no == MR_VERSION_2)
a36b5bd7 269 newqueries++;
270 else
271 oldqueries++;
272
de24f12d 273 if (strcmp(queryname, "_list_users") == 0)
d548a4e7 274 cl->reply.mr_status = list_users(retr_callback, (char *)cl);
de24f12d 275 else {
d548a4e7 276 cl->reply.mr_status =
277 mr_process_query(cl,
278 cl->args->mr_argv[0],
279 cl->args->mr_argc-1,
280 cl->args->mr_argv+1,
de24f12d 281 retr_callback,
282 (char *)cl);
283 }
630e8323 284 if (log_flags & LOG_RES)
285 com_err(whoami, 0, "Query complete.");
a3cf6921 286}
78849033 287
3630192b 288do_access(cl)
289 client *cl;
290{
d548a4e7 291 cl->reply.mr_argc = 0;
630e8323 292
d548a4e7 293 cl->reply.mr_status =
294 mr_check_access(cl,
295 cl->args->mr_argv[0],
296 cl->args->mr_argc-1,
297 cl->args->mr_argv+1);
3630192b 298
299 com_err(whoami, 0, "Access check complete.");
300}
8165c536 301
a36b5bd7 302
303/* trigger_dcm is also used as a followup routine to the
304 * set_server_host_override query, hence the two dummy arguments.
305 */
306
8165c536 307struct query pseudo_query = {
308 "trigger_dcm",
309 "tdcm",
310};
311
a36b5bd7 312trigger_dcm(dummy0, dummy1, cl)
313 int dummy0, dummy1;
8165c536 314 client *cl;
315{
316 register int pid;
185f76ce 317 char prog[128];
318
d548a4e7 319 cl->reply.mr_argc = 0;
8165c536 320
d548a4e7 321 if (cl->reply.mr_status = check_query_access(&pseudo_query, 0, cl) )
322 return(cl->reply.mr_status);
8165c536 323
185f76ce 324 sprintf(prog, "%s/startdcm", BIN_DIR);
8165c536 325 pid = vfork();
326 switch (pid) {
327 case 0:
9ddf3daa 328 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
329 close(dummy0);
185f76ce 330 execl(prog, "startdcm", 0);
8165c536 331 exit(1);
332
333 case -1:
d548a4e7 334 cl->reply.mr_status = errno;
a36b5bd7 335 return(0);
8165c536 336
337 default:
a36b5bd7 338 return(0);
8165c536 339 }
340}
341
57c08162 342
343get_motd(cl)
344client *cl;
345{
9cad7c8f 346 int motd, len;
57c08162 347 char buffer[1024];
348 char *arg[1];
349
350 arg[0] = buffer;
d548a4e7 351 cl->reply.mr_status = 0;
352 motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
9cad7c8f 353 if (motd < 0) return;
354 len = read(motd, buffer, sizeof(buffer) - 1);
355 close(motd);
356 buffer[len] = 0;
57c08162 357 retr_callback(1, arg, cl);
d548a4e7 358 cl->reply.mr_status = 0;
57c08162 359}
This page took 0.145321 seconds and 5 git commands to generate.