Commit a7889813 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Implement code to run tor as an NT service. More testing is needed, as is...

Implement code to run tor as an NT service.  More testing is needed, as is code to install the service.


svn:r1966
parent 125b3519
Loading
Loading
Loading
Loading
+77 −1
Original line number Diff line number Diff line
@@ -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
}

/*