chiark / gitweb /
parse_env_file() - return empty value strings like FOO="" as NULL value
[elogind.git] / src / vconsole-setup.c
index cb8fc43d2f43b98ee947e49aa003335f69745f22..7703361e33ef6029f372a04006d1806fe989a452 100644 (file)
@@ -40,7 +40,7 @@
 #include "log.h"
 #include "macro.h"
 
 #include "log.h"
 #include "macro.h"
 
-static bool is_console(int fd) {
+static bool is_vconsole(int fd) {
         unsigned char data[1];
 
         data[0] = TIOCL_GETFGCONSOLE;
         unsigned char data[1];
 
         data[0] = TIOCL_GETFGCONSOLE;
@@ -83,7 +83,7 @@ static int load_keymap(const char *vc, const char *map, bool utf8, pid_t *_pid)
         int i = 0;
         pid_t pid;
 
         int i = 0;
         pid_t pid;
 
-        args[i++] = "/bin/loadkeys";
+        args[i++] = KBD_LOADKEYS;
         args[i++] = "-q";
         args[i++] = "-C";
         args[i++] = vc;
         args[i++] = "-q";
         args[i++] = "-C";
         args[i++] = vc;
@@ -109,7 +109,7 @@ static int load_font(const char *vc, const char *font, const char *map, const ch
         int i = 0;
         pid_t pid;
 
         int i = 0;
         pid_t pid;
 
-        args[i++] = "/bin/setfont";
+        args[i++] = KBD_SETFONT;
         args[i++] = "-C";
         args[i++] = vc;
         args[i++] = font;
         args[i++] = "-C";
         args[i++] = vc;
         args[i++] = font;
@@ -141,6 +141,9 @@ int main(int argc, char **argv) {
         char *vc_font = NULL;
         char *vc_font_map = NULL;
         char *vc_font_unimap = NULL;
         char *vc_font = NULL;
         char *vc_font_map = NULL;
         char *vc_font_unimap = NULL;
+#ifdef TARGET_GENTOO
+        char *vc_unicode = NULL;
+#endif
         int fd = -1;
         bool utf8;
         int r = EXIT_FAILURE;
         int fd = -1;
         bool utf8;
         int r = EXIT_FAILURE;
@@ -160,80 +163,178 @@ int main(int argc, char **argv) {
                 goto finish;
         }
 
                 goto finish;
         }
 
-        if (!is_console(fd)) {
+        if (!is_vconsole(fd)) {
                 log_error("Device %s is not a virtual console.", vc);
                 goto finish;
         }
 
                 log_error("Device %s is not a virtual console.", vc);
                 goto finish;
         }
 
-        if (!(utf8 = is_locale_utf8()))
-                disable_utf8(fd);
+        utf8 = is_locale_utf8();
 
 
+        if ((r = parse_env_file("/proc/cmdline", WHITESPACE,
 #ifdef TARGET_FEDORA
 #ifdef TARGET_FEDORA
-        if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
                                 "SYSFONT", &vc_font,
                                 "SYSFONT", &vc_font,
-                                NULL)) < 0) {
-
-                if (r != -ENOENT)
-                        log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
-        }
-
-        if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
                                 "KEYTABLE", &vc_keymap,
                                 "KEYTABLE", &vc_keymap,
+#endif
+                                "vconsole.keymap", &vc_keymap,
+                                "vconsole.font", &vc_font,
+                                "vconsole.font.map", &vc_font_map,
+                                "vconsole.font.unimap", &vc_font_unimap,
                                 NULL)) < 0) {
 
                 if (r != -ENOENT)
                                 NULL)) < 0) {
 
                 if (r != -ENOENT)
-                        log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
         }
         }
-#endif
 
 
-        /* Override distribution-specific options with the
-         * distribution-independent configuration */
-        if ((r = parse_env_file("/etc/vconsole", NEWLINE,
-                                "VCONSOLE_KEYMAP", &vc_keymap,
-                                "VCONSOLE_FONT", &vc_font,
-                                "VCONSOLE_FONT_MAP", &vc_font_map,
-                                "VCONSOLE_FONT_UNIMAP", &vc_font_unimap,
+        /* Hmm, nothing set on the kernel cmd line? Then let's
+         * try /etc/vconsole.conf */
+        if (r <= 0 &&
+            (r = parse_env_file("/etc/vconsole.conf", NEWLINE,
+                                "KEYMAP", &vc_keymap,
+                                "FONT", &vc_font,
+                                "FONT_MAP", &vc_font_map,
+                                "FONT_UNIMAP", &vc_font_unimap,
                                 NULL)) < 0) {
 
                 if (r != -ENOENT)
                                 NULL)) < 0) {
 
                 if (r != -ENOENT)
-                        log_warning("Failed to read /etc/vconsole: %s", strerror(-r));
+                        log_warning("Failed to read /etc/vconsole.conf: %s", strerror(-r));
         }
 
         }
 
-        if ((r = parse_env_file("/proc/cmdline", WHITESPACE,
+        if (r <= 0) {
 #ifdef TARGET_FEDORA
 #ifdef TARGET_FEDORA
-                                "SYSFONT", &vc_font,
-                                "KEYTABLE", &vc_keymap,
+                if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
+                                        "SYSFONT", &vc_font,
+                                        "SYSFONTACM", &vc_font_map,
+                                        "UNIMAP", &vc_font_unimap,
+                                        NULL)) < 0) {
+
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+                }
+
+                if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
+                                        "KEYTABLE", &vc_keymap,
+                                        "KEYMAP", &vc_keymap,
+                                        NULL)) < 0) {
+
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+                }
+
+                if (access("/etc/sysconfig/console/default.kmap", F_OK) >= 0) {
+                        char *t;
+
+                        if (!(t = strdup("/etc/sysconfig/console/default.kmap"))) {
+                                log_error("Out of memory.");
+                                goto finish;
+                        }
+
+                        free(vc_keymap);
+                        vc_keymap = t;
+                }
+
+#elif defined(TARGET_SUSE)
+                if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
+                                        "KEYTABLE", &vc_keymap,
+                                        NULL)) < 0) {
+
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r));
+                }
+
+                if ((r = parse_env_file("/etc/sysconfig/console", NEWLINE,
+                                        "CONSOLE_FONT", &vc_font,
+                                        "CONSOLE_SCREENMAP", &vc_font_map,
+                                        "CONSOLE_UNICODEMAP", &vc_font_unimap,
+                                        NULL)) < 0) {
+
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r));
+                }
+
+#elif defined(TARGET_ARCH)
+                if ((r = parse_env_file("/etc/rc.conf", NEWLINE,
+                                        "KEYMAP", &vc_keymap,
+                                        "CONSOLEFONT", &vc_font,
+                                        "CONSOLEMAP", &vc_font_map,
+                                        NULL)) < 0) {
+
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/rc.conf: %s", strerror(-r));
+                }
+
+#elif defined(TARGET_GENTOO)
+                if ((r = parse_env_file("/etc/rc.conf", NEWLINE,
+                                        "unicode", &vc_unicode,
+                                        NULL)) < 0) {
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/rc.conf: %s", strerror(-r));
+                }
+
+                if (vc_unicode) {
+                        int rc_unicode;
+
+                        if ((rc_unicode = parse_boolean(vc_unicode)) < 0)
+                                log_error("Unknown value for /etc/rc.conf unicode=%s", vc_unicode);
+                        else {
+                                if (rc_unicode && !utf8)
+                                        log_warning("/etc/rc.conf wants unicode, but current locale is not UTF-8 capable!");
+                                else if (!rc_unicode && utf8) {
+                                        log_debug("/etc/rc.conf does not want unicode, leave it on in kernel but does not apply to vconsole.");
+                                        utf8 = false;
+                                }
+                        }
+                }
+
+                /* /etc/conf.d/consolefont comments and gentoo
+                 * documentation mention uppercase, but the actual
+                 * contents are lowercase.  the existing
+                 * /etc/init.d/consolefont tries both
+                 */
+                if ((r = parse_env_file("/etc/conf.d/consolefont", NEWLINE,
+                                        "CONSOLEFONT", &vc_font,
+                                        "consolefont", &vc_font,
+                                        "consoletranslation", &vc_font_map,
+                                        "CONSOLETRANSLATION", &vc_font_map,
+                                        "unicodemap", &vc_font_unimap,
+                                        "UNICODEMAP", &vc_font_unimap,
+                                        NULL)) < 0) {
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/conf.d/consolefont: %s", strerror(-r));
+                }
+
+                if ((r = parse_env_file("/etc/conf.d/keymaps", NEWLINE,
+                                        "keymap", &vc_keymap,
+                                        "KEYMAP", &vc_keymap,
+                                        NULL)) < 0) {
+                        if (r != -ENOENT)
+                                log_warning("Failed to read /etc/conf.d/keymaps: %s", strerror(-r));
+                }
 #endif
 #endif
-                                "vconsole.keymap", &vc_keymap,
-                                "vconsole.font", &vc_font,
-                                "vconsole.font.map", &vc_font_map,
-                                "vconsole.font.unimap", &vc_font_unimap,
-                                NULL)) < 0) {
-
-                if (r != -ENOENT)
-                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
         }
 
         if (!vc_keymap)
                 vc_keymap = strdup("us");
         if (!vc_font)
         }
 
         if (!vc_keymap)
                 vc_keymap = strdup("us");
         if (!vc_font)
-                vc_font = strdup("latarcyrheb-sun16");
+                vc_font = strdup(DEFAULT_FONT);
 
         if (!vc_keymap || !vc_font) {
                 log_error("Failed to allocate strings.");
                 goto finish;
         }
 
 
         if (!vc_keymap || !vc_font) {
                 log_error("Failed to allocate strings.");
                 goto finish;
         }
 
+        if (!utf8)
+                disable_utf8(fd);
+
         if (load_keymap(vc, vc_keymap, utf8, &keymap_pid) >= 0 &&
             load_font(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0)
                 r = EXIT_SUCCESS;
 
 finish:
         if (keymap_pid > 0)
         if (load_keymap(vc, vc_keymap, utf8, &keymap_pid) >= 0 &&
             load_font(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0)
                 r = EXIT_SUCCESS;
 
 finish:
         if (keymap_pid > 0)
-                wait_for_terminate_and_warn("/bin/loadkeys", keymap_pid);
+                wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid);
 
         if (font_pid > 0)
 
         if (font_pid > 0)
-                wait_for_terminate_and_warn("/bin/setfont", font_pid);
+                wait_for_terminate_and_warn(KBD_SETFONT, font_pid);
 
         free(vc_keymap);
         free(vc_font);
 
         free(vc_keymap);
         free(vc_font);