1 #include <assert.h>
2 #include <inttypes.h>
3 #include <stdio.h>
4 #include <getdns_libevent.h>
5 
6 /* Set up the callback function, which will also do the processing of the results */
callback(getdns_context * context,getdns_callback_type_t callback_type,getdns_dict * response,void * userarg,getdns_transaction_t transaction_id)7 void callback(getdns_context        *context,
8               getdns_callback_type_t callback_type,
9               getdns_dict           *response,
10               void                  *userarg,
11               getdns_transaction_t   transaction_id)
12 {
13 	getdns_return_t r;  /* Holder for all function returns */
14 	getdns_list    *replies_tree;
15 	size_t          n_replies, i;
16 
17 	(void) context; (void) userarg; /* unused parameters */
18 
19 	switch(callback_type) {
20 	case GETDNS_CALLBACK_CANCEL:
21 		printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
22 		return;
23 	case GETDNS_CALLBACK_TIMEOUT:
24 		printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
25 		return;
26 	case GETDNS_CALLBACK_ERROR:
27 		printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
28 		return;
29 	default: break;
30 	}
31 	assert( callback_type == GETDNS_CALLBACK_COMPLETE );
32 
33 	if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree)))
34 		fprintf(stderr, "Could not get \"replies_tree\" from response");
35 
36 	else if ((r = getdns_list_get_length(replies_tree, &n_replies)))
37 		fprintf(stderr, "Could not get replies_tree\'s length");
38 
39 	else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) {
40 		getdns_dict *reply;
41 		getdns_list *answer;
42 		size_t       n_answers, j;
43 
44 		if ((r = getdns_list_get_dict(replies_tree, i, &reply)))
45 			fprintf(stderr, "Could not get address %zu from just_address_answers", i);
46 
47 		else if ((r = getdns_dict_get_list(reply, "answer", &answer)))
48 			fprintf(stderr, "Could not get \"address_data\" from address");
49 
50 		else if ((r = getdns_list_get_length(answer, &n_answers)))
51 			fprintf(stderr, "Could not get answer section\'s length");
52 
53 		else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) {
54 			getdns_dict    *rr;
55 			getdns_bindata *address = NULL;
56 
57 			if ((r = getdns_list_get_dict(answer, j, &rr)))
58 				fprintf(stderr, "Could net get rr %zu from answer section", j);
59 
60 			else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD)
61 				printf("The IPv4 address is ");
62 
63 			else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD)
64 				printf("The IPv6 address is ");
65 
66 			if (address) {
67 				char *address_str;
68 				if (!(address_str = getdns_display_ip_address(address))) {
69 					fprintf(stderr, "Could not convert second address to string");
70 					r = GETDNS_RETURN_MEMORY_ERROR;
71 					break;
72 				}
73 				printf("%s\n", address_str);
74 				free(address_str);
75 			}
76 		}
77 	}
78 	if (r) {
79 		assert( r != GETDNS_RETURN_GOOD );
80 		fprintf(stderr, ": %d\n", r);
81 	}
82 	getdns_dict_destroy(response);
83 }
84 
main()85 int main()
86 {
87 	getdns_return_t      r;  /* Holder for all function returns */
88 	getdns_context      *context    = NULL;
89 	struct event_base   *event_base = NULL;
90 	getdns_dict         *extensions = NULL;
91 	char                *query_name = "www.example.com";
92 	/* Could add things here to help identify this call */
93 	char                *userarg    = NULL;
94 	getdns_transaction_t transaction_id;
95 
96 	if ((r = getdns_context_create(&context, 1)))
97 		fprintf(stderr, "Trying to create the context failed");
98 
99 	else if (!(event_base = event_base_new()))
100 		fprintf(stderr, "Trying to create the event base failed.\n");
101 
102 	else if ((r = getdns_extension_set_libevent_base(context, event_base)))
103 		fprintf(stderr, "Setting the event base failed");
104 
105 	else if ((r = getdns_address( context, query_name, extensions
106 	                            , userarg, &transaction_id, callback)))
107 		fprintf(stderr, "Error scheduling asynchronous request");
108 
109 	else if (event_base_dispatch(event_base) < 0)
110 		fprintf(stderr, "Error dispatching events\n");
111 
112 	/* Clean up */
113 	if (event_base)
114 		event_base_free(event_base);
115 
116 	if (context)
117 		getdns_context_destroy(context);
118 
119 	/* Assuming we get here, leave gracefully */
120 	exit(EXIT_SUCCESS);
121 }
122