summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c')
-rw-r--r--contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c1107
1 files changed, 0 insertions, 1107 deletions
diff --git a/contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c b/contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c
deleted file mode 100644
index 8c16fda..0000000
--- a/contrib/syslinux/syslinux-4.03/com32/menu/readconfig.c
+++ /dev/null
@@ -1,1107 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
- * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston MA 02110-1301, USA; either version 2 of the License, or
- * (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <minmax.h>
-#include <alloca.h>
-#include <inttypes.h>
-#include <colortbl.h>
-#include <com32.h>
-#include <syslinux/adv.h>
-#include <syslinux/config.h>
-
-#include "menu.h"
-
-/* Empty refstring */
-const char *empty_string;
-
-/* Root menu, starting menu, hidden menu, and list of all menus */
-struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
-
-/* These are global parameters regardless of which menu we're displaying */
-int shiftkey = 0; /* Only display menu if shift key pressed */
-int hiddenmenu = 0;
-int clearmenu = 0;
-long long totaltimeout = 0;
-
-/* Keep track of global default */
-static int has_ui = 0; /* DEFAULT only counts if UI is found */
-static const char *globaldefault = NULL;
-static bool menusave = false; /* True if there is any "menu save" */
-
-/* Linked list of all entires, hidden or not; used by unlabel() */
-static struct menu_entry *all_entries;
-static struct menu_entry **all_entries_end = &all_entries;
-
-static const struct messages messages[MSG_COUNT] = {
- [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."},
- [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"},
- [MSG_NOTAB] = {"notabmsg", ""},
- [MSG_PASSPROMPT] = {"passprompt", "Password required"},
-};
-
-#define astrdup(x) ({ char *__x = (x); \
- size_t __n = strlen(__x) + 1; \
- char *__p = alloca(__n); \
- if ( __p ) memcpy(__p, __x, __n); \
- __p; })
-
-/* Must match enum kernel_type */
-const char *const kernel_types[] = {
- "none",
- "localboot",
- "kernel",
- "linux",
- "boot",
- "bss",
- "pxe",
- "fdimage",
- "comboot",
- "com32",
- "config",
- NULL
-};
-
-/*
- * Search the list of all menus for a specific label
- */
-static struct menu *find_menu(const char *label)
-{
- struct menu *m;
-
- for (m = menu_list; m; m = m->next) {
- if (!strcmp(label, m->label))
- return m;
- }
-
- return NULL;
-}
-
-#define MAX_LINE 4096
-
-static char *skipspace(char *p)
-{
- while (*p && my_isspace(*p))
- p++;
-
- return p;
-}
-
-/* Strip ^ from a string, returning a new reference to the same refstring
- if none present */
-static const char *strip_caret(const char *str)
-{
- const char *p, *r;
- char *q;
- int carets = 0;
-
- p = str;
- for (;;) {
- p = strchr(p, '^');
- if (!p)
- break;
- carets++;
- p++;
- }
-
- if (!carets)
- return refstr_get(str);
-
- r = q = refstr_alloc(strlen(str) - carets);
- for (p = str; *p; p++)
- if (*p != '^')
- *q++ = *p;
-
- *q = '\0'; /* refstr_alloc() already did this... */
-
- return r;
-}
-
-/* Check to see if we are at a certain keyword (case insensitive) */
-/* Returns a pointer to the first character past the keyword */
-static char *looking_at(char *line, const char *kwd)
-{
- char *p = line;
- const char *q = kwd;
-
- while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
- p++;
- q++;
- }
-
- if (*q)
- return NULL; /* Didn't see the keyword */
-
- return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */
-}
-
-static struct menu *new_menu(struct menu *parent,
- struct menu_entry *parent_entry, const char *label)
-{
- struct menu *m = calloc(1, sizeof(struct menu));
- int i;
-
- m->label = label;
- m->title = refstr_get(empty_string);
-
- if (parent) {
- /* Submenu */
- m->parent = parent;
- m->parent_entry = parent_entry;
- parent_entry->action = MA_SUBMENU;
- parent_entry->submenu = m;
-
- for (i = 0; i < MSG_COUNT; i++)
- m->messages[i] = refstr_get(parent->messages[i]);
-
- memcpy(m->mparm, parent->mparm, sizeof m->mparm);
-
- m->allowedit = parent->allowedit;
- m->timeout = parent->timeout;
- m->save = parent->save;
- m->immediate = parent->immediate;
-
- m->ontimeout = refstr_get(parent->ontimeout);
- m->onerror = refstr_get(parent->onerror);
- m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
- m->menu_background = refstr_get(parent->menu_background);
-
- m->color_table = copy_color_table(parent->color_table);
-
- for (i = 0; i < 12; i++) {
- m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname);
- m->fkeyhelp[i].background =
- refstr_get(parent->fkeyhelp[i].background);
- }
- } else {
- /* Root menu */
- for (i = 0; i < MSG_COUNT; i++)
- m->messages[i] = refstrdup(messages[i].defmsg);
- for (i = 0; i < NPARAMS; i++)
- m->mparm[i] = mparm[i].value;
-
- m->allowedit = true; /* Allow edits of the command line */
- m->color_table = default_color_table();
- }
-
- m->next = menu_list;
- menu_list = m;
-
- return m;
-}
-
-struct labeldata {
- const char *label;
- const char *kernel;
- enum kernel_type type;
- const char *append;
- const char *initrd;
- const char *menulabel;
- const char *passwd;
- char *helptext;
- unsigned int ipappend;
- unsigned int menuhide;
- unsigned int menudefault;
- unsigned int menuseparator;
- unsigned int menudisabled;
- unsigned int menuindent;
- enum menu_action action;
- int save;
- int immediate;
- struct menu *submenu;
-};
-
-/* Menu currently being parsed */
-static struct menu *current_menu;
-
-static void clear_label_data(struct labeldata *ld)
-{
- refstr_put(ld->label);
- refstr_put(ld->kernel);
- refstr_put(ld->append);
- refstr_put(ld->initrd);
- refstr_put(ld->menulabel);
- refstr_put(ld->passwd);
-
- memset(ld, 0, sizeof *ld);
-}
-
-static struct menu_entry *new_entry(struct menu *m)
-{
- struct menu_entry *me;
-
- if (m->nentries >= m->nentries_space) {
- if (!m->nentries_space)
- m->nentries_space = 1;
- else
- m->nentries_space <<= 1;
-
- m->menu_entries = realloc(m->menu_entries, m->nentries_space *
- sizeof(struct menu_entry *));
- }
-
- me = calloc(1, sizeof(struct menu_entry));
- me->menu = m;
- me->entry = m->nentries;
- m->menu_entries[m->nentries++] = me;
- *all_entries_end = me;
- all_entries_end = &me->next;
-
- return me;
-}
-
-static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
-{
- const char *p = strchr(me->displayname, '^');
-
- if (me->action != MA_DISABLED) {
- if (p && p[1]) {
- unsigned char hotkey = p[1] & ~0x20;
- if (!m->menu_hotkeys[hotkey]) {
- me->hotkey = hotkey;
- m->menu_hotkeys[hotkey] = me;
- }
- }
- }
-}
-
-static void record(struct menu *m, struct labeldata *ld, const char *append)
-{
- int i;
- struct menu_entry *me;
- const struct syslinux_ipappend_strings *ipappend;
-
- if (!ld->label)
- return; /* Nothing defined */
-
- /* Hidden entries are recorded on a special "hidden menu" */
- if (ld->menuhide)
- m = hide_menu;
-
- if (ld->label) {
- char ipoptions[4096], *ipp;
- const char *a;
- char *s;
-
- me = new_entry(m);
-
- me->displayname = ld->menulabel
- ? refstr_get(ld->menulabel) : refstr_get(ld->label);
- me->label = refstr_get(ld->label);
- me->passwd = refstr_get(ld->passwd);
- me->helptext = ld->helptext;
- me->hotkey = 0;
- me->action = ld->action ? ld->action : MA_CMD;
- me->save = ld->save ? (ld->save > 0) : m->save;
- me->immediate = ld->immediate ? (ld->immediate > 0) : m->immediate;
-
- if (ld->menuindent) {
- const char *dn;
-
- rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname);
- refstr_put(me->displayname);
- me->displayname = dn;
- }
-
- if (ld->menuseparator) {
- refstr_put(me->displayname);
- me->displayname = refstr_get(empty_string);
- }
-
- if (ld->menuseparator || ld->menudisabled) {
- me->action = MA_DISABLED;
- refstr_put(me->label);
- me->label = NULL;
- refstr_put(me->passwd);
- me->passwd = NULL;
- }
-
- if (ld->menulabel)
- consider_for_hotkey(m, me);
-
- switch (me->action) {
- case MA_CMD:
- ipp = ipoptions;
- *ipp = '\0';
-
- if (ld->initrd)
- ipp += sprintf(ipp, " initrd=%s", ld->initrd);
-
- if (ld->ipappend) {
- ipappend = syslinux_ipappend_strings();
- for (i = 0; i < ipappend->count; i++) {
- if ((ld->ipappend & (1U << i)) && ipappend->ptr[i] &&
- ipappend->ptr[i][0])
- ipp += sprintf(ipp, " %s", ipappend->ptr[i]);
- }
- }
-
- a = ld->append;
- if (!a)
- a = append;
- if (!a || (a[0] == '-' && !a[1]))
- a = "";
- s = a[0] ? " " : "";
- if (ld->type == KT_KERNEL) {
- rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
- } else {
- rsprintf(&me->cmdline, ".%s %s%s%s%s",
- kernel_types[ld->type], ld->kernel, s, a, ipoptions);
- }
- break;
-
- case MA_GOTO_UNRES:
- case MA_EXIT_UNRES:
- me->cmdline = refstr_get(ld->kernel);
- break;
-
- case MA_GOTO:
- case MA_EXIT:
- me->submenu = ld->submenu;
- break;
-
- case MA_HELP:
- me->cmdline = refstr_get(ld->kernel);
- me->background = refstr_get(ld->append);
- break;
-
- default:
- break;
- }
-
- if (ld->menudefault && me->action == MA_CMD)
- m->defentry = m->nentries - 1;
- }
-
- clear_label_data(ld);
-}
-
-static struct menu *begin_submenu(const char *tag)
-{
- struct menu_entry *me;
-
- if (!tag[0])
- tag = NULL;
-
- me = new_entry(current_menu);
- me->displayname = refstrdup(tag);
- return new_menu(current_menu, me, refstr_get(me->displayname));
-}
-
-static struct menu *end_submenu(void)
-{
- return current_menu->parent ? current_menu->parent : current_menu;
-}
-
-static struct menu_entry *find_label(const char *str)
-{
- const char *p;
- struct menu_entry *me;
- int pos;
-
- p = str;
- while (*p && !my_isspace(*p))
- p++;
-
- /* p now points to the first byte beyond the kernel name */
- pos = p - str;
-
- for (me = all_entries; me; me = me->next) {
- if (!strncmp(str, me->label, pos) && !me->label[pos])
- return me;
- }
-
- return NULL;
-}
-
-static const char *unlabel(const char *str)
-{
- /* Convert a CLI-style command line to an executable command line */
- const char *p;
- const char *q;
- struct menu_entry *me;
- int pos;
-
- p = str;
- while (*p && !my_isspace(*p))
- p++;
-
- /* p now points to the first byte beyond the kernel name */
- pos = p - str;
-
- for (me = all_entries; me; me = me->next) {
- if (!strncmp(str, me->label, pos) && !me->label[pos]) {
- /* Found matching label */
- rsprintf(&q, "%s%s", me->cmdline, p);
- refstr_put(str);
- return q;
- }
- }
-
- return str;
-}
-
-static const char *refdup_word(char **p)
-{
- char *sp = *p;
- char *ep = sp;
-
- while (*ep && !my_isspace(*ep))
- ep++;
-
- *p = ep;
- return refstrndup(sp, ep - sp);
-}
-
-int my_isxdigit(char c)
-{
- unsigned int uc = c;
-
- return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6;
-}
-
-unsigned int hexval(char c)
-{
- unsigned char uc = c | 0x20;
- unsigned int v;
-
- v = uc - '0';
- if (v < 10)
- return v;
-
- return uc - 'a' + 10;
-}
-
-unsigned int hexval2(const char *p)
-{
- return (hexval(p[0]) << 4) + hexval(p[1]);
-}
-
-uint32_t parse_argb(char **p)
-{
- char *sp = *p;
- char *ep;
- uint32_t argb;
- size_t len, dl;
-
- if (*sp == '#')
- sp++;
-
- ep = sp;
-
- while (my_isxdigit(*ep))
- ep++;
-
- *p = ep;
- len = ep - sp;
-
- switch (len) {
- case 3: /* #rgb */
- argb =
- 0xff000000 +
- (hexval(sp[0]) * 0x11 << 16) +
- (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11);
- break;
- case 4: /* #argb */
- argb =
- (hexval(sp[0]) * 0x11 << 24) +
- (hexval(sp[1]) * 0x11 << 16) +
- (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11);
- break;
- case 6: /* #rrggbb */
- case 9: /* #rrrgggbbb */
- case 12: /* #rrrrggggbbbb */
- dl = len / 3;
- argb =
- 0xff000000 +
- (hexval2(sp + 0) << 16) +
- (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2);
- break;
- case 8: /* #aarrggbb */
- /* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb,
- assume the latter is a more common format */
- case 16: /* #aaaarrrrggggbbbb */
- dl = len / 4;
- argb =
- (hexval2(sp + 0) << 24) +
- (hexval2(sp + dl) << 16) +
- (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3);
- break;
- default:
- argb = 0xffff0000; /* Bright red (error indication) */
- break;
- }
-
- return argb;
-}
-
-/*
- * Parser state. This is global so that including multiple
- * files work as expected, which is that everything works the
- * same way as if the files had been concatenated together.
- */
-static const char *append = NULL;
-static unsigned int ipappend = 0;
-static struct labeldata ld;
-
-static int parse_one_config(const char *filename);
-
-static char *is_kernel_type(char *cmdstr, enum kernel_type *type)
-{
- const char *const *p;
- char *q;
- enum kernel_type t = KT_NONE;
-
- for (p = kernel_types; *p; p++, t++) {
- if ((q = looking_at(cmdstr, *p))) {
- *type = t;
- return q;
- }
- }
-
- return NULL;
-}
-
-static char *is_message_name(char *cmdstr, enum message_number *msgnr)
-{
- char *q;
- enum message_number i;
-
- for (i = 0; i < MSG_COUNT; i++) {
- if ((q = looking_at(cmdstr, messages[i].name))) {
- *msgnr = i;
- return q;
- }
- }
-
- return NULL;
-}
-
-static char *is_fkey(char *cmdstr, int *fkeyno)
-{
- char *q;
- int no;
-
- if ((cmdstr[0] | 0x20) != 'f')
- return NULL;
-
- no = strtoul(cmdstr + 1, &q, 10);
- if (!my_isspace(*q))
- return NULL;
-
- if (no < 0 || no > 12)
- return NULL;
-
- *fkeyno = (no == 0) ? 10 : no - 1;
- return q;
-}
-
-static void parse_config_file(FILE * f)
-{
- char line[MAX_LINE], *p, *ep, ch;
- enum kernel_type type = -1;
- enum message_number msgnr = -1;
- int fkeyno = 0;
- struct menu *m = current_menu;
-
- while (fgets(line, sizeof line, f)) {
- p = strchr(line, '\r');
- if (p)
- *p = '\0';
- p = strchr(line, '\n');
- if (p)
- *p = '\0';
-
- p = skipspace(line);
-
- if (looking_at(p, "menu")) {
- p = skipspace(p + 4);
-
- if (looking_at(p, "label")) {
- if (ld.label) {
- refstr_put(ld.menulabel);
- ld.menulabel = refstrdup(skipspace(p + 5));
- } else if (m->parent_entry) {
- refstr_put(m->parent_entry->displayname);
- m->parent_entry->displayname = refstrdup(skipspace(p + 5));
- consider_for_hotkey(m->parent, m->parent_entry);
- if (!m->title[0]) {
- /* MENU LABEL -> MENU TITLE on submenu */
- refstr_put(m->title);
- m->title = strip_caret(m->parent_entry->displayname);
- }
- }
- } else if (looking_at(p, "title")) {
- refstr_put(m->title);
- m->title = refstrdup(skipspace(p + 5));
- if (m->parent_entry) {
- /* MENU TITLE -> MENU LABEL on submenu */
- if (m->parent_entry->displayname == m->label) {
- refstr_put(m->parent_entry->displayname);
- m->parent_entry->displayname = refstr_get(m->title);
- }
- }
- } else if (looking_at(p, "default")) {
- if (ld.label) {
- ld.menudefault = 1;
- } else if (m->parent_entry) {
- m->parent->defentry = m->parent_entry->entry;
- }
- } else if (looking_at(p, "hide")) {
- ld.menuhide = 1;
- } else if (looking_at(p, "passwd")) {
- if (ld.label) {
- refstr_put(ld.passwd);
- ld.passwd = refstrdup(skipspace(p + 6));
- } else if (m->parent_entry) {
- refstr_put(m->parent_entry->passwd);
- m->parent_entry->passwd = refstrdup(skipspace(p + 6));
- }
- } else if (looking_at(p, "shiftkey")) {
- shiftkey = 1;
- } else if (looking_at(p, "save")) {
- menusave = true;
- if (ld.label)
- ld.save = 1;
- else
- m->save = true;
- } else if (looking_at(p, "nosave")) {
- if (ld.label)
- ld.save = -1;
- else
- m->save = false;
- } else if (looking_at(p, "immediate")) {
- if (ld.label)
- ld.immediate = 1;
- else
- m->immediate = true;
- } else if (looking_at(p, "noimmediate")) {
- if (ld.label)
- ld.immediate = -1;
- else
- m->immediate = false;
- } else if (looking_at(p, "onerror")) {
- refstr_put(m->onerror);
- m->onerror = refstrdup(skipspace(p + 7));
- } else if (looking_at(p, "master")) {
- p = skipspace(p + 6);
- if (looking_at(p, "passwd")) {
- refstr_put(m->menu_master_passwd);
- m->menu_master_passwd = refstrdup(skipspace(p + 6));
- }
- } else if ((ep = looking_at(p, "include"))) {
- goto do_include;
- } else if ((ep = looking_at(p, "background"))) {
- p = skipspace(ep);
- refstr_put(m->menu_background);
- m->menu_background = refdup_word(&p);
- } else if ((ep = looking_at(p, "hidden"))) {
- hiddenmenu = 1;
- } else if ((ep = looking_at(p, "clear"))) {
- clearmenu = 1;
- } else if ((ep = is_message_name(p, &msgnr))) {
- refstr_put(m->messages[msgnr]);
- m->messages[msgnr] = refstrdup(skipspace(ep));
- } else if ((ep = looking_at(p, "color")) ||
- (ep = looking_at(p, "colour"))) {
- int i;
- struct color_table *cptr;
- p = skipspace(ep);
- cptr = m->color_table;
- for (i = 0; i < menu_color_table_size; i++) {
- if ((ep = looking_at(p, cptr->name))) {
- p = skipspace(ep);
- if (*p) {
- if (looking_at(p, "*")) {
- p++;
- } else {
- refstr_put(cptr->ansi);
- cptr->ansi = refdup_word(&p);
- }
-
- p = skipspace(p);
- if (*p) {
- if (looking_at(p, "*"))
- p++;
- else
- cptr->argb_fg = parse_argb(&p);
-
- p = skipspace(p);
- if (*p) {
- if (looking_at(p, "*"))
- p++;
- else
- cptr->argb_bg = parse_argb(&p);
-
- /* Parse a shadow mode */
- p = skipspace(p);
- ch = *p | 0x20;
- if (ch == 'n') /* none */
- cptr->shadow = SHADOW_NONE;
- else if (ch == 's') /* std, standard */
- cptr->shadow = SHADOW_NORMAL;
- else if (ch == 'a') /* all */
- cptr->shadow = SHADOW_ALL;
- else if (ch == 'r') /* rev, reverse */
- cptr->shadow = SHADOW_REVERSE;
- }
- }
- }
- break;
- }
- cptr++;
- }
- } else if ((ep = looking_at(p, "msgcolor")) ||
- (ep = looking_at(p, "msgcolour"))) {
- unsigned int fg_mask = MSG_COLORS_DEF_FG;
- unsigned int bg_mask = MSG_COLORS_DEF_BG;
- enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW;
-
- p = skipspace(ep);
- if (*p) {
- if (!looking_at(p, "*"))
- fg_mask = parse_argb(&p);
-
- p = skipspace(p);
- if (*p) {
- if (!looking_at(p, "*"))
- bg_mask = parse_argb(&p);
-
- p = skipspace(p);
- switch (*p | 0x20) {
- case 'n':
- shadow = SHADOW_NONE;
- break;
- case 's':
- shadow = SHADOW_NORMAL;
- break;
- case 'a':
- shadow = SHADOW_ALL;
- break;
- case 'r':
- shadow = SHADOW_REVERSE;
- break;
- default:
- /* go with default */
- break;
- }
- }
- }
- set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow);
- } else if (looking_at(p, "separator")) {
- record(m, &ld, append);
- ld.label = refstr_get(empty_string);
- ld.menuseparator = 1;
- record(m, &ld, append);
- } else if (looking_at(p, "disable") || looking_at(p, "disabled")) {
- ld.menudisabled = 1;
- } else if (looking_at(p, "indent")) {
- ld.menuindent = atoi(skipspace(p + 6));
- } else if (looking_at(p, "begin")) {
- record(m, &ld, append);
- m = current_menu = begin_submenu(skipspace(p + 5));
- } else if (looking_at(p, "end")) {
- record(m, &ld, append);
- m = current_menu = end_submenu();
- } else if (looking_at(p, "quit")) {
- if (ld.label)
- ld.action = MA_QUIT;
- } else if (looking_at(p, "goto")) {
- if (ld.label) {
- ld.action = MA_GOTO_UNRES;
- refstr_put(ld.kernel);
- ld.kernel = refstrdup(skipspace(p + 4));
- }
- } else if (looking_at(p, "exit")) {
- p = skipspace(p + 4);
- if (ld.label && m->parent) {
- if (*p) {
- /* This is really just a goto, except for the marker */
- ld.action = MA_EXIT_UNRES;
- refstr_put(ld.kernel);
- ld.kernel = refstrdup(p);
- } else {
- ld.action = MA_EXIT;
- ld.submenu = m->parent;
- }
- }
- } else if (looking_at(p, "start")) {
- start_menu = m;
- } else if (looking_at(p, "help")) {
- if (ld.label) {
- ld.action = MA_HELP;
- p = skipspace(p + 4);
-
- refstr_put(ld.kernel);
- ld.kernel = refdup_word(&p);
-
- if (ld.append) {
- refstr_put(ld.append);
- ld.append = NULL;
- }
-
- if (*p) {
- p = skipspace(p);
- ld.append = refdup_word(&p); /* Background */
- }
- }
- } else if ((ep = looking_at(p, "resolution"))) {
- int x, y;
- x = strtoul(ep, &ep, 0);
- y = strtoul(skipspace(ep), NULL, 0);
- set_resolution(x, y);
- } else {
- /* Unknown, check for layout parameters */
- enum parameter_number mp;
- for (mp = 0; mp < NPARAMS; mp++) {
- if ((ep = looking_at(p, mparm[mp].name))) {
- m->mparm[mp] = atoi(skipspace(ep));
- break;
- }
- }
- }
- } else if (looking_at(p, "text")) {
- enum text_cmd {
- TEXT_UNKNOWN,
- TEXT_HELP
- } cmd = TEXT_UNKNOWN;
- int len = ld.helptext ? strlen(ld.helptext) : 0;
- int xlen;
-
- p = skipspace(p + 4);
-
- if (looking_at(p, "help"))
- cmd = TEXT_HELP;
-
- while (fgets(line, sizeof line, f)) {
- p = skipspace(line);
- if (looking_at(p, "endtext"))
- break;
-
- xlen = strlen(line);
-
- switch (cmd) {
- case TEXT_UNKNOWN:
- break;
- case TEXT_HELP:
- ld.helptext = realloc(ld.helptext, len + xlen + 1);
- memcpy(ld.helptext + len, line, xlen + 1);
- len += xlen;
- break;
- }
- }
- } else if ((ep = is_fkey(p, &fkeyno))) {
- p = skipspace(ep);
- if (m->fkeyhelp[fkeyno].textname) {
- refstr_put(m->fkeyhelp[fkeyno].textname);
- m->fkeyhelp[fkeyno].textname = NULL;
- }
- if (m->fkeyhelp[fkeyno].background) {
- refstr_put(m->fkeyhelp[fkeyno].background);
- m->fkeyhelp[fkeyno].background = NULL;
- }
-
- refstr_put(m->fkeyhelp[fkeyno].textname);
- m->fkeyhelp[fkeyno].textname = refdup_word(&p);
- if (*p) {
- p = skipspace(p);
- m->fkeyhelp[fkeyno].background = refdup_word(&p);
- }
- } else if ((ep = looking_at(p, "include"))) {
-do_include:
- {
- const char *file;
- p = skipspace(ep);
- file = refdup_word(&p);
- p = skipspace(p);
- if (*p) {
- record(m, &ld, append);
- m = current_menu = begin_submenu(p);
- parse_one_config(file);
- record(m, &ld, append);
- m = current_menu = end_submenu();
- } else {
- parse_one_config(file);
- }
- refstr_put(file);
- }
- } else if (looking_at(p, "append")) {
- const char *a = refstrdup(skipspace(p + 6));
- if (ld.label) {
- refstr_put(ld.append);
- ld.append = a;
- } else {
- refstr_put(append);
- append = a;
- }
- } else if (looking_at(p, "initrd")) {
- const char *a = refstrdup(skipspace(p + 6));
- if (ld.label) {
- refstr_put(ld.initrd);
- ld.initrd = a;
- } else {
- /* Ignore */
- }
- } else if (looking_at(p, "label")) {
- p = skipspace(p + 5);
- record(m, &ld, append);
- ld.label = refstrdup(p);
- ld.kernel = refstrdup(p);
- ld.type = KT_KERNEL;
- ld.passwd = NULL;
- ld.append = NULL;
- ld.initrd = NULL;
- ld.menulabel = NULL;
- ld.helptext = NULL;
- ld.ipappend = ipappend;
- ld.menudefault = ld.menuhide = ld.menuseparator =
- ld.menudisabled = ld.menuindent = 0;
- } else if ((ep = is_kernel_type(p, &type))) {
- if (ld.label) {
- refstr_put(ld.kernel);
- ld.kernel = refstrdup(skipspace(ep));
- ld.type = type;
- }
- } else if (looking_at(p, "timeout")) {
- m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
- } else if (looking_at(p, "totaltimeout")) {
- totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10;
- } else if (looking_at(p, "ontimeout")) {
- m->ontimeout = refstrdup(skipspace(p + 9));
- } else if (looking_at(p, "allowoptions")) {
- m->allowedit = !!atoi(skipspace(p + 12));
- } else if (looking_at(p, "ipappend")) {
- if (ld.label)
- ld.ipappend = atoi(skipspace(p + 8));
- else
- ipappend = atoi(skipspace(p + 8));
- } else if (looking_at(p, "default")) {
- refstr_put(globaldefault);
- globaldefault = refstrdup(skipspace(p + 7));
- } else if (looking_at(p, "ui")) {
- has_ui = 1;
- }
- }
-}
-
-static int parse_one_config(const char *filename)
-{
- FILE *f;
-
- if (!strcmp(filename, "~"))
- filename = syslinux_config_file();
-
- dprintf("Opening config file: %s ", filename);
-
- f = fopen(filename, "r");
- dprintf("%s\n", f ? "ok" : "failed");
-
- if (!f)
- return -1;
-
- parse_config_file(f);
- fclose(f);
-
- return 0;
-}
-
-static void resolve_gotos(void)
-{
- struct menu_entry *me;
- struct menu *m;
-
- for (me = all_entries; me; me = me->next) {
- if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) {
- m = find_menu(me->cmdline);
- refstr_put(me->cmdline);
- me->cmdline = NULL;
- if (m) {
- me->submenu = m;
- me->action--; /* Drop the _UNRES */
- } else {
- me->action = MA_DISABLED;
- }
- }
- }
-}
-
-void parse_configs(char **argv)
-{
- const char *filename;
- struct menu *m;
- struct menu_entry *me;
-
- empty_string = refstrdup("");
-
- /* Initialize defaults for the root and hidden menus */
- hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
- root_menu = new_menu(NULL, NULL, refstrdup(".top"));
- start_menu = root_menu;
-
- /* Other initialization */
- memset(&ld, 0, sizeof(struct labeldata));
-
- /* Actually process the files */
- current_menu = root_menu;
- if (!*argv) {
- parse_one_config("~");
- } else {
- while ((filename = *argv++))
- parse_one_config(filename);
- }
-
- /* On final EOF process the last label statement */
- record(current_menu, &ld, append);
-
- /* Common postprocessing */
- resolve_gotos();
-
- /* Handle global default */
- if (has_ui && globaldefault) {
- me = find_label(globaldefault);
- if (me && me->menu != hide_menu) {
- me->menu->defentry = me->entry;
- start_menu = me->menu;
- }
- }
-
- /* If "menu save" is active, let the ADV override the global default */
- if (menusave) {
- size_t len;
- const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
- char *lstr;
- if (lbl && len) {
- lstr = refstr_alloc(len);
- memcpy(lstr, lbl, len); /* refstr_alloc() adds the final null */
- me = find_label(lstr);
- if (me && me->menu != hide_menu) {
- me->menu->defentry = me->entry;
- start_menu = me->menu;
- }
- refstr_put(lstr);
- }
- }
-
- /* Final per-menu initialization, with all labels known */
- for (m = menu_list; m; m = m->next) {
- m->curentry = m->defentry; /* All menus start at their defaults */
-
- if (m->ontimeout)
- m->ontimeout = unlabel(m->ontimeout);
- if (m->onerror)
- m->onerror = unlabel(m->onerror);
- }
-}