named-checkzone.c revision 234010
1135446Strhodes/*
2234010Sdougb * Copyright (C) 2004-2011  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1999-2003  Internet Software Consortium.
4135446Strhodes *
5174187Sdougb * 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
18234010Sdougb/* $Id: named-checkzone.c,v 1.61.62.2 2011/12/22 23:45:54 tbox Exp $ */
19135446Strhodes
20170222Sdougb/*! \file */
21170222Sdougb
22135446Strhodes#include <config.h>
23135446Strhodes
24135446Strhodes#include <stdlib.h>
25135446Strhodes
26135446Strhodes#include <isc/app.h>
27135446Strhodes#include <isc/commandline.h>
28135446Strhodes#include <isc/dir.h>
29143731Sdougb#include <isc/entropy.h>
30143731Sdougb#include <isc/hash.h>
31135446Strhodes#include <isc/log.h>
32135446Strhodes#include <isc/mem.h>
33135446Strhodes#include <isc/socket.h>
34135446Strhodes#include <isc/string.h>
35135446Strhodes#include <isc/task.h>
36135446Strhodes#include <isc/timer.h>
37135446Strhodes#include <isc/util.h>
38135446Strhodes
39135446Strhodes#include <dns/db.h>
40135446Strhodes#include <dns/fixedname.h>
41135446Strhodes#include <dns/log.h>
42170222Sdougb#include <dns/masterdump.h>
43170222Sdougb#include <dns/name.h>
44135446Strhodes#include <dns/rdataclass.h>
45135446Strhodes#include <dns/rdataset.h>
46135446Strhodes#include <dns/result.h>
47170222Sdougb#include <dns/types.h>
48135446Strhodes#include <dns/zone.h>
49135446Strhodes
50135446Strhodes#include "check-tool.h"
51135446Strhodes
52135446Strhodesstatic int quiet = 0;
53135446Strhodesstatic isc_mem_t *mctx = NULL;
54143731Sdougbstatic isc_entropy_t *ectx = NULL;
55135446Strhodesdns_zone_t *zone = NULL;
56135446Strhodesdns_zonetype_t zonetype = dns_zone_master;
57135446Strhodesstatic int dumpzone = 0;
58135446Strhodesstatic const char *output_filename;
59170222Sdougbstatic char *prog_name = NULL;
60170222Sdougbstatic const dns_master_style_t *outputstyle = NULL;
61170222Sdougbstatic enum { progmode_check, progmode_compile } progmode;
62135446Strhodes
63135446Strhodes#define ERRRET(result, function) \
64135446Strhodes	do { \
65135446Strhodes		if (result != ISC_R_SUCCESS) { \
66135446Strhodes			if (!quiet) \
67135446Strhodes				fprintf(stderr, "%s() returned %s\n", \
68135446Strhodes					function, dns_result_totext(result)); \
69135446Strhodes			return (result); \
70135446Strhodes		} \
71135446Strhodes	} while (0)
72135446Strhodes
73224092SdougbISC_PLATFORM_NORETURN_PRE static void
74224092Sdougbusage(void) ISC_PLATFORM_NORETURN_POST;
75224092Sdougb
76135446Strhodesstatic void
77135446Strhodesusage(void) {
78135446Strhodes	fprintf(stderr,
79204619Sdougb		"usage: %s [-djqvD] [-c class] "
80170222Sdougb		"[-f inputformat] [-F outputformat] "
81143731Sdougb		"[-t directory] [-w directory] [-k (ignore|warn|fail)] "
82170222Sdougb		"[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
83224092Sdougb		"[-r (ignore|warn|fail)] "
84186462Sdougb		"[-i (full|full-sibling|local|local-sibling|none)] "
85186462Sdougb		"[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
86186462Sdougb		"[-W (ignore|warn)] "
87204619Sdougb		"%s zonename filename\n",
88204619Sdougb		prog_name,
89224092Sdougb		progmode == progmode_check ? "[-o filename]" : "-o filename");
90135446Strhodes	exit(1);
91135446Strhodes}
92135446Strhodes
93135446Strhodesstatic void
94135446Strhodesdestroy(void) {
95135446Strhodes	if (zone != NULL)
96135446Strhodes		dns_zone_detach(&zone);
97170222Sdougb	dns_name_destroy();
98135446Strhodes}
99135446Strhodes
100170222Sdougb/*% main processing routine */
101135446Strhodesint
102135446Strhodesmain(int argc, char **argv) {
103135446Strhodes	int c;
104135446Strhodes	char *origin = NULL;
105135446Strhodes	char *filename = NULL;
106135446Strhodes	isc_log_t *lctx = NULL;
107135446Strhodes	isc_result_t result;
108135446Strhodes	char classname_in[] = "IN";
109135446Strhodes	char *classname = classname_in;
110135446Strhodes	const char *workdir = NULL;
111170222Sdougb	const char *inputformatstr = NULL;
112170222Sdougb	const char *outputformatstr = NULL;
113170222Sdougb	dns_masterformat_t inputformat = dns_masterformat_text;
114170222Sdougb	dns_masterformat_t outputformat = dns_masterformat_text;
115234010Sdougb	isc_boolean_t logdump = ISC_FALSE;
116193149Sdougb	FILE *errout = stdout;
117135446Strhodes
118170222Sdougb	outputstyle = &dns_master_style_full;
119170222Sdougb
120170222Sdougb	prog_name = strrchr(argv[0], '/');
121174187Sdougb	if (prog_name == NULL)
122174187Sdougb		prog_name = strrchr(argv[0], '\\');
123170222Sdougb	if (prog_name != NULL)
124170222Sdougb		prog_name++;
125170222Sdougb	else
126170222Sdougb		prog_name = argv[0];
127170222Sdougb	/*
128170222Sdougb	 * Libtool doesn't preserve the program name prior to final
129170222Sdougb	 * installation.  Remove the libtool prefix ("lt-").
130170222Sdougb	 */
131170222Sdougb	if (strncmp(prog_name, "lt-", 3) == 0)
132170222Sdougb		prog_name += 3;
133194995Sdougb
134194995Sdougb#define PROGCMP(X) \
135194995Sdougb	(strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
136194995Sdougb
137194995Sdougb	if (PROGCMP("named-checkzone"))
138170222Sdougb		progmode = progmode_check;
139194995Sdougb	else if (PROGCMP("named-compilezone"))
140170222Sdougb		progmode = progmode_compile;
141170222Sdougb	else
142170222Sdougb		INSIST(0);
143170222Sdougb
144170222Sdougb	/* Compilation specific defaults */
145170222Sdougb	if (progmode == progmode_compile) {
146170222Sdougb		zone_options |= (DNS_ZONEOPT_CHECKNS |
147170222Sdougb				 DNS_ZONEOPT_FATALNS |
148224092Sdougb				 DNS_ZONEOPT_CHECKDUPRR |
149170222Sdougb				 DNS_ZONEOPT_CHECKNAMES |
150170222Sdougb				 DNS_ZONEOPT_CHECKNAMESFAIL |
151170222Sdougb				 DNS_ZONEOPT_CHECKWILDCARD);
152224092Sdougb	} else
153224092Sdougb		zone_options |= DNS_ZONEOPT_CHECKDUPRR;
154170222Sdougb
155170222Sdougb#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
156170222Sdougb
157193149Sdougb	isc_commandline_errprint = ISC_FALSE;
158193149Sdougb
159170222Sdougb	while ((c = isc_commandline_parse(argc, argv,
160224092Sdougb				       "c:df:hi:jk:m:n:qr:s:t:o:vw:DF:M:S:W:"))
161170222Sdougb	       != EOF) {
162135446Strhodes		switch (c) {
163135446Strhodes		case 'c':
164135446Strhodes			classname = isc_commandline_argument;
165135446Strhodes			break;
166135446Strhodes
167135446Strhodes		case 'd':
168135446Strhodes			debug++;
169135446Strhodes			break;
170135446Strhodes
171170222Sdougb		case 'i':
172170222Sdougb			if (ARGCMP("full")) {
173170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
174170222Sdougb						DNS_ZONEOPT_CHECKSIBLING;
175170222Sdougb				docheckmx = ISC_TRUE;
176170222Sdougb				docheckns = ISC_TRUE;
177170222Sdougb				dochecksrv = ISC_TRUE;
178170222Sdougb			} else if (ARGCMP("full-sibling")) {
179170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
180170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
181170222Sdougb				docheckmx = ISC_TRUE;
182170222Sdougb				docheckns = ISC_TRUE;
183170222Sdougb				dochecksrv = ISC_TRUE;
184170222Sdougb			} else if (ARGCMP("local")) {
185170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
186170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKSIBLING;
187170222Sdougb				docheckmx = ISC_FALSE;
188170222Sdougb				docheckns = ISC_FALSE;
189170222Sdougb				dochecksrv = ISC_FALSE;
190170222Sdougb			} else if (ARGCMP("local-sibling")) {
191170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
192170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
193170222Sdougb				docheckmx = ISC_FALSE;
194170222Sdougb				docheckns = ISC_FALSE;
195170222Sdougb				dochecksrv = ISC_FALSE;
196170222Sdougb			} else if (ARGCMP("none")) {
197170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
198170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
199170222Sdougb				docheckmx = ISC_FALSE;
200170222Sdougb				docheckns = ISC_FALSE;
201170222Sdougb				dochecksrv = ISC_FALSE;
202170222Sdougb			} else {
203170222Sdougb				fprintf(stderr, "invalid argument to -i: %s\n",
204170222Sdougb					isc_commandline_argument);
205170222Sdougb				exit(1);
206170222Sdougb			}
207170222Sdougb			break;
208170222Sdougb
209170222Sdougb		case 'f':
210170222Sdougb			inputformatstr = isc_commandline_argument;
211170222Sdougb			break;
212170222Sdougb
213170222Sdougb		case 'F':
214170222Sdougb			outputformatstr = isc_commandline_argument;
215170222Sdougb			break;
216170222Sdougb
217135446Strhodes		case 'j':
218135446Strhodes			nomerge = ISC_FALSE;
219135446Strhodes			break;
220135446Strhodes
221170222Sdougb		case 'k':
222170222Sdougb			if (ARGCMP("warn")) {
223170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKNAMES;
224170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
225170222Sdougb			} else if (ARGCMP("fail")) {
226170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKNAMES |
227170222Sdougb						DNS_ZONEOPT_CHECKNAMESFAIL;
228170222Sdougb			} else if (ARGCMP("ignore")) {
229170222Sdougb				zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
230170222Sdougb						  DNS_ZONEOPT_CHECKNAMESFAIL);
231170222Sdougb			} else {
232170222Sdougb				fprintf(stderr, "invalid argument to -k: %s\n",
233170222Sdougb					isc_commandline_argument);
234170222Sdougb				exit(1);
235170222Sdougb			}
236170222Sdougb			break;
237170222Sdougb
238135446Strhodes		case 'n':
239170222Sdougb			if (ARGCMP("ignore")) {
240135446Strhodes				zone_options &= ~(DNS_ZONEOPT_CHECKNS|
241135446Strhodes						  DNS_ZONEOPT_FATALNS);
242170222Sdougb			} else if (ARGCMP("warn")) {
243135446Strhodes				zone_options |= DNS_ZONEOPT_CHECKNS;
244135446Strhodes				zone_options &= ~DNS_ZONEOPT_FATALNS;
245170222Sdougb			} else if (ARGCMP("fail")) {
246135446Strhodes				zone_options |= DNS_ZONEOPT_CHECKNS|
247186462Sdougb						DNS_ZONEOPT_FATALNS;
248170222Sdougb			} else {
249170222Sdougb				fprintf(stderr, "invalid argument to -n: %s\n",
250170222Sdougb					isc_commandline_argument);
251170222Sdougb				exit(1);
252170222Sdougb			}
253135446Strhodes			break;
254135446Strhodes
255170222Sdougb		case 'm':
256170222Sdougb			if (ARGCMP("warn")) {
257170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKMX;
258170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
259170222Sdougb			} else if (ARGCMP("fail")) {
260170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKMX |
261170222Sdougb						DNS_ZONEOPT_CHECKMXFAIL;
262170222Sdougb			} else if (ARGCMP("ignore")) {
263170222Sdougb				zone_options &= ~(DNS_ZONEOPT_CHECKMX |
264170222Sdougb						  DNS_ZONEOPT_CHECKMXFAIL);
265170222Sdougb			} else {
266170222Sdougb				fprintf(stderr, "invalid argument to -m: %s\n",
267170222Sdougb					isc_commandline_argument);
268170222Sdougb				exit(1);
269135446Strhodes			}
270135446Strhodes			break;
271135446Strhodes
272224092Sdougb		case 'o':
273224092Sdougb			output_filename = isc_commandline_argument;
274224092Sdougb			break;
275224092Sdougb
276135446Strhodes		case 'q':
277135446Strhodes			quiet++;
278135446Strhodes			break;
279135446Strhodes
280224092Sdougb		case 'r':
281224092Sdougb			if (ARGCMP("warn")) {
282224092Sdougb				zone_options |= DNS_ZONEOPT_CHECKDUPRR;
283224092Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
284224092Sdougb			} else if (ARGCMP("fail")) {
285224092Sdougb				zone_options |= DNS_ZONEOPT_CHECKDUPRR |
286224092Sdougb						DNS_ZONEOPT_CHECKDUPRRFAIL;
287224092Sdougb			} else if (ARGCMP("ignore")) {
288224092Sdougb				zone_options &= ~(DNS_ZONEOPT_CHECKDUPRR |
289224092Sdougb						  DNS_ZONEOPT_CHECKDUPRRFAIL);
290224092Sdougb			} else {
291224092Sdougb				fprintf(stderr, "invalid argument to -r: %s\n",
292224092Sdougb					isc_commandline_argument);
293135446Strhodes				exit(1);
294135446Strhodes			}
295135446Strhodes			break;
296135446Strhodes
297170222Sdougb		case 's':
298170222Sdougb			if (ARGCMP("full"))
299170222Sdougb				outputstyle = &dns_master_style_full;
300170222Sdougb			else if (ARGCMP("relative")) {
301170222Sdougb				outputstyle = &dns_master_style_default;
302170222Sdougb			} else {
303170222Sdougb				fprintf(stderr,
304170222Sdougb					"unknown or unsupported style: %s\n",
305170222Sdougb					isc_commandline_argument);
306170222Sdougb				exit(1);
307170222Sdougb			}
308170222Sdougb			break;
309170222Sdougb
310224092Sdougb		case 't':
311224092Sdougb			result = isc_dir_chroot(isc_commandline_argument);
312224092Sdougb			if (result != ISC_R_SUCCESS) {
313224092Sdougb				fprintf(stderr, "isc_dir_chroot: %s: %s\n",
314224092Sdougb					isc_commandline_argument,
315224092Sdougb					isc_result_totext(result));
316224092Sdougb				exit(1);
317224092Sdougb			}
318135446Strhodes			break;
319135446Strhodes
320135446Strhodes		case 'v':
321135446Strhodes			printf(VERSION "\n");
322135446Strhodes			exit(0);
323135446Strhodes
324135446Strhodes		case 'w':
325135446Strhodes			workdir = isc_commandline_argument;
326135446Strhodes			break;
327135446Strhodes
328135446Strhodes		case 'D':
329135446Strhodes			dumpzone++;
330135446Strhodes			break;
331135446Strhodes
332170222Sdougb		case 'M':
333170222Sdougb			if (ARGCMP("fail")) {
334170222Sdougb				zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
335170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
336170222Sdougb			} else if (ARGCMP("warn")) {
337170222Sdougb				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
338170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
339170222Sdougb			} else if (ARGCMP("ignore")) {
340170222Sdougb				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
341170222Sdougb				zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
342170222Sdougb			} else {
343170222Sdougb				fprintf(stderr, "invalid argument to -M: %s\n",
344170222Sdougb					isc_commandline_argument);
345170222Sdougb				exit(1);
346170222Sdougb			}
347170222Sdougb			break;
348170222Sdougb
349170222Sdougb		case 'S':
350170222Sdougb			if (ARGCMP("fail")) {
351170222Sdougb				zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
352170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
353170222Sdougb			} else if (ARGCMP("warn")) {
354170222Sdougb				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
355170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
356170222Sdougb			} else if (ARGCMP("ignore")) {
357170222Sdougb				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
358170222Sdougb				zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
359170222Sdougb			} else {
360170222Sdougb				fprintf(stderr, "invalid argument to -S: %s\n",
361170222Sdougb					isc_commandline_argument);
362170222Sdougb				exit(1);
363170222Sdougb			}
364170222Sdougb			break;
365170222Sdougb
366170222Sdougb		case 'W':
367170222Sdougb			if (ARGCMP("warn"))
368170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
369170222Sdougb			else if (ARGCMP("ignore"))
370170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
371170222Sdougb			break;
372170222Sdougb
373193149Sdougb		case '?':
374193149Sdougb			if (isc_commandline_option != '?')
375193149Sdougb				fprintf(stderr, "%s: invalid argument -%c\n",
376193149Sdougb					prog_name, isc_commandline_option);
377193149Sdougb		case 'h':
378135446Strhodes			usage();
379135446Strhodes
380193149Sdougb		default:
381193149Sdougb			fprintf(stderr, "%s: unhandled option -%c\n",
382193149Sdougb				prog_name, isc_commandline_option);
383193149Sdougb			exit(1);
384170222Sdougb		}
385170222Sdougb	}
386170222Sdougb
387135446Strhodes	if (workdir != NULL) {
388135446Strhodes		result = isc_dir_chdir(workdir);
389135446Strhodes		if (result != ISC_R_SUCCESS) {
390135446Strhodes			fprintf(stderr, "isc_dir_chdir: %s: %s\n",
391135446Strhodes				workdir, isc_result_totext(result));
392135446Strhodes			exit(1);
393135446Strhodes		}
394135446Strhodes	}
395135446Strhodes
396170222Sdougb	if (inputformatstr != NULL) {
397170222Sdougb		if (strcasecmp(inputformatstr, "text") == 0)
398170222Sdougb			inputformat = dns_masterformat_text;
399170222Sdougb		else if (strcasecmp(inputformatstr, "raw") == 0)
400170222Sdougb			inputformat = dns_masterformat_raw;
401170222Sdougb		else {
402170222Sdougb			fprintf(stderr, "unknown file format: %s\n",
403170222Sdougb			    inputformatstr);
404170222Sdougb			exit(1);
405170222Sdougb		}
406170222Sdougb	}
407170222Sdougb
408170222Sdougb	if (outputformatstr != NULL) {
409170222Sdougb		if (strcasecmp(outputformatstr, "text") == 0)
410170222Sdougb			outputformat = dns_masterformat_text;
411170222Sdougb		else if (strcasecmp(outputformatstr, "raw") == 0)
412170222Sdougb			outputformat = dns_masterformat_raw;
413170222Sdougb		else {
414170222Sdougb			fprintf(stderr, "unknown file format: %s\n",
415170222Sdougb				outputformatstr);
416170222Sdougb			exit(1);
417170222Sdougb		}
418170222Sdougb	}
419170222Sdougb
420193149Sdougb	if (progmode == progmode_compile) {
421193149Sdougb		dumpzone = 1;	/* always dump */
422234010Sdougb		logdump = !quiet;
423193149Sdougb		if (output_filename == NULL) {
424193149Sdougb			fprintf(stderr,
425193149Sdougb				"output file required, but not specified\n");
426193149Sdougb			usage();
427193149Sdougb		}
428193149Sdougb	}
429193149Sdougb
430193149Sdougb	if (output_filename != NULL)
431193149Sdougb		dumpzone = 1;
432193149Sdougb
433193149Sdougb	/*
434193149Sdougb	 * If we are outputing to stdout then send the informational
435193149Sdougb	 * output to stderr.
436193149Sdougb	 */
437193149Sdougb	if (dumpzone &&
438193149Sdougb	    (output_filename == NULL ||
439193149Sdougb	     strcmp(output_filename, "-") == 0 ||
440193149Sdougb	     strcmp(output_filename, "/dev/fd/1") == 0 ||
441234010Sdougb	     strcmp(output_filename, "/dev/stdout") == 0)) {
442193149Sdougb		errout = stderr;
443234010Sdougb		logdump = ISC_FALSE;
444234010Sdougb	}
445193149Sdougb
446193149Sdougb	if (isc_commandline_index + 2 != argc)
447135446Strhodes		usage();
448135446Strhodes
449216175Sdougb#ifdef _WIN32
450216175Sdougb	InitSockets();
451216175Sdougb#endif
452216175Sdougb
453135446Strhodes	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
454170222Sdougb	if (!quiet)
455193149Sdougb		RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
456193149Sdougb			      == ISC_R_SUCCESS);
457143731Sdougb	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
458143731Sdougb	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
459143731Sdougb		      == ISC_R_SUCCESS);
460135446Strhodes
461135446Strhodes	dns_result_register();
462135446Strhodes
463135446Strhodes	origin = argv[isc_commandline_index++];
464135446Strhodes	filename = argv[isc_commandline_index++];
465170222Sdougb	result = load_zone(mctx, origin, filename, inputformat, classname,
466170222Sdougb			   &zone);
467135446Strhodes
468135446Strhodes	if (result == ISC_R_SUCCESS && dumpzone) {
469234010Sdougb		if (logdump) {
470193149Sdougb			fprintf(errout, "dump zone to %s...", output_filename);
471193149Sdougb			fflush(errout);
472170222Sdougb		}
473170222Sdougb		result = dump_zone(origin, zone, output_filename,
474170222Sdougb				   outputformat, outputstyle);
475234010Sdougb		if (logdump)
476193149Sdougb			fprintf(errout, "done\n");
477135446Strhodes	}
478135446Strhodes
479135446Strhodes	if (!quiet && result == ISC_R_SUCCESS)
480193149Sdougb		fprintf(errout, "OK\n");
481135446Strhodes	destroy();
482135446Strhodes	if (lctx != NULL)
483135446Strhodes		isc_log_destroy(&lctx);
484143731Sdougb	isc_hash_destroy();
485143731Sdougb	isc_entropy_detach(&ectx);
486135446Strhodes	isc_mem_destroy(&mctx);
487216175Sdougb#ifdef _WIN32
488216175Sdougb	DestroySockets();
489216175Sdougb#endif
490135446Strhodes	return ((result == ISC_R_SUCCESS) ? 0 : 1);
491135446Strhodes}
492