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