mkoptions.c revision 125935
1336821Sdim/* 2336821Sdim * Copyright (c) 1995 Peter Wemm 3353358Sdim * Copyright (c) 1980, 1993 4353358Sdim * The Regents of the University of California. All rights reserved. 5353358Sdim * 6336821Sdim * Redistribution and use in source and binary forms, with or without 7336821Sdim * modification, are permitted provided that the following conditions 8336821Sdim * are met: 9336821Sdim * 1. Redistributions of source code must retain the above copyright 10336821Sdim * notice, this list of conditions and the following disclaimer. 11336821Sdim * 2. Redistributions in binary form must reproduce the above copyright 12336821Sdim * notice, this list of conditions and the following disclaimer in the 13336821Sdim * documentation and/or other materials provided with the distribution. 14336821Sdim * 3. All advertising materials mentioning features or use of this software 15336821Sdim * must display the following acknowledgement: 16353358Sdim * This product includes software developed by the University of 17336821Sdim * California, Berkeley and its contributors. 18336821Sdim * 4. Neither the name of the University nor the names of its contributors 19353358Sdim * may be used to endorse or promote products derived from this software 20336821Sdim * without specific prior written permission. 21353358Sdim * 22353358Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23336821Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24336821Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25336821Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26336821Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27353358Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28353358Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29353358Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30336821Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31336821Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32353358Sdim * SUCH DAMAGE. 33353358Sdim */ 34353358Sdim 35336821Sdim#ifndef lint 36336821Sdim#if 0 37336821Sdimstatic char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; 38353358Sdim#endif 39336821Sdimstatic const char rcsid[] = 40336821Sdim "$FreeBSD: head/usr.sbin/config/mkoptions.c 125935 2004-02-17 09:59:45Z des $"; 41336821Sdim#endif /* not lint */ 42353358Sdim 43353358Sdim/* 44336821Sdim * Make all the .h files for the optional entries 45336821Sdim */ 46336821Sdim 47353358Sdim#include <ctype.h> 48336821Sdim#include <err.h> 49336821Sdim#include <stdio.h> 50336821Sdim#include <string.h> 51353358Sdim#include <sys/param.h> 52353358Sdim#include "config.h" 53336821Sdim#include "y.tab.h" 54336821Sdim 55336821Sdimstatic struct users { 56336821Sdim int u_default; 57336821Sdim int u_min; 58336821Sdim int u_max; 59336821Sdim} users = { 8, 2, 512 }; 60336821Sdim 61353358Sdimstatic char *lower(char *); 62336821Sdimstatic void read_options(void); 63336821Sdimstatic void do_option(char *); 64336821Sdimstatic char *tooption(char *); 65353358Sdim 66353358Sdimvoid 67336821Sdimoptions(void) 68353358Sdim{ 69353358Sdim char buf[40]; 70353358Sdim struct cputype *cp; 71353358Sdim struct opt_list *ol; 72336821Sdim struct opt *op; 73353358Sdim 74336821Sdim /* Fake the cpu types as options. */ 75353358Sdim SLIST_FOREACH(cp, &cputype, cpu_next) { 76353358Sdim op = (struct opt *)malloc(sizeof(*op)); 77353358Sdim memset(op, 0, sizeof(*op)); 78336821Sdim op->op_name = ns(cp->cpu_name); 79336821Sdim SLIST_INSERT_HEAD(&opt, op, op_next); 80 } 81 82 if (maxusers == 0) { 83 /* printf("maxusers not specified; will auto-size\n"); */ 84 } else if (maxusers < users.u_min) { 85 printf("minimum of %d maxusers assumed\n", users.u_min); 86 maxusers = users.u_min; 87 } else if (maxusers > users.u_max) 88 printf("warning: maxusers > %d (%d)\n", users.u_max, maxusers); 89 90 /* Fake MAXUSERS as an option. */ 91 op = (struct opt *)malloc(sizeof(*op)); 92 memset(op, 0, sizeof(*op)); 93 op->op_name = ns("MAXUSERS"); 94 snprintf(buf, sizeof(buf), "%d", maxusers); 95 op->op_value = ns(buf); 96 SLIST_INSERT_HEAD(&opt, op, op_next); 97 98 read_options(); 99 SLIST_FOREACH(ol, &otab, o_next) 100 do_option(ol->o_name); 101 SLIST_FOREACH(op, &opt, op_next) { 102 if (!op->op_ownfile && strncmp(op->op_name, "DEV_", 4)) { 103 printf("%s: unknown option \"%s\"\n", 104 PREFIX, op->op_name); 105 exit(1); 106 } 107 } 108} 109 110/* 111 * Generate an <options>.h file 112 */ 113 114static void 115do_option(char *name) 116{ 117 char *file, *inw; 118 const char *basefile; 119 struct opt_list *ol; 120 struct opt *op; 121 struct opt_head op_head; 122 FILE *inf, *outf; 123 char *value; 124 char *oldvalue; 125 int seen; 126 int tidy; 127 128 file = tooption(name); 129 130 /* 131 * Check to see if the option was specified.. 132 */ 133 value = NULL; 134 SLIST_FOREACH(op, &opt, op_next) { 135 if (eq(name, op->op_name)) { 136 oldvalue = value; 137 value = op->op_value; 138 if (value == NULL) 139 value = ns("1"); 140 if (oldvalue != NULL && !eq(value, oldvalue)) 141 printf( 142 "%s: option \"%s\" redefined from %s to %s\n", 143 PREFIX, op->op_name, oldvalue, 144 value); 145 op->op_ownfile++; 146 } 147 } 148 149 remember(file); 150 inf = fopen(file, "r"); 151 if (inf == 0) { 152 outf = fopen(file, "w"); 153 if (outf == 0) 154 err(1, "%s", file); 155 156 /* was the option in the config file? */ 157 if (value) { 158 fprintf(outf, "#define %s %s\n", name, value); 159 } /* else empty file */ 160 161 (void) fclose(outf); 162 return; 163 } 164 basefile = ""; 165 SLIST_FOREACH(ol, &otab, o_next) 166 if (eq(name, ol->o_name)) { 167 basefile = ol->o_file; 168 break; 169 } 170 oldvalue = NULL; 171 SLIST_INIT(&op_head); 172 seen = 0; 173 tidy = 0; 174 for (;;) { 175 char *cp; 176 char *invalue; 177 178 /* get the #define */ 179 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 180 break; 181 /* get the option name */ 182 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 183 break; 184 inw = ns(inw); 185 /* get the option value */ 186 if ((cp = get_word(inf)) == 0 || cp == (char *)EOF) 187 break; 188 /* option value */ 189 invalue = ns(cp); /* malloced */ 190 if (eq(inw, name)) { 191 oldvalue = invalue; 192 invalue = value; 193 seen++; 194 } 195 SLIST_FOREACH(ol, &otab, o_next) 196 if (eq(inw, ol->o_name)) 197 break; 198 if (!eq(inw, name) && !ol) { 199 printf("WARNING: unknown option `%s' removed from %s\n", 200 inw, file); 201 tidy++; 202 } else if (ol != NULL && !eq(basefile, ol->o_file)) { 203 printf("WARNING: option `%s' moved from %s to %s\n", 204 inw, basefile, ol->o_file); 205 tidy++; 206 } else { 207 op = (struct opt *) malloc(sizeof *op); 208 bzero(op, sizeof(*op)); 209 op->op_name = inw; 210 op->op_value = invalue; 211 SLIST_INSERT_HEAD(&op_head, op, op_next); 212 } 213 214 /* EOL? */ 215 cp = get_word(inf); 216 if (cp == (char *)EOF) 217 break; 218 } 219 (void) fclose(inf); 220 if (!tidy && ((value == NULL && oldvalue == NULL) || 221 (value && oldvalue && eq(value, oldvalue)))) { 222 while (!SLIST_EMPTY(&op_head)) { 223 op = SLIST_FIRST(&op_head); 224 SLIST_REMOVE_HEAD(&op_head, op_next); 225 free(op->op_name); 226 free(op->op_value); 227 free(op); 228 } 229 return; 230 } 231 232 if (value && !seen) { 233 /* New option appears */ 234 op = (struct opt *) malloc(sizeof *op); 235 bzero(op, sizeof(*op)); 236 op->op_name = ns(name); 237 op->op_value = value ? ns(value) : NULL; 238 SLIST_INSERT_HEAD(&op_head, op, op_next); 239 } 240 241 outf = fopen(file, "w"); 242 if (outf == 0) 243 err(1, "%s", file); 244 while (!SLIST_EMPTY(&op_head)) { 245 op = SLIST_FIRST(&op_head); 246 /* was the option in the config file? */ 247 if (op->op_value) { 248 fprintf(outf, "#define %s %s\n", 249 op->op_name, op->op_value); 250 } 251 SLIST_REMOVE_HEAD(&op_head, op_next); 252 free(op->op_name); 253 free(op->op_value); 254 free(op); 255 } 256 (void) fclose(outf); 257} 258 259/* 260 * Find the filename to store the option spec into. 261 */ 262static char * 263tooption(char *name) 264{ 265 static char hbuf[MAXPATHLEN]; 266 char nbuf[MAXPATHLEN]; 267 struct opt_list *po; 268 269 /* "cannot happen"? the otab list should be complete.. */ 270 (void) strlcpy(nbuf, "options.h", sizeof(nbuf)); 271 272 SLIST_FOREACH(po, &otab, o_next) { 273 if (eq(po->o_name, name)) { 274 strlcpy(nbuf, po->o_file, sizeof(nbuf)); 275 break; 276 } 277 } 278 279 (void) strlcpy(hbuf, path(nbuf), sizeof(hbuf)); 280 return (hbuf); 281} 282 283/* 284 * read the options and options.<machine> files 285 */ 286static void 287read_options(void) 288{ 289 FILE *fp; 290 char fname[MAXPATHLEN]; 291 char *wd, *this, *val; 292 struct opt_list *po; 293 int first = 1; 294 char genopt[MAXPATHLEN]; 295 296 SLIST_INIT(&otab); 297 if (ident == NULL) { 298 printf("no ident line specified\n"); 299 exit(1); 300 } 301 (void) snprintf(fname, sizeof(fname), "../../conf/options"); 302openit: 303 fp = fopen(fname, "r"); 304 if (fp == 0) { 305 return; 306 } 307next: 308 wd = get_word(fp); 309 if (wd == (char *)EOF) { 310 (void) fclose(fp); 311 if (first == 1) { 312 first++; 313 (void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename); 314 fp = fopen(fname, "r"); 315 if (fp != 0) 316 goto next; 317 (void) snprintf(fname, sizeof fname, "options.%s", machinename); 318 goto openit; 319 } 320 return; 321 } 322 if (wd == 0) 323 goto next; 324 if (wd[0] == '#') 325 { 326 while (((wd = get_word(fp)) != (char *)EOF) && wd) 327 ; 328 goto next; 329 } 330 this = ns(wd); 331 val = get_word(fp); 332 if (val == (char *)EOF) 333 return; 334 if (val == 0) { 335 char *s = ns(this); 336 (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s)); 337 val = genopt; 338 free(s); 339 } 340 val = ns(val); 341 342 SLIST_FOREACH(po, &otab, o_next) { 343 if (eq(po->o_name, this)) { 344 printf("%s: Duplicate option %s.\n", 345 fname, this); 346 exit(1); 347 } 348 } 349 350 po = (struct opt_list *) malloc(sizeof *po); 351 bzero(po, sizeof(*po)); 352 po->o_name = this; 353 po->o_file = val; 354 SLIST_INSERT_HEAD(&otab, po, o_next); 355 356 goto next; 357} 358 359static char * 360lower(char *str) 361{ 362 char *cp = str; 363 364 while (*str) { 365 if (isupper(*str)) 366 *str = tolower(*str); 367 str++; 368 } 369 return (cp); 370} 371