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