mirror of https://github.com/cutefishos/launcher
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.0 KiB
C++
124 lines
4.0 KiB
C++
#include "helperprocess.h"
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
|
|
#include "../common/wire.h"
|
|
|
|
namespace dm {
|
|
|
|
namespace {
|
|
|
|
QString helperPath()
|
|
{
|
|
const QString overridden = qEnvironmentVariable("CUTEFISH_DM_HELPER");
|
|
return overridden.isEmpty() ? QStringLiteral(DM_HELPER_PATH) : overridden;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
HelperProcess::HelperProcess(QObject* parent)
|
|
: QObject(parent)
|
|
{
|
|
m_process.setProgram(helperPath());
|
|
// The session's output shares the helper's stderr: the daemon's journal.
|
|
m_process.setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
|
connect(&m_process, &QProcess::readyReadStandardOutput, this, &HelperProcess::readMessages);
|
|
connect(&m_process, &QProcess::finished, this, [this] {
|
|
readMessages();
|
|
if (!m_authenticated && !m_failed) {
|
|
m_failed = true;
|
|
emit failed(false, QStringLiteral("The login helper exited"));
|
|
}
|
|
emit finished();
|
|
});
|
|
connect(&m_process, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
|
|
if (error == QProcess::FailedToStart) {
|
|
m_failed = true;
|
|
emit failed(false, QStringLiteral("The login helper did not start"));
|
|
emit finished();
|
|
}
|
|
});
|
|
}
|
|
|
|
HelperProcess::~HelperProcess()
|
|
{
|
|
disconnect(&m_process, nullptr, this, nullptr);
|
|
if (m_process.state() != QProcess::NotRunning) {
|
|
terminate();
|
|
if (!m_process.waitForFinished(3000))
|
|
m_process.kill();
|
|
m_process.waitForFinished(1000);
|
|
}
|
|
}
|
|
|
|
void HelperProcess::login(const QString& service, const QString& user, bool authenticate, int vt)
|
|
{
|
|
m_user = user;
|
|
m_process.start();
|
|
send({{QStringLiteral("type"), QStringLiteral("login")},
|
|
{QStringLiteral("service"), service},
|
|
{QStringLiteral("user"), user},
|
|
{QStringLiteral("authenticate"), authenticate},
|
|
{QStringLiteral("vt"), vt}});
|
|
}
|
|
|
|
void HelperProcess::answer(const QJsonValue& response)
|
|
{
|
|
send({{QStringLiteral("type"), QStringLiteral("answer")},
|
|
{QStringLiteral("response"), response}});
|
|
}
|
|
|
|
void HelperProcess::start(const QStringList& command, const QStringList& environment)
|
|
{
|
|
send({{QStringLiteral("type"), QStringLiteral("start")},
|
|
{QStringLiteral("cmd"), QJsonArray::fromStringList(command)},
|
|
{QStringLiteral("env"), QJsonArray::fromStringList(environment)}});
|
|
}
|
|
|
|
void HelperProcess::terminate()
|
|
{
|
|
// Never the session's pid itself: once reaped, another process may have it.
|
|
if (m_process.state() != QProcess::NotRunning)
|
|
m_process.terminate();
|
|
}
|
|
|
|
void HelperProcess::send(const QJsonObject& message)
|
|
{
|
|
QByteArray line = encodeLine(message);
|
|
m_process.write(line);
|
|
wipe(line);
|
|
}
|
|
|
|
void HelperProcess::readMessages()
|
|
{
|
|
m_buffer.append(m_process.readAllStandardOutput());
|
|
qsizetype end = 0;
|
|
while ((end = m_buffer.indexOf('\n')) >= 0) {
|
|
const auto message = decodeLine(m_buffer.left(end));
|
|
m_buffer.remove(0, end + 1);
|
|
if (!message)
|
|
continue;
|
|
const QString type = message->value(QStringLiteral("type")).toString();
|
|
if (type == QLatin1String("question")) {
|
|
emit question(message->value(QStringLiteral("style")).toString(),
|
|
message->value(QStringLiteral("text")).toString());
|
|
} else if (type == QLatin1String("authenticated")) {
|
|
m_authenticated = true;
|
|
emit authenticated();
|
|
} else if (type == QLatin1String("started")) {
|
|
m_sessionPid = message->value(QStringLiteral("pid")).toInteger();
|
|
m_sessionId = message->value(QStringLiteral("session")).toString();
|
|
emit started(m_sessionId);
|
|
} else if (type == QLatin1String("error")) {
|
|
m_failed = true;
|
|
emit failed(message->value(QStringLiteral("auth")).toBool(),
|
|
message->value(QStringLiteral("message")).toString());
|
|
} else if (type == QLatin1String("finished")) {
|
|
m_sessionPid = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace dm
|