#include #include #include #include static int debug = 0; static getdns_return_t dump_reply(FILE *fp, getdns_dict *reply, const char *section_name) { getdns_list *section = NULL; size_t section_len = -1; getdns_return_t r; uint8_t *res = NULL; size_t res_len; r = getdns_dict_get_list(reply, section_name, §ion); if (r) { fprintf(stderr, "unable to get section \"%s\" from reply\n", section_name); return r; } r = getdns_list_get_length(section, §ion_len); if (r) { fprintf(stderr, "unable to get length of section\n"); return r; } for (size_t j = 0; j < section_len; j++) { getdns_dict *rr = NULL; r = getdns_list_get_dict(section, j , &rr); if (r) { fprintf(stderr, "unable to get rr from entry " "%d: %d\n", j, r); return r; } r = getdns_rr_dict2wire(rr, &res, &res_len); if (r) { fprintf(stderr, "unable to convert entry %d " "to wire format: %d\n", j, r); return r; } if (0 && debug) { char *s = getdns_pretty_print_dict(rr); puts(s); free(s); } if (fwrite(res, 1, res_len, fp) != res_len) { fprintf(stderr, "unable to write buffer to file: %s\n", strerror(errno)); return -errno; } free(res); } return 0; } int dump_tree(FILE *fp, const getdns_dict *response, const char *tree_name, const char *section_name) { getdns_return_t r; getdns_list *tree = NULL; size_t n_replies = -1; r = getdns_dict_get_list(response, tree_name, &tree); if (r) { fprintf(stderr, "unable to get tree %s\n", tree_name); return r; } if (section_name == NULL) { size_t tree_len = 0; r = getdns_list_get_length(tree, &tree_len); if (r) { fprintf(stderr, "unable to get tree length\n"); return r; } for (size_t i = 0; i < tree_len; i++) { getdns_dict *rr = NULL; r = getdns_list_get_dict(tree, i , &rr); if (r) { fprintf(stderr, "unable to get rr from entry %d: %d\n", i, r); return r; } uint8_t *res = NULL; size_t res_len = 0; r = getdns_rr_dict2wire(rr, &res, &res_len); if (r) { fprintf(stderr, "unable to convert entry %d " "to wire format: %d\n", i, r); return r; } if (fwrite(res, 1, res_len, fp) != res_len) { fprintf(stderr, "unable to write buffer to file: %s\n", strerror(errno)); return errno; } free(res); } } else { r = getdns_list_get_length(tree, &n_replies); if (r) { fprintf(stderr, "unable to get number of replies\n"); return r; } for (size_t i = 0; i < n_replies; i++) { getdns_dict *reply = NULL; r = getdns_list_get_dict(tree, i, &reply); if (r) { fprintf(stderr, "unable to get reply %d from tree\n", i); return r; } if (debug) { char *s = getdns_pretty_print_dict(reply); printf("Pretty-printing reply #%d:%s\n", i, s); free(s); } dump_reply(fp, reply, section_name); } } return 0; } #define CHUNKSIZE 4096 size_t read_buffer(FILE *infp, uint8_t **bufp_out, size_t size_hint) { size_t nread = 0; uint8_t *wirebuf = NULL; size_t chunksize = CHUNKSIZE; int chunks = 1; if (size_hint > 0) chunksize = size_hint; wirebuf = malloc(chunksize); if (wirebuf == NULL) goto out; while (1) { size_t n = fread(wirebuf + nread, 1, chunksize, infp); nread += n; if (n < chunksize) break; /* Done. */ wirebuf = realloc(wirebuf, ++chunks * chunksize); if (wirebuf == NULL) break; } out: if (bufp_out != NULL) *bufp_out = wirebuf; return nread; } getdns_return_t wire_rrs2list(const uint8_t *buf, size_t buf_len, getdns_list **list_out) { getdns_return_t r = GETDNS_RETURN_GOOD; getdns_list *list = getdns_list_create(); getdns_dict *dict = NULL; size_t rr_count = 0; if (list == NULL) return GETDNS_RETURN_MEMORY_ERROR; while (buf_len > 0) { r = getdns_wire2rr_dict_scan(&buf, &buf_len, &dict); if (r) break; r = getdns_list_set_dict(list, rr_count, dict); getdns_dict_destroy(dict); /* The list has a copy. */ if (r) break; rr_count++; } if (list_out) *list_out = list; return r; }