xref: /netbsd-src/external/mpl/bind/dist/doc/misc/cfg_test.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
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