From b0aea66d1dd3deec393c373ef53ee9adfaed761e Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Thu, 17 Jun 1999 18:46:02 +0000 Subject: [PATCH] Recommit NT service changes (untested) with changes to resolve compiling errors on other platforms. Will need to update NT projects. --- servers/slapd/daemon.c | 90 ++++++++++++++++------- servers/slapd/main.c | 143 +++++++++++++++++++++++++++++++------ servers/slapd/proto-slap.h | 8 ++- 3 files changed, 192 insertions(+), 49 deletions(-) diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 148bb73afc..32cdf25d29 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1,4 +1,5 @@ #include "portable.h" +//#include "portable_err.h" #include @@ -22,18 +23,22 @@ int deny_severity = LOG_NOTICE; /* globals */ int dtblsize; +static int tcps; #ifdef HAVE_WINSOCK2 +// in nt_main.c +extern ldap_pvt_thread_cond_t started_event; /* forward reference */ void hit_socket(); /* In wsa_err.c */ char *WSAGetLastErrorString(); +static ldap_pvt_thread_t hit_tid; #define WAKE_LISTENER(w) \ do {\ if( w ) {\ ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );\ - hit_socket();\ + hit_socket(); \ }\ } while(0) #else @@ -45,9 +50,13 @@ do {\ } while(0) #endif +#ifndef HAVE_WINSOCK +static +#endif +volatile sig_atomic_t slapd_shutdown = 0; + static int daemon_initialized = 0; static ldap_pvt_thread_t listener_tid; -static volatile sig_atomic_t slapd_shutdown = 0; static volatile sig_atomic_t slapd_listener = 0; void sockinit(); @@ -119,17 +128,24 @@ void slapd_clr_write(int s, int wake) { FD_CLR( (unsigned) s, &slap_daemon.sd_writers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); + + if( wake ) { + ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); + } } void slapd_set_write(int s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); - assert( FD_ISSET( s, &slap_daemon.sd_actives) ); FD_SET( (unsigned) s, &slap_daemon.sd_writers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); + + if( wake ) { + ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); + } } void slapd_clr_read(int s, int wake) { @@ -141,6 +157,9 @@ void slapd_clr_read(int s, int wake) { ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); + if( wake ) { + ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); + } } void slapd_set_read(int s, int wake) { @@ -151,6 +170,10 @@ void slapd_set_read(int s, int wake) { FD_SET( (unsigned) s, &slap_daemon.sd_readers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); + + if( wake ) { + ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); + } } static void slapd_close(int s) { @@ -158,6 +181,8 @@ static void slapd_close(int s) { tcp_close(s); } + + int set_socket( struct sockaddr_in *addr ) { @@ -252,10 +277,14 @@ slapd_daemon_task( void *ptr ) { - int inetd = ((int *)ptr) [0]; - int tcps = ((int *)ptr) [1]; + int inetd; + struct slapd_args *args = (struct slapd_args *) ptr; + struct sockaddr_in *slapd_addr = args->addr; + + tcps = args->tcps; free( ptr ); + inetd = ( slapd_addr == NULL); if ( !daemon_initialized ) sockinit(); slapd_listener=1; @@ -289,6 +318,11 @@ slapd_daemon_task( slapd_add( 0 ); } +#ifdef HAVE_WINSOCK + if ( started_event != NULL ) + ldap_pvt_thread_cond_signal( &started_event ); +#endif + // initialization complete. Here comes the loop. while ( !slapd_shutdown ) { unsigned int i; int ns, nfds; @@ -302,7 +336,7 @@ slapd_daemon_task( #if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD) struct hostent *hp; #endif - struct timeval zero; + struct timeval zero; struct timeval *tvp; char *client_name; @@ -357,7 +391,11 @@ slapd_daemon_task( switch(ns = select( nfds, &readfds, &writefds, 0, tvp )) { case -1: { /* failure - try again */ +#ifdef HAVE_WINSOCK + int err = WSAGetLastError(); +#else int err = errno; +#endif if( err == EBADF && ++ebadf < SLAPD_EBADF_LIMIT) { continue; @@ -371,7 +409,8 @@ slapd_daemon_task( ? sys_errlist[err] : "unknown", 0 ); - slapd_shutdown = -1; + + slapd_shutdown = -1; } } continue; @@ -481,7 +520,6 @@ slapd_daemon_task( } #endif /* HAVE_TCPD */ - if( (id = connection_init(s, client_name, client_addr)) < 0 ) { Debug( LDAP_DEBUG_ANY, "daemon: connection_init(%d, %s, %s) failed.\n", @@ -548,7 +586,6 @@ slapd_daemon_task( if ( wd == tcps ) { continue; } - Debug( LDAP_DEBUG_CONNS, "daemon: write active on %d\n", wd, 0, 0 ); @@ -590,7 +627,6 @@ slapd_daemon_task( Debug ( LDAP_DEBUG_CONNS, "daemon: read activity on %d\n", rd, 0, 0 ); - /* * NOTE: it is possible that the connection was closed * and that the stream is now inactive. @@ -607,13 +643,13 @@ slapd_daemon_task( if( slapd_shutdown > 0 ) { Debug( LDAP_DEBUG_TRACE, - "daemon: shutdown requested (%d) and initiated.\n", - (int) slapd_shutdown, 0, 0 ); + "daemon: shutdown requested and initiated.\n", + 0, 0, 0 ); } else if ( slapd_shutdown < 0 ) { Debug( LDAP_DEBUG_TRACE, - "daemon: abnormal condition (%d), shutdown initiated.\n", - (int) slapd_shutdown, 0, 0 ); + "daemon: abnormal condition, shutdown initiated.\n", + 0, 0, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "daemon: no active streams, shutdown initiated.\n", @@ -624,9 +660,6 @@ slapd_daemon_task( slapd_close( tcps ); } - /* we only implement "quick" shutdown */ - connections_shutdown(); - ldap_pvt_thread_mutex_lock( &active_threads_mutex ); Debug( LDAP_DEBUG_ANY, "slapd shutdown: waiting for %d threads to terminate\n", @@ -636,16 +669,13 @@ slapd_daemon_task( } ldap_pvt_thread_mutex_unlock( &active_threads_mutex ); - slapd_listener = 0; return NULL; } -int slapd_daemon( int inetd, int tcps ) + +int slapd_daemon( struct slapd_args *args ) { int rc; - int *args = ch_malloc( sizeof( int[2] ) ); - args[0] = inetd; - args[1] = tcps; if ( !daemon_initialized ) sockinit(); @@ -717,25 +747,27 @@ void sockinit() daemon_initialized = 1; } /* The WinSock DLL is acceptable. Proceed. */ -void hit_socket( void ) +void hit_socket() { int s, on = 1; extern struct sockaddr_in bind_addr; /* throw something at the socket to terminate the select() in the daemon thread. */ if (( s = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) - Debug( LDAP_DEBUG_TRACE, + Debug( LDAP_DEBUG_ANY, "slap_set_shutdown: socket failed\n\tWSAGetLastError=%d (%s)\n", WSAGetLastError(), WSAGetLastErrorString(), 0 ); if ( ioctlsocket( s, FIONBIO, &on ) == -1 ) - Debug( LDAP_DEBUG_TRACE, + Debug( LDAP_DEBUG_ANY, "slap_set_shutdown:FIONBIO ioctl on %d faled\n\tWSAGetLastError=%d (%s)\n", s, WSAGetLastError(), WSAGetLastError() ); - + bind_addr.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); if ( connect( s, (struct sockaddr *)&bind_addr, sizeof( struct sockaddr_in )) == SOCKET_ERROR ) { + Debug( LDAP_DEBUG_ANY, + "hit_socket: error on connect: %d\n", WSAGetLastError(), 0 ); /* we can probably expect some error to occur here, mostly WSAEWOULDBLOCK */ } @@ -767,7 +799,11 @@ slap_set_shutdown( int sig ) ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); } #else - hit_socket(); + Debug( LDAP_DEBUG_TRACE, "Shutdown %d ordered", sig, 0 ); + // trying to "hit" the socket seems to always get a + // EWOULDBLOCK error, so just close the listen socket to + // break out of the select since we're shutting down anyway + tcp_close( tcps ); #endif /* reinstall self */ (void) SIGNAL( sig, slap_set_shutdown ); diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 6a96d847c0..8a42a012ea 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -13,12 +13,44 @@ #include "ldap_defaults.h" #include "slap.h" +#ifndef HAVE_WINSOCK #include "lutil.h" /* Get lutil_detach() */ +#endif #ifdef LDAP_SIGCHLD static RETSIGTYPE wait4child( int sig ); #endif +#ifdef HAVE_WINSOCK +#define SERVICE_NAME "OpenLDAP" + +struct sockaddr_in bind_addr; + +// in nt_main.c +extern SERVICE_STATUS SLAPDServiceStatus; +extern SERVICE_STATUS_HANDLE hSLAPDServiceStatus; +extern ldap_pvt_thread_cond_t started_event, stopped_event; +extern int is_NT_Service; + +void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, short port, int udp ); +void LogSlapdStoppedEvent( char *svc ); + +void CommenceStartupProcessing( LPCTSTR serviceName, + void(*stopper)(int)); +void ReportSlapdShutdownComplete( void ); +void *getRegParam( char *svc, char *value ); + +#define SERVICE_EXIT( e, n ) \ + if ( is_NT_Service ) \ +{ \ + SLAPDServiceStatus.dwWin32ExitCode = e; \ + SLAPDServiceStatus.dwServiceSpecificExitCode = n; \ +} +#else +#define SERVICE_EXIT( e, n ) +#endif + +short port = LDAP_PORT; /* * when more than one slapd is running on one machine, each one might have * it's own LOCAL for syslogging and must have its own pid/args files @@ -62,7 +94,7 @@ static void usage( char *name ) { fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]", name ); - fprintf( stderr, "\n [-a bind-address] [-i]" ); + fprintf( stderr, "\n [-a bind-address] [-i] [-u]" ); #if LDAP_CONNECTIONLESS fprintf( stderr, " [-c]" ); #endif @@ -80,39 +112,77 @@ usage( char *name ) time_t starttime; struct sockaddr_in bind_addr; +int tcps; -int -main( int argc, char **argv ) +#ifdef HAVE_WINSOCK +void WINAPI ServiceMain( DWORD argc, LPTSTR *argv ) +{ +#else +int main( int argc, char **argv ) { +#endif + int i; int inetd = 0; int rc; - int tcps; -#ifdef LDAP_CONNECTIONLESS + struct slapd_args args; int udp; +#if defined(HAVE_SETUID) && defined(HAVE_SETGID) + char *username = NULL; + char *groupname = NULL; #endif #ifdef LOG_LOCAL4 int syslogUser = DEFAULT_SYSLOG_USER; #endif -#if defined(HAVE_SETUID) && defined(HAVE_SETGID) - char *username = NULL, *groupname = NULL; +#ifdef HAVE_WINSOCK + char *configfile = ".\\slapd.conf"; +#else + char *configfile = SLAPD_DEFAULT_CONFIGFILE; #endif - char *configfile; char *serverName; int serverMode = SLAP_SERVER_MODE; - configfile = SLAPD_DEFAULT_CONFIGFILE; - (void) memset( (void*) &bind_addr, '\0', sizeof(bind_addr)); bind_addr.sin_family = AF_INET; bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind_addr.sin_port = htons(LDAP_PORT); + bind_addr.sin_port = htons(port); g_argc = argc; g_argv = argv; +#ifdef HAVE_WINSOCK + //if ( is_NT_Service ) + { + int *newPort; + int *newDebugLevel; + char *newConfigFile; + ldap_debug = 0xffff; + if ( is_NT_Service ) CommenceStartupProcessing( SERVICE_NAME, slap_set_shutdown ); + newPort = (int*)getRegParam( NULL, "Port" ); + if ( newPort != NULL ) + { + port = *newPort; + bind_addr.sin_port = htons(port); + Debug ( LDAP_DEBUG_ANY, "new port from registry is: %d\n", port, 0, 0 ); + } + newDebugLevel = (int*)getRegParam( NULL, "DebugLevel" ); + if ( newDebugLevel != NULL ) + { + slap_debug = *newDebugLevel; + Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 ); + } + newConfigFile = (char*)getRegParam( NULL, "ConfigFile" ); + if ( newConfigFile != NULL ) + { + configfile = newConfigFile; + Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", configfile, 0, 0 ); + } + } + +#endif + while ( (i = getopt( argc, argv, - "d:f:ia:p:s:" + "d:f:ia:p:s:u" #ifdef LOG_LOCAL4 "l:" #endif @@ -189,7 +259,7 @@ main( int argc, char **argv ) break; case 'p': { /* port on which to listen */ - short port = (short)atoi( optarg ); + port = (short)atoi( optarg ); if(! port ) { fprintf(stderr, "-p %s must be numeric\n", optarg); } else { @@ -234,7 +304,9 @@ main( int argc, char **argv ) default: usage( argv[0] ); - exit( 1 ); + rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 ); + goto stop; } } @@ -256,8 +328,6 @@ main( int argc, char **argv ) openlog( serverName, OPENLOG_OPTIONS ); #endif - tcps = set_socket( inetd ? NULL : &bind_addr ); - #if defined(HAVE_SETUID) && defined(HAVE_SETGID) if ( username != NULL || groupname != NULL ) slap_init_user( username, groupname ); @@ -265,14 +335,19 @@ main( int argc, char **argv ) if ( slap_init( serverMode, serverName ) != 0 ) { rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 ); goto destroy; } if ( read_config( configfile ) != 0 ) { rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 ); goto destroy; } + + tcps = set_socket( inetd ? NULL : &bind_addr ); + (void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing ); (void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown ); #ifdef SIGPIPE @@ -286,8 +361,12 @@ main( int argc, char **argv ) #ifdef LDAP_SIGCHLD (void) SIGNAL( LDAP_SIGCHLD, wait4child ); #endif +#ifdef HAVE_WINSOCK + // SIGBREAK is generated when Ctrl-Break is pressed. + (void) SIGNAL( SIGBREAK, slap_set_shutdown ); +#endif -#ifndef WIN32 +#ifndef HAVE_WINSOCK if(!inetd) { #ifdef LDAP_DEBUG lutil_detach( ldap_debug, 0 ); @@ -295,16 +374,19 @@ main( int argc, char **argv ) lutil_detach( 0, 0 ); #endif } -#endif /* WIN32 */ +#endif /* HAVE_WINSOC */ if ( slap_startup(-1) != 0 ) { rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); goto shutdown; } if(!inetd) { FILE *fp; + args.addr = &bind_addr; + Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 ); if (( slapd_pid_file != NULL ) && @@ -323,11 +405,25 @@ main( int argc, char **argv ) fprintf( fp, "\n" ); fclose( fp ); } + + } else { + args.addr = NULL; } + args.tcps = tcps; time( &starttime ); +#ifdef HAVE_WINSOCK + LogSlapdStartedEvent( SERVICE_NAME, slap_debug, configfile, port, udp ); +#endif + + rc = slapd_daemon( &args ); + +#ifdef HAVE_WINSOCK + // Throw away the event that we used during the startup process. + if ( is_NT_Service ) + ldap_pvt_thread_cond_destroy( &started_event ); +#endif - rc = slapd_daemon( inetd, tcps ); shutdown: /* remember an error during shutdown */ @@ -336,9 +432,16 @@ destroy: /* remember an error during destroy */ rc |= slap_destroy(); +stop: +#ifdef HAVE_WINSOCK + LogSlapdStoppedEvent( SERVICE_NAME ); +#endif Debug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 ); +#ifdef HAVE_WINSOCK + ReportSlapdShutdownComplete(); +#endif - closelog(); + closelog(); return rc; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 89348359e1..9b7b48ea18 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -338,8 +338,12 @@ extern int slap_shutdown LDAP_P((int dbnum)); extern int slap_destroy LDAP_P((void)); struct sockaddr_in; -extern int set_socket LDAP_P((struct sockaddr_in *addr)); -extern int slapd_daemon LDAP_P((int inetd, int tcps)); + +struct slapd_args { + struct sockaddr_in *addr; + int tcps; +}; +extern int slapd_daemon LDAP_P((struct slapd_args *args)); extern void slapd_set_write LDAP_P((int s, int wake)); extern void slapd_clr_write LDAP_P((int s, int wake)); -- 2.39.5