Windows service (re-)integration
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 60008ac..a977c23 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.96 2006/08/15 20:12:36 david__schmidt Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,9 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.96  2006/08/15 20:12:36  david__schmidt
+ *    Windows service integration
+ *
  *    Revision 1.95  2006/08/03 02:46:41  david__schmidt
  *    Incorporate Fabian Keil's patch work:\rhttp://www.fabiankeil.de/sourcecode/privoxy/
  *
@@ -642,6 +645,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp
 # ifndef _WIN_CONSOLE
 #  include "w32log.h"
 # endif /* ndef _WIN_CONSOLE */
+# include "w32svrapi.h"
 
 #else /* ifndef _WIN32 */
 
@@ -1876,6 +1880,34 @@ int main(int argc, const char *argv[])
     */
    while (++argc_pos < argc)
    {
+#ifdef _WIN32
+      /* Check to see if the service must be installed or uninstalled */
+      if (strncmp(argv[argc_pos], "--install", 9) == 0)
+      {
+         const char *pName = argv[argc_pos] + 9;
+         if (*pName == ':')
+            pName++;
+         exit( (install_service(pName)) ? 0 : 1 );
+      }
+      else if (strncmp(argv[argc_pos], "--uninstall", + 11) == 0)
+      {
+         const char *pName = argv[argc_pos] + 11;
+         if (*pName == ':')
+            pName++;
+         exit((uninstall_service(pName)) ? 0 : 1);
+      }
+      else if (strcmp(argv[argc_pos], "--service" ) == 0)
+      {
+         bRunAsService = TRUE;
+         w32_set_service_cwd();
+         atexit(w32_service_exit_notify);
+      }
+      else
+#endif /* defined(_WIN32) */
+
+
+#if !defined(_WIN32) || defined(_WIN_CONSOLE)
+
       if (strcmp(argv[argc_pos], "--help") == 0)
       {
          usage(argv[0]);
@@ -1927,8 +1959,7 @@ int main(int argc, const char *argv[])
       }
 
 #endif /* defined(unix) */
-
-      else
+#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
       {
          configfile = argv[argc_pos];
       }
@@ -2151,6 +2182,37 @@ int main(int argc, const char *argv[])
 }
 #endif /* defined unix */
 
+#ifdef _WIN32
+   /* This will be FALSE unless the command line specified --service
+    */
+   if (bRunAsService)
+   {
+      /* Yup, so now we must attempt to establish a connection 
+       * with the service dispatcher. This will only work if this
+       * process was launched by the service control manager to
+       * actually run as a service. If this isn't the case, i've
+       * known it take around 30 seconds or so for the call to return.
+       */
+
+      /* The StartServiceCtrlDispatcher won't return until the service is stopping */
+      if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable))
+      {
+         /* Service has run, and at this point is now being stopped, so just return */
+         return 0;
+      }
+
+#ifdef _WIN_CONSOLE
+      printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n");
+#endif
+      /* An error occurred. Usually it's because --service was wrongly specified
+       * and we were unable to connect to the Service Control Dispatcher because
+       * it wasn't expecting us and is therefore not listening.
+       *
+       * For now, just continue below to call the listen_loop function.
+       */
+   }
+#endif /* def _WIN32 */
+
    listen_loop();
 
    /* NOTREACHED */