/** Initialize the User Agent library. * * Initializes the network sub-system if required, the debug memory * allocator, and the transaction id (XID) sub-system. * * @return An OpenSLP API error code. * * @internal */ static SLPError InitUserAgentLibrary(void) { /* Initialize the system if this is the first handle opened. */ if (SLPAtomicInc(&s_OpenSLPHandleCount) == 1) { if (LIBSLPPropertyInit(LIBSLP_CONFFILE) != 0) { SLPAtomicDec(&s_OpenSLPHandleCount); return SLP_MEMORY_ALLOC_FAILED; } #ifdef _WIN32 { WSADATA wsaData; WORD wVersionRequested = MAKEWORD(1,1); if (WSAStartup(wVersionRequested, &wsaData) != 0) { LIBSLPPropertyCleanup(); SLPAtomicDec(&s_OpenSLPHandleCount); return SLP_NETWORK_INIT_FAILED; } } #endif #ifdef DEBUG xmalloc_init("libslp_xmalloc.log", 0); #endif SLPXidSeed(); s_HandlesInitialized = true; } else { /* wait for first thread to finish before going on */ while (!s_HandlesInitialized) sleep(0); } return SLP_OK; }
/*=========================================================================*/ int main(int argc, char* argv[]) /*=========================================================================*/ { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; /*------------------------*/ /* Parse the command line */ /*------------------------*/ if(SLPDParseCommandLine(argc,argv)) { SLPFatal("Invalid command line\n"); } /*------------------------------*/ /* Make sure we are root */ /*------------------------------*/ if(getuid() != 0) { SLPFatal("slpd must be started by root\n"); } /*--------------------------------------*/ /* Make sure we are not already running */ /*--------------------------------------*/ if(CheckPid(G_SlpdCommandLine.pidfile)) { SLPFatal("slpd is already running. Check %s\n", G_SlpdCommandLine.pidfile); } /*------------------------------*/ /* Initialize the log file */ /*------------------------------*/ if(SLPLogFileOpen(G_SlpdCommandLine.logfile, 1)) { SLPFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile); } /*------------------------*/ /* Seed the XID generator */ /*------------------------*/ SLPXidSeed(); /*---------------------*/ /* Log startup message */ /*---------------------*/ SLPLog("****************************************\n"); SLPLogTime(); SLPLog("SLPD daemon started\n"); SLPLog("****************************************\n"); SLPLog("Command line = %s\n",argv[0]); SLPLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile); SLPLog("Using registration file = %s\n",G_SlpdCommandLine.regfile); /*--------------------------------------------------*/ /* Initialize for the first time */ /*--------------------------------------------------*/ if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) || SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) { SLPFatal("slpd initialization failed\n"); } SLPLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces); SLPLog("Agent URL = %s\n",G_SlpdProperty.myUrl); /*---------------------------*/ /* make slpd run as a daemon */ /*---------------------------*/ if(Daemonize(G_SlpdCommandLine.pidfile)) { SLPFatal("Could not daemonize\n"); } /*-----------------------*/ /* Setup signal handlers */ /*-----------------------*/ if(SetUpSignalHandlers()) { SLPFatal("Error setting up signal handlers.\n"); } /*------------------------------*/ /* Set up alarm to age database */ /*------------------------------*/ alarm(SLPD_AGE_INTERVAL); /*-----------*/ /* Main loop */ /*-----------*/ SLPLog("Startup complete entering main run loop ...\n\n"); G_SIGALRM = 0; G_SIGTERM = 0; G_SIGHUP = 0; while(G_SIGTERM == 0) { /*--------------------------------------------------------*/ /* Load the fdsets up with all valid sockets in the list */ /*--------------------------------------------------------*/ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); /*--------------------------------------------------*/ /* Before select(), check to see if we got a signal */ /*--------------------------------------------------*/ if(G_SIGALRM || G_SIGHUP) { goto HANDLE_SIGNAL; } /*-------------*/ /* Main select */ /*-------------*/ fdcount = select(highfd+1,&readfds,&writefds,0,0); if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */ { SLPDIncomingHandler(&fdcount,&readfds,&writefds); SLPDOutgoingHandler(&fdcount,&readfds,&writefds); } /*----------------*/ /* Handle signals */ /*----------------*/ HANDLE_SIGNAL: if(G_SIGHUP) { HandleSigHup(); G_SIGHUP = 0; } if(G_SIGALRM) { HandleSigAlrm(); G_SIGALRM = 0; alarm(SLPD_AGE_INTERVAL); } } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); return 0; }
/*=========================================================================*/ SLPError SLPOpen(const char *pcLang, SLPBoolean isAsync, SLPHandle *phSLP) /* */ /* Returns a SLPHandle handle in the phSLP parameter for the language */ /* locale passed in as the pcLang parameter. The client indicates if */ /* operations on the handle are to be synchronous or asynchronous */ /* through the isAsync parameter. The handle encapsulates the language */ /* locale for SLP requests issued through the handle, and any other */ /* resources required by the implementation. However, SLP properties */ /* are not encapsulated by the handle; they are global. The return */ /* value of the function is an SLPError code indicating the status of */ /* the operation. Upon failure, the phSLP parameter is NULL. */ /* */ /* An SLPHandle can only be used for one SLP API operation at a time. */ /* If the original operation was started asynchronously, any attempt to */ /* start an additional operation on the handle while the original */ /* operation is pending results in the return of an SLP_HANDLE_IN_USE */ /* error from the API function. The SLPClose() API function terminates */ /* any outstanding calls on the handle. If an implementation is unable */ /* to support a asynchronous( resp. synchronous) operation, due to */ /* memory constraints or lack of threading support, the */ /* SLP_NOT_IMPLEMENTED flag may be returned when the isAsync flag is */ /* SLP_TRUE (resp. SLP_FALSE). */ /* */ /* pcLang A pointer to an array of characters containing the RFC 1766 */ /* Language Tag RFC 1766 for the natural language locale of */ /* requests and registrations issued on the handle. Pass in NULL */ /* or the empty string, "" to use the default locale */ /* */ /* isAsync An SLPBoolean indicating whether the SLPHandle should be opened*/ /* for asynchronous operation or not. */ /* */ /* phSLP A pointer to an SLPHandle, in which the open SLPHandle is */ /* returned. If an error occurs, the value upon return is NULL. */ /* */ /* Returns SLPError code */ /*=========================================================================*/ { SLPError result = SLP_OK; PSLPHandleInfo handle = 0; /*------------------------------*/ /* check for invalid parameters */ /*------------------------------*/ if(phSLP == 0) { result = SLP_PARAMETER_BAD; goto FINISHED; } /* assign out param to zero in just for paranoia */ *phSLP = 0; /*-------------------------------------------------------*/ /* TODO: remove this line when you implement async calls */ /*-------------------------------------------------------*/ if(isAsync == SLP_TRUE) { result = SLP_NOT_IMPLEMENTED; goto FINISHED; } /*------------------------------------*/ /* allocate a SLPHandleInfo structure */ /*------------------------------------*/ handle = (PSLPHandleInfo)malloc(sizeof(SLPHandleInfo)); if(handle == 0) { result = SLP_PARAMETER_BAD; goto FINISHED; } memset(handle,0,sizeof(SLPHandleInfo)); /*-------------------------------*/ /* Set the language tag */ /*-------------------------------*/ if(pcLang && *pcLang) { handle->langtaglen = strlen(pcLang); handle->langtag = (char*)malloc(handle->langtaglen + 1); if(handle->langtag == 0) { free(handle); result = SLP_PARAMETER_BAD; goto FINISHED; } memcpy(handle->langtag,pcLang,handle->langtaglen + 1); } else { handle->langtaglen = strlen(SLPGetProperty("net.slp.locale")); handle->langtag = (char*)malloc(handle->langtaglen + 1); if(handle->langtag == 0) { free(handle); result = SLP_PARAMETER_BAD; goto FINISHED; } memcpy(handle->langtag,SLPGetProperty("net.slp.locale"),handle->langtaglen + 1); } /*---------------------------------------------------------*/ /* Seed the XID generator if this is the first open handle */ /*---------------------------------------------------------*/ if(G_OpenSLPHandleCount == 0) { #ifdef WIN32 WSADATA wsaData; WORD wVersionRequested = MAKEWORD(1,1); if (0 != WSAStartup(wVersionRequested, &wsaData)) { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } #endif SLPXidSeed(); } handle->inUse = SLP_FALSE; handle->isAsync = isAsync; handle->sig = SLP_HANDLE_SIG; G_OpenSLPHandleCount ++; *phSLP = (SLPHandle)handle; FINISHED: if(result) { *phSLP = 0; } return result; }
/** Process main entry point. * * @param[in] argc - The number of command line arguments passed in @p argv. * @param[in] argv - An array of pointers to command line arguments. * * @return Zero on success, or a non-zero shell error code. * * @remarks This routine contains the main server loop. */ int main(int argc, char * argv[]) { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; time_t curtime; struct timeval timeout; #ifdef DEBUG xmalloc_init("/var/log/slpd_xmalloc.log", 0); #endif /* Parse the command line */ if (SLPDParseCommandLine(argc,argv)) SLPDFatal("Invalid command line\n"); /* make sure we are root */ if (getuid() != 0) SLPDFatal("slpd must be started by root\n"); /* make sure we are not already running */ if (CheckPid(G_SlpdCommandLine.pidfile)) SLPDFatal("slpd is already running. Check %s\n", G_SlpdCommandLine.pidfile); /* Initialize the preferences so we know if the log file is to be overwritten or appended.*/ if (SLPDPropertyInit(G_SlpdCommandLine.cfgfile)) SLPDFatal("slpd initialization failed during property load\n"); /* make slpd run as a daemon */ if (Daemonize(G_SlpdCommandLine.pidfile)) SLPDFatal("Could not daemonize\n"); /* initialize the log file */ if (SLPDLogFileOpen(G_SlpdCommandLine.logfile, G_SlpdProperty.appendLog)) SLPDFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile); /* seed the XID generator */ SLPXidSeed(); /* log startup message */ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon started\n"); SLPDLog("****************************************\n"); SLPDLog("Command line = %s\n", argv[0]); SLPDLog("Using configuration file = %s\n", G_SlpdCommandLine.cfgfile); SLPDLog("Using registration file = %s\n", G_SlpdCommandLine.regfile); #ifdef ENABLE_SLPv2_SECURITY SLPDLog("Using SPI file = %s\n", G_SlpdCommandLine.spifile); #endif /* initialize for the first time */ SLPDPropertyReinit(); /*So we get any property-related log messages*/ if ( #ifdef ENABLE_SLPv2_SECURITY SLPDSpiInit(G_SlpdCommandLine.spifile) || #endif SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) SLPDFatal("slpd initialization failed\n"); SLPDLog("Agent Interfaces = %s\n", G_SlpdProperty.interfaces); if (G_SlpdProperty.port != SLP_RESERVED_PORT) SLPDLog("Using port %d instead of default %d\n", G_SlpdProperty.port, SLP_RESERVED_PORT); /* drop privileges to reduce security risk */ if (DropPrivileges()) SLPDFatal("Could not drop privileges\n"); /* Setup signal handlers */ if (SetUpSignalHandlers()) SLPDFatal("Error setting up signal handlers.\n"); /* Set up alarm to age database -- a shorter start, so SAs register with us quickly on our startup */ alarm(2); /* Main loop */ SLPDLog("Startup complete entering main run loop ...\n\n"); G_SIGALRM = 0; G_SIGTERM = 0; G_SIGHUP = 0; #ifdef DEBUG G_SIGINT = 0; G_SIGUSR1 = 0; #endif while (G_SIGTERM == 0) { /* load the fdsets up with all valid sockets in the list */ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds, &writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds, &writefds); /* before select(), check to see if we got a signal */ if (G_SIGALRM || G_SIGHUP) goto HANDLE_SIGNAL; /* main select -- we time out every second so the outgoing retries can occur*/ time(&curtime); timeout.tv_sec = 1; timeout.tv_usec = 0; fdcount = select(highfd + 1, &readfds, &writefds, 0, &timeout); if (fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */ { SLPDIncomingHandler(&fdcount, &readfds, &writefds); SLPDOutgoingHandler(&fdcount, &readfds, &writefds); SLPDOutgoingRetry(time(0) - curtime); } else if (fdcount == 0) SLPDOutgoingRetry(time(0) - curtime); HANDLE_SIGNAL: if (G_SIGHUP) { HandleSigHup(); G_SIGHUP = 0; } if (G_SIGALRM) { HandleSigAlrm(); G_SIGALRM = 0; alarm(SLPD_AGE_INTERVAL); } #ifdef DEBUG if (G_SIGINT) { HandleSigInt(); G_SIGINT = 0; } if (G_SIGUSR1) { HandleSigUsr1(); G_SIGUSR1 = 0; } #endif } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); return 0; }
/*--------------------------------------------------------------------------*/ void ServiceStart (int argc, char **argv) /*--------------------------------------------------------------------------*/ { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; time_t curtime; time_t alarmtime; struct timeval timeout; WSADATA wsaData; WORD wVersionRequested = MAKEWORD(1,1); /*------------------------*/ /* Service initialization */ /*------------------------*/ if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state*/ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup; } if(WSAStartup(wVersionRequested, &wsaData) != 0) { (void)ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); goto cleanup; } /*------------------------*/ /* Parse the command line */ /*------------------------*/ if(SLPDParseCommandLine(argc,argv)) { ReportStatusToSCMgr(SERVICE_STOP_PENDING, /* service state */ NO_ERROR, /* exit code */ 0); /* wait hint */ goto cleanup_winsock; } if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup_winsock; } /*------------------------------*/ /* Initialize the log file */ /*------------------------------*/ if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1)) { SLPDLog("Could not open logfile %s\n",G_SlpdCommandLine.logfile); goto cleanup_winsock; } /*------------------------*/ /* Seed the XID generator */ /*------------------------*/ SLPXidSeed(); /*---------------------*/ /* Log startup message */ /*---------------------*/ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon started\n"); SLPDLog("****************************************\n"); SLPDLog("Command line = %s\n",argv[0]); SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile); SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile); if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup_winsock; } /*--------------------------------------------------*/ /* Initialize for the first time */ /*--------------------------------------------------*/ if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) || SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) { SLPDLog("slpd initialization failed\n"); goto cleanup_winsock; } SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces); /* Service is now running, perform work until shutdown */ if(!ReportStatusToSCMgr(SERVICE_RUNNING, /* service state */ NO_ERROR, /* exit code */ 0)) /* wait hint */ { goto cleanup_winsock; } /*-----------*/ /* Main loop */ /*-----------*/ SLPDLog("Startup complete entering main run loop ...\n\n"); G_SIGTERM = 0; curtime = time(&alarmtime); alarmtime = curtime + SLPD_AGE_INTERVAL; while(G_SIGTERM == 0) { /*--------------------------------------------------------*/ /* Load the fdsets up with all valid sockets in the list */ /*--------------------------------------------------------*/ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); /*--------------------------------------------------*/ /* Before select(), check to see if we got a signal */ /*--------------------------------------------------*/ if(G_SIGALRM) { goto HANDLE_SIGNAL; } /*-------------*/ /* Main select */ /*-------------*/ timeout.tv_sec = SLPD_AGE_INTERVAL; timeout.tv_usec = 0; fdcount = select(highfd+1,&readfds,&writefds,0,&timeout); if(fdcount > 0) /* fdcount will be < 0 when timed out */ { SLPDIncomingHandler(&fdcount,&readfds,&writefds); SLPDOutgoingHandler(&fdcount,&readfds,&writefds); } /*----------------*/ /* Handle signals */ /*----------------*/ HANDLE_SIGNAL: curtime = time(&curtime); if(curtime >= alarmtime) { HandleSigAlrm(); alarmtime = curtime + SLPD_AGE_INTERVAL; } } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); cleanup_winsock: WSACleanup(); cleanup: ; }