1 /* Handling and parsing of silo.conf
3 Copyright (C) 1995 Werner Almesberger
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; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* Imported functions */
28 extern int strcasecmp(const char *s1, const char *s2);
31 cft_strg, cft_flag, cft_end
41 #define MAX_VAR_NAME MAX_TOKEN
46 {cft_strg, "device", NULL},
47 {cft_strg, "partition", NULL},
48 {cft_strg, "default", NULL},
49 {cft_strg, "timeout", NULL},
50 {cft_strg, "password", NULL},
51 {cft_flag, "restricted", NULL},
52 {cft_strg, "message", NULL},
53 {cft_strg, "root", NULL},
54 {cft_strg, "ramdisk", NULL},
55 {cft_flag, "read-only", NULL},
56 {cft_flag, "read-write", NULL},
57 {cft_strg, "append", NULL},
58 {cft_strg, "initrd", NULL},
59 {cft_flag, "initrd-prompt", NULL},
60 {cft_strg, "initrd-size", NULL},
61 {cft_flag, "pause-after", NULL},
62 {cft_strg, "pause-message", NULL},
63 {cft_strg, "init-code", NULL},
64 {cft_strg, "init-message", NULL},
65 {cft_strg, "fgcolor", NULL},
66 {cft_strg, "bgcolor", NULL},
67 {cft_strg, "ptypewarning", NULL},
68 {cft_end, NULL, NULL}};
72 {cft_strg, "image", NULL},
73 {cft_strg, "label", NULL},
74 {cft_strg, "alias", NULL},
75 {cft_flag, "single-key", NULL},
76 {cft_flag, "restricted", NULL},
77 {cft_strg, "device", NULL},
78 {cft_strg, "partition", NULL},
79 {cft_strg, "root", NULL},
80 {cft_strg, "ramdisk", NULL},
81 {cft_flag, "read-only", NULL},
82 {cft_flag, "read-write", NULL},
83 {cft_strg, "append", NULL},
84 {cft_strg, "literal", NULL},
85 {cft_strg, "initrd", NULL},
86 {cft_flag, "initrd-prompt", NULL},
87 {cft_strg, "initrd-size", NULL},
88 {cft_flag, "pause-after", NULL},
89 {cft_strg, "pause-message", NULL},
90 {cft_flag, "novideo", NULL},
91 {cft_strg, "sysmap", NULL},
92 {cft_end, NULL, NULL}};
95 static char *last_token = NULL, *last_item = NULL, *last_value = NULL;
97 static int back = 0; /* can go back by one char */
98 static char *currp = NULL;
99 static char *endp = NULL;
100 static char *file_name = NULL;
101 static CONFIG *curr_table = cf_options;
104 static struct IMAGES {
105 CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
109 void cfg_error (char *msg,...)
114 prom_printf ("Config file error: ");
115 prom_vprintf (msg, ap);
117 prom_printf (" near line %d in file %s\n", line_num, file_name);
121 void cfg_warn (char *msg,...)
126 prom_printf ("Config file warning: ");
127 prom_vprintf (msg, ap);
129 prom_printf (" near line %d in file %s\n", line_num, file_name);
139 #define next_raw next
140 static int next (void)
151 static void again (int ch)
156 static char *cfg_get_token (void)
158 char buf[MAX_TOKEN + 1];
168 while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
169 if (ch == '\n' || ch == '\r')
171 if (ch == EOF || ch == (int)NULL)
175 while (ch = next_raw (), (ch != '\n' && ch != '\r'))
184 while (here - buf < MAX_TOKEN) {
185 if ((ch = next ()) == EOF)
186 cfg_error ("EOF in quoted string");
199 while ((ch = next ()), ch == ' ' || ch == '\t');
209 cfg_error ("Bad use of \\ in quoted string");
211 } else if ((ch == '\n') || (ch == '\r'))
212 cfg_error ("newline is not allowed in quoted strings");
215 cfg_error ("Quoted string is too long");
216 return 0; /* not reached */
220 while (here - buf < MAX_TOKEN) {
223 cfg_error ("\\ precedes EOF");
227 *here++ = ch == '\t' ? ' ' : ch;
230 if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '#' ||
231 ch == '=' || ch == EOF) {
236 if (!(escaped = (ch == '\\')))
241 cfg_error ("Token is too long");
242 return 0; /* not reached */
245 static void cfg_return_token (char *token)
250 static int cfg_next (char **item, char **value)
261 if (!(*item = cfg_get_token ()))
263 if (!strcmp (*item, "="))
264 cfg_error ("Syntax error");
265 if (!(this = cfg_get_token ()))
267 if (strcmp (this, "=")) {
268 cfg_return_token (this);
271 if (!(*value = cfg_get_token ()))
272 cfg_error ("Value expected at EOF");
273 if (!strcmp (*value, "="))
274 cfg_error ("Syntax error after %s", *item);
279 // The one and only call to this procedure is commented out
280 // below, so we don't need this unless we decide to use it again.
281 static void cfg_return (char *item, char *value)
288 static int cfg_set (char *item, char *value)
292 if (!strcasecmp (item, "image")) {
293 struct IMAGES **p = &images;
297 *p = (struct IMAGES *)malloc (sizeof (struct IMAGES));
299 prom_printf("malloc error in cfg_set\n");
303 curr_table = ((*p)->table);
304 memcpy (curr_table, cf_image, sizeof (cf_image));
306 for (walk = curr_table; walk->type != cft_end; walk++) {
307 if (walk->name && !strcasecmp (walk->name, item)) {
308 if (value && walk->type != cft_strg)
309 cfg_warn ("'%s' doesn't have a value", walk->name);
310 else if (!value && walk->type == cft_strg)
311 cfg_warn ("Value expected for '%s'", walk->name);
314 cfg_warn ("Duplicate entry '%s'", walk->name);
315 if (walk->type == cft_flag)
316 walk->data = &flag_set;
317 else if (walk->type == cft_strg)
323 if (walk->type != cft_end)
325 // cfg_return (item, value);
329 int cfg_parse (char *cfg_file, char *buff, int len)
333 file_name = cfg_file;
340 if (!cfg_next (&item, &value))
342 if (!cfg_set (item, value)) {
344 prom_printf("Can't set item %s to value %s\n", item, value);
351 static char *cfg_get_strg_i (CONFIG * table, char *item)
355 for (walk = table; walk->type != cft_end; walk++)
356 if (walk->name && !strcasecmp (walk->name, item))
361 char *cfg_get_strg (char *image, char *item)
368 return cfg_get_strg_i (cf_options, item);
369 for (p = images; p; p = p->next) {
370 label = cfg_get_strg_i (p->table, "label");
372 label = cfg_get_strg_i (p->table, "image");
373 alias = strrchr (label, '/');
377 alias = cfg_get_strg_i (p->table, "alias");
378 if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
379 ret = cfg_get_strg_i (p->table, item);
381 ret = cfg_get_strg_i (cf_options, item);
388 int cfg_get_flag (char *image, char *item)
390 return !!cfg_get_strg (image, item);
393 static int printl_count = 0;
394 static void printlabel (char *label, int defflag)
396 int len = strlen (label);
400 prom_printf ("%s %s",defflag?"*":" ", label);
404 if (printl_count == 3)
408 void cfg_print_images (void)
413 char *ret = cfg_get_strg_i (cf_options, "default");
417 for (p = images; p; p = p->next) {
418 label = cfg_get_strg_i (p->table, "label");
420 label = cfg_get_strg_i (p->table, "image");
421 alias = strrchr (label, '/');
425 if(!strcmp(ret,label))
429 alias = cfg_get_strg_i (p->table, "alias");
430 printlabel (label, defflag);
432 printlabel (alias, 0);
437 char *cfg_get_default (void)
440 char *ret = cfg_get_strg_i (cf_options, "default");
446 ret = cfg_get_strg_i (images->table, "label");
448 ret = cfg_get_strg_i (images->table, "image");
449 label = strrchr (ret, '/');
458 * c-file-style: "k&r"