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