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