]> andersk Git - moira.git/blob - server/mr_scall.c
Added the trigger_dcm function, which fires off a DCM to do the
[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  *
8  *      $Log$
9  *      Revision 1.11  1987-08-19 22:03:52  wesommer
10  *      Added the trigger_dcm function, which fires off a DCM to do the
11  *      update.
12  *
13  * Revision 1.10  87/08/19  18:39:04  wesommer
14  * Added list_users query.
15  * 
16  * Revision 1.9  87/08/04  02:41:22  wesommer
17  * Clean up messages.
18  * 
19  * Revision 1.8  87/07/16  15:43:19  wesommer
20  * Fixed bug where the argv was not copied to private storage
21  * (it got changed out from under us before it got sent..).
22  * 
23  * Revision 1.7  87/07/14  00:39:01  wesommer
24  * Rearranged loggin.
25  * 
26  * Revision 1.6  87/06/30  20:04:43  wesommer
27  * Free returned tuples when possible.
28  * 
29  * Revision 1.5  87/06/26  10:55:53  wesommer
30  * Added sms_access, now paiys attention to return code from 
31  * sms_process_query, sms_check_access.
32  * 
33  * Revision 1.4  87/06/21  16:42:00  wesommer
34  * Performance work, rearrangement of include files.
35  * 
36  * Revision 1.3  87/06/04  01:35:01  wesommer
37  * Added a working query request handler.
38  * 
39  * Revision 1.2  87/06/03  16:07:50  wesommer
40  * Fixes for lint.
41  * 
42  * Revision 1.1  87/06/02  20:07:10  wesommer
43  * Initial revision
44  * 
45  */
46
47 #ifndef lint
48 static char *rcsid_sms_scall_c = "$Header$";
49 #endif lint
50
51 #include <krb.h>
52 #include <errno.h>
53 #include "query.h"
54 #include "sms_server.h"
55 extern char buf1[];
56 extern int nclients;
57 extern char *whoami;
58 extern char *malloc();
59 extern int errno;
60
61 extern void clist_delete(), do_auth(), do_shutdown();
62 void do_call();
63
64 /*
65  * Welcome to the (finite state) machine (highest level).
66  */
67 void
68 do_client(cp)
69         client *cp;
70 {
71         free_rtn_tuples(cp);
72         if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
73                 com_err(whoami, 0, "Closed connection (now %d client%s)",
74                         nclients-1,
75                         nclients!=2?"s":"");
76                 clist_delete(cp);
77                 return;
78         }
79         switch (cp->action) {
80         case CL_ACCEPT:
81         case CL_SEND:
82                 /* Start recieving next request */
83                 initialize_operation(cp->pending_op, sms_start_recv,
84                                      (char *)&cp->args, (int (*)())NULL);
85                 queue_operation(cp->con, CON_INPUT, cp->pending_op);
86                 cp->action = CL_RECEIVE;
87                 break;
88         case CL_RECEIVE:
89                 /* Data is here. Process it & start it heading back */
90                 do_call(cp); /* This may block for a while. */
91                 sms_destroy_reply(cp->args);
92                 cp->args = NULL;
93                 initialize_operation(cp->pending_op, sms_start_send,
94                                      (char *)&cp->reply, (int (*)())NULL);
95                 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
96                 cp->action = CL_SEND;
97                 break;
98         }
99 }               
100
101 char *procnames[] = {
102          "noop",
103          "auth",
104          "shutdown",
105          "query",
106          "access",
107 };
108
109
110 void
111 do_call(cl)
112         client *cl;
113 {
114         int pn;
115         cl->reply.sms_argc = 0;
116         cl->reply.sms_status = 0;
117         if (((pn = cl->args->sms_procno) < 0) ||
118             (pn > SMS_MAX_PROC)) {
119                 com_err(whoami, 0, "procno out of range");
120                 cl->reply.sms_status = SMS_UNKNOWN_PROC;
121                 return;
122         }
123         if (log_flags & LOG_ARGS)
124                 log_args(procnames[pn], cl->args->sms_argc,
125                          cl->args->sms_argv);
126         else if (log_flags & LOG_REQUESTS)
127                 com_err(whoami, 0, "%s", procnames[pn]);
128
129         switch(pn) {
130         case SMS_NOOP:
131                 cl->reply.sms_status = 0;
132                 return;
133
134         case SMS_AUTH:
135                 do_auth(cl);
136                 return;
137
138         case SMS_QUERY:
139                 do_retr(cl);
140                 return;
141
142         case SMS_ACCESS:
143                 do_access(cl);
144                 return;
145                 
146         case SMS_SHUTDOWN:
147                 do_shutdown(cl);
148                 return;
149
150         case SMS_DO_UPDATE:
151                 trigger_dcm(cl);
152                 return;
153         }
154 }
155
156 free_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;
164
165                 sms_destroy_reply(t1->retval);
166 #ifdef notdef
167                 if (t1->retval) {
168                         register sms_params *p = t1->retval;
169                         if (p->sms_flattened)
170                                 free(p->sms_flattened);
171                         if (p->sms_argl)
172                                 free(p->sms_argl);
173                         free(p);
174                 }
175 #endif notdef
176                 delete_operation(t1->op);
177                 free(t1);
178         }
179         cp->first = temp;
180 }       
181
182 retr_callback(argc, argv, p_cp)
183         register int argc;
184         register char **argv;
185         char *p_cp;
186 {
187         register client *cp = (client *)p_cp;
188         /*
189          * This takes too much advantage of the fact that
190          * serialization of the data happens during the queue operation.
191          */
192         sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
193         returned_tuples *tp = (returned_tuples *)
194                 db_alloc(sizeof(returned_tuples));
195         register char **nargv = (char **)malloc(argc * sizeof(char *));
196         register int i;
197         
198         OPERATION op_tmp = create_operation();
199
200         if (log_flags & LOG_RESP)
201                 log_args("return: ", argc, argv);
202
203         tp->op = op_tmp;
204         tp->retval = arg_tmp;
205         tp->next = NULL;
206         
207         arg_tmp->sms_status = SMS_MORE_DATA;
208         arg_tmp->sms_argc = argc;
209         arg_tmp->sms_argv = nargv;
210         for (i = 0; i < argc; i++) {
211                 register int len = strlen(argv[i]) + 1;
212                 nargv[i] = malloc(len);
213                 bcopy(argv[i], nargv[i], len);
214         }
215         arg_tmp->sms_flattened = (char *)NULL;
216         arg_tmp->sms_argl = (int *)NULL;
217
218         if (cp->last) {
219                 cp->last->next = tp;
220                 cp->last = tp;
221         } else {
222                 cp->last = cp->first = tp;
223         }
224         
225         reset_operation(op_tmp);
226         initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
227                              (int (*)())NULL);
228         queue_operation(cp->con, CON_OUTPUT, op_tmp);
229 }
230
231 list_users(callbk, callarg)
232         int (*callbk)();
233         char *callarg;
234 {
235         char *argv[6];
236         char buf[30];
237         char buf1[30];
238         int i;
239         extern client **clients;
240         extern char *inet_ntoa();
241         char *cp;
242         char *index();
243         char *ctime();
244
245         for (i = 0; i < nclients; i++) {
246                 register client *cl = clients[i];
247                 if (cl->clname) 
248                         argv[0] = cl->clname;
249                 else argv[0] = "unauthenticated";
250                 
251                 argv[1] = inet_ntoa(cl->haddr.sin_addr);
252                 argv[2] = buf;
253                 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
254                 argv[3] = ctime(&cl->last_time_used);
255                 cp = index(argv[3], '\n');
256                 if (cp) *cp = '\0';
257                 argv[4] = buf1;
258                 sprintf(buf1, "[#%d]", cl->id);
259                 (*callbk)(5, argv, callarg);
260         }
261         return 0;
262 }
263
264 do_retr(cl)
265         register client *cl;
266 {
267         register char *queryname;
268
269         cl->reply.sms_argc = 0;
270         cl->reply.sms_status = 0;
271
272         queryname = cl->args->sms_argv[0];
273         
274         if (strcmp(queryname, "_list_users") == 0)
275                 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
276         else {
277                 cl->reply.sms_status = 
278                         sms_process_query(cl,
279                                           cl->args->sms_argv[0],
280                                           cl->args->sms_argc-1,
281                                           cl->args->sms_argv+1,
282                                           retr_callback,
283                                           (char *)cl);
284         }
285         if (log_flags & LOG_RES)
286                 com_err(whoami, 0, "Query complete.");
287 }
288
289 do_access(cl)
290         client *cl;
291 {
292         cl->reply.sms_argc = 0;
293
294         cl->reply.sms_status = 
295           sms_check_access(cl,
296                            cl->args->sms_argv[0],
297                            cl->args->sms_argc-1,
298                            cl->args->sms_argv+1);
299         
300         com_err(whoami, 0, "Access check complete.");
301 }
302
303 struct query pseudo_query = {
304         "trigger_dcm",
305         "tdcm",
306 };
307
308 trigger_dcm(cl)
309         client *cl;
310 {
311         register int pid;
312         
313         cl->reply.sms_argc = 0;
314
315         if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
316                 return;
317
318         pid = vfork();
319         switch (pid) {
320         case 0:
321                 execl("/u1/sms/bin/dcm", "dcm", 0);
322                 exit(1);
323                 
324         case -1:
325                 cl->reply.sms_status = errno;
326                 return;
327
328         default:
329                 return;
330         }
331 }
332
This page took 0.062942 seconds and 5 git commands to generate.