1
/* Handling and parsing of silo.conf
3
Copyright (C) 1995 Werner Almesberger
4
1996,1998 Jakub Jelinek
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22
/* This file gets included by the silo program (userspace), try to be nice */
26
#include <stringops.h>
29
#define NULL (void *)0
33
#endif /* !SILOCONFCHECK */
36
cft_strg, cft_flag, cft_end
46
#define MAX_VAR_NAME MAX_TOKEN
53
{cft_strg, "device", NULL},
54
{cft_strg, "partition", NULL},
55
{cft_strg, "default", NULL},
56
{cft_strg, "timeout", NULL},
57
{cft_strg, "message", NULL},
58
{cft_strg, "root", NULL},
59
{cft_strg, "ramdisk", NULL},
60
{cft_flag, "read-only", NULL},
61
{cft_flag, "read-write", NULL},
62
{cft_strg, "append", NULL},
63
{cft_strg, "initrd", NULL},
64
{cft_flag, "initrd-prompt", NULL},
65
{cft_strg, "initrd-size", NULL},
66
{cft_flag, "pause-after", NULL},
67
{cft_strg, "pause-message", NULL},
68
{cft_flag, "fill-reboot-cmd", NULL},
69
{cft_strg, "password", NULL},
70
{cft_flag, "restricted", NULL},
71
{cft_strg, "proll", NULL},
72
{cft_flag, "partition-boot", NULL},
73
{cft_strg, "secondary", NULL},
74
{cft_end, NULL, NULL}};
78
{cft_strg, "image", NULL},
79
{cft_strg, "other", NULL},
80
{cft_strg, "label", NULL},
81
{cft_strg, "alias", NULL},
82
{cft_strg, "device", NULL},
83
{cft_strg, "partition", NULL},
84
{cft_strg, "root", NULL},
85
{cft_strg, "ramdisk", NULL},
86
{cft_flag, "read-only", NULL},
87
{cft_flag, "read-write", NULL},
88
{cft_strg, "append", NULL},
89
{cft_strg, "literal", NULL},
90
{cft_strg, "initrd", NULL},
91
{cft_flag, "initrd-prompt", NULL},
92
{cft_strg, "initrd-size", NULL},
93
{cft_flag, "pause-after", NULL},
94
{cft_strg, "pause-message", NULL},
95
{cft_flag, "solaris", NULL},
96
{cft_flag, "fill-reboot-cmd", NULL},
97
{cft_strg, "bootblock", NULL},
98
{cft_flag, "single-key", NULL},
99
{cft_strg, "proll", NULL},
100
{cft_end, NULL, NULL}};
102
static char flag_set;
103
static char *last_token = NULL, *last_item = NULL, *last_value = NULL;
105
static int back = 0; /* can go back by one char */
108
static char *file_name;
109
static CONFIG *curr_table = cf_options;
112
static struct IMAGES {
113
CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
117
void cfg_error (char *msg,...)
122
printf ("Config file error: ");
125
printf (" near line %d in file %s\n", line_num, file_name);
129
inline int my_getc ()
136
#define next_raw next
137
static int next (void)
148
static void again (int ch)
153
static char *cfg_get_token (void)
155
char buf[MAX_TOKEN + 1];
165
while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n')
172
while (ch = next_raw (), ch != '\n')
181
while (here - buf < MAX_TOKEN) {
182
if ((ch = next ()) == EOF)
183
cfg_error ("EOF in quoted string");
190
if (ch != '"' && ch != '\\' && ch != '\n')
191
cfg_error ("Bad use of \\ in quoted string");
193
while ((ch = next ()), ch == ' ' || ch == '\t');
200
if (ch == '\n' || ch == '\t')
201
cfg_error ("\\n and \\t are not allowed in quoted strings");
204
cfg_error ("Quoted string is too long");
205
return 0; /* not reached */
209
while (here - buf < MAX_TOKEN) {
212
cfg_error ("\\ precedes EOF");
216
*here++ = ch == '\t' ? ' ' : ch;
219
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' ||
220
ch == '=' || ch == EOF) {
225
if (!(escaped = (ch == '\\')))
230
cfg_error ("Token is too long");
231
return 0; /* not reached */
234
static void cfg_return_token (char *token)
239
static int cfg_next (char **item, char **value)
250
if (!(*item = cfg_get_token ()))
252
if (!strcmp (*item, "="))
253
cfg_error ("Syntax error");
254
if (!(this = cfg_get_token ()))
256
if (strcmp (this, "=")) {
257
cfg_return_token (this);
260
if (!(*value = cfg_get_token ()))
261
cfg_error ("Value expected at EOF");
262
if (!strcmp (*value, "="))
263
cfg_error ("Syntax error after %s", *item);
267
static void cfg_return (char *item, char *value)
273
static int cfg_set (char *item, char *value)
277
if (!strncasecmp (item, "image", 5) || !strcasecmp (item, "other")) {
278
struct IMAGES **p = &images;
280
if (item[5] == '[' && item[strlen(item) - 1] == ']') {
284
for (p = item + 6; q; p = q) {
288
if (strncasecmp (p, "sun4", 4))
290
switch (tolower(p[4])) {
292
case ']': if (architecture == sun4) goto cfg_set_cont; break;
293
case 'c': if (architecture == sun4c) goto cfg_set_cont; break;
294
case 'd': if (architecture == sun4d) goto cfg_set_cont; break;
295
case 'e': if (architecture == sun4e) goto cfg_set_cont; break;
296
case 'm': if (architecture == sun4m) goto cfg_set_cont; break;
297
case 'u': if (architecture == sun4u) goto cfg_set_cont; break;
301
curr_table = (CONFIG *)malloc(sizeof (cf_image));
302
memcpy (curr_table, cf_image, sizeof (cf_image));
310
*p = malloc (sizeof (struct IMAGES));
312
curr_table = ((*p)->table);
313
memcpy (curr_table, cf_image, sizeof (cf_image));
316
for (walk = curr_table; walk->type != cft_end; walk++) {
317
if (walk->name && !strcasecmp (walk->name, item)) {
318
if (value && walk->type != cft_strg)
319
cfg_error ("'%s' doesn't have a value", walk->name);
320
if (!value && walk->type == cft_strg)
321
cfg_error ("Value expected for '%s'", walk->name);
323
cfg_error ("Duplicate entry '%s'", walk->name);
324
if (walk->type == cft_flag)
325
walk->data = &flag_set;
326
else if (walk->type == cft_strg)
331
if (walk->type != cft_end) {
332
if (!strcasecmp (item, "other")) {
338
cfg_return (item, value);
342
int cfg_parse (char *cfg_file, char *buff, int len)
346
file_name = cfg_file;
352
if (!cfg_next (&item, &value))
354
if (!cfg_set (item, value))
360
static char *cfg_get_strg_i (CONFIG * table, char *item)
364
for (walk = table; walk->type != cft_end; walk++)
365
if (walk->name && !strcasecmp (walk->name, item))
370
char *cfg_get_strg (char *image, char *item)
377
return cfg_get_strg_i (cf_options, item);
378
for (p = images; p; p = p->next) {
379
label = cfg_get_strg_i (p->table, "label");
381
label = cfg_get_strg_i (p->table, "image");
382
alias = strrchr (label, '/');
386
alias = cfg_get_strg_i (p->table, "alias");
387
if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
388
ret = cfg_get_strg_i (p->table, item);
390
ret = cfg_get_strg_i (cf_options, item);
397
int cfg_get_flag (char *image, char *item)
399
return !!cfg_get_strg (image, item);
402
static int printl_count = 0;
403
static void printlabel (const char *label, char **addr, const char *match)
405
int len = strlen (label);
408
(strlen(label) >= strlen(match) &&
409
!strncmp(match, label, strlen(match)))) {
412
strcpy(*addr, label);
413
*addr += strlen(label) + 1;
416
if (!(printl_count % 3))
418
printf ("%s", label);
426
int cfg_print_images (char *addr, char *match)
432
if (addr) addr[0] = '\0';
434
for (p = images; p; p = p->next) {
435
label = cfg_get_strg_i (p->table, "label");
437
label = cfg_get_strg_i (p->table, "image");
438
alias = strrchr (label, '/');
442
alias = cfg_get_strg_i (p->table, "alias");
443
printlabel(label, &addr, match);
445
printlabel (alias, &addr, match);
447
if (!addr && printl_count)
452
char *cfg_get_default (void)
455
char *ret = cfg_get_strg_i (cf_options, "default");
461
ret = cfg_get_strg_i (images->table, "label");
463
ret = cfg_get_strg_i (images->table, "image");
464
label = strrchr (ret, '/');