jabberd2  2.3.1
jsignal.c
Go to the documentation of this file.
1 /*
2  * A compatible implementation of signal which relies of sigaction.
3  * More or less taken from teh Stevens book.
4  */
5 
6 #include <signal.h>
7 #include "util.h"
8 
9 #ifdef _WIN32
10 /* Those routines define Windows jabberd2 services */
11 
12 #include <windows.h>
13 #include <winsvc.h>
14 #include <time.h>
15 
16 SERVICE_STATUS jabber_service_status;
17 SERVICE_STATUS_HANDLE jabber_service_status_handle;
18 
19 LPCTSTR jabber_service_name = NULL;
20 LPCTSTR jabber_service_display = NULL;
21 LPCTSTR jabber_service_description = NULL;
22 LPCTSTR jabber_service_depends = NULL;
23 jmainhandler_t *jabber_service_wrapper = NULL;
24 
25 void WINAPI jabber_service_main(DWORD argc, LPTSTR *argv);
26 void WINAPI jabber_service_ctrl_handler(DWORD Opcode);
27 BOOL jabber_install_service();
28 BOOL jabber_delete_service();
29 
30 jsighandler_t *jabber_term_handler = NULL;
31 #endif /* _WIN32 */
32 
34 {
35 #ifdef _WIN32
36  if(signo == SIGTERM) jabber_term_handler = func;
37  return NULL;
38 #else
39  struct sigaction act, oact;
40 
41  act.sa_handler = func;
42  sigemptyset(&act.sa_mask);
43  act.sa_flags = 0;
44 #ifdef SA_RESTART
45  if (signo != SIGALRM)
46  act.sa_flags |= SA_RESTART;
47 #endif
48  if (sigaction(signo, &act, &oact) < 0)
49  return (SIG_ERR);
50  return (oact.sa_handler);
51 #endif
52 }
53 
54 
55 #ifdef _WIN32
56 BOOL WINAPI jabber_ctrl_handler(DWORD dwCtrlType)
57 {
58  if(jabber_term_handler) jabber_term_handler(0);
59  return TRUE;
60 }
61 
62 int jabber_wrap_service(int argc, char** argv, jmainhandler_t *wrapper, LPCTSTR name, LPCTSTR display, LPCTSTR description, LPCTSTR depends)
63 {
64  jabber_service_wrapper = wrapper;
65  jabber_service_name = name;
66  jabber_service_display = display;
67  jabber_service_description = description;
68  jabber_service_depends = depends;
69 
70  if((argc == 2) && !strcmp(argv[1], "-I"))
71  {
72  // Jabber service installation requested
73  if(jabber_install_service())
74  printf("Service %s installed sucessfully.\n", jabber_service_name);
75  else
76  printf("Error installing service %s.\n", jabber_service_name);
77  return 0;
78  }
79  if((argc == 2) && !strcmp(argv[1], "-U"))
80  {
81  // Jabber service removal requested
82  if(jabber_delete_service())
83  printf("Service %s uninstalled sucessfully.\n", jabber_service_name);
84  else
85  printf("Error uninstalling service %s.\n", jabber_service_name);
86  return 0;
87  }
88  if((argc == 2) && !strcmp(argv[1], "-S"))
89  {
90  TCHAR szPathName[MAX_PATH]; LPTSTR slash = NULL;
91  SERVICE_TABLE_ENTRY DispatchTable[] = {{(LPTSTR)jabber_service_name, jabber_service_main}, {NULL, NULL}};
92 
93  GetModuleFileName(NULL, szPathName, sizeof(szPathName));
94 
95  // Set working directory to the service path
96  if(slash = strrchr(szPathName, '\\'))
97  {
98  *slash = 0;
99  SetCurrentDirectory(szPathName);
100  }
101 
102  // Run service dispatcher
103  StartServiceCtrlDispatcher(DispatchTable);
104  return 0;
105  }
106  // If we are not in the service, register console handle for shutdown
107  SetConsoleCtrlHandler(jabber_ctrl_handler, TRUE);
108 
109  // Wrap original main function
110  if(jabber_service_wrapper) return jabber_service_wrapper(argc, argv);
111  return 0;
112 }
113 
114 
115 void WINAPI jabber_service_main(DWORD argc, LPTSTR *argv)
116 {
117  jabber_service_status.dwServiceType = SERVICE_WIN32;
118  jabber_service_status.dwCurrentState = SERVICE_START_PENDING;
119  jabber_service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
120  jabber_service_status.dwWin32ExitCode = 0;
121  jabber_service_status.dwServiceSpecificExitCode = 0;
122  jabber_service_status.dwCheckPoint = 0;
123  jabber_service_status.dwWaitHint = 0;
124 
125  jabber_service_status_handle = RegisterServiceCtrlHandler(jabber_service_name, jabber_service_ctrl_handler);
126  if (jabber_service_status_handle == (SERVICE_STATUS_HANDLE)0)
127  return;
128 
129  jabber_service_status.dwCurrentState = SERVICE_RUNNING;
130  jabber_service_status.dwCheckPoint = 0;
131  jabber_service_status.dwWaitHint = 0;
132  SetServiceStatus(jabber_service_status_handle, &jabber_service_status);
133 
134  if(jabber_service_wrapper) jabber_service_wrapper(argc, argv);
135 
136  jabber_service_status.dwWin32ExitCode = 0;
137  jabber_service_status.dwCurrentState = SERVICE_STOPPED;
138  jabber_service_status.dwCheckPoint = 0;
139  jabber_service_status.dwWaitHint = 0;
140  SetServiceStatus(jabber_service_status_handle, &jabber_service_status);
141 
142  return;
143 }
144 
145 void WINAPI jabber_service_ctrl_handler(DWORD Opcode)
146 {
147  switch(Opcode)
148  {
149  case SERVICE_CONTROL_PAUSE:
150  jabber_service_status.dwCurrentState = SERVICE_PAUSED;
151  break;
152 
153  case SERVICE_CONTROL_CONTINUE:
154  jabber_service_status.dwCurrentState = SERVICE_RUNNING;
155  break;
156 
157  case SERVICE_CONTROL_STOP:
158  jabber_service_status.dwCurrentState = SERVICE_STOP_PENDING;
159  SetServiceStatus(jabber_service_status_handle, &jabber_service_status);
160 
161  // Call int signal
162  if(jabber_term_handler) jabber_term_handler(0);
163  break;
164 
165  case SERVICE_CONTROL_INTERROGATE:
166  break;
167  }
168  return;
169 }
170 
171 BOOL jabber_install_service()
172 {
173 
174  TCHAR szPathName[MAX_PATH];
175  TCHAR szCmd[MAX_PATH + 16];
176  HANDLE schSCManager, schService;
177  SERVICE_DESCRIPTION sdServiceDescription = { jabber_service_description };
178 
179  GetModuleFileName(NULL, szPathName, sizeof(szPathName));
180  sprintf(szCmd, "\"%s\" -S", szPathName);
181 
182  schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
183 
184  if (schSCManager == NULL)
185  return FALSE;
186 
187  schService = CreateService(schSCManager,
188  jabber_service_name, // service name (alias)
189  jabber_service_display, // service name to display
190  SERVICE_ALL_ACCESS, // desired access
191  SERVICE_WIN32_OWN_PROCESS, // service type
192  SERVICE_AUTO_START, // start type
193  SERVICE_ERROR_NORMAL, // error control type
194  szCmd, // service's binary
195  NULL, // no load ordering group
196  NULL, // no tag identifier
197  jabber_service_depends, // dependencies
198  NULL, // LocalSystem account
199  NULL); // no password
200 
201  if (schService == NULL)
202  return FALSE;
203 
204  ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPVOID)&sdServiceDescription);
205 
206  CloseServiceHandle(schService);
207 
208  return TRUE;
209 }
210 
211 BOOL jabber_delete_service()
212 {
213  HANDLE schSCManager;
214  SC_HANDLE hService;
215 
216  schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
217 
218  if (schSCManager == NULL)
219  return FALSE;
220 
221  hService=OpenService(schSCManager, jabber_service_name, SERVICE_ALL_ACCESS);
222 
223  if (hService == NULL)
224  return FALSE;
225 
226  if(DeleteService(hService)==0)
227  return FALSE;
228 
229  if(CloseServiceHandle(hService)==0)
230  return FALSE;
231  else
232  return TRUE;
233 }
234 #endif /* _WIN32 */
void jsighandler_t(int)
Definition: util.h:432
jsighandler_t * jabber_signal(int signo, jsighandler_t *func)
Definition: jsignal.c:33