diff options
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 | 2 | ||||
-rw-r--r-- | lib/proxy.c | 1 | ||||
-rw-r--r-- | lib/xmltree.c | 2 | ||||
-rw-r--r-- | lib/xmltree.h | 2 |
9 files changed, 136 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 ); @@ -46,6 +46,7 @@ #include <resolv.h> #endif +#include "md5.h" #include "ssl_client.h" void strip_linefeed(gchar *text) @@ -88,6 +89,7 @@ static const htmlentity_t ent[] = { "lt", "<" }, { "gt", ">" }, { "amp", "&" }, + { "apos", "'" }, { "quot", "\"" }, { "aacute", "á" }, { "eacute", "é" }, 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 ); |