[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [vidalia/alpha] Merge branch 'master' into alpha



commit 3d4bbd50e6b7d8f66d04ca2c59295fd99d68c6d4
Merge: cf0296a 8d691c7
Author: Tomas Touceda <chiiph@xxxxxxxxxx>
Date:   Tue May 3 11:14:00 2011 -0300

    Merge branch 'master' into alpha
    
    Conflicts:
    	src/vidalia/MainWindow.cpp

 src/vidalia/MainWindow.cpp         |   14 +++++++++++++-
 src/vidalia/config/TorSettings.cpp |   27 +++++++++++++++++++++++++++
 src/vidalia/config/TorSettings.h   |    9 +++++++++
 3 files changed, 49 insertions(+), 1 deletions(-)

diff --cc src/vidalia/MainWindow.cpp
index a3d3ae6,29c1330..540af15
--- a/src/vidalia/MainWindow.cpp
+++ b/src/vidalia/MainWindow.cpp
@@@ -559,284 -400,295 +559,296 @@@ MainWindow::start(
        return;
      }
    }
 -  vApp->quit();
 -}
  
-   /* Make sure the torrc we want to use really exists. */
 -/** Create and bind actions to events. Setup for initial
 - * tray menu configuration. */
 -void 
 -MainWindow::createActions()
 -{
 -  _actionStartStopTor = new QAction(tr("Start Tor"), this);
 -  connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start()));
 +  QString torrc = settings.getTorrc();
+ 
 -  _actionExit = new QAction(tr("Exit"), this);
 -  connect(_actionExit, SIGNAL(triggered()), this, SLOT(close()));
++  if(settings.bootstrap()) {
++    QString boottorrc = settings.bootstrapFrom();
++    vNotice(tr("Bootstrapping torrc from %1 to %2")
++        .arg(boottorrc).arg(torrc));
++    if(QFileInfo(boottorrc).exists()) {
++      if(QFile::copy(boottorrc, torrc)) {
++        settings.setBootstrap(false);
++      }
++    }
++  }
+ 
 -  _actionShowBandwidth = new QAction(tr("Bandwidth Graph"), this);
 -  connect(_actionShowBandwidth, SIGNAL(triggered()), 
 -          _bandwidthGraph, SLOT(showWindow()));
 -  connect(ui.lblBandwidthGraph, SIGNAL(clicked()),
 -          _bandwidthGraph, SLOT(showWindow()));
 -
 -  _actionShowMessageLog = new QAction(tr("Message Log"), this);
 -  connect(_actionShowMessageLog, SIGNAL(triggered()),
 -          _messageLog, SLOT(showWindow()));
 -  connect(ui.lblMessageLog, SIGNAL(clicked()),
 -          _messageLog, SLOT(showWindow()));
 -
 -  _actionShowNetworkMap = new QAction(tr("Network Map"), this);
 -  connect(_actionShowNetworkMap, SIGNAL(triggered()), 
 -          _netViewer, SLOT(showWindow()));
 -  connect(ui.lblViewNetwork, SIGNAL(clicked()),
 -          _netViewer, SLOT(showWindow()));
 -
 -  _actionShowControlPanel = new QAction(tr("Control Panel"), this);
 -  connect(_actionShowControlPanel, SIGNAL(triggered()), this, SLOT(show()));
++  /* Make sure the torrc we want to use really exists. */
 +  if (!torrc.isEmpty()) {
 +    if (!QFileInfo(torrc).exists())
 +      touch_file(torrc, true);
 +    args << "-f" << torrc;
 +  }
  
 -  _actionShowConfig = new QAction(tr("Settings"), this);
 -  connect(_actionShowConfig, SIGNAL(triggered()), this, SLOT(showConfigDialog()));
 +  /* Specify Tor's data directory, if different from the default */
 +  QString dataDirectory = settings.getDataDirectory();
 +  if (!dataDirectory.isEmpty())
 +    args << "DataDirectory" << expand_filename(dataDirectory);
    
 -  _actionShowAbout = new QAction(tr("About"), this);
 -  connect(_actionShowAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
 -
 -  _actionShowHelp = new QAction(tr("Help"), this);
 -  connect(_actionShowHelp, SIGNAL(triggered()), this, SLOT(showHelpDialog()));
 -  connect(ui.lblHelpBrowser, SIGNAL(clicked()), this, SLOT(showHelpDialog()));
 -
 -  _actionNewIdentity = new QAction(tr("New Identity"), this);
 -  _actionNewIdentity->setEnabled(false);
 -  connect(_actionNewIdentity, SIGNAL(triggered()), this, SLOT(newIdentity()));
 +  if(settings.getControlMethod() == ControlMethod::Port) {
 +    /* Add the intended control port value */
 +    quint16 controlPort = settings.getControlPort();
 +    if (controlPort)
 +      args << "ControlPort" << QString::number(controlPort);
 +  } else {
 +    QString path = settings.getSocketPath();
 +    args << "ControlSocket" << path;
 +  }
 +  
 +  /* Add the control port authentication arguments */
 +  switch (settings.getAuthenticationMethod()) {
 +    case TorSettings::PasswordAuth:
 +      if (! vApp->readPasswordFromStdin()) {
 +        if (settings.useRandomPassword()) {
 +          _controlPassword = TorSettings::randomPassword();
 +          _useSavedPassword = false;
 +        } else {
 +          _controlPassword = settings.getControlPassword();
 +          _useSavedPassword = true;
 +        }
 +      }
 +      args << "HashedControlPassword"
 +           << TorSettings::hashPassword(_controlPassword);
 +      break;
 +    case TorSettings::CookieAuth:
 +      args << "CookieAuthentication"  << "1";
 +      break;
 +    default:
 +      args << "CookieAuthentication"  << "0";
 +  }
  
 -#if !defined(Q_WS_MAC)
 -  /* Don't give the menu items icons on OS X, since they end up in the
 -   * application menu bar. Menu bar items on OS X typically do not have
 -   * icons. */
 -  _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16));
 -  _actionExit->setIcon(QIcon(IMG_EXIT));
 -  _actionShowBandwidth->setIcon(QIcon(IMG_BWGRAPH));
 -  _actionShowMessageLog->setIcon(QIcon(IMG_MESSAGELOG));
 -  _actionShowNetworkMap->setIcon(QIcon(IMG_NETWORK));
 -  _actionShowControlPanel->setIcon(QIcon(IMG_CONTROL_PANEL));
 -  _actionShowConfig->setIcon(QIcon(IMG_CONFIG));
 -  _actionShowAbout->setIcon(QIcon(IMG_ABOUT));
 -  _actionShowHelp->setIcon(QIcon(IMG_HELP));
 -  _actionNewIdentity->setIcon(QIcon(IMG_IDENTITY));
 -#endif
 +  /* This doesn't get set to false until Tor is actually up and running, so we
 +   * don't yell at users twice if their Tor doesn't even start, due to the fact
 +   * that QProcess::stopped() is emitted even if the process didn't even
 +   * start. */
 +  _isIntentionalExit = true;
 +  /* Kick off the Tor process */
 +  _torControl->start(settings.getExecutable(), args);
  }
  
 -/** Creates a tray icon with a context menu and adds it to the system
 - * notification area. On Mac, we also set up an application menubar. */
 -void
 -MainWindow::createTrayIcon()
 +/** Slot: Called when the Tor process is started. It will connect the control
 + * socket and set the icons and tooltips accordingly. */
 +void 
 +MainWindow::started()
  {
 -  QMenu *menu = createTrayMenu();
 -
 -  /* Add the menu it to the tray icon */
 -  _trayIcon.setContextMenu(menu);
 +  TorSettings settings;
  
 -  connect(&_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
 -          this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
 +  updateTorStatus(Started);
  
 -#if defined(Q_WS_MAC)
 -  createMenuBar();
 -  qt_mac_set_dock_menu(menu);
 -#endif
 +  /* Now that Tor is running, we want to know if it dies when we didn't want
 +   * it to. */
 +  _isIntentionalExit = false;
 +  /* We haven't started a delayed shutdown yet. */
 +  _delayedShutdownStarted = false;
 +  /* Remember whether we started Tor or not */
 +  _isVidaliaRunningTor = _torControl->isVidaliaRunningTor();
 +  /* Try to connect to Tor's control port */
 +  if(settings.getControlMethod() == ControlMethod::Port)
 +    _torControl->connect(settings.getControlAddress(),
 +                        settings.getControlPort());
 +  else
 +    _torControl->connect(settings.getSocketPath());
 +  setStartupProgress(STARTUP_PROGRESS_CONNECTING, tr("Connecting to Tor"));
  }
  
 -/** Creates a QMenu object that contains QActions which compose the system 
 - * tray menu. */
 -QMenu* 
 -MainWindow::createTrayMenu()
 +/** Disconnects the control socket and stops the Tor process. */
 +bool
 +MainWindow::stop()
  {
 -  QMenu *menu = new QMenu(this);
 -  menu->addAction(_actionStartStopTor);
 -  menu->addSeparator();
 -  menu->addAction(_actionShowBandwidth);
 -  menu->addAction(_actionShowMessageLog);
 -  menu->addAction(_actionShowNetworkMap);
 -  menu->addAction(_actionNewIdentity);
 -  menu->addSeparator();
 -  menu->addAction(_actionShowControlPanel);
 -  
 -#if !defined(Q_WS_MAC)
 -  /* These aren't added to the dock menu on Mac, since they are in the
 -   * standard Mac locations in the menu bar. */
 -  menu->addAction(_actionShowConfig);
 -  menu->addAction(_actionShowHelp);
 -  menu->addAction(_actionShowAbout);
 -  menu->addSeparator();
 -  menu->addAction(_actionExit);
 -#endif
 -  return menu;
 -}
 +  ServerSettings server(_torControl);
 +  QString errmsg;
 +  TorStatus prevStatus;
 +  bool rc;
  
 -/** Creates a new menubar with no parent, so Qt will use this as the "default
 - * menubar" on Mac. This adds on to the existing actions from the createMens()
 - * method. */
 -void
 -MainWindow::createMenuBar()
 -{
 -#if defined(Q_WS_MAC)
 -  /* Mac users sure like their shortcuts. Actions NOT mentioned below
 -   * don't explicitly need shortcuts, since they are merged to the default
 -   * menubar and get the default shortcuts anyway. */
 -  _actionStartStopTor->setShortcut(tr("Ctrl+T"));
 -  _actionShowBandwidth->setShortcut(tr("Ctrl+B"));
 -  _actionShowMessageLog->setShortcut(tr("Ctrl+L"));
 -  _actionShowNetworkMap->setShortcut(tr("Ctrl+N"));
 -  _actionShowHelp->setShortcut(tr("Ctrl+?"));
 -  _actionNewIdentity->setShortcut(tr("Ctrl+I"));
 -  _actionShowControlPanel->setShortcut(tr("Ctrl+P"));
 -
 -  /* Force Qt to put merge the Exit, Configure, and About menubar options into
 -   * the default menu, even if Vidalia is currently not speaking English. */
 -  _actionShowConfig->setText("config");
 -  _actionShowConfig->setMenuRole(QAction::PreferencesRole);
 -  _actionShowAbout->setText("about");
 -  _actionShowAbout->setMenuRole(QAction::AboutRole);
 -  _actionExit->setText("quit");
 -  _actionExit->setMenuRole(QAction::QuitRole);
 -
 -  /* The File, Help, and Configure menus will get merged into the application
 -   * menu by Qt. */
 -  if (_menuBar)
 -    delete _menuBar;
 -  _menuBar = new QMenuBar(0);
 -  QMenu *fileMenu = _menuBar->addMenu("File");
 -  fileMenu->addAction(_actionExit);
 -  fileMenu->addAction(_actionShowConfig);
 -
 -  QMenu *torMenu = _menuBar->addMenu(tr("Tor"));
 -  torMenu->addAction(_actionStartStopTor);
 -  torMenu->addSeparator();
 -  torMenu->addAction(_actionNewIdentity);
 -
 -  QMenu *viewMenu = _menuBar->addMenu(tr("View"));
 -  viewMenu->addAction(_actionShowControlPanel);
 -  viewMenu->addSeparator();
 -  viewMenu->addAction(_actionShowBandwidth);
 -  viewMenu->addAction(_actionShowMessageLog);
 -  viewMenu->addAction(_actionShowNetworkMap);
 +  /* If we're running a server, give users the option of terminating
 +   * gracefully so clients have time to find new servers. */
 +  if (server.isServerEnabled() && !_delayedShutdownStarted) {
 +    /* Ask the user if they want to shutdown nicely. */
 +    int response = VMessageBox::question(this, tr("Relaying is Enabled"),
 +                     tr("You are currently running a relay. "
 +                        "Terminating your relay will interrupt any "
 +                        "open connections from clients.\n\n"
 +                        "Would you like to shutdown gracefully and "
 +                        "give clients time to find a new relay?"),
 +                        VMessageBox::Yes|VMessageBox::Default, 
 +                        VMessageBox::No, 
 +                        VMessageBox::Cancel|VMessageBox::Escape);
 +    if (response == VMessageBox::Yes)
 +      _delayedShutdownStarted = true;
 +    else if (response == VMessageBox::Cancel)
 +      return false;
 +  }
    
 -  QMenu *helpMenu = _menuBar->addMenu(tr("Help"));
 -  _actionShowHelp->setText(tr("Vidalia Help"));
 -  helpMenu->addAction(_actionShowHelp);
 -  helpMenu->addAction(_actionShowAbout);
 -#endif
 +  prevStatus = updateTorStatus(Stopping);  
 +  if (_delayedShutdownStarted) {
 +    /* Start a delayed shutdown */
 +    rc = _torControl->signal(TorSignal::Shutdown, &errmsg);
 +  } else {
 +    /* We want Tor to stop now, regardless of whether we're a server. */
 +    _isIntentionalExit = true;
 +    rc = _torControl->stop(&errmsg);
 +  }
 +  
 +  if (!rc) {
 +    /* We couldn't tell Tor to stop, for some reason. */
 +    int response = VMessageBox::warning(this, tr("Error Shutting Down"),
 +                     p(tr("Vidalia was unable to stop the Tor software.")) 
 +                       + p(errmsg),
 +                     VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, 
 +                     VMessageBox::Help);
 +      
 +    if (response == VMessageBox::Help) {
 +      /* Show some troubleshooting help */
 +      showHelpDialog("troubleshooting.stop");
 +    }
 +    /* Tor is still running since stopping failed */
 +    _isIntentionalExit = false;
 +    _delayedShutdownStarted = false;
 +    updateTorStatus(prevStatus);
 +  }
 +  return rc;
  }
  
 -/** Sets the current tray or dock icon image to <b>iconFile</b>. */
 -void
 -MainWindow::setTrayIcon(const QString &iconFile)
 +/** Slot: Called when the Tor process has exited. It will adjust the tray
 + * icons and tooltips accordingly. */
 +void 
 +MainWindow::stopped(int exitCode, QProcess::ExitStatus exitStatus)
  {
 -#if defined(Q_WS_MAC)
 -  QApplication::setWindowIcon(QPixmap(iconFile));
 -#endif
 -  _trayIcon.setIcon(QIcon(iconFile));
 -}
 +  updateTorStatus(Stopped);
  
 -/** Respond to a double-click on the tray icon by opening the Control Panel
 - * window. */
 -void
 -MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
 -{
 -  if (reason == QSystemTrayIcon::DoubleClick)
 -    setVisible(true);
 +  /* If we didn't intentionally close Tor, then check to see if it crashed or
 +   * if it closed itself and returned an error code. */
 +  if (!_isIntentionalExit) {
 +    /* A quick overview of Tor's code tells me that if it catches a SIGTERM or
 +     * SIGINT, Tor will exit(0). We might need to change this warning message
 +     * if this turns out to not be the case. */
 +    if (exitStatus == QProcess::CrashExit || exitCode != 0) {
 +      int ret = VMessageBox::warning(this, tr("Unexpected Error"),
 +                  tr("Vidalia detected that the Tor software exited "
 +                     "unexpectedly.\n\n"
 +                     "Please check the message log for recent "
 +                     "warning or error messages."),
 +                  VMessageBox::Ok|VMessageBox::Escape, 
 +                  VMessageBox::ShowLog|VMessageBox::Default,
 +                  VMessageBox::Help);
 +      if (ret == VMessageBox::ShowLog)
 +        showMessageLogTab();
 +      else if (ret == VMessageBox::Help)
 +        showHelpDialog("troubleshooting.torexited");
 +    }
 +  }
  }
  
 -/** Start a web browser when given the directory containing the executable and profile */
 +/** Called when the Tor process fails to start, for example, because the path
 + * specified to the Tor executable didn't lead to an executable. */
  void
 -MainWindow::launchBrowserFromDirectory()
 +MainWindow::startFailed(QString errmsg)
  {
 -  VidaliaSettings settings;
 -
 -  QString browserDirectory = settings.getBrowserDirectory();
 -  QString browserDirectoryFilename = settings.getBrowserExecutable();
 +  /* We don't display the error message for now, because the error message
 +   * that Qt gives us in this instance is almost always "Unknown Error". That
 +   * will make users sad. */
 +  Q_UNUSED(errmsg);
 + 
 +  updateTorStatus(Stopped);
  
 -  /* Set TZ=UTC (to stop leaking timezone information) and
 -   * MOZ_NO_REMOTE=1 (to allow multiple instances of Firefox */
 -  QStringList env = QProcess::systemEnvironment();
 -  env << "TZ=UTC";
 -  env << "MOZ_NO_REMOTE=1";
 -  _browserProcess->setEnvironment(env);
 -
 -  /* The browser is in <browserDirectory>/App/Firefox/<browserDirectoryFilename> */
 -  QString browserExecutable =
 -    QDir::toNativeSeparators(browserDirectory + "/App/Firefox/" + browserDirectoryFilename);
 -  /* The profile is in <browserDirectory>/Data/profile */
 -  QString profileDir =
 -    QDir::toNativeSeparators(browserDirectory + "/Data/profile");
 -
 -  /* Copy the profile directory if it's not already there */
 -  QDir browserDirObj = QDir(browserDirectory);
 -
 -  /* Copy the profile directory if it's not already there */
 -  if (!browserDirObj.exists("Data/profile")) {
 -    browserDirObj.mkdir("Data/profile");
 -    copy_dir(browserDirectory + "/App/DefaultData/profile", browserDirectory + "/Data/profile");
 -  }
 +  /* Display an error message and see if the user wants some help */
 +  int response = VMessageBox::warning(this, tr("Error Starting Tor"),
 +                   tr("Vidalia was unable to start Tor. Check your settings "
 +                        "to ensure the correct name and location of your Tor "
 +                        "executable is specified."),
 +                   VMessageBox::ShowSettings|VMessageBox::Default,
 +                   VMessageBox::Cancel|VMessageBox::Escape,
 +                   VMessageBox::Help);
  
 -  /* Copy the plugins directory if it's not already there */
 -  if (!browserDirObj.exists("Data/plugins")) {
 -    browserDirObj.mkdir("Data/plugins");
 -    copy_dir(browserDirectory + "/App/DefaultData/plugins", browserDirectory + "/Data/plugins");
 +  if (response == VMessageBox::ShowSettings) {
 +    /* Show the settings dialog so the user can make sure they're pointing to
 +     * the correct Tor. */
 +     showConfigDialog();
 +  } else if (response == VMessageBox::Help) {
 +    /* Show troubleshooting information about starting Tor */
 +    showHelpDialog("troubleshooting.start");
    }
 -
 -  /* Build the command line arguments */
 -  QStringList commandLine;
 -  // Is this better or worse than MOZ_NO_REMOTE?
 -  //commandLine << "-no-remote";
 -  commandLine << "-profile";
 -  commandLine << profileDir;
 -
 -  /* Launch the browser */
 -  _browserProcess->start(browserExecutable, commandLine);
  }
  
 -/** Starts the web browser and IM client, if appropriately configured */
 +/** Called when the control socket has successfully connected to Tor. */
  void
 -MainWindow::startSubprocesses()
 +MainWindow::connected()
  {
 -  VidaliaSettings settings;
 -  QString subprocess;
 +  authenticate();
 +}
  
 -  /* Launch the web browser */
 -  if (!(subprocess = settings.getBrowserDirectory()).isEmpty()) {
 -    /* The user has set BrowserDirectory; use this */
 -    launchBrowserFromDirectory();
 -  } else if (!(subprocess = settings.getBrowserExecutable()).isEmpty()) {
 -    /* BrowserDirectory is not set, but BrowserExecutable is; use this */
 -    _browserProcess->setEnvironment(QProcess::systemEnvironment() << "TZ=UTC");
 -    _browserProcess->start(subprocess, QStringList());
 -  }
 +/** Called when the connection to the control socket fails. The reason will be
 + * given in the errmsg parameter. */
 +void
 +MainWindow::connectFailed(QString errmsg)
 +{
 +  /* Ok, ok. It really isn't going to connect. I give up. */
 +  int response = VMessageBox::warning(this, 
 +                   tr("Connection Error"), p(errmsg),
 +                   VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, 
 +                   VMessageBox::Retry, VMessageBox::Help);
  
 -  /* Launch the IM client */
 -  subprocess = settings.getIMExecutable();
  
 -  if (!subprocess.isEmpty())
 -    _imProcess->start(subprocess, QStringList());
 +  if (response == VMessageBox::Retry) {
 +    /* Let's give it another try. */
 +    TorSettings settings;
 +    _torControl->connect(settings.getControlAddress(),
 +                         settings.getControlPort());
 +  } else {
 +    /* Show the help browser (if requested) */
 +    if (response == VMessageBox::Help)
 +      showHelpDialog("troubleshooting.connect");
 +    /* Since Vidalia can't connect, we can't really do much, so stop Tor. */
 +    _torControl->stop();
 +  }
  }
  
 -/** Called when browser or IM client have exited */
 +/** Called when Vidalia has successfully authenticated to Tor. */
  void
 -MainWindow::onSubprocessFinished(int exitCode, QProcess::ExitStatus exitStatus)
 +MainWindow::authenticated()
  {
 -  Q_UNUSED(exitCode)
 -  Q_UNUSED(exitStatus)
 +  ServerSettings serverSettings(_torControl);
 +  QString errmsg;
  
 -  /* Get path to browser and IM client */
 -  VidaliaSettings settings;
 -  QString browserExecutable = settings.getBrowserExecutable();
 -  QString browserDirectory = settings.getBrowserDirectory();
 -  QString imExecutable = settings.getIMExecutable();
 +  updateTorStatus(Authenticated);
 +  
 +  /* If Tor doesn't have bootstrapping events, then update the current
 +   * status string and bump the progress bar along a bit. */
 +  if (_torControl->getTorVersion() < 0x020101) {
 +    setStartupProgress(STARTUP_PROGRESS_CIRCUITBUILD,
 +                       tr("Connecting to the Tor network"));
 +  }
 +  
 +  /* Let people click on their beloved "New Identity" button */
 +  _actionNewIdentity->setEnabled(true);
  
 -  /* A subprocess is finished if it successfully exited or was never asked to start */
 -  bool browserDone = (browserExecutable.isEmpty()
 -                        && browserDirectory.isEmpty())
 -                        || _browserProcess->isDone();
 -  bool imDone = imExecutable.isEmpty() || _imProcess->isDone();
 +  /* Register for any pertinent asynchronous events. */
 +  if (!_torControl->setEvents(&errmsg)) {
 +    VMessageBox::warning(this, tr("Error Registering for Events"),
 +      p(tr("Vidalia was unable to register for some events. "
 +           "Many of Vidalia's features may be unavailable."))
 +         + p(errmsg),
 +      VMessageBox::Ok);
 +  } else {
 +    /* Stop reading from Tor's stdout immediately, since we successfully
 +     * registered for Tor events, including any desired log events. */
 +    _torControl->closeTorStdout();
 +  }
  
 -  /* Exit if both subprocesses are finished */
 -  if (browserDone && imDone) {
 -    if (browserDirectory.isEmpty()) {
 -      /* We are using the standard launcher, exit immediately */
 -      vApp->quit();
 -    } else {
 -      /* We are using the alternate launcher, wait until the browser has really died */
 -      QTimer *browserWatcher = new QTimer(this);
 -      connect(browserWatcher, SIGNAL(timeout()), this, SLOT(onCheckForBrowser()));
 -      browserWatcher->start(2000);
 -    }
 +  /* Configure UPnP port forwarding if needed */
 +  serverSettings.configurePortForwarding();
 +
 +  /* Check if Tor has a circuit established */
 +  if (_torControl->isCircuitEstablished()) {
 +    circuitEstablished();
 +  }
 +  /* Check the status of Tor's version */
 +  if (_torControl->getTorVersion() >= 0x020001)
 +    checkTorVersion();
 +  if (_torControl->getTorVersion() >= 0x020102) {
 +    BootstrapStatus status = _torControl->bootstrapStatus();
 +    if (status.isValid())
 +      bootstrapStatusChanged(status);
    }
  }
  

_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits