jabberd2  2.2.16
util/jsignal.c
Go to the documentation of this file.
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 */