/*
    KFinger - ver 0.8.2

    KDE project - kdenetwork
    
    finger.C : Internet Finger protocol
    
    (c) Andrea Rizzi <rizzi@kde.org>
	27 May 1999
    
    License: GPL

*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <kapp.h>
#include "finger.h"
#include <unistd.h>
#include <errno.h>

FingerProtocol::FingerProtocol(/*const char * host,int port,*/char *buff) 
{
stopFlag=true ;
s=buff; 
}


FingerProtocol::~FingerProtocol() 
{
    close( sock); 
}


bool FingerProtocol::connection(  const char * host,int port) 
{
  sock=::socket(PF_INET,SOCK_STREAM,0);
  if (sock < 0) return false;        
  
  struct sockaddr_in server;
  struct hostent *hostinfo;
  server.sin_family = AF_INET;
  server.sin_port = htons(port);
  hostinfo = gethostbyname(host);
  if ( !hostinfo )
    {
	  debug("Unknown host: %s ", strerror(errno));
	  ::close( sock );
	  sock = -1;
	  return false;	    
    }
  server.sin_addr = *(struct in_addr*) hostinfo->h_addr;      
  fcntl(sock,F_SETFL,(fcntl(sock,F_GETFL)|O_NDELAY));

  errno = 0;
  if (::connect(sock, (struct sockaddr*)(&server), sizeof(server))==-1)
      if(errno != EINPROGRESS && errno != EWOULDBLOCK){
          ::close( sock );
          sock = -1;
          return false;   
      }

    sockNotif = new QSocketNotifier(sock,QSocketNotifier::Read,this);
    QObject::connect(sockNotif, SIGNAL(activated(int )),this,SLOT(readBuff(int ))); 

    sockNotif1 = new QSocketNotifier(sock,QSocketNotifier::Write,this);
    QObject::connect(sockNotif1, SIGNAL(activated(int )),this,SLOT(writeBuff(int ))); 
     sockNotif->setEnabled(TRUE);
  return true;       
}



void FingerProtocol::readBuff( int     ) 
{
 // warning("read buff" );
  sockNotif->setEnabled(FALSE);
  char *b;
  b=s;
  char c,n;
  int mn = recv( sock,   s    , 1, MSG_PEEK );
  if ( mn <= 0 ) {
	stopFlag=false;  
        close( sock); 
        emit finish();
	}
  else
	{
	 int bu=0;
	do  {
	    
	     n=read(sock,&c,1);
	     bu++;
	     if (c!='\r') 
	         *b++=c;
	    } while (n==1 && bu<1000);       
	 *b=0;    
	// warning("%i",bu);
         update();
         sockNotif->setEnabled(TRUE);
         }
 
}

void FingerProtocol::writeBuff(int  ) 
{
    int val;
    ksize_t len=sizeof(val); 
    getsockopt(sock,SOL_SOCKET,SO_ERROR,(char *) &val,&len );                   
//    warning("error %d ",val);
sockNotif1->setEnabled(FALSE);

    if(val==0)  
	write(sock,st,strlen(st));
   else if(val==111)
    {
      connectionRefused();
//     warning("connection refused");
    }
}

void FingerProtocol::writeString(QString s)
{
  st=s;
  sockNotif1->setEnabled(TRUE);

}

#include "finger.moc"

