[svn] dirmngr - r258 - trunk/src

svn author marcus cvs at cvs.gnupg.org
Sat Aug 4 05:40:05 CEST 2007


Author: marcus
Date: 2007-08-04 05:39:35 +0200 (Sat, 04 Aug 2007)
New Revision: 258

Modified:
   trunk/src/ChangeLog
   trunk/src/dirmngr.c
   trunk/src/dirmngr.h
   trunk/src/get-path.c
   trunk/src/util.h
Log:
2007-08-04  Marcus Brinkmann  <marcus at g10code.de>

	* dirmngr.h (opt): Add member system_service.
	* dirmngr.c (opts) [HAVE_W32_SYSTEM]: New entry for option
	--service.
	(DEFAULT_SOCKET_NAME): Removed.
	(service_handle, service_status,
	w32_service_control) [HAVE_W32_SYSTEM]: New symbols.
	(main) [HAVE_W32_SYSTEM]: New entry point for --service.  Rename
	old function to ...
	(real_main) [HAVE_W32_SYSTEM]: ... this.  Use default_socket_name
	instead of DEFAULT_SOCKET_NAME, and similar for other paths.
	Allow colons in Windows socket path name, and implement --service
	option.	
	* util.h (dirmngr_sysconfdir, dirmngr_libexecdir, dirmngr_datadir,
	dirmngr_cachedir, default_socket_name): New prototypes.
	* get-path.c (dirmngr_sysconfdir, dirmngr_libexecdir,
	dirmngr_datadir, dirmngr_cachedir, default_socket_name): New
	functions.
	(DIRSEP_C, DIRSEP_S): New macros.


Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2007-08-03 08:08:07 UTC (rev 257)
+++ trunk/src/ChangeLog	2007-08-04 03:39:35 UTC (rev 258)
@@ -1,3 +1,24 @@
+2007-08-04  Marcus Brinkmann  <marcus at g10code.de>
+
+	* dirmngr.h (opt): Add member system_service.
+	* dirmngr.c (opts) [HAVE_W32_SYSTEM]: New entry for option
+	--service.
+	(DEFAULT_SOCKET_NAME): Removed.
+	(service_handle, service_status,
+	w32_service_control) [HAVE_W32_SYSTEM]: New symbols.
+	(main) [HAVE_W32_SYSTEM]: New entry point for --service.  Rename
+	old function to ...
+	(real_main) [HAVE_W32_SYSTEM]: ... this.  Use default_socket_name
+	instead of DEFAULT_SOCKET_NAME, and similar for other paths.
+	Allow colons in Windows socket path name, and implement --service
+	option.	
+	* util.h (dirmngr_sysconfdir, dirmngr_libexecdir, dirmngr_datadir,
+	dirmngr_cachedir, default_socket_name): New prototypes.
+	* get-path.c (dirmngr_sysconfdir, dirmngr_libexecdir,
+	dirmngr_datadir, dirmngr_cachedir, default_socket_name): New
+	functions.
+	(DIRSEP_C, DIRSEP_S): New macros.
+
 2007-08-03  Marcus Brinkmann  <marcus at g10code.de>
 
 	* get-path.c: Really add the file this time.

Modified: trunk/src/dirmngr.c
===================================================================
--- trunk/src/dirmngr.c	2007-08-03 08:08:07 UTC (rev 257)
+++ trunk/src/dirmngr.c	2007-08-04 03:39:35 UTC (rev 258)
@@ -66,6 +66,7 @@
   
   aServer,
   aDaemon,
+  aService,
   aListCRLs,
   aLoadCRL,
   aFetchCRL,
@@ -118,6 +119,9 @@
 
   { aServer,   "server",    256, N_("run in server mode (foreground)") },
   { aDaemon,   "daemon",    256, N_("run in daemon mode (background)") },
+#if HAVE_W32_SYSTEM
+  { aService,  "service",   256, N_("run as windows service (background)") },
+#endif
   { aListCRLs, "list-crls", 256, N_("list the contents of the CRL cache")},
   { aLoadCRL,  "load-crl",  256, N_("|FILE|load CRL from FILE into cache")},
   { aFetchCRL, "fetch-crl", 256, N_("|URL|fetch a CRL from URL")},
@@ -195,7 +199,6 @@
 
 #define DEFAULT_MAX_REPLIES 10
 #define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */
-#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket"
 
 /* For the cleanup handler we need to keep track of the socket's name. */
 static const char *socket_name;
@@ -471,8 +474,43 @@
   return 1; /* Handled. */
 }
 
+
+#ifdef HAVE_W32_SYSTEM
+/* The global status of our service.  */
+SERVICE_STATUS_HANDLE service_handle;
+SERVICE_STATUS service_status;
+
+DWORD WINAPI
+w32_service_control (DWORD control, DWORD event_type, LPVOID event_data,
+		     LPVOID context)
+{
+  /* event_type and event_data are not used here.  */
+  switch (control)
+    {
+    case SERVICE_CONTROL_STOP:
+    case SERVICE_CONTROL_SHUTDOWN:
+      service_status.dwCurrentState = SERVICE_STOP_PENDING;
+      SetServiceStatus (service_handle, &service_status); 
+
+      if (!shutdown_pending)
+        log_info (_("SIGTERM received - shutting down ...\n"));
+      shutdown_pending++;
+      break;
+
+    default:
+      log_info (_("unhandled control request %lu\n"), control);
+      break;
+    }
+  return 0;
+}
+#endif
+
 int
-main (int argc, char **argv )
+#ifdef HAVE_W32_SYSTEM
+real_main (int argc, char **argv)
+#else
+main (int argc, char **argv)
+#endif
 {
   enum cmd_and_opt_values cmd = 0;
   ARGPARSE_ARGS pargs;
@@ -494,6 +532,29 @@
   int rc;
   int homedir_seen = 0;
 
+#ifdef HAVE_W32_SYSTEM
+  /* The option will be set by main() below if we should run as a
+     system daemon.  */
+  if (opt.system_service)
+    {
+      service_handle
+	= RegisterServiceCtrlHandlerEx ("DirMngr",
+					&w32_service_control, NULL /*FIXME*/);
+      if (service_handle == 0)
+	log_error ("failed to register service control handler: ec=%d",
+		   (int) GetLastError ());
+      service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+      service_status.dwCurrentState = SERVICE_START_PENDING;
+      service_status.dwControlsAccepted
+	= SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+      service_status.dwWin32ExitCode = NO_ERROR;
+      service_status.dwServiceSpecificExitCode = NO_ERROR;
+      service_status.dwCheckPoint = 0;
+      service_status.dwWaitHint = 10000; /* 10 seconds timeout.  */
+      SetServiceStatus (service_handle, &service_status); 
+    }
+#endif
+
   set_strusage (my_strusage);
   log_set_prefix ("dirmngr", 1|4); 
   
@@ -555,7 +616,7 @@
   opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
 
   /* Other defaults.  */
-  socket_name = DEFAULT_SOCKET_NAME;
+  socket_name = default_socket_name ();
 
 
   /* Check whether we have a config file given on the commandline */
@@ -583,6 +644,12 @@
         }
       else if (pargs.r_opt == aDaemon)
         opt.system_daemon = 1;
+      else if (pargs.r_opt == aService)
+        {
+	  /* Redundant.  The main function takes care of it.  */
+	  opt.system_service = 1;
+	  opt.system_daemon = 1;
+	}
     }
 
   /* If --daemon has been given on the command line but not --homedir,
@@ -590,9 +657,9 @@
      this also overrides the GNUPGHOME environment variable.  */
   if (opt.system_daemon && !homedir_seen)
     {
-      opt.homedir = DIRMNGR_SYSCONFDIR;
-      opt.homedir_data = DIRMNGR_DATADIR;
-      opt.homedir_cache = DIRMNGR_CACHEDIR;
+      opt.homedir = dirmngr_sysconfdir ();
+      opt.homedir_data = dirmngr_datadir ();
+      opt.homedir_cache = dirmngr_cachedir ();
     }
 
   if (default_config)
@@ -638,6 +705,7 @@
         {
         case aServer: 
         case aDaemon:
+        case aService:
         case aShutdown: 
         case aFlush: 
 	case aListCRLs: 
@@ -803,17 +871,19 @@
           current_logfile = xstrdup (logfile);
         }
 
-      if (strchr (socket_name, ':') )
+#ifndef HAVE_W32_SYSTEM
+      if (strchr (socket_name, ':'))
         {
           log_error (_("colons are not allowed in the socket name\n"));
           dirmngr_exit (1);
         }
+#endif
       if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) 
         {
           log_error (_("name of socket too long\n"));
           dirmngr_exit (1);
         }
-   
+    
 #ifdef HAVE_W32_SYSTEM
       fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);
 #else
@@ -951,9 +1021,23 @@
       launch_reaper_thread ();
       cert_cache_init ();
       crl_cache_init ();
+#ifdef HAVE_W32_SYSTEM
+      if (opt.system_service)
+	{
+	  service_status.dwCurrentState = SERVICE_RUNNING;
+	  SetServiceStatus (service_handle, &service_status);
+	}
+#endif
       handle_connections (fd);
       close (fd);
       shutdown_reaper ();
+#ifdef HAVE_W32_SYSTEM
+      if (opt.system_service)
+	{
+	  service_status.dwCurrentState = SERVICE_STOPPED;
+	  SetServiceStatus (service_handle, &service_status);
+	}
+#endif
     }
   else if (cmd == aListCRLs)
     {
@@ -1094,6 +1178,42 @@
 }
 
 
+#ifdef HAVE_W32_SYSTEM
+int
+main (int argc, char *argv[])
+{
+  int i;
+
+  /* Find out if we run in daemon mode or on the command line.  */
+  for (i = 1; i < argc; i++)
+    if (!strcmp (argv[i], "--service"))
+      {
+	opt.system_service = 1;
+	opt.system_daemon = 1;
+	break;
+      }
+
+  if (!opt.system_service)
+    return real_main (argc, argv);
+  else
+    {
+      SERVICE_TABLE_ENTRY DispatchTable [] =
+	{
+	  /* Ignore warning.  */
+	  { "DirMngr", &real_main },
+	  { NULL, NULL }
+	};
+
+      if (!StartServiceCtrlDispatcher (DispatchTable))
+	log_error (_("failed to start service ctrl dispatcher: ec=%d\n"),
+		   (int) GetLastError ());
+
+      return 0;
+    }
+}
+#endif
+
+
 static void
 cleanup (void)
 {

Modified: trunk/src/dirmngr.h
===================================================================
--- trunk/src/dirmngr.h	2007-08-03 08:08:07 UTC (rev 257)
+++ trunk/src/dirmngr.h	2007-08-04 03:39:35 UTC (rev 258)
@@ -72,6 +72,7 @@
   char *http_wrapper_program; /* Override value for the HTTP wrapper
                                  program.  */
 
+  int system_service;   /* We are running as W32 service (implies daemon).  */
   int system_daemon;    /* We are running in system daemon mode.  */
   int running_detached; /* We are running in detached mode.  */
 

Modified: trunk/src/get-path.c
===================================================================
--- trunk/src/get-path.c	2007-08-03 08:08:07 UTC (rev 257)
+++ trunk/src/get-path.c	2007-08-04 03:39:35 UTC (rev 258)
@@ -48,6 +48,14 @@
 #define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
 #endif 
 
+#ifdef HAVE_DOSISH_SYSTEM
+#define DIRSEP_C '\\'
+#define DIRSEP_S "\\"
+#else
+#define DIRSEP_C '/'
+#define DIRSEP_S "/"
+#endif
+
 
 #if HAVE_W32_SYSTEM
 #define RTLD_LAZY 0
@@ -364,3 +372,140 @@
 
   return dir;
 }
+
+
+#ifdef HAVE_W32_SYSTEM
+static const char *
+w32_rootdir (void)
+{
+  static int got_dir;
+  static char dir[MAX_PATH+5];
+
+  if (!got_dir)
+    {
+      char *p;
+
+      if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
+        {
+          log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
+          *dir = 0;
+        }
+      got_dir = 1;
+      p = strrchr (dir, DIRSEP_C);
+      if (p)
+        *p = 0;
+      else
+        {
+          log_debug ("bad filename `%s' returned for this process\n", dir);
+          *dir = 0; 
+        }
+    }
+
+  if (*dir)
+    return dir;
+  /* Fallback to the hardwired value. */
+  return DIRMNGR_LIBEXECDIR;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+
+
+/* Return the name of the sysconfdir.  This is a static string.  This
+   function is required because under Windows we can't simply compile
+   it in.  */
+const char *
+dirmngr_sysconfdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  static char *name;
+
+  if (!name)
+    {
+      const char *s1, *s2;
+      s1 = w32_rootdir ();
+      s2 = DIRSEP_S "etc" DIRSEP_S "dirmngr";
+      name = xmalloc (strlen (s1) + strlen (s2) + 1);
+      strcpy (stpcpy (name, s1), s2);
+    }
+  return name;
+#else /*!HAVE_W32_SYSTEM*/
+  return DIRMNGR_SYSCONFDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Return the name of the libexec directory.  The name is allocated in
+   a static area on the first use.  This function won't fail. */
+const char *
+dirmngr_libexecdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  return w32_rootdir ();
+#else /*!HAVE_W32_SYSTEM*/
+  return DIRMNGR_LIBEXECDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+const char *
+dirmngr_datadir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  static char *name;
+
+  if (!name)
+    {
+      const char *s1, *s2;
+      s1 = w32_rootdir (); /* FIXME: /var in windows? */
+      s2 = DIRSEP_S "lib" DIRSEP_S "dirmngr";
+      name = xmalloc (strlen (s1) + strlen (s2) + 1);
+      strcpy (stpcpy (name, s1), s2);
+    }
+  return name;
+#else /*!HAVE_W32_SYSTEM*/
+  return DIRMNGR_DATADIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+const char *
+dirmngr_cachedir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  static char *name;
+
+  if (!name)
+    {
+      const char *s1, *s2;
+      s1 = w32_rootdir (); /* FIXME: /var in windows? */
+      s2 = DIRSEP_S "cache" DIRSEP_S "dirmngr";
+      name = xmalloc (strlen (s1) + strlen (s2) + 1);
+      strcpy (stpcpy (name, s1), s2);
+    }
+  return name;
+#else /*!HAVE_W32_SYSTEM*/
+  return DIRMNGR_CACHEDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+const char *
+default_socket_name (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  static char *name;
+
+  if (!name)
+    {
+      const char *s1, *s2;
+      s1 = w32_rootdir (); /* FIXME: /var in windows? */
+      s2 = DIRSEP_S "S.dirmngr";
+      name = xmalloc (strlen (s1) + strlen (s2) + 1);
+      strcpy (stpcpy (name, s1), s2);
+    }
+  return name;
+#else /*!HAVE_W32_SYSTEM*/
+  return "/var/run/dirmngr/socket"
+#endif /*!HAVE_W32_SYSTEM*/
+}

Modified: trunk/src/util.h
===================================================================
--- trunk/src/util.h	2007-08-03 08:08:07 UTC (rev 257)
+++ trunk/src/util.h	2007-08-04 03:39:35 UTC (rev 258)
@@ -87,5 +87,10 @@
 
 /* Find the dirmngr_ldap program image.  */
 const char *get_dirmngr_ldap_path (void);
+const char *dirmngr_sysconfdir (void);
+const char *dirmngr_libexecdir (void);
+const char *dirmngr_datadir (void);
+const char *dirmngr_cachedir (void);
+const char *default_socket_name (void);
 
 #endif /*UTIL_H*/




More information about the Gnupg-commits mailing list