Added function yaz_log_xml_errors.
[yaz-moved-to-github.git] / src / statserv.c
index 5556cd1..63a5efb 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 1995-2006, Index Data ApS
+ * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
  * NT threaded server code by
  *   Chas Woodfield, Fretwell Downing Informatics.
  *
- * $Id: statserv.c,v 1.43 2006-09-27 11:39:02 adam Exp $
+ * $Id: statserv.c,v 1.52 2007-11-12 08:57:45 adam Exp $
  */
 
 /**
@@ -85,15 +85,13 @@ static statserv_options_block *current_control_block = 0;
 /*
  * default behavior.
  */
-#define STAT_DEFAULT_LOG_LEVEL "none,fatal,warn,log,server,session,request"
-/* the 'none' clears yaz' own default settings, including [log] */
+#define STAT_DEFAULT_LOG_LEVEL "server,session,request"
 
 int check_options(int argc, char **argv);
 statserv_options_block control_block = {
     1,                          /* dynamic mode */
     0,                          /* threaded mode */
     0,                          /* one shot (single session) */
-    0, /* __UNUSED_loglevel */
     "",                         /* no PDUs */
     "",                         /* diagnostic output to stderr */
     "tcp:@:9999",               /* default listener port */
@@ -185,7 +183,7 @@ static char *nmem_dup_xml_content(NMEM n, xmlNodePtr ptr)
             len += xmlStrlen(p->content);
     }
     /* now allocate for the string */
-    str = nmem_malloc(n, len);
+    str = (unsigned char *) nmem_malloc(n, len);
     *str = '\0'; /* so we can use strcat */
     for (p = ptr; p; p = p->next)
     {
@@ -214,12 +212,14 @@ static char *nmem_dup_xml_content(NMEM n, xmlNodePtr ptr)
 
 static struct gfs_server * gfs_server_new(void)
 {
-    struct gfs_server *n = nmem_malloc(gfs_nmem, sizeof(*n));
+    struct gfs_server *n = (struct gfs_server *)
+        nmem_malloc(gfs_nmem, sizeof(*n));
     memcpy(&n->cb, &control_block, sizeof(control_block));
     n->next = 0;
     n->host = 0;
     n->listen_ref = 0;
     n->cql_transform = 0;
+    n->ccl_transform = 0;
     n->server_node_ptr = 0;
     n->directory = 0;
     n->docpath = 0;
@@ -233,7 +233,8 @@ static struct gfs_server * gfs_server_new(void)
 static struct gfs_listen * gfs_listen_new(const char *id, 
                                           const char *address)
 {
-    struct gfs_listen *n = nmem_malloc(gfs_nmem, sizeof(*n));
+    struct gfs_listen *n = (struct gfs_listen *)
+        nmem_malloc(gfs_nmem, sizeof(*n));
     if (id)
         n->id = nmem_strdup(gfs_nmem, id);
     else
@@ -416,6 +417,20 @@ static void xml_config_read(void)
                         nmem_dup_xml_content(gfs_nmem, ptr->children)
                         );
                 }
+                else if (!strcmp((const char *) ptr->name, "ccl2rpn"))
+                {
+                    char *name;
+                    FILE *f;
+
+                    name = nmem_dup_xml_content(gfs_nmem, ptr->children);
+                    if ((f = fopen(name, "r")) == 0) {
+                        yaz_log(YLOG_FATAL, "can't open CCL file '%s'", name);
+                        exit(1);
+                    }
+                    gfs->ccl_transform = ccl_qual_mk();
+                    ccl_qual_file (gfs->ccl_transform, f);
+                    fclose(f);
+                }
                 else if (!strcmp((const char *) ptr->name, "directory"))
                 {
                     gfs->directory = 
@@ -434,7 +449,7 @@ static void xml_config_read(void)
                 else if (!strcmp((const char *) ptr->name, "stylesheet"))
                 {
                     char *s = nmem_dup_xml_content(gfs_nmem, ptr->children);
-                    gfs->stylesheet = 
+                    gfs->stylesheet = (char *)
                         nmem_malloc(gfs_nmem, strlen(s) + 2);
                     sprintf(gfs->stylesheet, "/%s", s);
                 }
@@ -756,7 +771,7 @@ void statserv_closedown()
 
 void __cdecl event_loop_thread (IOCHAN iochan)
 {
-    event_loop (&iochan);
+    iochan_event_loop (&iochan);
 }
 
 /* WIN32 listener */
@@ -983,7 +998,7 @@ static void *new_session (void *vp)
     association *newas;
     IOCHAN new_chan;
     COMSTACK new_line = (COMSTACK) vp;
-    IOCHAN parent_chan = new_line->user;
+    IOCHAN parent_chan = (IOCHAN) new_line->user;
 
     unsigned cs_get_mask, cs_accept_mask, mask =  
         ((new_line->io_pending & CS_WANT_WRITE) ? EVENT_OUTPUT : 0) |
@@ -1028,7 +1043,7 @@ static void *new_session (void *vp)
         control_block.one_shot = 1;
     if (control_block.threads)
     {
-        event_loop(&new_chan);
+        iochan_event_loop(&new_chan);
     }
     else
     {
@@ -1112,7 +1127,11 @@ static int add_listener(char *where, int listen_id)
 
     if (cs_bind(l, ap, CS_SERVER) < 0)
     {
-        yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to bind to %s", where);
+        if (cs_errno(l) == CSYSERR)
+            yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to bind to %s", where);
+        else
+            yaz_log(YLOG_FATAL, "Failed to bind to %s: %s", where,
+                    cs_strerror(l));
         cs_close (l);
         return -1;
     }
@@ -1151,7 +1170,8 @@ statserv_options_block *statserv_getcontrol(void)
         return &control_block;
 #elif YAZ_POSIX_THREADS
     if (init_control_tls)
-        return pthread_getspecific(current_control_tls);
+        return (statserv_options_block *)
+            pthread_getspecific(current_control_tls);
     else
         return &control_block;
 #else
@@ -1323,7 +1343,7 @@ int statserv_start(int argc, char **argv)
     if (pListener == NULL)
         return 1;
     yaz_log(YLOG_DEBUG, "Entering event loop.");
-    return event_loop(&pListener);
+    return iochan_event_loop(&pListener);
 }
 
 static void option_copy(char *dst, const char *src)
@@ -1337,19 +1357,12 @@ int check_options(int argc, char **argv)
     int ret = 0, r;
     char *arg;
 
-    if (getenv("YAZ_LOG") == 0) {
-        /*
-         * Set default log level.  We want to avoid doing this if the
-         * user has already explicitly specified a preferred default
-         * log-level, hence the inelegant peek at the YAZ_LOG
-         * environment variable that will subsequently be interpreted
-         * by the YAZ logging module itself.
-         */
-        yaz_log_init_level(yaz_log_mask_str(STAT_DEFAULT_LOG_LEVEL));
-    }
+    yaz_log_init_level(yaz_log_mask_str(STAT_DEFAULT_LOG_LEVEL)); 
 
+    yaz_log_xml_errors(0, YLOG_WARN);
     get_logbits(1); 
-    while ((ret = options("1a:iszSTl:v:u:c:w:t:k:d:A:p:DC:f:m:",
+
+    while ((ret = options("1a:iszSTl:v:u:c:w:t:k:d:A:p:DC:f:m:r:",
                           argv, argc, &arg)) != -2)
     {
         switch (ret)
@@ -1395,12 +1408,10 @@ int check_options(int argc, char **argv)
             }
             yaz_log_time_format(arg);
             break;
-        case 'v': {
-            int default_level = yaz_log_mask_str(STAT_DEFAULT_LOG_LEVEL);
-            yaz_log_init_level(yaz_log_mask_str_x(arg, default_level));
+        case 'v':
+            yaz_log_init_level(yaz_log_mask_str(arg));
             get_logbits(1); 
             break;
-        }
         case 'a':
             option_copy(control_block.apdufile, arg);
             break;
@@ -1459,6 +1470,14 @@ int check_options(int argc, char **argv)
         case 'D':
             control_block.background = 1;
             break;
+        case 'r':
+            if (!arg || !(r = atoi(arg)))
+            {
+                fprintf(stderr, "%s: Specify positive size for -r.\n", me);
+                return(1);
+            }
+            yaz_log_init_max_size(r * 1024);
+            break;
         default:
             fprintf(stderr, "Usage: %s [ -a <pdufile> -v <loglevel>"
                     " -l <logfile> -u <user> -c <config> -t <minutes>"