From d987ec044070c65ee459a9f76d163ba6b3588d28 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 11 Dec 2013 23:55:35 +0100 Subject: [PATCH] Update examples in the API specification They are now actually working with our implementation --- spec/example-reverse.c | 79 ++++-- spec/example-simple-answers.c | 35 ++- spec/example-synchronous.c | 35 ++- spec/example-tree.c | 65 +++-- spec/getdns-0.371.tgz | Bin 0 -> 36533 bytes spec/getdns_core_only.h | 2 +- spec/index.html | 139 ++++++---- src/getdns/index.html | 475 ++++++++++++++++++++-------------- 8 files changed, 510 insertions(+), 320 deletions(-) create mode 100644 spec/getdns-0.371.tgz diff --git a/spec/example-reverse.c b/spec/example-reverse.c index 795a8bae..4389dc42 100644 --- a/spec/example-reverse.c +++ b/spec/example-reverse.c @@ -20,37 +20,57 @@ void this_callbackfn(struct getdns_context *this_context, if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } - struct getdns_list * just_the_addresses_ptr; - this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); - if (this_ret != GETDNS_RETURN_GOOD) // This check is really not needed, but prevents a compiler error under "pedantic" + struct getdns_list *replies_tree; + this_ret = getdns_dict_get_list(this_response, "replies_tree", &replies_tree); // Ignore any error + size_t num_replies; + this_ret = getdns_list_get_length(replies_tree, &num_replies); // Ignore any error + /* Go through each reply */ + for ( size_t reply_count = 0; reply_count < num_replies; ++reply_count) { - fprintf(stderr, "Trying to get the answers failed: %d", this_ret); - return; - } - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error - /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) - { - struct getdns_dict * this_address; - this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error + struct getdns_dict * this_reply; + this_ret = getdns_list_get_dict(replies_tree, reply_count, &this_reply); // Ignore any error /* Just print the address */ - struct getdns_bindata * this_address_data; - this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + struct getdns_list* reply_answers; + this_ret = getdns_dict_get_list(this_reply, "answer", &reply_answers); // Ignore any error + size_t num_answers; + this_ret = getdns_list_get_length(reply_answers, &num_answers); // Ignore any error + /* Go through each answer */ + for ( size_t answer_count = 0; answer_count < num_answers; ++answer_count) + { + struct getdns_dict * this_rr; + this_ret = getdns_list_get_dict(reply_answers, answer_count, &this_rr); + /* Get the RDATA type */ + uint32_t this_type; + this_ret = getdns_dict_get_int(this_rr, "type", &this_type); // Ignore any error + if (this_type == GETDNS_RRTYPE_PTR) + { + struct getdns_dict *this_rdata; + this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error + + struct getdns_bindata * this_dname; + this_ret = getdns_dict_get_bindata(this_rdata, "rdata_raw", &this_dname); + char *this_dname_str = getdns_convert_dns_name_to_fqdn(this_dname->data); + printf("The dname is %s\n", this_dname_str); + free(this_dname_str); + + } + } + } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); else fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + getdns_dict_destroy(this_response); } int main() @@ -69,16 +89,18 @@ int main() if (this_event_base == NULL) { fprintf(stderr, "Trying to create the event base failed."); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } (void)getdns_extension_set_libevent_base(this_context, this_event_base); /* Set up the getdns call */ struct getdns_dict * this_addr_to_look_up = getdns_dict_create(); // TODO: check the return value above - struct getdns_bindata * this_type = { 4, 0x49507634 }; - getdns_return_t this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_type", this_type); - struct getdns_bindata * this_ipv4_addr = { 4, 0x08080808 }; - this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_data", this_ipv4_addr; + struct getdns_bindata this_type = { 5, (void *)"IPv4" }; + getdns_return_t this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_type", &this_type); + UNUSED_PARAM(this_ret); + struct getdns_bindata this_ipv4_addr = { 4, (void *)"\x08\x08\x08\x08" }; + this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_data", &this_ipv4_addr); char* this_userarg = "somestring"; // Could add things here to help identify this call getdns_transaction_t this_transaction_id = 0; @@ -87,7 +109,13 @@ int main() NULL, this_userarg, &this_transaction_id, this_callbackfn); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad IP address was used: %s. Exiting.", this_ipv4_addr); + char *ip_address_str = getdns_display_ip_address(&this_ipv4_addr); + + fprintf(stderr, "A bad IP address was used: %s. Exiting.\n", ip_address_str); + free(ip_address_str); + getdns_dict_destroy(this_addr_to_look_up); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else @@ -99,6 +127,7 @@ int main() } /* Clean up */ getdns_dict_destroy(this_addr_to_look_up); + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); diff --git a/spec/example-simple-answers.c b/spec/example-simple-answers.c index 4a4c2b2b..e9d75608 100644 --- a/spec/example-simple-answers.c +++ b/spec/example-simple-answers.c @@ -20,37 +20,42 @@ void this_callbackfn(struct getdns_context *this_context, if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } struct getdns_list * just_the_addresses_ptr; this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); if (this_ret != GETDNS_RETURN_GOOD) // This check is really not needed, but prevents a compiler error under "pedantic" { - fprintf(stderr, "Trying to get the answers failed: %d", this_ret); + fprintf(stderr, "Trying to get the answers failed: %d\n", this_ret); + getdns_dict_destroy(this_response); return; } - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + size_t num_addresses; + this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count ) { struct getdns_dict * this_address; this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error /* Just print the address */ struct getdns_bindata * this_address_data; this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + char *this_address_str = getdns_display_ip_address(this_address_data); + printf("The address is %s\n", this_address_str); + free(this_address_str); } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id); else - fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type); + getdns_dict_destroy(this_response); } int main() @@ -68,7 +73,8 @@ int main() this_event_base = event_base_new(); if (this_event_base == NULL) { - fprintf(stderr, "Trying to create the event base failed."); + fprintf(stderr, "Trying to create the event base failed.\n"); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } (void)getdns_extension_set_libevent_base(this_context, this_event_base); @@ -82,7 +88,9 @@ int main() NULL, this_userarg, &this_transaction_id, this_callbackfn); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else @@ -93,6 +101,7 @@ int main() // TODO: check the return value above } /* Clean up */ + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); diff --git a/spec/example-synchronous.c b/spec/example-synchronous.c index df987bbc..463a7e61 100644 --- a/spec/example-synchronous.c +++ b/spec/example-synchronous.c @@ -13,7 +13,7 @@ int main() getdns_return_t context_create_return = getdns_context_create(&this_context, 1); if (context_create_return != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return); return(GETDNS_RETURN_GENERIC_ERROR); } /* Set up the getdns_sync_request call */ @@ -24,7 +24,9 @@ int main() this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE); if (this_ret != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d", this_ret); + fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d\n", this_ret); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } struct getdns_dict * this_response = NULL; @@ -34,37 +36,46 @@ int main() this_extensions, &this_response); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } struct getdns_list * just_the_addresses_ptr; this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); // Ignore any error - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + size_t num_addresses; + this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count ) { struct getdns_dict * this_address; this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error /* Just print the address */ struct getdns_bindata * this_address_data; this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + char *this_address_str = getdns_display_ip_address(this_address_data); + printf("The address is %s\n", this_address_str); + free(this_address_str); } } /* Clean up */ - getdns_context_destroy(this_context); getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } diff --git a/spec/example-tree.c b/spec/example-tree.c index d4960967..dc264dc3 100644 --- a/spec/example-tree.c +++ b/spec/example-tree.c @@ -20,25 +20,27 @@ void this_callbackfn(struct getdns_context *this_context, if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } /* Find all the answers returned */ struct getdns_list * these_answers; - this_ret = getdns_dict_get_list(this_response, "replies-tree", &these_answers); + this_ret = getdns_dict_get_list(this_response, "replies_tree", &these_answers); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the response had no error, but also no replies-tree. Exiting."); + fprintf(stderr, "Weird: the response had no error, but also no replies_tree. Exiting.\n"); + getdns_dict_destroy(this_response); return; } - size_t * num_answers_ptr = NULL; - this_ret = getdns_list_get_length(these_answers, num_answers_ptr); + size_t num_answers; + this_ret = getdns_list_get_length(these_answers, &num_answers); /* Go through each answer */ - for ( size_t rec_count = 0; rec_count <= *num_answers_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_answers; ++rec_count ) { struct getdns_dict * this_record; this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record); // Ignore any error @@ -46,50 +48,57 @@ void this_callbackfn(struct getdns_context *this_context, struct getdns_list * this_answer; this_ret = getdns_dict_get_list(this_record, "answer", &this_answer); // Ignore any error /* Get each RR in the answer section */ - size_t * num_rrs_ptr = NULL; - this_ret = getdns_list_get_length(this_answer, num_rrs_ptr); - for ( size_t rr_count = 0; rr_count <= *num_rrs_ptr; ++rr_count ) + size_t num_rrs; + this_ret = getdns_list_get_length(this_answer, &num_rrs); + for ( size_t rr_count = 0; rr_count < num_rrs; ++rr_count ) { - struct getdns_dict * this_rr = NULL; + struct getdns_dict *this_rr = NULL; this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr); // Ignore any error /* Get the RDATA */ struct getdns_dict * this_rdata = NULL; this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error /* Get the RDATA type */ - uint32_t * this_type = NULL; - this_ret = getdns_dict_get_int(this_rdata, "type", this_type); // Ignore any error + uint32_t this_type; + this_ret = getdns_dict_get_int(this_rr, "type", &this_type); // Ignore any error /* If it is type A or AAAA, print the value */ - if (*this_type == GETDNS_RRTYPE_A) + if (this_type == GETDNS_RRTYPE_A) { struct getdns_bindata * this_a_record = NULL; this_ret = getdns_dict_get_bindata(this_rdata, "ipv4_address", &this_a_record); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.", + fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.\n", (int) rr_count, (int) rec_count); + getdns_dict_destroy(this_response); return; } - printf("The IPv4 address is %s", getdns_display_ip_address(this_a_record)); + char *this_address_str = getdns_display_ip_address(this_a_record); + printf("The IPv4 address is %s\n", this_address_str); + free(this_address_str); } - else if (*this_type == GETDNS_RRTYPE_AAAA) + else if (this_type == GETDNS_RRTYPE_AAAA) { struct getdns_bindata * this_aaaa_record = NULL; this_ret = getdns_dict_get_bindata(this_rdata, "ipv6_address", &this_aaaa_record); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.", + fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.\n", (int) rr_count, (int) rec_count); + getdns_dict_destroy(this_response); return; } - printf("The IPv6 address is %s", getdns_display_ip_address(this_aaaa_record)); + char *this_address_str = getdns_display_ip_address(this_aaaa_record); + printf("The IPv6 address is %s\n", this_address_str); + free(this_address_str); } } } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id); else - fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type); + getdns_dict_destroy(this_response); } int main() @@ -99,7 +108,7 @@ int main() getdns_return_t context_create_return = getdns_context_create(&this_context, 1); if (context_create_return != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return); return(GETDNS_RETURN_GENERIC_ERROR); } /* Create an event base and put it in the context using the unknown function name */ @@ -107,7 +116,8 @@ int main() this_event_base = event_base_new(); if (this_event_base == NULL) { - fprintf(stderr, "Trying to create the event base failed."); + fprintf(stderr, "Trying to create the event base failed.\n"); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } (void)getdns_extension_set_libevent_base(this_context, this_event_base); @@ -121,7 +131,9 @@ int main() NULL, this_userarg, &this_transaction_id, this_callbackfn); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else @@ -132,6 +144,7 @@ int main() // TODO: check the return value above } /* Clean up */ + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); diff --git a/spec/getdns-0.371.tgz b/spec/getdns-0.371.tgz new file mode 100644 index 0000000000000000000000000000000000000000..97c9fd4113e3aba6c12736f94e91678f1634e769 GIT binary patch literal 36533 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 xSM`8apVepeS$$TY)o1lteO8~ if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } struct getdns_list * just_the_addresses_ptr; this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); if (this_ret != GETDNS_RETURN_GOOD) // This check is really not needed, but prevents a compiler error under "pedantic" { - fprintf(stderr, "Trying to get the answers failed: %d", this_ret); + fprintf(stderr, "Trying to get the answers failed: %d\n", this_ret); + getdns_dict_destroy(this_response); return; } - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + size_t num_addresses; + this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count ) { struct getdns_dict * this_address; this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error /* Just print the address */ struct getdns_bindata * this_address_data; this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + char *this_address_str = getdns_display_ip_address(this_address_data); + printf("The address is %s\n", this_address_str); + free(this_address_str); } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id); else - fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type); + getdns_dict_destroy(this_response); } int main() @@ -1453,7 +1458,8 @@ function.

this_event_base = event_base_new(); if (this_event_base == NULL) { - fprintf(stderr, "Trying to create the event base failed."); + fprintf(stderr, "Trying to create the event base failed.\n"); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } (void)getdns_extension_set_libevent_base(this_context, this_event_base); @@ -1467,7 +1473,9 @@ function.

NULL, this_userarg, &this_transaction_id, this_callbackfn); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else @@ -1478,6 +1486,7 @@ function.

// TODO: check the return value above } /* Clean up */ + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); @@ -1514,25 +1523,27 @@ their TTLs.

if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } /* Find all the answers returned */ struct getdns_list * these_answers; - this_ret = getdns_dict_get_list(this_response, "replies-tree", &these_answers); + this_ret = getdns_dict_get_list(this_response, "replies_tree", &these_answers); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the response had no error, but also no replies-tree. Exiting."); + fprintf(stderr, "Weird: the response had no error, but also no replies_tree. Exiting.\n"); + getdns_dict_destroy(this_response); return; } - size_t * num_answers_ptr = NULL; - this_ret = getdns_list_get_length(these_answers, num_answers_ptr); + size_t num_answers; + this_ret = getdns_list_get_length(these_answers, &num_answers); /* Go through each answer */ - for ( size_t rec_count = 0; rec_count <= *num_answers_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_answers; ++rec_count ) { struct getdns_dict * this_record; this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record); // Ignore any error @@ -1540,50 +1551,57 @@ their TTLs.

struct getdns_list * this_answer; this_ret = getdns_dict_get_list(this_record, "answer", &this_answer); // Ignore any error /* Get each RR in the answer section */ - size_t * num_rrs_ptr = NULL; - this_ret = getdns_list_get_length(this_answer, num_rrs_ptr); - for ( size_t rr_count = 0; rr_count <= *num_rrs_ptr; ++rr_count ) + size_t num_rrs; + this_ret = getdns_list_get_length(this_answer, &num_rrs); + for ( size_t rr_count = 0; rr_count < num_rrs; ++rr_count ) { - struct getdns_dict * this_rr = NULL; + struct getdns_dict *this_rr = NULL; this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr); // Ignore any error /* Get the RDATA */ struct getdns_dict * this_rdata = NULL; this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error /* Get the RDATA type */ - uint32_t * this_type = NULL; - this_ret = getdns_dict_get_int(this_rdata, "type", this_type); // Ignore any error + uint32_t this_type; + this_ret = getdns_dict_get_int(this_rr, "type", &this_type); // Ignore any error /* If it is type A or AAAA, print the value */ - if (*this_type == GETDNS_RRTYPE_A) + if (this_type == GETDNS_RRTYPE_A) { struct getdns_bindata * this_a_record = NULL; this_ret = getdns_dict_get_bindata(this_rdata, "ipv4_address", &this_a_record); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.", + fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.\n", (int) rr_count, (int) rec_count); + getdns_dict_destroy(this_response); return; } - printf("The IPv4 address is %s", getdns_display_ip_address(this_a_record)); + char *this_address_str = getdns_display_ip_address(this_a_record); + printf("The IPv4 address is %s\n", this_address_str); + free(this_address_str); } - else if (*this_type == GETDNS_RRTYPE_AAAA) + else if (this_type == GETDNS_RRTYPE_AAAA) { struct getdns_bindata * this_aaaa_record = NULL; this_ret = getdns_dict_get_bindata(this_rdata, "ipv6_address", &this_aaaa_record); if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME) { - fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.", + fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.\n", (int) rr_count, (int) rec_count); + getdns_dict_destroy(this_response); return; } - printf("The IPv6 address is %s", getdns_display_ip_address(this_aaaa_record)); + char *this_address_str = getdns_display_ip_address(this_aaaa_record); + printf("The IPv6 address is %s\n", this_address_str); + free(this_address_str); } } } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); + fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id); else - fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type); + getdns_dict_destroy(this_response); } int main() @@ -1593,7 +1611,7 @@ their TTLs.

getdns_return_t context_create_return = getdns_context_create(&this_context, 1); if (context_create_return != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return); return(GETDNS_RETURN_GENERIC_ERROR); } /* Create an event base and put it in the context using the unknown function name */ @@ -1601,7 +1619,8 @@ their TTLs.

this_event_base = event_base_new(); if (this_event_base == NULL) { - fprintf(stderr, "Trying to create the event base failed."); + fprintf(stderr, "Trying to create the event base failed.\n"); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } (void)getdns_extension_set_libevent_base(this_context, this_event_base); @@ -1615,7 +1634,9 @@ their TTLs.

NULL, this_userarg, &this_transaction_id, this_callbackfn); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else @@ -1626,6 +1647,7 @@ their TTLs.

// TODO: check the return value above } /* Clean up */ + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); @@ -1686,7 +1708,7 @@ as it is for the synchronous example, it is just done in main().

getdns_return_t context_create_return = getdns_context_create(&this_context, 1); if (context_create_return != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to create the context failed: %d", context_create_return); + fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return); return(GETDNS_RETURN_GENERIC_ERROR); } /* Set up the getdns_sync_request call */ @@ -1697,7 +1719,9 @@ as it is for the synchronous example, it is just done in main().

this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE); if (this_ret != GETDNS_RETURN_GOOD) { - fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d", this_ret); + fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d\n", this_ret); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } struct getdns_dict * this_response = NULL; @@ -1707,37 +1731,46 @@ as it is for the synchronous example, it is just done in main().

this_extensions, &this_response); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { - fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name); + getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } else { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - this_ret = getdns_dict_get_int(this_response, "status", this_error); // Ignore any error - if (*this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" + uint32_t this_error; + this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error + if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good" { - fprintf(stderr, "The search had no results, and a return value of %d. Exiting.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); return(GETDNS_RETURN_GENERIC_ERROR); } struct getdns_list * just_the_addresses_ptr; this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); // Ignore any error - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error + size_t num_addresses; + this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) + for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count ) { struct getdns_dict * this_address; this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error /* Just print the address */ struct getdns_bindata * this_address_data; this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + char *this_address_str = getdns_display_ip_address(this_address_data); + printf("The address is %s\n", this_address_str); + free(this_address_str); } } /* Clean up */ - getdns_context_destroy(this_context); getdns_dict_destroy(this_response); + getdns_dict_destroy(this_extensions); + getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } @@ -2120,7 +2153,7 @@ getdns_context_set_extended_memory_functions( void (*free)(void *userarg, void *ptr) );

The given extended memory management functions will be used for creating the response dicts. -The value of userarg argument will be passed to the custom malloc, realloc, and free. +The value of userarg argument will be passed to the custom malloc, realloc, and free. The response dicts inherit the custom memory management functions and the value for userarg from the context and will deallocate themselves (and their members) with the custom deallocator.

8.10 Context Codes

@@ -2165,7 +2198,7 @@ The response dicts inherit the custom memory management functions and the value

9. The Generated Files

-

There is a tarball that includes the .h files, +

There is a tarball that includes the .h files, the examples, and so on. The examples all make, even though there is no API implementation, based on a pseudo-implementation in the tarball; see make-examples-PLATFORM.sh. Note that this currently builds fine on the Macintosh and Ubuntu; help is definitely appreciated on making the build process diff --git a/src/getdns/index.html b/src/getdns/index.html index 99c6218c..6f67b14c 100644 --- a/src/getdns/index.html +++ b/src/getdns/index.html @@ -2,6 +2,11 @@ DNS API Description + +