]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - usr.sbin/config/mkoptions.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / usr.sbin / config / mkoptions.c
1 /*
2  * Copyright (c) 1995  Peter Wemm
3  * Copyright (c) 1980, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 4. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 #ifndef lint
32 #if 0
33 static char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93";
34 #endif
35 static const char rcsid[] =
36   "$FreeBSD$";
37 #endif /* not lint */
38
39 /*
40  * Make all the .h files for the optional entries
41  */
42
43 #include <ctype.h>
44 #include <err.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <sys/param.h>
48 #include "config.h"
49 #include "y.tab.h"
50
51 static  struct users {
52         int     u_default;
53         int     u_min;
54         int     u_max;
55 } users = { 8, 2, 512 };
56
57 static char *lower(char *);
58 static void read_options(void);
59 static void do_option(char *);
60 static char *tooption(char *);
61
62 void
63 options(void)
64 {
65         char buf[40];
66         struct cputype *cp;
67         struct opt_list *ol;
68         struct opt *op;
69
70         /* Fake the cpu types as options. */
71         SLIST_FOREACH(cp, &cputype, cpu_next) {
72                 op = (struct opt *)calloc(1, sizeof(*op));
73                 op->op_name = ns(cp->cpu_name);
74                 SLIST_INSERT_HEAD(&opt, op, op_next);
75         }       
76
77         if (maxusers == 0) {
78                 /* printf("maxusers not specified; will auto-size\n"); */
79         } else if (maxusers < users.u_min) {
80                 printf("minimum of %d maxusers assumed\n", users.u_min);
81                 maxusers = users.u_min;
82         } else if (maxusers > users.u_max)
83                 printf("warning: maxusers > %d (%d)\n", users.u_max, maxusers);
84
85         /* Fake MAXUSERS as an option. */
86         op = (struct opt *)calloc(1, sizeof(*op));
87         op->op_name = ns("MAXUSERS");
88         snprintf(buf, sizeof(buf), "%d", maxusers);
89         op->op_value = ns(buf);
90         SLIST_INSERT_HEAD(&opt, op, op_next);
91
92         read_options();
93         SLIST_FOREACH(ol, &otab, o_next)
94                 do_option(ol->o_name);
95         SLIST_FOREACH(op, &opt, op_next) {
96                 if (!op->op_ownfile && strncmp(op->op_name, "DEV_", 4)) {
97                         printf("%s: unknown option \"%s\"\n",
98                                PREFIX, op->op_name);
99                         exit(1);
100                 }
101         }
102 }
103
104 /*
105  * Generate an <options>.h file
106  */
107
108 static void
109 do_option(char *name)
110 {
111         char *file, *inw;
112         const char *basefile;
113         struct opt_list *ol;
114         struct opt *op;
115         struct opt_head op_head;
116         FILE *inf, *outf;
117         char *value;
118         char *oldvalue;
119         int seen;
120         int tidy;
121
122         file = tooption(name);
123
124         /*
125          * Check to see if the option was specified..
126          */
127         value = NULL;
128         SLIST_FOREACH(op, &opt, op_next) {
129                 if (eq(name, op->op_name)) {
130                         oldvalue = value;
131                         value = op->op_value;
132                         if (value == NULL)
133                                 value = ns("1");
134                         if (oldvalue != NULL && !eq(value, oldvalue))
135                                 printf(
136                             "%s: option \"%s\" redefined from %s to %s\n",
137                                    PREFIX, op->op_name, oldvalue,
138                                    value);
139                         op->op_ownfile++;
140                 }
141         }
142
143         remember(file);
144         inf = fopen(file, "r");
145         if (inf == 0) {
146                 outf = fopen(file, "w");
147                 if (outf == 0)
148                         err(1, "%s", file);
149
150                 /* was the option in the config file? */
151                 if (value) {
152                         fprintf(outf, "#define %s %s\n", name, value);
153                 } /* else empty file */
154
155                 (void) fclose(outf);
156                 return;
157         }
158         basefile = "";
159         SLIST_FOREACH(ol, &otab, o_next)
160                 if (eq(name, ol->o_name)) {
161                         basefile = ol->o_file;
162                         break;
163                 }
164         oldvalue = NULL;
165         SLIST_INIT(&op_head);
166         seen = 0;
167         tidy = 0;
168         for (;;) {
169                 char *cp;
170                 char *invalue;
171
172                 /* get the #define */
173                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
174                         break;
175                 /* get the option name */
176                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
177                         break;
178                 inw = ns(inw);
179                 /* get the option value */
180                 if ((cp = get_word(inf)) == 0 || cp == (char *)EOF)
181                         break;
182                 /* option value */
183                 invalue = ns(cp); /* malloced */
184                 if (eq(inw, name)) {
185                         oldvalue = invalue;
186                         invalue = value;
187                         seen++;
188                 }
189                 SLIST_FOREACH(ol, &otab, o_next)
190                         if (eq(inw, ol->o_name))
191                                 break;
192                 if (!eq(inw, name) && !ol) {
193                         printf("WARNING: unknown option `%s' removed from %s\n",
194                                 inw, file);
195                         tidy++;
196                 } else if (ol != NULL && !eq(basefile, ol->o_file)) {
197                         printf("WARNING: option `%s' moved from %s to %s\n",
198                                 inw, basefile, ol->o_file);
199                         tidy++;
200                 } else {
201                         op = (struct opt *) calloc(1, sizeof *op);
202                         op->op_name = inw;
203                         op->op_value = invalue;
204                         SLIST_INSERT_HEAD(&op_head, op, op_next);
205                 }
206
207                 /* EOL? */
208                 cp = get_word(inf);
209                 if (cp == (char *)EOF)
210                         break;
211         }
212         (void) fclose(inf);
213         if (!tidy && ((value == NULL && oldvalue == NULL) ||
214             (value && oldvalue && eq(value, oldvalue)))) {      
215                 while (!SLIST_EMPTY(&op_head)) {
216                         op = SLIST_FIRST(&op_head);
217                         SLIST_REMOVE_HEAD(&op_head, op_next);
218                         free(op->op_name);
219                         free(op->op_value);
220                         free(op);
221                 }
222                 return;
223         }
224
225         if (value && !seen) {
226                 /* New option appears */
227                 op = (struct opt *) calloc(1, sizeof *op);
228                 op->op_name = ns(name);
229                 op->op_value = value ? ns(value) : NULL;
230                 SLIST_INSERT_HEAD(&op_head, op, op_next);
231         }
232
233         outf = fopen(file, "w");
234         if (outf == 0)
235                 err(1, "%s", file);
236         while (!SLIST_EMPTY(&op_head)) {
237                 op = SLIST_FIRST(&op_head);
238                 /* was the option in the config file? */
239                 if (op->op_value) {
240                         fprintf(outf, "#define %s %s\n",
241                                 op->op_name, op->op_value);
242                 }
243                 SLIST_REMOVE_HEAD(&op_head, op_next);
244                 free(op->op_name);
245                 free(op->op_value);
246                 free(op);
247         }
248         (void) fclose(outf);
249 }
250
251 /*
252  * Find the filename to store the option spec into.
253  */
254 static char *
255 tooption(char *name)
256 {
257         static char hbuf[MAXPATHLEN];
258         char nbuf[MAXPATHLEN];
259         struct opt_list *po;
260
261         /* "cannot happen"?  the otab list should be complete.. */
262         (void) strlcpy(nbuf, "options.h", sizeof(nbuf));
263
264         SLIST_FOREACH(po, &otab, o_next) {
265                 if (eq(po->o_name, name)) {
266                         strlcpy(nbuf, po->o_file, sizeof(nbuf));
267                         break;
268                 }
269         }
270
271         (void) strlcpy(hbuf, path(nbuf), sizeof(hbuf));
272         return (hbuf);
273 }
274
275 /*
276  * read the options and options.<machine> files
277  */
278 static void
279 read_options(void)
280 {
281         FILE *fp;
282         char fname[MAXPATHLEN];
283         char *wd, *this, *val;
284         struct opt_list *po;
285         int first = 1;
286         char genopt[MAXPATHLEN];
287
288         SLIST_INIT(&otab);
289         (void) snprintf(fname, sizeof(fname), "../../conf/options");
290 openit:
291         fp = fopen(fname, "r");
292         if (fp == 0) {
293                 return;
294         }
295 next:
296         wd = get_word(fp);
297         if (wd == (char *)EOF) {
298                 (void) fclose(fp);
299                 if (first == 1) {
300                         first++;
301                         (void) snprintf(fname, sizeof fname, "../../conf/options.%s", machinename);
302                         fp = fopen(fname, "r");
303                         if (fp != 0)
304                                 goto next;
305                         (void) snprintf(fname, sizeof fname, "options.%s", machinename);
306                         goto openit;
307                 }
308                 return;
309         }
310         if (wd == 0)
311                 goto next;
312         if (wd[0] == '#')
313         {
314                 while (((wd = get_word(fp)) != (char *)EOF) && wd)
315                 ;
316                 goto next;
317         }
318         this = ns(wd);
319         val = get_word(fp);
320         if (val == (char *)EOF)
321                 return;
322         if (val == 0) {
323                 char *s = ns(this);
324                 (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s));
325                 val = genopt;
326                 free(s);
327         }
328         val = ns(val);
329
330         SLIST_FOREACH(po, &otab, o_next) {
331                 if (eq(po->o_name, this)) {
332                         printf("%s: Duplicate option %s.\n",
333                                fname, this);
334                         exit(1);
335                 }
336         }
337         
338         po = (struct opt_list *) calloc(1, sizeof *po);
339         po->o_name = this;
340         po->o_file = val;
341         SLIST_INSERT_HEAD(&otab, po, o_next);
342
343         goto next;
344 }
345
346 static char *
347 lower(char *str)
348 {
349         char *cp = str;
350
351         while (*str) {
352                 if (isupper(*str))
353                         *str = tolower(*str);
354                 str++;
355         }
356         return (cp);
357 }