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