29 #include <sys/types.h>
42 #include <libxml/parser.h>
43 #include <libxml/tree.h>
44 #include <libxml/xinclude.h>
60 #include <yaz/xmosi.h>
76 static char *
me =
"statserver";
79 DWORD current_control_tls;
80 static int init_control_tls = 0;
81 #elif YAZ_POSIX_THREADS
82 static pthread_key_t current_control_tls;
83 static int init_control_tls = 0;
91 #define STAT_DEFAULT_LOG_LEVEL "server,session,request"
160 if (!ptr || ptr->type != XML_ELEMENT_NODE ||
161 strcmp((
const char *) ptr->name,
"yazgfs"))
181 for (p = ptr; p; p = p->next)
183 if (p->type == XML_TEXT_NODE)
184 len += xmlStrlen(p->content);
189 for (p = ptr; p; p = p->next)
191 if (p->type == XML_TEXT_NODE)
201 strcat((
char *)str, (
const char *)cp);
205 cp = strlen((
const char *)str) + str;
269 char vhost[128], *cp;
272 strncpy(vhost, host, 127);
274 cp = strchr(vhost,
':');
285 int listen_match = 0;
298 if (listen_match && host_match)
351 for (ptr = ptr->children; ptr; ptr = ptr->next)
353 struct _xmlAttr *attr;
354 if (ptr->type != XML_ELEMENT_NODE)
356 attr = ptr->properties;
357 if (!strcmp((
const char *) ptr->name,
"listen"))
363 const char *address =
365 for ( ; attr; attr = attr->next)
366 if (!xmlStrcmp(attr->name, BAD_CAST
"id")
367 && attr->children && attr->children->type == XML_TEXT_NODE)
372 gfslp = &(*gfslp)->
next;
376 else if (!strcmp((
const char *) ptr->name,
"server"))
378 xmlNodePtr ptr_server = ptr;
380 const char *listenref = 0;
384 for ( ; attr; attr = attr->next)
385 if (!xmlStrcmp(attr->name, BAD_CAST
"listenref")
386 && attr->children && attr->children->type == XML_TEXT_NODE)
388 else if (!xmlStrcmp(attr->name, BAD_CAST
"id")
390 && attr->children->type == XML_TEXT_NODE)
403 sizeof(
int) * (num + 1));
404 for (i = 0; i < num; i++)
409 for (id_no = 1; gl; gl = gl->
next, id_no++)
410 if (gl->
id && !strcmp(gl->
id, refs[i]))
417 "in server config element", refs[i]);
421 for (ptr = ptr_server->children; ptr; ptr = ptr->next)
423 if (ptr->type != XML_ELEMENT_NODE)
425 if (!strcmp((
const char *) ptr->name,
"host"))
430 else if (!strcmp((
const char *) ptr->name,
"config"))
437 base_path, 0, fpath))
440 else if (!strcmp((
const char *) ptr->name,
"cql2rpn"))
451 "open CQL transform file '%s'", fname);
455 else if (!strcmp((
const char *) ptr->name,
"ccl2rpn"))
457 char *fname, fpath[1024];
464 if ((f = fopen(fname,
"r")) == 0) {
472 else if (!strcmp((
const char *) ptr->name,
"directory"))
477 else if (!strcmp((
const char *) ptr->name,
"docpath"))
482 else if (!strcmp((
const char *) ptr->name,
"maximumrecordsize"))
487 else if (!strcmp((
const char *) ptr->name,
"stylesheet"))
494 else if (!strcmp((
const char *) ptr->name,
495 "client_query_charset"))
500 else if (!strcmp((
const char *) ptr->name,
"explain"))
504 else if (!strcmp((
const char *) ptr->name,
"retrievalinfo"))
523 gfsp = &(*gfsp)->
next;
540 init_control_tls = 1;
541 current_control_tls = TlsAlloc();
542 #elif YAZ_POSIX_THREADS
543 init_control_tls = 1;
544 pthread_key_create(¤t_control_tls, 0);
549 if (fname[0] ==
'\0')
563 if (noSubstitutions == -1)
571 last_p = strrchr(fname,
603 if (init_control_tls)
604 TlsFree(current_control_tls);
605 #elif YAZ_POSIX_THREADS
606 if (init_control_tls)
607 pthread_key_delete(current_control_tls);
617 for (id_no = 1; gfs; gfs = gfs->
next, id_no++)
630 for (; gfs; gfs = gfs->
next)
656 for (; gfs; gfs = gfs->
next)
684 typedef struct _ThreadList ThreadList;
693 static ThreadList *pFirstThread;
694 static CRITICAL_SECTION Thread_CritSect;
695 static BOOL bInitialized = FALSE;
697 static void ThreadList_Initialize()
700 InitializeCriticalSection(&Thread_CritSect);
709 static void statserv_add(HANDLE hThread,
IOCHAN pIOChannel)
712 EnterCriticalSection(&Thread_CritSect);
716 ThreadList *pNewThread = (ThreadList *)
malloc(
sizeof(ThreadList));
717 pNewThread->hThread = hThread;
718 pNewThread->pIOChannel = pIOChannel;
719 pNewThread->pNext = pFirstThread;
720 pFirstThread = pNewThread;
723 LeaveCriticalSection(&Thread_CritSect);
730 EnterCriticalSection(&Thread_CritSect);
733 ThreadList *pCurrentThread = pFirstThread;
734 ThreadList *pNextThread;
735 ThreadList *pPrevThread =NULL;
738 for (; pCurrentThread != NULL; pCurrentThread = pNextThread)
741 if (pCurrentThread->pIOChannel == pIOChannel)
745 if (pPrevThread == NULL)
746 pFirstThread = pCurrentThread->pNext;
748 pPrevThread->pNext = pCurrentThread->pNext;
751 free(pCurrentThread);
759 pNextThread = pCurrentThread->pNext;
760 pPrevThread = pCurrentThread;
765 LeaveCriticalSection(&Thread_CritSect);
776 HANDLE *pThreadHandles = NULL;
780 EnterCriticalSection(&Thread_CritSect);
785 ThreadList *pCurrentThread = pFirstThread;
791 for (; pCurrentThread != NULL; pCurrentThread = pCurrentThread->pNext)
795 closesocket(pCurrentThread->pIOChannel->fd);
803 HANDLE *pCurrentHandle ;
806 pThreadHandles = (HANDLE *)
malloc(
sizeof(HANDLE) * iHandles);
807 pCurrentHandle = pThreadHandles;
809 for (pCurrentThread = pFirstThread;
810 pCurrentThread != NULL;
811 pCurrentThread = pCurrentThread->pNext, pCurrentHandle++)
814 *pCurrentHandle = pCurrentThread->hThread;
819 LeaveCriticalSection(&Thread_CritSect);
827 WaitForMultipleObjects(iHandles, pThreadHandles, TRUE, INFINITE);
830 free(pThreadHandles);
835 DeleteCriticalSection(&Thread_CritSect);
901 newHandle = (HANDLE) _beginthread(event_loop_thread, 0, new_chan);
902 if (newHandle == (HANDLE) -1)
910 statserv_add(newHandle, new_chan);
912 yaz_log(
YLOG_DEBUG,
"Created new thread, id = %ld iochan %p",(
long) newHandle, new_chan);
983 if ((res = fork()) < 0)
1015 #if YAZ_POSIX_THREADS
1016 pthread_t child_thread;
1017 pthread_create(&child_thread, 0,
new_session, new_line);
1018 pthread_detach(child_thread);
1046 unsigned cs_get_mask, cs_accept_mask,
mask =
1052 cs_accept_mask =
mask;
1085 no_sessions, a ? a :
"[Unknown]", (
long) getpid());
1122 addr ? addr :
"[UNKNOWN]");
1161 listen_id, (
long) getpid());
1201 for (; l; l = l->
next)
1209 while (waitpid(-1, 0, WNOHANG) > 0)
1218 if (init_control_tls)
1222 #elif YAZ_POSIX_THREADS
1223 if (init_control_tls)
1225 pthread_getspecific(current_control_tls);
1243 if (init_control_tls)
1244 TlsSetValue(current_control_tls, block);
1245 #elif YAZ_POSIX_THREADS
1246 if (init_control_tls)
1247 pthread_setspecific(current_control_tls, block);
1274 char vstr[20], sha1_str[41];
1279 printf(
"YAZ DLL/SO: %s %s\n", vstr, sha1_str);
1288 ThreadList_Initialize();
1298 if ((
me = strrchr(argv[0], sep)))
1368 while ((ret =
options(
"1a:iszSTl:v:u:c:w:t:k:Kd:A:p:DC:f:m:r:V",
1369 argv, argc, &arg)) != -2)
1385 fprintf(stderr,
"%s: SR protocol no longer supported\n",
me);
1392 #if YAZ_POSIX_THREADS
1396 fprintf(stderr,
"%s: Threaded mode not available.\n",
me);
1406 fprintf(stderr,
"%s: Specify time format for log file.\n",
me);
1431 if (!arg || !(r = atoi(arg)))
1433 fprintf(stderr,
"%s: Specify positive timeout for -t.\n",
me);
1439 if (!arg || !(r = atoi(arg)))
1441 fprintf(stderr,
"%s: Specify positive size for -k.\n",
me);
1469 fprintf(stderr,
"%s: Option -f unsupported since YAZ is compiled without Libxml2 support\n",
me);
1477 if (!arg || !(r = atoi(arg)))
1479 fprintf(stderr,
"%s: Specify positive size for -r.\n",
me);
1488 fprintf(stderr,
"Usage: %s [ -a <pdufile> -v <loglevel>"
1489 " -l <logfile> -u <user> -c <config> -t <minutes>"
1490 " -k <kilobytes> -d <daemon> -p <pidfile> -C certfile"
1491 " -zKiDSTV1 -m <time-format> -w <directory> <listener-addr>... ]\n",
me);
1514 cb->service_name, cb->service_display_name
void ccl_qual_file(CCL_bibset bibset, FILE *inf)
CCL_bibset ccl_qual_mk(void)
creates Bibset
COMSTACK cs_create_host(const char *vhost, int blocking, void **vp)
void cs_set_max_recv_bytes(COMSTACK cs, int max_recv_bytes)
const char * cs_strerror(COMSTACK h)
#define cs_bind(handle, ad, mo)
#define cs_addrstr(handle)
#define cs_accept(handle)
#define cs_createbysocket(sock, type, blocking, proto)
#define cs_fileno(handle)
struct comstack * COMSTACK
#define cs_listen(handle, ap, al)
#define cs_listen_check(handle, ap, al, cf, cd)
int yaz_daemon(const char *progname, unsigned int flags, void(*work)(void *data), void *data, const char *pidfile, const char *uid)
daemon utility.
Header for errno utilities.
int iochan_event_loop(IOCHAN *iochans, int *watch_sig)
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, int chan_id)
Definitions for event loop handling for GFS.
#define iochan_settimeout(i, t)
#define iochan_getdata(i)
#define iochan_destroy(i)
#define iochan_getnext(i)
#define iochan_setdata(i, d)
#define iochan_setflags(i, d)
void yaz_log_init_prefix(const char *prefix)
sets log message prefix
int yaz_log_mask_str(const char *str)
converts log level string to log level (integer)
void yaz_log_init_max_size(int mx)
sets limit in bytes for size for log file
void yaz_log_init_level(int level)
sets log level
void yaz_log_time_format(const char *fmt)
sets time format for log mesages
void yaz_log(int level, const char *fmt,...)
Writes log message.
void yaz_log_init_file(const char *fname)
sets log file
int yaz_log_module_level(const char *name)
returns level for module
#define YLOG_WARN
log level: warning
#define YLOG_FATAL
log level: fatal
#define YLOG_ERRNO
log level: append system error message
#define YLOG_DEBUG
log level: debugging
#define YLOG_LOG
log level: log (regular)
NMEM nmem_create(void)
returns new NMEM handle
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
void nmem_destroy(NMEM n)
destroys NMEM handle and memory associated with it
void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, char ***darray, int *num)
allocates sub strings out of string using certain delimitors
char * nmem_strdup_null(NMEM mem, const char *src)
allocates string on NMEM handle - allows NULL ptr buffer
char * nmem_strdup(NMEM mem, const char *src)
allocates string on NMEM handle (similar strdup)
int options(const char *desc, char **argv, int argc, char **arg)
command-line options parsing for main
Header for command line options parsing utilities.
int yaz_retrieval_configure(yaz_retrieval_t p, const xmlNode *ptr)
const char * yaz_retrieval_get_error(yaz_retrieval_t p)
yaz_retrieval_t yaz_retrieval_create()
void yaz_retrieval_set_path(yaz_retrieval_t p, const char *path)
void yaz_sc_destroy(yaz_sc_t *s)
frees service control handle
int yaz_sc_program(yaz_sc_t s, int argc, char **argv, int(*sc_main)(yaz_sc_t s, int argc, char **argv), void(*sc_stop)(yaz_sc_t s))
registers service controlled program
yaz_sc_t yaz_sc_create(const char *service_name, const char *display_name)
creates service handle
void yaz_sc_running(yaz_sc_t s)
signals that sc_main applicatio starts running
Header for Windows Service Control utility.
association * create_association(IOCHAN channel, COMSTACK link, const char *apdufile)
void ir_session(IOCHAN h, int event)
static void * new_session(void *vp)
static void option_copy(char *dst, const char *src)
static xmlDocPtr xml_config_doc
static struct gfs_server * gfs_server_new(const char *id)
int statserv_main(int argc, char **argv, bend_initresult *(*bend_init)(bend_initrequest *r), void(*bend_close)(void *handle))
static struct gfs_listen * gfs_listen_list
static int statserv_sc_main(yaz_sc_t s, int argc, char **argv)
static void gfs_server_chdir(struct gfs_server *gfs)
static char gfs_root_dir[FILENAME_MAX+1]
static void statserv_reset(void)
static char * programname
static void catchchld(int num)
static void remove_listeners(void)
static struct gfs_server * gfs_server_list
static void inetd_connection(int what)
int control_association(association *assoc, const char *host, int force_open)
static void listener(IOCHAN h, int event)
static void xml_config_close(void)
int check_options(int argc, char **argv)
void statserv_sc_stop(yaz_sc_t s)
static statserv_options_block * current_control_block
statserv_options_block control_block
#define STAT_DEFAULT_LOG_LEVEL
void statserv_setcontrol(statserv_options_block *block)
static int xml_config_add_listeners(void)
static void xml_config_read(const char *base_path)
void statserv_remove(IOCHAN pIOChannel)
static void xml_config_bend_start(void)
static char * nmem_dup_xml_content(NMEM n, xmlNodePtr ptr)
static void statserv_closedown(void)
static void normal_stop_handler(int num)
statserv_options_block * statserv_getcontrol(void)
static int add_listener(char *where, int listen_id)
static void daemon_handler(void *data)
static void get_logbits(int force)
static xmlNodePtr xml_config_get_root(void)
static void show_version(void)
static void xml_config_bend_stop(void)
static struct gfs_listen * gfs_listen_new(const char *id, const char *address)
static int xml_config_open(void)
static int log_sessiondetail
Header for GFS (Obsolete. Use yaz/backend.h)
struct bend_initrequest * init
struct gfs_server * server
statserv_options_block * last_control
Information for the Init handler.
result for init handler (must be filled by handler)
yaz_retrieval_t retrieval
cql_transform_t cql_transform
statserv_options_block cb
char * client_query_charset
char daemon_name[BEND_NAME_MAX]
char apdufile[BEND_NAME_MAX]
bend_initresult *(* bend_init)(bend_initrequest *r)
char cert_fname[BEND_NAME_MAX]
void(* bend_start)(struct statserv_options_block *p)
char pid_fname[BEND_NAME_MAX]
void(* bend_stop)(struct statserv_options_block *p)
enum oid_proto default_proto
char xml_config[BEND_NAME_MAX]
char setuid[BEND_NAME_MAX]
char logfile[BEND_NAME_MAX]
char configname[BEND_NAME_MAX]
int(* check_ip)(void *cd, const char *addr, int len, int type)
void(* bend_close)(void *handle)
int(* options_func)(int argc, char **argv)
int check_ip_tcpd(void *cd, const char *addr, int len, int type)
int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname)
COMSTACK tcpip_type(int s, int flags, int protocol, void *vp)
Header for TCP/IP + SSL COMSTACK.
char * yaz_filepath_resolve(const char *fname, const char *path, const char *base, char *fullpath)
resolve file on path
unsigned long yaz_version(char *version_str, char *sha1_str)
returns YAZ version
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
WRBUF wrbuf_alloc(void)
construct WRBUF
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
#define xfree(x)
utility macro which calls xfree_f
void yaz_log_xml_errors(const char *prefix, int log_level)
Makes Libxml2 and Libxslt log errors through yaz_log.
Header for YAZ iconv interface.
#define YAZ_VERSION
YAZ version as string.
#define YAZ_VERSION_SHA1
SHA1 ID for YAZ (Git)
void bend_close(void *handle)
bend_initresult * bend_init(bend_initrequest *q)