]> andersk Git - moira.git/blob - server/mr_scall.c
moved directory definitions
[moira.git] / server / mr_scall.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_sms_scall_c = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/file.h>
20 #include <krb.h>
21 #include <errno.h>
22 #include "query.h"
23 #include "sms_server.h"
24 extern char buf1[];
25 extern int nclients;
26 extern char *whoami;
27 extern char *malloc();
28 extern int errno;
29
30 extern void clist_delete(), do_auth(), do_shutdown();
31 void do_call();
32
33 /*
34  * Welcome to the (finite state) machine (highest level).
35  */
36 void
37 do_client(cp)
38         client *cp;
39 {
40         struct stat stbuf;
41
42         free_rtn_tuples(cp);
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)",
45                         nclients-1,
46                         nclients!=2?"s":"",
47                         newqueries,
48                         oldqueries);
49                 clist_delete(cp);
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) &&
54                     (stat(SMS_MOTD_FILE, &stbuf) == 0)) {
55                     com_err(whoami, 0, "motd file exists, slumbertime");
56                     dormant = SLEEPY;
57                 }
58                 return;
59         }
60         switch (cp->action) {
61         case CL_ACCEPT:
62         case CL_SEND:
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;
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. */
72                 sms_destroy_reply(cp->args);
73                 cp->args = NULL;
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);
77                 cp->action = CL_SEND;
78                 break;
79         }
80 }               
81
82 char *procnames[] = {
83          "noop",
84          "auth",
85          "shutdown",
86          "query",
87          "access",
88          "dcm",
89          "motd",
90 };
91
92
93 void
94 do_call(cl)
95         client *cl;
96 {
97         int pn;
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;
105                 return;
106         }
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]);
112
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)");
118             return;
119         }
120
121         switch(pn) {
122         case SMS_NOOP:
123                 cl->reply.sms_status = 0;
124                 return;
125
126         case SMS_AUTH:
127                 do_auth(cl);
128                 return;
129
130         case SMS_QUERY:
131                 do_retr(cl);
132                 return;
133
134         case SMS_ACCESS:
135                 do_access(cl);
136                 return;
137                 
138         case SMS_SHUTDOWN:
139                 do_shutdown(cl);
140                 return;
141
142         case SMS_DO_UPDATE:
143                 trigger_dcm(0, 0, cl);
144                 return;
145
146         case SMS_MOTD:
147                 get_motd(cl);
148                 return;
149         }
150 }
151
152 free_rtn_tuples(cp)
153         client *cp;
154 {
155         register returned_tuples *temp;
156         for (temp=cp->first; temp && OP_DONE(temp->op); ) {
157                 register returned_tuples *t1=temp;
158                 temp = t1->next;
159                 if (t1 == cp->last) cp->last = NULL;
160
161                 sms_destroy_reply(t1->retval);
162                 delete_operation(t1->op);
163                 free(t1);
164         }
165         cp->first = temp;
166 }       
167
168 retr_callback(argc, argv, p_cp)
169         register int argc;
170         register char **argv;
171         char *p_cp;
172 {
173         register client *cp = (client *)p_cp;
174         /*
175          * This takes too much advantage of the fact that
176          * serialization of the data happens during the queue operation.
177          */
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 *));
182         register int i;
183         
184         OPERATION op_tmp = create_operation();
185
186         if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
187             com_err(whoami, SMS_NO_MEM, "while trimming args");
188         }
189         if (log_flags & LOG_RESP)
190                 log_args("return: ", cp->args->sms_version_no, argc, argv);
191
192         tp->op = op_tmp;
193         tp->retval = arg_tmp;
194         tp->next = NULL;
195         
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);
204         }
205         arg_tmp->sms_flattened = (char *)NULL;
206         arg_tmp->sms_argl = (int *)NULL;
207
208         if (cp->last) {
209                 cp->last->next = tp;
210                 cp->last = tp;
211         } else {
212                 cp->last = cp->first = tp;
213         }
214         
215         reset_operation(op_tmp);
216         initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
217                              (int (*)())NULL);
218         queue_operation(cp->con, CON_OUTPUT, op_tmp);
219 }
220
221 list_users(callbk, callarg)
222         int (*callbk)();
223         char *callarg;
224 {
225         char *argv[6];
226         char buf[30];
227         char buf1[30];
228         int i;
229         extern client **clients;
230         extern char *inet_ntoa();
231         char *cp;
232         char *index();
233         char *ctime();
234
235         for (i = 0; i < nclients; i++) {
236                 register client *cl = clients[i];
237                 if (cl->clname) 
238                         argv[0] = cl->clname;
239                 else argv[0] = "unauthenticated";
240                 
241                 argv[1] = inet_ntoa(cl->haddr.sin_addr);
242                 argv[2] = buf;
243                 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
244                 argv[3] = ctime(&cl->last_time_used);
245                 cp = index(argv[3], '\n');
246                 if (cp) *cp = '\0';
247                 argv[4] = buf1;
248                 sprintf(buf1, "[#%d]", cl->id);
249                 (*callbk)(5, argv, callarg);
250         }
251         return 0;
252 }
253
254 do_retr(cl)
255         register client *cl;
256 {
257         register char *queryname;
258
259         cl->reply.sms_argc = 0;
260         cl->reply.sms_status = 0;
261
262         queryname = cl->args->sms_argv[0];
263         
264         if (cl->args->sms_version_no == SMS_VERSION_2)
265           newqueries++;
266         else
267           oldqueries++;
268
269         if (strcmp(queryname, "_list_users") == 0)
270                 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
271         else {
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,
277                                           retr_callback,
278                                           (char *)cl);
279         }
280         if (log_flags & LOG_RES)
281                 com_err(whoami, 0, "Query complete.");
282 }
283
284 do_access(cl)
285         client *cl;
286 {
287         cl->reply.sms_argc = 0;
288
289         cl->reply.sms_status = 
290           sms_check_access(cl,
291                            cl->args->sms_argv[0],
292                            cl->args->sms_argc-1,
293                            cl->args->sms_argv+1);
294         
295         com_err(whoami, 0, "Access check complete.");
296 }
297
298
299 /* trigger_dcm is also used as a followup routine to the 
300  * set_server_host_override query, hence the two dummy arguments.
301  */
302
303 struct query pseudo_query = {
304         "trigger_dcm",
305         "tdcm",
306 };
307
308 trigger_dcm(dummy0, dummy1, cl)
309         int dummy0, dummy1;
310         client *cl;
311 {
312         register int pid;
313         char prog[128];
314
315         cl->reply.sms_argc = 0;
316
317         if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
318                 return(cl->reply.sms_status);
319
320         sprintf(prog, "%s/startdcm", BIN_DIR);
321         pid = vfork();
322         switch (pid) {
323         case 0:
324                 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
325                   close(dummy0);
326                 execl(prog, "startdcm", 0);
327                 exit(1);
328                 
329         case -1:
330                 cl->reply.sms_status = errno;
331                 return(0);
332
333         default:
334                 return(0);
335         }
336 }
337
338
339 get_motd(cl)
340 client *cl;
341 {
342     int motd, len;
343     char buffer[1024];
344     char *arg[1];
345
346     arg[0] = buffer;
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);
351     close(motd);
352     buffer[len] = 0;
353     retr_callback(1, arg, cl);
354     cl->reply.sms_status = 0;
355 }
This page took 0.065142 seconds and 5 git commands to generate.