]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-cui.c
discover: Nicely format IPMI response buffers
[petitboot] / ui / ncurses / nc-cui.c
index 3abeac3e2ff29d41a2ecfd34f552339d5637523e..8ad89553a5ebed3875d1eaa0da5e71235172a2ba 100644 (file)
@@ -92,16 +92,30 @@ static bool lockdown_active(void)
 #endif
 }
 
+static void cui_set_curses_options(bool curses_mode)
+{
+       if (curses_mode) {
+               cbreak();                       /* Disable line buffering. */
+               noecho();                       /* Disable getch() echo. */
+               nonl();                         /* Disable new-line translation. */
+               intrflush(stdscr, FALSE);       /* Disable interrupt flush. */
+               curs_set(0);                    /* Make cursor invisible */
+               nodelay(stdscr, TRUE);          /* Enable non-blocking getch() */
+       } else {
+               nocbreak();                     /* Enable line buffering. */
+               echo();                         /* Enable getch() echo. */
+               nl();                           /* Enable new-line translation. */
+               intrflush(stdscr, TRUE);        /* Enable interrupt flush. */
+               curs_set(1);                    /* Make cursor visible */
+               nodelay(stdscr, FALSE);         /* Disable non-blocking getch() */
+       }
+}
+
 static void cui_start(void)
 {
        initscr();                      /* Initialize ncurses. */
-       cbreak();                       /* Disable line buffering. */
-       noecho();                       /* Disable getch() echo. */
        keypad(stdscr, TRUE);           /* Enable num keypad keys. */
-       nonl();                         /* Disable new-line translation. */
-       intrflush(stdscr, FALSE);       /* Disable interrupt flush. */
-       curs_set(0);                    /* Make cursor invisible */
-       nodelay(stdscr, TRUE);          /* Enable non-blocking getch() */
+       cui_set_curses_options(true);
 
        /* We may be operating with an incorrect $TERM type; in this case
         * the keymappings will be slightly broken. We want at least
@@ -219,6 +233,17 @@ void cui_on_exit(struct pmenu *menu)
        talloc_free(sh_cmd);
 }
 
+/**
+ * cui_abort_on_exit - Force an exit of the main loop on menu exit.
+ *                     This is mainly for lockdown situations where
+ *                     the exit then triggers an expected reboot.
+ */
+void cui_abort_on_exit(struct pmenu *menu)
+{
+       struct cui *cui = cui_from_pmenu(menu);
+       cui->abort = 1;
+}
+
 /**
  * cui_run_cmd - A generic cb to run the supplied command.
  */
@@ -639,6 +664,12 @@ static int cui_process_key(void *arg)
                        }
                }
 
+               if (cui->preboot_mode) {
+                       /* Turn curses options back on if the user interacts */
+                       cui->preboot_mode = false;
+                       cui_set_curses_options(true);
+               }
+
                if (!cui->has_input && key_cancels_boot(c)) {
                        cui->has_input = true;
                        if (cui->client) {
@@ -969,8 +1000,21 @@ static void cui_update_status(struct status *status, void *arg)
        statuslog_append_steal(cui, cui->statuslog, status);
 
        /* Ignore status messages from the backlog */
-       if (!status->backlog)
-               nc_scr_status_printf(cui->current, "%s", status->message);
+       if (status->backlog)
+               return;
+
+       nc_scr_status_printf(cui->current, "%s", status->message);
+
+       if (cui->preboot_mode &&
+               (!status->boot_active || status->type == STATUS_ERROR)) {
+               cui_set_curses_options(true);
+               cui->preboot_mode = false;
+       } else {
+               cui->preboot_mode = status->boot_active &&
+                                               status->type == STATUS_INFO;
+               if (cui->preboot_mode)
+                       cui_set_curses_options(false);
+       }
 }
 
 /*
@@ -1298,7 +1342,7 @@ static struct pmenu *main_menu_init(struct cui *cui)
        int result;
        bool lockdown = lockdown_active();
 
-       m = pmenu_init(cui, 9, cui_on_exit);
+       m = pmenu_init(cui, 9, lockdown ? cui_abort_on_exit : cui_on_exit);
        if (!m) {
                pb_log_fn("failed\n");
                return NULL;