]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/locale-setup.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / core / locale-setup.c
CommitLineData
72bca11b
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
72bca11b
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
72bca11b 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
72bca11b
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <string.h>
23#include <stdlib.h>
24#include <errno.h>
25
26#include "locale-setup.h"
27#include "util.h"
28#include "macro.h"
5dc4c17f 29#include "virt.h"
72bca11b
LP
30
31enum {
97e3d13f
LP
32 /* We don't list LC_ALL here on purpose. People should be
33 * using LANG instead. */
34
72bca11b 35 VARIABLE_LANG,
07bceef2 36 VARIABLE_LANGUAGE,
72bca11b
LP
37 VARIABLE_LC_CTYPE,
38 VARIABLE_LC_NUMERIC,
39 VARIABLE_LC_TIME,
40 VARIABLE_LC_COLLATE,
41 VARIABLE_LC_MONETARY,
42 VARIABLE_LC_MESSAGES,
72bca11b
LP
43 VARIABLE_LC_PAPER,
44 VARIABLE_LC_NAME,
45 VARIABLE_LC_ADDRESS,
46 VARIABLE_LC_TELEPHONE,
47 VARIABLE_LC_MEASUREMENT,
48 VARIABLE_LC_IDENTIFICATION,
49 _VARIABLE_MAX
50};
51
52static const char * const variable_names[_VARIABLE_MAX] = {
53 [VARIABLE_LANG] = "LANG",
07bceef2 54 [VARIABLE_LANGUAGE] = "LANGUAGE",
72bca11b
LP
55 [VARIABLE_LC_CTYPE] = "LC_CTYPE",
56 [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
e624abf7
LP
57 [VARIABLE_LC_TIME] = "LC_TIME",
58 [VARIABLE_LC_COLLATE] = "LC_COLLATE",
59 [VARIABLE_LC_MONETARY] = "LC_MONETARY",
08a67ac4 60 [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
e624abf7
LP
61 [VARIABLE_LC_PAPER] = "LC_PAPER",
62 [VARIABLE_LC_NAME] = "LC_NAME",
63 [VARIABLE_LC_ADDRESS] = "LC_ADDRESS",
64 [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
65 [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
66 [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
72bca11b
LP
67};
68
69int locale_setup(void) {
70 char *variables[_VARIABLE_MAX];
d885ac66 71 int r = 0, i;
72bca11b
LP
72
73 zero(variables);
74
03aea2ae 75 if (detect_container(NULL) <= 0)
2fc97846 76 if ((r = parse_env_file("/proc/cmdline", WHITESPACE,
54e4fdef 77#if defined(TARGET_FEDORA) || defined(TARGET_MEEGO)
2fc97846 78 "LANG", &variables[VARIABLE_LANG],
ce8a6aa1 79#endif
2fc97846 80 "locale.LANG", &variables[VARIABLE_LANG],
07bceef2 81 "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
2fc97846
LP
82 "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
83 "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
84 "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
85 "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
86 "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
87 "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
88 "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
89 "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
90 "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
91 "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
92 "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
93 "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
94 NULL)) < 0) {
ce8a6aa1 95
2fc97846
LP
96 if (r != -ENOENT)
97 log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
98 }
ce8a6aa1
LP
99
100 /* Hmm, nothing set on the kernel cmd line? Then let's
fd5bf055 101 * try /etc/locale.conf */
ce8a6aa1 102 if (r <= 0 &&
fd5bf055 103 (r = parse_env_file("/etc/locale.conf", NEWLINE,
ce8a6aa1 104 "LANG", &variables[VARIABLE_LANG],
07bceef2 105 "LANGUAGE", &variables[VARIABLE_LANGUAGE],
ce8a6aa1
LP
106 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
107 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
108 "LC_TIME", &variables[VARIABLE_LC_TIME],
109 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
110 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
111 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
112 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
113 "LC_NAME", &variables[VARIABLE_LC_NAME],
114 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
115 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
116 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
117 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
118 NULL)) < 0) {
119
120 if (r != -ENOENT)
fd5bf055 121 log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
ce8a6aa1
LP
122 }
123
54e4fdef 124#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MEEGO)
ce8a6aa1
LP
125 if (r <= 0 &&
126 (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
72bca11b
LP
127 "LANG", &variables[VARIABLE_LANG],
128 NULL)) < 0) {
129
130 if (r != -ENOENT)
131 log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
132 }
653ab83b 133
03aeb5be
KS
134#elif defined(TARGET_SUSE)
135 if (r <= 0 &&
136 (r = parse_env_file("/etc/sysconfig/language", NEWLINE,
137 "RC_LANG", &variables[VARIABLE_LANG],
138 NULL)) < 0) {
139
140 if (r != -ENOENT)
141 log_warning("Failed to read /etc/sysconfig/language: %s", strerror(-r));
142 }
143
1bd8b818 144#elif defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
7472744b
MB
145 if (r <= 0 &&
146 (r = parse_env_file("/etc/default/locale", NEWLINE,
34f0fd81
FK
147 "LANG", &variables[VARIABLE_LANG],
148 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
149 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
150 "LC_TIME", &variables[VARIABLE_LC_TIME],
151 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
152 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
153 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
154 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
155 "LC_NAME", &variables[VARIABLE_LC_NAME],
156 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
157 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
158 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
159 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
7472744b
MB
160 NULL)) < 0) {
161
162 if (r != -ENOENT)
163 log_warning("Failed to read /etc/default/locale: %s", strerror(-r));
164 }
165
f2fcd59f 166#elif defined(TARGET_ARCH)
ce8a6aa1
LP
167 if (r <= 0 &&
168 (r = parse_env_file("/etc/rc.conf", NEWLINE,
97e3d13f
LP
169 "LOCALE", &variables[VARIABLE_LANG],
170 NULL)) < 0) {
f2fcd59f 171
97e3d13f
LP
172 if (r != -ENOENT)
173 log_warning("Failed to read /etc/rc.conf: %s", strerror(-r));
174 }
653ab83b 175
918f4c69
GSB
176#elif defined(TARGET_GENTOO)
177 /* Gentoo's openrc expects locale variables in /etc/env.d/
178 * These files are later compiled by env-update into shell
179 * export commands at /etc/profile.env, with variables being
180 * exported by openrc's runscript (so /etc/init.d/)
181 */
ce8a6aa1
LP
182 if (r <= 0 &&
183 (r = parse_env_file("/etc/profile.env", NEWLINE,
918f4c69
GSB
184 "export LANG", &variables[VARIABLE_LANG],
185 "export LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
186 "export LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
187 "export LC_TIME", &variables[VARIABLE_LC_TIME],
188 "export LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
189 "export LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
190 "export LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
918f4c69
GSB
191 "export LC_PAPER", &variables[VARIABLE_LC_PAPER],
192 "export LC_NAME", &variables[VARIABLE_LC_NAME],
193 "export LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
194 "export LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
195 "export LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
196 "export LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
197 NULL)) < 0) {
198
199 if (r != -ENOENT)
200 log_warning("Failed to read /etc/profile.env: %s", strerror(-r));
201 }
6fdae8a6 202#elif defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA )
1de4d79b
AB
203 if (r <= 0 &&
204 (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
205 "LANG", &variables[VARIABLE_LANG],
206 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
207 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
208 "LC_TIME", &variables[VARIABLE_LC_TIME],
209 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
210 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
211 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
212 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
213 "LC_NAME", &variables[VARIABLE_LC_NAME],
214 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
215 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
216 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
217 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
218 NULL)) < 0) {
219
07bceef2
LP
220 if (r != -ENOENT)
221 log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
1de4d79b
AB
222 }
223
72bca11b
LP
224#endif
225
72bca11b
LP
226 if (!variables[VARIABLE_LANG]) {
227 if (!(variables[VARIABLE_LANG] = strdup("C"))) {
228 r = -ENOMEM;
229 goto finish;
230 }
231 }
232
233 for (i = 0; i < _VARIABLE_MAX; i++) {
234
8780d48d
LP
235 if (variables[i]) {
236 if (setenv(variable_names[i], variables[i], 1) < 0) {
237 r = -errno;
238 goto finish;
239 }
240 } else
241 unsetenv(variable_names[i]);
72bca11b 242 }
8780d48d 243
72bca11b
LP
244 r = 0;
245
246finish:
247 for (i = 0; i < _VARIABLE_MAX; i++)
248 free(variables[i]);
249
250 return r;
251}