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