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