]> andersk Git - moira.git/blob - server/mr_scall.c
Added list_users query.
[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.10  1987-08-19 18:39:04  wesommer
10  *      Added list_users query.
11  *
12  * Revision 1.9  87/08/04  02:41:22  wesommer
13  * Clean up messages.
14  * 
15  * Revision 1.8  87/07/16  15:43:19  wesommer
16  * Fixed bug where the argv was not copied to private storage
17  * (it got changed out from under us before it got sent..).
18  * 
19  * Revision 1.7  87/07/14  00:39:01  wesommer
20  * Rearranged loggin.
21  * 
22  * Revision 1.6  87/06/30  20:04:43  wesommer
23  * Free returned tuples when possible.
24  * 
25  * Revision 1.5  87/06/26  10:55:53  wesommer
26  * Added sms_access, now paiys attention to return code from 
27  * sms_process_query, sms_check_access.
28  * 
29  * Revision 1.4  87/06/21  16:42:00  wesommer
30  * Performance work, rearrangement of include files.
31  * 
32  * Revision 1.3  87/06/04  01:35:01  wesommer
33  * Added a working query request handler.
34  * 
35  * Revision 1.2  87/06/03  16:07:50  wesommer
36  * Fixes for lint.
37  * 
38  * Revision 1.1  87/06/02  20:07:10  wesommer
39  * Initial revision
40  * 
41  */
42
43 #ifndef lint
44 static char *rcsid_sms_scall_c = "$Header$";
45 #endif lint
46
47 #include <krb.h>
48 #include <errno.h>
49 #include "sms_server.h"
50 extern char buf1[];
51 extern int nclients;
52 extern char *whoami;
53 extern char *malloc();
54
55 extern void clist_delete(), do_auth(), do_shutdown();
56 void do_call();
57
58 /*
59  * Welcome to the (finite state) machine (highest level).
60  */
61 void
62 do_client(cp)
63         client *cp;
64 {
65         free_rtn_tuples(cp);
66         if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
67                 com_err(whoami, 0, "Closed connection (now %d client%s)",
68                         nclients-1,
69                         nclients!=2?"s":"");
70                 clist_delete(cp);
71                 return;
72         }
73         switch (cp->action) {
74         case CL_ACCEPT:
75         case CL_SEND:
76                 /* Start recieving next request */
77                 initialize_operation(cp->pending_op, sms_start_recv,
78                                      (char *)&cp->args, (int (*)())NULL);
79                 queue_operation(cp->con, CON_INPUT, cp->pending_op);
80                 cp->action = CL_RECEIVE;
81                 break;
82         case CL_RECEIVE:
83                 /* Data is here. Process it & start it heading back */
84                 do_call(cp); /* This may block for a while. */
85                 sms_destroy_reply(cp->args);
86                 cp->args = NULL;
87                 initialize_operation(cp->pending_op, sms_start_send,
88                                      (char *)&cp->reply, (int (*)())NULL);
89                 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
90                 cp->action = CL_SEND;
91                 break;
92         }
93 }               
94
95 char *procnames[] = {
96          "noop",
97          "auth",
98          "shutdown",
99          "query",
100          "access",
101 };
102
103
104 void
105 do_call(cl)
106         client *cl;
107 {
108         int pn;
109         cl->reply.sms_argc = 0;
110         cl->reply.sms_status = 0;
111         if (((pn = cl->args->sms_procno) < 0) ||
112             (pn > SMS_MAX_PROC)) {
113                 com_err(whoami, 0, "procno out of range");
114                 cl->reply.sms_status = SMS_UNKNOWN_PROC;
115                 return;
116         }
117         if (log_flags & LOG_ARGS)
118                 log_args(procnames[pn], cl->args->sms_argc,
119                          cl->args->sms_argv);
120         else if (log_flags & LOG_REQUESTS)
121                 com_err(whoami, 0, "%s", procnames[pn]);
122
123         switch(pn) {
124         case SMS_NOOP:
125                 cl->reply.sms_status = 0;
126                 return;
127
128         case SMS_AUTH:
129                 do_auth(cl);
130                 return;
131
132         case SMS_QUERY:
133                 do_retr(cl);
134                 return;
135
136         case SMS_ACCESS:
137                 do_access(cl);
138                 return;
139                 
140         case SMS_SHUTDOWN:
141                 do_shutdown(cl);
142                 return;
143         }
144 }
145
146 free_rtn_tuples(cp)
147         client *cp;
148 {
149         register returned_tuples *temp;
150         for (temp=cp->first; temp && OP_DONE(temp->op); ) {
151                 register returned_tuples *t1=temp;
152                 temp = t1->next;
153                 if (t1 == cp->last) cp->last = NULL;
154
155                 sms_destroy_reply(t1->retval);
156 #ifdef notdef
157                 if (t1->retval) {
158                         register sms_params *p = t1->retval;
159                         if (p->sms_flattened)
160                                 free(p->sms_flattened);
161                         if (p->sms_argl)
162                                 free(p->sms_argl);
163                         free(p);
164                 }
165 #endif notdef
166                 delete_operation(t1->op);
167                 free(t1);
168         }
169         cp->first = temp;
170 }       
171
172 retr_callback(argc, argv, p_cp)
173         register int argc;
174         register char **argv;
175         char *p_cp;
176 {
177         register client *cp = (client *)p_cp;
178         /*
179          * This takes too much advantage of the fact that
180          * serialization of the data happens during the queue operation.
181          */
182         sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
183         returned_tuples *tp = (returned_tuples *)
184                 db_alloc(sizeof(returned_tuples));
185         register char **nargv = (char **)malloc(argc * sizeof(char *));
186         register int i;
187         
188         OPERATION op_tmp = create_operation();
189
190         if (log_flags & LOG_RESP)
191                 log_args("return: ", argc, argv);
192
193         tp->op = op_tmp;
194         tp->retval = arg_tmp;
195         tp->next = NULL;
196         
197         arg_tmp->sms_status = SMS_MORE_DATA;
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 (strcmp(queryname, "_list_users") == 0)
265                 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
266         else {
267                 cl->reply.sms_status = 
268                         sms_process_query(cl,
269                                           cl->args->sms_argv[0],
270                                           cl->args->sms_argc-1,
271                                           cl->args->sms_argv+1,
272                                           retr_callback,
273                                           (char *)cl);
274         }
275         if (log_flags & LOG_RES)
276                 com_err(whoami, 0, "Query complete.");
277 }
278
279 do_access(cl)
280         client *cl;
281 {
282         cl->reply.sms_argc = 0;
283
284         cl->reply.sms_status = 
285           sms_check_access(cl,
286                            cl->args->sms_argv[0],
287                            cl->args->sms_argc-1,
288                            cl->args->sms_argv+1);
289         
290         com_err(whoami, 0, "Access check complete.");
291 }
This page took 0.070145 seconds and 5 git commands to generate.