X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fstatserv.c;h=a32ce35084294f3f69dc7de4eaec7d84fa8c5d16;hb=30e703f75c26ad4b564e380d586d122edd49046d;hp=8d2629d41dabac5d353c5728225a918bafb319a8;hpb=c6e47cbbff56f39f6d81b079ebaeac41d793d4d9;p=yaz-moved-to-github.git diff --git a/src/statserv.c b/src/statserv.c index 8d2629d..a32ce35 100644 --- a/src/statserv.c +++ b/src/statserv.c @@ -1,12 +1,16 @@ /* - * Copyright (c) 1995-2003, Index Data + * Copyright (c) 1995-2004, Index Data * See the file LICENSE for details. - * Sebastian Hammer, Adam Dickmeiss * * NT threaded server code by * Chas Woodfield, Fretwell Downing Informatics. * - * $Id: statserv.c,v 1.1 2003-10-27 12:21:35 adam Exp $ + * $Id: statserv.c,v 1.11 2004-11-16 17:08:11 heikki Exp $ + */ + +/** + * \file statserv.c + * \brief Implements GFS logic */ #include @@ -44,10 +48,14 @@ static IOCHAN pListener = NULL; -static char *me = "statserver"; +static char *me = "statserver"; /* log prefix */ +static char *programname="statserver"; /* full program name */ /* * default behavior. */ +#define STAT_DEFAULT_LOG_LEVEL "none,fatal,warn,log,server,session,request" +/* the 'none' clears yaz' own default settings, including [log] */ + int check_options(int argc, char **argv); statserv_options_block control_block = { 1, /* dynamic mode */ @@ -77,11 +85,30 @@ statserv_options_block control_block = { "", /* NT Service Dependencies */ "Z39.50 Server", /* NT Service Display Name */ #endif /* WIN32 */ - 0 /* SOAP handlers */ + 0, /* SOAP handlers */ + "", /* PID fname */ + 0, /* background daemon */ + "" /* SSL certificate filename */ }; static int max_sessions = 0; +static int logbits_set=0; +static int log_session=0; +static int log_server=0; + +/** get_logbits sets global loglevel bits */ +static void get_logbits(int force) +{ /* needs to be called after parsing cmd-line args that can set loglevels!*/ + if (force || !logbits_set) + { + logbits_set=1; + log_session=yaz_log_module_level("session"); + log_server=yaz_log_module_level("server"); + } +} + + /* * handle incoming connect requests. * The dynamic mode is a bit tricky mostly because we want to avoid @@ -231,7 +258,7 @@ void statserv_closedown() /* Now we can really do something */ if (iHandles > 0) { - logf (LOG_LOG, "waiting for %d to die", iHandles); + logf (log_server, "waiting for %d to die", iHandles); /* This will now wait, until all the threads close */ WaitForMultipleObjects(iHandles, pThreadHandles, TRUE, INFINITE); @@ -416,11 +443,10 @@ static void listener(IOCHAN h, int event) iochan_destroy(pp); } } - sprintf(nbuf, "%s(%d)", me, getpid()); + sprintf(nbuf, "%s(%d)", me, no_sessions); yaz_log_init(control_block.loglevel, nbuf, 0); /* ensure that bend_stop is not called when each child exits - - only for the main process .. - */ + only for the main process .. */ control_block.bend_stop = 0; } else /* parent */ @@ -508,9 +534,9 @@ static void listener(IOCHAN h, int event) pth_attr_set (attr, PTH_ATTR_JOINABLE, FALSE); pth_attr_set (attr, PTH_ATTR_STACK_SIZE, 32*1024); pth_attr_set (attr, PTH_ATTR_NAME, "session"); - yaz_log (LOG_LOG, "pth_spawn begin"); + yaz_log (LOG_DEBUG, "pth_spawn begin"); child_thread = pth_spawn (attr, new_session, new_line); - yaz_log (LOG_LOG, "pth_spawn finish"); + yaz_log (LOG_DEBUG, "pth_spawn finish"); pth_attr_destroy (attr); } else @@ -521,7 +547,7 @@ static void listener(IOCHAN h, int event) } else if (event == EVENT_TIMEOUT) { - yaz_log(LOG_LOG, "Shutting down listener."); + yaz_log(log_server, "Shutting down listener."); iochan_destroy(h); } else @@ -573,8 +599,8 @@ static void *new_session (void *vp) #else a = 0; #endif - yaz_log(LOG_LOG, "Starting session %d from %s", - no_sessions, a ? a : "[Unknown]"); + yaz_log(log_session, "Starting session from %s (pid=%d)", + a ? a : "[Unknown]", getpid()); if (max_sessions && no_sessions == max_sessions) control_block.one_shot = 1; if (control_block.threads) @@ -608,7 +634,7 @@ static void inetd_connection(int what) iochan_setdata(chan, assoc); iochan_settimeout(chan, 60); addr = cs_addrstr(line); - yaz_log(LOG_LOG, "Inetd association from %s", + yaz_log(log_session, "Inetd association from %s", addr ? addr : "[UNKNOWN]"); assoc->cs_get_mask = EVENT_INPUT; } @@ -647,15 +673,18 @@ static int add_listener(char *where, int what) else mode = "static"; - yaz_log(LOG_LOG, "Adding %s %s listener on %s", mode, + yaz_log(log_server, "Adding %s %s listener on %s", mode, what == PROTO_SR ? "SR" : "Z3950", where); - l = cs_create_host(where, 0, &ap); + l = cs_create_host(where, 2, &ap); if (!l) { - yaz_log(LOG_FATAL|LOG_ERRNO, "Failed to listen on %s", where); + yaz_log(LOG_FATAL, "Failed to listen on %s", where); return -1; } + if (*control_block.cert_fname) + cs_set_ssl_certificate_file(l, control_block.cert_fname); + if (cs_bind(l, ap, CS_SERVER) < 0) { yaz_log(LOG_FATAL|LOG_ERRNO, "Failed to bind to %s", where); @@ -706,8 +735,8 @@ static void statserv_reset(void) int statserv_start(int argc, char **argv) { - int ret; - + int ret = 0; + char sep; #ifdef WIN32 /* We need to initialize the thread list */ ThreadList_Initialize(); @@ -715,27 +744,78 @@ int statserv_start(int argc, char **argv) #endif #ifdef WIN32 - if ((me = strrchr (argv[0], '\\'))) - me++; - else - me = argv[0]; + sep='\\'; #else - me = argv[0]; + sep='/'; #endif + if ((me = strrchr (argv[0], sep))) + me++; /* get the basename */ + else + me = argv[0]; + programname=argv[0]; + if (control_block.options_func(argc, argv)) return(1); if (control_block.bend_start) (*control_block.bend_start)(&control_block); #ifdef WIN32 - yaz_log (LOG_LOG, "Starting server %s", me); + yaz_log (log_server, "Starting server %s", me); + if (!pListener && *control_block.default_listen) + add_listener(control_block.default_listen, + control_block.default_proto); + + if (!pListener) + return 1; #else /* UNIX */ if (control_block.inetd) inetd_connection(control_block.default_proto); else { - yaz_log (LOG_LOG, "Starting server %s pid=%d", me, getpid()); + if (control_block.background) + { + switch (fork()) + { + case 0: + break; + case -1: + return 1; + default: + _exit(0); + } + + if (setsid() < 0) + return 1; + + close(0); + close(1); + close(2); + open("/dev/null",O_RDWR); + dup(0); dup(0); + } + if (!pListener && *control_block.default_listen) + add_listener(control_block.default_listen, + control_block.default_proto); + + if (!pListener) + return 1; + + if (*control_block.pid_fname) + { + FILE *f = fopen(control_block.pid_fname, "w"); + if (!f) + { + yaz_log(LOG_FATAL|LOG_ERRNO, "Couldn't create %s", + control_block.pid_fname); + exit(0); + } + fprintf(f, "%ld", (long) getpid()); + fclose(f); + } + + yaz_log (log_server, "Starting server %s pid=%d", programname, getpid()); + #if 0 sigset_t sigs_to_block; @@ -766,8 +846,6 @@ int statserv_start(int argc, char **argv) } /* UNIX */ #endif - - if ((pListener == NULL) && *control_block.default_listen) add_listener(control_block.default_listen, control_block.default_proto); @@ -776,7 +854,7 @@ int statserv_start(int argc, char **argv) ret = 1; else { - yaz_log(LOG_LOG, "Entering event loop."); + yaz_log(LOG_DEBUG, "Entering event loop."); ret = event_loop(&pListener); } return ret; @@ -787,7 +865,12 @@ int check_options(int argc, char **argv) int ret = 0, r; char *arg; - while ((ret = options("1a:iszSTl:v:u:c:w:t:k:d:D:", argv, argc, &arg)) != -2) + /* set default log level */ + control_block.loglevel = yaz_log_mask_str(STAT_DEFAULT_LOG_LEVEL); + yaz_log_init_level(control_block.loglevel); + + while ((ret = options("1a:iszSTl:v:u:c:w:t:k:d:A:p:DC:", + argv, argc, &arg)) != -2) { switch (ret) { @@ -826,7 +909,7 @@ int check_options(int argc, char **argv) yaz_log_init(control_block.loglevel, me, control_block.logfile); break; case 'v': - control_block.loglevel = yaz_log_mask_str(arg); + control_block.loglevel = yaz_log_mask_str_x(arg,control_block.loglevel); yaz_log_init(control_block.loglevel, me, control_block.logfile); break; case 'a': @@ -838,6 +921,9 @@ int check_options(int argc, char **argv) case 'c': strcpy(control_block.configname, arg ? arg : ""); break; + case 'C': + strcpy(control_block.cert_fname, arg ? arg : ""); + break; case 'd': strcpy(control_block.daemon_name, arg ? arg : ""); break; @@ -867,17 +953,29 @@ int check_options(int argc, char **argv) return 1; } break; - case 'D': + case 'A': max_sessions = atoi(arg); break; + case 'p': + if (strlen(arg) >= sizeof(control_block.pid_fname)) + { + yaz_log(LOG_FATAL, "pid fname too long"); + exit(1); + } + strcpy(control_block.pid_fname, arg); + break; + case 'D': + control_block.background = 1; + break; default: fprintf(stderr, "Usage: %s [ -a -v " " -l -u -c -t " - " -k -d " - " -ziST1 -w ... ]\n", me); + " -k -d -p -C certfile" + " -ziDST1 -w ... ]\n", me); return 1; } } + get_logbits(1); return 0; }