gen.c revision 254402
1135446Strhodes/* 2254402Serwin * Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1998-2003 Internet Software Consortium. 4135446Strhodes * 5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18170222Sdougb/*! \file */ 19170222Sdougb 20165071Sdougb#ifdef WIN32 21165071Sdougb/* 22165071Sdougb * Silence compiler warnings about using strcpy and friends. 23165071Sdougb */ 24165071Sdougb#define _CRT_SECURE_NO_DEPRECATE 1 25254402Serwin/* 26254402Serwin * We use snprintf. 27254402Serwin */ 28254402Serwin#define snprintf _snprintf 29165071Sdougb#endif 30135446Strhodes 31135446Strhodes#include <sys/types.h> 32135446Strhodes 33135446Strhodes#include <ctype.h> 34135446Strhodes#include <stdlib.h> 35135446Strhodes#include <stdio.h> 36135446Strhodes#include <stdlib.h> 37135446Strhodes#include <string.h> 38135446Strhodes#include <time.h> 39135446Strhodes 40135446Strhodes#ifdef WIN32 41135446Strhodes#include "gen-win32.h" 42135446Strhodes#else 43135446Strhodes#include "gen-unix.h" 44135446Strhodes#endif 45135446Strhodes 46254402Serwin#define INSIST(cond) \ 47254402Serwin if (!(cond)) { \ 48254402Serwin fprintf(stderr, "%s:%d: INSIST(%s)\n", \ 49254402Serwin __FILE__, __LINE__, #cond); \ 50254402Serwin abort(); \ 51254402Serwin } 52193149Sdougb 53135446Strhodes#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" 54135446Strhodes#define FROMTEXTCLASS "rdclass" 55135446Strhodes#define FROMTEXTTYPE "type" 56135446Strhodes#define FROMTEXTDEF "result = DNS_R_UNKNOWN" 57135446Strhodes 58135446Strhodes#define TOTEXTARGS "rdata, tctx, target" 59135446Strhodes#define TOTEXTCLASS "rdata->rdclass" 60135446Strhodes#define TOTEXTTYPE "rdata->type" 61135446Strhodes#define TOTEXTDEF "use_default = ISC_TRUE" 62135446Strhodes 63135446Strhodes#define FROMWIREARGS "rdclass, type, source, dctx, options, target" 64135446Strhodes#define FROMWIRECLASS "rdclass" 65135446Strhodes#define FROMWIRETYPE "type" 66135446Strhodes#define FROMWIREDEF "use_default = ISC_TRUE" 67135446Strhodes 68135446Strhodes#define TOWIREARGS "rdata, cctx, target" 69135446Strhodes#define TOWIRECLASS "rdata->rdclass" 70135446Strhodes#define TOWIRETYPE "rdata->type" 71135446Strhodes#define TOWIREDEF "use_default = ISC_TRUE" 72135446Strhodes 73135446Strhodes#define FROMSTRUCTARGS "rdclass, type, source, target" 74135446Strhodes#define FROMSTRUCTCLASS "rdclass" 75135446Strhodes#define FROMSTRUCTTYPE "type" 76135446Strhodes#define FROMSTRUCTDEF "use_default = ISC_TRUE" 77135446Strhodes 78135446Strhodes#define TOSTRUCTARGS "rdata, target, mctx" 79135446Strhodes#define TOSTRUCTCLASS "rdata->rdclass" 80135446Strhodes#define TOSTRUCTTYPE "rdata->type" 81135446Strhodes#define TOSTRUCTDEF "use_default = ISC_TRUE" 82135446Strhodes 83135446Strhodes#define FREESTRUCTARGS "source" 84135446Strhodes#define FREESTRUCTCLASS "common->rdclass" 85135446Strhodes#define FREESTRUCTTYPE "common->rdtype" 86135446Strhodes#define FREESTRUCTDEF NULL 87135446Strhodes 88135446Strhodes#define COMPAREARGS "rdata1, rdata2" 89135446Strhodes#define COMPARECLASS "rdata1->rdclass" 90135446Strhodes#define COMPARETYPE "rdata1->type" 91135446Strhodes#define COMPAREDEF "use_default = ISC_TRUE" 92135446Strhodes 93135446Strhodes#define ADDITIONALDATAARGS "rdata, add, arg" 94135446Strhodes#define ADDITIONALDATACLASS "rdata->rdclass" 95135446Strhodes#define ADDITIONALDATATYPE "rdata->type" 96135446Strhodes#define ADDITIONALDATADEF "use_default = ISC_TRUE" 97135446Strhodes 98135446Strhodes#define DIGESTARGS "rdata, digest, arg" 99135446Strhodes#define DIGESTCLASS "rdata->rdclass" 100135446Strhodes#define DIGESTTYPE "rdata->type" 101135446Strhodes#define DIGESTDEF "use_default = ISC_TRUE" 102135446Strhodes 103135446Strhodes#define CHECKOWNERARGS "name, rdclass, type, wildcard" 104135446Strhodes#define CHECKOWNERCLASS "rdclass" 105135446Strhodes#define CHECKOWNERTYPE "type" 106135446Strhodes#define CHECKOWNERDEF "result = ISC_TRUE" 107135446Strhodes 108135446Strhodes#define CHECKNAMESARGS "rdata, owner, bad" 109135446Strhodes#define CHECKNAMESCLASS "rdata->rdclass" 110135446Strhodes#define CHECKNAMESTYPE "rdata->type" 111135446Strhodes#define CHECKNAMESDEF "result = ISC_TRUE" 112135446Strhodes 113254402Serwinstatic const char copyright[] = 114135446Strhodes"/*\n" 115135446Strhodes" * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n" 116135446Strhodes" * Copyright (C) 1998-2003 Internet Software Consortium.\n" 117135446Strhodes" *\n" 118135446Strhodes" * Permission to use, copy, modify, and distribute this software for any\n" 119135446Strhodes" * purpose with or without fee is hereby granted, provided that the above\n" 120135446Strhodes" * copyright notice and this permission notice appear in all copies.\n" 121135446Strhodes" *\n" 122135446Strhodes" * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n" 123135446Strhodes" * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n" 124135446Strhodes" * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n" 125135446Strhodes" * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n" 126135446Strhodes" * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n" 127135446Strhodes" * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n" 128135446Strhodes" * PERFORMANCE OF THIS SOFTWARE.\n" 129135446Strhodes" */\n" 130135446Strhodes"\n" 131135446Strhodes"/***************\n" 132135446Strhodes" ***************\n" 133135446Strhodes" *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n" 134135446Strhodes" *************** DO NOT EDIT!\n" 135135446Strhodes" ***************\n" 136135446Strhodes" ***************/\n" 137170222Sdougb"\n" 138170222Sdougb"/*! \\file */\n" 139135446Strhodes"\n"; 140135446Strhodes 141254402Serwin#define STR_EXPAND(tok) #tok 142254402Serwin#define STR(tok) STR_EXPAND(tok) 143254402Serwin 144135446Strhodes#define TYPENAMES 256 145254402Serwin#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ 146254402Serwin#define TYPECLASSBUF (TYPECLASSLEN + 1) 147254402Serwin#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" 148254402Serwin#define ATTRIBUTESIZE 256 149254402Serwin#define DIRNAMESIZE 256 150135446Strhodes 151254402Serwinstatic struct cc { 152135446Strhodes struct cc *next; 153135446Strhodes int rdclass; 154254402Serwin char classname[TYPECLASSBUF]; 155135446Strhodes} *classes; 156135446Strhodes 157254402Serwinstatic struct tt { 158135446Strhodes struct tt *next; 159135446Strhodes int rdclass; 160135446Strhodes int type; 161254402Serwin char classname[TYPECLASSBUF]; 162254402Serwin char typename[TYPECLASSBUF]; 163254402Serwin char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ 164135446Strhodes} *types; 165135446Strhodes 166254402Serwinstatic struct ttnam { 167254402Serwin char typename[TYPECLASSBUF]; 168254402Serwin char macroname[TYPECLASSBUF]; 169254402Serwin char attr[ATTRIBUTESIZE]; 170135446Strhodes unsigned int sorted; 171135446Strhodes int type; 172135446Strhodes} typenames[TYPENAMES]; 173135446Strhodes 174254402Serwinstatic int maxtype = -1; 175135446Strhodes 176254402Serwinstatic char * 177135446Strhodesupper(char *); 178254402Serwinstatic char * 179135446Strhodesfunname(const char *, char *); 180254402Serwinstatic void 181135446Strhodesdoswitch(const char *, const char *, const char *, const char *, 182135446Strhodes const char *, const char *); 183254402Serwinstatic void 184135446Strhodesadd(int, const char *, int, const char *, const char *); 185254402Serwinstatic void 186135446Strhodessd(int, const char *, const char *, char); 187254402Serwinstatic void 188135446Strhodesinsert_into_typenames(int, const char *, const char *); 189135446Strhodes 190170222Sdougb/*% 191135446Strhodes * If you use more than 10 of these in, say, a printf(), you'll have problems. 192135446Strhodes */ 193254402Serwinstatic char * 194135446Strhodesupper(char *s) { 195135446Strhodes static int buf_to_use = 0; 196135446Strhodes static char buf[10][256]; 197135446Strhodes char *b; 198135446Strhodes int c; 199135446Strhodes 200135446Strhodes buf_to_use++; 201135446Strhodes if (buf_to_use > 9) 202135446Strhodes buf_to_use = 0; 203135446Strhodes 204135446Strhodes b = buf[buf_to_use]; 205135446Strhodes memset(b, 0, 256); 206135446Strhodes 207135446Strhodes while ((c = (*s++) & 0xff)) 208135446Strhodes *b++ = islower(c) ? toupper(c) : c; 209135446Strhodes *b = '\0'; 210135446Strhodes return (buf[buf_to_use]); 211135446Strhodes} 212135446Strhodes 213254402Serwinstatic char * 214135446Strhodesfunname(const char *s, char *buf) { 215135446Strhodes char *b = buf; 216135446Strhodes char c; 217135446Strhodes 218254402Serwin INSIST(strlen(s) < TYPECLASSBUF); 219135446Strhodes while ((c = *s++)) { 220135446Strhodes *b++ = (c == '-') ? '_' : c; 221135446Strhodes } 222135446Strhodes *b = '\0'; 223135446Strhodes return (buf); 224135446Strhodes} 225135446Strhodes 226254402Serwinstatic void 227135446Strhodesdoswitch(const char *name, const char *function, const char *args, 228135446Strhodes const char *tsw, const char *csw, const char *res) 229135446Strhodes{ 230135446Strhodes struct tt *tt; 231135446Strhodes int first = 1; 232135446Strhodes int lasttype = 0; 233135446Strhodes int subswitch = 0; 234254402Serwin char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; 235135446Strhodes const char *result = " result ="; 236135446Strhodes 237135446Strhodes if (res == NULL) 238135446Strhodes result = ""; 239135446Strhodes 240135446Strhodes for (tt = types; tt != NULL; tt = tt->next) { 241135446Strhodes if (first) { 242135446Strhodes fprintf(stdout, "\n#define %s \\\n", name); 243135446Strhodes fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw); 244135446Strhodes first = 0; 245135446Strhodes } 246135446Strhodes if (tt->type != lasttype && subswitch) { 247135446Strhodes if (res == NULL) 248135446Strhodes fprintf(stdout, "\t\tdefault: break; \\\n"); 249135446Strhodes else 250135446Strhodes fprintf(stdout, 251135446Strhodes "\t\tdefault: %s; break; \\\n", res); 252135446Strhodes fputs(/*{*/ "\t\t} \\\n", stdout); 253135446Strhodes fputs("\t\tbreak; \\\n", stdout); 254135446Strhodes subswitch = 0; 255135446Strhodes } 256135446Strhodes if (tt->rdclass && tt->type != lasttype) { 257135446Strhodes fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/, 258135446Strhodes tt->type, csw); 259135446Strhodes subswitch = 1; 260135446Strhodes } 261135446Strhodes if (tt->rdclass == 0) 262135446Strhodes fprintf(stdout, 263135446Strhodes "\tcase %d:%s %s_%s(%s); break;", 264135446Strhodes tt->type, result, function, 265135446Strhodes funname(tt->typename, buf1), args); 266135446Strhodes else 267135446Strhodes fprintf(stdout, 268135446Strhodes "\t\tcase %d:%s %s_%s_%s(%s); break;", 269135446Strhodes tt->rdclass, result, function, 270135446Strhodes funname(tt->classname, buf1), 271135446Strhodes funname(tt->typename, buf2), args); 272135446Strhodes fputs(" \\\n", stdout); 273135446Strhodes lasttype = tt->type; 274135446Strhodes } 275135446Strhodes if (subswitch) { 276135446Strhodes if (res == NULL) 277135446Strhodes fprintf(stdout, "\t\tdefault: break; \\\n"); 278135446Strhodes else 279135446Strhodes fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); 280135446Strhodes fputs(/*{*/ "\t\t} \\\n", stdout); 281135446Strhodes fputs("\t\tbreak; \\\n", stdout); 282135446Strhodes } 283135446Strhodes if (first) { 284135446Strhodes if (res == NULL) 285135446Strhodes fprintf(stdout, "\n#define %s\n", name); 286135446Strhodes else 287135446Strhodes fprintf(stdout, "\n#define %s %s;\n", name, res); 288135446Strhodes } else { 289135446Strhodes if (res == NULL) 290135446Strhodes fprintf(stdout, "\tdefault: break; \\\n"); 291135446Strhodes else 292135446Strhodes fprintf(stdout, "\tdefault: %s; break; \\\n", res); 293135446Strhodes fputs(/*{*/ "\t}\n", stdout); 294135446Strhodes } 295135446Strhodes} 296135446Strhodes 297135446Strhodesstatic struct ttnam * 298135446Strhodesfind_typename(int type) { 299135446Strhodes int i; 300135446Strhodes 301135446Strhodes for (i = 0; i < TYPENAMES; i++) { 302135446Strhodes if (typenames[i].typename[0] != 0 && 303135446Strhodes typenames[i].type == type) 304135446Strhodes return (&typenames[i]); 305135446Strhodes } 306135446Strhodes return (NULL); 307135446Strhodes} 308135446Strhodes 309254402Serwinstatic void 310135446Strhodesinsert_into_typenames(int type, const char *typename, const char *attr) { 311135446Strhodes struct ttnam *ttn = NULL; 312254402Serwin int c, i, n; 313135446Strhodes char tmp[256]; 314135446Strhodes 315254402Serwin INSIST(strlen(typename) < TYPECLASSBUF); 316135446Strhodes for (i = 0; i < TYPENAMES; i++) { 317135446Strhodes if (typenames[i].typename[0] != 0 && 318135446Strhodes typenames[i].type == type && 319135446Strhodes strcmp(typename, typenames[i].typename) != 0) { 320135446Strhodes fprintf(stderr, 321135446Strhodes "Error: type %d has two names: %s, %s\n", 322135446Strhodes type, typenames[i].typename, typename); 323135446Strhodes exit(1); 324135446Strhodes } 325135446Strhodes if (typenames[i].typename[0] == 0 && ttn == NULL) 326135446Strhodes ttn = &typenames[i]; 327135446Strhodes } 328135446Strhodes if (ttn == NULL) { 329135446Strhodes fprintf(stderr, "Error: typenames array too small\n"); 330135446Strhodes exit(1); 331135446Strhodes } 332193149Sdougb 333135446Strhodes if (strlen(typename) > sizeof(ttn->typename) - 1) { 334135446Strhodes fprintf(stderr, "Error: type name %s is too long\n", 335135446Strhodes typename); 336135446Strhodes exit(1); 337135446Strhodes } 338254402Serwin strncpy(ttn->typename, typename, sizeof(ttn->typename)); 339135446Strhodes ttn->type = type; 340135446Strhodes 341254402Serwin strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); 342135446Strhodes c = strlen(ttn->macroname); 343135446Strhodes while (c > 0) { 344135446Strhodes if (ttn->macroname[c - 1] == '-') 345135446Strhodes ttn->macroname[c - 1] = '_'; 346135446Strhodes c--; 347135446Strhodes } 348135446Strhodes 349135446Strhodes if (attr == NULL) { 350254402Serwin n = snprintf(tmp, sizeof(tmp), 351254402Serwin "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); 352254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(tmp)); 353135446Strhodes attr = tmp; 354135446Strhodes } 355135446Strhodes 356135446Strhodes if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { 357135446Strhodes fprintf(stderr, "Error: type %d has different attributes: " 358135446Strhodes "%s, %s\n", type, ttn->attr, attr); 359135446Strhodes exit(1); 360135446Strhodes } 361135446Strhodes 362135446Strhodes if (strlen(attr) > sizeof(ttn->attr) - 1) { 363135446Strhodes fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", 364135446Strhodes attr, typename); 365135446Strhodes exit(1); 366135446Strhodes } 367254402Serwin strncpy(ttn->attr, attr, sizeof(ttn->attr)); 368135446Strhodes ttn->sorted = 0; 369135446Strhodes if (maxtype < type) 370135446Strhodes maxtype = type; 371135446Strhodes} 372135446Strhodes 373254402Serwinstatic void 374135446Strhodesadd(int rdclass, const char *classname, int type, const char *typename, 375135446Strhodes const char *dirname) 376135446Strhodes{ 377135446Strhodes struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); 378135446Strhodes struct tt *tt, *oldtt; 379135446Strhodes struct cc *newcc; 380135446Strhodes struct cc *cc, *oldcc; 381135446Strhodes 382254402Serwin INSIST(strlen(typename) < TYPECLASSBUF); 383254402Serwin INSIST(strlen(classname) < TYPECLASSBUF); 384254402Serwin INSIST(strlen(dirname) < DIRNAMESIZE); 385254402Serwin 386135446Strhodes insert_into_typenames(type, typename, NULL); 387135446Strhodes 388135446Strhodes if (newtt == NULL) { 389135446Strhodes fprintf(stderr, "malloc() failed\n"); 390135446Strhodes exit(1); 391135446Strhodes } 392135446Strhodes 393135446Strhodes newtt->next = NULL; 394135446Strhodes newtt->rdclass = rdclass; 395135446Strhodes newtt->type = type; 396254402Serwin strncpy(newtt->classname, classname, sizeof(newtt->classname)); 397254402Serwin strncpy(newtt->typename, typename, sizeof(newtt->typename)); 398193149Sdougb if (strncmp(dirname, "./", 2) == 0) 399193149Sdougb dirname += 2; 400254402Serwin strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); 401135446Strhodes 402135446Strhodes tt = types; 403135446Strhodes oldtt = NULL; 404135446Strhodes 405135446Strhodes while ((tt != NULL) && (tt->type < type)) { 406135446Strhodes oldtt = tt; 407135446Strhodes tt = tt->next; 408135446Strhodes } 409135446Strhodes 410135446Strhodes while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { 411135446Strhodes if (strcmp(tt->typename, typename) != 0) 412135446Strhodes exit(1); 413135446Strhodes oldtt = tt; 414135446Strhodes tt = tt->next; 415135446Strhodes } 416135446Strhodes 417135446Strhodes if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) 418135446Strhodes exit(1); 419135446Strhodes 420135446Strhodes newtt->next = tt; 421135446Strhodes if (oldtt != NULL) 422135446Strhodes oldtt->next = newtt; 423135446Strhodes else 424135446Strhodes types = newtt; 425135446Strhodes 426135446Strhodes /* 427135446Strhodes * Do a class switch for this type. 428135446Strhodes */ 429135446Strhodes if (rdclass == 0) 430135446Strhodes return; 431135446Strhodes 432135446Strhodes newcc = (struct cc *)malloc(sizeof(*newcc)); 433254402Serwin if (newcc == NULL) { 434254402Serwin fprintf(stderr, "malloc() failed\n"); 435254402Serwin exit(1); 436254402Serwin } 437135446Strhodes newcc->rdclass = rdclass; 438254402Serwin strncpy(newcc->classname, classname, sizeof(newcc->classname)); 439135446Strhodes cc = classes; 440135446Strhodes oldcc = NULL; 441135446Strhodes 442135446Strhodes while ((cc != NULL) && (cc->rdclass < rdclass)) { 443135446Strhodes oldcc = cc; 444135446Strhodes cc = cc->next; 445135446Strhodes } 446135446Strhodes 447135446Strhodes if ((cc != NULL) && cc->rdclass == rdclass) { 448135446Strhodes free((char *)newcc); 449135446Strhodes return; 450135446Strhodes } 451135446Strhodes 452135446Strhodes newcc->next = cc; 453135446Strhodes if (oldcc != NULL) 454135446Strhodes oldcc->next = newcc; 455135446Strhodes else 456135446Strhodes classes = newcc; 457135446Strhodes} 458135446Strhodes 459254402Serwinstatic void 460135446Strhodessd(int rdclass, const char *classname, const char *dirname, char filetype) { 461254402Serwin char buf[TYPECLASSLEN + sizeof("_65535.h")]; 462254402Serwin char typename[TYPECLASSBUF]; 463254402Serwin int type, n; 464135446Strhodes isc_dir_t dir; 465135446Strhodes 466135446Strhodes if (!start_directory(dirname, &dir)) 467135446Strhodes return; 468135446Strhodes 469135446Strhodes while (next_file(&dir)) { 470254402Serwin if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) 471135446Strhodes continue; 472135446Strhodes if ((type > 65535) || (type < 0)) 473135446Strhodes continue; 474135446Strhodes 475254402Serwin n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, 476254402Serwin type, filetype); 477254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(buf)); 478135446Strhodes if (strcmp(buf, dir.filename) != 0) 479135446Strhodes continue; 480135446Strhodes add(rdclass, classname, type, typename, dirname); 481135446Strhodes } 482135446Strhodes 483135446Strhodes end_directory(&dir); 484135446Strhodes} 485135446Strhodes 486135446Strhodesstatic unsigned int 487135446StrhodesHASH(char *string) { 488135446Strhodes unsigned int n; 489135446Strhodes unsigned char a, b; 490135446Strhodes 491135446Strhodes n = strlen(string); 492135446Strhodes if (n == 0) { 493135446Strhodes fprintf(stderr, "n == 0?\n"); 494135446Strhodes exit(1); 495135446Strhodes } 496135446Strhodes a = tolower((unsigned char)string[0]); 497135446Strhodes b = tolower((unsigned char)string[n - 1]); 498135446Strhodes 499135446Strhodes return ((a + n) * b) % 256; 500135446Strhodes} 501135446Strhodes 502135446Strhodesint 503135446Strhodesmain(int argc, char **argv) { 504254402Serwin char buf[DIRNAMESIZE]; /* XXX Should be max path length */ 505254402Serwin char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ 506135446Strhodes int rdclass; 507254402Serwin char classname[TYPECLASSBUF]; 508135446Strhodes struct tt *tt; 509135446Strhodes struct cc *cc; 510135446Strhodes struct ttnam *ttn, *ttn2; 511135446Strhodes unsigned int hash; 512135446Strhodes struct tm *tm; 513135446Strhodes time_t now; 514135446Strhodes char year[11]; 515135446Strhodes int lasttype; 516135446Strhodes int code = 1; 517135446Strhodes int class_enum = 0; 518135446Strhodes int type_enum = 0; 519135446Strhodes int structs = 0; 520135446Strhodes int depend = 0; 521254402Serwin int c, i, j, n; 522254402Serwin char buf1[TYPECLASSBUF]; 523135446Strhodes char filetype = 'c'; 524135446Strhodes FILE *fd; 525135446Strhodes char *prefix = NULL; 526135446Strhodes char *suffix = NULL; 527135446Strhodes char *file = NULL; 528135446Strhodes isc_dir_t dir; 529135446Strhodes 530135446Strhodes for (i = 0; i < TYPENAMES; i++) 531135446Strhodes memset(&typenames[i], 0, sizeof(typenames[i])); 532135446Strhodes 533135446Strhodes strcpy(srcdir, ""); 534135446Strhodes while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) 535135446Strhodes switch (c) { 536135446Strhodes case 'c': 537135446Strhodes code = 0; 538135446Strhodes depend = 0; 539135446Strhodes type_enum = 0; 540135446Strhodes class_enum = 1; 541135446Strhodes filetype = 'c'; 542135446Strhodes structs = 0; 543135446Strhodes break; 544135446Strhodes case 'd': 545135446Strhodes code = 0; 546135446Strhodes depend = 1; 547135446Strhodes class_enum = 0; 548135446Strhodes type_enum = 0; 549135446Strhodes structs = 0; 550135446Strhodes filetype = 'h'; 551135446Strhodes break; 552135446Strhodes case 't': 553135446Strhodes code = 0; 554135446Strhodes depend = 0; 555135446Strhodes class_enum = 0; 556135446Strhodes type_enum = 1; 557135446Strhodes filetype = 'c'; 558135446Strhodes structs = 0; 559135446Strhodes break; 560135446Strhodes case 'i': 561135446Strhodes code = 0; 562135446Strhodes depend = 0; 563135446Strhodes class_enum = 0; 564135446Strhodes type_enum = 0; 565135446Strhodes structs = 1; 566135446Strhodes filetype = 'h'; 567135446Strhodes break; 568135446Strhodes case 's': 569254402Serwin if (strlen(isc_commandline_argument) > 570254402Serwin DIRNAMESIZE - 2 * TYPECLASSLEN - 571254402Serwin sizeof("/rdata/_65535_65535")) { 572254402Serwin fprintf(stderr, "\"%s\" too long\n", 573254402Serwin isc_commandline_argument); 574254402Serwin exit(1); 575254402Serwin } 576254402Serwin n = snprintf(srcdir, sizeof(srcdir), "%s/", 577254402Serwin isc_commandline_argument); 578254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 579135446Strhodes break; 580135446Strhodes case 'F': 581135446Strhodes file = isc_commandline_argument; 582135446Strhodes break; 583135446Strhodes case 'P': 584135446Strhodes prefix = isc_commandline_argument; 585135446Strhodes break; 586135446Strhodes case 'S': 587135446Strhodes suffix = isc_commandline_argument; 588135446Strhodes break; 589135446Strhodes case '?': 590135446Strhodes exit(1); 591135446Strhodes } 592135446Strhodes 593254402Serwin n = snprintf(buf, sizeof(buf), "%srdata", srcdir); 594254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 595135446Strhodes 596135446Strhodes if (!start_directory(buf, &dir)) 597135446Strhodes exit(1); 598135446Strhodes 599135446Strhodes while (next_file(&dir)) { 600254402Serwin if (sscanf(dir.filename, TYPECLASSFMT, classname, 601254402Serwin &rdclass) != 2) 602135446Strhodes continue; 603135446Strhodes if ((rdclass > 65535) || (rdclass < 0)) 604135446Strhodes continue; 605135446Strhodes 606254402Serwin n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", 607254402Serwin srcdir, classname, rdclass); 608254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(buf)); 609135446Strhodes if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) 610135446Strhodes continue; 611135446Strhodes sd(rdclass, classname, buf, filetype); 612135446Strhodes } 613135446Strhodes end_directory(&dir); 614254402Serwin n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); 615254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 616135446Strhodes sd(0, "", buf, filetype); 617135446Strhodes 618135446Strhodes if (time(&now) != -1) { 619254402Serwin if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { 620254402Serwin n = snprintf(year, sizeof(year), "-%d", 621254402Serwin tm->tm_year + 1900); 622254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(year)); 623254402Serwin } else 624135446Strhodes year[0] = 0; 625135446Strhodes } else 626135446Strhodes year[0] = 0; 627135446Strhodes 628135446Strhodes if (!depend) fprintf(stdout, copyright, year); 629135446Strhodes 630135446Strhodes if (code) { 631135446Strhodes fputs("#ifndef DNS_CODE_H\n", stdout); 632135446Strhodes fputs("#define DNS_CODE_H 1\n\n", stdout); 633135446Strhodes 634135446Strhodes fputs("#include <isc/boolean.h>\n", stdout); 635135446Strhodes fputs("#include <isc/result.h>\n\n", stdout); 636135446Strhodes fputs("#include <dns/name.h>\n\n", stdout); 637135446Strhodes 638135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 639135446Strhodes fprintf(stdout, "#include \"%s/%s_%d.c\"\n", 640135446Strhodes tt->dirname, tt->typename, tt->type); 641135446Strhodes 642135446Strhodes fputs("\n\n", stdout); 643135446Strhodes 644135446Strhodes doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, 645135446Strhodes FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); 646135446Strhodes doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, 647135446Strhodes TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); 648135446Strhodes doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, 649135446Strhodes FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); 650135446Strhodes doswitch("TOWIRESWITCH", "towire", TOWIREARGS, 651135446Strhodes TOWIRETYPE, TOWIRECLASS, TOWIREDEF); 652135446Strhodes doswitch("COMPARESWITCH", "compare", COMPAREARGS, 653135446Strhodes COMPARETYPE, COMPARECLASS, COMPAREDEF); 654224092Sdougb doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, 655224092Sdougb COMPARETYPE, COMPARECLASS, COMPAREDEF); 656135446Strhodes doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, 657135446Strhodes FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); 658135446Strhodes doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, 659135446Strhodes TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); 660135446Strhodes doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, 661135446Strhodes FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); 662135446Strhodes doswitch("ADDITIONALDATASWITCH", "additionaldata", 663135446Strhodes ADDITIONALDATAARGS, ADDITIONALDATATYPE, 664135446Strhodes ADDITIONALDATACLASS, ADDITIONALDATADEF); 665135446Strhodes doswitch("DIGESTSWITCH", "digest", 666135446Strhodes DIGESTARGS, DIGESTTYPE, 667135446Strhodes DIGESTCLASS, DIGESTDEF); 668135446Strhodes doswitch("CHECKOWNERSWITCH", "checkowner", 669135446Strhodes CHECKOWNERARGS, CHECKOWNERTYPE, 670135446Strhodes CHECKOWNERCLASS, CHECKOWNERDEF); 671135446Strhodes doswitch("CHECKNAMESSWITCH", "checknames", 672135446Strhodes CHECKNAMESARGS, CHECKNAMESTYPE, 673135446Strhodes CHECKNAMESCLASS, CHECKNAMESDEF); 674135446Strhodes 675135446Strhodes /* 676135446Strhodes * From here down, we are processing the rdata names and 677135446Strhodes * attributes. 678135446Strhodes */ 679135446Strhodes 680135446Strhodes#define PRINT_COMMA(x) (x == maxtype ? "" : ",") 681135446Strhodes 682135446Strhodes#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ 683135446Strhodes "DNS_RDATATYPEATTR_NOTQUESTION" 684135446Strhodes#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ 685135446Strhodes "DNS_RDATATYPEATTR_QUESTIONONLY" 686135446Strhodes#define RESERVED "DNS_RDATATYPEATTR_RESERVED" 687135446Strhodes 688135446Strhodes /* 689135446Strhodes * Add in reserved/special types. This will let us 690135446Strhodes * sort them without special cases. 691135446Strhodes */ 692135446Strhodes insert_into_typenames(0, "reserved0", RESERVED); 693135446Strhodes insert_into_typenames(31, "eid", RESERVED); 694135446Strhodes insert_into_typenames(32, "nimloc", RESERVED); 695135446Strhodes insert_into_typenames(34, "atma", RESERVED); 696135446Strhodes insert_into_typenames(100, "uinfo", RESERVED); 697135446Strhodes insert_into_typenames(101, "uid", RESERVED); 698135446Strhodes insert_into_typenames(102, "gid", RESERVED); 699135446Strhodes insert_into_typenames(251, "ixfr", METAQUESTIONONLY); 700135446Strhodes insert_into_typenames(252, "axfr", METAQUESTIONONLY); 701135446Strhodes insert_into_typenames(253, "mailb", METAQUESTIONONLY); 702135446Strhodes insert_into_typenames(254, "maila", METAQUESTIONONLY); 703135446Strhodes insert_into_typenames(255, "any", METAQUESTIONONLY); 704135446Strhodes 705135446Strhodes /* 706135446Strhodes * Spit out a quick and dirty hash function. Here, 707135446Strhodes * we walk through the list of type names, and calculate 708135446Strhodes * a hash. This isn't perfect, but it will generate "pretty 709135446Strhodes * good" estimates. Lowercase the characters before 710135446Strhodes * computing in all cases. 711135446Strhodes * 712135446Strhodes * Here, walk the list from top to bottom, calculating 713135446Strhodes * the hash (mod 256) for each name. 714135446Strhodes */ 715135446Strhodes fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); 716135446Strhodes fprintf(stdout, "\tdo { \\\n"); 717135446Strhodes fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" 718135446Strhodes "\t\t strncasecmp(_s,(_tn)," 719135446Strhodes "(sizeof(_s) - 1)) == 0) { \\\n"); 720135446Strhodes fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " 721193149Sdougb "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); 722135446Strhodes fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); 723135446Strhodes fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); 724135446Strhodes fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); 725135446Strhodes fprintf(stdout, "\t\t} \\\n"); 726135446Strhodes fprintf(stdout, "\t} while (0)\n\n"); 727135446Strhodes 728135446Strhodes fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," 729135446Strhodes "_typename,_length,_typep) \\\n"); 730135446Strhodes fprintf(stdout, "\tswitch (_hash) { \\\n"); 731135446Strhodes for (i = 0; i <= maxtype; i++) { 732135446Strhodes ttn = find_typename(i); 733135446Strhodes if (ttn == NULL) 734135446Strhodes continue; 735135446Strhodes 736135446Strhodes /* 737135446Strhodes * Skip entries we already processed. 738135446Strhodes */ 739135446Strhodes if (ttn->sorted != 0) 740135446Strhodes continue; 741135446Strhodes 742135446Strhodes hash = HASH(ttn->typename); 743135446Strhodes fprintf(stdout, "\t\tcase %u: \\\n", hash); 744135446Strhodes 745135446Strhodes /* 746135446Strhodes * Find all other entries that happen to match 747135446Strhodes * this hash. 748135446Strhodes */ 749135446Strhodes for (j = 0; j <= maxtype; j++) { 750135446Strhodes ttn2 = find_typename(j); 751135446Strhodes if (ttn2 == NULL) 752135446Strhodes continue; 753135446Strhodes if (hash == HASH(ttn2->typename)) { 754135446Strhodes fprintf(stdout, "\t\t\tRDATATYPE_COMPARE" 755135446Strhodes "(\"%s\", %u, " 756135446Strhodes "_typename, _length, _typep); \\\n", 757135446Strhodes ttn2->typename, ttn2->type); 758135446Strhodes ttn2->sorted = 1; 759135446Strhodes } 760135446Strhodes } 761135446Strhodes fprintf(stdout, "\t\t\tbreak; \\\n"); 762135446Strhodes } 763135446Strhodes fprintf(stdout, "\t}\n"); 764135446Strhodes 765135446Strhodes fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); 766135446Strhodes fprintf(stdout, "\tswitch (type) { \\\n"); 767135446Strhodes for (i = 0; i <= maxtype; i++) { 768135446Strhodes ttn = find_typename(i); 769135446Strhodes if (ttn == NULL) 770135446Strhodes continue; 771135446Strhodes fprintf(stdout, "\tcase %u: return (%s); \\\n", 772193149Sdougb i, upper(ttn->attr)); 773135446Strhodes } 774135446Strhodes fprintf(stdout, "\t}\n"); 775135446Strhodes 776135446Strhodes fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); 777135446Strhodes fprintf(stdout, "\tswitch (type) { \\\n"); 778135446Strhodes for (i = 0; i <= maxtype; i++) { 779135446Strhodes ttn = find_typename(i); 780135446Strhodes if (ttn == NULL) 781135446Strhodes continue; 782135446Strhodes fprintf(stdout, "\tcase %u: return " 783135446Strhodes "(str_totext(\"%s\", target)); \\\n", 784193149Sdougb i, upper(ttn->typename)); 785135446Strhodes } 786135446Strhodes fprintf(stdout, "\t}\n"); 787135446Strhodes 788135446Strhodes fputs("#endif /* DNS_CODE_H */\n", stdout); 789135446Strhodes } else if (type_enum) { 790135446Strhodes char *s; 791135446Strhodes 792135446Strhodes fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); 793135446Strhodes fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); 794135446Strhodes 795135446Strhodes fprintf(stdout, "enum {\n"); 796135446Strhodes fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); 797135446Strhodes 798135446Strhodes lasttype = 0; 799135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 800135446Strhodes if (tt->type != lasttype) 801135446Strhodes fprintf(stdout, 802135446Strhodes "\tdns_rdatatype_%s = %d,\n", 803135446Strhodes funname(tt->typename, buf1), 804135446Strhodes lasttype = tt->type); 805135446Strhodes 806135446Strhodes fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); 807135446Strhodes fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); 808135446Strhodes fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); 809135446Strhodes fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); 810135446Strhodes fprintf(stdout, "\tdns_rdatatype_any = 255\n"); 811135446Strhodes 812135446Strhodes fprintf(stdout, "};\n\n"); 813135446Strhodes 814135446Strhodes fprintf(stdout, "#define dns_rdatatype_none\t" 815135446Strhodes "((dns_rdatatype_t)dns_rdatatype_none)\n"); 816135446Strhodes 817135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 818135446Strhodes if (tt->type != lasttype) { 819135446Strhodes s = funname(tt->typename, buf1); 820135446Strhodes fprintf(stdout, 821135446Strhodes "#define dns_rdatatype_%s\t%s" 822135446Strhodes "((dns_rdatatype_t)dns_rdatatype_%s)" 823135446Strhodes "\n", 824135446Strhodes s, strlen(s) < 2U ? "\t" : "", s); 825135446Strhodes lasttype = tt->type; 826135446Strhodes } 827135446Strhodes 828135446Strhodes fprintf(stdout, "#define dns_rdatatype_ixfr\t" 829135446Strhodes "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); 830135446Strhodes fprintf(stdout, "#define dns_rdatatype_axfr\t" 831135446Strhodes "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); 832135446Strhodes fprintf(stdout, "#define dns_rdatatype_mailb\t" 833135446Strhodes "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); 834135446Strhodes fprintf(stdout, "#define dns_rdatatype_maila\t" 835135446Strhodes "((dns_rdatatype_t)dns_rdatatype_maila)\n"); 836135446Strhodes fprintf(stdout, "#define dns_rdatatype_any\t" 837135446Strhodes "((dns_rdatatype_t)dns_rdatatype_any)\n"); 838135446Strhodes 839135446Strhodes fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); 840135446Strhodes 841135446Strhodes } else if (class_enum) { 842135446Strhodes char *s; 843135446Strhodes int classnum; 844135446Strhodes 845135446Strhodes fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); 846135446Strhodes fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); 847135446Strhodes 848135446Strhodes fprintf(stdout, "enum {\n"); 849135446Strhodes 850135446Strhodes fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); 851135446Strhodes fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" 852135446Strhodes "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); 853135446Strhodes 854135446Strhodes#define PRINTCLASS(name, num) \ 855135446Strhodes do { \ 856135446Strhodes s = funname(name, buf1); \ 857135446Strhodes classnum = num; \ 858135446Strhodes fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ 859135446Strhodes classnum != 255 ? "," : ""); \ 860135446Strhodes fprintf(stdout, "#define dns_rdataclass_%s\t" \ 861135446Strhodes "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ 862135446Strhodes } while (0) 863135446Strhodes 864135446Strhodes for (cc = classes; cc != NULL; cc = cc->next) { 865170222Sdougb if (cc->rdclass == 3) 866135446Strhodes PRINTCLASS("chaos", 3); 867170222Sdougb else if (cc->rdclass == 255) 868135446Strhodes PRINTCLASS("none", 254); 869135446Strhodes PRINTCLASS(cc->classname, cc->rdclass); 870135446Strhodes } 871135446Strhodes 872135446Strhodes#undef PRINTCLASS 873135446Strhodes 874135446Strhodes fprintf(stdout, "};\n\n"); 875135446Strhodes fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); 876135446Strhodes } else if (structs) { 877135446Strhodes if (prefix != NULL) { 878135446Strhodes if ((fd = fopen(prefix,"r")) != NULL) { 879135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 880135446Strhodes fputs(buf, stdout); 881135446Strhodes fclose(fd); 882135446Strhodes } 883135446Strhodes } 884135446Strhodes for (tt = types; tt != NULL; tt = tt->next) { 885254402Serwin snprintf(buf, sizeof(buf), "%s/%s_%d.h", 886135446Strhodes tt->dirname, tt->typename, tt->type); 887135446Strhodes if ((fd = fopen(buf,"r")) != NULL) { 888135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 889135446Strhodes fputs(buf, stdout); 890135446Strhodes fclose(fd); 891135446Strhodes } 892135446Strhodes } 893135446Strhodes if (suffix != NULL) { 894135446Strhodes if ((fd = fopen(suffix,"r")) != NULL) { 895135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 896135446Strhodes fputs(buf, stdout); 897135446Strhodes fclose(fd); 898135446Strhodes } 899135446Strhodes } 900135446Strhodes } else if (depend) { 901135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 902135446Strhodes fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, 903135446Strhodes tt->dirname, tt->typename, tt->type); 904135446Strhodes } 905135446Strhodes 906135446Strhodes if (ferror(stdout) != 0) 907135446Strhodes exit(1); 908135446Strhodes 909135446Strhodes return (0); 910135446Strhodes} 911