/***************************************************************
* PrSocket.cpp
*
* This is an implementation of socket methods.
*
****************************************************************/

/*
* modification history
*----------------------
*
* 02/13/98: K.C. Chang: created.
*/

#include "PrSocket.h"

#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include <netdb.h>  // gethostbyname();

#include <sys/ioctl.h> // ioctl();

PrSocket::PrSocket( int sockfd )
{
   socketFD_ = -1;
   socketFD_ = sockfd;
   flag_ = PR_SOCKET_ERROR;
   flag_ = Init();
}

PrSocket::PrSocket( char *hostname, int portNum )
{
   socketFD_ = -1;
   flag_ = PR_SOCKET_ERROR;
   flag_ = Connect(hostname,portNum);
}

PrSocket::~PrSocket()
{
   close();
}

void PrSocket::close()
{
   if (socketFD_>=0)
   {
      ::close(socketFD_);
   }
   socketFD_ = -1;
}

int PrSocket::Init()
{
   // Non-blocking socket
   int on=1;
#ifdef PR_QNX
   if (ioctl((short)socketFD_,FIONBIO,&on)<0)
#else // PR_QNX
   if (ioctl(socketFD_,FIONBIO,&on)<0)
#endif // PR_QNX
   {
      perror("PrSocket::Init():ioctl() F_SETFL, FNDELAY");
      return PR_SOCKET_ERROR;
   }
   return PR_SOCKET_OK;
}

int PrSocket::Connect( char *hostname, int portNum )
{
   struct sockaddr_in serv_addr;

   struct hostent *hp = gethostbyname(hostname);
   if (hp == NULL)
   {
      perror("PrSocket: Connect() error");
      return PR_SOCKET_ERROR;
   }

   memset((char *)&serv_addr,'\0',sizeof(serv_addr));
#ifdef PR_QNX
   serv_addr.sin_family = (unsigned char)hp->h_addrtype;
#else // PR_QNX
   serv_addr.sin_family = hp->h_addrtype;
#endif // PR_QNX
   memcpy((char *)&serv_addr.sin_addr, hp->h_addr, hp->h_length);
   serv_addr.sin_port = htons((unsigned short)portNum);

   if ((socketFD_ = socket(AF_INET,SOCK_STREAM,0))<0)
   {
      perror("PrSocket: can't open stream socket");
      return PR_SOCKET_ERROR;
   }
   if (connect(socketFD_,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
   {
      perror("PrSocket: can't connect to server");
      return PR_SOCKET_ERROR;
   }

   // Non-blocking socket
   int on=1;
#ifdef PR_QNX
   if (ioctl((short)socketFD_,FIONBIO,&on)<0)
#else // PR_QNX
   if (ioctl(socketFD_,FIONBIO,&on)<0)
#endif // PR_QNX
   {
      perror("PrSocket::Connect():ioctl() F_SETFL, FNDELAY");
      return PR_SOCKET_ERROR;
   }
   return PR_SOCKET_OK;
}
