#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
void cui_abort(struct cui *cui)
{
- pb_log("%s: exiting\n", __func__);
+ pb_log_fn("exiting\n");
cui->abort = 1;
}
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.
*/
nc_scr_post(cui->current);
if (result) {
- pb_log("%s: failed: '%s'\n", __func__, cmd_argv[0]);
+ pb_log_fn("failed: '%s'\n", cmd_argv[0]);
nc_scr_status_printf(cui->current, _("Failed: %s"),
cmd_argv[0]);
}
return 0;
}
+static int menu_sysinfo_execute(struct pmenu_item *item)
+{
+ cui_show_sysinfo(cui_from_item(item));
+ return 0;
+}
+
+static int menu_config_execute(struct pmenu_item *item)
+{
+ cui_show_config(cui_from_item(item));
+ return 0;
+}
+
+static int menu_lang_execute(struct pmenu_item *item)
+{
+ cui_show_lang(cui_from_item(item));
+ return 0;
+}
+
+static int menu_statuslog_execute(struct pmenu_item *item)
+{
+ cui_show_statuslog(cui_from_item(item));
+ return 0;
+}
+
+static int menu_reinit_execute(struct pmenu_item *item)
+{
+ if (cui_from_item(item)->client)
+ cui_send_reinit(cui_from_item(item));
+ return 0;
+}
+
+static int menu_add_url_execute(struct pmenu_item *item)
+{
+ if (cui_from_item(item)->client)
+ cui_show_add_url(cui_from_item(item));
+ return 0;
+}
+
+static int menu_plugin_execute(struct pmenu_item *item)
+{
+ if (cui_from_item(item)->client)
+ cui_show_plugin_menu(cui_from_item(item));
+ return 0;
+}
+
static void cui_boot_editor_on_exit(struct cui *cui,
struct pmenu_item *item,
struct pb_boot_data *bd)
}
}
+ 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) {
struct winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
- pb_log("%s: ioctl failed: %s\n", __func__, strerror(errno));
+ pb_log_fn("ioctl failed: %s\n", strerror(errno));
return;
}
result = set_menu_items(menu->ncm, NULL);
if (result)
- pb_log("%s: set_menu_items failed: %d\n", __func__, result);
+ pb_log_fn("set_menu_items failed: %d\n", result);
/* Insert new items at insert_pt. */
if (dev_hdr) {
}
if (plugin_option) {
- pb_log("%s: adding plugin '%s'\n", __func__, cod->name);
+ pb_log_fn("adding plugin '%s'\n", cod->name);
pb_log(" file '%s'\n", cod->pd->plugin_file);
} else {
- pb_log("%s: adding opt '%s'\n", __func__, cod->name);
+ pb_log_fn("adding opt '%s'\n", cod->name);
pb_log(" image '%s'\n", cod->bd->image);
pb_log(" initrd '%s'\n", cod->bd->initrd);
pb_log(" args '%s'\n", cod->bd->args);
result = set_menu_items(cui->main->ncm, NULL);
for (j = 0 ; j < cui->main->item_count; j++) {
item = item_userptr(cui->main->items[j]);
- if (strncmp(item->nci->name.str, "Plugins", strlen("Plugins")))
+ if (item->on_execute != menu_plugin_execute)
continue;
cui->n_plugins++;
- char *label = talloc_asprintf(item, "Plugins (%u)",
+ char *label = talloc_asprintf(item, _("Plugins (%u)"),
cui->n_plugins);
pmenu_item_update(item, label);
talloc_free(label);
}
result = set_menu_items(cui->main->ncm, cui->main->items);
if (result)
- pb_log("%s: set_menu_items failed: %d\n", __func__, result);
+ pb_log_fn("set_menu_items failed: %d\n", result);
}
/* Re-attach the items array. */
result = set_menu_items(menu->ncm, menu->items);
if (result)
- pb_log("%s: set_menu_items failed: %d\n", __func__, result);
+ pb_log_fn("set_menu_items failed: %d\n", result);
if (0) {
pb_log("%s\n", __func__);
int rows, cols, top, last;
int result;
- pb_log("%s: %p %s\n", __func__, dev, dev->id);
+ pb_log_fn("%p %s\n", dev, dev->id);
if (cui->current == &cui->main->scr)
nc_scr_unpost(cui->current);
result |= set_menu_items(cui->plugin_menu->ncm, NULL);
if (result)
- pb_log("%s: set_menu_items failed: %d\n", __func__, result);
+ pb_log_fn("set_menu_items failed: %d\n", result);
list_for_each_entry(&dev->boot_options, opt, list) {
struct pmenu_item *item = pmenu_item_from_arg(opt->ui_info);
}
if (result)
- pb_log("%s: set_menu_items failed: %d\n", __func__, result);
+ pb_log_fn("set_menu_items failed: %d\n", result);
if (0) {
pb_log("%s\n", __func__);
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);
+ }
}
/*
set_menu_items(cui->main->ncm, NULL);
for (i = 0; i < cui->main->item_count; i++) {
item = item_userptr(cui->main->items[i]);
- if (strncmp(item->nci->name.str, "Plugins", strlen("Plugins")))
+ if (item->on_execute != menu_plugin_execute)
continue;
cui->n_plugins = 0;
- pmenu_item_update(item, "Plugins (0)");
+ pmenu_item_update(item, _("Plugins (0)"));
break;
}
discover_client_send_reinit(cui->client);
}
-static int menu_sysinfo_execute(struct pmenu_item *item)
-{
- cui_show_sysinfo(cui_from_item(item));
- return 0;
-}
-
-static int menu_config_execute(struct pmenu_item *item)
-{
- cui_show_config(cui_from_item(item));
- return 0;
-}
-
-static int menu_lang_execute(struct pmenu_item *item)
-{
- cui_show_lang(cui_from_item(item));
- return 0;
-}
-
-static int menu_statuslog_execute(struct pmenu_item *item)
-{
- cui_show_statuslog(cui_from_item(item));
- return 0;
-}
-
-static int menu_reinit_execute(struct pmenu_item *item)
-{
- if (cui_from_item(item)->client)
- cui_send_reinit(cui_from_item(item));
- return 0;
-}
-
-static int menu_add_url_execute(struct pmenu_item *item)
-{
- if (cui_from_item(item)->client)
- cui_show_add_url(cui_from_item(item));
- return 0;
-}
-
-static int menu_plugin_execute(struct pmenu_item *item)
-{
- if (cui_from_item(item)->client)
- cui_show_plugin_menu(cui_from_item(item));
- return 0;
-}
-
/**
* pb_mm_init - Setup the main menu instance.
*/
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("%s: failed\n", __func__);
+ pb_log_fn("failed\n");
return NULL;
}
m->n_hot_keys = 1;
m->hot_keys = talloc_array(m, hot_key_fn, m->n_hot_keys);
if (!m->hot_keys) {
- pb_log("%s: failed to allocate hot_keys\n", __func__);
+ pb_log_fn("failed to allocate hot_keys\n");
talloc_free(m);
return NULL;
}
cui = talloc_zero(NULL, struct cui);
if (!cui) {
- pb_log("%s: alloc cui failed.\n", __func__);
+ pb_log_fn("alloc cui failed.\n");
fprintf(stderr, _("%s: alloc cui failed.\n"), __func__);
goto fail_alloc;
}
&cui_client_ops, cui);
if (cui->client || !i)
break;
- pb_log("%s: waiting for server %d\n", __func__, i);
+ pb_log_fn("waiting for server %d\n", i);
sleep(1);
}
if (!result)
goto retry_start;
- pb_log("%s: discover_client_init failed.\n", __func__);
+ pb_log_fn("discover_client_init failed.\n");
fprintf(stderr, _("%s: error: discover_client_init failed.\n"),
__func__);
fprintf(stderr, _("could not start pb-discover, the petitboot "
waiter_register_timeout(cui->waitset, 0,
cui_server_wait, cui);
} else if (!cui->client) {
- pb_log("%s: discover_client_init failed.\n", __func__);
+ pb_log_fn("discover_client_init failed.\n");
fprintf(stderr, _("%s: error: discover_client_init failed.\n"),
__func__);
fprintf(stderr, _("check that pb-discover, "
int result = waiter_poll(cui->waitset);
if (result < 0) {
- pb_log("%s: poll: %s\n", __func__, strerror(errno));
+ pb_log_fn("poll: %s\n", strerror(errno));
break;
}