int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { if( lpCmdLine[0] == _T('-') || lpCmdLine[0] == _T('/') ){ if( lstrcmpi(_T("install"), lpCmdLine + 1) == 0 ){ bool installed = false; TCHAR exePath[512]; if( GetModuleFileName(NULL, exePath, _countof(exePath)) != 0 ){ SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE); if( hScm != NULL ){ SC_HANDLE hSrv = CreateService( hScm, SERVICE_NAME, SERVICE_NAME, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, exePath, NULL, NULL, NULL, NULL, NULL); if( hSrv != NULL ){ installed = true; CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } } if( installed == false ){ //コンソールがないのでメッセージボックスで伝える MessageBox(NULL, L"Failed to install/remove " SERVICE_NAME L".\r\nRun as Administrator on Vista and later.", NULL, MB_ICONERROR); } return 0; }else if( lstrcmpi(_T("remove"), lpCmdLine + 1) == 0 ){ bool removed = false; SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if( hScm != NULL ){ SC_HANDLE hSrv = OpenService(hScm, SERVICE_NAME, DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if( hSrv != NULL ){ SERVICE_STATUS srvStatus; if( QueryServiceStatus(hSrv, &srvStatus) != FALSE ){ if( srvStatus.dwCurrentState == SERVICE_STOPPED || ControlService(hSrv, SERVICE_CONTROL_STOP, &srvStatus) != FALSE ){ removed = DeleteService(hSrv) != FALSE; } } CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } if( removed == false ){ MessageBox(NULL, L"Failed to install/remove " SERVICE_NAME L".\r\nRun as Administrator on Vista and later.", NULL, MB_ICONERROR); } return 0; } } if( IsInstallService(SERVICE_NAME) == FALSE ){ //普通にexeとして起動を行う HANDLE hMutex = CreateMutex(NULL, TRUE, EPG_TIMER_BON_SRV_MUTEX); if( hMutex != NULL ){ if( GetLastError() != ERROR_ALREADY_EXISTS ){ StartDebugLog(); //メインスレッドに対するCOMの初期化 CoInitialize(NULL); CEpgTimerSrvMain* pMain = new CEpgTimerSrvMain; if( pMain->Main(false) == false ){ OutputDebugString(_T("_tWinMain(): Failed to start\r\n")); } delete pMain; CoUninitialize(); StopDebugLog(); } ReleaseMutex(hMutex); CloseHandle(hMutex); } }else if( IsStopService(SERVICE_NAME) == FALSE ){ //サービスとして実行 HANDLE hMutex = CreateMutex(NULL, TRUE, EPG_TIMER_BON_SRV_MUTEX); if( hMutex != NULL ){ if( GetLastError() != ERROR_ALREADY_EXISTS ){ StartDebugLog(); SERVICE_TABLE_ENTRY dispatchTable[] = { { SERVICE_NAME, service_main }, { NULL, NULL } }; if( StartServiceCtrlDispatcher(dispatchTable) == FALSE ){ OutputDebugString(_T("_tWinMain(): StartServiceCtrlDispatcher failed\r\n")); } StopDebugLog(); } ReleaseMutex(hMutex); CloseHandle(hMutex); } }else{ //Stop状態なのでサービスの開始を要求 bool started = false; SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if( hScm != NULL ){ SC_HANDLE hSrv = OpenService(hScm, SERVICE_NAME, SERVICE_START); if( hSrv != NULL ){ started = StartService(hSrv, 0, NULL) != FALSE; CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } if( started == false ){ OutputDebugString(_T("_tWinMain(): Failed to start\r\n")); } } return 0; }
int main(int argc, char **argv) { const char *sopt = "hVvdm:p:l:f:F::b:s:t:"; const char *method = NULL, *path = NULL; const char *log_filepath = NULL; const char *pid_filepath; #ifdef CONFIG_FSFREEZE const char *fsfreeze_hook = NULL; #endif const char *state_dir; #ifdef _WIN32 const char *service = NULL; #endif const struct option lopt[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, { "logfile", 1, NULL, 'l' }, { "pidfile", 1, NULL, 'f' }, #ifdef CONFIG_FSFREEZE { "fsfreeze-hook", 2, NULL, 'F' }, #endif { "verbose", 0, NULL, 'v' }, { "method", 1, NULL, 'm' }, { "path", 1, NULL, 'p' }, { "daemonize", 0, NULL, 'd' }, { "blacklist", 1, NULL, 'b' }, #ifdef _WIN32 { "service", 1, NULL, 's' }, #endif { "statedir", 1, NULL, 't' }, { NULL, 0, NULL, 0 } }; int opt_ind = 0, ch, daemonize = 0, i, j, len; GLogLevelFlags log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; GList *blacklist = NULL; GAState *s; module_call_init(MODULE_INIT_QAPI); init_dfl_pathnames(); pid_filepath = dfl_pathnames.pidfile; state_dir = dfl_pathnames.state_dir; while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 'm': method = optarg; break; case 'p': path = optarg; break; case 'l': log_filepath = optarg; break; case 'f': pid_filepath = optarg; break; #ifdef CONFIG_FSFREEZE case 'F': fsfreeze_hook = optarg ? optarg : QGA_FSFREEZE_HOOK_DEFAULT; break; #endif case 't': state_dir = optarg; break; case 'v': /* enable all log levels */ log_level = G_LOG_LEVEL_MASK; break; case 'V': printf("QEMU Guest Agent %s\n", QEMU_VERSION); return 0; case 'd': daemonize = 1; break; case 'b': { if (is_help_option(optarg)) { qmp_for_each_command(ga_print_cmd, NULL); return 0; } for (j = 0, i = 0, len = strlen(optarg); i < len; i++) { if (optarg[i] == ',') { optarg[i] = 0; blacklist = g_list_append(blacklist, &optarg[j]); j = i + 1; } } if (j < i) { blacklist = g_list_append(blacklist, &optarg[j]); } break; } #ifdef _WIN32 case 's': service = optarg; if (strcmp(service, "install") == 0) { const char *fixed_state_dir; /* If the user passed the "-t" option, we save that state dir * in the service. Otherwise we let the service fetch the state * dir from the environment when it starts. */ fixed_state_dir = (state_dir == dfl_pathnames.state_dir) ? NULL : state_dir; if (ga_install_vss_provider()) { return EXIT_FAILURE; } if (ga_install_service(path, log_filepath, fixed_state_dir)) { return EXIT_FAILURE; } return 0; } else if (strcmp(service, "uninstall") == 0) { ga_uninstall_vss_provider(); return ga_uninstall_service(); } else { printf("Unknown service command.\n"); return EXIT_FAILURE; } break; #endif case 'h': usage(argv[0]); return 0; case '?': g_print("Unknown option, try '%s --help' for more information.\n", argv[0]); return EXIT_FAILURE; } } #ifdef _WIN32 /* On win32 the state directory is application specific (be it the default * or a user override). We got past the command line parsing; let's create * the directory (with any intermediate directories). If we run into an * error later on, we won't try to clean up the directory, it is considered * persistent. */ if (g_mkdir_with_parents(state_dir, S_IRWXU) == -1) { g_critical("unable to create (an ancestor of) the state directory" " '%s': %s", state_dir, strerror(errno)); return EXIT_FAILURE; } #endif s = g_malloc0(sizeof(GAState)); s->log_level = log_level; s->log_file = stderr; #ifdef CONFIG_FSFREEZE s->fsfreeze_hook = fsfreeze_hook; #endif g_log_set_default_handler(ga_log, s); g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR); ga_enable_logging(s); s->state_filepath_isfrozen = g_strdup_printf("%s/qga.state.isfrozen", state_dir); s->pstate_filepath = g_strdup_printf("%s/qga.state", state_dir); s->frozen = false; #ifndef _WIN32 /* check if a previous instance of qemu-ga exited with filesystems' state * marked as frozen. this could be a stale value (a non-qemu-ga process * or reboot may have since unfrozen them), but better to require an * uneeded unfreeze than to risk hanging on start-up */ struct stat st; if (stat(s->state_filepath_isfrozen, &st) == -1) { /* it's okay if the file doesn't exist, but if we can't access for * some other reason, such as permissions, there's a configuration * that needs to be addressed. so just bail now before we get into * more trouble later */ if (errno != ENOENT) { g_critical("unable to access state file at path %s: %s", s->state_filepath_isfrozen, strerror(errno)); return EXIT_FAILURE; } } else { g_warning("previous instance appears to have exited with frozen" " filesystems. deferring logging/pidfile creation and" " disabling non-fsfreeze-safe commands until" " guest-fsfreeze-thaw is issued, or filesystems are" " manually unfrozen and the file %s is removed", s->state_filepath_isfrozen); s->frozen = true; } #endif if (ga_is_frozen(s)) { if (daemonize) { /* delay opening/locking of pidfile till filesystems are unfrozen */ s->deferred_options.pid_filepath = pid_filepath; become_daemon(NULL); } if (log_filepath) { /* delay opening the log file till filesystems are unfrozen */ s->deferred_options.log_filepath = log_filepath; } ga_disable_logging(s); qmp_for_each_command(ga_disable_non_whitelisted, NULL); } else { if (daemonize) { become_daemon(pid_filepath); } if (log_filepath) { FILE *log_file = ga_open_logfile(log_filepath); if (!log_file) { g_critical("unable to open specified log file: %s", strerror(errno)); goto out_bad; } s->log_file = log_file; } } /* load persistent state from disk */ if (!read_persistent_state(&s->pstate, s->pstate_filepath, ga_is_frozen(s))) { g_critical("failed to load persistent state"); goto out_bad; } blacklist = ga_command_blacklist_init(blacklist); if (blacklist) { s->blacklist = blacklist; do { g_debug("disabling command: %s", (char *)blacklist->data); qmp_disable_command(blacklist->data); blacklist = g_list_next(blacklist); } while (blacklist); } s->command_state = ga_command_state_new(); ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); json_message_parser_init(&s->parser, process_event); ga_state = s; #ifndef _WIN32 if (!register_signal_handlers()) { g_critical("failed to register signal handlers"); goto out_bad; } #endif s->main_loop = g_main_loop_new(NULL, false); if (!channel_init(ga_state, method, path)) { g_critical("failed to initialize guest agent channel"); goto out_bad; } #ifndef _WIN32 g_main_loop_run(ga_state->main_loop); #else if (daemonize) { SERVICE_TABLE_ENTRY service_table[] = { { (char *)QGA_SERVICE_NAME, service_main }, { NULL, NULL } }; StartServiceCtrlDispatcher(service_table); } else { g_main_loop_run(ga_state->main_loop); } #endif ga_command_state_cleanup_all(ga_state->command_state); ga_channel_free(ga_state->channel); if (daemonize) { unlink(pid_filepath); } return 0; out_bad: if (daemonize) { unlink(pid_filepath); } return EXIT_FAILURE; }
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static SERVICE_TABLE_ENTRY service_table[] = { {server_name, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, {NULL, NULL} }; int service_installed; char buf[200], *service_argv[] = {__argv[0], NULL}; POINT pt; HMENU hMenu; switch (msg) { case WM_CREATE: if (__argv[1] != NULL && !strcmp(__argv[1], service_magic_argument)) { start_mongoose(1, service_argv); StartServiceCtrlDispatcher(service_table); exit(EXIT_SUCCESS); } else { start_mongoose(__argc, __argv); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_QUIT: mg_stop(ctx); Shell_NotifyIcon(NIM_DELETE, &TrayIcon); PostQuitMessage(0); break; case ID_EDIT_CONFIG: edit_config_file(); break; case ID_INSTALL_SERVICE: case ID_REMOVE_SERVICE: manage_service(LOWORD(wParam)); break; } break; case WM_USER: switch (lParam) { case WM_RBUTTONUP: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING | MF_GRAYED, ID_SEPARATOR, server_name); AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, ""); service_installed = manage_service(0); snprintf(buf, sizeof(buf), "NT service: %s installed", service_installed ? "" : "not"); AppendMenu(hMenu, MF_STRING | MF_GRAYED, ID_SEPARATOR, buf); AppendMenu(hMenu, MF_STRING | (service_installed ? MF_GRAYED : 0), ID_INSTALL_SERVICE, "Install service"); AppendMenu(hMenu, MF_STRING | (!service_installed ? MF_GRAYED : 0), ID_REMOVE_SERVICE, "Deinstall service"); AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, ""); AppendMenu(hMenu, MF_STRING, ID_EDIT_CONFIG, "Edit config file"); AppendMenu(hMenu, MF_STRING, ID_QUIT, "Exit"); GetCursorPos(&pt); SetForegroundWindow(hWnd); TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hWnd, NULL); PostMessage(hWnd, WM_NULL, 0, 0); DestroyMenu(hMenu); break; } break; case WM_CLOSE: mg_stop(ctx); Shell_NotifyIcon(NIM_DELETE, &TrayIcon); PostQuitMessage(0); return 0; // We've just sent our own quit message, with proper hwnd. } return DefWindowProc(hWnd, msg, wParam, lParam); }
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE /*hPrevInst*/, LPSTR lpszArgs, int nWndMode) { /************************************** * * W i n M a i n * ************************************** * * Functional description * Run the server with NT named * pipes and/or TCP/IP sockets. * **************************************/ hInst = hThisInst; // We want server to crash without waiting for feedback from the user try { if (!Config::getBugcheckAbort()) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); } catch (Firebird::fatal_exception& e) { MessageBox(NULL, e.what(), "Firebird server failure", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY); return STARTUP_ERROR; // see /jrd/common.h } catch (Firebird::status_exception& e) { TEXT buffer[BUFFER_LARGE]; const ISC_STATUS* vector = e.value(); if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector))) { strcpy(buffer, "Unknown internal failure"); } MessageBox(NULL, buffer, "Firebird server failure", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY); return STARTUP_ERROR; // see /jrd/common.h } #ifdef SUPERSERVER server_flag = SRVR_multi_client; #else server_flag = 0; #endif #ifdef SUPERSERVER SetProcessAffinityMask(GetCurrentProcess(), static_cast<DWORD>(Config::getCpuAffinityMask())); #endif protocol_inet[0] = 0; protocol_wnet[0] = 0; strcpy(instance, FB_DEFAULT_INSTANCE); const HANDLE connection_handle = parse_args(lpszArgs, &server_flag); #ifdef SUPERSERVER // get priority class from the config file int priority = Config::getProcessPriorityLevel(); // override it, if necessary if (server_flag & SRVR_high_priority) { priority = 1; } // set priority class if (priority > 0) { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else if (priority < 0) { SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); } #endif TEXT mutex_name[MAXPATHLEN]; fb_utils::snprintf(mutex_name, sizeof(mutex_name), SERVER_MUTEX, instance); fb_utils::prefix_kernel_object_name(mutex_name, sizeof(mutex_name)); CreateMutex(ISC_get_security_desc(), FALSE, mutex_name); // Initialize the service ISC_signal_init(); Firebird::FpeControl::maskAll(); int nReturnValue = 0; ISC_STATUS_ARRAY status_vector; fb_utils::init_status(status_vector); fb_shutdown_callback(0, wait_threads, fb_shut_finish, NULL); if (connection_handle != INVALID_HANDLE_VALUE) { rem_port* port = 0; if (server_flag & SRVR_inet) { port = INET_reconnect((SOCKET) connection_handle, status_vector); if (port) { SRVR_multi_thread(port, server_flag); port = NULL; } } else if (server_flag & SRVR_wnet) port = WNET_reconnect(connection_handle, status_vector); else if (server_flag & SRVR_xnet) port = XNET_reconnect((ULONG) connection_handle, status_vector); if (port) { service_connection(port); } else if (status_vector[1]) gds__log_status(0, status_vector); fb_shutdown(5 * 1000 /*5 seconds*/, fb_shutrsn_no_connection); } else if (!(server_flag & SRVR_non_service)) { Firebird::string service_name; service_name.printf(REMOTE_SERVICE, instance); CNTL_init(start_connections_thread, instance); const SERVICE_TABLE_ENTRY service_table[] = { {const_cast<char*>(service_name.c_str()), CNTL_main_thread}, {NULL, NULL} }; // BRS There is a error in MinGW (3.1.0) headers // the parameter of StartServiceCtrlDispatcher is declared const in msvc headers #if defined(MINGW) if (!StartServiceCtrlDispatcher(const_cast<SERVICE_TABLE_ENTRY*>(service_table))) { #else if (!StartServiceCtrlDispatcher(service_table)) { #endif if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) { CNTL_shutdown_service("StartServiceCtrlDispatcher failed"); } server_flag |= SRVR_non_service; } } else { start_connections_thread(0); nReturnValue = WINDOW_main(hThisInst, nWndMode, server_flag); } #ifdef DEBUG_GDS_ALLOC // In Debug mode - this will report all server-side memory leaks // due to remote access //gds_alloc_report(0, __FILE__, __LINE__); Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_LOG, "memdebug.log"); FILE* file = fopen(name.c_str(), "w+t"); if (file) { fprintf(file, "Global memory pool allocated objects\n"); getDefaultMemoryPool()->print_contents(file); fclose(file); } #endif return nReturnValue; } THREAD_ENTRY_DECLARE process_connection_thread(THREAD_ENTRY_PARAM arg) { /************************************** * * p r o c e s s _ c o n n e c t i o n _ t h r e a d * ************************************** * * Functional description * **************************************/ ThreadCounter counter; service_connection((rem_port*) arg); return 0; }
/* ------------------------------------------------------------------- * main() * Entry point into Iperf * * sets up signal handlers * initialize global locks and conditions * parses settings from environment and command line * starts up server or client thread * waits for all threads to complete * ------------------------------------------------------------------- */ int main( int argc, char **argv ) { // Set SIGTERM and SIGINT to call our user interrupt function my_signal( SIGTERM, Sig_Interupt ); my_signal( SIGINT, Sig_Interupt ); my_signal( SIGALRM, Sig_Interupt ); #ifndef WIN32 // Ignore broken pipes signal(SIGPIPE,SIG_IGN); #else // Start winsock WSADATA wsaData; int rc = WSAStartup( 0x202, &wsaData ); WARN_errno( rc == SOCKET_ERROR, "WSAStartup" ); if (rc == SOCKET_ERROR) return 0; // Tell windows we want to handle our own signals SetConsoleCtrlHandler( sig_dispatcher, true ); #endif // Initialize global mutexes and conditions Condition_Initialize ( &ReportCond ); Mutex_Initialize( &groupCond ); Mutex_Initialize( &clients_mutex ); // Initialize the thread subsystem thread_init( ); // Initialize the interrupt handling thread to 0 sThread = thread_zeroid(); // perform any cleanup when quitting Iperf atexit( cleanup ); // Allocate the "global" settings thread_Settings* ext_gSettings = new thread_Settings; // Initialize settings to defaults Settings_Initialize( ext_gSettings ); // read settings from environment variables Settings_ParseEnvironment( ext_gSettings ); // read settings from command-line parameters Settings_ParseCommandLine( argc, argv, ext_gSettings ); // Check for either having specified client or server if ( ext_gSettings->mThreadMode == kMode_Client || ext_gSettings->mThreadMode == kMode_Listener ) { #ifdef WIN32 // Start the server as a daemon // Daemon mode for non-windows in handled // in the listener_spawn function if ( isDaemon( ext_gSettings ) ) { CmdInstallService(argc, argv); return 0; } // Remove the Windows service if requested if ( isRemoveService( ext_gSettings ) ) { // remove the service if ( CmdRemoveService() ) { fprintf(stderr, "IPerf Service is removed.\n"); return 0; } } #endif // initialize client(s) if ( ext_gSettings->mThreadMode == kMode_Client ) { client_init( ext_gSettings ); } #ifdef HAVE_THREAD // start up the reporter and client(s) or listener { thread_Settings *into = NULL; // Create the settings structure for the reporter thread Settings_Copy( ext_gSettings, &into ); into->mThreadMode = kMode_Reporter; // Have the reporter launch the client or listener into->runNow = ext_gSettings; // Start all the threads that are ready to go thread_start( into ); } #else // No need to make a reporter thread because we don't have threads thread_start( ext_gSettings ); #endif } else { // neither server nor client mode was specified // print usage and exit #ifdef WIN32 // In Win32 we also attempt to start a previously defined service // Starting in 2.0 to restart a previously defined service // you must call iperf with "iperf -D" or using the environment variable SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main}, { NULL, NULL} }; // Only attempt to start the service if "-D" was specified if ( !isDaemon(ext_gSettings) || // starting the service by SCM, there is no arguments will be passed in. // the arguments will pass into Service_Main entry. !StartServiceCtrlDispatcher(dispatchTable) ) // If the service failed to start then print usage #endif fprintf( stderr, usage_short, argv[0], argv[0] ); return 0; } // wait for other (client, server) threads to complete thread_joinall(); // all done! return 0; } // end main
int CSystemService::StartServiceMain(LPCWSTR servicename,int argc, TCHAR *argv[]) { ServiceTable[0].lpServiceName=const_cast<LPWSTR>(servicename); if(argc>=2) { if(_tcscmp(_T("-install"),argv[1])==0 || _tcscmp(_T("-i"),argv[1])==0) { if(argc>=3) Install(argv[2]); else Install(nullptr); } else if(_tcscmp(_T("-uninstall"),argv[1])==0 || _tcscmp(_T("-u"),argv[1])==0) { Uninstall(); } else if(_tcscmp(_T("-s"),argv[1])==0) { if(!StartServiceCtrlDispatcher(ServiceTable)) { printf("RegisterServer First"); } } } else { if(can_direct_run==false) { Install(nullptr); return 0; } _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); DWORD threadid=GetCurrentThreadId(); CloseHandle((HANDLE)_beginthreadex(0,0,DebugHelpProc,&threadid,0,0)); if(ServiceStart && !ServiceStart()) return 1; BOOL bRet; MSG msg; while(true) { bRet = PeekMessage( &msg, 0, 0, 0, PM_REMOVE ); if(bRet==FALSE) { if(ServiceIdle) ServiceIdle(); bRet = GetMessage( &msg, 0, 0, 0 ); if(bRet==0)break; } else { if(msg.message==WM_QUIT) break; } if (bRet == -1) { return 0; } else { TranslateMessage(&msg); DispatchMessage(&msg); if(ServiceMSG)ServiceMSG(msg); } } if(ServiceStop && !ServiceStop()) return 2; } return 0; }
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstExePrev, LPSTR pszCmdLine, int nCmdShow) { // ***** To debug this application **** // set fDebug to 1, then recompile (in debug mode) // and run the program in a debugger like any windows .exe // The exact same code executes as if the user clicked the // 'start' button in the NT services manager. int fDebug = 0; int nArgc = __argc; #ifdef UNICODE LPCTSTR *ppArgv = (LPCTSTR*) CommandLineToArgvW(GetCommandLine(), &nArgc); #else LPCTSTR *ppArgv = (LPCTSTR*) __argv; #endif BOOL fStartService = (nArgc < 2); int i; int bInstall = 0; int bRemove = 0; int bChange = 0; GString strPort("10888"); GString strBoot; GString strRoot("NotUsed"); for (i = 1; i < nArgc; i++) { if ((ppArgv[i][0] == __TEXT('-')) || (ppArgv[i][0] == __TEXT('/'))) { // Command line switch if (lstrcmpi(&ppArgv[i][1], __TEXT("install")) == 0) bInstall = 1; if (lstrcmpi(&ppArgv[i][1], __TEXT("remove")) == 0) bRemove = 1; if (lstrcmpi(&ppArgv[i][1], __TEXT("change")) == 0) bChange = 1; GString strTemp(&ppArgv[i][1],strlen("desc:")); if (strTemp.CompareNoCase("desc:") == 0) { strServerDescription = &ppArgv[i][1+strlen("desc:")]; } GString strTemp2(&ppArgv[i][1],strlen("name:")); if (strTemp2.CompareNoCase("name:") == 0) { strServerName = &ppArgv[i][1+strlen("name:")]; } GString strTemp3(&ppArgv[i][1],strlen("pass:"******"pass:"******"pass:"******"boot:")); if (strTemp4.CompareNoCase("boot:") == 0) { strBoot = &ppArgv[i][1+strlen("boot:")]; } GString strTemp5(&ppArgv[i][1],strlen("port:")); if (strTemp5.CompareNoCase("port:") == 0) { strPort = &ppArgv[i][1+strlen("port:")]; } GString strTemp6(&ppArgv[i][1],strlen("root:")); if (strTemp6.CompareNoCase("root:") == 0) { strRoot = &ppArgv[i][1+strlen("root:")]; } } } if (bChange) { ModifyStartupFile(strBoot,strServerPassword,strRoot,strPort); } if (bInstall) { GString strThisEXEName(GetThisEXEName()); // uuencode strBoot BUFFER b; BufferInit(&b); uuencode((unsigned char *)(const char *)strBoot, (int)strBoot.Length(), &b); GString strEncodedBoot((char *)b.pBuf, b.cLen); BufferTerminate(&b); // open the registry, save the coded boot key, close the registry HKEY hk; if (RegCreateKey(HKEY_CLASSES_ROOT,(const char *)strThisEXEName,&hk) == ERROR_SUCCESS) { RegSetValue(hk,NULL,REG_SZ,(const char *)strEncodedBoot,0); RegCloseKey(hk); } // use root of file system to store the startup file // unless specified otherwise by environment setting GString strOutFile("c:\\"); strOutFile += strThisEXEName; if (getenv(strThisEXEName)) { strOutFile += getenv(strThisEXEName); } // create the startup file GString strTempFile; strTempFile << strServerPassword << "&&" << strRoot << "&&" << strPort; strTempFile.ToFile("tempfile"); GString strErrorOut; FileEncrypt(strBoot, "tempfile", strOutFile, strErrorOut); unlink("tempfile"); InstallService(); } if (bRemove) { RemoveService(); GString strThisEXEName(GetThisEXEName()); // remove the registry entry RegDeleteKey(HKEY_CLASSES_ROOT,(const char *)strThisEXEName); // remove the startup file GString strOutFile("c:\\"); strOutFile += strThisEXEName; if (getenv(strThisEXEName)) { strOutFile += getenv(strThisEXEName); } unlink(strOutFile); } strcpy(pzServer,strServerName); if (fDebug) { // Running as EXE not as service, just run the service for debugging TimeServiceMain(0, NULL); } if (fStartService) { SERVICE_TABLE_ENTRY ServiceTable[] = { { pzServer, TimeServiceMain }, { NULL, NULL } // End of list }; StartServiceCtrlDispatcher(ServiceTable); } return(0); }
int DEFAULT_CC main(int argc, char **argv) { int test; int host_be; #if defined(_WIN32) WSADATA w; SC_HANDLE sc_man; SC_HANDLE sc_ser; int run_as_service; SERVICE_TABLE_ENTRY te[2]; #else int pid; int fd; int no_daemon; char text[256]; char pid_file[256]; #endif g_init(); ssl_init(); /* check compiled endian with actual endian */ test = 1; host_be = !((int)(*(unsigned char *)(&test))); #if defined(B_ENDIAN) if (!host_be) #endif #if defined(L_ENDIAN) if (host_be) #endif { g_writeln("endian wrong, edit arch.h"); return 0; } /* check long, int and void* sizes */ if (sizeof(int) != 4) { g_writeln("unusable int size, must be 4"); return 0; } if (sizeof(long) != sizeof(void *)) { g_writeln("long size must match void* size"); return 0; } if (sizeof(long) != 4 && sizeof(long) != 8) { g_writeln("unusable long size, must be 4 or 8"); return 0; } if (sizeof(tui64) != 8) { g_writeln("unusable tui64 size, must be 8"); return 0; } #if defined(_WIN32) run_as_service = 1; if (argc == 2) { if (g_strncasecmp(argv[1], "-help", 255) == 0 || g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -install: install service"); g_writeln(" -remove: remove service"); g_writeln(""); g_exit(0); } else if (g_strncasecmp(argv[1], "-install", 255) == 0 || g_strncasecmp(argv[1], "--install", 255) == 0 || g_strncasecmp(argv[1], "-i", 255) == 0) { /* open service manager */ sc_man = OpenSCManager(0, 0, GENERIC_WRITE); if (sc_man == 0) { g_writeln("error OpenSCManager, do you have rights?"); g_exit(0); } /* check if service is allready installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) { /* install service */ CreateService(sc_man, "xrdp", "xrdp", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, "c:\\temp\\xrdp\\xrdp.exe", 0, 0, 0, 0, 0); } else { g_writeln("error service is allready installed"); CloseServiceHandle(sc_ser); CloseServiceHandle(sc_man); g_exit(0); } CloseServiceHandle(sc_man); g_exit(0); } else if (g_strncasecmp(argv[1], "-remove", 255) == 0 || g_strncasecmp(argv[1], "--remove", 255) == 0 || g_strncasecmp(argv[1], "-r", 255) == 0) { /* open service manager */ sc_man = OpenSCManager(0, 0, GENERIC_WRITE); if (sc_man == 0) { g_writeln("error OpenSCManager, do you have rights?"); g_exit(0); } /* check if service is allready installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) { g_writeln("error service is not installed"); CloseServiceHandle(sc_man); g_exit(0); } DeleteService(sc_ser); CloseServiceHandle(sc_man); g_exit(0); } else { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } } else if (argc > 1) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } if (run_as_service) { g_memset(&te, 0, sizeof(te)); te[0].lpServiceName = "xrdp"; te[0].lpServiceProc = MyServiceMain; StartServiceCtrlDispatcher(&te); g_exit(0); } WSAStartup(2, &w); #else /* _WIN32 */ g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); no_daemon = 0; if (argc == 2) { if ((g_strncasecmp(argv[1], "-kill", 255) == 0) || (g_strncasecmp(argv[1], "--kill", 255) == 0) || (g_strncasecmp(argv[1], "-k", 255) == 0)) { g_writeln("stopping xrdp"); /* read the xrdp.pid file */ fd = -1; if (g_file_exist(pid_file)) /* xrdp.pid */ { fd = g_file_open(pid_file); /* xrdp.pid */ } if (fd == -1) { g_writeln("problem opening to xrdp.pid"); g_writeln("maybe its not running"); } else { g_memset(text, 0, 32); g_file_read(fd, text, 31); pid = g_atoi(text); g_writeln("stopping process id %d", pid); if (pid > 0) { g_sigterm(pid); } g_file_close(fd); } g_exit(0); } else if (g_strncasecmp(argv[1], "-nodaemon", 255) == 0 || g_strncasecmp(argv[1], "--nodaemon", 255) == 0 || g_strncasecmp(argv[1], "-nd", 255) == 0 || g_strncasecmp(argv[1], "--nd", 255) == 0 || g_strncasecmp(argv[1], "-ns", 255) == 0 || g_strncasecmp(argv[1], "--ns", 255) == 0) { no_daemon = 1; } else if (g_strncasecmp(argv[1], "-help", 255) == 0 || g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -nodaemon: don't fork into background"); g_writeln(" -kill: shut down xrdp"); g_writeln(""); g_exit(0); } else if ((g_strncasecmp(argv[1], "-v", 255) == 0) || (g_strncasecmp(argv[1], "--version", 255) == 0)) { g_writeln(""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln("Version %s", PACKAGE_VERSION); g_writeln(""); g_exit(0); } else { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } } else if (argc > 1) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); g_writeln(""); g_exit(0); } if (g_file_exist(pid_file)) /* xrdp.pid */ { g_writeln("It looks like xrdp is allready running,"); g_writeln("if not delete the xrdp.pid file and try again"); g_exit(0); } if (!no_daemon) { /* make sure we can write to pid file */ fd = g_file_open(pid_file); /* xrdp.pid */ if (fd == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_exit(0); } if (g_file_write(fd, "0", 1) == -1) { g_writeln("running in daemon mode with no access to pid files, quitting"); g_exit(0); } g_file_close(fd); g_file_delete(pid_file); } if (!no_daemon) { /* start of daemonizing code */ pid = g_fork(); if (pid == -1) { g_writeln("problem forking"); g_exit(1); } if (0 != pid) { g_writeln("process %d started ok", pid); /* exit, this is the main process */ g_exit(0); } g_sleep(1000); g_file_close(0); g_file_close(1); g_file_close(2); g_file_open("/dev/null"); g_file_open("/dev/null"); g_file_open("/dev/null"); /* end of daemonizing code */ } if (!no_daemon) { /* write the pid to file */ pid = g_getpid(); fd = g_file_open(pid_file); /* xrdp.pid */ if (fd == -1) { g_writeln("trying to write process id to xrdp.pid"); g_writeln("problem opening xrdp.pid"); g_writeln("maybe no rights"); } else { g_sprintf(text, "%d", pid); g_file_write(fd, text, g_strlen(text)); g_file_close(fd); } } #endif g_threadid = tc_get_threadid(); g_listen = xrdp_listen_create(); g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); g_sync_event = g_create_wait_obj(text); if (g_term_event == 0) { g_writeln("error creating g_term_event"); } xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); tc_mutex_delete(g_sync1_mutex); g_delete_wait_obj(g_term_event); g_delete_wait_obj(g_sync_event); #if defined(_WIN32) /* I don't think it ever gets here */ /* when running in win32 app mode, control c exits right away */ WSACleanup(); #else /* delete the xrdp.pid file */ g_file_delete(pid_file); #endif return 0; }
int main(int argc, char** argv) { int argn; char* arg; char* p; char path[MAX_PATH+1]; char fname[MAX_PATH+1]; char ini_fname[MAX_PATH+1]; /*******************************/ /* Generate and display banner */ /*******************************/ sscanf("$Revision: 1.28 $", "%*s %s", revision); sprintf(banner,"\n%s v%s-%s" " Copyright %s Rob Swindell" ,TITLE ,revision ,PLATFORM_DESC ,__DATE__+7 ); fprintf(stdout,"%s\n\n", banner); /**********************/ /* Parse command-line */ /**********************/ for(argn=1; argn<argc; argn++) { arg=argv[argn]; while(*arg=='-') arg++; if(stricmp(arg,"help")==0 || *arg=='?') return usage(argv[0]); #ifdef _WIN32 else if(stricmp(arg,"service")==0) daemonize=TRUE; else if(stricmp(arg,"install")==0) return install(); else if(stricmp(arg,"remove")==0) return uninstall(); else if(stricmp(arg,"disable")==0) return enable(FALSE); else if(stricmp(arg,"enable")==0) return enable(TRUE); #endif } /******************/ /* Read .ini file */ /******************/ /* Generate path/sexpots[.host].ini from path/sexpots[.exe] */ SAFECOPY(path,argv[0]); p=getfname(path); SAFECOPY(fname,p); *p=0; if((p=getfext(fname))!=NULL) *p=0; strcat(fname,".ini"); iniFileName(ini_fname,sizeof(ini_fname),path,fname); parse_ini_file(ini_fname); #if defined(_WIN32) if(daemonize) { SERVICE_TABLE_ENTRY ServiceDispatchTable[] = { { NAME, (void(WINAPI*)(DWORD, char**))service_loop }, { NULL, NULL } /* Terminator */ }; printf("Starting service control dispatcher.\n" ); printf("This may take several seconds. Please wait.\n" ); if(!StartServiceCtrlDispatcher(ServiceDispatchTable)) { lprintf(LOG_ERR,"StartServiceCtrlDispatcher ERROR %d",GetLastError()); return -1; } return 0; } SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */); #endif service_loop(argc,argv); return 0; }
int main(int argc, char **argv) { _gc = new GlobalConfig; #ifdef WIN32 _verbase = false; if (argc == 2 && strcmp(argv[1], "/install") == 0) { return install_service(argv[0]); } if (argc == 2 && strcmp(argv[1], "/uninstall") == 0) { return uninstall_service(argv[0]); } if (argc == 2 && strcmp(argv[1], "/debug") == 0) { _verbase = true; } // if (argc == 1) // _verbase = true; #if LICENSE int lcs_chk = el_init("zonekey_mcu.lcs"); if (lcs_chk == -1) { fprintf(stderr, "ERR: license check error\n"); return -1; } else if (lcs_chk == -2) { fprintf(stderr, "ERR: license timeout\n"); return -2; } const char *feathers = el_getfeatures(); KVS fs = parse_feathers(feathers); // TODO: 检查是否限制同时启动的数目 ... KVS::const_iterator itf = fs.find("cap_max"); if (itf != fs.end()) { _gc->cap_max = atoi(itf->second.c_str()); if (_gc->cap_max == 0) _gc->cap_max = 1; } #endif // HANDLE env = OpenEvent(EVENT_MODIFY_STATE, 0, GLOBAL_NAME); if (env) { fprintf(stderr, "zonekey_mcu: only one instance running\n"); CloseHandle(env); return -1; } else { env = CreateEvent(0, 0, 0, GLOBAL_NAME); _global_obj = env; if (!_verbase) { SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)mainp }, { 0, 0 }, }; // 启动服务的控制分派机线程,这个将直到服务结束后,返回 StartServiceCtrlDispatcher(ServiceTable); return 0; } else { mainp(argc, argv); return 0; } } #else // // linux mainp(argc, argv); return 0; #endif // }
int main( int argc, char *argv[] ) { #ifdef WIN32 if( argv[0] ) { char *szEndPos = strrchr( argv[0], '\\' ); if( szEndPos ) { char *szEXEPath = new char[szEndPos - argv[0] + 1]; memcpy( szEXEPath, argv[0], szEndPos - argv[0] ); szEXEPath[szEndPos - argv[0]] = '\0'; SetCurrentDirectory( szEXEPath ); delete [] szEXEPath; } } if( argc > 1 ) { CFG_Open( CFG_FILE ); #define BNBT_SERVICE_NAME const_cast<LPSTR> (CFG_GetString( "cbtt_service_name", "CBTT Service" ).c_str()) CFG_Close( CFG_FILE ); printf( "Service name "); printf( BNBT_SERVICE_NAME ); printf( "\n" ); if( _stricmp( argv[1], "-i" ) == 0 ) { // install service if( UTIL_NTServiceTest( ) ) printf( "BNBT Service is already installed!\n" ); else { if( UTIL_NTServiceInstall( ) ) printf( "BNBT Service installed.\n" ); else printf( "BNBT Service failed to install (error %d).\n", GetLastError( ) ); } return 0; } else if( _stricmp( argv[1], "-u" ) == 0 ) { // uninstall service if( !UTIL_NTServiceTest( ) ) printf( "BNBT Service is not installed!\n" ); else { if( UTIL_NTServiceUninstall( ) ) printf( "BNBT Service uninstalled.\n" ); else printf( "BNBT Service failed to uninstall (error %d).\n", GetLastError( ) ); } return 0; } else if( _stricmp( argv[1], "-start" ) == 0 ) { // start if( !UTIL_NTServiceTest( ) ) printf( "BNBT Service is not installed!\n" ); else { printf( "Starting BNBT Service.\n" ); if( !UTIL_NTServiceStart( ) ) printf( "BNBT Service failed to start (error %d).\n", GetLastError( ) ); } return 0; } else if( _stricmp( argv[1], "-stop" ) == 0 ) { // stop if( !UTIL_NTServiceTest( ) ) printf( "BNBT Service is not installed!\n" ); else { printf( "Stopping BNBT Service.\n" ); if( !UTIL_NTServiceStop( ) ) printf( "BNBT Service failed to stop (error %d).\n", GetLastError( ) ); } return 0; } else if( _stricmp( argv[1], "-s" ) == 0 ) { // internal start SERVICE_TABLE_ENTRY st[] = { { BNBT_SERVICE_NAME, NTServiceMain }, { NULL, NULL } }; StartServiceCtrlDispatcher( st ); return 0; } } #else // disable SIGPIPE since some systems like OS X don't define MSG_NOSIGNAL signal( SIGPIPE, SIG_IGN ); #endif // catch SIGABRT and SIGINT // 2006/12/04 and SIGTERM and SIGHUP signal( SIGABRT, sigCatcher ); signal( SIGINT, sigCatcher ); signal( SIGTERM, sigCatcher ); #ifndef WIN32 signal( SIGHUP, sigCatcher ); #endif return bnbtmain( ); }
int main(int argc, char* argv[]) { SC_HANDLE hSCManager = NULL, hService = NULL; TCHAR szImagePath[MAX_PATH]; HKEY hk; DWORD dwType; SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, ServiceMain }, { NULL, NULL } }; LPSTR szRoot; if(argc==1) { // Attempt to start service. If this fails we're probably // not running as a service if(!StartServiceCtrlDispatcher(ServiceTable)) return 0; } if(argc<2 || (strcmp(argv[1],"-i") && strcmp(argv[1],"-reglsa") && strcmp(argv[1],"-u") && strcmp(argv[1],"-unreglsa") && strcmp(argv[1],"-test") && strcmp(argv[1],"-v") )) { fprintf(stderr, "CVSNT Service Handler\n\n" "Arguments:\n" "\t%s -i [cvsroot]\tInstall\n" "\t%s -reglsa\tRegister LSA helper\n" "\t%s -u\tUninstall\n" "\t%s -unreglsa\tUnregister LSA helper\n" "\t%s -test\tInteractive run\n" "\t%s -v\tReport version number\n", basename(argv[0]),basename(argv[0]), basename(argv[0]), basename(argv[0]), basename(argv[0]), basename(argv[0]) ); return -1; } if(!strcmp(argv[1],"-reglsa")) { TCHAR lsaBuf[10240]; DWORD dwLsaBuf; if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Control\\Lsa"),0,KEY_ALL_ACCESS,&hk)) { fprintf(stderr,"Couldn't open LSA registry key, error %d\n",GetLastError()); return -1; } dwLsaBuf=sizeof(lsaBuf); if(RegQueryValueEx(hk,_T("Authentication Packages"),NULL,&dwType,(BYTE*)lsaBuf,&dwLsaBuf)) { fprintf(stderr,"Couldn't read LSA registry key, error %d\n",GetLastError()); return -1; } if(dwType!=REG_MULTI_SZ) { fprintf(stderr,"LSA key isn't REG_MULTI_SZ!!!\n"); return -1; } lsaBuf[dwLsaBuf]='\0'; TCHAR *p = lsaBuf; while(*p) { if(!_tcscmp(p,"setuid")) break; p+=strlen(p)+1; } if(!*p) { strcpy(p,"setuid"); dwLsaBuf+=strlen(p)+1; lsaBuf[dwLsaBuf]='\0'; if(RegSetValueEx(hk,_T("Authentication Packages"),NULL,dwType,(BYTE*)lsaBuf,dwLsaBuf)) { fprintf(stderr,"Couldn't write LSA registry key, error %d\n",GetLastError()); return -1; } } return 0; } if(!strcmp(argv[1],"-unreglsa")) { TCHAR lsaBuf[10240]; DWORD dwLsaBuf; if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Control\\Lsa"),0,KEY_ALL_ACCESS,&hk)) { fprintf(stderr,"Couldn't open LSA registry key, error %d\n",GetLastError()); return -1; } dwLsaBuf=sizeof(lsaBuf); if(RegQueryValueEx(hk,_T("Authentication Packages"),NULL,&dwType,(BYTE*)lsaBuf,&dwLsaBuf)) { fprintf(stderr,"Couldn't read LSA registry key, error %d\n",GetLastError()); return -1; } if(dwType!=REG_MULTI_SZ) { fprintf(stderr,"LSA key isn't REG_MULTI_SZ!!!\n"); return -1; } lsaBuf[dwLsaBuf]='\0'; TCHAR *p = lsaBuf; while(*p) { if(!_tcscmp(p,"setuid")) break; p+=strlen(p)+1; } if(*p) { size_t l = strlen(p)+1; memcpy(p,p+l,(dwLsaBuf-((p+l)-lsaBuf))+1); dwLsaBuf-=l; if(RegSetValueEx(hk,_T("Authentication Packages"),NULL,dwType,(BYTE*)lsaBuf,dwLsaBuf)) { fprintf(stderr,"Couldn't write LSA registry key, error %d\n",GetLastError()); return -1; } } return 0; } if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\CVS\\Pserver"),NULL,_T(""),REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hk,NULL)) { fprintf(stderr,"Couldn't create HKLM\\Software\\CVS\\Pserver key, error %d\n",GetLastError()); return -1; } if (!strcmp(argv[1],"-v")) { puts(NTSERVICE_VERSION_STRING); return 0; } if(!strcmp(argv[1],"-i")) { if(argc==3) { szRoot = argv[2]; if(GetFileAttributesA(szRoot)==(DWORD)-1) { fprintf(stderr,"Repository directory '%s' not found\n",szRoot); return -1; } dwType=REG_SZ; RegSetValueExA(hk,"Repository0",NULL,dwType,(BYTE*)szRoot,strlen(szRoot)+1); } // connect to the service control manager if((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { fprintf(stderr,"OpenSCManager Failed\n"); return -1; } if((hService=OpenService(hSCManager,SERVICE_NAME,DELETE))!=NULL) { DeleteService(hService); CloseServiceHandle(hService); } GetModuleFileName(NULL,szImagePath,MAX_PATH); if ((hService = CreateService(hSCManager,SERVICE_NAME,DISPLAY_NAME, STANDARD_RIGHTS_REQUIRED|SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szImagePath, NULL, NULL, NULL, NULL, NULL)) == NULL) { fprintf(stderr,"CreateService Failed: %s\n",GetErrorString()); return -1; } { BOOL (WINAPI *pChangeServiceConfig2)(SC_HANDLE,DWORD,LPVOID); pChangeServiceConfig2=(BOOL (WINAPI *)(SC_HANDLE,DWORD,LPVOID))GetProcAddress(GetModuleHandle("advapi32"),"ChangeServiceConfig2A"); if(pChangeServiceConfig2) { SERVICE_DESCRIPTION sd = { NTSERVICE_VERSION_STRING }; if(!pChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sd)) { 0; } } } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); ReportError(FALSE,DISPLAY_NAMEA " installed successfully"); printf(DISPLAY_NAMEA " installed successfully\n"); } RegCloseKey(hk); if(!strcmp(argv[1],"-u")) { // connect to the service control manager if((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { fprintf(stderr,"OpenSCManager Failed\n"); return -1; } if((hService=OpenService(hSCManager,SERVICE_NAME,DELETE))==NULL) { fprintf(stderr,"OpenService Failed: %s\n",GetErrorString()); return -1; } if(!DeleteService(hService)) { fprintf(stderr,"DeleteService Failed: %s\n",GetErrorString()); return -1; } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); ReportError(FALSE,DISPLAY_NAMEA " uninstalled successfully"); printf(DISPLAY_NAMEA " uninstalled successfully\n"); } else if(!strcmp(argv[1],"-test")) { ServiceMain(999,NULL); } return 0; }
int _tmain (int argc, TCHAR *argv[]) { fs::path exe_path( fs::initial_path<fs::path>() ); exe_path = fs::system_complete( fs::path(argv[0]) ); fs::current_path(exe_path.parent_path()); Config& config = Config::getInstance(); config.cfg_file = fs::current_path().string() + "\\daemon.cfg"; config.output_log = fs::current_path().string() + "\\" + std::string(LOG_DIRECTORY) + std::string(LOG_MAIN_FILE); config.error_log = fs::current_path().string() + "\\" + std::string(LOG_DIRECTORY) + std::string(LOG_ERROR_FILE); if (!fs::exists(LOG_DIRECTORY)) { fs::create_directory(LOG_DIRECTORY); } time_t now = time(nullptr); tm *ltm = localtime(&now); char buffer_time[256]; strftime(buffer_time, sizeof(buffer_time), "%Y%m%d_%H%M", ltm); if (fs::exists(config.output_log) && fs::file_size(config.output_log) > 0) { fs::rename( config.output_log, boost::str(boost::format("%1%main_%2%.log") % LOG_DIRECTORY % buffer_time) ); } if (fs::exists(config.error_log) && fs::file_size(config.error_log) > 0) { fs::rename( config.error_log, boost::str(boost::format("%1%error_%2%.log") % LOG_DIRECTORY % buffer_time) ); } #ifndef NON_DAEMON freopen(config.output_log.c_str(), "w", stdout); freopen(config.error_log.c_str(), "w", stderr); #endif // Info std::cout << "CurrentPath: " << fs::current_path() << std::endl; std::cout << "Config: " << config.cfg_file << std::endl; std::cout << "OutputLog: " << config.output_log << std::endl; std::cout << "ErrorLog: " << config.error_log << std::endl; #ifdef NON_DAEMON run_daemon(); #else SERVICE_TABLE_ENTRY ServiceTable[] = { {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, {NULL, NULL} }; if (StartServiceCtrlDispatcher (ServiceTable) == FALSE) { return GetLastError (); } #endif }
/** start */ void start_and_wait(std::string name) { name_ = utf8::cvt<std::wstring>(name); print_debug(_T("Starting: ") + name_); create_dispatch_table(name_); StartServiceCtrlDispatcher(); }
int _tmain(int argc, TCHAR **argv) { check_console(); #ifdef UNICODE /* Ensure we write in UTF-16 mode, so that non-ASCII characters don't get mangled. If we were compiled in ANSI mode it won't work. */ _setmode(_fileno(stdout), _O_U16TEXT); _setmode(_fileno(stderr), _O_U16TEXT); #endif /* Remember if we are admin */ check_admin(); /* Set up function pointers. */ if (get_imports()) exit(111); /* Remember our path for later. */ GetModuleFileName(0, unquoted_imagepath, _countof(unquoted_imagepath)); GetModuleFileName(0, imagepath, _countof(imagepath)); PathQuoteSpaces(imagepath); /* Elevate */ if (argc > 1) { /* Valid commands are: start, stop, pause, continue, install, edit, get, set, reset, unset, remove */ if (str_equiv(argv[1], _T("start"))) exit(control_service(NSSM_SERVICE_CONTROL_START, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("stop"))) exit(control_service(SERVICE_CONTROL_STOP, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("restart"))) { int ret = control_service(SERVICE_CONTROL_STOP, argc - 2, argv + 2); if (ret) exit(ret); exit(control_service(NSSM_SERVICE_CONTROL_START, argc - 2, argv + 2)); } if (str_equiv(argv[1], _T("pause"))) exit(control_service(SERVICE_CONTROL_PAUSE, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("continue"))) exit(control_service(SERVICE_CONTROL_CONTINUE, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("status"))) exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("rotate"))) exit(control_service(NSSM_SERVICE_CONTROL_ROTATE, argc - 2, argv + 2)); if (str_equiv(argv[1], _T("install"))) { if (! is_admin) exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL)); create_messages(); exit(pre_install_service(argc - 2, argv + 2)); } if (str_equiv(argv[1], _T("edit")) || str_equiv(argv[1], _T("get")) || str_equiv(argv[1], _T("set")) || str_equiv(argv[1], _T("reset")) || str_equiv(argv[1], _T("unset"))) { int ret = pre_edit_service(argc - 1, argv + 1); if (ret == 3 && ! is_admin && argc == 3) exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_EDIT)); /* There might be a password here. */ for (int i = 0; i < argc; i++) SecureZeroMemory(argv[i], _tcslen(argv[i]) * sizeof(TCHAR)); exit(ret); } if (str_equiv(argv[1], _T("list"))) exit(list_nssm_services()); if (str_equiv(argv[1], _T("remove"))) { if (! is_admin) exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_REMOVE)); exit(pre_remove_service(argc - 2, argv + 2)); } } /* Thread local storage for error message buffer */ tls_index = TlsAlloc(); /* Register messages */ if (is_admin) create_messages(); /* Optimisation for Windows 2000: When we're run from the command line the StartServiceCtrlDispatcher() call will time out after a few seconds on Windows 2000. On newer versions the call returns instantly. Check for stdin first and only try to call the function if there's no input stream found. Although it's possible that we're running with input redirected it's much more likely that we're actually running as a service. This will save time when running with no arguments from a command prompt. */ if (! GetStdHandle(STD_INPUT_HANDLE)) { /* Start service magic */ SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } }; if (! StartServiceCtrlDispatcher(table)) { unsigned long error = GetLastError(); /* User probably ran nssm with no argument */ if (error == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) exit(usage(1)); log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, error_string(error), 0); free_imports(); exit(100); } } else exit(usage(1)); /* And nothing more to do */ exit(0); }
int daemon_main(const char * ident, const daemon_winsvc_options * svc_opts, int (*main_func)(int, char **), int argc, char **argv ) { int rc; #ifdef _DEBUG // Enable Debug heap checks _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) |_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF); #endif // Check for [status|stop|reload|restart|sigusr1|sigusr2] parameters if ((rc = initd_main(ident, argc, argv)) >= 0) return rc; // Check for [install|remove] parameters if (svc_opts && (rc = svcadm_main(ident, svc_opts, argc, argv)) >= 0) return rc; // Run as service if svc_opts.cmd_opt is given as first(!) argument svc_mode = (svc_opts && argc >= 2 && !strcmp(argv[1], svc_opts->cmd_opt)); if (!svc_mode) { // Daemon: Try to simulate a Unix-like daemon HANDLE rev; BOOL exists; // Create main event to detect process type: // 1. new: parent process => start child and wait for detach() or exit() of child. // 2. exists && signaled: child process => do the real work, signal detach() to parent // 3. exists && !signaled: already running => exit() if (!(rev = create_event(EVT_RUNNING, TRUE/*signaled*/, TRUE, &exists))) return 100; if (!exists && !debugging()) { // Event new => parent process return parent_main(rev); } if (WaitForSingleObject(rev, 0) == WAIT_OBJECT_0) { // Event was signaled => In child process return child_main(rev, main_func, argc, argv); } // Event no longer signaled => Already running! daemon_help(stdout, ident, "already running"); CloseHandle(rev); return 1; } else { // Service: Start service_main() via SCM SERVICE_TABLE_ENTRY service_table[] = { { (char*)svc_opts->svcname, service_main }, { NULL, NULL } }; svc_main_func = main_func; svc_main_argc = argc; svc_main_argv = argv; if (!StartServiceCtrlDispatcher(service_table)) { printf("%s: cannot dispatch service, Error=%ld\n" "Option \"%s\" cannot be used to start %s as a service from console.\n" "Use \"%s install ...\" to install the service\n" "and \"net start %s\" to start it.\n", ident, GetLastError(), svc_opts->cmd_opt, ident, ident, ident); #ifdef _DEBUG if (debugging()) service_main(argc, argv); #endif return 100; } Sleep(1000); ExitThread(0); // Do not redo exit() processing /*NOTREACHED*/ return 0; } }
/* the main application entry point */ int main(int argc, char *argv[]) { char pid_path[PATH_MAX] = ""; /* full path to the pid file */ char pid_buffer[32] = ""; /* pid string */ char old_pid_buffer[32] = ""; /* pid string */ switch_size_t pid_len, old_pid_len; const char *err = NULL; /* error value for return from freeswitch initialization */ #ifndef WIN32 switch_bool_t nf = SWITCH_FALSE; /* TRUE if we are running in nofork mode */ switch_bool_t do_wait = SWITCH_FALSE; char *runas_user = NULL; char *runas_group = NULL; int fds[2] = { 0, 0 }; #else switch_bool_t win32_service = SWITCH_FALSE; #endif switch_bool_t nc = SWITCH_FALSE; /* TRUE if we are running in noconsole mode */ pid_t pid = 0; int i, x; char *opts; char opts_str[1024] = ""; char *local_argv[1024] = { 0 }; int local_argc = argc; char *arg_argv[128] = { 0 }; int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0; int priority = 0; #ifdef __sun switch_core_flag_t flags = SCF_USE_SQL; #else switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT; #endif int ret = 0; switch_status_t destroy_status; switch_file_t *fd; switch_memory_pool_t *pool = NULL; #ifdef HAVE_SETRLIMIT #ifndef FS_64BIT switch_bool_t waste = SWITCH_FALSE; #endif #endif for (x = 0; x < argc; x++) { local_argv[x] = argv[x]; } if ((opts = getenv("FREESWITCH_OPTS"))) { strncpy(opts_str, opts, sizeof(opts_str) - 1); i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0]))); for (x = 0; x < i; x++) { local_argv[local_argc++] = arg_argv[x]; } } if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) { nc = SWITCH_TRUE; } for (x = 1; x < local_argc; x++) { if (switch_strlen_zero(local_argv[x])) continue; if (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")) { printf("%s\n", usage); exit(EXIT_SUCCESS); } #ifdef WIN32 if (x == 1 && !strcmp(local_argv[x], "-service")) { /* New installs will always have the service name specified, but keep a default for compat */ x++; if (!switch_strlen_zero(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } win32_service = SWITCH_TRUE; continue; } else if (x == 1 && !strcmp(local_argv[x], "-install")) { char servicePath[PATH_MAX]; char exePath[PATH_MAX]; SC_HANDLE hService; SC_HANDLE hSCManager; SERVICE_DESCRIPTION desc; desc.lpDescription = "The FreeSWITCH service."; x++; if (!switch_strlen_zero(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } GetModuleFileName(NULL, exePath, sizeof(exePath)); snprintf(servicePath, sizeof(servicePath), "%s -service %s", exePath, service_name); /* Perform service installation */ hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hSCManager) { fprintf(stderr, "Could not open service manager (%u).\n", GetLastError()); exit(EXIT_FAILURE); } hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, servicePath, NULL, NULL, NULL, NULL, /* Service start name */ NULL); if (!hService) { fprintf(stderr, "Error creating freeswitch service (%u).\n", GetLastError()); CloseServiceHandle(hSCManager); exit(EXIT_FAILURE); } /* Set desc, and don't care if it succeeds */ if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) { fprintf(stderr, "FreeSWITCH installed, but could not set the service description (%u).\n", GetLastError()); } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); exit(EXIT_SUCCESS); } else if (x == 1 && !strcmp(local_argv[x], "-uninstall")) { SC_HANDLE hService; SC_HANDLE hSCManager; BOOL deleted; x++; if (!switch_strlen_zero(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } /* Do the uninstallation */ hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hSCManager) { fprintf(stderr, "Could not open service manager (%u).\n", GetLastError()); exit(EXIT_FAILURE); } hService = OpenService(hSCManager, service_name, DELETE); if (!hService) { fprintf(stderr, "Error opening service (%u).\n", GetLastError()); CloseServiceHandle(hSCManager); exit(EXIT_FAILURE); } /* remove the service! */ deleted = DeleteService(hService); if (!deleted) { fprintf(stderr, "Error deleting service (%u).\n", GetLastError()); } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE); } else if (!strcmp(local_argv[x], "-monotonic-clock")) { flags |= SCF_USE_WIN32_MONOTONIC; } #else else if (!strcmp(local_argv[x], "-u")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]); exit(EXIT_FAILURE); } runas_user = local_argv[x]; } else if (!strcmp(local_argv[x], "-g")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]); exit(EXIT_FAILURE); } runas_group = local_argv[x]; } else if (!strcmp(local_argv[x], "-nf")) { nf = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); exit(EXIT_SUCCESS); } #endif #ifdef HAVE_SETRLIMIT else if (!strcmp(local_argv[x], "-core")) { struct rlimit rlp; memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = RLIM_INFINITY; rlp.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlp); } else if (!strcmp(local_argv[x], "-waste")) { #ifndef FS_64BIT fprintf(stderr, "WARNING: Wasting up to 8 megs of memory per thread.\n"); sleep(2); waste = SWITCH_TRUE; #endif } else if (!strcmp(local_argv[x], "-no-auto-stack")) { #ifndef FS_64BIT waste = SWITCH_TRUE; #endif } #endif else if (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp")) { priority = 2; } else if (!strcmp(local_argv[x], "-lp")) { priority = -1; } else if (!strcmp(local_argv[x], "-np")) { priority = 1; } else if (!strcmp(local_argv[x], "-nosql")) { flags &= ~SCF_USE_SQL; } else if (!strcmp(local_argv[x], "-nonat")) { flags &= ~SCF_USE_AUTO_NAT; } else if (!strcmp(local_argv[x], "-nonatmap")) { flags &= ~SCF_USE_NAT_MAPPING; } else if (!strcmp(local_argv[x], "-heavy-timer")) { flags |= SCF_USE_HEAVY_TIMING; } else if (!strcmp(local_argv[x], "-nort")) { flags &= ~SCF_USE_CLOCK_RT; } else if (!strcmp(local_argv[x], "-nocal")) { flags &= ~SCF_CALIBRATE_CLOCK; } else if (!strcmp(local_argv[x], "-vg")) { flags |= SCF_VG; } else if (!strcmp(local_argv[x], "-stop")) { do_kill = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-nc")) { nc = SWITCH_TRUE; } #ifndef WIN32 else if (!strcmp(local_argv[x], "-ncwait")) { nc = SWITCH_TRUE; do_wait = SWITCH_TRUE; } #endif else if (!strcmp(local_argv[x], "-c")) { nc = SWITCH_FALSE; } else if (!strcmp(local_argv[x], "-conf")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -conf you must specify a config directory\n"); return 255; } SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.conf_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]); alt_dirs++; } else if (!strcmp(local_argv[x], "-mod")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -mod you must specify a module directory\n"); return 255; } SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.mod_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.mod_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-log")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -log you must specify a log directory\n"); return 255; } SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.log_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]); alt_dirs++; log_set = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-run")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -run you must specify a pid directory\n"); return 255; } SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.run_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.run_dir, local_argv[x]); run_set = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-db")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -db you must specify a db directory\n"); return 255; } SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.db_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]); alt_dirs++; } else if (!strcmp(local_argv[x], "-scripts")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -scripts you must specify a scripts directory\n"); return 255; } SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.script_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.script_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-htdocs")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n"); return 255; } SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.htdocs_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.htdocs_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-base")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -base you must specify a base directory\n"); return 255; } SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.base_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.base_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-temp")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -temp you must specify a temp directory\n"); return 255; } SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.temp_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.temp_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-storage")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -storage you must specify a storage directory\n"); return 255; } SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.storage_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.storage_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-recordings")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -recordings you must specify a recording directory\n"); return 255; } SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.recordings_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.recordings_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-grammar")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -grammar you must specify a grammar directory\n"); return 255; } SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.grammar_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.grammar_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-sounds")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -sounds you must specify a sounds directory\n"); return 255; } SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.sounds_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.sounds_dir, local_argv[x]); } else if (!strcmp(local_argv[x], "-cfgname")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -cfgname you must specify a filename\n"); return 255; } SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_filenames.conf_name) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_filenames.conf_name, local_argv[x]); } /* Unknown option (always last!) */ else { fprintf(stderr, "Unknown option '%s', see '%s -help' for a list of valid options\n", local_argv[x], local_argv[0]); exit(EXIT_FAILURE); } } if (log_set && !run_set) { SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(SWITCH_GLOBAL_dirs.log_dir) + 1); if (!SWITCH_GLOBAL_dirs.run_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir); } if (do_kill) { return freeswitch_kill_background(); } if (apr_initialize() != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "FATAL ERROR! Could not initialize APR\n"); return 255; } if (alt_dirs && alt_dirs != 3) { fprintf(stderr, "You must specify all or none of -conf, -log, and -db\n"); return 255; } #ifndef FS_64BIT #if defined(HAVE_SETRLIMIT) && !defined(__sun) if (!waste && !(flags & SCF_VG)) { struct rlimit rlp; memset(&rlp, 0, sizeof(rlp)); getrlimit(RLIMIT_STACK, &rlp); if (rlp.rlim_cur != SWITCH_THREAD_STACKSIZE) { char buf[1024] = ""; int i = 0; memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; setrlimit(RLIMIT_STACK, &rlp); apr_terminate(); ret = (int) execv(argv[0], argv); for (i = 0; i < argc; i++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]); } return system(buf); } } #endif #endif signal(SIGILL, handle_SIGILL); signal(SIGTERM, handle_SIGILL); #ifndef WIN32 if (do_wait) { if (pipe(fds)) { fprintf(stderr, "System Error!\n"); exit(-1); } signal(SIGCHLD, handle_SIGCHLD); } #endif if (nc) { #ifdef WIN32 FreeConsole(); #else if (!nf) { daemonize(do_wait ? fds : NULL); } #endif } switch (priority) { case 2: set_realtime_priority(); break; case 1: set_normal_priority(); break; case -1: set_low_priority(); break; default: set_auto_priority(); break; } switch_core_setrlimits(); #ifndef WIN32 if (runas_user || runas_group) { if (change_user_group(runas_user, runas_group) < 0) { fprintf(stderr, "Failed to switch user [%s] / group [%s]\n", switch_strlen_zero(runas_user) ? "-" : runas_user, switch_strlen_zero(runas_group) ? "-" : runas_group); return 255; } } #else if (win32_service) { /* Attempt to start service */ SERVICE_TABLE_ENTRY dispatchTable[] = { {service_name, &service_main} , {NULL, NULL} }; service_flags = flags; /* copy parsed flags for service startup */ if (StartServiceCtrlDispatcher(dispatchTable) == 0) { /* Not loaded as a service */ fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n"); fprintf(stderr, "To install the service load freeswitch with -install\n"); } exit(EXIT_SUCCESS); } #endif switch_core_set_globals(); pid = getpid(); memset(pid_buffer, 0, sizeof(pid_buffer)); switch_snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile); switch_snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid); pid_len = strlen(pid_buffer); apr_pool_create(&pool, NULL); switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, pool); if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) == SWITCH_STATUS_SUCCESS) { old_pid_len = sizeof(old_pid_buffer); switch_file_read(fd, old_pid_buffer, &old_pid_len); switch_file_close(fd); } if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot open pid file %s.\n", pid_path); return 255; } if (switch_file_lock(fd, SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot lock pid file %s.\n", pid_path); old_pid_len = strlen(old_pid_buffer); if (strlen(old_pid_buffer)) { switch_file_write(fd, old_pid_buffer, &old_pid_len); } return 255; } switch_file_write(fd, pid_buffer, &pid_len); if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot Initialize [%s]\n", err); return 255; } #ifndef WIN32 if (do_wait) { if (fds[1] > -1) { int i, v = 1; if ((i = write(fds[1], &v, sizeof(v))) < 0) { fprintf(stderr, "System Error [%s]\n", strerror(errno)); } else { i = read(fds[1], &v, sizeof(v)); } shutdown(fds[1], 2); close(fds[1]); fds[1] = -1; } } #endif switch_core_runtime_loop(nc); destroy_status = switch_core_destroy(); switch_file_close(fd); apr_pool_destroy(pool); if (unlink(pid_path) != 0) { fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path); } if (destroy_status == SWITCH_STATUS_RESTART) { char buf[1024] = ""; int j = 0; switch_sleep(1000000); ret = (int) execv(argv[0], argv); fprintf(stderr, "Restart Failed [%s] resorting to plan b\n", strerror(errno)); for (j = 0; j < argc; j++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[j]); } ret = system(buf); } return ret; }
int _tmain(int argc, _TCHAR* argv []) { if (argc < 3 || argc > 4) { puts("usage: System.ServiceProcess.ServiceController.TestNativeService.exe <ServiceName> <DisplayName> [create|delete]"); return 1; } gServiceName = argv[1]; gServiceDisplayName = argv[2]; if (argc == 3) { // When run with just a service name, just run as a service SERVICE_TABLE_ENTRY DispatchTable [] = { { gServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, { NULL, NULL } }; // This call returns when the service has stopped. // The process should simply terminate when the call returns. if (!StartServiceCtrlDispatcher(DispatchTable)) { LogMessage(L"error: StartServiceCtrlDispatcher failed (%d)\n", GetLastError()); } } else if (argc == 4) { if (!InitModulePath()) { return -1; } GenerateDependentServiceNames(); std::wstring action = argv[3]; if (action == L"create") { if (!CreateTestServices()) { wprintf(L"error: Creating the test services failed\n"); DeleteTestServices(); return -1; } } else if (action == L"delete") { if (!DeleteTestServices()) { wprintf(L"error: Deleting the test services failed\n"); return -1; } } else { wprintf(L"error: Invalid action '%s'\n", action.c_str()); return -1; } } return 0; }
// ------------------------------------------------------------------------ // ========================================================================= int main( int argc, char *argv[] ){ // Предстартовая инициализация JOB = 0; int buf_in_len = 0; char *buf_in = malloc( sizeof( char ) * ( BUF_SIZE + 2 )); // -- sprintf( msg_err, "Main init" ); buf_in_len = GetModuleFileName( NULL, buf_in, BUF_SIZE ); //путь и имя запускаемого сервиса if( buf_in_len < 4 ) return GetLastError(); // -- buf_in_len -= 5; // отрезаем ".exe" buf_in[buf_in_len+1] = 0; buf_in[buf_in_len+2] = 0; // -- int it = buf_in_len; for(; it > 1 ; it--) if( buf_in[it] == '\\' )break; it++; service_path = malloc( sizeof( char ) * ( it + 1 )); strncpy( service_path, buf_in, it ); // -- service_name = malloc( sizeof( char ) * (( buf_in_len - it) + 2 )); strcpy( service_name, ( buf_in + it )); // -- it -= 2; for(; it > 1; it--) if( buf_in[it] == '\\' )break; it++; service_work = malloc( sizeof( char ) * ( it + 1 )); strncpy( service_work, buf_in, it ); // -- if(( strlen( service_path ) > 3 )||( strlen( service_work ) > 3 )){ memset( buf_in, '\0', BUF_SIZE ); sprintf( buf_in, "%slog\\%s.log", service_work, service_name ); if( open_log( buf_in )){ sprintf( msg_err, "Main - Ok." ); free( buf_in ); SetUnhandledExceptionFilter( UnhandledException ); // Ловим некоторые ексепшены // -- SERVICE_TABLE_ENTRY service_table[] = {{service_name, ServiceMain}, { NULL, NULL }}; if( !StartServiceCtrlDispatcher( service_table )){ // Регистрация сервиса DWORD er = GetLastError(); if( er == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ){ if( argc != 2 ){ // Получение консольных параметров fprintf( stderr, "\n******* %s *******\n", version ); fprintf( stderr, "No Exec! Run is Service ( install, remove ).\n" ); }else{ if( strcasecmp( argv[1], "install" ) == 0 ) install_symon(); if( strcasecmp( argv[1], "remove" ) == 0 ) remove_symon(); } fprintf( stderr, "Press <Enter> to exit.\n"); getc(stdin); }else if( er ){ fprintf( stderr, "StartServiceCtrlDispatcher failed.\n"); } } } } // -- // prn_log("Ok."); close_log(); // if( buf_in ) free( buf_in ); if( service_name ) free( service_name ); if( service_work ) free( service_work ); if( service_path ) free( service_path ); // -- return GetLastError(); }
int CArchDaemonWindows::daemonize(const char* name, DaemonFunc func) { assert(name != NULL); assert(func != NULL); // windows 95 family services if (CArchMiscWindows::isWindows95Family()) { typedef DWORD (WINAPI *RegisterServiceProcessT)(DWORD, DWORD); // mark this process as a service so it's not killed when the // user logs off. HINSTANCE kernel = LoadLibrary("kernel32.dll"); if (kernel == NULL) { throw XArchDaemonFailed(new XArchEvalWindows); } RegisterServiceProcessT RegisterServiceProcess = reinterpret_cast<RegisterServiceProcessT>( GetProcAddress(kernel, "RegisterServiceProcess")); if (RegisterServiceProcess == NULL) { // missing RegisterServiceProcess function DWORD err = GetLastError(); FreeLibrary(kernel); throw XArchDaemonFailed(new XArchEvalWindows(err)); } if (RegisterServiceProcess(0, 1) == 0) { // RegisterServiceProcess failed DWORD err = GetLastError(); FreeLibrary(kernel); throw XArchDaemonFailed(new XArchEvalWindows(err)); } FreeLibrary(kernel); // now simply call the daemon function return func(1, &name); } // windows NT family services else { // save daemon function m_daemonFunc = func; // construct the service entry SERVICE_TABLE_ENTRY entry[2]; entry[0].lpServiceName = const_cast<char*>(name); entry[0].lpServiceProc = &CArchDaemonWindows::serviceMainEntry; entry[1].lpServiceName = NULL; entry[1].lpServiceProc = NULL; // hook us up to the service control manager. this won't return // (if successful) until the processes have terminated. s_daemon = this; if (StartServiceCtrlDispatcher(entry) == 0) { // StartServiceCtrlDispatcher failed s_daemon = NULL; throw XArchDaemonFailed(new XArchEvalWindows); } s_daemon = NULL; return m_daemonResult; } }
/* Registers the call-back and configures the actions in case of a failure * with the Windows services manager. */ void service_start(int *argcp, char **argvp[]) { int argc = *argcp; char **argv = *argvp; int i; SERVICE_TABLE_ENTRY service_table[] = { {(LPTSTR)program_name, (LPSERVICE_MAIN_FUNCTION)main}, {NULL, NULL} }; /* 'detached' is 'false' when service_start() is called the first time. * It is 'true', when it is called the second time by the Windows services * manager. */ if (detached) { init_service_status(); wevent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!wevent) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed to create a event (%s).", msg_buf); } poll_fd_wait_event(0, wevent, POLLIN); /* Register the control handler. This function is called by the service * manager to stop the service. */ hstatus = RegisterServiceCtrlHandler(program_name, (LPHANDLER_FUNCTION)control_handler); if (!hstatus) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed to register the service control handler (%s).", msg_buf); } if (monitor) { set_config_failure_actions(); } /* When the service control manager does the call back, it does not * send the same arguments as sent to the main function during the * service start. So, use the arguments passed over during the first * time. */ *argcp = sargc; *argvp = *sargvp; /* XXX: Windows implementation cannot have a unixctl commands in the * traditional sense of unix domain sockets. If an implementation is * done that involves 'unixctl' vlog commands the following call is * needed to make sure that the unixctl commands for vlog get * registered in a daemon, even before the first log message. */ vlog_init(); return; } assert_single_threaded(); /* A reference to arguments passed to the main function the first time. * We need it after the call-back from service control manager. */ sargc = argc; sargvp = argvp; /* We are only interested in the '--service' and '--service-monitor' * options before the call-back from the service control manager. */ for (i = 0; i < argc; i ++) { if (!strcmp(argv[i], "--service")) { detach = true; } else if (!strcmp(argv[i], "--service-monitor")) { monitor = true; } } /* If '--service' is not a command line option, run in foreground. */ if (!detach) { return; } /* If we have been configured to run as a service, then that service * should already have been created either manually or through a start up * script. */ check_service(); detached = true; /* StartServiceCtrlDispatcher blocks and returns after the service is * stopped. */ if (!StartServiceCtrlDispatcher(service_table)) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed at StartServiceCtrlDispatcher (%s)", msg_buf); } exit(0); }
AUGSERV_API aug_result aug_daemonise_BIN(const struct aug_options* options) { const char* sname; SERVICE_TABLE_ENTRY table[] = { { NULL, service_ }, { NULL, NULL } }; aug_result result; /* Make options available to service callback. */ memcpy(&options_, options, sizeof(options_)); if (!(sname = aug_getservopt(AUG_OPTSHORTNAME))) { aug_setctxerror(aug_tlx, __FILE__, __LINE__, "aug", AUG_EINVAL, AUG_MSG("option 'AUG_OPTSHORTNAME' not set")); return -1; } table[0].lpServiceName = (char*)sname; /* The service control dispatcher creates a new thread to execute the ServiceMain function of the service being started. */ /* Flush pending writes to main memory. */ aug_wmb(); /* StartServiceCtrlDispatcher() waits indefinitely for commands from the SCM, and returns control to the process's main function only when all the process' services have stopped, allowing the service process to clean up resources before exiting. */ if (StartServiceCtrlDispatcher(table)) { result = 0; } else { DWORD err = GetLastError(); if (ERROR_FAILED_SERVICE_CONTROLLER_CONNECT == err) { /* This error typically indicates that the program is being run as a console application rather than as a service. If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned. */ aug_setexcept(aug_tlx, AUG_EXNONE); } else aug_setwin32error(aug_tlx, __FILE__, __LINE__, err); result = -1; } /* Ensure writes performed on service thread are visible. */ aug_rmb(); return result; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR lpszCmdLine, int /*nCmdShow*/) { /************************************** * * m a i n * ************************************** * * Functional description * The main routine for Windows based server guardian. * **************************************/ strcpy(instance, FB_DEFAULT_INSTANCE); service_flag = parse_args(lpszCmdLine); service_name->printf(ISCGUARD_SERVICE, instance); remote_name->printf(REMOTE_SERVICE, instance); mutex_name->printf(GUARDIAN_MUTEX, instance); // set the global HINSTANCE as we need it in WINDOW_main hInstance_gbl = hInstance; // allocate space for the event list log_entry = static_cast<log_info*>(malloc(sizeof(log_info))); log_entry->next = NULL; // since the flag is set we run as a service if (service_flag) { CNTL_init(WINDOW_main, instance); const SERVICE_TABLE_ENTRY service_table[] = { {const_cast<char*>(service_name->c_str()), CNTL_main_thread}, {NULL, NULL} }; // BRS There is a error in MinGW (3.1.0) headers // the parameter of StartServiceCtrlDispatcher is declared const in msvc headers #if defined(MINGW) if (!StartServiceCtrlDispatcher(const_cast<SERVICE_TABLE_ENTRY*>(service_table))) #else if (!StartServiceCtrlDispatcher(service_table)) #endif { if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) CNTL_shutdown_service("StartServiceCtrlDispatcher failed"); } if (watcher_thd) { WaitForSingleObject(watcher_thd, 5000); CloseHandle(watcher_thd); } } else { return WINDOW_main(0); } return TRUE; }
VOID _CRTAPI1 main ( VOID ) /*++ Routine Description: This is a main routine for the LANMan Remote Program Load Services. It basically sets up the ControlDispatcher and, on return, exits from this main thread. The call to NetServiceStartCtrlDispatcher does not return until all services have terminated, and this process can go away. It will be up to the ControlDispatcher thread to start/stop/pause/continue any services. If a service is to be started, it will create a thread and then call the main routine of that service. Arguments: Anything passed in from the "command line". Currently, NOTHING. Return Value: NONE Note: --*/ { NTSTATUS ntstatus; // // Create well-known SIDs // if (! NT_SUCCESS (ntstatus = NetpCreateWellKnownSids(NULL))) { KdPrint(( "[RplSvc] main: Failed to create well-known SIDs, ntstatus=0x%x\n", ntstatus )); return; } // // Initialize the RpcServer Locks. // NetpInitRpcServer(); // // Call ServiceStartCtrlDispatcher to set up the control interface. // The API won't return until all services have been terminated. At that // point, we just exit. // #ifndef RPL_NO_SERVICE if ( !StartServiceCtrlDispatcher ( RPLServiceDispatchTable)) { DWORD error = GetLastError(); // // RPL service will eventually go in the same exe with all // other services. Thus, no need here to log anything. // KdPrint(( "[RplSvc] main: StartServiceCtrlDispatcher() fails with error=%d\n", error )); } #else RPL_main( 1, (LPWSTR *)NULL); #endif ExitProcess(0); }
/* in ntservice.c */ 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 Directory 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; }
/* the main application entry point */ int main(int argc, char *argv[]) { char pid_path[256] = ""; /* full path to the pid file */ char pid_buffer[32] = ""; /* pid string */ char old_pid_buffer[32] = ""; /* pid string */ switch_size_t pid_len, old_pid_len; const char *err = NULL; /* error value for return from freeswitch initialization */ #ifndef WIN32 int nf = 0; /* TRUE if we are running in nofork mode */ char *runas_user = NULL; char *runas_group = NULL; #else int win32_service = 0; #endif int nc = 0; /* TRUE if we are running in noconsole mode */ pid_t pid = 0; int i, x; char *opts; char opts_str[1024] = ""; char *local_argv[1024] = { 0 }; int local_argc = argc; char *arg_argv[128] = { 0 }; char *usageDesc; int alt_dirs = 0, log_set = 0, run_set = 0, kill = 0; int known_opt; int high_prio = 0; #ifdef __sun switch_core_flag_t flags = SCF_USE_SQL; #else switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT; #endif int ret = 0; switch_status_t destroy_status; switch_file_t *fd; switch_memory_pool_t *pool = NULL; #ifdef HAVE_SETRLIMIT struct rlimit rlp; int waste = 0; #endif for (x = 0; x < argc; x++) { local_argv[x] = argv[x]; } if ((opts = getenv("FREESWITCH_OPTS"))) { strncpy(opts_str, opts, sizeof(opts_str) - 1); i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0]))); for (x = 0; x < i; x++) { local_argv[local_argc++] = arg_argv[x]; } } if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) { nc++; } usageDesc = "these are the optional arguments you can pass to freeswitch\n" #ifdef WIN32 "\t-service [name] -- start freeswitch as a service, cannot be used if loaded as a console app\n" "\t-install [name] -- install freeswitch as a service, with optional service name\n" "\t-uninstall -- remove freeswitch as a service\n" #else "\t-nf -- no forking\n" "\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n" #endif "\t-help -- this message\n" "\t-version -- print the version and exit\n" #ifdef HAVE_SETRLIMIT "\t-waste -- allow memory waste\n" "\t-core -- dump cores\n" #endif "\t-hp -- enable high priority settings\n" "\t-vg -- run under valgrind\n" "\t-nosql -- disable internal sql scoreboard\n" "\t-heavy-timer -- Heavy Timer, possibly more accurate but at a cost\n" "\t-nonat -- disable auto nat detection\n" "\t-nocal -- disable clock calibration\n" "\t-nort -- disable clock clock_realtime\n" "\t-stop -- stop freeswitch\n" "\t-nc -- do not output to a console and background\n" "\t-c -- output to a console and stay in the foreground\n" "\t-conf [confdir] -- specify an alternate config dir\n" "\t-log [logdir] -- specify an alternate log dir\n" "\t-run [rundir] -- specify an alternate run dir\n" "\t-db [dbdir] -- specify an alternate db dir\n" "\t-mod [moddir] -- specify an alternate mod dir\n" "\t-htdocs [htdocsdir] -- specify an alternate htdocs dir\n" "\t-scripts [scriptsdir] -- specify an alternate scripts dir\n"; for (x = 1; x < local_argc; x++) { known_opt = 0; #ifdef WIN32 if (x == 1) { if (local_argv[x] && !strcmp(local_argv[x], "-service")) { /* New installs will always have the service name specified, but keep a default for compat */ x++; if (local_argv[x] && strlen(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } known_opt++; win32_service++; continue; } if (local_argv[x] && !strcmp(local_argv[x], "-install")) { char exePath[1024]; char servicePath[1024]; x++; if (local_argv[x] && strlen(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } known_opt++; GetModuleFileName(NULL, exePath, 1024); snprintf(servicePath, sizeof(servicePath), "%s -service %s", exePath, service_name); { /* Perform service installation */ SC_HANDLE hService; SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hSCManager) { fprintf(stderr, "Could not open service manager (%d).\n", GetLastError()); exit(1); } hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, servicePath, NULL, NULL, NULL, NULL, /* Service start name */ NULL); if (!hService) { fprintf(stderr, "Error creating freeswitch service (%d).\n", GetLastError()); } else { /* Set desc, and don't care if it succeeds */ SERVICE_DESCRIPTION desc; desc.lpDescription = "The FreeSWITCH service."; if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) { fprintf(stderr, "FreeSWITCH installed, but could not set the service description (%d).\n", GetLastError()); } CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); exit(0); } } if (local_argv[x] && !strcmp(local_argv[x], "-uninstall")) { x++; if (local_argv[x] && strlen(local_argv[x])) { switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN); } else { switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN); } { /* Do the uninstallation */ SC_HANDLE hService; SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hSCManager) { fprintf(stderr, "Could not open service manager (%d).\n", GetLastError()); exit(1); } hService = OpenService(hSCManager, service_name, DELETE); known_opt++; if (hService != NULL) { /* remove the service! */ if (!DeleteService(hService)) { fprintf(stderr, "Error deleting service (%d).\n", GetLastError()); } CloseServiceHandle(hService); } else { fprintf(stderr, "Error opening service (%d).\n", GetLastError()); } CloseServiceHandle(hSCManager); exit(0); } } } #else if (local_argv[x] && !strcmp(local_argv[x], "-u")) { x++; if (local_argv[x] && strlen(local_argv[x])) { runas_user = local_argv[x]; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-g")) { x++; if (local_argv[x] && strlen(local_argv[x])) { runas_group = local_argv[x]; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nf")) { nf++; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s\n", SWITCH_VERSION_FULL); return 0; known_opt++; } #endif #ifdef HAVE_SETRLIMIT if (local_argv[x] && !strcmp(local_argv[x], "-core")) { memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = RLIM_INFINITY; rlp.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlp); known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-waste")) { waste++; known_opt++; } #endif if (local_argv[x] && !strcmp(local_argv[x], "-hp")) { high_prio++; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nosql")) { flags &= ~SCF_USE_SQL; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nonat")) { flags &= ~SCF_USE_AUTO_NAT; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-heavy-timer")) { flags |= SCF_USE_HEAVY_TIMING; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nort")) { flags &= ~SCF_USE_CLOCK_RT; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nocal")) { flags &= ~SCF_CALIBRATE_CLOCK; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-vg")) { flags |= SCF_VG; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-stop")) { kill++; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-nc")) { nc++; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-c")) { nc = 0; known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-conf")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.conf_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]); alt_dirs++; } else { fprintf(stderr, "When using -conf you must specify a config directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-mod")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.mod_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.mod_dir, local_argv[x]); } else { fprintf(stderr, "When using -mod you must specify a module directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-log")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.log_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]); alt_dirs++; log_set++; } else { fprintf(stderr, "When using -log you must specify a log directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-run")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.run_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.run_dir, local_argv[x]); run_set++; } else { fprintf(stderr, "When using -run you must specify a pid directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-db")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.db_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]); alt_dirs++; } else { fprintf(stderr, "When using -db you must specify a db directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-scripts")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.script_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.script_dir, local_argv[x]); } else { fprintf(stderr, "When using -scripts you must specify a scripts directory\n"); return 255; } known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-htdocs")) { x++; if (local_argv[x] && strlen(local_argv[x])) { SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.htdocs_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.htdocs_dir, local_argv[x]); } else { fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n"); return 255; } known_opt++; } if (!known_opt || (local_argv[x] && (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")))) { printf("%s\n", usageDesc); exit(0); } } if (log_set && !run_set) { SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(SWITCH_GLOBAL_dirs.log_dir) + 1); if (!SWITCH_GLOBAL_dirs.run_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir); } if (kill) { return freeswitch_kill_background(); } if (apr_initialize() != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "FATAL ERROR! Could not initialize APR\n"); return 255; } if (alt_dirs && alt_dirs != 3) { fprintf(stderr, "You must specify all or none of -conf, -log, and -db\n"); return 255; } signal(SIGILL, handle_SIGILL); signal(SIGTERM, handle_SIGILL); if (nc) { #ifdef WIN32 FreeConsole(); #else if (!nf) { daemonize(); } #endif } #if defined(HAVE_SETRLIMIT) && !defined(__sun) if (!waste && !(flags & SCF_VG)) { memset(&rlp, 0, sizeof(rlp)); getrlimit(RLIMIT_STACK, &rlp); if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) { char buf[1024] = ""; int i = 0; fprintf(stderr, "Error: stacksize %d is too large: run ulimit -s %d or run %s -waste.\nauto-adjusting stack size for optimal performance...\n", (int) (rlp.rlim_max / 1024), SWITCH_THREAD_STACKSIZE / 1024, local_argv[0]); memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; rlp.rlim_max = SWITCH_THREAD_STACKSIZE; setrlimit(RLIMIT_STACK, &rlp); apr_terminate(); ret = (int) execv(argv[0], argv); for (i = 0; i < argc; i++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]); } return system(buf); } } #endif if (high_prio) { set_high_priority(); } switch_core_setrlimits(); #ifndef WIN32 if (runas_user || runas_group) { if (change_user_group(runas_user, runas_group) < 0) { fprintf(stderr, "Failed to switch user / group\n"); return 255; } } #else if (win32_service) { { /* Attempt to start service */ SERVICE_TABLE_ENTRY dispatchTable[] = { {service_name, &service_main} , {NULL, NULL} }; if (StartServiceCtrlDispatcher(dispatchTable) == 0) { /* Not loaded as a service */ fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n"); fprintf(stderr, "To install the service load freeswitch with -install\n"); } exit(0); } } #endif switch_core_set_globals(); pid = getpid(); memset(pid_buffer, 0, sizeof(pid_buffer)); switch_snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile); switch_snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid); pid_len = strlen(pid_buffer); apr_pool_create(&pool, NULL); switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, pool); if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) == SWITCH_STATUS_SUCCESS) { old_pid_len = sizeof(old_pid_buffer); switch_file_read(fd, old_pid_buffer, &old_pid_len); switch_file_close(fd); } if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot open pid file %s.\n", pid_path); return 255; } if (switch_file_lock(fd, SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot lock pid file %s.\n", pid_path); old_pid_len = strlen(old_pid_buffer); if (strlen(old_pid_buffer)) { switch_file_write(fd, old_pid_buffer, &old_pid_len); } return 255; } switch_file_write(fd, pid_buffer, &pid_len); if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot Initialize [%s]\n", err); return 255; } switch_core_runtime_loop(nc); destroy_status = switch_core_destroy(); switch_file_close(fd); if (unlink(pid_path) != 0) { fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path); } if (destroy_status == SWITCH_STATUS_RESTART) { char buf[1024] = ""; int j = 0; switch_sleep(1000000); ret = (int) execv(argv[0], argv); fprintf(stderr, "Restart Failed [%s] resorting to plan b\n", strerror(errno)); for (j = 0; j < argc; j++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[j]); } ret = system(buf); } return ret; }
int main(int argc, char* argv[]) { SC_HANDLE hSCManager = NULL, hService = NULL; char szImagePath[MAX_PATH]; SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, ServiceMain }, { NULL, NULL } }; if(argc==1) { // Attempt to start service. If this fails we're probably // not running as a service if(!StartServiceCtrlDispatcher(ServiceTable)) return 0; } if(argc!=2 || (strcmp(argv[1],"-i") && strcmp(argv[1],"-u") && strcmp(argv[1],"-test") && strcmp(argv[1],"-v") && strcmp(argv[1],"-systray") )) { fprintf(stderr, "NT CVS Service Handler\n\n" "Arguments:\n" "\t%s -i\tInstall\n" "\t%s -u\tUninstall\n" "\t%s -test\tInteractive run" "\t%s -v\tReport version number", basename(argv[0]),basename(argv[0]), basename(argv[0]), basename(argv[0])); return -1; } if (!strcmp(argv[1],"-v")) { puts(NTSERVICE_VERSION_STRING); return 0; } if(!strcmp(argv[1],"-i")) { // connect to the service control manager if((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { fprintf(stderr,"OpenSCManager Failed\n"); return -1; } if((hService=OpenService(hSCManager,SERVICE_NAME,DELETE))!=NULL) { DeleteService(hService); CloseServiceHandle(hService); } GetModuleFileName(NULL,szImagePath,MAX_PATH); if ((hService = CreateService(hSCManager,SERVICE_NAME,DISPLAY_NAME, STANDARD_RIGHTS_REQUIRED|SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szImagePath, NULL, NULL, NULL, NULL, NULL)) == NULL) { fprintf(stderr,"CreateService Failed: %s\n",GetErrorString()); return -1; } { BOOL (WINAPI *pChangeServiceConfig2)(SC_HANDLE,DWORD,LPVOID); pChangeServiceConfig2=(BOOL (WINAPI *)(SC_HANDLE,DWORD,LPVOID))GetProcAddress(GetModuleHandle("advapi32"),"ChangeServiceConfig2A"); if(pChangeServiceConfig2) { SERVICE_DESCRIPTION sd = { NTSERVICE_VERSION_STRING }; pChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sd); } } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); ReportError(FALSE,DISPLAY_NAME " installed successfully"); printf(DISPLAY_NAME " installed successfully\n"); } if(!strcmp(argv[1],"-u")) { // connect to the service control manager if((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) { fprintf(stderr,"OpenSCManager Failed\n"); return -1; } if((hService=OpenService(hSCManager,SERVICE_NAME,DELETE))==NULL) { fprintf(stderr,"OpenService Failed: %s\n",GetErrorString()); return -1; } if(!DeleteService(hService)) { fprintf(stderr,"DeleteService Failed: %s\n",GetErrorString()); return -1; } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); ReportError(FALSE,DISPLAY_NAME " uninstalled successfully"); printf(DISPLAY_NAME " uninstalled successfully\n"); } else if(!strcmp(argv[1],"-test")) { ServiceMain(999,NULL); } return 0; }
int main(int argc, char* argv[]) { char *arg; if (!initService()) { logMessage("ERROR: Failed to initialise service.\n"); return 1; } if (argc == 1) { /* Service table entry to start service. */ SERVICE_TABLE_ENTRY lpServiceTable[] = { {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, {0, 0} }; /* Start the service. */ if (!StartServiceCtrlDispatcher(lpServiceTable)) { DWORD err = GetLastError(); if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { logMessage("ERROR: Can't run service as a command line program, it must be installed as a service and the '%s' service started.\n", SERVICE_NAME); printf("Can't run service as a command line program, it must be installed as a service and the '%s' service started.\n\n", SERVICE_NAME); } else if (err == ERROR_INVALID_DATA) { logMessage("BUG: Invalid service dispatch table information.\n"); } else if (err == ERROR_SERVICE_ALREADY_RUNNING) { logMessage("ERROR: Failed to start service %s because it is already running.\n", SERVICE_NAME); } else { logMessage("ERROR: Failed to start service %s because it is already running.\n", SERVICE_NAME); } } } else { arg = argv[1]; while (*arg != '\0' && *arg == '-') arg++; if (_stricmp("install", arg) == 0) { /* Install the service. */ return installService(); } else if (_stricmp("uninstall", arg) == 0) { /* Remove the service. */ return uninstallService(); } else if (_stricmp("help", arg) == 0 || *arg == 'h') { /* Print help. */ printf("Usage: %s [install]|[uninstall]\n\n", argv[0]); printf("\t- install - Installs the %s service. For installation to\n", SERVICE_NAME); printf("\t succeed the service must not be currently install.\n"); printf("\t- uninstall - Removes the service %s.\n\n", SERVICE_NAME); printf("Once the service is installed the following Windows commands allow\n"); printf("the %s service to started and stopped\n\n", SERVICE_NAME); printf("\t- Start %s: net start \"%s\"\n", SERVICE_NAME, SERVICE_NAME); printf("\t- Stop %s: net stop \"%s\"\n\n", SERVICE_NAME, SERVICE_NAME); printf("Alternatively, the %s service may be started or stopped using the\n", SERVICE_NAME); printf("Windows Services Administrative Tool, located in:\n\n"); printf("\tControl Panel -> Administrative Tools -> Services\n\n"); } } return 0; }
int __cdecl main(int argc, char* argv[]) { ::SetDllDirectory(""); #ifndef _WIN64 HINSTANCE hKernel32 = ::LoadLibrary("Kernel32.dll"); typedef BOOL (WINAPI * SPDEPP)(DWORD); SPDEPP pSPDEPP = (SPDEPP)::GetProcAddress(hKernel32, "SetProcessDEPPolicy"); if(pSPDEPP != NULL) { pSPDEPP(PROCESS_DEP_ENABLE); } ::FreeLibrary(hKernel32); #endif sTitle = "PtokaX DC Hub " + string(PtokaXVersionString); #ifdef _DEBUG sTitle += " [debug]"; #endif #ifdef _DEBUG // AllocConsole(); // hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Cout("PtokaX Debug console\n"); #endif char sBuf[MAX_PATH+1]; ::GetModuleFileName(NULL, sBuf, MAX_PATH); char * sPath = strrchr(sBuf, '\\'); if(sPath != NULL) { PATH = string(sBuf, sPath-sBuf); } else { PATH = sBuf; } char * sServiceName = NULL; bool bInstallService = false; for(int i = 0; i < argc; i++) { if(stricmp(argv[i], "-s") == NULL || stricmp(argv[i], "/service") == NULL) { if(++i == argc) { AppendLog("Missing service name!"); return EXIT_FAILURE; } sServiceName = argv[i]; bService = true; } else if(stricmp(argv[i], "-c") == 0) { if(++i == argc) { printf("Missing config directory!"); return EXIT_FAILURE; } size_t szLen = strlen(argv[i]); if(szLen >= 1 && argv[i][0] != '\\' && argv[i][0] != '/') { if(szLen < 4 || (argv[i][1] != ':' || (argv[i][2] != '\\' && argv[i][2] != '/'))) { printf("Config directory must be absolute path!"); return EXIT_FAILURE; } } if(argv[i][szLen - 1] == '/' || argv[i][szLen - 1] == '\\') { PATH = string(argv[i], szLen - 1); } else { PATH = string(argv[i], szLen); } if(DirExist(PATH.c_str()) == false) { if(CreateDirectory(PATH.c_str(), NULL) == 0) { printf("Config directory not exist and can't be created!"); return EXIT_FAILURE; } } } else if(stricmp(argv[i], "-i") == NULL || stricmp(argv[i], "/install") == NULL) { if(++i == argc) { printf("Please specify service name!"); return EXIT_FAILURE; } sServiceName = argv[i]; bInstallService = true; } else if(stricmp(argv[i], "-u") == NULL || stricmp(argv[i], "/uninstall") == NULL) { if(++i == argc) { printf("Please specify service name!"); return EXIT_FAILURE; } sServiceName = argv[i]; return UninstallService(sServiceName); } else if(stricmp(argv[i], "-v") == NULL || stricmp(argv[i], "/version") == NULL) { printf((sTitle+" built on "+__DATE__+" "+__TIME__).c_str()); return EXIT_SUCCESS; } else if(stricmp(argv[i], "-h") == NULL || stricmp(argv[i], "/help") == NULL) { printf("PtokaX [-c <configdir>] [-i <servicename>] [-u <servicename>] [-v]"); return EXIT_SUCCESS; } else if(stricmp(argv[i], "/nokeycheck") == NULL) { bCmdNoKeyCheck = true; } else if(stricmp(argv[i], "/generatexmllanguage") == NULL) { LangMan::GenerateXmlExample(); return EXIT_SUCCESS; } } if(bInstallService == true) { if(sPath == NULL && strcmp(PATH.c_str(), sBuf) == 0) { return InstallService(sServiceName, NULL); } else { return InstallService(sServiceName, PATH.c_str()); } } ExceptionHandlingInitialize(PATH, sBuf); if(bService == false) { ServerInitialize(); if(ServerStart() == false) { printf("Server start failed!"); ExceptionHandlingUnitialize(); return EXIT_FAILURE; } else { printf((sTitle+" running...\n").c_str()); } MSG msg; BOOL bRet; while((bRet = ::GetMessage(&msg, NULL, 0, 0)) != 0) { if(bRet == -1) { // handle the error and possibly exit } else { if(msg.message == WM_USER+1) { break; } else if(msg.message == WM_TIMER) { if(msg.wParam == srvLoopTimer) { srvLoop->Looper(); } else if(msg.wParam == regtimer) { ServerOnRegTimer(); } else { //Must be script timer ScriptOnTimer(msg.wParam); } } ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } ExceptionHandlingUnitialize(); } else { SERVICE_TABLE_ENTRY DispatchTable[] = { { sServiceName, StartService }, { NULL, NULL } }; if(StartServiceCtrlDispatcher(DispatchTable) == false) { AppendLog("StartServiceCtrlDispatcher failed ("+string((uint32_t)GetLastError())+")!"); ExceptionHandlingUnitialize(); return EXIT_FAILURE; } } return EXIT_SUCCESS; }
int __cdecl main(int argc, char ** argv) { int i; SERVICE_TABLE_ENTRY serviceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, { NULL, NULL } }; BOOL success; if (argc == 1) { // // Register with the SCM // success = StartServiceCtrlDispatcher(serviceTable); if (!success) { service_error_handler("StartServiceCtrlDispatcher", GetLastError()); exit(0); } } else for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-run") == 0) { g_console_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (g_console_event == NULL) { sw_debug(SW_LOG_ERROR, "CreateEvent failed: %d\n", GetLastError()); exit(-1); } SetConsoleCtrlHandler(console_ctrl_handler, TRUE); if (start_mDNSResponder() != S_OK) { exit(-1); } WaitForSingleObject(g_console_event, INFINITE); CloseHandle(g_console_event); stop_mDNSResponder(); exit(0); } else if (strcmp(argv[i], "-install") == 0) { register_service(argc, argv); break; } else if (strcmp(argv[i], "-remove") == 0) { unregister_service(argc, argv); break; } else if (strcmp(argv[i], "-debug") == 0) { // sw_debug_enable(1); } else { fprintf(stderr, "usage: %s [-run][-install][-remove]\n", argv[0]); break; } } return 0; }