#include "./syncthingconfig.h" #include "./utils.h" #include "resources/config.h" #include #include #include #include #include namespace Data { /*! * \struct SyncthingConfig * \brief The SyncthingConfig struct holds the configuration of the local Syncthing instance read from config.xml in the Syncthing home directory. * \remarks Only a few fields are required since most of the Syncthing config can be accessed via SyncthingConnection class. */ /*! * \brief Locates the file with the specified \a fileName in Syncthing's config directory. * \remarks The lookup within QStandardPaths::RuntimeLocation is mainly for macOS where the full path * is "$HOME/Library/Application Support/Syncthing/config.xml". */ QString SyncthingConfig::locateConfigFile(const QString &fileName) { auto path = qEnvironmentVariable(PROJECT_VARNAME_UPPER "_SYNCTHING_CONFIG_DIR"); if (!path.isEmpty()) { if (!QFile::exists(path = path % QChar('/') % fileName)) { path.clear(); } return path; } static const QString casings[] = { QStringLiteral("syncthing/"), QStringLiteral("Syncthing/") }; static const QStandardPaths::StandardLocation locations[] = { QStandardPaths::GenericConfigLocation, QStandardPaths::RuntimeLocation }; for (const auto location : locations) { for (const auto &casing : casings) { if (!(path = QStandardPaths::locate(location, casing + fileName)).isEmpty()) { return path; } } } return path; } /*! * \brief Locates Syncthing's main config file ("config.xml"). */ QString SyncthingConfig::locateConfigFile() { return locateConfigFile(QStringLiteral("config.xml")); } /*! * \brief Locates Syncthing's GUI HTTPS certificate. */ QString SyncthingConfig::locateHttpsCertificate() { return locateConfigFile(QStringLiteral("https-cert.pem")); } bool SyncthingConfig::restore(const QString &configFilePath) { QFile configFile(configFilePath); if (!configFile.open(QFile::ReadOnly)) { return false; } QXmlStreamReader xmlReader(&configFile); bool ok = false; #include children { // only version 16 supported, try to parse other versions anyways since the changes might not affect // the few parts read here version = attribute("version").toString(); children { iftag("gui") { ok = true; guiEnabled = attributeFlag("enabled"); guiEnforcesSecureConnection = attributeFlag("tls"); children { iftag("address") { guiAddress = text; } eliftag("user") { guiUser = text; } eliftag("password") { guiPasswordHash = text; } eliftag("apikey") { guiApiKey = text; } else_skip } } else_skip } } #include return ok; } QString SyncthingConfig::syncthingUrl() const { return (guiEnforcesSecureConnection || !isLocal(stripPort(guiAddress)) ? QStringLiteral("https://") : QStringLiteral("http://")) + guiAddress; } } // namespace Data