Logo Search packages:      
Sourcecode: m68k-vme-tftplilo version File versions  Download package

config.c

/*
 *  VME Linux/m68k TFTP Loader
 *
 *  (c) Copyright 1998 by Nick Holgate
 *
 *  This file is subject to the terms and conditions of the GNU General
 *  Public License.  See the file COPYING for more details.
 */

/*--------------------------------------------------------------------------*/

#include "defs.h"

/*--------------------------------------------------------------------------*/

#define RAMDISK(name)   (equal_strings(name, "none") ? NULL : name)

/*--------------------------------------------------------------------------*/

enum keyword_id {
      KW_UNKNOWN,
      KW_TIMEOUT,
      KW_DELAY,
      KW_PROMPT,
      KW_KERNEL,
      KW_CMDLINE,
      KW_APPEND,
      KW_RESTRICTED,
      KW_CALLDBG,
      KW_MEMSIZE,
      KW_LABEL,
      KW_ALIAS,
      KW_RAMDISK,
      KW_BOOT,
      KW_DEFAULT,
      KW_IP,
      KW_DEBUG,
      KW_ROOT,
      KW_CONSOLE,
      KW_READ_ONLY,
      KW_READ_WRITE,
      KW_DESCRIPTION,
      KW_DISPLAY
};

static struct keyword {
      char  *name;
      short id;
} keywords[] = {
      {"timeout",       KW_TIMEOUT        },
      {"delay",         KW_DELAY          },
      {"prompt",        KW_PROMPT         },
      {"kernel",        KW_KERNEL         },
      {"image",         KW_KERNEL         },
      {"cmdline",       KW_CMDLINE        },
      {"append",        KW_APPEND         },
      {"restricted",    KW_RESTRICTED     },
      {"calldbg",       KW_CALLDBG        },
      {"callmonitor",   KW_CALLDBG        },
      {"memsize",       KW_MEMSIZE        },
      {"label",         KW_LABEL          },
      {"alias",         KW_ALIAS          },
      {"ramdisk",       KW_RAMDISK        },
      {"boot",          KW_BOOT                 },
      {"default",       KW_DEFAULT        },
      {"ip",                  KW_IP             },
      {"debug",         KW_DEBUG          },
      {"root",          KW_ROOT                 },
      {"console",       KW_CONSOLE        },
      {"read-only",     KW_READ_ONLY      },
      {"read-write",    KW_READ_WRITE     },
      {"description",   KW_DESCRIPTION    },
      {"display",       KW_DISPLAY        }
};

#define NUMKEYWORDS     (sizeof(keywords) / sizeof(keywords[0]))

/*--------------------------------------------------------------------------*/

int
keyword
(     const char        *name
)
{     struct keyword    *kw = keywords;
      int                     i     = NUMKEYWORDS;

      do    {
            if (equal_strings(kw->name, name))
                  return kw->id;
            kw++;
      } while (--i);

      return KW_UNKNOWN;
}

/*--------------------------------------------------------------------------*/
/* return pointer to specified line of configuration data
 */

char *
goto_line
(     int         line
)
{     char  *p = config_data;

      if (line)
      {
            while (--line && (p != config_data_end))
            {
                  p += (strlen(p) + 1);
            }
      }

      return p;
}

/*--------------------------------------------------------------------------*/
/* Find start of spacified [display] section.
 * Returns line number of line following section marker or zero if not found.
 */

int
find_display_section
(     const char  *label
)
{     char        name[32];
      char        buff[sizeof(name)];
      int               line     = 1;
      char        *cfgp    = config_data;
      char        *p;

      strcpy(buff, "display");
      if (label && *label)
      {
            strcat(buff, "-");
            strcatn(buff, label, sizeof(buff));
      }
      label = buff;

      while (cfgp != config_data_end)
      {
            if (*cfgp == '[')
            {
                  /* get section name */
                  p = extract(name, cfgp + 1, sizeof(name), ']');

                  /* is this the section */
                  if (equal_strings(name, label) && check_arch(p))
                  {
                        return line + 1;
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      /* not found */
      return 0;
}

/*--------------------------------------------------------------------------*/
/* Find start of [boot] section with specified label name.
 * Returns line number of first option in section or zero if not found.
 */

int
find_boot_section
(     const char  *label
)
{     char        name[32];
      int               where    = 0;
      int               in_section = FALSE;
      int               line     = 1;
      char        *cfgp    = config_data;
      char        *p;

      while (cfgp != config_data_end)
      {
            if (*cfgp == '[')
            {
                  /* get section name */
                  p = extract(name, cfgp + 1, sizeof(name), ']');

                  /* is this the section */
                  if (equal_strings(name, "boot") && check_arch(p))
                  {
                        in_section = TRUE;
                        where    = line;
                  }
                  else
                  {
                        in_section = FALSE;
                  }
            }
            else if (in_section)
            {
                  /* get option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  if (equal_strings(name, "label")
                  ||    equal_strings(name, "alias"))
                  {
                        if (equal_strings(label, despace(p)))
                        {
                              return where + 1;
                        }
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      return 0;
}

/*--------------------------------------------------------------------------*/
/* Find start of [crate] configuration section with an 'ip' option that
 * corresponds to the given IP address or search name.
 * Returns line number of first option in section or zero if not found.
 */

int
find_crate_section
(     const char  *search
)
{     char        name[32];
      int               where    = 0;
      int               in_section = FALSE;
      int               line     = 1;
      char        *cfgp    = config_data;
      char        *p;

      if (search == NULL)
      {
            return 0;
      }

      while (cfgp != config_data_end)
      {
            if (*cfgp == '[')
            {
                  /* get section name */
                  p = extract(name, cfgp + 1, sizeof(name), ']');

                  /* is this a [crate] section */
                  if (equal_strings(name, "crate") && check_arch(p))
                  {
                        in_section = TRUE;
                        where    = line;
                  }
                  else
                  {
                        in_section = FALSE;
                  }
            }
            else if (in_section)
            {
                  /* get option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  if (equal_strings(name, "ip"))
                  {
                        /* check if value matches string or IP range pattern */
                        if (equal_strings(search, p) || compare_ip(search, p))
                        {
                              return where + 1;
                        }
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      return 0;
}

/*--------------------------------------------------------------------------*/
/* Find start of [crate] configuration section without an any 'ip' option.
 * Returns line number of first option in section or zero if not found.
 */

int
find_default_crate_section
(     void
)
{     char        name[32];
      int               where    = 0;
      int               in_section = FALSE;
      int               line     = 1;
      char        *cfgp    = config_data;
      char        *p;

      while (cfgp != config_data_end)
      {
            if (*cfgp == '[')
            {
                  /* if last crate section was not named */
                  if (where)
                  {
                        /* found it */
                        break;
                  }

                  /* get section name */
                  p = extract(name, cfgp + 1, sizeof(name), ']');

                  /* is this a [crate] section */
                  if (equal_strings(name, "crate") && check_arch(p))
                  {
                        in_section = TRUE;
                        where    = line + 1;
                  }
                  else
                  {
                        in_section = FALSE;
                        where      = 0;
                  }
            }
            else if (in_section)
            {
                  /* get option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  if (equal_strings(name, "ip"))
                  {
                        where = 0;
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      return where;
}

/*--------------------------------------------------------------------------*/

int
get_number
(     const char        *p,
      unsigned long     *result
)
{     char              c;
      int                     base;
      int                     digits;
      unsigned long     number;

      if (*p == '\0')
      {
            return FALSE;
      }

      /* determine number base from prefix */
      if (*p == '0')
      {
            if (p[1] == 'X' || p[1] == 'x')
            {
                  p     += 2;
                  base = 16;
            }
            else if (p[1] == 'B' || p[1] == 'b')
            {
                  p     += 2;
                  base = 2;
            }
            else
            {
                  base = 8;
            }
      }
      else
      {
            base = 10;
      }

      number = 0;
      digits = 0;

      while (*p != '\0')
      {
            c = *p++;

            if (c < '!')
            {
                  break;
            }

            /* look for 'M' and 'K' suffixes */
            if (digits && (*p < '!'))
            {
                  if (c == 'M' || c == 'm')
                  {
                        number = number * 1024 * 1024;
                        break;
                  }

                  if (c == 'K' || c == 'k')
                  {
                        number = number * 1024;
                        break;
                  }
            }

            if (c >= '0' && c <= '9')
            {
                  c -= '0';
            }

            else if (c >= 'a' && c <= 'z')
            {
                  c -= 'a' - 10;
            }

            else if (c >= 'A' && c <= 'Z')
            {
                  c -= 'A' - 10;
            }

            else                    /* unrecognised character     */
            {
                  return FALSE;
            }

            if (c >= base)          /* not in number base         */
            {
                  return FALSE;
            }

            digits++;
            switch (base)
            {
                  case  2: number = (number << 1); break;
                  case  8: number = (number << 3); break;
                  case 10: number = (number << 3)
                                          + (number << 1); break;
                  case 16: number = (number << 4); break;
            }
            number += c;
      }

      if (digits == 0)
      {
            return FALSE;
      }

      *result = number;

      return TRUE;
}

/*--------------------------------------------------------------------------*/

int
get_bool
(     const char        *text
)
{     unsigned long     result;

      if (text[0] == '\0')
      {
            return TRUE;
      }

      if (equal_strings(text, "true")
      ||    equal_strings(text, "yes" ))
      {
            return TRUE;
      }

      if (equal_strings(text, "false")
      ||    equal_strings(text, "no"   ))
      {
            return FALSE;
      }

      if (get_number(text, &result))
      {
            return (result != 0);
      }

      return FAILURE;
}

/*--------------------------------------------------------------------------*/

void
config_error
(     int         line,
      char  *data
)
{
      printf("Configuration line %u reads:\n %s\n", line, data);
}

/*--------------------------------------------------------------------------*/

int
bool_config_error
(     int         line,
      char  *data,
      int         willuse
)
{
      config_error(line, data);
      printf("Invalid boolean expression, using default value of %s.\n",
            willuse ? "True" : "False");

      return willuse;
}

/*--------------------------------------------------------------------------*/

unsigned long
number_config_error
(     int                     line,
      char              *data,
      unsigned long     willuse
)
{
      config_error(line, data);
      printf("Invalid numeric constant, using default value %lu.\n", willuse);

      return willuse;
}

/*--------------------------------------------------------------------------*/

void
ignore_option
(     int                     line,
      char              *data
)
{
      config_error(line, data);
      printf("I don't recognise this here, so I am ignoring it.\n");
}

/*--------------------------------------------------------------------------*/

void
duplicate_option
(     int                     line,
      char              *data
)
{
      config_error(line, data);
      printf("This parameter has already been defined, so I will ignore it\n");
}

/*--------------------------------------------------------------------------*/
/* scan list of boot configurations to find specified boot configuration
 */

BOOT *
find_boot_config
(     BOOT  *boot,
      char  *bootname
)
{
      while (boot)
      {
            if (equal_strings(boot->label, bootname)
            ||    equal_strings(boot->alias, bootname))
            {
                  break;
            }

            boot = boot->next;
      }

      return boot;
}

/*--------------------------------------------------------------------------*/
/* Add boot configuration to crate
 */

BOOT *
add_boot
(     CRATE *crate,
      BOOT  *boot
)
{     BOOT  **last = &crate->boot_list;

      if (boot)
      {
            while (*last)
                  last = &(*last)->next;

            *last      = boot;
            boot->next = NULL;
      }

      return boot;
}

/*--------------------------------------------------------------------------*/

void
dump_crate
(     CRATE             *crate
)
{     BOOT              *boot;
      unsigned long     ms;

      put_str("[crate]\n");
      printf("timeout       = %lu seconds\n", crate->timeout);
      printf("delay         = %lu seconds\n", crate->delay  );
      printf("prompt        = %s\n", crate->prompt ? "Yes" : "No");
      printf("default       = %s\n", crate->boot_dflt->label);

      for (boot = crate->boot_list; boot; boot = boot->next)
      {
            put_str("\n[boot]\n");
            printf("label         = %s\n", boot->label);
            if (boot->alias)
                  printf("alias         = %s\n", boot->alias);
            if (boot->description)
                  printf("description   = %s\n", boot->description);
            printf("kernel        = %s\n", boot->kernel);
            printf("ramdisk       = %s\n", boot->ramdisk ? boot->ramdisk : "None");
            printf("console       = %s\n", boot->console ? boot->console : "");
            printf("root          = %s\n", boot->root    ? boot->root    : "");
            if      (boot->read_only == TRUE ) printf("read-only\n");
            else if (boot->read_only == FALSE) printf("read-write\n");
            printf("cmdline       = %s\n", boot->cmdline ? boot->cmdline : "");
            printf("append        = %s\n", boot->append  ? boot->append  : "");
            printf("restricted    = %s\n", boot->restricted ? "Yes" : "No");
            printf("call debugger = %s\n", boot->calldbg ? "Yes" : "No");
            put_str("memory size   = ");
            if ((ms = boot->memsize) == 0)
            {
                  ms = detected_mem_size;
                  put_str("auto detected ");
            }
            printf("%luK\n", ms >> 10);
      }

      put_char('\n');
}

/*--------------------------------------------------------------------------*/
/* parse boot configuration at specified line and return pointer to
 * allocated boot configuration data or NULL if error.
 */

BOOT *
parse_boot
(     int                     line,
      CRATE             *crate
)
{     char              *cfgp;
      char              *p;
      char              name[32];
      int                     bool;
      unsigned long     number;
      int                     saveline = line;
      BOOT              *boot  = xmalloc(sizeof(BOOT));

      /* setup defaults */
      boot->restricted  = crate->restricted;
      boot->calldbg       = crate->calldbg;
      boot->memsize       = crate->memsize;
      boot->cmdline       = crate->cmdline;
      boot->append        = crate->append;
      boot->kernel        = crate->kernel;
      boot->ramdisk       = crate->ramdisk;
      boot->root        = crate->root;
      boot->console     = crate->console;
      boot->read_only   = crate->read_only;
      boot->description = NULL;
      boot->alias         = NULL;
      boot->label         = NULL;
      boot->next          = NULL;

      /* seek to specified line number */
      cfgp = goto_line(line);

      /* until end of data or start of next section */
      while ((cfgp != config_data_end) && (*cfgp != '['))
      {
            /* ignore blank lines */
            if (*cfgp != '\0')
            {
                  /* copy option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  switch (keyword(name))
                  {
                        case KW_DEBUG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, debug_mode);
                              debug_mode = bool;
                              break;

                        case KW_LABEL:
                              if (boot->label)
                                    goto duplicate;
                              boot->label = despace(p);
                              break;

                        case KW_ALIAS:
                              if (boot->alias)
                                    goto duplicate;
                              boot->alias = despace(p);
                              break;

                        case KW_DESCRIPTION:
                              boot->description = p;
                              break;

                        case KW_CMDLINE:
                              boot->cmdline = p;
                              break;

                        case KW_APPEND:
                              boot->append = p;
                              break;

                        case KW_KERNEL:
                              boot->kernel = p;
                              break;

                        case KW_RAMDISK:
                              boot->ramdisk = RAMDISK(p);
                              break;

                        case KW_RESTRICTED:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, boot->restricted);
                              boot->restricted = bool;
                              break;

                        case KW_CALLDBG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, boot->calldbg);
                              boot->calldbg = bool;
                              break;

                        case KW_MEMSIZE:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, boot->memsize);

                              /* force to PAGE_SIZE boundary */
                              boot->memsize = PAGE_BOUNDARY(number);
                              break;

                        case KW_ROOT:
                              boot->root = p;
                              break;

                        case KW_CONSOLE:
                              if (mem_cmp(p, "/dev/", 5) == 0)
                                    p += 5;
                              boot->console = p;
                              break;

                        case KW_READ_ONLY:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, boot->read_only != FALSE);
                              boot->read_only = bool;
                              break;

                        case KW_READ_WRITE:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, boot->read_only == FALSE);
                              boot->read_only = !bool;
                              break;

                        default:
                              ignore_option(line, cfgp);
                              break;

                        duplicate:
                              duplicate_option(line, cfgp);
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      /* if no label use alias as label */
      if (boot->label == NULL)
      {
            /* If no alias, silently discard this boot configuration.
             * We will only get here if building a list of all
             * boot configurations so we don't want to include it
             * as it can't be listed or selected.
             */
            if (boot->alias == NULL)
            {
                  goto bad;
            }

            boot->label = boot->alias;
            boot->alias = NULL;
      }

      if (boot->kernel == NULL)
      {
            printf("[boot] section starting at line %u is not bootable\n",
                        saveline - 1);
            goto bad;
      }

      return boot;

bad:
      free(boot);
      return NULL;
}

/*--------------------------------------------------------------------------*/
/* build a boot configuration from crate default values
 */

void
build_boot_from_defaults
(     CRATE       *crate
)
{     BOOT        *boot;

      /* if no default kernel */
      if (crate->kernel == NULL)
      {
            /* not bootable */
            return;
      }

      boot = xmalloc(sizeof(BOOT));

      /* setup defaults */
      boot->restricted  = crate->restricted;
      boot->calldbg       = crate->calldbg;
      boot->memsize       = crate->memsize;
      boot->cmdline       = crate->cmdline;
      boot->append        = crate->append;
      boot->kernel        = crate->kernel;
      boot->ramdisk       = crate->ramdisk;
      boot->root        = crate->root;
      boot->console     = crate->console;
      boot->read_only   = crate->read_only;
      boot->description = NULL;
      boot->alias         = NULL;
      boot->label         = "linux";
      boot->next          = NULL;

      add_boot(crate, boot);
}

/*--------------------------------------------------------------------------*/
/* build a boot configuration list using all defined [boot] sections
 */

void
build_boot_list
(     CRATE             *crate
)
{     char              *cfgp   = config_data;
      int                     line    = 1;
      char              name[32];
      char              *p;

      /* until end of data */
      while (cfgp != config_data_end)
      {
            /* if start of a new section */
            if (*cfgp == '[')
            {
                  /* get section name */
                  p = extract(name, cfgp + 1, sizeof(name), ']');

                  if (equal_strings(name, "boot") && check_arch(p))
                  {
                        /* add it */
                        add_boot(crate, parse_boot(line + 1, crate));
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }
}

/*--------------------------------------------------------------------------*/

void
parse_globals
(     CRATE             *crate
)
{     char              *cfgp = config_data;
      int                     line  = 1;
      char              *p;
      unsigned long     number;
      int                     bool;
      char              name[32];

      /* setup default values for crate */
      debug_mode          = FALSE;
      crate->timeout      = 0;
      crate->delay        = 3;
      crate->prompt       = FALSE;
      crate->display    = NULL;
      crate->cmdline      = NULL;
      crate->append       = NULL;
      crate->kernel     = NULL;
      crate->ramdisk    = NULL;
      crate->root       = NULL;
      crate->console    = "ttyS0";
      crate->read_only  = -1;       /* undefined */
      crate->restricted = FALSE;
      crate->calldbg      = FALSE;
      crate->memsize      = 0;            /* auto detect */

      /* until end of data or start of first section */
      while ((cfgp != config_data_end) && (*cfgp != '['))
      {
            /* ignore blank lines */
            if (*cfgp != '\0')
            {
                  /* copy option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  switch (keyword(name))
                  {
                        case KW_DEBUG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, debug_mode);
                              debug_mode = bool;
                              break;

                        case KW_TIMEOUT:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->timeout);
                              crate->timeout = number;
                              break;

                        case KW_DELAY:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->delay);
                              crate->delay = number;
                              break;

                        case KW_PROMPT:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->prompt);
                              crate->prompt = bool;
                              break;

                        case KW_RESTRICTED:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->restricted);
                              crate->restricted = bool;
                              break;

                        case KW_CALLDBG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->calldbg);
                              crate->calldbg = bool;
                              break;

                        case KW_MEMSIZE:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->memsize);

                              /* force to PAGE_SIZE boundary */
                              crate->memsize = PAGE_BOUNDARY(number);
                              break;

                        case KW_DISPLAY:
                              if (crate->display)
                                    goto duplicate;
                              crate->display = p;
                              break;

                        case KW_KERNEL:
                              if (crate->kernel)
                                    goto duplicate;
                              crate->kernel = p;
                              break;

                        case KW_RAMDISK:
                              if (crate->ramdisk)
                                    goto duplicate;
                              crate->ramdisk = RAMDISK(p);

                        case KW_CMDLINE:
                              if (crate->cmdline)
                                    goto duplicate;
                              crate->cmdline = p;
                              break;

                        case KW_APPEND:
                              if (crate->append)
                                    goto duplicate;
                              crate->append = p;
                              break;

                        case KW_ROOT:
                              if (crate->root)
                                    goto duplicate;
                              crate->root = p;
                              break;

                        case KW_CONSOLE:
                              if (mem_cmp(p, "/dev/", 5) == 0)
                                    p += 5;
                              crate->console = p;
                              break;

                        case KW_READ_ONLY:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->read_only != FALSE);
                              crate->read_only = bool;
                              break;

                        case KW_READ_WRITE:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->read_only == FALSE);
                              crate->read_only = !bool;
                              break;

                        default:
                              ignore_option(line, cfgp);
                              break;

                        duplicate:
                              duplicate_option(line, cfgp);
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }
}

/*--------------------------------------------------------------------------*/
/* get configuration for given IP address from configuration data.
 */

void
parse_config
(     CRATE             *crate
)
{     char              *cfgp;
      char              *p;
      char              name[32];
      int                     bool;
      int                     line;
      int                     startline;
      int                     bootline;
      unsigned long     number;
      BOOT              *boot;
      int                     kw;
      const char        *myip = get_ip(IP_CLIENT);

      if (myip == NULL || *myip == '\0')
      {
            myip = "0.0.0.0";
      }

      /* find crate configuration with specified address */
      if ((line = find_crate_section(myip)) == 0)
      {
            if ((line = find_crate_section("any")) == 0)
            {
                  /* find first crate section without an 'ip' option */
                  if ((line = find_default_crate_section()) == 0)
                  {
                        panic("Can't find configuration data for \"%s\".", myip);
                  }
            }
      }

      /* remember where crate configuration starts */
      startline = line;

      /* get default values from global definitions */
      parse_globals(crate);

      /* set other default values */
      crate->boot_list  = NULL;     /* no boot configurations           */
      crate->boot_dflt  = NULL;     /* no default                             */

      /* seek to specified line number */
      cfgp = goto_line(line);

      /* until end of data or start of next section */
      while ((cfgp != config_data_end) && (*cfgp != '['))
      {
            /* ignore blank lines */
            if (*cfgp != '\0')
            {
                  /* copy option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  switch (keyword(name))
                  {
                        case KW_DEBUG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, debug_mode);
                              debug_mode = bool;
                              break;

                        case KW_TIMEOUT:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->timeout);
                              crate->timeout = number;
                              break;

                        case KW_DELAY:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->delay);
                              crate->delay = number;
                              break;

                        case KW_PROMPT:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->prompt);
                              crate->prompt = bool;
                              break;

                        case KW_DISPLAY:
                              crate->display = p;
                              break;

                        case KW_KERNEL:
                              crate->kernel = p;
                              break;

                        case KW_RAMDISK:
                              crate->ramdisk = RAMDISK(p);
                              break;
 
                        case KW_CMDLINE:
                              crate->cmdline = p;
                              break;

                        case KW_APPEND:
                              crate->append = p;
                              break;

                        case KW_RESTRICTED:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->restricted);
                              crate->restricted = bool;
                              break;

                        case KW_CALLDBG:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->calldbg);
                              crate->calldbg = bool;
                              break;

                        case KW_MEMSIZE:
                              if (!get_number(p, &number))
                                    number = number_config_error(line, cfgp, crate->memsize);

                              /* force to PAGE_SIZE boundary */
                              crate->memsize = PAGE_BOUNDARY(number);
                              break;

                        case KW_ROOT:
                              crate->root = p;
                              break;

                        case KW_CONSOLE:
                              if (mem_cmp(p, "/dev/", 5) == 0)
                                    p += 5;
                              crate->console = p;
                              break;

                        case KW_READ_ONLY:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->read_only != FALSE);
                              crate->read_only = bool;
                              break;

                        case KW_READ_WRITE:
                              if ((bool = get_bool(p)) == FAILURE)
                                    bool = bool_config_error(line, cfgp, crate->read_only == FALSE);
                              crate->read_only = !bool;
                              break;

                        case KW_BOOT:
                        case KW_DEFAULT:
                              /* handle these in second pass
                               */
                              break;

                        case KW_IP:
                              /* we've already used this as a search key
                               * so we don't need to process it again
                               */
                              break;

                        default:
                              ignore_option(line, cfgp);
                              break;
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      /* parse boot configurations in second pass so that
       * default options can take effect even if specified
       * after a boot configuration selection.
       */

      /* seek back to start line number */
      cfgp = goto_line(line = startline);

      /* until end of data or start of next section */
      while ((cfgp != config_data_end) && (*cfgp != '['))
      {
            /* ignore blank lines */
            if (*cfgp != '\0')
            {
                  /* copy option name */
                  p = extract(name, cfgp, sizeof(name), '=');

                  switch (kw = keyword(name))
                  {
                        case KW_BOOT:
                        case KW_DEFAULT:
                              /* remove embedded spaces */
                              despace(p);

                              /* if item is already in boot list */
                              if (find_boot_config(crate->boot_list, p) != NULL)
                                    break;

                              /* find boot section with specified label or alias */
                              if (!(bootline = find_boot_section(p)))
                              {
                                    printf( "ignoring, boot item '%s' at line %d\n"
                                                "boot configuration not found\n",
                                                      p, line);

                                    break;
                              }

                              /* parse boot configuration */
                              if ((boot = parse_boot(bootline, crate)) == NULL)
                                    break;

                              /* set default boot item if not already set */
                              if (kw == KW_DEFAULT && crate->boot_dflt == NULL)
                                    crate->boot_dflt = boot;

                              /* add it */
                              add_boot(crate, boot);
                              break;
                  }
            }

            /* next line */
            line++;
            cfgp += (strlen(cfgp) + 1);
      }

      /* if no boot configurations */
      if (crate->boot_list == NULL)
      {
            /* build a boot configuration from default values
             */
            build_boot_from_defaults(crate);

            if (crate->boot_list == NULL)
            {
                  /* final chance try building a boot list from all the available
                   * boot configurations
                   */
                  build_boot_list(crate);

                  if (crate->boot_list == NULL)
                  {
                        panic("Crate at line %d has no valid boot configurations",
                              startline);
                  }
            }
      }

      /* if no default item specified */
      if (crate->boot_dflt == NULL)
      {
            /* use first */
            crate->boot_dflt = crate->boot_list;
      }

      if (debug_mode)
            dump_crate(crate);
}

/*--------------------------------------------------------------------------*/
/* Dump contents of [display] section to console
 * Returns TRUE if message printed or no message required
 */

int
print_display_section
(     const char  *label
)
{     char        *cfgp;
      int               line;

      if ((line = find_display_section(label)) == 0)
      {
            return label ? FALSE : TRUE;
      }

      cfgp = goto_line(line);

      /* until end of data or start of next section */
      while (cfgp != config_data_end && *cfgp != '[')
      {
            /* ignore blank lines */
            if (*cfgp != '\0')
            {
                  put_estr(cfgp);
            }

            /* next line */
            cfgp += (strlen(cfgp) + 1);
      }

      return TRUE;
}

/*-----------------------------< end of file >------------------------------*/

Generated by  Doxygen 1.6.0   Back to index