setup_once.h: refactor inclusion of <unistd.h> and <sys/socket.h>
[platform/upstream/c-ares.git] / ahost.c
1 /* Copyright 1998 by the Massachusetts Institute of Technology.
2  *
3  *
4  * Permission to use, copy, modify, and distribute this
5  * software and its documentation for any purpose and without
6  * fee is hereby granted, provided that the above copyright
7  * notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting
9  * documentation, and that the name of M.I.T. not be used in
10  * advertising or publicity pertaining to distribution of the
11  * software without specific, written prior permission.
12  * M.I.T. makes no representations about the suitability of
13  * this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  */
16
17 #include "ares_setup.h"
18
19 #if !defined(WIN32) || defined(WATT32)
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22 #include <netdb.h>
23 #endif
24
25 #ifdef HAVE_STRINGS_H
26 #include <strings.h>
27 #endif
28
29 #include "ares.h"
30 #include "ares_dns.h"
31 #include "inet_ntop.h"
32 #include "inet_net_pton.h"
33 #include "ares_getopt.h"
34 #include "ares_ipv6.h"
35 #include "ares_nowarn.h"
36
37 #ifndef HAVE_STRDUP
38 #  include "ares_strdup.h"
39 #  define strdup(ptr) ares_strdup(ptr)
40 #endif
41
42 #ifndef HAVE_STRCASECMP
43 #  include "ares_strcasecmp.h"
44 #  define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
45 #endif
46
47 #ifndef HAVE_STRNCASECMP
48 #  include "ares_strcasecmp.h"
49 #  define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
50 #endif
51
52 static void callback(void *arg, int status, int timeouts, struct hostent *host);
53 static void usage(void);
54
55 int main(int argc, char **argv)
56 {
57   ares_channel channel;
58   int status, nfds, c, addr_family = AF_INET;
59   fd_set read_fds, write_fds;
60   struct timeval *tvp, tv;
61   struct in_addr addr4;
62   struct ares_in6_addr addr6;
63
64 #ifdef USE_WINSOCK
65   WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
66   WSADATA wsaData;
67   WSAStartup(wVersionRequested, &wsaData);
68 #endif
69
70   status = ares_library_init(ARES_LIB_INIT_ALL);
71   if (status != ARES_SUCCESS)
72     {
73       fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
74       return 1;
75     }
76
77   while ((c = ares_getopt(argc,argv,"dt:h")) != -1)
78     {
79       switch (c)
80         {
81         case 'd':
82 #ifdef WATT32
83           dbug_init();
84 #endif
85           break;
86         case 't':
87           if (!strcasecmp(optarg,"a"))
88             addr_family = AF_INET;
89           else if (!strcasecmp(optarg,"aaaa"))
90             addr_family = AF_INET6;
91           else
92             usage();
93           break;
94         case 'h':
95         default:
96           usage();
97           break;
98         }
99     }
100
101   argc -= optind;
102   argv += optind;
103   if (argc < 1)
104     usage();
105
106   status = ares_init(&channel);
107   if (status != ARES_SUCCESS)
108     {
109       fprintf(stderr, "ares_init: %s\n", ares_strerror(status));
110       return 1;
111     }
112
113   /* Initiate the queries, one per command-line argument. */
114   for ( ; *argv; argv++)
115     {
116       if (ares_inet_pton(AF_INET, *argv, &addr4) == 1)
117         {
118           ares_gethostbyaddr(channel, &addr4, sizeof(addr4), AF_INET, callback,
119                              *argv);
120         }
121       else if (ares_inet_pton(AF_INET6, *argv, &addr6) == 1)
122         {
123           ares_gethostbyaddr(channel, &addr6, sizeof(addr6), AF_INET6, callback,
124                              *argv);
125         }
126       else
127         {
128           ares_gethostbyname(channel, *argv, addr_family, callback, *argv);
129         }
130     }
131
132   /* Wait for all queries to complete. */
133   for (;;)
134     {
135       FD_ZERO(&read_fds);
136       FD_ZERO(&write_fds);
137       nfds = ares_fds(channel, &read_fds, &write_fds);
138       if (nfds == 0)
139         break;
140       tvp = ares_timeout(channel, NULL, &tv);
141       select(nfds, &read_fds, &write_fds, NULL, tvp);
142       ares_process(channel, &read_fds, &write_fds);
143     }
144
145   ares_destroy(channel);
146
147   ares_library_cleanup();
148
149 #ifdef USE_WINSOCK
150   WSACleanup();
151 #endif
152
153   return 0;
154 }
155
156 static void callback(void *arg, int status, int timeouts, struct hostent *host)
157 {
158   char **p;
159
160   (void)timeouts;
161
162   if (status != ARES_SUCCESS)
163     {
164       fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status));
165       return;
166     }
167
168   for (p = host->h_addr_list; *p; p++)
169     {
170       char addr_buf[46] = "??";
171
172       ares_inet_ntop(host->h_addrtype, *p, addr_buf, sizeof(addr_buf));
173       printf("%-32s\t%s", host->h_name, addr_buf);
174 #if 0
175       if (host->h_aliases[0])
176         {
177            int i;
178
179            printf (", Aliases: ");
180            for (i = 0; host->h_aliases[i]; i++)
181                printf("%s ", host->h_aliases[i]);
182         }
183 #endif
184       puts("");
185     }
186 }
187
188 static void usage(void)
189 {
190   fprintf(stderr, "usage: ahost [-t {a|aaaa}] {host|addr} ...\n");
191   exit(1);
192 }