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