]> andersk Git - moira.git/blob - server/mr_main.c
Added startup support.
[moira.git] / server / mr_main.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *
8  *
9  *      SMS server process.
10  *
11  *      Most of this is stolen from ../gdb/tsr.c
12  *
13  *      You are in a maze of twisty little finite automata, all different.
14  *      Let the reader beware.
15  * 
16  *      $Log$
17  *      Revision 1.6  1987-06-03 17:41:00  wesommer
18  *      Added startup support.
19  *
20  * Revision 1.5  87/06/03  16:07:17  wesommer
21  * Fixes for lint.
22  * 
23  * Revision 1.4  87/06/02  20:05:11  wesommer
24  * Bug fixes on memory allocation.
25  * 
26  * Revision 1.3  87/06/01  04:34:27  wesommer
27  * Changed returned error code.
28  * 
29  * Revision 1.2  87/06/01  03:34:53  wesommer
30  * Added shutdown, logging.
31  * 
32  * Revision 1.1  87/05/31  22:06:56  wesommer
33  * Initial revision
34  * 
35  */
36
37 static char *rcsid_sms_main_c = "$Header$";
38
39 #include <strings.h>
40 #include <sys/errno.h>
41 #include <sys/signal.h>
42 #include "sms_private.h"
43 #include "sms_server.h"
44
45 extern CONNECTION newconn, listencon;
46
47 extern int nclients;
48 extern client **clients, *cur_client;
49
50 extern OPERATION listenop;
51 extern LIST_OF_OPERATIONS op_list;
52
53 extern struct sockaddr_in client_addr;
54 extern int client_addrlen;
55 extern TUPLE client_tuple;
56
57 extern char *whoami;
58 extern char buf1[BUFSIZ];
59 extern char *takedown;
60 extern int errno;
61
62
63 extern char *malloc();
64 extern char *inet_ntoa();
65 extern void sms_com_err();
66 extern void do_client();
67
68 extern int sigshut();
69 void clist_append();
70 void oplist_append();
71 extern u_short ntohs();
72
73 /*
74  * Main SMS server loop.
75  *
76  * Initialize the world, then start accepting connections and
77  * making progress on current connections.
78  */
79
80 /*ARGSUSED*/
81 int
82 main(argc, argv)
83         int argc;
84         char **argv;
85 {
86         int status;
87         
88         whoami = argv[0];
89         /*
90          * Error handler init.
91          */
92         init_sms_err_tbl();
93         init_krb_err_tbl();
94         set_com_err_hook(sms_com_err);
95
96         if (argc != 1) {
97                 com_err(whoami, 0, "Usage: smsd");
98                 exit(1);
99         }               
100         
101         /*
102          * GDB initialization.
103          */
104         if(gdb_init() != 0) {
105                 com_err(whoami, 0, "GDB initialization failed.");
106                 exit(1);
107         }
108
109         /*
110          * Database initialization.
111          */
112
113         if ((status = sms_open_database()) != 0) {
114                 com_err(whoami, status, "when trying to open database.");
115                 exit(1);
116         }
117         
118         /*
119          * Set up client array handler.
120          */
121         nclients = 0;
122         clients = (client **) malloc(0);
123         
124         /*
125          * Signal handlers
126          *      There should probably be a few more of these.
127          */
128         
129         if ((((int)signal (SIGTERM, sigshut)) < 0) ||
130             (((int)signal (SIGHUP, sigshut)) < 0)) {
131                 com_err(whoami, errno, "Unable to establish signal handler.");
132                 exit(1);
133         }
134         
135         /*
136          * Establish template connection.
137          */
138         if ((status = do_listen()) != 0) {
139                 com_err(whoami, status,
140                         "while trying to create listening connection");
141                 exit(1);
142         }
143         
144         op_list = create_list_of_operations(1, listenop);
145         
146         (void) sprintf(buf1, "started (pid %d)", getpid());
147         com_err(whoami, 0, buf1);
148         com_err(whoami, 0, rcsid_sms_main_c);
149
150         /*
151          * Run until shut down.
152          */
153         while(!takedown) {              
154                 register int i;
155                 /*
156                  * Block until something happens.
157                  */
158 #ifdef notdef
159                 com_err(whoami, 0, "tick");
160 #endif notdef
161                 errno = 0;
162                 status = op_select_any(op_list, 0,
163                                        (fd_set *)NULL, (fd_set *)NULL,
164                                        (fd_set *)NULL, (struct timeval *)NULL);
165
166                 if (status == -1) {
167                         com_err(whoami, errno, "error from op_select");
168                         continue;
169                 } else if (status != -2) {
170                         com_err(whoami, 0, "wrong return from op_select_any");
171                         continue;
172                 }
173                 if (takedown) break;
174 #ifdef notdef
175                 fprintf(stderr, "    tick\n");
176 #endif notdef
177                 /*
178                  * Handle any existing connections.
179                  */
180                 for (i=0; i<nclients; i++) {
181                         if (OP_DONE(clients[i]->pending_op)) {
182                                 cur_client = clients[i];
183                                 do_client(cur_client);
184                                 cur_client = NULL;
185                                 if (takedown) break;
186                         }
187                 }
188                 /*
189                  * Handle any new connections.
190                  */
191                 if (OP_DONE(listenop)) {
192                         if ((status = new_connection()) != 0) {
193                                 com_err(whoami, errno,
194                                         "Error on listening operation.");
195                                 /*
196                                  * Sleep here to prevent hosing?
197                                  */
198                         }
199                 }
200         }
201         com_err(whoami, 0, takedown);
202         sms_close_database();
203         return 0;
204 }
205
206 /*
207  * Set up the template connection and queue the first accept.
208  */
209
210 int
211 do_listen()
212 {
213         char *service = index(SMS_GDB_SERV, ':') + 1;
214
215         listencon = create_listening_connection(service);
216
217         if (listencon == NULL)
218                 return errno;
219
220         listenop = create_operation();
221         client_addrlen = sizeof(client_addr);
222
223         start_accepting_client(listencon, listenop, &newconn,
224                                (char *)&client_addr,
225                                &client_addrlen, &client_tuple);
226         return 0;
227 }
228
229 /*
230  * This routine is called when a new connection comes in.
231  *
232  * It sets up a new client and adds it to the list of currently active clients.
233  */
234 int
235 new_connection()
236 {
237         register client *cp = (client *)malloc(sizeof *cp);
238         static counter = 0;
239         
240         /*
241          * Make sure there's been no error
242          */
243         if(OP_STATUS(listenop) != OP_COMPLETE ||
244            newconn == NULL) {
245                 return errno;
246 #ifdef notdef
247                 exit(8); /* XXX */
248 #endif notdef
249         }
250
251         /*
252          * Set up the new connection and reply to the client
253          */
254
255         cp->state = CL_STARTING;
256         cp->action = CL_ACCEPT;
257         cp->con = newconn;
258         cp->id = counter++;
259         cp->args = NULL;
260         cp->clname = NULL;
261         cp->reply.sms_argv = NULL;
262
263         newconn = NULL;
264         
265         cp->pending_op = create_operation();
266         reset_operation(cp->pending_op);
267         oplist_append(&op_list, cp->pending_op);
268         cur_client = cp;
269         
270         /*
271          * Add a new client to the array..
272          */
273         clist_append(cp);
274         
275         /*
276          * Let him know we heard him.
277          */
278         start_replying_to_client(cp->pending_op, cp->con, GDB_ACCEPTED,
279                                  "", "");
280
281         cp->haddr = client_addr;
282         
283         /*
284          * Log new connection.
285          */
286         
287         (void) sprintf(buf1,
288                        "New connection from %s port %d (now %d client%s)",
289                        inet_ntoa(cp->haddr.sin_addr),
290                        (int)ntohs(cp->haddr.sin_port),
291                        nclients,
292                        nclients!=1?"s":"");
293         com_err(whoami, 0, buf1);
294         
295         /*
296          * Get ready to accept the next connection.
297          */
298         reset_operation(listenop);
299         client_addrlen = sizeof(client_addr);
300
301         start_accepting_client(listencon, listenop, &newconn,
302                                (char *)&client_addr,
303                                &client_addrlen, &client_tuple);
304         return 0;
305 }
306
307 /*
308  * Add a new client to the known clients.
309  */
310 void
311 clist_append(cp)
312         client *cp;
313 {               
314         client **clients_n;
315         
316         nclients++;
317         clients_n = (client **)malloc
318                 ((unsigned)(nclients * sizeof(client *)));
319         bcopy((char *)clients, (char *)clients_n, (nclients-1)*sizeof(cp));
320         clients_n[nclients-1] = cp;
321         free((char *)clients);
322         clients = clients_n;
323         clients_n = NULL;
324 }
325
326                 
327 void
328 clist_delete(cp)
329         client *cp;
330 {
331         client **clients_n, **scpp, **dcpp; /* source and dest client */
332                                             /* ptr ptr */
333         
334         int found_it = 0;
335         
336         clients_n = (client **)malloc
337                 ((unsigned)((nclients - 1)* sizeof(client *)));
338         for (scpp = clients, dcpp = clients_n; scpp < clients+nclients; ) {
339                 if (*scpp != cp) {
340                         *dcpp++ = *scpp++;
341                 } else {
342                         scpp++;
343                         if (found_it) abort();
344                         found_it = 1;
345                 }                       
346         }
347         --nclients;     
348         free((char *)clients);
349         clients = clients_n;
350         clients_n = NULL;
351
352         reset_operation(cp->pending_op);
353         delete_operation(cp->pending_op);
354         free((char *)cp);
355 }
356
357 /*
358  * Add a new operation to a list of operations.
359  *
360  * This should be rewritten to use realloc instead, since in most
361  * cases it won't have to copy the array.
362  */
363
364 void
365 oplist_append(oplp, op)
366         LIST_OF_OPERATIONS *oplp;
367         OPERATION op;
368 {
369         int count = (*oplp)->count+1;
370         LIST_OF_OPERATIONS newlist = (LIST_OF_OPERATIONS)
371                 db_alloc(size_of_list_of_operations(count));
372         bcopy((char *)(*oplp), (char *)newlist,
373               size_of_list_of_operations((*oplp)->count));
374         newlist->count++;
375         newlist->op[count-1] = op;
376         db_free((*oplp), size_of_list_of_operations(count-1));
377         (*oplp) = newlist;
378 }
379
This page took 0.209125 seconds and 5 git commands to generate.