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