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
#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" );
}
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;
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;
*/
static char *get_record LDAP_P(( FILE * ));
static void populate_queue LDAP_P(( char *f ));
-static RETSIGTYPE set_shutdown LDAP_P((int));
/*
* 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 ) {
/*
* 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 */
(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 */
}
#endif
int ldap_debug = 0;
-
/*
* Initialize the globals
*/
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';
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" );
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 */
#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 */
return( 1 );
#else
- int i;
+ int i, rc = 0;
/* initialize thread package */
ldap_pvt_thread_initialize();
*/
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;
}
/*
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
*/
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;
}
/*
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;
}
/*
* 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;
}
/*
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).
*/
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;
}
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.
*/
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();
#else
Debug( LDAP_DEBUG_ANY, "slurpd: terminated.\n", 0, 0, 0 );
#endif
- return 0;
+ MAIN_RETURN(rc);
#endif /* !NO_THREADS */
}
--- /dev/null
+/* $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
/* 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;
#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 * ));
#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"