#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

void parse_inaddr(struct addrinfo **head, const char *hostname, const char *port) {
  struct addrinfo hint;

  memset(&hint, 0, sizeof(struct addrinfo));
  hint.ai_family = AF_INET;
  hint.ai_socktype = SOCK_STREAM;
  hint.ai_protocol = 0;
  hint.ai_flags = AI_NUMERICSERV;

  int r = getaddrinfo(hostname, port, &hint, head);
  if (r != 0) {
    if (r == EAI_SYSTEM) {
      perror("getaddrinfo");
    } else {
      fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
    }
    exit(1);
  }
}

int main(int argc, char **argv)
{
  if (argc < 3) {
    fprintf(stderr, "Need IPv4 address and port.\n");
    return 1;
  }

  struct addrinfo *head;
  parse_inaddr(&head, argv[1], argv[2]);

  int s = socket(head->ai_family, head->ai_socktype, head->ai_protocol);
  if (-1 == connect(s, head->ai_addr, head->ai_addrlen)) {
    perror("connect");
    return 1;
  }
  freeaddrinfo(head);

  // TODO: A select() or epoll_wait() loop to copy stdin to socket, copy socket
  // to stdout.
  // Do not exit until both stdin and socket are EOF.
  // Do not monitor an FD for reading if it reached EOF in the past, lest you
  // would cause busy-polling. (Why?)

  close(s);
  return 0;
}
