X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fexecwrapper.cpp;h=7c9ce12d4deebc99a51de4d92b5ad217f5eb228c;hp=8ef819436b9d5d88a794ede8c58eb9c54afd03d1;hb=694f9bfbf7f1af19108461c7e00d133e55082bce;hpb=dd381ac71adfcd9bcad028b277fe65e13fecaf15 diff --git a/src/client/execwrapper.cpp b/src/client/execwrapper.cpp index 8ef81943..7c9ce12d 100644 --- a/src/client/execwrapper.cpp +++ b/src/client/execwrapper.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include +#include #include "execwrapper.h" @@ -26,68 +27,117 @@ #include "messagemodel.h" #include "quassel.h" -ExecWrapper::ExecWrapper(QObject* parent) : QObject(parent) { - connect(&_process, SIGNAL(readyReadStandardOutput()), SLOT(processReadStdout())); - connect(&_process, SIGNAL(readyReadStandardError()), SLOT(processReadStderr())); - connect(&_process, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(processFinished(int, QProcess::ExitStatus))); - connect(&_process, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError))); +ExecWrapper::ExecWrapper(QObject *parent) : QObject(parent) +{ + connect(&_process, SIGNAL(readyReadStandardOutput()), SLOT(processReadStdout())); + connect(&_process, SIGNAL(readyReadStandardError()), SLOT(processReadStderr())); + connect(&_process, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(processFinished(int, QProcess::ExitStatus))); + connect(&_process, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError))); - connect(this, SIGNAL(stdout(QString)), SLOT(postStdout(QString))); - connect(this, SIGNAL(stderr(QString)), SLOT(postStderr(QString))); + connect(this, SIGNAL(output(QString)), SLOT(postStdout(QString))); + connect(this, SIGNAL(error(QString)), SLOT(postStderr(QString))); } -void ExecWrapper::start(const BufferInfo &info, const QString &scriptName, const QStringList& params) { - _bufferInfo = info; - _scriptName = scriptName; - foreach(QString scriptDir, Quassel::scriptDirPaths()) { - QString fileName = scriptDir + '/' + scriptName; - if(!QFile::exists(fileName)) - continue; - _process.start(fileName, params); - return; - } - emit stderr(tr("Could not find script \"%1\"").arg(scriptName)); - deleteLater(); + +void ExecWrapper::start(const BufferInfo &info, const QString &command) +{ + _bufferInfo = info; + QString params; + + QRegExp rx("^\\s*(\\S+)(\\s+(.*))?$"); + if (!rx.exactMatch(command)) { + emit error(tr("Invalid command string for /exec: %1").arg(command)); + } + else { + _scriptName = rx.cap(1); + params = rx.cap(3); + } + + // Make sure we don't execute something outside a script dir + if (_scriptName.contains("../") || _scriptName.contains("..\\")) + emit error(tr("Name \"%1\" is invalid: ../ or ..\\ are not allowed!").arg(_scriptName)); + + else { + foreach(QString scriptDir, Quassel::scriptDirPaths()) { + QString fileName = scriptDir + _scriptName; + if (!QFile::exists(fileName)) + continue; + _process.setWorkingDirectory(scriptDir); + _process.start('"' + fileName + "\" " + params); + return; + } + emit error(tr("Could not find script \"%1\"").arg(_scriptName)); + } + + deleteLater(); // self-destruct } -void ExecWrapper::postStdout(const QString &msg) { - if(_bufferInfo.isValid()) - Client::userInput(_bufferInfo, msg); + +void ExecWrapper::postStdout(const QString &msg) +{ + if (_bufferInfo.isValid()) + Client::userInput(_bufferInfo, msg); } -void ExecWrapper::postStderr(const QString &msg) { - if(_bufferInfo.isValid()) - Client::messageModel()->insertErrorMessage(_bufferInfo, msg); + +void ExecWrapper::postStderr(const QString &msg) +{ + if (_bufferInfo.isValid()) + Client::messageModel()->insertErrorMessage(_bufferInfo, msg); } -void ExecWrapper::processFinished(int exitCode, QProcess::ExitStatus status) { - if(status == QProcess::CrashExit) { - emit stderr(tr("Script \"%1\" crashed with exit code %2.").arg(_scriptName).arg(exitCode)); - } - // TODO empty buffers +void ExecWrapper::processFinished(int exitCode, QProcess::ExitStatus status) +{ + if (status == QProcess::CrashExit) { + emit error(tr("Script \"%1\" crashed with exit code %2.").arg(_scriptName).arg(exitCode)); + } + + // empty buffers + if (!_stdoutBuffer.isEmpty()) + foreach(QString msg, _stdoutBuffer.split('\n')) + emit output(msg); + if (!_stderrBuffer.isEmpty()) + foreach(QString msg, _stderrBuffer.split('\n')) + emit error(msg); - deleteLater(); + deleteLater(); } -void ExecWrapper::processError(QProcess::ProcessError error) { - emit stderr(tr("Script \"%1\" caused error %2.").arg(_scriptName).arg(error)); + +void ExecWrapper::processError(QProcess::ProcessError err) +{ + if (err == QProcess::FailedToStart) + emit error(tr("Script \"%1\" could not start.").arg(_scriptName)); + else + emit error(tr("Script \"%1\" caused error %2.").arg(_scriptName).arg(err)); + + if (_process.state() != QProcess::Running) + deleteLater(); } -void ExecWrapper::processReadStdout() { - _stdoutBuffer.append(_process.readAllStandardOutput()); - int idx; - while((idx = _stdoutBuffer.indexOf('\n')) >= 0) { - emit stdout(_stdoutBuffer.left(idx)); - _stdoutBuffer = _stdoutBuffer.mid(idx + 1); - } + +void ExecWrapper::processReadStdout() +{ + QString str = QTextCodec::codecForLocale()->toUnicode(_process.readAllStandardOutput()); + str.replace(QRegExp("\r\n?"), "\n"); + _stdoutBuffer.append(str); + int idx; + while ((idx = _stdoutBuffer.indexOf('\n')) >= 0) { + emit output(_stdoutBuffer.left(idx)); + _stdoutBuffer = _stdoutBuffer.mid(idx + 1); + } } -void ExecWrapper::processReadStderr() { - _stderrBuffer.append(_process.readAllStandardError()); - int idx; - while((idx = _stderrBuffer.indexOf('\n')) >= 0) { - emit stdout(_stderrBuffer.left(idx)); - _stderrBuffer = _stderrBuffer.mid(idx + 1); - } + +void ExecWrapper::processReadStderr() +{ + QString str = QTextCodec::codecForLocale()->toUnicode(_process.readAllStandardError()); + str.replace(QRegExp("\r\n?"), "\n"); + _stderrBuffer.append(str); + int idx; + while ((idx = _stderrBuffer.indexOf('\n')) >= 0) { + emit error(_stderrBuffer.left(idx)); + _stderrBuffer = _stderrBuffer.mid(idx + 1); + } }