1 /* $NetBSD: cfg_test.c,v 1.4 2025/01/26 16:25:17 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <errno.h> 19 #include <stdbool.h> 20 #include <stdlib.h> 21 22 #include <isc/mem.h> 23 #include <isc/string.h> 24 #include <isc/util.h> 25 26 #include <dns/log.h> 27 28 #include <isccfg/grammar.h> 29 #include <isccfg/namedconf.h> 30 31 static void 32 check_result(isc_result_t result, const char *format, ...) { 33 va_list args; 34 35 if (result == ISC_R_SUCCESS) { 36 return; 37 } 38 39 va_start(args, format); 40 vfprintf(stderr, format, args); 41 va_end(args); 42 fprintf(stderr, ": %s\n", isc_result_totext(result)); 43 exit(EXIT_FAILURE); 44 } 45 46 static void 47 output(void *closure, const char *text, int textlen) { 48 UNUSED(closure); 49 (void)fwrite(text, 1, textlen, stdout); 50 } 51 52 static void 53 usage(void) { 54 fprintf(stderr, "usage: cfg_test --rndc|--named " 55 "[--grammar] [--zonegrammar] [--active] " 56 "[--memstats] conffile\n"); 57 exit(EXIT_FAILURE); 58 } 59 60 int 61 main(int argc, char **argv) { 62 isc_result_t result; 63 isc_mem_t *mctx = NULL; 64 isc_log_t *lctx = NULL; 65 isc_logconfig_t *lcfg = NULL; 66 isc_logdestination_t destination; 67 cfg_parser_t *pctx = NULL; 68 cfg_obj_t *cfg = NULL; 69 cfg_type_t *type = NULL; 70 bool grammar = false; 71 bool memstats = false; 72 char *filename = NULL; 73 unsigned int zonetype = 0; 74 unsigned int pflags = 0; 75 76 isc_mem_create(&mctx); 77 78 isc_log_create(mctx, &lctx, &lcfg); 79 isc_log_setcontext(lctx); 80 81 /* 82 * Create and install the default channel. 83 */ 84 destination.file.stream = stderr; 85 destination.file.name = NULL; 86 destination.file.versions = ISC_LOG_ROLLNEVER; 87 destination.file.maximum_size = 0; 88 isc_log_createchannel(lcfg, "_default", ISC_LOG_TOFILEDESC, 89 ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME); 90 91 result = isc_log_usechannel(lcfg, "_default", NULL, NULL); 92 check_result(result, "isc_log_usechannel()"); 93 94 /* 95 * Set the initial debug level. 96 */ 97 isc_log_setdebuglevel(lctx, 2); 98 99 if (argc < 3) { 100 usage(); 101 } 102 103 while (argc > 1) { 104 if (strcmp(argv[1], "--active") == 0) { 105 pflags |= CFG_PRINTER_ACTIVEONLY; 106 } else if (strcmp(argv[1], "--grammar") == 0) { 107 grammar = true; 108 } else if (strcmp(argv[1], "--zonegrammar") == 0) { 109 argv++, argc--; 110 if (argc <= 1) { 111 usage(); 112 } 113 if (strcmp(argv[1], "master") == 0 || 114 strcmp(argv[1], "primary") == 0) 115 { 116 zonetype = CFG_ZONE_PRIMARY; 117 } else if (strcmp(argv[1], "slave") == 0 || 118 strcmp(argv[1], "secondary") == 0) 119 { 120 zonetype = CFG_ZONE_SECONDARY; 121 } else if (strcmp(argv[1], "mirror") == 0) { 122 zonetype = CFG_ZONE_MIRROR; 123 } else if (strcmp(argv[1], "stub") == 0) { 124 zonetype = CFG_ZONE_STUB; 125 } else if (strcmp(argv[1], "static-stub") == 0) { 126 zonetype = CFG_ZONE_STATICSTUB; 127 } else if (strcmp(argv[1], "hint") == 0) { 128 zonetype = CFG_ZONE_HINT; 129 } else if (strcmp(argv[1], "forward") == 0) { 130 zonetype = CFG_ZONE_FORWARD; 131 } else if (strcmp(argv[1], "redirect") == 0) { 132 zonetype = CFG_ZONE_REDIRECT; 133 } else if (strcmp(argv[1], "in-view") == 0) { 134 zonetype = CFG_ZONE_INVIEW; 135 } else { 136 usage(); 137 } 138 } else if (strcmp(argv[1], "--memstats") == 0) { 139 memstats = true; 140 } else if (strcmp(argv[1], "--named") == 0) { 141 type = &cfg_type_namedconf; 142 } else if (strcmp(argv[1], "--rndc") == 0) { 143 type = &cfg_type_rndcconf; 144 } else if (argv[1][0] == '-') { 145 usage(); 146 } else { 147 filename = argv[1]; 148 } 149 argv++, argc--; 150 } 151 152 if (grammar) { 153 if (type == NULL) { 154 usage(); 155 } 156 cfg_print_grammar(type, pflags, output, NULL); 157 } else if (zonetype != 0) { 158 cfg_print_zonegrammar(zonetype, pflags, output, NULL); 159 } else { 160 if (type == NULL || filename == NULL) { 161 usage(); 162 } 163 RUNTIME_CHECK(cfg_parser_create(mctx, lctx, &pctx) == 164 ISC_R_SUCCESS); 165 166 result = cfg_parse_file(pctx, filename, type, &cfg); 167 168 fprintf(stderr, "read config: %s\n", isc_result_totext(result)); 169 170 if (result != ISC_R_SUCCESS) { 171 exit(EXIT_FAILURE); 172 } 173 174 cfg_print(cfg, output, NULL); 175 176 cfg_obj_destroy(pctx, &cfg); 177 178 cfg_parser_destroy(&pctx); 179 } 180 181 isc_log_destroy(&lctx); 182 if (memstats) { 183 isc_mem_stats(mctx, stderr); 184 } 185 isc_mem_destroy(&mctx); 186 187 fflush(stdout); 188 if (ferror(stdout)) { 189 fprintf(stderr, "write error\n"); 190 return 1; 191 } 192 193 return 0; 194 } 195