Commit 5459338c authored by Tomi Leppänen's avatar Tomi Leppänen

Store locale.conf per user and set system locale.

[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's avatarTomi Leppänen <tomi.leppanen@jolla.com>
parent cc0a4308
......@@ -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}.
......
/*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
* Contact: Pekka Vuorela <pekka.vuorela@jolla.com>
*
* 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 <QDir>
#include <QFile>
#include <QFileInfo>
#include <QRegularExpression>
#include <QDebug>
......@@ -38,9 +41,68 @@
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sailfishaccesscontrol.h>
#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;
}
......@@ -5,6 +5,9 @@ target.path = $$TARGETPATH
QT = core
CONFIG += link_pkgconfig
PKGCONFIG += sailfishaccesscontrol
SOURCES += \
main.cpp \
../src/localeconfig.cpp
......
/*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
* Contact: Pekka Vuorela <pekka.vuorela@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
......@@ -36,17 +37,15 @@
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
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");
}
/*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
* Contact: Pekka Vuorela <pekka.vuorela@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
......@@ -36,5 +37,6 @@
#include <QString>
QString localeConfigPath();
QString systemLocaleConfigPath();
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment