From f632ef89394d67d96be4efa62be5dea95bc3f2e8 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 6 Oct 2015 12:29:15 +0200 Subject: [PATCH] The tree example with json pointers --- spec/example/Makefile.in | 10 ++- spec/example/simple-concise.c | 2 +- spec/example/simple-json-pointer.c | 2 +- spec/example/tree-json-pointer.c | 119 +++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 spec/example/tree-json-pointer.c diff --git a/spec/example/Makefile.in b/spec/example/Makefile.in index 1b45fc97..6313c4b2 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 +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 -PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse synchronous-json-pointer simple-json-pointer +PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse synchronous-json-pointer simple-json-pointer tree-json-pointer .SUFFIXES: .c .o .a .lo .h @@ -80,6 +80,9 @@ synchronous-json-pointer: 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 + $(EXTENSION_LIBEVENT_LIB): @echo "***" @echo "*** Three examples from the specification need libevent." @@ -176,3 +179,6 @@ synchronous-concise.lo synchronous-concise.o: $(srcdir)/synchronous-concise.c $( ../../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/simple-concise.c b/spec/example/simple-concise.c index 54bcb449..4448e542 100644 --- a/spec/example/simple-concise.c +++ b/spec/example/simple-concise.c @@ -91,7 +91,7 @@ int main() else if ((r = getdns_extension_set_libevent_base(context, event_base))) fprintf(stderr, "Setting the event base failed"); - else if ((r = getdns_address( context, "www.example.com", extensions + else if ((r = getdns_address( context, query_name, extensions , userarg, &transaction_id, callback))) fprintf(stderr, "Error scheduling asynchronous request"); diff --git a/spec/example/simple-json-pointer.c b/spec/example/simple-json-pointer.c index ae3a611f..ae802ea7 100644 --- a/spec/example/simple-json-pointer.c +++ b/spec/example/simple-json-pointer.c @@ -85,7 +85,7 @@ int main() else if ((r = getdns_extension_set_libevent_base(context, event_base))) fprintf(stderr, "Setting the event base failed"); - else if ((r = getdns_address( context, "www.example.com", extensions + else if ((r = getdns_address( context, query_name, extensions , userarg, &transaction_id, callback))) fprintf(stderr, "Error scheduling asynchronous request"); diff --git a/spec/example/tree-json-pointer.c b/spec/example/tree-json-pointer.c new file mode 100644 index 00000000..77493d10 --- /dev/null +++ b/spec/example/tree-json-pointer.c @@ -0,0 +1,119 @@ +#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); +}