Reformat ALL the source!
[quassel.git] / src / client / execwrapper.cpp
index b6dfc98..7c9ce12 100644 (file)
@@ -19,6 +19,7 @@
 ***************************************************************************/
 
 #include <QFile>
+#include <QTextCodec>
 
 #include "execwrapper.h"
 
 #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));
-  }
 
-  // empty buffers
-  if(!_stdoutBuffer.isEmpty())
-    foreach(QString msg, _stdoutBuffer.split('\n'))
-      emit stdout(msg);
-  if(!_stderrBuffer.isEmpty())
-    foreach(QString msg, _stderrBuffer.split('\n'))
-    emit stderr(msg);
+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);
+    }
 }