diff options
Diffstat (limited to 'lib/dns/gen.c')
-rw-r--r-- | lib/dns/gen.c | 923 |
1 files changed, 923 insertions, 0 deletions
diff --git a/lib/dns/gen.c b/lib/dns/gen.c new file mode 100644 index 0000000..2a3b94b --- /dev/null +++ b/lib/dns/gen.c @@ -0,0 +1,923 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/*! \file */ + +#ifdef WIN32 +/* + * Silence compiler warnings about using strcpy and friends. + */ +#define _CRT_SECURE_NO_DEPRECATE 1 +/* + * We use snprintf which was defined late in Windows even it is in C99. + */ +#if _MSC_VER < 1900 +#define snprintf _snprintf +#endif +#endif + +#include <sys/types.h> + +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#ifdef WIN32 +#include "gen-win32.h" +#else +#include "gen-unix.h" +#endif + +#define INSIST(cond) \ + if (!(cond)) { \ + fprintf(stderr, "%s:%d: INSIST(%s)\n", \ + __FILE__, __LINE__, #cond); \ + abort(); \ + } + +#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" +#define FROMTEXTCLASS "rdclass" +#define FROMTEXTTYPE "type" +#define FROMTEXTDEF "result = DNS_R_UNKNOWN" + +#define TOTEXTARGS "rdata, tctx, target" +#define TOTEXTCLASS "rdata->rdclass" +#define TOTEXTTYPE "rdata->type" +#define TOTEXTDEF "use_default = true" + +#define FROMWIREARGS "rdclass, type, source, dctx, options, target" +#define FROMWIRECLASS "rdclass" +#define FROMWIRETYPE "type" +#define FROMWIREDEF "use_default = true" + +#define TOWIREARGS "rdata, cctx, target" +#define TOWIRECLASS "rdata->rdclass" +#define TOWIRETYPE "rdata->type" +#define TOWIREDEF "use_default = true" + +#define FROMSTRUCTARGS "rdclass, type, source, target" +#define FROMSTRUCTCLASS "rdclass" +#define FROMSTRUCTTYPE "type" +#define FROMSTRUCTDEF "use_default = true" + +#define TOSTRUCTARGS "rdata, target, mctx" +#define TOSTRUCTCLASS "rdata->rdclass" +#define TOSTRUCTTYPE "rdata->type" +#define TOSTRUCTDEF "use_default = true" + +#define FREESTRUCTARGS "source" +#define FREESTRUCTCLASS "common->rdclass" +#define FREESTRUCTTYPE "common->rdtype" +#define FREESTRUCTDEF NULL + +#define COMPAREARGS "rdata1, rdata2" +#define COMPARECLASS "rdata1->rdclass" +#define COMPARETYPE "rdata1->type" +#define COMPAREDEF "use_default = true" + +#define ADDITIONALDATAARGS "rdata, add, arg" +#define ADDITIONALDATACLASS "rdata->rdclass" +#define ADDITIONALDATATYPE "rdata->type" +#define ADDITIONALDATADEF "use_default = true" + +#define DIGESTARGS "rdata, digest, arg" +#define DIGESTCLASS "rdata->rdclass" +#define DIGESTTYPE "rdata->type" +#define DIGESTDEF "use_default = true" + +#define CHECKOWNERARGS "name, rdclass, type, wildcard" +#define CHECKOWNERCLASS "rdclass" +#define CHECKOWNERTYPE "type" +#define CHECKOWNERDEF "result = true" + +#define CHECKNAMESARGS "rdata, owner, bad" +#define CHECKNAMESCLASS "rdata->rdclass" +#define CHECKNAMESTYPE "rdata->type" +#define CHECKNAMESDEF "result = true" + +static const char copyright[] = +"/*\n" +" * Copyright (C) 1998%s Internet Systems Consortium, Inc. (\"ISC\")\n" +" *\n" +" * This Source Code Form is subject to the terms of the Mozilla Public\n" +" * License, v. 2.0. If a copy of the MPL was not distributed with this\n" +" * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n" +" */\n" +"\n" +"/***************\n" +" ***************\n" +" *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n" +" *************** DO NOT EDIT!\n" +" ***************\n" +" ***************/\n" +"\n" +"/*! \\file */\n" +"\n"; + +#define STR_EXPAND(tok) #tok +#define STR(tok) STR_EXPAND(tok) + +#define TYPENAMES 256 +#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ +#define TYPECLASSBUF (TYPECLASSLEN + 1) +#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" +#define ATTRIBUTESIZE 256 +#define DIRNAMESIZE 256 + +static struct cc { + struct cc *next; + int rdclass; + char classname[TYPECLASSBUF]; +} *classes; + +static struct tt { + struct tt *next; + int rdclass; + int type; + char classname[TYPECLASSBUF]; + char typename[TYPECLASSBUF]; + char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ +} *types; + +static struct ttnam { + char typename[TYPECLASSBUF]; + char macroname[TYPECLASSBUF]; + char attr[ATTRIBUTESIZE]; + unsigned int sorted; + int type; +} typenames[TYPENAMES]; + +static int maxtype = -1; + +static char * +upper(char *); +static char * +funname(const char *, char *); +static void +doswitch(const char *, const char *, const char *, const char *, + const char *, const char *); +static void +add(int, const char *, int, const char *, const char *); +static void +sd(int, const char *, const char *, char); +static void +insert_into_typenames(int, const char *, const char *); + +/*% + * If you use more than 10 of these in, say, a printf(), you'll have problems. + */ +static char * +upper(char *s) { + static int buf_to_use = 0; + static char buf[10][256]; + char *b; + int c; + + buf_to_use++; + if (buf_to_use > 9) + buf_to_use = 0; + + b = buf[buf_to_use]; + memset(b, 0, 256); + + while ((c = (*s++) & 0xff)) + *b++ = islower(c) ? toupper(c) : c; + *b = '\0'; + return (buf[buf_to_use]); +} + +static char * +funname(const char *s, char *buf) { + char *b = buf; + char c; + + INSIST(strlen(s) < TYPECLASSBUF); + while ((c = *s++)) { + *b++ = (c == '-') ? '_' : c; + } + *b = '\0'; + return (buf); +} + +static void +doswitch(const char *name, const char *function, const char *args, + const char *tsw, const char *csw, const char *res) +{ + struct tt *tt; + int first = 1; + int lasttype = 0; + int subswitch = 0; + char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; + const char *result = " result ="; + + if (res == NULL) + result = ""; + + for (tt = types; tt != NULL; tt = tt->next) { + if (first) { + fprintf(stdout, "\n#define %s \\\n", name); + fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw); + first = 0; + } + if (tt->type != lasttype && subswitch) { + if (res == NULL) + fprintf(stdout, "\t\tdefault: break; \\\n"); + else + fprintf(stdout, + "\t\tdefault: %s; break; \\\n", res); + fputs(/*{*/ "\t\t} \\\n", stdout); + fputs("\t\tbreak; \\\n", stdout); + subswitch = 0; + } + if (tt->rdclass && tt->type != lasttype) { + fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/, + tt->type, csw); + subswitch = 1; + } + if (tt->rdclass == 0) + fprintf(stdout, + "\tcase %d:%s %s_%s(%s); break;", + tt->type, result, function, + funname(tt->typename, buf1), args); + else + fprintf(stdout, + "\t\tcase %d:%s %s_%s_%s(%s); break;", + tt->rdclass, result, function, + funname(tt->classname, buf1), + funname(tt->typename, buf2), args); + fputs(" \\\n", stdout); + lasttype = tt->type; + } + if (subswitch) { + if (res == NULL) + fprintf(stdout, "\t\tdefault: break; \\\n"); + else + fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); + fputs(/*{*/ "\t\t} \\\n", stdout); + fputs("\t\tbreak; \\\n", stdout); + } + if (first) { + if (res == NULL) + fprintf(stdout, "\n#define %s\n", name); + else + fprintf(stdout, "\n#define %s %s;\n", name, res); + } else { + if (res == NULL) + fprintf(stdout, "\tdefault: break; \\\n"); + else + fprintf(stdout, "\tdefault: %s; break; \\\n", res); + fputs(/*{*/ "\t}\n", stdout); + } +} + +static struct ttnam * +find_typename(int type) { + int i; + + for (i = 0; i < TYPENAMES; i++) { + if (typenames[i].typename[0] != 0 && + typenames[i].type == type) + return (&typenames[i]); + } + return (NULL); +} + +static void +insert_into_typenames(int type, const char *typename, const char *attr) { + struct ttnam *ttn = NULL; + size_t c; + int i, n; + char tmp[256]; + + INSIST(strlen(typename) < TYPECLASSBUF); + for (i = 0; i < TYPENAMES; i++) { + if (typenames[i].typename[0] != 0 && + typenames[i].type == type && + strcmp(typename, typenames[i].typename) != 0) { + fprintf(stderr, + "Error: type %d has two names: %s, %s\n", + type, typenames[i].typename, typename); + exit(1); + } + if (typenames[i].typename[0] == 0 && ttn == NULL) + ttn = &typenames[i]; + } + if (ttn == NULL) { + fprintf(stderr, "Error: typenames array too small\n"); + exit(1); + } + + /* XXXMUKS: This is redundant due to the INSIST above. */ + if (strlen(typename) > sizeof(ttn->typename) - 1) { + fprintf(stderr, "Error: type name %s is too long\n", + typename); + exit(1); + } + + strncpy(ttn->typename, typename, sizeof(ttn->typename)); + ttn->typename[sizeof(ttn->typename) - 1] = '\0'; + + strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); + ttn->macroname[sizeof(ttn->macroname) - 1] = '\0'; + + ttn->type = type; + c = strlen(ttn->macroname); + while (c > 0) { + if (ttn->macroname[c - 1] == '-') + ttn->macroname[c - 1] = '_'; + c--; + } + + if (attr == NULL) { + n = snprintf(tmp, sizeof(tmp), + "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); + INSIST(n > 0 && (unsigned)n < sizeof(tmp)); + attr = tmp; + } + + if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { + fprintf(stderr, "Error: type %d has different attributes: " + "%s, %s\n", type, ttn->attr, attr); + exit(1); + } + + if (strlen(attr) > sizeof(ttn->attr) - 1) { + fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", + attr, typename); + exit(1); + } + + strncpy(ttn->attr, attr, sizeof(ttn->attr)); + ttn->attr[sizeof(ttn->attr) - 1] = '\0'; + + ttn->sorted = 0; + if (maxtype < type) + maxtype = type; +} + +static void +add(int rdclass, const char *classname, int type, const char *typename, + const char *dirname) +{ + struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); + struct tt *tt, *oldtt; + struct cc *newcc; + struct cc *cc, *oldcc; + + INSIST(strlen(typename) < TYPECLASSBUF); + INSIST(strlen(classname) < TYPECLASSBUF); + INSIST(strlen(dirname) < DIRNAMESIZE); + + insert_into_typenames(type, typename, NULL); + + if (newtt == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(1); + } + + newtt->next = NULL; + newtt->rdclass = rdclass; + newtt->type = type; + + strncpy(newtt->classname, classname, sizeof(newtt->classname)); + newtt->classname[sizeof(newtt->classname) - 1] = '\0'; + + strncpy(newtt->typename, typename, sizeof(newtt->typename)); + newtt->typename[sizeof(newtt->typename) - 1] = '\0'; + + if (strncmp(dirname, "./", 2) == 0) + dirname += 2; + strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); + newtt->dirname[sizeof(newtt->dirname) - 1] = '\0'; + + tt = types; + oldtt = NULL; + + while ((tt != NULL) && (tt->type < type)) { + oldtt = tt; + tt = tt->next; + } + + while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { + if (strcmp(tt->typename, typename) != 0) + exit(1); + oldtt = tt; + tt = tt->next; + } + + if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) + exit(1); + + newtt->next = tt; + if (oldtt != NULL) + oldtt->next = newtt; + else + types = newtt; + + /* + * Do a class switch for this type. + */ + if (rdclass == 0) + return; + + newcc = (struct cc *)malloc(sizeof(*newcc)); + if (newcc == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(1); + } + newcc->rdclass = rdclass; + strncpy(newcc->classname, classname, sizeof(newcc->classname)); + newcc->classname[sizeof(newcc->classname) - 1] = '\0'; + cc = classes; + oldcc = NULL; + + while ((cc != NULL) && (cc->rdclass < rdclass)) { + oldcc = cc; + cc = cc->next; + } + + if ((cc != NULL) && cc->rdclass == rdclass) { + free((char *)newcc); + return; + } + + newcc->next = cc; + if (oldcc != NULL) + oldcc->next = newcc; + else + classes = newcc; +} + +static void +sd(int rdclass, const char *classname, const char *dirname, char filetype) { + char buf[TYPECLASSLEN + sizeof("_65535.h")]; + char typename[TYPECLASSBUF]; + int type, n; + isc_dir_t dir; + + if (!start_directory(dirname, &dir)) + return; + + while (next_file(&dir)) { + if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) + continue; + if ((type > 65535) || (type < 0)) + continue; + + n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, + type, filetype); + INSIST(n > 0 && (unsigned)n < sizeof(buf)); + if (strcmp(buf, dir.filename) != 0) + continue; + add(rdclass, classname, type, typename, dirname); + } + + end_directory(&dir); +} + +static unsigned int +HASH(char *string) { + size_t n; + unsigned char a, b; + + n = strlen(string); + if (n == 0) { + fprintf(stderr, "n == 0?\n"); + exit(1); + } + a = tolower((unsigned char)string[0]); + b = tolower((unsigned char)string[n - 1]); + + return ((a + n) * b) % 256; +} + +int +main(int argc, char **argv) { + char buf[DIRNAMESIZE]; /* XXX Should be max path length */ + char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ + int rdclass; + char classname[TYPECLASSBUF]; + struct tt *tt; + struct cc *cc; + struct ttnam *ttn, *ttn2; + unsigned int hash; + struct tm *tm; + time_t now; + char year[11]; + int lasttype; + int code = 1; + int class_enum = 0; + int type_enum = 0; + int structs = 0; + int depend = 0; + int c, i, j, n; + char buf1[TYPECLASSBUF]; + char filetype = 'c'; + FILE *fd; + char *prefix = NULL; + char *suffix = NULL; + char *file = NULL; + isc_dir_t dir; + + for (i = 0; i < TYPENAMES; i++) + memset(&typenames[i], 0, sizeof(typenames[i])); + + srcdir[0] = '\0'; + while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) + switch (c) { + case 'c': + code = 0; + depend = 0; + type_enum = 0; + class_enum = 1; + filetype = 'c'; + structs = 0; + break; + case 'd': + code = 0; + depend = 1; + class_enum = 0; + type_enum = 0; + structs = 0; + filetype = 'h'; + break; + case 't': + code = 0; + depend = 0; + class_enum = 0; + type_enum = 1; + filetype = 'c'; + structs = 0; + break; + case 'i': + code = 0; + depend = 0; + class_enum = 0; + type_enum = 0; + structs = 1; + filetype = 'h'; + break; + case 's': + if (strlen(isc_commandline_argument) > + DIRNAMESIZE - 2 * TYPECLASSLEN - + sizeof("/rdata/_65535_65535")) { + fprintf(stderr, "\"%s\" too long\n", + isc_commandline_argument); + exit(1); + } + n = snprintf(srcdir, sizeof(srcdir), "%s/", + isc_commandline_argument); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); + break; + case 'F': + file = isc_commandline_argument; + break; + case 'P': + prefix = isc_commandline_argument; + break; + case 'S': + suffix = isc_commandline_argument; + break; + case '?': + exit(1); + } + + n = snprintf(buf, sizeof(buf), "%srdata", srcdir); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); + + if (!start_directory(buf, &dir)) + exit(1); + + while (next_file(&dir)) { + if (sscanf(dir.filename, TYPECLASSFMT, classname, + &rdclass) != 2) + continue; + if ((rdclass > 65535) || (rdclass < 0)) + continue; + + n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", + srcdir, classname, rdclass); + INSIST(n > 0 && (unsigned)n < sizeof(buf)); + if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) + continue; + sd(rdclass, classname, buf, filetype); + } + end_directory(&dir); + n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); + INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); + sd(0, "", buf, filetype); + + if (time(&now) != -1) { + if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { + n = snprintf(year, sizeof(year), "-%d", + tm->tm_year + 1900); + INSIST(n > 0 && (unsigned)n < sizeof(year)); + } else { + snprintf(year, sizeof(year), "-2016"); + } + } else { + snprintf(year, sizeof(year), "-2016"); + } + + if (!depend) + fprintf(stdout, copyright, year); + + if (code) { + fputs("#ifndef DNS_CODE_H\n", stdout); + fputs("#define DNS_CODE_H 1\n\n", stdout); + + fputs("#include <isc/result.h>\n\n", stdout); + fputs("#include <dns/name.h>\n\n", stdout); + + for (tt = types; tt != NULL; tt = tt->next) + fprintf(stdout, "#include \"%s/%s_%d.c\"\n", + tt->dirname, tt->typename, tt->type); + + fputs("\n\n", stdout); + + doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, + FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); + doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, + TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); + doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, + FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); + doswitch("TOWIRESWITCH", "towire", TOWIREARGS, + TOWIRETYPE, TOWIRECLASS, TOWIREDEF); + doswitch("COMPARESWITCH", "compare", COMPAREARGS, + COMPARETYPE, COMPARECLASS, COMPAREDEF); + doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, + COMPARETYPE, COMPARECLASS, COMPAREDEF); + doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, + FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); + doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, + TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); + doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, + FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); + doswitch("ADDITIONALDATASWITCH", "additionaldata", + ADDITIONALDATAARGS, ADDITIONALDATATYPE, + ADDITIONALDATACLASS, ADDITIONALDATADEF); + doswitch("DIGESTSWITCH", "digest", + DIGESTARGS, DIGESTTYPE, + DIGESTCLASS, DIGESTDEF); + doswitch("CHECKOWNERSWITCH", "checkowner", + CHECKOWNERARGS, CHECKOWNERTYPE, + CHECKOWNERCLASS, CHECKOWNERDEF); + doswitch("CHECKNAMESSWITCH", "checknames", + CHECKNAMESARGS, CHECKNAMESTYPE, + CHECKNAMESCLASS, CHECKNAMESDEF); + + /* + * From here down, we are processing the rdata names and + * attributes. + */ + +#define PRINT_COMMA(x) (x == maxtype ? "" : ",") + +#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ + "DNS_RDATATYPEATTR_NOTQUESTION" +#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ + "DNS_RDATATYPEATTR_QUESTIONONLY" +#define RESERVED "DNS_RDATATYPEATTR_RESERVED" + + /* + * Add in reserved/special types. This will let us + * sort them without special cases. + */ + insert_into_typenames(0, "reserved0", RESERVED); + insert_into_typenames(31, "eid", RESERVED); + insert_into_typenames(32, "nimloc", RESERVED); + insert_into_typenames(34, "atma", RESERVED); + insert_into_typenames(100, "uinfo", RESERVED); + insert_into_typenames(101, "uid", RESERVED); + insert_into_typenames(102, "gid", RESERVED); + insert_into_typenames(251, "ixfr", METAQUESTIONONLY); + insert_into_typenames(252, "axfr", METAQUESTIONONLY); + insert_into_typenames(253, "mailb", METAQUESTIONONLY); + insert_into_typenames(254, "maila", METAQUESTIONONLY); + insert_into_typenames(255, "any", METAQUESTIONONLY); + + /* + * Spit out a quick and dirty hash function. Here, + * we walk through the list of type names, and calculate + * a hash. This isn't perfect, but it will generate "pretty + * good" estimates. Lowercase the characters before + * computing in all cases. + * + * Here, walk the list from top to bottom, calculating + * the hash (mod 256) for each name. + */ + fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); + fprintf(stdout, "\tdo { \\\n"); + fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" + "\t\t strncasecmp(_s,(_tn)," + "(sizeof(_s) - 1)) == 0) { \\\n"); + fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " + "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); + fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); + fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); + fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); + fprintf(stdout, "\t\t} \\\n"); + fprintf(stdout, "\t} while (0)\n\n"); + + fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," + "_typename,_length,_typep) \\\n"); + fprintf(stdout, "\tswitch (_hash) { \\\n"); + for (i = 0; i <= maxtype; i++) { + ttn = find_typename(i); + if (ttn == NULL) + continue; + + /* + * Skip entries we already processed. + */ + if (ttn->sorted != 0) + continue; + + hash = HASH(ttn->typename); + fprintf(stdout, "\t\tcase %u: \\\n", hash); + + /* + * Find all other entries that happen to match + * this hash. + */ + for (j = 0; j <= maxtype; j++) { + ttn2 = find_typename(j); + if (ttn2 == NULL) + continue; + if (hash == HASH(ttn2->typename)) { + fprintf(stdout, "\t\t\tRDATATYPE_COMPARE" + "(\"%s\", %d, " + "_typename, _length, _typep); \\\n", + ttn2->typename, ttn2->type); + ttn2->sorted = 1; + } + } + fprintf(stdout, "\t\t\tbreak; \\\n"); + } + fprintf(stdout, "\t}\n"); + + fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); + fprintf(stdout, "\tswitch (type) { \\\n"); + for (i = 0; i <= maxtype; i++) { + ttn = find_typename(i); + if (ttn == NULL) + continue; + fprintf(stdout, "\tcase %d: return (%s); \\\n", + i, upper(ttn->attr)); + } + fprintf(stdout, "\t}\n"); + + fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); + fprintf(stdout, "\tswitch (type) { \\\n"); + for (i = 0; i <= maxtype; i++) { + ttn = find_typename(i); + if (ttn == NULL) + continue; + /* + * Remove KEYDATA (65533) from the type to memonic + * translation as it is internal use only. This + * stops the tools from displaying KEYDATA instead + * of TYPE65533. + */ + if (i == 65533U) + continue; + fprintf(stdout, "\tcase %d: return " + "(str_totext(\"%s\", target)); \\\n", + i, upper(ttn->typename)); + } + fprintf(stdout, "\t}\n"); + + fputs("#endif /* DNS_CODE_H */\n", stdout); + } else if (type_enum) { + char *s; + + fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); + fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); + + fprintf(stdout, "enum {\n"); + fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); + + lasttype = 0; + for (tt = types; tt != NULL; tt = tt->next) + if (tt->type != lasttype) + fprintf(stdout, + "\tdns_rdatatype_%s = %d,\n", + funname(tt->typename, buf1), + lasttype = tt->type); + + fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); + fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); + fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); + fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); + fprintf(stdout, "\tdns_rdatatype_any = 255\n"); + + fprintf(stdout, "};\n\n"); + + fprintf(stdout, "#define dns_rdatatype_none\t" + "((dns_rdatatype_t)dns_rdatatype_none)\n"); + + for (tt = types; tt != NULL; tt = tt->next) + if (tt->type != lasttype) { + s = funname(tt->typename, buf1); + fprintf(stdout, + "#define dns_rdatatype_%s\t%s" + "((dns_rdatatype_t)dns_rdatatype_%s)" + "\n", + s, strlen(s) < 2U ? "\t" : "", s); + lasttype = tt->type; + } + + fprintf(stdout, "#define dns_rdatatype_ixfr\t" + "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); + fprintf(stdout, "#define dns_rdatatype_axfr\t" + "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); + fprintf(stdout, "#define dns_rdatatype_mailb\t" + "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); + fprintf(stdout, "#define dns_rdatatype_maila\t" + "((dns_rdatatype_t)dns_rdatatype_maila)\n"); + fprintf(stdout, "#define dns_rdatatype_any\t" + "((dns_rdatatype_t)dns_rdatatype_any)\n"); + + fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); + + } else if (class_enum) { + char *s; + int classnum; + + fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); + fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); + + fprintf(stdout, "enum {\n"); + + fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); + fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" + "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); + +#define PRINTCLASS(name, num) \ + do { \ + s = funname(name, buf1); \ + classnum = num; \ + fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ + classnum != 255 ? "," : ""); \ + fprintf(stdout, "#define dns_rdataclass_%s\t" \ + "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ + } while (0) + + for (cc = classes; cc != NULL; cc = cc->next) { + if (cc->rdclass == 3) + PRINTCLASS("chaos", 3); + else if (cc->rdclass == 255) + PRINTCLASS("none", 254); + PRINTCLASS(cc->classname, cc->rdclass); + } + +#undef PRINTCLASS + + fprintf(stdout, "};\n\n"); + fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); + } else if (structs) { + if (prefix != NULL) { + if ((fd = fopen(prefix,"r")) != NULL) { + while (fgets(buf, sizeof(buf), fd) != NULL) + fputs(buf, stdout); + fclose(fd); + } + } + for (tt = types; tt != NULL; tt = tt->next) { + snprintf(buf, sizeof(buf), "%s/%s_%d.h", + tt->dirname, tt->typename, tt->type); + if ((fd = fopen(buf,"r")) != NULL) { + while (fgets(buf, sizeof(buf), fd) != NULL) + fputs(buf, stdout); + fclose(fd); + } + } + if (suffix != NULL) { + if ((fd = fopen(suffix,"r")) != NULL) { + while (fgets(buf, sizeof(buf), fd) != NULL) + fputs(buf, stdout); + fclose(fd); + } + } + } else if (depend) { + for (tt = types; tt != NULL; tt = tt->next) + fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, + tt->dirname, tt->typename, tt->type); + } + + if (ferror(stdout) != 0) + exit(1); + + return (0); +} |