diff --git a/spec/example/Makefile.in b/spec/example/Makefile.in index 8d13de75..c38be1b8 100644 --- a/spec/example/Makefile.in +++ b/spec/example/Makefile.in @@ -48,9 +48,9 @@ LDFLAGS=@LDFLAGS@ -L../../src LDLIBS=../../src/libgetdns.la @LIBS@ -OBJS=example-all-functions.lo example-simple-answers.lo example-tree.lo example-synchronous.lo example-reverse.lo synchronous-json-pointer.lo simple-json-pointer.lo tree-json-pointer.lo reverse-json-pointer.lo +OBJS=example-all-functions.lo example-simple-answers.lo example-tree.lo example-synchronous.lo example-reverse.lo -PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse synchronous-json-pointer simple-json-pointer tree-json-pointer reverse-json-pointer +PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse .SUFFIXES: .c .o .a .lo .h @@ -74,18 +74,6 @@ example-all-functions: example-all-functions.lo example-synchronous: example-synchronous.lo $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ example-synchronous.lo -synchronous-json-pointer: synchronous-json-pointer.lo - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ synchronous-json-pointer.lo - -simple-json-pointer: simple-json-pointer.lo - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ simple-json-pointer.lo - -tree-json-pointer: tree-json-pointer.lo - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ tree-json-pointer.lo - -reverse-json-pointer: reverse-json-pointer.lo - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ reverse-json-pointer.lo - $(EXTENSION_LIBEVENT_LIB): @echo "***" @echo "*** Three examples from the specification need libevent." @@ -172,19 +160,3 @@ example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $( example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \ ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ $(srcdir)/../../src/getdns/getdns_extra.h -reverse-json-pointer.lo reverse-json-pointer.o: $(srcdir)/reverse-json-pointer.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h -simple-concise.lo simple-concise.o: $(srcdir)/simple-concise.c $(srcdir)/getdns_libevent.h ../../src/config.h \ - ../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \ - $(srcdir)/../../src/getdns/getdns_extra.h -simple-json-pointer.lo simple-json-pointer.o: $(srcdir)/simple-json-pointer.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h -synchronous-concise.lo synchronous-concise.o: $(srcdir)/synchronous-concise.c $(srcdir)/getdns_core_only.h \ - ../../src/getdns/getdns.h -synchronous-json-pointer.lo synchronous-json-pointer.o: $(srcdir)/synchronous-json-pointer.c $(srcdir)/getdns_core_only.h \ - ../../src/getdns/getdns.h -tree-json-pointer.lo tree-json-pointer.o: $(srcdir)/tree-json-pointer.c $(srcdir)/getdns_libevent.h \ - ../../src/config.h ../../src/getdns/getdns.h \ - $(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h diff --git a/spec/example/example-reverse.c b/spec/example/example-reverse.c index b91e6c9e..4b92040d 100644 --- a/spec/example/example-reverse.c +++ b/spec/example/example-reverse.c @@ -1,135 +1,112 @@ -#include -#include -#include -#include +#include #include +#include #include -#define UNUSED_PARAM(x) ((void)(x)) - /* Set up the callback function, which will also do the processing of the results */ -void this_callbackfn(getdns_context *this_context, - getdns_callback_type_t this_callback_type, - getdns_dict *this_response, - void *this_userarg, - getdns_transaction_t this_transaction_id) +void callback(getdns_context *context, + getdns_callback_type_t callback_type, + getdns_dict *response, + void *userarg, + getdns_transaction_t transaction_id) { - getdns_return_t this_ret; /* Holder for all function returns */ - UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */ - UNUSED_PARAM(this_context); /* Not looking at the context for this example */ - UNUSED_PARAM(this_ret); /* Set, but not read */ - if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ - { - /* Be sure the search returned something */ - 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.\n", this_error); - getdns_dict_destroy(this_response); - return; - } - 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) - { - getdns_dict * this_reply; - this_ret = getdns_list_get_dict(replies_tree, reply_count, &this_reply); // Ignore any error - /* Just print the address */ - 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) - { - 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) - { - getdns_dict *this_rdata; - this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error + getdns_return_t r; /* Holder for all function returns */ + getdns_list *answer; + size_t n_answers, i; - getdns_bindata * this_dname; - this_ret = getdns_dict_get_bindata(this_rdata, "rdata_raw", &this_dname); - char *this_dname_str; - this_ret = getdns_convert_dns_name_to_fqdn(this_dname, &this_dname_str); // Ignore any error - printf("The dname is %s\n", this_dname_str); - free(this_dname_str); - } - } + (void) context; (void) userarg; /* unused parameters */ + switch(callback_type) { + case GETDNS_CALLBACK_CANCEL: + printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); + return; + case GETDNS_CALLBACK_TIMEOUT: + printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); + return; + case GETDNS_CALLBACK_ERROR: + printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); + return; + default: break; + } + assert( callback_type == GETDNS_CALLBACK_COMPLETE ); + + if ((r = getdns_dict_get_list(response, "/replies_tree/0/answer", &answer))) + fprintf(stderr, "Could not get \"answer\" section from first reply in the reponse"); + + else if ((r = getdns_list_get_length(answer, &n_answers))) + fprintf(stderr, "Could not get replies_tree\'s length"); + + else for (i = 0; i < n_answers && r == GETDNS_RETURN_GOOD; i++) { + getdns_dict *rr; + getdns_bindata *dname; + char *dname_str; + + if ((r = getdns_list_get_dict(answer, i, &rr))) + fprintf(stderr, "Could not get rr %zu from answer section", i); + + else if (getdns_dict_get_bindata(rr, "/rdata/ptrdname", &dname)) + continue; /* Not a PTR */ + + else if ((r = getdns_convert_dns_name_to_fqdn(dname, &dname_str))) + fprintf(stderr, "Could not convert PTR dname to string"); + + else { + printf("The dname is %s\n", dname_str); + free(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); + if (r) { + assert( r != GETDNS_RETURN_GOOD ); + fprintf(stderr, ": %d\n", r); + } + getdns_dict_destroy(response); } int main() { - /* Create the DNS context for this call */ - getdns_context *this_context = NULL; - 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); - return(GETDNS_RETURN_GENERIC_ERROR); - } - /* Create an event base and put it in the context using the unknown function name */ - struct event_base *this_event_base; - this_event_base = event_base_new(); - 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 */ - getdns_dict * this_addr_to_look_up = getdns_dict_create(); - // TODO: check the return value above - getdns_bindata this_type = { 4, (void *)"IPv4" }; - getdns_return_t this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_type", &this_type); - UNUSED_PARAM(this_ret); - 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; + getdns_return_t r; /* Holder for all function returns */ + getdns_context *context = NULL; + struct event_base *event_base = NULL; + getdns_bindata address_type = { 4, (void *)"IPv4" }; + getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" }; + getdns_dict *address = NULL; + getdns_dict *extensions = NULL; + /* Could add things here to help identify this call */ + char *userarg = NULL; + getdns_transaction_t transaction_id; - /* Make the call */ - getdns_return_t dns_request_return = getdns_hostname(this_context, this_addr_to_look_up, - NULL, this_userarg, &this_transaction_id, this_callbackfn); - if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) - { - char *ip_address_str = getdns_display_ip_address(&this_ipv4_addr); + if ((r = getdns_context_create(&context, 1))) + fprintf(stderr, "Trying to create the context failed"); + + else if (!(event_base = event_base_new())) + fprintf(stderr, "Trying to create the event base failed.\n"); + + else if ((r = getdns_extension_set_libevent_base(context, event_base))) + fprintf(stderr, "Setting the event base failed"); + + else if (!(address = getdns_dict_create())) + fprintf(stderr, "Could not create address dict.\n"); + + else if ((r = getdns_dict_set_bindata(address, "address_type", &address_type))) + fprintf(stderr, "Could not set address_type in address dict.\n"); + + else if ((r = getdns_dict_set_bindata(address, "address_data", &address_data))) + fprintf(stderr, "Could not set address_data in address dict.\n"); + + else if ((r = getdns_hostname( context, address, extensions + , userarg, &transaction_id, callback))) + fprintf(stderr, "Error scheduling asynchronous request"); + + else if (event_base_dispatch(event_base) < 0) + fprintf(stderr, "Error dispatching events\n"); - 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 - { - /* Call the event loop */ - int dispatch_return = event_base_dispatch(this_event_base); - UNUSED_PARAM(dispatch_return); - // TODO: check the return value above - } /* Clean up */ - getdns_dict_destroy(this_addr_to_look_up); - event_base_free(this_event_base); - getdns_context_destroy(this_context); + if (event_base) + event_base_free(event_base); + + if (context) + getdns_context_destroy(context); + /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } diff --git a/spec/example/example-simple-answers.c b/spec/example/example-simple-answers.c index 1866543c..a861e0f6 100644 --- a/spec/example/example-simple-answers.c +++ b/spec/example/example-simple-answers.c @@ -1,108 +1,109 @@ -#include -#include -#include -#include +#include #include +#include #include -#define UNUSED_PARAM(x) ((void)(x)) - /* Set up the callback function, which will also do the processing of the results */ -void this_callbackfn(getdns_context *this_context, - getdns_callback_type_t this_callback_type, - getdns_dict *this_response, - void *this_userarg, - getdns_transaction_t this_transaction_id) +void callback(getdns_context *context, + getdns_callback_type_t callback_type, + getdns_dict *response, + void *userarg, + getdns_transaction_t transaction_id) { - UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */ - UNUSED_PARAM(this_context); /* Not looking at the context for this example */ - getdns_return_t this_ret; /* Holder for all function returns */ - if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ - { - /* Be sure the search returned something */ - 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.\n", this_error); - getdns_dict_destroy(this_response); - return; - } - 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\n", this_ret); - getdns_dict_destroy(this_response); - return; - } - 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; ++rec_count ) - { - 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 */ - getdns_bindata * this_address_data; - this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - char *this_address_str = getdns_display_ip_address(this_address_data); - printf("The address is %s\n", this_address_str); - free(this_address_str); - } + getdns_return_t r; /* Holder for all function returns */ + uint32_t status; + getdns_bindata *address_data; + char *first = NULL, *second = NULL; + + (void) context; /* unused parameter */ + + printf( "Callback for query \"%s\" with request ID %"PRIu64".\n" + , (char *)userarg, transaction_id ); + + switch(callback_type) { + case GETDNS_CALLBACK_CANCEL: + printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); + return; + case GETDNS_CALLBACK_TIMEOUT: + printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); + return; + case GETDNS_CALLBACK_ERROR: + printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); + return; + default: break; } - else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - 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.\n", this_callback_type); - getdns_dict_destroy(this_response); + assert( callback_type == GETDNS_CALLBACK_COMPLETE ); + + if ((r = getdns_dict_get_int(response, "status", &status))) + fprintf(stderr, "Could not get \"status\" from reponse"); + + else if (status != GETDNS_RESPSTATUS_GOOD) + fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status); + + else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data))) + fprintf(stderr, "Could not get first address"); + + else if (!(first = getdns_display_ip_address(address_data))) + fprintf(stderr, "Could not convert first address to string\n"); + + else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data))) + fprintf(stderr, "Could not get second address"); + + else if (!(second = getdns_display_ip_address(address_data))) + fprintf(stderr, "Could not convert second address to string\n"); + + if (first) { + printf("The address is %s\n", first); + free(first); + } + if (second) { + printf("The address is %s\n", second); + free(second); + } + if (r) { + assert( r != GETDNS_RETURN_GOOD ); + fprintf(stderr, ": %d\n", r); + } + getdns_dict_destroy(response); } int main() { - /* Create the DNS context for this call */ - getdns_context *this_context = NULL; - 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); - return(GETDNS_RETURN_GENERIC_ERROR); - } - /* Create an event base and put it in the context using the unknown function name */ - struct event_base *this_event_base; - this_event_base = event_base_new(); - if (this_event_base == NULL) - { - 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); - /* Set up the getdns call */ - const char * this_name = "www.example.com"; - char* this_userarg = "somestring"; // Could add things here to help identify this call - getdns_transaction_t this_transaction_id = 0; + getdns_return_t r; /* Holder for all function returns */ + getdns_context *context = NULL; + struct event_base *event_base = NULL; + getdns_dict *extensions = NULL; + char *query_name = "www.example.com"; + /* Could add things here to help identify this call */ + char *userarg = query_name; + getdns_transaction_t transaction_id; - /* Make the call */ - getdns_return_t dns_request_return = getdns_address(this_context, this_name, - 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.\n", this_name); - event_base_free(this_event_base); - getdns_context_destroy(this_context); - return(GETDNS_RETURN_GENERIC_ERROR); - } - else - { - /* Call the event loop */ - int dispatch_return = event_base_dispatch(this_event_base); - UNUSED_PARAM(dispatch_return); - // TODO: check the return value above + if ((r = getdns_context_create(&context, 1))) + fprintf(stderr, "Trying to create the context failed"); + + else if (!(event_base = event_base_new())) + fprintf(stderr, "Trying to create the event base failed.\n"); + + else if ((r = getdns_extension_set_libevent_base(context, event_base))) + fprintf(stderr, "Setting the event base failed"); + + else if ((r = getdns_address( context, query_name, extensions + , userarg, &transaction_id, callback))) + fprintf(stderr, "Error scheduling asynchronous request"); + + else { + printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id); + if (event_base_dispatch(event_base) < 0) + fprintf(stderr, "Error dispatching events\n"); } + /* Clean up */ - event_base_free(this_event_base); - getdns_context_destroy(this_context); + if (event_base) + event_base_free(event_base); + + if (context) + getdns_context_destroy(context); + /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } diff --git a/spec/example/example-synchronous.c b/spec/example/example-synchronous.c index 4095388b..9d0aa2af 100644 --- a/spec/example/example-synchronous.c +++ b/spec/example/example-synchronous.c @@ -1,81 +1,66 @@ #include -#include -#include -#include -#include +#include #include int main() { - getdns_return_t this_ret; /* Holder for all function returns */ - /* Create the DNS context for this call */ - getdns_context *this_context = NULL; - 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\n", context_create_return); - return(GETDNS_RETURN_GENERIC_ERROR); - } - /* Set up the getdns_sync_request call */ - const char * this_name = "www.example.com"; - uint8_t this_request_type = GETDNS_RRTYPE_A; - /* Get the A and AAAA records */ - getdns_dict * this_extensions = getdns_dict_create(); - 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\n", this_ret); - getdns_dict_destroy(this_extensions); - getdns_context_destroy(this_context); - return(GETDNS_RETURN_GENERIC_ERROR); - } - getdns_dict * this_response = NULL; + getdns_return_t r; /* Holder for all function returns */ + getdns_context *context = NULL; + getdns_dict *response = NULL; + getdns_dict *extensions = NULL; + getdns_bindata *address_data; + char *first = NULL, *second = NULL; - /* Make the call */ - getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type, - this_extensions, &this_response); - if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_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); + /* Create the DNS context for this call */ + if ((r = getdns_context_create(&context, 1))) + fprintf(stderr, "Trying to create the context failed"); + + else if (!(extensions = getdns_dict_create())) + fprintf(stderr, "Could not create extensions dict.\n"); + + else if ((r = getdns_dict_set_int(extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE))) + fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed"); + + else if ((r = getdns_general_sync(context, "example.com", GETDNS_RRTYPE_A, extensions, &response))) + fprintf(stderr, "Error scheduling synchronous request"); + + else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data))) + fprintf(stderr, "Could not get first address"); + + else if (!(first = getdns_display_ip_address(address_data))) + fprintf(stderr, "Could not convert first address to string\n"); + + else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data))) + fprintf(stderr, "Could not get second address"); + + else if (!(second = getdns_display_ip_address(address_data))) + fprintf(stderr, "Could not convert second address to string\n"); + + if (first) { + printf("The address is %s\n", first); + free(first); } - else - { - /* Be sure the search returned something */ - 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.\n", this_error); - getdns_dict_destroy(this_response); - getdns_dict_destroy(this_extensions); - getdns_context_destroy(this_context); - return(GETDNS_RETURN_GENERIC_ERROR); - } - 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; - 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; ++rec_count ) - { - 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 */ - getdns_bindata * this_address_data; - this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - char *this_address_str = getdns_display_ip_address(this_address_data); - printf("The address is %s\n", this_address_str); - free(this_address_str); - } + if (second) { + printf("The address is %s\n", second); + free(second); } /* Clean up */ - getdns_dict_destroy(this_response); - getdns_dict_destroy(this_extensions); - getdns_context_destroy(this_context); + if (response) + getdns_dict_destroy(response); + + if (extensions) + getdns_dict_destroy(extensions); + + if (context) + getdns_context_destroy(context); + + if (r) { + assert( r != GETDNS_RETURN_GOOD ); + + fprintf(stderr, ": %d\n", r); + exit(EXIT_FAILURE); + } /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } + diff --git a/spec/example/example-tree.c b/spec/example/example-tree.c index f815baee..f88299bb 100644 --- a/spec/example/example-tree.c +++ b/spec/example/example-tree.c @@ -1,151 +1,121 @@ -#include -#include -#include -#include +#include #include +#include #include -#define UNUSED_PARAM(x) ((void)(x)) - /* Set up the callback function, which will also do the processing of the results */ -void this_callbackfn(getdns_context *this_context, - getdns_callback_type_t this_callback_type, - getdns_dict *this_response, - void *this_userarg, - getdns_transaction_t this_transaction_id) +void callback(getdns_context *context, + getdns_callback_type_t callback_type, + getdns_dict *response, + void *userarg, + getdns_transaction_t transaction_id) { - UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */ - UNUSED_PARAM(this_context); /* Not looking at the context for this example */ - getdns_return_t this_ret; /* Holder for all function returns */ - if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ - { - /* Be sure the search returned something */ - 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.\n", this_error); - getdns_dict_destroy(this_response); - return; - } - /* Find all the answers returned */ - getdns_list * 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.\n"); - getdns_dict_destroy(this_response); - return; - } - 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; ++rec_count ) - { - getdns_dict * this_record; - this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record); // Ignore any error - /* Get the answer section */ - 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; - this_ret = getdns_list_get_length(this_answer, &num_rrs); - for ( size_t rr_count = 0; rr_count < num_rrs; ++rr_count ) - { - getdns_dict *this_rr = NULL; - this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr); // Ignore any error - /* Get the RDATA */ - 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; - 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) - { - 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.\n", - (int) rr_count, (int) rec_count); - getdns_dict_destroy(this_response); - return; - } - 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) - { - 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.\n", - (int) rr_count, (int) rec_count); - getdns_dict_destroy(this_response); - return; - } - 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); + getdns_return_t r; /* Holder for all function returns */ + getdns_list *replies_tree; + size_t n_replies, i; + + (void) context; (void) userarg; /* unused parameters */ + + switch(callback_type) { + case GETDNS_CALLBACK_CANCEL: + printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); + return; + case GETDNS_CALLBACK_TIMEOUT: + printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); + return; + case GETDNS_CALLBACK_ERROR: + printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); + return; + default: break; + } + assert( callback_type == GETDNS_CALLBACK_COMPLETE ); + + if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree))) + fprintf(stderr, "Could not get \"replies_tree\" from reponse"); + + else if ((r = getdns_list_get_length(replies_tree, &n_replies))) + fprintf(stderr, "Could not get replies_tree\'s length"); + + else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) { + getdns_dict *reply; + getdns_list *answer; + size_t n_answers, j; + + if ((r = getdns_list_get_dict(replies_tree, i, &reply))) + fprintf(stderr, "Could not get address %zu from just_address_answers", i); + + else if ((r = getdns_dict_get_list(reply, "answer", &answer))) + fprintf(stderr, "Could not get \"address_data\" from address"); + + else if ((r = getdns_list_get_length(answer, &n_answers))) + fprintf(stderr, "Could not get answer section\'s length"); + + else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) { + getdns_dict *rr; + getdns_bindata *address = NULL; + + if ((r = getdns_list_get_dict(answer, j, &rr))) + fprintf(stderr, "Could net get rr %zu from answer section", j); + + else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD) + printf("The IPv4 address is "); + + else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD) + printf("The IPv6 address is "); + + if (address) { + char *address_str; + if (!(address_str = getdns_display_ip_address(address))) { + fprintf(stderr, "Could not convert second address to string"); + r = GETDNS_RETURN_MEMORY_ERROR; + break; } + printf("%s\n", address_str); + free(address_str); } } } - else if (this_callback_type == GETDNS_CALLBACK_CANCEL) - 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.\n", this_callback_type); - getdns_dict_destroy(this_response); + if (r) { + assert( r != GETDNS_RETURN_GOOD ); + fprintf(stderr, ": %d\n", r); + } + getdns_dict_destroy(response); } int main() { - /* Create the DNS context for this call */ - getdns_context *this_context = NULL; - 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\n", context_create_return); - return(GETDNS_RETURN_GENERIC_ERROR); - } - /* Create an event base and put it in the context using the unknown function name */ - struct event_base *this_event_base; - this_event_base = event_base_new(); - if (this_event_base == NULL) - { - 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); - /* Set up the getdns call */ - const char * this_name = "www.example.com"; - char* this_userarg = "somestring"; // Could add things here to help identify this call - getdns_transaction_t this_transaction_id = 0; + getdns_return_t r; /* Holder for all function returns */ + getdns_context *context = NULL; + struct event_base *event_base = NULL; + getdns_dict *extensions = NULL; + char *query_name = "www.example.com"; + /* Could add things here to help identify this call */ + char *userarg = NULL; + getdns_transaction_t transaction_id; + + if ((r = getdns_context_create(&context, 1))) + fprintf(stderr, "Trying to create the context failed"); + + else if (!(event_base = event_base_new())) + fprintf(stderr, "Trying to create the event base failed.\n"); + + else if ((r = getdns_extension_set_libevent_base(context, event_base))) + fprintf(stderr, "Setting the event base failed"); + + else if ((r = getdns_address( context, query_name, extensions + , userarg, &transaction_id, callback))) + fprintf(stderr, "Error scheduling asynchronous request"); + + else if (event_base_dispatch(event_base) < 0) + fprintf(stderr, "Error dispatching events\n"); - /* Make the call */ - getdns_return_t dns_request_return = getdns_address(this_context, this_name, - 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.\n", this_name); - event_base_free(this_event_base); - getdns_context_destroy(this_context); - return(GETDNS_RETURN_GENERIC_ERROR); - } - else - { - /* Call the event loop */ - int dispatch_return = event_base_dispatch(this_event_base); - UNUSED_PARAM(dispatch_return); - // TODO: check the return value above - } /* Clean up */ - event_base_free(this_event_base); - getdns_context_destroy(this_context); + if (event_base) + event_base_free(event_base); + + if (context) + getdns_context_destroy(context); + /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } diff --git a/spec/example/reverse-json-pointer.c b/spec/example/reverse-json-pointer.c deleted file mode 100644 index 2b62b72f..00000000 --- a/spec/example/reverse-json-pointer.c +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include -#include - -/* Set up the callback function, which will also do the processing of the results */ -void callback(getdns_context *context, - getdns_callback_type_t callback_type, - getdns_dict *response, - void *userarg, - getdns_transaction_t transaction_id) -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_list *answer; - size_t n_answers, i; - - switch(callback_type) { - case GETDNS_CALLBACK_CANCEL: - printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); - return; - case GETDNS_CALLBACK_TIMEOUT: - printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); - return; - case GETDNS_CALLBACK_ERROR: - printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); - return; - default: break; - } - assert( callback_type == GETDNS_CALLBACK_COMPLETE ); - - if ((r = getdns_dict_get_list(response, "/replies_tree/0/answer", &answer))) - fprintf(stderr, "Could not get \"answer\" section from first reply in the reponse"); - - else if ((r = getdns_list_get_length(answer, &n_answers))) - fprintf(stderr, "Could not get replies_tree\'s length"); - - else for (i = 0; i < n_answers && r == GETDNS_RETURN_GOOD; i++) { - getdns_dict *rr; - getdns_bindata *dname; - char *dname_str; - - if ((r = getdns_list_get_dict(answer, i, &rr))) - fprintf(stderr, "Could not get rr %zu from answer section", i); - - else if (getdns_dict_get_bindata(rr, "/rdata/ptrdname", &dname)) - continue; /* Not a PTR */ - - else if ((r = getdns_convert_dns_name_to_fqdn(dname, &dname_str))) - fprintf(stderr, "Could not convert PTR dname to string"); - - else { - printf("The dname is %s\n", dname_str); - free(dname_str); - } - } - if (r) { - assert( r != GETDNS_RETURN_GOOD ); - fprintf(stderr, ": %d\n", r); - } - getdns_dict_destroy(response); -} - -int main() -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_context *context = NULL; - struct event_base *event_base = NULL; - getdns_bindata address_type = { 4, (void *)"IPv4" }; - getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" }; - getdns_dict *address = NULL; - getdns_dict *extensions = NULL; - /* Could add things here to help identify this call */ - char *userarg = NULL; - getdns_transaction_t transaction_id; - - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if (!(event_base = event_base_new())) - fprintf(stderr, "Trying to create the event base failed.\n"); - - else if ((r = getdns_extension_set_libevent_base(context, event_base))) - fprintf(stderr, "Setting the event base failed"); - - else if (!(address = getdns_dict_create())) - fprintf(stderr, "Could not create address dict.\n"); - - else if ((r = getdns_dict_set_bindata(address, "address_type", &address_type))) - fprintf(stderr, "Could not set address_type in address dict.\n"); - - else if ((r = getdns_dict_set_bindata(address, "address_data", &address_data))) - fprintf(stderr, "Could not set address_data in address dict.\n"); - - else if ((r = getdns_hostname( context, address, extensions - , userarg, &transaction_id, callback))) - fprintf(stderr, "Error scheduling asynchronous request"); - - else if (event_base_dispatch(event_base) < 0) - fprintf(stderr, "Error dispatching events\n"); - - /* Clean up */ - if (event_base) - event_base_free(event_base); - - if (context) - getdns_context_destroy(context); - - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} diff --git a/spec/example/simple-concise.c b/spec/example/simple-concise.c deleted file mode 100644 index 4448e542..00000000 --- a/spec/example/simple-concise.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include - -/* Set up the callback function, which will also do the processing of the results */ -void callback(getdns_context *context, - getdns_callback_type_t callback_type, - getdns_dict *response, - void *userarg, - getdns_transaction_t transaction_id) -{ - getdns_return_t r; /* Holder for all function returns */ - uint32_t status; - getdns_list *just_address_answers; - size_t length, i; - - printf( "Callback for query \"%s\" with request ID %"PRIu64".\n" - , (char *)userarg, transaction_id ); - - switch(callback_type) { - case GETDNS_CALLBACK_CANCEL: - printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); - return; - case GETDNS_CALLBACK_TIMEOUT: - printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); - return; - case GETDNS_CALLBACK_ERROR: - printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); - return; - default: break; - } - assert( callback_type == GETDNS_CALLBACK_COMPLETE ); - - if ((r = getdns_dict_get_int(response, "status", &status))) - fprintf(stderr, "Could not get \"status\" from reponse"); - - else if (status != GETDNS_RESPSTATUS_GOOD) - fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status); - - else if ((r = getdns_dict_get_list(response, "just_address_answers", &just_address_answers))) - fprintf(stderr, "Could not get \"just_address_answers\" from reponse"); - - else if ((r = getdns_list_get_length(just_address_answers, &length))) - fprintf(stderr, "Could not get just_address_answers\' length"); - - else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) { - getdns_dict *address; - getdns_bindata *address_data; - char *address_str; - - if ((r = getdns_list_get_dict(just_address_answers, i, &address))) - fprintf(stderr, "Could not get address %zu from just_address_answers", i); - - else if ((r = getdns_dict_get_bindata(address, "address_data", &address_data))) - fprintf(stderr, "Could not get \"address_data\" from address"); - - else if (!(address_str = getdns_display_ip_address(address_data))) { - fprintf(stderr, "Could not convert address to string"); - r = GETDNS_RETURN_MEMORY_ERROR; - } - else { - printf("The address is %s\n", address_str); - free(address_str); - } - } - if (r) { - assert( r != GETDNS_RETURN_GOOD ); - fprintf(stderr, ": %d\n", r); - } - getdns_dict_destroy(response); -} - -int main() -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_context *context = NULL; - struct event_base *event_base = NULL; - getdns_dict *extensions = NULL; - char *query_name = "www.example.com"; - /* Could add things here to help identify this call */ - char *userarg = query_name; - getdns_transaction_t transaction_id; - - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if (!(event_base = event_base_new())) - fprintf(stderr, "Trying to create the event base failed.\n"); - - else if ((r = getdns_extension_set_libevent_base(context, event_base))) - fprintf(stderr, "Setting the event base failed"); - - else if ((r = getdns_address( context, query_name, extensions - , userarg, &transaction_id, callback))) - fprintf(stderr, "Error scheduling asynchronous request"); - - else { - printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id); - if (event_base_dispatch(event_base) < 0) - fprintf(stderr, "Error dispatching events\n"); - } - - /* Clean up */ - if (event_base) - event_base_free(event_base); - - if (context) - getdns_context_destroy(context); - - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} diff --git a/spec/example/simple-json-pointer.c b/spec/example/simple-json-pointer.c deleted file mode 100644 index ae802ea7..00000000 --- a/spec/example/simple-json-pointer.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include - -/* Set up the callback function, which will also do the processing of the results */ -void callback(getdns_context *context, - getdns_callback_type_t callback_type, - getdns_dict *response, - void *userarg, - getdns_transaction_t transaction_id) -{ - getdns_return_t r; /* Holder for all function returns */ - uint32_t status; - getdns_bindata *address_data; - char *first = NULL, *second = NULL; - - printf( "Callback for query \"%s\" with request ID %"PRIu64".\n" - , (char *)userarg, transaction_id ); - - switch(callback_type) { - case GETDNS_CALLBACK_CANCEL: - printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); - return; - case GETDNS_CALLBACK_TIMEOUT: - printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); - return; - case GETDNS_CALLBACK_ERROR: - printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); - return; - default: break; - } - assert( callback_type == GETDNS_CALLBACK_COMPLETE ); - - if ((r = getdns_dict_get_int(response, "status", &status))) - fprintf(stderr, "Could not get \"status\" from reponse"); - - else if (status != GETDNS_RESPSTATUS_GOOD) - fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status); - - else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data))) - fprintf(stderr, "Could not get first address"); - - else if (!(first = getdns_display_ip_address(address_data))) - fprintf(stderr, "Could not convert first address to string\n"); - - else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data))) - fprintf(stderr, "Could not get second address"); - - else if (!(second = getdns_display_ip_address(address_data))) - fprintf(stderr, "Could not convert second address to string\n"); - - if (first) { - printf("The address is %s\n", first); - free(first); - } - if (second) { - printf("The address is %s\n", second); - free(second); - } - if (r) { - assert( r != GETDNS_RETURN_GOOD ); - fprintf(stderr, ": %d\n", r); - } - getdns_dict_destroy(response); -} - -int main() -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_context *context = NULL; - struct event_base *event_base = NULL; - getdns_dict *extensions = NULL; - char *query_name = "www.example.com"; - /* Could add things here to help identify this call */ - char *userarg = query_name; - getdns_transaction_t transaction_id; - - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if (!(event_base = event_base_new())) - fprintf(stderr, "Trying to create the event base failed.\n"); - - else if ((r = getdns_extension_set_libevent_base(context, event_base))) - fprintf(stderr, "Setting the event base failed"); - - else if ((r = getdns_address( context, query_name, extensions - , userarg, &transaction_id, callback))) - fprintf(stderr, "Error scheduling asynchronous request"); - - else { - printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id); - if (event_base_dispatch(event_base) < 0) - fprintf(stderr, "Error dispatching events\n"); - } - - /* Clean up */ - if (event_base) - event_base_free(event_base); - - if (context) - getdns_context_destroy(context); - - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} diff --git a/spec/example/synchronous-concise.c b/spec/example/synchronous-concise.c deleted file mode 100644 index 98e257b2..00000000 --- a/spec/example/synchronous-concise.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include - -int main() -{ - getdns_return_t r; - getdns_context *context = NULL; - getdns_dict *response = NULL; - uint32_t status; - getdns_list *just_address_answers; - size_t length, i; - - /* Create the DNS context for this call */ - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if ((r = getdns_address_sync(context, "example.com", NULL, &response))) - fprintf(stderr, "Error scheduling synchronous request"); - - else if ((r = getdns_dict_get_int(response, "status", &status))) - fprintf(stderr, "Could not get \"status\" from reponse"); - - else if (status != GETDNS_RESPSTATUS_GOOD) - fprintf(stderr, "The search had no results, and a return value of %zu.\n", status); - - else if ((r = getdns_dict_get_list(response, "just_address_answers", &just_address_answers))) - fprintf(stderr, "Could not get \"just_address_answers\" from reponse"); - - else if ((r = getdns_list_get_length(just_address_answers, &length))) - fprintf(stderr, "Could not get just_address_answers\' length"); - - else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) { - getdns_dict *address; - getdns_bindata *address_data; - char *address_str; - - if ((r = getdns_list_get_dict(just_address_answers, i, &address))) - fprintf(stderr, "Could not get address %zu from just_address_answers", i); - - else if ((r = getdns_dict_get_bindata(address, "address_data", &address_data))) - fprintf(stderr, "Could not get \"address_data\" from address"); - - else if (!(address_str = getdns_display_ip_address(address_data))) { - fprintf(stderr, "Could not convert address to string"); - r = GETDNS_RETURN_MEMORY_ERROR; - } - else { - printf("The address is %s\n", address_str); - free(address_str); - } - } - /* Clean up */ - if (response) - getdns_dict_destroy(response); - - if (context) - getdns_context_destroy(context); - - if (r) { - fprintf(stderr, ": %d\n", r); - exit(EXIT_FAILURE); - } - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} diff --git a/spec/example/synchronous-json-pointer.c b/spec/example/synchronous-json-pointer.c deleted file mode 100644 index d80182e7..00000000 --- a/spec/example/synchronous-json-pointer.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include - -int main() -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_context *context = NULL; - getdns_dict *response = NULL; - getdns_bindata *address_data; - char *first = NULL, *second = NULL; - - /* Create the DNS context for this call */ - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if ((r = getdns_address_sync(context, "example.com", NULL, &response))) - fprintf(stderr, "Error scheduling synchronous request"); - - else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data))) - fprintf(stderr, "Could not get first address"); - - else if (!(first = getdns_display_ip_address(address_data))) - fprintf(stderr, "Could not convert first address to string\n"); - - else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data))) - fprintf(stderr, "Could not get second address"); - - else if (!(second = getdns_display_ip_address(address_data))) - fprintf(stderr, "Could not convert second address to string\n"); - - if (first) { - printf("The address is %s\n", first); - free(first); - } - if (second) { - printf("The address is %s\n", second); - free(second); - } - /* Clean up */ - if (response) - getdns_dict_destroy(response); - - if (context) - getdns_context_destroy(context); - - if (r) { - assert( r != GETDNS_RETURN_GOOD ); - - fprintf(stderr, ": %d\n", r); - exit(EXIT_FAILURE); - } - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} - diff --git a/spec/example/tree-json-pointer.c b/spec/example/tree-json-pointer.c deleted file mode 100644 index 77493d10..00000000 --- a/spec/example/tree-json-pointer.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include - -/* Set up the callback function, which will also do the processing of the results */ -void callback(getdns_context *context, - getdns_callback_type_t callback_type, - getdns_dict *response, - void *userarg, - getdns_transaction_t transaction_id) -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_list *replies_tree; - size_t length, i; - - switch(callback_type) { - case GETDNS_CALLBACK_CANCEL: - printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); - return; - case GETDNS_CALLBACK_TIMEOUT: - printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); - return; - case GETDNS_CALLBACK_ERROR: - printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); - return; - default: break; - } - assert( callback_type == GETDNS_CALLBACK_COMPLETE ); - - if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree))) - fprintf(stderr, "Could not get \"replies_tree\" from reponse"); - - else if ((r = getdns_list_get_length(replies_tree, &length))) - fprintf(stderr, "Could not get replies_tree\'s length"); - - else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) { - getdns_dict *reply; - getdns_list *answer; - size_t n_answers, j; - - if ((r = getdns_list_get_dict(replies_tree, i, &reply))) - fprintf(stderr, "Could not get address %zu from just_address_answers", i); - - else if ((r = getdns_dict_get_list(reply, "answer", &answer))) - fprintf(stderr, "Could not get \"address_data\" from address"); - - else if ((r = getdns_list_get_length(answer, &n_answers))) - fprintf(stderr, "Could not get answer section\'s length"); - - else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) { - getdns_dict *rr; - getdns_bindata *address = NULL; - - if ((r = getdns_list_get_dict(answer, j, &rr))) - fprintf(stderr, "Could net get rr %zu from answer section", j); - - else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD) - printf("The IPv4 address is "); - - else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD) - printf("The IPv6 address is "); - - if (address) { - char *address_str; - if (!(address_str = getdns_display_ip_address(address))) { - fprintf(stderr, "Could not convert second address to string"); - r = GETDNS_RETURN_MEMORY_ERROR; - break; - } - printf("%s\n", address_str); - free(address_str); - } - } - } - if (r) { - assert( r != GETDNS_RETURN_GOOD ); - fprintf(stderr, ": %d\n", r); - } - getdns_dict_destroy(response); -} - -int main() -{ - getdns_return_t r; /* Holder for all function returns */ - getdns_context *context = NULL; - struct event_base *event_base = NULL; - getdns_dict *extensions = NULL; - char *query_name = "www.example.com"; - /* Could add things here to help identify this call */ - char *userarg = NULL; - getdns_transaction_t transaction_id; - - if ((r = getdns_context_create(&context, 1))) - fprintf(stderr, "Trying to create the context failed"); - - else if (!(event_base = event_base_new())) - fprintf(stderr, "Trying to create the event base failed.\n"); - - else if ((r = getdns_extension_set_libevent_base(context, event_base))) - fprintf(stderr, "Setting the event base failed"); - - else if ((r = getdns_address( context, query_name, extensions - , userarg, &transaction_id, callback))) - fprintf(stderr, "Error scheduling asynchronous request"); - - else if (event_base_dispatch(event_base) < 0) - fprintf(stderr, "Error dispatching events\n"); - - /* Clean up */ - if (event_base) - event_base_free(event_base); - - if (context) - getdns_context_destroy(context); - - /* Assuming we get here, leave gracefully */ - exit(EXIT_SUCCESS); -} diff --git a/spec/getdns-0.604.tgz b/spec/getdns-0.604.tgz deleted file mode 100644 index c3e50060..00000000 Binary files a/spec/getdns-0.604.tgz and /dev/null differ diff --git a/spec/index.html b/spec/index.html index 05375e7e..2f04d6ea 100644 --- a/spec/index.html +++ b/spec/index.html @@ -94,7 +94,7 @@ tr.code { font-family: monospace }

Originally edited by Paul Hoffman

Currently maintained by the getdns team

-

Document version: "getdns July 2015"

+

Document version: "getdns October 2015 - release candidate 1"

This document describes a modern asynchronous DNS API. This new API is intended to be useful to application developers and operating system distributors as a way of making @@ -558,6 +558,8 @@ The user must not directly destroy these retrieved "child" data structures; inst they will automatically be destroyed when the containing "parent" data structure is destroyed. Because of this, retrieved "child" data structures cannot be used any more after the containing "parent" data structure has been destroyed.

+

When the name parameter to the getdns_dict_get_ functions, starts with a '/' (%x2F) character, it is interpreted as a JSON Pointer as described in RFC 6901, and will then be used to dereference the nested data structures to get to the requested data type.

+

2.1 Creating Data Structures

Some of the features of the API require that you create your own data structures to be used in @@ -626,6 +628,8 @@ list. getdns_dict_remove_name() will return

The helper setter functions store copies of the given "child" values. It is the responsibility of the caller to dispose of the original values.

+

When the name parameter to the getdns_dict_set_ functions, starts with a '/' (%x2F) character, it is interpreted as a JSON Pointer as described in RFC 6901, and will then be used to dereference the nested data structures to set the given value at the specified name or list index.

+

3. Extensions

Extensions are dict data structures. The names in the dict are the names of the extensions. @@ -1169,6 +1173,8 @@ typedef struct getdns_list getdns_list;

Unable to allocate the memory required.

GETDNS_RETURN_INVALID_PARAMETER

A required parameter had an invalid value.

+

GETDNS_RETURN_NOT_IMPLEMENTED

+

The library did not have the requested API feature implemented.

5.3 Types of RDATA Returned in the API

@@ -1464,111 +1470,112 @@ function.

This is an example of a common call to getdns_address().

-
#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
+
#include <assert.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include <getdns_libevent.h>
 
-#define UNUSED_PARAM(x) ((void)(x))
-
 /* Set up the callback function, which will also do the processing of the results */
-void this_callbackfn(getdns_context *this_context,
-                     getdns_callback_type_t this_callback_type,
-                     getdns_dict *this_response, 
-                     void *this_userarg,
-                     getdns_transaction_t this_transaction_id)
+void callback(getdns_context        *context,
+              getdns_callback_type_t callback_type,
+              getdns_dict           *response, 
+              void                  *userarg,
+              getdns_transaction_t   transaction_id)
 {
-    UNUSED_PARAM(this_userarg);  /* Not looking at the userarg for this example */
-    UNUSED_PARAM(this_context);  /* Not looking at the context for this example */
-    getdns_return_t this_ret;  /* Holder for all function returns */
-    if (this_callback_type == GETDNS_CALLBACK_COMPLETE)  /* This is a callback with data */
-    {
-        /* Be sure the search returned something */
-        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.\n", this_error);
-            getdns_dict_destroy(this_response);
-            return;
-        }
-        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\n", this_ret);
-            getdns_dict_destroy(this_response);
-            return;
-        }
-        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; ++rec_count )
-        {
-            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 */
-            getdns_bindata * this_address_data;
-            this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
-            char *this_address_str = getdns_display_ip_address(this_address_data);
-            printf("The address is %s\n", this_address_str);
-            free(this_address_str);
-        }
+    getdns_return_t r;  /* Holder for all function returns */
+    uint32_t        status;
+    getdns_bindata  *address_data;
+    char            *first = NULL, *second = NULL;
+
+    (void) context; /* unused parameter */
+
+    printf( "Callback for query \"%s\" with request ID %"PRIu64".\n"
+          , (char *)userarg, transaction_id );
+
+    switch(callback_type) {
+    case GETDNS_CALLBACK_CANCEL:
+        printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_TIMEOUT:
+        printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_ERROR:
+        printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
+        return;
+    default: break;
     }
-    else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
-        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.\n", this_callback_type);
-    getdns_dict_destroy(this_response);
+    assert( callback_type == GETDNS_CALLBACK_COMPLETE );
+
+    if ((r = getdns_dict_get_int(response, "status", &status)))
+        fprintf(stderr, "Could not get \"status\" from reponse");
+
+    else if (status != GETDNS_RESPSTATUS_GOOD)
+        fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status);
+
+    else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
+        fprintf(stderr, "Could not get first address");
+
+    else if (!(first = getdns_display_ip_address(address_data)))
+        fprintf(stderr, "Could not convert first address to string\n");
+
+    else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
+        fprintf(stderr, "Could not get second address");
+
+    else if (!(second = getdns_display_ip_address(address_data)))
+        fprintf(stderr, "Could not convert second address to string\n");
+
+    if (first) {
+        printf("The address is %s\n", first);
+        free(first);
+    }
+    if (second) {
+        printf("The address is %s\n", second);
+        free(second);
+    }
+    if (r) {
+        assert( r != GETDNS_RETURN_GOOD );
+        fprintf(stderr, ": %d\n", r);
+    }
+    getdns_dict_destroy(response); 
 }
 
 int main()
 {
-    /* Create the DNS context for this call */
-    getdns_context *this_context = NULL;
-    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);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    /* Create an event base and put it in the context using the unknown function name */
-    struct event_base *this_event_base;
-    this_event_base = event_base_new();
-    if (this_event_base == NULL)
-    {
-        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);
-    /* Set up the getdns call */
-    const char * this_name  = "www.example.com";
-    char* this_userarg = "somestring"; // Could add things here to help identify this call
-    getdns_transaction_t this_transaction_id = 0;
+    getdns_return_t      r;  /* Holder for all function returns */
+    getdns_context      *context    = NULL;
+    struct event_base   *event_base = NULL;
+    getdns_dict         *extensions = NULL;
+    char                *query_name = "www.example.com";
+    /* Could add things here to help identify this call */
+    char                *userarg    = query_name;
+    getdns_transaction_t transaction_id;
 
-    /* Make the call */
-    getdns_return_t dns_request_return = getdns_address(this_context, this_name,
-        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.\n", this_name);
-        event_base_free(this_event_base);
-        getdns_context_destroy(this_context);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    else
-    {
-        /* Call the event loop */
-        int dispatch_return = event_base_dispatch(this_event_base);
-        UNUSED_PARAM(dispatch_return);
-        // TODO: check the return value above
+    if ((r = getdns_context_create(&context, 1)))
+        fprintf(stderr, "Trying to create the context failed");
+
+    else if (!(event_base = event_base_new()))
+        fprintf(stderr, "Trying to create the event base failed.\n");
+
+    else if ((r = getdns_extension_set_libevent_base(context, event_base)))
+        fprintf(stderr, "Setting the event base failed");
+
+    else if ((r = getdns_address( context, query_name, extensions
+                                , userarg, &transaction_id, callback)))
+        fprintf(stderr, "Error scheduling asynchronous request");
+
+    else {
+        printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id);
+        if (event_base_dispatch(event_base) < 0)
+            fprintf(stderr, "Error dispatching events\n");
     }
+
     /* Clean up */
-    event_base_free(this_event_base);
-    getdns_context_destroy(this_context);
+    if (event_base)
+        event_base_free(event_base);
+
+    if (context)
+        getdns_context_destroy(context);
+
     /* Assuming we get here, leave gracefully */
     exit(EXIT_SUCCESS);
 }
@@ -1582,154 +1589,124 @@ function.

the addresses, so it traverses the replies_tree. In this case, it gets both the addresses and their TTLs.

-
#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
+
#include <assert.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include <getdns_libevent.h>
 
-#define UNUSED_PARAM(x) ((void)(x))
-
 /* Set up the callback function, which will also do the processing of the results */
-void this_callbackfn(getdns_context *this_context,
-                     getdns_callback_type_t this_callback_type,
-                     getdns_dict *this_response, 
-                     void *this_userarg,
-                     getdns_transaction_t this_transaction_id)
+void callback(getdns_context        *context,
+              getdns_callback_type_t callback_type,
+              getdns_dict           *response, 
+              void                  *userarg,
+              getdns_transaction_t   transaction_id)
 {
-    UNUSED_PARAM(this_userarg);  /* Not looking at the userarg for this example */
-    UNUSED_PARAM(this_context);  /* Not looking at the context for this example */
-    getdns_return_t this_ret;  /* Holder for all function returns */
-    if (this_callback_type == GETDNS_CALLBACK_COMPLETE)  /* This is a callback with data */
-    {
-        /* Be sure the search returned something */
-        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.\n", this_error);
-            getdns_dict_destroy(this_response);
-            return;
-        }
-        /* Find all the answers returned */
-        getdns_list * 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.\n");
-            getdns_dict_destroy(this_response);
-            return;
-        }
-        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; ++rec_count )
-        {
-            getdns_dict * this_record;
-            this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record);  // Ignore any error
-            /* Get the answer section */
-            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;
-            this_ret = getdns_list_get_length(this_answer, &num_rrs);
-            for ( size_t rr_count = 0; rr_count < num_rrs; ++rr_count )
-            {
-                getdns_dict *this_rr = NULL;
-                this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr);  // Ignore any error
-                /* Get the RDATA */
-                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;
-                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)
-                {
-                    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.\n",
-                            (int) rr_count, (int) rec_count);
-                        getdns_dict_destroy(this_response);
-                        return;
-                    }
-                    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)
-                {
-                    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.\n",
-                            (int) rr_count, (int) rec_count);
-                        getdns_dict_destroy(this_response);
-                        return;
-                    }
-                    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);
+    getdns_return_t r;  /* Holder for all function returns */
+    getdns_list    *replies_tree;
+    size_t          n_replies, i;
+
+    (void) context; (void) userarg; /* unused parameters */
+
+    switch(callback_type) {
+    case GETDNS_CALLBACK_CANCEL:
+        printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_TIMEOUT:
+        printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_ERROR:
+        printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
+        return;
+    default: break;
+    }
+    assert( callback_type == GETDNS_CALLBACK_COMPLETE );
+
+    if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree)))
+        fprintf(stderr, "Could not get \"replies_tree\" from reponse");
+
+    else if ((r = getdns_list_get_length(replies_tree, &n_replies)))
+        fprintf(stderr, "Could not get replies_tree\'s length");
+
+    else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) {
+        getdns_dict *reply;
+        getdns_list *answer;
+        size_t       n_answers, j;
+
+        if ((r = getdns_list_get_dict(replies_tree, i, &reply)))
+            fprintf(stderr, "Could not get address %zu from just_address_answers", i);
+
+        else if ((r = getdns_dict_get_list(reply, "answer", &answer)))
+            fprintf(stderr, "Could not get \"address_data\" from address");
+
+        else if ((r = getdns_list_get_length(answer, &n_answers)))
+            fprintf(stderr, "Could not get answer section\'s length");
+
+        else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) {
+            getdns_dict    *rr;
+            getdns_bindata *address = NULL;
+
+            if ((r = getdns_list_get_dict(answer, j, &rr)))
+                fprintf(stderr, "Could net get rr %zu from answer section", j);
+
+            else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD)
+                printf("The IPv4 address is ");
+
+            else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD)
+                printf("The IPv6 address is ");
+
+            if (address) {
+                char *address_str;
+                if (!(address_str = getdns_display_ip_address(address))) {
+                    fprintf(stderr, "Could not convert second address to string");
+                    r = GETDNS_RETURN_MEMORY_ERROR;
+                    break;
                 }
+                printf("%s\n", address_str);
+                free(address_str);
             }
         }
     }
-    else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
-        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.\n", this_callback_type);
-    getdns_dict_destroy(this_response);
+    if (r) {
+        assert( r != GETDNS_RETURN_GOOD );
+        fprintf(stderr, ": %d\n", r);
+    }
+    getdns_dict_destroy(response); 
 }
 
 int main()
 {
-    /* Create the DNS context for this call */
-    getdns_context *this_context = NULL;
-    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\n", context_create_return);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    /* Create an event base and put it in the context using the unknown function name */
-    struct event_base *this_event_base;
-    this_event_base = event_base_new();
-    if (this_event_base == NULL)
-    {
-        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);
-    /* Set up the getdns call */
-    const char * this_name  = "www.example.com";
-    char* this_userarg = "somestring"; // Could add things here to help identify this call
-    getdns_transaction_t this_transaction_id = 0;
+    getdns_return_t      r;  /* Holder for all function returns */
+    getdns_context      *context    = NULL;
+    struct event_base   *event_base = NULL;
+    getdns_dict         *extensions = NULL;
+    char                *query_name = "www.example.com";
+    /* Could add things here to help identify this call */
+    char                *userarg    = NULL;
+    getdns_transaction_t transaction_id;
+
+    if ((r = getdns_context_create(&context, 1)))
+        fprintf(stderr, "Trying to create the context failed");
+
+    else if (!(event_base = event_base_new()))
+        fprintf(stderr, "Trying to create the event base failed.\n");
+
+    else if ((r = getdns_extension_set_libevent_base(context, event_base)))
+        fprintf(stderr, "Setting the event base failed");
+
+    else if ((r = getdns_address( context, query_name, extensions
+                                , userarg, &transaction_id, callback)))
+        fprintf(stderr, "Error scheduling asynchronous request");
+
+    else if (event_base_dispatch(event_base) < 0)
+        fprintf(stderr, "Error dispatching events\n");
 
-    /* Make the call */
-    getdns_return_t dns_request_return = getdns_address(this_context, this_name,
-        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.\n", this_name);
-        event_base_free(this_event_base);
-        getdns_context_destroy(this_context);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    else
-    {
-        /* Call the event loop */
-        int dispatch_return = event_base_dispatch(this_event_base);
-        UNUSED_PARAM(dispatch_return);
-        // TODO: check the return value above
-    }
     /* Clean up */
-    event_base_free(this_event_base);
-    getdns_context_destroy(this_context);
+    if (event_base)
+        event_base_free(event_base);
+
+    if (context)
+        getdns_context_destroy(context);
+
     /* Assuming we get here, leave gracefully */
     exit(EXIT_SUCCESS);
 }
@@ -1745,20 +1722,17 @@ callback function, add a check for the DNSSEC status. It shows how to add two
 extensions to the extensions argument of the call.

-getdns_dict * this_extensions = getdns_dict_create();
-this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
-this_ret = getdns_dict_set_int(this_extensions, "dnssec_return_status", GETDNS_EXTENSION_TRUE);
+getdns_dict *extensions = getdns_dict_create();
+r = getdns_dict_set_int(extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
+r = getdns_dict_set_int(extensions, "dnssec_return_status", GETDNS_EXTENSION_TRUE);
 . . .
-if (this_type == GETDNS_RRTYPE_A)
-{
-    uint32_t this_dnssec_status;
-    this_ret = getdns_dict_get_int(this_answer, "dnssec_status", &this_dnssec_status);
-    if (this_dnssec_status != GETDNS_DNSSEC_SECURE)
-    {
+if (rr_type == GETDNS_RRTYPE_A) {
+    uint32_t dnssec_status;
+    r = getdns_dict_get_int(answer, "dnssec_status", &dnssec_status);
+    if (dnssec_status != GETDNS_DNSSEC_SECURE) {
         // Log the DNSSEC status somewhere
-    }
-    else
-    {
+
+    } else {
         // Deal with the record however you were going to
     }
 }
@@ -1775,83 +1749,67 @@ and thus does not use the async code. Note that the processing of the answers is
 as it is for the synchronous example, it is just done in main().


#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
+#include <assert.h>
 #include <getdns_core_only.h>
 
 int main()
 {
-    getdns_return_t this_ret;  /* Holder for all function returns */
-    /* Create the DNS context for this call */
-    getdns_context *this_context = NULL;
-    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\n", context_create_return);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    /* Set up the getdns_sync_request call */
-    const char * this_name  = "www.example.com";
-    uint8_t this_request_type = GETDNS_RRTYPE_A;
-    /* Get the A and AAAA records */
-    getdns_dict * this_extensions = getdns_dict_create();
-    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\n", this_ret);
-        getdns_dict_destroy(this_extensions);
-        getdns_context_destroy(this_context);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    getdns_dict * this_response = NULL;
+    getdns_return_t  r; /* Holder for all function returns */
+    getdns_context  *context    = NULL;
+    getdns_dict     *response   = NULL;
+    getdns_dict     *extensions = NULL;
+    getdns_bindata  *address_data;
+    char            *first = NULL, *second = NULL;
 
-    /* Make the call */
-    getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type,
-        this_extensions, &this_response);
-    if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_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);
+    /* Create the DNS context for this call */
+    if ((r = getdns_context_create(&context, 1)))
+        fprintf(stderr, "Trying to create the context failed");
+
+    else if (!(extensions = getdns_dict_create()))
+        fprintf(stderr, "Could not create extensions dict.\n");
+
+    else if ((r = getdns_dict_set_int(extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE)))
+        fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed");
+
+    else if ((r = getdns_general_sync(context, "example.com", GETDNS_RRTYPE_A, extensions, &response)))
+        fprintf(stderr, "Error scheduling synchronous request");
+    
+    else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
+        fprintf(stderr, "Could not get first address");
+
+    else if (!(first = getdns_display_ip_address(address_data)))
+        fprintf(stderr, "Could not convert first address to string\n");
+
+    else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
+        fprintf(stderr, "Could not get second address");
+
+    else if (!(second = getdns_display_ip_address(address_data)))
+        fprintf(stderr, "Could not convert second address to string\n");
+
+    if (first) {
+        printf("The address is %s\n", first);
+        free(first);
     }
-    else
-    {
-        /* Be sure the search returned something */
-        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.\n", this_error);
-            getdns_dict_destroy(this_response);
-            getdns_dict_destroy(this_extensions);
-            getdns_context_destroy(this_context);
-            return(GETDNS_RETURN_GENERIC_ERROR);
-        }
-        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;
-        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; ++rec_count )
-        {
-            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 */
-            getdns_bindata * this_address_data;
-            this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
-            char *this_address_str = getdns_display_ip_address(this_address_data);
-            printf("The address is %s\n", this_address_str);
-            free(this_address_str);
-        }
+    if (second) {
+        printf("The address is %s\n", second);
+        free(second);
     }
     /* Clean up */
-    getdns_dict_destroy(this_response); 
-    getdns_dict_destroy(this_extensions);
-    getdns_context_destroy(this_context);
+    if (response)
+        getdns_dict_destroy(response); 
+
+    if (extensions)
+        getdns_dict_destroy(extensions);
+
+    if (context)
+        getdns_context_destroy(context);
+
+    if (r) {
+        assert( r != GETDNS_RETURN_GOOD );
+
+        fprintf(stderr, ": %d\n", r);
+        exit(EXIT_FAILURE);
+    }
     /* Assuming we get here, leave gracefully */
     exit(EXIT_SUCCESS);
 }
@@ -1863,138 +1821,115 @@ as it is for the synchronous example, it is just done in main().

This example shows how to use getdns_hostname() to get names from the DNS reverse tree.

-
#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
+
#include <assert.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include <getdns_libevent.h>
 
-#define UNUSED_PARAM(x) ((void)(x))
-
 /* Set up the callback function, which will also do the processing of the results */
-void this_callbackfn(getdns_context *this_context,
-                     getdns_callback_type_t this_callback_type,
-                     getdns_dict *this_response, 
-                     void *this_userarg,
-                     getdns_transaction_t this_transaction_id)
+void callback(getdns_context        *context,
+              getdns_callback_type_t callback_type,
+              getdns_dict           *response, 
+              void                  *userarg,
+              getdns_transaction_t   transaction_id)
 {
-    getdns_return_t this_ret;  /* Holder for all function returns */
-    UNUSED_PARAM(this_userarg);  /* Not looking at the userarg for this example */
-    UNUSED_PARAM(this_context);  /* Not looking at the context for this example */
-    UNUSED_PARAM(this_ret); /* Set, but not read */
-    if (this_callback_type == GETDNS_CALLBACK_COMPLETE)  /* This is a callback with data */
-    {
-        /* Be sure the search returned something */
-        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.\n", this_error);
-            getdns_dict_destroy(this_response);
-            return;
-        }
-        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)
-        {
-            getdns_dict * this_reply;
-            this_ret = getdns_list_get_dict(replies_tree, reply_count, &this_reply);  // Ignore any error
-            /* Just print the address */
-            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)
-            {
-                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)
-                {
-                    getdns_dict *this_rdata;
-                    this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata);  // Ignore any error
+    getdns_return_t r;  /* Holder for all function returns */
+    getdns_list    *answer;
+    size_t          n_answers, i;
 
-                    getdns_bindata * this_dname;
-                    this_ret = getdns_dict_get_bindata(this_rdata, "rdata_raw", &this_dname);
-                    char *this_dname_str;
-                           this_ret = getdns_convert_dns_name_to_fqdn(this_dname, &this_dname_str); // Ignore any error
-                    printf("The dname is %s\n", this_dname_str);
-                    free(this_dname_str);
-                }
-            }
+    (void) context; (void) userarg; /* unused parameters */
 
+    switch(callback_type) {
+    case GETDNS_CALLBACK_CANCEL:
+        printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_TIMEOUT:
+        printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
+        return;
+    case GETDNS_CALLBACK_ERROR:
+        printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
+        return;
+    default: break;
+    }
+    assert( callback_type == GETDNS_CALLBACK_COMPLETE );
+
+    if ((r = getdns_dict_get_list(response, "/replies_tree/0/answer", &answer)))
+        fprintf(stderr, "Could not get \"answer\" section from first reply in the reponse");
+
+    else if ((r = getdns_list_get_length(answer, &n_answers)))
+        fprintf(stderr, "Could not get replies_tree\'s length");
+
+    else for (i = 0; i < n_answers && r == GETDNS_RETURN_GOOD; i++) {
+        getdns_dict    *rr;
+        getdns_bindata *dname;
+        char           *dname_str;
+
+        if ((r = getdns_list_get_dict(answer, i, &rr)))
+            fprintf(stderr, "Could not get rr %zu from answer section", i);
+
+        else if (getdns_dict_get_bindata(rr, "/rdata/ptrdname", &dname))
+            continue; /* Not a PTR */
+
+        else if ((r = getdns_convert_dns_name_to_fqdn(dname, &dname_str)))
+            fprintf(stderr, "Could not convert PTR dname to string");
+
+        else {
+            printf("The dname is %s\n", dname_str);
+            free(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);
+    if (r) {
+        assert( r != GETDNS_RETURN_GOOD );
+        fprintf(stderr, ": %d\n", r);
+    }
+    getdns_dict_destroy(response); 
 }
 
 int main()
 {
-    /* Create the DNS context for this call */
-    getdns_context *this_context = NULL;
-    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);
-        return(GETDNS_RETURN_GENERIC_ERROR);
-    }
-    /* Create an event base and put it in the context using the unknown function name */
-    struct event_base *this_event_base;
-    this_event_base = event_base_new();
-    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 */
-    getdns_dict * this_addr_to_look_up = getdns_dict_create();
-    // TODO: check the return value above
-    getdns_bindata this_type = { 4, (void *)"IPv4" };
-    getdns_return_t this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_type", &this_type);
-    UNUSED_PARAM(this_ret);
-    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;
+    getdns_return_t      r;  /* Holder for all function returns */
+    getdns_context      *context      = NULL;
+    struct event_base   *event_base   = NULL;
+    getdns_bindata       address_type = { 4, (void *)"IPv4" };
+    getdns_bindata       address_data = { 4, (void *)"\x08\x08\x08\x08" };
+    getdns_dict         *address      = NULL;
+    getdns_dict         *extensions   = NULL;
+    /* Could add things here to help identify this call */
+    char                *userarg      = NULL;
+    getdns_transaction_t transaction_id;
 
-    /* Make the call */
-    getdns_return_t dns_request_return = getdns_hostname(this_context, this_addr_to_look_up,
-        NULL, this_userarg, &this_transaction_id, this_callbackfn);
-    if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
-    {
-        char *ip_address_str = getdns_display_ip_address(&this_ipv4_addr);
+    if ((r = getdns_context_create(&context, 1)))
+        fprintf(stderr, "Trying to create the context failed");
+
+    else if (!(event_base = event_base_new()))
+        fprintf(stderr, "Trying to create the event base failed.\n");
+
+    else if ((r = getdns_extension_set_libevent_base(context, event_base)))
+        fprintf(stderr, "Setting the event base failed");
+
+    else if (!(address = getdns_dict_create()))
+        fprintf(stderr, "Could not create address dict.\n");
+
+    else if ((r = getdns_dict_set_bindata(address, "address_type", &address_type)))
+        fprintf(stderr, "Could not set address_type in address dict.\n");
+
+    else if ((r = getdns_dict_set_bindata(address, "address_data", &address_data)))
+        fprintf(stderr, "Could not set address_data in address dict.\n");
+
+    else if ((r = getdns_hostname( context, address, extensions
+                                 , userarg, &transaction_id, callback)))
+        fprintf(stderr, "Error scheduling asynchronous request");
+
+    else if (event_base_dispatch(event_base) < 0)
+        fprintf(stderr, "Error dispatching events\n");
 
-        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
-    {
-        /* Call the event loop */
-        int dispatch_return = event_base_dispatch(this_event_base);
-        UNUSED_PARAM(dispatch_return);
-        // TODO: check the return value above
-    }
     /* Clean up */
-    getdns_dict_destroy(this_addr_to_look_up);
-    event_base_free(this_event_base);
-    getdns_context_destroy(this_context);
+    if (event_base)
+        event_base_free(event_base);
+
+    if (context)
+        getdns_context_destroy(context);
+
     /* Assuming we get here, leave gracefully */
     exit(EXIT_SUCCESS);
 }
@@ -2209,9 +2144,7 @@ getdns_context_set_dns_transport_list(
 

The transports array contains an ordered list of transports that will be used for DNS lookups. If only one transport value is specified it will be the only transport used. Should it not be available basic resolution will fail. -Fallback transport options are specified by including multiple values in the list. Currently the TLS and STARTTLS options -perform Strict TLS which requires a hostname to be -specified so that authentication can be performed. This hostname can be specified in the tls_auth_name parameter for an upstream. +Fallback transport options are specified by including multiple values in the list. The values are GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP, @@ -2493,7 +2426,7 @@ getdns_pretty_print_dict() for debugging.

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