/*
- * Copyright (c) 1995-2002, Index Data
+ * Copyright (c) 1995-2003, 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.82 2002-05-17 12:48:29 adam Exp $
+ * $Id: statserv.c,v 1.94 2003-02-18 21:27:53 adam Exp $
*/
#include <stdio.h>
"", /* diagnostic output to stderr */
"tcp:@:9999", /* default listener port */
PROTO_Z3950, /* default application protocol */
- 60, /* idle timeout (minutes) */
+ 15, /* idle timeout (minutes) */
1024*1024, /* maximum PDU size (approx.) to allow */
"default-config", /* configuration name to pass to backend */
"", /* set user id */
0, /* default value for inet deamon */
0, /* handle (for service, etc) */
0, /* bend_init handle */
- 0 /* bend_close handle */
+ 0, /* bend_close handle */
#ifdef WIN32
- ,"Z39.50 Server", /* NT Service Name */
+ "Z39.50 Server", /* NT Service Name */
"Server", /* NT application Name */
"", /* NT Service Dependencies */
- "Z39.50 Server" /* NT Service Display Name */
+ "Z39.50 Server", /* NT Service Display Name */
#endif /* WIN32 */
+ 0 /* SOAP handlers */
};
/*
yaz_log(LOG_DEBUG, "Setting timeout %d", control_block.idle_timeout);
iochan_setdata(new_chan, newas);
- iochan_settimeout(new_chan, control_block.idle_timeout * 60);
+ iochan_settimeout(new_chan, 60);
/* Now what we need todo is create a new thread with this iochan as
the parameter */
}
}
+int statserv_must_terminate(void)
+{
+ return 0;
+}
+
#else /* ! WIN32 */
-/* To save having an #ifdef in event_loop we need to define this empty function */
+static int term_flag = 0;
+/* To save having an #ifdef in event_loop we need to
+ define this empty function
+*/
+int statserv_must_terminate(void)
+{
+ return term_flag;
+}
+
void statserv_remove(IOCHAN pIOChannel)
{
}
if (control_block.bend_stop)
(*control_block.bend_stop)(&control_block);
-
for (p = pListener; p; p = p->next)
+ {
iochan_destroy(p);
+ }
}
void sigterm(int sig)
{
- statserv_closedown();
- exit (0);
+ term_flag = 1;
}
static void *new_session (void *vp);
}
sprintf(nbuf, "%s(%d)", me, getpid());
yaz_log_init(control_block.loglevel, nbuf, 0);
+ /* ensure that bend_stop is not called when each child exits -
+ only for the main process ..
+ */
+ control_block.bend_stop = 0;
}
else /* parent */
{
char dummy[1];
int res;
- if ((res = read(hand[0], dummy, 1)) < 0 && errno != EINTR)
+ if ((res = read(hand[0], dummy, 1)) < 0 &&
+ yaz_errno() != EINTR)
{
yaz_log(LOG_FATAL|LOG_ERRNO, "handshake read");
return;
if ((res = cs_listen_check(line, 0, 0, control_block.check_ip,
control_block.daemon_name)) < 0)
{
- yaz_log(LOG_WARN, "cs_listen failed");
+ yaz_log(LOG_WARN|LOG_ERRNO, "cs_listen failed");
return;
}
else if (res == 1)
new_session(new_line);
#endif
}
+ else if (event == EVENT_TIMEOUT)
+ {
+ yaz_log(LOG_LOG, "Shutting down listener.");
+ iochan_destroy(h);
+ }
else
{
yaz_log(LOG_FATAL, "Bad event on listener.");
iochan_destroy(h);
- return;
}
}
newas->cs_get_mask = cs_get_mask;
iochan_setdata(new_chan, newas);
- iochan_settimeout(new_chan, control_block.idle_timeout * 60);
+ iochan_settimeout(new_chan, 60);
a = cs_addrstr(new_line);
yaz_log(LOG_LOG, "Starting session %d from %s",
no_sessions, a ? a : "[Unknown]");
return 0;
}
-#endif /* WIN32 */
+/* UNIX */
+#endif
static void inetd_connection(int what)
{
if ((assoc = create_association(chan, line)))
{
iochan_setdata(chan, assoc);
- iochan_settimeout(chan, control_block.idle_timeout * 60);
+ iochan_settimeout(chan, 60);
addr = cs_addrstr(line);
yaz_log(LOG_LOG, "Inetd association from %s",
addr ? addr : "[UNKNOWN]");
}
#ifndef WIN32
-/* For windows we don't need to catch the signals */
+/* UNIX only (for windows we don't need to catch the signals) */
static void catchchld(int num)
{
while (waitpid(-1, 0, WNOHANG) > 0)
;
signal(SIGCHLD, catchchld);
}
-#endif /* WIN32 */
+#endif
statserv_options_block *statserv_getcontrol(void)
{
memcpy(&control_block, block, sizeof(*block));
}
+void statserv_add_soap_handler(int (*h)(struct bend_soap_rr *rr),
+ const char *ns)
+{
+ struct bend_soap_handler *sh = (struct bend_soap_handler *)
+ xmalloc(sizeof(*sh));
+
+ sh->handler = h;
+ sh->ns = xstrdup(ns);
+ sh->next = control_block.soap_handlers;
+ control_block.soap_handlers = sh;
+ yaz_log(LOG_LOG, "soap handler added");
+}
+
+static void statserv_reset(void)
+{
+ struct bend_soap_handler *sh = control_block.soap_handlers;
+
+ control_block.soap_handlers = 0;
+ while (sh)
+ {
+ struct bend_soap_handler *sh_next = sh->next;
+ xfree (sh->ns);
+ xfree (sh);
+ sh = sh_next;
+ }
+}
+
int statserv_start(int argc, char **argv)
{
int ret;
#ifdef WIN32
/* We need to initialize the thread list */
ThreadList_Initialize();
-#endif /* WIN32 */
+/* WIN32 */
+#endif
#ifdef WIN32
if ((me = strrchr (argv[0], '\\')))
if (control_block.bend_start)
(*control_block.bend_start)(&control_block);
#ifdef WIN32
- logf (LOG_LOG, "Starting server %s", me);
+ yaz_log (LOG_LOG, "Starting server %s", me);
#else
+/* UNIX */
if (control_block.inetd)
inetd_connection(control_block.default_proto);
else
{
- logf (LOG_LOG, "Starting server %s pid=%d", me, getpid());
+ yaz_log (LOG_LOG, "Starting server %s pid=%d", me, getpid());
#if 0
sigset_t sigs_to_block;
exit(1);
}
}
-#endif /* WIN32 */
-
+/* UNIX */
+#endif
+
+
if ((pListener == NULL) && *control_block.default_listen)
add_listener(control_block.default_listen,
control_block.default_proto);
fprintf(stderr, "Usage: %s [ -a <pdufile> -v <loglevel>"
" -l <logfile> -u <user> -c <config> -t <minutes>"
" -k <kilobytes> -d <daemon>"
- " -ziST -w <directory> <listender-addr>... ]\n", me);
+ " -ziST1 -w <directory> <listender-addr>... ]\n", me);
return 1;
}
}
/* Now setup the service with the service controller */
SetupService(argc, argv, &ArgDetails, SZAPPNAME,
cb->service_name, /* internal service name */
- cb->service_name, /* displayed name of the service */
+ cb->service_display_name, /* displayed name */
SZDEPENDENCIES);
return 0;
}
{
/* Stops the app */
statserv_closedown();
+ statserv_reset();
}
+/* WIN32 */
#else
+/* UNIX */
int statserv_main(int argc, char **argv,
bend_initresult *(*bend_init)(bend_initrequest *r),
void (*bend_close)(void *handle))
statserv_setcontrol(cb);
ret = statserv_start (argc, argv);
statserv_closedown ();
+ statserv_reset();
return ret;
}
#endif