Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / bind / dist / lib / export / samples / sample-update.c
blobf02da5f33a7ce6db45e8567acd0ac422e718d44a
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id: sample-update.c,v 1.5 2009/09/29 15:06:07 fdupont Exp */
21 #include <config.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
26 #include <netinet/in.h>
28 #include <arpa/inet.h>
30 #include <unistd.h>
31 #include <ctype.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <netdb.h>
37 #include <isc/buffer.h>
38 #include <isc/lex.h>
39 #include <isc/lib.h>
40 #include <isc/mem.h>
41 #include <isc/parseint.h>
42 #include <isc/sockaddr.h>
43 #include <isc/util.h>
45 #include <dns/callbacks.h>
46 #include <dns/client.h>
47 #include <dns/fixedname.h>
48 #include <dns/lib.h>
49 #include <dns/name.h>
50 #include <dns/rdata.h>
51 #include <dns/rdataclass.h>
52 #include <dns/rdatalist.h>
53 #include <dns/rdataset.h>
54 #include <dns/rdatastruct.h>
55 #include <dns/rdatatype.h>
56 #include <dns/result.h>
57 #include <dns/secalg.h>
58 #include <dns/tsec.h>
60 #include <dst/dst.h>
62 static dns_tsec_t *tsec = NULL;
63 static const dns_rdataclass_t default_rdataclass = dns_rdataclass_in;
64 static isc_bufferlist_t usedbuffers;
65 static ISC_LIST(dns_rdatalist_t) usedrdatalists;
67 static void setup_tsec(char *keyfile, isc_mem_t *mctx);
68 static void update_addordelete(isc_mem_t *mctx, char *cmdline,
69 isc_boolean_t isdelete, dns_name_t *name);
70 static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name);
72 ISC_PLATFORM_NORETURN_PRE static void
73 usage(void) ISC_PLATFORM_NORETURN_POST;
75 static void
76 usage(void) {
77 fprintf(stderr, "sample-update "
78 "[-a auth_server] "
79 "[-k keyfile] "
80 "[-p prerequisite] "
81 "[-r recursive_server] "
82 "[-z zonename] "
83 "(add|delete) \"name TTL RRtype RDATA\"\n");
84 exit(1);
87 int
88 main(int argc, char *argv[]) {
89 int ch;
90 struct addrinfo hints, *res;
91 int gai_error;
92 dns_client_t *client = NULL;
93 char *zonenamestr = NULL;
94 char *keyfilename = NULL;
95 char *prereqstr = NULL;
96 isc_sockaddrlist_t auth_servers;
97 char *auth_server = NULL;
98 char *recursive_server = NULL;
99 isc_sockaddr_t sa_auth, sa_recursive;
100 isc_sockaddrlist_t rec_servers;
101 isc_result_t result;
102 isc_boolean_t isdelete;
103 isc_buffer_t b, *buf;
104 dns_fixedname_t zname0, pname0, uname0;
105 size_t namelen;
106 dns_name_t *zname = NULL, *uname, *pname;
107 dns_rdataset_t *rdataset;
108 dns_rdatalist_t *rdatalist;
109 dns_rdata_t *rdata;
110 dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
111 isc_mem_t *umctx = NULL;
113 while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) {
114 switch (ch) {
115 case 'k':
116 keyfilename = optarg;
117 break;
118 case 'a':
119 auth_server = optarg;
120 break;
121 case 'p':
122 prereqstr = optarg;
123 break;
124 case 'r':
125 recursive_server = optarg;
126 break;
127 case 'z':
128 zonenamestr = optarg;
129 break;
130 default:
131 usage();
135 argc -= optind;
136 argv += optind;
137 if (argc < 2)
138 usage();
140 /* command line argument validation */
141 if (strcmp(argv[0], "delete") == 0)
142 isdelete = ISC_TRUE;
143 else if (strcmp(argv[0], "add") == 0)
144 isdelete = ISC_FALSE;
145 else {
146 fprintf(stderr, "invalid update command: %s\n", argv[0]);
147 exit(1);
150 if (auth_server == NULL && recursive_server == NULL) {
151 fprintf(stderr, "authoritative or recursive server "
152 "must be specified\n");
153 usage();
156 /* Initialization */
157 ISC_LIST_INIT(usedbuffers);
158 ISC_LIST_INIT(usedrdatalists);
159 ISC_LIST_INIT(prereqlist);
160 ISC_LIST_INIT(auth_servers);
161 isc_lib_register();
162 result = dns_lib_init();
163 if (result != ISC_R_SUCCESS) {
164 fprintf(stderr, "dns_lib_init failed: %d\n", result);
165 exit(1);
167 result = isc_mem_create(0, 0, &umctx);
168 if (result != ISC_R_SUCCESS) {
169 fprintf(stderr, "failed to crate mctx\n");
170 exit(1);
173 result = dns_client_create(&client, 0);
174 if (result != ISC_R_SUCCESS) {
175 fprintf(stderr, "dns_client_create failed: %d\n", result);
176 exit(1);
179 /* Set the authoritative server */
180 if (auth_server != NULL) {
181 memset(&hints, 0, sizeof(hints));
182 hints.ai_family = AF_UNSPEC;
183 hints.ai_socktype = SOCK_DGRAM;
184 hints.ai_protocol = IPPROTO_UDP;
185 hints.ai_flags = AI_NUMERICHOST;
186 gai_error = getaddrinfo(auth_server, "53", &hints, &res);
187 if (gai_error != 0) {
188 fprintf(stderr, "getaddrinfo failed: %s\n",
189 gai_strerror(gai_error));
190 exit(1);
192 INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
193 memcpy(&sa_auth.type, res->ai_addr, res->ai_addrlen);
194 freeaddrinfo(res);
195 sa_auth.length = res->ai_addrlen;
196 ISC_LINK_INIT(&sa_auth, link);
198 ISC_LIST_APPEND(auth_servers, &sa_auth, link);
201 /* Set the recursive server */
202 if (recursive_server != NULL) {
203 memset(&hints, 0, sizeof(hints));
204 hints.ai_family = AF_UNSPEC;
205 hints.ai_socktype = SOCK_DGRAM;
206 hints.ai_protocol = IPPROTO_UDP;
207 hints.ai_flags = AI_NUMERICHOST;
208 gai_error = getaddrinfo(recursive_server, "53", &hints, &res);
209 if (gai_error != 0) {
210 fprintf(stderr, "getaddrinfo failed: %s\n",
211 gai_strerror(gai_error));
212 exit(1);
214 INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
215 memcpy(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
216 freeaddrinfo(res);
217 sa_recursive.length = res->ai_addrlen;
218 ISC_LINK_INIT(&sa_recursive, link);
219 ISC_LIST_INIT(rec_servers);
220 ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
221 result = dns_client_setservers(client, dns_rdataclass_in,
222 NULL, &rec_servers);
223 if (result != ISC_R_SUCCESS) {
224 fprintf(stderr, "set server failed: %d\n", result);
225 exit(1);
229 /* Construct zone name */
230 zname = NULL;
231 if (zonenamestr != NULL) {
232 namelen = strlen(zonenamestr);
233 isc_buffer_init(&b, zonenamestr, namelen);
234 isc_buffer_add(&b, namelen);
235 dns_fixedname_init(&zname0);
236 zname = dns_fixedname_name(&zname0);
237 result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
238 if (result != ISC_R_SUCCESS)
239 fprintf(stderr, "failed to convert zone name: %d\n",
240 result);
243 /* Construct prerequisite name (if given) */
244 if (prereqstr != NULL) {
245 dns_fixedname_init(&pname0);
246 pname = dns_fixedname_name(&pname0);
247 evaluate_prereq(umctx, prereqstr, pname);
248 ISC_LIST_APPEND(prereqlist, pname, link);
249 prereqlistp = &prereqlist;
252 /* Construct update name */
253 ISC_LIST_INIT(updatelist);
254 dns_fixedname_init(&uname0);
255 uname = dns_fixedname_name(&uname0);
256 update_addordelete(umctx, argv[1], isdelete, uname);
257 ISC_LIST_APPEND(updatelist, uname, link);
259 /* Set up TSIG/SIG(0) key (if given) */
260 if (keyfilename != NULL)
261 setup_tsec(keyfilename, umctx);
263 /* Perform update */
264 result = dns_client_update(client,
265 default_rdataclass, /* XXX: fixed */
266 zname, prereqlistp, &updatelist,
267 (auth_server == NULL) ? NULL :
268 &auth_servers, tsec, 0);
269 if (result != ISC_R_SUCCESS) {
270 fprintf(stderr,
271 "update failed: %s\n", dns_result_totext(result));
272 } else
273 fprintf(stderr, "update succeeded\n");
275 /* Cleanup */
276 while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
277 while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
278 ISC_LIST_UNLINK(pname->list, rdataset, link);
279 dns_rdataset_disassociate(rdataset);
280 isc_mem_put(umctx, rdataset, sizeof(*rdataset));
282 ISC_LIST_UNLINK(prereqlist, pname, link);
284 while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
285 while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
286 ISC_LIST_UNLINK(uname->list, rdataset, link);
287 dns_rdataset_disassociate(rdataset);
288 isc_mem_put(umctx, rdataset, sizeof(*rdataset));
290 ISC_LIST_UNLINK(updatelist, uname, link);
292 while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
293 while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
294 ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
295 isc_mem_put(umctx, rdata, sizeof(*rdata));
297 ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
298 isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
300 while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
301 ISC_LIST_UNLINK(usedbuffers, buf, link);
302 isc_buffer_free(&buf);
304 if (tsec != NULL)
305 dns_tsec_destroy(&tsec);
306 isc_mem_destroy(&umctx);
307 dns_client_destroy(&client);
308 dns_lib_shutdown();
310 exit(0);
314 * Subroutines borrowed from nsupdate.c
316 #define MAXWIRE (64 * 1024)
317 #define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
319 static char *
320 nsu_strsep(char **stringp, const char *delim) {
321 char *string = *stringp;
322 char *s;
323 const char *d;
324 char sc, dc;
326 if (string == NULL)
327 return (NULL);
329 for (; *string != '\0'; string++) {
330 sc = *string;
331 for (d = delim; (dc = *d) != '\0'; d++) {
332 if (sc == dc)
333 break;
335 if (dc == 0)
336 break;
339 for (s = string; *s != '\0'; s++) {
340 sc = *s;
341 for (d = delim; (dc = *d) != '\0'; d++) {
342 if (sc == dc) {
343 *s++ = '\0';
344 *stringp = s;
345 return (string);
349 *stringp = NULL;
350 return (string);
353 static void
354 fatal(const char *format, ...) {
355 va_list args;
357 va_start(args, format);
358 vfprintf(stderr, format, args);
359 va_end(args);
360 fprintf(stderr, "\n");
361 exit(1);
364 static inline void
365 check_result(isc_result_t result, const char *msg) {
366 if (result != ISC_R_SUCCESS)
367 fatal("%s: %s", msg, isc_result_totext(result));
370 static void
371 parse_name(char **cmdlinep, dns_name_t *name) {
372 isc_result_t result;
373 char *word;
374 isc_buffer_t source;
376 word = nsu_strsep(cmdlinep, " \t\r\n");
377 if (*word == 0) {
378 fprintf(stderr, "could not read owner name\n");
379 exit(1);
382 isc_buffer_init(&source, word, strlen(word));
383 isc_buffer_add(&source, strlen(word));
384 result = dns_name_fromtext(name, &source, dns_rootname, 0, NULL);
385 check_result(result, "dns_name_fromtext");
386 isc_buffer_invalidate(&source);
389 static void
390 parse_rdata(isc_mem_t *mctx, char **cmdlinep, dns_rdataclass_t rdataclass,
391 dns_rdatatype_t rdatatype, dns_rdata_t *rdata)
393 char *cmdline = *cmdlinep;
394 isc_buffer_t source, *buf = NULL, *newbuf = NULL;
395 isc_region_t r;
396 isc_lex_t *lex = NULL;
397 dns_rdatacallbacks_t callbacks;
398 isc_result_t result;
400 while (cmdline != NULL && *cmdline != 0 &&
401 isspace((unsigned char)*cmdline))
402 cmdline++;
404 if (cmdline != NULL && *cmdline != 0) {
405 dns_rdatacallbacks_init(&callbacks);
406 result = isc_lex_create(mctx, strlen(cmdline), &lex);
407 check_result(result, "isc_lex_create");
408 isc_buffer_init(&source, cmdline, strlen(cmdline));
409 isc_buffer_add(&source, strlen(cmdline));
410 result = isc_lex_openbuffer(lex, &source);
411 check_result(result, "isc_lex_openbuffer");
412 result = isc_buffer_allocate(mctx, &buf, MAXWIRE);
413 check_result(result, "isc_buffer_allocate");
414 result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex,
415 dns_rootname, 0, mctx, buf,
416 &callbacks);
417 isc_lex_destroy(&lex);
418 if (result == ISC_R_SUCCESS) {
419 isc_buffer_usedregion(buf, &r);
420 result = isc_buffer_allocate(mctx, &newbuf, r.length);
421 check_result(result, "isc_buffer_allocate");
422 isc_buffer_putmem(newbuf, r.base, r.length);
423 isc_buffer_usedregion(newbuf, &r);
424 dns_rdata_reset(rdata);
425 dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r);
426 isc_buffer_free(&buf);
427 ISC_LIST_APPEND(usedbuffers, newbuf, link);
428 } else {
429 fprintf(stderr, "invalid rdata format: %s\n",
430 isc_result_totext(result));
431 isc_buffer_free(&buf);
432 exit(1);
434 } else {
435 rdata->flags = DNS_RDATA_UPDATE;
437 *cmdlinep = cmdline;
440 static void
441 update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
442 dns_name_t *name)
444 isc_result_t result;
445 isc_uint32_t ttl;
446 char *word;
447 dns_rdataclass_t rdataclass;
448 dns_rdatatype_t rdatatype;
449 dns_rdata_t *rdata = NULL;
450 dns_rdatalist_t *rdatalist = NULL;
451 dns_rdataset_t *rdataset = NULL;
452 isc_textregion_t region;
455 * Read the owner name.
457 parse_name(&cmdline, name);
459 rdata = isc_mem_get(mctx, sizeof(*rdata));
460 if (rdata == NULL) {
461 fprintf(stderr, "memory allocation for rdata failed\n");
462 exit(1);
464 dns_rdata_init(rdata);
467 * If this is an add, read the TTL and verify that it's in range.
468 * If it's a delete, ignore a TTL if present (for compatibility).
470 word = nsu_strsep(&cmdline, " \t\r\n");
471 if (word == NULL || *word == 0) {
472 if (!isdelete) {
473 fprintf(stderr, "could not read owner ttl\n");
474 exit(1);
476 else {
477 ttl = 0;
478 rdataclass = dns_rdataclass_any;
479 rdatatype = dns_rdatatype_any;
480 rdata->flags = DNS_RDATA_UPDATE;
481 goto doneparsing;
484 result = isc_parse_uint32(&ttl, word, 10);
485 if (result != ISC_R_SUCCESS) {
486 if (isdelete) {
487 ttl = 0;
488 goto parseclass;
489 } else {
490 fprintf(stderr, "ttl '%s': %s\n", word,
491 isc_result_totext(result));
492 exit(1);
496 if (isdelete)
497 ttl = 0;
498 else if (ttl > TTL_MAX) {
499 fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
500 word, TTL_MAX);
501 exit(1);
505 * Read the class or type.
507 word = nsu_strsep(&cmdline, " \t\r\n");
508 parseclass:
509 if (word == NULL || *word == 0) {
510 if (isdelete) {
511 rdataclass = dns_rdataclass_any;
512 rdatatype = dns_rdatatype_any;
513 rdata->flags = DNS_RDATA_UPDATE;
514 goto doneparsing;
515 } else {
516 fprintf(stderr, "could not read class or type\n");
517 exit(1);
520 region.base = word;
521 region.length = strlen(word);
522 result = dns_rdataclass_fromtext(&rdataclass, &region);
523 if (result == ISC_R_SUCCESS) {
525 * Now read the type.
527 word = nsu_strsep(&cmdline, " \t\r\n");
528 if (word == NULL || *word == 0) {
529 if (isdelete) {
530 rdataclass = dns_rdataclass_any;
531 rdatatype = dns_rdatatype_any;
532 rdata->flags = DNS_RDATA_UPDATE;
533 goto doneparsing;
534 } else {
535 fprintf(stderr, "could not read type\n");
536 exit(1);
539 region.base = word;
540 region.length = strlen(word);
541 result = dns_rdatatype_fromtext(&rdatatype, &region);
542 if (result != ISC_R_SUCCESS) {
543 fprintf(stderr, "'%s' is not a valid type: %s\n",
544 word, isc_result_totext(result));
545 exit(1);
547 } else {
548 rdataclass = default_rdataclass;
549 result = dns_rdatatype_fromtext(&rdatatype, &region);
550 if (result != ISC_R_SUCCESS) {
551 fprintf(stderr, "'%s' is not a valid class or type: "
552 "%s\n", word, isc_result_totext(result));
553 exit(1);
557 parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
559 if (isdelete) {
560 if ((rdata->flags & DNS_RDATA_UPDATE) != 0)
561 rdataclass = dns_rdataclass_any;
562 else
563 rdataclass = dns_rdataclass_none;
564 } else {
565 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
566 fprintf(stderr, "could not read rdata\n");
567 exit(1);
571 doneparsing:
573 rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
574 if (rdatalist == NULL) {
575 fprintf(stderr, "memory allocation for rdatalist failed\n");
576 exit(1);
578 dns_rdatalist_init(rdatalist);
579 rdatalist->type = rdatatype;
580 rdatalist->rdclass = rdataclass;
581 rdatalist->covers = rdatatype;
582 rdatalist->ttl = (dns_ttl_t)ttl;
583 ISC_LIST_INIT(rdatalist->rdata);
584 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
585 ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
587 rdataset = isc_mem_get(mctx, sizeof(*rdataset));
588 if (rdataset == NULL) {
589 fprintf(stderr, "memory allocation for rdataset failed\n");
590 exit(1);
592 dns_rdataset_init(rdataset);
593 dns_rdatalist_tordataset(rdatalist, rdataset);
594 ISC_LIST_INIT(name->list);
595 ISC_LIST_APPEND(name->list, rdataset, link);
598 static void
599 make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive,
600 isc_boolean_t isrrset, dns_name_t *name)
602 isc_result_t result;
603 char *word;
604 isc_textregion_t region;
605 dns_rdataset_t *rdataset = NULL;
606 dns_rdatalist_t *rdatalist = NULL;
607 dns_rdataclass_t rdataclass;
608 dns_rdatatype_t rdatatype;
609 dns_rdata_t *rdata = NULL;
612 * Read the owner name
614 parse_name(&cmdline, name);
617 * If this is an rrset prereq, read the class or type.
619 if (isrrset) {
620 word = nsu_strsep(&cmdline, " \t\r\n");
621 if (word == NULL || *word == 0) {
622 fprintf(stderr, "could not read class or type\n");
623 exit(1);
625 region.base = word;
626 region.length = strlen(word);
627 result = dns_rdataclass_fromtext(&rdataclass, &region);
628 if (result == ISC_R_SUCCESS) {
630 * Now read the type.
632 word = nsu_strsep(&cmdline, " \t\r\n");
633 if (word == NULL || *word == 0) {
634 fprintf(stderr, "could not read type\n");
635 exit(1);
637 region.base = word;
638 region.length = strlen(word);
639 result = dns_rdatatype_fromtext(&rdatatype, &region);
640 if (result != ISC_R_SUCCESS) {
641 fprintf(stderr, "invalid type: %s\n", word);
642 exit(1);
644 } else {
645 rdataclass = default_rdataclass;
646 result = dns_rdatatype_fromtext(&rdatatype, &region);
647 if (result != ISC_R_SUCCESS) {
648 fprintf(stderr, "invalid type: %s\n", word);
649 exit(1);
652 } else
653 rdatatype = dns_rdatatype_any;
655 rdata = isc_mem_get(mctx, sizeof(*rdata));
656 if (rdata == NULL) {
657 fprintf(stderr, "memory allocation for rdata failed\n");
658 exit(1);
660 dns_rdata_init(rdata);
662 if (isrrset && ispositive)
663 parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
664 else
665 rdata->flags = DNS_RDATA_UPDATE;
667 rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
668 if (rdatalist == NULL) {
669 fprintf(stderr, "memory allocation for rdatalist failed\n");
670 exit(1);
672 dns_rdatalist_init(rdatalist);
673 rdatalist->type = rdatatype;
674 if (ispositive) {
675 if (isrrset && rdata->data != NULL)
676 rdatalist->rdclass = rdataclass;
677 else
678 rdatalist->rdclass = dns_rdataclass_any;
679 } else
680 rdatalist->rdclass = dns_rdataclass_none;
681 rdatalist->covers = 0;
682 rdatalist->ttl = 0;
683 rdata->rdclass = rdatalist->rdclass;
684 rdata->type = rdatatype;
685 ISC_LIST_INIT(rdatalist->rdata);
686 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
687 ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
689 rdataset = isc_mem_get(mctx, sizeof(*rdataset));
690 if (rdataset == NULL) {
691 fprintf(stderr, "memory allocation for rdataset failed\n");
692 exit(1);
694 dns_rdataset_init(rdataset);
695 dns_rdatalist_tordataset(rdatalist, rdataset);
696 ISC_LIST_INIT(name->list);
697 ISC_LIST_APPEND(name->list, rdataset, link);
700 static void
701 evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name) {
702 char *word;
703 isc_boolean_t ispositive, isrrset;
705 word = nsu_strsep(&cmdline, " \t\r\n");
706 if (word == NULL || *word == 0) {
707 fprintf(stderr, "could not read operation code\n");
708 exit(1);
710 if (strcasecmp(word, "nxdomain") == 0) {
711 ispositive = ISC_FALSE;
712 isrrset = ISC_FALSE;
713 } else if (strcasecmp(word, "yxdomain") == 0) {
714 ispositive = ISC_TRUE;
715 isrrset = ISC_FALSE;
716 } else if (strcasecmp(word, "nxrrset") == 0) {
717 ispositive = ISC_FALSE;
718 isrrset = ISC_TRUE;
719 } else if (strcasecmp(word, "yxrrset") == 0) {
720 ispositive = ISC_TRUE;
721 isrrset = ISC_TRUE;
722 } else {
723 fprintf(stderr, "incorrect operation code: %s\n", word);
724 exit(1);
727 make_prereq(mctx, cmdline, ispositive, isrrset, name);
730 static void
731 setup_tsec(char *keyfile, isc_mem_t *mctx) {
732 dst_key_t *dstkey = NULL;
733 isc_result_t result;
734 dns_tsectype_t tsectype;
736 result = dst_key_fromnamedfile(keyfile, NULL,
737 DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
738 &dstkey);
739 if (result != ISC_R_SUCCESS) {
740 fprintf(stderr, "could not read key from %s: %s\n",
741 keyfile, isc_result_totext(result));
742 exit(1);
745 if (dst_key_alg(dstkey) == DST_ALG_HMACMD5)
746 tsectype = dns_tsectype_tsig;
747 else
748 tsectype = dns_tsectype_sig0;
750 result = dns_tsec_create(mctx, tsectype, dstkey, &tsec);
751 if (result != ISC_R_SUCCESS) {
752 fprintf(stderr, "could not create tsec: %s\n",
753 isc_result_totext(result));
754 exit(1);