summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2004-12-21 01:37:43 +0000
committerhpa <hpa>2004-12-21 01:37:43 +0000
commit8d6c07657b1bb3c990a38af4132a424e5033d5f2 (patch)
treeece3f595b10d2d00e6f1f2521aa2549e23f3b52c
parent02b5962d945dcc7a81ba6da1dfb7590f4030244c (diff)
downloadsyslinux-8d6c07657b1bb3c990a38af4132a424e5033d5f2.tar.gz
More work on menu module. Looks like the file libc isn't quite there
yet; however, debugging needed.
-rw-r--r--com32/lib/Makefile2
-rw-r--r--com32/libutil/ansiraw.c2
-rw-r--r--com32/modules/Makefile6
-rw-r--r--com32/modules/menu.c62
-rw-r--r--com32/modules/menu.h44
-rw-r--r--com32/modules/readconfig.c170
6 files changed, 243 insertions, 43 deletions
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 8ba4220e..522761b5 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -13,7 +13,7 @@ LIBOBJS = abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o \
strntoimax.o strntoumax.o strrchr.o strsep.o strspn.o strstr.o \
strtoimax.o strtok.o strtol.o strtoll.o strtoul.o strtoull.o \
strtoumax.o vfprintf.o vprintf.o vsnprintf.o vsprintf.o \
- asprintf.o vasprintf.o \
+ asprintf.o vasprintf.o strlcpy.o strlcat.o \
vsscanf.o libgcc/__ashldi3.o libgcc/__udivdi3.o \
libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o \
libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o \
diff --git a/com32/libutil/ansiraw.c b/com32/libutil/ansiraw.c
index 1a0820d3..8761b596 100644
--- a/com32/libutil/ansiraw.c
+++ b/com32/libutil/ansiraw.c
@@ -86,7 +86,7 @@ void console_ansi_raw(void)
tio.c_lflag &= ~(ISIG|ICANON|ECHO);
tio.c_cc[VMIN] = 0;
tio.c_cc[VTIME] = 1; /* Don't 100% busy-wait in Linux */
- tcsetattr(0, TCSANOW, &tio);
+ tcsetattr(0, TCSAFLUSH, &tio);
fputs("\033[0m\033[20h", stdout);
}
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 4b6f335e..570ec9c0 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -76,6 +76,12 @@ all: $(MODULES)
%.c32: %.elf
$(OBJCOPY) -O binary $< $@
+menu.elf : menu.o readconfig.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
index 6757a9f9..e3dace2f 100644
--- a/com32/modules/menu.c
+++ b/com32/modules/menu.c
@@ -29,21 +29,7 @@
#include <com32.h>
#endif
-struct menu_entry {
- char *displayname;
- char *cmdline;
-};
-
-#define MAX_CMDLINE_LEN 256
-
-#define MAX_ENTRIES 4096 /* Oughta be enough for anybody */
-struct menu_entry menu_entries[MAX_ENTRIES];
-
-int nentries = 0;
-int defentry = 0;
-int allowedit = 1; /* Allow edits of the command line */
-
-char *menu_title = "This is the menu title";
+#include "menu.h"
struct menu_attrib {
const char *border; /* Border area */
@@ -145,15 +131,6 @@ void draw_menu(int sel, int top)
if ( allowedit )
printf("%s\033[%d;1H%s", menu_attrib->tabmsg, TABMSG_ROW,
pad_line("Press [Tab] to edit options", 1, WIDTH));
-
- /* sel == -1 is a valid way of saying "draw nothing" */
- if ( sel >= 0 ) {
- printf("\033[%d;1H%s> %s%s\033[%d;1H",
- CMDLINE_ROW, menu_attrib->cmdmark,
- menu_attrib->cmdline,
- pad_line(menu_entries[sel].cmdline, 0, 255),
- END_ROW);
- }
}
char *edit_cmdline(char *input)
@@ -242,7 +219,7 @@ const char *run_menu(void)
entry = nentries-1;
if ( top < 0 || top < entry-MENU_ROWS+1 )
- top = max(0,entry-MENU_ROWS+1);
+ top = max(0, entry-MENU_ROWS+1);
else if ( top > entry )
top = entry;
@@ -284,21 +261,24 @@ const char *run_menu(void)
top++;
break;
case KEY_TAB:
- draw_menu(-1, top); /* Disable bar */
- cmdline = edit_cmdline(menu_entries[entry].cmdline);
- if ( cmdline )
- return cmdline;
+ if ( allowedit ) {
+ draw_menu(-1, top); /* Disable bar */
+ cmdline = edit_cmdline(menu_entries[entry].cmdline);
+ if ( cmdline )
+ return cmdline;
+ }
break;
case KEY_CTRL('C'): /* Ctrl-C */
case KEY_ESC: /* Esc */
- exit(1); /* FIX THIS... do something sane here */
+ if ( allowedit )
+ return NULL;
default:
break;
}
}
- printf("\033[%d;1H\033[0m", END_ROW);
- return menu_entries[defentry].cmdline;
+ /* Return the label name so localboot and ipappend work */
+ return menu_entries[entry].displayname;
}
@@ -320,21 +300,21 @@ void __attribute__((noreturn)) execute(const char *cmdline)
#endif
}
-int main(void)
+int main(int argc, char *argv[])
{
const char *cmdline;
- int i;
- console_ansi_raw();
+ (void)argc;
+ console_ansi_raw();
fputs("\033%@\033(U", stdout); /* Enable CP 437 graphics on a real console */
- for ( i = 1 ; i < 30 ; i++ ) {
- asprintf(&menu_entries[nentries].displayname, "entry %2d", i);
- asprintf(&menu_entries[nentries].cmdline, "runentry n=%d", i);
- nentries++;
- }
+ parse_config(argv[1]);
cmdline = run_menu();
- execute(cmdline);
+ printf("\033[%d;1H\033[0m", END_ROW);
+ if ( cmdline )
+ execute(cmdline);
+ else
+ return 0;
}
diff --git a/com32/modules/menu.h b/com32/modules/menu.h
new file mode 100644
index 00000000..e892a124
--- /dev/null
+++ b/com32/modules/menu.h
@@ -0,0 +1,44 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2004 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 menu project
+ */
+
+#ifndef MENU_H
+#define MENU_H
+
+struct menu_entry {
+ char *displayname;
+ char *cmdline;
+};
+
+#define MAX_CMDLINE_LEN 256
+
+#define MAX_ENTRIES 4096 /* Oughta be enough for anybody */
+extern struct menu_entry menu_entries[];
+
+extern int nentries;
+extern int defentry;
+extern int allowedit;
+extern int timeout;
+
+extern char *menu_title;
+extern char *ontimeout;
+
+void parse_config(const char *filename);
+
+#endif /* MENU_H */
+
diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c
new file mode 100644
index 00000000..dec0ae52
--- /dev/null
+++ b/com32/modules/readconfig.c
@@ -0,0 +1,170 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2004 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 <alloca.h>
+#ifdef __COM32__
+# include <com32.h>
+#endif
+
+#include "menu.h"
+
+int nentries = 0;
+int defentry = 0;
+int allowedit = 1; /* Allow edits of the command line */
+int timeout = 0;
+
+char *menu_title = "";
+char *ontimeout = NULL;
+
+struct menu_entry menu_entries[MAX_ENTRIES];
+
+#define astrdup(x) ({ char *__x = (x); \
+ size_t __n = strlen(__x) + 1; \
+ char *__p = alloca(__n); \
+ if ( __p ) memcpy(__p, __x, __n); \
+ __p; })
+
+
+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 && *p <= ' ' )
+ p++;
+
+ return p;
+}
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+static int looking_at(const char *line, const char *kwd)
+{
+ const char *p = line;
+ const char *q = kwd;
+
+ while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) {
+ p++;
+ q++;
+ }
+
+ if ( *q )
+ return 0; /* Didn't see the keyword */
+
+ return *p <= ' '; /* Must be EOL or whitespace */
+}
+
+static void record(char *label, char *lkernel, char *lappend, char *append)
+{
+ if ( label ) {
+ char *a, *s;
+ menu_entries[nentries].displayname = label;
+ a = lappend;
+ if ( !a ) a = append;
+ if ( !a || (a[0] == '-' && !a[1]) ) a = "";
+ s = a[0] ? " " : "";
+ asprintf(&menu_entries[nentries].cmdline, "%s%s%s", lkernel, s, a);
+
+ printf("displayname: %s\n", menu_entries[nentries].displayname);
+ printf("cmdline: %s\n", menu_entries[nentries].cmdline);
+
+ label = NULL;
+ free(lkernel);
+ if ( lappend )
+ free(lappend);
+ nentries++;
+ }
+}
+
+void parse_config(const char *filename)
+{
+ char line[MAX_LINE], *p;
+ FILE *f;
+ char *append = NULL;
+ char *label = NULL, *lkernel = NULL, *lappend = NULL;
+
+ if ( !filename )
+ filename = get_config();
+
+ f = fopen(filename, "r");
+ if ( !f )
+ return;
+
+ 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);
+ printf("> %s\n", p);
+
+ if ( looking_at(p, "menu") ) {
+ p = skipspace(line+4);
+
+ if ( looking_at(p, "title") ) {
+ menu_title = strdup(skipspace(p+5));
+ } else if ( looking_at(p, "default") ) {
+ defentry = atoi(skipspace(p+7));
+ } else {
+ /* Unknown, ignore for now */
+ }
+ } else if ( looking_at(p, "append") ) {
+ char *a = strdup(skipspace(p+6));
+ if ( label )
+ lappend = a;
+ else
+ append = a;
+ } else if ( looking_at(p, "label") ) {
+ p = skipspace(p+5);
+ record(label, lkernel, lappend, append);
+ label = strdup(p);
+ lkernel = strdup(p);
+ lappend = NULL;
+ } else if ( looking_at(p, "kernel") ) {
+ if ( label ) {
+ free(lkernel);
+ lkernel = strdup(skipspace(p+6));
+ }
+ } else if ( looking_at(p, "timeout") ) {
+ timeout = atoi(skipspace(p+7));
+ } else if ( looking_at(p, "ontimeout") ) {
+ ontimeout = strdup(skipspace(p+9));
+ } else if ( looking_at(p, "allowoptions") ) {
+ allowedit = atoi(skipspace(p+12));
+ }
+ }
+
+ record(label, lkernel, lappend, append);
+ fclose(f);
+}