diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-06-21 18:34:33 +0200 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-06-21 18:34:33 +0200 | 
| commit | b72caac09b5944ee9954eb18262fe45228665570 (patch) | |
| tree | b44353f8ab3d23702f49e129d53b787952fe6546 /protocols/proxy.c | |
| parent | 3af70b06b2f0fb0fb41a041f6d86e3711b9eea3f (diff) | |
| parent | df417ca6657bc824e1dbd4a6026284656a42ce40 (diff) | |
Merging libevent branch: Events can now be handles by both glib and libevent.
Diffstat (limited to 'protocols/proxy.c')
| -rw-r--r-- | protocols/proxy.c | 180 | 
1 files changed, 68 insertions, 112 deletions
| diff --git a/protocols/proxy.c b/protocols/proxy.c index 1ca35dfe..b8aa304d 100644 --- a/protocols/proxy.c +++ b/protocols/proxy.c @@ -20,10 +20,6 @@   *   */ -/* this is a little piece of code to handle proxy connection */ -/* it is intended to : 1st handle http proxy, using the CONNECT command - , 2nd provide an easy way to add socks support */ -  #define BITLBEE_CORE  #include <stdio.h>  #include <stdlib.h> @@ -45,10 +41,6 @@  #include "nogaim.h"  #include "proxy.h" -#define GAIM_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR) -#define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) -#define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL) -  char proxyhost[128] = "";  int proxyport = 0;  int proxytype = PROXY_NONE; @@ -56,7 +48,7 @@ char proxyuser[128] = "";  char proxypass[128] = "";  struct PHB { -	GaimInputFunction func, proxy_func; +	b_event_handler func, proxy_func;  	gpointer data, proxy_data;  	char *host;  	int port; @@ -64,12 +56,6 @@ struct PHB {  	gint inpa;  }; -typedef struct _GaimIOClosure { -	GaimInputFunction function; -	guint result; -	gpointer data; -} GaimIOClosure; -  static struct sockaddr_in *gaim_gethostbyname(const char *host, int port) @@ -91,27 +77,7 @@ static struct sockaddr_in *gaim_gethostbyname(const char *host, int port)  	return &sin;  } -static void gaim_io_destroy(gpointer data) -{ -	g_free(data); -} - -static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) -{ -	GaimIOClosure *closure = data; -	GaimInputCondition gaim_cond = 0; - -	if (condition & GAIM_READ_COND) -		gaim_cond |= GAIM_INPUT_READ; -	if (condition & GAIM_WRITE_COND) -		gaim_cond |= GAIM_INPUT_WRITE; - -	closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); - -	return TRUE; -} - -static void gaim_io_connected(gpointer data, gint source, GaimInputCondition cond) +static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)  {  	struct PHB *phb = data;  	unsigned int len; @@ -121,24 +87,26 @@ static void gaim_io_connected(gpointer data, gint source, GaimInputCondition con  #ifndef _WIN32  	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {  		closesocket(source); -		gaim_input_remove(phb->inpa); +		b_event_remove(phb->inpa);  		if( phb->proxy_func )  			phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ);  		else {  			phb->func(phb->data, -1, GAIM_INPUT_READ);  			g_free(phb);  		} -		return; +		return FALSE;  	}  #endif  	sock_make_blocking(source); -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	if( phb->proxy_func )  		phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ);  	else {  		phb->func(phb->data, source, GAIM_INPUT_READ);  		g_free(phb);  	} +	 +	return FALSE;  }  static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb) @@ -157,10 +125,12 @@ static int proxy_connect_none(const char *host, unsigned short port, struct PHB  	}  	sock_make_nonblocking(fd); - +	 +	event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd); +	  	if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) {  		if (sockerr_again()) { -			phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb); +			phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb);  			phb->fd = fd;  		} else {  			closesocket(fd); @@ -178,14 +148,14 @@ static int proxy_connect_none(const char *host, unsigned short port, struct PHB  #define HTTP_GOODSTRING "HTTP/1.0 200 Connection established"  #define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" -static void http_canread(gpointer data, gint source, GaimInputCondition cond) +static gboolean http_canread(gpointer data, gint source, b_input_condition cond)  {  	int nlc = 0;  	int pos = 0;  	struct PHB *phb = data;  	char inputline[8192]; -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {  		if (inputline[pos - 1] == '\n') @@ -200,31 +170,32 @@ static void http_canread(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, source, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	close(source);  	phb->func(phb->data, -1, GAIM_INPUT_READ);  	g_free(phb->host);  	g_free(phb); -	return; +	 +	return FALSE;  } -static void http_canwrite(gpointer data, gint source, GaimInputCondition cond) +static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond)  {  	char cmd[384];  	struct PHB *phb = data;  	unsigned int len;  	int error = ETIMEDOUT;  	if (phb->inpa > 0) -		gaim_input_remove(phb->inpa); +		b_event_remove(phb->inpa);  	len = sizeof(error);  	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	sock_make_blocking(source); @@ -235,7 +206,7 @@ static void http_canwrite(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	if (proxyuser && *proxyuser) { @@ -250,7 +221,7 @@ static void http_canwrite(gpointer data, gint source, GaimInputCondition cond)  			phb->func(phb->data, -1, GAIM_INPUT_READ);  			g_free(phb->host);  			g_free(phb); -			return; +			return FALSE;  		}  	} @@ -260,10 +231,12 @@ static void http_canwrite(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	} -	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb); +	phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb); +	 +	return FALSE;  }  static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb) @@ -279,28 +252,30 @@ static int proxy_connect_http(const char *host, unsigned short port, struct PHB  /* Connecting to SOCKS4 proxies */ -static void s4_canread(gpointer data, gint source, GaimInputCondition cond) +static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)  {  	unsigned char packet[12];  	struct PHB *phb = data; -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	memset(packet, 0, sizeof(packet));  	if (read(source, packet, 9) >= 4 && packet[1] == 90) {  		phb->func(phb->data, source, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	close(source);  	phb->func(phb->data, -1, GAIM_INPUT_READ);  	g_free(phb->host);  	g_free(phb); +	 +	return FALSE;  } -static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond) +static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)  {  	unsigned char packet[12];  	struct hostent *hp; @@ -308,14 +283,14 @@ static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond)  	unsigned int len;  	int error = ETIMEDOUT;  	if (phb->inpa > 0) -		gaim_input_remove(phb->inpa); +		b_event_remove(phb->inpa);  	len = sizeof(error);  	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	sock_make_blocking(source); @@ -325,7 +300,7 @@ static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	packet[0] = 4; @@ -342,10 +317,12 @@ static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	} -	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb); +	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb); +	 +	return FALSE;  }  static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb) @@ -361,32 +338,33 @@ static int proxy_connect_socks4(const char *host, unsigned short port, struct PH  /* Connecting to SOCKS5 proxies */ -static void s5_canread_again(gpointer data, gint source, GaimInputCondition cond) +static gboolean s5_canread_again(gpointer data, gint source, b_input_condition cond)  {  	unsigned char buf[512];  	struct PHB *phb = data; -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	if (read(source, buf, 10) < 10) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	phb->func(phb->data, source, GAIM_INPUT_READ);  	g_free(phb->host);  	g_free(phb); -	return; +	 +	return FALSE;  }  static void s5_sendconnect(gpointer data, gint source) @@ -394,7 +372,7 @@ static void s5_sendconnect(gpointer data, gint source)  	unsigned char buf[512];  	struct PHB *phb = data;  	int hlen = strlen(phb->host); - +	  	buf[0] = 0x05;  	buf[1] = 0x01;		/* CONNECT */  	buf[2] = 0x00;		/* reserved */ @@ -412,22 +390,22 @@ static void s5_sendconnect(gpointer data, gint source)  		return;  	} -	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); +	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb);  } -static void s5_readauth(gpointer data, gint source, GaimInputCondition cond) +static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)  {  	unsigned char buf[512];  	struct PHB *phb = data; -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	if (read(source, buf, 2) < 2) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	if ((buf[0] != 0x01) || (buf[1] != 0x00)) { @@ -435,25 +413,27 @@ static void s5_readauth(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	s5_sendconnect(phb, source); +	 +	return FALSE;  } -static void s5_canread(gpointer data, gint source, GaimInputCondition cond) +static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)  {  	unsigned char buf[512];  	struct PHB *phb = data; -	gaim_input_remove(phb->inpa); +	b_event_remove(phb->inpa);  	if (read(source, buf, 2) < 2) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	if ((buf[0] != 0x05) || (buf[1] == 0xff)) { @@ -461,7 +441,7 @@ static void s5_canread(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	if (buf[1] == 0x02) { @@ -476,16 +456,18 @@ static void s5_canread(gpointer data, gint source, GaimInputCondition cond)  			phb->func(phb->data, -1, GAIM_INPUT_READ);  			g_free(phb->host);  			g_free(phb); -			return; +			return FALSE;  		} -		phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); +		phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb);  	} else {  		s5_sendconnect(phb, source);  	} +	 +	return FALSE;  } -static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond) +static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)  {  	unsigned char buf[512];  	int i; @@ -493,14 +475,14 @@ static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond)  	unsigned int len;  	int error = ETIMEDOUT;  	if (phb->inpa > 0) -		gaim_input_remove(phb->inpa); +		b_event_remove(phb->inpa);  	len = sizeof(error);  	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {  		close(source);  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	}  	sock_make_blocking(source); @@ -522,10 +504,12 @@ static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond)  		phb->func(phb->data, -1, GAIM_INPUT_READ);  		g_free(phb->host);  		g_free(phb); -		return; +		return FALSE;  	} -	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb); +	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb); +	 +	return FALSE;  }  static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb) @@ -541,35 +525,7 @@ static int proxy_connect_socks5(const char *host, unsigned short port, struct PH  /* Export functions */ -gint gaim_input_add(gint source, GaimInputCondition condition, GaimInputFunction function, gpointer data) -{ -	GaimIOClosure *closure = g_new0(GaimIOClosure, 1); -	GIOChannel *channel; -	GIOCondition cond = 0; -	 -	closure->function = function; -	closure->data = data; -	 -	if (condition & GAIM_INPUT_READ) -		cond |= GAIM_READ_COND; -	if (condition & GAIM_INPUT_WRITE) -		cond |= GAIM_WRITE_COND; -	 -	channel = g_io_channel_unix_new(source); -	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, -					      gaim_io_invoke, closure, gaim_io_destroy); -	 -	g_io_channel_unref(channel); -	return closure->result; -} - -void gaim_input_remove(gint tag) -{ -	if (tag > 0) -		g_source_remove(tag); -} - -int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data) +int proxy_connect(const char *host, int port, b_event_handler func, gpointer data)  {  	struct PHB *phb; | 
