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