]> andersk Git - moira.git/blame - server/mr_main.c
added variables to count queries by version, and journal file
[moira.git] / server / mr_main.c
CommitLineData
0fa91a0a 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$
23e476e8 17 * Revision 1.14 1987-09-12 20:41:50 wesommer
18 * Be paranoid.
0fa91a0a 19 *
23e476e8 20 * Revision 1.14 87/09/12 20:08:01 wesommer
21 * Add some defensive programming to defend against people who don't
22 * understand what the contents of the cl struct mean.
23 *
24 * Revision 1.13 87/08/04 02:40:30 wesommer
25 * Do end run around minor hotspot.
26 *
f5c72293 27 * Revision 1.12 87/08/04 01:50:00 wesommer
28 * Rearranged messages.
29 *
b4182127 30 * Revision 1.11 87/07/29 16:04:54 wesommer
31 * Add keepalive feature.
32 *
0eb9f52f 33 * Revision 1.10 87/06/30 20:02:26 wesommer
34 * Added returned tuple chain to client structure.
35 * Added local realm global variable.
36 *
4a06eb54 37 * Revision 1.9 87/06/21 16:39:54 wesommer
38 * Performance work, rearrangement of include files.
39 *
c27b3454 40 * Revision 1.8 87/06/09 18:44:45 wesommer
41 * modified error handling.
42 *
7f024a70 43 * Revision 1.7 87/06/08 02:44:44 wesommer
44 * Minor lint fix.
45 *
467f5982 46 * Revision 1.6 87/06/03 17:41:00 wesommer
47 * Added startup support.
48 *
f6cc38de 49 * Revision 1.5 87/06/03 16:07:17 wesommer
50 * Fixes for lint.
51 *
5dbd09a0 52 * Revision 1.4 87/06/02 20:05:11 wesommer
53 * Bug fixes on memory allocation.
54 *
0ec57336 55 * Revision 1.3 87/06/01 04:34:27 wesommer
56 * Changed returned error code.
57 *
d9ecb02a 58 * Revision 1.2 87/06/01 03:34:53 wesommer
59 * Added shutdown, logging.
60 *
70d54e43 61 * Revision 1.1 87/05/31 22:06:56 wesommer
62 * Initial revision
63 *
0fa91a0a 64 */
65
0fa91a0a 66static char *rcsid_sms_main_c = "$Header$";
0fa91a0a 67
70d54e43 68#include <strings.h>
69#include <sys/errno.h>
70d54e43 70#include <sys/signal.h>
0fa91a0a 71#include "sms_server.h"
70d54e43 72
0ec57336 73extern CONNECTION newconn, listencon;
0fa91a0a 74
0ec57336 75extern int nclients;
76extern client **clients, *cur_client;
0fa91a0a 77
0ec57336 78extern OPERATION listenop;
79extern LIST_OF_OPERATIONS op_list;
0fa91a0a 80
0ec57336 81extern struct sockaddr_in client_addr;
82extern int client_addrlen;
83extern TUPLE client_tuple;
0fa91a0a 84
0ec57336 85extern char *whoami;
86extern char buf1[BUFSIZ];
87extern char *takedown;
88extern int errno;
0fa91a0a 89
70d54e43 90
0ec57336 91extern char *malloc();
f5c72293 92extern int free();
0ec57336 93extern char *inet_ntoa();
94extern void sms_com_err();
95extern void do_client();
70d54e43 96
0ec57336 97extern int sigshut();
98void clist_append();
99void oplist_append();
100extern u_short ntohs();
0fa91a0a 101
0eb9f52f 102extern time_t now;
103
0ec57336 104/*
105 * Main SMS server loop.
106 *
107 * Initialize the world, then start accepting connections and
108 * making progress on current connections.
109 */
0fa91a0a 110
0ec57336 111/*ARGSUSED*/
112int
0fa91a0a 113main(argc, argv)
70d54e43 114 int argc;
115 char **argv;
0fa91a0a 116{
0ec57336 117 int status;
0eb9f52f 118 time_t tardy;
0ec57336 119
120 whoami = argv[0];
121 /*
122 * Error handler init.
123 */
124 init_sms_err_tbl();
125 init_krb_err_tbl();
126 set_com_err_hook(sms_com_err);
b4182127 127 setlinebuf(stderr);
128
0ec57336 129 if (argc != 1) {
130 com_err(whoami, 0, "Usage: smsd");
131 exit(1);
132 }
f5c72293 133
134 /* Profiling implies that getting rid of one level of call
135 * indirection here wins us maybe 1% on the VAX.
136 */
137 gdb_amv = malloc;
138 gdb_fmv = free;
0ec57336 139
140 /*
141 * GDB initialization.
142 */
5dbd09a0 143 if(gdb_init() != 0) {
144 com_err(whoami, 0, "GDB initialization failed.");
145 exit(1);
146 }
7f024a70 147 gdb_debug(0); /* this can be patched, if necessary, to enable */
148 /* GDB level debugging .. */
4a06eb54 149 krb_realm = malloc(REALM_SZ);
150 get_krbrlm(krb_realm, 1);
7f024a70 151
f6cc38de 152 /*
153 * Database initialization.
154 */
155
156 if ((status = sms_open_database()) != 0) {
157 com_err(whoami, status, "when trying to open database.");
158 exit(1);
159 }
160
0ec57336 161 /*
162 * Set up client array handler.
163 */
0fa91a0a 164 nclients = 0;
165 clients = (client **) malloc(0);
70d54e43 166
0ec57336 167 /*
168 * Signal handlers
f6cc38de 169 * There should probably be a few more of these.
0ec57336 170 */
70d54e43 171
0ec57336 172 if ((((int)signal (SIGTERM, sigshut)) < 0) ||
173 (((int)signal (SIGHUP, sigshut)) < 0)) {
174 com_err(whoami, errno, "Unable to establish signal handler.");
175 exit(1);
176 }
177
178 /*
179 * Establish template connection.
180 */
181 if ((status = do_listen()) != 0) {
182 com_err(whoami, status,
183 "while trying to create listening connection");
184 exit(1);
185 }
0fa91a0a 186
0fa91a0a 187 op_list = create_list_of_operations(1, listenop);
0fa91a0a 188
b4182127 189 com_err(whoami, 0, "started (pid %d)", getpid());
0ec57336 190 com_err(whoami, 0, rcsid_sms_main_c);
191
192 /*
193 * Run until shut down.
194 */
70d54e43 195 while(!takedown) {
0ec57336 196 register int i;
197 /*
198 * Block until something happens.
199 */
5dbd09a0 200#ifdef notdef
201 com_err(whoami, 0, "tick");
202#endif notdef
203 errno = 0;
204 status = op_select_any(op_list, 0,
205 (fd_set *)NULL, (fd_set *)NULL,
206 (fd_set *)NULL, (struct timeval *)NULL);
207
208 if (status == -1) {
209 com_err(whoami, errno, "error from op_select");
210 continue;
211 } else if (status != -2) {
212 com_err(whoami, 0, "wrong return from op_select_any");
213 continue;
214 }
70d54e43 215 if (takedown) break;
0eb9f52f 216 time(&now);
70d54e43 217#ifdef notdef
218 fprintf(stderr, " tick\n");
219#endif notdef
b4182127 220 /*
221 * Handle any new connections; this comes first so
222 * errno isn't tromped on.
223 */
224 if (OP_DONE(listenop)) {
225 if (OP_STATUS(listenop) == OP_CANCELLED) {
226 if (errno == EWOULDBLOCK) {
227 do_reset_listen();
228 } else {
229 com_err(whoami, errno,
230 "error on listen");
231 exit(1);
232 }
233 } else if ((status = new_connection()) != 0) {
234 com_err(whoami, errno,
235 "Error on listening operation.");
236 /*
237 * Sleep here to prevent hosing?
238 */
239 }
240 }
0ec57336 241 /*
242 * Handle any existing connections.
243 */
0eb9f52f 244 tardy = now - 30*60;
245
0fa91a0a 246 for (i=0; i<nclients; i++) {
0eb9f52f 247 cur_client = clients[i];
0fa91a0a 248 if (OP_DONE(clients[i]->pending_op)) {
0eb9f52f 249 cur_client->last_time_used = now;
70d54e43 250 do_client(cur_client);
0eb9f52f 251 } else if (clients[i]->last_time_used < tardy) {
252 com_err(whoami, 0, "Shutting down connection due to inactivity");
253 shutdown(cur_client->con->in.fd, 0);
0fa91a0a 254 }
0eb9f52f 255 cur_client = NULL;
256 if (takedown) break;
0fa91a0a 257 }
0fa91a0a 258 }
b4182127 259 com_err(whoami, 0, "%s", takedown);
f6cc38de 260 sms_close_database();
0ec57336 261 return 0;
70d54e43 262}
263
0ec57336 264/*
265 * Set up the template connection and queue the first accept.
266 */
267
268int
269do_listen()
70d54e43 270{
0ec57336 271 char *service = index(SMS_GDB_SERV, ':') + 1;
272
273 listencon = create_listening_connection(service);
274
275 if (listencon == NULL)
276 return errno;
277
278 listenop = create_operation();
279 client_addrlen = sizeof(client_addr);
280
281 start_accepting_client(listencon, listenop, &newconn,
282 (char *)&client_addr,
283 &client_addrlen, &client_tuple);
284 return 0;
0fa91a0a 285}
286
b4182127 287
288do_reset_listen()
289{
290 client_addrlen = sizeof(client_addr);
291 start_accepting_client(listencon, listenop, &newconn,
292 (char *)&client_addr,
293 &client_addrlen, &client_tuple);
294}
295
0ec57336 296/*
297 * This routine is called when a new connection comes in.
298 *
299 * It sets up a new client and adds it to the list of currently active clients.
300 */
301int
5dbd09a0 302new_connection()
0fa91a0a 303{
7f024a70 304 register client *cp;
70d54e43 305 static counter = 0;
0fa91a0a 306
0fa91a0a 307 /*
308 * Make sure there's been no error
309 */
c27b3454 310 if(OP_STATUS(listenop) != OP_COMPLETE) {
0ec57336 311 return errno;
c27b3454 312 }
313
314 if (newconn == NULL) {
315 return SMS_NOT_CONNECTED;
0fa91a0a 316 }
317
0fa91a0a 318 /*
319 * Set up the new connection and reply to the client
320 */
7f024a70 321 cp = (client *)malloc(sizeof *cp);
23e476e8 322 bzero(cp, sizeof(*cp));
0fa91a0a 323 cp->state = CL_STARTING;
324 cp->action = CL_ACCEPT;
325 cp->con = newconn;
70d54e43 326 cp->id = counter++;
0ec57336 327 cp->args = NULL;
328 cp->clname = NULL;
329 cp->reply.sms_argv = NULL;
4a06eb54 330 cp->first = NULL;
331 cp->last = NULL;
0eb9f52f 332 cp->last_time_used = now;
0fa91a0a 333 newconn = NULL;
334
335 cp->pending_op = create_operation();
336 reset_operation(cp->pending_op);
337 oplist_append(&op_list, cp->pending_op);
70d54e43 338 cur_client = cp;
339
0ec57336 340 /*
341 * Add a new client to the array..
342 */
343 clist_append(cp);
344
345 /*
346 * Let him know we heard him.
347 */
0fa91a0a 348 start_replying_to_client(cp->pending_op, cp->con, GDB_ACCEPTED,
349 "", "");
0ec57336 350
351 cp->haddr = client_addr;
352
353 /*
354 * Log new connection.
355 */
356
b4182127 357 com_err(whoami, 0, "New connection from %s port %d (now %d client%s)",
358 inet_ntoa(cp->haddr.sin_addr),
359 (int)ntohs(cp->haddr.sin_port),
360 nclients,
361 nclients!=1?"s":"");
0fa91a0a 362
363 /*
0ec57336 364 * Get ready to accept the next connection.
0fa91a0a 365 */
366 reset_operation(listenop);
0ec57336 367 client_addrlen = sizeof(client_addr);
0fa91a0a 368
369 start_accepting_client(listencon, listenop, &newconn,
0ec57336 370 (char *)&client_addr,
371 &client_addrlen, &client_tuple);
372 return 0;
0fa91a0a 373}
374
0fa91a0a 375/*
376 * Add a new client to the known clients.
377 */
0ec57336 378void
0fa91a0a 379clist_append(cp)
380 client *cp;
381{
382 client **clients_n;
383
384 nclients++;
0ec57336 385 clients_n = (client **)malloc
386 ((unsigned)(nclients * sizeof(client *)));
0fa91a0a 387 bcopy((char *)clients, (char *)clients_n, (nclients-1)*sizeof(cp));
388 clients_n[nclients-1] = cp;
389 free((char *)clients);
390 clients = clients_n;
391 clients_n = NULL;
392}
393
70d54e43 394
0ec57336 395void
70d54e43 396clist_delete(cp)
397 client *cp;
398{
70d54e43 399 client **clients_n, **scpp, **dcpp; /* source and dest client */
400 /* ptr ptr */
401
70d54e43 402 int found_it = 0;
403
0ec57336 404 clients_n = (client **)malloc
405 ((unsigned)((nclients - 1)* sizeof(client *)));
70d54e43 406 for (scpp = clients, dcpp = clients_n; scpp < clients+nclients; ) {
407 if (*scpp != cp) {
408 *dcpp++ = *scpp++;
409 } else {
410 scpp++;
411 if (found_it) abort();
412 found_it = 1;
413 }
414 }
415 --nclients;
416 free((char *)clients);
417 clients = clients_n;
418 clients_n = NULL;
c27b3454 419 oplist_delete(op_list, cp->pending_op);
70d54e43 420 reset_operation(cp->pending_op);
421 delete_operation(cp->pending_op);
7f024a70 422 sever_connection(cp->con);
0ec57336 423 free((char *)cp);
70d54e43 424}
0ec57336 425
0fa91a0a 426/*
0ec57336 427 * Add a new operation to a list of operations.
428 *
429 * This should be rewritten to use realloc instead, since in most
430 * cases it won't have to copy the array.
0fa91a0a 431 */
432
0ec57336 433void
0fa91a0a 434oplist_append(oplp, op)
435 LIST_OF_OPERATIONS *oplp;
436 OPERATION op;
437{
438 int count = (*oplp)->count+1;
439 LIST_OF_OPERATIONS newlist = (LIST_OF_OPERATIONS)
440 db_alloc(size_of_list_of_operations(count));
441 bcopy((char *)(*oplp), (char *)newlist,
442 size_of_list_of_operations((*oplp)->count));
0fa91a0a 443 newlist->count++;
444 newlist->op[count-1] = op;
467f5982 445 db_free((char *)(*oplp), size_of_list_of_operations(count-1));
0fa91a0a 446 (*oplp) = newlist;
447}
448
c27b3454 449
450oplist_delete(oplp, op)
451 LIST_OF_OPERATIONS oplp;
452 register OPERATION op;
453{
454 register OPERATION *s;
455 register int c;
456
457 for (s = oplp->op, c=oplp->count; c; --c, ++s) {
458 if (*s == op) {
459 while (c > 0) {
460 *s = *(s+1);
461 ++s;
462 --c;
463 }
464 oplp->count--;
465 return;
466 }
467 }
468 abort();
469}
This page took 0.13434 seconds and 5 git commands to generate.