1%{ 2/* $NetBSD: gram.y,v 1.23 2010/03/08 11:12:32 pooka Exp $ */ 3 4/* 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This software was developed by the Computer Systems Engineering group 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * contributed to Berkeley. 11 * 12 * All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by the University of 15 * California, Lawrence Berkeley Laboratories. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * from: @(#)gram.y 8.1 (Berkeley) 6/6/93 42 */ 43 44#include <sys/types.h> 45#include <sys/param.h> 46#include <ctype.h> 47#include <stdio.h> 48#include <stdlib.h> 49#include <string.h> 50#include <errno.h> 51#include "defs.h" 52#include "sem.h" 53 54#define FORMAT(n) (((n).fmt == 8 && (n).val != 0) ? "0%llo" : \ 55 ((n).fmt == 16) ? "0x%llx" : "%lld") 56 57#define stop(s) cfgerror(s), exit(1) 58 59static struct config conf; /* at most one active at a time */ 60 61/* the following is used to recover nvlist space after errors */ 62static struct nvlist *alloc[1000]; 63static int adepth; 64#define new0(n,s,p,i,x) (alloc[adepth++] = newnv(n, s, p, i, x)) 65#define new_n(n) new0(n, NULL, NULL, 0, NULL) 66#define new_nx(n, x) new0(n, NULL, NULL, 0, x) 67#define new_ns(n, s) new0(n, s, NULL, 0, NULL) 68#define new_si(s, i) new0(NULL, s, NULL, i, NULL) 69#define new_nsi(n,s,i) new0(n, s, NULL, i, NULL) 70#define new_np(n, p) new0(n, NULL, p, 0, NULL) 71#define new_s(s) new0(NULL, s, NULL, 0, NULL) 72#define new_p(p) new0(NULL, NULL, p, 0, NULL) 73#define new_px(p, x) new0(NULL, NULL, p, 0, x) 74#define new_sx(s, x) new0(NULL, s, NULL, 0, x) 75#define new_nsx(n,s,x) new0(n, s, NULL, 0, x) 76#define new_i(i) new0(NULL, NULL, NULL, i, NULL) 77 78#define fx_atom(s) new0(s, NULL, NULL, FX_ATOM, NULL) 79#define fx_not(e) new0(NULL, NULL, NULL, FX_NOT, e) 80#define fx_and(e1, e2) new0(NULL, NULL, e1, FX_AND, e2) 81#define fx_or(e1, e2) new0(NULL, NULL, e1, FX_OR, e2) 82 83static void cleanup(void); 84static void setmachine(const char *, const char *, struct nvlist *, int); 85static void check_maxpart(void); 86 87static void app(struct nvlist *, struct nvlist *); 88 89static struct nvlist *mk_nsis(const char *, int, struct nvlist *, int); 90static struct nvlist *mk_ns(const char *, struct nvlist *); 91 92%} 93 94%union { 95 struct attr *attr; 96 struct devbase *devb; 97 struct deva *deva; 98 struct nvlist *list; 99 const char *str; 100 struct numconst num; 101 int64_t val; 102} 103 104%token AND AT ATTACH 105%token BLOCK BUILD 106%token CHAR COLONEQ COMPILE_WITH CONFIG 107%token DEFFS DEFINE DEFOPT DEFPARAM DEFFLAG DEFPSEUDO DEFPSEUDODEV 108%token DEVICE DEVCLASS DUMPS DEVICE_MAJOR 109%token ENDFILE 110%token XFILE FILE_SYSTEM FLAGS 111%token IDENT IOCONF 112%token LINKZERO 113%token XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS MINOR 114%token NEEDS_COUNT NEEDS_FLAG NO 115%token XOBJECT OBSOLETE ON OPTIONS 116%token PACKAGE PLUSEQ PREFIX PSEUDO_DEVICE PSEUDO_ROOT 117%token ROOT 118%token SINGLE SOURCE 119%token TYPE 120%token VECTOR VERSION 121%token WITH 122%token <num> NUMBER 123%token <str> PATHNAME QSTRING WORD EMPTYSTRING 124%token ENDDEFS 125 126%left '|' 127%left '&' 128 129%type <list> fopts fexpr fatom 130%type <str> fs_spec 131%type <val> fflgs fflag oflgs oflag 132%type <str> rule 133%type <attr> attr 134%type <devb> devbase 135%type <deva> devattach_opt 136%type <list> atlist interface_opt 137%type <str> atname 138%type <list> loclist_opt loclist locdef 139%type <str> locdefault 140%type <list> values locdefaults 141%type <list> attrs_opt attrs 142%type <list> locators locator 143%type <list> dev_spec 144%type <str> device_instance 145%type <str> attachment 146%type <str> value 147%type <val> major_minor npseudo 148%type <num> signed_number 149%type <val> flags_opt 150%type <str> deffs 151%type <list> deffses 152%type <list> defopt 153%type <list> defopts 154%type <str> optdep 155%type <list> optdeps 156%type <list> defoptdeps 157%type <str> optfile_opt 158%type <list> subarches_opt subarches 159%type <str> filename stringvalue locname mkvarname 160%type <val> device_major_block device_major_char 161%type <list> devnodes devnodetype devnodeflags devnode_dims 162 163%% 164 165/* 166 * A configuration consists of a machine type, followed by the machine 167 * definition files (via the include() mechanism), followed by the 168 * configuration specification(s) proper. In effect, this is two 169 * separate grammars, with some shared terminals and nonterminals. 170 * Note that we do not have sufficient keywords to enforce any order 171 * between elements of "topthings" without introducing shift/reduce 172 * conflicts. Instead, check order requirements in the C code. 173 */ 174Configuration: 175 topthings /* dirspecs, include "std.arch" */ 176 machine_spec /* "machine foo" from machine descr. */ 177 dev_defs ENDDEFS /* all machine definition files */ 178 { check_maxpart(); check_version(); } 179 specs; /* rest of machine description */ 180 181topthings: 182 topthings topthing | 183 /* empty */; 184 185topthing: 186 SOURCE filename '\n' { if (!srcdir) srcdir = $2; } | 187 BUILD filename '\n' { if (!builddir) builddir = $2; } | 188 '\n'; 189 190machine_spec: 191 XMACHINE WORD '\n' { setmachine($2,NULL,NULL,0); } | 192 XMACHINE WORD WORD subarches_opt '\n' { setmachine($2,$3,$4,0); } | 193 IOCONF WORD '\n' { setmachine($2,NULL,NULL,1); } | 194 error { stop("cannot proceed without machine or ioconf specifier"); }; 195 196subarches_opt: 197 subarches | 198 /* empty */ { $$ = NULL; }; 199 200subarches: 201 subarches WORD { $$ = new_nx($2, $1); } | 202 WORD { $$ = new_n($1); }; 203 204/* 205 * Various nonterminals shared between the grammars. 206 */ 207file: 208 XFILE filename fopts fflgs rule { addfile($2, $3, $4, $5); }; 209 210object: 211 XOBJECT filename fopts oflgs { addobject($2, $3, $4); }; 212 213device_major: 214 DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes 215 { adddevm($2, $3, $4, $5, $6); }; 216 217device_major_block: 218 BLOCK NUMBER { $$ = $2.val; } | 219 /* empty */ { $$ = -1; }; 220 221device_major_char: 222 CHAR NUMBER { $$ = $2.val; } | 223 /* empty */ { $$ = -1; }; 224 225/* order of options is important, must use right recursion */ 226fopts: 227 fexpr { $$ = $1; } | 228 /* empty */ { $$ = NULL; }; 229 230fexpr: 231 fatom { $$ = $1; } | 232 '!' fatom { $$ = fx_not($2); } | 233 fexpr '&' fexpr { $$ = fx_and($1, $3); } | 234 fexpr '|' fexpr { $$ = fx_or($1, $3); } | 235 '(' fexpr ')' { $$ = $2; }; 236 237fatom: 238 WORD { $$ = fx_atom($1); }; 239 240fflgs: 241 fflgs fflag { $$ = $1 | $2; } | 242 /* empty */ { $$ = 0; }; 243 244fflag: 245 NEEDS_COUNT { $$ = FI_NEEDSCOUNT; } | 246 NEEDS_FLAG { $$ = FI_NEEDSFLAG; }; 247 248devnodes: 249 devnodetype ',' devnodeflags { $$ = nvcat($1, $3); } | 250 devnodetype { $$ = $1; } | 251 /* empty */ { $$ = new_s("DEVNODE_DONTBOTHER"); }; 252 253devnodetype: 254 SINGLE { $$ = new_s("DEVNODE_SINGLE"); } | 255 VECTOR '=' devnode_dims { $$ = nvcat(new_s("DEVNODE_VECTOR"), $3); }; 256 257devnode_dims: 258 NUMBER ':' NUMBER { struct nvlist *__nv1, *__nv2; 259 __nv1 = new_i($1.val); 260 __nv2 = new_i($3.val); 261 $$ = nvcat(__nv1, __nv2); } | 262 NUMBER { $$ = new_i($1.val); } 263 264devnodeflags: 265 LINKZERO { $$ = new_s("DEVNODE_FLAG_LINKZERO");}; 266 267oflgs: 268 oflgs oflag { $$ = $1 | $2; } | 269 /* empty */ { $$ = 0; }; 270 271oflag: 272 NEEDS_FLAG { $$ = OI_NEEDSFLAG; }; 273 274rule: 275 COMPILE_WITH stringvalue { $$ = $2; } | 276 /* empty */ { $$ = NULL; }; 277 278prefix: 279 PREFIX filename { prefix_push($2); } | 280 PREFIX { prefix_pop(); }; 281 282/* 283 * The machine definitions grammar. 284 */ 285dev_defs: 286 dev_defs dev_def | 287 dev_defs ENDFILE { enddefs(); checkfiles(); } | 288 /* empty */; 289 290dev_def: 291 one_def '\n' { adepth = 0; } | 292 '\n' | 293 error '\n' { cleanup(); }; 294 295one_def: 296 file | 297 object | 298 device_major { do_devsw = 1; } | 299 prefix | 300 DEVCLASS WORD { (void)defattr($2, NULL, NULL, 1); } | 301 DEFFS deffses defoptdeps { deffilesystem($2, $3); } | 302 DEFINE WORD interface_opt attrs_opt 303 { (void)defattr($2, $3, $4, 0); } | 304 DEFOPT optfile_opt defopts defoptdeps 305 { defoption($2, $3, $4); } | 306 DEFFLAG optfile_opt defopts defoptdeps 307 { defflag($2, $3, $4, 0); } | 308 OBSOLETE DEFFLAG optfile_opt defopts 309 { defflag($3, $4, NULL, 1); } | 310 DEFPARAM optfile_opt defopts defoptdeps 311 { defparam($2, $3, $4, 0); } | 312 OBSOLETE DEFPARAM optfile_opt defopts 313 { defparam($3, $4, NULL, 1); } | 314 DEVICE devbase interface_opt attrs_opt 315 { defdev($2, $3, $4, 0); } | 316 ATTACH devbase AT atlist devattach_opt attrs_opt 317 { defdevattach($5, $2, $4, $6); } | 318 MAXPARTITIONS NUMBER { maxpartitions = $2.val; } | 319 MAXUSERS NUMBER NUMBER NUMBER { setdefmaxusers($2.val, $3.val, $4.val); } | 320 MAKEOPTIONS condmkopt_list | 321 /* interface_opt in DEFPSEUDO is for backwards compatibility */ 322 DEFPSEUDO devbase interface_opt attrs_opt 323 { defdev($2, $3, $4, 1); } | 324 DEFPSEUDODEV devbase interface_opt attrs_opt 325 { defdev($2, $3, $4, 2); } | 326 MAJOR '{' majorlist '}' | 327 VERSION NUMBER { setversion($2.val); }; 328 329atlist: 330 atlist ',' atname { $$ = new_nx($3, $1); } | 331 atname { $$ = new_n($1); }; 332 333atname: 334 WORD { $$ = $1; } | 335 ROOT { $$ = NULL; }; 336 337deffses: 338 deffses deffs { $$ = new_nx($2, $1); } | 339 deffs { $$ = new_n($1); }; 340 341deffs: 342 WORD { $$ = $1; }; 343 344defoptdeps: 345 ':' optdeps { $$ = $2; } | 346 /* empty */ { $$ = NULL; }; 347 348optdeps: 349 optdeps ',' optdep { $$ = new_nx($3, $1); } | 350 optdep { $$ = new_n($1); }; 351 352optdep: 353 WORD { $$ = $1; }; 354 355defopts: 356 defopts defopt { $$ = nvcat($2, $1); } | 357 defopt { $$ = $1; }; 358 359defopt: 360 WORD { $$ = new_n($1); } | 361 WORD '=' value { $$ = new_ns($1, $3); } | 362 WORD COLONEQ value { 363 struct nvlist *__nv = 364 new_n($1); 365 $$ = new_nsx("", $3, __nv); 366 } | 367 WORD '=' value COLONEQ value { 368 struct nvlist *__nv = 369 new_n($1); 370 $$ = new_nsx("", $5, __nv); 371 }; 372 373devbase: 374 WORD { $$ = getdevbase($1); }; 375 376devattach_opt: 377 WITH WORD { $$ = getdevattach($2); } | 378 /* empty */ { $$ = NULL; }; 379 380interface_opt: 381 '{' loclist_opt '}' { $$ = new_nx("", $2); } | 382 /* empty */ { $$ = NULL; }; 383 384loclist_opt: 385 loclist { $$ = $1; } | 386 /* empty */ { $$ = NULL; }; 387 388/* loclist order matters, must use right recursion */ 389loclist: 390 locdef ',' loclist { $$ = $1; app($1, $3); } | 391 locdef { $$ = $1; }; 392 393/* "[ WORD locdefault ]" syntax may be unnecessary... */ 394locdef: 395 locname locdefault { $$ = new_nsi($1, $2, 0); } | 396 locname { $$ = new_nsi($1, NULL, 0); } | 397 '[' locname locdefault ']' { $$ = new_nsi($2, $3, 1); } | 398 locname '[' NUMBER ']' { $$ = mk_nsis($1, $3.val, NULL, 0); } | 399 locname '[' NUMBER ']' locdefaults 400 { $$ = mk_nsis($1, $3.val, $5, 0); } | 401 '[' locname '[' NUMBER ']' locdefaults ']' 402 { $$ = mk_nsis($2, $4.val, $6, 1); }; 403 404locname: 405 WORD { $$ = $1; } | 406 QSTRING { $$ = $1; }; 407 408locdefault: 409 '=' value { $$ = $2; }; 410 411locdefaults: 412 '=' '{' values '}' { $$ = $3; }; 413 414optfile_opt: 415 filename { $$ = $1; } | 416 /* empty */ { $$ = NULL; }; 417 418filename: 419 QSTRING { $$ = $1; } | 420 PATHNAME { $$ = $1; }; 421 422value: 423 QSTRING { $$ = $1; } | 424 WORD { $$ = $1; } | 425 EMPTYSTRING { $$ = $1; } | 426 signed_number { char bf[40]; 427 (void)snprintf(bf, sizeof(bf), 428 FORMAT($1), (long long)$1.val); 429 $$ = intern(bf); }; 430 431stringvalue: 432 QSTRING { $$ = $1; } | 433 WORD { $$ = $1; }; 434 435values: 436 value ',' values { $$ = new_sx($1, $3); } | 437 value { $$ = new_s($1); }; 438 439signed_number: 440 NUMBER { $$ = $1; } | 441 '-' NUMBER { $$.fmt = $2.fmt; $$.val = -$2.val; }; 442 443attrs_opt: 444 ':' attrs { $$ = $2; } | 445 /* empty */ { $$ = NULL; }; 446 447attrs: 448 attrs ',' attr { $$ = new_px($3, $1); } | 449 attr { $$ = new_p($1); }; 450 451attr: 452 WORD { $$ = getattr($1); }; 453 454majorlist: 455 majorlist ',' majordef | 456 majordef; 457 458majordef: 459 devbase '=' NUMBER { setmajor($1, $3.val); }; 460 461 462/* 463 * The configuration grammar. 464 */ 465specs: 466 specs spec | 467 /* empty */; 468 469spec: 470 config_spec '\n' { adepth = 0; } | 471 '\n' | 472 error '\n' { cleanup(); }; 473 474config_spec: 475 one_def | 476 NO FILE_SYSTEM no_fs_list | 477 FILE_SYSTEM fs_list | 478 NO MAKEOPTIONS no_mkopt_list | 479 MAKEOPTIONS mkopt_list | 480 NO OPTIONS no_opt_list | 481 OPTIONS opt_list | 482 MAXUSERS NUMBER { setmaxusers($2.val); } | 483 IDENT stringvalue { setident($2); } | 484 CONFIG conf root_spec sysparam_list 485 { addconf(&conf); } | 486 NO CONFIG WORD { delconf($3); } | 487 NO PSEUDO_DEVICE WORD { delpseudo($3); } | 488 PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); } | 489 PSEUDO_ROOT device_instance { addpseudoroot($2); } | 490 NO device_instance AT attachment 491 { deldevi($2, $4); } | 492 NO DEVICE AT attachment { deldeva($4); } | 493 NO device_instance { deldev($2); } | 494 device_instance AT attachment locators flags_opt 495 { adddev($1, $3, $4, $5); }; 496 497fs_list: 498 fs_list ',' fsoption | 499 fsoption; 500 501fsoption: 502 WORD { addfsoption($1); }; 503 504no_fs_list: 505 no_fs_list ',' no_fsoption | 506 no_fsoption; 507 508no_fsoption: 509 WORD { delfsoption($1); }; 510 511mkopt_list: 512 mkopt_list ',' mkoption | 513 mkoption; 514 515mkvarname: 516 QSTRING { $$ = $1; } | 517 WORD { $$ = $1; }; 518 519mkoption: 520 mkvarname '=' value { addmkoption($1, $3); } | 521 mkvarname PLUSEQ value { appendmkoption($1, $3); }; 522 523condmkopt_list: 524 condmkopt_list ',' condmkoption | 525 condmkoption; 526 527condmkoption: 528 fexpr mkvarname PLUSEQ value { appendcondmkoption($1, $2, $4); }; 529 530no_mkopt_list: 531 no_mkopt_list ',' no_mkoption | 532 no_mkoption; 533 534no_mkoption: 535 WORD { delmkoption($1); } 536 537opt_list: 538 opt_list ',' option | 539 option; 540 541option: 542 WORD { addoption($1, NULL); } | 543 WORD '=' value { addoption($1, $3); }; 544 545no_opt_list: 546 no_opt_list ',' no_option | 547 no_option; 548 549no_option: 550 WORD { deloption($1); }; 551 552conf: 553 WORD { conf.cf_name = $1; 554 conf.cf_lineno = currentline(); 555 conf.cf_fstype = NULL; 556 conf.cf_root = NULL; 557 conf.cf_dump = NULL; }; 558 559root_spec: 560 ROOT on_opt dev_spec fs_spec_opt 561 { setconf(&conf.cf_root, "root", $3); }; 562 563fs_spec_opt: 564 TYPE fs_spec { setfstype(&conf.cf_fstype, $2); } | 565 /* empty */; 566 567fs_spec: 568 '?' { $$ = intern("?"); } | 569 WORD { $$ = $1; }; 570 571sysparam_list: 572 sysparam_list sysparam | 573 /* empty */; 574 575sysparam: 576 DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); }; 577 578dev_spec: 579 '?' { $$ = new_si(intern("?"), NODEV); } | 580 WORD { $$ = new_si($1, NODEV); } | 581 major_minor { $$ = new_si(NULL, $1); }; 582 583major_minor: 584 MAJOR NUMBER MINOR NUMBER { $$ = makedev($2.val, $4.val); }; 585 586on_opt: 587 ON | /* empty */; 588 589npseudo: 590 NUMBER { $$ = $1.val; } | 591 /* empty */ { $$ = 1; }; 592 593device_instance: 594 WORD '*' { $$ = starref($1); } | 595 WORD { $$ = $1; }; 596 597attachment: 598 ROOT { $$ = NULL; } | 599 WORD '?' { $$ = wildref($1); } | 600 WORD { $$ = $1; }; 601 602locators: 603 locators locator { $$ = $2; app($2, $1); } | 604 /* empty */ { $$ = NULL; }; 605 606locator: 607 WORD values { $$ = mk_ns($1, $2); } | 608 WORD '?' { $$ = new_ns($1, NULL); }; 609 610flags_opt: 611 FLAGS NUMBER { $$ = $2.val; } | 612 /* empty */ { $$ = 0; }; 613 614%% 615 616void 617yyerror(const char *s) 618{ 619 620 cfgerror("%s", s); 621} 622 623/* 624 * Cleanup procedure after syntax error: release any nvlists 625 * allocated during parsing the current line. 626 */ 627static void 628cleanup(void) 629{ 630 struct nvlist **np; 631 int i; 632 633 for (np = alloc, i = adepth; --i >= 0; np++) 634 nvfree(*np); 635 adepth = 0; 636} 637 638static void 639setmachine(const char *mch, const char *mcharch, struct nvlist *mchsubarches, 640 int isioconf) 641{ 642 char buf[MAXPATHLEN]; 643 struct nvlist *nv; 644 645 if (isioconf) { 646 fprintf(stderr, "WARNING: ioconf is an experimental feature\n"); 647 if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0) 648 exit(1); 649 ioconfname = mch; 650 return; 651 } 652 653 machine = mch; 654 machinearch = mcharch; 655 machinesubarches = mchsubarches; 656 657 /* 658 * Define attributes for all the given names 659 */ 660 if (defattr(machine, NULL, NULL, 0) != 0 || 661 (machinearch != NULL && 662 defattr(machinearch, NULL, NULL, 0) != 0)) 663 exit(1); 664 for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) { 665 if (defattr(nv->nv_name, NULL, NULL, 0) != 0) 666 exit(1); 667 } 668 669 /* 670 * Set up the file inclusion stack. This empty include tells 671 * the parser there are no more device definitions coming. 672 */ 673 if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0) 674 exit(1); 675 676 /* Include arch/${MACHINE}/conf/files.${MACHINE} */ 677 (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 678 machine, machine); 679 if (include(buf, ENDFILE, 0, 0) != 0) 680 exit(1); 681 682 /* Include any arch/${MACHINE_SUBARCH}/conf/files.${MACHINE_SUBARCH} */ 683 for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) { 684 (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 685 nv->nv_name, nv->nv_name); 686 if (include(buf, ENDFILE, 0, 0) != 0) 687 exit(1); 688 } 689 690 /* Include any arch/${MACHINE_ARCH}/conf/files.${MACHINE_ARCH} */ 691 if (machinearch != NULL) 692 (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 693 machinearch, machinearch); 694 else 695 strlcpy(buf, _PATH_DEVNULL, sizeof(buf)); 696 if (include(buf, ENDFILE, 0, 0) != 0) 697 exit(1); 698 699 /* 700 * Include the global conf/files. As the last thing 701 * pushed on the stack, it will be processed first. 702 */ 703 if (include("conf/files", ENDFILE, 0, 0) != 0) 704 exit(1); 705 706 oktopackage = 1; 707} 708 709static void 710check_maxpart(void) 711{ 712 713 if (maxpartitions <= 0 && ioconfname == NULL) { 714 stop("cannot proceed without maxpartitions specifier"); 715 } 716} 717 718static void 719check_version(void) 720{ 721 /* 722 * In essence, version is 0 and is not supported anymore 723 */ 724 if (version < CONFIG_MINVERSION) 725 stop("your sources are out of date -- please update."); 726} 727 728static void 729app(struct nvlist *p, struct nvlist *q) 730{ 731 while (p->nv_next) 732 p = p->nv_next; 733 p->nv_next = q; 734} 735 736static struct nvlist * 737mk_nsis(const char *name, int count, struct nvlist *adefs, int opt) 738{ 739 struct nvlist *defs = adefs; 740 struct nvlist **p; 741 char buf[200]; 742 int i; 743 744 if (count <= 0) { 745 fprintf(stderr, "config: array with <= 0 size: %s\n", name); 746 exit(1); 747 } 748 p = &defs; 749 for(i = 0; i < count; i++) { 750 if (*p == NULL) 751 *p = new_s("0"); 752 snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i); 753 (*p)->nv_name = i == 0 ? name : intern(buf); 754 (*p)->nv_num = i > 0 || opt; 755 p = &(*p)->nv_next; 756 } 757 *p = 0; 758 return defs; 759} 760 761 762static struct nvlist * 763mk_ns(const char *name, struct nvlist *vals) 764{ 765 struct nvlist *p; 766 char buf[200]; 767 int i; 768 769 for(i = 0, p = vals; p; i++, p = p->nv_next) { 770 snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i); 771 p->nv_name = i == 0 ? name : intern(buf); 772 } 773 return vals; 774} 775 776