mkoptions.c revision 69004
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 69004 2000-11-21 19:58:55Z imp $"; 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; 5937578Sbde} users[] = { 6037578Sbde { 8, 2, 512 }, /* MACHINE_I386 */ 6137578Sbde { 8, 2, 512 }, /* MACHINE_PC98 */ 6237578Sbde { 8, 2, 512 }, /* MACHINE_ALPHA */ 6366457Sdfr { 8, 2, 512 }, /* MACHINE_IA64 */ 6437578Sbde}; 6537578Sbde#define NUSERS (sizeof (users) / sizeof (users[0])) 6637578Sbde 6761640Speterstatic char *lower(char *); 6861640Speterstatic void read_options(void); 6961640Speterstatic void do_option(char *); 7061640Speterstatic char *tooption(char *); 7120458Sjoerg 7229451Scharniervoid 7361640Speteroptions(void) 7412772Speter{ 7537578Sbde char buf[40]; 7637578Sbde struct cputype *cp; 7712772Speter struct opt_list *ol; 7837578Sbde struct opt *op; 7937578Sbde struct users *up; 8012772Speter 8137578Sbde /* Fake the cpu types as options. */ 8237578Sbde for (cp = cputype; cp != NULL; cp = cp->cpu_next) { 8337578Sbde op = (struct opt *)malloc(sizeof(*op)); 8412772Speter memset(op, 0, sizeof(*op)); 8520458Sjoerg op->op_name = ns(cp->cpu_name); 8612772Speter op->op_next = opt; 8712772Speter opt = op; 8812772Speter } 8912772Speter 9037578Sbde /* Initialize `maxusers'. */ 9137578Sbde if ((unsigned)machine > NUSERS) { 9245775Speter printf("maxusers config info isn't present, using i386\n"); 9345744Speter up = &users[MACHINE_I386 - 1]; 9437578Sbde } else 9537578Sbde up = &users[machine - 1]; 9637578Sbde if (maxusers == 0) { 9737578Sbde printf("maxusers not specified; %d assumed\n", up->u_default); 9837578Sbde maxusers = up->u_default; 9937578Sbde } else if (maxusers < up->u_min) { 10037578Sbde printf("minimum of %d maxusers assumed\n", up->u_min); 10137578Sbde maxusers = up->u_min; 10237578Sbde } else if (maxusers > up->u_max) 10337578Sbde printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers); 10437578Sbde 10537578Sbde /* Fake MAXUSERS as an option. */ 10637578Sbde op = (struct opt *)malloc(sizeof(*op)); 10737578Sbde memset(op, 0, sizeof(*op)); 10837578Sbde op->op_name = "MAXUSERS"; 10946021Speter snprintf(buf, sizeof(buf), "%d", maxusers); 11037578Sbde op->op_value = ns(buf); 11137578Sbde op->op_next = opt; 11237578Sbde opt = op; 11337578Sbde 11412772Speter read_options(); 11512772Speter for (ol = otab; ol != 0; ol = ol->o_next) 11612772Speter do_option(ol->o_name); 11761523Speter for (op = opt; op; op = op->op_next) { 11861523Speter if (!op->op_ownfile) { 11961523Speter printf("%s:%d: unknown option \"%s\"\n", 12061523Speter PREFIX, op->op_line, op->op_name); 12161523Speter exit(1); 12261523Speter } 12361523Speter } 12412772Speter} 12512772Speter 12612772Speter/* 12712772Speter * Generate an <options>.h file 12812772Speter */ 12912772Speter 13045744Speterstatic void 13161640Speterdo_option(char *name) 13212772Speter{ 13355659Sbde char *basefile, *file, *inw; 13448401Speter struct opt_list *ol; 13512772Speter struct opt *op, *op_head, *topp; 13612772Speter FILE *inf, *outf; 13712772Speter char *value; 13812772Speter char *oldvalue; 13912772Speter int seen; 14048401Speter int tidy; 14112772Speter 14212772Speter file = tooption(name); 14312772Speter 14412772Speter /* 14512772Speter * Check to see if the option was specified.. 14612772Speter */ 14712772Speter value = NULL; 14812772Speter for (op = opt; op; op = op->op_next) { 14912772Speter if (eq(name, op->op_name)) { 15037577Sbde oldvalue = value; 15112772Speter value = op->op_value; 15237577Sbde if (value == NULL) 15312772Speter value = ns("1"); 15437577Sbde if (oldvalue != NULL && !eq(value, oldvalue)) 15537577Sbde printf( 15637577Sbde "%s:%d: option \"%s\" redefined from %s to %s\n", 15737577Sbde PREFIX, op->op_line, op->op_name, oldvalue, 15837577Sbde value); 15912772Speter op->op_ownfile++; 16012772Speter } 16112772Speter } 16212772Speter 16312772Speter inf = fopen(file, "r"); 16412772Speter if (inf == 0) { 16512772Speter outf = fopen(file, "w"); 16629451Scharnier if (outf == 0) 16729451Scharnier err(1, "%s", file); 16812772Speter 16912772Speter /* was the option in the config file? */ 17012772Speter if (value) { 17112772Speter fprintf(outf, "#define %s %s\n", name, value); 17212772Speter } /* else empty file */ 17312772Speter 17412772Speter (void) fclose(outf); 17512772Speter return; 17612772Speter } 17755659Sbde basefile = ""; 17855659Sbde for (ol = otab; ol != 0; ol = ol->o_next) 17955659Sbde if (eq(name, ol->o_name)) { 18055659Sbde basefile = ol->o_file; 18155659Sbde break; 18255659Sbde } 18312772Speter oldvalue = NULL; 18412772Speter op_head = NULL; 18512772Speter seen = 0; 18648401Speter tidy = 0; 18712772Speter for (;;) { 18812772Speter char *cp; 18912772Speter char *invalue; 19012772Speter 19112772Speter /* get the #define */ 19212772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 19312772Speter break; 19412772Speter /* get the option name */ 19512772Speter if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 19612772Speter break; 19712772Speter inw = ns(inw); 19848401Speter /* get the option value */ 19948401Speter if ((cp = get_word(inf)) == 0 || cp == (char *)EOF) 20012772Speter break; 20112772Speter /* option value */ 20212772Speter invalue = ns(cp); /* malloced */ 20312772Speter if (eq(inw, name)) { 20412772Speter oldvalue = invalue; 20512772Speter invalue = value; 20612772Speter seen++; 20712772Speter } 20848401Speter for (ol = otab; ol != 0; ol = ol->o_next) 20948401Speter if (eq(inw, ol->o_name)) 21048401Speter break; 21155603Sbde if (!eq(inw, name) && !ol) { 21248401Speter printf("WARNING: unknown option `%s' removed from %s\n", 21348401Speter inw, file); 21448401Speter tidy++; 21555659Sbde } else if (ol != NULL && !eq(basefile, ol->o_file)) { 21655659Sbde printf("WARNING: option `%s' moved from %s to %s\n", 21755659Sbde inw, basefile, ol->o_file); 21855659Sbde tidy++; 21948401Speter } else { 22048401Speter op = (struct opt *) malloc(sizeof *op); 22148401Speter bzero(op, sizeof(*op)); 22248401Speter op->op_name = inw; 22348401Speter op->op_value = invalue; 22448401Speter op->op_next = op_head; 22548401Speter op_head = op; 22648401Speter } 22712772Speter 22812772Speter /* EOL? */ 22912772Speter cp = get_word(inf); 23012772Speter if (cp == (char *)EOF) 23112772Speter break; 23212772Speter } 23312772Speter (void) fclose(inf); 23448401Speter if (!tidy && ((value == NULL && oldvalue == NULL) || 23548401Speter (value && oldvalue && eq(value, oldvalue)))) { 23612772Speter for (op = op_head; op != NULL; op = topp) { 23712772Speter topp = op->op_next; 23812772Speter free(op->op_name); 23912772Speter free(op->op_value); 24012772Speter free(op); 24112772Speter } 24212772Speter return; 24312772Speter } 24412772Speter 24512772Speter if (value && !seen) { 24612772Speter /* New option appears */ 24712772Speter op = (struct opt *) malloc(sizeof *op); 24812772Speter bzero(op, sizeof(*op)); 24912772Speter op->op_name = ns(name); 25012772Speter op->op_value = value ? ns(value) : NULL; 25112772Speter op->op_next = op_head; 25212772Speter op_head = op; 25312772Speter } 25412772Speter 25512772Speter outf = fopen(file, "w"); 25629451Scharnier if (outf == 0) 25729451Scharnier err(1, "%s", file); 25812772Speter for (op = op_head; op != NULL; op = topp) { 25912772Speter /* was the option in the config file? */ 26012772Speter if (op->op_value) { 26112772Speter fprintf(outf, "#define %s %s\n", 26212772Speter op->op_name, op->op_value); 26312772Speter } 26412772Speter topp = op->op_next; 26512772Speter free(op->op_name); 26612772Speter free(op->op_value); 26712772Speter free(op); 26812772Speter } 26912772Speter (void) fclose(outf); 27012772Speter} 27112772Speter 27212772Speter/* 27312772Speter * Find the filename to store the option spec into. 27412772Speter */ 27545744Speterstatic char * 27661640Spetertooption(char *name) 27712772Speter{ 27869004Simp static char hbuf[MAXPATHLEN]; 27969004Simp char nbuf[MAXPATHLEN]; 28012772Speter struct opt_list *po; 28112772Speter 28212772Speter /* "cannot happen"? the otab list should be complete.. */ 28369004Simp (void) strlcpy(nbuf, "options.h", sizeof(nbuf)); 28412772Speter 28512772Speter for (po = otab ; po != 0; po = po->o_next) { 28612772Speter if (eq(po->o_name, name)) { 28769004Simp strlcpy(nbuf, po->o_file, sizeof(nbuf)); 28812772Speter break; 28912772Speter } 29012772Speter } 29112772Speter 29269004Simp (void) strlcpy(hbuf, path(nbuf), sizeof(hbuf)); 29312772Speter return (hbuf); 29412772Speter} 29512772Speter 29612772Speter/* 29712772Speter * read the options and options.<machine> files 29812772Speter */ 29945744Speterstatic void 30061640Speterread_options(void) 30112772Speter{ 30212772Speter FILE *fp; 30369004Simp char fname[MAXPATHLEN]; 30412772Speter char *wd, *this, *val; 30512772Speter struct opt_list *po; 30612772Speter int first = 1; 30769004Simp char genopt[MAXPATHLEN]; 30812772Speter 30912772Speter otab = 0; 31055614Speter if (ident == NULL) { 31155614Speter printf("no ident line specified\n"); 31255614Speter exit(1); 31355614Speter } 31469004Simp (void) snprintf(fname, sizeof(fname), "../../conf/options"); 31512772Speteropenit: 31612772Speter fp = fopen(fname, "r"); 31712772Speter if (fp == 0) { 31812772Speter return; 31912772Speter } 32012772Speternext: 32112772Speter wd = get_word(fp); 32212772Speter if (wd == (char *)EOF) { 32312772Speter (void) fclose(fp); 32412772Speter if (first == 1) { 32555614Speter first++; 32655614Speter (void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename); 32755614Speter fp = fopen(fname, "r"); 32855614Speter if (fp != 0) 32955614Speter goto next; 33020457Sjoerg (void) snprintf(fname, sizeof fname, "options.%s", machinename); 33112772Speter goto openit; 33212772Speter } 33312772Speter if (first == 2) { 33455614Speter first++; 33545744Speter (void) snprintf(fname, sizeof fname, "options.%s", raisestr(ident)); 33612772Speter fp = fopen(fname, "r"); 33712772Speter if (fp != 0) 33812772Speter goto next; 33912772Speter } 34012772Speter return; 34112772Speter } 34212772Speter if (wd == 0) 34312772Speter goto next; 34452098Speter if (wd[0] == '#') 34512772Speter { 34652098Speter while (((wd = get_word(fp)) != (char *)EOF) && wd) 34712772Speter ; 34812772Speter goto next; 34912772Speter } 35012772Speter this = ns(wd); 35112772Speter val = get_word(fp); 35212772Speter if (val == (char *)EOF) 35312772Speter return; 35412772Speter if (val == 0) { 35512772Speter char *s = ns(this); 35669004Simp (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s)); 35712772Speter val = genopt; 35812772Speter free(s); 35912772Speter } 36012772Speter val = ns(val); 36112772Speter 36212772Speter for (po = otab ; po != 0; po = po->o_next) { 36312772Speter if (eq(po->o_name, this)) { 36412772Speter printf("%s: Duplicate option %s.\n", 36512772Speter fname, this); 36612772Speter exit(1); 36712772Speter } 36812772Speter } 36912772Speter 37012772Speter po = (struct opt_list *) malloc(sizeof *po); 37112772Speter bzero(po, sizeof(*po)); 37212772Speter po->o_name = this; 37312772Speter po->o_file = val; 37412772Speter po->o_next = otab; 37512772Speter otab = po; 37612772Speter 37712772Speter goto next; 37812772Speter} 37912772Speter 38020458Sjoergstatic char * 38161640Speterlower(char *str) 38212772Speter{ 38361640Speter char *cp = str; 38412772Speter 38512772Speter while (*str) { 38612772Speter if (isupper(*str)) 38712772Speter *str = tolower(*str); 38812772Speter str++; 38912772Speter } 39012772Speter return (cp); 39112772Speter} 392