*/
#include <library.h>
-#include <hydra.h>
#include <daemon.h>
#include <utils/backtrace.h>
*/
extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
+/**
+ * Forward declaration
+ */
+static DWORD WINAPI service_handler(DWORD dwControl, DWORD dwEventType,
+ LPVOID lpEventData, LPVOID lpContext);
+
/**
* Logging hook for library logs, using stderr output
*/
}
/**
- * Initialize and run charon
+ * Control handler for console
*/
-static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv)
+static BOOL WINAPI console_handler(DWORD dwCtrlType)
+{
+ switch (dwCtrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ DBG1(DBG_DMN, "application is stopping, cleaning up");
+ if (status.dwCurrentState == SERVICE_RUNNING)
+ {
+ charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
+ dwCtrlType);
+ }
+ /* signal main thread to clean up */
+ SetEvent(event);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Service handler function
+ */
+static DWORD WINAPI service_handler(DWORD dwControl, DWORD dwEventType,
+ LPVOID lpEventData, LPVOID lpContext)
+{
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ DBG1(DBG_DMN, "service is stopping, cleaning up");
+ if (status.dwCurrentState == SERVICE_RUNNING)
+ {
+ charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
+ dwControl);
+ }
+ /* signal main thread to clean up */
+ SetEvent(event);
+ return NO_ERROR;
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+}
+
+/**
+ * Wait for console program shutdown
+ */
+static int console_wait()
+{
+ update_status(SERVICE_RUNNING);
+
+ if (WaitForSingleObjectEx(event, INFINITE, TRUE) != WAIT_OBJECT_0)
+ {
+ return 2;
+ }
+ return 0;
+}
+
+/**
+ * Wait for service shutdown
+ */
+static int service_wait()
+{
+ /* service is initialized, we now accept control requests */
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ update_status(SERVICE_RUNNING);
+ status.dwControlsAccepted = 0;
+
+ if (WaitForSingleObjectEx(event, INFINITE, TRUE) != WAIT_OBJECT_0)
+ {
+ return 2;
+ }
+ return 0;
+}
+
+/**
+ * Add namespace alias
+ */
+static void __attribute__ ((constructor))register_namespace()
+{
+ /* inherit settings from charon */
+ library_add_namespace("charon");
+}
+
+/**
+ * Initialize and run charon using a wait function
+ */
+static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv, int (*wait)())
{
level_t levels[DBG_MAX];
int i;
if (library_init(NULL, SERVICE_NAME))
{
update_status(SERVICE_START_PENDING);
- if (libhydra_init())
+ if (libcharon_init())
{
+ charon->set_default_loggers(charon, levels, TRUE);
+ charon->load_loggers(charon);
+ print_version();
update_status(SERVICE_START_PENDING);
- if (libcharon_init())
+ if (charon->initialize(charon, PLUGINS))
{
- charon->load_loggers(charon, levels, TRUE);
- print_version();
update_status(SERVICE_START_PENDING);
- if (charon->initialize(charon, PLUGINS))
- {
- update_status(SERVICE_START_PENDING);
- lib->plugins->status(lib->plugins, LEVEL_CTRL);
-
- charon->start(charon);
+ lib->plugins->status(lib->plugins, LEVEL_CTRL);
- status.dwWin32ExitCode = 0;
- update_status(SERVICE_RUNNING);
+ charon->start(charon);
- /* main thread goes to sleep */
- WaitForSingleObjectEx(event, INFINITE, TRUE);
- }
- update_status(SERVICE_STOP_PENDING);
- libcharon_deinit();
+ status.dwWin32ExitCode = wait();
}
update_status(SERVICE_STOP_PENDING);
- libhydra_deinit();
+ libcharon_deinit();
}
update_status(SERVICE_STOP_PENDING);
library_deinit();
update_status(SERVICE_STOPPED);
}
-/**
- * Control handler for console
- */
-static BOOL console_handler(DWORD dwCtrlType)
-{
- switch (dwCtrlType)
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_CLOSE_EVENT:
- DBG1(DBG_DMN, "application is stopping, cleaning up");
- if (status.dwCurrentState == SERVICE_RUNNING)
- {
- charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
- dwCtrlType);
- }
- /* signal main thread to clean up */
- SetEvent(event);
- return TRUE;
- default:
- return FALSE;
- }
-}
-
/**
* Main routine when running from console
*/
if (SetConsoleCtrlHandler(console_handler, TRUE))
{
- init_and_run(dwArgc, lpszArgv);
+ init_and_run(dwArgc, lpszArgv, console_wait);
SetConsoleCtrlHandler(console_handler, FALSE);
}
}
-/**
- * Service handler function
- */
-static DWORD service_handler(DWORD dwControl, DWORD dwEventType,
- LPVOID lpEventData, LPVOID lpContext)
-{
- switch (dwControl)
- {
- case SERVICE_CONTROL_STOP:
- case SERVICE_CONTROL_SHUTDOWN:
- DBG1(DBG_DMN, "service is stopping, cleaning up");
- if (status.dwCurrentState == SERVICE_RUNNING)
- {
- charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
- dwControl);
- }
- /* signal main thread to clean up */
- SetEvent(event);
- return NO_ERROR;
- case SERVICE_CONTROL_INTERROGATE:
- return NO_ERROR;
- default:
- return ERROR_CALL_NOT_IMPLEMENTED;
- }
-}
-
/**
* Switch the working directory to the executable directory
*/
/**
* Service main routine when running as service
*/
-static void service_main(DWORD dwArgc, LPTSTR *lpszArgv)
+static void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
memset(&status, 0, sizeof(status));
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
status.dwWin32ExitCode = 1;
handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, service_handler, NULL);
{
if (switch_workingdir())
{
- init_and_run(dwArgc, lpszArgv);
+ init_and_run(dwArgc, lpszArgv, service_wait);
}
}
}