mkoptions.c revision 205880
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 * 4. Neither the name of the University nor the names of its contributors 1512772Speter * may be used to endorse or promote products derived from this software 1612772Speter * without specific prior written permission. 1712772Speter * 1812772Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1912772Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2012772Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2112772Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2212772Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2312772Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2412772Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2512772Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2612772Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2712772Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2812772Speter * SUCH DAMAGE. 2912772Speter */ 3012772Speter 3112772Speter#ifndef lint 3229451Scharnier#if 0 3312772Speterstatic char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; 3429451Scharnier#endif 3529451Scharnierstatic const char rcsid[] = 3650479Speter "$FreeBSD: head/usr.sbin/config/mkoptions.c 205880 2010-03-30 13:46:40Z ru $"; 3712772Speter#endif /* not lint */ 3812772Speter 3912772Speter/* 4012772Speter * Make all the .h files for the optional entries 4112772Speter */ 4212772Speter 4329451Scharnier#include <ctype.h> 4429451Scharnier#include <err.h> 4512772Speter#include <stdio.h> 4620458Sjoerg#include <string.h> 4769004Simp#include <sys/param.h> 4812772Speter#include "config.h" 4916073Sphk#include "y.tab.h" 5012772Speter 5137578Sbdestatic struct users { 5237578Sbde int u_default; 5337578Sbde int u_min; 5437578Sbde int u_max; 55125935Sdes} users = { 8, 2, 512 }; 5637578Sbde 5761640Speterstatic char *lower(char *); 5861640Speterstatic void read_options(void); 5961640Speterstatic void do_option(char *); 6061640Speterstatic char *tooption(char *); 6120458Sjoerg 6229451Scharniervoid 6361640Speteroptions(void) 6412772Speter{ 6537578Sbde char buf[40]; 6637578Sbde struct cputype *cp; 6712772Speter struct opt_list *ol; 6837578Sbde struct opt *op; 6912772Speter 7037578Sbde /* Fake the cpu types as options. */ 71110895Sru SLIST_FOREACH(cp, &cputype, cpu_next) { 72159362Sdelphij op = (struct opt *)calloc(1, sizeof(*op)); 73205880Sru if (op == NULL) 74205880Sru err(EXIT_FAILURE, "calloc"); 7520458Sjoerg op->op_name = ns(cp->cpu_name); 76110895Sru SLIST_INSERT_HEAD(&opt, op, op_next); 7712772Speter } 7812772Speter 7937578Sbde if (maxusers == 0) { 8087546Sdillon /* printf("maxusers not specified; will auto-size\n"); */ 8172000Speter } else if (maxusers < users.u_min) { 8272000Speter printf("minimum of %d maxusers assumed\n", users.u_min); 8372000Speter maxusers = users.u_min; 8472000Speter } else if (maxusers > users.u_max) 8572000Speter printf("warning: maxusers > %d (%d)\n", users.u_max, maxusers); 8637578Sbde 8737578Sbde /* Fake MAXUSERS as an option. */ 88159362Sdelphij op = (struct opt *)calloc(1, sizeof(*op)); 89205880Sru if (op == NULL) 90205880Sru err(EXIT_FAILURE, "calloc"); 9172684Speter op->op_name = ns("MAXUSERS"); 9246021Speter snprintf(buf, sizeof(buf), "%d", maxusers); 9337578Sbde op->op_value = ns(buf); 94110895Sru SLIST_INSERT_HEAD(&opt, op, op_next); 9537578Sbde 9612772Speter read_options(); 97110895Sru SLIST_FOREACH(ol, &otab, o_next) 9812772Speter do_option(ol->o_name); 99110895Sru SLIST_FOREACH(op, &opt, op_next) { 10071251Speter if (!op->op_ownfile && strncmp(op->op_name, "DEV_", 4)) { 10172841Speter printf("%s: unknown option \"%s\"\n", 10272841Speter PREFIX, op->op_name); 10361523Speter exit(1); 10461523Speter } 10561523Speter } 10612772Speter} 10712772Speter 10812772Speter/* 10912772Speter * Generate an <options>.h file 11012772Speter */ 11112772Speter 11245744Speterstatic void 11361640Speterdo_option(char *name) 11412772Speter{ 11572684Speter char *file, *inw; 11672684Speter const char *basefile; 11748401Speter struct opt_list *ol; 118110895Sru struct opt *op; 119110895Sru struct opt_head op_head; 12012772Speter FILE *inf, *outf; 12112772Speter char *value; 12212772Speter char *oldvalue; 12312772Speter int seen; 12448401Speter int tidy; 12512772Speter 12612772Speter file = tooption(name); 12712772Speter 12812772Speter /* 12912772Speter * Check to see if the option was specified.. 13012772Speter */ 13112772Speter value = NULL; 132110895Sru SLIST_FOREACH(op, &opt, op_next) { 13312772Speter if (eq(name, op->op_name)) { 13437577Sbde oldvalue = value; 13512772Speter value = op->op_value; 13637577Sbde if (value == NULL) 13712772Speter value = ns("1"); 13837577Sbde if (oldvalue != NULL && !eq(value, oldvalue)) 13937577Sbde printf( 14072841Speter "%s: option \"%s\" redefined from %s to %s\n", 14172841Speter PREFIX, op->op_name, oldvalue, 14237577Sbde value); 14312772Speter op->op_ownfile++; 14412772Speter } 14512772Speter } 14612772Speter 14771866Speter remember(file); 14812772Speter inf = fopen(file, "r"); 14912772Speter if (inf == 0) { 15012772Speter outf = fopen(file, "w"); 15129451Scharnier if (outf == 0) 15229451Scharnier err(1, "%s", file); 15312772Speter 15412772Speter /* was the option in the config file? */ 15512772Speter if (value) { 15612772Speter fprintf(outf, "#define %s %s\n", name, value); 15712772Speter } /* else empty file */ 15812772Speter 15912772Speter (void) fclose(outf); 16012772Speter return; 16112772Speter } 16255659Sbde basefile = ""; 163110895Sru SLIST_FOREACH(ol, &otab, o_next) 16455659Sbde if (eq(name, ol->o_name)) { 16555659Sbde basefile = ol->o_file; 16655659Sbde break; 16755659Sbde } 16812772Speter oldvalue = NULL; 169110895Sru SLIST_INIT(&op_head); 17012772Speter seen = 0; 17148401Speter tidy = 0; 17212772Speter for (;;) { 17312772Speter char *cp; 17412772Speter char *invalue; 17512772Speter 17612772Speter /* get the #define */ 17712772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 17812772Speter break; 17912772Speter /* get the option name */ 18012772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 18112772Speter break; 18212772Speter inw = ns(inw); 18348401Speter /* get the option value */ 18448401Speter if ((cp = get_word(inf)) == 0 || cp == (char *)EOF) 18512772Speter break; 18612772Speter /* option value */ 18712772Speter invalue = ns(cp); /* malloced */ 18812772Speter if (eq(inw, name)) { 18912772Speter oldvalue = invalue; 19012772Speter invalue = value; 19112772Speter seen++; 19212772Speter } 193110895Sru SLIST_FOREACH(ol, &otab, o_next) 19448401Speter if (eq(inw, ol->o_name)) 19548401Speter break; 19655603Sbde if (!eq(inw, name) && !ol) { 19748401Speter printf("WARNING: unknown option `%s' removed from %s\n", 19848401Speter inw, file); 19948401Speter tidy++; 20055659Sbde } else if (ol != NULL && !eq(basefile, ol->o_file)) { 20155659Sbde printf("WARNING: option `%s' moved from %s to %s\n", 20255659Sbde inw, basefile, ol->o_file); 20355659Sbde tidy++; 20448401Speter } else { 205159362Sdelphij op = (struct opt *) calloc(1, sizeof *op); 206205880Sru if (op == NULL) 207205880Sru err(EXIT_FAILURE, "calloc"); 20848401Speter op->op_name = inw; 20948401Speter op->op_value = invalue; 210110895Sru SLIST_INSERT_HEAD(&op_head, op, op_next); 21148401Speter } 21212772Speter 21312772Speter /* EOL? */ 21412772Speter cp = get_word(inf); 21512772Speter if (cp == (char *)EOF) 21612772Speter break; 21712772Speter } 21812772Speter (void) fclose(inf); 21948401Speter if (!tidy && ((value == NULL && oldvalue == NULL) || 22048401Speter (value && oldvalue && eq(value, oldvalue)))) { 221110895Sru while (!SLIST_EMPTY(&op_head)) { 222110895Sru op = SLIST_FIRST(&op_head); 223110895Sru SLIST_REMOVE_HEAD(&op_head, op_next); 22412772Speter free(op->op_name); 22512772Speter free(op->op_value); 22612772Speter free(op); 22712772Speter } 22812772Speter return; 22912772Speter } 23012772Speter 23112772Speter if (value && !seen) { 23212772Speter /* New option appears */ 233159362Sdelphij op = (struct opt *) calloc(1, sizeof *op); 234205880Sru if (op == NULL) 235205880Sru err(EXIT_FAILURE, "calloc"); 23612772Speter op->op_name = ns(name); 23712772Speter op->op_value = value ? ns(value) : NULL; 238110895Sru SLIST_INSERT_HEAD(&op_head, op, op_next); 23912772Speter } 24012772Speter 24112772Speter outf = fopen(file, "w"); 24229451Scharnier if (outf == 0) 24329451Scharnier err(1, "%s", file); 244110895Sru while (!SLIST_EMPTY(&op_head)) { 245110895Sru op = SLIST_FIRST(&op_head); 24612772Speter /* was the option in the config file? */ 24712772Speter if (op->op_value) { 24812772Speter fprintf(outf, "#define %s %s\n", 24912772Speter op->op_name, op->op_value); 25012772Speter } 251110895Sru SLIST_REMOVE_HEAD(&op_head, op_next); 25212772Speter free(op->op_name); 25312772Speter free(op->op_value); 25412772Speter free(op); 25512772Speter } 25612772Speter (void) fclose(outf); 25712772Speter} 25812772Speter 25912772Speter/* 26012772Speter * Find the filename to store the option spec into. 26112772Speter */ 26245744Speterstatic char * 26361640Spetertooption(char *name) 26412772Speter{ 26569004Simp static char hbuf[MAXPATHLEN]; 26669004Simp char nbuf[MAXPATHLEN]; 26712772Speter struct opt_list *po; 26812772Speter 26912772Speter /* "cannot happen"? the otab list should be complete.. */ 27069004Simp (void) strlcpy(nbuf, "options.h", sizeof(nbuf)); 27112772Speter 272110895Sru SLIST_FOREACH(po, &otab, o_next) { 27312772Speter if (eq(po->o_name, name)) { 27469004Simp strlcpy(nbuf, po->o_file, sizeof(nbuf)); 27512772Speter break; 27612772Speter } 27712772Speter } 27812772Speter 27969004Simp (void) strlcpy(hbuf, path(nbuf), sizeof(hbuf)); 28012772Speter return (hbuf); 28112772Speter} 28212772Speter 28312772Speter/* 28412772Speter * read the options and options.<machine> files 28512772Speter */ 28645744Speterstatic void 28761640Speterread_options(void) 28812772Speter{ 28912772Speter FILE *fp; 29069004Simp char fname[MAXPATHLEN]; 29112772Speter char *wd, *this, *val; 29212772Speter struct opt_list *po; 29312772Speter int first = 1; 29469004Simp char genopt[MAXPATHLEN]; 29512772Speter 296110895Sru SLIST_INIT(&otab); 29769004Simp (void) snprintf(fname, sizeof(fname), "../../conf/options"); 29812772Speteropenit: 29912772Speter fp = fopen(fname, "r"); 30012772Speter if (fp == 0) { 30112772Speter return; 30212772Speter } 30312772Speternext: 30412772Speter wd = get_word(fp); 30512772Speter if (wd == (char *)EOF) { 30612772Speter (void) fclose(fp); 30712772Speter if (first == 1) { 30855614Speter first++; 30955614Speter (void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename); 31055614Speter fp = fopen(fname, "r"); 31155614Speter if (fp != 0) 31255614Speter goto next; 31320457Sjoerg (void) snprintf(fname, sizeof fname, "options.%s", machinename); 31412772Speter goto openit; 31512772Speter } 31612772Speter return; 31712772Speter } 31812772Speter if (wd == 0) 31912772Speter goto next; 32052098Speter if (wd[0] == '#') 32112772Speter { 32252098Speter while (((wd = get_word(fp)) != (char *)EOF) && wd) 32312772Speter ; 32412772Speter goto next; 32512772Speter } 32612772Speter this = ns(wd); 32712772Speter val = get_word(fp); 32812772Speter if (val == (char *)EOF) 32912772Speter return; 33012772Speter if (val == 0) { 33112772Speter char *s = ns(this); 33269004Simp (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s)); 33312772Speter val = genopt; 33412772Speter free(s); 33512772Speter } 33612772Speter val = ns(val); 33712772Speter 338110895Sru SLIST_FOREACH(po, &otab, o_next) { 33912772Speter if (eq(po->o_name, this)) { 34012772Speter printf("%s: Duplicate option %s.\n", 34112772Speter fname, this); 34212772Speter exit(1); 34312772Speter } 34412772Speter } 34512772Speter 346159362Sdelphij po = (struct opt_list *) calloc(1, sizeof *po); 347205880Sru if (po == NULL) 348205880Sru err(EXIT_FAILURE, "calloc"); 34912772Speter po->o_name = this; 35012772Speter po->o_file = val; 351110895Sru SLIST_INSERT_HEAD(&otab, po, o_next); 35212772Speter 35312772Speter goto next; 35412772Speter} 35512772Speter 35620458Sjoergstatic char * 35761640Speterlower(char *str) 35812772Speter{ 35961640Speter char *cp = str; 36012772Speter 36112772Speter while (*str) { 36212772Speter if (isupper(*str)) 36312772Speter *str = tolower(*str); 36412772Speter str++; 36512772Speter } 36612772Speter return (cp); 36712772Speter} 368