From 5459338c4869feacda08b9bb4b834d28418e9d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Lepp=C3=A4nen?= Date: Wed, 12 Feb 2020 13:45:12 +0200 Subject: [PATCH] Store locale.conf per user and set system locale. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [systemsettings] Store locale to path based on uid. Contributes to JB#47651 [systemsettings] Set system locale. Contributes to JB#47651 Store user and system locale in separate directories. Store user locale based on uid instead of username since that is easier to handle in certain service files. Setting device owner locale sets system locale too. Working with paths that may not exist is a little ugly in Qt and it doesn't seem to have a way to set directory permissions at all. Signed-off-by: Tomi Leppänen --- rpm/nemo-qml-plugin-systemsettings.spec | 1 + setlocale/main.cpp | 84 +++++++++++++++++++++---- setlocale/setlocale.pro | 3 + src/localeconfig.cpp | 17 +++-- src/localeconfig.h | 2 + 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/rpm/nemo-qml-plugin-systemsettings.spec b/rpm/nemo-qml-plugin-systemsettings.spec index 63393ba..a64dc06 100644 --- a/rpm/nemo-qml-plugin-systemsettings.spec +++ b/rpm/nemo-qml-plugin-systemsettings.spec @@ -30,6 +30,7 @@ BuildRequires: pkgconfig(connman-qt5) >= 1.2.23 BuildRequires: pkgconfig(ssu-sysinfo) >= 1.1.0 BuildRequires: pkgconfig(packagekitqt5) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(sailfishaccesscontrol) %description %{summary}. diff --git a/setlocale/main.cpp b/setlocale/main.cpp index 6b62d1f..93830ff 100644 --- a/setlocale/main.cpp +++ b/setlocale/main.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2019 Jolla Ltd. + * Copyright (C) 2020 Open Mobile Platform LLC. * Contact: Pekka Vuorela * * You may use this file under the terms of the BSD license as follows: @@ -30,7 +31,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." */ +#include #include +#include #include #include @@ -38,9 +41,68 @@ #include #include #include +#include +#include #include "../src/localeconfig.h" +static bool ensureDirectory(QString filePath) +{ + auto directory = QFileInfo(filePath).dir(); + + if (directory.exists()) + return true; + + // Ensure parent with correct rights (recursion) + if (!ensureDirectory(directory.path())) + return false; + + // Create this directory + if (!directory.mkpath(QStringLiteral("."))) + return false; + + // Set correct access perms, root:root 755 + auto pathArray = directory.path().toUtf8(); + const char *path = pathArray.data(); + + if (chmod(path, S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) + qWarning() << "Failed to set directory permissions" << directory.path() << ":" << strerror(errno); + + if (chown(path, 0, 0) == -1) + qWarning() << "Failed to set directory as root:root" << directory.path() << ":" << strerror(errno); + + return true; +} + +static bool writeLocale(QString &configPath, QString &locale) +{ + QFile localeConfig(configPath); + if (!ensureDirectory(configPath)) { + qWarning() << "Unable to create directory for locale configuration file"; + return false; + } + + if (!localeConfig.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { + qWarning() << "Unable to open locale configuration file for writing:" << configPath + << "-" << localeConfig.errorString(); + return false; + } + + localeConfig.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | + QFileDevice::ReadGroup | QFileDevice::ReadOther); + + if (fchown(localeConfig.handle(), 0, 0) == -1) { + qWarning() << "Failed to set localeconfig as root:root:" << configPath << ":" << strerror(errno); + } + + if (!configPath.startsWith("/etc/")) + localeConfig.write("# Autogenerated by settings\n"); + + localeConfig.write(QString("LANG=%1\n").arg(locale).toLatin1()); + localeConfig.close(); + return true; +} + int main(int argc, char *argv[]) { if (argc != 2) { @@ -61,23 +123,19 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - QFile localeConfig(configPath); - if (!localeConfig.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { - qWarning() << "Unable to open locale configuration file for writing:" << configPath - << "-" << localeConfig.errorString(); + if (!writeLocale(configPath, newLocale)) return EXIT_FAILURE; - } - localeConfig.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | - QFileDevice::ReadGroup | QFileDevice::ReadOther); + // Set system locale as well if the user is device owner + if (sailfish_access_control_hasgroup(getuid(), "sailfish-system")) { + QString configPath = systemLocaleConfigPath(); - if (fchown(localeConfig.handle(), 0, 0)) { - qWarning() << "Failed to set localeconfig as root:root" << strerror(errno); + if (configPath.isEmpty()) { + qWarning() << "No path for system locale"; + } else if (!writeLocale(configPath, newLocale)) { + qWarning() << "Could not set system locale"; + } // else success } - localeConfig.write("# Autogenerated by settings\n"); - localeConfig.write(QString("LANG=%1\n").arg(newLocale).toLatin1()); - localeConfig.close(); - return EXIT_SUCCESS; } diff --git a/setlocale/setlocale.pro b/setlocale/setlocale.pro index f4c0f16..4c8ad39 100644 --- a/setlocale/setlocale.pro +++ b/setlocale/setlocale.pro @@ -5,6 +5,9 @@ target.path = $$TARGETPATH QT = core +CONFIG += link_pkgconfig +PKGCONFIG += sailfishaccesscontrol + SOURCES += \ main.cpp \ ../src/localeconfig.cpp diff --git a/src/localeconfig.cpp b/src/localeconfig.cpp index 714b6d2..ffb59ab 100644 --- a/src/localeconfig.cpp +++ b/src/localeconfig.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2019 Jolla Ltd. + * Copyright (C) 2020 Open Mobile Platform LLC. * Contact: Pekka Vuorela * * You may use this file under the terms of the BSD license as follows: @@ -36,17 +37,15 @@ #include #include -#include QString localeConfigPath() { - struct passwd *passwdInfo = getpwuid(getuid()); + // User-wide locale config + return QString("/home/.system/var/lib/environment/%1/locale.conf").arg(getuid()); +} - if (passwdInfo) { - QString userName = passwdInfo->pw_name; - return QString("/var/lib/environment/%1/locale.conf").arg(userName); - } else { - qWarning() << "Unable to get user info"; - return QString(); - } +QString systemLocaleConfigPath() +{ + // System-wide locale config + return QString("/etc/locale.conf"); } diff --git a/src/localeconfig.h b/src/localeconfig.h index 03e2584..021d3d0 100644 --- a/src/localeconfig.h +++ b/src/localeconfig.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2019 Jolla Ltd. + * Copyright (C) 2020 Open Mobile Platform LLC. * Contact: Pekka Vuorela * * You may use this file under the terms of the BSD license as follows: @@ -36,5 +37,6 @@ #include QString localeConfigPath(); +QString systemLocaleConfigPath(); #endif