Add new function nmem_strsplitx.
[yaz-moved-to-github.git] / src / sc.c
index 7102fa8..ef5d097 100644 (file)
--- a/src/sc.c
+++ b/src/sc.c
@@ -1,7 +1,14 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2008 Index Data
+ * Copyright (C) 1995-2011 Index Data
  * See the file LICENSE for details.
  */
+/**
+ * \file sc.c
+ * \brief Windows Service Control
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #ifdef WIN32
 #include <windows.h>
@@ -25,27 +32,34 @@ struct sc_s {
     char *display_name;
     int (*sc_main)(yaz_sc_t s, int argc, char **argv);
     void (*sc_stop)(yaz_sc_t s);
+    int argc;
+    char **argv;
+#ifdef WIN32
     SERVICE_STATUS_HANDLE   gSvcStatusHandle;
     SERVICE_STATUS          gSvcStatus;
+#endif
 };
 
 
 yaz_sc_t yaz_sc_create(const char *service_name, const char *display_name)
 {
-    yaz_sc_t s = xmalloc(sizeof(*s));
+    yaz_sc_t s = (yaz_sc_t) xmalloc(sizeof(*s));
 
-    s->service_name = xstrdup(service_name);
-    s->display_name = xstrdup(display_name);
+    s->service_name = service_name ? xstrdup(service_name) : 0;
+    s->display_name = display_name ? xstrdup(display_name) : 0;
     s->install_flag = 0;
     s->start_flag = 0;
     s->remove_flag = 0;
     s->run_flag = 0;
     s->sc_main = 0;
     s->sc_stop = 0;
+#ifdef WIN32
     s->gSvcStatusHandle = 0;
+#endif
     return s;
 }
 
+#ifdef WIN32
 static void parse_args(yaz_sc_t s, int *argc_p, char ***argv_p)
 {
     int skip_opt = 0;
@@ -81,16 +95,18 @@ static void parse_args(yaz_sc_t s, int *argc_p, char ***argv_p)
             /* -run dir */
             const char *dir = (*argv_p)[i+1];
             s->run_flag = 1;
-            chdir(dir);\r
-                skip_opt = 2;
-                break;
+            chdir(dir);
+            skip_opt = 2;
+            break;
         }
     }
-    *argc_p -= skip_opt;
+    *argc_p = *argc_p - skip_opt;
     for (; i < *argc_p; i++)
         (*argv_p)[i] = (*argv_p)[i + skip_opt];
 
+    /* now look for the service arguments */
     /* we must have a YAZ log file to work with */
+    skip_opt = 0;
     for (i = 1; i < *argc_p; i++)
     {
         const char *opt = (*argv_p)[i];
@@ -122,8 +138,10 @@ static void parse_args(yaz_sc_t s, int *argc_p, char ***argv_p)
     }
     if (s->run_flag)
     {   /* remove  -l logfile for a running service */
+        *argc_p = *argc_p - skip_opt;
         for (; i < *argc_p; i++)
             (*argv_p)[i] = (*argv_p)[i + skip_opt];
+
     }
 }
 
@@ -198,15 +216,18 @@ static void WINAPI sc_service_main(DWORD argc, char **argv)
 
     sc_ReportSvcStatus(s, SERVICE_START_PENDING, NO_ERROR, 3000);
 
-    ret_code = s->sc_main(s, argc, argv);
+    ret_code = s->sc_main(s, s->argc, s->argv);
        
     sc_ReportSvcStatus(s, SERVICE_STOPPED,
                        ret_code ? ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR, ret_code);
 }
+#endif
 
 void yaz_sc_running(yaz_sc_t s)
 {
+#ifdef WIN32
     sc_ReportSvcStatus(s, SERVICE_RUNNING, NO_ERROR, 0);
+#endif
 }
 
 int yaz_sc_program(yaz_sc_t s, int argc, char **argv,
@@ -216,6 +237,7 @@ int yaz_sc_program(yaz_sc_t s, int argc, char **argv,
 {
     s->sc_main = sc_main;
     s->sc_stop = sc_stop;
+#ifdef WIN32
     parse_args(s, &argc, &argv);
 
     if (s->install_flag || s->remove_flag)
@@ -248,7 +270,11 @@ int yaz_sc_program(yaz_sc_t s, int argc, char **argv,
             for (i = 1; i < argc; i++)
             {
                 wrbuf_puts(w, " ");
+                if (strchr(argv[i], ' '))
+                    wrbuf_puts(w, "\"");
                 wrbuf_puts(w, argv[i]);
+                if (strchr(argv[i], ' '))
+                    wrbuf_puts(w, "\"");
             }
             wrbuf_puts(w, " -run \"");
             wrbuf_puts(w, cwdstr);
@@ -328,18 +354,18 @@ int yaz_sc_program(yaz_sc_t s, int argc, char **argv,
         dt[1].lpServiceName = 0;
         dt[1].lpServiceProc = 0;
 
+        s->argc = argc;
+        s->argv = argv;
         if (!StartServiceCtrlDispatcher(dt))
         {
             yaz_log(YLOG_FATAL|YLOG_ERRNO, "Service %s could not be controlled",
                     s->service_name);
         }
+        return 0;
     }
-    else
-    {
-        /* run the program standalone (with no service) */
-        return s->sc_main(s, argc, argv);
-    }
-    return 0;
+#endif /* WIN32 */
+    /* run the program standalone (with no service) */
+    return s->sc_main(s, argc, argv);
 }
 
 void yaz_sc_destroy(yaz_sc_t *s)
@@ -353,6 +379,7 @@ void yaz_sc_destroy(yaz_sc_t *s)
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab