xref: /openbsd-src/usr.sbin/nsd/nsd-checkzone.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
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 
25 struct nsd nsd;
26 
27 /*
28  * Print the help text.
29  *
30  */
31 static void
32 usage (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 
40 static void
41 check_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 */
80 int writepid(struct nsd * ATTR_UNUSED(nsd))
81 {
82 	        return 0;
83 }
84 void unlinkpid(const char * ATTR_UNUSED(file))
85 {
86 }
87 void bind8_stats(struct nsd * ATTR_UNUSED(nsd))
88 {
89 }
90 
91 void sig_handler(int ATTR_UNUSED(sig))
92 {
93 }
94 
95 extern char *optarg;
96 extern int optind;
97 
98 int
99 main(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