diff options
Diffstat (limited to 'src/hci/tui/settings_ui.c')
| -rw-r--r-- | src/hci/tui/settings_ui.c | 150 |
1 files changed, 44 insertions, 106 deletions
diff --git a/src/hci/tui/settings_ui.c b/src/hci/tui/settings_ui.c index be421cc0a..a069c527d 100644 --- a/src/hci/tui/settings_ui.c +++ b/src/hci/tui/settings_ui.c @@ -22,9 +22,11 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <stdarg.h> +#include <stdlib.h> #include <unistd.h> #include <string.h> #include <curses.h> @@ -34,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/keys.h> #include <ipxe/ansicol.h> #include <ipxe/jumpscroll.h> +#include <ipxe/message.h> #include <ipxe/settings_ui.h> #include <config/branding.h> @@ -58,12 +61,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); char start[0]; \ char pad1[1]; \ union { \ - char settings[ cols - 1 - 1 - 1 - 1 ]; \ + struct { \ + char name[ cols - 1 - 1 - 1 - 1 - 1 ]; \ + char pad2[1]; \ + } __attribute__ (( packed )) settings; \ struct { \ char name[15]; \ char pad2[1]; \ char value[ cols - 1 - 15 - 1 - 1 - 1 - 1 ]; \ - } setting; \ + } __attribute__ (( packed )) setting; \ } u; \ char pad3[1]; \ char nul; \ @@ -92,8 +98,8 @@ struct settings_ui_row { struct edit_box editbox; /** Editing in progress flag */ int editing; - /** Buffer for setting's value */ - char value[256]; /* enough size for a DHCP string */ + /** Dynamically allocated buffer for setting's value */ + char *buf; }; /** A settings user interface */ @@ -121,24 +127,22 @@ static unsigned int select_setting_row ( struct settings_ui *ui, struct setting *previous = NULL; unsigned int count = 0; + /* Free any previous setting value */ + free ( ui->row.buf ); + ui->row.buf = NULL; + /* Initialise structure */ memset ( &ui->row, 0, sizeof ( ui->row ) ); ui->row.row = ( SETTINGS_LIST_ROW + index - ui->scroll.first ); /* Include parent settings block, if applicable */ - if ( ui->settings->parent && ( count++ == index ) ) { + if ( ui->settings->parent && ( count++ == index ) ) ui->row.settings = ui->settings->parent; - snprintf ( ui->row.value, sizeof ( ui->row.value ), - "../" ); - } /* Include any child settings blocks, if applicable */ list_for_each_entry ( settings, &ui->settings->children, siblings ) { - if ( count++ == index ) { + if ( count++ == index ) ui->row.settings = settings; - snprintf ( ui->row.value, sizeof ( ui->row.value ), - "%s/", settings->name ); - } } /* Include any applicable settings */ @@ -155,18 +159,18 @@ static unsigned int select_setting_row ( struct settings_ui *ui, /* Read current setting value and origin */ if ( count++ == index ) { - fetchf_setting ( ui->settings, setting, &ui->row.origin, - &ui->row.setting, ui->row.value, - sizeof ( ui->row.value ) ); + fetchf_setting_copy ( ui->settings, setting, + &ui->row.origin, + &ui->row.setting, &ui->row.buf ); } } /* Initialise edit box */ - init_editbox ( &ui->row.editbox, ui->row.value, - sizeof ( ui->row.value ), NULL, ui->row.row, + memset ( &ui->row.editbox, 0, sizeof ( ui->row.editbox ) ); + init_editbox ( &ui->row.editbox, ui->row.row, ( SETTINGS_LIST_COL + offsetof ( typeof ( *text ), u.setting.value ) ), - sizeof ( text->u.setting.value ), 0 ); + sizeof ( text->u.setting.value ), 0, &ui->row.buf ); return count; } @@ -197,7 +201,7 @@ static size_t string_copy ( char *dest, const char *src, size_t len ) { static void draw_setting_row ( struct settings_ui *ui ) { SETTING_ROW_TEXT ( COLS ) text; unsigned int curs_offset; - char *value; + const char *value; /* Fill row with spaces */ memset ( &text, ' ', sizeof ( text ) ); @@ -207,10 +211,12 @@ static void draw_setting_row ( struct settings_ui *ui ) { if ( ui->row.settings ) { /* Construct space-padded name */ - curs_offset = ( offsetof ( typeof ( text ), u.settings ) + - string_copy ( text.u.settings, - ui->row.value, - sizeof ( text.u.settings ) ) ); + value = ( ( ui->row.settings == ui->settings->parent ) ? + ".." : ui->row.settings->name ); + curs_offset = string_copy ( text.u.settings.name, value, + sizeof ( text.u.settings.name ) ); + text.u.settings.name[curs_offset] = '/'; + curs_offset += offsetof ( typeof ( text ), u.settings ); } else { @@ -221,12 +227,12 @@ static void draw_setting_row ( struct settings_ui *ui ) { sizeof ( text.u.setting.name ) ); /* Construct space-padded value */ - value = ui->row.value; - if ( ! *value ) + value = ui->row.buf; + if ( ! ( value && value[0] ) ) value = "<not specified>"; - curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) + - string_copy ( text.u.setting.value, value, - sizeof ( text.u.setting.value ))); + curs_offset = string_copy ( text.u.setting.value, value, + sizeof ( text.u.setting.value ) ); + curs_offset += offsetof ( typeof ( text ), u.setting.value ); } /* Print row */ @@ -247,7 +253,7 @@ static void draw_setting_row ( struct settings_ui *ui ) { static int edit_setting ( struct settings_ui *ui, int key ) { assert ( ui->row.setting.name != NULL ); ui->row.editing = 1; - return edit_editbox ( &ui->row.editbox, key ); + return edit_widget ( &ui->row.editbox.widget, key ); } /** @@ -257,76 +263,7 @@ static int edit_setting ( struct settings_ui *ui, int key ) { */ static int save_setting ( struct settings_ui *ui ) { assert ( ui->row.setting.name != NULL ); - return storef_setting ( ui->settings, &ui->row.setting, ui->row.value ); -} - -/** - * Print message centred on specified row - * - * @v row Row - * @v fmt printf() format string - * @v args printf() argument list - */ -static void vmsg ( unsigned int row, const char *fmt, va_list args ) { - char buf[COLS]; - size_t len; - - len = vsnprintf ( buf, sizeof ( buf ), fmt, args ); - mvprintw ( row, ( ( COLS - len ) / 2 ), "%s", buf ); -} - -/** - * Print message centred on specified row - * - * @v row Row - * @v fmt printf() format string - * @v .. printf() arguments - */ -static void msg ( unsigned int row, const char *fmt, ... ) { - va_list args; - - va_start ( args, fmt ); - vmsg ( row, fmt, args ); - va_end ( args ); -} - -/** - * Clear message on specified row - * - * @v row Row - */ -static void clearmsg ( unsigned int row ) { - move ( row, 0 ); - clrtoeol(); -} - -/** - * Print alert message - * - * @v fmt printf() format string - * @v args printf() argument list - */ -static void valert ( const char *fmt, va_list args ) { - clearmsg ( ALERT_ROW ); - color_set ( CPAIR_ALERT, NULL ); - vmsg ( ALERT_ROW, fmt, args ); - sleep ( 2 ); - color_set ( CPAIR_NORMAL, NULL ); - clearmsg ( ALERT_ROW ); -} - -/** - * Print alert message - * - * @v fmt printf() format string - * @v ... printf() arguments - */ -static void alert ( const char *fmt, ... ) { - va_list args; - - va_start ( args, fmt ); - valert ( fmt, args ); - va_end ( args ); + return storef_setting ( ui->settings, &ui->row.setting, ui->row.buf ); } /** @@ -443,8 +380,8 @@ static void select_settings ( struct settings_ui *ui, static int main_loop ( struct settings *settings ) { struct settings_ui ui; unsigned int previous; + unsigned int move; int redraw = 1; - int move; int key; int rc; @@ -474,17 +411,17 @@ static int main_loop ( struct settings *settings ) { assert ( ui.row.setting.name != NULL ); /* Redraw edit box */ - color_set ( CPAIR_EDIT, NULL ); - draw_editbox ( &ui.row.editbox ); - color_set ( CPAIR_NORMAL, NULL ); + draw_widget ( &ui.row.editbox.widget ); /* Process keypress */ key = edit_setting ( &ui, getkey ( 0 ) ); switch ( key ) { case CR: case LF: - if ( ( rc = save_setting ( &ui ) ) != 0 ) - alert ( " %s ", strerror ( rc ) ); + if ( ( rc = save_setting ( &ui ) ) != 0 ) { + alert ( ALERT_ROW, " %s ", + strerror ( rc ) ); + } /* Fall through */ case CTRL_C: select_setting_row ( &ui, ui.scroll.current ); @@ -521,12 +458,13 @@ static int main_loop ( struct settings *settings ) { break; if ( ( rc = delete_setting ( ui.settings, &ui.row.setting ) ) != 0 ){ - alert ( " %s ", strerror ( rc ) ); + alert ( ALERT_ROW, " %s ", strerror ( rc ) ); } select_setting_row ( &ui, ui.scroll.current ); redraw = 1; break; case CTRL_X: + select_setting_row ( &ui, -1U ); return 0; case CR: case LF: |
