| File: | build-scan/../src/locale/keymap-util.c |
| Warning: | line 628, column 21 Array access (from variable 'a') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <errno(*__errno_location ()).h> | |||
| 4 | #include <stdio_ext.h> | |||
| 5 | #include <string.h> | |||
| 6 | #include <unistd.h> | |||
| 7 | ||||
| 8 | #include "def.h" | |||
| 9 | #include "env-util.h" | |||
| 10 | #include "fd-util.h" | |||
| 11 | #include "fileio-label.h" | |||
| 12 | #include "fileio.h" | |||
| 13 | #include "keymap-util.h" | |||
| 14 | #include "locale-util.h" | |||
| 15 | #include "macro.h" | |||
| 16 | #include "mkdir.h" | |||
| 17 | #include "string-util.h" | |||
| 18 | #include "strv.h" | |||
| 19 | ||||
| 20 | static bool_Bool startswith_comma(const char *s, const char *prefix) { | |||
| 21 | s = startswith(s, prefix); | |||
| 22 | if (!s) | |||
| 23 | return false0; | |||
| 24 | ||||
| 25 | return IN_SET(*s, ',', '\0')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){',', '\0'})/sizeof(int)]; switch(*s) { case ',': case '\0': _found = 1; break; default: break; } _found; }); | |||
| 26 | } | |||
| 27 | ||||
| 28 | static const char* strnulldash(const char *s) { | |||
| 29 | return isempty(s) || streq(s, "-")(strcmp((s),("-")) == 0) ? NULL((void*)0) : s; | |||
| 30 | } | |||
| 31 | ||||
| 32 | static const char* systemd_kbd_model_map(void) { | |||
| 33 | const char* s; | |||
| 34 | ||||
| 35 | s = getenv("SYSTEMD_KBD_MODEL_MAP"); | |||
| 36 | if (s) | |||
| 37 | return s; | |||
| 38 | ||||
| 39 | return SYSTEMD_KBD_MODEL_MAP"/usr/share/systemd/kbd-model-map"; | |||
| 40 | } | |||
| 41 | ||||
| 42 | static const char* systemd_language_fallback_map(void) { | |||
| 43 | const char* s; | |||
| 44 | ||||
| 45 | s = getenv("SYSTEMD_LANGUAGE_FALLBACK_MAP"); | |||
| 46 | if (s) | |||
| 47 | return s; | |||
| 48 | ||||
| 49 | return SYSTEMD_LANGUAGE_FALLBACK_MAP"/usr/share/systemd/language-fallback-map"; | |||
| 50 | } | |||
| 51 | ||||
| 52 | static void context_free_x11(Context *c) { | |||
| 53 | c->x11_layout = mfree(c->x11_layout); | |||
| 54 | c->x11_options = mfree(c->x11_options); | |||
| 55 | c->x11_model = mfree(c->x11_model); | |||
| 56 | c->x11_variant = mfree(c->x11_variant); | |||
| 57 | } | |||
| 58 | ||||
| 59 | static void context_free_vconsole(Context *c) { | |||
| 60 | c->vc_keymap = mfree(c->vc_keymap); | |||
| 61 | c->vc_keymap_toggle = mfree(c->vc_keymap_toggle); | |||
| 62 | } | |||
| 63 | ||||
| 64 | static void context_free_locale(Context *c) { | |||
| 65 | int p; | |||
| 66 | ||||
| 67 | for (p = 0; p < _VARIABLE_LC_MAX; p++) | |||
| 68 | c->locale[p] = mfree(c->locale[p]); | |||
| 69 | } | |||
| 70 | ||||
| 71 | void context_free(Context *c) { | |||
| 72 | context_free_locale(c); | |||
| 73 | context_free_x11(c); | |||
| 74 | context_free_vconsole(c); | |||
| 75 | }; | |||
| 76 | ||||
| 77 | void locale_simplify(char *locale[_VARIABLE_LC_MAX]) { | |||
| 78 | int p; | |||
| 79 | ||||
| 80 | for (p = VARIABLE_LANG+1; p < _VARIABLE_LC_MAX; p++) | |||
| 81 | if (isempty(locale[p]) || streq_ptr(locale[VARIABLE_LANG], locale[p])) | |||
| 82 | locale[p] = mfree(locale[p]); | |||
| 83 | } | |||
| 84 | ||||
| 85 | int locale_read_data(Context *c, sd_bus_message *m) { | |||
| 86 | struct stat st; | |||
| 87 | int r; | |||
| 88 | ||||
| 89 | /* Do not try to re-read the file within single bus operation. */ | |||
| 90 | if (m && m == c->locale_cache) | |||
| 91 | return 0; | |||
| 92 | ||||
| 93 | /* To suppress multiple call of stat(), store the message to cache here. */ | |||
| 94 | c->locale_cache = m; | |||
| 95 | ||||
| 96 | r = stat("/etc/locale.conf", &st); | |||
| 97 | if (r < 0 && errno(*__errno_location ()) != ENOENT2) | |||
| 98 | return -errno(*__errno_location ()); | |||
| 99 | ||||
| 100 | if (r >= 0) { | |||
| 101 | usec_t t; | |||
| 102 | ||||
| 103 | /* If mtime is not changed, then we do not need to re-read the file. */ | |||
| 104 | t = timespec_load(&st.st_mtim); | |||
| 105 | if (c->locale_mtime != USEC_INFINITY((usec_t) -1) && t == c->locale_mtime) | |||
| 106 | return 0; | |||
| 107 | ||||
| 108 | c->locale_mtime = t; | |||
| 109 | context_free_locale(c); | |||
| 110 | ||||
| 111 | r = parse_env_file(NULL((void*)0), "/etc/locale.conf", NEWLINE"\n\r", | |||
| 112 | "LANG", &c->locale[VARIABLE_LANG], | |||
| 113 | "LANGUAGE", &c->locale[VARIABLE_LANGUAGE], | |||
| 114 | "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE], | |||
| 115 | "LC_NUMERIC", &c->locale[VARIABLE_LC_NUMERIC], | |||
| 116 | "LC_TIME", &c->locale[VARIABLE_LC_TIME], | |||
| 117 | "LC_COLLATE", &c->locale[VARIABLE_LC_COLLATE], | |||
| 118 | "LC_MONETARY", &c->locale[VARIABLE_LC_MONETARY], | |||
| 119 | "LC_MESSAGES", &c->locale[VARIABLE_LC_MESSAGES], | |||
| 120 | "LC_PAPER", &c->locale[VARIABLE_LC_PAPER], | |||
| 121 | "LC_NAME", &c->locale[VARIABLE_LC_NAME], | |||
| 122 | "LC_ADDRESS", &c->locale[VARIABLE_LC_ADDRESS], | |||
| 123 | "LC_TELEPHONE", &c->locale[VARIABLE_LC_TELEPHONE], | |||
| 124 | "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT], | |||
| 125 | "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION], | |||
| 126 | NULL((void*)0)); | |||
| 127 | if (r < 0) | |||
| 128 | return r; | |||
| 129 | } else { | |||
| 130 | int p; | |||
| 131 | ||||
| 132 | c->locale_mtime = USEC_INFINITY((usec_t) -1); | |||
| 133 | context_free_locale(c); | |||
| 134 | ||||
| 135 | /* Fill in what we got passed from systemd. */ | |||
| 136 | for (p = 0; p < _VARIABLE_LC_MAX; p++) { | |||
| 137 | const char *name; | |||
| 138 | ||||
| 139 | name = locale_variable_to_string(p); | |||
| 140 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/locale/keymap-util.c", 140 , __PRETTY_FUNCTION__); } while (0); | |||
| 141 | ||||
| 142 | r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name))); | |||
| 143 | if (r < 0) | |||
| 144 | return r; | |||
| 145 | } | |||
| 146 | } | |||
| 147 | ||||
| 148 | locale_simplify(c->locale); | |||
| 149 | return 0; | |||
| 150 | } | |||
| 151 | ||||
| 152 | int vconsole_read_data(Context *c, sd_bus_message *m) { | |||
| 153 | struct stat st; | |||
| 154 | usec_t t; | |||
| 155 | int r; | |||
| 156 | ||||
| 157 | /* Do not try to re-read the file within single bus operation. */ | |||
| 158 | if (m && m == c->vc_cache) | |||
| 159 | return 0; | |||
| 160 | ||||
| 161 | /* To suppress multiple call of stat(), store the message to cache here. */ | |||
| 162 | c->vc_cache = m; | |||
| 163 | ||||
| 164 | if (stat("/etc/vconsole.conf", &st) < 0) { | |||
| 165 | if (errno(*__errno_location ()) != ENOENT2) | |||
| 166 | return -errno(*__errno_location ()); | |||
| 167 | ||||
| 168 | c->vc_mtime = USEC_INFINITY((usec_t) -1); | |||
| 169 | context_free_vconsole(c); | |||
| 170 | return 0; | |||
| 171 | } | |||
| 172 | ||||
| 173 | /* If mtime is not changed, then we do not need to re-read */ | |||
| 174 | t = timespec_load(&st.st_mtim); | |||
| 175 | if (c->vc_mtime != USEC_INFINITY((usec_t) -1) && t == c->vc_mtime) | |||
| 176 | return 0; | |||
| 177 | ||||
| 178 | c->vc_mtime = t; | |||
| 179 | context_free_vconsole(c); | |||
| 180 | ||||
| 181 | r = parse_env_file(NULL((void*)0), "/etc/vconsole.conf", NEWLINE"\n\r", | |||
| 182 | "KEYMAP", &c->vc_keymap, | |||
| 183 | "KEYMAP_TOGGLE", &c->vc_keymap_toggle, | |||
| 184 | NULL((void*)0)); | |||
| 185 | if (r < 0) | |||
| 186 | return r; | |||
| 187 | ||||
| 188 | return 0; | |||
| 189 | } | |||
| 190 | ||||
| 191 | int x11_read_data(Context *c, sd_bus_message *m) { | |||
| 192 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 193 | bool_Bool in_section = false0; | |||
| 194 | char line[LINE_MAX2048]; | |||
| 195 | struct stat st; | |||
| 196 | usec_t t; | |||
| 197 | int r; | |||
| 198 | ||||
| 199 | /* Do not try to re-read the file within single bus operation. */ | |||
| 200 | if (m && m == c->x11_cache) | |||
| 201 | return 0; | |||
| 202 | ||||
| 203 | /* To suppress multiple call of stat(), store the message to cache here. */ | |||
| 204 | c->x11_cache = m; | |||
| 205 | ||||
| 206 | if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) < 0) { | |||
| 207 | if (errno(*__errno_location ()) != ENOENT2) | |||
| 208 | return -errno(*__errno_location ()); | |||
| 209 | ||||
| 210 | c->x11_mtime = USEC_INFINITY((usec_t) -1); | |||
| 211 | context_free_x11(c); | |||
| 212 | return 0; | |||
| 213 | } | |||
| 214 | ||||
| 215 | /* If mtime is not changed, then we do not need to re-read */ | |||
| 216 | t = timespec_load(&st.st_mtim); | |||
| 217 | if (c->x11_mtime != USEC_INFINITY((usec_t) -1) && t == c->x11_mtime) | |||
| 218 | return 0; | |||
| 219 | ||||
| 220 | c->x11_mtime = t; | |||
| 221 | context_free_x11(c); | |||
| 222 | ||||
| 223 | f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re"); | |||
| 224 | if (!f) | |||
| 225 | return -errno(*__errno_location ()); | |||
| 226 | ||||
| 227 | while (fgets(line, sizeof(line), f)) { | |||
| 228 | char *l; | |||
| 229 | ||||
| 230 | char_array_0(line)line[sizeof(line)-1] = 0;; | |||
| 231 | l = strstrip(line); | |||
| 232 | ||||
| 233 | if (IN_SET(l[0], 0, '#')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0, '#'})/sizeof(int)]; switch(l[0]) { case 0: case '#': _found = 1; break; default: break; } _found; })) | |||
| 234 | continue; | |||
| 235 | ||||
| 236 | if (in_section && first_word(l, "Option")) { | |||
| 237 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | |||
| 238 | ||||
| 239 | r = strv_split_extract(&a, l, WHITESPACE" \t\n\r", EXTRACT_QUOTES); | |||
| 240 | if (r < 0) | |||
| 241 | return r; | |||
| 242 | ||||
| 243 | if (strv_length(a) == 3) { | |||
| 244 | char **p = NULL((void*)0); | |||
| 245 | ||||
| 246 | if (streq(a[1], "XkbLayout")(strcmp((a[1]),("XkbLayout")) == 0)) | |||
| 247 | p = &c->x11_layout; | |||
| 248 | else if (streq(a[1], "XkbModel")(strcmp((a[1]),("XkbModel")) == 0)) | |||
| 249 | p = &c->x11_model; | |||
| 250 | else if (streq(a[1], "XkbVariant")(strcmp((a[1]),("XkbVariant")) == 0)) | |||
| 251 | p = &c->x11_variant; | |||
| 252 | else if (streq(a[1], "XkbOptions")(strcmp((a[1]),("XkbOptions")) == 0)) | |||
| 253 | p = &c->x11_options; | |||
| 254 | ||||
| 255 | if (p) { | |||
| 256 | free_and_replace(*p, a[2])({ free(*p); (*p) = (a[2]); (a[2]) = ((void*)0); 0; }); | |||
| 257 | } | |||
| 258 | } | |||
| 259 | ||||
| 260 | } else if (!in_section && first_word(l, "Section")) { | |||
| 261 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | |||
| 262 | ||||
| 263 | r = strv_split_extract(&a, l, WHITESPACE" \t\n\r", EXTRACT_QUOTES); | |||
| 264 | if (r < 0) | |||
| 265 | return -ENOMEM12; | |||
| 266 | ||||
| 267 | if (strv_length(a) == 2 && streq(a[1], "InputClass")(strcmp((a[1]),("InputClass")) == 0)) | |||
| 268 | in_section = true1; | |||
| 269 | ||||
| 270 | } else if (in_section && first_word(l, "EndSection")) | |||
| 271 | in_section = false0; | |||
| 272 | } | |||
| 273 | ||||
| 274 | return 0; | |||
| 275 | } | |||
| 276 | ||||
| 277 | int locale_write_data(Context *c, char ***settings) { | |||
| 278 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | |||
| 279 | struct stat st; | |||
| 280 | int r, p; | |||
| 281 | ||||
| 282 | /* Set values will be returned as strv in *settings on success. */ | |||
| 283 | ||||
| 284 | for (p = 0; p < _VARIABLE_LC_MAX; p++) { | |||
| 285 | _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0); | |||
| 286 | char **u; | |||
| 287 | const char *name; | |||
| 288 | ||||
| 289 | name = locale_variable_to_string(p); | |||
| 290 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/locale/keymap-util.c", 290 , __PRETTY_FUNCTION__); } while (0); | |||
| 291 | ||||
| 292 | if (isempty(c->locale[p])) | |||
| 293 | continue; | |||
| 294 | ||||
| 295 | if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0) | |||
| 296 | return -ENOMEM12; | |||
| 297 | ||||
| 298 | u = strv_env_set(l, t); | |||
| 299 | if (!u) | |||
| 300 | return -ENOMEM12; | |||
| 301 | ||||
| 302 | strv_free_and_replace(l, u)({ strv_free(l); (l) = (u); (u) = ((void*)0); 0; }); | |||
| 303 | } | |||
| 304 | ||||
| 305 | if (strv_isempty(l)) { | |||
| 306 | if (unlink("/etc/locale.conf") < 0) | |||
| 307 | return errno(*__errno_location ()) == ENOENT2 ? 0 : -errno(*__errno_location ()); | |||
| 308 | ||||
| 309 | c->locale_mtime = USEC_INFINITY((usec_t) -1); | |||
| 310 | return 0; | |||
| 311 | } | |||
| 312 | ||||
| 313 | r = write_env_file_label("/etc/locale.conf", l); | |||
| 314 | if (r < 0) | |||
| 315 | return r; | |||
| 316 | ||||
| 317 | *settings = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | |||
| 318 | ||||
| 319 | if (stat("/etc/locale.conf", &st) >= 0) | |||
| 320 | c->locale_mtime = timespec_load(&st.st_mtim); | |||
| 321 | ||||
| 322 | return 0; | |||
| 323 | } | |||
| 324 | ||||
| 325 | int vconsole_write_data(Context *c) { | |||
| 326 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | |||
| 327 | struct stat st; | |||
| 328 | int r; | |||
| 329 | ||||
| 330 | r = load_env_file(NULL((void*)0), "/etc/vconsole.conf", NULL((void*)0), &l); | |||
| 331 | if (r < 0 && r != -ENOENT2) | |||
| 332 | return r; | |||
| 333 | ||||
| 334 | if (isempty(c->vc_keymap)) | |||
| 335 | l = strv_env_unset(l, "KEYMAP"); | |||
| 336 | else { | |||
| 337 | _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0); | |||
| 338 | char **u; | |||
| 339 | ||||
| 340 | s = strappend("KEYMAP=", c->vc_keymap); | |||
| 341 | if (!s) | |||
| 342 | return -ENOMEM12; | |||
| 343 | ||||
| 344 | u = strv_env_set(l, s); | |||
| 345 | if (!u) | |||
| 346 | return -ENOMEM12; | |||
| 347 | ||||
| 348 | strv_free_and_replace(l, u)({ strv_free(l); (l) = (u); (u) = ((void*)0); 0; }); | |||
| 349 | } | |||
| 350 | ||||
| 351 | if (isempty(c->vc_keymap_toggle)) | |||
| 352 | l = strv_env_unset(l, "KEYMAP_TOGGLE"); | |||
| 353 | else { | |||
| 354 | _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0); | |||
| 355 | char **u; | |||
| 356 | ||||
| 357 | s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle); | |||
| 358 | if (!s) | |||
| 359 | return -ENOMEM12; | |||
| 360 | ||||
| 361 | u = strv_env_set(l, s); | |||
| 362 | if (!u) | |||
| 363 | return -ENOMEM12; | |||
| 364 | ||||
| 365 | strv_free_and_replace(l, u)({ strv_free(l); (l) = (u); (u) = ((void*)0); 0; }); | |||
| 366 | } | |||
| 367 | ||||
| 368 | if (strv_isempty(l)) { | |||
| 369 | if (unlink("/etc/vconsole.conf") < 0) | |||
| 370 | return errno(*__errno_location ()) == ENOENT2 ? 0 : -errno(*__errno_location ()); | |||
| 371 | ||||
| 372 | c->vc_mtime = USEC_INFINITY((usec_t) -1); | |||
| 373 | return 0; | |||
| 374 | } | |||
| 375 | ||||
| 376 | r = write_env_file_label("/etc/vconsole.conf", l); | |||
| 377 | if (r < 0) | |||
| 378 | return r; | |||
| 379 | ||||
| 380 | if (stat("/etc/vconsole.conf", &st) >= 0) | |||
| 381 | c->vc_mtime = timespec_load(&st.st_mtim); | |||
| 382 | ||||
| 383 | return 0; | |||
| 384 | } | |||
| 385 | ||||
| 386 | int x11_write_data(Context *c) { | |||
| 387 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 388 | _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0); | |||
| 389 | struct stat st; | |||
| 390 | int r; | |||
| 391 | ||||
| 392 | if (isempty(c->x11_layout) && | |||
| 393 | isempty(c->x11_model) && | |||
| 394 | isempty(c->x11_variant) && | |||
| 395 | isempty(c->x11_options)) { | |||
| 396 | ||||
| 397 | if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) | |||
| 398 | return errno(*__errno_location ()) == ENOENT2 ? 0 : -errno(*__errno_location ()); | |||
| 399 | ||||
| 400 | c->vc_mtime = USEC_INFINITY((usec_t) -1); | |||
| 401 | return 0; | |||
| 402 | } | |||
| 403 | ||||
| 404 | mkdir_p_label("/etc/X11/xorg.conf.d", 0755); | |||
| 405 | ||||
| 406 | r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path); | |||
| 407 | if (r < 0) | |||
| 408 | return r; | |||
| 409 | ||||
| 410 | (void) __fsetlocking(f, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER); | |||
| 411 | (void) fchmod(fileno(f), 0644); | |||
| 412 | ||||
| 413 | fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n" | |||
| 414 | "# probably wise not to edit this file manually. Use localectl(1) to\n" | |||
| 415 | "# instruct systemd-localed to update it.\n" | |||
| 416 | "Section \"InputClass\"\n" | |||
| 417 | " Identifier \"system-keyboard\"\n" | |||
| 418 | " MatchIsKeyboard \"on\"\n", f); | |||
| 419 | ||||
| 420 | if (!isempty(c->x11_layout)) | |||
| 421 | fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout); | |||
| 422 | ||||
| 423 | if (!isempty(c->x11_model)) | |||
| 424 | fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model); | |||
| 425 | ||||
| 426 | if (!isempty(c->x11_variant)) | |||
| 427 | fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant); | |||
| 428 | ||||
| 429 | if (!isempty(c->x11_options)) | |||
| 430 | fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options); | |||
| 431 | ||||
| 432 | fputs("EndSection\n", f); | |||
| 433 | ||||
| 434 | r = fflush_sync_and_check(f); | |||
| 435 | if (r < 0) | |||
| 436 | goto fail; | |||
| 437 | ||||
| 438 | if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) { | |||
| 439 | r = -errno(*__errno_location ()); | |||
| 440 | goto fail; | |||
| 441 | } | |||
| 442 | ||||
| 443 | if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) >= 0) | |||
| 444 | c->x11_mtime = timespec_load(&st.st_mtim); | |||
| 445 | ||||
| 446 | return 0; | |||
| 447 | ||||
| 448 | fail: | |||
| 449 | if (temp_path) | |||
| 450 | (void) unlink(temp_path); | |||
| 451 | ||||
| 452 | return r; | |||
| 453 | } | |||
| 454 | ||||
| 455 | static int read_next_mapping(const char* filename, | |||
| 456 | unsigned min_fields, unsigned max_fields, | |||
| 457 | FILE *f, unsigned *n, char ***a) { | |||
| 458 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/locale/keymap-util.c", 458 , __PRETTY_FUNCTION__); } while (0); | |||
| 459 | assert(n)do { if ((__builtin_expect(!!(!(n)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n"), "../src/locale/keymap-util.c", 459 , __PRETTY_FUNCTION__); } while (0); | |||
| 460 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/locale/keymap-util.c", 460 , __PRETTY_FUNCTION__); } while (0); | |||
| 461 | ||||
| 462 | for (;;) { | |||
| 463 | char line[LINE_MAX2048]; | |||
| 464 | char *l, **b; | |||
| 465 | int r; | |||
| 466 | size_t length; | |||
| 467 | ||||
| 468 | errno(*__errno_location ()) = 0; | |||
| 469 | if (!fgets(line, sizeof(line), f)) { | |||
| 470 | ||||
| 471 | if (ferror(f)) | |||
| 472 | return errno(*__errno_location ()) > 0 ? -errno(*__errno_location ()) : -EIO5; | |||
| 473 | ||||
| 474 | return 0; | |||
| 475 | } | |||
| 476 | ||||
| 477 | (*n)++; | |||
| 478 | ||||
| 479 | l = strstrip(line); | |||
| 480 | if (IN_SET(l[0], 0, '#')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0, '#'})/sizeof(int)]; switch(l[0]) { case 0: case '#': _found = 1; break; default: break; } _found; })) | |||
| 481 | continue; | |||
| 482 | ||||
| 483 | r = strv_split_extract(&b, l, WHITESPACE" \t\n\r", EXTRACT_QUOTES); | |||
| 484 | if (r < 0) | |||
| 485 | return r; | |||
| 486 | ||||
| 487 | length = strv_length(b); | |||
| 488 | if (length < min_fields || length > max_fields) { | |||
| 489 | log_error("Invalid line %s:%u, ignoring.", filename, *n)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 489, __func__, "Invalid line %s:%u, ignoring." , filename, *n) : -abs(_e); }); | |||
| 490 | strv_free(b); | |||
| 491 | continue; | |||
| 492 | ||||
| 493 | } | |||
| 494 | ||||
| 495 | *a = b; | |||
| 496 | return 1; | |||
| 497 | } | |||
| 498 | } | |||
| 499 | ||||
| 500 | int vconsole_convert_to_x11(Context *c) { | |||
| 501 | const char *map; | |||
| 502 | int modified = -1; | |||
| 503 | ||||
| 504 | map = systemd_kbd_model_map(); | |||
| 505 | ||||
| 506 | if (isempty(c->vc_keymap)) { | |||
| 507 | modified = | |||
| 508 | !isempty(c->x11_layout) || | |||
| 509 | !isempty(c->x11_model) || | |||
| 510 | !isempty(c->x11_variant) || | |||
| 511 | !isempty(c->x11_options); | |||
| 512 | ||||
| 513 | context_free_x11(c); | |||
| 514 | } else { | |||
| 515 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 516 | unsigned n = 0; | |||
| 517 | ||||
| 518 | f = fopen(map, "re"); | |||
| 519 | if (!f) | |||
| 520 | return -errno(*__errno_location ()); | |||
| 521 | ||||
| 522 | for (;;) { | |||
| 523 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | |||
| 524 | int r; | |||
| 525 | ||||
| 526 | r = read_next_mapping(map, 5, UINT_MAX(2147483647 *2U +1U), f, &n, &a); | |||
| 527 | if (r < 0) | |||
| 528 | return r; | |||
| 529 | if (r == 0) | |||
| 530 | break; | |||
| 531 | ||||
| 532 | if (!streq(c->vc_keymap, a[0])(strcmp((c->vc_keymap),(a[0])) == 0)) | |||
| 533 | continue; | |||
| 534 | ||||
| 535 | if (!streq_ptr(c->x11_layout, strnulldash(a[1])) || | |||
| 536 | !streq_ptr(c->x11_model, strnulldash(a[2])) || | |||
| 537 | !streq_ptr(c->x11_variant, strnulldash(a[3])) || | |||
| 538 | !streq_ptr(c->x11_options, strnulldash(a[4]))) { | |||
| 539 | ||||
| 540 | if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 || | |||
| 541 | free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 || | |||
| 542 | free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 || | |||
| 543 | free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0) | |||
| 544 | return -ENOMEM12; | |||
| 545 | ||||
| 546 | modified = true1; | |||
| 547 | } | |||
| 548 | ||||
| 549 | break; | |||
| 550 | } | |||
| 551 | } | |||
| 552 | ||||
| 553 | if (modified > 0) | |||
| 554 | log_info("Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 558, __func__, "Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'" , strempty(c->x11_layout), strempty(c->x11_model), strempty (c->x11_variant), strempty(c->x11_options)) : -abs(_e); }) | |||
| 555 | strempty(c->x11_layout),({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 558, __func__, "Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'" , strempty(c->x11_layout), strempty(c->x11_model), strempty (c->x11_variant), strempty(c->x11_options)) : -abs(_e); }) | |||
| 556 | strempty(c->x11_model),({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 558, __func__, "Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'" , strempty(c->x11_layout), strempty(c->x11_model), strempty (c->x11_variant), strempty(c->x11_options)) : -abs(_e); }) | |||
| 557 | strempty(c->x11_variant),({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 558, __func__, "Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'" , strempty(c->x11_layout), strempty(c->x11_model), strempty (c->x11_variant), strempty(c->x11_options)) : -abs(_e); }) | |||
| 558 | strempty(c->x11_options))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 558, __func__, "Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'" , strempty(c->x11_layout), strempty(c->x11_model), strempty (c->x11_variant), strempty(c->x11_options)) : -abs(_e); }); | |||
| 559 | else if (modified < 0) | |||
| 560 | log_notice("X11 keyboard layout was not modified: no conversion found for \"%s\".",({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 561, __func__, "X11 keyboard layout was not modified: no conversion found for \"%s\"." , c->vc_keymap) : -abs(_e); }) | |||
| 561 | c->vc_keymap)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 561, __func__, "X11 keyboard layout was not modified: no conversion found for \"%s\"." , c->vc_keymap) : -abs(_e); }); | |||
| 562 | else | |||
| 563 | log_debug("X11 keyboard layout did not need to be modified.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 563, __func__, "X11 keyboard layout did not need to be modified." ) : -abs(_e); }); | |||
| 564 | ||||
| 565 | return modified > 0; | |||
| 566 | } | |||
| 567 | ||||
| 568 | int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap) { | |||
| 569 | const char *dir; | |||
| 570 | _cleanup_free___attribute__((cleanup(freep))) char *n; | |||
| 571 | ||||
| 572 | if (x11_variant) | |||
| 573 | n = strjoin(x11_layout, "-", x11_variant)strjoin_real((x11_layout), "-", x11_variant, ((void*)0)); | |||
| 574 | else | |||
| 575 | n = strdup(x11_layout); | |||
| 576 | if (!n) | |||
| 577 | return -ENOMEM12; | |||
| 578 | ||||
| 579 | NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)for ((dir) = ("/usr/share/keymaps/\0" "/usr/share/kbd/keymaps/\0" "/usr/lib/kbd/keymaps/\0"); (dir) && *(dir); (dir) = strchr((dir), 0)+1) { | |||
| 580 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *pz = NULL((void*)0); | |||
| 581 | bool_Bool uncompressed; | |||
| 582 | ||||
| 583 | p = strjoin(dir, "xkb/", n, ".map")strjoin_real((dir), "xkb/", n, ".map", ((void*)0)); | |||
| 584 | pz = strjoin(dir, "xkb/", n, ".map.gz")strjoin_real((dir), "xkb/", n, ".map.gz", ((void*)0)); | |||
| 585 | if (!p || !pz) | |||
| 586 | return -ENOMEM12; | |||
| 587 | ||||
| 588 | uncompressed = access(p, F_OK0) == 0; | |||
| 589 | if (uncompressed || access(pz, F_OK0) == 0) { | |||
| 590 | log_debug("Found converted keymap %s at %s",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 591, __func__, "Found converted keymap %s at %s" , n, uncompressed ? p : pz) : -abs(_e); }) | |||
| 591 | n, uncompressed ? p : pz)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 591, __func__, "Found converted keymap %s at %s" , n, uncompressed ? p : pz) : -abs(_e); }); | |||
| 592 | ||||
| 593 | *new_keymap = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
| 594 | return 1; | |||
| 595 | } | |||
| 596 | } | |||
| 597 | ||||
| 598 | return 0; | |||
| 599 | } | |||
| 600 | ||||
| 601 | int find_legacy_keymap(Context *c, char **ret) { | |||
| 602 | const char *map; | |||
| 603 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 604 | _cleanup_free___attribute__((cleanup(freep))) char *new_keymap = NULL((void*)0); | |||
| 605 | unsigned n = 0; | |||
| 606 | unsigned best_matching = 0; | |||
| 607 | int r; | |||
| 608 | ||||
| 609 | assert(!isempty(c->x11_layout))do { if ((__builtin_expect(!!(!(!isempty(c->x11_layout))), 0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!isempty(c->x11_layout)" ), "../src/locale/keymap-util.c", 609, __PRETTY_FUNCTION__); } while (0); | |||
| 610 | ||||
| 611 | map = systemd_kbd_model_map(); | |||
| 612 | ||||
| 613 | f = fopen(map, "re"); | |||
| 614 | if (!f) | |||
| 615 | return -errno(*__errno_location ()); | |||
| 616 | ||||
| 617 | for (;;) { | |||
| 618 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | |||
| 619 | unsigned matching = 0; | |||
| 620 | ||||
| 621 | r = read_next_mapping(map, 5, UINT_MAX(2147483647 *2U +1U), f, &n, &a); | |||
| 622 | if (r < 0) | |||
| 623 | return r; | |||
| 624 | if (r == 0) | |||
| 625 | break; | |||
| 626 | ||||
| 627 | /* Determine how well matching this entry is */ | |||
| 628 | if (streq(c->x11_layout, a[1])(strcmp((c->x11_layout),(a[1])) == 0)) | |||
| ||||
| 629 | /* If we got an exact match, this is best */ | |||
| 630 | matching = 10; | |||
| 631 | else { | |||
| 632 | /* We have multiple X layouts, look for an | |||
| 633 | * entry that matches our key with everything | |||
| 634 | * but the first layout stripped off. */ | |||
| 635 | if (startswith_comma(c->x11_layout, a[1])) | |||
| 636 | matching = 5; | |||
| 637 | else { | |||
| 638 | char *x; | |||
| 639 | ||||
| 640 | /* If that didn't work, strip off the | |||
| 641 | * other layouts from the entry, too */ | |||
| 642 | x = strndupa(a[1], strcspn(a[1], ","))(__extension__ ({ const char *__old = (a[1]); size_t __len = strnlen (__old, (strcspn(a[1], ","))); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old , __len); })); | |||
| 643 | if (startswith_comma(c->x11_layout, x)) | |||
| 644 | matching = 1; | |||
| 645 | } | |||
| 646 | } | |||
| 647 | ||||
| 648 | if (matching > 0) { | |||
| 649 | if (isempty(c->x11_model) || streq_ptr(c->x11_model, a[2])) { | |||
| 650 | matching++; | |||
| 651 | ||||
| 652 | if (streq_ptr(c->x11_variant, a[3])) { | |||
| 653 | matching++; | |||
| 654 | ||||
| 655 | if (streq_ptr(c->x11_options, a[4])) | |||
| 656 | matching++; | |||
| 657 | } | |||
| 658 | } | |||
| 659 | } | |||
| 660 | ||||
| 661 | /* The best matching entry so far, then let's save that */ | |||
| 662 | if (matching >= MAX(best_matching, 1u)__extension__ ({ const typeof((best_matching)) __unique_prefix_A2 = ((best_matching)); const typeof((1u)) __unique_prefix_B3 = ((1u)); __unique_prefix_A2 > __unique_prefix_B3 ? __unique_prefix_A2 : __unique_prefix_B3; })) { | |||
| 663 | log_debug("Found legacy keymap %s with score %u",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 664, __func__, "Found legacy keymap %s with score %u" , a[0], matching) : -abs(_e); }) | |||
| 664 | a[0], matching)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 664, __func__, "Found legacy keymap %s with score %u" , a[0], matching) : -abs(_e); }); | |||
| 665 | ||||
| 666 | if (matching > best_matching) { | |||
| 667 | best_matching = matching; | |||
| 668 | ||||
| 669 | r = free_and_strdup(&new_keymap, a[0]); | |||
| 670 | if (r < 0) | |||
| 671 | return r; | |||
| 672 | } | |||
| 673 | } | |||
| 674 | } | |||
| 675 | ||||
| 676 | if (best_matching < 10 && c->x11_layout) { | |||
| 677 | /* The best match is only the first part of the X11 | |||
| 678 | * keymap. Check if we have a converted map which | |||
| 679 | * matches just the first layout. | |||
| 680 | */ | |||
| 681 | char *l, *v = NULL((void*)0), *converted; | |||
| 682 | ||||
| 683 | l = strndupa(c->x11_layout, strcspn(c->x11_layout, ","))(__extension__ ({ const char *__old = (c->x11_layout); size_t __len = strnlen (__old, (strcspn(c->x11_layout, ","))); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len); })); | |||
| 684 | if (c->x11_variant) | |||
| 685 | v = strndupa(c->x11_variant, strcspn(c->x11_variant, ","))(__extension__ ({ const char *__old = (c->x11_variant); size_t __len = strnlen (__old, (strcspn(c->x11_variant, ","))); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len); })); | |||
| 686 | r = find_converted_keymap(l, v, &converted); | |||
| 687 | if (r < 0) | |||
| 688 | return r; | |||
| 689 | if (r > 0) | |||
| 690 | free_and_replace(new_keymap, converted)({ free(new_keymap); (new_keymap) = (converted); (converted) = ((void*)0); 0; }); | |||
| 691 | } | |||
| 692 | ||||
| 693 | *ret = TAKE_PTR(new_keymap)({ typeof(new_keymap) _ptr_ = (new_keymap); (new_keymap) = (( void*)0); _ptr_; }); | |||
| 694 | return (bool_Bool) *ret; | |||
| 695 | } | |||
| 696 | ||||
| 697 | int find_language_fallback(const char *lang, char **language) { | |||
| 698 | const char *map; | |||
| 699 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 700 | unsigned n = 0; | |||
| 701 | ||||
| 702 | assert(lang)do { if ((__builtin_expect(!!(!(lang)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lang"), "../src/locale/keymap-util.c", 702 , __PRETTY_FUNCTION__); } while (0); | |||
| 703 | assert(language)do { if ((__builtin_expect(!!(!(language)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("language"), "../src/locale/keymap-util.c" , 703, __PRETTY_FUNCTION__); } while (0); | |||
| 704 | ||||
| 705 | map = systemd_language_fallback_map(); | |||
| 706 | ||||
| 707 | f = fopen(map, "re"); | |||
| 708 | if (!f) | |||
| 709 | return -errno(*__errno_location ()); | |||
| 710 | ||||
| 711 | for (;;) { | |||
| 712 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | |||
| 713 | int r; | |||
| 714 | ||||
| 715 | r = read_next_mapping(map, 2, 2, f, &n, &a); | |||
| 716 | if (r <= 0) | |||
| 717 | return r; | |||
| 718 | ||||
| 719 | if (streq(lang, a[0])(strcmp((lang),(a[0])) == 0)) { | |||
| 720 | assert(strv_length(a) == 2)do { if ((__builtin_expect(!!(!(strv_length(a) == 2)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("strv_length(a) == 2"), "../src/locale/keymap-util.c" , 720, __PRETTY_FUNCTION__); } while (0); | |||
| 721 | *language = TAKE_PTR(a[1])({ typeof(a[1]) _ptr_ = (a[1]); (a[1]) = ((void*)0); _ptr_; } ); | |||
| 722 | return 1; | |||
| 723 | } | |||
| 724 | } | |||
| 725 | ||||
| 726 | assert_not_reached("should not be here")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "should not be here"), "../src/locale/keymap-util.c", 726, __PRETTY_FUNCTION__ ); } while (0); | |||
| 727 | } | |||
| 728 | ||||
| 729 | int x11_convert_to_vconsole(Context *c) { | |||
| 730 | bool_Bool modified = false0; | |||
| 731 | ||||
| 732 | if (isempty(c->x11_layout)) { | |||
| ||||
| 733 | modified = | |||
| 734 | !isempty(c->vc_keymap) || | |||
| 735 | !isempty(c->vc_keymap_toggle); | |||
| 736 | ||||
| 737 | context_free_vconsole(c); | |||
| 738 | } else { | |||
| 739 | _cleanup_free___attribute__((cleanup(freep))) char *new_keymap = NULL((void*)0); | |||
| 740 | int r; | |||
| 741 | ||||
| 742 | r = find_converted_keymap(c->x11_layout, c->x11_variant, &new_keymap); | |||
| 743 | if (r < 0) | |||
| 744 | return r; | |||
| 745 | else if (r == 0) { | |||
| 746 | r = find_legacy_keymap(c, &new_keymap); | |||
| 747 | if (r < 0) | |||
| 748 | return r; | |||
| 749 | } | |||
| 750 | if (r == 0) | |||
| 751 | /* We search for layout-variant match first, but then we also look | |||
| 752 | * for anything which matches just the layout. So it's accurate to say | |||
| 753 | * that we couldn't find anything which matches the layout. */ | |||
| 754 | log_notice("No conversion to virtual console map found for \"%s\".",({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 755, __func__, "No conversion to virtual console map found for \"%s\"." , c->x11_layout) : -abs(_e); }) | |||
| 755 | c->x11_layout)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 755, __func__, "No conversion to virtual console map found for \"%s\"." , c->x11_layout) : -abs(_e); }); | |||
| 756 | ||||
| 757 | if (!streq_ptr(c->vc_keymap, new_keymap)) { | |||
| 758 | free_and_replace(c->vc_keymap, new_keymap)({ free(c->vc_keymap); (c->vc_keymap) = (new_keymap); ( new_keymap) = ((void*)0); 0; }); | |||
| 759 | c->vc_keymap_toggle = mfree(c->vc_keymap_toggle); | |||
| 760 | modified = true1; | |||
| 761 | } | |||
| 762 | } | |||
| 763 | ||||
| 764 | if (modified) | |||
| 765 | log_info("Changing virtual console keymap to '%s' toggle '%s'",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 766, __func__, "Changing virtual console keymap to '%s' toggle '%s'" , strempty(c->vc_keymap), strempty(c->vc_keymap_toggle) ) : -abs(_e); }) | |||
| 766 | strempty(c->vc_keymap), strempty(c->vc_keymap_toggle))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 766, __func__, "Changing virtual console keymap to '%s' toggle '%s'" , strempty(c->vc_keymap), strempty(c->vc_keymap_toggle) ) : -abs(_e); }); | |||
| 767 | else | |||
| 768 | log_debug("Virtual console keymap was not modified.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/locale/keymap-util.c", 768, __func__, "Virtual console keymap was not modified." ) : -abs(_e); }); | |||
| 769 | ||||
| 770 | return modified; | |||
| 771 | } |