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; 312262706Serwin size_t c; 313262706Serwin int i, n; 314135446Strhodes char tmp[256]; 315135446Strhodes 316254402Serwin INSIST(strlen(typename) < TYPECLASSBUF); 317135446Strhodes for (i = 0; i < TYPENAMES; i++) { 318135446Strhodes if (typenames[i].typename[0] != 0 && 319135446Strhodes typenames[i].type == type && 320135446Strhodes strcmp(typename, typenames[i].typename) != 0) { 321135446Strhodes fprintf(stderr, 322135446Strhodes "Error: type %d has two names: %s, %s\n", 323135446Strhodes type, typenames[i].typename, typename); 324135446Strhodes exit(1); 325135446Strhodes } 326135446Strhodes if (typenames[i].typename[0] == 0 && ttn == NULL) 327135446Strhodes ttn = &typenames[i]; 328135446Strhodes } 329135446Strhodes if (ttn == NULL) { 330135446Strhodes fprintf(stderr, "Error: typenames array too small\n"); 331135446Strhodes exit(1); 332135446Strhodes } 333193149Sdougb 334135446Strhodes if (strlen(typename) > sizeof(ttn->typename) - 1) { 335135446Strhodes fprintf(stderr, "Error: type name %s is too long\n", 336135446Strhodes typename); 337135446Strhodes exit(1); 338135446Strhodes } 339254402Serwin strncpy(ttn->typename, typename, sizeof(ttn->typename)); 340135446Strhodes ttn->type = type; 341135446Strhodes 342254402Serwin strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); 343135446Strhodes c = strlen(ttn->macroname); 344135446Strhodes while (c > 0) { 345135446Strhodes if (ttn->macroname[c - 1] == '-') 346135446Strhodes ttn->macroname[c - 1] = '_'; 347135446Strhodes c--; 348135446Strhodes } 349135446Strhodes 350135446Strhodes if (attr == NULL) { 351254402Serwin n = snprintf(tmp, sizeof(tmp), 352254402Serwin "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); 353254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(tmp)); 354135446Strhodes attr = tmp; 355135446Strhodes } 356135446Strhodes 357135446Strhodes if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { 358135446Strhodes fprintf(stderr, "Error: type %d has different attributes: " 359135446Strhodes "%s, %s\n", type, ttn->attr, attr); 360135446Strhodes exit(1); 361135446Strhodes } 362135446Strhodes 363135446Strhodes if (strlen(attr) > sizeof(ttn->attr) - 1) { 364135446Strhodes fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", 365135446Strhodes attr, typename); 366135446Strhodes exit(1); 367135446Strhodes } 368254402Serwin strncpy(ttn->attr, attr, sizeof(ttn->attr)); 369135446Strhodes ttn->sorted = 0; 370135446Strhodes if (maxtype < type) 371135446Strhodes maxtype = type; 372135446Strhodes} 373135446Strhodes 374254402Serwinstatic void 375135446Strhodesadd(int rdclass, const char *classname, int type, const char *typename, 376135446Strhodes const char *dirname) 377135446Strhodes{ 378135446Strhodes struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); 379135446Strhodes struct tt *tt, *oldtt; 380135446Strhodes struct cc *newcc; 381135446Strhodes struct cc *cc, *oldcc; 382135446Strhodes 383254402Serwin INSIST(strlen(typename) < TYPECLASSBUF); 384254402Serwin INSIST(strlen(classname) < TYPECLASSBUF); 385254402Serwin INSIST(strlen(dirname) < DIRNAMESIZE); 386254402Serwin 387135446Strhodes insert_into_typenames(type, typename, NULL); 388135446Strhodes 389135446Strhodes if (newtt == NULL) { 390135446Strhodes fprintf(stderr, "malloc() failed\n"); 391135446Strhodes exit(1); 392135446Strhodes } 393135446Strhodes 394135446Strhodes newtt->next = NULL; 395135446Strhodes newtt->rdclass = rdclass; 396135446Strhodes newtt->type = type; 397254402Serwin strncpy(newtt->classname, classname, sizeof(newtt->classname)); 398254402Serwin strncpy(newtt->typename, typename, sizeof(newtt->typename)); 399193149Sdougb if (strncmp(dirname, "./", 2) == 0) 400193149Sdougb dirname += 2; 401254402Serwin strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); 402135446Strhodes 403135446Strhodes tt = types; 404135446Strhodes oldtt = NULL; 405135446Strhodes 406135446Strhodes while ((tt != NULL) && (tt->type < type)) { 407135446Strhodes oldtt = tt; 408135446Strhodes tt = tt->next; 409135446Strhodes } 410135446Strhodes 411135446Strhodes while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { 412135446Strhodes if (strcmp(tt->typename, typename) != 0) 413135446Strhodes exit(1); 414135446Strhodes oldtt = tt; 415135446Strhodes tt = tt->next; 416135446Strhodes } 417135446Strhodes 418135446Strhodes if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) 419135446Strhodes exit(1); 420135446Strhodes 421135446Strhodes newtt->next = tt; 422135446Strhodes if (oldtt != NULL) 423135446Strhodes oldtt->next = newtt; 424135446Strhodes else 425135446Strhodes types = newtt; 426135446Strhodes 427135446Strhodes /* 428135446Strhodes * Do a class switch for this type. 429135446Strhodes */ 430135446Strhodes if (rdclass == 0) 431135446Strhodes return; 432135446Strhodes 433135446Strhodes newcc = (struct cc *)malloc(sizeof(*newcc)); 434254402Serwin if (newcc == NULL) { 435254402Serwin fprintf(stderr, "malloc() failed\n"); 436254402Serwin exit(1); 437254402Serwin } 438135446Strhodes newcc->rdclass = rdclass; 439254402Serwin strncpy(newcc->classname, classname, sizeof(newcc->classname)); 440135446Strhodes cc = classes; 441135446Strhodes oldcc = NULL; 442135446Strhodes 443135446Strhodes while ((cc != NULL) && (cc->rdclass < rdclass)) { 444135446Strhodes oldcc = cc; 445135446Strhodes cc = cc->next; 446135446Strhodes } 447135446Strhodes 448135446Strhodes if ((cc != NULL) && cc->rdclass == rdclass) { 449135446Strhodes free((char *)newcc); 450135446Strhodes return; 451135446Strhodes } 452135446Strhodes 453135446Strhodes newcc->next = cc; 454135446Strhodes if (oldcc != NULL) 455135446Strhodes oldcc->next = newcc; 456135446Strhodes else 457135446Strhodes classes = newcc; 458135446Strhodes} 459135446Strhodes 460254402Serwinstatic void 461135446Strhodessd(int rdclass, const char *classname, const char *dirname, char filetype) { 462254402Serwin char buf[TYPECLASSLEN + sizeof("_65535.h")]; 463254402Serwin char typename[TYPECLASSBUF]; 464254402Serwin int type, n; 465135446Strhodes isc_dir_t dir; 466135446Strhodes 467135446Strhodes if (!start_directory(dirname, &dir)) 468135446Strhodes return; 469135446Strhodes 470135446Strhodes while (next_file(&dir)) { 471254402Serwin if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) 472135446Strhodes continue; 473135446Strhodes if ((type > 65535) || (type < 0)) 474135446Strhodes continue; 475135446Strhodes 476254402Serwin n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, 477254402Serwin type, filetype); 478254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(buf)); 479135446Strhodes if (strcmp(buf, dir.filename) != 0) 480135446Strhodes continue; 481135446Strhodes add(rdclass, classname, type, typename, dirname); 482135446Strhodes } 483135446Strhodes 484135446Strhodes end_directory(&dir); 485135446Strhodes} 486135446Strhodes 487135446Strhodesstatic unsigned int 488135446StrhodesHASH(char *string) { 489262706Serwin size_t n; 490135446Strhodes unsigned char a, b; 491135446Strhodes 492135446Strhodes n = strlen(string); 493135446Strhodes if (n == 0) { 494135446Strhodes fprintf(stderr, "n == 0?\n"); 495135446Strhodes exit(1); 496135446Strhodes } 497135446Strhodes a = tolower((unsigned char)string[0]); 498135446Strhodes b = tolower((unsigned char)string[n - 1]); 499135446Strhodes 500135446Strhodes return ((a + n) * b) % 256; 501135446Strhodes} 502135446Strhodes 503135446Strhodesint 504135446Strhodesmain(int argc, char **argv) { 505254402Serwin char buf[DIRNAMESIZE]; /* XXX Should be max path length */ 506254402Serwin char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ 507135446Strhodes int rdclass; 508254402Serwin char classname[TYPECLASSBUF]; 509135446Strhodes struct tt *tt; 510135446Strhodes struct cc *cc; 511135446Strhodes struct ttnam *ttn, *ttn2; 512135446Strhodes unsigned int hash; 513135446Strhodes struct tm *tm; 514135446Strhodes time_t now; 515135446Strhodes char year[11]; 516135446Strhodes int lasttype; 517135446Strhodes int code = 1; 518135446Strhodes int class_enum = 0; 519135446Strhodes int type_enum = 0; 520135446Strhodes int structs = 0; 521135446Strhodes int depend = 0; 522254402Serwin int c, i, j, n; 523254402Serwin char buf1[TYPECLASSBUF]; 524135446Strhodes char filetype = 'c'; 525135446Strhodes FILE *fd; 526135446Strhodes char *prefix = NULL; 527135446Strhodes char *suffix = NULL; 528135446Strhodes char *file = NULL; 529135446Strhodes isc_dir_t dir; 530135446Strhodes 531135446Strhodes for (i = 0; i < TYPENAMES; i++) 532135446Strhodes memset(&typenames[i], 0, sizeof(typenames[i])); 533135446Strhodes 534135446Strhodes strcpy(srcdir, ""); 535135446Strhodes while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) 536135446Strhodes switch (c) { 537135446Strhodes case 'c': 538135446Strhodes code = 0; 539135446Strhodes depend = 0; 540135446Strhodes type_enum = 0; 541135446Strhodes class_enum = 1; 542135446Strhodes filetype = 'c'; 543135446Strhodes structs = 0; 544135446Strhodes break; 545135446Strhodes case 'd': 546135446Strhodes code = 0; 547135446Strhodes depend = 1; 548135446Strhodes class_enum = 0; 549135446Strhodes type_enum = 0; 550135446Strhodes structs = 0; 551135446Strhodes filetype = 'h'; 552135446Strhodes break; 553135446Strhodes case 't': 554135446Strhodes code = 0; 555135446Strhodes depend = 0; 556135446Strhodes class_enum = 0; 557135446Strhodes type_enum = 1; 558135446Strhodes filetype = 'c'; 559135446Strhodes structs = 0; 560135446Strhodes break; 561135446Strhodes case 'i': 562135446Strhodes code = 0; 563135446Strhodes depend = 0; 564135446Strhodes class_enum = 0; 565135446Strhodes type_enum = 0; 566135446Strhodes structs = 1; 567135446Strhodes filetype = 'h'; 568135446Strhodes break; 569135446Strhodes case 's': 570254402Serwin if (strlen(isc_commandline_argument) > 571254402Serwin DIRNAMESIZE - 2 * TYPECLASSLEN - 572254402Serwin sizeof("/rdata/_65535_65535")) { 573254402Serwin fprintf(stderr, "\"%s\" too long\n", 574254402Serwin isc_commandline_argument); 575254402Serwin exit(1); 576254402Serwin } 577254402Serwin n = snprintf(srcdir, sizeof(srcdir), "%s/", 578254402Serwin isc_commandline_argument); 579254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 580135446Strhodes break; 581135446Strhodes case 'F': 582135446Strhodes file = isc_commandline_argument; 583135446Strhodes break; 584135446Strhodes case 'P': 585135446Strhodes prefix = isc_commandline_argument; 586135446Strhodes break; 587135446Strhodes case 'S': 588135446Strhodes suffix = isc_commandline_argument; 589135446Strhodes break; 590135446Strhodes case '?': 591135446Strhodes exit(1); 592135446Strhodes } 593135446Strhodes 594254402Serwin n = snprintf(buf, sizeof(buf), "%srdata", srcdir); 595254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 596135446Strhodes 597135446Strhodes if (!start_directory(buf, &dir)) 598135446Strhodes exit(1); 599135446Strhodes 600135446Strhodes while (next_file(&dir)) { 601254402Serwin if (sscanf(dir.filename, TYPECLASSFMT, classname, 602254402Serwin &rdclass) != 2) 603135446Strhodes continue; 604135446Strhodes if ((rdclass > 65535) || (rdclass < 0)) 605135446Strhodes continue; 606135446Strhodes 607254402Serwin n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", 608254402Serwin srcdir, classname, rdclass); 609254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(buf)); 610135446Strhodes if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) 611135446Strhodes continue; 612135446Strhodes sd(rdclass, classname, buf, filetype); 613135446Strhodes } 614135446Strhodes end_directory(&dir); 615254402Serwin n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); 616254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 617135446Strhodes sd(0, "", buf, filetype); 618135446Strhodes 619135446Strhodes if (time(&now) != -1) { 620254402Serwin if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { 621254402Serwin n = snprintf(year, sizeof(year), "-%d", 622254402Serwin tm->tm_year + 1900); 623254402Serwin INSIST(n > 0 && (unsigned)n < sizeof(year)); 624254402Serwin } else 625135446Strhodes year[0] = 0; 626135446Strhodes } else 627135446Strhodes year[0] = 0; 628135446Strhodes 629135446Strhodes if (!depend) fprintf(stdout, copyright, year); 630135446Strhodes 631135446Strhodes if (code) { 632135446Strhodes fputs("#ifndef DNS_CODE_H\n", stdout); 633135446Strhodes fputs("#define DNS_CODE_H 1\n\n", stdout); 634135446Strhodes 635135446Strhodes fputs("#include <isc/boolean.h>\n", stdout); 636135446Strhodes fputs("#include <isc/result.h>\n\n", stdout); 637135446Strhodes fputs("#include <dns/name.h>\n\n", stdout); 638135446Strhodes 639135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 640135446Strhodes fprintf(stdout, "#include \"%s/%s_%d.c\"\n", 641135446Strhodes tt->dirname, tt->typename, tt->type); 642135446Strhodes 643135446Strhodes fputs("\n\n", stdout); 644135446Strhodes 645135446Strhodes doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, 646135446Strhodes FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); 647135446Strhodes doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, 648135446Strhodes TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); 649135446Strhodes doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, 650135446Strhodes FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); 651135446Strhodes doswitch("TOWIRESWITCH", "towire", TOWIREARGS, 652135446Strhodes TOWIRETYPE, TOWIRECLASS, TOWIREDEF); 653135446Strhodes doswitch("COMPARESWITCH", "compare", COMPAREARGS, 654135446Strhodes COMPARETYPE, COMPARECLASS, COMPAREDEF); 655224092Sdougb doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, 656224092Sdougb COMPARETYPE, COMPARECLASS, COMPAREDEF); 657135446Strhodes doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, 658135446Strhodes FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); 659135446Strhodes doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, 660135446Strhodes TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); 661135446Strhodes doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, 662135446Strhodes FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); 663135446Strhodes doswitch("ADDITIONALDATASWITCH", "additionaldata", 664135446Strhodes ADDITIONALDATAARGS, ADDITIONALDATATYPE, 665135446Strhodes ADDITIONALDATACLASS, ADDITIONALDATADEF); 666135446Strhodes doswitch("DIGESTSWITCH", "digest", 667135446Strhodes DIGESTARGS, DIGESTTYPE, 668135446Strhodes DIGESTCLASS, DIGESTDEF); 669135446Strhodes doswitch("CHECKOWNERSWITCH", "checkowner", 670135446Strhodes CHECKOWNERARGS, CHECKOWNERTYPE, 671135446Strhodes CHECKOWNERCLASS, CHECKOWNERDEF); 672135446Strhodes doswitch("CHECKNAMESSWITCH", "checknames", 673135446Strhodes CHECKNAMESARGS, CHECKNAMESTYPE, 674135446Strhodes CHECKNAMESCLASS, CHECKNAMESDEF); 675135446Strhodes 676135446Strhodes /* 677135446Strhodes * From here down, we are processing the rdata names and 678135446Strhodes * attributes. 679135446Strhodes */ 680135446Strhodes 681135446Strhodes#define PRINT_COMMA(x) (x == maxtype ? "" : ",") 682135446Strhodes 683135446Strhodes#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ 684135446Strhodes "DNS_RDATATYPEATTR_NOTQUESTION" 685135446Strhodes#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ 686135446Strhodes "DNS_RDATATYPEATTR_QUESTIONONLY" 687135446Strhodes#define RESERVED "DNS_RDATATYPEATTR_RESERVED" 688135446Strhodes 689135446Strhodes /* 690135446Strhodes * Add in reserved/special types. This will let us 691135446Strhodes * sort them without special cases. 692135446Strhodes */ 693135446Strhodes insert_into_typenames(0, "reserved0", RESERVED); 694135446Strhodes insert_into_typenames(31, "eid", RESERVED); 695135446Strhodes insert_into_typenames(32, "nimloc", RESERVED); 696135446Strhodes insert_into_typenames(34, "atma", RESERVED); 697135446Strhodes insert_into_typenames(100, "uinfo", RESERVED); 698135446Strhodes insert_into_typenames(101, "uid", RESERVED); 699135446Strhodes insert_into_typenames(102, "gid", RESERVED); 700135446Strhodes insert_into_typenames(251, "ixfr", METAQUESTIONONLY); 701135446Strhodes insert_into_typenames(252, "axfr", METAQUESTIONONLY); 702135446Strhodes insert_into_typenames(253, "mailb", METAQUESTIONONLY); 703135446Strhodes insert_into_typenames(254, "maila", METAQUESTIONONLY); 704135446Strhodes insert_into_typenames(255, "any", METAQUESTIONONLY); 705135446Strhodes 706135446Strhodes /* 707135446Strhodes * Spit out a quick and dirty hash function. Here, 708135446Strhodes * we walk through the list of type names, and calculate 709135446Strhodes * a hash. This isn't perfect, but it will generate "pretty 710135446Strhodes * good" estimates. Lowercase the characters before 711135446Strhodes * computing in all cases. 712135446Strhodes * 713135446Strhodes * Here, walk the list from top to bottom, calculating 714135446Strhodes * the hash (mod 256) for each name. 715135446Strhodes */ 716135446Strhodes fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); 717135446Strhodes fprintf(stdout, "\tdo { \\\n"); 718135446Strhodes fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" 719135446Strhodes "\t\t strncasecmp(_s,(_tn)," 720135446Strhodes "(sizeof(_s) - 1)) == 0) { \\\n"); 721135446Strhodes fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " 722193149Sdougb "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); 723135446Strhodes fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); 724135446Strhodes fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); 725135446Strhodes fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); 726135446Strhodes fprintf(stdout, "\t\t} \\\n"); 727135446Strhodes fprintf(stdout, "\t} while (0)\n\n"); 728135446Strhodes 729135446Strhodes fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," 730135446Strhodes "_typename,_length,_typep) \\\n"); 731135446Strhodes fprintf(stdout, "\tswitch (_hash) { \\\n"); 732135446Strhodes for (i = 0; i <= maxtype; i++) { 733135446Strhodes ttn = find_typename(i); 734135446Strhodes if (ttn == NULL) 735135446Strhodes continue; 736135446Strhodes 737135446Strhodes /* 738135446Strhodes * Skip entries we already processed. 739135446Strhodes */ 740135446Strhodes if (ttn->sorted != 0) 741135446Strhodes continue; 742135446Strhodes 743135446Strhodes hash = HASH(ttn->typename); 744135446Strhodes fprintf(stdout, "\t\tcase %u: \\\n", hash); 745135446Strhodes 746135446Strhodes /* 747135446Strhodes * Find all other entries that happen to match 748135446Strhodes * this hash. 749135446Strhodes */ 750135446Strhodes for (j = 0; j <= maxtype; j++) { 751135446Strhodes ttn2 = find_typename(j); 752135446Strhodes if (ttn2 == NULL) 753135446Strhodes continue; 754135446Strhodes if (hash == HASH(ttn2->typename)) { 755135446Strhodes fprintf(stdout, "\t\t\tRDATATYPE_COMPARE" 756135446Strhodes "(\"%s\", %u, " 757135446Strhodes "_typename, _length, _typep); \\\n", 758135446Strhodes ttn2->typename, ttn2->type); 759135446Strhodes ttn2->sorted = 1; 760135446Strhodes } 761135446Strhodes } 762135446Strhodes fprintf(stdout, "\t\t\tbreak; \\\n"); 763135446Strhodes } 764135446Strhodes fprintf(stdout, "\t}\n"); 765135446Strhodes 766135446Strhodes fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); 767135446Strhodes fprintf(stdout, "\tswitch (type) { \\\n"); 768135446Strhodes for (i = 0; i <= maxtype; i++) { 769135446Strhodes ttn = find_typename(i); 770135446Strhodes if (ttn == NULL) 771135446Strhodes continue; 772135446Strhodes fprintf(stdout, "\tcase %u: return (%s); \\\n", 773193149Sdougb i, upper(ttn->attr)); 774135446Strhodes } 775135446Strhodes fprintf(stdout, "\t}\n"); 776135446Strhodes 777135446Strhodes fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); 778135446Strhodes fprintf(stdout, "\tswitch (type) { \\\n"); 779135446Strhodes for (i = 0; i <= maxtype; i++) { 780135446Strhodes ttn = find_typename(i); 781135446Strhodes if (ttn == NULL) 782135446Strhodes continue; 783262706Serwin /* 784262706Serwin * Remove KEYDATA (65533) from the type to memonic 785262706Serwin * translation as it is internal use only. This 786262706Serwin * stops the tools from displaying KEYDATA instead 787262706Serwin * of TYPE65533. 788262706Serwin */ 789262706Serwin if (i == 65533U) 790262706Serwin continue; 791135446Strhodes fprintf(stdout, "\tcase %u: return " 792135446Strhodes "(str_totext(\"%s\", target)); \\\n", 793193149Sdougb i, upper(ttn->typename)); 794135446Strhodes } 795135446Strhodes fprintf(stdout, "\t}\n"); 796135446Strhodes 797135446Strhodes fputs("#endif /* DNS_CODE_H */\n", stdout); 798135446Strhodes } else if (type_enum) { 799135446Strhodes char *s; 800135446Strhodes 801135446Strhodes fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); 802135446Strhodes fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); 803135446Strhodes 804135446Strhodes fprintf(stdout, "enum {\n"); 805135446Strhodes fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); 806135446Strhodes 807135446Strhodes lasttype = 0; 808135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 809135446Strhodes if (tt->type != lasttype) 810135446Strhodes fprintf(stdout, 811135446Strhodes "\tdns_rdatatype_%s = %d,\n", 812135446Strhodes funname(tt->typename, buf1), 813135446Strhodes lasttype = tt->type); 814135446Strhodes 815135446Strhodes fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); 816135446Strhodes fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); 817135446Strhodes fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); 818135446Strhodes fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); 819135446Strhodes fprintf(stdout, "\tdns_rdatatype_any = 255\n"); 820135446Strhodes 821135446Strhodes fprintf(stdout, "};\n\n"); 822135446Strhodes 823135446Strhodes fprintf(stdout, "#define dns_rdatatype_none\t" 824135446Strhodes "((dns_rdatatype_t)dns_rdatatype_none)\n"); 825135446Strhodes 826135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 827135446Strhodes if (tt->type != lasttype) { 828135446Strhodes s = funname(tt->typename, buf1); 829135446Strhodes fprintf(stdout, 830135446Strhodes "#define dns_rdatatype_%s\t%s" 831135446Strhodes "((dns_rdatatype_t)dns_rdatatype_%s)" 832135446Strhodes "\n", 833135446Strhodes s, strlen(s) < 2U ? "\t" : "", s); 834135446Strhodes lasttype = tt->type; 835135446Strhodes } 836135446Strhodes 837135446Strhodes fprintf(stdout, "#define dns_rdatatype_ixfr\t" 838135446Strhodes "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); 839135446Strhodes fprintf(stdout, "#define dns_rdatatype_axfr\t" 840135446Strhodes "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); 841135446Strhodes fprintf(stdout, "#define dns_rdatatype_mailb\t" 842135446Strhodes "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); 843135446Strhodes fprintf(stdout, "#define dns_rdatatype_maila\t" 844135446Strhodes "((dns_rdatatype_t)dns_rdatatype_maila)\n"); 845135446Strhodes fprintf(stdout, "#define dns_rdatatype_any\t" 846135446Strhodes "((dns_rdatatype_t)dns_rdatatype_any)\n"); 847135446Strhodes 848135446Strhodes fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); 849135446Strhodes 850135446Strhodes } else if (class_enum) { 851135446Strhodes char *s; 852135446Strhodes int classnum; 853135446Strhodes 854135446Strhodes fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); 855135446Strhodes fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); 856135446Strhodes 857135446Strhodes fprintf(stdout, "enum {\n"); 858135446Strhodes 859135446Strhodes fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); 860135446Strhodes fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" 861135446Strhodes "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); 862135446Strhodes 863135446Strhodes#define PRINTCLASS(name, num) \ 864135446Strhodes do { \ 865135446Strhodes s = funname(name, buf1); \ 866135446Strhodes classnum = num; \ 867135446Strhodes fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ 868135446Strhodes classnum != 255 ? "," : ""); \ 869135446Strhodes fprintf(stdout, "#define dns_rdataclass_%s\t" \ 870135446Strhodes "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ 871135446Strhodes } while (0) 872135446Strhodes 873135446Strhodes for (cc = classes; cc != NULL; cc = cc->next) { 874170222Sdougb if (cc->rdclass == 3) 875135446Strhodes PRINTCLASS("chaos", 3); 876170222Sdougb else if (cc->rdclass == 255) 877135446Strhodes PRINTCLASS("none", 254); 878135446Strhodes PRINTCLASS(cc->classname, cc->rdclass); 879135446Strhodes } 880135446Strhodes 881135446Strhodes#undef PRINTCLASS 882135446Strhodes 883135446Strhodes fprintf(stdout, "};\n\n"); 884135446Strhodes fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); 885135446Strhodes } else if (structs) { 886135446Strhodes if (prefix != NULL) { 887135446Strhodes if ((fd = fopen(prefix,"r")) != NULL) { 888135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 889135446Strhodes fputs(buf, stdout); 890135446Strhodes fclose(fd); 891135446Strhodes } 892135446Strhodes } 893135446Strhodes for (tt = types; tt != NULL; tt = tt->next) { 894254402Serwin snprintf(buf, sizeof(buf), "%s/%s_%d.h", 895135446Strhodes tt->dirname, tt->typename, tt->type); 896135446Strhodes if ((fd = fopen(buf,"r")) != NULL) { 897135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 898135446Strhodes fputs(buf, stdout); 899135446Strhodes fclose(fd); 900135446Strhodes } 901135446Strhodes } 902135446Strhodes if (suffix != NULL) { 903135446Strhodes if ((fd = fopen(suffix,"r")) != NULL) { 904135446Strhodes while (fgets(buf, sizeof(buf), fd) != NULL) 905135446Strhodes fputs(buf, stdout); 906135446Strhodes fclose(fd); 907135446Strhodes } 908135446Strhodes } 909135446Strhodes } else if (depend) { 910135446Strhodes for (tt = types; tt != NULL; tt = tt->next) 911135446Strhodes fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, 912135446Strhodes tt->dirname, tt->typename, tt->type); 913135446Strhodes } 914135446Strhodes 915135446Strhodes if (ferror(stdout) != 0) 916135446Strhodes exit(1); 917135446Strhodes 918135446Strhodes return (0); 919135446Strhodes} 920