diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/Makefile | 2 | ||||
| -rw-r--r-- | protocols/events.h | 66 | ||||
| -rw-r--r-- | protocols/events_glib.c | 137 | ||||
| -rw-r--r-- | protocols/events_libevent.c | 236 | ||||
| -rw-r--r-- | protocols/http_client.c | 45 | ||||
| -rw-r--r-- | protocols/jabber/jabber.c | 28 | ||||
| -rw-r--r-- | protocols/msn/msn.h | 4 | ||||
| -rw-r--r-- | protocols/msn/ns.c | 20 | ||||
| -rw-r--r-- | protocols/msn/sb.c | 20 | ||||
| -rw-r--r-- | protocols/nogaim.c | 267 | ||||
| -rw-r--r-- | protocols/nogaim.h | 17 | ||||
| -rw-r--r-- | protocols/oscar/aim.h | 7 | ||||
| -rw-r--r-- | protocols/oscar/chat.c | 16 | ||||
| -rw-r--r-- | protocols/oscar/im.c | 2 | ||||
| -rw-r--r-- | protocols/oscar/oscar.c | 120 | ||||
| -rw-r--r-- | protocols/proxy.c | 180 | ||||
| -rw-r--r-- | protocols/proxy.h | 15 | ||||
| -rw-r--r-- | protocols/ssl_bogus.c | 2 | ||||
| -rw-r--r-- | protocols/ssl_client.h | 4 | ||||
| -rw-r--r-- | protocols/ssl_gnutls.c | 28 | ||||
| -rw-r--r-- | protocols/ssl_nss.c | 10 | ||||
| -rw-r--r-- | protocols/ssl_openssl.c | 29 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo.c | 28 | 
23 files changed, 891 insertions, 392 deletions
| diff --git a/protocols/Makefile b/protocols/Makefile index 4016e7fd..b74212f4 100644 --- a/protocols/Makefile +++ b/protocols/Makefile @@ -9,7 +9,7 @@  -include ../Makefile.settings  # [SH] Program variables -objects = http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT) +objects = $(EVENT_HANDLER) http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT)  # [SH] The next two lines should contain the directory name (in $(subdirs))  #      and the name of the object file, which should be linked into diff --git a/protocols/events.h b/protocols/events.h new file mode 100644 index 00000000..781fca6a --- /dev/null +++ b/protocols/events.h @@ -0,0 +1,66 @@ +/* + * nogaim + * + * Copyright (C) 2006 Wilmer van der Gaast and others + * + * 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. + * + * 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.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +/* + * Split off the event handling things from proxy.[ch] (and adding timer + * stuff. This to allow BitlBee to use other libs than GLib for event + * handling. + */ + + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +#include <sys/types.h> +#ifndef _WIN32 +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#endif +#include <glib.h> +#include <gmodule.h> + +typedef enum { +	GAIM_INPUT_READ = 1 << 1, +	GAIM_INPUT_WRITE = 1 << 2 +} b_input_condition; +typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond); + +#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) + +// #define event_debug( x... ) printf( x ) +#define event_debug( x... ) + +G_MODULE_EXPORT void b_main_init(); +G_MODULE_EXPORT void b_main_run(); +G_MODULE_EXPORT void b_main_quit(); + +G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data); +G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data); +G_MODULE_EXPORT void b_event_remove(gint id); + +#ifdef EVENTS_LIBEVENT +G_MODULE_EXPORT void closesocket(int fd); +#endif + +#endif /* _EVENTS_H_ */ diff --git a/protocols/events_glib.c b/protocols/events_glib.c new file mode 100644 index 00000000..620720cd --- /dev/null +++ b/protocols/events_glib.c @@ -0,0 +1,137 @@ +  /********************************************************************\ +  * BitlBee -- An IRC to other IM-networks gateway                     * +  *                                                                    * +  * Copyright 2002-2006 Wilmer van der Gaast and others                * +  \********************************************************************/ + +/* + * Event handling (using GLib) + */ + +/* +  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. + +  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.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public License with +  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; +  if not, write to the Free Software Foundation, Inc., 59 Temple Place, +  Suite 330, Boston, MA  02111-1307  USA +*/ + +#define BITLBEE_CORE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#ifndef _WIN32 +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#else +#include "sock.h" +#define ETIMEDOUT WSAETIMEDOUT +#define EINPROGRESS WSAEINPROGRESS +#endif +#include <fcntl.h> +#include <errno.h> +#include "proxy.h" + +typedef struct _GaimIOClosure { +	b_event_handler function; +	guint result; +	gpointer data; +} GaimIOClosure; + +static GMainLoop *loop; + +void b_main_init() +{ +	loop = g_main_new( FALSE ); +} + +void b_main_run() +{ +	g_main_run( loop ); +} + +void b_main_quit() +{ +	g_main_quit( loop ); +} + +static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) +{ +	GaimIOClosure *closure = data; +	b_input_condition gaim_cond = 0; +	gboolean st; + +	if (condition & GAIM_READ_COND) +		gaim_cond |= GAIM_INPUT_READ; +	if (condition & GAIM_WRITE_COND) +		gaim_cond |= GAIM_INPUT_WRITE; +	 +	event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data ); + +	st = closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); +	 +	if( !st ) +		event_debug( "Returned FALSE, cancelling.\n" ); +	 +	return st; +} + +static void gaim_io_destroy(gpointer data) +{ +	event_debug( "gaim_io_destroy( 0x%x )\n", data ); +	g_free(data); +} + +gint b_input_add(gint source, b_input_condition condition, b_event_handler 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); +	 +	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d (0x%x)\n", source, condition, function, data, closure->result, closure ); +	 +	g_io_channel_unref(channel); +	return closure->result; +} + +gint b_timeout_add(gint timeout, b_event_handler func, gpointer data) +{ +	gint st = g_timeout_add(timeout, func, data); +	 +	event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st ); +	 +	return st; +} + +void b_event_remove(gint tag) +{ +	event_debug( "b_event_remove( %d )\n", tag ); +	 +	if (tag > 0) +		g_source_remove(tag); +} diff --git a/protocols/events_libevent.c b/protocols/events_libevent.c new file mode 100644 index 00000000..3328f68b --- /dev/null +++ b/protocols/events_libevent.c @@ -0,0 +1,236 @@ +  /********************************************************************\ +  * BitlBee -- An IRC to other IM-networks gateway                     * +  *                                                                    * +  * Copyright 2002-2006 Wilmer van der Gaast and others                * +  \********************************************************************/ + +/* + * Event handling (using libevent) + */ + +/* +  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. + +  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.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public License with +  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; +  if not, write to the Free Software Foundation, Inc., 59 Temple Place, +  Suite 330, Boston, MA  02111-1307  USA +*/ + +#define BITLBEE_CORE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include "proxy.h" + +#include <sys/time.h> +#include <event.h> + +static guint id_next; +static GHashTable *id_hash; + +/* Since libevent doesn't handle two event handlers for one fd-condition +   very well (which happens sometimes when BitlBee changes event handlers +   for a combination), let's buid some indexes so we can delete them here +   already, just in time. */ +static GHashTable *read_hash; +static GHashTable *write_hash; + +struct b_event_data +{ +	guint id; +	struct event evinfo; +	gint timeout; +	b_event_handler function; +	void *data; +}; + +void b_main_init() +{ +	event_init(); +	 +	id_next = 1; +	id_hash = g_hash_table_new( g_int_hash, g_int_equal ); +	read_hash = g_hash_table_new( g_int_hash, g_int_equal ); +	write_hash = g_hash_table_new( g_int_hash, g_int_equal ); +} + +void b_main_run() +{ +	event_dispatch(); +} + +void b_main_quit() +{ +	struct timeval tv; +	 +	memset( &tv, 0, sizeof( struct timeval ) ); +	event_loopexit( &tv ); +} + +static void b_event_passthrough( int fd, short event, void *data ) +{ +	struct b_event_data *b_ev = data; +	b_input_condition cond = 0; +	int id; +	 +	if( fd >= 0 ) +	{ +		if( event & EV_READ ) +			cond |= GAIM_INPUT_READ; +		if( event & EV_WRITE ) +			cond |= GAIM_INPUT_WRITE; +	} +	 +	event_debug( "b_event_passthrough( %d, %d, 0x%x ) (%d)\n", fd, event, (int) data, b_ev->id ); +	 +	/* Since the called function might cancel this handler already +	   (which free()s b_ev, we have to remember the ID here. */ +	id = b_ev->id; +	 +	if( !b_ev->function( b_ev->data, fd, cond ) ) +	{ +		event_debug( "Handler returned FALSE: " ); +		b_event_remove( id ); +	} +	else if( fd == -1 ) +	{ +		struct timeval tv; +		 +		tv.tv_sec = b_ev->timeout / 1000; +		tv.tv_usec = ( b_ev->timeout % 1000 ) * 1000; +		 +		evtimer_add( &b_ev->evinfo, &tv ); +	} +} + +gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data ) +{ +	struct b_event_data *b_ev; +	 +	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data ); +	 +	if( ( condition & GAIM_INPUT_READ  && ( b_ev = g_hash_table_lookup( read_hash,  &fd ) ) ) || +	    ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) ) +	{ +		/* We'll stick with this libevent entry, but give it a new BitlBee id. */ +		g_hash_table_remove( id_hash, &b_ev->id ); +		 +		event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next ); +		 +		b_ev->id = id_next++; +		b_ev->function = function; +		b_ev->data = data; +	} +	else +	{ +		GIOCondition out_cond; +		 +		event_debug( "(new) = %d\n", id_next ); +		 +		b_ev = g_new0( struct b_event_data, 1 ); +		b_ev->id = id_next++; +		b_ev->function = function; +		b_ev->data = data; +		 +		out_cond = EV_PERSIST; +		if( condition & GAIM_INPUT_READ ) +			out_cond |= EV_READ; +		if( condition & GAIM_INPUT_WRITE ) +			out_cond |= EV_WRITE; +		 +		event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev ); +		event_add( &b_ev->evinfo, NULL ); +		 +		if( out_cond & EV_READ ) +			g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev ); +		if( out_cond & EV_WRITE ) +			g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev ); +	} +	 +	g_hash_table_insert( id_hash, &b_ev->id, b_ev ); +	return b_ev->id; +} + +/* TODO: Persistence for timers! */ +gint b_timeout_add( gint timeout, b_event_handler function, gpointer data ) +{ +	struct b_event_data *b_ev = g_new0( struct b_event_data, 1 ); +	struct timeval tv; +	 +	b_ev->id = id_next++; +	b_ev->timeout = timeout; +	b_ev->function = function; +	b_ev->data = data; +	 +	tv.tv_sec = timeout / 1000; +	tv.tv_usec = ( timeout % 1000 ) * 1000; +	 +	evtimer_set( &b_ev->evinfo, b_event_passthrough, b_ev ); +	evtimer_add( &b_ev->evinfo, &tv ); +	 +	event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id ); +	 +	g_hash_table_insert( id_hash, &b_ev->id, b_ev ); +	 +	return b_ev->id; +} + +void b_event_remove( gint id ) +{ +	struct b_event_data *b_ev = g_hash_table_lookup( id_hash, &id ); +	 +	event_debug( "b_event_remove( %d )\n", id ); +	if( b_ev ) +	{ +		g_hash_table_remove( id_hash, &b_ev->id ); +		if( b_ev->evinfo.ev_fd >= 0 ) +		{ +			if( b_ev->evinfo.ev_events & EV_READ ) +				g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd ); +			if( b_ev->evinfo.ev_events & EV_WRITE ) +				g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd ); +		} +		 +		event_del( &b_ev->evinfo ); +		g_free( b_ev ); +	} +	else +	{ +		event_debug( "Already removed?\n" ); +	} +} + +void closesocket( int fd ) +{ +	struct b_event_data *b_ev; +	 +	/* Since epoll() (the main reason we use libevent) automatically removes sockets from +	   the epoll() list when a socket gets closed and some modules have a habit of +	   closing sockets before removing event handlers, our and libevent's administration +	   get a little bit messed up. So this little function will remove the handlers +	   properly before closing a socket. */ +	 +	if( ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) +	{ +		event_debug( "Warning: fd %d still had a read event handler when shutting down.\n", fd ); +		b_event_remove( b_ev->id ); +	} +	if( ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) +	{ +		event_debug( "Warning: fd %d still had a write event handler when shutting down.\n", fd ); +		b_event_remove( b_ev->id ); +	} +	 +	close( fd ); +} diff --git a/protocols/http_client.c b/protocols/http_client.c index 5db31782..1a431e25 100644 --- a/protocols/http_client.c +++ b/protocols/http_client.c @@ -31,9 +31,9 @@  #include "sock.h" -static void http_connected( gpointer data, int source, GaimInputCondition cond ); -static void http_ssl_connected( gpointer data, void *source, GaimInputCondition cond ); -static void http_incoming_data( gpointer data, int source, GaimInputCondition cond ); +static gboolean http_connected( gpointer data, int source, b_input_condition cond ); +static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond ); +static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond );  void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data ) @@ -103,7 +103,7 @@ void *http_dorequest_url( char *url_string, http_input_function func, gpointer d  /* This one is actually pretty simple... Might get more calls if we can't write      the whole request at once. */ -static void http_connected( gpointer data, int source, GaimInputCondition cond ) +static gboolean http_connected( gpointer data, int source, b_input_condition cond )  {  	struct http_request *req = data;  	int st; @@ -112,7 +112,7 @@ static void http_connected( gpointer data, int source, GaimInputCondition cond )  		goto error;  	if( req->inpa > 0 ) -		gaim_input_remove( req->inpa ); +		b_event_remove( req->inpa );  	sock_make_nonblocking( req->fd ); @@ -147,13 +147,13 @@ static void http_connected( gpointer data, int source, GaimInputCondition cond )  		req->bytes_written += st;  	if( req->bytes_written < req->request_length ) -		req->inpa = gaim_input_add( source, -		                            req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE, -	        	                    http_connected, req ); +		req->inpa = b_input_add( source, +		                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE, +	        	                 http_connected, req );  	else -		req->inpa = gaim_input_add( source, GAIM_INPUT_READ, http_incoming_data, req ); +		req->inpa = b_input_add( source, GAIM_INPUT_READ, http_incoming_data, req ); -	return; +	return FALSE;  error:  	req->func( req ); @@ -161,10 +161,10 @@ error:  	g_free( req->request );  	g_free( req ); -	return; +	return FALSE;  } -static void http_ssl_connected( gpointer data, void *source, GaimInputCondition cond ) +static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond )  {  	struct http_request *req = data; @@ -176,7 +176,7 @@ static void http_ssl_connected( gpointer data, void *source, GaimInputCondition  	return http_connected( data, req->fd, cond );  } -static void http_incoming_data( gpointer data, int source, GaimInputCondition cond ) +static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )  {  	struct http_request *req = data;  	int evil_server = 0; @@ -185,7 +185,7 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co  	int st;  	if( req->inpa > 0 ) -		gaim_input_remove( req->inpa ); +		b_event_remove( req->inpa );  	if( req->ssl )  	{ @@ -232,13 +232,18 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co  	}  	/* There will be more! */ -	req->inpa = gaim_input_add( req->fd, -	                            req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ, -	                            http_incoming_data, req ); +	req->inpa = b_input_add( req->fd, +	                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ, +	                         http_incoming_data, req ); -	return; +	return FALSE;  got_reply: +	/* Maybe if the webserver is overloaded, or when there's bad SSL +	   support... */ +	if( req->bytes_read == 0 ) +		goto cleanup; +	  	/* Zero termination is very convenient. */  	req->reply_headers[req->bytes_read] = 0; @@ -395,7 +400,7 @@ got_reply:  		req->bytes_read = req->bytes_written = req->inpa = 0;  		req->reply_headers = req->reply_body = NULL; -		return; +		return FALSE;  	}  	/* Assume that a closed connection means we're finished, this indeed @@ -413,4 +418,6 @@ cleanup:  	g_free( req->request );  	g_free( req->reply_headers );  	g_free( req ); +	 +	return FALSE;  } diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index ac6481a1..029473fd 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -470,12 +470,14 @@ static void endElement(void *userdata, const char *name)  	gjc->current = x;  } -static void jabber_callback(gpointer data, gint source, GaimInputCondition condition) +static gboolean jabber_callback(gpointer data, gint source, b_input_condition condition)  {  	struct gaim_connection *gc = (struct gaim_connection *)data;  	struct jabber_data *jd = (struct jabber_data *)gc->proto_data;  	gjab_recv(jd->gjc); +	 +	return TRUE;  }  static void charData(void *userdata, const char *s, int slen) @@ -486,7 +488,7 @@ static void charData(void *userdata, const char *s, int slen)  		xmlnode_insert_cdata(gjc->current, s, slen);  } -static void gjab_connected(gpointer data, gint source, GaimInputCondition cond) +static gboolean gjab_connected(gpointer data, gint source, b_input_condition cond)  {  	xmlnode x;  	char *t, *t2; @@ -496,7 +498,7 @@ static void gjab_connected(gpointer data, gint source, GaimInputCondition cond)  	if (!g_slist_find(get_connections(), gc)) {  		closesocket(source); -		return; +		return FALSE;  	}  	jd = gc->proto_data; @@ -507,7 +509,7 @@ static void gjab_connected(gpointer data, gint source, GaimInputCondition cond)  	if (source == -1) {  		STATE_EVT(JCONN_STATE_OFF) -		return; +		return FALSE;  	}  	gjc->state = JCONN_STATE_CONNECTED; @@ -529,10 +531,12 @@ static void gjab_connected(gpointer data, gint source, GaimInputCondition cond)  	STATE_EVT(JCONN_STATE_ON);  	gc = GJ_GC(gjc); -	gc->inpa = gaim_input_add(gjc->fd, GAIM_INPUT_READ, jabber_callback, gc); +	gc->inpa = b_input_add(gjc->fd, GAIM_INPUT_READ, jabber_callback, gc); +	 +	return FALSE;  } -static void gjab_connected_ssl(gpointer data, void *source, GaimInputCondition cond) +static gboolean gjab_connected_ssl(gpointer data, void *source, b_input_condition cond)  {  	struct gaim_connection *gc = data;  	struct jabber_data *jd; @@ -543,15 +547,15 @@ static void gjab_connected_ssl(gpointer data, void *source, GaimInputCondition c  	if (source == NULL) {  		STATE_EVT(JCONN_STATE_OFF) -		return; +		return FALSE;  	}  	if (!g_slist_find(get_connections(), gc)) {  		ssl_disconnect(source); -		return; +		return FALSE;  	} -	gjab_connected(data, gjc->fd, cond); +	return gjab_connected(data, gjc->fd, cond);  }  static void gjab_start(gjconn gjc) @@ -1542,7 +1546,7 @@ static gboolean jabber_destroy_hash(gpointer key, gpointer val, gpointer data) {  	return TRUE;  } -static gboolean jabber_free(gpointer data) +static gboolean jabber_free(gpointer data, gint fd, b_input_condition cond)  {  	struct jabber_data *jd = data; @@ -1587,10 +1591,10 @@ static void jabber_close(struct gaim_connection *gc)  		}  	}  	if (gc->inpa) -		gaim_input_remove(gc->inpa); +		b_event_remove(gc->inpa);  	if(jd) { -		g_timeout_add(50, jabber_free, jd); +		b_timeout_add(50, jabber_free, jd);  		if(jd->gjc != NULL)  			xmlnode_free(jd->gjc->current);  	} diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 0cd174f2..dbbb6aa0 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -145,7 +145,7 @@ GSList *msn_connections;  GSList *msn_switchboards;  /* ns.c */ -void msn_ns_connected( gpointer data, gint source, GaimInputCondition cond ); +gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond );  /* msn_util.c */  int msn_write( struct gaim_connection *gc, char *s, int len ); @@ -172,4 +172,4 @@ struct msn_switchboard *msn_sb_spare( struct gaim_connection *gc );  int msn_sb_sendmessage( struct msn_switchboard *sb, char *text );  void msn_sb_to_chat( struct msn_switchboard *sb );  void msn_sb_destroy( struct msn_switchboard *sb ); -void msn_sb_connected( gpointer data, gint source, GaimInputCondition cond ); +gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 90d525ef..af3793f2 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -29,26 +29,26 @@  #include "passport.h"  #include "md5.h" -static void msn_ns_callback( gpointer data, gint source, GaimInputCondition cond ); +static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond );  static int msn_ns_command( gpointer data, char **cmd, int num_parts );  static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );  static void msn_auth_got_passport_id( struct passport_reply *rep ); -void msn_ns_connected( gpointer data, gint source, GaimInputCondition cond ) +gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )  {  	struct gaim_connection *gc = data;  	struct msn_data *md;  	char s[1024];  	if( !g_slist_find( msn_connections, gc ) ) -		return; +		return FALSE;  	if( source == -1 )  	{  		hide_login_progress( gc, "Could not connect to server" );  		signoff( gc ); -		return; +		return FALSE;  	}  	md = gc->proto_data; @@ -74,12 +74,14 @@ void msn_ns_connected( gpointer data, gint source, GaimInputCondition cond )  	g_snprintf( s, sizeof( s ), "VER %d MSNP8 CVR0\r\n", ++md->trId );  	if( msn_write( gc, s, strlen( s ) ) )  	{ -		gc->inpa = gaim_input_add( md->fd, GAIM_INPUT_READ, msn_ns_callback, gc ); +		gc->inpa = b_input_add( md->fd, GAIM_INPUT_READ, msn_ns_callback, gc );  		set_login_progress( gc, 1, "Connected to server, waiting for reply" );  	} +	 +	return FALSE;  } -void msn_ns_callback( gpointer data, gint source, GaimInputCondition cond ) +static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond )  {  	struct gaim_connection *gc = data;  	struct msn_data *md = gc->proto_data; @@ -88,7 +90,11 @@ void msn_ns_callback( gpointer data, gint source, GaimInputCondition cond )  	{  		hide_login_progress( gc, "Error while reading from server" );  		signoff( gc ); +		 +		return FALSE;  	} +	else +		return TRUE;  }  static int msn_ns_command( gpointer data, char **cmd, int num_parts ) @@ -129,7 +135,7 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )  		if( num_parts == 6 && strcmp( cmd[2], "NS" ) == 0 )  		{ -			gaim_input_remove( gc->inpa ); +			b_event_remove( gc->inpa );  			gc->inpa = 0;  			closesocket( md->fd ); diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 234be1d6..54e89043 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -29,7 +29,7 @@  #include "passport.h"  #include "md5.h" -static void msn_sb_callback( gpointer data, gint source, GaimInputCondition cond ); +static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );  static int msn_sb_command( gpointer data, char **cmd, int num_parts );  static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); @@ -236,7 +236,7 @@ void msn_sb_destroy( struct msn_switchboard *sb )  		g_free( sb->handler );  	} -	if( sb->inp ) gaim_input_remove( sb->inp ); +	if( sb->inp ) b_event_remove( sb->inp );  	closesocket( sb->fd );  	msn_switchboards = g_slist_remove( msn_switchboards, sb ); @@ -244,7 +244,7 @@ void msn_sb_destroy( struct msn_switchboard *sb )  	g_free( sb );  } -void msn_sb_connected( gpointer data, gint source, GaimInputCondition cond ) +gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond )  {  	struct msn_switchboard *sb = data;  	struct gaim_connection *gc; @@ -253,7 +253,7 @@ void msn_sb_connected( gpointer data, gint source, GaimInputCondition cond )  	/* Are we still alive? */  	if( !g_slist_find( msn_switchboards, sb ) ) -		return; +		return FALSE;  	gc = sb->gc;  	md = gc->proto_data; @@ -262,7 +262,7 @@ void msn_sb_connected( gpointer data, gint source, GaimInputCondition cond )  	{  		debug( "ERROR %d while connecting to switchboard server", 1 );  		msn_sb_destroy( sb ); -		return; +		return FALSE;  	}  	/* Prepare the callback */ @@ -279,12 +279,14 @@ void msn_sb_connected( gpointer data, gint source, GaimInputCondition cond )  		g_snprintf( buf, sizeof( buf ), "ANS %d %s %s %d\r\n", ++sb->trId, gc->username, sb->key, sb->session );  	if( msn_sb_write( sb, buf, strlen( buf ) ) ) -		sb->inp = gaim_input_add( sb->fd, GAIM_INPUT_READ, msn_sb_callback, sb ); +		sb->inp = b_input_add( sb->fd, GAIM_INPUT_READ, msn_sb_callback, sb );  	else  		debug( "ERROR %d while connecting to switchboard server", 2 ); +	 +	return FALSE;  } -static void msn_sb_callback( gpointer data, gint source, GaimInputCondition cond ) +static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond )  {  	struct msn_switchboard *sb = data; @@ -292,7 +294,11 @@ static void msn_sb_callback( gpointer data, gint source, GaimInputCondition cond  	{  		debug( "ERROR: Switchboard died" );  		msn_sb_destroy( sb ); +		 +		return FALSE;  	} +	else +		return TRUE;  }  static int msn_sb_command( gpointer data, char **cmd, int num_parts ) diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 568afe33..b1975f19 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -1,7 +1,7 @@    /********************************************************************\    * BitlBee -- An IRC to other IM-networks gateway                     *    *                                                                    * -  * Copyright 2002-2004 Wilmer van der Gaast and others                * +  * Copyright 2002-2006 Wilmer van der Gaast and others                *    \********************************************************************/  /* @@ -12,8 +12,6 @@   * This file contains functions called by the Gaim IM-modules. It's written   * from scratch for BitlBee and doesn't contain any code from Gaim anymore   * (except for the function names). - * - * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net> and others   */  /* @@ -37,19 +35,6 @@  #include "nogaim.h"  #include <ctype.h> -static char *proto_away_alias[8][5] = -{ -	{ "Away from computer", "Away", "Extended away", NULL }, -	{ "NA", "N/A", "Not available", NULL }, -	{ "Busy", "Do not disturb", "DND", "Occupied", NULL }, -	{ "Be right back", "BRB", NULL }, -	{ "On the phone", "Phone", "On phone", NULL }, -	{ "Out to lunch", "Lunch", "Food", NULL }, -	{ "Invisible", "Hidden" }, -	{ NULL } -}; -static char *proto_away_alias_find( GList *gcm, char *away ); -  static int remove_chat_buddy_silent( struct conversation *b, char *handle );  GSList *connections; @@ -157,83 +142,6 @@ void nogaim_init()  GSList *get_connections() { return connections; } -int proto_away( struct gaim_connection *gc, char *away ) -{ -	GList *m, *ms; -	char *s; -	 -	if( !away ) away = ""; -	ms = m = gc->prpl->away_states( gc ); -	 -	while( m ) -	{ -		if( *away ) -		{ -			if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 ) -				break; -		} -		else -		{ -			if( g_strcasecmp( m->data, "Available" ) == 0 ) -				break; -			if( g_strcasecmp( m->data, "Online" ) == 0 ) -				break; -		} -		m = m->next; -	} -	 -	if( m ) -	{ -		gc->prpl->set_away( gc, m->data, *away ? away : NULL ); -	} -	else -	{ -		s = proto_away_alias_find( ms, away ); -		if( s ) -		{ -			gc->prpl->set_away( gc, s, away ); -			if( set_getint( gc->irc, "debug" ) ) -				serv_got_crap( gc, "Setting away state to %s", s ); -		} -		else -			gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); -	} -	 -	g_list_free( ms ); -	 -	return( 1 ); -} - -static char *proto_away_alias_find( GList *gcm, char *away ) -{ -	GList *m; -	int i, j; -	 -	for( i = 0; *proto_away_alias[i]; i ++ ) -	{ -		for( j = 0; proto_away_alias[i][j]; j ++ ) -			if( g_strncasecmp( away, proto_away_alias[i][j], strlen( proto_away_alias[i][j] ) ) == 0 ) -				break; -		 -		if( !proto_away_alias[i][j] )	/* If we reach the end, this row */ -			continue;		/* is not what we want. Next!    */ -		 -		/* Now find an entry in this row which exists in gcm */ -		for( j = 0; proto_away_alias[i][j]; j ++ ) -		{ -			m = gcm; -			while( m ) -			{ -				if( g_strcasecmp( proto_away_alias[i][j], m->data ) == 0 ) -					return( proto_away_alias[i][j] ); -				m = m->next; -			} -		} -	} -	 -	return( NULL ); -} -  /* multi.c */  struct gaim_connection *new_gaim_conn( struct aim_user *user ) @@ -249,7 +157,7 @@ struct gaim_connection *new_gaim_conn( struct aim_user *user )  	/* [MD]	BUGFIX: don't set gc->irc to the global IRC, but use the one from the struct aim_user.  	 * This fixes daemon mode breakage where IRC doesn't point to the currently active connection.  	 */ -	gc->irc=user->irc; +	gc->irc = user->irc;  	connections = g_slist_append( connections, gc ); @@ -329,7 +237,7 @@ void serv_got_crap( struct gaim_connection *gc, char *format, ... )  	g_free( text );  } -static gboolean send_keepalive( gpointer d ) +static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond )  {  	struct gaim_connection *gc = d; @@ -353,15 +261,15 @@ void account_online( struct gaim_connection *gc )  	serv_got_crap( gc, "Logged in" ); -	gc->keepalive = g_timeout_add( 60000, send_keepalive, gc ); +	gc->keepalive = b_timeout_add( 60000, send_keepalive, gc );  	gc->flags |= OPT_LOGGED_IN;  	/* Also necessary when we're not away, at least for some of the  	   protocols. */ -	proto_away( gc, u->away ); +	bim_set_away( gc, u->away );  } -gboolean auto_reconnect( gpointer data ) +gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond )  {  	account_t *a = data; @@ -373,7 +281,8 @@ gboolean auto_reconnect( gpointer data )  void cancel_auto_reconnect( account_t *a )  { -	while( g_source_remove_by_user_data( (gpointer) a ) ); +	/* while( b_event_remove_by_data( (gpointer) a ) ); */ +	b_event_remove( a->reconnect );  	a->reconnect = 0;  } @@ -385,10 +294,10 @@ void signoff( struct gaim_connection *gc )  	serv_got_crap( gc, "Signing off.." ); -	gaim_input_remove( gc->keepalive ); +	b_event_remove( gc->keepalive );  	gc->keepalive = 0;  	gc->prpl->close( gc ); -	gaim_input_remove( gc->inpa ); +	b_event_remove( gc->inpa );  	while( u )  	{ @@ -415,10 +324,9 @@ void signoff( struct gaim_connection *gc )  	else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) )  	{  		int delay = set_getint( irc, "auto_reconnect_delay" ); -		serv_got_crap( gc, "Reconnecting in %d seconds..", delay ); -		a->reconnect = 1; -		g_timeout_add( delay * 1000, auto_reconnect, a ); +		serv_got_crap( gc, "Reconnecting in %d seconds..", delay ); +		a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a );  	}  	destroy_gaim_conn( gc ); @@ -1030,24 +938,30 @@ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )  	return( set_eval_bool( irc, set, value ) );  } -int serv_send_im( irc_t *irc, user_t *u, char *msg, int flags ) + + + +/* The plan is to not allow straight calls to prpl functions anymore, but do +   them all from some wrappers. We'll start to define some down here: */ + +int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flags )  {  	char *buf = NULL;  	int st; -	if( ( u->gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) +	if( ( gc->flags & OPT_CONN_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )  	{  		buf = escape_html( msg );  		msg = buf;  	} -	st = ((struct gaim_connection *)u->gc)->prpl->send_im( u->gc, u->handle, msg, strlen( msg ), flags ); +	st = gc->prpl->send_im( gc, handle, msg, strlen( msg ), flags );  	g_free( buf );  	return st;  } -int serv_send_chat( irc_t *irc, struct gaim_connection *gc, int id, char *msg ) +int bim_chat_msg( struct gaim_connection *gc, int id, char *msg )  {  	char *buf = NULL;  	int st; @@ -1063,3 +977,140 @@ int serv_send_chat( irc_t *irc, struct gaim_connection *gc, int id, char *msg )  	return st;  } + +static char *bim_away_alias_find( GList *gcm, char *away ); + +int bim_set_away( struct gaim_connection *gc, char *away ) +{ +	GList *m, *ms; +	char *s; +	 +	if( !away ) away = ""; +	ms = m = gc->prpl->away_states( gc ); +	 +	while( m ) +	{ +		if( *away ) +		{ +			if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 ) +				break; +		} +		else +		{ +			if( g_strcasecmp( m->data, "Available" ) == 0 ) +				break; +			if( g_strcasecmp( m->data, "Online" ) == 0 ) +				break; +		} +		m = m->next; +	} +	 +	if( m ) +	{ +		gc->prpl->set_away( gc, m->data, *away ? away : NULL ); +	} +	else +	{ +		s = bim_away_alias_find( ms, away ); +		if( s ) +		{ +			gc->prpl->set_away( gc, s, away ); +			if( set_getint( gc->irc, "debug" ) ) +				serv_got_crap( gc, "Setting away state to %s", s ); +		} +		else +			gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); +	} +	 +	g_list_free( ms ); +	 +	return( 1 ); +} + +static char *bim_away_alias_list[8][5] = +{ +	{ "Away from computer", "Away", "Extended away", NULL }, +	{ "NA", "N/A", "Not available", NULL }, +	{ "Busy", "Do not disturb", "DND", "Occupied", NULL }, +	{ "Be right back", "BRB", NULL }, +	{ "On the phone", "Phone", "On phone", NULL }, +	{ "Out to lunch", "Lunch", "Food", NULL }, +	{ "Invisible", "Hidden" }, +	{ NULL } +}; + +static char *bim_away_alias_find( GList *gcm, char *away ) +{ +	GList *m; +	int i, j; +	 +	for( i = 0; *bim_away_alias_list[i]; i ++ ) +	{ +		for( j = 0; bim_away_alias_list[i][j]; j ++ ) +			if( g_strncasecmp( away, bim_away_alias_list[i][j], strlen( bim_away_alias_list[i][j] ) ) == 0 ) +				break; +		 +		if( !bim_away_alias_list[i][j] )	/* If we reach the end, this row */ +			continue;			/* is not what we want. Next!    */ +		 +		/* Now find an entry in this row which exists in gcm */ +		for( j = 0; bim_away_alias_list[i][j]; j ++ ) +		{ +			m = gcm; +			while( m ) +			{ +				if( g_strcasecmp( bim_away_alias_list[i][j], m->data ) == 0 ) +					return( bim_away_alias_list[i][j] ); +				m = m->next; +			} +		} +	} +	 +	return( NULL ); +} + +void bim_add_allow( struct gaim_connection *gc, char *handle ) +{ +	if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) +	{ +		gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) ); +	} +	 +	gc->prpl->add_permit( gc, handle ); +} + +void bim_rem_allow( struct gaim_connection *gc, char *handle ) +{ +	GSList *l; +	 +	if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) +	{ +		g_free( l->data ); +		gc->permit = g_slist_delete_link( gc->permit, l ); +	} +	 +	gc->prpl->rem_permit( gc, handle ); +} + +void bim_add_block( struct gaim_connection *gc, char *handle ) +{ +	if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) +	{ +		gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) ); +	} +	 +	gc->prpl->add_deny( gc, handle ); +} + +void bim_rem_block( struct gaim_connection *gc, char *handle ) +{ +	GSList *l; +	 +	if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) +	{ +		g_free( l->data ); +		gc->deny = g_slist_delete_link( gc->deny, l ); +	} +	 +	gc->prpl->rem_deny( gc, handle ); +} diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 4251fbaa..b0319d27 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -51,7 +51,7 @@  #define SELF_ALIAS_LEN 400  #define BUDDY_ALIAS_MAXLEN 388   /* because MSN names can be 387 characters */ -#define WEBSITE "http://www.bitlee.org/" +#define WEBSITE "http://www.bitlbee.org/"  #define IM_FLAG_AWAY 0x0020  #define OPT_CONN_HTML 0x00000001  #define OPT_LOGGED_IN 0x00010000 @@ -193,14 +193,19 @@ G_MODULE_EXPORT struct prpl *find_protocol(const char *name);  G_MODULE_EXPORT void register_protocol(struct prpl *);  /* nogaim.c */ -int serv_send_im(irc_t *irc, user_t *u, char *msg, int flags); -int serv_send_chat(irc_t *irc, struct gaim_connection *gc, int id, char *msg ); +int bim_set_away( struct gaim_connection *gc, char *away ); +int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flags ); +int bim_chat_msg( struct gaim_connection *gc, int id, char *msg ); + +void bim_add_allow( struct gaim_connection *gc, char *handle ); +void bim_rem_allow( struct gaim_connection *gc, char *handle ); +void bim_add_block( struct gaim_connection *gc, char *handle ); +void bim_rem_block( struct gaim_connection *gc, char *handle );  void nogaim_init(); -int proto_away( struct gaim_connection *gc, char *away );  char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ); -gboolean auto_reconnect( gpointer data ); +gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );  void cancel_auto_reconnect( struct account *a );  /* multi.c */ @@ -209,7 +214,7 @@ G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc );  G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg );  G_MODULE_EXPORT void hide_login_progress( struct gaim_connection *gc, char *msg );  G_MODULE_EXPORT void hide_login_progress_error( struct gaim_connection *gc, char *msg ); -G_MODULE_EXPORT void serv_got_crap( struct gaim_connection *gc, char *format, ... ); +G_MODULE_EXPORT void serv_got_crap( struct gaim_connection *gc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );  G_MODULE_EXPORT void account_online( struct gaim_connection *gc );  G_MODULE_EXPORT void signoff( struct gaim_connection *gc ); diff --git a/protocols/oscar/aim.h b/protocols/oscar/aim.h index 24cd7730..93887103 100644 --- a/protocols/oscar/aim.h +++ b/protocols/oscar/aim.h @@ -727,8 +727,11 @@ struct aim_chat_exchangeinfo {  	char *lang2;  }; -#define AIM_CHATFLAGS_NOREFLECT 0x0001 -#define AIM_CHATFLAGS_AWAY      0x0002 +#define AIM_CHATFLAGS_NOREFLECT 	0x0001 +#define AIM_CHATFLAGS_AWAY      	0x0002 +#define AIM_CHATFLAGS_UNICODE		0x0004 +#define AIM_CHATFLAGS_ISO_8859_1	0x0008 +  int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen);  int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);  int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance); diff --git a/protocols/oscar/chat.c b/protocols/oscar/chat.c index 033c2577..df535c4f 100644 --- a/protocols/oscar/chat.c +++ b/protocols/oscar/chat.c @@ -158,7 +158,21 @@ int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const  	 */  	if (flags & AIM_CHATFLAGS_AWAY)  		aim_addtlvtochain_noval(&otl, 0x0007); - +	 +	/* [WvG] This wasn't there originally, but we really should send +	         the right charset flags, as we also do with normal +	         messages. Hope this will work. :-) */ +	/* +	if (flags & AIM_CHATFLAGS_UNICODE) +		aimbs_put16(&fr->data, 0x0002); +	else if (flags & AIM_CHATFLAGS_ISO_8859_1) +		aimbs_put16(&fr->data, 0x0003); +	else +		aimbs_put16(&fr->data, 0x0000); +	 +	aimbs_put16(&fr->data, 0x0000); +	*/ +	  	/*  	 * SubTLV: Type 1: Message  	 */ diff --git a/protocols/oscar/im.c b/protocols/oscar/im.c index c829d409..7cccabc7 100644 --- a/protocols/oscar/im.c +++ b/protocols/oscar/im.c @@ -1468,7 +1468,7 @@ static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod              case AIM_MTYPE_AUTOFFC:  	    case 0x9c:	/* ICQ 5 seems to send this */                  aim_send_im_ch2_statusmessage(sess, userinfo->sn, args->cookie, -                        gc->away, sess->aim_icq_state, dc); +                        gc->away ? gc->away : "", sess->aim_icq_state, dc);                  break;          } diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 53da1e27..7c76533a 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -1,6 +1,8 @@  /*   * gaim   * + * Some code copyright (C) 2002-2006, Jelmer Vernooij <jelmer@samba.org> + *                                    and the BitlBee team.   * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net>   * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx>   * @@ -135,9 +137,9 @@ static char *extract_name(const char *name) {  	char *tmp;  	int i, j;  	char *x = strchr(name, '-'); -	if (!x) return NULL; +	if (!x) return g_strdup(name);  	x = strchr(++x, '-'); -	if (!x) return NULL; +	if (!x) return g_strdup(name);  	tmp = g_strdup(++x);  	for (i = 0, j = 0; x[i]; i++) { @@ -252,8 +254,8 @@ static char *msgerrreason[] = {  };  static int msgerrreasonlen = 25; -static void oscar_callback(gpointer data, gint source, -				GaimInputCondition condition) { +static gboolean oscar_callback(gpointer data, gint source, +				b_input_condition condition) {  	aim_conn_t *conn = (aim_conn_t *)data;  	aim_session_t *sess = aim_conn_getsess(conn);  	struct gaim_connection *gc = sess ? sess->aux_data : NULL; @@ -261,13 +263,13 @@ static void oscar_callback(gpointer data, gint source,  	if (!gc) {  		/* gc is null. we return, else we seg SIGSEG on next line. */ -		return; +		return FALSE;  	}  	if (!g_slist_find(get_connections(), gc)) {  		/* oh boy. this is probably bad. i guess the only thing we   		 * can really do is return? */ -		return; +		return FALSE;  	}  	odata = (struct oscar_data *)gc->proto_data; @@ -287,7 +289,7 @@ static void oscar_callback(gpointer data, gint source,  				char buf[BUF_LONG];  				c->conn = NULL;  				if (c->inpa > 0) -					gaim_input_remove(c->inpa); +					b_event_remove(c->inpa);  				c->inpa = 0;  				c->fd = -1;  				aim_conn_kill(odata->sess, &conn); @@ -295,7 +297,7 @@ static void oscar_callback(gpointer data, gint source,  				do_error_dialog(sess->aux_data, buf, _("Chat Error!"));  			} else if (conn->type == AIM_CONN_TYPE_CHATNAV) {  				if (odata->cnpa > 0) -					gaim_input_remove(odata->cnpa); +					b_event_remove(odata->cnpa);  				odata->cnpa = 0;  				while (odata->create_rooms) {  					struct create_room *cr = odata->create_rooms->data; @@ -309,17 +311,22 @@ static void oscar_callback(gpointer data, gint source,  				aim_conn_kill(odata->sess, &conn);  			} else if (conn->type == AIM_CONN_TYPE_AUTH) {  				if (odata->paspa > 0) -					gaim_input_remove(odata->paspa); +					b_event_remove(odata->paspa);  				odata->paspa = 0;  				aim_conn_kill(odata->sess, &conn);  			} else {  				aim_conn_kill(odata->sess, &conn);  			}  		} +	} else { +		/* WTF??? */ +		return FALSE;  	} +		 +	return TRUE;  } -static void oscar_login_connect(gpointer data, gint source, GaimInputCondition cond) +static gboolean oscar_login_connect(gpointer data, gint source, b_input_condition cond)  {  	struct gaim_connection *gc = data;  	struct oscar_data *odata; @@ -328,7 +335,7 @@ static void oscar_login_connect(gpointer data, gint source, GaimInputCondition c  	if (!g_slist_find(get_connections(), gc)) {  		closesocket(source); -		return; +		return FALSE;  	}  	odata = gc->proto_data; @@ -338,12 +345,14 @@ static void oscar_login_connect(gpointer data, gint source, GaimInputCondition c  	if (source < 0) {  		hide_login_progress(gc, _("Couldn't connect to host"));  		signoff(gc); -		return; +		return FALSE;  	}  	aim_conn_completeconnect(sess, conn); -	gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, +	gc->inpa = b_input_add(conn->fd, GAIM_INPUT_READ,  			oscar_callback, conn); +	 +	return FALSE;  }  static void oscar_login(struct aim_user *user) { @@ -382,7 +391,7 @@ static void oscar_login(struct aim_user *user) {  	if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 &&  	    g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) { -		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails."); +		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]);  	}  	g_snprintf(buf, sizeof(buf), _("Signon: %s"), gc->username); @@ -411,7 +420,7 @@ static void oscar_close(struct gaim_connection *gc) {  	while (odata->oscar_chats) {  		struct chat_connection *n = odata->oscar_chats->data;  		if (n->inpa > 0) -			gaim_input_remove(n->inpa); +			b_event_remove(n->inpa);  		g_free(n->name);  		g_free(n->show);  		odata->oscar_chats = g_slist_remove(odata->oscar_chats, n); @@ -430,11 +439,11 @@ static void oscar_close(struct gaim_connection *gc) {  	if (odata->oldp)  		g_free(odata->oldp);  	if (gc->inpa > 0) -		gaim_input_remove(gc->inpa); +		b_event_remove(gc->inpa);  	if (odata->cnpa > 0) -		gaim_input_remove(odata->cnpa); +		b_event_remove(odata->cnpa);  	if (odata->paspa > 0) -		gaim_input_remove(odata->paspa); +		b_event_remove(odata->paspa);  	aim_session_kill(odata->sess);  	g_free(odata->sess);  	odata->sess = NULL; @@ -442,7 +451,7 @@ static void oscar_close(struct gaim_connection *gc) {  	gc->proto_data = NULL;  } -static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) { +static gboolean oscar_bos_connect(gpointer data, gint source, b_input_condition cond) {  	struct gaim_connection *gc = data;  	struct oscar_data *odata;  	aim_session_t *sess; @@ -450,7 +459,7 @@ static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition con  	if (!g_slist_find(get_connections(), gc)) {  		closesocket(source); -		return; +		return FALSE;  	}  	odata = gc->proto_data; @@ -460,13 +469,15 @@ static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition con  	if (source < 0) {  		hide_login_progress(gc, _("Could Not Connect"));  		signoff(gc); -		return; +		return FALSE;  	}  	aim_conn_completeconnect(sess, bosconn); -	gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, +	gc->inpa = b_input_add(bosconn->fd, GAIM_INPUT_READ,  			oscar_callback, bosconn);  	set_login_progress(gc, 4, _("Connection established, cookie sent")); +	 +	return FALSE;  }  static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { @@ -569,7 +580,7 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) {  		return 0;  	}  	aim_sendcookie(sess, bosconn, info->cookie); -	gaim_input_remove(gc->inpa); +	b_event_remove(gc->inpa);  	return 1;  } @@ -584,7 +595,7 @@ struct pieceofcrap {  	unsigned int inpa;  }; -static void damn_you(gpointer data, gint source, GaimInputCondition c) +static gboolean damn_you(gpointer data, gint source, b_input_condition c)  {  	struct pieceofcrap *pos = data;  	struct oscar_data *od = pos->gc->proto_data; @@ -604,21 +615,23 @@ static void damn_you(gpointer data, gint source, GaimInputCondition c)  	if (in != '\n') {  		do_error_dialog(pos->gc, "Gaim was unable to get a valid hash for logging into AIM."  				" You may be disconnected shortly.", "Login Error"); -		gaim_input_remove(pos->inpa); +		b_event_remove(pos->inpa);  		closesocket(pos->fd);  		g_free(pos); -		return; +		return FALSE;  	}  	/* [WvG] Wheeeee! Who needs error checking anyway? ;-) */  	read(pos->fd, m, 16);  	m[16] = '\0'; -	gaim_input_remove(pos->inpa); +	b_event_remove(pos->inpa);  	closesocket(pos->fd);  	aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH);  	g_free(pos); +	 +	return FALSE;  } -static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond) { +static gboolean straight_to_hell(gpointer data, gint source, b_input_condition cond) {  	struct pieceofcrap *pos = data;  	char buf[BUF_LONG]; @@ -628,7 +641,7 @@ static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond  		if (pos->modname)  			g_free(pos->modname);  		g_free(pos); -		return; +		return FALSE;  	}  	g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA @@ -637,8 +650,8 @@ static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond  	write(pos->fd, buf, strlen(buf));  	if (pos->modname)  		g_free(pos->modname); -	pos->inpa = gaim_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); -	return; +	pos->inpa = b_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); +	return FALSE;  }  /* size of icbmui.ocm, the largest module in AIM 3.5 */ @@ -760,7 +773,7 @@ static int conninitdone_chatnav(aim_session_t *sess, aim_frame_t *fr, ...) {  	return 1;  } -static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) { +static gboolean oscar_chatnav_connect(gpointer data, gint source, b_input_condition cond) {  	struct gaim_connection *gc = data;  	struct oscar_data *odata;  	aim_session_t *sess; @@ -768,7 +781,7 @@ static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition  	if (!g_slist_find(get_connections(), gc)) {  		closesocket(source); -		return; +		return FALSE;  	}  	odata = gc->proto_data; @@ -777,15 +790,17 @@ static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition  	if (source < 0) {  		aim_conn_kill(sess, &tstconn); -		return; +		return FALSE;  	}  	aim_conn_completeconnect(sess, tstconn); -	odata->cnpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, +	odata->cnpa = b_input_add(tstconn->fd, GAIM_INPUT_READ,  					oscar_callback, tstconn); +	 +	return FALSE;  } -static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition cond) +static gboolean oscar_auth_connect(gpointer data, gint source, b_input_condition cond)  {  	struct gaim_connection *gc = data;  	struct oscar_data *odata; @@ -794,7 +809,7 @@ static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition co  	if (!g_slist_find(get_connections(), gc)) {  		closesocket(source); -		return; +		return FALSE;  	}  	odata = gc->proto_data; @@ -803,15 +818,17 @@ static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition co  	if (source < 0) {  		aim_conn_kill(sess, &tstconn); -		return; +		return FALSE;  	}  	aim_conn_completeconnect(sess, tstconn); -	odata->paspa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, +	odata->paspa = b_input_add(tstconn->fd, GAIM_INPUT_READ,  				oscar_callback, tstconn); +	 +	return FALSE;  } -static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition cond) +static gboolean oscar_chat_connect(gpointer data, gint source, b_input_condition cond)  {  	struct chat_connection *ccon = data;  	struct gaim_connection *gc = ccon->gc; @@ -824,7 +841,7 @@ static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition co  		g_free(ccon->show);  		g_free(ccon->name);  		g_free(ccon); -		return; +		return FALSE;  	}  	odata = gc->proto_data; @@ -836,14 +853,16 @@ static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition co  		g_free(ccon->show);  		g_free(ccon->name);  		g_free(ccon); -		return; +		return FALSE;  	}  	aim_conn_completeconnect(sess, ccon->conn); -	ccon->inpa = gaim_input_add(tstconn->fd, +	ccon->inpa = b_input_add(tstconn->fd,  			GAIM_INPUT_READ,  			oscar_callback, tstconn);  	odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon); +	 +	return FALSE;  }  /* Hrmph. I don't know how to make this look better. --mid */ @@ -2499,6 +2518,7 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  	struct chat_connection * ccon;  	int ret;  	guint8 len = strlen(message); +	guint16 flags;  	char *s;  	if(!(ccon = find_oscar_chat(gc, id))) @@ -2507,15 +2527,19 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  	for (s = message; *s; s++)  		if (*s & 128)  			break; -	  	 +	 +	flags = AIM_CHATFLAGS_NOREFLECT; +	  	/* Message contains high ASCII chars, time for some translation! */  	if (*s) {  		s = g_malloc(BUF_LONG);  		/* Try if we can put it in an ISO8859-1 string first.  		   If we can't, fall back to UTF16. */  		if ((ret = do_iconv("UTF-8", "ISO8859-1", message, s, len, BUF_LONG)) >= 0) { +			flags |= AIM_CHATFLAGS_ISO_8859_1;  			len = ret;  		} else if ((ret = do_iconv("UTF-8", "UNICODEBIG", message, s, len, BUF_LONG)) >= 0) { +			flags |= AIM_CHATFLAGS_UNICODE;  			len = ret;  		} else {  			/* OOF, translation failed... Oh well.. */ @@ -2526,7 +2550,7 @@ int oscar_chat_send(struct gaim_connection * gc, int id, char *message)  		s = message;  	} -	ret = aim_chat_send_im(od->sess, ccon->conn, AIM_CHATFLAGS_NOREFLECT, s, len); +	ret = aim_chat_send_im(od->sess, ccon->conn, flags, s, len);  	if (s != message) {	  		g_free(s); @@ -2557,7 +2581,7 @@ void oscar_chat_kill(struct gaim_connection *gc, struct chat_connection *cc)  	/* Destroy the chat_connection */  	od->oscar_chats = g_slist_remove(od->oscar_chats, cc);  	if (cc->inpa > 0) -		gaim_input_remove(cc->inpa); +		b_event_remove(cc->inpa);  	aim_conn_kill(od->sess, &cc->conn);  	g_free(cc->name);  	g_free(cc->show); @@ -2599,9 +2623,9 @@ int oscar_chat_open(struct gaim_connection * gc, char *who)  	struct oscar_data * od = (struct oscar_data *)gc->proto_data;  	int ret;  	static int chat_id = 0; -	char * chatname = g_new0(char, strlen(gc->username)+4); +	char * chatname; -	g_snprintf(chatname, strlen(gc->username) + 4, "%s%d", gc->username, chat_id++); +	chatname = g_strdup_printf("%s%d", gc->username, chat_id++);  	ret = oscar_chat_join(gc, chatname); 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; diff --git a/protocols/proxy.h b/protocols/proxy.h index 47c966d2..680790a5 100644 --- a/protocols/proxy.h +++ b/protocols/proxy.h @@ -1,5 +1,5 @@  /* - * gaim + * nogaim   *   * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>   * @@ -35,6 +35,8 @@  #include <glib.h>  #include <gmodule.h> +#include "events.h" +  #define PROXY_NONE 0  #define PROXY_HTTP 1  #define PROXY_SOCKS4 2 @@ -46,15 +48,6 @@ extern int  proxytype;  extern char proxyuser[128];  extern char proxypass[128]; -typedef enum { -	GAIM_INPUT_READ = 1 << 0, -	GAIM_INPUT_WRITE = 1 << 1 -} GaimInputCondition; -typedef void (*GaimInputFunction)(gpointer, gint, GaimInputCondition); - -G_MODULE_EXPORT gint gaim_input_add(int, GaimInputCondition, GaimInputFunction, gpointer); -G_MODULE_EXPORT void gaim_input_remove(gint); - -G_MODULE_EXPORT int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data); +G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data);  #endif /* _PROXY_H_ */ diff --git a/protocols/ssl_bogus.c b/protocols/ssl_bogus.c index 52406b75..00aaa7c4 100644 --- a/protocols/ssl_bogus.c +++ b/protocols/ssl_bogus.c @@ -51,7 +51,7 @@ int ssl_getfd( void *conn )  	return( -1 );  } -GaimInputCondition ssl_getdirection( void *conn ) +b_input_condition ssl_getdirection( void *conn )  {  	return GAIM_INPUT_READ;  } diff --git a/protocols/ssl_client.h b/protocols/ssl_client.h index 89189db9..1a9c79e9 100644 --- a/protocols/ssl_client.h +++ b/protocols/ssl_client.h @@ -32,11 +32,11 @@  extern int ssl_errno; -typedef void (*ssl_input_function)(gpointer, void*, GaimInputCondition); +typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);  G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );  G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );  G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );  G_MODULE_EXPORT void ssl_disconnect( void *conn_ );  G_MODULE_EXPORT int ssl_getfd( void *conn ); -G_MODULE_EXPORT GaimInputCondition ssl_getdirection( void *conn ); +G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn ); diff --git a/protocols/ssl_gnutls.c b/protocols/ssl_gnutls.c index f2cb3e08..3ebe1756 100644 --- a/protocols/ssl_gnutls.c +++ b/protocols/ssl_gnutls.c @@ -47,7 +47,7 @@ struct scd  	gnutls_certificate_credentials xcred;  }; -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ); +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );  void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) @@ -80,9 +80,9 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data  	return( conn );  } -static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ); +static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ); -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )  {  	struct scd *conn = data; @@ -95,32 +95,26 @@ static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )  		g_free( conn ); -		return; +		return FALSE;  	}  	sock_make_nonblocking( conn->fd );  	gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd ); -	ssl_handshake( data, source, cond ); +	return ssl_handshake( data, source, cond );  } -static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ) +static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )  {  	struct scd *conn = data;  	int st; -	if( conn->inpa != -1 ) -	{ -		gaim_input_remove( conn->inpa ); -		conn->inpa = -1; -	} -	  	if( ( st = gnutls_handshake( conn->session ) ) < 0 )  	{  		if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )  		{ -			conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ), -			                             ssl_handshake, data ); +			conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), +			                          ssl_handshake, data );  		}  		else  		{ @@ -141,6 +135,8 @@ static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond )  		conn->established = TRUE;  		conn->func( conn->data, conn, cond );  	} +	 +	return FALSE;  }  int ssl_read( void *conn, char *buf, int len ) @@ -186,7 +182,7 @@ void ssl_disconnect( void *conn_ )  	struct scd *conn = conn_;  	if( conn->inpa != -1 ) -		gaim_input_remove( conn->inpa ); +		b_event_remove( conn->inpa );  	if( conn->established )  		gnutls_bye( conn->session, GNUTLS_SHUT_WR ); @@ -203,7 +199,7 @@ int ssl_getfd( void *conn )  	return( ((struct scd*)conn)->fd );  } -GaimInputCondition ssl_getdirection( void *conn ) +b_input_condition ssl_getdirection( void *conn )  {  	return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ?  	        GAIM_INPUT_WRITE : GAIM_INPUT_READ ); diff --git a/protocols/ssl_nss.c b/protocols/ssl_nss.c index 00d32834..218b3a80 100644 --- a/protocols/ssl_nss.c +++ b/protocols/ssl_nss.c @@ -51,7 +51,7 @@ struct scd  	gboolean established;  }; -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ); +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );  static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver) @@ -115,7 +115,7 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data  	return( conn );  } -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )  {  	struct scd *conn = data; @@ -139,7 +139,7 @@ static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )  	conn->established = TRUE;  	conn->func( conn->data, conn, cond ); -	return; +	return FALSE;  	ssl_connected_failure: @@ -148,6 +148,8 @@ static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )  	PR_Close( conn -> prfd );  	if( source >= 0 ) closesocket( source );  	g_free( conn ); +	 +	return FALSE;  }  int ssl_read( void *conn, char *buf, int len ) @@ -181,7 +183,7 @@ int ssl_getfd( void *conn )  	return( ((struct scd*)conn)->fd );  } -GaimInputCondition ssl_getdirection( void *conn ) +b_input_condition ssl_getdirection( void *conn )  {  	/* Just in case someone calls us, let's return the most likely case: */  	return GAIM_INPUT_READ; diff --git a/protocols/ssl_openssl.c b/protocols/ssl_openssl.c index b79088cc..b6f6c520 100644 --- a/protocols/ssl_openssl.c +++ b/protocols/ssl_openssl.c @@ -51,8 +51,7 @@ struct scd  	SSL_CTX *ssl_ctx;  }; -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ); - +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );  void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) @@ -94,47 +93,41 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data  	return( conn );  } -static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ); +static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ); -static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ) +static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )  {  	struct scd *conn = data;  	if( source == -1 )  		return ssl_handshake( data, -1, cond ); -	/* Make it non-blocking at least during the handshake... */ +	/* We can do at least the handshake with non-blocking I/O */  	sock_make_nonblocking( conn->fd );  	SSL_set_fd( conn->ssl, conn->fd );  	return ssl_handshake( data, source, cond );  }	 -static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond ) +static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )  {  	struct scd *conn = data;  	int st; -	if( conn->inpa != -1 ) -	{ -		gaim_input_remove( conn->inpa ); -		conn->inpa = -1; -	} -	  	if( ( st = SSL_connect( conn->ssl ) ) < 0 )  	{  		conn->lasterr = SSL_get_error( conn->ssl, st );  		if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE )  			goto ssl_connected_failure; -		conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data ); -		return; +		conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data ); +		return FALSE;  	}  	conn->established = TRUE;  	sock_make_blocking( conn->fd );		/* For now... */  	conn->func( conn->data, conn, cond ); -	return; +	return FALSE;  ssl_connected_failure:  	conn->func( conn->data, NULL, cond ); @@ -150,6 +143,8 @@ ssl_connected_failure:  	}  	if( source >= 0 ) closesocket( source );  	g_free( conn ); +	 +	return FALSE;  }  int ssl_read( void *conn, char *buf, int len ) @@ -203,7 +198,7 @@ void ssl_disconnect( void *conn_ )  	struct scd *conn = conn_;  	if( conn->inpa != -1 ) -		gaim_input_remove( conn->inpa ); +		b_event_remove( conn->inpa );  	if( conn->established )  		SSL_shutdown( conn->ssl ); @@ -220,7 +215,7 @@ int ssl_getfd( void *conn )  	return( ((struct scd*)conn)->fd );  } -GaimInputCondition ssl_getdirection( void *conn ) +b_input_condition ssl_getdirection( void *conn )  {  	return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ );  } diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 1c3c73d9..79c0febb 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -442,7 +442,7 @@ struct byahoo_connect_callback_data  	int id;  }; -void byahoo_connect_callback( gpointer data, gint source, GaimInputCondition cond ) +void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond )  {  	struct byahoo_connect_callback_data *d = data; @@ -464,18 +464,17 @@ struct byahoo_read_ready_data  	gpointer data;  }; -void byahoo_read_ready_callback( gpointer data, gint source, GaimInputCondition cond ) +gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_condition cond )  {  	struct byahoo_read_ready_data *d = data;  	if( !byahoo_get_gc_by_id( d->id ) ) -	{  		/* WTF doesn't libyahoo clean this up? */ -		ext_yahoo_remove_handler( d->id, d->tag ); -		return; -	} +		return FALSE;  	yahoo_read_ready( d->id, d->fd, d->data ); +	 +	return TRUE;  }  struct byahoo_write_ready_data @@ -486,18 +485,17 @@ struct byahoo_write_ready_data  	gpointer data;  }; -void byahoo_write_ready_callback( gpointer data, gint source, GaimInputCondition cond ) +gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condition cond )  {  	struct byahoo_write_ready_data *d = data;  	if( !byahoo_get_gc_by_id( d->id ) ) -	{  		/* WTF doesn't libyahoo clean this up? */ -		ext_yahoo_remove_handler( d->id, d->tag ); -		return; -	} +		return FALSE;  	yahoo_write_ready( d->id, d->fd, d->data ); +	 +	return FALSE;  }  void ext_yahoo_login_response( int id, int succ, char *url ) @@ -686,7 +684,7 @@ int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *dat  		d->data = data;  		inp->d = d; -		d->tag = inp->h = gaim_input_add( fd, GAIM_INPUT_READ, (GaimInputFunction) byahoo_read_ready_callback, (gpointer) d ); +		d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );  	}  	else if( cond == YAHOO_INPUT_WRITE )  	{ @@ -697,7 +695,7 @@ int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *dat  		d->data = data;  		inp->d = d; -		d->tag = inp->h = gaim_input_add( fd, GAIM_INPUT_WRITE, (GaimInputFunction) byahoo_write_ready_callback, (gpointer) d ); +		d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );  	}  	else  	{ @@ -728,7 +726,7 @@ void ext_yahoo_remove_handler( int id, int tag )  		l = l->next;  	} -	gaim_input_remove( tag ); +	b_event_remove( tag );  }  int ext_yahoo_connect_async( int id, char *host, int port, yahoo_connect_callback callback, void *data ) @@ -737,7 +735,7 @@ int ext_yahoo_connect_async( int id, char *host, int port, yahoo_connect_callbac  	int fd;  	d = g_new0( struct byahoo_connect_callback_data, 1 ); -	if( ( fd = proxy_connect( host, port, (GaimInputFunction) byahoo_connect_callback, (gpointer) d ) ) < 0 ) +	if( ( fd = proxy_connect( host, port, (b_event_handler) byahoo_connect_callback, (gpointer) d ) ) < 0 )  	{  		g_free( d );  		return( fd ); | 
