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