Hacker News new | past | comments | ask | show | jobs | submit login

How about a few lines of C?

  // clang -lcares -I/opt/local/include -L/opt/local/lib -o domains domains.c
  #include <ares.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/socket.h>
  #include <arpa/inet.h>
  #include <netinet/in.h>
  #include <netdb.h>
  #include <stdarg.h>
  #include <string.h>
  #include <ctype.h>
  #include <unistd.h>
  #include <sys/queue.h>
  #include <fcntl.h>
  
  static void callback(void *arg, int status, int timeouts, struct hostent *host)
  {
  
      if(!host || status != ARES_SUCCESS){
          printf("Failed to lookup %s\n", ares_strerror(status));
          return;
      }
  
      char ip[INET6_ADDRSTRLEN];
      int i = 0;
  
      for (i = 0; host->h_addr_list[i]; ++i) {
          inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
          printf("%s: %s\n", host->h_name, ip);
      }
  }
  
  static void wait_ares(ares_channel channel)
  {
      for(;;){
          struct timeval *tvp, tv;
          fd_set read_fds, write_fds;
          int nfds;
  
          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);
          select(nfds, &read_fds, &write_fds, NULL, tvp);
          ares_process(channel, &read_fds, &write_fds);
      }
  }
  
  struct Request {
      ares_channel channel;
      char* domain;
      SLIST_ENTRY(Request) next;
  };
  
  int main(const int argc, const char* argv[]) {
      SLIST_HEAD(Requests, Request) requests;
      SLIST_INIT(&requests);
      struct Request* last = NULL;
  
      int status;
      struct ares_options options;
      int optmask = 0;
      const char* path;
  
      optmask |= ARES_OPT_TIMEOUTMS;
      options.timeout = 1000;
  
      status = ares_library_init(ARES_LIB_INIT_ALL);
      if (status != ARES_SUCCESS){
          printf("ares_library_init: %s\n", ares_strerror(status));
          return 1;
      }
  
      for (int i = 1; (path = argv[i]) != NULL || i == 0; i++) {
          
          int fd = open(path, O_RDONLY);
          FILE* fp = fdopen(fd, "r");
          char* buffer = NULL;
          size_t bufferSize = 0;
          int lineLength = 0;
          
          while ((lineLength = getline(&buffer, &bufferSize, fp)) > 0) {
  
              struct Request* request = malloc(sizeof(struct Request));
  
              status = ares_init_options(&request->channel, &options, optmask);
              if(status != ARES_SUCCESS) {
                  printf("ares_init_options: %s\n", ares_strerror(status));
                  continue;
              }
              
              buffer[lineLength - 1] = '\0';
  
              request->domain = buffer;
              buffer = NULL;
              if (NULL == last) {
                  SLIST_INSERT_HEAD(&requests, request, next);
              } else {
                  SLIST_INSERT_AFTER(last, request, next);
              }
              last = request;
  
              ares_gethostbyname(request->channel, request->domain, AF_INET, callback, NULL);
          }
      }
  
      while (!SLIST_EMPTY(&requests)) {
          struct Request* request = SLIST_FIRST(&requests);
          wait_ares(request->channel);
          ares_destroy(request->channel);
          free(request->domain);
          SLIST_REMOVE_HEAD(&requests, next);
          free(request);
      }
  
      ares_library_cleanup();
      return 0;
  }



Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: