6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 * For copying and distribution information, please see the file
13 static char *rcsid_sms_scall_c = "$Header$";
16 #include <mit-copyright.h>
17 #include <sys/types.h>
23 #include "sms_server.h"
27 extern char *malloc();
30 extern void clist_delete(), do_auth(), do_shutdown();
34 * Welcome to the (finite state) machine (highest level).
43 if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
44 com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
50 /* if we no longer have any clients, and we're supposed to
51 * go down, then go down now.
53 if ((dormant == AWAKE) && (nclients == 0) &&
54 (stat(SMS_MOTD_FILE, &stbuf) == 0)) {
55 com_err(whoami, 0, "motd file exists, slumbertime");
63 /* Start recieving next request */
64 initialize_operation(cp->pending_op, sms_start_recv,
65 (char *)&cp->args, (int (*)())NULL);
66 queue_operation(cp->con, CON_INPUT, cp->pending_op);
67 cp->action = CL_RECEIVE;
70 /* Data is here. Process it & start it heading back */
71 do_call(cp); /* This may block for a while. */
72 sms_destroy_reply(cp->args);
74 initialize_operation(cp->pending_op, sms_start_send,
75 (char *)&cp->reply, (int (*)())NULL);
76 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
98 cl->reply.sms_argc = 0;
99 cl->reply.sms_status = 0;
100 cl->reply.sms_version_no = cl->args->sms_version_no;
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;
107 if (log_flags & LOG_ARGS)
108 log_args(procnames[pn], cl->args->sms_version_no,
109 cl->args->sms_argc, cl->args->sms_argv);
110 else if (log_flags & LOG_REQUESTS)
111 com_err(whoami, 0, "%s", procnames[pn]);
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)");
123 cl->reply.sms_status = 0;
143 trigger_dcm(0, 0, cl);
155 register returned_tuples *temp;
156 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
157 register returned_tuples *t1=temp;
159 if (t1 == cp->last) cp->last = NULL;
161 sms_destroy_reply(t1->retval);
162 delete_operation(t1->op);
168 retr_callback(argc, argv, p_cp)
170 register char **argv;
173 register client *cp = (client *)p_cp;
175 * This takes too much advantage of the fact that
176 * serialization of the data happens during the queue operation.
178 sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
179 returned_tuples *tp = (returned_tuples *)
180 db_alloc(sizeof(returned_tuples));
181 register char **nargv = (char **)malloc(argc * sizeof(char *));
184 OPERATION op_tmp = create_operation();
186 if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
187 com_err(whoami, SMS_NO_MEM, "while trimming args");
189 if (log_flags & LOG_RESP)
190 log_args("return: ", cp->args->sms_version_no, argc, argv);
193 tp->retval = arg_tmp;
196 arg_tmp->sms_status = SMS_MORE_DATA;
197 arg_tmp->sms_version_no = cp->args->sms_version_no;
198 arg_tmp->sms_argc = argc;
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);
205 arg_tmp->sms_flattened = (char *)NULL;
206 arg_tmp->sms_argl = (int *)NULL;
212 cp->last = cp->first = tp;
215 reset_operation(op_tmp);
216 initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
218 queue_operation(cp->con, CON_OUTPUT, op_tmp);
221 list_users(callbk, callarg)
229 extern client **clients;
230 extern char *inet_ntoa();
235 for (i = 0; i < nclients; i++) {
236 register client *cl = clients[i];
238 argv[0] = cl->clname;
239 else argv[0] = "unauthenticated";
241 argv[1] = inet_ntoa(cl->haddr.sin_addr);
243 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
244 argv[3] = ctime(&cl->last_time_used);
245 cp = index(argv[3], '\n');
248 sprintf(buf1, "[#%d]", cl->id);
249 (*callbk)(5, argv, callarg);
257 register char *queryname;
259 cl->reply.sms_argc = 0;
260 cl->reply.sms_status = 0;
262 queryname = cl->args->sms_argv[0];
264 if (cl->args->sms_version_no == SMS_VERSION_2)
269 if (strcmp(queryname, "_list_users") == 0)
270 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
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,
280 if (log_flags & LOG_RES)
281 com_err(whoami, 0, "Query complete.");
287 cl->reply.sms_argc = 0;
289 cl->reply.sms_status =
291 cl->args->sms_argv[0],
292 cl->args->sms_argc-1,
293 cl->args->sms_argv+1);
295 com_err(whoami, 0, "Access check complete.");
299 /* trigger_dcm is also used as a followup routine to the
300 * set_server_host_override query, hence the two dummy arguments.
303 struct query pseudo_query = {
308 trigger_dcm(dummy0, dummy1, cl)
315 cl->reply.sms_argc = 0;
317 if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
318 return(cl->reply.sms_status);
320 sprintf(prog, "%s/startdcm", BIN_DIR);
324 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
326 execl(prog, "startdcm", 0);
330 cl->reply.sms_status = errno;
347 cl->reply.sms_status = 0;
348 motd = open(SMS_MOTD_FILE, 0, O_RDONLY);
349 if (motd < 0) return;
350 len = read(motd, buffer, sizeof(buffer) - 1);
353 retr_callback(1, arg, cl);
354 cl->reply.sms_status = 0;