Git init
[external/ifupdown.git] / config.c
1 #line 1033 "ifupdown.nw"
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <assert.h>
7 #line 1044 "ifupdown.nw"
8 #include "header.h"
9 #line 1263 "ifupdown.nw"
10 #include <errno.h>
11 #line 1397 "ifupdown.nw"
12 #include <ctype.h>
13 #line 1240 "ifupdown.nw"
14 static int get_line(char **result, size_t *result_len, FILE *f, int *line);
15 #line 1467 "ifupdown.nw"
16 static char *next_word(char *buf, char *word, int maxlen);
17 #line 1704 "ifupdown.nw"
18 static address_family *get_address_family(address_family *af[], char *name);
19 #line 1739 "ifupdown.nw"
20 static method *get_method(address_family *af, char *name);
21 #line 1800 "ifupdown.nw"
22 static int duplicate_if(interface_defn *ifa, interface_defn *ifb);
23 #line 1919 "ifupdown.nw"
24 allowup_defn *get_allowup(allowup_defn **allowups, char *name);
25
26 #line 1957 "ifupdown.nw"
27 allowup_defn *add_allow_up(char *filename, int line,
28          allowup_defn *allow_up, char *iface_name);
29 #line 1174 "ifupdown.nw"
30 interfaces_file *read_interfaces(char *filename) {
31         
32 #line 1210 "ifupdown.nw"
33 FILE *f;
34 int line;
35 #line 1247 "ifupdown.nw"
36 char *buf = NULL;
37 size_t buf_len = 0;
38 #line 1447 "ifupdown.nw"
39 interface_defn *currif = NULL;
40 mapping_defn *currmap = NULL;
41 enum { NONE, IFACE, MAPPING } currently_processing = NONE;
42 #line 1458 "ifupdown.nw"
43 char firstword[80];
44 char *rest;
45 #line 1176 "ifupdown.nw"
46         interfaces_file *defn;
47
48         
49 #line 1195 "ifupdown.nw"
50 defn = malloc(sizeof(interfaces_file));
51 if (defn == NULL) {
52         return NULL;
53 }
54 defn->allowups = NULL;
55 defn->mappings = NULL;
56 defn->ifaces = NULL;
57 #line 1179 "ifupdown.nw"
58         
59 #line 1215 "ifupdown.nw"
60 f = fopen(filename, "r");
61 if ( f == NULL ) return NULL;
62 line = 0;
63
64 #line 1181 "ifupdown.nw"
65         while (
66 #line 1255 "ifupdown.nw"
67 get_line(&buf,&buf_len,f,&line)
68 #line 1181 "ifupdown.nw"
69                                              ) {
70                 
71 #line 1494 "ifupdown.nw"
72 rest = next_word(buf, firstword, 80);
73 if (rest == NULL) continue; /* blank line */
74
75 if (strcmp(firstword, "mapping") == 0) {
76         
77 #line 1546 "ifupdown.nw"
78 currmap = malloc(sizeof(mapping_defn));
79 if (currmap == NULL) {
80         
81 #line 2008 "ifupdown.nw"
82 perror(filename);
83 return NULL;
84 #line 1549 "ifupdown.nw"
85 }
86 #line 1553 "ifupdown.nw"
87 currmap->max_matches = 0;
88 currmap->n_matches = 0;
89 currmap->match = NULL;
90
91 while((rest = next_word(rest, firstword, 80))) {
92         if (currmap->max_matches == currmap->n_matches) {
93                 char **tmp;
94                 currmap->max_matches = currmap->max_matches * 2 + 1;
95                 tmp = realloc(currmap->match, 
96                         sizeof(*tmp) * currmap->max_matches);
97                 if (tmp == NULL) {
98                         currmap->max_matches = (currmap->max_matches - 1) / 2;
99                         
100 #line 2008 "ifupdown.nw"
101 perror(filename);
102 return NULL;
103 #line 1566 "ifupdown.nw"
104                 }
105                 currmap->match = tmp;
106         }
107
108         currmap->match[currmap->n_matches++] = strdup(firstword);
109 }
110 #line 1575 "ifupdown.nw"
111 currmap->script = NULL;
112
113 currmap->max_mappings = 0;
114 currmap->n_mappings = 0;
115 currmap->mapping = NULL;
116 #line 1583 "ifupdown.nw"
117 {
118         mapping_defn **where = &defn->mappings;
119         while(*where != NULL) {
120                 where = &(*where)->next;
121         }
122         *where = currmap;
123         currmap->next = NULL;
124 }
125 #line 1499 "ifupdown.nw"
126         currently_processing = MAPPING;
127 } else if (strcmp(firstword, "iface") == 0) {
128         
129 #line 1635 "ifupdown.nw"
130 {
131         
132 #line 1668 "ifupdown.nw"
133 char iface_name[80];
134 char address_family_name[80];
135 char method_name[80];
136
137 #line 1638 "ifupdown.nw"
138         
139 #line 1656 "ifupdown.nw"
140 currif = malloc(sizeof(interface_defn));
141 if (!currif) {
142         
143 #line 2008 "ifupdown.nw"
144 perror(filename);
145 return NULL;
146 #line 1659 "ifupdown.nw"
147 }
148
149 #line 1640 "ifupdown.nw"
150         
151 #line 1674 "ifupdown.nw"
152 rest = next_word(rest, iface_name, 80);
153 rest = next_word(rest, address_family_name, 80);
154 rest = next_word(rest, method_name, 80);
155
156 if (rest == NULL) {
157         
158 #line 2013 "ifupdown.nw"
159 fprintf(stderr, "%s:%d: too few parameters for iface line\n", filename, line);
160 return NULL;
161 #line 1680 "ifupdown.nw"
162 }
163
164 if (rest[0] != '\0') {
165         
166 #line 2018 "ifupdown.nw"
167 fprintf(stderr, "%s:%d: too many parameters for iface line\n", filename, line);
168 return NULL;
169 #line 1684 "ifupdown.nw"
170 }
171
172 #line 1642 "ifupdown.nw"
173         
174 #line 1690 "ifupdown.nw"
175 currif->logical_iface = strdup(iface_name);
176 if (!currif->logical_iface) {
177         
178 #line 2008 "ifupdown.nw"
179 perror(filename);
180 return NULL;
181 #line 1693 "ifupdown.nw"
182 }
183 #line 1643 "ifupdown.nw"
184         
185 #line 1708 "ifupdown.nw"
186 currif->address_family = get_address_family(addr_fams, address_family_name);
187 if (!currif->address_family) {
188         
189 #line 2023 "ifupdown.nw"
190 fprintf(stderr, "%s:%d: unknown address type\n", filename, line);
191 return NULL;
192 #line 1711 "ifupdown.nw"
193 }
194 #line 1644 "ifupdown.nw"
195         
196 #line 1743 "ifupdown.nw"
197 currif->method = get_method(currif->address_family, method_name);
198 if (!currif->method) {
199         
200 #line 2028 "ifupdown.nw"
201 fprintf(stderr, "%s:%d: unknown method\n", filename, line);
202 return NULL;
203 #line 1746 "ifupdown.nw"
204         return NULL; /* FIXME */
205 }
206 #line 1645 "ifupdown.nw"
207         
208 #line 1766 "ifupdown.nw"
209 currif->automatic = 1;
210 currif->max_options = 0;
211 currif->n_options = 0;
212 currif->option = NULL;
213
214 #line 1647 "ifupdown.nw"
215         
216 #line 1782 "ifupdown.nw"
217 {
218         interface_defn **where = &defn->ifaces; 
219         while(*where != NULL) {
220                 if (duplicate_if(*where, currif)) {
221                         
222 #line 2033 "ifupdown.nw"
223 fprintf(stderr, "%s:%d: duplicate interface\n", filename, line);
224 return NULL;
225 #line 1787 "ifupdown.nw"
226                 }
227                 where = &(*where)->next;
228         }
229
230         *where = currif;
231         currif->next = NULL;
232 }
233 #line 1648 "ifupdown.nw"
234 }
235 #line 1502 "ifupdown.nw"
236         currently_processing = IFACE;
237 } else if (strcmp(firstword, "auto") == 0) {
238         
239 #line 1898 "ifupdown.nw"
240 allowup_defn *auto_ups = get_allowup(&defn->allowups, "auto");
241 if (!auto_ups) {
242         
243 #line 2008 "ifupdown.nw"
244 perror(filename);
245 return NULL;
246 #line 1901 "ifupdown.nw"
247 }
248 while((rest = next_word(rest, firstword, 80))) {
249         if (!add_allow_up(filename, line, auto_ups, firstword))
250                 return NULL;
251 }
252 #line 1505 "ifupdown.nw"
253         currently_processing = NONE;
254 } else if (strncmp(firstword, "allow-", 6) == 0 && strlen(firstword) > 6) {
255         
256 #line 1908 "ifupdown.nw"
257 allowup_defn *allow_ups = get_allowup(&defn->allowups, firstword + 6);
258 if (!allow_ups) {
259         
260 #line 2008 "ifupdown.nw"
261 perror(filename);
262 return NULL;
263 #line 1911 "ifupdown.nw"
264 }
265 while((rest = next_word(rest, firstword, 80))) {
266         if (!add_allow_up(filename, line, allow_ups, firstword))
267                 return NULL;
268 }
269 #line 1508 "ifupdown.nw"
270         currently_processing = NONE;
271 } else {
272         
273 #line 1515 "ifupdown.nw"
274 switch(currently_processing) {
275         case IFACE:
276                 
277 #line 1821 "ifupdown.nw"
278 if (strcmp(firstword, "post-up") == 0) {
279         strcpy(firstword, "up");
280 }
281 if (strcmp(firstword, "pre-down") == 0) {
282         strcpy(firstword, "down");
283
284 #line 1830 "ifupdown.nw"
285 {
286         int i;
287
288         if (strlen (rest) == 0) {
289                 
290 #line 2059 "ifupdown.nw"
291 fprintf(stderr, "%s:%d: option with empty value\n", filename, line);
292 return NULL;
293 #line 1835 "ifupdown.nw"
294         }
295
296         if (strcmp(firstword, "pre-up") != 0 
297             && strcmp(firstword, "up") != 0
298             && strcmp(firstword, "down") != 0
299             && strcmp(firstword, "post-down") != 0)
300         {
301                 for (i = 0; i < currif->n_options; i++) {
302                         if (strcmp(currif->option[i].name, firstword) == 0) {
303                                 
304 #line 2044 "ifupdown.nw"
305 fprintf(stderr, "%s:%d: duplicate option\n", filename, line);
306 return NULL;
307 #line 1845 "ifupdown.nw"
308                         }
309                 }
310         }
311 }
312 #line 1857 "ifupdown.nw"
313 if (currif->n_options >= currif->max_options) {
314         
315 #line 1879 "ifupdown.nw"
316 {
317         variable *opt;
318         currif->max_options = currif->max_options + 10;
319         opt = realloc(currif->option, sizeof(*opt) * currif->max_options);
320         if (opt == NULL) {
321                 
322 #line 2008 "ifupdown.nw"
323 perror(filename);
324 return NULL;
325 #line 1885 "ifupdown.nw"
326         }
327         currif->option = opt;
328 }
329 #line 1859 "ifupdown.nw"
330 }
331
332 currif->option[currif->n_options].name = strdup(firstword);
333 currif->option[currif->n_options].value = strdup(rest);
334
335 if (!currif->option[currif->n_options].name) {
336         
337 #line 2008 "ifupdown.nw"
338 perror(filename);
339 return NULL;
340 #line 1866 "ifupdown.nw"
341 }
342
343 if (!currif->option[currif->n_options].value) {
344         
345 #line 2008 "ifupdown.nw"
346 perror(filename);
347 return NULL;
348 #line 1870 "ifupdown.nw"
349 }
350
351 currif->n_options++;    
352 #line 1518 "ifupdown.nw"
353                 break;
354         case MAPPING:
355                 
356 #line 1598 "ifupdown.nw"
357 if (strcmp(firstword, "script") == 0) {
358         
359 #line 1608 "ifupdown.nw"
360 if (currmap->script != NULL) {
361         
362 #line 2049 "ifupdown.nw"
363 fprintf(stderr, "%s:%d: duplicate script in mapping\n", filename, line);
364 return NULL;
365 #line 1610 "ifupdown.nw"
366 } else {
367         currmap->script = strdup(rest);
368 }
369 #line 1600 "ifupdown.nw"
370 } else if (strcmp(firstword, "map") == 0) {
371         
372 #line 1616 "ifupdown.nw"
373 if (currmap->max_mappings == currmap->n_mappings) {
374         char **opt;
375         currmap->max_mappings = currmap->max_mappings * 2 + 1;
376         opt = realloc(currmap->mapping, sizeof(*opt) * currmap->max_mappings);
377         if (opt == NULL) {
378                 
379 #line 2008 "ifupdown.nw"
380 perror(filename);
381 return NULL;
382 #line 1622 "ifupdown.nw"
383         }
384         currmap->mapping = opt;
385 }
386 currmap->mapping[currmap->n_mappings] = strdup(rest);
387 currmap->n_mappings++;
388 #line 1602 "ifupdown.nw"
389 } else {
390         
391 #line 2054 "ifupdown.nw"
392 fprintf(stderr, "%s:%d: misplaced option\n", filename, line);
393 return NULL;
394 #line 1604 "ifupdown.nw"
395 }
396 #line 1521 "ifupdown.nw"
397                 break;
398         case NONE:
399         default:
400                 
401 #line 2054 "ifupdown.nw"
402 fprintf(stderr, "%s:%d: misplaced option\n", filename, line);
403 return NULL;
404 #line 1525 "ifupdown.nw"
405 }
406 #line 1511 "ifupdown.nw"
407 }
408 #line 1183 "ifupdown.nw"
409         }
410         if (
411 #line 1267 "ifupdown.nw"
412 ferror(f) != 0
413 #line 1184 "ifupdown.nw"
414                                            ) {
415                 
416 #line 2008 "ifupdown.nw"
417 perror(filename);
418 return NULL;
419 #line 1186 "ifupdown.nw"
420         }
421
422         
423 #line 1221 "ifupdown.nw"
424 fclose(f);
425 line = -1;
426
427 #line 1190 "ifupdown.nw"
428         return defn;
429 }
430 #line 1280 "ifupdown.nw"
431 static int get_line(char **result, size_t *result_len, FILE *f, int *line) {
432         
433 #line 1305 "ifupdown.nw"
434 size_t pos;
435
436 #line 1283 "ifupdown.nw"
437         do {
438                 
439 #line 1312 "ifupdown.nw"
440 pos = 0;
441 #line 1285 "ifupdown.nw"
442                 
443 #line 1323 "ifupdown.nw"
444 do {
445         
446 #line 1344 "ifupdown.nw"
447 if (*result_len - pos < 10) {
448         char *newstr = realloc(*result, *result_len * 2 + 80);
449         if (newstr == NULL) {
450                 return 0;
451         }
452         *result = newstr;
453         *result_len = *result_len * 2 + 80;
454 }
455 #line 1325 "ifupdown.nw"
456         
457 #line 1373 "ifupdown.nw"
458 if (!fgets(*result + pos, *result_len - pos, f)) {
459         if (ferror(f) == 0 && pos == 0) return 0;
460         if (ferror(f) != 0) return 0;
461 }
462 pos += strlen(*result + pos);
463 #line 1326 "ifupdown.nw"
464 } while(
465 #line 1364 "ifupdown.nw"
466 pos == *result_len - 1 && (*result)[pos-1] != '\n'
467 #line 1326 "ifupdown.nw"
468                                    );
469
470 #line 1385 "ifupdown.nw"
471 if (pos != 0 && (*result)[pos-1] == '\n') {
472         (*result)[--pos] = '\0';
473 }
474
475 #line 1330 "ifupdown.nw"
476 (*line)++;
477
478 assert( (*result)[pos] == '\0' );
479 #line 1286 "ifupdown.nw"
480                 
481 #line 1401 "ifupdown.nw"
482
483         int first = 0; 
484         while (isspace((*result)[first]) && (*result)[first]) {
485                 first++;
486         }
487
488         memmove(*result, *result + first, pos - first + 1);
489         pos -= first;
490 }
491 #line 1287 "ifupdown.nw"
492         } while (
493 #line 1425 "ifupdown.nw"
494 (*result)[0] == '#'
495 #line 1287 "ifupdown.nw"
496                                );
497
498         while (
499 #line 1429 "ifupdown.nw"
500 (*result)[pos-1] == '\\'
501 #line 1289 "ifupdown.nw"
502                                ) {
503                 
504 #line 1433 "ifupdown.nw"
505 (*result)[--pos] = '\0';
506 #line 1291 "ifupdown.nw"
507                 
508 #line 1323 "ifupdown.nw"
509 do {
510         
511 #line 1344 "ifupdown.nw"
512 if (*result_len - pos < 10) {
513         char *newstr = realloc(*result, *result_len * 2 + 80);
514         if (newstr == NULL) {
515                 return 0;
516         }
517         *result = newstr;
518         *result_len = *result_len * 2 + 80;
519 }
520 #line 1325 "ifupdown.nw"
521         
522 #line 1373 "ifupdown.nw"
523 if (!fgets(*result + pos, *result_len - pos, f)) {
524         if (ferror(f) == 0 && pos == 0) return 0;
525         if (ferror(f) != 0) return 0;
526 }
527 pos += strlen(*result + pos);
528 #line 1326 "ifupdown.nw"
529 } while(
530 #line 1364 "ifupdown.nw"
531 pos == *result_len - 1 && (*result)[pos-1] != '\n'
532 #line 1326 "ifupdown.nw"
533                                    );
534
535 #line 1385 "ifupdown.nw"
536 if (pos != 0 && (*result)[pos-1] == '\n') {
537         (*result)[--pos] = '\0';
538 }
539
540 #line 1330 "ifupdown.nw"
541 (*line)++;
542
543 assert( (*result)[pos] == '\0' );
544 #line 1292 "ifupdown.nw"
545         }
546
547         
548 #line 1413 "ifupdown.nw"
549 while (isspace((*result)[pos-1])) { /* remove trailing whitespace */
550         pos--;
551 }
552 (*result)[pos] = '\0';
553
554 #line 1296 "ifupdown.nw"
555         return 1;
556 }
557 #line 1471 "ifupdown.nw"
558 static char *next_word(char *buf, char *word, int maxlen) {
559         if (!buf) return NULL;
560         if (!*buf) return NULL;
561
562         while(!isspace(*buf) && *buf) {
563                 if (maxlen-- > 1) *word++ = *buf;
564                 buf++;
565         }
566         if (maxlen > 0) *word = '\0';
567
568         while(isspace(*buf) && *buf) buf++;
569
570         return buf;
571 }
572 #line 1720 "ifupdown.nw"
573 static address_family *get_address_family(address_family *af[], char *name) {
574         int i;
575         for (i = 0; af[i]; i++) {
576                 if (strcmp(af[i]->name, name) == 0) {
577                         return af[i];
578                 }
579         }
580         return NULL;
581 }
582 #line 1751 "ifupdown.nw"
583 static method *get_method(address_family *af, char *name) {
584         int i;
585         for (i = 0; i < af->n_methods; i++) {
586                 if (strcmp(af->method[i].name, name) == 0) {
587                         return &af->method[i];
588                 }
589         }
590         return NULL;
591 }
592 #line 1804 "ifupdown.nw"
593 static int duplicate_if(interface_defn *ifa, interface_defn *ifb) {
594         if (strcmp(ifa->logical_iface, ifb->logical_iface) != 0) return 0;
595         if (ifa->address_family != ifb->address_family) return 0;
596         return 1;
597 }
598 #line 1922 "ifupdown.nw"
599 allowup_defn *get_allowup(allowup_defn **allowups, char *name) {
600         for (; *allowups; allowups = &(*allowups)->next) {
601                 if (strcmp((*allowups)->when, name) == 0) break;
602         }
603         if (*allowups == NULL) {
604                 *allowups = malloc(sizeof(allowup_defn));
605                 if (*allowups == NULL) return NULL;
606                 (*allowups)->when = strdup(name);
607                 (*allowups)->next = NULL;
608                 (*allowups)->max_interfaces = 0;
609                 (*allowups)->n_interfaces = 0;
610                 (*allowups)->interfaces = NULL;
611         }
612         return *allowups;
613 }
614 #line 1947 "ifupdown.nw"
615 allowup_defn *find_allowup(interfaces_file *defn, char *name) {
616         allowup_defn *allowups = defn->allowups;
617         for (; allowups; allowups = allowups->next) {
618                 if (strcmp(allowups->when, name) == 0) break;
619         }
620         return allowups;
621 }
622 #line 1962 "ifupdown.nw"
623 allowup_defn *add_allow_up(char *filename, int line,
624         allowup_defn *allow_up, char *iface_name)
625 {
626         
627 #line 1972 "ifupdown.nw"
628 {
629         int i;
630
631         for (i = 0; i < allow_up->n_interfaces; i++) {
632                 if (strcmp(iface_name, allow_up->interfaces[i]) == 0) {
633                         
634 #line 2038 "ifupdown.nw"
635 fprintf(stderr, "%s:%d: interface %s declared allow-%s twice\n", 
636         filename, line, iface_name, allow_up->when);
637 return NULL;
638 #line 1978 "ifupdown.nw"
639                 }
640         }
641 }
642 #line 1966 "ifupdown.nw"
643         
644 #line 1984 "ifupdown.nw"
645 if (allow_up->n_interfaces == allow_up->max_interfaces) {
646         char **tmp;
647         allow_up->max_interfaces *= 2;
648         allow_up->max_interfaces++;
649         tmp = realloc(allow_up->interfaces, 
650                 sizeof(*tmp) * allow_up->max_interfaces);
651         if (tmp == NULL) {
652                 
653 #line 2008 "ifupdown.nw"
654 perror(filename);
655 return NULL;
656 #line 1992 "ifupdown.nw"
657         }
658         allow_up->interfaces = tmp;
659 }
660
661 allow_up->interfaces[allow_up->n_interfaces] = strdup(iface_name);
662 allow_up->n_interfaces++;
663 #line 1967 "ifupdown.nw"
664         return allow_up;
665 }