/* easysock.c (emx+gcc) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "easysock.h"

int es_dot_count (const char *src)
{
  int n;

  n = 0;
  while (*src != 0)
    if (*src++ == '.')
      ++n;
  return n;
}


void es_parse_host (struct sockaddr_in *dst, const char *src)
{
  unsigned long ip;

  memset (dst, 0, sizeof (*dst));

  ip = inet_addr (src);
  if (ip != INADDR_NONE && es_dot_count (src) == 3)
    {
      dst->sin_family = AF_INET;
      dst->sin_addr.s_addr = ip;
    }
  else
    {
      struct hostent *host;

      host = gethostbyname (src);
      if (host == NULL)
        {
          herror ("gethostbyname()");
          exit (1);
        }
      dst->sin_family = host->h_addrtype;
      memcpy (&dst->sin_addr, host->h_addr, host->h_length);
    }
}


void es_parse_port (int *dst, const char *src)
{
  if (isdigit ((unsigned char)src[0]))
    *dst = htons (atoi (src));
  else
    {
      struct servent *serv;

      serv = getservbyname (src, NULL);
      if (serv == NULL)
        {
          fputs ("getservbyname(): Service not found\n", stderr);
          exit (1);
        }
      *dst = serv->s_port;
    }
}


void es_socket (int *ps)
{
  int s;

  s = socket (AF_INET, SOCK_STREAM, 0);
  if (s < 0)
    {
      perror ("socket()");
      exit (1);
    }
  *ps = s;
}


void es_reuse (int s)
{
  int i;

  i = 0;
  if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)) != 0)
    {
      perror ("setsockopt()");
      exit (1);
    }
}



void es_bind_any (int s)
{
  struct sockaddr_in in;

  memset (&in, 0, sizeof (in));
  in.sin_family = AF_INET;
  in.sin_addr.s_addr = INADDR_ANY;
  in.sin_port = 0;
  if (bind (s, (struct sockaddr *)&in, sizeof (in)) < 0)
    {
      perror ("bind()");
      exit (1);
    }
}


void es_connect (int s, const struct sockaddr_in *in)
{
  if (connect (s, (struct sockaddr *)in, sizeof (*in)) < 0)
    {
      perror ("connect()");
      exit (1);
    }
}


void es_getsockname (struct sockaddr_in *in, int s)
{
  int i;

  i = sizeof (*in);
  if (getsockname (s, (struct sockaddr *)in, &i) != 0)
    {
      perror ("getsockname()");
      exit (1);
    }
}
