Peter,
Paulo reported some problems with his config files under ISOLINUX and
PXELINUX - basically TIMEOUT and TOTALTIMEOUT were broken. The patches
I've pushed to the elflink branch fix this and also fix parsing of the
ALLOWOPTIONS config directive.
The following changes since commit d5e02fb16a11bfdbce1e90a39e6cb5f2ad925389:
get_key: Valid key values are positive (2012-04-17 11:25:53 -0700)
are available in the git repository at:
git://git.zytor.com/users/mfleming/syslinux.git elflink
Matt Fleming (3):
ldlinux: Don't drop args if we auto-lookup cmd extension
elflink: Fix TIMEOUT and TOTALTIMEOUT handling
ldlinux: Parse ALLOWOPTIONS directive
com32/elflink/ldlinux/cli.c | 65 ++++++++++++++++-------------------
com32/elflink/ldlinux/config.h | 1 +
com32/elflink/ldlinux/ldlinux.c | 32 +++++++++++-------
com32/elflink/ldlinux/readconfig.c | 9 +++--
com32/include/menu.h | 1 +
5 files changed, 58 insertions(+), 50 deletions(-)
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index 498644e..211a796 100644
--- a/com32/elflink/ldlinux/cli.c
+++ b/com32/elflink/ldlinux/cli.c
@@ -19,8 +19,6 @@
#include "cli.h"
#include "config.h"
-static jmp_buf timeout_jump;
-
static struct list_head cli_history_head;
void clear_screen(void)
@@ -29,46 +27,37 @@ void clear_screen(void)
fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
}
-int mygetkey(clock_t timeout)
+static int mygetkey_timeout(clock_t *kbd_to, clock_t *tto)
{
- clock_t t0, t;
- clock_t tto, to;
+ clock_t t0, t1;
int key;
- //dprintf("enter");
- if (!totaltimeout)
- return get_key(stdin, 0);
-
- for (;;) {
- tto = min(totaltimeout, INT_MAX);
- to = timeout ? min(tto, timeout) : tto;
+ t0 = times(NULL);
+ key = get_key(stdin, *kbd_to ? *kbd_to : *tto);
- t0 = 0;
- key = get_key(stdin, 0);
- t = 0 - t0;
+ /* kbdtimeout only applies to the first character */
+ if (*kbd_to)
+ *kbd_to = 0;
- if (totaltimeout <= t)
- longjmp(timeout_jump, 1);
+ t1 = times(NULL) - t0;
+ if (*tto) {
+ /* Timed out. */
+ if (*tto <= (long long)t1)
+ key = KEY_NONE;
+ else {
+ /* Did it wrap? */
+ if (*tto > totaltimeout)
+ key = KEY_NONE;
- totaltimeout -= t;
-
- if (key != KEY_NONE) {
- //dprintf("get key 0x%x", key);
- return key;
- }
-
- if (timeout) {
- if (timeout <= t) {
- //dprintf("timeout");
- return KEY_NONE;
- }
-
- timeout -= t;
+ *tto -= t1;
}
}
+
+ return key;
}
-static const char * cmd_reverse_search(int *cursor)
+static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
+ clock_t *tto)
{
int key;
int i = 0;
@@ -83,7 +72,7 @@ static const char * cmd_reverse_search(int *cursor)
eprintf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
while (1) {
- key = mygetkey(0);
+ key = mygetkey_timeout(kbd_to, tto);
if (key == KEY_CTRL('C')) {
return NULL;
@@ -140,6 +129,8 @@ const char *edit_cmdline(const char *input, int top /*, int
width */ ,
const char *ret;
int width = 0;
struct cli_command *comm_counter = NULL;
+ clock_t kbd_to = kbdtimeout;
+ clock_t tto = totaltimeout;
if (!width) {
int height;
@@ -205,9 +196,13 @@ const char *edit_cmdline(const char *input, int top /*, int
width */ ,
redraw = 0;
}
- key = mygetkey(0);
+ key = mygetkey_timeout(&kbd_to, &tto);
switch (key) {
+ case KEY_NONE:
+ /* We timed out. */
+ return NULL;
+
case KEY_CTRL('L'):
redraw = 2;
break;
@@ -381,7 +376,7 @@ const char *edit_cmdline(const char *input, int top /*, int
width */ ,
* Handle this case in another function, since it's
* a kind of special.
*/
- const char *p = cmd_reverse_search(&cursor);
+ const char *p = cmd_reverse_search(&cursor, &kbd_to,
&tto);
if (p) {
strcpy(cmdline, p);
len = strlen(cmdline);
diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h
index cab4c70..b15a082 100644
--- a/com32/elflink/ldlinux/config.h
+++ b/com32/elflink/ldlinux/config.h
@@ -35,6 +35,7 @@ extern short nohalt; //idle.inc
extern const char *default_cmd; //"default" command line
extern const char *onerror; //"onerror" command line
+extern const char *ontimeout; //"ontimeout" command line
extern void cat_help_file(int key);
extern struct menu_entry *find_label(const char *str);
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index da93c54..f11a65c 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -124,7 +124,7 @@ static const char *apply_extension(const char *kernel, const
char *ext)
/* Copy the rest of the command line */
strcpy(k + len + elen, p);
- k[len + elen] = '\0';
+ k[len + elen + strlen(p)] = '\0';
return k;
}
@@ -164,6 +164,12 @@ static void load_kernel(const char *command_line)
if (!allowimplicit)
goto bad_implicit;
+ /* Insert a null character to ignore any user-specified options */
+ if (!allowoptions) {
+ char *p = (char *)find_command(kernel);
+ *p = '\0';
+ }
+
type = parse_kernel_type(kernel);
if (type == KT_KERNEL) {
const char *ext;
@@ -209,16 +215,12 @@ static void enter_cmdline(void)
/* Enter endless command line prompt, should support "exit" */
while (1) {
cmdline = edit_cmdline("syslinux$", 1, NULL, cat_help_file);
- if (!cmdline)
- continue;
-
- /* return if user only press enter */
- if (cmdline[0] == '\0') {
- printf("\n");
- continue;
- }
printf("\n");
+ /* return if user only press enter or we timed out */
+ if (!cmdline || cmdline[0] == '\0')
+ return;
+
load_kernel(cmdline);
}
}
@@ -226,6 +228,7 @@ static void enter_cmdline(void)
int main(int argc __unused, char **argv __unused)
{
const void *adv;
+ const char *cmdline;
size_t count = 0;
char *config_argv[2] = { NULL, NULL };
@@ -242,7 +245,6 @@ int main(int argc __unused, char **argv __unused)
* We apparently have a boot-once set; clear it and
* then execute the boot-once.
*/
- const char *cmdline;
char *src, *dst;
size_t i;
@@ -270,12 +272,14 @@ int main(int argc __unused, char **argv __unused)
if (forceprompt)
goto cmdline;
+ cmdline = default_cmd;
+auto_boot:
/*
* Auto boot
*/
if (defaultlevel || noescape) {
if (defaultlevel) {
- load_kernel(default_cmd); /* Shouldn't return */
+ load_kernel(cmdline); /* Shouldn't return */
} else {
printf("No DEFAULT or UI configuration directive found!\n");
@@ -285,8 +289,12 @@ int main(int argc __unused, char **argv __unused)
}
cmdline:
- /* Should never return */
+ /* Only returns if the user pressed enter or input timed out */
enter_cmdline();
+ cmdline = ontimeoutlen ? ontimeout : default_cmd;
+
+ goto auto_boot;
+
return 0;
}
diff --git a/com32/elflink/ldlinux/readconfig.c
b/com32/elflink/ldlinux/readconfig.c
index 70fe346..1a8434c 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -68,6 +68,7 @@ short nohalt = 1; //idle.inc
const char *default_cmd = NULL; //"default" command line
const char *onerror = NULL; //"onerror" command line
+const char *ontimeout = NULL; //"ontimeout" command line
/* Empty refstring */
const char *empty_string;
@@ -79,6 +80,7 @@ struct menu *root_menu, *start_menu, *hide_menu, *menu_list,
*default_menu;
int shiftkey = 0; /* Only display menu if shift key pressed */
int hiddenmenu = 0;
long long totaltimeout = 0;
+unsigned int kbdtimeout = 0;
/* Keep track of global default */
static int has_ui = 0; /* DEFAULT only counts if UI is found */
@@ -1081,13 +1083,14 @@ do_include:
//dprintf("got a kernel: %s, type = %d", ld.kernel, ld.type);
}
} else if (looking_at(p, "timeout")) {
- m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
+ kbdtimeout = (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")) {
- m->ontimeout = refstrdup(skipspace(p + 9));
+ ontimeout = refstrdup(skipspace(p + 9));
+ ontimeoutlen = strlen(ontimeout);
} else if (looking_at(p, "allowoptions")) {
- m->allowedit = !!atoi(skipspace(p + 12));
+ allowoptions = !!atoi(skipspace(p + 12));
} else if (looking_at(p, "ipappend")) {
if (ld.label)
ld.ipappend = atoi(skipspace(p + 8));
diff --git a/com32/include/menu.h b/com32/include/menu.h
index 1db4d7c..ba6b9ce 100644
--- a/com32/include/menu.h
+++ b/com32/include/menu.h
@@ -187,6 +187,7 @@ extern int shiftkey;
extern int hiddenmenu;
extern int clearmenu;
extern long long totaltimeout;
+extern clock_t kbdtimeout;
extern const char *hide_key[KEY_MAX];
void parse_configs(char **argv);