]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/locale-setup.c
Merge pull request #2495 from heftig/master
[thirdparty/systemd.git] / src / core / locale-setup.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <stdlib.h>
22
23 #include "env-util.h"
24 #include "fileio.h"
25 #include "locale-setup.h"
26 #include "locale-util.h"
27 #include "string-util.h"
28 #include "strv.h"
29 #include "util.h"
30 #include "virt.h"
31
32 int locale_setup(char ***environment) {
33 char **add;
34 char *variables[_VARIABLE_LC_MAX] = {};
35 int r = 0, i;
36
37 if (detect_container() <= 0) {
38 r = parse_env_file("/proc/cmdline", WHITESPACE,
39 "locale.LANG", &variables[VARIABLE_LANG],
40 "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
41 "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
42 "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
43 "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
44 "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
45 "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
46 "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
47 "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
48 "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
49 "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
50 "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
51 "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
52 "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
53 NULL);
54
55 if (r < 0 && r != -ENOENT)
56 log_warning_errno(r, "Failed to read /proc/cmdline: %m");
57 }
58
59 /* Hmm, nothing set on the kernel cmd line? Then let's
60 * try /etc/locale.conf */
61 if (r <= 0) {
62 r = parse_env_file("/etc/locale.conf", NEWLINE,
63 "LANG", &variables[VARIABLE_LANG],
64 "LANGUAGE", &variables[VARIABLE_LANGUAGE],
65 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
66 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
67 "LC_TIME", &variables[VARIABLE_LC_TIME],
68 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
69 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
70 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
71 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
72 "LC_NAME", &variables[VARIABLE_LC_NAME],
73 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
74 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
75 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
76 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
77 NULL);
78
79 if (r < 0 && r != -ENOENT)
80 log_warning_errno(r, "Failed to read /etc/locale.conf: %m");
81 }
82
83 add = NULL;
84 for (i = 0; i < _VARIABLE_LC_MAX; i++) {
85 char *s;
86
87 if (!variables[i])
88 continue;
89
90 s = strjoin(locale_variable_to_string(i), "=", variables[i], NULL);
91 if (!s) {
92 r = -ENOMEM;
93 goto finish;
94 }
95
96 if (strv_consume(&add, s) < 0) {
97 r = -ENOMEM;
98 goto finish;
99 }
100 }
101
102 if (!strv_isempty(add)) {
103 char **e;
104
105 e = strv_env_merge(2, *environment, add);
106 if (!e) {
107 r = -ENOMEM;
108 goto finish;
109 }
110
111 strv_free(*environment);
112 *environment = e;
113 }
114
115 r = 0;
116
117 finish:
118 strv_free(add);
119
120 for (i = 0; i < _VARIABLE_LC_MAX; i++)
121 free(variables[i]);
122
123 return r;
124 }