X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=config.c;h=d144c9f0a9b1620a0f10b2ac98edce55f790ceb7;hb=8d96dc4fad7b7fb7985f9568c27649de3e43d6bc;hp=e24c0c0198613c2338215e4302ed12428e7c4295;hpb=8e0034665aa8483b27191c723608575536d01303;p=debian%2Felilo diff --git a/config.c b/config.c index e24c0c0..d144c9f 100644 --- a/config.c +++ b/config.c @@ -1,6 +1,9 @@ /* * Copyright (C) 2001-2003 Hewlett-Packard Co. * Contributed by Stephane Eranian + * Contributed by Fenghua Yu + * Contributed by Bibo Mao + * Contributed by Chandramouli Narayanan * * This file is part of the ELILO, the EFI Linux boot loader. * @@ -42,6 +45,8 @@ #define ELILO_ARCH_DEFAULT_CONFIG L"elilo-ia64.conf" #elif defined (CONFIG_ia32) #define ELILO_ARCH_DEFAULT_CONFIG L"elilo-ia32.conf" +#elif defined (CONFIG_x86_64) +#define ELILO_ARCH_DEFAULT_CONFIG L"elilo-x86_64.conf" #else #error "You need to specfy your default arch config file" #endif @@ -51,7 +56,7 @@ */ #define ELILO_DEFAULT_CONFIG L"elilo.conf" -#define MAX_STRING CMDLINE_MAXLEN +#define MAX_STRING 512 #define CONFIG_BUFSIZE 512 /* input buffer size */ /* @@ -66,7 +71,7 @@ typedef struct boot_image { struct boot_image *next; CHAR16 label[MAX_STRING]; CHAR16 kname[FILENAME_MAXLEN]; - CHAR16 options[MAX_STRING]; + CHAR16 options[CMDLINE_MAXLEN]; CHAR16 initrd[FILENAME_MAXLEN]; CHAR16 vmcode[FILENAME_MAXLEN]; CHAR16 root[FILENAME_MAXLEN]; @@ -95,7 +100,7 @@ typedef struct { CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */ CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */ CHAR16 vmcode[FILENAME_MAXLEN];/* globally defined boot-time module */ - CHAR16 options[MAX_STRING]; + CHAR16 options[CMDLINE_MAXLEN]; CHAR16 default_image_name[MAX_STRING]; CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN]; CHAR16 chooser[FILENAME_MAXLEN];/* which image chooser to use */ @@ -204,14 +209,8 @@ static fops_fd_t config_fd; static VOID config_error(CHAR16 *msg,...) { - va_list ap; - extern UINTN _IPrint (UINTN, UINTN, SIMPLE_TEXT_OUTPUT_INTERFACE *, CHAR16 *, CHAR8 *, va_list); - Print(L"near line %d: ",line_num); - - va_start(ap,msg); - _IPrint((UINTN)-1, (UINTN)-1, systab->ConOut, msg, NULL, ap); - va_end(ap); + IPrint(systab->ConOut, msg); Print(L"\n"); } @@ -256,7 +255,16 @@ next(VOID) back = 0; return ch; } - return getc(); +/* + * config files served from pxe/tftpboot windows servers can contain + * extraneous '\r' characters, often the first char in the file, and + * we need to simply skip over those and continue on + */ + ch = getc(); + if(ch == '\r') + ch = getc(); + + return ch; } /* @@ -305,23 +313,23 @@ find_option(config_option_group_t *grp, CHAR16 *str) * - TOK_ERR: in case of (parsing) error */ static token_t -get_token(CHAR16 *str, UINTN maxlen) +get_token_core(CHAR16 *str, UINTN maxlen, BOOLEAN rhs) { INTN ch, escaped; CHAR16 *here; for (;;) { - while ((ch = next()), ch == ' ' || ch == '\t' || ch == '\n') if (ch == '\n') line_num++; + while ((ch = next()), ch == ' ' || ch == '\t' || ch == '\n') if (ch == '\n' ) line_num++; if (ch == CHAR_EOF) return TOK_EOF; + /* skip comment line */ if (ch != '#') break; - /* skip comment line */ while ((ch = next()), ch != '\n') if (ch == CHAR_EOF) return TOK_EOF; line_num++; } - if (ch == '=') return TOK_EQUAL; + if (ch == '=' && !rhs) return TOK_EQUAL; if (ch == '"') { here = str; @@ -374,7 +382,7 @@ get_token(CHAR16 *str, UINTN maxlen) } else { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' || - ch == '=' || ch == CHAR_EOF) { + ch == CHAR_EOF || (ch == '=' && !rhs)) { again(ch); *here = 0; return TOK_STR; @@ -387,6 +395,18 @@ get_token(CHAR16 *str, UINTN maxlen) return TOK_ERR; } +static token_t +get_token(CHAR16 *str, UINTN maxlen) +{ + return get_token_core(str, maxlen, FALSE); +} + +static token_t +get_token_rhs(CHAR16 *str, UINTN maxlen) +{ + return get_token_core(str, maxlen, TRUE); +} + static INTN image_check(boot_image_t *img) { @@ -680,7 +700,7 @@ do_string_core(config_option_t *p, CHAR16 *str, UINTN maxlen, CHAR16 *msg) /* * now get the value */ - tok = get_token(str, maxlen); + tok = get_token_rhs(str, maxlen); if (tok != TOK_STR) { config_error(L"Option %s expects %s", p->name, msg); return -1; @@ -751,7 +771,10 @@ config_parse(VOID) if (tok == TOK_EOF) break; - if (tok == TOK_ERR) return -1; + if (tok == TOK_ERR) { + Print(L"Bad Token from elilo config file, parser read: %s\n elilo exiting\n", str); + return -1; + } if ( (p = find_option(current_options, str)) == NULL) { config_error(L"Unkown option %s", str); @@ -886,10 +909,10 @@ print_label_list(VOID) { boot_image_t *img, *dfl = global_config.default_image; - if (dfl) Print(L"\t%s\n", dfl->label); + if (dfl) Print(L" %s\n", dfl->label); for (img = image_list; img; img = img->next) { - if (img != dfl) Print(L"\t%s\n", img->label); + if (img != dfl) Print(L" %s\n", img->label); } } @@ -936,6 +959,37 @@ find_description(CHAR16 *label) return NULL; } +static void +add_root_to_options(CHAR16 *options, CHAR16 *root, CHAR16 *vmcode) +{ + CHAR16 *o, ko[CMDLINE_MAXLEN]; + + if (vmcode[0]) { + for (o = options; *o; o++) { + if (*o == '-' && *(o+1) == '-') + break; + } + if (! *o) { + /* no separator found, add one */ + StrCpy(o, L" -- "); + o++; + } + + /* advance past separator and whitespace */ + o += 2; + while (*o == ' ') o++; + } else { + o = options; + } + + /* insert root param at this point */ + StrCpy(ko, o); + StrCpy(o, L"root="); + StrCat(o, root); + StrCat(o, L" "); + StrCat(o, ko); +} + INTN find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 *vmcode) { @@ -958,15 +1012,12 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 /* * when the label does not exist, we still propagate the global options */ - if (global_config.root[0]) { - StrCpy(options, L" root="); - StrCat(options, global_config.root); - } - if (global_config.options[0]) { StrCat(options, L" "); StrCat(options, global_config.options); } + if (global_config.root[0]) + add_root_to_options(options, global_config.root, global_config.vmcode); if (global_config.readonly) StrCat(options, L" ro"); if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd); @@ -979,21 +1030,33 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 found: StrCpy(kname, img->kname); + /* per image initrd has precedence over global initrd */ + if (img->initrd[0]) + StrCpy(initrd, img->initrd); + else + StrCpy(initrd, global_config.initrd); + + /* per image vmcode has precedence over global vmcode */ + if (img->vmcode[0]) + StrCpy(vmcode, img->vmcode); + else + StrCpy(vmcode, global_config.vmcode); + /* * literal option overrides any other image-based or global option * * In any case, the image option has priority over the global option */ if (img->literal == 0) { - if (img->root[0] || global_config.root[0]) { - StrCat(options, L"root="); - StrCat(options, img->root[0] ? img->root : global_config.root); - } /* XXX: check max length */ if (img->options[0] || global_config.options[0]) { StrCat(options, L" "); StrCat(options, img->options[0] ? img->options: global_config.options); } + if (img->root[0] || global_config.root[0]) { + add_root_to_options(options, img->root[0] + ? img->root : global_config.root, vmcode); + } if (img->readonly || global_config.readonly) { StrCat(options, L" ro"); } @@ -1002,17 +1065,6 @@ found: StrCpy(options, img->options); } - /* per image initrd has precedence over global initrd */ - if (img->initrd[0]) - StrCpy(initrd, img->initrd); - else if (global_config.initrd[0]) - StrCpy(initrd, global_config.initrd); - - if (img->vmcode[0]) - StrCpy(vmcode, img->vmcode); - else if (global_config.vmcode[0]) - StrCpy(vmcode, global_config.vmcode); - /* * point to architecture dependent options for this image */