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