File indexing completed on 2024-04-28 16:54:29
0001 /* 0002 SPDX-FileCopyrightText: 2005-2010 David Jarvie <djarvie@kde.org> 0003 SPDX-FileCopyrightText: 2005 S.R.Haque <srhaque@iee.org> 0004 SPDX-FileCopyrightText: 2013 Martin Klapetek <mklapetek@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "ktimezoned.h" 0010 0011 #include <QDBusConnection> 0012 #include <QDBusMessage> 0013 #include <QDebug> 0014 #include <QDir> 0015 #include <QFileInfo> 0016 #include <QTimeZone> 0017 0018 #include <KConfig> 0019 #include <KConfigGroup> 0020 #include <KDirWatch> 0021 #include <KPluginFactory> 0022 0023 K_PLUGIN_CLASS_WITH_JSON(KTimeZoned, "ktimezoned.json") 0024 0025 const char LOCAL_ZONE[] = "LocalZone"; // name of local time zone 0026 const char ZONEINFO_DIR[] = "ZoneinfoDir"; // path to zoneinfo/ directory 0027 const char ZONE_TAB[] = "Zonetab"; // path & name of zone.tab 0028 0029 KTimeZoned::KTimeZoned(QObject *parent, const QList<QVariant> &l) 0030 : KTimeZonedBase(parent, l) 0031 { 0032 init(false); 0033 } 0034 0035 KTimeZoned::~KTimeZoned() 0036 { 0037 delete m_dirWatch; 0038 m_dirWatch = nullptr; 0039 delete m_zoneTabWatch; 0040 m_zoneTabWatch = nullptr; 0041 } 0042 0043 void KTimeZoned::init(bool restart) 0044 { 0045 if (restart) { 0046 delete m_dirWatch; 0047 m_dirWatch = nullptr; 0048 delete m_zoneTabWatch; 0049 m_zoneTabWatch = nullptr; 0050 m_localZone = QString(); 0051 m_zoneinfoDir = QString(); 0052 m_zoneTab = QString(); 0053 } 0054 0055 KConfig config(QStringLiteral("ktimezonedrc")); 0056 if (restart) 0057 config.reparseConfiguration(); 0058 0059 KConfigGroup group(&config, "TimeZones"); 0060 m_localZone = group.readEntry(LOCAL_ZONE); 0061 m_zoneinfoDir = group.readEntry(ZONEINFO_DIR); 0062 m_zoneTab = group.readEntry(ZONE_TAB); 0063 0064 updateLocalZone(); 0065 0066 if (!m_dirWatch) { 0067 m_dirWatch = new KDirWatch(this); 0068 m_dirWatch->addFile(QStringLiteral("/etc/timezone")); 0069 m_dirWatch->addFile(QStringLiteral("/etc/localtime")); 0070 0071 connect(m_dirWatch, &KDirWatch::dirty, this, &KTimeZoned::updateLocalZone); 0072 connect(m_dirWatch, &KDirWatch::deleted, this, &KTimeZoned::updateLocalZone); 0073 connect(m_dirWatch, &KDirWatch::created, this, &KTimeZoned::updateLocalZone); 0074 } 0075 0076 if (!m_zoneTabWatch && findZoneTab(m_zoneTab)) { 0077 // cache the values so we don't look it up on next startup 0078 KConfig config(QStringLiteral("ktimezonedrc")); 0079 KConfigGroup group(&config, "TimeZones"); 0080 group.writeEntry(ZONEINFO_DIR, m_zoneinfoDir); 0081 group.writeEntry(ZONE_TAB, m_zoneTab); 0082 group.sync(); 0083 0084 m_zoneTabWatch = new KDirWatch(this); 0085 m_zoneTabWatch->addDir(m_zoneinfoDir, KDirWatch::WatchFiles); 0086 0087 connect(m_dirWatch, &KDirWatch::dirty, this, &KTimeZoned::updateLocalZone); 0088 connect(m_dirWatch, &KDirWatch::created, this, &KTimeZoned::updateLocalZone); 0089 connect(m_dirWatch, &KDirWatch::deleted, this, &KTimeZoned::updateLocalZone); 0090 } 0091 } 0092 0093 // Check if the local zone has been updated, and if so, write the new 0094 // zone to the config file and notify interested parties. 0095 void KTimeZoned::updateLocalZone() 0096 { 0097 QString systemTimeZone = QTimeZone::systemTimeZoneId(); 0098 0099 if (m_localZone != systemTimeZone) { 0100 qDebug() << "System timezone has been changed, new timezone is" << systemTimeZone; 0101 0102 KConfig config(QStringLiteral("ktimezonedrc")); 0103 KConfigGroup group(&config, "TimeZones"); 0104 m_localZone = systemTimeZone; 0105 group.writeEntry(LOCAL_ZONE, m_localZone); 0106 group.sync(); 0107 0108 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Daemon"), QStringLiteral("org.kde.KTimeZoned"), QStringLiteral("timeZoneChanged")); 0109 QDBusConnection::sessionBus().send(message); 0110 } 0111 } 0112 0113 /* 0114 * Find the location of the zoneinfo files and store in m_zoneinfoDir. 0115 */ 0116 bool KTimeZoned::findZoneTab(const QString &pathFromConfig) 0117 { 0118 // First try the cached path 0119 if (QFileInfo::exists(pathFromConfig)) { 0120 return true; 0121 } 0122 0123 const QString ZONE_TAB_FILE = QStringLiteral("/zone.tab"); 0124 const QString ZONE_INFO_DIR = QStringLiteral("/usr/share/zoneinfo"); 0125 0126 // Find and open zone.tab - it's all easy except knowing where to look. 0127 // Try the LSB location first. 0128 QDir dir; 0129 QString zoneinfoDir = ZONE_INFO_DIR; 0130 QString zoneTab = ZONE_INFO_DIR + ZONE_TAB_FILE; 0131 // make a note if the dir exists; whether it contains zone.tab or not 0132 if (dir.exists(zoneinfoDir) && QFileInfo::exists(zoneTab)) { 0133 m_zoneinfoDir = zoneinfoDir; 0134 m_zoneTab = zoneTab; 0135 return true; 0136 } 0137 0138 zoneinfoDir = QStringLiteral("/usr/lib/zoneinfo"); 0139 zoneTab = zoneinfoDir + ZONE_TAB_FILE; 0140 if (dir.exists(zoneinfoDir) && QFileInfo::exists(zoneTab)) { 0141 m_zoneinfoDir = zoneinfoDir; 0142 m_zoneTab = zoneTab; 0143 return true; 0144 } 0145 0146 zoneinfoDir = ::getenv("TZDIR"); 0147 zoneTab = zoneinfoDir + ZONE_TAB_FILE; 0148 if (!zoneinfoDir.isEmpty() && dir.exists(zoneinfoDir) && QFileInfo::exists(zoneTab)) { 0149 m_zoneinfoDir = zoneinfoDir; 0150 m_zoneTab = zoneTab; 0151 return true; 0152 } 0153 0154 zoneinfoDir = QLatin1String("/usr/share/lib/zoneinfo"); 0155 zoneTab = zoneinfoDir + ZONE_TAB_FILE; 0156 if (dir.exists(zoneinfoDir + QLatin1String("/src")) && QFileInfo::exists(zoneTab)) { 0157 m_zoneinfoDir = zoneinfoDir; 0158 m_zoneTab = zoneTab; 0159 return true; 0160 } 0161 0162 return false; 0163 } 0164 0165 void KTimeZoned::zonetabChanged() 0166 { 0167 QDBusMessage message = 0168 QDBusMessage::createSignal(QStringLiteral("/Daemon"), QStringLiteral("org.kde.KTimeZoned"), QStringLiteral("timeZoneDatabaseUpdated")); 0169 QDBusConnection::sessionBus().send(message); 0170 } 0171 0172 #include "ktimezoned.moc" 0173 #include "moc_ktimezonedbase.cpp"