X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fstatserv.c;h=19db7f49d9d4d98d26249e618549419b692aa241;hb=af2e686d7372a0a2f4175cbe46d99fadd64bb465;hp=d63e349a548aa5cfcaef13575b1dfa1f85aa49a6;hpb=8258e03b8aca7dd78c650b6461e240e3f22cb8dd;p=yaz-moved-to-github.git diff --git a/src/statserv.c b/src/statserv.c index d63e349..19db7f4 100644 --- a/src/statserv.c +++ b/src/statserv.c @@ -5,7 +5,7 @@ * NT threaded server code by * Chas Woodfield, Fretwell Downing Informatics. * - * $Id: statserv.c,v 1.21 2005-02-02 20:25:37 adam Exp $ + * $Id: statserv.c,v 1.25 2005-03-05 12:14:12 adam Exp $ */ /** @@ -64,11 +64,15 @@ static IOCHAN pListener = NULL; static struct gfs_server *gfs_server_list = 0; +static struct gfs_listen *gfs_listen_list = 0; static NMEM gfs_nmem = 0; static char *me = "statserver"; /* log prefix */ static char *programname="statserver"; /* full program name */ -#if YAZ_POSIX_THREADS +#ifdef WIN32 +DWORD current_control_tls; +static int init_control_tls = 0; +#elif YAZ_POSIX_THREADS static pthread_key_t current_control_tls; static int init_control_tls = 0; #else @@ -114,7 +118,7 @@ statserv_options_block control_block = { "", /* PID fname */ 0, /* background daemon */ "", /* SSL certificate filename */ - "", /* XML config filename */ + "" /* XML config filename */ }; static int max_sessions = 0; @@ -209,7 +213,22 @@ static struct gfs_server * gfs_server_new() memcpy(&n->cb, &control_block, sizeof(control_block)); n->next = 0; n->host = 0; - n->port = 0; + n->listen_ref = 0; + n->cql_transform = 0; + n->server_node_ptr = 0; + return n; +} + +static struct gfs_listen * gfs_listen_new(const char *id, + const char *address) +{ + struct gfs_listen *n = nmem_malloc(gfs_nmem, sizeof(*n)); + if (id) + n->id = nmem_strdup(gfs_nmem, id); + else + n->id = 0; + n->next = 0; + n->address = nmem_strdup(gfs_nmem, address); return n; } @@ -230,13 +249,14 @@ int control_association(association *assoc, const char *host, int force_open) struct gfs_server *gfs; for (gfs = gfs_server_list; gfs; gfs = gfs->next) { - int port_match = 0; + int listen_match = 0; int host_match = 0; if ( !gfs->host || (host && gfs->host && !strcmp(host, gfs->host))) host_match = 1; - if (assoc->client_chan->port == gfs->port) - port_match= 1; - if (port_match && host_match) + if (!gfs->listen_ref || + gfs->listen_ref == assoc->client_chan->chan_id) + listen_match = 1; + if (listen_match && host_match) { if (force_open || (assoc->last_control != &gfs->cb && assoc->backend)) @@ -248,19 +268,28 @@ int control_association(association *assoc, const char *host, int force_open) xfree(assoc->init); assoc->init = 0; } + assoc->cql_transform = gfs->cql_transform; + assoc->server_node_ptr = gfs->server_node_ptr; assoc->last_control = &gfs->cb; statserv_setcontrol(&gfs->cb); + yaz_log(YLOG_DEBUG, "server select: %s", gfs->cb.configname); return 1; } } statserv_setcontrol(0); assoc->last_control = 0; + assoc->cql_transform = 0; + assoc->server_node_ptr = 0; + yaz_log(YLOG_DEBUG, "server select: no match"); return 0; } else { statserv_setcontrol(&control_block); assoc->last_control = &control_block; + assoc->cql_transform = 0; + assoc->server_node_ptr = 0; + yaz_log(YLOG_DEBUG, "server select: config=%s", control_block.configname); return 1; } } @@ -268,6 +297,7 @@ int control_association(association *assoc, const char *host, int force_open) static void xml_config_read() { struct gfs_server **gfsp = &gfs_server_list; + struct gfs_listen **gfslp = &gfs_listen_list; #if HAVE_XML2 xmlNodePtr ptr = xml_config_get_root(); @@ -275,33 +305,75 @@ static void xml_config_read() return; for (ptr = ptr->children; ptr; ptr = ptr->next) { - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "server")) + struct _xmlAttr *attr; + if (ptr->type != XML_ELEMENT_NODE) + continue; + attr = ptr->properties; + if (!strcmp((const char *) ptr->name, "listen")) { - xmlNodePtr ptr_children = ptr->children; + /* + tcp:@:9999 + */ + const char *id = 0; + const char *address = + nmem_dup_xml_content(gfs_nmem, ptr->children); + for ( ; attr; attr = attr->next) + if (!strcmp(attr->name, "id") + && attr->children && attr->children->type == XML_TEXT_NODE) + id = nmem_dup_xml_content(gfs_nmem, attr->children); + if (address) + { + *gfslp = gfs_listen_new(id, address); + gfslp = &(*gfslp)->next; + *gfslp = 0; /* make listener list consistent for search */ + } + } + else if (!strcmp((const char *) ptr->name, "server")) + { + xmlNodePtr ptr_server = ptr; xmlNodePtr ptr; - + const char *listenref = 0; + + for ( ; attr; attr = attr->next) + if (!strcmp(attr->name, "listenref") + && attr->children && attr->children->type == XML_TEXT_NODE) + listenref = nmem_dup_xml_content(gfs_nmem, attr->children); *gfsp = gfs_server_new(); - for (ptr = ptr_children; ptr; ptr = ptr->next) + (*gfsp)->server_node_ptr = ptr_server; + if (listenref) { - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "host")) + int id_no; + struct gfs_listen *gl = gfs_listen_list; + for (id_no = 1; gl; gl = gl->next, id_no++) + if (gl->id && !strcmp(gl->id, listenref)) + { + (*gfsp)->listen_ref = id_no; + break; + } + if (!gl) + yaz_log(YLOG_WARN, "Non-existent listenref '%s' in server " + "config element", listenref); + } + for (ptr = ptr_server->children; ptr; ptr = ptr->next) + { + if (ptr->type != XML_ELEMENT_NODE) + continue; + if (!strcmp((const char *) ptr->name, "host")) { (*gfsp)->host = nmem_dup_xml_content(gfs_nmem, ptr->children); } - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "port")) - { - (*gfsp)->port = atoi(nmem_dup_xml_content(gfs_nmem, - ptr->children)); - } - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "config")) + if (!strcmp((const char *) ptr->name, "config")) { strcpy((*gfsp)->cb.configname, nmem_dup_xml_content(gfs_nmem, ptr->children)); } + if (!strcmp((const char *) ptr->name, "cql2rpn")) + { + (*gfsp)->cql_transform = cql_transform_open_fname( + nmem_dup_xml_content(gfs_nmem, ptr->children) + ); + } } gfsp = &(*gfsp)->next; } @@ -312,6 +384,14 @@ static void xml_config_read() static void xml_config_open() { +#ifdef WIN32 + init_control_tls = 1; + current_control_tls = TlsAlloc(); +#elif YAZ_POSIX_THREADS + init_control_tls = 1; + pthread_key_create(¤t_control_tls, 0); +#endif + gfs_nmem = nmem_create(); #if HAVE_XML2 if (control_block.xml_config[0] == '\0') @@ -327,7 +407,6 @@ static void xml_config_open() } } xml_config_read(); - #endif } @@ -342,34 +421,24 @@ static void xml_config_close() #endif gfs_server_list = 0; nmem_destroy(gfs_nmem); +#ifdef WIN32 + if (init_control_tls) + TlsFree(current_control_tls); +#elif YAZ_POSIX_THREADS + if (init_control_tls) + pthread_key_delete(current_control_tls); +#endif } static void xml_config_add_listeners() { -#define MAX_PORTS 200 - struct gfs_server *gfs = gfs_server_list; - int i, ports[MAX_PORTS]; - for (i = 0; inext) + for (id_no = 1; gfs; gfs = gfs->next, id_no++) { - int port = gfs->port; - if (port) - { - for (i = 0; iaddress) + add_listener(gfs->address, id_no); } } @@ -593,6 +662,7 @@ void __cdecl event_loop_thread (IOCHAN iochan) static void listener(IOCHAN h, int event) { COMSTACK line = (COMSTACK) iochan_getdata(h); + IOCHAN parent_chan = line->user; association *newas; int res; HANDLE newHandle; @@ -625,7 +695,7 @@ static void listener(IOCHAN h, int event) yaz_log(YLOG_DEBUG, "Accept ok"); if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, - EVENT_INPUT))) + EVENT_INPUT, parent_chan->chan_id))) { yaz_log(YLOG_FATAL, "Failed to create iochan"); iochan_destroy(h); @@ -634,7 +704,7 @@ static void listener(IOCHAN h, int event) yaz_log(YLOG_DEBUG, "Creating association"); if (!(newas = create_association(new_chan, new_line, - control_block.apdu_file))) + control_block.apdufile))) { yaz_log(YLOG_FATAL, "Failed to create new assoc."); iochan_destroy(h); @@ -702,9 +772,6 @@ void statserv_closedown() iochan_destroy(p); } xml_config_close(); -#if YAZ_POSIX_THREADS - pthread_key_delete(current_control_tls); -#endif } void sigterm(int sig) @@ -839,7 +906,7 @@ static void *new_session (void *vp) } if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, mask, - parent_chan->port))) + parent_chan->chan_id))) { yaz_log(YLOG_FATAL, "Failed to create iochan"); return 0; @@ -982,7 +1049,12 @@ static void catchchld(int num) statserv_options_block *statserv_getcontrol(void) { -#if YAZ_POSIX_THREADS +#ifdef WIN32 + if (init_control_tls) + return (statserv_options_block *) TlsGetValue(current_control_tls); + else + return &control_block; +#elif YAZ_POSIX_THREADS if (init_control_tls) return pthread_getspecific(current_control_tls); else @@ -996,7 +1068,10 @@ statserv_options_block *statserv_getcontrol(void) void statserv_setcontrol(statserv_options_block *block) { -#if YAZ_POSIX_THREADS +#ifdef WIN32 + if (init_control_tls) + TlsSetValue(current_control_tls, block); +#elif YAZ_POSIX_THREADS if (init_control_tls) pthread_setspecific(current_control_tls, block); #else @@ -1032,11 +1107,6 @@ int statserv_start(int argc, char **argv) if (control_block.options_func(argc, argv)) return 1; -#if YAZ_POSIX_THREADS - init_control_tls = 1; - pthread_key_create(¤t_control_tls, 0); -#endif - xml_config_open(); xml_config_bend_start(); @@ -1308,8 +1378,9 @@ int statserv_main(int argc, char **argv, bend_initresult *(*bend_init)(bend_initrequest *r), void (*bend_close)(void *handle)) { - control_block.bend_init = bend_init; - control_block.bend_close = bend_close; + struct statserv_options_block *cb = &control_block; + cb->bend_init = bend_init; + cb->bend_close = bend_close; /* Lets setup the Arg structure */ ArgDetails.argc = argc;