diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2009-12-07 21:54:19 +0000 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2009-12-07 21:54:19 +0000 | 
| commit | 2288705af462b4aca2d56f228bff269eab8d8b5f (patch) | |
| tree | cbdf792579f11297773583cc822548867fdfc19c /lib | |
| parent | aac40178a6669e20855b7f5d3cc6a82cba10042e (diff) | |
| parent | 36cf9fda6a5cc4bcbfe98319b48af636fa142590 (diff) | |
Merging head.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/events_libevent.c | 28 | ||||
| -rw-r--r-- | lib/http_client.c | 19 | ||||
| -rw-r--r-- | lib/http_client.h | 2 | ||||
| -rw-r--r-- | lib/ini.c | 129 | ||||
| -rw-r--r-- | lib/ini.h | 12 | ||||
| -rw-r--r-- | lib/misc.c | 1 | ||||
| -rw-r--r-- | lib/proxy.c | 1 | ||||
| -rw-r--r-- | lib/xmltree.c | 2 | ||||
| -rw-r--r-- | lib/xmltree.h | 2 | 
9 files changed, 135 insertions, 61 deletions
| diff --git a/lib/events_libevent.c b/lib/events_libevent.c index d3403152..cf616576 100644 --- a/lib/events_libevent.c +++ b/lib/events_libevent.c @@ -36,9 +36,11 @@  #include "proxy.h"  static void b_main_restart(); -static guint id_next = 1; +static guint id_next = 1; /* Next ID to be allocated to an event handler. */ +static guint id_cur = 0; /* Event ID that we're currently handling. */ +static guint id_dead; /* Set to 1 if b_event_remove removes id_cur. */  static GHashTable *id_hash; -static int quitting = 0; +static int quitting = 0; /* Prepare to quit, stop handling events. */  /* Since libevent doesn't handle two event handlers for one fd-condition     very well (which happens sometimes when BitlBee changes event handlers @@ -118,7 +120,7 @@ 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; +	gboolean st;  	if( fd >= 0 )  	{ @@ -132,21 +134,30 @@ static void b_event_passthrough( int fd, short event, void *data )  	/* 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; +	id_cur = b_ev->id; +	id_dead = 0;  	if( quitting )  	{ -		b_event_remove( id ); +		b_event_remove( id_cur );  		return;  	} -	if( !b_ev->function( b_ev->data, fd, cond ) ) +	st = b_ev->function( b_ev->data, fd, cond ); +	if( id_dead ) +	{ +		/* This event was killed already, don't touch it! */ +		return; +	} +	else if( !st )  	{  		event_debug( "Handler returned FALSE: " ); -		b_event_remove( id ); +		b_event_remove( id_cur );  	}  	else if( fd == -1 )  	{ +		/* fd == -1 means it was a timer. These can't be auto-repeated +		   so it has to be recreated every time. */  		struct timeval tv;  		tv.tv_sec = b_ev->timeout / 1000; @@ -235,6 +246,9 @@ void b_event_remove( gint id )  	event_debug( "b_event_remove( %d )\n", id );  	if( b_ev )  	{ +		if( id == id_cur ) +			id_dead = TRUE; +		  		g_hash_table_remove( id_hash, &b_ev->id );  		if( b_ev->evinfo.ev_fd >= 0 )  		{ diff --git a/lib/http_client.c b/lib/http_client.c index b00fcf98..aae5645b 100644 --- a/lib/http_client.c +++ b/lib/http_client.c @@ -58,8 +58,8 @@ void *http_dorequest( char *host, int port, int ssl, char *request, http_input_f  	if( error )  	{ -		g_free( req ); -		return( NULL ); +		http_free( req ); +		return NULL;  	}  	req->func = func; @@ -159,10 +159,7 @@ error:  	req->status_string = g_strdup( "Error while writing HTTP request" );  	req->func( req ); -	 -	g_free( req->request ); -	g_free( req ); -	 +	http_free( req );  	return FALSE;  } @@ -443,11 +440,15 @@ cleanup:  		closesocket( req->fd );  	req->func( req ); -	 +	http_free( req ); +	return FALSE; +} + +void http_free( struct http_request *req ) +{  	g_free( req->request );  	g_free( req->reply_headers );  	g_free( req->status_string );  	g_free( req ); -	 -	return FALSE;  } + diff --git a/lib/http_client.h b/lib/http_client.h index 78d6dbd1..d73894a4 100644 --- a/lib/http_client.h +++ b/lib/http_client.h @@ -80,3 +80,5 @@ struct http_request     are also supported (using ssl_client). */  void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );  void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ); + +void http_free( struct http_request *req ); @@ -1,7 +1,7 @@    /********************************************************************\    * BitlBee -- An IRC to other IM-networks gateway                     *    *                                                                    * -  * Copyright 2002-2005 Wilmer van der Gaast and others                * +  * Copyright 2002-2008 Wilmer van der Gaast and others                *    \********************************************************************/  /* INI file reading code						*/ @@ -27,64 +27,119 @@  ini_t *ini_open( char *file )  { -	ini_t *ini = g_new0( ini_t, 1 ); +	int fd; +	ini_t *ini = NULL; +	struct stat fi; -	if( ( ini->fp = fopen( file, "r" ) ) == NULL ) +	if( ( fd = open( file, O_RDONLY ) ) != -1 && +	    fstat( fd, &fi ) == 0 && +	    fi.st_size <= 16384 && +	    ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) && +	    read( fd, ini->file, fi.st_size ) == fi.st_size )  	{ -		g_free( ini ); -		return( NULL ); +		memset( ini, 0, sizeof( ini_t ) ); +		ini->size = fi.st_size; +		ini->file[ini->size] = 0; +		ini->cur = ini->file; +		ini->c_section = ""; +		 +		close( fd ); +		 +		return ini;  	} + +	if( fd >= 0 ) +		close( fd ); -	return( ini ); +	ini_close( ini ); + +	return NULL; +} + +/* Strips leading and trailing whitespace and returns a pointer to the first +   non-ws character of the given string. */ +static char *ini_strip_whitespace( char *in ) +{ +	char *e; + +	while( isspace( *in ) ) +		in++; + +	e = in + strlen( in ) - 1; +	while( e > in && isspace( *e ) ) +		e--; +	e[1] = 0; +	 +	return in;  }  int ini_read( ini_t *file )  { -	char key[MAX_STRING], s[MAX_STRING], *t; -	int i; +	char *s; -	while( !feof( file->fp ) ) +	while( file->cur && file->cur < file->file + file->size )  	{ -		*s = 0; -		fscanf( file->fp, "%127[^\n#]s", s ); -		fscanf( file->fp, "%*[^\n]s" ); -		fgetc( file->fp );		/* Skip newline		*/ -		file->line ++; -		if( strchr( s, '=' ) ) +		char *e, *next; +		 +		file->line++; + +		/* Find the end of line */ +		if( ( e = strchr( file->cur, '\n' ) ) != NULL ) +		{ +			*e = 0; +			next = e + 1; +		} +		else  		{ -			sscanf( s, "%[^ =]s", key ); -			if( ( t = strchr( key, '.' ) ) ) +			/* No more lines. */ +			e = file->cur + strlen( file->cur ); +			next = NULL; +		} +		 +		/* Comment? */ +		if( ( s = strchr( file->cur, '#' ) ) != NULL ) +			*s = 0; +		 +		file->cur = ini_strip_whitespace( file->cur ); +		 +		if( *file->cur == '[' ) +		{ +			file->cur++; +			if( ( s = strchr( file->cur, ']' ) ) != NULL )  			{ -				*t = 0; -				strcpy( file->section, key ); -				t ++; +				*s = 0; +				file->c_section = file->cur; +			} +		} +		else if( ( s = strchr( file->cur, '=' ) ) != NULL ) +		{ +			*s = 0; +			file->key = ini_strip_whitespace( file->cur ); +			file->value = ini_strip_whitespace( s + 1 ); +			 +			if( ( s = strchr( file->key, '.' ) ) != NULL ) +			{ +				*s = 0; +				file->section = file->key; +				file->key = s + 1;  			}  			else  			{ -				strcpy( file->section, file->c_section ); -				t = key; +				file->section = file->c_section;  			} -			sscanf( t, "%s", file->key ); -			t = strchr( s, '=' ) + 1; -			for( i = 0; t[i] == ' '; i ++ ); -			strcpy( file->value, &t[i] ); -			for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- ) -				file->value[i] = 0; -			return( 1 ); -		} -		else if( ( t = strchr( s, '[' ) ) ) -		{ -			strcpy( file->c_section, t + 1 ); -			t = strchr( file->c_section, ']' ); -			*t = 0; +			file->cur = next; +			return 1;  		} +		/* else: noise/comment/etc, let's just ignore it. */ + +		file->cur = next;  	} -	return( 0 ); +	 +	return 0;  }  void ini_close( ini_t *file )  { -	fclose( file->fp );  	g_free( file );  } @@ -28,12 +28,14 @@  typedef struct  { -	FILE *fp;  	int line; -	char c_section[MAX_STRING]; -	char section[MAX_STRING]; -	char key[MAX_STRING]; -	char value[MAX_STRING]; +	char *c_section; +	char *section; +	char *key; +	char *value; +	int size; +	char *cur, *tok; +	char file[];  } ini_t;  ini_t *ini_open( char *file ); @@ -45,6 +45,7 @@  #include <resolv.h>  #endif +#include "md5.h"  #include "ssl_client.h"  void strip_linefeed(gchar *text) diff --git a/lib/proxy.c b/lib/proxy.c index 91493557..e52837fe 100644 --- a/lib/proxy.c +++ b/lib/proxy.c @@ -557,7 +557,6 @@ int proxy_connect(const char *host, int port, b_event_handler func, gpointer dat  	else if (proxytype == PROXY_SOCKS5)  		return proxy_connect_socks5(host, port, phb); -	if (phb->host) g_free(phb);  	g_free(phb);  	return -1;  } diff --git a/lib/xmltree.c b/lib/xmltree.c index e65b4f41..67fe46e1 100644 --- a/lib/xmltree.c +++ b/lib/xmltree.c @@ -471,7 +471,7 @@ char *xt_find_attr( struct xt_node *node, const char *key )  	return node->attr[i].value;  } -struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children ) +struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children )  {  	struct xt_node *node, *c; diff --git a/lib/xmltree.h b/lib/xmltree.h index 10677412..34e3be68 100644 --- a/lib/xmltree.h +++ b/lib/xmltree.h @@ -89,7 +89,7 @@ void xt_free( struct xt_parser *xt );  struct xt_node *xt_find_node( struct xt_node *node, const char *name );  char *xt_find_attr( struct xt_node *node, const char *key ); -struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children ); +struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children );  void xt_add_child( struct xt_node *parent, struct xt_node *child );  void xt_add_attr( struct xt_node *node, const char *key, const char *value );  int xt_remove_attr( struct xt_node *node, const char *key ); | 
