]> git.sur5r.net Git - openldap/commitdiff
Added NT service support
authorHoward Chu <hyc@openldap.org>
Mon, 3 Mar 2003 11:47:16 +0000 (11:47 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 3 Mar 2003 11:47:16 +0000 (11:47 +0000)
servers/slurpd/Makefile.in
servers/slurpd/args.c
servers/slurpd/fm.c
servers/slurpd/globals.c
servers/slurpd/globals.h
servers/slurpd/main.c
servers/slurpd/nt_svc.c [new file with mode: 0644]
servers/slurpd/proto-slurp.h
servers/slurpd/re.c
servers/slurpd/slurp.h

index b647edb2bde8e59306c05c6804e96752e84ecbff..b44f3b40ef904e7ef1829a5cdc80bb223d756908 100644 (file)
@@ -10,12 +10,17 @@ XPROGRAMS = sslurpd
 
 XSRCS  = version.c
 
+NT_SRCS        = nt_svc.c
+NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
+
 SRCS   =       admin.c args.c ch_malloc.c config.c \
                fm.c globals.c ldap_op.c lock.c main.c re.c \
-               reject.c replica.c replog.c ri.c rq.c sanity.c st.c
+               reject.c replica.c replog.c ri.c rq.c sanity.c st.c \
+               $(@PLAT@_SRCS)
 OBJS   =       admin.o args.o ch_malloc.o config.o \
                fm.o globals.o ldap_op.o lock.o main.o re.o \
-               reject.o replica.o replog.o ri.o rq.o sanity.o st.o
+               reject.o replica.o replog.o ri.o rq.o sanity.o st.o \
+               $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
index b7147ab22f5afab1b3a943591b5dd1b08323bf8b..97dd2bd4df9c16040374d820394dcf909d19dba3 100644 (file)
@@ -44,6 +44,7 @@ usage( char *name )
 #else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
     fprintf( stderr, "\t\t[-t tmp-dir] [-o]\n" );
 #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
+    fprintf( stderr, "\t\t[-n service-name]\n" );
 }
 
 
@@ -67,7 +68,7 @@ doargs(
        g->myname = strdup( g->myname + 1 );
     }
 
-    while ( (i = getopt( argc, argv, "d:f:or:t:" )) != EOF ) {
+    while ( (i = getopt( argc, argv, "d:f:n:or:t:" )) != EOF ) {
        switch ( i ) {
        case 'd':       /* set debug level and 'do not detach' flag */
            g->no_detach = 1;
@@ -109,6 +110,10 @@ doargs(
        case 'f':       /* slapd config file */
            g->slapd_configfile = strdup( optarg );
            break;
+       case 'n':       /* NT service name *.
+           if ( g->serverName ) free( g->serverName );
+           g->serverName = strdup( optarg );
+           break;
        case 'o':
            g->one_shot_mode = 1;
            break;
index 6725a604aa7c1cc0a285933d500ca23d1af8eeee..50740f25b5bf225ec1fba51078f7fcdba05edef2 100644 (file)
@@ -36,7 +36,6 @@
  */
 static char *get_record LDAP_P(( FILE * ));
 static void populate_queue LDAP_P(( char *f ));
-static RETSIGTYPE set_shutdown LDAP_P((int));
 
 
 /*
@@ -60,11 +59,14 @@ fm(
         * LDAP_SIGUSR2 - causes a shutdown
      */
     (void) SIGNAL( LDAP_SIGUSR1, do_nothing );
-    (void) SIGNAL( LDAP_SIGUSR2, set_shutdown );
-    (void) SIGNAL( SIGTERM, set_shutdown );
-    (void) SIGNAL( SIGINT, set_shutdown );
+    (void) SIGNAL( LDAP_SIGUSR2, slurp_set_shutdown );
+    (void) SIGNAL( SIGTERM, slurp_set_shutdown );
+    (void) SIGNAL( SIGINT, slurp_set_shutdown );
 #ifdef SIGHUP
-    (void) SIGNAL( SIGHUP, set_shutdown );
+    (void) SIGNAL( SIGHUP, slurp_set_shutdown );
+#endif
+#ifdef SIGBREAK
+    (void) SIGNAL( SIGBREAK, slurp_set_shutdown );
 #endif
 
     if ( sglob->one_shot_mode ) {
@@ -155,11 +157,15 @@ fm(
 /*
  * Set a global flag which signals that we're shutting down.
  */
-static RETSIGTYPE
-set_shutdown(int sig)
+RETSIGTYPE
+slurp_set_shutdown(int sig)
 {
     int        i;
 
+#if HAVE_NT_SERVICE_MANAGER && SIGBREAK
+    if (sig == SIGBREAK) return do_nothing( sig );
+#endif
+
     sglob->slurpd_shutdown = 1;                                /* set flag */
     ldap_pvt_thread_kill( sglob->fm_tid, LDAP_SIGUSR1 );       /* wake up file mgr */
     sglob->rq->rq_lock( sglob->rq );                   /* lock queue */
@@ -168,7 +174,7 @@ set_shutdown(int sig)
        (sglob->replicas[ i ])->ri_wake( sglob->replicas[ i ]);
     }
     sglob->rq->rq_unlock( sglob->rq );                 /* unlock queue */
-    (void) SIGNAL_REINSTALL( sig, set_shutdown );      /* reinstall handlers */
+    (void) SIGNAL_REINSTALL( sig, slurp_set_shutdown );        /* reinstall handlers */
 }
 
 
index 8a1cecbd52791e560469dcb5cce45f766d71c180..5ff11118a0c2a8ba5dbbbb25ce804f2242ec8e5e 100644 (file)
@@ -39,7 +39,6 @@ int ldap_syslog_level = 0;
 #endif
 int ldap_debug = 0;
 
-
 /*
  * Initialize the globals
  */
@@ -53,12 +52,17 @@ init_globals( void )
        return NULL;
     }
 
+#ifdef HAVE_NT_SERVICE_MANAGER
+    g->slapd_configfile = ".\\slapd.conf";
+    g->slurpd_rdir = ".\\replica";
+#else
     g->slapd_configfile = SLAPD_DEFAULT_CONFIGFILE;
+    g->slurpd_rdir = DEFAULT_SLURPD_REPLICA_DIR "/replica";
+#endif
     g->no_work_interval = DEFAULT_NO_WORK_INTERVAL;
     g->slurpd_shutdown = 0;
     g->num_replicas = 0;
     g->replicas = NULL;
-    g->slurpd_rdir = DEFAULT_SLURPD_REPLICA_DIR "/replica";
     strcpy( g->slurpd_status_file, DEFAULT_SLURPD_STATUS_FILE );
     g->slapd_replogfile[ 0 ] = '\0';
     g->slurpd_replogfile[ 0 ] = '\0';
@@ -66,6 +70,7 @@ init_globals( void )
     g->one_shot_mode = 0;
     g->no_detach = 0;
     g->myname = NULL;
+    g->serverName = NULL;
     g->srpos = 0L;
     if ( St_init( &(g->st)) < 0 ) {
        fprintf( stderr, "Cannot initialize status data\n" );
index fbbca495916669e4147473cedb0700e98c703ff4..7aba1c67278947d1b5f04138cc1864204976664b 100644 (file)
@@ -53,6 +53,8 @@ typedef struct globals {
     int no_detach;
     /* Name of program */
     char *myname;
+    /* NT service name */
+    char *serverName;
     /* Current offset into slurpd replica logfile */
     off_t srpos;
     /* mutex to serialize access to reject file */
index 3525146aedc22aa9484f88500f2787bc5e0e58a6..3220853fb7f0d97fb46ab51e0b37e29fa6deb1e4 100644 (file)
 
 #include <ldap_pvt.h>
 
-int
-main(
-    int                argc,
-    char       **argv
-)
+#ifdef HAVE_NT_SERVICE_MANAGER
+#define        MAIN_RETURN(x)  return
+#define SERVICE_EXIT( e, n )   do { \
+       if ( is_NT_Service ) { \
+               lutil_ServiceStatus.dwWin32ExitCode = (e); \
+               lutil_ServiceStatus.dwServiceSpecificExitCode = (n); \
+       } \
+} while ( 0 )
+#else
+#define SERVICE_EXIT( e, n )
+#define        MAIN_RETURN(x)  return(x)
+#endif
+
+#ifdef HAVE_NT_SERVICE_MANAGER
+void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
+#else
+int main( int argc, char **argv )
+#endif
 {
 #ifdef NO_THREADS
     /* Haven't yet written the non-threaded version */
@@ -44,7 +57,7 @@ main(
     return( 1 );
 #else
 
-    int                        i;
+    int                        i, rc = 0;
 
     /* initialize thread package */
     ldap_pvt_thread_initialize();
@@ -55,14 +68,60 @@ main(
      */
     if (( sglob = init_globals()) == NULL ) {
        fprintf( stderr, "Out of memory initializing globals\n" );
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_NOT_ENOUGH_MEMORY, 0 );
+       rc = 1;
+       goto stop;
     }
 
+#ifdef HAVE_NT_SERVICE_MANAGER
+       {
+               int *i;
+               char *newConfigFile;
+               char *regService = NULL;
+
+               if ( is_NT_Service ) {
+                       sglob->serverName = argv[0];
+                       lutil_CommenceStartupProcessing( sglob->serverName, slurp_set_shutdown );
+                       if ( strcmp(sglob->serverName, SERVICE_NAME) )
+                           regService = sglob->serverName;
+               }
+
+               i = (int*)lutil_getRegParam( regService, "DebugLevel" );
+               if ( i != NULL ) 
+               {
+                       ldap_debug = *i;
+#ifdef NEW_LOGGING
+                       lutil_log_initialize( argc, argv );
+                       LDAP_LOG( SLURPD, INFO, 
+                               "main: new debug level from registry is: %d\n", 
+                               ldap_debug, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", ldap_debug, 0, 0 );
+#endif
+               }
+
+               newConfigFile = (char*)lutil_getRegParam( regService, "ConfigFile" );
+               if ( newConfigFile != NULL ) 
+               {
+                       sglob->slapd_configfile = newConfigFile;
+#ifdef NEW_LOGGING
+                       LDAP_LOG( SLURPD, INFO, 
+                               "main: new config file from registry is: %s\n", sglob->slapd_configfile, 0, 0 );
+#else
+                       Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", sglob->slapd_configfile, 0, 0 );
+#endif
+
+               }
+       }
+#endif
+
     /*
      * Process command-line args and fill in globals.
      */
     if ( doargs( argc, argv, sglob ) < 0 ) {
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
+       rc = 1;
+       goto stop;
     }
 
     /*
@@ -72,13 +131,17 @@ main(
        fprintf( stderr,
                "Errors encountered while processing config file \"%s\"\n",
                sglob->slapd_configfile );
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
+       rc = 1;
+       goto stop;
     }
 
 #ifdef HAVE_TLS
        if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx() ) {
                fprintf( stderr, "TLS Initialization failed.\n" );
-               exit( EXIT_FAILURE);
+               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
+               rc = 1;
+               goto stop;
        }
 #endif
 
@@ -87,7 +150,9 @@ main(
      */
     if ( mkdir(sglob->slurpd_rdir, 0755) == -1 && errno != EEXIST) {
        perror(sglob->slurpd_rdir);
-       exit( 1 );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
+       rc = 1;
+       goto stop;
     }
 
     /*
@@ -96,7 +161,9 @@ main(
     if ( sglob->st->st_read( sglob->st )) {
        fprintf( stderr, "Malformed slurpd status file \"%s\"\n",
                sglob->slurpd_status_file, 0, 0 );
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 17 );
+       rc = 1;
+       goto stop;
     }
 
     /*
@@ -104,7 +171,9 @@ main(
      * Check for any fatal error conditions before we get started
      */
      if ( sanity() < 0 ) {
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
+       rc = 1;
+       goto stop;
     }
 
     /*
@@ -116,6 +185,10 @@ main(
        lutil_detach( 0, 0 );
 #endif
 
+#ifdef HAVE_NT_EVENT_LOG
+       if (is_NT_Service) lutil_LogStartedEvent( sglob->serverName, ldap_debug, sglob->slapd_configfile, "n/a" );
+#endif
+
     /*
      * Start the main file manager thread (in fm.c).
      */
@@ -129,7 +202,9 @@ main(
        Debug( LDAP_DEBUG_ANY, "file manager ldap_pvt_thread_create failed\n",
                0, 0, 0 );
 #endif
-       exit( EXIT_FAILURE );
+       SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
+       rc = 1;
+       goto stop;
 
     }
 
@@ -147,6 +222,10 @@ main(
        start_replica_thread( sglob->replicas[ i ]);
     }
 
+#ifdef HAVE_NT_SERVICE_MANAGER
+    if ( started_event ) ldap_pvt_thread_cond_signal( &started_event );
+#endif
+
     /*
      * Wait for the fm thread to finish.
      */
@@ -161,6 +240,14 @@ main(
        ldap_pvt_thread_join( sglob->replicas[ i ]->ri_tid, (void *) NULL );
     }
 
+stop:
+#ifdef HAVE_NT_SERVICE_MANAGER
+       if (is_NT_Service) {
+               ldap_pvt_thread_cond_destroy( &started_event );
+               lutil_LogStoppedEvent( sglob->serverName );
+               lutil_ReportShutdownComplete();
+       }
+#endif
     /* destroy the thread package */
     ldap_pvt_thread_destroy();
 
@@ -169,6 +256,6 @@ main(
 #else
     Debug( LDAP_DEBUG_ANY, "slurpd: terminated.\n", 0, 0, 0 );
 #endif
-       return 0;
+       MAIN_RETURN(rc);
 #endif /* !NO_THREADS */
 }
diff --git a/servers/slurpd/nt_svc.c b/servers/slurpd/nt_svc.c
new file mode 100644 (file)
index 0000000..9be6d49
--- /dev/null
@@ -0,0 +1,101 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+#include <stdio.h>
+#include <ac/string.h>
+#include <ac/stdlib.h>
+#include "slurp.h"
+#include "lutil.h"
+
+#ifdef HAVE_NT_SERVICE_MANAGER
+
+/* in main.c */
+void WINAPI ServiceMain( DWORD argc, LPTSTR *argv );
+
+int main( int argc, LPTSTR *argv )
+{
+       int             length;
+       char    filename[MAX_PATH], *fname_start;
+
+       /*
+        * Because the service was registered as SERVICE_WIN32_OWN_PROCESS,
+        * the lpServiceName element of the SERVICE_TABLE_ENTRY will be
+        * ignored.
+        */
+
+       SERVICE_TABLE_ENTRY             DispatchTable[] = {
+               {       "",     (LPSERVICE_MAIN_FUNCTION) ServiceMain   },
+               {       NULL,                   NULL    }
+       };
+
+       /*
+        * set the service's current directory to the installation directory
+        * for the service. this way we don't have to write absolute paths
+        * in the configuration files
+        */
+       GetModuleFileName( NULL, filename, sizeof( filename ) );
+       fname_start = strrchr( filename, *LDAP_DIRSEP );
+
+       if ( argc > 1 ) {
+               if ( _stricmp( "install", argv[1] ) == 0 ) 
+               {
+                       char *svcName = SERVICE_NAME;
+                       char *displayName = "OpenLDAP Replication Service";
+                       BOOL auto_start = FALSE;
+
+                       if ( (argc > 2) && (argv[2] != NULL) )
+                               svcName = argv[2];
+
+                       if ( argc > 3 && argv[3])
+                               displayName = argv[3];
+
+                       if ( argc > 4 && stricmp(argv[4], "auto") == 0)
+                               auto_start = TRUE;
+
+                       strcat(filename, " service");
+                       if ( !lutil_srv_install(svcName, displayName, filename, auto_start) ) 
+                       {
+                               fputs( "service failed installation ...\n", stderr  );
+                               return EXIT_FAILURE;
+                       }
+                       fputs( "service has been installed ...\n", stderr  );
+                       return EXIT_SUCCESS;
+               }
+
+               if ( _stricmp( "remove", argv[1] ) == 0 ) 
+               {
+                       char *svcName = SERVICE_NAME;
+                       if ( (argc > 2) && (argv[2] != NULL) )
+                               svcName = argv[2];
+                       if ( !lutil_srv_remove(svcName, filename) ) 
+                       {
+                               fputs( "failed to remove the service ...\n", stderr  );
+                               return EXIT_FAILURE;
+                       }
+                       fputs( "service has been removed ...\n", stderr );
+                       return EXIT_SUCCESS;
+               }
+               if ( _stricmp( "service", argv[1] ) == 0 )
+               {
+                       is_NT_Service = 1;
+                       *fname_start = '\0';
+                       SetCurrentDirectory( filename );
+               }
+       }
+
+       if (is_NT_Service)
+       {
+               StartServiceCtrlDispatcher(DispatchTable);
+       } else
+       {
+               ServiceMain( argc, argv );
+       }
+
+       return EXIT_SUCCESS;
+}
+
+#endif
index 5fec1060d18db92e58cef4146154c94d3f553908..bdcce9ad688fda088a725e2e9d702995c5d78f6b 100644 (file)
@@ -38,6 +38,7 @@ void ch_free LDAP_P(( void *p ));
 /* fm.c */
 void *fm       LDAP_P((void *arg));
 RETSIGTYPE do_nothing  LDAP_P((int i));
+RETSIGTYPE slurp_set_shutdown LDAP_P((int));
 
 /* globals.c */
 extern struct globals *sglob;
index 1100396a8707b279c5ecdc320a397779ca778141..f063c39f96e82f9559ef941ffc59d0813fa0cec5 100644 (file)
 #include <ac/string.h>
 #include <ac/ctype.h>
 
+#include "../slapd/slap.h"
+
 #include "slurp.h"
 #include "globals.h"
 
-#include "../slapd/slap.h"
-
 /* Forward references */
 static Rh      *get_repl_hosts LDAP_P(( char *, int *, char ** ));
 static int     gettype LDAP_P(( char * ));
index 63afb0792a75f183bcff166108ee691317f857eb..43f310dc623d0c0cf0274160840de94716264a49 100644 (file)
@@ -49,6 +49,9 @@
 #define S_IWGRP 0
 #endif
 
+#undef SERVICE_NAME
+#define SERVICE_NAME   OPENLDAP_PACKAGE "-slurpd"
+
 /* Default directory for slurpd's private copy of replication logs */
 #define        DEFAULT_SLURPD_REPLICA_DIR      LDAP_RUNDIR LDAP_DIRSEP "openldap-slurp"