128 lines
3.3 KiB
C++
128 lines
3.3 KiB
C++
#include "i2p-controller.h"
|
|
#include "prog-constains.h"
|
|
#include "locales.h"
|
|
|
|
I2PController::I2PController(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
this->isFatalErrored = false;
|
|
|
|
connect(&i2p, &QProcess::errorOccurred,
|
|
this, &I2PController::onProcessError);
|
|
|
|
connect(&i2p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &I2PController::onProcessFinished);
|
|
|
|
connect(&i2p, &QProcess::readyReadStandardOutput, this, [this]() {
|
|
qDebug() << "[i2pd]" << i2p.readAllStandardOutput();
|
|
});
|
|
|
|
connect(&i2p, &QProcess::readyReadStandardError, this, [this]() {
|
|
QString msg = i2p.readAllStandardError();
|
|
qDebug() << "[i2pd ERROR]" << msg;
|
|
if (msg.contains("missing/unreadable config file:")) {
|
|
emit fatalError(msg);
|
|
}
|
|
});
|
|
|
|
// Close the launcher
|
|
connect(this, &I2PController::fatalError, [this](QString msg) {
|
|
this->isFatalErrored = true;
|
|
qCritical() << msg;
|
|
LocaleMap* locale = getLocale();
|
|
|
|
QMessageBox::critical(
|
|
nullptr,
|
|
QString::fromStdString(locale->at("i2pd.errorTitle")),
|
|
QString::fromStdString(locale->at("i2pd.errorDescription.p1")) + msg +
|
|
QString::fromStdString(locale->at("i2pd.errorDescription.p2")),
|
|
QMessageBox::Ok
|
|
);
|
|
qApp->exit(1);
|
|
});
|
|
}
|
|
|
|
void I2PController::start() {
|
|
if (i2p.state() != QProcess::NotRunning)
|
|
{
|
|
qDebug() << "i2pd already running";
|
|
return;
|
|
}
|
|
|
|
QStringList args;
|
|
#if defined(Q_OS_WIN)
|
|
this->i2p.start(QDir(I2P_INSTALL_PATH).filePath("i2pd.exe"), args);
|
|
#elif defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
|
QString configsFolder = QDir(I2P_INSTALL_PATH).filePath("configs");
|
|
QString logsFolder = QDir(I2P_INSTALL_PATH).filePath("logs");
|
|
|
|
args << "--datadir" << QDir(I2P_INSTALL_PATH).filePath("data")
|
|
<< "--conf" << QDir(configsFolder).filePath("i2pd.conf")
|
|
<< "--tunconf" << QDir(configsFolder).filePath("tunnels.conf")
|
|
<< "--log" << QDir(logsFolder).filePath("i2pd.log");
|
|
|
|
this->i2p.start(QDir(I2P_INSTALL_PATH).filePath("i2pd"), args);
|
|
#else
|
|
#endif
|
|
|
|
}
|
|
|
|
void I2PController::onProcessError(QProcess::ProcessError error)
|
|
{
|
|
qDebug() << "I2P process error:" << error;
|
|
|
|
switch (error)
|
|
{
|
|
case QProcess::FailedToStart:
|
|
qCritical() << "i2pd failed to start";
|
|
emit fatalError("Failed to start i2pd");
|
|
break;
|
|
|
|
case QProcess::Crashed:
|
|
qWarning() << "i2pd crashed";
|
|
restartI2P();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void I2PController::onProcessFinished(int exitCode, QProcess::ExitStatus status)
|
|
{
|
|
qDebug() << "i2pd finished" << exitCode << status;
|
|
|
|
if (status == QProcess::CrashExit)
|
|
{
|
|
qWarning() << "i2pd crashed, restarting...";
|
|
restartI2P();
|
|
return;
|
|
}
|
|
|
|
if (exitCode != 0)
|
|
{
|
|
qWarning() << "i2pd exited with error";
|
|
restartI2P();
|
|
}
|
|
}
|
|
|
|
void I2PController::restartI2P()
|
|
{
|
|
if (isFatalErrored) return;
|
|
|
|
static int restartCount = 0;
|
|
|
|
if (restartCount > 5)
|
|
{
|
|
qCritical() << "i2pd crashed too many times";
|
|
emit fatalError("i2pd keeps crashing");
|
|
return;
|
|
}
|
|
|
|
restartCount++;
|
|
|
|
QTimer::singleShot(3000, [this]() {
|
|
start();
|
|
});
|
|
}
|