예제 #1
0
/*% directory callback */
static isc_result_t
directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
	isc_result_t result;
	const char *directory;

	REQUIRE(strcasecmp("directory", clausename) == 0);

	UNUSED(arg);
	UNUSED(clausename);

	/*
	 * Change directory.
	 */
	directory = cfg_obj_asstring(obj);
	result = isc_dir_chdir(directory);
	if (result != ISC_R_SUCCESS) {
		cfg_obj_log(obj, logc, ISC_LOG_ERROR,
			    "change directory to '%s' failed: %s\n",
			    directory, isc_result_totext(result));
		return (result);
	}

	return (ISC_R_SUCCESS);
}
예제 #2
0
/*% main processing routine */
int
main(int argc, char **argv) {
	int c;
	char *origin = NULL;
	char *filename = NULL;
	isc_log_t *lctx = NULL;
	isc_result_t result;
	char classname_in[] = "IN";
	char *classname = classname_in;
	const char *workdir = NULL;
	const char *inputformatstr = NULL;
	const char *outputformatstr = NULL;
	dns_masterformat_t inputformat = dns_masterformat_text;
	dns_masterformat_t outputformat = dns_masterformat_text;

	outputstyle = &dns_master_style_full;

	prog_name = strrchr(argv[0], '/');
	if (prog_name == NULL)
		prog_name = strrchr(argv[0], '\\');
	if (prog_name != NULL)
		prog_name++;
	else
		prog_name = argv[0];
	/*
	 * Libtool doesn't preserve the program name prior to final
	 * installation.  Remove the libtool prefix ("lt-").
	 */
	if (strncmp(prog_name, "lt-", 3) == 0)
		prog_name += 3;
	if (strcmp(prog_name, "named-checkzone") == 0)
		progmode = progmode_check;
	else if (strcmp(prog_name, "named-compilezone") == 0)
		progmode = progmode_compile;
	else
		INSIST(0);

	/* Compilation specific defaults */
	if (progmode == progmode_compile) {
		zone_options |= (DNS_ZONEOPT_CHECKNS |
				 DNS_ZONEOPT_FATALNS |
				 DNS_ZONEOPT_CHECKNAMES |
				 DNS_ZONEOPT_CHECKNAMESFAIL |
				 DNS_ZONEOPT_CHECKWILDCARD);
	}

#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)

	while ((c = isc_commandline_parse(argc, argv,
					  "c:df:i:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
	       != EOF) {
		switch (c) {
		case 'c':
			classname = isc_commandline_argument;
			break;

		case 'd':
			debug++;
			break;

		case 'i':
			if (ARGCMP("full")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
						DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_TRUE;
				docheckns = ISC_TRUE;
				dochecksrv = ISC_TRUE;
			} else if (ARGCMP("full-sibling")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_TRUE;
				docheckns = ISC_TRUE;
				dochecksrv = ISC_TRUE;
			} else if (ARGCMP("local")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options |= DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else if (ARGCMP("local-sibling")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else if (ARGCMP("none")) {
				zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else {
				fprintf(stderr, "invalid argument to -i: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'f':
			inputformatstr = isc_commandline_argument;
			break;

		case 'F':
			outputformatstr = isc_commandline_argument;
			break;

		case 'j':
			nomerge = ISC_FALSE;
			break;

		case 'k':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES;
				zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES |
						DNS_ZONEOPT_CHECKNAMESFAIL;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
						  DNS_ZONEOPT_CHECKNAMESFAIL);
			} else {
				fprintf(stderr, "invalid argument to -k: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'n':
			if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKNS|
						  DNS_ZONEOPT_FATALNS);
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKNS;
				zone_options &= ~DNS_ZONEOPT_FATALNS;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKNS|
					        DNS_ZONEOPT_FATALNS;
			} else {
				fprintf(stderr, "invalid argument to -n: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'm':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKMX;
				zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKMX |
						DNS_ZONEOPT_CHECKMXFAIL;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKMX |
						  DNS_ZONEOPT_CHECKMXFAIL);
			} else {
				fprintf(stderr, "invalid argument to -m: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'q':
			quiet++;
			break;

		case 't':
			result = isc_dir_chroot(isc_commandline_argument);
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chroot: %s: %s\n",
					isc_commandline_argument,
					isc_result_totext(result));
				exit(1);
			}
			result = isc_dir_chdir("/");
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chdir: %s\n",
					isc_result_totext(result));
				exit(1);
			}
			break;

		case 's':
			if (ARGCMP("full"))
				outputstyle = &dns_master_style_full;
			else if (ARGCMP("relative")) {
				outputstyle = &dns_master_style_default;
			} else {
				fprintf(stderr,
					"unknown or unsupported style: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'o':
			output_filename = isc_commandline_argument;
			break;

		case 'v':
			printf(VERSION "\n");
			exit(0);

		case 'w':
			workdir = isc_commandline_argument;
			break;

		case 'D':
			dumpzone++;
			break;

		case 'M':
			if (ARGCMP("fail")) {
				zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
			} else if (ARGCMP("ignore")) {
				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
				zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
			} else {
				fprintf(stderr, "invalid argument to -M: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'S':
			if (ARGCMP("fail")) {
				zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
			} else if (ARGCMP("ignore")) {
				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
				zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
			} else {
				fprintf(stderr, "invalid argument to -S: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'W':
			if (ARGCMP("warn"))
				zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
			else if (ARGCMP("ignore"))
				zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
			break;

		default:
			usage();
		}
	}

	if (progmode == progmode_compile) {
		dumpzone = 1;	/* always dump */
		if (output_filename == NULL) {
			fprintf(stderr,
				"output file required, but not specified\n");
			usage();
		}
	}

	if (workdir != NULL) {
		result = isc_dir_chdir(workdir);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "isc_dir_chdir: %s: %s\n",
				workdir, isc_result_totext(result));
			exit(1);
		}
	}

	if (inputformatstr != NULL) {
		if (strcasecmp(inputformatstr, "text") == 0)
			inputformat = dns_masterformat_text;
		else if (strcasecmp(inputformatstr, "raw") == 0)
			inputformat = dns_masterformat_raw;
		else {
			fprintf(stderr, "unknown file format: %s\n",
			    inputformatstr);
			exit(1);
		}
	}

	if (outputformatstr != NULL) {
		if (strcasecmp(outputformatstr, "text") == 0)
			outputformat = dns_masterformat_text;
		else if (strcasecmp(outputformatstr, "raw") == 0)
			outputformat = dns_masterformat_raw;
		else {
			fprintf(stderr, "unknown file format: %s\n",
				outputformatstr);
			exit(1);
		}
	}

	if (isc_commandline_index + 2 > argc)
		usage();

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	if (!quiet)
		RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
		      == ISC_R_SUCCESS);

	dns_result_register();

	origin = argv[isc_commandline_index++];
	filename = argv[isc_commandline_index++];
	result = load_zone(mctx, origin, filename, inputformat, classname,
			   &zone);

	if (result == ISC_R_SUCCESS && dumpzone) {
		if (!quiet && progmode == progmode_compile) {
			fprintf(stdout, "dump zone to %s...", output_filename);
			fflush(stdout);
		}
		result = dump_zone(origin, zone, output_filename,
				   outputformat, outputstyle);
		if (!quiet && progmode == progmode_compile)
			fprintf(stdout, "done\n");
	}

	if (!quiet && result == ISC_R_SUCCESS)
		fprintf(stdout, "OK\n");
	destroy();
	if (lctx != NULL)
		isc_log_destroy(&lctx);
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);
	return ((result == ISC_R_SUCCESS) ? 0 : 1);
}
예제 #3
0
/*% The main processing routine */
int
main(int argc, char **argv) {
	int c;
	cfg_parser_t *parser = NULL;
	cfg_obj_t *config = NULL;
	const char *conffile = NULL;
	isc_mem_t *mctx = NULL;
	isc_result_t result;
	int exit_status = 0;
	isc_entropy_t *ectx = NULL;
	isc_boolean_t load_zones = ISC_FALSE;
	
	isc_commandline_errprint = ISC_FALSE;

	while ((c = isc_commandline_parse(argc, argv, "dhjt:vz")) != EOF) {
		switch (c) {
		case 'd':
			debug++;
			break;

		case 'j':
			nomerge = ISC_FALSE;
			break;

		case 't':
			result = isc_dir_chroot(isc_commandline_argument);
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chroot: %s\n",
					isc_result_totext(result));
				exit(1);
			}
			result = isc_dir_chdir("/");
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chdir: %s\n",
					isc_result_totext(result));
				exit(1);
			}
			break;

		case 'v':
			printf(VERSION "\n");
			exit(0);

		case 'z':
			load_zones = ISC_TRUE;
			docheckmx = ISC_FALSE;
			docheckns = ISC_FALSE;
			dochecksrv = ISC_FALSE;
			break;

		case '?':
			if (isc_commandline_option != '?')
				fprintf(stderr, "%s: invalid argument -%c\n",
					program, isc_commandline_option);
		case 'h':
			usage();

		default:
			fprintf(stderr, "%s: unhandled option -%c\n",
				program, isc_commandline_option);
			exit(1);
		}
	}

	if (isc_commandline_index + 1 < argc)
		usage();
	if (argv[isc_commandline_index] != NULL)
		conffile = argv[isc_commandline_index];
	if (conffile == NULL || conffile[0] == '\0')
		conffile = NAMED_CONFFILE;

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);

	RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
		      == ISC_R_SUCCESS);

	dns_result_register();

	RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS);

	cfg_parser_setcallback(parser, directory_callback, NULL);

	if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) !=
	    ISC_R_SUCCESS)
		exit(1);

	result = bind9_check_namedconf(config, logc, mctx);
	if (result != ISC_R_SUCCESS)
		exit_status = 1;

	if (result == ISC_R_SUCCESS && load_zones) {
		result = load_zones_fromconfig(config, mctx);
		if (result != ISC_R_SUCCESS)
			exit_status = 1;
	}

	cfg_obj_destroy(parser, &config);

	cfg_parser_destroy(&parser);

	dns_name_destroy();

	isc_log_destroy(&logc);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);

	isc_mem_destroy(&mctx);

	return (exit_status);
}
int
main(int argc, char **argv) {
	int c;
	char *origin = NULL;
	char *filename = NULL;
	isc_log_t *lctx = NULL;
	isc_result_t result;
	char classname_in[] = "IN";
	char *classname = classname_in;
	const char *workdir = NULL;

	while ((c = isc_commandline_parse(argc, argv, "c:dijk:n:qst:o:vw:D")) != EOF) {
		switch (c) {
		case 'c':
			classname = isc_commandline_argument;
			break;

		case 'd':
			debug++;
			break;

		case 'j':
			nomerge = ISC_FALSE;
			break;

		case 'n':
			if (!strcmp(isc_commandline_argument, "ignore"))
				zone_options &= ~(DNS_ZONEOPT_CHECKNS|
						  DNS_ZONEOPT_FATALNS);
			else if (!strcmp(isc_commandline_argument, "warn")) {
				zone_options |= DNS_ZONEOPT_CHECKNS;
				zone_options &= ~DNS_ZONEOPT_FATALNS;
			} else if (!strcmp(isc_commandline_argument, "fail"))
				zone_options |= DNS_ZONEOPT_CHECKNS|
					        DNS_ZONEOPT_FATALNS;
			break;

		case 'k':
			if (!strcmp(isc_commandline_argument, "check-names")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES;
			} else if (!strcmp(isc_commandline_argument,
					   "check-names-fail")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES |
						DNS_ZONEOPT_CHECKNAMESFAIL;
			}
			break;

		case 'q':
			quiet++;
			break;

		case 't':
			result = isc_dir_chroot(isc_commandline_argument);
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chroot: %s: %s\n",
					isc_commandline_argument,
					isc_result_totext(result));
				exit(1);
			}
			result = isc_dir_chdir("/");
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chdir: %s\n",
					isc_result_totext(result));
				exit(1);
			}
			break;

		case 'o':
			output_filename = isc_commandline_argument;
			break;

		case 'v':
			printf(VERSION "\n");
			exit(0);

		case 'w':
			workdir = isc_commandline_argument;
			break;

		case 'D':
			dumpzone++;
			break;

		default:
			usage();
		}
	}

	if (workdir != NULL) {
		result = isc_dir_chdir(workdir);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "isc_dir_chdir: %s: %s\n",
				workdir, isc_result_totext(result));
			exit(1);
		}
	}

	if (isc_commandline_index + 2 > argc)
		usage();

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	if (!quiet) {
		RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS);
		dns_log_init(lctx);
		dns_log_setcontext(lctx);
	}

	dns_result_register();

	origin = argv[isc_commandline_index++];
	filename = argv[isc_commandline_index++];
	result = load_zone(mctx, origin, filename, classname, &zone);

	if (result == ISC_R_SUCCESS && dumpzone) {
		result = dump_zone(origin, zone, output_filename);
	}

	if (!quiet && result == ISC_R_SUCCESS)
		fprintf(stdout, "OK\n");
	destroy();
	if (lctx != NULL)
		isc_log_destroy(&lctx);
	isc_mem_destroy(&mctx);
	return ((result == ISC_R_SUCCESS) ? 0 : 1);
}
예제 #5
0
/*% main processing routine */
int
main(int argc, char **argv) {
	int c;
	char *origin = NULL;
	char *filename = NULL;
	isc_log_t *lctx = NULL;
	isc_result_t result;
	char classname_in[] = "IN";
	char *classname = classname_in;
	const char *workdir = NULL;
	const char *inputformatstr = NULL;
	const char *outputformatstr = NULL;
	dns_masterformat_t inputformat = dns_masterformat_text;
	dns_masterformat_t outputformat = dns_masterformat_text;
	dns_masterrawheader_t header;
	isc_uint32_t rawversion = 1, serialnum = 0;
	isc_boolean_t snset = ISC_FALSE;
	isc_boolean_t logdump = ISC_FALSE;
	FILE *errout = stdout;
	char *endp;

	outputstyle = &dns_master_style_full;

	prog_name = strrchr(argv[0], '/');
	if (prog_name == NULL)
		prog_name = strrchr(argv[0], '\\');
	if (prog_name != NULL)
		prog_name++;
	else
		prog_name = argv[0];
	/*
	 * Libtool doesn't preserve the program name prior to final
	 * installation.  Remove the libtool prefix ("lt-").
	 */
	if (strncmp(prog_name, "lt-", 3) == 0)
		prog_name += 3;

#define PROGCMP(X) \
	(strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)

	if (PROGCMP("named-checkzone"))
		progmode = progmode_check;
	else if (PROGCMP("named-compilezone"))
		progmode = progmode_compile;
	else
		INSIST(0);

	/* Compilation specific defaults */
	if (progmode == progmode_compile) {
		zone_options |= (DNS_ZONEOPT_CHECKNS |
				 DNS_ZONEOPT_FATALNS |
				 DNS_ZONEOPT_CHECKSPF |
				 DNS_ZONEOPT_CHECKDUPRR |
				 DNS_ZONEOPT_CHECKNAMES |
				 DNS_ZONEOPT_CHECKNAMESFAIL |
				 DNS_ZONEOPT_CHECKWILDCARD);
	} else
		zone_options |= (DNS_ZONEOPT_CHECKDUPRR |
				 DNS_ZONEOPT_CHECKSPF);

#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)

	isc_commandline_errprint = ISC_FALSE;

	while ((c = isc_commandline_parse(argc, argv,
			       "c:df:hi:jk:L:m:n:qr:s:t:o:vw:DF:M:S:T:W:"))
	       != EOF) {
		switch (c) {
		case 'c':
			classname = isc_commandline_argument;
			break;

		case 'd':
			debug++;
			break;

		case 'i':
			if (ARGCMP("full")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
						DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_TRUE;
				docheckns = ISC_TRUE;
				dochecksrv = ISC_TRUE;
			} else if (ARGCMP("full-sibling")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_TRUE;
				docheckns = ISC_TRUE;
				dochecksrv = ISC_TRUE;
			} else if (ARGCMP("local")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options |= DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else if (ARGCMP("local-sibling")) {
				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else if (ARGCMP("none")) {
				zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
				docheckmx = ISC_FALSE;
				docheckns = ISC_FALSE;
				dochecksrv = ISC_FALSE;
			} else {
				fprintf(stderr, "invalid argument to -i: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'f':
			inputformatstr = isc_commandline_argument;
			break;

		case 'F':
			outputformatstr = isc_commandline_argument;
			break;

		case 'j':
			nomerge = ISC_FALSE;
			break;

		case 'k':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES;
				zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKNAMES |
						DNS_ZONEOPT_CHECKNAMESFAIL;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
						  DNS_ZONEOPT_CHECKNAMESFAIL);
			} else {
				fprintf(stderr, "invalid argument to -k: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'L':
			snset = ISC_TRUE;
			endp = NULL;
			serialnum = strtol(isc_commandline_argument, &endp, 0);
			if (*endp != '\0') {
				fprintf(stderr, "source serial number "
						"must be numeric");
				exit(1);
			}
			break;

		case 'n':
			if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKNS|
						  DNS_ZONEOPT_FATALNS);
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKNS;
				zone_options &= ~DNS_ZONEOPT_FATALNS;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKNS|
						DNS_ZONEOPT_FATALNS;
			} else {
				fprintf(stderr, "invalid argument to -n: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'm':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKMX;
				zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKMX |
						DNS_ZONEOPT_CHECKMXFAIL;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKMX |
						  DNS_ZONEOPT_CHECKMXFAIL);
			} else {
				fprintf(stderr, "invalid argument to -m: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'o':
			output_filename = isc_commandline_argument;
			break;

		case 'q':
			quiet++;
			break;

		case 'r':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKDUPRR;
				zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
			} else if (ARGCMP("fail")) {
				zone_options |= DNS_ZONEOPT_CHECKDUPRR |
						DNS_ZONEOPT_CHECKDUPRRFAIL;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~(DNS_ZONEOPT_CHECKDUPRR |
						  DNS_ZONEOPT_CHECKDUPRRFAIL);
			} else {
				fprintf(stderr, "invalid argument to -r: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 's':
			if (ARGCMP("full"))
				outputstyle = &dns_master_style_full;
			else if (ARGCMP("relative")) {
				outputstyle = &dns_master_style_default;
			} else {
				fprintf(stderr,
					"unknown or unsupported style: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 't':
			result = isc_dir_chroot(isc_commandline_argument);
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr, "isc_dir_chroot: %s: %s\n",
					isc_commandline_argument,
					isc_result_totext(result));
				exit(1);
			}
			break;

		case 'v':
			printf(VERSION "\n");
			exit(0);

		case 'w':
			workdir = isc_commandline_argument;
			break;

		case 'D':
			dumpzone++;
			break;

		case 'M':
			if (ARGCMP("fail")) {
				zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
			} else if (ARGCMP("ignore")) {
				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
				zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
			} else {
				fprintf(stderr, "invalid argument to -M: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'S':
			if (ARGCMP("fail")) {
				zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
			} else if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
			} else if (ARGCMP("ignore")) {
				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
				zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
			} else {
				fprintf(stderr, "invalid argument to -S: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'T':
			if (ARGCMP("warn")) {
				zone_options |= DNS_ZONEOPT_CHECKSPF;
			} else if (ARGCMP("ignore")) {
				zone_options &= ~DNS_ZONEOPT_CHECKSPF;
			} else {
				fprintf(stderr, "invalid argument to -T: %s\n",
					isc_commandline_argument);
				exit(1);
			}
			break;

		case 'W':
			if (ARGCMP("warn"))
				zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
			else if (ARGCMP("ignore"))
				zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
			break;

		case '?':
			if (isc_commandline_option != '?')
				fprintf(stderr, "%s: invalid argument -%c\n",
					prog_name, isc_commandline_option);
			/* FALLTHROUGH */
		case 'h':
			usage();

		default:
			fprintf(stderr, "%s: unhandled option -%c\n",
				prog_name, isc_commandline_option);
			exit(1);
		}
	}

	if (workdir != NULL) {
		result = isc_dir_chdir(workdir);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "isc_dir_chdir: %s: %s\n",
				workdir, isc_result_totext(result));
			exit(1);
		}
	}

	if (inputformatstr != NULL) {
		if (strcasecmp(inputformatstr, "text") == 0)
			inputformat = dns_masterformat_text;
		else if (strcasecmp(inputformatstr, "raw") == 0)
			inputformat = dns_masterformat_raw;
		else if (strncasecmp(inputformatstr, "raw=", 4) == 0) {
			inputformat = dns_masterformat_raw;
			fprintf(stderr,
				"WARNING: input format raw, version ignored\n");
		} else {
			fprintf(stderr, "unknown file format: %s\n",
			    inputformatstr);
			exit(1);
		}
	}

	if (outputformatstr != NULL) {
		if (strcasecmp(outputformatstr, "text") == 0) {
			outputformat = dns_masterformat_text;
		} else if (strcasecmp(outputformatstr, "raw") == 0) {
			outputformat = dns_masterformat_raw;
		} else if (strncasecmp(outputformatstr, "raw=", 4) == 0) {
			char *end;

			outputformat = dns_masterformat_raw;
			rawversion = strtol(outputformatstr + 4, &end, 10);
			if (end == outputformatstr + 4 || *end != '\0' ||
			    rawversion > 1U) {
				fprintf(stderr,
					"unknown raw format version\n");
				exit(1);
			}
		} else {
			fprintf(stderr, "unknown file format: %s\n",
				outputformatstr);
			exit(1);
		}
	}

	if (progmode == progmode_compile) {
		dumpzone = 1;	/* always dump */
		logdump = !quiet;
		if (output_filename == NULL) {
			fprintf(stderr,
				"output file required, but not specified\n");
			usage();
		}
	}

	if (output_filename != NULL)
		dumpzone = 1;

	/*
	 * If we are outputing to stdout then send the informational
	 * output to stderr.
	 */
	if (dumpzone &&
	    (output_filename == NULL ||
	     strcmp(output_filename, "-") == 0 ||
	     strcmp(output_filename, "/dev/fd/1") == 0 ||
	     strcmp(output_filename, "/dev/stdout") == 0)) {
		errout = stderr;
		logdump = ISC_FALSE;
	}

	if (isc_commandline_index + 2 != argc)
		usage();

#ifdef _WIN32
	InitSockets();
#endif

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	if (!quiet)
		RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
			      == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
		      == ISC_R_SUCCESS);

	dns_result_register();

	origin = argv[isc_commandline_index++];
	filename = argv[isc_commandline_index++];
	result = load_zone(mctx, origin, filename, inputformat, classname,
			   &zone);

	if (snset) {
		dns_master_initrawheader(&header);
		header.flags = DNS_MASTERRAW_SOURCESERIALSET;
		header.sourceserial = serialnum;
		dns_zone_setrawdata(zone, &header);
	}

	if (result == ISC_R_SUCCESS && dumpzone) {
		if (logdump) {
			fprintf(errout, "dump zone to %s...", output_filename);
			fflush(errout);
		}
		result = dump_zone(origin, zone, output_filename,
				   outputformat, outputstyle, rawversion);
		if (logdump)
			fprintf(errout, "done\n");
	}

	if (!quiet && result == ISC_R_SUCCESS)
		fprintf(errout, "OK\n");
	destroy();
	if (lctx != NULL)
		isc_log_destroy(&lctx);
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);
#ifdef _WIN32
	DestroySockets();
#endif
	return ((result == ISC_R_SUCCESS) ? 0 : 1);
}