summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-06-12 21:43:02 +0000
committerNick Mathewson <nickm@torproject.org>2004-06-12 21:43:02 +0000
commita788981399afbf493a9d852bffea52e032a8160e (patch)
treece1f13b6b01d6ee7fd5745b4b51dd1991d85b5da
parent125b351970d52269553aeb460b418f668a63d6ce (diff)
downloadtor-a788981399afbf493a9d852bffea52e032a8160e.tar.gz
tor-a788981399afbf493a9d852bffea52e032a8160e.zip
Implement code to run tor as an NT service. More testing is needed, as is code to install the service.
svn:r1966
-rw-r--r--src/or/main.c78
1 files changed, 77 insertions, 1 deletions
diff --git a/src/or/main.c b/src/or/main.c
index ce7da3cd2a..4f40f8adb2 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -55,6 +55,11 @@ int has_fetched_directory=0;
* entry to inform the user that Tor is working. */
int has_completed_circuit=0;
+#ifdef MS_WINDOWS
+SERVICE_STATUS service_status;
+SERVICE_STATUS_HANDLE hStatus;
+#endif
+
/********* END VARIABLES ************/
/****************************************************************************
@@ -699,7 +704,11 @@ static int do_main_loop(void) {
}
for(;;) {
-#ifndef MS_WINDOWS /* do signal stuff only on unix */
+#ifdef MS_WINDOWS /* Do service stuff only on windows. */
+ if (service_status.dwCurrentState != SERVICE_RUNNING) {
+ return 0;
+ }
+#else /* do signal stuff only on unix */
if(please_dumpstats) {
/* prefer to log it at INFO, but make sure we always see it */
dumpstats(get_min_log_level()>LOG_INFO ? get_min_log_level() : LOG_INFO);
@@ -922,12 +931,79 @@ void tor_cleanup(void) {
crypto_global_cleanup();
}
+#ifdef MS_WINDOWS
+void nt_service_control(DWORD request)
+{
+ switch (request) {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ log(LOG_ERR, "Got stop/shutdown request; shutting down cleanly.");
+ service_status.dwWin32ExitCode = 0;
+ service_status.dwCurrentState = SERVICE_STOPPED;
+ return;
+ }
+ SetServiceStatus(hStatus, &service_status);
+}
+
+void nt_service_body(int argc, char **argv)
+{
+ int err;
+ FILE *f;
+ f = fopen("d:\\foo.txt", "w");
+ fprintf(f, "POINT 1\n");
+ fclose(f);
+ service_status.dwServiceType = SERVICE_WIN32;
+ service_status.dwCurrentState = SERVICE_START_PENDING;
+ service_status.dwControlsAccepted =
+ SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_SHUTDOWN;
+ service_status.dwWin32ExitCode = 0;
+ service_status.dwServiceSpecificExitCode = 0;
+ service_status.dwCheckPoint = 0;
+ service_status.dwWaitHint = 0;
+ hStatus = RegisterServiceCtrlHandler("Tor", (LPHANDLER_FUNCTION) nt_service_control);
+ if (hStatus == 0) {
+ // failed;
+ return;
+ }
+ err = tor_init(argc, argv); // refactor this part out of tor_main and do_main_loop
+ if (err) {
+ // failed.
+ service_status.dwCurrentState = SERVICE_STOPPED;
+ service_status.dwWin32ExitCode = -1;
+ SetServiceStatus(hStatus, &service_status);
+ return;
+ }
+ service_status.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus(hStatus, &service_status);
+ do_main_loop();
+ tor_cleanup();
+ return;
+}
+
+void nt_service_main(void)
+{
+ SERVICE_TABLE_ENTRY table[2];
+ table[0].lpServiceName = "Tor";
+ table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)nt_service_body;
+ table[1].lpServiceName = NULL;
+ table[1].lpServiceProc = NULL;
+ if (!StartServiceCtrlDispatcher(table))
+ printf("Error was %d\n",GetLastError());
+}
+#endif
+
int tor_main(int argc, char *argv[]) {
+#ifdef MS_WINDOWS_SERVICE
+ nt_service_main();
+ return 0;
+#else
if (tor_init(argc, argv)<0)
return -1;
do_main_loop();
tor_cleanup();
return -1;
+#endif
}
/*