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