#include "./setupdetection.h" #include "./settingsdialog.h" // use meta-data of syncthingtray application here #include "resources/../../tray/resources/config.h" #include #if defined(LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD) && (defined(PLATFORM_UNIX) || defined(PLATFORM_MINGW) || defined(PLATFORM_CYGWIN)) #define PLATFORM_HAS_GETLOGIN #include #endif namespace QtGui { SetupDetection::SetupDetection(QObject *parent) : QObject(parent) { // assume default service names const auto defaultUserUnit = qEnvironmentVariable(PROJECT_VARNAME_UPPER "_SYSTEMD_USER_UNIT", QStringLiteral("syncthing.service")); #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD userService.setUnitName(defaultUserUnit); systemService.setUnitName(QStringLiteral("syncthing@") % #ifdef PLATFORM_HAS_GETLOGIN QString::fromLocal8Bit(getlogin()) % #endif QStringLiteral(".service")); #endif // configure launcher to test invocation of "syncthing --version" capturing output defaultSyncthingArgs = launcherSettings.syncthingArgs; launcherSettings.syncthingArgs = QStringLiteral("--version"); launcher.setEmittingOutput(true); // configure timeout auto hasConfiguredTimeout = false; auto configuredTimeout = qEnvironmentVariableIntValue(PROJECT_VARNAME_UPPER "_WIZARD_SETUP_DETECTION_TIMEOUT", &hasConfiguredTimeout); timeout.setInterval(hasConfiguredTimeout ? configuredTimeout : 2500); timeout.setSingleShot(true); // connect signals & slots connect(&connection, &Data::SyncthingConnection::error, this, &SetupDetection::handleConnectionError); connect(&connection, &Data::SyncthingConnection::statusChanged, this, &SetupDetection::checkDone); #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD connect(&userService, &Data::SyncthingService::unitFileStateChanged, this, &SetupDetection::checkDone); connect(&systemService, &Data::SyncthingService::unitFileStateChanged, this, &SetupDetection::checkDone); #endif connect(&launcher, &Data::SyncthingLauncher::outputAvailable, this, &SetupDetection::handleLauncherOutput); connect(&launcher, &Data::SyncthingLauncher::exited, this, &SetupDetection::handleLauncherExit); connect(&launcher, &Data::SyncthingLauncher::errorOccurred, this, &SetupDetection::handleLauncherError); connect(&timeout, &QTimer::timeout, this, &SetupDetection::handleTimeout); } void SetupDetection::determinePaths() { configFilePath = Data::SyncthingConfig::locateConfigFile(); certPath = Data::SyncthingConfig::locateHttpsCertificate(); } void SetupDetection::restoreConfig() { configOk = config.restore(configFilePath); } void SetupDetection::initConnection() { auto settings = Data::SyncthingConnectionSettings(); settings.syncthingUrl = config.syncthingUrl(); settings.apiKey = config.guiApiKey.toLocal8Bit(); settings.httpsCertPath = certPath; settings.loadHttpsCert(); connection.applySettings(settings); } bool SetupDetection::hasConfig() const { return configOk && !config.guiAddress.isEmpty() && !config.guiApiKey.isEmpty(); } bool SetupDetection::isDone() const { return timedOut || (!connection.isConnecting() && (launcherExitCode.has_value() || launcherError.has_value()) #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD && !userService.unitFileState().isEmpty() && !systemService.unitFileState().isEmpty() #endif ); } void SetupDetection::reset() { timeout.stop(); timedOut = false; configOk = false; autostartEnabled = false; autostartConfiguredPath.reset(); config.guiAddress.clear(); config.guiApiKey.clear(); connection.disconnect(); launcher.terminate(); connectionErrors.clear(); launcherExitCode.reset(); launcherExitStatus.reset(); launcherError.reset(); launcherOutput.clear(); m_testStarted = false; } void SetupDetection::startTest() { if (m_testStarted) { return; } m_testStarted = true; restoreConfig(); initConnection(); connection.reconnect(); launcher.launch(launcherSettings); autostartConfiguredPath = configuredAutostartPath(); autostartEnabled = autostartConfiguredPath.has_value() ? !autostartConfiguredPath.value().isEmpty() : isAutostartEnabled(); autostartSupposedPath = supposedAutostartPath(); timeout.start(); } void SetupDetection::handleConnectionError(const QString &error) { connectionErrors << error; } void SetupDetection::handleLauncherExit(int exitCode, QProcess::ExitStatus exitStatus) { launcherExitCode = exitCode; launcherExitStatus = exitStatus; checkDone(); } void SetupDetection::handleLauncherError(QProcess::ProcessError error) { launcherError = error; checkDone(); } void SetupDetection::handleLauncherOutput(const QByteArray &output) { launcherOutput.append(output); } void SetupDetection::handleTimeout() { timedOut = true; checkDone(); } void SetupDetection::checkDone() { if (!m_testStarted) { return; } if (isDone()) { timeout.stop(); m_testStarted = false; emit done(); } } } // namespace QtGui