1 /* Async DNS lookup. Shows passing complex data through pool. */
2 #include "ccan/antithread/antithread.h"
3 #include "ccan/string/string.h"
4 #include "ccan/talloc/talloc.h"
5 #include "md5_finder.h"
7 #include <sys/select.h>
12 struct lookup_answer {
16 int herrno; /* If !ok */
20 /* Including NULL terminator. */
21 static inline unsigned count_entries(char **entries)
25 for (i = 0; entries[i]; i++);
29 /* Copy as one nice tallocated object. Since ans is in the pool, it
30 * all gets put in the pool. */
31 static void copy_answer(struct lookup_answer *ans, const struct hostent *host)
35 ans->hent.h_name = talloc_strdup(ans, host->h_name);
36 ans->hent.h_aliases = talloc_array(ans, char *,
37 count_entries(host->h_aliases));
38 for (i = 0; host->h_aliases[i]; i++)
39 ans->hent.h_aliases[i] = talloc_strdup(ans->hent.h_aliases,
41 ans->hent.h_aliases[i] = NULL;
42 ans->hent.h_addrtype = host->h_addrtype;
43 ans->hent.h_length = host->h_length;
44 ans->hent.h_addr_list = talloc_array(ans, char *,
45 count_entries(host->h_addr_list));
46 for (i = 0; host->h_addr_list[i]; i++)
47 ans->hent.h_addr_list[i] = talloc_memdup(ans->hent.h_addr_list,
52 static void *lookup_dns(struct at_pool *atp, char *name)
54 struct lookup_answer *ans;
57 host = gethostbyname(name);
59 ans = talloc(at_pool_ctx(atp), struct lookup_answer);
62 ans->herrno = h_errno;
65 copy_answer(ans, host);
71 static void report_answer(const char *name, const struct lookup_answer *ans)
76 printf("%s: %s\n", name, hstrerror(ans->herrno));
81 for (i = 0; ans->hent.h_aliases[i]; i++)
82 printf("%c%s", i == 0 ? '[' : ' ', ans->hent.h_aliases[i]);
85 printf("%#x", ans->hent.h_addrtype);
86 for (i = 0; ans->hent.h_addr_list[i]; i++) {
89 for (j = 0; j < ans->hent.h_length; j++)
90 printf("%02x", ans->hent.h_addr_list[i][j]);
95 int main(int argc, char *argv[])
102 errx(1, "Usage: dns_lookup [--sync] name...");
104 /* Give it plenty of room. */
105 atp = at_pool(argc * 1024*1024);
107 err(1, "Can't create pool");
109 /* Free pool on exit. */
110 talloc_steal(talloc_autofree_context(), atp);
112 if (streq(argv[1], "--sync")) {
113 for (i = 2; i < argc; i++) {
114 struct lookup_answer *ans = lookup_dns(atp, argv[i]);
115 report_answer(argv[i], ans);
121 at = talloc_array(atp, struct athread *, argc);
123 for (i = 1; i < argc; i++) {
124 at[i] = at_run(atp, lookup_dns, argv[i]);
126 err(1, "Can't spawn child");
129 for (i = 1; i < argc; i++) {
130 struct lookup_answer *ans = at_read(at[i]);
132 warn("Child died on '%s'", argv[i]);
134 report_answer(argv[i], ans);