]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/locale-setup.c
honor SELinux labels, when creating and writing config files
[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"
72bca11b
LP
31
32enum {
97e3d13f
LP
33 /* We don't list LC_ALL here on purpose. People should be
34 * using LANG instead. */
35
72bca11b 36 VARIABLE_LANG,
07bceef2 37 VARIABLE_LANGUAGE,
72bca11b
LP
38 VARIABLE_LC_CTYPE,
39 VARIABLE_LC_NUMERIC,
40 VARIABLE_LC_TIME,
41 VARIABLE_LC_COLLATE,
42 VARIABLE_LC_MONETARY,
43 VARIABLE_LC_MESSAGES,
72bca11b
LP
44 VARIABLE_LC_PAPER,
45 VARIABLE_LC_NAME,
46 VARIABLE_LC_ADDRESS,
47 VARIABLE_LC_TELEPHONE,
48 VARIABLE_LC_MEASUREMENT,
49 VARIABLE_LC_IDENTIFICATION,
50 _VARIABLE_MAX
51};
52
53static const char * const variable_names[_VARIABLE_MAX] = {
54 [VARIABLE_LANG] = "LANG",
07bceef2 55 [VARIABLE_LANGUAGE] = "LANGUAGE",
72bca11b
LP
56 [VARIABLE_LC_CTYPE] = "LC_CTYPE",
57 [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
e624abf7
LP
58 [VARIABLE_LC_TIME] = "LC_TIME",
59 [VARIABLE_LC_COLLATE] = "LC_COLLATE",
60 [VARIABLE_LC_MONETARY] = "LC_MONETARY",
08a67ac4 61 [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
e624abf7
LP
62 [VARIABLE_LC_PAPER] = "LC_PAPER",
63 [VARIABLE_LC_NAME] = "LC_NAME",
64 [VARIABLE_LC_ADDRESS] = "LC_ADDRESS",
65 [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
66 [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
67 [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
72bca11b
LP
68};
69
70int locale_setup(void) {
71 char *variables[_VARIABLE_MAX];
d885ac66 72 int r = 0, i;
72bca11b
LP
73
74 zero(variables);
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 if (!variables[VARIABLE_LANG]) {
39d99a07
LP
123 variables[VARIABLE_LANG] = strdup("C");
124 if (!variables[VARIABLE_LANG]) {
72bca11b
LP
125 r = -ENOMEM;
126 goto finish;
127 }
128 }
129
130 for (i = 0; i < _VARIABLE_MAX; i++) {
8780d48d
LP
131 if (variables[i]) {
132 if (setenv(variable_names[i], variables[i], 1) < 0) {
133 r = -errno;
134 goto finish;
135 }
136 } else
137 unsetenv(variable_names[i]);
72bca11b 138 }
8780d48d 139
72bca11b
LP
140 r = 0;
141
142finish:
143 for (i = 0; i < _VARIABLE_MAX; i++)
144 free(variables[i]);
145
146 return r;
147}