%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/cares/src/tools/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/cares/src/tools/ahost.c |
/* MIT License * * Copyright (c) 1998 Massachusetts Institute of Technology * Copyright (c) The c-ares project and its contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * SPDX-License-Identifier: MIT */ #include "ares_setup.h" #if !defined(WIN32) || defined(WATT32) # include <netinet/in.h> # include <arpa/inet.h> # include <netdb.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #include "ares.h" #include "ares_dns.h" #include "ares_getopt.h" #include "ares_ipv6.h" #ifndef HAVE_STRDUP # include "ares_str.h" # define strdup(ptr) ares_strdup(ptr) #endif #ifndef HAVE_STRCASECMP # include "ares_strcasecmp.h" # define strcasecmp(p1, p2) ares_strcasecmp(p1, p2) #endif #ifndef HAVE_STRNCASECMP # include "ares_strcasecmp.h" # define strncasecmp(p1, p2, n) ares_strncasecmp(p1, p2, n) #endif static void callback(void *arg, int status, int timeouts, struct hostent *host); static void ai_callback(void *arg, int status, int timeouts, struct ares_addrinfo *result); static void usage(void); static void print_help_info_ahost(void); int main(int argc, char **argv) { struct ares_options options; int optmask = 0; ares_channel_t *channel; int status; int nfds; int c; int addr_family = AF_UNSPEC; fd_set read_fds; fd_set write_fds; struct timeval *tvp; struct timeval tv; struct in_addr addr4; struct ares_in6_addr addr6; ares_getopt_state_t state; char *servers = NULL; #ifdef USE_WINSOCK WORD wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); WSADATA wsaData; WSAStartup(wVersionRequested, &wsaData); #endif memset(&options, 0, sizeof(options)); status = ares_library_init(ARES_LIB_INIT_ALL); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status)); return 1; } ares_getopt_init(&state, argc, (const char **)argv); while ((c = ares_getopt(&state, "dt:h?D:s:")) != -1) { switch (c) { case 'd': #ifdef WATT32 dbug_init(); #endif break; case 'D': optmask |= ARES_OPT_DOMAINS; options.ndomains++; options.domains = (char **)realloc( options.domains, (size_t)options.ndomains * sizeof(char *)); options.domains[options.ndomains - 1] = strdup(state.optarg); break; case 't': if (!strcasecmp(state.optarg, "a")) { addr_family = AF_INET; } else if (!strcasecmp(state.optarg, "aaaa")) { addr_family = AF_INET6; } else if (!strcasecmp(state.optarg, "u")) { addr_family = AF_UNSPEC; } else { usage(); } break; case 's': if (state.optarg == NULL) { fprintf(stderr, "%s", "missing servers"); usage(); break; } if (servers) { free(servers); } servers = strdup(state.optarg); break; case 'h': case '?': print_help_info_ahost(); break; default: usage(); break; } } argc -= state.optind; argv += state.optind; if (argc < 1) { usage(); } status = ares_init_options(&channel, &options, optmask); if (status != ARES_SUCCESS) { free(servers); fprintf(stderr, "ares_init: %s\n", ares_strerror(status)); return 1; } if (servers) { status = ares_set_servers_csv(channel, servers); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_set_serveres_csv: %s\n", ares_strerror(status)); free(servers); usage(); return 1; } free(servers); } /* Initiate the queries, one per command-line argument. */ for (; *argv; argv++) { if (ares_inet_pton(AF_INET, *argv, &addr4) == 1) { ares_gethostbyaddr(channel, &addr4, sizeof(addr4), AF_INET, callback, *argv); } else if (ares_inet_pton(AF_INET6, *argv, &addr6) == 1) { ares_gethostbyaddr(channel, &addr6, sizeof(addr6), AF_INET6, callback, *argv); } else { struct ares_addrinfo_hints hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = addr_family; ares_getaddrinfo(channel, *argv, NULL, &hints, ai_callback, *argv); } } /* Wait for all queries to complete. */ for (;;) { int res; FD_ZERO(&read_fds); FD_ZERO(&write_fds); nfds = ares_fds(channel, &read_fds, &write_fds); if (nfds == 0) { break; } tvp = ares_timeout(channel, NULL, &tv); if (tvp == NULL) { break; } res = select(nfds, &read_fds, &write_fds, NULL, tvp); if (-1 == res) { break; } ares_process(channel, &read_fds, &write_fds); } ares_destroy(channel); ares_library_cleanup(); #ifdef USE_WINSOCK WSACleanup(); #endif return 0; } static void callback(void *arg, int status, int timeouts, struct hostent *host) { char **p; (void)timeouts; if (status != ARES_SUCCESS) { fprintf(stderr, "%s: %s\n", (char *)arg, ares_strerror(status)); return; } for (p = host->h_addr_list; *p; p++) { char addr_buf[46] = "??"; ares_inet_ntop(host->h_addrtype, *p, addr_buf, sizeof(addr_buf)); printf("%-32s\t%s", host->h_name, addr_buf); puts(""); } } static void ai_callback(void *arg, int status, int timeouts, struct ares_addrinfo *result) { struct ares_addrinfo_node *node = NULL; (void)timeouts; if (status != ARES_SUCCESS) { fprintf(stderr, "%s: %s\n", (char *)arg, ares_strerror(status)); return; } for (node = result->nodes; node != NULL; node = node->ai_next) { char addr_buf[64] = ""; const void *ptr = NULL; if (node->ai_family == AF_INET) { const struct sockaddr_in *in_addr = (const struct sockaddr_in *)((void *)node->ai_addr); ptr = &in_addr->sin_addr; } else if (node->ai_family == AF_INET6) { const struct sockaddr_in6 *in_addr = (const struct sockaddr_in6 *)((void *)node->ai_addr); ptr = &in_addr->sin6_addr; } else { continue; } ares_inet_ntop(node->ai_family, ptr, addr_buf, sizeof(addr_buf)); printf("%-32s\t%s\n", result->name, addr_buf); } ares_freeaddrinfo(result); } static void usage(void) { fprintf(stderr, "usage: ahost [-h] [-d] [[-D {domain}] ...] [-s {server}] " "[-t {a|aaaa|u}] {host|addr} ...\n"); exit(1); } /* Information from the man page. Formatting taken from man -h */ static void print_help_info_ahost(void) { printf("ahost, version %s\n\n", ARES_VERSION_STR); printf( "usage: ahost [-h] [-d] [-D domain] [-s server] [-t a|aaaa|u] host|addr " "...\n\n" " -h : Display this help and exit.\n" " -d : Print some extra debugging output.\n\n" " -D domain : Specify the domain to search instead of using the default " "values\n" " -s server : Connect to the specified DNS server, instead of the\n" " system's default one(s). Servers are tried in round-robin,\n" " if the previous one failed.\n" " -t type : If type is \"a\", print the A record.\n" " If type is \"aaaa\", print the AAAA record.\n" " If type is \"u\" (default), print both A and AAAA records.\n" "\n"); exit(0); }