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