summaryrefslogtreecommitdiff
path: root/com32/modules
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-10 22:26:06 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-10 22:26:06 -0800
commit9fd7fad275a23cdfad680f56d1199acab675ef2a (patch)
treef1f70293c6f78c8e4a433cdbe95a3b4f942a4bb6 /com32/modules
parent55bf6f17d1e646580342bda77d15878e293faad7 (diff)
downloadsyslinux-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/Makefile16
-rw-r--r--com32/modules/menu.c44
-rw-r--r--com32/modules/menu.h143
-rw-r--r--com32/modules/menumain.c1230
-rw-r--r--com32/modules/printmsg.c107
-rw-r--r--com32/modules/readconfig.c793
-rw-r--r--com32/modules/vesamenu.c53
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);
-}