/***************************************************************************
                          net.cpp  -  description
                             -------------------
    begin                : Thu Nov 20 2003
    copyright            : (C) 2003 by Wei Zheng
    email                : v_zheng@yahoo.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "net.h"

net::net(){
  fd = 0;
  debug_switch = 0;
}

net::~net(){
}

/** No descriptions */
int net::make_connect(char * address, int port){

  struct sockaddr_in myaddress;
  struct hostent *host;
  int v;

  host=gethostbyname(address);
  if(host==NULL)
  {
    return(-1);
  }

  myaddress.sin_family=host->h_addrtype;
  myaddress.sin_addr.s_addr=*((long *)host->h_addr);
  myaddress.sin_port=htons(port);
  v=socket(AF_INET,SOCK_STREAM,0);

  if(v==-1)
  {
    return(-1);
  }
  if(connect(v,(struct sockaddr *)&myaddress,sizeof(myaddress))<0)
  {
    close(v);
    return(-1);
  }
  fd = v;
  return(v);
}

/** No descriptions */
int net::full_read(char *buf, int len){

  int cc;
  int total;
  total = 0;
  while(len > 0)
  {
    cc = read(fd,buf,len);
    if (cc <=0)
    return -1;
    buf += cc;
    total += cc;
    len -= cc;
  }
  return total;
}

/** No descriptions */
int net::full_write(char *buf, int len){

  int cc;
  int total;
  total = 0;

  while (len > 0)
  {
    cc = write(fd, buf, len);
    if (cc < 0)
      return -1;
    buf += cc;
    total += cc;
    len -= cc;
  }
  return total;
}

/** No descriptions */
int net::send_line(char * buf){

  if(debug_switch == 1) debug(">>> %s",buf);
  if(full_write(buf,strlen(buf))!=strlen(buf))
  {
    perror("sendline");
    return(-1);
  }
  return(0);
}

/** No descriptions */
int net::debug(char *fmt,...){
  int n;
  int size = 200;
  char * p;

  va_list ap;
  p=(char *) malloc(size);

  if((p=(char *)malloc(size))==NULL)
  {
    p=NULL;
    return 1;
  }

  while(1)
  {
    va_start(ap, fmt);
    n = vsnprintf(p, size, fmt, ap);
    va_end(ap);
    if (n > -1 && n < size)
      break;
    if (n > -1)
      size = n+1;
    else
      size *= 2;
    if ((p = (char *)realloc(p, size)) == NULL)
    {
       p=NULL;
       return 1;
    }
  }

  if(debug_switch==1)
    fprintf(stderr,"%s",p);
  return 0;
}

/** No descriptions */
int net::get_line(int fd,char *buf,int len){

  int got=0;
  int err;
  while(1)
  {
    if(got==len)
    {
      return(-2);
    }
    err=read(fd,&buf[got],1);
    if(err!=1)
    {
      if(errno!=EINTR)
        return(-1);
      return(-3);
    }
    if(buf[got]=='\n')
    {
      if(got>0 && buf[got-1]=='\r')
        buf[got-1]=0;
      else
        buf[got]=0;
      if(debug_switch==1) debug("<<< %s\n",buf);
      return(0);
    }
    got++;
  }
}

/** No descriptions */
int net::make_close(){
  return close(fd);
}
