Merge from vendor branch GCC:
[dragonfly.git] / contrib / bind-9.3 / bin / check / named-checkzone.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: named-checkzone.c,v 1.13.2.3.8.11 2004/10/25 01:36:06 marka Exp $ */
19
20 #include <config.h>
21
22 #include <stdlib.h>
23
24 #include <isc/app.h>
25 #include <isc/commandline.h>
26 #include <isc/dir.h>
27 #include <isc/entropy.h>
28 #include <isc/hash.h>
29 #include <isc/log.h>
30 #include <isc/mem.h>
31 #include <isc/socket.h>
32 #include <isc/string.h>
33 #include <isc/task.h>
34 #include <isc/timer.h>
35 #include <isc/util.h>
36
37 #include <dns/db.h>
38 #include <dns/fixedname.h>
39 #include <dns/log.h>
40 #include <dns/rdataclass.h>
41 #include <dns/rdataset.h>
42 #include <dns/result.h>
43 #include <dns/zone.h>
44
45 #include "check-tool.h"
46
47 static int quiet = 0;
48 static isc_mem_t *mctx = NULL;
49 static isc_entropy_t *ectx = NULL;
50 dns_zone_t *zone = NULL;
51 dns_zonetype_t zonetype = dns_zone_master;
52 static int dumpzone = 0;
53 static const char *output_filename;
54
55 #define ERRRET(result, function) \
56         do { \
57                 if (result != ISC_R_SUCCESS) { \
58                         if (!quiet) \
59                                 fprintf(stderr, "%s() returned %s\n", \
60                                         function, dns_result_totext(result)); \
61                         return (result); \
62                 } \
63         } while (0)
64
65 static void
66 usage(void) {
67         fprintf(stderr,
68                 "usage: named-checkzone [-djqvD] [-c class] [-o output] "
69                 "[-t directory] [-w directory] [-k (ignore|warn|fail)] "
70                 "[-n (ignore|warn|fail)] zonename filename\n");
71         exit(1);
72 }
73
74 static void
75 destroy(void) {
76         if (zone != NULL)
77                 dns_zone_detach(&zone);
78 }
79
80 int
81 main(int argc, char **argv) {
82         int c;
83         char *origin = NULL;
84         char *filename = NULL;
85         isc_log_t *lctx = NULL;
86         isc_result_t result;
87         char classname_in[] = "IN";
88         char *classname = classname_in;
89         const char *workdir = NULL;
90
91         while ((c = isc_commandline_parse(argc, argv, "c:dijk:n:qst:o:vw:D")) != EOF) {
92                 switch (c) {
93                 case 'c':
94                         classname = isc_commandline_argument;
95                         break;
96
97                 case 'd':
98                         debug++;
99                         break;
100
101                 case 'j':
102                         nomerge = ISC_FALSE;
103                         break;
104
105                 case 'n':
106                         if (!strcmp(isc_commandline_argument, "ignore"))
107                                 zone_options &= ~(DNS_ZONEOPT_CHECKNS|
108                                                   DNS_ZONEOPT_FATALNS);
109                         else if (!strcmp(isc_commandline_argument, "warn")) {
110                                 zone_options |= DNS_ZONEOPT_CHECKNS;
111                                 zone_options &= ~DNS_ZONEOPT_FATALNS;
112                         } else if (!strcmp(isc_commandline_argument, "fail"))
113                                 zone_options |= DNS_ZONEOPT_CHECKNS|
114                                                 DNS_ZONEOPT_FATALNS;
115                         break;
116
117                 case 'k':
118                         if (!strcmp(isc_commandline_argument, "warn")) {
119                                 zone_options |= DNS_ZONEOPT_CHECKNAMES;
120                                 zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
121                         } else if (!strcmp(isc_commandline_argument,
122                                            "fail")) {
123                                 zone_options |= DNS_ZONEOPT_CHECKNAMES |
124                                                 DNS_ZONEOPT_CHECKNAMESFAIL;
125                         } else if (!strcmp(isc_commandline_argument,
126                                            "ignore")) {
127                                 zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
128                                                   DNS_ZONEOPT_CHECKNAMESFAIL);
129                         }
130                         break;
131
132                 case 'q':
133                         quiet++;
134                         break;
135
136                 case 't':
137                         result = isc_dir_chroot(isc_commandline_argument);
138                         if (result != ISC_R_SUCCESS) {
139                                 fprintf(stderr, "isc_dir_chroot: %s: %s\n",
140                                         isc_commandline_argument,
141                                         isc_result_totext(result));
142                                 exit(1);
143                         }
144                         result = isc_dir_chdir("/");
145                         if (result != ISC_R_SUCCESS) {
146                                 fprintf(stderr, "isc_dir_chdir: %s\n",
147                                         isc_result_totext(result));
148                                 exit(1);
149                         }
150                         break;
151
152                 case 'o':
153                         output_filename = isc_commandline_argument;
154                         break;
155
156                 case 'v':
157                         printf(VERSION "\n");
158                         exit(0);
159
160                 case 'w':
161                         workdir = isc_commandline_argument;
162                         break;
163
164                 case 'D':
165                         dumpzone++;
166                         break;
167
168                 default:
169                         usage();
170                 }
171         }
172
173         if (workdir != NULL) {
174                 result = isc_dir_chdir(workdir);
175                 if (result != ISC_R_SUCCESS) {
176                         fprintf(stderr, "isc_dir_chdir: %s: %s\n",
177                                 workdir, isc_result_totext(result));
178                         exit(1);
179                 }
180         }
181
182         if (isc_commandline_index + 2 > argc)
183                 usage();
184
185         RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
186         if (!quiet) {
187                 RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS);
188                 dns_log_init(lctx);
189                 dns_log_setcontext(lctx);
190         }
191         RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
192         RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
193                       == ISC_R_SUCCESS);
194
195         dns_result_register();
196
197         origin = argv[isc_commandline_index++];
198         filename = argv[isc_commandline_index++];
199         result = load_zone(mctx, origin, filename, classname, &zone);
200
201         if (result == ISC_R_SUCCESS && dumpzone) {
202                 result = dump_zone(origin, zone, output_filename);
203         }
204
205         if (!quiet && result == ISC_R_SUCCESS)
206                 fprintf(stdout, "OK\n");
207         destroy();
208         if (lctx != NULL)
209                 isc_log_destroy(&lctx);
210         isc_hash_destroy();
211         isc_entropy_detach(&ectx);
212         isc_mem_destroy(&mctx);
213         return ((result == ISC_R_SUCCESS) ? 0 : 1);
214 }