[tor-commits] [vidalia/alpha] Another approach to the Control Password problem

chiiph at torproject.org chiiph at torproject.org
Tue May 3 14:21:32 UTC 2011


commit e428847150a282aa107b0ba173f3956453810eb4
Author: Tomas Touceda <chiiph at gentoo.org>
Date:   Fri Apr 22 01:02:21 2011 -0300

    Another approach to the Control Password problem
    
    - Tries kills only the tor process that's listening to the ControlPort
    	specified in the config.
    - Doesn't ask for password anymore. Now it displays nice messages, courtesy
    	of nickm (thanks!).
    
    - Fixes problem with saving advanced settings when Vidalia isn't running
    	Tor because the instance got "zombied" in another Vidalia run&crash.
---
 src/common/procutil.cpp                   |   66 ++++++++++++++++++++++++++---
 src/common/procutil.h                     |    3 +-
 src/vidalia/ControlPasswordInputDialog.ui |   15 +++----
 src/vidalia/MainWindow.cpp                |   10 ++---
 src/vidalia/config/AdvancedPage.cpp       |    3 +-
 5 files changed, 74 insertions(+), 23 deletions(-)

diff --git a/src/common/procutil.cpp b/src/common/procutil.cpp
index c2fbbc4..cad0add 100644
--- a/src/common/procutil.cpp
+++ b/src/common/procutil.cpp
@@ -21,6 +21,11 @@
 #include <QFileInfo>
 #include <QTextStream>
 #include <QApplication>
+#include <QProcess>
+
+#if !defined(Q_OS_WIN)
+#include <signal.h>
+#endif
 
 
 /** Returns the PID of the current process. */
@@ -104,13 +109,9 @@ read_pidfile(const QString &pidFileName, QString *errmsg)
 }
 
 QHash<qint64, QString>
-process_list()
+process_list(quint16 port)
 {
-#if defined(Q_OS_WIN32)
-  return win32_process_list();
-#else
-  return QHash<qint64, QString>();
-#endif
+  return universal_process_list(port);
 }
 
 bool
@@ -127,7 +128,60 @@ process_kill(qint64 pid)
 
   return (ret != FALSE);
 #else
+  if(!kill(pid, 15))
+    return true;
   return false;
 #endif
 }
 
+QHash<qint64, QString>
+universal_process_list(quint16 port)
+{
+  QHash<qint64, QString> pl;
+
+  QProcess ps;
+  QStringList args;
+#if defined(Q_OS_LINUX)
+  args << "-npl";
+#else
+  args << "-no";
+#endif
+
+  ps.start("netstat", args, QIODevice::ReadOnly);
+  while(!ps.waitForFinished());
+
+  QString flt = QString("127.0.0.1:%1").arg(port);
+  QStringList lines = QString(ps.readAllStandardOutput()).split("\n");
+  QStringList filtered = lines.filter(flt);
+
+#if defined(Q_OS_WIN)
+  filtered = filtered.filter("LISTENING");
+#endif
+
+  if(filtered.length() == 0)
+    return QHash<qint64, QString>();
+
+  qint64 pid = 0;
+  QString proc = "";
+#if defined(Q_OS_LINUX)
+  foreach(QString line, lines) {
+    QStringList items = line.trimmed().split(" ");
+    if(items.length() < 1)
+      continue;
+    items = items.last().trimmed().split("/");
+    if(items.length() < 2)
+      continue;
+
+    pid = items[0].toLong();
+    proc = items[1];
+
+    pl.insert(pid, proc);
+  }
+#else
+  pid = filtered[0].split(" ").last().trimmed().toLong();
+  proc = "tor";
+  pl.insert(pid, proc);
+#endif
+
+  return pl;
+}
diff --git a/src/common/procutil.h b/src/common/procutil.h
index 7e9b7dc..537fda0 100644
--- a/src/common/procutil.h
+++ b/src/common/procutil.h
@@ -45,7 +45,8 @@ qint64 read_pidfile(const QString &pidfile, QString *errmsg = 0);
 
 /** Return a list of all currently running PIDs and their associated process
  * names. */
-QHash<qint64, QString> process_list();
+QHash<qint64, QString> process_list(quint16 port = 0);
+QHash<qint64, QString> universal_process_list(quint16 port);
 
 /** Attempt to kill process <b>pid</b>. Return true if the specified process
  * was successfully terminated. Otherwise, return false. */
diff --git a/src/vidalia/ControlPasswordInputDialog.ui b/src/vidalia/ControlPasswordInputDialog.ui
index 0b51081..07b761c 100644
--- a/src/vidalia/ControlPasswordInputDialog.ui
+++ b/src/vidalia/ControlPasswordInputDialog.ui
@@ -9,7 +9,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>356</width>
+    <width>470</width>
     <height>189</height>
    </rect>
   </property>
@@ -59,7 +59,9 @@
         </size>
        </property>
        <property name="text">
-        <string>Vidalia has detected that there is a Tor running, probably launched by another Vidalia instance.</string>
+        <string>Tor is already running, but Vidalia can't connect to it.
+
+This can happen when something else (such as another active Vidalia process, or a Vidalia process that crashed) launched Tor.</string>
        </property>
        <property name="textFormat">
         <enum>Qt::PlainText</enum>
@@ -97,9 +99,7 @@
         <number>1</number>
        </property>
        <property name="text">
-        <string>Vidalia is unable to connect to it. 
-You could:
-* Exit Vidalia, and try to kill the running Tor instance.</string>
+        <string>You will need to shut down the Tor process before Vidalia can launch a new one. </string>
        </property>
        <property name="textFormat">
         <enum>Qt::AutoText</enum>
@@ -124,10 +124,7 @@ You could:
         </sizepolicy>
        </property>
        <property name="text">
-        <string>Vidalia is unable to connect to it. 
-You could:
-* Exit Vidalia, or 
-* Press Reset to try to restart Tor.</string>
+        <string>Vidalia can try to restart Tor for you.  Doing so will close all currently active connections through your Tor process.</string>
        </property>
        <property name="wordWrap">
         <bool>true</bool>
diff --git a/src/vidalia/MainWindow.cpp b/src/vidalia/MainWindow.cpp
index 84849b6..db28916 100644
--- a/src/vidalia/MainWindow.cpp
+++ b/src/vidalia/MainWindow.cpp
@@ -851,18 +851,16 @@ MainWindow::authenticationFailed(QString errmsg)
 
     qint64 torPid = 0;
 
-#if defined(Q_OS_WIN32)
-    QHash<qint64, QString> procs = process_list();
+    TorSettings settings;
+    QHash<qint64, QString> procs = process_list(settings.getControlPort());
     foreach (qint64 pid, procs.keys()) {
-      if (! procs.value(pid).compare("tor.exe", Qt::CaseInsensitive)) {
+      if (! procs.value(pid).compare("tor", Qt::CaseInsensitive)) {
         torPid = pid;
         break;
       }
     }
+    
     dlg.setResetEnabled(torPid > 0);
-#else
-    dlg.setResetEnabled(false);
-#endif
 
     int ret = dlg.exec();
     if (ret == QDialogButtonBox::Reset) {
diff --git a/src/vidalia/config/AdvancedPage.cpp b/src/vidalia/config/AdvancedPage.cpp
index 94c0308..3f0fc2b 100644
--- a/src/vidalia/config/AdvancedPage.cpp
+++ b/src/vidalia/config/AdvancedPage.cpp
@@ -165,7 +165,8 @@ AdvancedPage::save(QString &errmsg)
 
   /* Only remember the torrc and datadir values if Vidalia started Tor, or
    * if the user changed the displayed values. */
-  if (Vidalia::torControl()->isVidaliaRunningTor()) {
+  if (Vidalia::torControl()->isVidaliaRunningTor() or
+      not Vidalia::torControl()->isRunning()) {
     QString torrc = ui.lineTorConfig->text();
     if (torrc != _settings->getTorrc()) {
       _settings->setTorrc(torrc);





More information about the tor-commits mailing list