#include <pthread.h>
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include "sock_lib.h"

#define MAX_INNER_LOOPS	1

/* common library of socket code */

void
die(char *msg)
{
  printf("FATAL ERROR: %s\n", msg);
  exit(1);
}

void
print_sockaddr_in(addr)
     struct sockaddr_in *addr;
{
  printf("%s:%d", inet_ntoa(addr->sin_addr), (int)ntohs(addr->sin_port));
}

void
print_socket_info(s)
     int s;
{
  struct sockaddr_in addr;
  int size;

  printf("<socket %d <local ", s);
  size = sizeof(addr);
  if (getsockname(s, (struct sockaddr *)&addr, &size) < 0)
    die("getsockname");
  print_sockaddr_in(&addr);
  printf("> <peer ");
  size = sizeof(addr);
  if (getpeername(s, (struct sockaddr *)&addr, &size) < 0)
    die("getpeername");
  print_sockaddr_in(&addr);
  printf(">>");
}

int
socket_to_service(char *host_name, char *svc_name, char *svc_type)
{
  struct hostent *host;
  struct servent *service;
  struct sockaddr_in local_addr, addr;
  int sock;

  host = gethostbyname(host_name);
  if (!host)
    return -1;
  bcopy((char*)host->h_addr, &addr.sin_addr, sizeof(addr.sin_addr));
  service = getservbyname(svc_name, svc_type);
  if (!service)
    return -2;
  addr.sin_family = AF_INET;
  addr.sin_port = service->s_port;
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0) {
    perror("socket");
    return -3;
  }
  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    close(sock);
    perror("connect");
    printf("could not connect to ");
    print_sockaddr_in(&addr);
    printf("\n");
    return -5;
  }
  return sock;
}

main(int argc, char **argv)
{
  int count = 0, test_count;
  char host_name[512];

  setbuf(stdout, NULL);
  test_count = 100;
  if (argc == 1) {
    if (gethostname(host_name, sizeof(host_name)) < 0) {
      perror("gethostname");
      exit(1);
    }
  } else {
    strcpy(host_name, argv[1]);
  }
  printf("will use echo service on host %s\n", host_name);
  while (test_count-- >= 0) {
    FILE *rfp, *wfp;
    int c, s, dup_s, inner_loop;

    printf("*** start %d ***\n", ++count);
    s = socket_to_service(host_name, "echo", "tcp");
    if (s < 0) {
      printf("socket_to_service => %d\n", s);
      exit(1);
    }
    rfp = fdopen(s, "r");
    if (!rfp) {
      printf("fdopen(rfp) died\n");
      exit(1);
    }
    dup_s = dup(s);
    if (dup_s < 0) {
      printf("dup(%d) failed\n", s);
      exit(1);
    } else {
	  printf("dup(%d) returned %d\n", s, dup_s);
	}
    wfp = fdopen(dup_s, "w");
    if (!wfp) {
      printf("fdopen(wfp) died\n");
      exit(1);
    }
    for (inner_loop = 0; inner_loop < MAX_INNER_LOOPS; inner_loop++) {
      fprintf(wfp, "ugga bugga boo!\n");
      fflush(wfp);
      while ((c = getc(rfp)) != EOF) {
	putchar(c);
	if (c == '\n') break;
      }
    }
    fclose(rfp);
    fclose(wfp);
    printf("*** end %d ***\n\n", count);
  }
  exit(0);
}
