From a0a8b02e26697f932f8d2285b8166aa3fc632414 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Sat, 30 Sep 2023 02:18:20 +0200 Subject: [PATCH] [PosixTimezone] Refactor timezone reading --- xbmc/platform/posix/PosixTimezone.cpp | 90 +++++++++++++++------------ xbmc/platform/posix/PosixTimezone.h | 14 +++-- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/xbmc/platform/posix/PosixTimezone.cpp b/xbmc/platform/posix/PosixTimezone.cpp index 1a1f7d59fbd5f..56297bb54b7ca 100644 --- a/xbmc/platform/posix/PosixTimezone.cpp +++ b/xbmc/platform/posix/PosixTimezone.cpp @@ -6,21 +6,24 @@ * See LICENSES/README.md for more information. */ -#include -#include "PlatformDefs.h" #include "PosixTimezone.h" -#include "utils/SystemInfo.h" #include "ServiceBroker.h" -#include "utils/StringUtils.h" #include "XBDateTime.h" -#include "settings/lib/Setting.h" -#include "settings/lib/SettingDefinitions.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" -#include +#include "settings/lib/Setting.h" +#include "settings/lib/SettingDefinitions.h" +#include "utils/StringUtils.h" +#include "utils/SystemInfo.h" #include +#include +#include +#include +#include + +#include "PlatformDefs.h" CPosixTimezone::CPosixTimezone() { @@ -195,44 +198,51 @@ void CPosixTimezone::SetTimezone(const std::string& timezoneName) std::string CPosixTimezone::GetOSConfiguredTimezone() { - char timezoneName[255]; + std::string timezoneName; - // try Slackware approach first - ssize_t rlrc = readlink("/etc/localtime-copied-from" - , timezoneName, sizeof(timezoneName)-1); + // try Slackware approach first + timezoneName = ReadFromLocaltime("/etc/localtime-copied-from"); - // RHEL and maybe other distros make /etc/localtime a symlink - if (rlrc == -1) - rlrc = readlink("/etc/localtime", timezoneName, sizeof(timezoneName)-1); + // RHEL and maybe other distros make /etc/localtime a symlink + if (timezoneName.empty()) + timezoneName = ReadFromLocaltime("/etc/localtime"); - if (rlrc != -1) - { - timezoneName[rlrc] = '\0'; - - char* p = strrchr(timezoneName,'/'); - if (p) - { // we want the previous '/' - char* q = p; - *q = 0; - p = strrchr(timezoneName,'/'); - *q = '/'; - if (p) - p++; - } - return p; - } + // now try Debian approach + if (timezoneName.empty()) + timezoneName = ReadFromTimezone("/etc/timezone"); - // now try Debian approach - timezoneName[0] = 0; - FILE* fp = fopen("/etc/timezone", "r"); - if (fp) - { - if (fgets(timezoneName, sizeof(timezoneName), fp)) - timezoneName[strlen(timezoneName)-1] = '\0'; - fclose(fp); - } + return timezoneName; +} + +std::string CPosixTimezone::ReadFromLocaltime(const std::string_view filename) +{ + std::error_code e; + std::string path = std::filesystem::read_symlink(filename, e); + + // Read the timezone starting from the second last occurrence of / + size_t pos = path.rfind('/'); + if (pos == std::string::npos) + return ""; + + pos = path.rfind('/', pos - 1); + if (pos == std::string::npos) + return ""; + + return path.substr(pos + 1); +} + +std::string CPosixTimezone::ReadFromTimezone(const std::string_view filename) +{ + std::string timezoneName; + std::ifstream file(filename.data()); + + if (file.is_open()) + { + std::getline(file, timezoneName); + file.close(); + } - return timezoneName; + return timezoneName; } void CPosixTimezone::SettingOptionsTimezoneCountriesFiller( diff --git a/xbmc/platform/posix/PosixTimezone.h b/xbmc/platform/posix/PosixTimezone.h index 076e87fa51e98..26a7f0934079c 100644 --- a/xbmc/platform/posix/PosixTimezone.h +++ b/xbmc/platform/posix/PosixTimezone.h @@ -46,12 +46,14 @@ class CPosixTimezone : public ISettingCallback, public ISettingsHandler void* data); private: - std::vector m_counties; - std::map m_countryByCode; - std::map m_countryByName; - - std::map > m_timezonesByCountryCode; - std::map m_countriesByTimezoneName; + std::string ReadFromLocaltime(std::string_view filename); + std::string ReadFromTimezone(std::string_view filename); + std::vector m_counties; + std::map m_countryByCode; + std::map m_countryByName; + + std::map> m_timezonesByCountryCode; + std::map m_countriesByTimezoneName; }; extern CPosixTimezone g_timezone;