]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
72bca11b | 2 | |
72bca11b | 3 | #include <errno.h> |
07630cea | 4 | #include <stdlib.h> |
dccca82b | 5 | #include <string.h> |
72bca11b | 6 | |
686d13b9 | 7 | #include "env-file.h" |
bcd8e6d1 | 8 | #include "env-util.h" |
cf0fbc49 | 9 | #include "locale-setup.h" |
a3428668 | 10 | #include "locale-util.h" |
cd45734f | 11 | #include "proc-cmdline.h" |
07630cea LP |
12 | #include "string-util.h" |
13 | #include "strv.h" | |
14 | #include "util.h" | |
15 | #include "virt.h" | |
72bca11b | 16 | |
e21fea24 | 17 | int locale_setup(char ***environment) { |
e6755a33 | 18 | _cleanup_(locale_variables_freep) char *variables[_VARIABLE_LC_MAX] = {}; |
05e062cb | 19 | _cleanup_strv_free_ char **add = NULL; |
6176be15 | 20 | LocaleVariable i; |
cd45734f | 21 | int r; |
72bca11b | 22 | |
cd45734f LP |
23 | r = proc_cmdline_get_key_many(PROC_CMDLINE_STRIP_RD_PREFIX, |
24 | "locale.LANG", &variables[VARIABLE_LANG], | |
25 | "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], | |
26 | "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], | |
27 | "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], | |
28 | "locale.LC_TIME", &variables[VARIABLE_LC_TIME], | |
29 | "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], | |
30 | "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], | |
31 | "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], | |
32 | "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], | |
33 | "locale.LC_NAME", &variables[VARIABLE_LC_NAME], | |
34 | "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], | |
35 | "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], | |
36 | "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], | |
37 | "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); | |
38 | if (r < 0 && r != -ENOENT) | |
39 | log_warning_errno(r, "Failed to read /proc/cmdline: %m"); | |
39d99a07 | 40 | |
cd45734f | 41 | /* Hmm, nothing set on the kernel cmd line? Then let's try /etc/locale.conf */ |
39d99a07 | 42 | if (r <= 0) { |
aa8fbc74 | 43 | r = parse_env_file(NULL, "/etc/locale.conf", |
39d99a07 LP |
44 | "LANG", &variables[VARIABLE_LANG], |
45 | "LANGUAGE", &variables[VARIABLE_LANGUAGE], | |
46 | "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], | |
47 | "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], | |
48 | "LC_TIME", &variables[VARIABLE_LC_TIME], | |
49 | "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], | |
50 | "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], | |
51 | "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], | |
52 | "LC_PAPER", &variables[VARIABLE_LC_PAPER], | |
53 | "LC_NAME", &variables[VARIABLE_LC_NAME], | |
54 | "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], | |
55 | "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], | |
56 | "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], | |
13df9c39 | 57 | "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); |
39d99a07 | 58 | if (r < 0 && r != -ENOENT) |
da927ba9 | 59 | log_warning_errno(r, "Failed to read /etc/locale.conf: %m"); |
ce8a6aa1 LP |
60 | } |
61 | ||
a3428668 | 62 | for (i = 0; i < _VARIABLE_LC_MAX; i++) { |
bcd8e6d1 LP |
63 | char *s; |
64 | ||
e21fea24 KS |
65 | if (!variables[i]) |
66 | continue; | |
67 | ||
605405c6 | 68 | s = strjoin(locale_variable_to_string(i), "=", variables[i]); |
e6755a33 LP |
69 | if (!s) |
70 | return -ENOMEM; | |
bcd8e6d1 | 71 | |
e6755a33 LP |
72 | if (strv_consume(&add, s) < 0) |
73 | return -ENOMEM; | |
bcd8e6d1 LP |
74 | } |
75 | ||
0db9bd20 | 76 | if (strv_isempty(add)) { |
8ca9e92c | 77 | /* If no locale is configured then default to compile-time default. */ |
bcd8e6d1 | 78 | |
8ca9e92c | 79 | add = strv_new("LANG=" SYSTEMD_DEFAULT_LOCALE); |
e6755a33 LP |
80 | if (!add) |
81 | return -ENOMEM; | |
0db9bd20 LP |
82 | } |
83 | ||
84 | if (strv_isempty(*environment)) | |
85 | strv_free_and_replace(*environment, add); | |
86 | else { | |
87 | char **merged; | |
88 | ||
89 | merged = strv_env_merge(2, *environment, add); | |
e6755a33 LP |
90 | if (!merged) |
91 | return -ENOMEM; | |
e21fea24 | 92 | |
0db9bd20 | 93 | strv_free_and_replace(*environment, merged); |
72bca11b | 94 | } |
8780d48d | 95 | |
e6755a33 | 96 | return 0; |
72bca11b | 97 | } |