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>
22 #include "sms_server.h"
26 extern char *malloc();
29 extern void clist_delete(), do_auth(), do_shutdown();
33 * Welcome to the (finite state) machine (highest level).
42 if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
43 com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
49 /* if we no longer have any clients, and we're supposed to
50 * go down, then go down now.
52 if ((dormant == AWAKE) && (nclients == 0) &&
53 (stat(SMS_MOTD_FILE, &stbuf) == 0)) {
54 com_err(whoami, 0, "motd file exists, slumbertime");
62 /* Start recieving next request */
63 initialize_operation(cp->pending_op, sms_start_recv,
64 (char *)&cp->args, (int (*)())NULL);
65 queue_operation(cp->con, CON_INPUT, cp->pending_op);
66 cp->action = CL_RECEIVE;
69 /* Data is here. Process it & start it heading back */
70 do_call(cp); /* This may block for a while. */
71 sms_destroy_reply(cp->args);
73 initialize_operation(cp->pending_op, sms_start_send,
74 (char *)&cp->reply, (int (*)())NULL);
75 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
97 cl->reply.sms_argc = 0;
98 cl->reply.sms_status = 0;
99 cl->reply.sms_version_no = cl->args->sms_version_no;
100 if (((pn = cl->args->sms_procno) < 0) ||
101 (pn > SMS_MAX_PROC)) {
102 com_err(whoami, 0, "procno out of range");
103 cl->reply.sms_status = SMS_UNKNOWN_PROC;
106 if (log_flags & LOG_ARGS)
107 log_args(procnames[pn], cl->args->sms_version_no,
108 cl->args->sms_argc, cl->args->sms_argv);
109 else if (log_flags & LOG_REQUESTS)
110 com_err(whoami, 0, "%s", procnames[pn]);
112 if ((dormant == ASLEEP || dormant == GROGGY) &&
113 pn != SMS_NOOP && pn != SMS_MOTD) {
114 cl->reply.sms_status = SMS_DOWN;
115 if (log_flags & LOG_RES)
116 com_err(whoami, SMS_DOWN, "(query refused)");
122 cl->reply.sms_status = 0;
142 trigger_dcm(0, 0, cl);
154 register returned_tuples *temp;
155 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
156 register returned_tuples *t1=temp;
158 if (t1 == cp->last) cp->last = NULL;
160 sms_destroy_reply(t1->retval);
161 delete_operation(t1->op);
167 retr_callback(argc, argv, p_cp)
169 register char **argv;
172 register client *cp = (client *)p_cp;
174 * This takes too much advantage of the fact that
175 * serialization of the data happens during the queue operation.
177 sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
178 returned_tuples *tp = (returned_tuples *)
179 db_alloc(sizeof(returned_tuples));
180 register char **nargv = (char **)malloc(argc * sizeof(char *));
183 OPERATION op_tmp = create_operation();
185 if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
186 com_err(whoami, SMS_NO_MEM, "while trimming args");
188 if (log_flags & LOG_RESP)
189 log_args("return: ", cp->args->sms_version_no, argc, argv);
192 tp->retval = arg_tmp;
195 arg_tmp->sms_status = SMS_MORE_DATA;
196 arg_tmp->sms_version_no = cp->args->sms_version_no;
197 arg_tmp->sms_argc = argc;
198 arg_tmp->sms_argv = nargv;
199 for (i = 0; i < argc; i++) {
200 register int len = strlen(argv[i]) + 1;
201 nargv[i] = malloc(len);
202 bcopy(argv[i], nargv[i], len);
204 arg_tmp->sms_flattened = (char *)NULL;
205 arg_tmp->sms_argl = (int *)NULL;
211 cp->last = cp->first = tp;
214 reset_operation(op_tmp);
215 initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
217 queue_operation(cp->con, CON_OUTPUT, op_tmp);
220 list_users(callbk, callarg)
228 extern client **clients;
229 extern char *inet_ntoa();
234 for (i = 0; i < nclients; i++) {
235 register client *cl = clients[i];
237 argv[0] = cl->clname;
238 else argv[0] = "unauthenticated";
240 argv[1] = inet_ntoa(cl->haddr.sin_addr);
242 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
243 argv[3] = ctime(&cl->last_time_used);
244 cp = index(argv[3], '\n');
247 sprintf(buf1, "[#%d]", cl->id);
248 (*callbk)(5, argv, callarg);
256 register char *queryname;
258 cl->reply.sms_argc = 0;
259 cl->reply.sms_status = 0;
261 queryname = cl->args->sms_argv[0];
263 if (cl->args->sms_version_no == SMS_VERSION_2)
268 if (strcmp(queryname, "_list_users") == 0)
269 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
271 cl->reply.sms_status =
272 sms_process_query(cl,
273 cl->args->sms_argv[0],
274 cl->args->sms_argc-1,
275 cl->args->sms_argv+1,
279 if (log_flags & LOG_RES)
280 com_err(whoami, 0, "Query complete.");
286 cl->reply.sms_argc = 0;
288 cl->reply.sms_status =
290 cl->args->sms_argv[0],
291 cl->args->sms_argc-1,
292 cl->args->sms_argv+1);
294 com_err(whoami, 0, "Access check complete.");
298 /* trigger_dcm is also used as a followup routine to the
299 * set_server_host_override query, hence the two dummy arguments.
302 struct query pseudo_query = {
307 trigger_dcm(dummy0, dummy1, cl)
313 cl->reply.sms_argc = 0;
315 if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
316 return(cl->reply.sms_status);
321 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
323 execl("/u1/sms/bin/startdcm", "startdcm", 0);
327 cl->reply.sms_status = errno;
344 cl->reply.sms_status = 0;
345 motd = fopen(SMS_MOTD_FILE, "r");
346 if (motd == NULL) return;
347 fgets(buffer, sizeof(buffer), motd);
349 retr_callback(1, arg, cl);
350 cl->reply.sms_status = 0;