176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ----------------------------------------------------------------------- *
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Copyright 2009-2013 Intel Corporation; author: H. Peter Anvin
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   This program is free software; you can redistribute it and/or modify
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   it under the terms of the GNU General Public License as published by
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Boston MA 02110-1301, USA; either version 2 of the License, or
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   (at your option) any later version; incorporated herein by reference.
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ----------------------------------------------------------------------- */
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <sys/io.h>
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <fcntl.h>
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h>
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdbool.h>
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h>
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h>
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <minmax.h>
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <alloca.h>
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <inttypes.h>
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <colortbl.h>
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <com32.h>
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/adv.h>
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/config.h>
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <dprintf.h>
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <ctype.h>
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <bios.h>
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <core.h>
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <fs.h>
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/pxe_api.h>
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "menu.h"
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "config.h"
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "getkey.h"
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "core.h"
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "fs.h"
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst struct menu_parameter mparm[NPARAMS] = {
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_WIDTH] = {"width", 0},
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_MARGIN] = {"margin", 10},
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_MENU_ROWS] = {"rows", 12},
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_TABMSG_ROW] = {"tabmsgrow", 18},
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_END_ROW] = {"endrow", -1},
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_PASSWD_ROW] = {"passwordrow", 11},
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_HSHIFT] = {"hshift", 0},
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_VSHIFT] = {"vshift", 0},
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [P_HIDDEN_ROW] = {"hiddenrow", -2},
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Must match enum kernel_type */
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *const kernel_types[] = {
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "none",
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "localboot",
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "kernel",
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "linux",
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "boot",
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "bss",
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "pxe",
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "fdimage",
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "comboot",
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "com32",
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "config",
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    NULL
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort uappendlen = 0;		//bytes in append= command
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort ontimeoutlen = 0;		//bytes in ontimeout command
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort onerrorlen = 0;		//bytes in onerror command
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort forceprompt = 0;		//force prompt
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort noescape = 0;		//no escape
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort nocomplete = 0;		//no label completion on TAB key
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort allowimplicit = 1;	//allow implicit kernels
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort allowoptions = 1;		//user-specified options allowed
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort includelevel = 1;		//nesting level
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort defaultlevel = 0;		//the current level of default
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanshort vkernel = 0;		//have we seen any "label" statements?
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern short NoHalt;		//idle.c
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst char *onerror = NULL;	//"onerror" command line
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst char *ontimeout = NULL;	//"ontimeout" command line
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__export const char *default_cmd = NULL;	//"default" command line
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Empty refstring */
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst char *empty_string;
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Root menu, starting menu, hidden menu, and list of all menus */
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* These are global parameters regardless of which menu we're displaying */
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint shiftkey = 0;		/* Only display menu if shift key pressed */
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint hiddenmenu = 0;
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanlong long totaltimeout = 0;
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanunsigned int kbdtimeout = 0;
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Keep track of global default */
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int has_ui = 0;		/* DEFAULT only counts if UI is found */
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern const char *globaldefault;
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic bool menusave = false;	/* True if there is any "menu save" */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Linked list of all entires, hidden or not; used by unlabel() */
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu_entry *all_entries;
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu_entry **all_entries_end = &all_entries;
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const struct messages messages[MSG_COUNT] = {
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."},
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"},
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [MSG_NOTAB] = {"notabmsg", ""},
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    [MSG_PASSPROMPT] = {"passprompt", "Password required"},
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define astrdup(x) ({ char *__x = (x); \
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                      size_t __n = strlen(__x) + 1; \
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                      char *__p = alloca(__n); \
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                      if ( __p ) memcpy(__p, __x, __n); \
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                      __p; })
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Search the list of all menus for a specific label
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu *find_menu(const char *label)
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *m;
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (m = menu_list; m; m = m->next) {
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!strcmp(label, m->label))
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return m;
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return NULL;
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_LINE 4096
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Strip ^ from a string, returning a new reference to the same refstring
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if none present */
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *strip_caret(const char *str)
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *p, *r;
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *q;
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int carets = 0;
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = str;
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (;;) {
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p = strchr(p, '^');
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!p)
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	carets++;
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p++;
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (!carets)
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return refstr_get(str);
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    r = q = refstr_alloc(strlen(str) - carets);
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (p = str; *p; p++)
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (*p != '^')
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *q++ = *p;
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    *q = '\0';			/* refstr_alloc() already did this... */
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return r;
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Check to see if we are at a certain keyword (case insensitive) */
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Returns a pointer to the first character past the keyword */
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic char *looking_at(char *line, const char *kwd)
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *p = line;
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *q = kwd;
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p++;
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	q++;
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (*q)
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return NULL;		/* Didn't see the keyword */
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return my_isspace(*p) ? p : NULL;	/* Must be EOL or whitespace */
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu *new_menu(struct menu *parent,
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			     struct menu_entry *parent_entry, const char *label)
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *m = calloc(1, sizeof(struct menu));
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int i;
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	//dprintf("enter: menu_label = %s", label);
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    m->label = label;
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    m->title = refstr_get(empty_string);
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (parent) {
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Submenu */
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->parent = parent;
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->parent_entry = parent_entry;
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	parent_entry->action = MA_SUBMENU;
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	parent_entry->submenu = m;
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (i = 0; i < MSG_COUNT; i++)
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->messages[i] = refstr_get(parent->messages[i]);
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memcpy(m->mparm, parent->mparm, sizeof m->mparm);
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->allowedit = parent->allowedit;
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->timeout = parent->timeout;
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->save = parent->save;
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->ontimeout = refstr_get(parent->ontimeout);
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->onerror = refstr_get(parent->onerror);
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->menu_background = refstr_get(parent->menu_background);
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->color_table = copy_color_table(parent->color_table);
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (i = 0; i < 12; i++) {
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname);
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->fkeyhelp[i].background =
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_get(parent->fkeyhelp[i].background);
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    } else {
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Root menu */
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (i = 0; i < MSG_COUNT; i++)
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->messages[i] = refstrdup(messages[i].defmsg);
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (i = 0; i < NPARAMS; i++)
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->mparm[i] = mparm[i].value;
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->allowedit = true;	/* Allow edits of the command line */
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->color_table = default_color_table();
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    m->next = menu_list;
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    menu_list = m;
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return m;
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct labeldata {
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *label;
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *kernel;
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum kernel_type type;
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *append;
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *initrd;
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *menulabel;
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *passwd;
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *helptext;
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int ipappend;
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int menuhide;
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int menudefault;
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int menuseparator;
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int menudisabled;
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int menuindent;
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum menu_action action;
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int save;
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *submenu;
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Menu currently being parsed */
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu *current_menu;
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void clear_label_data(struct labeldata *ld)
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->label);
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->kernel);
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->append);
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->initrd);
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->menulabel);
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(ld->passwd);
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(ld, 0, sizeof *ld);
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu_entry *new_entry(struct menu *m)
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    //dprintf("enter, call from menu %s", m->label);
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (m->nentries >= m->nentries_space) {
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!m->nentries_space)
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->nentries_space = 1;
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->nentries_space <<= 1;
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->menu_entries = realloc(m->menu_entries, m->nentries_space *
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				  sizeof(struct menu_entry *));
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    me = calloc(1, sizeof(struct menu_entry));
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    me->menu = m;
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    me->entry = m->nentries;
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    m->menu_entries[m->nentries++] = me;
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    *all_entries_end = me;
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    all_entries_end = &me->next;
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return me;
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void consider_for_hotkey(struct menu *m, struct menu_entry *me)
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *p = strchr(me->displayname, '^');
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (me->action != MA_DISABLED) {
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (p && p[1]) {
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    unsigned char hotkey = p[1] & ~0x20;
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (!m->menu_hotkeys[hotkey]) {
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		me->hotkey = hotkey;
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->menu_hotkeys[hotkey] = me;
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copy a string, converting whitespace characters to underscores
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and compacting them.  Return a pointer to the final null.
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic char *copy_sysappend_string(char *dst, const char *src)
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    bool was_space = true;	/* Kill leading whitespace */
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *end = dst;
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char c;
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while ((c = *src++)) {
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (c <= ' ' && c == '\x7f') {
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (!was_space)
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		*dst++ = '_';
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    was_space = true;
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else {
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *dst++ = c;
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    end = dst;
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    was_space = false;
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    *end = '\0';
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return end;
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void record(struct menu *m, struct labeldata *ld, const char *append)
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int i;
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct menu_entry *me;
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const struct syslinux_ipappend_strings *ipappend;
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!ld->label)
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return;			/* Nothing defined */
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Hidden entries are recorded on a special "hidden menu" */
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menuhide)
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m = hide_menu;
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char ipoptions[4096], *ipp;
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char *a;
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *s;
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me = new_entry(m);
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->displayname = ld->menulabel
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ? refstr_get(ld->menulabel) : refstr_get(ld->label);
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->label = refstr_get(ld->label);
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->passwd = refstr_get(ld->passwd);
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->helptext = ld->helptext;
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->hotkey = 0;
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->action = ld->action ? ld->action : MA_CMD;
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me->save = ld->save ? (ld->save > 0) : m->save;
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menuindent) {
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    const char *dn;
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname);
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(me->displayname);
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->displayname = dn;
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menuseparator) {
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(me->displayname);
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->displayname = refstr_get(empty_string);
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menuseparator || ld->menudisabled) {
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->action = MA_DISABLED;
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(me->label);
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->label = NULL;
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(me->passwd);
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->passwd = NULL;
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menulabel)
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    consider_for_hotkey(m, me);
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch (me->action) {
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case MA_CMD:
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ipp = ipoptions;
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *ipp = '\0';
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld->initrd)
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ipp += sprintf(ipp, " initrd=%s", ld->initrd);
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld->ipappend) {
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ipappend = syslinux_ipappend_strings();
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		for (i = 0; i < ipappend->count; i++) {
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if ((ld->ipappend & (1U << i)) &&
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ipappend->ptr[i] && ipappend->ptr[i][0]) {
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			*ipp++ = ' ';
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ipp = copy_sysappend_string(ipp, ipappend->ptr[i]);
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    }
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    a = ld->append;
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (!a)
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		a = append;
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (!a || (a[0] == '-' && !a[1]))
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		a = "";
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    s = a[0] ? " " : "";
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld->type == KT_KERNEL)
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    else
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rsprintf(&me->cmdline, ".%s %s%s%s%s",
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			 kernel_types[ld->type], ld->kernel, s, a, ipoptions);
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		dprintf("type = %s, cmd = %s", kernel_types[ld->type], me->cmdline);
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case MA_GOTO_UNRES:
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case MA_EXIT_UNRES:
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->cmdline = refstr_get(ld->kernel);
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case MA_GOTO:
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case MA_EXIT:
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->submenu = ld->submenu;
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (ld->menudefault && me->action == MA_CMD)
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->defentry = m->nentries - 1;
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    clear_label_data(ld);
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu *begin_submenu(const char *tag)
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (!tag[0])
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	tag = NULL;
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    me = new_entry(current_menu);
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    me->displayname = refstrdup(tag);
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return new_menu(current_menu, me, refstr_get(me->displayname));
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct menu *end_submenu(void)
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return current_menu->parent ? current_menu->parent : current_menu;
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid print_labels(const char *prefix, size_t len)
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    printf("\n");
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (me = all_entries; me; me = me->next ) {
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!me->label)
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    continue;
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!strncmp(prefix, me->label, len))
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    printf(" %s", me->label);
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    printf("\n");
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct menu_entry *find_label(const char *str)
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *p;
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int pos;
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = str;
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (*p && !my_isspace(*p))
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p++;
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* p now points to the first byte beyond the kernel name */
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    pos = p - str;
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (me = all_entries; me; me = me->next) {
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!strncmp(str, me->label, pos) && !me->label[pos])
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return me;
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return NULL;
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *unlabel(const char *str)
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Convert a CLI-style command line to an executable command line */
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *p;
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *q;
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int pos;
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = str;
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (*p && !my_isspace(*p))
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p++;
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* p now points to the first byte beyond the kernel name */
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    pos = p - str;
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (me = all_entries; me; me = me->next) {
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!strncmp(str, me->label, pos) && !me->label[pos]) {
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* Found matching label */
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    rsprintf(&q, "%s%s", me->cmdline, p);
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(str);
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return q;
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return str;
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *__refdup_word(char *p, char **ref)
53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *sp = p;
53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *ep = sp;
53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (*ep && !my_isspace(*ep))
53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ep++;
54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (ref)
54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	*ref = ep;
54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return refstrndup(sp, ep - sp);
54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *refdup_word(char **p)
54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return __refdup_word(*p, p);
54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint my_isxdigit(char c)
55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int uc = c;
55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6;
55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanunsigned int hexval(char c)
55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned char uc = c | 0x20;
56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    unsigned int v;
56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    v = uc - '0';
56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (v < 10)
56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return v;
56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return uc - 'a' + 10;
56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanunsigned int hexval2(const char *p)
57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return (hexval(p[0]) << 4) + hexval(p[1]);
57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanuint32_t parse_argb(char **p)
57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *sp = *p;
57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *ep;
57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t argb;
58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    size_t len, dl;
58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (*sp == '#')
58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	sp++;
58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    ep = sp;
58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (my_isxdigit(*ep))
58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ep++;
58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    *p = ep;
59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    len = ep - sp;
59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    switch (len) {
59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 3:			/* #rgb */
59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argb =
59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    0xff000000 +
59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval(sp[0]) * 0x11 << 16) +
59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11);
59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	break;
60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 4:			/* #argb */
60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argb =
60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval(sp[0]) * 0x11 << 24) +
60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval(sp[1]) * 0x11 << 16) +
60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11);
60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	break;
60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 6:			/* #rrggbb */
60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 9:			/* #rrrgggbbb */
60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 12:			/* #rrrrggggbbbb */
60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	dl = len / 3;
61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argb =
61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    0xff000000 +
61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval2(sp + 0) << 16) +
61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2);
61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	break;
61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 8:			/* #aarrggbb */
61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb,
61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   assume the latter is a more common format */
61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    case 16:			/* #aaaarrrrggggbbbb */
61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	dl = len / 4;
62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argb =
62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval2(sp + 0) << 24) +
62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval2(sp + dl) << 16) +
62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3);
62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	break;
62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    default:
62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argb = 0xffff0000;	/* Bright red (error indication) */
62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	break;
62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return argb;
63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parser state.  This is global so that including multiple
63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * files work as expected, which is that everything works the
63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * same way as if the files had been concatenated together.
63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//static const char *append = NULL;
63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern const char *append;
64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t PXERetry;
64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct labeldata ld;
64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int parse_main_config(const char *filename);
64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic char *is_kernel_type(char *cmdstr, enum kernel_type *type)
64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *const *p;
64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *q;
64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum kernel_type t = KT_NONE;
65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (p = kernel_types; *p; p++, t++) {
65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ((q = looking_at(cmdstr, *p))) {
65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *type = t;
65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return q;
65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return NULL;
65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic char *is_message_name(char *cmdstr, enum message_number *msgnr)
66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *q;
66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum message_number i;
66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (i = 0; i < MSG_COUNT; i++) {
66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ((q = looking_at(cmdstr, messages[i].name))) {
66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *msgnr = i;
66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return q;
67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return NULL;
67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void get_msg_file(char *);
67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid cat_help_file(int key)
67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct menu *cm = current_menu;
68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int fkey;
68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	switch (key) {
68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F1:
68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 0;
68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F2:
68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 1;
68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F3:
69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 2;
69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F4:
69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 3;
69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F5:
69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 4;
69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F6:
70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 5;
70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F7:
70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 6;
70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F8:
70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 7;
70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F9:
70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 8;
71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F10:
71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 9;
71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F11:
71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 10;
71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	case KEY_F12:
71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = 11;
71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	default:
72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fkey = -1;
72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		break;
72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (fkey == -1)
72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return;
72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (cm->fkeyhelp[fkey].textname) {
72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		printf("\n");
73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		get_msg_file((char *)cm->fkeyhelp[fkey].textname);
73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic char *is_fkey(char *cmdstr, int *fkeyno)
73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *q;
73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int no;
73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if ((cmdstr[0] | 0x20) != 'f')
74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return NULL;
74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    no = strtoul(cmdstr + 1, &q, 10);
74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (!my_isspace(*q))
74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return NULL;
74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (no < 0 || no > 12)
74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return NULL;
74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    *fkeyno = (no == 0) ? 10 : no - 1;
75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return q;
75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint8_t FlowIgnore;
75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint8_t FlowInput;
75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint8_t FlowOutput;
75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t SerialPort;
75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t BaudDivisor;
75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic uint8_t SerialNotice = 1;
75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DEFAULT_BAUD	9600
76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define BAUD_DIVISOR	115200
76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void sirq_cleanup_nowipe(void);
76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void sirq_install(void);
76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void write_serial_str(char *);
76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void loadfont(const char *);
76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void loadkeys(const char *);
76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern char syslinux_banner[];
77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern char copyright_str[];
77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * PATH-based lookup
77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Each entry in the PATH directive is separated by a colon, e.g.
77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *     PATH /bar:/bin/foo:/baz/bar/bin
77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int parse_path(char *p)
78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct path_entry *entry;
78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *str;
78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (*p) {
78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *c = p;
78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Find the next directory */
78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while (*c && *c != ':')
79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    c++;
79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	str = refstrndup(p, c - p);
79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!str)
79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    goto bail;
79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	entry = path_add(str);
79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	refstr_put(str);
79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!entry)
80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    goto bail;
80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!*c++)
80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    break;
80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p = c;
80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return 0;
80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbail:
81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return -1;
81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void parse_config_file(FILE * f);
81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void do_include_menu(char *str, struct menu *m)
81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *file;
81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *p;
81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    FILE *f;
82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int fd;
82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = skipspace(str);
82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    file = refdup_word(&p);
82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = skipspace(p);
82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    fd = open(file, O_RDONLY);
82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (fd < 0)
82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	goto put;
82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    f = fdopen(fd, "r");
83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (!f)
83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	goto bail;
83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (*p) {
83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	record(m, &ld, append);
83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m = current_menu = begin_submenu(p);
83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    parse_config_file(f);
84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (*p) {
84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	record(m, &ld, append);
84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m = current_menu = end_submenu();
84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbail:
84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    close(fd);
84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanput:
84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(file);
85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void do_include(char *str)
85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *file;
85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char *p;
85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    FILE *f;
85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int fd;
85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    p = skipspace(str);
86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    file = refdup_word(&p);
86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    fd = open(file, O_RDONLY);
86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (fd < 0)
86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	goto put;
86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    f = fdopen(fd, "r");
86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (f)
86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	parse_config_file(f);
87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    close(fd);
87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanput:
87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    refstr_put(file);
87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void parse_config_file(FILE * f)
87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char line[MAX_LINE], *p, *ep, ch;
87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum kernel_type type;
88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    enum message_number msgnr;
88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int fkeyno;
88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *m = current_menu;
88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (fgets(line, sizeof line, f)) {
88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p = strchr(line, '\r');
88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (p)
88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *p = '\0';
88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p = strchr(line, '\n');
88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (p)
89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    *p = '\0';
89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	p = skipspace(line);
89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (looking_at(p, "menu")) {
89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    p = skipspace(p + 4);
89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (looking_at(p, "label")) {
89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (ld.label) {
90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				refstr_put(ld.menulabel);
90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				ld.menulabel = refstrdup(skipspace(p + 5));
90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			} else if (m->parent_entry) {
90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				refstr_put(m->parent_entry->displayname);
90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				m->parent_entry->displayname = refstrdup(skipspace(p + 5));
90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				consider_for_hotkey(m->parent, m->parent_entry);
90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (!m->title[0]) {
90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				/* MENU LABEL -> MENU TITLE on submenu */
90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				refstr_put(m->title);
90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				m->title = strip_caret(m->parent_entry->displayname);
91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				}
91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			} else if (looking_at(p, "title")) {
91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			refstr_put(m->title);
91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			m->title = refstrdup(skipspace(p + 5));
91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (m->parent_entry) {
91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				/* MENU TITLE -> MENU LABEL on submenu */
91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (m->parent_entry->displayname == m->label) {
91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				refstr_put(m->parent_entry->displayname);
91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				m->parent_entry->displayname = refstr_get(m->title);
92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				}
92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "default")) {
92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label) {
92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.menudefault = 1;
92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		} else if (m->parent_entry) {
92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    m->parent->defentry = m->parent_entry->entry;
92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "hide")) {
92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.menuhide = 1;
93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "passwd")) {
93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label) {
93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    refstr_put(ld.passwd);
93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.passwd = refstrdup(skipspace(p + 6));
93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		} else if (m->parent_entry) {
93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    refstr_put(m->parent_entry->passwd);
93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    m->parent_entry->passwd = refstrdup(skipspace(p + 6));
93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "shiftkey")) {
93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		shiftkey = 1;
94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "save")) {
94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		menusave = true;
94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label)
94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.save = 1;
94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		else
94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    m->save = true;
94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "nosave")) {
94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label)
94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.save = -1;
94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		else
95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    m->save = false;
95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "onerror")) {
95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->onerror);
95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->onerror = refstrdup(skipspace(p + 7));
95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		onerrorlen = strlen(m->onerror);
95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(onerror);
95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		onerror = refstrdup(m->onerror);
95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "master")) {
95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(p + 6);
95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (looking_at(p, "passwd")) {
96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    refstr_put(m->menu_master_passwd);
96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    m->menu_master_passwd = refstrdup(skipspace(p + 6));
96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = looking_at(p, "include"))) {
96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		do_include_menu(ep, m);
96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = looking_at(p, "background"))) {
96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(ep);
96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->menu_background);
96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->menu_background = refdup_word(&p);
96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = looking_at(p, "hidden"))) {
97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		hiddenmenu = 1;
97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = is_message_name(p, &msgnr))) {
97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->messages[msgnr]);
97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->messages[msgnr] = refstrdup(skipspace(ep));
97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = looking_at(p, "color")) ||
97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       (ep = looking_at(p, "colour"))) {
97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		int i;
97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		struct color_table *cptr;
97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(ep);
97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		cptr = m->color_table;
98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		for (i = 0; i < menu_color_table_size; i++) {
98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if ((ep = looking_at(p, cptr->name))) {
98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			p = skipspace(ep);
98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (*p) {
98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    if (looking_at(p, "*")) {
98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				p++;
98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    } else {
98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				refstr_put(cptr->ansi);
98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				cptr->ansi = refdup_word(&p);
98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    }
99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    p = skipspace(p);
99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    if (*p) {
99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (looking_at(p, "*"))
99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    p++;
99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				else
99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    cptr->argb_fg = parse_argb(&p);
99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				p = skipspace(p);
99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				if (*p) {
100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    if (looking_at(p, "*"))
100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					p++;
100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    else
100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					cptr->argb_bg = parse_argb(&p);
100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    /* Parse a shadow mode */
100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    p = skipspace(p);
100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    ch = *p | 0x20;
100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    if (ch == 'n')	/* none */
100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					cptr->shadow = SHADOW_NONE;
101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    else if (ch == 's')	/* std, standard */
101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					cptr->shadow = SHADOW_NORMAL;
101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    else if (ch == 'a')	/* all */
101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					cptr->shadow = SHADOW_ALL;
101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				    else if (ch == 'r')	/* rev, reverse */
101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					cptr->shadow = SHADOW_REVERSE;
101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				}
101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    }
101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			break;
102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    }
102176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    cptr++;
102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
102376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if ((ep = looking_at(p, "msgcolor")) ||
102476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		       (ep = looking_at(p, "msgcolour"))) {
102576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		unsigned int fg_mask = MSG_COLORS_DEF_FG;
102676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		unsigned int bg_mask = MSG_COLORS_DEF_BG;
102776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW;
102876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
102976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(ep);
103076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (*p) {
103176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if (!looking_at(p, "*"))
103276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			fg_mask = parse_argb(&p);
103376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
103476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    p = skipspace(p);
103576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if (*p) {
103676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (!looking_at(p, "*"))
103776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    bg_mask = parse_argb(&p);
103876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
103976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			p = skipspace(p);
104076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			switch (*p | 0x20) {
104176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			case 'n':
104276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    shadow = SHADOW_NONE;
104376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    break;
104476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			case 's':
104576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    shadow = SHADOW_NORMAL;
104676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    break;
104776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			case 'a':
104876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    shadow = SHADOW_ALL;
104976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    break;
105076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			case 'r':
105176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    shadow = SHADOW_REVERSE;
105276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    break;
105376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			default:
105476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    /* go with default */
105576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			    break;
105676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
105776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    }
105876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
105976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow);
106076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "separator")) {
106176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		record(m, &ld, append);
106276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.label = refstr_get(empty_string);
106376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.menuseparator = 1;
106476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		record(m, &ld, append);
106576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "disable") || looking_at(p, "disabled")) {
106676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.menudisabled = 1;
106776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "indent")) {
106876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.menuindent = atoi(skipspace(p + 6));
106976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "begin")) {
107076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		record(m, &ld, append);
107176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m = current_menu = begin_submenu(skipspace(p + 5));
107276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "end")) {
107376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		record(m, &ld, append);
107476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m = current_menu = end_submenu();
107576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "quit")) {
107676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label)
107776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.action = MA_QUIT;
107876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "goto")) {
107976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label) {
108076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.action = MA_GOTO_UNRES;
108176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    refstr_put(ld.kernel);
108276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.kernel = refstrdup(skipspace(p + 4));
108376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
108476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "exit")) {
108576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(p + 4);
108676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (ld.label && m->parent) {
108776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if (*p) {
108876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* This is really just a goto, except for the marker */
108976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ld.action = MA_EXIT_UNRES;
109076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			refstr_put(ld.kernel);
109176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ld.kernel = refstrdup(p);
109276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    } else {
109376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ld.action = MA_EXIT;
109476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ld.submenu = m->parent;
109576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    }
109676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
109776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else if (looking_at(p, "start")) {
109876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		start_menu = m;
109976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else {
110076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Unknown, check for layout parameters */
110176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		enum parameter_number mp;
110276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		for (mp = 0; mp < NPARAMS; mp++) {
110376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    if ((ep = looking_at(p, mparm[mp].name))) {
110476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			m->mparm[mp] = atoi(skipspace(ep));
110576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			break;
110676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    }
110776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
110876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
110976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
111076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* feng: menu handling end */
111176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if (looking_at(p, "text")) {
111276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
111376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* loop till we fined the "endtext" */
111476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    enum text_cmd {
111576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		TEXT_UNKNOWN,
111676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		TEXT_HELP
111776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } cmd = TEXT_UNKNOWN;
111876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    int len = ld.helptext ? strlen(ld.helptext) : 0;
111976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    int xlen;
112076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    p = skipspace(p + 4);
112276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (looking_at(p, "help"))
112476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		cmd = TEXT_HELP;
112576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    while (fgets(line, sizeof line, f)) {
112776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(line);
112876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (looking_at(p, "endtext"))
112976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    break;
113076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
113176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xlen = strlen(line);
113276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
113376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		switch (cmd) {
113476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		case TEXT_UNKNOWN:
113576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    break;
113676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		case TEXT_HELP:
113776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    ld.helptext = realloc(ld.helptext, len + xlen + 1);
113876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    memcpy(ld.helptext + len, line, xlen + 1);
113976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    len += xlen;
114076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    break;
114176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
114276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
114376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ((ep = is_fkey(p, &fkeyno))) {
114476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    p = skipspace(ep);
114576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (m->fkeyhelp[fkeyno].textname) {
114676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->fkeyhelp[fkeyno].textname);
114776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->fkeyhelp[fkeyno].textname = NULL;
114876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
114976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (m->fkeyhelp[fkeyno].background) {
115076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->fkeyhelp[fkeyno].background);
115176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->fkeyhelp[fkeyno].background = NULL;
115276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
115376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(m->fkeyhelp[fkeyno].textname);
115576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->fkeyhelp[fkeyno].textname = refdup_word(&p);
115676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (*p) {
115776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(p);
115876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->fkeyhelp[fkeyno].background = refdup_word(&p);
115976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
116076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ((ep = looking_at(p, "include"))) {
116176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    do_include(ep);
116276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "append")) {
116376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    const char *a = refstrdup(skipspace(p + 6));
116476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld.label) {
116576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(ld.append);
116676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.append = a;
116776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else {
116876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(append);
116976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		append = a;
117076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
117176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    //dprintf("we got a append: %s", a);
117276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "initrd")) {
117376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    const char *a = refstrdup(skipspace(p + 6));
117476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld.label) {
117576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(ld.initrd);
117676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.initrd = a;
117776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else {
117876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Ignore */
117976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
118076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "label")) {
118176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    p = skipspace(p + 5);
118276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* when first time see "label", it will not really record anything */
118376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    record(m, &ld, append);
118476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.label = __refdup_word(p, NULL);
118576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.kernel = __refdup_word(p, NULL);
118676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* feng: this is the default type for all */
118776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.type = KT_KERNEL;
118876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.passwd = NULL;
118976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.append = NULL;
119076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.initrd = NULL;
119176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.menulabel = NULL;
119276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.helptext = NULL;
119376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.ipappend = SysAppends;
119476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ld.menudefault = ld.menuhide = ld.menuseparator =
119576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.menudisabled = ld.menuindent = 0;
119676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ((ep = is_kernel_type(p, &type))) {
119776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld.label) {
119876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(ld.kernel);
119976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.kernel = refstrdup(skipspace(ep));
120076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.type = type;
120176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		//dprintf("got a kernel: %s, type = %d", ld.kernel, ld.type);
120276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
120376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "timeout")) {
120476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    kbdtimeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
120576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "totaltimeout")) {
120676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10;
120776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "ontimeout")) {
120876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ontimeout = refstrdup(skipspace(p + 9));
120976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    ontimeoutlen = strlen(ontimeout);
121076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "allowoptions")) {
121176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    allowoptions = !!atoi(skipspace(p + 12));
121276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ((ep = looking_at(p, "ipappend")) ||
121376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   (ep = looking_at(p, "sysappend"))) {
121476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    uint32_t s = strtoul(skipspace(ep), NULL, 0);
121576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (ld.label)
121676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ld.ipappend = s;
121776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    else
121876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		SysAppends = s;
121976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "default")) {
122076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* default could be a kernel image or another label */
122176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(globaldefault);
122276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    globaldefault = refstrdup(skipspace(p + 7));
122376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
122476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /*
122576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     * On the chance that "default" is actually a kernel image
122676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     * and not a label, store a copy of it, but only if we
122776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     * haven't seen a "ui" command. "ui" commands take
122876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     * precendence over "default" commands.
122976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     */
123076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (defaultlevel < LEVEL_UI) {
123176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		defaultlevel = LEVEL_DEFAULT;
123276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(default_cmd);
123376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		default_cmd = refstrdup(globaldefault);
123476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
123576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "ui")) {
123676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    has_ui = 1;
123776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    defaultlevel = LEVEL_UI;
123876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(default_cmd);
123976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    default_cmd = refstrdup(skipspace(p + 2));
124076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
124176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
124276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
124376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * subset 1:  pc_opencmd
124476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * display/font/kbdmap are rather similar, open a file then do sth
124576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
124676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if (looking_at(p, "display")) {
124776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		const char *filename;
124876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		char *dst = KernelName;
124976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		size_t len = FILENAME_MAX - 1;
125076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
125176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		filename = refstrdup(skipspace(p + 7));
125276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
125376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		while (len-- && not_whitespace(*filename))
125476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			*dst++ = *filename++;
125576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		*dst = '\0';
125676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
125776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		get_msg_file(KernelName);
125876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(filename);
125976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "font")) {
126076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		const char *filename;
126176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		char *dst = KernelName;
126276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		size_t len = FILENAME_MAX - 1;
126376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
126476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		filename = refstrdup(skipspace(p + 4));
126576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
126676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		while (len-- && not_whitespace(*filename))
126776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			*dst++ = *filename++;
126876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		*dst = '\0';
126976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		loadfont(KernelName);
127176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(filename);
127276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "kbdmap")) {
127376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		const char *filename;
127476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		filename = refstrdup(skipspace(p + 6));
127676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		loadkeys(filename);
127776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(filename);
127876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
127976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
128076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * subset 2:  pc_setint16
128176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * set a global flag
128276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
128376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if (looking_at(p, "implicit")) {
128476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		allowimplicit = atoi(skipspace(p + 8));
128576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "prompt")) {
128676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		forceprompt = atoi(skipspace(p + 6));
128776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "console")) {
128876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		DisplayCon = atoi(skipspace(p + 7));
128976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "allowoptions")) {
129076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		allowoptions = atoi(skipspace(p + 12));
129176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "noescape")) {
129276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		noescape = atoi(skipspace(p + 8));
129376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "nocomplete")) {
129476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		nocomplete = atoi(skipspace(p + 10));
129576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "nohalt")) {
129676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		NoHalt = atoi(skipspace(p + 8));
129776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "onerror")) {
129876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(m->onerror);
129976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		m->onerror = refstrdup(skipspace(p + 7));
130076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		onerrorlen = strlen(m->onerror);
130176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		refstr_put(onerror);
130276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		onerror = refstrdup(m->onerror);
130376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
130476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
130576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if (looking_at(p, "pxeretry"))
130676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		PXERetry = atoi(skipspace(p + 8));
130776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
130876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* serial setting, bps, flow control */
130976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else if (looking_at(p, "serial")) {
131076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		uint16_t port, flow;
131176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		uint32_t baud;
131276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
131376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(p + 6);
131476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		port = atoi(p);
131576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
131676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		while (isalnum(*p))
131776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			p++;
131876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p = skipspace(p);
131976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
132076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Default to no flow control */
132176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		FlowOutput = 0;
132276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		FlowInput = 0;
132376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
132476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		baud = DEFAULT_BAUD;
132576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (isalnum(*p)) {
132676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			uint8_t ignore;
132776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
132876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* setup baud */
132976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			baud = atoi(p);
133076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			while (isalnum(*p))
133176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				p++;
133276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			p = skipspace(p);
133376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
133476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			ignore = 0;
133576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			flow = 0;
133676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			if (isalnum(*p)) {
133776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				/* flow control */
133876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				flow = atoi(p);
133976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman				ignore = ((flow & 0x0F00) >> 4);
134076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			}
134176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
134276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			FlowIgnore = ignore;
134376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			flow = ((flow & 0xff) << 8) | (flow & 0xff);
134476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			flow &= 0xF00B;
134576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			FlowOutput = (flow & 0xff);
134676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			FlowInput = ((flow & 0xff00) >> 8);
134776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
134876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
134976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/*
135076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * Parse baud
135176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 */
135276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (baud < 75) {
135376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* < 75 baud == bogus */
135476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			SerialPort = 0;
135576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			continue;
135676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
135776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
135876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		baud = BAUD_DIVISOR / baud;
135976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		baud &= 0xffff;
136076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		BaudDivisor = baud;
136176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
136276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		port = get_serial_port(port);
136376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		SerialPort = port;
136476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
136576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/*
136676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * Begin code to actually set up the serial port
136776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 */
136876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sirq_cleanup_nowipe();
136976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb(0x83, port + 3); /* Enable DLAB */
137176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
137276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb((baud & 0xff), port); /* write divisor to LS */
137476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
137576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb(((baud & 0xff00) >> 8), port + 1); /* write to MS */
137776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
137876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb(0x03, port + 3); /* Disable DLAB */
138076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
138176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
138276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/*
138376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * Read back LCR (detect missing hw). If nothing here
138476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 * we'll read 00 or FF.
138576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		 */
138676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (inb(port + 3) != 0x03) {
138776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			/* Assume serial port busted */
138876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			SerialPort = 0;
138976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			continue;
139076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
139176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb(0x01, port + 2); /* Enable FIFOs if present */
139376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
139476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Disable FIFO if unusable */
139676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (inb(port + 2) < 0x0C0) {
139776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			outb(0, port + 2);
139876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			io_delay();
139976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
140076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Assert bits in MCR */
140276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		outb(FlowOutput, port + 4);
140376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		io_delay();
140476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Enable interrupts if requested */
140676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (FlowOutput & 0x8)
140776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			sirq_install();
140876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		/* Show some life */
141076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (SerialNotice != 0) {
141176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			SerialNotice = 0;
141276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
141376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			write_serial_str(syslinux_banner);
141476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			write_serial_str(copyright_str);
141576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
141676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
141776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "say")) {
141876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		printf("%s\n", p+4);
141976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "path")) {
142076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (parse_path(skipspace(p + 4)))
142176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			printf("Failed to parse PATH\n");
142276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if (looking_at(p, "sendcookies")) {
142376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		const union syslinux_derivative_info *sdi;
142476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		p += strlen("sendcookies");
142676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sdi = syslinux_derivative_info();
142776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
142976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			SendCookies = strtoul(skipspace(p), NULL, 10);
143076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			http_bake_cookies();
143176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		}
143276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
143376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
143476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
143576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
143676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int parse_main_config(const char *filename)
143776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
143876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char *mode = "r";
143976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	FILE *f;
144076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int fd;
144176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (!filename)
144376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fd = open_config();
144476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	else
144576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		fd = open(filename, O_RDONLY);
144676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (fd < 0)
144876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return fd;
144976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
145076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (config_cwd[0]) {
145176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if (chdir(config_cwd) < 0)
145276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			printf("Failed to chdir to %s\n", config_cwd);
145376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		config_cwd[0] = '\0';
145476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
145576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
145676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	f = fdopen(fd, mode);
145776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	parse_config_file(f);
145876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
145976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
146076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Update ConfigName so that syslinux_config_file() returns
146176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * the filename we just opened. filesystem-specific
146276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * open_config() implementations are expected to update
146376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * ConfigName themselves.
146476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
146576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (filename)
146676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    strcpy(ConfigName, filename);
146776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
146876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return 0;
146976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
147076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
147176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void resolve_gotos(void)
147276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
147376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
147476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *m;
147576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
147676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (me = all_entries; me; me = me->next) {
147776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) {
147876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m = find_menu(me->cmdline);
147976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(me->cmdline);
148076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->cmdline = NULL;
148176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (m) {
148276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		me->submenu = m;
148376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		me->action--;	/* Drop the _UNRES */
148476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    } else {
148576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		me->action = MA_DISABLED;
148676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
148776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
148876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
148976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
149076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid parse_configs(char **argv)
149276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
149376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *filename;
149476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu *m;
149576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct menu_entry *me;
149676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    dprintf("enter");
149776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    empty_string = refstrdup("");
149976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* feng: reset current menu_list and entry list */
150176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    menu_list = NULL;
150276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    all_entries = NULL;
150376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Initialize defaults for the root and hidden menus */
150576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
150676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    root_menu = new_menu(NULL, NULL, refstrdup(".top"));
150776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    start_menu = root_menu;
150876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Other initialization */
151076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&ld, 0, sizeof(struct labeldata));
151176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
151276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Actually process the files */
151376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    current_menu = root_menu;
151476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
151576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (!argv || !*argv) {
151676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (parse_main_config(NULL) < 0) {
151776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    printf("WARNING: No configuration file found\n");
151876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return;
151976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
152076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    } else {
152176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	while ((filename = *argv++)) {
152276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		dprintf("Parsing config: %s", filename);
152376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    parse_main_config(filename);
152476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
152576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
152676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
152776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* On final EOF process the last label statement */
152876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    record(current_menu, &ld, append);
152976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Common postprocessing */
153176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    resolve_gotos();
153276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Handle global default */
153476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    //if (has_ui && globaldefault) {
153576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (globaldefault) {
153676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	dprintf("gloabldefault = %s", globaldefault);
153776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	me = find_label(globaldefault);
153876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (me && me->menu != hide_menu) {
153976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me->menu->defentry = me->entry;
154076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    start_menu = me->menu;
154176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    default_menu = me->menu;
154276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
154376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
154476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
154576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* If "menu save" is active, let the ADV override the global default */
154676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (menusave) {
154776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t len;
154876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
154976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char *lstr;
155076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (lbl && len) {
155176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    lstr = refstr_alloc(len);
155276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    memcpy(lstr, lbl, len);	/* refstr_alloc() adds the final null */
155376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    me = find_label(lstr);
155476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    if (me && me->menu != hide_menu) {
155576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		me->menu->defentry = me->entry;
155676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		start_menu = me->menu;
155776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    }
155876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    refstr_put(lstr);
155976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
156076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
156176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Final per-menu initialization, with all labels known */
156376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    for (m = menu_list; m; m = m->next) {
156476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	m->curentry = m->defentry;	/* All menus start at their defaults */
156576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (m->ontimeout)
156776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->ontimeout = unlabel(m->ontimeout);
156876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (m->onerror)
156976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    m->onerror = unlabel(m->onerror);
157076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
157176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
1572