/*
 * kbiffimap.cpp -- Implementation of class KBiffImap.
 * Author: Kurt Granroth (granroth@kde.org)
 * Version: $Id: kbiffimap.cpp,v 1.1 1999/07/22 18:16:56 tibirna Exp $
 */

#include "kbiffimap.h"

#include <qregexp.h>

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

KBiffSocket::KBiffSocket()
	: _messages( -1 )
{
}

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

void KBiffSocket::close()
{
	::close(_socket);
}

bool KBiffSocket::connect(const char* host, unsigned int port)
{
	sockaddr_in  sin;
	hostent     *hent; 
	int addr;

	// get the socket
	_socket = ::socket( AF_INET, SOCK_STREAM, IPPROTO_IP );

	// start setting up the socket info
	memset( ( char * )&sin, 0, sizeof( sin ) );
	sin.sin_family = AF_INET;
	sin.sin_port   = htons( port );

	// get the address
	if( ( addr = inet_addr( host ) ) == -1 )
	{
		// get the address by host name
		if( ( hent = gethostbyname( host ) ) == 0 )
			return false;

		memcpy( (void *)&sin.sin_addr, *(hent->h_addr_list), hent->h_length );
	}
	else
		// get the address by IP
		memcpy( (void *)&sin.sin_addr, (void *)&addr, sizeof( addr ) );

	// the socket is correctly setup.  now connect
	if( ::connect( _socket, (sockaddr *)&sin, sizeof( sockaddr_in ) ) == -1 )
		return false;

	// we're connected!  see if the connection is good
	QString line( readLine() );
	if( ( line.find("OK") == -1 ) && ( line.find("PREAUTH") == -1) )
		return false;

	// everything is swell
	return true;
}

int KBiffSocket::writeLine(const QString& line)
{
	int bytes;

	if( (bytes = ::write( _socket, line, line.length() - 1 ) ) <= 0 )
		close();

	return bytes;
}

QString KBiffSocket::readLine()
{
	QString response;
	char buffer;

	while( ( ::read( _socket, &buffer, 1 ) > 0 ) && ( buffer != '\n' ) )
		response += buffer;

	return response;
}

bool KBiffImap::command( const QString& line, unsigned int seq )
{
	int len, match;

	if( writeLine( line ) <= 0 )
		return false;

	QString ok, response;
	ok.sprintf( "%d OK", seq );
	while( response = readLine() )
	{
		// if the response is either good or bad, then return
		if( response.find( ok ) > -1 )
			return true;
		if( response.find( "BAD" ) > -1 )
			return false;
		if( response.find( "NO " ) > -1 )
			return false;

		// check for new mail
		QRegExp recent_re( "RECENT [0-9]*" );
		if( ( match = recent_re.match( response, 0, &len ) ) > -1 )
			_messages = response.mid( match + 7, len - 7 ).toInt();
	}

	return false;
}

QString KBiffImap::mungeUser(const QString& old_user)
{
	if( old_user.contains(' ') > 0 )
	{
		QString new_user( old_user );

		if( new_user.left( 1 ) != "\"" )
			new_user.prepend( "\"" );
		if( new_user.right( 1 ) != "\"" )
			new_user.append( "\"" );

		return new_user;
	}
	else
		return old_user;
}
