Logo Search packages:      
Sourcecode: dbtcp version File versions  Download package

socket.c

/*****************************************************************************
Funzioni per l'accesso alla rete TCP/IP
Da integrare con le funzioni per usare i socket locali.
*****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>

#include <define.h>
#include <dbug/dbug.h>
#include <socket.h>
#include <my_error.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>


#ifdef _WIN32
int gethostname (char *name, int size);
#endif


/***************************************************************** Funzioni */

/* Wrapper per le routine read e write sulla rete */
ssize_t dbtcp_net_read ( int fd, char *buf, size_t count )
{
  ssize_t ret=1,my_count=0;

  DBUG_ENTER ( "dbtcp_net_read" );
  while ( ( ret > 0 ) && ( my_count < count ) )
    {
      ret=read(fd,&buf[my_count],count-my_count);
      if ( ret == 0 )
      {
         /* EOF */
         errno = EBADF;
         DBUG_RETURN ( -1 );
         return ( -1 );
      }
      my_count += ret;
      DBUG_PRINT( "dbtcp_net_read", ( "RET=%d", ret ) );
    }

  DBUG_RETURN ( my_count );
  return ( my_count );

} 

ssize_t dbtcp_net_write ( int fd, char *buf, size_t count )
{
  /*
  ssize_t ret;
  struct tms buffer;
  unsigned long delay;*/

  DBUG_ENTER ( "dbtcp_net_write" );

  /*
  delay=(unsigned long) times (&buffer);
  ret=write(fd,buf,count);
  delay = ((unsigned long) times (&buffer))- delay;

  printf ( "DELAY %ld\n", delay ); 
  DBUG_PRINT ( "dbtcp_net_write", ( "DELAY %ld\n", delay ) );

  DBUG_RETURN ( ret );
  return ( ret );*/

  DBUG_RETURN ( write(fd,buf,count) );
  return ( write(fd,buf,count) );
}


int socket_set_options (int s)
{
  int idmy=1;

  DBUG_ENTER ( "socket_set_options" );

  if ( (setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (char *) &idmy, sizeof (int)) < 0) ||
       ( setsockopt ( s, SOL_SOCKET, SO_OOBINLINE, (char *)&idmy, sizeof(int)) < 0 ) ||
       ( setsockopt ( s, IPPROTO_TCP, TCP_NODELAY, (char *)&idmy, sizeof(int)) < 0 ) )
    {
      DBUG_RETURN ( ERR );
      return ( ERR );
    }

  DBUG_RETURN ( OK );
  return ( OK );

}

/******************************************************************************
int socket_status_rx ( int sock )
Controlla se su un socket ci sono a disposizione dei dati da leggere.
Valori ritornati:
                  OK  - Dati presenti
                  ERR - Errore nel socket
******************************************************************************/
int 
socket_status_rx (int sock)
{
  fd_set rdfs;
  struct timeval tv;
  int retval;

  tv.tv_sec = 1;
  tv.tv_usec = 0;
  FD_ZERO (&rdfs);
  FD_SET (sock, &rdfs);

  retval = select (sock + 1, &rdfs, NULL, NULL, &tv);

  if (retval == 1)
    return (OK);
  else
    return (ERR);
}

/******************************************************************************
int socket_status_tx ( int sock )
Controlla se e' possibile scrivere sul socket 's'.
Valori ritornati:
                        OK  - Dati presenti
                        ERR - Dati non presenti
******************************************************************************/

int
socket_status_tx (int sock)
{
  fd_set rdfs;
  struct timeval tv;
  int retval;

  tv.tv_sec = 1;
  tv.tv_usec = 0;
  FD_ZERO (&rdfs);
  FD_SET (sock, &rdfs);

  retval = select (sock + 1, NULL, &rdfs, NULL, &tv);
  DBUG_PRINT ( "SocketStatusTX",("retval %d", retval ));

  if (retval == 1)
    return (OK);
  else
    return (ERR);

}

/*****************************************************************************
int socket_open_client ( int *sock, char *host, int port char *err_buf, int err_len)
Crea un nuovo socket e lo assegna a 'sock', lo connette alla macchina 'host'
sulla porta 'port' con un socket bloccante.
err_buf e' un puntatore a un buffer per il messaggio di errore e err_len e' la grandezza del buffer.
Valori ritornati:
                  OK  - Socket creato e connessione effettuata
                  ERR - Impossibile connettersi
                              err_buff contiene il messaggio di errore
*****************************************************************************/
int socket_open_client ( int *sock, char *host, int port, char *err_buf, int err_len )
{
  struct sockaddr_in remote_ip_addr;
  struct hostent *hp2;
  int s;

  DBUG_ENTER ("socket_open_client");
  DBUG_PRINT ("socket_open_client",("sock %d - host '%s' - port %d", *sock, host, port ) );

  hp2 = gethostbyname (host);
  if ( hp2 == NULL )
    {
      switch ( h_errno )
      {
      case HOST_NOT_FOUND:
        dbftp_error ( err_buf, err_len, "Host %s not found\n", host );
        break;

      case NO_ADDRESS:
        dbftp_error ( err_buf, err_len, "No IP associated to %s\n", host );
        break;

      case NO_RECOVERY:
      case TRY_AGAIN:
      default:
        dbftp_error( err_buf, err_len, "Error gethostbyname %d\n", h_errno );
        break;
      }

      DBUG_RETURN ( ERR );
      return ( ERR );

    }
  bzero ((char *) &remote_ip_addr, sizeof (remote_ip_addr));

  memcpy ((char *) &remote_ip_addr.sin_addr, hp2->h_addr, hp2->h_length);
  remote_ip_addr.sin_family = AF_INET;
  remote_ip_addr.sin_port = htons ((unsigned short int) port);

  /* -------------------------------------------------------- Apre un socket */
  s = socket ( AF_INET, SOCK_STREAM, IPPROTO_IP);
  if ((int) s == -1)
    {
      dbftp_error( err_buf, err_len, "Unable to create socket (%d)\n", errno );
      return (ERR);
    }

  /* ---------------------------------------- Setta il socket come bloccante */
  if ( fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) & ~O_NONBLOCK) == -1 )
    {
      dbftp_error (err_buf, err_len, "Error in fcntl (%d-'%s')\n", errno, strerror(errno) );
    }

  /* ---------------------------------------------------- Opzioni del socket */
  if (socket_set_options (s) == ERR)
    {
      dbftp_error (err_buf, err_len, "Error in socket_set_options (%d-'%s')\n", errno, strerror(errno) );
    }

  /* ----------------------------------------------------- Connect al remoto */
  if (connect (s, (struct sockaddr *) &remote_ip_addr, sizeof (remote_ip_addr)) == -1)
    {
      dbftp_error ( err_buf, err_len, "Unable to connect to %s:%d %s (%d)\n", host, port, strerror(errno), errno );
      
      DBUG_RETURN ( ERR );
      return ( ERR );
    }

  *sock = s;
  
  DBUG_RETURN ( OK );
  return (OK);

}

/******************************************************************************
int socket_open_server ( int *sock )
Apre un socket in ricezione sulla porta definita da PORT ( 3000 ) e lo prepara
alla ricezione di connessioni.
(bind,listen)
Valori ritornati:
                  OK  - Socket aperto e pronto ad accettare connessioni
                  ERR - Impossibile aprire il socket
******************************************************************************/
int 
socket_open_server (int *sock, unsigned short port, char *err_buf, int err_len)
{
  struct in_addr host_ip_number;
  struct sockaddr_in host_ip_addr;
  struct hostent *hp;
  char hostname[100];
  int s, tmp;

  DBUG_ENTER ("socket_open_server" );

  gethostname (hostname, sizeof (hostname));

  hp = gethostbyname (hostname);

  bzero ((char *) &host_ip_addr, sizeof (host_ip_addr));
  memcpy ((char *) &host_ip_addr.sin_addr, hp->h_addr, hp->h_length);
  host_ip_addr.sin_family = hp->h_addrtype;
  host_ip_number = host_ip_addr.sin_addr;
  host_ip_addr.sin_port = htons ( port );
  host_ip_addr.sin_addr.s_addr = INADDR_ANY;

  /* open a socket s */
  s = socket (host_ip_addr.sin_family, SOCK_STREAM, 0);
  if ((int) s == -1)
    {
      dbftp_error ( err_buf, err_len, "Unable to create socket (%d-'%s')", errno, strerror(errno) );

      DBUG_RETURN ( ERR );
      return ( ERR );
    }

  tmp = 1;
  if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp)) < 0)
    {
      dbftp_error ( err_buf, err_len, "Error in setsockopt (%d-'%s')", errno, strerror(errno) );

      DBUG_RETURN ( ERR );
      return ( ERR );
    }

  if ( socket_set_options (s) == ERR)
    {
      dbftp_error ( err_buf, err_len, "Errore in (%d-'%s')", errno, strerror(errno) );
    }


  /* bind the socket to the server */
  if (bind (s, (struct sockaddr *) &host_ip_addr, sizeof (host_ip_addr)) == -1)
    {
      if (errno == EADDRINUSE)
      {
        dbftp_error ( err_buf, err_len, "Socket already bound" );

        DBUG_RETURN ( ERR );
        return ( ERR );
      }
      else
      {
        dbftp_error ( err_buf, err_len, "Error binding socket (%d-'%s')", errno, strerror(errno) );
        
        DBUG_RETURN ( ERR );
        return ( ERR );
      }
    }

  if (listen (s, 5) == -1)
    {
      dbftp_error ( err_buf, err_len, "Error in listen (%d-'%s')", errno, strerror(errno) );
      DBUG_RETURN ( ERR );
      return ( ERR );
    }

  *sock = s;
  return (OK);

}

int socket_close ( int s )
{
  DBUG_ENTER ("socket_close");

  shutdown ( s, 2);
  close ( s );
  
  DBUG_RETURN ( OK );
  return ( OK );
}










Generated by  Doxygen 1.6.0   Back to index