diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index 660b86d3..2f62f2d9 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -176,12 +176,12 @@ #include "plugin/device.h" #include "plugin/deviceclass.h" #include "plugin/deviceplugin.h" +#include "guhsettings.h" #include #include #include #include -#include #include #include #include @@ -199,8 +199,6 @@ DeviceManager::DeviceManager(QObject *parent) : m_pluginTimer.setInterval(10000); connect(&m_pluginTimer, &QTimer::timeout, this, &DeviceManager::timerEvent); - m_settingsFile = QCoreApplication::instance()->organizationName() + "/devices"; - // Give hardware a chance to start up before loading plugins etc. QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "loadConfiguredDevices", Qt::QueuedConnection); @@ -282,7 +280,7 @@ DeviceManager::DeviceError DeviceManager::setPluginConfig(const PluginId &plugin if (result != DeviceErrorNoError) { return result; } - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRolePlugins); settings.beginGroup("PluginConfig"); settings.beginGroup(plugin->pluginId().toString()); foreach (const Param ¶m, pluginConfig) { @@ -680,7 +678,7 @@ DeviceManager::DeviceError DeviceManager::removeConfiguredDevice(const DeviceId } device->deleteLater(); - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleDevices); settings.beginGroup("DeviceConfig"); settings.beginGroup(deviceId.toString()); settings.remove(""); @@ -807,7 +805,7 @@ void DeviceManager::loadPlugins() m_supportedDevices.insert(deviceClass.id(), deviceClass); qCDebug(dcDeviceManager) << "* Loaded device class:" << deviceClass.name(); } - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRolePlugins); settings.beginGroup("PluginConfig"); ParamList params; if (settings.childGroups().contains(pluginIface->pluginId().toString())) { @@ -850,7 +848,7 @@ void DeviceManager::loadPlugins() void DeviceManager::loadConfiguredDevices() { - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleDevices); settings.beginGroup("DeviceConfig"); qCDebug(dcDeviceManager) << "loading devices from" << settings.fileName(); foreach (const QString &idString, settings.childGroups()) { @@ -883,7 +881,7 @@ void DeviceManager::loadConfiguredDevices() void DeviceManager::storeConfiguredDevices() { - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleDevices); settings.beginGroup("DeviceConfig"); foreach (Device *device, m_configuredDevices) { settings.beginGroup(device->id().toString()); diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index fe7825ed..ec405e3d 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -166,8 +166,6 @@ private: QHash m_devicePlugins; - QString m_settingsFile; - // Hardware Resources Radio433* m_radio433; QTimer m_pluginTimer; diff --git a/libguh/guhsettings.cpp b/libguh/guhsettings.cpp new file mode 100644 index 00000000..bff94cbc --- /dev/null +++ b/libguh/guhsettings.cpp @@ -0,0 +1,199 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2015 Simon Stuerz * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "guhsettings.h" +#include "unistd.h" + +#include +#include +#include +#include + +GuhSettings::GuhSettings(const SettingsRole &role, QObject *parent): + QObject(parent), + m_role(role) +{ + QString settingsFile; + QString settingsPrefix = QCoreApplication::instance()->organizationName(); + bool rootPrivilege = isRoot(); + + switch (role) { + case SettingsRoleNone: + break; + case SettingsRoleDevices: + // check if we are running a test + if (settingsPrefix == "guh-test") { + settingsFile = settingsPrefix + "/test-devices"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created test-devices settings" << m_settings->fileName(); + } else if (rootPrivilege) { + settingsFile = "/etc/" + settingsPrefix + "/devices.conf"; + m_settings = new QSettings(settingsFile, QSettings::IniFormat, this); + qDebug() << "Created device settings" << m_settings->fileName(); + } else { + settingsFile = settingsPrefix + "/devices"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created device settings" << m_settings->fileName(); + } + break; + case SettingsRoleRules: + // check if we are running a test + if (settingsPrefix == "guh-test") { + settingsFile = settingsPrefix + "/test-rules"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created test-rules settings" << m_settings->fileName(); + } else if (rootPrivilege) { + settingsFile = "/etc/" + settingsPrefix + "/rules.conf"; + m_settings = new QSettings(settingsFile, QSettings::IniFormat, this); + qDebug() << "Created rule settings" << m_settings->fileName(); + } else { + settingsFile = settingsPrefix + "/rules"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created rule settings" << m_settings->fileName(); + } + break; + case SettingsRolePlugins: + // check if we are running a test + if (settingsPrefix == "guh-test") { + settingsFile = settingsPrefix + "/test-plugins"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created test-plugins settings" << m_settings->fileName(); + } else if (rootPrivilege) { + settingsFile = "/etc/" + settingsPrefix + "/plugins.conf"; + m_settings = new QSettings(settingsFile, QSettings::IniFormat, this); + qDebug() << "Created plugin settings" << m_settings->fileName(); + } else { + settingsFile = settingsPrefix + "/plugins"; + m_settings = new QSettings(settingsFile, QSettings::NativeFormat, this); + qDebug() << "Created plugin settings" << m_settings->fileName(); + } + break; + case SettingsRoleGlobal: + // this file schould always be readable and should never be written + settingsFile = "/etc/guh/guhd.conf"; + m_settings = new QSettings(settingsFile, QSettings::IniFormat, this); + qDebug() << "Created test guhd settings" << m_settings->fileName(); + break; + default: + break; + } +} + +GuhSettings::~GuhSettings() +{ + m_settings->sync(); + delete m_settings; +} + +GuhSettings::SettingsRole GuhSettings::settingsRole() const +{ + return m_role; +} + +bool GuhSettings::isRoot() +{ + if (getuid() != 0) + return false; + + return true; +} + +QString GuhSettings::logPath() +{ + QString logPath; + QString organisationName = QCoreApplication::instance()->organizationName(); + + if (organisationName == "guh-test") { + logPath = QDir::homePath() + ".config/" + organisationName + "/guhd-test.log"; + } else if (GuhSettings::isRoot()) { + logPath = "/var/log/guhd.log"; + } else { + logPath = QDir::homePath() + ".config/" + organisationName + "/guhd.log"; + } + + return logPath; +} + +QStringList GuhSettings::allKeys() const +{ + return m_settings->allKeys(); +} + +void GuhSettings::beginGroup(const QString &prefix) +{ + m_settings->beginGroup(prefix); +} + +QStringList GuhSettings::childGroups() const +{ + return m_settings->childGroups(); +} + +QStringList GuhSettings::childKeys() const +{ + return m_settings->childKeys(); +} + +void GuhSettings::clear() +{ + m_settings->clear(); +} + +bool GuhSettings::contains(const QString &key) const +{ + return m_settings->contains(key); +} + +void GuhSettings::endGroup() +{ + m_settings->endGroup(); +} + +QString GuhSettings::group() const +{ + return m_settings->group(); +} + +QString GuhSettings::fileName() const +{ + return m_settings->fileName(); +} + +bool GuhSettings::isWritable() const +{ + return m_settings->isWritable(); +} + +void GuhSettings::remove(const QString &key) +{ + m_settings->remove(key); +} + +void GuhSettings::setValue(const QString &key, const QVariant &value) +{ + Q_ASSERT_X(m_role != GuhSettings::SettingsRoleGlobal, "GuhSettings", "Bad settings implementation. The global settings file is read only."); + m_settings->setValue(key, value); +} + +QVariant GuhSettings::value(const QString &key, const QVariant &defaultValue) const +{ + return m_settings->value(key, defaultValue); +} + diff --git a/libguh/guhsettings.h b/libguh/guhsettings.h new file mode 100644 index 00000000..5f3a1a35 --- /dev/null +++ b/libguh/guhsettings.h @@ -0,0 +1,70 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2015 Simon Stuerz * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef GUHSETTINGS_H +#define GUHSETTINGS_H + +#include +#include + +class QSettings; + +class GuhSettings : public QObject +{ + Q_OBJECT +public: + enum SettingsRole { + SettingsRoleNone, + SettingsRoleDevices, + SettingsRoleRules, + SettingsRolePlugins, + SettingsRoleGlobal + }; + + explicit GuhSettings(const SettingsRole &role = SettingsRoleNone, QObject *parent = 0); + ~GuhSettings(); + + SettingsRole settingsRole() const; + + static bool isRoot(); + static QString logPath(); + + // forwarded QSettings methods + QStringList allKeys() const; + void beginGroup(const QString &prefix); + QStringList childGroups() const; + QStringList childKeys() const; + void clear(); + bool contains(const QString &key) const; + void endGroup(); + QString group() const; + QString fileName() const; + bool isWritable() const; + void remove(const QString &key); + void setValue(const QString & key, const QVariant &value); + QVariant value(const QString & key, const QVariant & defaultValue = QVariant()) const; + +private: + QSettings *m_settings; + SettingsRole m_role; + +}; + +#endif // GUHSETTINGS_H diff --git a/libguh/libguh.pro b/libguh/libguh.pro index f881fd38..bfa9ad1e 100644 --- a/libguh/libguh.pro +++ b/libguh/libguh.pro @@ -37,6 +37,8 @@ SOURCES += plugin/device.cpp \ types/ruleaction.cpp \ types/ruleactionparam.cpp \ types/statedescriptor.cpp \ + loggingcategories.cpp \ + guhsettings.cpp HEADERS += plugin/device.h \ plugin/deviceclass.h \ @@ -70,4 +72,5 @@ HEADERS += plugin/device.h \ types/statedescriptor.h \ typeutils.h \ loggingcategories.h \ + guhsettings.h diff --git a/server/main.cpp b/server/main.cpp index bd8763d0..f2a56815 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -27,6 +27,7 @@ #include #include +#include "unistd.h" #include "guhcore.h" #include "guhservice.h" #include "loggingcategories.h" @@ -123,6 +124,15 @@ int main(int argc, char *argv[]) bool startForeground = parser.isSet(foregroundOption); if (startForeground) { + // inform about userid + int userId = getuid(); + if (userId != 0) { + qCDebug(dcApplication) << "guhd started as user with ID" << userId; + } else { + qCDebug(dcApplication) << "guhd started as root."; + } + + // create core instance GuhCore::instance()->setRunningMode(GuhCore::RunningModeApplication); return application.exec(); } diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index ca10e7d2..5de59650 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -83,13 +83,13 @@ #include "loggingcategories.h" #include "types/paramdescriptor.h" #include "types/eventdescriptor.h" +#include "guhsettings.h" #include "guhcore.h" #include "devicemanager.h" #include "plugin/device.h" -#include #include #include #include @@ -103,8 +103,7 @@ namespace guhserver { RuleEngine::RuleEngine(QObject *parent) : QObject(parent) { - m_settingsFile = QCoreApplication::instance()->organizationName() + "/rules"; - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleRules); qCDebug(dcRuleEngine) << "laoding rules from" << settings.fileName(); foreach (const QString &idString, settings.childGroups()) { settings.beginGroup(idString); @@ -416,7 +415,7 @@ RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId, bool fromEdit m_ruleIds.takeAt(index); m_rules.remove(ruleId); - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleRules); settings.beginGroup(ruleId.toString()); settings.remove(""); settings.endGroup(); @@ -569,7 +568,7 @@ void RuleEngine::appendRule(const Rule &rule) void RuleEngine::saveRule(const Rule &rule) { // Save Events / EventDescriptors - QSettings settings(m_settingsFile); + GuhSettings settings(GuhSettings::SettingsRoleRules); settings.beginGroup(rule.id().toString()); settings.setValue("name", rule.name()); settings.setValue("enabled", rule.enabled()); diff --git a/server/ruleengine.h b/server/ruleengine.h index 844c35fe..111be986 100644 --- a/server/ruleengine.h +++ b/server/ruleengine.h @@ -92,7 +92,6 @@ private: void saveRule(const Rule &rule); private: - QString m_settingsFile; QList m_ruleIds; // Keeping a list of RuleIds to keep sorting order... QHash m_rules; // ...but use a Hash for faster finding QList m_activeRules; diff --git a/server/stateevaluator.cpp b/server/stateevaluator.cpp index 5fe8d53d..da5f5de2 100644 --- a/server/stateevaluator.cpp +++ b/server/stateevaluator.cpp @@ -23,6 +23,7 @@ #include "guhcore.h" #include "devicemanager.h" #include "loggingcategories.h" +#include "guhsettings.h" namespace guhserver { @@ -128,7 +129,7 @@ void StateEvaluator::removeDevice(const DeviceId &deviceId) } } -void StateEvaluator::dumpToSettings(QSettings &settings, const QString &groupName) const +void StateEvaluator::dumpToSettings(GuhSettings &settings, const QString &groupName) const { settings.beginGroup(groupName); @@ -150,7 +151,7 @@ void StateEvaluator::dumpToSettings(QSettings &settings, const QString &groupNam settings.endGroup(); } -StateEvaluator StateEvaluator::loadFromSettings(QSettings &settings, const QString &groupName) +StateEvaluator StateEvaluator::loadFromSettings(GuhSettings &settings, const QString &groupName) { settings.beginGroup(groupName); settings.beginGroup("stateDescriptor"); diff --git a/server/stateevaluator.h b/server/stateevaluator.h index 25b6f77f..0b50ee2c 100644 --- a/server/stateevaluator.h +++ b/server/stateevaluator.h @@ -25,9 +25,10 @@ #include "types/state.h" #include "types/statedescriptor.h" -#include #include +class GuhSettings; + namespace guhserver { class StateEvaluator @@ -50,8 +51,8 @@ public: void removeDevice(const DeviceId &deviceId); - void dumpToSettings(QSettings &settings, const QString &groupName) const; - static StateEvaluator loadFromSettings(QSettings &settings, const QString &groupPrefix); + void dumpToSettings(GuhSettings &settings, const QString &groupName) const; + static StateEvaluator loadFromSettings(GuhSettings &settings, const QString &groupPrefix); private: StateDescriptor m_stateDescriptor; diff --git a/server/tcpserver.cpp b/server/tcpserver.cpp index 42ecc513..06e98699 100644 --- a/server/tcpserver.cpp +++ b/server/tcpserver.cpp @@ -21,10 +21,10 @@ #include "tcpserver.h" #include "loggingcategories.h" +#include "guhsettings.h" #include #include -#include namespace guhserver { @@ -45,7 +45,7 @@ TcpServer::TcpServer(QObject *parent) : // load settings bool ok; - QSettings settings("/etc/guh/guhd.conf"); + GuhSettings settings(GuhSettings::SettingsRoleGlobal); settings.beginGroup("JSONRPC"); // TODO: handle interfaces in settings (enable just localhost ecc...) diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index 3daf65b3..13e585ed 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -22,6 +22,7 @@ #include "guhtestbase.h" #include "guhcore.h" #include "devicemanager.h" +#include "guhsettings.h" #include "plugin/deviceplugin.h" #include @@ -865,7 +866,7 @@ void TestDevices::removeDevice() QFETCH(DeviceId, deviceId); QFETCH(DeviceManager::DeviceError, deviceError); - QSettings settings(m_deviceSettings); + GuhSettings settings(GuhSettings::SettingsRoleDevices); settings.beginGroup("DeviceConfig"); if (deviceError == DeviceManager::DeviceErrorNoError) { settings.beginGroup(m_mockDeviceId.toString()); diff --git a/tests/auto/guhtestbase.cpp b/tests/auto/guhtestbase.cpp index bf9d1180..c7e39602 100644 --- a/tests/auto/guhtestbase.cpp +++ b/tests/auto/guhtestbase.cpp @@ -22,6 +22,7 @@ #include "guhtestbase.h" #include "mocktcpserver.h" #include "guhcore.h" +#include "guhsettings.h" #include "devicemanager.h" #include "jsontypes.h" @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -63,18 +63,15 @@ GuhTestBase::GuhTestBase(QObject *parent) : m_mockDevice1Port = 1337 + (qrand() % 1000); m_mockDevice2Port = 7331 + (qrand() % 1000); QCoreApplication::instance()->setOrganizationName("guh-test"); - - m_rulesSettings = QCoreApplication::instance()->organizationName() + "/rules"; - m_deviceSettings = QCoreApplication::instance()->organizationName() + "/devices"; } void GuhTestBase::initTestCase() { // If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers - QSettings rulesSettings(m_rulesSettings); + GuhSettings rulesSettings(GuhSettings::SettingsRoleRules); rulesSettings.clear(); - QSettings deviceSettings(m_deviceSettings); + GuhSettings deviceSettings(GuhSettings::SettingsRoleDevices); deviceSettings.clear(); GuhCore::instance(); diff --git a/tests/auto/guhtestbase.h b/tests/auto/guhtestbase.h index 62dd1679..81bd6ee4 100644 --- a/tests/auto/guhtestbase.h +++ b/tests/auto/guhtestbase.h @@ -135,8 +135,6 @@ protected: DeviceId m_mockDeviceId; - QString m_deviceSettings; - QString m_rulesSettings; }; }