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