diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-02-10 22:26:06 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-02-10 22:26:06 -0800 |
commit | 9fd7fad275a23cdfad680f56d1199acab675ef2a (patch) | |
tree | f1f70293c6f78c8e4a433cdbe95a3b4f942a4bb6 /com32/modules | |
parent | 55bf6f17d1e646580342bda77d15878e293faad7 (diff) | |
download | syslinux-9fd7fad275a23cdfad680f56d1199acab675ef2a.tar.gz |
Simple menu system: move to dedicated subdirectory
Move the simple menu system into its own subdirectory, to make it more
obvious which source files are part of it.
Diffstat (limited to 'com32/modules')
-rw-r--r-- | com32/modules/Makefile | 16 | ||||
-rw-r--r-- | com32/modules/menu.c | 44 | ||||
-rw-r--r-- | com32/modules/menu.h | 143 | ||||
-rw-r--r-- | com32/modules/menumain.c | 1230 | ||||
-rw-r--r-- | com32/modules/printmsg.c | 107 | ||||
-rw-r--r-- | com32/modules/readconfig.c | 793 | ||||
-rw-r--r-- | com32/modules/vesamenu.c | 53 |
7 files changed, 3 insertions, 2383 deletions
diff --git a/com32/modules/Makefile b/com32/modules/Makefile index 0347c17c..6291a6a4 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -11,7 +11,7 @@ ## ----------------------------------------------------------------------- ## -## samples for syslinux users +## COM32 standard modules ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) @@ -47,9 +47,8 @@ AUXDIR = $(LIBDIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 -MODULES = chain.c32 menu.c32 vesamenu.c32 ethersel.c32 mboot.c32 \ - dmitest.c32 cpuidtest.c32 pcitest.c32 elf.c32 linux.c32 \ - reboot.c32 pmload.c32 meminfo.c32 +MODULES = chain.c32 ethersel.c32 mboot.c32 dmitest.c32 cpuidtest.c32 \ + pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 meminfo.c32 TESTFILES = all: $(MODULES) $(TESTFILES) @@ -90,18 +89,9 @@ cpuidtest.elf : cpuidtest.o cpuid.o $(LIBS) dmitest.elf : dmitest.o dmi_utils.o dmi.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ -menu.elf : menu.o menumain.o readconfig.o printmsg.o $(LIBS) - $(LD) $(LDFLAGS) -o $@ $^ - -vesamenu.elf : vesamenu.o menumain.o readconfig.o printmsg.o $(LIBS) - $(LD) $(LDFLAGS) -o $@ $^ - ethersel.elf : ethersel.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ -menu.lnx : menu.lo readconfig.lo $(LNXLIBS) - $(CC) $(LNXLDFLAGS) -o $@ $^ - tidy: rm -f *.o *.lo *.a *.lst *.elf diff --git a/com32/modules/menu.c b/com32/modules/menu.c deleted file mode 100644 index acc19f59..00000000 --- a/com32/modules/menu.c +++ /dev/null @@ -1,44 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * menu.c - * - * Simple menu system which displays a list and allows the user to select - * a command line and/or edit it. - */ - -#include <consoles.h> -#include "menu.h" - -void console_prepare(void) -{ - /* Nothing special to do */ -} - -void console_cleanup(void) -{ - /* Nothing special to do */ -} - -int draw_background(const char *arg) -{ - /* Nothing to do... */ - (void)arg; -} - -int main(int argc, char *argv[]) -{ - console_ansi_raw(); - - return menu_main(argc, argv); -} diff --git a/com32/modules/menu.h b/com32/modules/menu.h deleted file mode 100644 index 1c516ef2..00000000 --- a/com32/modules/menu.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * menu.h - * - * Header file for the simple menu system - */ - -#ifndef MENU_H -#define MENU_H - -#include <time.h> -#include <sys/time.h> -#include <sys/times.h> -#include <inttypes.h> -#include <unistd.h> -#include <colortbl.h> - -#ifndef CLK_TCK -# define CLK_TCK sysconf(_SC_CLK_TCK) -#endif - -struct menu_entry { - char *displayname; - char *label; - char *cmdline; - char *passwd; - char *helptext; - unsigned char hotkey; - unsigned char disabled; -}; - -enum kernel_type { - /* Meta-types for internal use */ - KT_NONE, - KT_LOCALBOOT, - - /* The ones we can pass off to SYSLINUX, in order */ - KT_KERNEL, /* Undefined type */ - KT_LINUX, /* Linux kernel */ - KT_BOOT, /* Bootstrap program */ - KT_BSS, /* Boot sector with patch */ - KT_PXE, /* PXE NBP */ - KT_FDIMAGE, /* Floppy disk image */ - KT_COMBOOT, /* COMBOOT image */ - KT_COM32, /* COM32 image */ - KT_CONFIG, /* Configuration file */ -}; - -extern const char *kernel_types[]; - -/* Configurable messages */ -enum message_number { - MSG_TITLE, - MSG_AUTOBOOT, - MSG_TAB, - MSG_NOTAB, - MSG_PASSPROMPT, - - MSG_COUNT -}; -struct messages { - const char *name; /* Message configuration name */ - const char *defmsg; /* Default message text */ - char *msg; /* Actual message text */ -}; -extern struct messages messages[MSG_COUNT]; - -/* 512 is the current definition inside syslinux */ -#define MAX_CMDLINE_LEN 512 - -#define MAX_ENTRIES 4096 /* Oughta be enough for anybody */ -extern struct menu_entry menu_entries[]; -extern struct menu_entry *menu_hotkeys[256]; - -struct menu_parameter { - const char *name; - int value; -}; - -extern struct menu_parameter mparm[]; - -extern int nentries; -extern int defentry; -extern int allowedit; -extern int timeout; -extern int shiftkey; -extern int hiddenmenu; -extern long long totaltimeout; - -extern char *ontimeout; -extern char *onerror; -extern char *menu_master_passwd; -extern char *menu_tab_msg; -extern char *menu_autoboot_msg; -extern char *menu_passprompt_msg; - -extern char *menu_background; - -struct fkey_help { - const char *textname; - const char *background; -}; -extern struct fkey_help fkeyhelp[12]; - -void parse_configs(char **argv); -int draw_background(const char *filename); - -static inline int my_isspace(char c) -{ - return (unsigned char)c <= ' '; -} - -int my_isxdigit(char c); -unsigned int hexval(char c); -unsigned int hexval2(const char *p); -uint32_t parse_argb(char **p); - -int menu_main(int argc, char *argv[]); -void console_prepare(void); -void console_cleanup(void); - -extern const int message_base_color; -int mygetkey(clock_t timeout); -int show_message_file(const char *filename, const char *background); - -#define MSG_COLORS_DEF_FG 0x90ffffff -#define MSG_COLORS_DEF_BG 0x80ffffff -#define MSG_COLORS_DEF_SHADOW SHADOW_NORMAL -void set_msg_colors_global(unsigned int fg, unsigned int bg, - enum color_table_shadow shadow); - -#endif /* MENU_H */ diff --git a/com32/modules/menumain.c b/com32/modules/menumain.c deleted file mode 100644 index fad49a28..00000000 --- a/com32/modules/menumain.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * menumain.c - * - * Simple menu system which displays a list and allows the user to select - * a command line and/or edit it. - */ - -#define _GNU_SOURCE /* Needed for asprintf() on Linux */ -#include <ctype.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <consoles.h> -#include <getkey.h> -#include <minmax.h> -#include <setjmp.h> -#include <limits.h> -#include <sha1.h> -#include <md5.h> -#include <base64.h> -#include <colortbl.h> -#include <com32.h> - -#include "menu.h" - -/* - * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows - * - * 00 - screen Rest of the screen - * 01 - border Border area - * 02 - title Title bar - * 03 - unsel Unselected menu item - * 04 - hotkey Unselected hotkey - * 05 - sel Selection bar - * 06 - hotsel Selected hotkey - * 07 - scrollbar Scroll bar - * 08 - tabmsg Press [Tab] message - * 09 - cmdmark Command line marker - * 10 - cmdline Command line - * 11 - pwdborder Password box border - * 12 - pwdheader Password box header - * 13 - pwdentry Password box contents - * 14 - timeout_msg Timeout message - * 15 - timeout Timeout counter - * 16 - help Current entry help text - * 17 - disabled Disabled menu item - */ - -static const struct color_table default_color_table[] = { - { "screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, - { "border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, - { "title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL }, - { "unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL }, - { "hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL }, - { "sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL }, - { "hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL }, - { "scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, - { "tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL }, - { "cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL }, - { "cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, - { "pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, - { "pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL }, - { "pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, - { "timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, - { "timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, - { "help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, - { "disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL }, -}; - -#define NCOLORS (sizeof default_color_table/sizeof(struct color_table)) -const int message_base_color = NCOLORS; - -struct menu_parameter mparm[] = { - { "width", 80 }, - { "margin", 10 }, - { "passwordmargin", 3 }, - { "rows", 12 }, - { "tabmsgrow", 18 }, - { "cmdlinerow", 18 }, - { "endrow", -1 }, - { "passwordrow", 11 }, - { "timeoutrow", 20 }, - { "helpmsgrow", 22 }, - { "helpmsgendrow", -1 }, - { "hshift", 0 }, - { "vshift", 0 }, - { "hiddenrow", -2 }, - { NULL, 0 } -}; - -#define WIDTH mparm[0].value -#define MARGIN mparm[1].value -#define PASSWD_MARGIN mparm[2].value -#define MENU_ROWS mparm[3].value -#define TABMSG_ROW (mparm[4].value+VSHIFT) -#define CMDLINE_ROW (mparm[5].value+VSHIFT) -#define END_ROW mparm[6].value -#define PASSWD_ROW (mparm[7].value+VSHIFT) -#define TIMEOUT_ROW (mparm[8].value+VSHIFT) -#define HELPMSG_ROW (mparm[9].value+VSHIFT) -#define HELPMSGEND_ROW mparm[10].value -#define HSHIFT mparm[11].value -#define VSHIFT mparm[12].value -#define HIDDEN_ROW mparm[13].value - -void set_msg_colors_global(unsigned int fg, unsigned int bg, - enum color_table_shadow shadow) -{ - struct color_table *cp = console_color_table+message_base_color; - unsigned int i; - unsigned int fga, bga; - unsigned int fgh, bgh; - unsigned int fg_idx, bg_idx; - unsigned int fg_rgb, bg_rgb; - - static const unsigned int pc2rgb[8] = - { 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, - 0xffffff }; - - /* Converting PC RGBI to sensible RGBA values is an "interesting" - proposition. This algorithm may need plenty of tweaking. */ - - fga = fg & 0xff000000; - fgh = ((fg >> 1) & 0xff000000) | 0x80000000; - - bga = bg & 0xff000000; - bgh = ((bg >> 1) & 0xff000000) | 0x80000000; - - for (i = 0; i < 256; i++) { - fg_idx = i & 15; - bg_idx = i >> 4; - - fg_rgb = pc2rgb[fg_idx & 7] & fg; - bg_rgb = pc2rgb[bg_idx & 7] & bg; - - if (fg_idx & 8) { - /* High intensity foreground */ - fg_rgb |= fgh; - } else { - fg_rgb |= fga; - } - - if (bg_idx == 0) { - /* Default black background, assume transparent */ - bg_rgb = 0; - } else if (bg_idx & 8) { - bg_rgb |= bgh; - } else { - bg_rgb |= bga; - } - - cp->argb_fg = fg_rgb; - cp->argb_bg = bg_rgb; - cp->shadow = shadow; - cp++; - } -} - -static void -install_default_color_table(void) -{ - unsigned int i; - const struct color_table *dp; - struct color_table *cp; - static struct color_table color_table[NCOLORS+256]; - static const int pc2ansi[8] = {0, 4, 2, 6, 1, 5, 3, 7}; - - dp = default_color_table; - cp = color_table; - - for (i = 0; i < NCOLORS; i++) { - if (cp->ansi) - free((void *)cp->ansi); - - *cp = *dp; - cp->ansi = strdup(dp->ansi); - - cp++; - dp++; - } - - for (i = 0; i < 256; i++) { - if (!cp->name) - asprintf((char **)&cp->name, "msg%02x", i); - - if (cp->ansi) - free((void *)cp->ansi); - - asprintf((char **)&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "", - pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]); - - cp++; - } - - console_color_table = color_table; - console_color_table_size = NCOLORS+256; - - set_msg_colors_global(MSG_COLORS_DEF_FG, MSG_COLORS_DEF_BG, - MSG_COLORS_DEF_SHADOW); -} - -static char * -pad_line(const char *text, int align, int width) -{ - static char buffer[MAX_CMDLINE_LEN]; - int n, p; - - if ( width >= (int) sizeof buffer ) - return NULL; /* Can't do it */ - - n = strlen(text); - if ( n >= width ) - n = width; - - memset(buffer, ' ', width); - buffer[width] = 0; - p = ((width-n)*align)>>1; - memcpy(buffer+p, text, n); - - return buffer; -} - -/* Display an entry, with possible hotkey highlight. Assumes - that the current attribute is the non-hotkey one, and will - guarantee that as an exit condition as well. */ -static void -display_entry(const struct menu_entry *entry, const char *attrib, - const char *hotattrib, int width) -{ - const char *p = entry->displayname; - - while ( width ) { - if ( *p ) { - if ( *p == '^' ) { - p++; - if ( *p && ((unsigned char)*p & ~0x20) == entry->hotkey ) { - fputs(hotattrib, stdout); - putchar(*p++); - fputs(attrib, stdout); - width--; - } - } else { - putchar(*p++); - width--; - } - } else { - putchar(' '); - width--; - } - } -} - -static void -draw_row(int y, int sel, int top, int sbtop, int sbbot) -{ - int i = (y-4-VSHIFT)+top; - int dis = (i < nentries) && menu_entries[i].disabled; - - printf("\033[%d;%dH\1#1\016x\017%s ", - y, MARGIN+1+HSHIFT, - (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3"); - - if ( i >= nentries ) { - fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout); - } else { - display_entry(&menu_entries[i], - (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3", - (i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4", - WIDTH-2*MARGIN-4); - } - - if ( nentries <= MENU_ROWS ) { - printf(" \1#1\016x\017"); - } else if ( sbtop > 0 ) { - if ( y >= sbtop && y <= sbbot ) - printf(" \1#7\016a\017"); - else - printf(" \1#1\016x\017"); - } else { - putchar(' '); /* Don't modify the scrollbar */ - } -} - -static int passwd_compare_sha1(const char *passwd, const char *entry) -{ - const char *p; - SHA1_CTX ctx; - unsigned char sha1[20], pwdsha1[20]; - - SHA1Init(&ctx); - - if ( (p = strchr(passwd+3, '$')) ) { - SHA1Update(&ctx, (void *)passwd+3, p-(passwd+3)); - p++; - } else { - p = passwd+3; /* Assume no salt */ - } - - SHA1Update(&ctx, (void *)entry, strlen(entry)); - SHA1Final(sha1, &ctx); - - memset(pwdsha1, 0, 20); - unbase64(pwdsha1, 20, p); - - return !memcmp(sha1, pwdsha1, 20); -} - -static int passwd_compare_md5(const char *passwd, const char *entry) -{ - const char *crypted = crypt_md5(entry, passwd+3); - int len = strlen(crypted); - - return !strncmp(crypted, passwd, len) && - (passwd[len] == '\0' || passwd[len] == '$'); -} - -static int -passwd_compare(const char *passwd, const char *entry) -{ - if ( passwd[0] != '$' ) /* Plaintext passwd, yuck! */ - return !strcmp(entry, passwd); - else if ( !strncmp(passwd, "$4$", 3) ) - return passwd_compare_sha1(passwd, entry); - else if ( !strncmp(passwd, "$1$", 3) ) - return passwd_compare_md5(passwd, entry); - else - return 0; /* Invalid encryption algorithm */ -} - -static jmp_buf timeout_jump; - -int mygetkey(clock_t timeout) -{ - clock_t t0, t; - clock_t tto, to; - int key; - - if ( !totaltimeout ) - return get_key(stdin, timeout); - - for (;;) { - tto = min(totaltimeout, INT_MAX); - to = timeout ? min(tto, timeout) : tto; - - t0 = times(NULL); - key = get_key(stdin, to); - t = times(NULL) - t0; - - if ( totaltimeout <= t ) - longjmp(timeout_jump, 1); - - totaltimeout -= t; - - if ( key != KEY_NONE ) - return key; - - if ( timeout ) { - if ( timeout <= t ) - return KEY_NONE; - - timeout -= t; - } - } -} - -static int -ask_passwd(const char *menu_entry) -{ - char user_passwd[WIDTH], *p; - int done; - int key; - int x; - - printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1); - for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) - putchar('q'); - - printf("k\033[%d;%dHx", PASSWD_ROW+1, PASSWD_MARGIN+1); - for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) - putchar(' '); - - printf("x\033[%d;%dHm", PASSWD_ROW+2, PASSWD_MARGIN+1); - for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) - putchar('q'); - - printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13", - PASSWD_ROW, (WIDTH-(strlen(messages[MSG_PASSPROMPT].msg)+2))/2, - messages[MSG_PASSPROMPT].msg, PASSWD_ROW+1, PASSWD_MARGIN+3); - - /* Actually allow user to type a password, then compare to the SHA1 */ - done = 0; - p = user_passwd; - - while ( !done ) { - key = mygetkey(0); - - switch ( key ) { - case KEY_ENTER: - case KEY_CTRL('J'): - done = 1; - break; - - case KEY_ESC: - case KEY_CTRL('C'): - p = user_passwd; /* No password entered */ - done = 1; - break; - - case KEY_BACKSPACE: - case KEY_DEL: - case KEY_DELETE: - if ( p > user_passwd ) { - printf("\b \b"); - p--; - } - break; - - case KEY_CTRL('U'): - while ( p > user_passwd ) { - printf("\b \b"); - p--; - } - break; - - default: - if ( key >= ' ' && key <= 0xFF && - (p-user_passwd) < WIDTH-2*PASSWD_MARGIN-5 ) { - *p++ = key; - putchar('*'); - } - break; - } - } - - if ( p == user_passwd ) - return 0; /* No password entered */ - - *p = '\0'; - - return (menu_master_passwd && passwd_compare(menu_master_passwd, user_passwd)) - || (menu_entry && passwd_compare(menu_entry, user_passwd)); -} - - -static void -draw_menu(int sel, int top, int edit_line) -{ - int x, y; - int sbtop = 0, sbbot = 0; - const char *tabmsg; - int tabmsg_len; - - if ( nentries > MENU_ROWS ) { - int sblen = MENU_ROWS*MENU_ROWS/nentries; - sbtop = (MENU_ROWS-sblen+1)*top/(nentries-MENU_ROWS+1); - sbbot = sbtop + sblen - 1; - - sbtop += 4; sbbot += 4; /* Starting row of scrollbar */ - } - - printf("\033[%d;%dH\1#1\016l", VSHIFT+1, HSHIFT+MARGIN+1); - for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) - putchar('q'); - - printf("k\033[%d;%dH\1#1x\017\1#2 %s \1#1\016x", - VSHIFT+2, - HSHIFT+MARGIN+1, - pad_line(messages[MSG_TITLE].msg, 1, WIDTH-2*MARGIN-4)); - - printf("\033[%d;%dH\1#1t", VSHIFT+3, HSHIFT+MARGIN+1); - for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) - putchar('q'); - fputs("u\017", stdout); - - for ( y = 4+VSHIFT ; y < 4+VSHIFT+MENU_ROWS ; y++ ) - draw_row(y, sel, top, sbtop, sbbot); - - printf("\033[%d;%dH\1#1\016m", y, HSHIFT+MARGIN+1); - for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) - putchar('q'); - fputs("j\017", stdout); - - if ( edit_line && allowedit && !menu_master_passwd ) - tabmsg = messages[MSG_TAB].msg; - else - tabmsg = messages[MSG_NOTAB].msg; - - tabmsg_len = strlen(tabmsg); - - printf("\1#8\033[%d;%dH%s", - TABMSG_ROW, 1+HSHIFT+((WIDTH-tabmsg_len)>>1), tabmsg); - printf("\1#0\033[%d;1H", END_ROW); -} - -static void -clear_screen(void) -{ - fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout); -} - -static void -display_help(const char *text) -{ - int row; - const char *p; - - if (!text) { - text = ""; - printf("\1#0\033[%d;1H", HELPMSG_ROW); - } else { - printf("\2#16\033[%d;1H", HELPMSG_ROW); - } - - for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) { - switch (*p) { - case '\r': - case '\f': - case '\v': - case '\033': - break; - case '\n': - printf("\033[K\033[%d;1H", ++row); - break; - default: - putchar(*p); - } - } - - fputs("\033[K", stdout); - - while (row <= HELPMSGEND_ROW) { - printf("\033[K\033[%d;1H", ++row); - } -} - -static void show_fkey(int key) -{ - int fkey; - - while (1) { - switch (key) { - case KEY_F1: fkey = 0; break; - case KEY_F2: fkey = 1; break; - case KEY_F3: fkey = 2; break; - case KEY_F4: fkey = 3; break; - case KEY_F5: fkey = 4; break; - case KEY_F6: fkey = 5; break; - case KEY_F7: fkey = 6; break; - case KEY_F8: fkey = 7; break; - case KEY_F9: fkey = 8; break; - case KEY_F10: fkey = 9; break; - case KEY_F11: fkey = 10; break; - case KEY_F12: fkey = 11; break; - default: fkey = -1; break; - } - - if (fkey == -1) - break; - - if (fkeyhelp[fkey].textname) - key = show_message_file(fkeyhelp[fkey].textname, - fkeyhelp[fkey].background); - else - break; - } -} - -static const char * -edit_cmdline(char *input, int top) -{ - static char cmdline[MAX_CMDLINE_LEN]; - int key, len, prev_len, cursor; - int redraw = 1; /* We enter with the menu already drawn */ - - strncpy(cmdline, input, MAX_CMDLINE_LEN); - cmdline[MAX_CMDLINE_LEN-1] = '\0'; - - len = cursor = strlen(cmdline); - prev_len = 0; - - for (;;) { - if ( redraw > 1 ) { - /* Clear and redraw whole screen */ - /* Enable ASCII on G0 and DEC VT on G1; do it in this order - to avoid confusing the Linux console */ - clear_screen(); - draw_menu(-1, top, 1); - prev_len = 0; - } - - if ( redraw > 0 ) { - /* Redraw the command line */ - printf("\033[?25l\033[%d;1H\1#9> \2#10%s", - CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len))); - printf("\2#10\033[%d;3H%s\033[?25h", - CMDLINE_ROW, pad_line(cmdline, 0, cursor)); - prev_len = len; - redraw = 0; - } - - key = mygetkey(0); - - switch( key ) { - case KEY_CTRL('L'): - redraw = 2; - break; - - case KEY_ENTER: - case KEY_CTRL('J'): - return cmdline; - - case KEY_ESC: - case KEY_CTRL('C'): - return NULL; - - case KEY_BACKSPACE: - case KEY_DEL: - if ( cursor ) { - memmove(cmdline+cursor-1, cmdline+cursor, len-cursor+1); - len--; - cursor--; - redraw = 1; - } - break; - - case KEY_CTRL('D'): - case KEY_DELETE: - if ( cursor < len ) { - memmove(cmdline+cursor, cmdline+cursor+1, len-cursor); - len--; - redraw = 1; - } - break; - - case KEY_CTRL('U'): - if ( len ) { - len = cursor = 0; - cmdline[len] = '\0'; - redraw = 1; - } - break; - - case KEY_CTRL('W'): - if ( cursor ) { - int prevcursor = cursor; - - while ( cursor && my_isspace(cmdline[cursor-1]) ) - cursor--; - - while ( cursor && !my_isspace(cmdline[cursor-1]) ) - cursor--; - - memmove(cmdline+cursor, cmdline+prevcursor, len-prevcursor+1); - len -= (cursor-prevcursor); - redraw = 1; - } - break; - - case KEY_LEFT: - case KEY_CTRL('B'): - if ( cursor ) { - cursor--; - redraw = 1; - } - break; - - case KEY_RIGHT: - case KEY_CTRL('F'): - if ( cursor < len ) { - putchar(cmdline[cursor++]); - } - break; - - case KEY_CTRL('K'): - if ( cursor < len ) { - cmdline[len = cursor] = '\0'; - redraw = 1; - } - break; - - case KEY_HOME: - case KEY_CTRL('A'): - if ( cursor ) { - cursor = 0; - redraw = 1; - } - break; - - case KEY_END: - case KEY_CTRL('E'): - if ( cursor != len ) { - cursor = len; - redraw = 1; - } - break; - - case KEY_F1: - case KEY_F2: - case KEY_F3: - case KEY_F4: - case KEY_F5: - case KEY_F6: - case KEY_F7: - case KEY_F8: - case KEY_F9: - case KEY_F10: - case KEY_F11: - case KEY_F12: - show_fkey(key); - redraw = 1; - break; - - default: - if ( key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN-1 ) { - if ( cursor == len ) { - cmdline[len] = key; - cmdline[++len] = '\0'; - cursor++; - putchar(key); - prev_len++; - } else { - memmove(cmdline+cursor+1, cmdline+cursor, len-cursor+1); - cmdline[cursor++] = key; - len++; - redraw = 1; - } - } - break; - } - } -} - -static inline int -shift_is_held(void) -{ - uint8_t shift_bits = *(uint8_t *)0x417; - - return !!(shift_bits & 0x5d); /* Caps/Scroll/Alt/Shift */ -} - -static void -print_timeout_message(int tol, int row, const char *msg) -{ - char buf[256]; - int nc = 0, nnc; - const char *tp = msg; - char tc; - char *tq = buf; - - while ((size_t)(tq-buf) < (sizeof buf-16) && (tc = *tp)) { - tp++; - if (tc == '#') { - nnc = sprintf(tq, "\2#15%d\2#14", tol); - tq += nnc; - nc += nnc-8; /* 8 formatting characters */ - } else if (tc == '{') { - /* Deal with {singular[,dual],plural} constructs */ - struct { - const char *s, *e; - } tx[3]; - const char *tpp; - int n = 0; - - memset(tx, 0, sizeof tx); - - tx[0].s = tp; - - while (*tp && *tp != '}') { - if (*tp == ',' && n < 2) { - tx[n].e = tp; - n++; - tx[n].s = tp+1; - } - tp++; - } - tx[n].e = tp; - - if (*tp) - tp++; /* Skip final bracket */ - - if (!tx[1].s) - tx[1] = tx[0]; - if (!tx[2].s) - tx[2] = tx[1]; - - /* Now [0] is singular, [1] is dual, and [2] is plural, - even if the user only specified some of them. */ - - switch (tol) { - case 1: n = 0; break; - case 2: n = 1; break; - default: n = 2; break; - } - - for (tpp = tx[n].s; tpp < tx[n].e; tpp++) { - if ((size_t)(tq-buf) < (sizeof buf)) { - *tq++ = *tpp; - nc++; - } - } - } else { - *tq++ = tc; - nc++; - } - } - *tq = '\0'; - - /* Let's hope 4 spaces on each side is enough... */ - printf("\033[%d;%dH\2#14 %s ", row, HSHIFT+1+((WIDTH-nc-8)>>1), buf); -} - -static const char * -do_hidden_menu(void) -{ - int key; - int timeout_left, this_timeout; - - clear_screen(); - - if ( !setjmp(timeout_jump) ) { - timeout_left = timeout; - - while (!timeout || timeout_left) { - int tol = timeout_left/CLK_TCK; - - print_timeout_message(tol, HIDDEN_ROW, messages[MSG_AUTOBOOT].msg); - - this_timeout = min(timeout_left, CLK_TCK); - key = mygetkey(this_timeout); - - if (key != KEY_NONE) - return NULL; /* Key pressed */ - - timeout_left -= this_timeout; - } - } - - return menu_entries[defentry].cmdline; /* Default entry */ -} - -static const char * -run_menu(void) -{ - int key; - int done = 0; - volatile int entry = defentry, prev_entry = -1; - int top = 0, prev_top = -1; - int clear = 1, to_clear; - const char *cmdline = NULL; - volatile clock_t key_timeout, timeout_left, this_timeout; - - /* Note: for both key_timeout and timeout == 0 means no limit */ - timeout_left = key_timeout = timeout; - - /* If we're in shiftkey mode, exit immediately unless a shift key is pressed */ - if ( shiftkey && !shift_is_held() ) { - return menu_entries[defentry].cmdline; - } - - /* Handle hiddenmenu */ - if ( hiddenmenu ) { - cmdline = do_hidden_menu(); - if (cmdline) - return cmdline; - - /* Otherwise display the menu now; the timeout has already been - cancelled, since the user pressed a key. */ - hiddenmenu = 0; - key_timeout = 0; - } - - /* Handle both local and global timeout */ - if ( setjmp(timeout_jump) ) { - entry = defentry; - - if ( top < 0 || top < entry-MENU_ROWS+1 ) - top = max(0, entry-MENU_ROWS+1); - else if ( top > entry || top > max(0,nentries-MENU_ROWS) ) - top = min(entry, max(0,nentries-MENU_ROWS)); - - draw_menu(ontimeout ? -1 : entry, top, 1); - cmdline = ontimeout ? ontimeout : menu_entries[entry].cmdline; - done = 1; - } - - while ( !done ) { - if ( entry <= 0 ) { - entry = 0; - while ( entry < nentries && menu_entries[entry].disabled ) entry++; - } - - if ( entry >= nentries ) { - entry = nentries-1; - while ( entry > 0 && menu_entries[entry].disabled ) entry--; - } - - if ( top < 0 || top < entry-MENU_ROWS+1 ) - top = max(0, entry-MENU_ROWS+1); - else if ( top > entry || top > max(0,nentries-MENU_ROWS) ) - top = min(entry, max(0,nentries-MENU_ROWS)); - - /* Start with a clear screen */ - if ( clear ) { - /* Clear and redraw whole screen */ - /* Enable ASCII on G0 and DEC VT on G1; do it in this order - to avoid confusing the Linux console */ - clear_screen(); - clear = 0; - prev_entry = prev_top = -1; - } - - if ( top != prev_top ) { - draw_menu(entry, top, 1); - display_help(menu_entries[entry].helptext); - } else if ( entry != prev_entry ) { - draw_row(prev_entry-top+4+VSHIFT, entry, top, 0, 0); - draw_row(entry-top+4+VSHIFT, entry, top, 0, 0); - display_help(menu_entries[entry].helptext); - } - - prev_entry = entry; prev_top = top; - - /* Cursor movement cancels timeout */ - if ( entry != defentry ) - key_timeout = 0; - - if ( key_timeout ) { - int tol = timeout_left/CLK_TCK; - print_timeout_message(tol, TIMEOUT_ROW, messages[MSG_AUTOBOOT].msg); - to_clear = 1; - } else { - to_clear = 0; - } - - this_timeout = min(min(key_timeout, timeout_left), CLK_TCK); - key = mygetkey(this_timeout); - - if ( key != KEY_NONE ) { - timeout_left = key_timeout; - if ( to_clear ) - printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW); - } - - switch ( key ) { - case KEY_NONE: /* Timeout */ - /* This is somewhat hacky, but this at least lets the user - know what's going on, and still deals with "phantom inputs" - e.g. on serial ports. - - Warning: a timeout will boot the default entry without any - password! */ - if ( key_timeout ) { - if ( timeout_left <= this_timeout ) - longjmp(timeout_jump, 1); - - timeout_left -= this_timeout; - } - break; - - case KEY_CTRL('L'): - clear = 1; - break; - - case KEY_ENTER: - case KEY_CTRL('J'): - key_timeout = 0; /* Cancels timeout */ - if ( menu_entries[entry].passwd ) { - clear = 1; - done = ask_passwd(menu_entries[entry].passwd); - } else { - done = 1; - } - cmdline = menu_entries[entry].cmdline; - break; - - case KEY_UP: - case KEY_CTRL('P'): - while ( entry > 0 && entry-- && menu_entries[entry].disabled ) { - if ( entry < top ) - top -= MENU_ROWS; - } - - if ( entry == 0 ) { - while ( menu_entries[entry].disabled ) - entry++; - } - break; - - case KEY_DOWN: - case KEY_CTRL('N'): - while ( entry < nentries-1 && entry++ && menu_entries[entry].disabled ) { - if ( entry >= top+MENU_ROWS ) - top += MENU_ROWS; - } - - if ( entry == nentries-1 ) { - while ( menu_entries[entry].disabled ) - entry--; - } - break; - - case KEY_PGUP: - case KEY_LEFT: - case KEY_CTRL('B'): - case '<': - entry -= MENU_ROWS; - top -= MENU_ROWS; - break; - - case KEY_PGDN: - case KEY_RIGHT: - case KEY_CTRL('F'): - case '>': - case ' ': - entry += MENU_ROWS; - top += MENU_ROWS; - break; - - case '-': - entry--; - top--; - break; - - case '+': - entry++; - top++; - break; - - case KEY_CTRL('A'): - case KEY_HOME: - top = entry = 0; - break; - - case KEY_CTRL('E'): - case KEY_END: - entry = nentries - 1; - top = max(0, nentries-MENU_ROWS); - break; - - case KEY_F1: - case KEY_F2: - case KEY_F3: - case KEY_F4: - case KEY_F5: - case KEY_F6: - case KEY_F7: - case KEY_F8: - case KEY_F9: - case KEY_F10: - case KEY_F11: - case KEY_F12: - show_fkey(key); - clear = 1; - break; - - case KEY_TAB: - if ( allowedit ) { - int ok = 1; - - key_timeout = 0; /* Cancels timeout */ - draw_row(entry-top+4+VSHIFT, -1, top, 0, 0); - - if ( menu_master_passwd ) { - ok = ask_passwd(NULL); - clear_screen(); - draw_menu(-1, top, 0); - } else { - /* Erase [Tab] message and help text*/ - printf("\033[%d;1H\1#0\033[K", TABMSG_ROW); - display_help(NULL); - } - - if ( ok ) { - cmdline = edit_cmdline(menu_entries[entry].cmdline, top); - done = !!cmdline; - clear = 1; /* In case we hit [Esc] and done is null */ - } else { - draw_row(entry-top+4+VSHIFT, entry, top, 0, 0); - } - } - break; - case KEY_CTRL('C'): /* Ctrl-C */ - case KEY_ESC: /* Esc */ - if ( allowedit ) { - done = 1; - clear = 1; - key_timeout = 0; - - draw_row(entry-top+4+VSHIFT, -1, top, 0, 0); - - if ( menu_master_passwd ) - done = ask_passwd(NULL); - } - break; - default: - if ( key > 0 && key < 0xFF ) { - key &= ~0x20; /* Upper case */ - if ( menu_hotkeys[key] ) { - key_timeout = 0; - entry = menu_hotkeys[key] - menu_entries; - /* Should we commit at this point? */ - } - } - break; - } - } - - printf("\033[?25h"); /* Show cursor */ - - /* Return the label name so localboot and ipappend work */ - return cmdline; -} - - -static void -execute(const char *cmdline, enum kernel_type type) -{ - com32sys_t ireg; - const char *p, **pp; - char *q = __com32.cs_bounce; - const char *kernel, *args; - - memset(&ireg, 0, sizeof ireg); - - kernel = q; - p = cmdline; - while ( *p && !my_isspace(*p) ) { - *q++ = *p++; - } - *q++ = '\0'; - - args = q; - while ( *p && my_isspace(*p) ) - p++; - - strcpy(q, p); - - if (kernel[0] == '.' && type == KT_NONE) { - /* It might be a type specifier */ - enum kernel_type type = KT_NONE; - for (pp = kernel_types; *pp; pp++, type++) { - if (!strcmp(kernel+1, *pp)) { - execute(p, type); /* Strip the type specifier and retry */ - } - } - } - - if (type == KT_LOCALBOOT) { - ireg.eax.w[0] = 0x0014; /* Local boot */ - ireg.edx.w[0] = strtoul(kernel, NULL, 0); - } else { - if (type < KT_KERNEL) - type = KT_KERNEL; - - ireg.eax.w[0] = 0x0016; /* Run kernel image */ - ireg.esi.w[0] = OFFS(kernel); - ireg.ds = SEG(kernel); - ireg.ebx.w[0] = OFFS(args); - ireg.es = SEG(args); - ireg.edx.l = type-KT_KERNEL; - /* ireg.ecx.l = 0; */ /* We do ipappend "manually" */ - } - - __intcall(0x22, &ireg, NULL); - - /* If this returns, something went bad; return to menu */ -} - -int menu_main(int argc, char *argv[]) -{ - const char *cmdline; - int rows, cols; - int i; - - (void)argc; - - console_prepare(); - - install_default_color_table(); - if (getscreensize(1, &rows, &cols)) { - /* Unknown screen size? */ - rows = 24; - cols = 80; - } - - WIDTH = cols; - parse_configs(argv+1); - - /* If anyone has specified negative parameters, consider them - relative to the bottom row of the screen. */ - for (i = 0; mparm[i].name; i++) - if (mparm[i].value < 0) - mparm[i].value = max(mparm[i].value+rows, 0); - - draw_background(menu_background); - - if ( !nentries ) { - fputs("No LABEL entries found in configuration file!\n", stdout); - return 1; /* Error! */ - } - - for(;;) { - cmdline = run_menu(); - - printf("\033[?25h\033[%d;1H\033[0m", END_ROW); - console_cleanup(); - - if ( cmdline ) { - execute(cmdline, KT_NONE); - if ( onerror ) - execute(onerror, KT_NONE); - } else { - return 0; /* Exit */ - } - - console_prepare(); /* If we're looping... */ - } -} diff --git a/com32/modules/printmsg.c b/com32/modules/printmsg.c deleted file mode 100644 index 128bbc03..00000000 --- a/com32/modules/printmsg.c +++ /dev/null @@ -1,107 +0,0 @@ -#define _GNU_SOURCE /* Needed for asprintf() on Linux */ -#include <ctype.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <consoles.h> -#include <getkey.h> -#include <minmax.h> -#include <setjmp.h> -#include <limits.h> -#include <sha1.h> -#include <base64.h> -#include <colortbl.h> -#ifdef __COM32__ -#include <com32.h> -#endif - -#include "menu.h" - -static int draw_message_file(const char *filename) -{ - FILE *f; - int ch; - enum msgname_state { - st_init, /* Base state */ - st_si_1, /* <SI> digit 1 */ - st_si_2, /* <SI> digit 2 */ - st_skipline, /* Skip until NL */ - } state = st_init; - int eof = 0; - int attr = 0; - - f = fopen(filename, "r"); - if (!f) - return -1; - - /* Clear screen, hide cursor, default attribute */ - printf("\033e\033%%@\033)0\033(B\3#%03d\033[?25l\033[2J\033[H", - message_base_color+0x07); - - while (!eof && (ch = getc(f)) != EOF) { - switch (state) { - case st_init: - switch (ch) { - case '\f': - fputs("\033[2J\033[H", stdout); - break; - case 15: /* SI */ - state = st_si_1; - break; - case 24: - state = st_skipline; - break; - case 26: - eof = 1; - break; - case '\a': - case '\n': - case '\r': - putchar(ch); - break; - default: - if (ch >= 32) - putchar(ch); - break; - } - break; - - case st_si_1: - attr = hexval(ch) << 4; - state = st_si_2; - break; - - case st_si_2: - attr |= hexval(ch); - printf("\3#%03d", attr+message_base_color); - state = st_init; - break; - - case st_skipline: - if (ch == '\n') - state = st_init; - break; - } - } - - fclose(f); - return 0; -} - -int show_message_file(const char *filename, const char *background) -{ - int rv = KEY_NONE; - - if (background && (!menu_background || strcmp(background, menu_background))) - draw_background(background); - else - background = NULL; - - if ( !(rv = draw_message_file(filename)) ) - rv = mygetkey(0); /* Wait for keypress */ - - if (background) - draw_background(menu_background); - - return rv; -} diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c deleted file mode 100644 index 5de9a7da..00000000 --- a/com32/modules/readconfig.c +++ /dev/null @@ -1,793 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -#define _GNU_SOURCE /* Needed for asprintf() on Linux */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <minmax.h> -#include <alloca.h> -#include <inttypes.h> -#include <colortbl.h> -#ifdef __COM32__ -# include <com32.h> -#endif - -#include "menu.h" - -int nentries = 0; -int nhidden = 0; -int defentry = 0; -int allowedit = 1; /* Allow edits of the command line */ -int timeout = 0; -int shiftkey = 0; /* Only display menu if shift key pressed */ -int hiddenmenu = 0; -long long totaltimeout = 0; - -char *ontimeout = NULL; -char *onerror = NULL; - -char *menu_master_passwd = NULL; -char *menu_background = NULL; - -struct fkey_help fkeyhelp[12]; - -struct menu_entry menu_entries[MAX_ENTRIES]; -struct menu_entry hide_entries[MAX_ENTRIES]; -struct menu_entry *menu_hotkeys[256]; - -struct messages messages[MSG_COUNT] = { - [MSG_TITLE] = - { "title", "", NULL }, - [MSG_AUTOBOOT] = - { "autoboot", "Automatic boot in # second{,s}...", NULL }, - [MSG_TAB] = - { "tabmsg", "Press [Tab] to edit options", NULL }, - [MSG_NOTAB] = - { "notabmsg", "", NULL }, - [MSG_PASSPROMPT] = - { "passprompt", "Password required", NULL }, -}; - -#define astrdup(x) ({ char *__x = (x); \ - size_t __n = strlen(__x) + 1; \ - char *__p = alloca(__n); \ - if ( __p ) memcpy(__p, __x, __n); \ - __p; }) - -/* Must match enum kernel_type */ -const char *kernel_types[] = { - "none", - "localboot", - "kernel", - "linux", - "boot", - "bss", - "pxe", - "fdimage", - "comboot", - "com32", - "config", - NULL -}; - -const char *ipappends[32]; - -static void -get_ipappend(void) -{ -#ifdef __COM32__ - static com32sys_t r; - uint16_t *ipp; - int i; - int nipappends; - - r.eax.w[0] = 0x000F; - __intcall(0x22, &r, &r); - - nipappends = min(r.ecx.w[0], 32); - ipp = MK_PTR(r.es, r.ebx.w[0]); - for ( i = 0 ; i < nipappends ; i++ ) { - ipappends[i] = MK_PTR(r.es, *ipp++); - } -#else - ipappends[0] = "ip=foo:bar:baz:quux"; - ipappends[1] = "BOOTIF=01-aa-bb-cc-dd-ee-ff"; -#endif -} - -static const char * -get_config(void) -{ -#ifdef __COM32__ - static com32sys_t r; - - r.eax.w[0] = 0x000E; - __intcall(0x22, &r, &r); - - return MK_PTR(r.es, r.ebx.w[0]); -#else - return "syslinux.cfg"; /* Dummy default name */ -#endif -} - -#define MAX_LINE 512 - -static char * -skipspace(char *p) -{ - while (*p && my_isspace(*p)) - p++; - - return p; -} - -/* Check to see if we are at a certain keyword (case insensitive) */ -/* Returns a pointer to the first character past the keyword */ -static char * -looking_at(char *line, const char *kwd) -{ - char *p = line; - const char *q = kwd; - - while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) { - p++; - q++; - } - - if ( *q ) - return NULL; /* Didn't see the keyword */ - - return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */ -} - -struct labeldata { - char *label; - char *kernel; - enum kernel_type type; - char *append; - char *menulabel; - char *passwd; - char *helptext; - unsigned int ipappend; - unsigned int menuhide; - unsigned int menudefault; - unsigned int menuseparator; - unsigned int menudisabled; - unsigned int menuindent; -}; - -static void -record(struct labeldata *ld, char *append) -{ - char ipoptions[256], *ipp; - int i; - struct menu_entry *me = &menu_entries[nentries]; - - if ( ld->label ) { - char *a, *s; - me->displayname = ld->menulabel ? ld->menulabel : ld->label; - me->label = ld->label; - me->passwd = ld->passwd; - me->helptext = ld->helptext; - me->hotkey = 0; - me->disabled = 0; - - if ( ld->menuindent ) { - char *n = (char *)malloc(ld->menuindent + strlen(me->displayname) + 1); - memset(n, 32, ld->menuindent); - strcpy(n + ld->menuindent, me->displayname); - me->displayname = n; - } - - if ( ld->menulabel ) { - unsigned char *p = (unsigned char *)strchr(ld->menulabel, '^'); - if ( p && p[1] ) { - int hotkey = p[1] & ~0x20; - if ( !menu_hotkeys[hotkey] ) { - me->hotkey = hotkey; - } - } - } - - ipp = ipoptions; - *ipp = '\0'; - for ( i = 0 ; i < 32 ; i++ ) { - if ( (ld->ipappend & (1U << i)) && ipappends[i] ) - ipp += sprintf(ipp, " %s", ipappends[i]); - } - - a = ld->append; - if ( !a ) a = append; - if ( !a || (a[0] == '-' && !a[1]) ) a = ""; - s = a[0] ? " " : ""; - if (ld->type == KT_KERNEL) { - asprintf(&me->cmdline, "%s%s%s%s", - ld->kernel, s, a, ipoptions); - } else { - asprintf(&me->cmdline, ".%s %s%s%s%s", - kernel_types[ld->type], ld->kernel, s, a, ipoptions); - } - - if ( ld->menuseparator ) - me->displayname = ""; - - if ( ld->menuseparator || ld->menudisabled ) { - me->label = NULL; - me->passwd = NULL; - me->disabled = 1; - - if ( me->cmdline ) - free(me->cmdline); - - me->cmdline = NULL; - } - - ld->label = NULL; - ld->passwd = NULL; - - free(ld->kernel); - ld->kernel = NULL; - - if ( ld->append ) { - free(ld->append); - ld->append = NULL; - } - - if ( !ld->menuhide ) { - if ( me->hotkey ) - menu_hotkeys[me->hotkey] = me; - - if ( ld->menudefault && !ld->menudisabled && !ld->menuseparator ) - defentry = nentries; - - nentries++; - } - else { - hide_entries[nhidden].displayname = me->displayname; - hide_entries[nhidden].label = me->label; - hide_entries[nhidden].cmdline = me->cmdline; - hide_entries[nhidden].passwd = me->passwd; - - me->displayname = NULL; - me->label = NULL; - me->cmdline = NULL; - me->passwd = NULL; - - nhidden++; - } - } -} - -static char * -unlabel(char *str) -{ - /* Convert a CLI-style command line to an executable command line */ - const char *p; - char *q; - struct menu_entry *me; - int i, pos; - - p = str; - while ( *p && !my_isspace(*p) ) - p++; - - /* p now points to the first byte beyond the kernel name */ - pos = p-str; - - for ( i = 0 ; i < nentries ; i++ ) { - me = &menu_entries[i]; - - if ( !strncmp(str, me->label, pos) && !me->label[pos] ) { - /* Found matching label */ - q = malloc(strlen(me->cmdline) + strlen(p) + 1); - strcpy(q, me->cmdline); - strcat(q, p); - - free(str); - - return q; - } - } - - for ( i = 0 ; i < nhidden ; i++ ) { - me = &hide_entries[i]; - - if ( !strncmp(str, me->label, pos) && !me->label[pos] ) { - /* Found matching label */ - q = malloc(strlen(me->cmdline) + strlen(p) + 1); - strcpy(q, me->cmdline); - strcat(q, p); - - free(str); - - return q; - } - } - - return str; -} - -static char * -dup_word(char **p) -{ - char *sp = *p; - char *ep = sp; - char *dp; - size_t len; - - while (*ep && !my_isspace(*ep)) - ep++; - - *p = ep; - len = ep-sp; - - dp = malloc(len+1); - memcpy(dp, sp, len); - dp[len] = '\0'; - - return dp; -} - -int my_isxdigit(char c) -{ - unsigned int uc = c; - - return (uc-'0') < 10 || - ((uc|0x20)-'a') < 6; -} - -unsigned int hexval(char c) -{ - unsigned char uc = c | 0x20; - unsigned int v; - - v = uc-'0'; - if (v < 10) - return v; - - return uc-'a'+10; -} - -unsigned int hexval2(const char *p) -{ - return (hexval(p[0]) << 4)+hexval(p[1]); -} - -uint32_t parse_argb(char **p) -{ - char *sp = *p; - char *ep; - uint32_t argb; - size_t len, dl; - - if (*sp == '#') - sp++; - - ep = sp; - - while (my_isxdigit(*ep)) - ep++; - - *p = ep; - len = ep-sp; - - switch(len) { - case 3: /* #rgb */ - argb = - 0xff000000 + - (hexval(sp[0])*0x11 << 16) + - (hexval(sp[1])*0x11 << 8) + - (hexval(sp[2])*0x11); - break; - case 4: /* #argb */ - argb = - (hexval(sp[0])*0x11 << 24) + - (hexval(sp[1])*0x11 << 16) + - (hexval(sp[2])*0x11 << 8) + - (hexval(sp[3])*0x11); - break; - case 6: /* #rrggbb */ - case 9: /* #rrrgggbbb */ - case 12: /* #rrrrggggbbbb */ - dl = len/3; - argb = - 0xff000000 + - (hexval2(sp+0) << 16) + - (hexval2(sp+dl) << 8) + - hexval2(sp+dl*2); - break; - case 8: /* #aarrggbb */ - /* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb, - assume the latter is a more common format */ - case 16: /* #aaaarrrrggggbbbb */ - dl = len/4; - argb = - (hexval2(sp+0) << 24) + - (hexval2(sp+dl) << 16) + - (hexval2(sp+dl*2) << 8) + - hexval2(sp+dl*3); - break; - default: - argb = 0xffff0000; /* Bright red (error indication) */ - break; - } - - return argb; -} - -/* - * Parser state. This is global so that including multiple - * files work as expected, which is that everything works the - * same way as if the files had been concatenated together. - */ -static char *append = NULL; -static unsigned int ipappend = 0; -static struct labeldata ld; - -static int parse_one_config(const char *filename); - -static char *is_kernel_type(char *cmdstr, enum kernel_type *type) -{ - const char **p; - char *q; - enum kernel_type t = KT_NONE; - - for (p = kernel_types; *p; p++, t++) { - if ((q = looking_at(cmdstr, *p))) { - *type = t; - return q; - } - } - - return NULL; -} - -static char *is_message_name(char *cmdstr, struct messages **msgptr) -{ - char *q; - int i; - - for (i = 0; i < MSG_COUNT; i++) { - if ((q = looking_at(cmdstr, messages[i].name))) { - *msgptr = &messages[i]; - return q; - } - } - - return NULL; -} - -static char *is_fkey(char *cmdstr, int *fkeyno) -{ - char *q; - int no; - - if ((cmdstr[0]|0x20) != 'f') - return NULL; - - no = strtoul(cmdstr+1, &q, 10); - if (!my_isspace(*q)) - return NULL; - - if (no < 0 || no > 12) - return NULL; - - *fkeyno = (no == 0) ? 10 : no-1; - return q; -} - -static void parse_config_file(FILE *f) -{ - char line[MAX_LINE], *p, *ep, ch; - enum kernel_type type; - struct messages *msgptr; - int fkeyno; - - while ( fgets(line, sizeof line, f) ) { - p = strchr(line, '\r'); - if ( p ) - *p = '\0'; - p = strchr(line, '\n'); - if ( p ) - *p = '\0'; - - p = skipspace(line); - - if ( looking_at(p, "menu") ) { - p = skipspace(p+4); - - if ( looking_at(p, "label") ) { - if ( ld.label ) - ld.menulabel = strdup(skipspace(p+5)); - } else if ( looking_at(p, "default") ) { - ld.menudefault = 1; - } else if ( looking_at(p, "hide") ) { - ld.menuhide = 1; - } else if ( looking_at(p, "passwd") ) { - ld.passwd = strdup(skipspace(p+6)); - } else if ( looking_at(p, "shiftkey") ) { - shiftkey = 1; - } else if ( looking_at(p, "onerror") ) { - onerror = strdup(skipspace(p+7)); - } else if ( looking_at(p, "master") ) { - p = skipspace(p+6); - if ( looking_at(p, "passwd") ) { - menu_master_passwd = strdup(skipspace(p+6)); - } - } else if ( (ep = looking_at(p, "include")) ) { - p = skipspace(ep); - parse_one_config(p); - } else if ( (ep = looking_at(p, "background")) ) { - p = skipspace(ep); - if (menu_background) - free(menu_background); - menu_background = dup_word(&p); - } else if ( (ep = looking_at(p, "hidden")) ) { - hiddenmenu = 1; - } else if ( (ep = is_message_name(p, &msgptr)) ) { - free(msgptr->msg); - msgptr->msg = strdup(skipspace(ep)); - } else if ((ep = looking_at(p, "color")) || - (ep = looking_at(p, "colour"))) { - int i; - struct color_table *cptr; - p = skipspace(ep); - cptr = console_color_table; - for ( i = 0; i < console_color_table_size; i++ ) { - if ( (ep = looking_at(p, cptr->name)) ) { - p = skipspace(ep); - if (*p) { - if (looking_at(p, "*")) { - p++; - } else { - free((void *)cptr->ansi); - cptr->ansi = dup_word(&p); - } - - p = skipspace(p); - if (*p) { - if (looking_at(p, "*")) - p++; - else - cptr->argb_fg = parse_argb(&p); - - p = skipspace(p); - if (*p) { - if (looking_at(p, "*")) - p++; - else - cptr->argb_bg = parse_argb(&p); - - /* Parse a shadow mode */ - p = skipspace(p); - ch = *p | 0x20; - if (ch == 'n') /* none */ - cptr->shadow = SHADOW_NONE; - else if (ch == 's') /* std, standard */ - cptr->shadow = SHADOW_NORMAL; - else if (ch == 'a') /* all */ - cptr->shadow = SHADOW_ALL; - else if (ch == 'r') /* rev, reverse */ - cptr->shadow = SHADOW_REVERSE; - } - } - } - break; - } - cptr++; - } - } else if ((ep = looking_at(p, "msgcolor")) || - (ep = looking_at(p, "msgcolour"))) { - unsigned int fg_mask = MSG_COLORS_DEF_FG; - unsigned int bg_mask = MSG_COLORS_DEF_BG; - enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW; - - p = skipspace(ep); - if (*p) { - if (!looking_at(p, "*")) - fg_mask = parse_argb(&p); - - p = skipspace(p); - if (*p) { - if (!looking_at(p, "*")) - bg_mask = parse_argb(&p); - - p = skipspace(p); - switch (*p | 0x20) { - case 'n': - shadow = SHADOW_NONE; - break; - case 's': - shadow = SHADOW_NORMAL; - break; - case 'a': - shadow = SHADOW_ALL; - break; - case 'r': - shadow = SHADOW_REVERSE; - break; - default: - /* go with default */ - break; - } - } - } - set_msg_colors_global(fg_mask, bg_mask, shadow); - } else if ( looking_at(p, "separator") ) { - record(&ld, append); - memset(&ld, 0, sizeof(struct labeldata)); - ld.label = ""; - ld.menuseparator = 1; - record(&ld, append); - memset(&ld, 0, sizeof(struct labeldata)); - } else if ( looking_at(p, "disable") || - looking_at(p, "disabled")) { - ld.menudisabled = 1; - } else if ( looking_at(p, "indent") ) { - ld.menuindent = atoi(skipspace(p+6)); - } else { - /* Unknown, check for layout parameters */ - struct menu_parameter *pp; - for ( pp = mparm ; pp->name ; pp++ ) { - if ( (ep = looking_at(p, pp->name)) ) { - pp->value = atoi(skipspace(ep)); - break; - } - } - } - } else if ( looking_at(p, "text") ) { - enum text_cmd { - TEXT_UNKNOWN, - TEXT_HELP - } cmd = TEXT_UNKNOWN; - int len = ld.helptext ? strlen(ld.helptext) : 0; - int xlen; - - p = skipspace(p+4); - - if (looking_at(p, "help")) - cmd = TEXT_HELP; - - while ( fgets(line, sizeof line, f) ) { - p = skipspace(line); - if (looking_at(p, "endtext")) - break; - - xlen = strlen(line); - - switch (cmd) { - case TEXT_UNKNOWN: - break; - case TEXT_HELP: - ld.helptext = realloc(ld.helptext, len+xlen+1); - memcpy(ld.helptext+len, line, xlen+1); - len += xlen; - break; - } - } - } else if ( (ep = is_fkey(p, &fkeyno)) ) { - p = skipspace(ep); - if (fkeyhelp[fkeyno].textname) { - free((void *)fkeyhelp[fkeyno].textname); - fkeyhelp[fkeyno].textname = NULL; - } - if (fkeyhelp[fkeyno].background) { - free((void *)fkeyhelp[fkeyno].background); - fkeyhelp[fkeyno].background = NULL; - } - - fkeyhelp[fkeyno].textname = dup_word(&p); - if (*p) { - p = skipspace(p); - fkeyhelp[fkeyno].background = dup_word(&p); - } - } else if ( (ep = looking_at(p, "include")) ) { - p = skipspace(ep); - parse_one_config(p); - } else if ( looking_at(p, "append") ) { - char *a = strdup(skipspace(p+6)); - if ( ld.label ) - ld.append = a; - else - append = a; - } else if ( looking_at(p, "label") ) { - p = skipspace(p+5); - record(&ld, append); - ld.label = strdup(p); - ld.kernel = strdup(p); - ld.type = KT_KERNEL; - ld.passwd = NULL; - ld.append = NULL; - ld.menulabel = NULL; - ld.helptext = NULL; - ld.ipappend = ipappend; - ld.menudefault = ld.menuhide = ld.menuseparator = - ld.menudisabled = ld.menuindent = 0; - } else if ( (ep = is_kernel_type(p, &type)) ) { - if ( ld.label ) { - free(ld.kernel); - ld.kernel = strdup(skipspace(ep)); - ld.type = type; - } - } else if ( looking_at(p, "timeout") ) { - timeout = (atoi(skipspace(p+7))*CLK_TCK+9)/10; - } else if ( looking_at(p, "totaltimeout") ) { - totaltimeout = (atoll(skipspace(p+13))*CLK_TCK+9)/10; - } else if ( looking_at(p, "ontimeout") ) { - ontimeout = strdup(skipspace(p+9)); - } else if ( looking_at(p, "allowoptions") ) { - allowedit = atoi(skipspace(p+12)); - } else if ( looking_at(p, "ipappend") ) { - if (ld.label) - ld.ipappend = atoi(skipspace(p+8)); - else - ipappend = atoi(skipspace(p+8)); - } - } -} - -static int parse_one_config(const char *filename) -{ - FILE *f; - - if (!strcmp(filename, "~")) - filename = get_config(); - - f = fopen(filename, "r"); - if ( !f ) - return -1; - - parse_config_file(f); - fclose(f); - - return 0; -} - -void parse_configs(char **argv) -{ - const char *filename; - int i; - - /* Initialize defaults */ - - for (i = 0; i < MSG_COUNT; i++) { - if (messages[i].msg) - free(messages[i].msg); - messages[i].msg = strdup(messages[i].defmsg); - } - - /* Other initialization */ - - get_ipappend(); - memset(&ld, 0, sizeof(struct labeldata)); - - /* Actually process the files */ - - if ( !*argv ) { - parse_one_config("~"); - } else { - while ( (filename = *argv++) ) - parse_one_config(filename); - } - - /* On final EOF process the last label statement */ - - record(&ld, append); - - /* Common postprocessing */ - - if ( ontimeout ) - ontimeout = unlabel(ontimeout); - if ( onerror ) - onerror = unlabel(onerror); -} diff --git a/com32/modules/vesamenu.c b/com32/modules/vesamenu.c deleted file mode 100644 index 495cfb82..00000000 --- a/com32/modules/vesamenu.c +++ /dev/null @@ -1,53 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * vesamenu.c - * - * Simple menu system which displays a list and allows the user to select - * a command line and/or edit it. - * - * VESA graphics version. - */ - -#include <stdio.h> -#include <console.h> -#include <syslinux/vesacon.h> - -#include "menu.h" - -void console_prepare(void) -{ - fputs("\033[0m\033[20h\033[25l", stdout); -} - -void console_cleanup(void) -{ - /* For the serial console, be nice and clean up */ - fputs("\033[0m\033[20l", stdout); -} - -int draw_background(const char *what) -{ - if (!what) - return vesacon_default_background(); - else if (what[0] == '#') - return vesacon_set_background(parse_argb((char **)&what)); - else - return vesacon_load_background(what); -} - -int main(int argc, char *argv[]) -{ - openconsole(&dev_rawcon_r, &dev_vesaserial_w); - return menu_main(argc, argv); -} |