TorProcess.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "TorProcess.h"
00018 #include "tcglobal.h"
00019
00020 #include "stringutil.h"
00021
00022 #include <QString>
00023
00024
00025 #if defined (Q_OS_WIN32)
00026 #include <windows.h>
00027 #endif
00028
00029
00030
00031 TorProcess::TorProcess(QObject *parent)
00032 : QProcess(parent)
00033 {
00034 openStdout();
00035 connect(this, SIGNAL(readyReadStandardOutput()),
00036 this, SLOT(onReadyRead()));
00037 connect(this, SIGNAL(error(QProcess::ProcessError)),
00038 this, SLOT(onError(QProcess::ProcessError)));
00039 }
00040
00041
00042 QString
00043 TorProcess::formatArguments(const QStringList &args)
00044 {
00045 QStringList out;
00046 foreach (QString arg, args) {
00047 out << (arg.contains(" ") || arg.isEmpty() ? string_escape(arg) : arg);
00048 }
00049 return out.join(" ");
00050 }
00051
00052
00053
00054
00055
00056 void
00057 TorProcess::start(const QString &app, const QStringList &args)
00058 {
00059 QString exe = app;
00060 #if defined(Q_OS_WIN32)
00061
00062
00063 exe = "\"" + exe + "\"";
00064 #endif
00065
00066
00067 QStringList env = QProcess::systemEnvironment();
00068 #if !defined(Q_OS_WIN32)
00069
00070
00071
00072 for (int i = 0; i < env.size(); i++) {
00073 QString envVar = env.at(i);
00074 if (envVar.startsWith("PATH="))
00075 env.replace(i, envVar += ":/usr/sbin");
00076 }
00077 #endif
00078 setEnvironment(env);
00079
00080 tc::debug("Starting Tor using '%1 %2'").arg(app).arg(formatArguments(args));
00081 QProcess::start(exe, args, QIODevice::ReadOnly | QIODevice::Text);
00082 }
00083
00084
00085 bool
00086 TorProcess::stop(QString *errmsg)
00087 {
00088
00089
00090 if (state() == QProcess::NotRunning) {
00091 return true;
00092 }
00093
00094 tc::debug("Stopping the Tor process.");
00095
00096 #if defined(Q_OS_WIN32)
00097
00098
00099 kill();
00100 #else
00101 terminate();
00102
00103
00104 if (!waitForFinished(5000)) {
00105 tc::error("Tor failed to stop: %1").arg(errorString());
00106 if (errmsg) {
00107 *errmsg =
00108 tr("Process %1 failed to stop. [%2]").arg(pid()).arg(errorString());
00109 }
00110 return false;
00111 }
00112 #endif
00113 return true;
00114 }
00115
00116
00117 quint64
00118 TorProcess::pid()
00119 {
00120 #if defined(Q_OS_WIN32)
00121 return (quint64)((QProcess::pid())->dwProcessId);
00122 #else
00123 return QProcess::pid();
00124 #endif
00125 }
00126
00127
00128
00129 void
00130 TorProcess::openStdout()
00131 {
00132 setReadChannelMode(QProcess::MergedChannels);
00133 setReadChannel(QProcess::StandardOutput);
00134 }
00135
00136
00137
00138 void
00139 TorProcess::closeStdout()
00140 {
00141
00142 closeReadChannel(QProcess::StandardOutput);
00143
00144 onReadyRead();
00145 }
00146
00147
00148 void
00149 TorProcess::onReadyRead()
00150 {
00151 int i, j;
00152 QString line;
00153
00154 while (canReadLine()) {
00155 line = readLine();
00156 if (!line.isEmpty()) {
00157
00158 i = line.indexOf("[");
00159 j = line.indexOf("]");
00160 if (i > 0 && j > i && line.length() >= j+2) {
00161 emit log(line.mid(i+1, j-i-1), line.mid(j+2));
00162 }
00163 }
00164 }
00165 }
00166
00167
00168
00169
00170 void
00171 TorProcess::onError(QProcess::ProcessError error)
00172 {
00173 if (error == QProcess::FailedToStart) {
00174 tc::error("The Tor process failed to start: %1").arg(errorString());
00175
00176 emit startFailed(errorString());
00177 } else {
00178 tc::error("Tor process error: %1").arg(errorString());
00179 }
00180 }
00181
00182
00183
00184 QString
00185 TorProcess::version(const QString &exe)
00186 {
00187 QProcess tor;
00188
00189 tor.start(exe, QStringList() << "--version");
00190 if (!tor.waitForStarted() || !tor.waitForFinished())
00191 return QString();
00192
00193 while (tor.canReadLine()) {
00194 QString line = tor.readLine();
00195 if (line.startsWith("Tor version", Qt::CaseInsensitive)) {
00196 QStringList parts = line.split(" ");
00197 if (parts.size() >= 3)
00198 return parts.at(2);
00199 }
00200 }
00201 return QString();
00202 }
00203