/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/



#include	"memory_debug.h"
#include	"blacklist.h"
#include	"utils.h"
#include	"client.h"
#include	"machine/err.h"

typedef struct new_connection_cmd {
	BL_CMD		c;
	int *		cerr;
	char *		hostname;
	int		ip;
	short		port;
	int 		(*func)();
	void *		work;

	STREAM *	ret;
} NEW_CONNECTION_CMD;


int
_new_connect_retry(BLACKLIST * bl)
{
int ret;
STREAM * _ret;
int ip;
char * hostname;
int *ipp;
int cerr;
	if ( ((char*)bl->name)[0] == 0 ) {
		hostname = 0;
		ipp = (int*)bl->name;
		ip = ipp[1];
	}
	else {
		hostname = bl->name;
		ip = 0;
	}
	cerr = 0;
	_ret = new_connection(
			&cerr,
			hostname,
			ip,
			bl->port,
			0,0);
	if ( _ret )
		s_close(_ret);
	if ( cerr == ESYS_CTIMEOUT )
		ret = BLS_ERROR;
	else	ret = BLS_OK;
	return ret;
}

int
_new_connect_proc(BLACKLIST * bl,NEW_CONNECTION_CMD * c)
{
int ret;
	bl->port = c->port;
	if ( bl->state[BLT_RESOLVE].state == BLS_ERROR )
		return BLS_ERROR;
	*c->cerr = 0;
	c->ret = new_connection(
			c->cerr,
			c->hostname,
			c->ip,
			c->port,
			c->func,
			c->work);
	if ( *c->cerr == ESYS_CTIMEOUT )
		ret = BLS_ERROR;
	else	ret = BLS_OK;
	bl->polling_interval = 0;
	return ret;
}

STREAM *
bl_new_connection(
	int * cerr,
	char * hostname,
	int ip,
	short port,
	int (*func)(),
	void * work)
{
NEW_CONNECTION_CMD	c;
int * ipp;

	c.cerr = cerr;
	c.hostname = hostname;
	c.ip = ip;
	c.port = port;
	c.func = func;
	c.work = work;
	c.ret = 0;
	if ( hostname ) {
		c.c.name = copy_str(hostname);
		c.c.name_len = strlen(c.c.name)+1;
	}
	else {
		ipp = d_alloc(sizeof(int)*2);
		ipp[0] = 0;
		ipp[1] = ip;
		c.c.name = (char*)ipp;
		c.c.name_len = 2*sizeof(int);
	}
	c.c.retry = _new_connect_retry;
	c.c.proc = _new_connect_proc;
	c.c.type = BLT_CONNECT;

	bl_do(&c);

	d_f_ree(c.c.name);
	return c.ret;
}


