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