xref: /openbsd/usr.sbin/nsd/nsd-checkzone.c (revision a6445c1d)
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 static void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
26 struct nsd nsd;
27 
28 /*
29  * Print the help text.
30  *
31  */
32 static void
33 usage (void)
34 {
35 	fprintf(stderr, "Usage: nsd-checkzone <zone name> <zone file>\n");
36 	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
37 		PACKAGE_VERSION, PACKAGE_BUGREPORT);
38 }
39 
40 /*
41  * Something went wrong, give error messages and exit.
42  *
43  */
44 static void
45 error(const char *format, ...)
46 {
47 	va_list args;
48 	va_start(args, format);
49 	log_vmsg(LOG_ERR, format, args);
50 	va_end(args);
51 	exit(1);
52 }
53 
54 static void
55 check_zone(struct nsd* nsd, const char* name, const char* fname)
56 {
57 	const dname_type* dname;
58 	zone_options_t* zo;
59 	zone_type* zone;
60 	unsigned errors;
61 
62 	/* init*/
63 	nsd->db = namedb_open("", nsd->options);
64 	dname = dname_parse(nsd->options->region, name);
65 	if(!dname) {
66 		/* parse failure */
67 		error("cannot parse zone name '%s'", name);
68 	}
69 	zo = zone_options_create(nsd->options->region);
70 	memset(zo, 0, sizeof(*zo));
71 	zo->node.key = dname;
72 	zo->name = name;
73 	zone = namedb_zone_create(nsd->db, dname, zo);
74 
75 	/* read the zone */
76 	errors = zonec_read(name, fname, zone);
77 	if(errors > 0) {
78 		printf("zone %s file %s has %u errors\n", name, fname, errors);
79 		exit(1);
80 	}
81 	printf("zone %s is ok\n", name);
82 	namedb_close(nsd->db);
83 }
84 
85 /* dummy functions to link */
86 int writepid(struct nsd * ATTR_UNUSED(nsd))
87 {
88 	        return 0;
89 }
90 void unlinkpid(const char * ATTR_UNUSED(file))
91 {
92 }
93 void bind8_stats(struct nsd * ATTR_UNUSED(nsd))
94 {
95 }
96 
97 void sig_handler(int ATTR_UNUSED(sig))
98 {
99 }
100 
101 extern char *optarg;
102 extern int optind;
103 
104 int
105 main(int argc, char *argv[])
106 {
107 	/* Scratch variables... */
108 	int c;
109 	struct nsd nsd;
110 	memset(&nsd, 0, sizeof(nsd));
111 
112 	log_init("nsd-checkzone");
113 
114 	/* Parse the command line... */
115 	while ((c = getopt(argc, argv, "h")) != -1) {
116 		switch (c) {
117 		case 'h':
118 			usage();
119 			exit(0);
120 		case '?':
121 		default:
122 			usage();
123 			exit(1);
124 		}
125 	}
126 	argc -= optind;
127 	argv += optind;
128 
129 	/* Commandline parse error */
130 	if (argc != 2) {
131 		fprintf(stderr, "wrong number of arguments.\n");
132 		usage();
133 		exit(1);
134 	}
135 
136 	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
137 		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
138 		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
139 	if (verbosity == 0)
140 		verbosity = nsd.options->verbosity;
141 
142 	check_zone(&nsd, argv[0], argv[1]);
143 	region_destroy(nsd.options->region);
144 	/* yylex_destroy(); but, not available in all versions of flex */
145 
146 	exit(0);
147 }
148