document distributed with 4.2BSD
[unix-history] / usr / src / usr.sbin / config / config.y
CommitLineData
22d68ad0
BJ
1%union {
2 char *str;
3 int val;
36edb824 4 struct file_list *file;
22d68ad0
BJ
5 struct idlst *lst;
6}
7
36edb824
SL
8%token AND
9%token ANY
10%token ARGS
11%token AT
12%token COMMA
13%token CONFIG
14%token CONTROLLER
15%token CPU
16%token CSR
17%token DEVICE
18%token DISK
19%token DRIVE
20%token DST
21%token DUMPS
22%token EQUALS
23%token FLAGS
24%token HZ
25%token IDENT
f025f13d 26%token MACHINE
36edb824
SL
27%token MAJOR
28%token MASTER
29%token MAXUSERS
30%token MBA
31%token MINOR
32%token MINUS
33%token NEXUS
34%token ON
35%token OPTIONS
7c1d4665 36%token MAKEOPTIONS
36edb824
SL
37%token PRIORITY
38%token PSEUDO_DEVICE
39%token ROOT
40%token SEMICOLON
41%token SIZE
42%token SLAVE
43%token SWAP
44%token TIMEZONE
45%token TRACE
46%token UBA
47%token VECTOR
22d68ad0
BJ
48
49%token <str> ID
50%token <val> NUMBER
51%token <val> FPNUMBER
52
53%type <str> Save_id
54%type <str> Opt_value
55%type <str> Dev
56%type <lst> Id_list
36edb824
SL
57%type <val> optional_size
58%type <str> device_name
59%type <val> major_minor
60%type <val> arg_device_spec
61%type <val> root_device_spec
62%type <val> dump_device_spec
63%type <file> swap_device_spec
22d68ad0 64
2f47f1cc 65%{
0bf41cfc 66
cd68466f
DF
67/*
68 * Copyright (c) 1980 Regents of the University of California.
69 * All rights reserved. The Berkeley software License Agreement
70 * specifies the terms and conditions for redistribution.
71 *
7c1d4665 72 * @(#)config.y 5.2 (Berkeley) %G%
cd68466f 73 */
0bf41cfc 74
2f47f1cc 75#include "config.h"
36edb824 76#include <ctype.h>
2f47f1cc 77#include <stdio.h>
f025f13d
BJ
78
79struct device cur;
80struct device *curp = 0;
81char *temp_id;
82char *val_id;
22d68ad0 83char *malloc();
f025f13d 84
2f47f1cc
MT
85%}
86%%
87Configuration:
88 Many_specs
36edb824 89 = { verifysystemspecs(); }
22d68ad0 90 ;
2f47f1cc
MT
91
92Many_specs:
93 Many_specs Spec
22d68ad0
BJ
94 |
95 /* lambda */
96 ;
2f47f1cc
MT
97
98Spec:
22d68ad0
BJ
99 Device_spec SEMICOLON
100 = { newdev(&cur); } |
101 Config_spec SEMICOLON
102 |
103 TRACE SEMICOLON
104 = { do_trace = !do_trace; } |
105 SEMICOLON
106 |
2f47f1cc 107 error SEMICOLON
22d68ad0 108 ;
2f47f1cc
MT
109
110Config_spec:
22d68ad0
BJ
111 MACHINE Save_id
112 = {
0bf41cfc
BJ
113 if (!strcmp($2, "vax")) {
114 machine = MACHINE_VAX;
115 machinename = "vax";
116 } else if (!strcmp($2, "sun")) {
117 machine = MACHINE_SUN;
118 machinename = "sun";
119 } else
120 yyerror("Unknown machine type");
22d68ad0
BJ
121 } |
122 CPU Save_id
123 = {
124 struct cputype *cp =
125 (struct cputype *)malloc(sizeof (struct cputype));
126 cp->cpu_name = ns($2);
127 cp->cpu_next = cputype;
128 cputype = cp;
129 free(temp_id);
130 } |
131 OPTIONS Opt_list
132 |
7c1d4665
MK
133 MAKEOPTIONS Mkopt_list
134 |
22d68ad0
BJ
135 IDENT ID
136 = { ident = ns($2); } |
36edb824
SL
137 System_spec
138 |
22d68ad0
BJ
139 HZ NUMBER
140 = { yyerror("HZ specification obsolete; delete"); } |
141 TIMEZONE NUMBER
142 = { timezone = 60 * $2; check_tz(); } |
c00c470f
SL
143 TIMEZONE NUMBER DST NUMBER
144 = { timezone = 60 * $2; dst = $4; check_tz(); } |
22d68ad0
BJ
145 TIMEZONE NUMBER DST
146 = { timezone = 60 * $2; dst = 1; check_tz(); } |
147 TIMEZONE FPNUMBER
148 = { timezone = $2; check_tz(); } |
c00c470f
SL
149 TIMEZONE FPNUMBER DST NUMBER
150 = { timezone = $2; dst = $4; check_tz(); } |
22d68ad0
BJ
151 TIMEZONE FPNUMBER DST
152 = { timezone = $2; dst = 1; check_tz(); } |
153 TIMEZONE MINUS NUMBER
154 = { timezone = -60 * $3; check_tz(); } |
c00c470f
SL
155 TIMEZONE MINUS NUMBER DST NUMBER
156 = { timezone = -60 * $3; dst = $5; check_tz(); } |
22d68ad0
BJ
157 TIMEZONE MINUS NUMBER DST
158 = { timezone = -60 * $3; dst = 1; check_tz(); } |
159 TIMEZONE MINUS FPNUMBER
160 = { timezone = -$3; check_tz(); } |
c00c470f
SL
161 TIMEZONE MINUS FPNUMBER DST NUMBER
162 = { timezone = -$3; dst = $5; check_tz(); } |
22d68ad0
BJ
163 TIMEZONE MINUS FPNUMBER DST
164 = { timezone = -$3; dst = 1; check_tz(); } |
165 MAXUSERS NUMBER
166 = { maxusers = $2; };
2f47f1cc 167
36edb824
SL
168System_spec:
169 System_id System_parameter_list
170 = { checksystemspec(*confp); }
171 ;
172
173System_id:
174 CONFIG Save_id
175 = { mkconf($2); }
176 ;
177
178System_parameter_list:
179 System_parameter_list System_parameter
180 | System_parameter
181 ;
182
183System_parameter:
184 swap_spec
185 | root_spec
186 | dump_spec
187 | arg_spec
188 ;
189
190swap_spec:
191 SWAP optional_on swap_device_list
192 ;
193
194swap_device_list:
195 swap_device_list AND swap_device
196 | swap_device
197 ;
198
199swap_device:
200 swap_device_spec optional_size
201 = { mkswap(*confp, $1, $2); }
202 ;
203
204swap_device_spec:
205 device_name
206 = {
207 struct file_list *fl = newswap();
208
209 if (eq($1, "generic"))
210 fl->f_fn = $1;
211 else {
212 fl->f_swapdev = nametodev($1, 0, 'b');
213 fl->f_fn = devtoname(fl->f_swapdev);
214 }
215 $$ = fl;
216 }
217 | major_minor
218 = {
219 struct file_list *fl = newswap();
220
221 fl->f_swapdev = $1;
222 fl->f_fn = devtoname($1);
223 $$ = fl;
224 }
225 ;
226
227root_spec:
228 ROOT optional_on root_device_spec
229 = {
230 struct file_list *fl = *confp;
231
232 if (fl && fl->f_rootdev != NODEV)
233 yyerror("extraneous root device specification");
234 else
235 fl->f_rootdev = $3;
236 }
237 ;
238
239root_device_spec:
240 device_name
241 = { $$ = nametodev($1, 0, 'a'); }
242 | major_minor
243 ;
244
245dump_spec:
246 DUMPS optional_on dump_device_spec
247 = {
248 struct file_list *fl = *confp;
249
250 if (fl && fl->f_dumpdev != NODEV)
251 yyerror("extraneous dump device specification");
252 else
253 fl->f_dumpdev = $3;
254 }
255
256 ;
257
258dump_device_spec:
259 device_name
260 = { $$ = nametodev($1, 0, 'b'); }
261 | major_minor
262 ;
263
264arg_spec:
265 ARGS optional_on arg_device_spec
266 = {
267 struct file_list *fl = *confp;
268
269 if (fl && fl->f_argdev != NODEV)
270 yyerror("extraneous arg device specification");
271 else
272 fl->f_argdev = $3;
273 }
274 ;
275
276arg_device_spec:
277 device_name
278 = { $$ = nametodev($1, 0, 'b'); }
279 | major_minor
280 ;
281
282major_minor:
283 MAJOR NUMBER MINOR NUMBER
284 = { $$ = makedev($2, $4); }
285 ;
286
287optional_on:
288 ON
289 | /* empty */
290 ;
291
292optional_size:
293 SIZE NUMBER
294 = { $$ = $2; }
295 | /* empty */
296 = { $$ = 0; }
297 ;
298
299device_name:
300 Save_id
301 = { $$ = $1; }
302 | Save_id NUMBER
303 = {
304 char buf[80];
305
306 (void) sprintf(buf, "%s%d", $1, $2);
307 $$ = ns(buf); free($1);
308 }
309 | Save_id NUMBER ID
310 = {
311 char buf[80];
312
313 (void) sprintf(buf, "%s%d%s", $1, $2, $3);
314 $$ = ns(buf); free($1);
315 }
316 ;
317
b1e602f2 318Opt_list:
22d68ad0
BJ
319 Opt_list COMMA Option
320 |
b1e602f2 321 Option
22d68ad0 322 ;
b1e602f2
MT
323
324Option:
22d68ad0
BJ
325 Save_id
326 = {
327 struct opt *op = (struct opt *)malloc(sizeof (struct opt));
328 op->op_name = ns($1);
329 op->op_next = opt;
330 op->op_value = 0;
331 opt = op;
332 free(temp_id);
333 } |
334 Save_id EQUALS Opt_value
335 = {
336 struct opt *op = (struct opt *)malloc(sizeof (struct opt));
337 op->op_name = ns($1);
338 op->op_next = opt;
339 op->op_value = ns($3);
340 opt = op;
341 free(temp_id);
342 free(val_id);
343 } ;
b1e602f2 344
841254c0 345Opt_value:
22d68ad0
BJ
346 ID
347 = { $$ = val_id = ns($1); } |
348 NUMBER
349 = { char nb[16]; $$ = val_id = ns(sprintf(nb, "%d", $1)); };
841254c0
RE
350
351
2f47f1cc 352Save_id:
22d68ad0
BJ
353 ID
354 = { $$ = temp_id = ns($1); }
2f47f1cc 355 ;
7c1d4665
MK
356
357Mkopt_list:
358 Mkopt_list COMMA Mkoption
359 |
360 Mkoption
361 ;
362
363Mkoption:
364 Save_id EQUALS Opt_value
365 = {
366 struct opt *op = (struct opt *)malloc(sizeof (struct opt));
367 op->op_name = ns($1);
368 op->op_next = mkopt;
369 op->op_value = ns($3);
370 mkopt = op;
371 free(temp_id);
372 free(val_id);
373 } ;
2f47f1cc
MT
374
375Dev:
22d68ad0
BJ
376 UBA
377 = { $$ = ns("uba"); } |
378 MBA
379 = { $$ = ns("mba"); } |
380 ID
381 = { $$ = ns($1); }
2f47f1cc
MT
382 ;
383
384Device_spec:
22d68ad0
BJ
385 DEVICE Dev_name Dev_info Int_spec
386 = { cur.d_type = DEVICE; } |
387 MASTER Dev_name Dev_info Int_spec
388 = { cur.d_type = MASTER; } |
389 DISK Dev_name Dev_info Int_spec
390 = { cur.d_dk = 1; cur.d_type = DEVICE; } |
391 CONTROLLER Dev_name Dev_info Int_spec
392 = { cur.d_type = CONTROLLER; } |
393 PSEUDO_DEVICE Init_dev Dev
394 = {
395 cur.d_name = $3;
396 cur.d_type = PSEUDO_DEVICE;
397 } |
398 PSEUDO_DEVICE Init_dev Dev NUMBER
399 = {
400 cur.d_name = $3;
401 cur.d_type = PSEUDO_DEVICE;
402 cur.d_slave = $4;
403 };
2f47f1cc
MT
404
405Dev_name:
22d68ad0
BJ
406 Init_dev Dev NUMBER
407 = {
408 cur.d_name = $2;
409 if (eq($2, "mba"))
410 seen_mba = 1;
411 else if (eq($2, "uba"))
412 seen_uba = 1;
413 cur.d_unit = $3;
414 };
2f47f1cc
MT
415
416Init_dev:
22d68ad0
BJ
417 /* lambda */
418 = { init_dev(&cur); };
2f47f1cc
MT
419
420Dev_info:
421 Con_info Info_list
22d68ad0
BJ
422 |
423 /* lambda */
424 ;
2f47f1cc
MT
425
426Con_info:
22d68ad0
BJ
427 AT Dev NUMBER
428 = {
b1e602f2
MT
429 if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba"))
430 yyerror(sprintf(errbuf,
22d68ad0 431 "%s must be connected to a nexus", cur.d_name));
b1e602f2 432 cur.d_conn = connect($2, $3);
22d68ad0
BJ
433 } |
434 AT NEXUS NUMBER
435 = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; };
2f47f1cc
MT
436
437Info_list:
438 Info_list Info
22d68ad0
BJ
439 |
440 /* lambda */
441 ;
2f47f1cc
MT
442
443Info:
22d68ad0
BJ
444 CSR NUMBER
445 = { cur.d_addr = $2; } |
446 DRIVE NUMBER
447 = { cur.d_drive = $2; } |
448 SLAVE NUMBER
449 = {
450 if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
451 cur.d_conn->d_type == MASTER)
b1e602f2
MT
452 cur.d_slave = $2;
453 else
454 yyerror("can't specify slave--not to master");
22d68ad0
BJ
455 } |
456 FLAGS NUMBER
457 = { cur.d_flags = $2; };
2f47f1cc
MT
458
459Int_spec:
22d68ad0
BJ
460 VECTOR Id_list
461 = { cur.d_vec = $2; } |
462 PRIORITY NUMBER
463 = { cur.d_pri = $2; } |
464 /* lambda */
465 ;
08f9a943
BJ
466
467Id_list:
22d68ad0
BJ
468 Save_id
469 = {
470 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
471 a->id = $1; a->id_next = 0; $$ = a;
472 } |
08f9a943 473 Save_id Id_list =
22d68ad0
BJ
474 {
475 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
476 a->id = $1; a->id_next = $2; $$ = a;
477 };
478
2f47f1cc
MT
479%%
480
481yyerror(s)
f025f13d 482 char *s;
2f47f1cc 483{
f025f13d 484
36edb824 485 fprintf(stderr, "config: line %d: %s\n", yyline, s);
2f47f1cc
MT
486}
487
488/*
f025f13d 489 * return the passed string in a new space
2f47f1cc 490 */
2f47f1cc
MT
491char *
492ns(str)
f025f13d 493 register char *str;
2f47f1cc
MT
494{
495 register char *cp;
496
22d68ad0
BJ
497 cp = malloc((unsigned)(strlen(str)+1));
498 (void) strcpy(cp, str);
499 return (cp);
2f47f1cc
MT
500}
501
502/*
f025f13d 503 * add a device to the list of devices
2f47f1cc 504 */
2f47f1cc 505newdev(dp)
f025f13d 506 register struct device *dp;
2f47f1cc
MT
507{
508 register struct device *np;
509
510 np = (struct device *) malloc(sizeof *np);
511 *np = *dp;
f025f13d 512 if (curp == 0)
b1e602f2
MT
513 dtab = np;
514 else
515 curp->d_next = np;
516 curp = np;
2f47f1cc
MT
517}
518
519/*
f025f13d 520 * note that a configuration should be made
2f47f1cc 521 */
36edb824
SL
522mkconf(sysname)
523 char *sysname;
2f47f1cc 524{
36edb824 525 register struct file_list *fl, **flp;
2f47f1cc
MT
526
527 fl = (struct file_list *) malloc(sizeof *fl);
36edb824
SL
528 fl->f_type = SYSTEMSPEC;
529 fl->f_needs = sysname;
530 fl->f_rootdev = NODEV;
531 fl->f_argdev = NODEV;
532 fl->f_dumpdev = NODEV;
533 fl->f_fn = 0;
534 fl->f_next = 0;
535 for (flp = confp; *flp; flp = &(*flp)->f_next)
536 ;
537 *flp = fl;
538 confp = flp;
539}
540
541struct file_list *
542newswap()
543{
544 struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
545
546 fl->f_type = SWAPSPEC;
547 fl->f_next = 0;
548 fl->f_swapdev = NODEV;
549 fl->f_swapsize = 0;
550 fl->f_needs = 0;
551 fl->f_fn = 0;
552 return (fl);
553}
554
555/*
556 * Add a swap device to the system's configuration
557 */
558mkswap(system, fl, size)
559 struct file_list *system, *fl;
560 int size;
561{
562 register struct file_list **flp;
563 char *cp, name[80];
564
565 if (system == 0 || system->f_type != SYSTEMSPEC) {
566 yyerror("\"swap\" spec precedes \"config\" specification");
567 return;
568 }
569 if (size < 0) {
570 yyerror("illegal swap partition size");
571 return;
572 }
573 /*
574 * Append swap description to the end of the list.
575 */
576 flp = &system->f_next;
577 for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
578 ;
579 fl->f_next = *flp;
580 *flp = fl;
8df5b824 581 fl->f_swapsize = size;
36edb824
SL
582 /*
583 * If first swap device for this system,
584 * set up f_fn field to insure swap
585 * files are created with unique names.
586 */
587 if (system->f_fn)
588 return;
589 if (eq(fl->f_fn, "generic"))
590 system->f_fn = ns(fl->f_fn);
2f47f1cc 591 else
36edb824 592 system->f_fn = ns(system->f_needs);
2f47f1cc
MT
593}
594
595/*
f025f13d
BJ
596 * find the pointer to connect to the given device and number.
597 * returns 0 if no such device and prints an error message
2f47f1cc 598 */
f025f13d
BJ
599struct device *
600connect(dev, num)
601 register char *dev;
602 register int num;
2f47f1cc
MT
603{
604 register struct device *dp;
f6f4af06 605 struct device *huhcon();
2f47f1cc 606
a5e18d6b 607 if (num == QUES)
f025f13d
BJ
608 return (huhcon(dev));
609 for (dp = dtab; dp != 0; dp = dp->d_next) {
610 if ((num != dp->d_unit) || !eq(dev, dp->d_name))
611 continue;
612 if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
a5e18d6b
MT
613 yyerror(sprintf(errbuf,
614 "%s connected to non-controller", dev));
f025f13d
BJ
615 return (0);
616 }
617 return (dp);
618 }
2f47f1cc 619 yyerror(sprintf(errbuf, "%s %d not defined", dev, num));
f025f13d 620 return (0);
2f47f1cc 621}
f6f4af06
MT
622
623/*
f025f13d 624 * connect to an unspecific thing
f6f4af06 625 */
f025f13d
BJ
626struct device *
627huhcon(dev)
628 register char *dev;
f6f4af06 629{
f025f13d
BJ
630 register struct device *dp, *dcp;
631 struct device rdev;
632 int oldtype;
633
f6f4af06 634 /*
f025f13d 635 * First make certain that there are some of these to wildcard on
f6f4af06 636 */
f025f13d
BJ
637 for (dp = dtab; dp != 0; dp = dp->d_next)
638 if (eq(dp->d_name, dev))
639 break;
640 if (dp == 0) {
641 yyerror(sprintf(errbuf, "no %s's to wildcard", dev));
642 return (0);
643 }
644 oldtype = dp->d_type;
645 dcp = dp->d_conn;
646 /*
647 * Now see if there is already a wildcard entry for this device
648 * (e.g. Search for a "uba ?")
649 */
650 for (; dp != 0; dp = dp->d_next)
651 if (eq(dev, dp->d_name) && dp->d_unit == -1)
652 break;
653 /*
654 * If there isn't, make one because everything needs to be connected
655 * to something.
656 */
657 if (dp == 0) {
658 dp = &rdev;
659 init_dev(dp);
660 dp->d_unit = QUES;
661 dp->d_name = ns(dev);
662 dp->d_type = oldtype;
663 newdev(dp);
664 dp = curp;
665 /*
666 * Connect it to the same thing that other similar things are
667 * connected to, but make sure it is a wildcard unit
668 * (e.g. up connected to sc ?, here we make connect sc? to a
669 * uba?). If other things like this are on the NEXUS or
670 * if they aren't connected to anything, then make the same
671 * connection, else call ourself to connect to another
672 * unspecific device.
673 */
674 if (dcp == TO_NEXUS || dcp == 0)
675 dp->d_conn = dcp;
676 else
677 dp->d_conn = connect(dcp->d_name, QUES);
678 }
679 return (dp);
f6f4af06
MT
680}
681
682init_dev(dp)
f025f13d 683 register struct device *dp;
f6f4af06 684{
f025f13d
BJ
685
686 dp->d_name = "OHNO!!!";
687 dp->d_type = DEVICE;
688 dp->d_conn = 0;
689 dp->d_vec = 0;
690 dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0;
691 dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
a5e18d6b
MT
692}
693
694/*
f025f13d 695 * make certain that this is a reasonable type of thing to connect to a nexus
a5e18d6b 696 */
a5e18d6b 697check_nexus(dev, num)
f025f13d
BJ
698 register struct device *dev;
699 int num;
a5e18d6b 700{
f025f13d 701
0bf41cfc 702 switch (machine) {
f025f13d 703
0bf41cfc
BJ
704 case MACHINE_VAX:
705 if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba"))
706 yyerror("only uba's and mba's should be connected to the nexus");
707 if (num != QUES)
708 yyerror("can't give specific nexus numbers");
709 break;
710
711 case MACHINE_SUN:
712 if (!eq(dev->d_name, "mb"))
713 yyerror("only mb's should be connected to the nexus");
714 break;
715 }
f6f4af06 716}
b1e602f2
MT
717
718/*
719 * Check the timezone to make certain it is sensible
720 */
721
722check_tz()
723{
841254c0 724 if (abs(timezone) > 12 * 60)
b1e602f2
MT
725 yyerror("timezone is unreasonable");
726 else
f025f13d 727 hadtz = 1;
b1e602f2 728}
36edb824
SL
729
730/*
731 * Check system specification and apply defaulting
732 * rules on root, argument, dump, and swap devices.
733 */
734checksystemspec(fl)
735 register struct file_list *fl;
736{
737 char buf[BUFSIZ];
738 register struct file_list *swap;
739 int generic;
740
741 if (fl == 0 || fl->f_type != SYSTEMSPEC) {
742 yyerror("internal error, bad system specification");
743 exit(1);
744 }
745 swap = fl->f_next;
746 generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
747 if (fl->f_rootdev == NODEV && !generic) {
748 yyerror("no root device specified");
749 exit(1);
750 }
751 /*
752 * Default swap area to be in 'b' partition of root's
753 * device. If root specified to be other than on 'a'
754 * partition, give warning, something probably amiss.
755 */
756 if (swap == 0 || swap->f_type != SWAPSPEC) {
757 dev_t dev;
758
759 swap = newswap();
760 dev = fl->f_rootdev;
761 if (minor(dev) & 07) {
762 sprintf(buf,
763"Warning, swap defaulted to 'b' partition with root on '%c' partition",
764 (minor(dev) & 07) + 'a');
765 yyerror(buf);
766 }
767 swap->f_swapdev =
768 makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
769 swap->f_fn = devtoname(swap->f_swapdev);
770 mkswap(fl, swap, 0);
771 }
772 /*
773 * Make sure a generic swap isn't specified, along with
774 * other stuff (user must really be confused).
775 */
776 if (generic) {
777 if (fl->f_rootdev != NODEV)
778 yyerror("root device specified with generic swap");
779 if (fl->f_argdev != NODEV)
780 yyerror("arg device specified with generic swap");
781 if (fl->f_dumpdev != NODEV)
782 yyerror("dump device specified with generic swap");
783 return;
784 }
785 /*
786 * Default argument device and check for oddball arrangements.
787 */
788 if (fl->f_argdev == NODEV)
789 fl->f_argdev = swap->f_swapdev;
790 if (fl->f_argdev != swap->f_swapdev)
791 yyerror("Warning, arg device different than primary swap");
792 /*
793 * Default dump device and warn if place is not a
794 * swap area or the argument device partition.
795 */
796 if (fl->f_dumpdev == NODEV)
797 fl->f_dumpdev = swap->f_swapdev;
798 if (fl->f_dumpdev != swap->f_swapdev && fl->f_dumpdev != fl->f_argdev) {
799 struct file_list *p = swap->f_next;
800
801 for (; p && p->f_type == SWAPSPEC; p = p->f_next)
802 if (fl->f_dumpdev == p->f_swapdev)
803 return;
804 sprintf(buf, "Warning, orphaned dump device, %s",
805 "do you know what you're doing");
806 yyerror(buf);
807 }
808}
809
810/*
811 * Verify all devices specified in the system specification
812 * are present in the device specifications.
813 */
814verifysystemspecs()
815{
816 register struct file_list *fl;
817 dev_t checked[50], *verifyswap();
818 register dev_t *pchecked = checked;
819
820 for (fl = conf_list; fl; fl = fl->f_next) {
821 if (fl->f_type != SYSTEMSPEC)
822 continue;
823 if (!finddev(fl->f_rootdev))
824 deverror(fl->f_needs, "root");
825 *pchecked++ = fl->f_rootdev;
826 pchecked = verifyswap(fl->f_next, checked, pchecked);
827#define samedev(dev1, dev2) \
828 ((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
829 if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
830 if (!finddev(fl->f_dumpdev))
831 deverror(fl->f_needs, "dump");
832 *pchecked++ = fl->f_dumpdev;
833 }
834 if (!alreadychecked(fl->f_argdev, checked, pchecked)) {
835 if (!finddev(fl->f_argdev))
836 deverror(fl->f_needs, "arg");
837 *pchecked++ = fl->f_argdev;
838 }
839 }
840}
841
842/*
843 * Do as above, but for swap devices.
844 */
845dev_t *
846verifyswap(fl, checked, pchecked)
847 register struct file_list *fl;
848 dev_t checked[];
849 register dev_t *pchecked;
850{
851
852 for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
853 if (eq(fl->f_fn, "generic"))
854 continue;
855 if (alreadychecked(fl->f_swapdev, checked, pchecked))
856 continue;
857 if (!finddev(fl->f_swapdev))
858 fprintf(stderr,
859 "config: swap device %s not configured", fl->f_fn);
860 *pchecked++ = fl->f_swapdev;
861 }
862 return (pchecked);
863}
864
865/*
866 * Has a device already been checked
867 * for it's existence in the configuration?
868 */
869alreadychecked(dev, list, last)
870 dev_t dev, list[];
871 register dev_t *last;
872{
873 register dev_t *p;
874
875 for (p = list; p < last; p++)
876 if (samedev(*p, dev))
877 return (1);
878 return (0);
879}
880
881deverror(systemname, devtype)
882 char *systemname, *devtype;
883{
884
885 fprintf(stderr, "config: %s: %s device not configured\n",
886 systemname, devtype);
887}
888
889/*
890 * Look for the device in the list of
891 * configured hardware devices. Must
892 * take into account stuff wildcarded.
893 */
894finddev(dev)
895 dev_t dev;
896{
897
898 /* punt on this right now */
899 return (1);
900}