gen.c revision 1.5 1 1.4 christos /* $NetBSD: gen.c,v 1.5 2019/09/05 19:32:58 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
7 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
8 1.1 christos * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 1.1 christos *
10 1.1 christos * See the COPYRIGHT file distributed with this work for additional
11 1.1 christos * information regarding copyright ownership.
12 1.1 christos */
13 1.1 christos
14 1.1 christos /*! \file */
15 1.1 christos
16 1.1 christos #ifdef WIN32
17 1.1 christos /*
18 1.1 christos * Silence compiler warnings about using strcpy and friends.
19 1.1 christos */
20 1.1 christos #define _CRT_SECURE_NO_DEPRECATE 1
21 1.1 christos /*
22 1.1 christos * We use snprintf which was defined late in Windows even it is in C99.
23 1.1 christos */
24 1.1 christos #if _MSC_VER < 1900
25 1.1 christos #define snprintf _snprintf
26 1.1 christos #endif
27 1.1 christos #endif
28 1.1 christos
29 1.1 christos #include <sys/types.h>
30 1.1 christos
31 1.1 christos #include <ctype.h>
32 1.4 christos #include <limits.h>
33 1.4 christos #include <stdint.h>
34 1.1 christos #include <stdlib.h>
35 1.1 christos #include <stdio.h>
36 1.1 christos #include <stdlib.h>
37 1.1 christos #include <string.h>
38 1.1 christos #include <time.h>
39 1.5 christos #include <errno.h>
40 1.5 christos #include <limits.h>
41 1.1 christos
42 1.1 christos #ifdef WIN32
43 1.1 christos #include "gen-win32.h"
44 1.1 christos #else
45 1.1 christos #include "gen-unix.h"
46 1.1 christos #endif
47 1.1 christos
48 1.5 christos #ifndef ULLONG_MAX
49 1.5 christos #define ULLONG_MAX (~0ULL)
50 1.5 christos #endif
51 1.5 christos
52 1.1 christos #define INSIST(cond) \
53 1.1 christos if (!(cond)) { \
54 1.1 christos fprintf(stderr, "%s:%d: INSIST(%s)\n", \
55 1.1 christos __FILE__, __LINE__, #cond); \
56 1.1 christos abort(); \
57 1.1 christos }
58 1.1 christos
59 1.1 christos #define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
60 1.1 christos #define FROMTEXTCLASS "rdclass"
61 1.1 christos #define FROMTEXTTYPE "type"
62 1.1 christos #define FROMTEXTDEF "result = DNS_R_UNKNOWN"
63 1.1 christos
64 1.1 christos #define TOTEXTARGS "rdata, tctx, target"
65 1.1 christos #define TOTEXTCLASS "rdata->rdclass"
66 1.1 christos #define TOTEXTTYPE "rdata->type"
67 1.3 christos #define TOTEXTDEF "use_default = true"
68 1.1 christos
69 1.1 christos #define FROMWIREARGS "rdclass, type, source, dctx, options, target"
70 1.1 christos #define FROMWIRECLASS "rdclass"
71 1.1 christos #define FROMWIRETYPE "type"
72 1.3 christos #define FROMWIREDEF "use_default = true"
73 1.1 christos
74 1.1 christos #define TOWIREARGS "rdata, cctx, target"
75 1.1 christos #define TOWIRECLASS "rdata->rdclass"
76 1.1 christos #define TOWIRETYPE "rdata->type"
77 1.3 christos #define TOWIREDEF "use_default = true"
78 1.1 christos
79 1.1 christos #define FROMSTRUCTARGS "rdclass, type, source, target"
80 1.1 christos #define FROMSTRUCTCLASS "rdclass"
81 1.1 christos #define FROMSTRUCTTYPE "type"
82 1.3 christos #define FROMSTRUCTDEF "use_default = true"
83 1.1 christos
84 1.1 christos #define TOSTRUCTARGS "rdata, target, mctx"
85 1.1 christos #define TOSTRUCTCLASS "rdata->rdclass"
86 1.1 christos #define TOSTRUCTTYPE "rdata->type"
87 1.3 christos #define TOSTRUCTDEF "use_default = true"
88 1.1 christos
89 1.1 christos #define FREESTRUCTARGS "source"
90 1.1 christos #define FREESTRUCTCLASS "common->rdclass"
91 1.1 christos #define FREESTRUCTTYPE "common->rdtype"
92 1.1 christos #define FREESTRUCTDEF NULL
93 1.1 christos
94 1.1 christos #define COMPAREARGS "rdata1, rdata2"
95 1.1 christos #define COMPARECLASS "rdata1->rdclass"
96 1.1 christos #define COMPARETYPE "rdata1->type"
97 1.3 christos #define COMPAREDEF "use_default = true"
98 1.1 christos
99 1.1 christos #define ADDITIONALDATAARGS "rdata, add, arg"
100 1.1 christos #define ADDITIONALDATACLASS "rdata->rdclass"
101 1.1 christos #define ADDITIONALDATATYPE "rdata->type"
102 1.3 christos #define ADDITIONALDATADEF "use_default = true"
103 1.1 christos
104 1.1 christos #define DIGESTARGS "rdata, digest, arg"
105 1.1 christos #define DIGESTCLASS "rdata->rdclass"
106 1.1 christos #define DIGESTTYPE "rdata->type"
107 1.3 christos #define DIGESTDEF "use_default = true"
108 1.1 christos
109 1.1 christos #define CHECKOWNERARGS "name, rdclass, type, wildcard"
110 1.1 christos #define CHECKOWNERCLASS "rdclass"
111 1.1 christos #define CHECKOWNERTYPE "type"
112 1.3 christos #define CHECKOWNERDEF "result = true"
113 1.1 christos
114 1.1 christos #define CHECKNAMESARGS "rdata, owner, bad"
115 1.1 christos #define CHECKNAMESCLASS "rdata->rdclass"
116 1.1 christos #define CHECKNAMESTYPE "rdata->type"
117 1.3 christos #define CHECKNAMESDEF "result = true"
118 1.1 christos
119 1.1 christos static const char copyright[] =
120 1.1 christos "/*\n"
121 1.1 christos " * Copyright (C) 1998%s Internet Systems Consortium, Inc. (\"ISC\")\n"
122 1.1 christos " *\n"
123 1.1 christos " * This Source Code Form is subject to the terms of the Mozilla Public\n"
124 1.1 christos " * License, v. 2.0. If a copy of the MPL was not distributed with this\n"
125 1.1 christos " * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n"
126 1.1 christos " */\n"
127 1.1 christos "\n"
128 1.1 christos "/***************\n"
129 1.1 christos " ***************\n"
130 1.1 christos " *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n"
131 1.1 christos " *************** DO NOT EDIT!\n"
132 1.1 christos " ***************\n"
133 1.1 christos " ***************/\n"
134 1.1 christos "\n"
135 1.1 christos "/*! \\file */\n"
136 1.1 christos "\n";
137 1.1 christos
138 1.1 christos #define STR_EXPAND(tok) #tok
139 1.1 christos #define STR(tok) STR_EXPAND(tok)
140 1.1 christos
141 1.1 christos #define TYPENAMES 256
142 1.1 christos #define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */
143 1.1 christos #define TYPECLASSBUF (TYPECLASSLEN + 1)
144 1.1 christos #define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
145 1.1 christos #define ATTRIBUTESIZE 256
146 1.4 christos
147 1.4 christos #ifndef PATH_MAX
148 1.4 christos #define PATH_MAX 1024
149 1.4 christos #endif
150 1.1 christos
151 1.1 christos static struct cc {
152 1.1 christos struct cc *next;
153 1.1 christos int rdclass;
154 1.3 christos char classbuf[TYPECLASSBUF];
155 1.1 christos } *classes;
156 1.1 christos
157 1.1 christos static struct tt {
158 1.1 christos struct tt *next;
159 1.4 christos uint16_t rdclass;
160 1.4 christos uint16_t type;
161 1.3 christos char classbuf[TYPECLASSBUF];
162 1.3 christos char typebuf[TYPECLASSBUF];
163 1.4 christos char dirbuf[PATH_MAX-30];
164 1.1 christos } *types;
165 1.1 christos
166 1.1 christos static struct ttnam {
167 1.3 christos char typebuf[TYPECLASSBUF];
168 1.1 christos char macroname[TYPECLASSBUF];
169 1.1 christos char attr[ATTRIBUTESIZE];
170 1.1 christos unsigned int sorted;
171 1.4 christos uint16_t type;
172 1.1 christos } typenames[TYPENAMES];
173 1.1 christos
174 1.1 christos static int maxtype = -1;
175 1.1 christos
176 1.1 christos static char *
177 1.1 christos upper(char *);
178 1.1 christos static char *
179 1.1 christos funname(const char *, char *);
180 1.1 christos static void
181 1.1 christos doswitch(const char *, const char *, const char *, const char *,
182 1.1 christos const char *, const char *);
183 1.1 christos static void
184 1.1 christos add(int, const char *, int, const char *, const char *);
185 1.1 christos static void
186 1.1 christos sd(int, const char *, const char *, char);
187 1.1 christos static void
188 1.1 christos insert_into_typenames(int, const char *, const char *);
189 1.1 christos
190 1.1 christos /*%
191 1.1 christos * If you use more than 10 of these in, say, a printf(), you'll have problems.
192 1.1 christos */
193 1.1 christos static char *
194 1.1 christos upper(char *s) {
195 1.1 christos static int buf_to_use = 0;
196 1.1 christos static char buf[10][256];
197 1.1 christos char *b;
198 1.1 christos int c;
199 1.1 christos
200 1.1 christos buf_to_use++;
201 1.1 christos if (buf_to_use > 9)
202 1.1 christos buf_to_use = 0;
203 1.1 christos
204 1.1 christos b = buf[buf_to_use];
205 1.1 christos memset(b, 0, 256);
206 1.1 christos
207 1.1 christos while ((c = (*s++) & 0xff))
208 1.1 christos *b++ = islower(c) ? toupper(c) : c;
209 1.1 christos *b = '\0';
210 1.1 christos return (buf[buf_to_use]);
211 1.1 christos }
212 1.1 christos
213 1.1 christos static char *
214 1.1 christos funname(const char *s, char *buf) {
215 1.1 christos char *b = buf;
216 1.1 christos char c;
217 1.1 christos
218 1.1 christos INSIST(strlen(s) < TYPECLASSBUF);
219 1.1 christos while ((c = *s++)) {
220 1.1 christos *b++ = (c == '-') ? '_' : c;
221 1.1 christos }
222 1.1 christos *b = '\0';
223 1.1 christos return (buf);
224 1.1 christos }
225 1.1 christos
226 1.1 christos static void
227 1.1 christos doswitch(const char *name, const char *function, const char *args,
228 1.1 christos const char *tsw, const char *csw, const char *res)
229 1.1 christos {
230 1.1 christos struct tt *tt;
231 1.1 christos int first = 1;
232 1.1 christos int lasttype = 0;
233 1.1 christos int subswitch = 0;
234 1.1 christos char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
235 1.1 christos const char *result = " result =";
236 1.1 christos
237 1.1 christos if (res == NULL)
238 1.1 christos result = "";
239 1.1 christos
240 1.1 christos for (tt = types; tt != NULL; tt = tt->next) {
241 1.1 christos if (first) {
242 1.1 christos fprintf(stdout, "\n#define %s \\\n", name);
243 1.1 christos fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
244 1.1 christos first = 0;
245 1.1 christos }
246 1.1 christos if (tt->type != lasttype && subswitch) {
247 1.1 christos if (res == NULL)
248 1.1 christos fprintf(stdout, "\t\tdefault: break; \\\n");
249 1.1 christos else
250 1.1 christos fprintf(stdout,
251 1.1 christos "\t\tdefault: %s; break; \\\n", res);
252 1.1 christos fputs(/*{*/ "\t\t} \\\n", stdout);
253 1.1 christos fputs("\t\tbreak; \\\n", stdout);
254 1.1 christos subswitch = 0;
255 1.1 christos }
256 1.1 christos if (tt->rdclass && tt->type != lasttype) {
257 1.1 christos fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
258 1.1 christos tt->type, csw);
259 1.1 christos subswitch = 1;
260 1.1 christos }
261 1.1 christos if (tt->rdclass == 0)
262 1.1 christos fprintf(stdout,
263 1.1 christos "\tcase %d:%s %s_%s(%s); break;",
264 1.1 christos tt->type, result, function,
265 1.3 christos funname(tt->typebuf, buf1), args);
266 1.1 christos else
267 1.1 christos fprintf(stdout,
268 1.1 christos "\t\tcase %d:%s %s_%s_%s(%s); break;",
269 1.1 christos tt->rdclass, result, function,
270 1.3 christos funname(tt->classbuf, buf1),
271 1.3 christos funname(tt->typebuf, buf2), args);
272 1.1 christos fputs(" \\\n", stdout);
273 1.1 christos lasttype = tt->type;
274 1.1 christos }
275 1.1 christos if (subswitch) {
276 1.1 christos if (res == NULL)
277 1.1 christos fprintf(stdout, "\t\tdefault: break; \\\n");
278 1.1 christos else
279 1.1 christos fprintf(stdout, "\t\tdefault: %s; break; \\\n", res);
280 1.1 christos fputs(/*{*/ "\t\t} \\\n", stdout);
281 1.1 christos fputs("\t\tbreak; \\\n", stdout);
282 1.1 christos }
283 1.1 christos if (first) {
284 1.1 christos if (res == NULL)
285 1.1 christos fprintf(stdout, "\n#define %s\n", name);
286 1.1 christos else
287 1.1 christos fprintf(stdout, "\n#define %s %s;\n", name, res);
288 1.1 christos } else {
289 1.1 christos if (res == NULL)
290 1.1 christos fprintf(stdout, "\tdefault: break; \\\n");
291 1.1 christos else
292 1.1 christos fprintf(stdout, "\tdefault: %s; break; \\\n", res);
293 1.1 christos fputs(/*{*/ "\t}\n", stdout);
294 1.1 christos }
295 1.1 christos }
296 1.1 christos
297 1.1 christos static struct ttnam *
298 1.1 christos find_typename(int type) {
299 1.1 christos int i;
300 1.1 christos
301 1.1 christos for (i = 0; i < TYPENAMES; i++) {
302 1.3 christos if (typenames[i].typebuf[0] != 0 &&
303 1.1 christos typenames[i].type == type)
304 1.3 christos {
305 1.1 christos return (&typenames[i]);
306 1.3 christos }
307 1.1 christos }
308 1.1 christos return (NULL);
309 1.1 christos }
310 1.1 christos
311 1.1 christos static void
312 1.3 christos insert_into_typenames(int type, const char *typebuf, const char *attr) {
313 1.1 christos struct ttnam *ttn = NULL;
314 1.1 christos size_t c;
315 1.1 christos int i, n;
316 1.1 christos char tmp[256];
317 1.1 christos
318 1.3 christos INSIST(strlen(typebuf) < TYPECLASSBUF);
319 1.1 christos for (i = 0; i < TYPENAMES; i++) {
320 1.3 christos if (typenames[i].typebuf[0] != 0 &&
321 1.1 christos typenames[i].type == type &&
322 1.3 christos strcmp(typebuf, typenames[i].typebuf) != 0)
323 1.3 christos {
324 1.1 christos fprintf(stderr,
325 1.1 christos "Error: type %d has two names: %s, %s\n",
326 1.3 christos type, typenames[i].typebuf, typebuf);
327 1.1 christos exit(1);
328 1.1 christos }
329 1.3 christos if (typenames[i].typebuf[0] == 0 && ttn == NULL) {
330 1.1 christos ttn = &typenames[i];
331 1.3 christos }
332 1.1 christos }
333 1.1 christos if (ttn == NULL) {
334 1.1 christos fprintf(stderr, "Error: typenames array too small\n");
335 1.1 christos exit(1);
336 1.1 christos }
337 1.1 christos
338 1.1 christos /* XXXMUKS: This is redundant due to the INSIST above. */
339 1.3 christos if (strlen(typebuf) > sizeof(ttn->typebuf) - 1) {
340 1.1 christos fprintf(stderr, "Error: type name %s is too long\n",
341 1.3 christos typebuf);
342 1.1 christos exit(1);
343 1.1 christos }
344 1.1 christos
345 1.3 christos strncpy(ttn->typebuf, typebuf, sizeof(ttn->typebuf));
346 1.3 christos ttn->typebuf[sizeof(ttn->typebuf) - 1] = '\0';
347 1.1 christos
348 1.3 christos strncpy(ttn->macroname, ttn->typebuf, sizeof(ttn->macroname));
349 1.1 christos ttn->macroname[sizeof(ttn->macroname) - 1] = '\0';
350 1.1 christos
351 1.1 christos ttn->type = type;
352 1.1 christos c = strlen(ttn->macroname);
353 1.1 christos while (c > 0) {
354 1.3 christos if (ttn->macroname[c - 1] == '-') {
355 1.1 christos ttn->macroname[c - 1] = '_';
356 1.3 christos }
357 1.1 christos c--;
358 1.1 christos }
359 1.1 christos
360 1.1 christos if (attr == NULL) {
361 1.1 christos n = snprintf(tmp, sizeof(tmp),
362 1.1 christos "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
363 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(tmp));
364 1.1 christos attr = tmp;
365 1.1 christos }
366 1.1 christos
367 1.1 christos if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) {
368 1.1 christos fprintf(stderr, "Error: type %d has different attributes: "
369 1.1 christos "%s, %s\n", type, ttn->attr, attr);
370 1.1 christos exit(1);
371 1.1 christos }
372 1.1 christos
373 1.1 christos if (strlen(attr) > sizeof(ttn->attr) - 1) {
374 1.1 christos fprintf(stderr, "Error: attr (%s) [name %s] is too long\n",
375 1.3 christos attr, typebuf);
376 1.1 christos exit(1);
377 1.1 christos }
378 1.1 christos
379 1.1 christos strncpy(ttn->attr, attr, sizeof(ttn->attr));
380 1.1 christos ttn->attr[sizeof(ttn->attr) - 1] = '\0';
381 1.1 christos
382 1.1 christos ttn->sorted = 0;
383 1.3 christos if (maxtype < type) {
384 1.1 christos maxtype = type;
385 1.3 christos }
386 1.1 christos }
387 1.1 christos
388 1.1 christos static void
389 1.3 christos add(int rdclass, const char *classbuf, int type, const char *typebuf,
390 1.3 christos const char *dirbuf)
391 1.1 christos {
392 1.1 christos struct tt *newtt = (struct tt *)malloc(sizeof(*newtt));
393 1.1 christos struct tt *tt, *oldtt;
394 1.1 christos struct cc *newcc;
395 1.1 christos struct cc *cc, *oldcc;
396 1.1 christos
397 1.3 christos INSIST(strlen(typebuf) < TYPECLASSBUF);
398 1.3 christos INSIST(strlen(classbuf) < TYPECLASSBUF);
399 1.4 christos INSIST(strlen(dirbuf) < PATH_MAX);
400 1.1 christos
401 1.3 christos insert_into_typenames(type, typebuf, NULL);
402 1.1 christos
403 1.1 christos if (newtt == NULL) {
404 1.1 christos fprintf(stderr, "malloc() failed\n");
405 1.1 christos exit(1);
406 1.1 christos }
407 1.1 christos
408 1.1 christos newtt->next = NULL;
409 1.1 christos newtt->rdclass = rdclass;
410 1.1 christos newtt->type = type;
411 1.1 christos
412 1.3 christos strncpy(newtt->classbuf, classbuf, sizeof(newtt->classbuf));
413 1.3 christos newtt->classbuf[sizeof(newtt->classbuf) - 1] = '\0';
414 1.1 christos
415 1.3 christos strncpy(newtt->typebuf, typebuf, sizeof(newtt->typebuf));
416 1.3 christos newtt->typebuf[sizeof(newtt->typebuf) - 1] = '\0';
417 1.1 christos
418 1.3 christos if (strncmp(dirbuf, "./", 2) == 0) {
419 1.3 christos dirbuf += 2;
420 1.3 christos }
421 1.3 christos strncpy(newtt->dirbuf, dirbuf, sizeof(newtt->dirbuf));
422 1.3 christos newtt->dirbuf[sizeof(newtt->dirbuf) - 1] = '\0';
423 1.1 christos
424 1.1 christos tt = types;
425 1.1 christos oldtt = NULL;
426 1.1 christos
427 1.1 christos while ((tt != NULL) && (tt->type < type)) {
428 1.1 christos oldtt = tt;
429 1.1 christos tt = tt->next;
430 1.1 christos }
431 1.1 christos
432 1.1 christos while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) {
433 1.3 christos if (strcmp(tt->typebuf, typebuf) != 0) {
434 1.1 christos exit(1);
435 1.3 christos }
436 1.1 christos oldtt = tt;
437 1.1 christos tt = tt->next;
438 1.1 christos }
439 1.1 christos
440 1.3 christos if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) {
441 1.1 christos exit(1);
442 1.3 christos }
443 1.1 christos
444 1.1 christos newtt->next = tt;
445 1.3 christos if (oldtt != NULL) {
446 1.1 christos oldtt->next = newtt;
447 1.3 christos } else {
448 1.1 christos types = newtt;
449 1.3 christos }
450 1.1 christos
451 1.1 christos /*
452 1.1 christos * Do a class switch for this type.
453 1.1 christos */
454 1.3 christos if (rdclass == 0) {
455 1.1 christos return;
456 1.3 christos }
457 1.1 christos
458 1.1 christos newcc = (struct cc *)malloc(sizeof(*newcc));
459 1.1 christos if (newcc == NULL) {
460 1.1 christos fprintf(stderr, "malloc() failed\n");
461 1.1 christos exit(1);
462 1.1 christos }
463 1.1 christos newcc->rdclass = rdclass;
464 1.3 christos strncpy(newcc->classbuf, classbuf, sizeof(newcc->classbuf));
465 1.3 christos newcc->classbuf[sizeof(newcc->classbuf) - 1] = '\0';
466 1.1 christos cc = classes;
467 1.1 christos oldcc = NULL;
468 1.1 christos
469 1.1 christos while ((cc != NULL) && (cc->rdclass < rdclass)) {
470 1.1 christos oldcc = cc;
471 1.1 christos cc = cc->next;
472 1.1 christos }
473 1.1 christos
474 1.1 christos if ((cc != NULL) && cc->rdclass == rdclass) {
475 1.1 christos free((char *)newcc);
476 1.1 christos return;
477 1.1 christos }
478 1.1 christos
479 1.1 christos newcc->next = cc;
480 1.3 christos if (oldcc != NULL) {
481 1.1 christos oldcc->next = newcc;
482 1.3 christos } else {
483 1.1 christos classes = newcc;
484 1.3 christos }
485 1.1 christos }
486 1.1 christos
487 1.1 christos static void
488 1.3 christos sd(int rdclass, const char *classbuf, const char *dirbuf, char filetype) {
489 1.1 christos char buf[TYPECLASSLEN + sizeof("_65535.h")];
490 1.3 christos char typebuf[TYPECLASSBUF];
491 1.1 christos int type, n;
492 1.1 christos isc_dir_t dir;
493 1.1 christos
494 1.3 christos if (!start_directory(dirbuf, &dir)) {
495 1.1 christos return;
496 1.3 christos }
497 1.1 christos
498 1.1 christos while (next_file(&dir)) {
499 1.3 christos if (sscanf(dir.filename, TYPECLASSFMT, typebuf, &type) != 2) {
500 1.1 christos continue;
501 1.3 christos }
502 1.3 christos if ((type > 65535) || (type < 0)) {
503 1.1 christos continue;
504 1.3 christos }
505 1.1 christos
506 1.3 christos n = snprintf(buf, sizeof(buf), "%s_%d.%c", typebuf,
507 1.1 christos type, filetype);
508 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(buf));
509 1.3 christos if (strcmp(buf, dir.filename) != 0) {
510 1.1 christos continue;
511 1.3 christos }
512 1.3 christos add(rdclass, classbuf, type, typebuf, dirbuf);
513 1.1 christos }
514 1.1 christos
515 1.1 christos end_directory(&dir);
516 1.1 christos }
517 1.1 christos
518 1.1 christos static unsigned int
519 1.1 christos HASH(char *string) {
520 1.1 christos size_t n;
521 1.1 christos unsigned char a, b;
522 1.1 christos
523 1.1 christos n = strlen(string);
524 1.1 christos if (n == 0) {
525 1.1 christos fprintf(stderr, "n == 0?\n");
526 1.1 christos exit(1);
527 1.1 christos }
528 1.1 christos a = tolower((unsigned char)string[0]);
529 1.1 christos b = tolower((unsigned char)string[n - 1]);
530 1.1 christos
531 1.1 christos return ((a + n) * b) % 256;
532 1.1 christos }
533 1.1 christos
534 1.1 christos int
535 1.1 christos main(int argc, char **argv) {
536 1.4 christos char buf[PATH_MAX];
537 1.4 christos char srcdir[PATH_MAX];
538 1.1 christos int rdclass;
539 1.3 christos char classbuf[TYPECLASSBUF];
540 1.1 christos struct tt *tt;
541 1.1 christos struct cc *cc;
542 1.1 christos struct ttnam *ttn, *ttn2;
543 1.1 christos unsigned int hash;
544 1.1 christos time_t now;
545 1.1 christos char year[11];
546 1.1 christos int lasttype;
547 1.1 christos int code = 1;
548 1.1 christos int class_enum = 0;
549 1.1 christos int type_enum = 0;
550 1.1 christos int structs = 0;
551 1.1 christos int depend = 0;
552 1.1 christos int c, i, j, n;
553 1.1 christos char buf1[TYPECLASSBUF];
554 1.1 christos char filetype = 'c';
555 1.1 christos FILE *fd;
556 1.1 christos char *prefix = NULL;
557 1.1 christos char *suffix = NULL;
558 1.1 christos char *file = NULL;
559 1.5 christos char *source_date_epoch;
560 1.5 christos unsigned long long epoch;
561 1.5 christos char *endptr;
562 1.1 christos isc_dir_t dir;
563 1.1 christos
564 1.1 christos for (i = 0; i < TYPENAMES; i++)
565 1.1 christos memset(&typenames[i], 0, sizeof(typenames[i]));
566 1.1 christos
567 1.1 christos srcdir[0] = '\0';
568 1.1 christos while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1)
569 1.1 christos switch (c) {
570 1.1 christos case 'c':
571 1.1 christos code = 0;
572 1.1 christos depend = 0;
573 1.1 christos type_enum = 0;
574 1.1 christos class_enum = 1;
575 1.1 christos filetype = 'c';
576 1.1 christos structs = 0;
577 1.1 christos break;
578 1.1 christos case 'd':
579 1.1 christos code = 0;
580 1.1 christos depend = 1;
581 1.1 christos class_enum = 0;
582 1.1 christos type_enum = 0;
583 1.1 christos structs = 0;
584 1.1 christos filetype = 'h';
585 1.1 christos break;
586 1.1 christos case 't':
587 1.1 christos code = 0;
588 1.1 christos depend = 0;
589 1.1 christos class_enum = 0;
590 1.1 christos type_enum = 1;
591 1.1 christos filetype = 'c';
592 1.1 christos structs = 0;
593 1.1 christos break;
594 1.1 christos case 'i':
595 1.1 christos code = 0;
596 1.1 christos depend = 0;
597 1.1 christos class_enum = 0;
598 1.1 christos type_enum = 0;
599 1.1 christos structs = 1;
600 1.1 christos filetype = 'h';
601 1.1 christos break;
602 1.1 christos case 's':
603 1.1 christos if (strlen(isc_commandline_argument) >
604 1.4 christos PATH_MAX - 2 * TYPECLASSLEN -
605 1.3 christos sizeof("/rdata/_65535_65535"))
606 1.3 christos {
607 1.1 christos fprintf(stderr, "\"%s\" too long\n",
608 1.1 christos isc_commandline_argument);
609 1.1 christos exit(1);
610 1.1 christos }
611 1.1 christos n = snprintf(srcdir, sizeof(srcdir), "%s/",
612 1.1 christos isc_commandline_argument);
613 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
614 1.1 christos break;
615 1.1 christos case 'F':
616 1.1 christos file = isc_commandline_argument;
617 1.1 christos break;
618 1.1 christos case 'P':
619 1.1 christos prefix = isc_commandline_argument;
620 1.1 christos break;
621 1.1 christos case 'S':
622 1.1 christos suffix = isc_commandline_argument;
623 1.1 christos break;
624 1.1 christos case '?':
625 1.1 christos exit(1);
626 1.1 christos }
627 1.1 christos
628 1.1 christos n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
629 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
630 1.1 christos
631 1.3 christos if (!start_directory(buf, &dir)) {
632 1.1 christos exit(1);
633 1.3 christos }
634 1.1 christos
635 1.1 christos while (next_file(&dir)) {
636 1.3 christos if (sscanf(dir.filename, TYPECLASSFMT, classbuf,
637 1.1 christos &rdclass) != 2)
638 1.3 christos {
639 1.1 christos continue;
640 1.3 christos }
641 1.3 christos if ((rdclass > 65535) || (rdclass < 0)) {
642 1.1 christos continue;
643 1.3 christos }
644 1.1 christos
645 1.1 christos n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
646 1.3 christos srcdir, classbuf, rdclass);
647 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(buf));
648 1.3 christos if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) {
649 1.1 christos continue;
650 1.3 christos }
651 1.3 christos sd(rdclass, classbuf, buf, filetype);
652 1.1 christos }
653 1.1 christos end_directory(&dir);
654 1.1 christos n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
655 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
656 1.1 christos sd(0, "", buf, filetype);
657 1.1 christos
658 1.5 christos source_date_epoch = getenv("SOURCE_DATE_EPOCH");
659 1.5 christos if (source_date_epoch) {
660 1.5 christos errno = 0;
661 1.5 christos epoch = strtoull(source_date_epoch, &endptr, 10);
662 1.5 christos if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
663 1.5 christos || (errno != 0 && epoch == 0)) {
664 1.5 christos fprintf(stderr, "Environment variable "
665 1.5 christos "$SOURCE_DATE_EPOCH: strtoull: %s\n",
666 1.5 christos strerror(errno));
667 1.5 christos exit (EXIT_FAILURE);
668 1.5 christos }
669 1.5 christos if (endptr == source_date_epoch) {
670 1.5 christos fprintf(stderr, "Environment variable "
671 1.5 christos "$SOURCE_DATE_EPOCH: "
672 1.5 christos "No digits were found: %s\n",
673 1.5 christos endptr);
674 1.5 christos exit (EXIT_FAILURE);
675 1.5 christos }
676 1.5 christos if (*endptr != '\0') {
677 1.5 christos fprintf(stderr, "Environment variable "
678 1.5 christos "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n",
679 1.5 christos endptr);
680 1.5 christos exit (EXIT_FAILURE);
681 1.5 christos }
682 1.5 christos if (epoch > ULONG_MAX) {
683 1.5 christos fprintf(stderr, "Environment variable "
684 1.5 christos "$SOURCE_DATE_EPOCH: value must be "
685 1.5 christos "smaller than or equal to: %lu but "
686 1.5 christos "was found to be: %llu \n",
687 1.5 christos ULONG_MAX, epoch);
688 1.5 christos exit (EXIT_FAILURE);
689 1.5 christos }
690 1.5 christos now = epoch;
691 1.5 christos } else {
692 1.5 christos time(&now);
693 1.5 christos }
694 1.5 christos
695 1.5 christos if (now != -1) {
696 1.5 christos struct tm *tm = gmtime(&now);
697 1.5 christos if (tm != NULL && tm->tm_year > 104) {
698 1.1 christos n = snprintf(year, sizeof(year), "-%d",
699 1.1 christos tm->tm_year + 1900);
700 1.1 christos INSIST(n > 0 && (unsigned)n < sizeof(year));
701 1.1 christos } else {
702 1.1 christos snprintf(year, sizeof(year), "-2016");
703 1.1 christos }
704 1.1 christos } else {
705 1.1 christos snprintf(year, sizeof(year), "-2016");
706 1.1 christos }
707 1.1 christos
708 1.3 christos if (!depend) {
709 1.1 christos fprintf(stdout, copyright, year);
710 1.3 christos }
711 1.1 christos
712 1.1 christos if (code) {
713 1.1 christos fputs("#ifndef DNS_CODE_H\n", stdout);
714 1.1 christos fputs("#define DNS_CODE_H 1\n\n", stdout);
715 1.1 christos
716 1.3 christos fputs("#include <stdbool.h>\n", stdout);
717 1.1 christos fputs("#include <isc/result.h>\n\n", stdout);
718 1.1 christos fputs("#include <dns/name.h>\n\n", stdout);
719 1.1 christos
720 1.3 christos for (tt = types; tt != NULL; tt = tt->next) {
721 1.1 christos fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
722 1.3 christos tt->dirbuf, tt->typebuf, tt->type);
723 1.3 christos }
724 1.1 christos
725 1.1 christos fputs("\n\n", stdout);
726 1.1 christos
727 1.1 christos doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
728 1.1 christos FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
729 1.1 christos doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
730 1.1 christos TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
731 1.1 christos doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
732 1.1 christos FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
733 1.1 christos doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
734 1.1 christos TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
735 1.1 christos doswitch("COMPARESWITCH", "compare", COMPAREARGS,
736 1.1 christos COMPARETYPE, COMPARECLASS, COMPAREDEF);
737 1.1 christos doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS,
738 1.1 christos COMPARETYPE, COMPARECLASS, COMPAREDEF);
739 1.1 christos doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
740 1.1 christos FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
741 1.1 christos doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
742 1.1 christos TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
743 1.1 christos doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS,
744 1.1 christos FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF);
745 1.1 christos doswitch("ADDITIONALDATASWITCH", "additionaldata",
746 1.1 christos ADDITIONALDATAARGS, ADDITIONALDATATYPE,
747 1.1 christos ADDITIONALDATACLASS, ADDITIONALDATADEF);
748 1.1 christos doswitch("DIGESTSWITCH", "digest",
749 1.1 christos DIGESTARGS, DIGESTTYPE,
750 1.1 christos DIGESTCLASS, DIGESTDEF);
751 1.1 christos doswitch("CHECKOWNERSWITCH", "checkowner",
752 1.1 christos CHECKOWNERARGS, CHECKOWNERTYPE,
753 1.1 christos CHECKOWNERCLASS, CHECKOWNERDEF);
754 1.1 christos doswitch("CHECKNAMESSWITCH", "checknames",
755 1.1 christos CHECKNAMESARGS, CHECKNAMESTYPE,
756 1.1 christos CHECKNAMESCLASS, CHECKNAMESDEF);
757 1.1 christos
758 1.1 christos /*
759 1.1 christos * From here down, we are processing the rdata names and
760 1.1 christos * attributes.
761 1.1 christos */
762 1.1 christos
763 1.1 christos #define PRINT_COMMA(x) (x == maxtype ? "" : ",")
764 1.1 christos
765 1.1 christos #define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \
766 1.1 christos "DNS_RDATATYPEATTR_NOTQUESTION"
767 1.1 christos #define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \
768 1.1 christos "DNS_RDATATYPEATTR_QUESTIONONLY"
769 1.3 christos #define RESERVEDNAME "0"
770 1.3 christos #define RESERVED "DNS_RDATATYPEATTR_RESERVED"
771 1.1 christos
772 1.1 christos /*
773 1.1 christos * Add in reserved/special types. This will let us
774 1.1 christos * sort them without special cases.
775 1.1 christos */
776 1.1 christos insert_into_typenames(0, "reserved0", RESERVED);
777 1.3 christos insert_into_typenames(100, "uinfo", RESERVEDNAME);
778 1.3 christos insert_into_typenames(101, "uid", RESERVEDNAME);
779 1.3 christos insert_into_typenames(102, "gid", RESERVEDNAME);
780 1.5 christos insert_into_typenames(103, "unspec", RESERVEDNAME);
781 1.1 christos insert_into_typenames(251, "ixfr", METAQUESTIONONLY);
782 1.1 christos insert_into_typenames(252, "axfr", METAQUESTIONONLY);
783 1.1 christos insert_into_typenames(253, "mailb", METAQUESTIONONLY);
784 1.1 christos insert_into_typenames(254, "maila", METAQUESTIONONLY);
785 1.1 christos insert_into_typenames(255, "any", METAQUESTIONONLY);
786 1.1 christos
787 1.1 christos /*
788 1.1 christos * Spit out a quick and dirty hash function. Here,
789 1.1 christos * we walk through the list of type names, and calculate
790 1.1 christos * a hash. This isn't perfect, but it will generate "pretty
791 1.1 christos * good" estimates. Lowercase the characters before
792 1.1 christos * computing in all cases.
793 1.1 christos *
794 1.1 christos * Here, walk the list from top to bottom, calculating
795 1.1 christos * the hash (mod 256) for each name.
796 1.1 christos */
797 1.1 christos fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n");
798 1.1 christos fprintf(stdout, "\tdo { \\\n");
799 1.1 christos fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n"
800 1.1 christos "\t\t strncasecmp(_s,(_tn),"
801 1.1 christos "(sizeof(_s) - 1)) == 0) { \\\n");
802 1.1 christos fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & "
803 1.1 christos "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n");
804 1.1 christos fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n");
805 1.1 christos fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n");
806 1.1 christos fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n");
807 1.1 christos fprintf(stdout, "\t\t} \\\n");
808 1.2 christos fprintf(stdout, "\t} while (/*CONSTCOND*/0)\n\n");
809 1.1 christos
810 1.1 christos fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash,"
811 1.1 christos "_typename,_length,_typep) \\\n");
812 1.1 christos fprintf(stdout, "\tswitch (_hash) { \\\n");
813 1.1 christos for (i = 0; i <= maxtype; i++) {
814 1.1 christos ttn = find_typename(i);
815 1.3 christos if (ttn == NULL) {
816 1.1 christos continue;
817 1.3 christos }
818 1.1 christos
819 1.1 christos /*
820 1.1 christos * Skip entries we already processed.
821 1.1 christos */
822 1.3 christos if (ttn->sorted != 0) {
823 1.1 christos continue;
824 1.3 christos }
825 1.1 christos
826 1.3 christos hash = HASH(ttn->typebuf);
827 1.1 christos fprintf(stdout, "\t\tcase %u: \\\n", hash);
828 1.1 christos
829 1.1 christos /*
830 1.1 christos * Find all other entries that happen to match
831 1.1 christos * this hash.
832 1.1 christos */
833 1.1 christos for (j = 0; j <= maxtype; j++) {
834 1.1 christos ttn2 = find_typename(j);
835 1.3 christos if (ttn2 == NULL) {
836 1.1 christos continue;
837 1.3 christos }
838 1.3 christos if (hash == HASH(ttn2->typebuf)) {
839 1.3 christos fprintf(stdout, "\t\t\t"
840 1.3 christos "RDATATYPE_COMPARE"
841 1.3 christos "(\"%s\", %d, _typename, "
842 1.3 christos " _length, _typep); \\\n",
843 1.3 christos ttn2->typebuf, ttn2->type);
844 1.1 christos ttn2->sorted = 1;
845 1.1 christos }
846 1.1 christos }
847 1.1 christos fprintf(stdout, "\t\t\tbreak; \\\n");
848 1.1 christos }
849 1.1 christos fprintf(stdout, "\t}\n");
850 1.1 christos
851 1.1 christos fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n");
852 1.1 christos fprintf(stdout, "\tswitch (type) { \\\n");
853 1.1 christos for (i = 0; i <= maxtype; i++) {
854 1.1 christos ttn = find_typename(i);
855 1.3 christos if (ttn == NULL) {
856 1.1 christos continue;
857 1.3 christos }
858 1.1 christos fprintf(stdout, "\tcase %d: return (%s); \\\n",
859 1.1 christos i, upper(ttn->attr));
860 1.1 christos }
861 1.1 christos fprintf(stdout, "\t}\n");
862 1.1 christos
863 1.1 christos fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n");
864 1.1 christos fprintf(stdout, "\tswitch (type) { \\\n");
865 1.1 christos for (i = 0; i <= maxtype; i++) {
866 1.1 christos ttn = find_typename(i);
867 1.3 christos if (ttn == NULL) {
868 1.1 christos continue;
869 1.3 christos }
870 1.1 christos /*
871 1.1 christos * Remove KEYDATA (65533) from the type to memonic
872 1.1 christos * translation as it is internal use only. This
873 1.1 christos * stops the tools from displaying KEYDATA instead
874 1.1 christos * of TYPE65533.
875 1.1 christos */
876 1.3 christos if (i == 65533U) {
877 1.1 christos continue;
878 1.3 christos }
879 1.1 christos fprintf(stdout, "\tcase %d: return "
880 1.1 christos "(str_totext(\"%s\", target)); \\\n",
881 1.3 christos i, upper(ttn->typebuf));
882 1.1 christos }
883 1.1 christos fprintf(stdout, "\t}\n");
884 1.1 christos
885 1.1 christos fputs("#endif /* DNS_CODE_H */\n", stdout);
886 1.1 christos } else if (type_enum) {
887 1.1 christos char *s;
888 1.1 christos
889 1.1 christos fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n");
890 1.1 christos fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n");
891 1.1 christos
892 1.1 christos fprintf(stdout, "enum {\n");
893 1.1 christos fprintf(stdout, "\tdns_rdatatype_none = 0,\n");
894 1.1 christos
895 1.1 christos lasttype = 0;
896 1.3 christos for (tt = types; tt != NULL; tt = tt->next) {
897 1.3 christos if (tt->type != lasttype) {
898 1.1 christos fprintf(stdout,
899 1.1 christos "\tdns_rdatatype_%s = %d,\n",
900 1.3 christos funname(tt->typebuf, buf1),
901 1.1 christos lasttype = tt->type);
902 1.3 christos }
903 1.3 christos }
904 1.1 christos
905 1.1 christos fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n");
906 1.1 christos fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n");
907 1.1 christos fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n");
908 1.1 christos fprintf(stdout, "\tdns_rdatatype_maila = 254,\n");
909 1.1 christos fprintf(stdout, "\tdns_rdatatype_any = 255\n");
910 1.1 christos
911 1.1 christos fprintf(stdout, "};\n\n");
912 1.1 christos
913 1.1 christos fprintf(stdout, "#define dns_rdatatype_none\t"
914 1.1 christos "((dns_rdatatype_t)dns_rdatatype_none)\n");
915 1.1 christos
916 1.3 christos for (tt = types; tt != NULL; tt = tt->next) {
917 1.1 christos if (tt->type != lasttype) {
918 1.3 christos s = funname(tt->typebuf, buf1);
919 1.1 christos fprintf(stdout,
920 1.1 christos "#define dns_rdatatype_%s\t%s"
921 1.1 christos "((dns_rdatatype_t)dns_rdatatype_%s)"
922 1.1 christos "\n",
923 1.1 christos s, strlen(s) < 2U ? "\t" : "", s);
924 1.1 christos lasttype = tt->type;
925 1.1 christos }
926 1.3 christos }
927 1.1 christos
928 1.1 christos fprintf(stdout, "#define dns_rdatatype_ixfr\t"
929 1.1 christos "((dns_rdatatype_t)dns_rdatatype_ixfr)\n");
930 1.1 christos fprintf(stdout, "#define dns_rdatatype_axfr\t"
931 1.1 christos "((dns_rdatatype_t)dns_rdatatype_axfr)\n");
932 1.1 christos fprintf(stdout, "#define dns_rdatatype_mailb\t"
933 1.1 christos "((dns_rdatatype_t)dns_rdatatype_mailb)\n");
934 1.1 christos fprintf(stdout, "#define dns_rdatatype_maila\t"
935 1.1 christos "((dns_rdatatype_t)dns_rdatatype_maila)\n");
936 1.1 christos fprintf(stdout, "#define dns_rdatatype_any\t"
937 1.1 christos "((dns_rdatatype_t)dns_rdatatype_any)\n");
938 1.1 christos
939 1.1 christos fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n");
940 1.1 christos
941 1.1 christos } else if (class_enum) {
942 1.1 christos char *s;
943 1.1 christos int classnum;
944 1.1 christos
945 1.1 christos fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n");
946 1.1 christos fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n");
947 1.1 christos
948 1.1 christos fprintf(stdout, "enum {\n");
949 1.1 christos
950 1.1 christos fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n");
951 1.1 christos fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t"
952 1.1 christos "((dns_rdataclass_t)dns_rdataclass_reserved0)\n");
953 1.1 christos
954 1.1 christos #define PRINTCLASS(name, num) \
955 1.1 christos do { \
956 1.1 christos s = funname(name, buf1); \
957 1.1 christos classnum = num; \
958 1.1 christos fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \
959 1.1 christos classnum != 255 ? "," : ""); \
960 1.1 christos fprintf(stdout, "#define dns_rdataclass_%s\t" \
961 1.1 christos "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \
962 1.2 christos } while (/*CONSTCOND*/0)
963 1.1 christos
964 1.1 christos for (cc = classes; cc != NULL; cc = cc->next) {
965 1.3 christos if (cc->rdclass == 3) {
966 1.1 christos PRINTCLASS("chaos", 3);
967 1.3 christos } else if (cc->rdclass == 255) {
968 1.1 christos PRINTCLASS("none", 254);
969 1.3 christos }
970 1.3 christos PRINTCLASS(cc->classbuf, cc->rdclass);
971 1.1 christos }
972 1.1 christos
973 1.1 christos #undef PRINTCLASS
974 1.1 christos
975 1.1 christos fprintf(stdout, "};\n\n");
976 1.1 christos fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n");
977 1.1 christos } else if (structs) {
978 1.1 christos if (prefix != NULL) {
979 1.1 christos if ((fd = fopen(prefix,"r")) != NULL) {
980 1.3 christos while (fgets(buf, sizeof(buf), fd) != NULL) {
981 1.1 christos fputs(buf, stdout);
982 1.3 christos }
983 1.1 christos fclose(fd);
984 1.1 christos }
985 1.1 christos }
986 1.1 christos for (tt = types; tt != NULL; tt = tt->next) {
987 1.1 christos snprintf(buf, sizeof(buf), "%s/%s_%d.h",
988 1.3 christos tt->dirbuf, tt->typebuf, tt->type);
989 1.1 christos if ((fd = fopen(buf,"r")) != NULL) {
990 1.3 christos while (fgets(buf, sizeof(buf), fd) != NULL) {
991 1.1 christos fputs(buf, stdout);
992 1.3 christos }
993 1.1 christos fclose(fd);
994 1.1 christos }
995 1.1 christos }
996 1.1 christos if (suffix != NULL) {
997 1.1 christos if ((fd = fopen(suffix,"r")) != NULL) {
998 1.3 christos while (fgets(buf, sizeof(buf), fd) != NULL) {
999 1.1 christos fputs(buf, stdout);
1000 1.3 christos }
1001 1.1 christos fclose(fd);
1002 1.1 christos }
1003 1.1 christos }
1004 1.1 christos } else if (depend) {
1005 1.3 christos for (tt = types; tt != NULL; tt = tt->next) {
1006 1.1 christos fprintf(stdout, "%s:\t%s/%s_%d.h\n", file,
1007 1.3 christos tt->dirbuf, tt->typebuf, tt->type);
1008 1.3 christos }
1009 1.1 christos }
1010 1.1 christos
1011 1.3 christos if (ferror(stdout) != 0) {
1012 1.1 christos exit(1);
1013 1.3 christos }
1014 1.1 christos
1015 1.1 christos return (0);
1016 1.1 christos }
1017