jabberd2
2.2.16
|
00001 /* 00002 * A compatible implementation of signal which relies of sigaction. 00003 * More or less taken from teh Stevens book. 00004 */ 00005 00006 #include <signal.h> 00007 #include "util.h" 00008 00009 #ifdef _WIN32 00010 /* Those routines define Windows jabberd2 services */ 00011 00012 #include <windows.h> 00013 #include <winsvc.h> 00014 #include <time.h> 00015 00016 SERVICE_STATUS jabber_service_status; 00017 SERVICE_STATUS_HANDLE jabber_service_status_handle; 00018 00019 LPCTSTR jabber_service_name = NULL; 00020 LPCTSTR jabber_service_display = NULL; 00021 LPCTSTR jabber_service_description = NULL; 00022 LPCTSTR jabber_service_depends = NULL; 00023 jmainhandler_t *jabber_service_wrapper = NULL; 00024 00025 void WINAPI jabber_service_main(DWORD argc, LPTSTR *argv); 00026 void WINAPI jabber_service_ctrl_handler(DWORD Opcode); 00027 BOOL jabber_install_service(); 00028 BOOL jabber_delete_service(); 00029 00030 jsighandler_t *jabber_term_handler = NULL; 00031 #endif /* _WIN32 */ 00032 00033 jsighandler_t* jabber_signal(int signo, jsighandler_t *func) 00034 { 00035 #ifdef _WIN32 00036 if(signo == SIGTERM) jabber_term_handler = func; 00037 return NULL; 00038 #else 00039 struct sigaction act, oact; 00040 00041 act.sa_handler = func; 00042 sigemptyset(&act.sa_mask); 00043 act.sa_flags = 0; 00044 #ifdef SA_RESTART 00045 if (signo != SIGALRM) 00046 act.sa_flags |= SA_RESTART; 00047 #endif 00048 if (sigaction(signo, &act, &oact) < 0) 00049 return (SIG_ERR); 00050 return (oact.sa_handler); 00051 #endif 00052 } 00053 00054 00055 #ifdef _WIN32 00056 BOOL WINAPI jabber_ctrl_handler(DWORD dwCtrlType) 00057 { 00058 if(jabber_term_handler) jabber_term_handler(0); 00059 return TRUE; 00060 } 00061 00062 int jabber_wrap_service(int argc, char** argv, jmainhandler_t *wrapper, LPCTSTR name, LPCTSTR display, LPCTSTR description, LPCTSTR depends) 00063 { 00064 jabber_service_wrapper = wrapper; 00065 jabber_service_name = name; 00066 jabber_service_display = display; 00067 jabber_service_description = description; 00068 jabber_service_depends = depends; 00069 00070 if((argc == 2) && !strcmp(argv[1], "-I")) 00071 { 00072 // Jabber service installation requested 00073 if(jabber_install_service()) 00074 printf("Service %s installed sucessfully.\n", jabber_service_name); 00075 else 00076 printf("Error installing service %s.\n", jabber_service_name); 00077 return 0; 00078 } 00079 if((argc == 2) && !strcmp(argv[1], "-U")) 00080 { 00081 // Jabber service removal requested 00082 if(jabber_delete_service()) 00083 printf("Service %s uninstalled sucessfully.\n", jabber_service_name); 00084 else 00085 printf("Error uninstalling service %s.\n", jabber_service_name); 00086 return 0; 00087 } 00088 if((argc == 2) && !strcmp(argv[1], "-S")) 00089 { 00090 TCHAR szPathName[MAX_PATH]; LPTSTR slash = NULL; 00091 SERVICE_TABLE_ENTRY DispatchTable[] = {{(LPTSTR)jabber_service_name, jabber_service_main}, {NULL, NULL}}; 00092 00093 GetModuleFileName(NULL, szPathName, sizeof(szPathName)); 00094 00095 // Set working directory to the service path 00096 if(slash = strrchr(szPathName, '\\')) 00097 { 00098 *slash = 0; 00099 SetCurrentDirectory(szPathName); 00100 } 00101 00102 // Run service dispatcher 00103 StartServiceCtrlDispatcher(DispatchTable); 00104 return 0; 00105 } 00106 // If we are not in the service, register console handle for shutdown 00107 SetConsoleCtrlHandler(jabber_ctrl_handler, TRUE); 00108 00109 // Wrap original main function 00110 if(jabber_service_wrapper) return jabber_service_wrapper(argc, argv); 00111 return 0; 00112 } 00113 00114 00115 void WINAPI jabber_service_main(DWORD argc, LPTSTR *argv) 00116 { 00117 jabber_service_status.dwServiceType = SERVICE_WIN32; 00118 jabber_service_status.dwCurrentState = SERVICE_START_PENDING; 00119 jabber_service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; 00120 jabber_service_status.dwWin32ExitCode = 0; 00121 jabber_service_status.dwServiceSpecificExitCode = 0; 00122 jabber_service_status.dwCheckPoint = 0; 00123 jabber_service_status.dwWaitHint = 0; 00124 00125 jabber_service_status_handle = RegisterServiceCtrlHandler(jabber_service_name, jabber_service_ctrl_handler); 00126 if (jabber_service_status_handle == (SERVICE_STATUS_HANDLE)0) 00127 return; 00128 00129 jabber_service_status.dwCurrentState = SERVICE_RUNNING; 00130 jabber_service_status.dwCheckPoint = 0; 00131 jabber_service_status.dwWaitHint = 0; 00132 SetServiceStatus(jabber_service_status_handle, &jabber_service_status); 00133 00134 if(jabber_service_wrapper) jabber_service_wrapper(argc, argv); 00135 00136 jabber_service_status.dwWin32ExitCode = 0; 00137 jabber_service_status.dwCurrentState = SERVICE_STOPPED; 00138 jabber_service_status.dwCheckPoint = 0; 00139 jabber_service_status.dwWaitHint = 0; 00140 SetServiceStatus(jabber_service_status_handle, &jabber_service_status); 00141 00142 return; 00143 } 00144 00145 void WINAPI jabber_service_ctrl_handler(DWORD Opcode) 00146 { 00147 switch(Opcode) 00148 { 00149 case SERVICE_CONTROL_PAUSE: 00150 jabber_service_status.dwCurrentState = SERVICE_PAUSED; 00151 break; 00152 00153 case SERVICE_CONTROL_CONTINUE: 00154 jabber_service_status.dwCurrentState = SERVICE_RUNNING; 00155 break; 00156 00157 case SERVICE_CONTROL_STOP: 00158 jabber_service_status.dwCurrentState = SERVICE_STOP_PENDING; 00159 SetServiceStatus(jabber_service_status_handle, &jabber_service_status); 00160 00161 // Call int signal 00162 if(jabber_term_handler) jabber_term_handler(0); 00163 break; 00164 00165 case SERVICE_CONTROL_INTERROGATE: 00166 break; 00167 } 00168 return; 00169 } 00170 00171 BOOL jabber_install_service() 00172 { 00173 00174 TCHAR szPathName[MAX_PATH]; 00175 TCHAR szCmd[MAX_PATH + 16]; 00176 HANDLE schSCManager, schService; 00177 SERVICE_DESCRIPTION sdServiceDescription = { jabber_service_description }; 00178 00179 GetModuleFileName(NULL, szPathName, sizeof(szPathName)); 00180 sprintf(szCmd, "\"%s\" -S", szPathName); 00181 00182 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00183 00184 if (schSCManager == NULL) 00185 return FALSE; 00186 00187 schService = CreateService(schSCManager, 00188 jabber_service_name, // service name (alias) 00189 jabber_service_display, // service name to display 00190 SERVICE_ALL_ACCESS, // desired access 00191 SERVICE_WIN32_OWN_PROCESS, // service type 00192 SERVICE_AUTO_START, // start type 00193 SERVICE_ERROR_NORMAL, // error control type 00194 szCmd, // service's binary 00195 NULL, // no load ordering group 00196 NULL, // no tag identifier 00197 jabber_service_depends, // dependencies 00198 NULL, // LocalSystem account 00199 NULL); // no password 00200 00201 if (schService == NULL) 00202 return FALSE; 00203 00204 ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPVOID)&sdServiceDescription); 00205 00206 CloseServiceHandle(schService); 00207 00208 return TRUE; 00209 } 00210 00211 BOOL jabber_delete_service() 00212 { 00213 HANDLE schSCManager; 00214 SC_HANDLE hService; 00215 00216 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 00217 00218 if (schSCManager == NULL) 00219 return FALSE; 00220 00221 hService=OpenService(schSCManager, jabber_service_name, SERVICE_ALL_ACCESS); 00222 00223 if (hService == NULL) 00224 return FALSE; 00225 00226 if(DeleteService(hService)==0) 00227 return FALSE; 00228 00229 if(CloseServiceHandle(hService)==0) 00230 return FALSE; 00231 else 00232 return TRUE; 00233 } 00234 #endif /* _WIN32 */