nsd-checkzone.c revision 1.5
1/*
2 * nsd-checkzone.c -- nsd-checkzone(8) checks zones for syntax errors
3 *
4 * Copyright (c) 2013, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10#include "config.h"
11
12#include <assert.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <time.h>
17#include <unistd.h>
18#include <errno.h>
19
20#include "nsd.h"
21#include "options.h"
22#include "util.h"
23#include "zonec.h"
24
25struct nsd nsd;
26
27/*
28 * Print the help text.
29 *
30 */
31static void
32usage (void)
33{
34	fprintf(stderr, "Usage: nsd-checkzone [-p] <zone name> <zone file>\n");
35	fprintf(stderr, "\t-p\tprint the zone if the zone is ok\n");
36	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
37		PACKAGE_VERSION, PACKAGE_BUGREPORT);
38}
39
40static void
41check_zone(struct nsd* nsd, const char* name, const char* fname, FILE *out)
42{
43	const dname_type* dname;
44	zone_options_type* zo;
45	zone_type* zone;
46	unsigned errors;
47
48	/* init*/
49	nsd->db = namedb_open("", nsd->options);
50	dname = dname_parse(nsd->options->region, name);
51	if(!dname) {
52		/* parse failure */
53		error("cannot parse zone name '%s'", name);
54	}
55	zo = zone_options_create(nsd->options->region);
56	memset(zo, 0, sizeof(*zo));
57	zo->node.key = dname;
58	zo->name = name;
59	zone = namedb_zone_create(nsd->db, dname, zo);
60
61	/* read the zone */
62	errors = zonec_read(name, fname, zone);
63	if(errors > 0) {
64		printf("zone %s file %s has %u errors\n", name, fname, errors);
65#ifdef MEMCLEAN /* otherwise, the OS collects memory pages */
66		namedb_close(nsd->db);
67		region_destroy(nsd->options->region);
68#endif
69		exit(1);
70	}
71	if (out) {
72		print_rrs(out, zone);
73		printf("; ");
74	}
75	printf("zone %s is ok\n", name);
76	namedb_close(nsd->db);
77}
78
79/* dummy functions to link */
80int writepid(struct nsd * ATTR_UNUSED(nsd))
81{
82	        return 0;
83}
84void unlinkpid(const char * ATTR_UNUSED(file))
85{
86}
87void bind8_stats(struct nsd * ATTR_UNUSED(nsd))
88{
89}
90
91void sig_handler(int ATTR_UNUSED(sig))
92{
93}
94
95extern char *optarg;
96extern int optind;
97
98int
99main(int argc, char *argv[])
100{
101	/* Scratch variables... */
102	int c;
103	int print_zone = 0;
104	struct nsd nsd;
105	memset(&nsd, 0, sizeof(nsd));
106
107	log_init("nsd-checkzone");
108
109	/* Parse the command line... */
110	while ((c = getopt(argc, argv, "hp")) != -1) {
111		switch (c) {
112		case 'h':
113			usage();
114			exit(0);
115		case 'p':
116			print_zone = 1;
117			break;
118		case '?':
119		default:
120			usage();
121			exit(1);
122		}
123	}
124	argc -= optind;
125	argv += optind;
126
127	/* Commandline parse error */
128	if (argc != 2) {
129		fprintf(stderr, "wrong number of arguments.\n");
130		usage();
131		exit(1);
132	}
133
134	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
135		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
136		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
137	if (verbosity == 0)
138		verbosity = nsd.options->verbosity;
139
140	check_zone(&nsd, argv[0], argv[1], print_zone ? stdout : NULL);
141	region_destroy(nsd.options->region);
142	/* yylex_destroy(); but, not available in all versions of flex */
143
144	exit(0);
145}
146