[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