mkoptions.c revision 72684
112772Speter/*
212772Speter * Copyright (c) 1995  Peter Wemm
312772Speter * Copyright (c) 1980, 1993
412772Speter *	The Regents of the University of California.  All rights reserved.
512772Speter *
612772Speter * Redistribution and use in source and binary forms, with or without
712772Speter * modification, are permitted provided that the following conditions
812772Speter * are met:
912772Speter * 1. Redistributions of source code must retain the above copyright
1012772Speter *    notice, this list of conditions and the following disclaimer.
1112772Speter * 2. Redistributions in binary form must reproduce the above copyright
1212772Speter *    notice, this list of conditions and the following disclaimer in the
1312772Speter *    documentation and/or other materials provided with the distribution.
1412772Speter * 3. All advertising materials mentioning features or use of this software
1512772Speter *    must display the following acknowledgement:
1612772Speter *	This product includes software developed by the University of
1712772Speter *	California, Berkeley and its contributors.
1812772Speter * 4. Neither the name of the University nor the names of its contributors
1912772Speter *    may be used to endorse or promote products derived from this software
2012772Speter *    without specific prior written permission.
2112772Speter *
2212772Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312772Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412772Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512772Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612772Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712772Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812772Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912772Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012772Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112772Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212772Speter * SUCH DAMAGE.
3312772Speter */
3412772Speter
3512772Speter#ifndef lint
3629451Scharnier#if 0
3712772Speterstatic char sccsid[] = "@(#)mkheaders.c	8.1 (Berkeley) 6/6/93";
3829451Scharnier#endif
3929451Scharnierstatic const char rcsid[] =
4050479Speter  "$FreeBSD: head/usr.sbin/config/mkoptions.c 72684 2001-02-19 04:43:21Z peter $";
4112772Speter#endif /* not lint */
4212772Speter
4312772Speter/*
4412772Speter * Make all the .h files for the optional entries
4512772Speter */
4612772Speter
4729451Scharnier#include <ctype.h>
4829451Scharnier#include <err.h>
4912772Speter#include <stdio.h>
5020458Sjoerg#include <string.h>
5169004Simp#include <sys/param.h>
5212772Speter#include "config.h"
5316073Sphk#include "y.tab.h"
5412772Speter
5537578Sbdestatic	struct users {
5637578Sbde	int	u_default;
5737578Sbde	int	u_min;
5837578Sbde	int	u_max;
5972000Speter} users= { 8, 2, 512 };
6037578Sbde
6161640Speterstatic char *lower(char *);
6261640Speterstatic void read_options(void);
6361640Speterstatic void do_option(char *);
6461640Speterstatic char *tooption(char *);
6520458Sjoerg
6629451Scharniervoid
6761640Speteroptions(void)
6812772Speter{
6937578Sbde	char buf[40];
7037578Sbde	struct cputype *cp;
7112772Speter	struct opt_list *ol;
7237578Sbde	struct opt *op;
7312772Speter
7437578Sbde	/* Fake the cpu types as options. */
7537578Sbde	for (cp = cputype; cp != NULL; cp = cp->cpu_next) {
7637578Sbde		op = (struct opt *)malloc(sizeof(*op));
7712772Speter		memset(op, 0, sizeof(*op));
7820458Sjoerg		op->op_name = ns(cp->cpu_name);
7912772Speter		op->op_next = opt;
8012772Speter		opt = op;
8112772Speter	}
8212772Speter
8337578Sbde	if (maxusers == 0) {
8472000Speter		printf("maxusers not specified; %d assumed\n", users.u_default);
8572000Speter		maxusers = users.u_default;
8672000Speter	} else if (maxusers < users.u_min) {
8772000Speter		printf("minimum of %d maxusers assumed\n", users.u_min);
8872000Speter		maxusers = users.u_min;
8972000Speter	} else if (maxusers > users.u_max)
9072000Speter		printf("warning: maxusers > %d (%d)\n", users.u_max, maxusers);
9137578Sbde
9237578Sbde	/* Fake MAXUSERS as an option. */
9337578Sbde	op = (struct opt *)malloc(sizeof(*op));
9437578Sbde	memset(op, 0, sizeof(*op));
9572684Speter	op->op_name = ns("MAXUSERS");
9646021Speter	snprintf(buf, sizeof(buf), "%d", maxusers);
9737578Sbde	op->op_value = ns(buf);
9837578Sbde	op->op_next = opt;
9937578Sbde	opt = op;
10037578Sbde
10112772Speter	read_options();
10212772Speter	for (ol = otab; ol != 0; ol = ol->o_next)
10312772Speter		do_option(ol->o_name);
10461523Speter	for (op = opt; op; op = op->op_next) {
10571251Speter		if (!op->op_ownfile && strncmp(op->op_name, "DEV_", 4)) {
10661523Speter			printf("%s:%d: unknown option \"%s\"\n",
10761523Speter			       PREFIX, op->op_line, op->op_name);
10861523Speter			exit(1);
10961523Speter		}
11061523Speter	}
11112772Speter}
11212772Speter
11312772Speter/*
11412772Speter * Generate an <options>.h file
11512772Speter */
11612772Speter
11745744Speterstatic void
11861640Speterdo_option(char *name)
11912772Speter{
12072684Speter	char *file, *inw;
12172684Speter	const char *basefile;
12248401Speter	struct opt_list *ol;
12312772Speter	struct opt *op, *op_head, *topp;
12412772Speter	FILE *inf, *outf;
12512772Speter	char *value;
12612772Speter	char *oldvalue;
12712772Speter	int seen;
12848401Speter	int tidy;
12912772Speter
13012772Speter	file = tooption(name);
13112772Speter
13212772Speter	/*
13312772Speter	 * Check to see if the option was specified..
13412772Speter	 */
13512772Speter	value = NULL;
13612772Speter	for (op = opt; op; op = op->op_next) {
13712772Speter		if (eq(name, op->op_name)) {
13837577Sbde			oldvalue = value;
13912772Speter			value = op->op_value;
14037577Sbde			if (value == NULL)
14112772Speter				value = ns("1");
14237577Sbde			if (oldvalue != NULL && !eq(value, oldvalue))
14337577Sbde				printf(
14437577Sbde			    "%s:%d: option \"%s\" redefined from %s to %s\n",
14537577Sbde				   PREFIX, op->op_line, op->op_name, oldvalue,
14637577Sbde				   value);
14712772Speter			op->op_ownfile++;
14812772Speter		}
14912772Speter	}
15012772Speter
15171866Speter	remember(file);
15212772Speter	inf = fopen(file, "r");
15312772Speter	if (inf == 0) {
15412772Speter		outf = fopen(file, "w");
15529451Scharnier		if (outf == 0)
15629451Scharnier			err(1, "%s", file);
15712772Speter
15812772Speter		/* was the option in the config file? */
15912772Speter		if (value) {
16012772Speter			fprintf(outf, "#define %s %s\n", name, value);
16112772Speter		} /* else empty file */
16212772Speter
16312772Speter		(void) fclose(outf);
16412772Speter		return;
16512772Speter	}
16655659Sbde	basefile = "";
16755659Sbde	for (ol = otab; ol != 0; ol = ol->o_next)
16855659Sbde		if (eq(name, ol->o_name)) {
16955659Sbde			basefile = ol->o_file;
17055659Sbde			break;
17155659Sbde		}
17212772Speter	oldvalue = NULL;
17312772Speter	op_head = NULL;
17412772Speter	seen = 0;
17548401Speter	tidy = 0;
17612772Speter	for (;;) {
17712772Speter		char *cp;
17812772Speter		char *invalue;
17912772Speter
18012772Speter		/* get the #define */
18112772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
18212772Speter			break;
18312772Speter		/* get the option name */
18412772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
18512772Speter			break;
18612772Speter		inw = ns(inw);
18748401Speter		/* get the option value */
18848401Speter		if ((cp = get_word(inf)) == 0 || cp == (char *)EOF)
18912772Speter			break;
19012772Speter		/* option value */
19112772Speter		invalue = ns(cp); /* malloced */
19212772Speter		if (eq(inw, name)) {
19312772Speter			oldvalue = invalue;
19412772Speter			invalue = value;
19512772Speter			seen++;
19612772Speter		}
19748401Speter		for (ol = otab; ol != 0; ol = ol->o_next)
19848401Speter			if (eq(inw, ol->o_name))
19948401Speter				break;
20055603Sbde		if (!eq(inw, name) && !ol) {
20148401Speter			printf("WARNING: unknown option `%s' removed from %s\n",
20248401Speter				inw, file);
20348401Speter			tidy++;
20455659Sbde		} else if (ol != NULL && !eq(basefile, ol->o_file)) {
20555659Sbde			printf("WARNING: option `%s' moved from %s to %s\n",
20655659Sbde				inw, basefile, ol->o_file);
20755659Sbde			tidy++;
20848401Speter		} else {
20948401Speter			op = (struct opt *) malloc(sizeof *op);
21048401Speter			bzero(op, sizeof(*op));
21148401Speter			op->op_name = inw;
21248401Speter			op->op_value = invalue;
21348401Speter			op->op_next = op_head;
21448401Speter			op_head = op;
21548401Speter		}
21612772Speter
21712772Speter		/* EOL? */
21812772Speter		cp = get_word(inf);
21912772Speter		if (cp == (char *)EOF)
22012772Speter			break;
22112772Speter	}
22212772Speter	(void) fclose(inf);
22348401Speter	if (!tidy && ((value == NULL && oldvalue == NULL) ||
22448401Speter	    (value && oldvalue && eq(value, oldvalue)))) {
22512772Speter		for (op = op_head; op != NULL; op = topp) {
22612772Speter			topp = op->op_next;
22712772Speter			free(op->op_name);
22812772Speter			free(op->op_value);
22912772Speter			free(op);
23012772Speter		}
23112772Speter		return;
23212772Speter	}
23312772Speter
23412772Speter	if (value && !seen) {
23512772Speter		/* New option appears */
23612772Speter		op = (struct opt *) malloc(sizeof *op);
23712772Speter		bzero(op, sizeof(*op));
23812772Speter		op->op_name = ns(name);
23912772Speter		op->op_value = value ? ns(value) : NULL;
24012772Speter		op->op_next = op_head;
24112772Speter		op_head = op;
24212772Speter	}
24312772Speter
24412772Speter	outf = fopen(file, "w");
24529451Scharnier	if (outf == 0)
24629451Scharnier		err(1, "%s", file);
24712772Speter	for (op = op_head; op != NULL; op = topp) {
24812772Speter		/* was the option in the config file? */
24912772Speter		if (op->op_value) {
25012772Speter			fprintf(outf, "#define %s %s\n",
25112772Speter				op->op_name, op->op_value);
25212772Speter		}
25312772Speter		topp = op->op_next;
25412772Speter		free(op->op_name);
25512772Speter		free(op->op_value);
25612772Speter		free(op);
25712772Speter	}
25812772Speter	(void) fclose(outf);
25912772Speter}
26012772Speter
26112772Speter/*
26212772Speter * Find the filename to store the option spec into.
26312772Speter */
26445744Speterstatic char *
26561640Spetertooption(char *name)
26612772Speter{
26769004Simp	static char hbuf[MAXPATHLEN];
26869004Simp	char nbuf[MAXPATHLEN];
26912772Speter	struct opt_list *po;
27012772Speter
27112772Speter	/* "cannot happen"?  the otab list should be complete.. */
27269004Simp	(void) strlcpy(nbuf, "options.h", sizeof(nbuf));
27312772Speter
27412772Speter	for (po = otab ; po != 0; po = po->o_next) {
27512772Speter		if (eq(po->o_name, name)) {
27669004Simp			strlcpy(nbuf, po->o_file, sizeof(nbuf));
27712772Speter			break;
27812772Speter		}
27912772Speter	}
28012772Speter
28169004Simp	(void) strlcpy(hbuf, path(nbuf), sizeof(hbuf));
28212772Speter	return (hbuf);
28312772Speter}
28412772Speter
28512772Speter/*
28612772Speter * read the options and options.<machine> files
28712772Speter */
28845744Speterstatic void
28961640Speterread_options(void)
29012772Speter{
29112772Speter	FILE *fp;
29269004Simp	char fname[MAXPATHLEN];
29312772Speter	char *wd, *this, *val;
29412772Speter	struct opt_list *po;
29512772Speter	int first = 1;
29669004Simp	char genopt[MAXPATHLEN];
29712772Speter
29812772Speter	otab = 0;
29955614Speter	if (ident == NULL) {
30055614Speter		printf("no ident line specified\n");
30155614Speter		exit(1);
30255614Speter	}
30369004Simp	(void) snprintf(fname, sizeof(fname), "../../conf/options");
30412772Speteropenit:
30512772Speter	fp = fopen(fname, "r");
30612772Speter	if (fp == 0) {
30712772Speter		return;
30812772Speter	}
30912772Speternext:
31012772Speter	wd = get_word(fp);
31112772Speter	if (wd == (char *)EOF) {
31212772Speter		(void) fclose(fp);
31312772Speter		if (first == 1) {
31455614Speter			first++;
31555614Speter			(void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename);
31655614Speter			fp = fopen(fname, "r");
31755614Speter			if (fp != 0)
31855614Speter				goto next;
31920457Sjoerg			(void) snprintf(fname, sizeof fname, "options.%s", machinename);
32012772Speter			goto openit;
32112772Speter		}
32212772Speter		if (first == 2) {
32355614Speter			first++;
32445744Speter			(void) snprintf(fname, sizeof fname, "options.%s", raisestr(ident));
32512772Speter			fp = fopen(fname, "r");
32612772Speter			if (fp != 0)
32712772Speter				goto next;
32812772Speter		}
32912772Speter		return;
33012772Speter	}
33112772Speter	if (wd == 0)
33212772Speter		goto next;
33352098Speter	if (wd[0] == '#')
33412772Speter	{
33552098Speter		while (((wd = get_word(fp)) != (char *)EOF) && wd)
33612772Speter		;
33712772Speter		goto next;
33812772Speter	}
33912772Speter	this = ns(wd);
34012772Speter	val = get_word(fp);
34112772Speter	if (val == (char *)EOF)
34212772Speter		return;
34312772Speter	if (val == 0) {
34412772Speter		char *s = ns(this);
34569004Simp		(void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s));
34612772Speter		val = genopt;
34712772Speter		free(s);
34812772Speter	}
34912772Speter	val = ns(val);
35012772Speter
35112772Speter	for (po = otab ; po != 0; po = po->o_next) {
35212772Speter		if (eq(po->o_name, this)) {
35312772Speter			printf("%s: Duplicate option %s.\n",
35412772Speter			       fname, this);
35512772Speter			exit(1);
35612772Speter		}
35712772Speter	}
35812772Speter
35912772Speter	po = (struct opt_list *) malloc(sizeof *po);
36012772Speter	bzero(po, sizeof(*po));
36112772Speter	po->o_name = this;
36212772Speter	po->o_file = val;
36312772Speter	po->o_next = otab;
36412772Speter	otab = po;
36512772Speter
36612772Speter	goto next;
36712772Speter}
36812772Speter
36920458Sjoergstatic char *
37061640Speterlower(char *str)
37112772Speter{
37261640Speter	char *cp = str;
37312772Speter
37412772Speter	while (*str) {
37512772Speter		if (isupper(*str))
37612772Speter			*str = tolower(*str);
37712772Speter		str++;
37812772Speter	}
37912772Speter	return (cp);
38012772Speter}
381