📄 slpd_win32.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol Version 2 *//* *//* File: slpd_win32.c *//* *//* Abstract: Win32 specific part, to make SLPD run as a "service" *//* *//*-------------------------------------------------------------------------*//* *//* Please submit patches to http://www.openslp.org *//* *//*-------------------------------------------------------------------------*//* *//* Copyright (C) 2000 Caldera Systems, Inc *//* All rights reserved. *//* *//* Redistribution and use in source and binary forms, with or without *//* modification, are permitted provided that the following conditions are *//* met: */ /* *//* Redistributions of source code must retain the above copyright *//* notice, this list of conditions and the following disclaimer. *//* *//* Redistributions in binary form must reproduce the above copyright *//* notice, this list of conditions and the following disclaimer in *//* the documentation and/or other materials provided with the *//* distribution. *//* *//* Neither the name of Caldera Systems nor the names of its *//* contributors may be used to endorse or promote products derived *//* from this software without specific prior written permission. *//* *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* *//***************************************************************************/#include "slpd.h"/*=========================================================================*//* slpd includes *//*=========================================================================*/#include "slpd_cmdline.h"#include "slpd_log.h"#include "slpd_property.h"#include "slpd_database.h"#include "slpd_socket.h"#include "slpd_incoming.h"#include "slpd_outgoing.h"#include "slpd_knownda.h"/*=========================================================================*//* common code includes *//*=========================================================================*/#include "slp_linkedlist.h"#include "slp_xid.h"SERVICE_STATUS ssStatus; /* current status of the service */SERVICE_STATUS_HANDLE sshStatusHandle; BOOL bDebug = FALSE; TCHAR szErr[256];/*-------------------------------------------------------------------------*/extern int G_SIGTERM;/* see slpd_main.c *//*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/void LoadFdSets(SLPList* socklist, int* highfd, fd_set* readfds, fd_set* writefds);/* see slpd_main.c *//*-------------------------------------------------------------------------*//*------------------------------------------------------------------------*/void HandleSigTerm();/* see slpd_main.c *//*------------------------------------------------------------------------*//*------------------------------------------------------------------------*/void HandleSigAlrm();/* see slpd_main.c *//*------------------------------------------------------------------------*//*--------------------------------------------------------------------------*/BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) /* *//* PURPOSE: Sets the current status of the service and *//* reports it to the Service Control Manager *//* *//* PARAMETERS: *//* dwCurrentState - the state of the service *//* dwWin32ExitCode - error code to report *//* dwWaitHint - worst case estimate to next checkpoint *//* *//* RETURN VALUE: *//* TRUE - success *//* FALSE - failure *//* *//*--------------------------------------------------------------------------*/{ static DWORD dwCheckPoint = 1; BOOL fResult = TRUE; /* when debugging we don't report to the SCM */ if(G_SlpdCommandLine.action != SLPD_DEBUG) { if(dwCurrentState == SERVICE_START_PENDING) { ssStatus.dwControlsAccepted = 0; } else { ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; } ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; if(( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED )) { ssStatus.dwCheckPoint = 0; } else { ssStatus.dwCheckPoint = dwCheckPoint++; } /* Report the status of the service to the service control manager.*/ if(!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { SLPDLog("SetServiceStatus failed"); } } return fResult; } /*--------------------------------------------------------------------------*/LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ) /* *//* PURPOSE: copies error message text to string *//* *//* PARAMETERS: *//* lpszBuf - destination buffer *//* dwSize - size of buffer *//* *//* RETURN VALUE: *//* destination buffer *//* *//*--------------------------------------------------------------------------*/{ DWORD dwRet; LPTSTR lpszTemp = NULL; dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&lpszTemp, 0, NULL ); /* supplied buffer is not long enough */ if(!dwRet || ( (long)dwSize < (long)dwRet+14 )) { lpszBuf[0] = TEXT('\0'); } else { lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); sprintf( lpszBuf, "%s (0x%x)", lpszTemp, GetLastError() ); } if(lpszTemp) { LocalFree((HLOCAL) lpszTemp ); } return lpszBuf; } /*--------------------------------------------------------------------------*/void ServiceStop() /*--------------------------------------------------------------------------*/{ G_SIGTERM = 1; ReportStatusToSCMgr(SERVICE_STOPPED, /* service state */ NO_ERROR, /* exit code */ 3000); /* wait hint */} /*--------------------------------------------------------------------------*/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); SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl); /* 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -