locale-setup.c revision bcd8e6d1bd3f434af894faeb400fee0e99445a7f
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen/***
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen This file is part of systemd.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen Copyright 2010 Lennart Poettering
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen systemd is free software; you can redistribute it and/or modify it
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen under the terms of the GNU Lesser General Public License as published by
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen (at your option) any later version.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen systemd is distributed in the hope that it will be useful, but
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen Lesser General Public License for more details.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen You should have received a copy of the GNU Lesser General Public License
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen***/
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen#include <string.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <stdlib.h>
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen#include <errno.h>
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "locale-setup.h"
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen#include "util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "macro.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "virt.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "fileio.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen#include "env-util.h"
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersenenum {
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen /* We don't list LC_ALL here on purpose. People should be
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * using LANG instead. */
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LANG,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LANGUAGE,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_CTYPE,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_NUMERIC,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_TIME,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_COLLATE,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_MONETARY,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_MESSAGES,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_PAPER,
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen VARIABLE_LC_NAME,
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen VARIABLE_LC_ADDRESS,
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen VARIABLE_LC_TELEPHONE,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_MEASUREMENT,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen VARIABLE_LC_IDENTIFICATION,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen _VARIABLE_MAX
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen};
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersenstatic const char * const variable_names[_VARIABLE_MAX] = {
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LANG] = "LANG",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LANGUAGE] = "LANGUAGE",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_CTYPE] = "LC_CTYPE",
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_TIME] = "LC_TIME",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_COLLATE] = "LC_COLLATE",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_MONETARY] = "LC_MONETARY",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_PAPER] = "LC_PAPER",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_NAME] = "LC_NAME",
75f86906c52735c98dc0aa7e24b773edb42ee814Lennart Poettering [VARIABLE_LC_ADDRESS] = "LC_ADDRESS",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen};
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersenint locale_setup(char ***environment) {
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen char **add;
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen char *variables[_VARIABLE_MAX] = {};
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen int r = 0, i;
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen if (detect_container(NULL) <= 0) {
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen r = parse_env_file("/proc/cmdline", WHITESPACE,
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen "locale.LANG", &variables[VARIABLE_LANG],
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
40862866417265ac8c20422cb44f14a8f141ce0dTom Gundersen "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
e2acdb6b0f68d9b4152708a9f21bf9e11f8b9e7eTorstein Husebø "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen NULL);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen if (r < 0 && r != -ENOENT)
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
}
/* Hmm, nothing set on the kernel cmd line? Then let's
* try /etc/locale.conf */
if (r <= 0) {
r = parse_env_file("/etc/locale.conf", NEWLINE,
"LANG", &variables[VARIABLE_LANG],
"LANGUAGE", &variables[VARIABLE_LANGUAGE],
"LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
"LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
"LC_TIME", &variables[VARIABLE_LC_TIME],
"LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
"LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
"LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
"LC_PAPER", &variables[VARIABLE_LC_PAPER],
"LC_NAME", &variables[VARIABLE_LC_NAME],
"LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
"LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
"LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
"LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
NULL);
if (r < 0 && r != -ENOENT)
log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
}
add = NULL;
for (i = 0; i < _VARIABLE_MAX; i++) {
char *s;
if (!variables[i])
continue;
s = strjoin(variable_names[i], "=", variables[i], NULL);
if (!s) {
r = -ENOMEM;
goto finish;
}
if (strv_push(&add, s) < 0) {
free(s);
r = -ENOMEM;
goto finish;
}
}
if (!strv_isempty(add)) {
char **e;
e = strv_env_merge(2, *environment, add);
if (!e) {
r = -ENOMEM;
goto finish;
}
strv_free(*environment);
*environment = e;
}
r = 0;
finish:
strv_free(add);
for (i = 0; i < _VARIABLE_MAX; i++)
free(variables[i]);
return r;
}