mkoptions.c revision 207265
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 207265 2010-04-27 06:14:30Z imp $"; 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(); 97206664Simp SLIST_FOREACH(op, &opt, op_next) { 98206664Simp SLIST_FOREACH(ol, &otab, o_next) { 99206664Simp if (eq(op->op_name, ol->o_name) && 100206664Simp (ol->o_flags & OL_ALIAS)) { 101206664Simp printf("Mapping option %s to %s.\n", 102206664Simp op->op_name, ol->o_file); 103206664Simp op->op_name = ol->o_file; 104206664Simp break; 105206664Simp } 106206664Simp } 107206664Simp } 108110895Sru SLIST_FOREACH(ol, &otab, o_next) 10912772Speter do_option(ol->o_name); 110110895Sru SLIST_FOREACH(op, &opt, op_next) { 11171251Speter if (!op->op_ownfile && strncmp(op->op_name, "DEV_", 4)) { 11272841Speter printf("%s: unknown option \"%s\"\n", 11372841Speter PREFIX, op->op_name); 11461523Speter exit(1); 11561523Speter } 11661523Speter } 11712772Speter} 11812772Speter 11912772Speter/* 12012772Speter * Generate an <options>.h file 12112772Speter */ 12212772Speter 12345744Speterstatic void 12461640Speterdo_option(char *name) 12512772Speter{ 12672684Speter char *file, *inw; 12772684Speter const char *basefile; 12848401Speter struct opt_list *ol; 129110895Sru struct opt *op; 130110895Sru struct opt_head op_head; 13112772Speter FILE *inf, *outf; 13212772Speter char *value; 13312772Speter char *oldvalue; 13412772Speter int seen; 13548401Speter int tidy; 13612772Speter 13712772Speter file = tooption(name); 13812772Speter /* 13912772Speter * Check to see if the option was specified.. 14012772Speter */ 14112772Speter value = NULL; 142110895Sru SLIST_FOREACH(op, &opt, op_next) { 14312772Speter if (eq(name, op->op_name)) { 14437577Sbde oldvalue = value; 14512772Speter value = op->op_value; 14637577Sbde if (value == NULL) 14712772Speter value = ns("1"); 14837577Sbde if (oldvalue != NULL && !eq(value, oldvalue)) 14937577Sbde printf( 15072841Speter "%s: option \"%s\" redefined from %s to %s\n", 15172841Speter PREFIX, op->op_name, oldvalue, 15237577Sbde value); 15312772Speter op->op_ownfile++; 15412772Speter } 15512772Speter } 15612772Speter 15771866Speter remember(file); 15812772Speter inf = fopen(file, "r"); 15912772Speter if (inf == 0) { 16012772Speter outf = fopen(file, "w"); 16129451Scharnier if (outf == 0) 16229451Scharnier err(1, "%s", file); 16312772Speter 16412772Speter /* was the option in the config file? */ 16512772Speter if (value) { 16612772Speter fprintf(outf, "#define %s %s\n", name, value); 16712772Speter } /* else empty file */ 16812772Speter 169207263Simp (void)fclose(outf); 17012772Speter return; 17112772Speter } 17255659Sbde basefile = ""; 173110895Sru SLIST_FOREACH(ol, &otab, o_next) 17455659Sbde if (eq(name, ol->o_name)) { 17555659Sbde basefile = ol->o_file; 17655659Sbde break; 17755659Sbde } 17812772Speter oldvalue = NULL; 179110895Sru SLIST_INIT(&op_head); 18012772Speter seen = 0; 18148401Speter tidy = 0; 18212772Speter for (;;) { 18312772Speter char *cp; 18412772Speter char *invalue; 18512772Speter 18612772Speter /* get the #define */ 18712772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 18812772Speter break; 18912772Speter /* get the option name */ 19012772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 19112772Speter break; 19212772Speter inw = ns(inw); 19348401Speter /* get the option value */ 19448401Speter if ((cp = get_word(inf)) == 0 || cp == (char *)EOF) 19512772Speter break; 19612772Speter /* option value */ 19712772Speter invalue = ns(cp); /* malloced */ 19812772Speter if (eq(inw, name)) { 19912772Speter oldvalue = invalue; 20012772Speter invalue = value; 20112772Speter seen++; 20212772Speter } 203110895Sru SLIST_FOREACH(ol, &otab, o_next) 20448401Speter if (eq(inw, ol->o_name)) 20548401Speter break; 20655603Sbde if (!eq(inw, name) && !ol) { 20748401Speter printf("WARNING: unknown option `%s' removed from %s\n", 20848401Speter inw, file); 20948401Speter tidy++; 21055659Sbde } else if (ol != NULL && !eq(basefile, ol->o_file)) { 21155659Sbde printf("WARNING: option `%s' moved from %s to %s\n", 21255659Sbde inw, basefile, ol->o_file); 21355659Sbde tidy++; 21448401Speter } else { 215159362Sdelphij op = (struct opt *) calloc(1, sizeof *op); 216205880Sru if (op == NULL) 217205880Sru err(EXIT_FAILURE, "calloc"); 21848401Speter op->op_name = inw; 21948401Speter op->op_value = invalue; 220110895Sru SLIST_INSERT_HEAD(&op_head, op, op_next); 22148401Speter } 22212772Speter 22312772Speter /* EOL? */ 22412772Speter cp = get_word(inf); 22512772Speter if (cp == (char *)EOF) 22612772Speter break; 22712772Speter } 228207263Simp (void)fclose(inf); 22948401Speter if (!tidy && ((value == NULL && oldvalue == NULL) || 23048401Speter (value && oldvalue && eq(value, oldvalue)))) { 231110895Sru while (!SLIST_EMPTY(&op_head)) { 232110895Sru op = SLIST_FIRST(&op_head); 233110895Sru SLIST_REMOVE_HEAD(&op_head, op_next); 23412772Speter free(op->op_name); 23512772Speter free(op->op_value); 23612772Speter free(op); 23712772Speter } 23812772Speter return; 23912772Speter } 24012772Speter 24112772Speter if (value && !seen) { 24212772Speter /* New option appears */ 243159362Sdelphij op = (struct opt *) calloc(1, sizeof *op); 244205880Sru if (op == NULL) 245205880Sru err(EXIT_FAILURE, "calloc"); 24612772Speter op->op_name = ns(name); 24712772Speter op->op_value = value ? ns(value) : NULL; 248110895Sru SLIST_INSERT_HEAD(&op_head, op, op_next); 24912772Speter } 25012772Speter 25112772Speter outf = fopen(file, "w"); 25229451Scharnier if (outf == 0) 25329451Scharnier err(1, "%s", file); 254110895Sru while (!SLIST_EMPTY(&op_head)) { 255110895Sru op = SLIST_FIRST(&op_head); 25612772Speter /* was the option in the config file? */ 25712772Speter if (op->op_value) { 25812772Speter fprintf(outf, "#define %s %s\n", 25912772Speter op->op_name, op->op_value); 26012772Speter } 261110895Sru SLIST_REMOVE_HEAD(&op_head, op_next); 26212772Speter free(op->op_name); 26312772Speter free(op->op_value); 26412772Speter free(op); 26512772Speter } 266207263Simp (void)fclose(outf); 26712772Speter} 26812772Speter 26912772Speter/* 27012772Speter * Find the filename to store the option spec into. 27112772Speter */ 27245744Speterstatic char * 27361640Spetertooption(char *name) 27412772Speter{ 27569004Simp static char hbuf[MAXPATHLEN]; 27669004Simp char nbuf[MAXPATHLEN]; 27712772Speter struct opt_list *po; 27812772Speter 27912772Speter /* "cannot happen"? the otab list should be complete.. */ 280207263Simp (void)strlcpy(nbuf, "options.h", sizeof(nbuf)); 28112772Speter 282110895Sru SLIST_FOREACH(po, &otab, o_next) { 28312772Speter if (eq(po->o_name, name)) { 28469004Simp strlcpy(nbuf, po->o_file, sizeof(nbuf)); 28512772Speter break; 28612772Speter } 28712772Speter } 28812772Speter 289207263Simp (void)strlcpy(hbuf, path(nbuf), sizeof(hbuf)); 29012772Speter return (hbuf); 29112772Speter} 29212772Speter 293207263Simp 29445744Speterstatic void 295207265Simpcheck_duplicate(const char *fname, const char *this) 29612772Speter{ 297207263Simp struct opt_list *po; 298207263Simp 299207265Simp SLIST_FOREACH(po, &otab, o_next) { 300207265Simp if (eq(po->o_name, this)) { 301207265Simp printf("%s: Duplicate option %s.\n", 302207265Simp fname, this); 303207265Simp exit(1); 304207265Simp } 305207265Simp } 306207265Simp} 307207265Simp 308207265Simpstatic void 309207265Simpinsert_option(const char *fname, char *this, char *val) 310207265Simp{ 311207265Simp struct opt_list *po; 312207265Simp 313207265Simp check_duplicate(fname, this); 314207263Simp po = (struct opt_list *) calloc(1, sizeof *po); 315207263Simp if (po == NULL) 316207263Simp err(EXIT_FAILURE, "calloc"); 317207263Simp po->o_name = this; 318207263Simp po->o_file = val; 319207265Simp po->o_flags = 0; 320207263Simp SLIST_INSERT_HEAD(&otab, po, o_next); 321207263Simp} 322207263Simp 323207263Simpstatic void 324207265Simpupdate_option(const char *this, char *val, int flags) 325207263Simp{ 326207263Simp struct opt_list *po; 327207263Simp 328207263Simp SLIST_FOREACH(po, &otab, o_next) { 329207263Simp if (eq(po->o_name, this)) { 330207265Simp free(po->o_file); 331207265Simp po->o_file = val; 332207265Simp po->o_flags = flags; 333207265Simp return; 334207263Simp } 335207263Simp } 336207265Simp printf("Compat option %s not listed in options file.\n", this); 337207265Simp exit(1); 338207263Simp} 339207263Simp 340207263Simpstatic int 341207263Simpread_option_file(const char *fname, int flags) 342207263Simp{ 34312772Speter FILE *fp; 34412772Speter char *wd, *this, *val; 34569004Simp char genopt[MAXPATHLEN]; 34612772Speter 34712772Speter fp = fopen(fname, "r"); 348207263Simp if (fp == 0) 349207263Simp return (0); 350207263Simp while ((wd = get_word(fp)) != (char *)EOF) { 351207263Simp if (wd == 0) 352207263Simp continue; 353207263Simp if (wd[0] == '#') { 354207263Simp while (((wd = get_word(fp)) != (char *)EOF) && wd) 355207263Simp continue; 356207263Simp continue; 35712772Speter } 358207263Simp this = ns(wd); 359206664Simp val = get_word(fp); 360207263Simp if (val == (char *)EOF) 361207263Simp return (1); 362206664Simp if (val == 0) { 363207263Simp if (flags) { 364207263Simp printf("%s: compat file requires two words " 365207263Simp "per line at %s\n", fname, this); 366207263Simp exit(1); 367207263Simp } 368207263Simp char *s = ns(this); 369207263Simp (void)snprintf(genopt, sizeof(genopt), "opt_%s.h", 370207263Simp lower(s)); 371207263Simp val = genopt; 372207263Simp free(s); 373206664Simp } 374207263Simp val = ns(val); 375207265Simp if (flags == 0) 376207265Simp insert_option(fname, this, val); 377207265Simp else 378207265Simp update_option(this, val, flags); 37912772Speter } 380207263Simp (void)fclose(fp); 381207263Simp return (1); 382207263Simp} 38312772Speter 384207263Simp/* 385207263Simp * read the options and options.<machine> files 386207263Simp */ 387207263Simpstatic void 388207263Simpread_options(void) 389207263Simp{ 390207263Simp char fname[MAXPATHLEN]; 391207263Simp 392207263Simp SLIST_INIT(&otab); 393207263Simp read_option_file("../../conf/options", 0); 394207263Simp (void)snprintf(fname, sizeof fname, "../../conf/options.%s", 395207263Simp machinename); 396207263Simp if (!read_option_file(fname, 0)) { 397207263Simp (void)snprintf(fname, sizeof fname, "options.%s", machinename); 398207263Simp read_option_file(fname, 0); 39912772Speter } 400207263Simp read_option_file("../../conf/options-compat", OL_ALIAS); 40112772Speter} 40212772Speter 40320458Sjoergstatic char * 40461640Speterlower(char *str) 40512772Speter{ 40661640Speter char *cp = str; 40712772Speter 40812772Speter while (*str) { 40912772Speter if (isupper(*str)) 41012772Speter *str = tolower(*str); 41112772Speter str++; 41212772Speter } 41312772Speter return (cp); 41412772Speter} 415