home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / com32 / modules / readconfig.c < prev   
Encoding:
C/C++ Source or Header  |  2004-12-28  |  5.5 KB  |  247 lines

  1. #ident "$Id: readconfig.c,v 1.4 2004/12/28 23:18:27 hpa Exp $"
  2. /* ----------------------------------------------------------------------- *
  3.  *   
  4.  *   Copyright 2004 H. Peter Anvin - All Rights Reserved
  5.  *
  6.  *   This program is free software; you can redistribute it and/or modify
  7.  *   it under the terms of the GNU General Public License as published by
  8.  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
  9.  *   Boston MA 02111-1307, USA; either version 2 of the License, or
  10.  *   (at your option) any later version; incorporated herein by reference.
  11.  *
  12.  * ----------------------------------------------------------------------- */
  13.  
  14. #define _GNU_SOURCE        /* Needed for asprintf() on Linux */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <minmax.h>
  19. #include <alloca.h>
  20. #ifdef __COM32__
  21. # include <com32.h>
  22. #endif
  23.  
  24. #include "menu.h"
  25.  
  26. int nentries  = 0;
  27. int defentry  = 0;
  28. int allowedit = 1;        /* Allow edits of the command line */
  29. int timeout   = 0;
  30.  
  31. char *menu_title = "";
  32. char *ontimeout  = NULL;
  33.  
  34. struct menu_entry menu_entries[MAX_ENTRIES];
  35. struct menu_entry *menu_hotkeys[256];
  36.  
  37. #define astrdup(x) ({ char *__x = (x); \
  38.                       size_t __n = strlen(__x) + 1; \
  39.                       char *__p = alloca(__n); \
  40.                       if ( __p ) memcpy(__p, __x, __n); \
  41.                       __p; })
  42.  
  43. const char *ipappends[32];
  44.                       
  45. static void
  46. get_ipappend(void)
  47. {
  48. #ifdef __COM32__
  49.   static com32sys_t r;
  50.   uint16_t *ipp;
  51.   int i;
  52.   int nipappends;
  53.  
  54.   r.eax.w[0] = 0x000F;
  55.   __intcall(0x22, &r, &r);
  56.  
  57.   nipappends = min(r.ecx.w[0], 32);
  58.   ipp        = MK_PTR(r.es, r.ebx.w[0]);
  59.   for ( i = 0 ; i < nipappends ; i++ ) {
  60.     ipappends[i] = MK_PTR(r.es, *ipp++);
  61.   }
  62. #else
  63.   ipappends[0] = "ip=foo:bar:baz:quux";
  64.   ipappends[1] = "BOOTIF=01-aa-bb-cc-dd-ee-ff";
  65. #endif
  66. }
  67.  
  68. static const char *
  69. get_config(void)
  70. {
  71. #ifdef __COM32__
  72.   static com32sys_t r;
  73.   
  74.   r.eax.w[0] = 0x000E;
  75.   __intcall(0x22, &r, &r);
  76.  
  77.   return MK_PTR(r.es, r.ebx.w[0]);
  78. #else
  79.   return "syslinux.cfg";    /* Dummy default name */
  80. #endif
  81. }
  82.   
  83. #define MAX_LINE 512
  84.  
  85. static char *
  86. skipspace(char *p)
  87. {
  88.   while ( *p && *p <= ' ' )
  89.     p++;
  90.   
  91.   return p;
  92. }
  93.  
  94. /* Check to see if we are at a certain keyword (case insensitive) */
  95. static int looking_at(const char *line, const char *kwd)
  96. {
  97.   const char *p = line;
  98.   const char *q = kwd;
  99.  
  100.   while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) {
  101.     p++;
  102.     q++;
  103.   }
  104.  
  105.   if ( *q )
  106.     return 0;            /* Didn't see the keyword */
  107.  
  108.   return *p <= ' ';        /* Must be EOL or whitespace */
  109. }
  110.  
  111. struct labeldata {
  112.   char *label;
  113.   char *kernel;
  114.   char *append;
  115.   char *menulabel;
  116.   unsigned int ipappend;
  117.   unsigned int menuhide;
  118.   unsigned int menudefault;
  119. };
  120.  
  121. static void record(struct labeldata *ld, char *append)
  122. {
  123.   char ipoptions[256], *ipp;
  124.   int i;
  125.   struct menu_entry *me = &menu_entries[nentries];
  126.  
  127.   if ( ld->label ) {
  128.     char *a, *s;
  129.     me->displayname = ld->menulabel ? ld->menulabel : ld->label;
  130.     me->label       = ld->label;
  131.     me->hotkey = 0;
  132.  
  133.     if ( ld->menulabel ) {
  134.       unsigned char *p = strchr(ld->menulabel, '^');
  135.       if ( p && p[1] ) {
  136.     int hotkey = p[1] & ~0x20;
  137.     if ( !menu_hotkeys[hotkey] ) {
  138.       me->hotkey = hotkey;
  139.     }
  140.       }
  141.     }
  142.  
  143.     ipp = ipoptions;
  144.     *ipp = '\0';
  145.     for ( i = 0 ; i < 32 ; i++ ) {
  146.       if ( (ld->ipappend & (1U << i)) && ipappends[i] )
  147.     ipp += sprintf(ipp, " %s", ipappends[i]);
  148.     }
  149.  
  150.     a = ld->append;
  151.     if ( !a ) a = append;
  152.     if ( !a || (a[0] == '-' && !a[1]) ) a = "";
  153.     s = a[0] ? " " : "";
  154.     asprintf(&me->cmdline, "%s%s%s%s", ld->kernel, ipoptions, s, a);
  155.  
  156.     ld->label = NULL;
  157.     free(ld->kernel);
  158.     if ( ld->append )
  159.       free(ld->append);
  160.  
  161.     if ( !ld->menuhide ) {
  162.       if ( me->hotkey )
  163.     menu_hotkeys[me->hotkey] = me;
  164.  
  165.       if ( ld->menudefault )
  166.     defentry = nentries;
  167.  
  168.       nentries++;
  169.     }
  170.   }
  171. }
  172.  
  173. void parse_config(const char *filename)
  174. {
  175.   char line[MAX_LINE], *p;
  176.   FILE *f;
  177.   char *append = NULL;
  178.   static struct labeldata ld;
  179.  
  180.   get_ipappend();
  181.  
  182.   if ( !filename )
  183.     filename = get_config();
  184.  
  185.   f = fopen(filename, "r");
  186.   if ( !f )
  187.     return;
  188.  
  189.   while ( fgets(line, sizeof line, f) ) {
  190.     p = strchr(line, '\r');
  191.     if ( p )
  192.       *p = '\0';
  193.     p = strchr(line, '\n');
  194.     if ( p )
  195.       *p = '\0';
  196.  
  197.     p = skipspace(line);
  198.  
  199.     if ( looking_at(p, "menu") ) {
  200.       p = skipspace(p+4);
  201.       
  202.       if ( looking_at(p, "title") ) {
  203.     menu_title = strdup(skipspace(p+5));
  204.       } else if ( looking_at(p, "label") ) {
  205.     if ( ld.label )
  206.       ld.menulabel = strdup(skipspace(p+5));
  207.       } else if ( looking_at(p, "default") ) {
  208.     ld.menudefault = 1;
  209.       } else if ( looking_at(p, "hide") ) {
  210.     ld.menuhide = 1;
  211.       } else {
  212.     /* Unknown, ignore for now */
  213.       }
  214.     } else if ( looking_at(p, "append") ) {
  215.       char *a = strdup(skipspace(p+6));
  216.       if ( ld.label )
  217.     ld.append = a;
  218.       else
  219.     append = a;
  220.     } else if ( looking_at(p, "label") ) {
  221.       p = skipspace(p+5);
  222.       record(&ld, append);
  223.       ld.label     = strdup(p);
  224.       ld.kernel    = strdup(p);
  225.       ld.append    = NULL;
  226.       ld.menulabel = NULL;
  227.       ld.ipappend  = ld.menudefault = ld.menuhide = 0;
  228.     } else if ( looking_at(p, "kernel") ) {
  229.       if ( ld.label ) {
  230.     free(ld.kernel);
  231.     ld.kernel = strdup(skipspace(p+6));
  232.       }
  233.     } else if ( looking_at(p, "timeout") ) {
  234.       timeout = atoi(skipspace(p+7));
  235.     } else if ( looking_at(p, "ontimeout") ) {
  236.       ontimeout = strdup(skipspace(p+9));
  237.     } else if ( looking_at(p, "allowoptions") ) {
  238.       allowedit = atoi(skipspace(p+12));
  239.     } else if ( looking_at(p, "ipappend") ) {
  240.       ld.ipappend = atoi(skipspace(p+8));
  241.     }
  242.   }
  243.   
  244.   record(&ld, append);
  245.   fclose(f);
  246. }
  247.