]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/locale-setup.c
fileio: make parse_env_file() return number of parsed items
[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"
a5c32cff 30#include "fileio.h"
e21fea24 31#include "strv.h"
bcd8e6d1 32#include "env-util.h"
72bca11b
LP
33
34enum {
97e3d13f
LP
35 /* We don't list LC_ALL here on purpose. People should be
36 * using LANG instead. */
37
72bca11b 38 VARIABLE_LANG,
07bceef2 39 VARIABLE_LANGUAGE,
72bca11b
LP
40 VARIABLE_LC_CTYPE,
41 VARIABLE_LC_NUMERIC,
42 VARIABLE_LC_TIME,
43 VARIABLE_LC_COLLATE,
44 VARIABLE_LC_MONETARY,
45 VARIABLE_LC_MESSAGES,
72bca11b
LP
46 VARIABLE_LC_PAPER,
47 VARIABLE_LC_NAME,
48 VARIABLE_LC_ADDRESS,
49 VARIABLE_LC_TELEPHONE,
50 VARIABLE_LC_MEASUREMENT,
51 VARIABLE_LC_IDENTIFICATION,
52 _VARIABLE_MAX
53};
54
55static const char * const variable_names[_VARIABLE_MAX] = {
56 [VARIABLE_LANG] = "LANG",
07bceef2 57 [VARIABLE_LANGUAGE] = "LANGUAGE",
72bca11b
LP
58 [VARIABLE_LC_CTYPE] = "LC_CTYPE",
59 [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
e624abf7
LP
60 [VARIABLE_LC_TIME] = "LC_TIME",
61 [VARIABLE_LC_COLLATE] = "LC_COLLATE",
62 [VARIABLE_LC_MONETARY] = "LC_MONETARY",
08a67ac4 63 [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
e624abf7
LP
64 [VARIABLE_LC_PAPER] = "LC_PAPER",
65 [VARIABLE_LC_NAME] = "LC_NAME",
66 [VARIABLE_LC_ADDRESS] = "LC_ADDRESS",
67 [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
68 [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
69 [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
72bca11b
LP
70};
71
e21fea24 72int locale_setup(char ***environment) {
bcd8e6d1 73 char **add;
b92bea5d 74 char *variables[_VARIABLE_MAX] = {};
d885ac66 75 int r = 0, i;
72bca11b 76
39d99a07
LP
77 if (detect_container(NULL) <= 0) {
78 r = parse_env_file("/proc/cmdline", WHITESPACE,
39d99a07
LP
79 "locale.LANG", &variables[VARIABLE_LANG],
80 "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
81 "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
82 "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
83 "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
84 "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
85 "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
86 "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
87 "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
88 "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
89 "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
90 "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
91 "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
92 "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
93 NULL);
94
95 if (r < 0 && r != -ENOENT)
96 log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
97 }
ce8a6aa1
LP
98
99 /* Hmm, nothing set on the kernel cmd line? Then let's
fd5bf055 100 * try /etc/locale.conf */
39d99a07
LP
101 if (r <= 0) {
102 r = parse_env_file("/etc/locale.conf", NEWLINE,
103 "LANG", &variables[VARIABLE_LANG],
104 "LANGUAGE", &variables[VARIABLE_LANGUAGE],
105 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
106 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
107 "LC_TIME", &variables[VARIABLE_LC_TIME],
108 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
109 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
110 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
111 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
112 "LC_NAME", &variables[VARIABLE_LC_NAME],
113 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
114 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
115 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
116 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
117 NULL);
118
119 if (r < 0 && r != -ENOENT)
fd5bf055 120 log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
ce8a6aa1
LP
121 }
122
bcd8e6d1 123 add = NULL;
72bca11b 124 for (i = 0; i < _VARIABLE_MAX; i++) {
bcd8e6d1
LP
125 char *s;
126
e21fea24
KS
127 if (!variables[i])
128 continue;
129
bcd8e6d1
LP
130 s = strjoin(variable_names[i], "=", variables[i], NULL);
131 if (!s) {
132 r = -ENOMEM;
133 goto finish;
134 }
135
6e18964d 136 if (strv_consume(&add, s) < 0) {
bcd8e6d1
LP
137 r = -ENOMEM;
138 goto finish;
139 }
140 }
141
142 if (!strv_isempty(add)) {
143 char **e;
144
145 e = strv_env_merge(2, *environment, add);
146 if (!e) {
e21fea24
KS
147 r = -ENOMEM;
148 goto finish;
149 }
150
bcd8e6d1
LP
151 strv_free(*environment);
152 *environment = e;
72bca11b 153 }
8780d48d 154
72bca11b
LP
155 r = 0;
156
157finish:
bcd8e6d1
LP
158 strv_free(add);
159
72bca11b
LP
160 for (i = 0; i < _VARIABLE_MAX; i++)
161 free(variables[i]);
162
163 return r;
164}