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