xref: /netbsd-src/external/mpl/bind/dist/doc/misc/cfg_test.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 /*	$NetBSD: cfg_test.c,v 1.2 2024/02/21 22:51:54 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/print.h>
24 #include <isc/string.h>
25 #include <isc/util.h>
26 
27 #include <dns/log.h>
28 
29 #include <isccfg/grammar.h>
30 #include <isccfg/namedconf.h>
31 
32 static void
33 check_result(isc_result_t result, const char *format, ...) {
34 	va_list args;
35 
36 	if (result == ISC_R_SUCCESS) {
37 		return;
38 	}
39 
40 	va_start(args, format);
41 	vfprintf(stderr, format, args);
42 	va_end(args);
43 	fprintf(stderr, ": %s\n", isc_result_totext(result));
44 	exit(1);
45 }
46 
47 static void
48 output(void *closure, const char *text, int textlen) {
49 	UNUSED(closure);
50 	(void)fwrite(text, 1, textlen, stdout);
51 }
52 
53 static void
54 usage(void) {
55 	fprintf(stderr, "usage: cfg_test --rndc|--named "
56 			"[--grammar] [--zonegrammar] [--active] "
57 			"[--memstats] conffile\n");
58 	exit(1);
59 }
60 
61 int
62 main(int argc, char **argv) {
63 	isc_result_t result;
64 	isc_mem_t *mctx = NULL;
65 	isc_log_t *lctx = NULL;
66 	isc_logconfig_t *lcfg = NULL;
67 	isc_logdestination_t destination;
68 	cfg_parser_t *pctx = NULL;
69 	cfg_obj_t *cfg = NULL;
70 	cfg_type_t *type = NULL;
71 	bool grammar = false;
72 	bool memstats = false;
73 	char *filename = NULL;
74 	unsigned int zonetype = 0;
75 	unsigned int pflags = 0;
76 
77 	isc_mem_create(&mctx);
78 
79 	isc_log_create(mctx, &lctx, &lcfg);
80 	isc_log_setcontext(lctx);
81 
82 	/*
83 	 * Create and install the default channel.
84 	 */
85 	destination.file.stream = stderr;
86 	destination.file.name = NULL;
87 	destination.file.versions = ISC_LOG_ROLLNEVER;
88 	destination.file.maximum_size = 0;
89 	isc_log_createchannel(lcfg, "_default", ISC_LOG_TOFILEDESC,
90 			      ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME);
91 
92 	result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
93 	check_result(result, "isc_log_usechannel()");
94 
95 	/*
96 	 * Set the initial debug level.
97 	 */
98 	isc_log_setdebuglevel(lctx, 2);
99 
100 	if (argc < 3) {
101 		usage();
102 	}
103 
104 	while (argc > 1) {
105 		if (strcmp(argv[1], "--active") == 0) {
106 			pflags |= CFG_PRINTER_ACTIVEONLY;
107 		} else if (strcmp(argv[1], "--grammar") == 0) {
108 			grammar = true;
109 		} else if (strcmp(argv[1], "--zonegrammar") == 0) {
110 			argv++, argc--;
111 			if (argc <= 1) {
112 				usage();
113 			}
114 			if (strcmp(argv[1], "master") == 0 ||
115 			    strcmp(argv[1], "primary") == 0)
116 			{
117 				zonetype = CFG_ZONE_PRIMARY;
118 			} else if (strcmp(argv[1], "slave") == 0 ||
119 				   strcmp(argv[1], "secondary") == 0)
120 			{
121 				zonetype = CFG_ZONE_SECONDARY;
122 			} else if (strcmp(argv[1], "mirror") == 0) {
123 				zonetype = CFG_ZONE_MIRROR;
124 			} else if (strcmp(argv[1], "stub") == 0) {
125 				zonetype = CFG_ZONE_STUB;
126 			} else if (strcmp(argv[1], "static-stub") == 0) {
127 				zonetype = CFG_ZONE_STATICSTUB;
128 			} else if (strcmp(argv[1], "hint") == 0) {
129 				zonetype = CFG_ZONE_HINT;
130 			} else if (strcmp(argv[1], "forward") == 0) {
131 				zonetype = CFG_ZONE_FORWARD;
132 			} else if (strcmp(argv[1], "redirect") == 0) {
133 				zonetype = CFG_ZONE_REDIRECT;
134 			} else if (strcmp(argv[1], "delegation-only") == 0) {
135 				zonetype = CFG_ZONE_DELEGATION;
136 			} else if (strcmp(argv[1], "in-view") == 0) {
137 				zonetype = CFG_ZONE_INVIEW;
138 			} else {
139 				usage();
140 			}
141 		} else if (strcmp(argv[1], "--memstats") == 0) {
142 			memstats = true;
143 		} else if (strcmp(argv[1], "--named") == 0) {
144 			type = &cfg_type_namedconf;
145 		} else if (strcmp(argv[1], "--rndc") == 0) {
146 			type = &cfg_type_rndcconf;
147 		} else if (argv[1][0] == '-') {
148 			usage();
149 		} else {
150 			filename = argv[1];
151 		}
152 		argv++, argc--;
153 	}
154 
155 	if (grammar) {
156 		if (type == NULL) {
157 			usage();
158 		}
159 		cfg_print_grammar(type, pflags, output, NULL);
160 	} else if (zonetype != 0) {
161 		cfg_print_zonegrammar(zonetype, pflags, output, NULL);
162 	} else {
163 		if (type == NULL || filename == NULL) {
164 			usage();
165 		}
166 		RUNTIME_CHECK(cfg_parser_create(mctx, lctx, &pctx) ==
167 			      ISC_R_SUCCESS);
168 
169 		result = cfg_parse_file(pctx, filename, type, &cfg);
170 
171 		fprintf(stderr, "read config: %s\n", isc_result_totext(result));
172 
173 		if (result != ISC_R_SUCCESS) {
174 			exit(1);
175 		}
176 
177 		cfg_print(cfg, output, NULL);
178 
179 		cfg_obj_destroy(pctx, &cfg);
180 
181 		cfg_parser_destroy(&pctx);
182 	}
183 
184 	isc_log_destroy(&lctx);
185 	if (memstats) {
186 		isc_mem_stats(mctx, stderr);
187 	}
188 	isc_mem_destroy(&mctx);
189 
190 	fflush(stdout);
191 	if (ferror(stdout)) {
192 		fprintf(stderr, "write error\n");
193 		return (1);
194 	} else {
195 		return (0);
196 	}
197 }
198