Home | History | Annotate | Line # | Download | only in dist
nsd-checkzone.c revision 1.1.1.6
      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 #include "ixfr.h"
     25 #include "ixfrcreate.h"
     26 #include "difffile.h"
     27 
     28 struct nsd nsd;
     29 
     30 /*
     31  * Print the help text.
     32  *
     33  */
     34 static void
     35 usage (void)
     36 {
     37 	fprintf(stderr, "Usage: nsd-checkzone [-p] <zone name> <zone file>\n");
     38 	fprintf(stderr, "\t-p\tprint the zone if the zone is ok\n");
     39 	fprintf(stderr, "\t-i <old zone file>\tcreate an IXFR from the differences between the\n\t\told zone file and the new zone file. Writes to \n\t\t<zonefile>.ixfr and renames other <zonefile>.ixfr files to\n\t\t<zonefile>.ixfr.num+1.\n");
     40 	fprintf(stderr, "\t-n <ixfr number>\tnumber of IXFR versions to store, at most.\n\t\tdefault %d.\n", (int)IXFR_NUMBER_DEFAULT);
     41 	fprintf(stderr, "\t-s <ixfr size>\tsize of IXFR to store, at most. default %d.\n", (int)IXFR_SIZE_DEFAULT);
     42 	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
     43 		PACKAGE_VERSION, PACKAGE_BUGREPORT);
     44 }
     45 
     46 static void
     47 check_zone(struct nsd* nsd, const char* name, const char* fname, FILE *out,
     48 	const char* oldzone, uint32_t ixfr_number, uint64_t ixfr_size)
     49 {
     50 	const dname_type* dname;
     51 	zone_options_type* zo;
     52 	zone_type* zone;
     53 	unsigned errors;
     54 	struct ixfr_create* ixfrcr = NULL;
     55 
     56 	/* init*/
     57 	nsd->db = namedb_open(nsd->options);
     58 	dname = dname_parse(nsd->options->region, name);
     59 	if(!dname) {
     60 		/* parse failure */
     61 		error("cannot parse zone name '%s'", name);
     62 	}
     63 	zo = zone_options_create(nsd->options->region);
     64 	memset(zo, 0, sizeof(*zo));
     65 	zo->node.key = dname;
     66 	zo->name = name;
     67 	zone = namedb_zone_create(nsd->db, dname, zo);
     68 
     69 	if(oldzone) {
     70 		errors = zonec_read(name, oldzone, zone);
     71 		if(errors > 0) {
     72 			printf("zone %s file %s has %u errors\n", name, oldzone, errors);
     73 			exit(1);
     74 		}
     75 		ixfrcr = ixfr_create_start(zone, fname, ixfr_size, 1);
     76 		if(!ixfrcr) {
     77 			error("out of memory");
     78 		}
     79 		delete_zone_rrs(nsd->db, zone);
     80 	}
     81 
     82 	/* read the zone */
     83 	errors = zonec_read(name, fname, zone);
     84 	if(errors > 0) {
     85 		printf("zone %s file %s has %u errors\n", name, fname, errors);
     86 		ixfr_create_cancel(ixfrcr);
     87 #ifdef MEMCLEAN /* otherwise, the OS collects memory pages */
     88 		namedb_close(nsd->db);
     89 		region_destroy(nsd->options->region);
     90 #endif
     91 		exit(1);
     92 	}
     93 	if(ixfrcr) {
     94 		if(!ixfr_create_perform(ixfrcr, zone, 0, nsd, fname,
     95 			ixfr_number)) {
     96 #ifdef MEMCLEAN /* otherwise, the OS collects memory pages */
     97 			namedb_close(nsd->db);
     98 			region_destroy(nsd->options->region);
     99 			ixfr_create_free(ixfrcr);
    100 #endif
    101 			error("could not create IXFR");
    102 		}
    103 		printf("zone %s created IXFR %s.ixfr\n", name, fname);
    104 		ixfr_create_free(ixfrcr);
    105 	}
    106 	if (out) {
    107 		print_rrs(out, zone);
    108 		printf("; ");
    109 	}
    110 	printf("zone %s is ok\n", name);
    111 	namedb_close(nsd->db);
    112 }
    113 
    114 /* dummy functions to link */
    115 int writepid(struct nsd * ATTR_UNUSED(nsd))
    116 {
    117 	        return 0;
    118 }
    119 void unlinkpid(const char * ATTR_UNUSED(file))
    120 {
    121 }
    122 void bind8_stats(struct nsd * ATTR_UNUSED(nsd))
    123 {
    124 }
    125 
    126 void sig_handler(int ATTR_UNUSED(sig))
    127 {
    128 }
    129 
    130 extern char *optarg;
    131 extern int optind;
    132 
    133 int
    134 main(int argc, char *argv[])
    135 {
    136 	/* Scratch variables... */
    137 	int c;
    138 	int print_zone = 0;
    139 	uint32_t ixfr_number = IXFR_NUMBER_DEFAULT;
    140 	uint64_t ixfr_size = IXFR_SIZE_DEFAULT;
    141 	char* oldzone = NULL;
    142 	struct nsd nsd;
    143 	memset(&nsd, 0, sizeof(nsd));
    144 
    145 	log_init("nsd-checkzone");
    146 
    147 	/* Parse the command line... */
    148 	while ((c = getopt(argc, argv, "hi:n:ps:")) != -1) {
    149 		switch (c) {
    150 		case 'h':
    151 			usage();
    152 			exit(0);
    153 		case 'i':
    154 			oldzone = optarg;
    155 			break;
    156 		case 'n':
    157 			ixfr_number = (uint32_t)atoi(optarg);
    158 			break;
    159 		case 'p':
    160 			print_zone = 1;
    161 			break;
    162 		case 's':
    163 			ixfr_size = (uint64_t)atoi(optarg);
    164 			break;
    165 		case '?':
    166 		default:
    167 			usage();
    168 			exit(1);
    169 		}
    170 	}
    171 	argc -= optind;
    172 	argv += optind;
    173 
    174 	/* Commandline parse error */
    175 	if (argc != 2) {
    176 		fprintf(stderr, "wrong number of arguments.\n");
    177 		usage();
    178 		exit(1);
    179 	}
    180 
    181 	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
    182 		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
    183 		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
    184 	if (verbosity == 0)
    185 		verbosity = nsd.options->verbosity;
    186 
    187 	check_zone(&nsd, argv[0], argv[1], print_zone ? stdout : NULL,
    188 		oldzone, ixfr_number, ixfr_size);
    189 	region_destroy(nsd.options->region);
    190 	/* yylex_destroy(); but, not available in all versions of flex */
    191 
    192 	exit(0);
    193 }
    194