contrib/newshound/socket.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. alrmbrk
  2. atoport
  3. atoaddr
  4. make_connection
  5. sock_write
  6. sock_gets
  7. sock_puts

/* This code was developed by Vic Metcalfe (vic@brutus.tlug.org)       */
/* The source has no copyright and was taken from the unix-socket-faq. */

#include "conf.h"

void alrmbrk()
/* [<][>][^][v][top][bottom][index][help] */
  {
   done = 1;
  }

int atoport(char *service, char *proto) 
/* [<][>][^][v][top][bottom][index][help] */
  {
   int port;
   long int lport;
   struct servent *serv;
   char *errpos;

  /* First try to read it from /etc/services */
   serv = getservbyname(service, proto);
   if (serv != NULL)
     port = serv->s_port;
   else 
     { /* Not in services, maybe a number? */
      lport = strtol(service,&errpos,0);
      if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) )
        return -1; /* Invalid port address */
      port = htons(lport);
     }
   return port;
  }

struct in_addr *atoaddr(char *address) 
/* [<][>][^][v][top][bottom][index][help] */
  {
   struct hostent *host;
   static struct in_addr saddr;

   /* First try it as aaa.bbb.ccc.ddd. */
   saddr.s_addr = inet_addr(address);
   if (saddr.s_addr != -1) 
     {
      return &saddr;
     }
   host = gethostbyname(address);
   if (host != NULL) 
     {
      return (struct in_addr *) *host->h_addr_list;
     }
   return NULL;
  }

int make_connection(char *service, int type, char *netaddress) 
/* [<][>][^][v][top][bottom][index][help] */
  {
   /* First convert service from a string, to a number... */
   int port = -1;
   struct in_addr *addr;
   int sock, connected;
   struct sockaddr_in address;

   if (type == SOCK_STREAM)
     port = atoport(service, "tcp");
   if (type == SOCK_DGRAM)
     port = atoport(service, "udp");
   if (port == -1) 
     {
      fprintf(stderr,"make_connection:  Invalid socket type.\n");
      return -1;
     }
   addr = atoaddr(netaddress);
   if (addr == NULL) 
     {
      fprintf(stderr,"make_connection:  Invalid network address.\n");
      return -1;
     }

   memset((char *) &address, 0, sizeof(address));
   address.sin_family = AF_INET;
   address.sin_port = (port);
   address.sin_addr.s_addr = addr->s_addr;

   sock = socket(AF_INET, type, 0);

   if (debug>=1) 
     printf("Connecting to %s on port %d.\n",inet_ntoa(*addr),htons(port));

   if (type == SOCK_STREAM) 
     {
      connected = connect(sock, (struct sockaddr *) &address,
      sizeof(address));
      if (connected < 0) 
        {
         perror("connect");
         return -1;
        }
      return sock;
     }
     /* Otherwise, must be for udp, so bind to address. */
     if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0) 
       {
        perror("bind");
        return -1;
       }
   return sock;
  }

int sock_write(int sockfd, const char *buf, size_t count) 
/* [<][>][^][v][top][bottom][index][help] */
  {
   size_t bytes_sent = 0;
   int this_write;

   while (bytes_sent < count) 
     {
      do
        this_write = write(sockfd, buf, count - bytes_sent);
      while ( (this_write < 0) && (errno == EINTR) );
      if (this_write <= 0)
        return this_write;
      bytes_sent += this_write;
      buf += this_write;
     }
   return count;
  }

int sock_gets(int sockfd, char *str, size_t count) {
/* [<][>][^][v][top][bottom][index][help] */
  int bytes_read;
  int total_count = 0;
  char *current_position;
  char last_read = 0;
  done = 0;

  current_position = str;
  signal(SIGALRM, alrmbrk);

  while ((last_read != 10) && (done != 1)){
    alarm(60);
    bytes_read = read(sockfd, &last_read, 1);
    if (bytes_read <= 0) {
      /* The other side may have closed unexpectedly */
      return -1; /* Is this effective on other platforms than linux? */
    }
    if ( (total_count < count) && (last_read != 10) && (last_read !=13) ) {
      current_position[0] = last_read;
      current_position++;
      total_count++;
    }
  }
  if (count > 0)
    current_position[0] = 0;
return total_count;
}

int sock_puts(int sockfd, const char *str) {
/* [<][>][^][v][top][bottom][index][help] */
  return sock_write(sockfd, str, strlen(str));
}

/* [<][>][^][v][top][bottom][index][help] */