aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/arc.c170
-rw-r--r--lib/arc.h11
-rw-r--r--lib/base64.c6
-rw-r--r--lib/base64.h8
-rw-r--r--lib/events.h10
-rw-r--r--lib/events_glib.c79
-rw-r--r--lib/events_libevent.c251
-rw-r--r--lib/ftutil.c110
-rw-r--r--lib/ftutil.h3
-rw-r--r--lib/http_client.c839
-rw-r--r--lib/http_client.h35
-rw-r--r--lib/ini.c104
-rw-r--r--lib/ini.h11
-rw-r--r--lib/json.c1640
-rw-r--r--lib/json.h313
-rw-r--r--lib/json_util.c41
-rw-r--r--lib/json_util.h14
-rw-r--r--lib/md5.c2
-rw-r--r--lib/misc.c692
-rw-r--r--lib/misc.h84
-rw-r--r--lib/ns_parse.c139
-rw-r--r--lib/oauth.c507
-rw-r--r--lib/oauth.h47
-rw-r--r--lib/oauth2.c212
-rw-r--r--lib/oauth2.h15
-rw-r--r--lib/proxy.c149
-rw-r--r--lib/proxy.h6
-rw-r--r--lib/sha1.c90
-rw-r--r--lib/ssl_client.h29
-rw-r--r--lib/ssl_gnutls.c488
-rw-r--r--lib/ssl_nss.c115
-rw-r--r--lib/ssl_openssl.c281
-rw-r--r--lib/url.c94
-rw-r--r--lib/url.h15
-rw-r--r--lib/xmltree.c731
-rw-r--r--lib/xmltree.h80
36 files changed, 3716 insertions, 3705 deletions
diff --git a/lib/arc.c b/lib/arc.c
index cf50c51f..4787e30e 100644
--- a/lib/arc.c
+++ b/lib/arc.c
@@ -21,20 +21,20 @@
* *
\***************************************************************************/
-/*
+/*
This file implements ArcFour-encryption, which will mainly be used to
save IM passwords safely in the new XML-format. Possibly other uses will
come up later. It's supposed to be quite reliable (thanks to the use of a
6-byte IV/seed), certainly compared to the old format. The only realistic
way to crack BitlBee passwords now is to use a sniffer to get your hands
on the user's password.
-
+
If you see that something's wrong in this implementation (I asked a
couple of people to look at it already, but who knows), please tell me.
-
+
The reason I picked ArcFour is because it's pretty simple but effective,
so it will work without adding several KBs or an extra library dependency.
-
+
(ArcFour is an RC4-compatible cipher. See for details:
http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt)
*/
@@ -56,37 +56,37 @@
many bytes we'll request before we'll really use them for encryption. */
#define ARC_CYCLES 1024
-struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles )
+struct arc_state *arc_keymaker(unsigned char *key, int kl, int cycles)
{
struct arc_state *st;
int i, j, tmp;
unsigned char S2[256];
-
- st = g_malloc( sizeof( struct arc_state ) );
+
+ st = g_malloc(sizeof(struct arc_state));
st->i = st->j = 0;
- if( kl <= 0 )
- kl = strlen( (char*) key );
-
- for( i = 0; i < 256; i ++ )
- {
+ if (kl <= 0) {
+ kl = strlen((char *) key);
+ }
+
+ for (i = 0; i < 256; i++) {
st->S[i] = i;
- S2[i] = key[i%kl];
+ S2[i] = key[i % kl];
}
-
- for( i = j = 0; i < 256; i ++ )
- {
- j = ( j + st->S[i] + S2[i] ) & 0xff;
+
+ for (i = j = 0; i < 256; i++) {
+ j = (j + st->S[i] + S2[i]) & 0xff;
tmp = st->S[i];
st->S[i] = st->S[j];
st->S[j] = tmp;
}
-
- memset( S2, 0, 256 );
+
+ memset(S2, 0, 256);
i = j = 0;
-
- for( i = 0; i < cycles; i ++ )
- arc_getbyte( st );
-
+
+ for (i = 0; i < cycles; i++) {
+ arc_getbyte(st);
+ }
+
return st;
}
@@ -95,23 +95,23 @@ struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles )
a stream of bytes after you give it a key. Just get a byte from it and
xor it with your cleartext. To decrypt, just give it the same key again
and start xorring.
-
+
The function above initializes the byte generator, the next function can
be used to get bytes from the generator (and shuffle things a bit).
*/
-unsigned char arc_getbyte( struct arc_state *st )
+unsigned char arc_getbyte(struct arc_state *st)
{
unsigned char tmp;
-
+
/* Unfortunately the st-> stuff doesn't really improve readability here... */
- st->i ++;
+ st->i++;
st->j += st->S[st->i];
tmp = st->S[st->i];
st->S[st->i] = st->S[st->j];
st->S[st->j] = tmp;
tmp = (st->S[st->i] + st->S[st->j]) & 0xff;
-
+
return st->S[tmp];
}
@@ -121,103 +121,105 @@ unsigned char arc_getbyte( struct arc_state *st )
by default) random bytes to the password before setting up the state
structures. These 6 bytes are also saved in the results, because of
course we'll need them in arc_decode().
-
+
Because the length of the resulting string is unknown to the caller,
it should pass a char**. Since the encode/decode functions allocate
memory for the string, make sure the char** points at a NULL-pointer
(or at least to something you already free()d), or you'll leak
memory. And of course, don't forget to free() the result when you
don't need it anymore.
-
+
Both functions return the number of bytes in the result string.
-
+
Note that if you use the pad_to argument, you will need zero-termi-
nation to find back the original string length after decryption. So
it shouldn't be used if your string contains \0s by itself!
*/
-int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to )
+int arc_encode(char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to)
{
struct arc_state *st;
unsigned char *key;
char *padded = NULL;
int key_len, i, padded_len;
-
- key_len = strlen( password ) + ARC_IV_LEN;
- if( clear_len <= 0 )
- clear_len = strlen( clear );
-
+
+ key_len = strlen(password) + ARC_IV_LEN;
+ if (clear_len <= 0) {
+ clear_len = strlen(clear);
+ }
+
/* Pad the string to the closest multiple of pad_to. This makes it
impossible to see the exact length of the password. */
- if( pad_to > 0 && ( clear_len % pad_to ) > 0 )
- {
- padded_len = clear_len + pad_to - ( clear_len % pad_to );
- padded = g_malloc( padded_len );
- memcpy( padded, clear, clear_len );
-
+ if (pad_to > 0 && (clear_len % pad_to) > 0) {
+ padded_len = clear_len + pad_to - (clear_len % pad_to);
+ padded = g_malloc(padded_len);
+ memcpy(padded, clear, clear_len);
+
/* First a \0 and then random data, so we don't have to do
anything special when decrypting. */
padded[clear_len] = 0;
- random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 );
-
+ random_bytes((unsigned char *) padded + clear_len + 1, padded_len - clear_len - 1);
+
clear = padded;
clear_len = padded_len;
}
-
+
/* Prepare buffers and the key + IV */
- *crypt = g_malloc( clear_len + ARC_IV_LEN );
- key = g_malloc( key_len );
- strcpy( (char*) key, password );
-
+ *crypt = g_malloc(clear_len + ARC_IV_LEN);
+ key = g_malloc(key_len);
+ strcpy((char *) key, password);
+
/* Add the salt. Save it for later (when decrypting) and, of course,
add it to the encryption key. */
- random_bytes( crypt[0], ARC_IV_LEN );
- memcpy( key + key_len - ARC_IV_LEN, crypt[0], ARC_IV_LEN );
-
+ random_bytes(crypt[0], ARC_IV_LEN);
+ memcpy(key + key_len - ARC_IV_LEN, crypt[0], ARC_IV_LEN);
+
/* Generate the initial S[] from the IVed key. */
- st = arc_keymaker( key, key_len, ARC_CYCLES );
- g_free( key );
-
- for( i = 0; i < clear_len; i ++ )
- crypt[0][i+ARC_IV_LEN] = clear[i] ^ arc_getbyte( st );
-
- g_free( st );
- g_free( padded );
-
+ st = arc_keymaker(key, key_len, ARC_CYCLES);
+ g_free(key);
+
+ for (i = 0; i < clear_len; i++) {
+ crypt[0][i + ARC_IV_LEN] = clear[i] ^ arc_getbyte(st);
+ }
+
+ g_free(st);
+ g_free(padded);
+
return clear_len + ARC_IV_LEN;
}
-int arc_decode( unsigned char *crypt, int crypt_len, char **clear, const char *password )
+int arc_decode(unsigned char *crypt, int crypt_len, char **clear, const char *password)
{
struct arc_state *st;
unsigned char *key;
int key_len, clear_len, i;
-
- key_len = strlen( password ) + ARC_IV_LEN;
+
+ key_len = strlen(password) + ARC_IV_LEN;
clear_len = crypt_len - ARC_IV_LEN;
-
- if( clear_len < 0 )
- {
- *clear = g_strdup( "" );
+
+ if (clear_len < 0) {
+ *clear = g_strdup("");
return -1;
}
-
+
/* Prepare buffers and the key + IV */
- *clear = g_malloc( clear_len + 1 );
- key = g_malloc( key_len );
- strcpy( (char*) key, password );
- for( i = 0; i < ARC_IV_LEN; i ++ )
- key[key_len-ARC_IV_LEN+i] = crypt[i];
-
+ *clear = g_malloc(clear_len + 1);
+ key = g_malloc(key_len);
+ strcpy((char *) key, password);
+ for (i = 0; i < ARC_IV_LEN; i++) {
+ key[key_len - ARC_IV_LEN + i] = crypt[i];
+ }
+
/* Generate the initial S[] from the IVed key. */
- st = arc_keymaker( key, key_len, ARC_CYCLES );
- g_free( key );
-
- for( i = 0; i < clear_len; i ++ )
- clear[0][i] = crypt[i+ARC_IV_LEN] ^ arc_getbyte( st );
+ st = arc_keymaker(key, key_len, ARC_CYCLES);
+ g_free(key);
+
+ for (i = 0; i < clear_len; i++) {
+ clear[0][i] = crypt[i + ARC_IV_LEN] ^ arc_getbyte(st);
+ }
clear[0][i] = 0; /* Nice to have for plaintexts. */
-
- g_free( st );
-
+
+ g_free(st);
+
return clear_len;
}
diff --git a/lib/arc.h b/lib/arc.h
index a58c3490..5edcc65a 100644
--- a/lib/arc.h
+++ b/lib/arc.h
@@ -24,8 +24,7 @@
/* See arc.c for more information. */
-struct arc_state
-{
+struct arc_state {
unsigned char S[256];
unsigned char i, j;
};
@@ -34,7 +33,7 @@ struct arc_state
#define G_GNUC_MALLOC
#endif
-G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );
-unsigned char arc_getbyte( struct arc_state *st );
-int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to );
-int arc_decode( unsigned char *crypt, int crypt_len, char **clear, const char *password );
+G_GNUC_MALLOC struct arc_state *arc_keymaker(unsigned char *key, int kl, int cycles);
+unsigned char arc_getbyte(struct arc_state *st);
+int arc_encode(char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to);
+int arc_decode(unsigned char *crypt, int crypt_len, char **clear, const char *password);
diff --git a/lib/base64.c b/lib/base64.c
index 884f00c0..0c36153f 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -28,7 +28,7 @@
char *tobase64(const char *text)
{
- return base64_encode((const unsigned char *)text, strlen(text));
+ return base64_encode((const unsigned char *) text, strlen(text));
}
char *base64_encode(const unsigned char *in, int len)
@@ -41,13 +41,15 @@ char *base64_encode(const unsigned char *in, int len)
char *frombase64(const char *in)
{
unsigned char *out;
+
base64_decode(in, &out);
- return (char*) out;
+ return (char *) out;
}
int base64_decode(const char *in, unsigned char **out)
{
gsize len;
+
*out = g_base64_decode(in, &len);
/* Some silly functions expect it to be zero terminated */
diff --git a/lib/base64.h b/lib/base64.h
index dc199c55..233e07b9 100644
--- a/lib/base64.h
+++ b/lib/base64.h
@@ -25,7 +25,7 @@
#include <glib.h>
#include <gmodule.h>
-G_MODULE_EXPORT char *tobase64( const char *text );
-G_MODULE_EXPORT char *base64_encode( const unsigned char *in, int len );
-G_MODULE_EXPORT char *frombase64( const char *in );
-G_MODULE_EXPORT int base64_decode( const char *in, unsigned char **out );
+G_MODULE_EXPORT char *tobase64(const char *text);
+G_MODULE_EXPORT char *base64_encode(const unsigned char *in, int len);
+G_MODULE_EXPORT char *frombase64(const char *in);
+G_MODULE_EXPORT int base64_decode(const char *in, unsigned char **out);
diff --git a/lib/events.h b/lib/events.h
index 0446aa0f..193065f9 100644
--- a/lib/events.h
+++ b/lib/events.h
@@ -25,7 +25,7 @@
ground and calls a callback function once the connection is ready to use.
This function (proxy_connect()) can be found in proxy.c. (It also
transparently handles HTTP/SOCKS proxies, when necessary.)
-
+
This file offers some extra event handling toys, which will be handled
by GLib or libevent. The advantage of using libevent is that it can use
more advanced I/O polling functions like epoll() in recent Linux
@@ -46,9 +46,9 @@
the given callback function. */
typedef enum {
B_EV_IO_READ = 1 << 0,
- B_EV_IO_WRITE = 1 << 1,
- B_EV_FLAG_FORCE_ONCE = 1 << 16,
- B_EV_FLAG_FORCE_REPEAT = 1 << 17,
+ B_EV_IO_WRITE = 1 << 1,
+ B_EV_FLAG_FORCE_ONCE = 1 << 16,
+ B_EV_FLAG_FORCE_REPEAT = 1 << 17,
} b_input_condition;
typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond);
@@ -58,7 +58,7 @@ typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition co
#define GAIM_ERR_COND (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
/* #define event_debug( x... ) printf( x ) */
-#define event_debug( x... )
+#define event_debug(x ...)
/* Call this once when the program starts. It'll initialize the event handler
library (if necessary) and then return immediately. */
diff --git a/lib/events_glib.c b/lib/events_glib.c
index c6bb3d9e..404031e8 100644
--- a/lib/events_glib.c
+++ b/lib/events_glib.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2006 Wilmer van der Gaast and others *
@@ -49,18 +49,19 @@ static GMainLoop *loop = NULL;
void b_main_init()
{
- if( loop == NULL )
- loop = g_main_new( FALSE );
+ if (loop == NULL) {
+ loop = g_main_new(FALSE);
+ }
}
void b_main_run()
{
- g_main_run( loop );
+ g_main_run(loop);
}
void b_main_quit()
{
- g_main_quit( loop );
+ g_main_quit(loop);
}
static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
@@ -68,33 +69,38 @@ static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpoin
GaimIOClosure *closure = data;
b_input_condition gaim_cond = 0;
gboolean st;
-
- if (condition & G_IO_NVAL)
+
+ if (condition & G_IO_NVAL) {
return FALSE;
+ }
- if (condition & GAIM_READ_COND)
+ if (condition & GAIM_READ_COND) {
gaim_cond |= B_EV_IO_READ;
- if (condition & GAIM_WRITE_COND)
+ }
+ if (condition & GAIM_WRITE_COND) {
gaim_cond |= B_EV_IO_WRITE;
-
- event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data );
+ }
+
+ 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" );
-
- if (closure->flags & B_EV_FLAG_FORCE_ONCE)
+
+ if (!st) {
+ event_debug("Returned FALSE, cancelling.\n");
+ }
+
+ if (closure->flags & B_EV_FLAG_FORCE_ONCE) {
return FALSE;
- else if (closure->flags & B_EV_FLAG_FORCE_REPEAT)
+ } else if (closure->flags & B_EV_FLAG_FORCE_REPEAT) {
return TRUE;
- else
+ } else {
return st;
+ }
}
static void gaim_io_destroy(gpointer data)
{
- event_debug( "gaim_io_destroy( 0x%x )\n", data );
+ event_debug("gaim_io_destroy( 0x%x )\n", data);
g_free(data);
}
@@ -104,22 +110,24 @@ gint b_input_add(gint source, b_input_condition condition, b_event_handler funct
GIOChannel *channel;
GIOCondition cond = 0;
int st;
-
+
closure->function = function;
closure->data = data;
closure->flags = condition;
-
- if (condition & B_EV_IO_READ)
+
+ if (condition & B_EV_IO_READ) {
cond |= GAIM_READ_COND;
- if (condition & B_EV_IO_WRITE)
+ }
+ if (condition & B_EV_IO_WRITE) {
cond |= GAIM_WRITE_COND;
-
+ }
+
channel = g_io_channel_unix_new(source);
st = 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 (%p)\n", source, condition, function, data, st, closure );
-
+
+ event_debug("b_input_add( %d, %d, 0x%x, 0x%x ) = %d (%p)\n", source, condition, function, data, st, closure);
+
g_io_channel_unref(channel);
return st;
}
@@ -130,21 +138,22 @@ gint b_timeout_add(gint timeout, b_event_handler func, gpointer data)
really the same, but they're "compatible". ;-) It will do
for now, BitlBee only looks at the "data" argument. */
gint st = g_timeout_add(timeout, (GSourceFunc) func, data);
-
- event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st );
-
+
+ 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)
+ event_debug("b_event_remove( %d )\n", tag);
+
+ if (tag > 0) {
g_source_remove(tag);
+ }
}
-void closesocket( int fd )
+void closesocket(int fd)
{
- close( fd );
+ close(fd);
}
diff --git a/lib/events_libevent.c b/lib/events_libevent.c
index cf4eee8f..854af010 100644
--- a/lib/events_libevent.c
+++ b/lib/events_libevent.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2006 Wilmer van der Gaast and others *
@@ -52,8 +52,7 @@ static GHashTable *write_hash;
struct event_base *leh;
struct event_base *old_leh;
-struct b_event_data
-{
+struct b_event_data {
guint id;
struct event evinfo;
gint timeout;
@@ -64,47 +63,44 @@ struct b_event_data
void b_main_init()
{
- if( leh != NULL )
- {
+ if (leh != NULL) {
/* Clean up the hash tables? */
-
+
b_main_restart();
old_leh = leh;
}
-
+
leh = event_init();
-
- 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 );
+
+ 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()
{
/* This while loop is necessary to exit the event loop and start a
different one (necessary for ForkDaemon mode). */
- while( event_base_dispatch( leh ) == 0 && !quitting )
- {
- if( old_leh != NULL )
- {
+ while (event_base_dispatch(leh) == 0 && !quitting) {
+ if (old_leh != NULL) {
/* For some reason this just isn't allowed...
Possibly a bug in older versions, will see later.
event_base_free( old_leh ); */
old_leh = NULL;
}
-
- event_debug( "New event loop.\n" );
+
+ event_debug("New event loop.\n");
}
}
static void b_main_restart()
{
struct timeval tv;
-
- memset( &tv, 0, sizeof( struct timeval ) );
- event_base_loopexit( leh, &tv );
-
- event_debug( "b_main_restart()\n" );
+
+ memset(&tv, 0, sizeof(struct timeval));
+ event_base_loopexit(leh, &tv);
+
+ event_debug("b_main_restart()\n");
}
void b_main_quit()
@@ -113,182 +109,175 @@ void b_main_quit()
libevent sometimes generates events before really quitting,
we want to stop them. */
quitting = 1;
-
+
b_main_restart();
}
-static void b_event_passthrough( int fd, short event, void *data )
+static void b_event_passthrough(int fd, short event, void *data)
{
struct b_event_data *b_ev = data;
b_input_condition cond = 0;
gboolean st;
-
- if( fd >= 0 )
- {
- if( event & EV_READ )
+
+ if (fd >= 0) {
+ if (event & EV_READ) {
cond |= B_EV_IO_READ;
- if( event & EV_WRITE )
+ }
+ if (event & EV_WRITE) {
cond |= B_EV_IO_WRITE;
+ }
}
-
- event_debug( "b_event_passthrough( %d, %d, 0x%x ) (%d)\n", fd, event, (int) data, b_ev->id );
-
+
+ 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_cur = b_ev->id;
id_dead = 0;
-
- if( quitting )
- {
- b_event_remove( id_cur );
+
+ if (quitting) {
+ b_event_remove(id_cur);
return;
}
-
- st = b_ev->function( b_ev->data, fd, cond );
- if( id_dead )
- {
+
+ 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 && !( b_ev->flags & B_EV_FLAG_FORCE_REPEAT ) )
- {
- event_debug( "Handler returned FALSE: " );
- b_event_remove( id_cur );
- }
- else if( fd == -1 )
- {
+ } else if (!st && !(b_ev->flags & B_EV_FLAG_FORCE_REPEAT)) {
+ event_debug("Handler returned FALSE: ");
+ 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;
- tv.tv_usec = ( b_ev->timeout % 1000 ) * 1000;
-
- evtimer_add( &b_ev->evinfo, &tv );
+ 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 )
+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 & B_EV_IO_READ && ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) ||
- ( condition & B_EV_IO_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) )
- {
+
+ event_debug("b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data);
+
+ if ((condition & B_EV_IO_READ && (b_ev = g_hash_table_lookup(read_hash, &fd))) ||
+ (condition & B_EV_IO_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 );
-
+ 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
- {
+ } else {
GIOCondition out_cond;
-
- event_debug( "(new) = %d\n", id_next );
-
- b_ev = g_new0( struct b_event_data, 1 );
+
+ 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 & B_EV_IO_READ )
+ if (condition & B_EV_IO_READ) {
out_cond |= EV_READ;
- if( condition & B_EV_IO_WRITE )
+ }
+ if (condition & B_EV_IO_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 );
+ }
+
+ 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);
+ }
}
-
+
b_ev->flags = condition;
- g_hash_table_insert( id_hash, &b_ev->id, 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 )
+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 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 );
-
+ 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 )
+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 )
- {
- if( id == id_cur )
+ struct b_event_data *b_ev = g_hash_table_lookup(id_hash, &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 )
- {
- 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" );
+
+ 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 )
+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(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 );
+ 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 );
+
+ close(fd);
}
diff --git a/lib/ftutil.c b/lib/ftutil.c
index 3b29d2f4..7606890f 100644
--- a/lib/ftutil.c
+++ b/lib/ftutil.c
@@ -28,117 +28,107 @@
#include "lib/ftutil.h"
#define ASSERTSOCKOP(op, msg) \
- if( (op) == -1 ) {\
- g_snprintf( errmsg, sizeof( errmsg ), msg ": %s", strerror( errno ) ); \
+ if ((op) == -1) { \
+ g_snprintf(errmsg, sizeof(errmsg), msg ": %s", strerror(errno)); \
return -1; }
/*
* Creates a listening socket and returns it in saddr_ptr.
*/
-int ft_listen( struct sockaddr_storage *saddr_ptr, char *host, char *port, int copy_fd, int for_bitlbee_client, char **errptr )
+int ft_listen(struct sockaddr_storage *saddr_ptr, char *host, char *port, int copy_fd, int for_bitlbee_client,
+ char **errptr)
{
int fd, gret, saddrlen;
struct addrinfo hints, *rp;
- socklen_t ssize = sizeof( struct sockaddr_storage );
+ socklen_t ssize = sizeof(struct sockaddr_storage);
struct sockaddr_storage saddrs, *saddr = &saddrs;
static char errmsg[1024];
char *ftlisten = global.conf->ft_listen;
- if( errptr )
+ if (errptr) {
*errptr = errmsg;
+ }
- strcpy( port, "0" );
+ strcpy(port, "0");
/* Format is <IP-A>[:<Port-A>];<IP-B>[:<Port-B>] where
* A is for connections with the bitlbee client (DCC)
* and B is for connections with IM peers.
*/
- if( ftlisten )
- {
- char *scolon = strchr( ftlisten, ';' );
+ if (ftlisten) {
+ char *scolon = strchr(ftlisten, ';');
char *colon;
- if( scolon )
- {
- if( for_bitlbee_client )
- {
+ if (scolon) {
+ if (for_bitlbee_client) {
*scolon = '\0';
- strncpy( host, ftlisten, HOST_NAME_MAX );
+ strncpy(host, ftlisten, HOST_NAME_MAX);
*scolon = ';';
+ } else {
+ strncpy(host, scolon + 1, HOST_NAME_MAX);
}
- else
- {
- strncpy( host, scolon + 1, HOST_NAME_MAX );
- }
- }
- else
- {
- strncpy( host, ftlisten, HOST_NAME_MAX );
+ } else {
+ strncpy(host, ftlisten, HOST_NAME_MAX);
}
- if( ( colon = strchr( host, ':' ) ) )
- {
+ if ((colon = strchr(host, ':'))) {
*colon = '\0';
- strncpy( port, colon + 1, 5 );
+ strncpy(port, colon + 1, 5);
}
- }
- else if( copy_fd >= 0 && getsockname( copy_fd, (struct sockaddr*) &saddrs, &ssize ) == 0 &&
- ( saddrs.ss_family == AF_INET || saddrs.ss_family == AF_INET6 ) &&
- getnameinfo( (struct sockaddr*) &saddrs, ssize, host, HOST_NAME_MAX,
- NULL, 0, NI_NUMERICHOST ) == 0 )
- {
+ } else if (copy_fd >= 0 && getsockname(copy_fd, (struct sockaddr*) &saddrs, &ssize) == 0 &&
+ (saddrs.ss_family == AF_INET || saddrs.ss_family == AF_INET6) &&
+ getnameinfo((struct sockaddr*) &saddrs, ssize, host, HOST_NAME_MAX,
+ NULL, 0, NI_NUMERICHOST) == 0) {
/* We just took our local address on copy_fd, which is likely to be a
sensible address from which we can do a file transfer now - the
most sensible we can get easily. */
- }
- else
- {
- ASSERTSOCKOP( gethostname( host, HOST_NAME_MAX + 1 ), "gethostname()" );
+ } else {
+ ASSERTSOCKOP(gethostname(host, HOST_NAME_MAX + 1), "gethostname()");
}
- memset( &hints, 0, sizeof( struct addrinfo ) );
+ memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
- if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) != 0 )
- {
- sprintf( errmsg, "getaddrinfo() failed: %s", gai_strerror( gret ) );
+ if ((gret = getaddrinfo(host, port, &hints, &rp)) != 0) {
+ sprintf(errmsg, "getaddrinfo() failed: %s", gai_strerror(gret));
return -1;
}
saddrlen = rp->ai_addrlen;
- memcpy( saddr, rp->ai_addr, saddrlen );
+ memcpy(saddr, rp->ai_addr, saddrlen);
- freeaddrinfo( rp );
+ freeaddrinfo(rp);
- ASSERTSOCKOP( fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" );
- ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, saddrlen ), "Binding socket" );
- ASSERTSOCKOP( listen( fd, 1 ), "Making socket listen" );
+ ASSERTSOCKOP(fd = socket(saddr->ss_family, SOCK_STREAM, 0), "Opening socket");
+ ASSERTSOCKOP(bind(fd, ( struct sockaddr *) saddr, saddrlen), "Binding socket");
+ ASSERTSOCKOP(listen(fd, 1), "Making socket listen");
- if ( !inet_ntop( saddr->ss_family, saddr->ss_family == AF_INET ?
- ( void * )&( ( struct sockaddr_in * ) saddr )->sin_addr.s_addr :
- ( void * )&( ( struct sockaddr_in6 * ) saddr )->sin6_addr.s6_addr,
- host, HOST_NAME_MAX ) )
- {
- strcpy( errmsg, "inet_ntop failed on listening socket" );
+ if (!inet_ntop(saddr->ss_family, saddr->ss_family == AF_INET ?
+ ( void * ) &(( struct sockaddr_in * ) saddr)->sin_addr.s_addr :
+ ( void * ) &(( struct sockaddr_in6 * ) saddr)->sin6_addr.s6_addr,
+ host, HOST_NAME_MAX)) {
+ strcpy(errmsg, "inet_ntop failed on listening socket");
return -1;
}
- ssize = sizeof( struct sockaddr_storage );
- ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" );
+ ssize = sizeof(struct sockaddr_storage);
+ ASSERTSOCKOP(getsockname(fd, ( struct sockaddr *) saddr, &ssize), "Getting socket name");
- if( saddr->ss_family == AF_INET )
- g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in *) saddr )->sin_port ) );
- else
- g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in6 *) saddr )->sin6_port ) );
+ if (saddr->ss_family == AF_INET) {
+ g_snprintf(port, 6, "%d", ntohs(((struct sockaddr_in *) saddr)->sin_port));
+ } else {
+ g_snprintf(port, 6, "%d", ntohs(((struct sockaddr_in6 *) saddr)->sin6_port));
+ }
- if( saddr_ptr )
- memcpy( saddr_ptr, saddr, saddrlen );
+ if (saddr_ptr) {
+ memcpy(saddr_ptr, saddr, saddrlen);
+ }
/* I hate static-length strings.. */
- host[HOST_NAME_MAX-1] = '\0';
+ host[HOST_NAME_MAX - 1] = '\0';
port[5] = '\0';
-
+
return fd;
}
diff --git a/lib/ftutil.h b/lib/ftutil.h
index 09c1104e..d8317b2f 100644
--- a/lib/ftutil.h
+++ b/lib/ftutil.h
@@ -37,4 +37,5 @@
/* This function should be used with care. host should be AT LEAST a
char[HOST_NAME_MAX+1] and port AT LEAST a char[6]. */
-int ft_listen( struct sockaddr_storage *saddr_ptr, char *host, char *port, int copy_fd, int for_bitlbee_client, char **errptr );
+int ft_listen(struct sockaddr_storage *saddr_ptr, char *host, char *port, int copy_fd, int for_bitlbee_client,
+ char **errptr);
diff --git a/lib/http_client.c b/lib/http_client.c
index 2481997a..1dc5947a 100644
--- a/lib/http_client.c
+++ b/lib/http_client.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2013 Wilmer van der Gaast and others *
@@ -31,165 +31,159 @@
#include "sock.h"
-static gboolean http_connected( gpointer data, int source, b_input_condition cond );
-static gboolean http_ssl_connected( gpointer data, int returncode, void *source, b_input_condition cond );
-static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond );
-static void http_free( struct http_request *req );
+static gboolean http_connected(gpointer data, int source, b_input_condition cond);
+static gboolean http_ssl_connected(gpointer data, int returncode, void *source, b_input_condition cond);
+static gboolean http_incoming_data(gpointer data, int source, b_input_condition cond);
+static void http_free(struct http_request *req);
-struct http_request *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data )
+struct http_request *http_dorequest(char *host, int port, int ssl, char *request, http_input_function func,
+ gpointer data)
{
struct http_request *req;
int error = 0;
-
- req = g_new0( struct http_request, 1 );
-
- if( ssl )
- {
- req->ssl = ssl_connect( host, port, TRUE, http_ssl_connected, req );
- if( req->ssl == NULL )
+
+ req = g_new0(struct http_request, 1);
+
+ if (ssl) {
+ req->ssl = ssl_connect(host, port, TRUE, http_ssl_connected, req);
+ if (req->ssl == NULL) {
error = 1;
- }
- else
- {
- req->fd = proxy_connect( host, port, http_connected, req );
- if( req->fd < 0 )
+ }
+ } else {
+ req->fd = proxy_connect(host, port, http_connected, req);
+ if (req->fd < 0) {
error = 1;
+ }
}
-
- if( error )
- {
- http_free( req );
+
+ if (error) {
+ http_free(req);
return NULL;
}
-
+
req->func = func;
req->data = data;
- req->request = g_strdup( request );
- req->request_length = strlen( request );
+ req->request = g_strdup(request);
+ req->request_length = strlen(request);
req->redir_ttl = 3;
req->content_length = -1;
-
- if( getenv( "BITLBEE_DEBUG" ) )
- printf( "About to send HTTP request:\n%s\n", req->request );
-
+
+ if (getenv("BITLBEE_DEBUG")) {
+ printf("About to send HTTP request:\n%s\n", req->request);
+ }
+
return req;
}
-struct http_request *http_dorequest_url( char *url_string, http_input_function func, gpointer data )
+struct http_request *http_dorequest_url(char *url_string, http_input_function func, gpointer data)
{
- url_t *url = g_new0( url_t, 1 );
+ url_t *url = g_new0(url_t, 1);
char *request;
void *ret;
-
- if( !url_set( url, url_string ) )
- {
- g_free( url );
+
+ if (!url_set(url, url_string)) {
+ g_free(url);
return NULL;
}
-
- if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
- {
- g_free( url );
+
+ if (url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS) {
+ g_free(url);
return NULL;
}
-
- request = g_strdup_printf( "GET %s HTTP/1.0\r\n"
- "Host: %s\r\n"
- "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n"
- "\r\n", url->file, url->host );
-
- ret = http_dorequest( url->host, url->port,
- url->proto == PROTO_HTTPS, request, func, data );
-
- g_free( url );
- g_free( request );
+
+ request = g_strdup_printf("GET %s HTTP/1.0\r\n"
+ "Host: %s\r\n"
+ "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n"
+ "\r\n", url->file, url->host);
+
+ ret = http_dorequest(url->host, url->port,
+ url->proto == PROTO_HTTPS, request, func, data);
+
+ g_free(url);
+ g_free(request);
return ret;
}
-/* This one is actually pretty simple... Might get more calls if we can't write
+/* This one is actually pretty simple... Might get more calls if we can't write
the whole request at once. */
-static gboolean http_connected( gpointer data, int source, b_input_condition cond )
+static gboolean http_connected(gpointer data, int source, b_input_condition cond)
{
struct http_request *req = data;
int st;
-
- if( source < 0 )
+
+ if (source < 0) {
goto error;
-
- if( req->inpa > 0 )
- b_event_remove( req->inpa );
-
- sock_make_nonblocking( req->fd );
-
- if( req->ssl )
- {
- st = ssl_write( req->ssl, req->request + req->bytes_written,
- req->request_length - req->bytes_written );
- if( st < 0 )
- {
- if( ssl_errno != SSL_AGAIN )
- {
- ssl_disconnect( req->ssl );
+ }
+
+ if (req->inpa > 0) {
+ b_event_remove(req->inpa);
+ }
+
+ sock_make_nonblocking(req->fd);
+
+ if (req->ssl) {
+ st = ssl_write(req->ssl, req->request + req->bytes_written,
+ req->request_length - req->bytes_written);
+ if (st < 0) {
+ if (ssl_errno != SSL_AGAIN) {
+ ssl_disconnect(req->ssl);
goto error;
}
}
- }
- else
- {
- st = write( source, req->request + req->bytes_written,
- req->request_length - req->bytes_written );
- if( st < 0 )
- {
- if( !sockerr_again() )
- {
- closesocket( req->fd );
+ } else {
+ st = write(source, req->request + req->bytes_written,
+ req->request_length - req->bytes_written);
+ if (st < 0) {
+ if (!sockerr_again()) {
+ closesocket(req->fd);
goto error;
}
}
}
-
- if( st > 0 )
+
+ if (st > 0) {
req->bytes_written += st;
-
- if( req->bytes_written < req->request_length )
- req->inpa = b_input_add( source,
- req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_WRITE,
- http_connected, req );
- else
- req->inpa = b_input_add( source, B_EV_IO_READ, http_incoming_data, req );
-
+ }
+
+ if (req->bytes_written < req->request_length) {
+ req->inpa = b_input_add(source,
+ req->ssl ? ssl_getdirection(req->ssl) : B_EV_IO_WRITE,
+ http_connected, req);
+ } else {
+ req->inpa = b_input_add(source, B_EV_IO_READ, http_incoming_data, req);
+ }
+
return FALSE;
-
+
error:
- if( req->status_string == NULL )
- req->status_string = g_strdup( "Error while writing HTTP request" );
-
- req->func( req );
- http_free( req );
+ if (req->status_string == NULL) {
+ req->status_string = g_strdup("Error while writing HTTP request");
+ }
+
+ req->func(req);
+ http_free(req);
return FALSE;
}
-static gboolean http_ssl_connected( gpointer data, int returncode, void *source, b_input_condition cond )
+static gboolean http_ssl_connected(gpointer data, int returncode, void *source, b_input_condition cond)
{
struct http_request *req = data;
-
- if( source == NULL )
- {
- if( returncode != 0 )
- {
- char *err = ssl_verify_strerror( returncode );
+
+ if (source == NULL) {
+ if (returncode != 0) {
+ char *err = ssl_verify_strerror(returncode);
req->status_string = g_strdup_printf(
- "Certificate verification problem 0x%x: %s",
- returncode, err ? err : "Unknown" );
- g_free( err );
+ "Certificate verification problem 0x%x: %s",
+ returncode, err ? err : "Unknown");
+ g_free(err);
}
- return http_connected( data, -1, cond );
+ return http_connected(data, -1, cond);
}
-
- req->fd = ssl_getfd( source );
-
- return http_connected( data, req->fd, cond );
+
+ req->fd = ssl_getfd(source);
+
+ return http_connected(data, req->fd, cond);
}
typedef enum {
@@ -199,97 +193,87 @@ typedef enum {
CR_ABORT,
} http_ret_t;
-static gboolean http_handle_headers( struct http_request *req );
-static http_ret_t http_process_chunked_data( struct http_request *req, const char *buffer, int len );
-static http_ret_t http_process_data( struct http_request *req, const char *buffer, int len );
+static gboolean http_handle_headers(struct http_request *req);
+static http_ret_t http_process_chunked_data(struct http_request *req, const char *buffer, int len);
+static http_ret_t http_process_data(struct http_request *req, const char *buffer, int len);
-static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )
+static gboolean http_incoming_data(gpointer data, int source, b_input_condition cond)
{
struct http_request *req = data;
char buffer[4096];
int st;
-
- if( req->inpa > 0 )
- {
- b_event_remove( req->inpa );
+
+ if (req->inpa > 0) {
+ b_event_remove(req->inpa);
req->inpa = 0;
}
-
- if( req->ssl )
- {
- st = ssl_read( req->ssl, buffer, sizeof( buffer ) );
- if( st < 0 )
- {
- if( ssl_errno != SSL_AGAIN )
- {
+
+ if (req->ssl) {
+ st = ssl_read(req->ssl, buffer, sizeof(buffer));
+ if (st < 0) {
+ if (ssl_errno != SSL_AGAIN) {
/* goto cleanup; */
-
+
/* YAY! We have to deal with crappy Microsoft
servers that LOVE to send invalid TLS
packets that abort connections! \o/ */
-
+
goto eof;
}
- }
- else if( st == 0 )
- {
+ } else if (st == 0) {
goto eof;
}
- }
- else
- {
- st = read( req->fd, buffer, sizeof( buffer ) );
- if( st < 0 )
- {
- if( !sockerr_again() )
- {
- req->status_string = g_strdup( strerror( errno ) );
+ } else {
+ st = read(req->fd, buffer, sizeof(buffer));
+ if (st < 0) {
+ if (!sockerr_again()) {
+ req->status_string = g_strdup(strerror(errno));
goto cleanup;
}
- }
- else if( st == 0 )
- {
+ } else if (st == 0) {
goto eof;
}
}
-
- if( st > 0 )
- {
+
+ if (st > 0) {
http_ret_t c;
-
- if( req->flags & HTTPC_CHUNKED )
- c = http_process_chunked_data( req, buffer, st );
- else
- c = http_process_data( req, buffer, st );
-
- if( c == CR_EOF )
+
+ if (req->flags & HTTPC_CHUNKED) {
+ c = http_process_chunked_data(req, buffer, st);
+ } else {
+ c = http_process_data(req, buffer, st);
+ }
+
+ if (c == CR_EOF) {
goto eof;
- else if( c == CR_ERROR || c == CR_ABORT )
+ } else if (c == CR_ERROR || c == CR_ABORT) {
return FALSE;
+ }
}
-
- if( req->content_length != -1 &&
- req->body_size >= req->content_length )
+
+ if (req->content_length != -1 &&
+ req->body_size >= req->content_length) {
goto eof;
-
- if( ssl_pending( req->ssl ) )
- return http_incoming_data( data, source, cond );
-
+ }
+
+ if (ssl_pending(req->ssl)) {
+ return http_incoming_data(data, source, cond);
+ }
+
/* There will be more! */
- req->inpa = b_input_add( req->fd,
- req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_READ,
- http_incoming_data, req );
-
+ req->inpa = b_input_add(req->fd,
+ req->ssl ? ssl_getdirection(req->ssl) : B_EV_IO_READ,
+ http_incoming_data, req);
+
return FALSE;
eof:
req->flags |= HTTPC_EOF;
-
+
/* Maybe if the webserver is overloaded, or when there's bad SSL
support... */
- if( req->bytes_read == 0 )
- {
- req->status_string = g_strdup( "Empty HTTP reply" );
+ if (req->bytes_read == 0) {
+ req->status_string = g_strdup("Empty HTTP reply");
goto cleanup;
}
@@ -297,433 +281,432 @@ cleanup:
/* Avoid g_source_remove warnings */
req->inpa = 0;
- if( req->ssl )
- ssl_disconnect( req->ssl );
- else
- closesocket( req->fd );
-
- if( req->body_size < req->content_length )
- {
+ if (req->ssl) {
+ ssl_disconnect(req->ssl);
+ } else {
+ closesocket(req->fd);
+ }
+
+ if (req->body_size < req->content_length) {
req->status_code = -1;
- g_free( req->status_string );
- req->status_string = g_strdup( "Response truncated" );
- }
-
- if( getenv( "BITLBEE_DEBUG" ) && req )
- printf( "Finishing HTTP request with status: %s\n",
- req->status_string ? req->status_string : "NULL" );
-
- req->func( req );
- http_free( req );
+ g_free(req->status_string);
+ req->status_string = g_strdup("Response truncated");
+ }
+
+ if (getenv("BITLBEE_DEBUG") && req) {
+ printf("Finishing HTTP request with status: %s\n",
+ req->status_string ? req->status_string : "NULL");
+ }
+
+ req->func(req);
+ http_free(req);
return FALSE;
}
-static http_ret_t http_process_chunked_data( struct http_request *req, const char *buffer, int len )
+static http_ret_t http_process_chunked_data(struct http_request *req, const char *buffer, int len)
{
char *chunk, *eos, *s;
-
- if( len < 0 )
+
+ if (len < 0) {
return TRUE;
-
- if( len > 0 )
- {
- req->cbuf = g_realloc( req->cbuf, req->cblen + len + 1 );
- memcpy( req->cbuf + req->cblen, buffer, len );
+ }
+
+ if (len > 0) {
+ req->cbuf = g_realloc(req->cbuf, req->cblen + len + 1);
+ memcpy(req->cbuf + req->cblen, buffer, len);
req->cblen += len;
req->cbuf[req->cblen] = '\0';
}
-
+
/* Turns out writing a proper chunked-encoding state machine is not
that simple. :-( I've tested this one feeding it byte by byte so
I hope it's solid now. */
chunk = req->cbuf;
eos = req->cbuf + req->cblen;
- while( TRUE )
- {
+ while (TRUE) {
int clen = 0;
-
+
/* Might be a \r\n from the last chunk. */
s = chunk;
- while( g_ascii_isspace( *s ) )
- s ++;
+ while (g_ascii_isspace(*s)) {
+ s++;
+ }
/* Chunk length. Might be incomplete. */
- if( s < eos && sscanf( s, "%x", &clen ) != 1 )
+ if (s < eos && sscanf(s, "%x", &clen) != 1) {
return CR_ERROR;
- while( g_ascii_isxdigit( *s ) )
- s ++;
-
+ }
+ while (g_ascii_isxdigit(*s)) {
+ s++;
+ }
+
/* If we read anything here, it *must* be \r\n. */
- if( strncmp( s, "\r\n", MIN( 2, eos - s ) ) != 0 )
+ if (strncmp(s, "\r\n", MIN(2, eos - s)) != 0) {
return CR_ERROR;
+ }
s += 2;
-
- if( s >= eos )
+
+ if (s >= eos) {
break;
-
- /* 0-length chunk means end of response. */
- if( clen == 0 )
+ }
+
+ /* 0-length chunk means end of response. */
+ if (clen == 0) {
return CR_EOF;
-
+ }
+
/* Wait for the whole chunk to arrive. */
- if( s + clen > eos )
+ if (s + clen > eos) {
break;
- if( http_process_data( req, s, clen ) != CR_OK )
+ }
+ if (http_process_data(req, s, clen) != CR_OK) {
return CR_ABORT;
-
+ }
+
chunk = s + clen;
}
-
- if( chunk != req->cbuf )
- {
+
+ if (chunk != req->cbuf) {
req->cblen = eos - chunk;
- s = g_memdup( chunk, req->cblen + 1 );
- g_free( req->cbuf );
+ s = g_memdup(chunk, req->cblen + 1);
+ g_free(req->cbuf);
req->cbuf = s;
}
-
+
return CR_OK;
}
-static http_ret_t http_process_data( struct http_request *req, const char *buffer, int len )
+static http_ret_t http_process_data(struct http_request *req, const char *buffer, int len)
{
- if( len <= 0 )
+ if (len <= 0) {
return CR_OK;
-
- if( !req->reply_body )
- {
- req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + len + 1 );
- memcpy( req->reply_headers + req->bytes_read, buffer, len );
+ }
+
+ if (!req->reply_body) {
+ req->reply_headers = g_realloc(req->reply_headers, req->bytes_read + len + 1);
+ memcpy(req->reply_headers + req->bytes_read, buffer, len);
req->bytes_read += len;
req->reply_headers[req->bytes_read] = '\0';
-
- if( strstr( req->reply_headers, "\r\n\r\n" ) ||
- strstr( req->reply_headers, "\n\n" ) )
- {
+
+ if (strstr(req->reply_headers, "\r\n\r\n") ||
+ strstr(req->reply_headers, "\n\n")) {
/* We've now received all headers. Look for something
interesting. */
- if( !http_handle_headers( req ) )
+ if (!http_handle_headers(req)) {
return CR_ABORT;
-
+ }
+
/* Start parsing the body as chunked if required. */
- if( req->flags & HTTPC_CHUNKED )
- return http_process_chunked_data( req, NULL, 0 );
+ if (req->flags & HTTPC_CHUNKED) {
+ return http_process_chunked_data(req, NULL, 0);
+ }
}
- }
- else
- {
+ } else {
int pos = req->reply_body - req->sbuf;
- req->sbuf = g_realloc( req->sbuf, req->sblen + len + 1 );
- memcpy( req->sbuf + req->sblen, buffer, len );
+ req->sbuf = g_realloc(req->sbuf, req->sblen + len + 1);
+ memcpy(req->sbuf + req->sblen, buffer, len);
req->bytes_read += len;
req->sblen += len;
req->sbuf[req->sblen] = '\0';
req->reply_body = req->sbuf + pos;
req->body_size = req->sblen - pos;
}
-
- if( ( req->flags & HTTPC_STREAMING ) && req->reply_body )
- req->func( req );
-
+
+ if ((req->flags & HTTPC_STREAMING) && req->reply_body) {
+ req->func(req);
+ }
+
return CR_OK;
}
/* Splits headers and body. Checks result code, in case of 300s it'll handle
redirects. If this returns FALSE, don't call any callbacks! */
-static gboolean http_handle_headers( struct http_request *req )
+static gboolean http_handle_headers(struct http_request *req)
{
char *end1, *end2, *s;
int evil_server = 0;
-
+
/* Zero termination is very convenient. */
req->reply_headers[req->bytes_read] = '\0';
-
+
/* Find the separation between headers and body, and keep stupid
webservers in mind. */
- end1 = strstr( req->reply_headers, "\r\n\r\n" );
- end2 = strstr( req->reply_headers, "\n\n" );
-
- if( end2 && end2 < end1 )
- {
+ end1 = strstr(req->reply_headers, "\r\n\r\n");
+ end2 = strstr(req->reply_headers, "\n\n");
+
+ if (end2 && end2 < end1) {
end1 = end2 + 1;
evil_server = 1;
- }
- else if( end1 )
- {
+ } else if (end1) {
end1 += 2;
- }
- else
- {
- req->status_string = g_strdup( "Malformed HTTP reply" );
+ } else {
+ req->status_string = g_strdup("Malformed HTTP reply");
return TRUE;
}
-
+
*end1 = '\0';
-
- if( getenv( "BITLBEE_DEBUG" ) )
- printf( "HTTP response headers:\n%s\n", req->reply_headers );
-
- if( evil_server )
+
+ if (getenv("BITLBEE_DEBUG")) {
+ printf("HTTP response headers:\n%s\n", req->reply_headers);
+ }
+
+ if (evil_server) {
req->reply_body = end1 + 1;
- else
+ } else {
req->reply_body = end1 + 2;
-
+ }
+
/* Separately allocated space for headers and body. */
req->sblen = req->body_size = req->reply_headers + req->bytes_read - req->reply_body;
- req->sbuf = req->reply_body = g_memdup( req->reply_body, req->body_size + 1 );
- req->reply_headers = g_realloc( req->reply_headers, end1 - req->reply_headers + 1 );
-
- if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
- {
- if( sscanf( end1 + 1, "%hd", &req->status_code ) != 1 )
- {
- req->status_string = g_strdup( "Can't parse status code" );
+ req->sbuf = req->reply_body = g_memdup(req->reply_body, req->body_size + 1);
+ req->reply_headers = g_realloc(req->reply_headers, end1 - req->reply_headers + 1);
+
+ if ((end1 = strchr(req->reply_headers, ' ')) != NULL) {
+ if (sscanf(end1 + 1, "%hd", &req->status_code) != 1) {
+ req->status_string = g_strdup("Can't parse status code");
req->status_code = -1;
- }
- else
- {
+ } else {
char *eol;
-
- if( evil_server )
- eol = strchr( end1, '\n' );
- else
- eol = strchr( end1, '\r' );
-
- req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
-
+
+ if (evil_server) {
+ eol = strchr(end1, '\n');
+ } else {
+ eol = strchr(end1, '\r');
+ }
+
+ req->status_string = g_strndup(end1 + 1, eol - end1 - 1);
+
/* Just to be sure... */
- if( ( eol = strchr( req->status_string, '\r' ) ) )
+ if ((eol = strchr(req->status_string, '\r'))) {
*eol = 0;
- if( ( eol = strchr( req->status_string, '\n' ) ) )
+ }
+ if ((eol = strchr(req->status_string, '\n'))) {
*eol = 0;
+ }
}
- }
- else
- {
- req->status_string = g_strdup( "Can't locate status code" );
+ } else {
+ req->status_string = g_strdup("Can't locate status code");
req->status_code = -1;
}
-
- if( ( ( req->status_code >= 301 && req->status_code <= 303 ) ||
- req->status_code == 307 ) && req->redir_ttl-- > 0 )
- {
+
+ if (((req->status_code >= 301 && req->status_code <= 303) ||
+ req->status_code == 307) && req->redir_ttl-- > 0) {
char *loc, *new_request, *new_host;
int error = 0, new_port, new_proto;
-
+
/* We might fill it again, so let's not leak any memory. */
- g_free( req->status_string );
+ g_free(req->status_string);
req->status_string = NULL;
-
- loc = strstr( req->reply_headers, "\nLocation: " );
- if( loc == NULL ) /* We can't handle this redirect... */
- {
- req->status_string = g_strdup( "Can't locate Location: header" );
+
+ loc = strstr(req->reply_headers, "\nLocation: ");
+ if (loc == NULL) { /* We can't handle this redirect... */
+ req->status_string = g_strdup("Can't locate Location: header");
return TRUE;
}
-
+
loc += 11;
- while( *loc == ' ' )
- loc ++;
-
+ while (*loc == ' ') {
+ loc++;
+ }
+
/* TODO/FIXME: Possibly have to handle relative redirections,
and rewrite Host: headers. Not necessary for now, it's
enough for passport authentication like this. */
-
- if( *loc == '/' )
- {
+
+ if (*loc == '/') {
/* Just a different pathname... */
-
+
/* Since we don't cache the servername, and since we
don't need this yet anyway, I won't implement it. */
-
- req->status_string = g_strdup( "Can't handle relative redirects" );
-
+
+ req->status_string = g_strdup("Can't handle relative redirects");
+
return TRUE;
- }
- else
- {
+ } else {
/* A whole URL */
url_t *url;
char *s, *version, *headers;
const char *new_method;
-
- s = strstr( loc, "\r\n" );
- if( s == NULL )
+
+ s = strstr(loc, "\r\n");
+ if (s == NULL) {
return TRUE;
-
- url = g_new0( url_t, 1 );
+ }
+
+ url = g_new0(url_t, 1);
*s = 0;
-
- if( !url_set( url, loc ) )
- {
- req->status_string = g_strdup( "Malformed redirect URL" );
- g_free( url );
+
+ if (!url_set(url, loc)) {
+ req->status_string = g_strdup("Malformed redirect URL");
+ g_free(url);
return TRUE;
}
-
+
/* Find all headers and, if necessary, the POST request contents.
Skip the old Host: header though. This crappy code here means
anything using this http_client MUST put the Host: header at
the top. */
- if( !( ( s = strstr( req->request, "\r\nHost: " ) ) &&
- ( s = strstr( s + strlen( "\r\nHost: " ), "\r\n" ) ) ) )
- {
- req->status_string = g_strdup( "Error while rebuilding request string" );
- g_free( url );
+ if (!((s = strstr(req->request, "\r\nHost: ")) &&
+ (s = strstr(s + strlen("\r\nHost: "), "\r\n")))) {
+ req->status_string = g_strdup("Error while rebuilding request string");
+ g_free(url);
return TRUE;
}
headers = s;
-
+
/* More or less HTTP/1.0 compliant, from my reading of RFC 2616.
Always perform a GET request unless we received a 301. 303 was
meant for this but it's HTTP/1.1-only and we're specifically
speaking HTTP/1.0. ...
-
+
Well except someone at identi.ca's didn't bother reading any
RFCs and just return HTTP/1.1-specific status codes to HTTP/1.0
requests. Fuckers. So here we are, handle 301..303,307. */
- if( strncmp( req->request, "GET", 3 ) == 0 )
+ if (strncmp(req->request, "GET", 3) == 0) {
/* GETs never become POSTs. */
new_method = "GET";
- else if( req->status_code == 302 || req->status_code == 303 )
+ } else if (req->status_code == 302 || req->status_code == 303) {
/* 302 de-facto becomes GET, 303 as specified by RFC 2616#10.3.3 */
new_method = "GET";
- else
+ } else {
/* 301 de-facto should stay POST, 307 specifally RFC 2616#10.3.8 */
new_method = "POST";
-
- if( ( version = strstr( req->request, " HTTP/" ) ) &&
- ( s = strstr( version, "\r\n" ) ) )
- {
- version ++;
- version = g_strndup( version, s - version );
}
- else
- version = g_strdup( "HTTP/1.0" );
-
+
+ if ((version = strstr(req->request, " HTTP/")) &&
+ (s = strstr(version, "\r\n"))) {
+ version++;
+ version = g_strndup(version, s - version);
+ } else {
+ version = g_strdup("HTTP/1.0");
+ }
+
/* Okay, this isn't fun! We have to rebuild the request... :-( */
- new_request = g_strdup_printf( "%s %s %s\r\nHost: %s%s",
- new_method, url->file, version,
- url->host, headers );
-
- new_host = g_strdup( url->host );
+ new_request = g_strdup_printf("%s %s %s\r\nHost: %s%s",
+ new_method, url->file, version,
+ url->host, headers);
+
+ new_host = g_strdup(url->host);
new_port = url->port;
new_proto = url->proto;
-
+
/* If we went from POST to GET, truncate the request content. */
- if( new_request[0] != req->request[0] && new_request[0] == 'G' &&
- ( s = strstr( new_request, "\r\n\r\n" ) ) )
+ if (new_request[0] != req->request[0] && new_request[0] == 'G' &&
+ (s = strstr(new_request, "\r\n\r\n"))) {
s[4] = '\0';
-
- g_free( url );
- g_free( version );
+ }
+
+ g_free(url);
+ g_free(version);
+ }
+
+ if (req->ssl) {
+ ssl_disconnect(req->ssl);
+ } else {
+ closesocket(req->fd);
}
-
- if( req->ssl )
- ssl_disconnect( req->ssl );
- else
- closesocket( req->fd );
-
+
req->fd = -1;
req->ssl = NULL;
-
- if( getenv( "BITLBEE_DEBUG" ) )
- printf( "New headers for redirected HTTP request:\n%s\n", new_request );
-
- if( new_proto == PROTO_HTTPS )
- {
- req->ssl = ssl_connect( new_host, new_port, TRUE, http_ssl_connected, req );
- if( req->ssl == NULL )
- error = 1;
+
+ if (getenv("BITLBEE_DEBUG")) {
+ printf("New headers for redirected HTTP request:\n%s\n", new_request);
}
- else
- {
- req->fd = proxy_connect( new_host, new_port, http_connected, req );
- if( req->fd < 0 )
+
+ if (new_proto == PROTO_HTTPS) {
+ req->ssl = ssl_connect(new_host, new_port, TRUE, http_ssl_connected, req);
+ if (req->ssl == NULL) {
error = 1;
+ }
+ } else {
+ req->fd = proxy_connect(new_host, new_port, http_connected, req);
+ if (req->fd < 0) {
+ error = 1;
+ }
}
- g_free( new_host );
-
- if( error )
- {
- req->status_string = g_strdup( "Connection problem during redirect" );
- g_free( new_request );
+ g_free(new_host);
+
+ if (error) {
+ req->status_string = g_strdup("Connection problem during redirect");
+ g_free(new_request);
return TRUE;
}
-
- g_free( req->request );
- g_free( req->reply_headers );
- g_free( req->sbuf );
+
+ g_free(req->request);
+ g_free(req->reply_headers);
+ g_free(req->sbuf);
req->request = new_request;
- req->request_length = strlen( new_request );
+ req->request_length = strlen(new_request);
req->bytes_read = req->bytes_written = req->inpa = 0;
req->reply_headers = req->reply_body = NULL;
req->sbuf = req->cbuf = NULL;
req->sblen = req->cblen = 0;
-
+
return FALSE;
}
- if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) &&
- sscanf( s, "%d", &req->content_length ) != 1 )
+ if ((s = get_rfc822_header(req->reply_headers, "Content-Length", 0)) &&
+ sscanf(s, "%d", &req->content_length) != 1) {
req->content_length = -1;
- g_free( s );
-
- if( ( s = get_rfc822_header( req->reply_headers, "Transfer-Encoding", 0 ) ) )
- {
- if( strcasestr( s, "chunked" ) )
- {
+ }
+ g_free(s);
+
+ if ((s = get_rfc822_header(req->reply_headers, "Transfer-Encoding", 0))) {
+ if (strcasestr(s, "chunked")) {
req->flags |= HTTPC_CHUNKED;
req->cbuf = req->sbuf;
req->cblen = req->sblen;
-
- req->reply_body = req->sbuf = g_strdup( "" );
+
+ req->reply_body = req->sbuf = g_strdup("");
req->body_size = req->sblen = 0;
}
- g_free( s );
+ g_free(s);
}
-
+
return TRUE;
}
-void http_flush_bytes( struct http_request *req, size_t len )
+void http_flush_bytes(struct http_request *req, size_t len)
{
- if( len <= 0 || len > req->body_size || !( req->flags & HTTPC_STREAMING ) )
+ if (len <= 0 || len > req->body_size || !(req->flags & HTTPC_STREAMING)) {
return;
-
+ }
+
req->reply_body += len;
req->body_size -= len;
-
- if( req->reply_body - req->sbuf >= 512 )
- {
- char *new = g_memdup( req->reply_body, req->body_size + 1 );
- g_free( req->sbuf );
+
+ if (req->reply_body - req->sbuf >= 512) {
+ char *new = g_memdup(req->reply_body, req->body_size + 1);
+ g_free(req->sbuf);
req->reply_body = req->sbuf = new;
req->sblen = req->body_size;
}
}
-void http_close( struct http_request *req )
+void http_close(struct http_request *req)
{
- if( !req )
+ if (!req) {
return;
-
- if( req->inpa > 0 )
- b_event_remove( req->inpa );
-
- if( req->ssl )
- ssl_disconnect( req->ssl );
- else
- closesocket( req->fd );
-
- http_free( req );
+ }
+
+ if (req->inpa > 0) {
+ b_event_remove(req->inpa);
+ }
+
+ if (req->ssl) {
+ ssl_disconnect(req->ssl);
+ } else {
+ closesocket(req->fd);
+ }
+
+ http_free(req);
}
-static void http_free( struct http_request *req )
+static void http_free(struct http_request *req)
{
- g_free( req->request );
- g_free( req->reply_headers );
- g_free( req->status_string );
- g_free( req->sbuf );
- g_free( req->cbuf );
- g_free( req );
+ g_free(req->request);
+ g_free(req->reply_headers);
+ g_free(req->status_string);
+ g_free(req->sbuf);
+ g_free(req->cbuf);
+ g_free(req);
}
diff --git a/lib/http_client.h b/lib/http_client.h
index 99add28f..899b3ccd 100644
--- a/lib/http_client.h
+++ b/lib/http_client.h
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -27,7 +27,7 @@
In the "background" it will send the whole query and wait for a complete
response to come back. Initially written for MS Passport authentication,
but used for many other things now like OAuth and Twitter.
-
+
It's very useful for doing quick requests without blocking the whole
program. Unfortunately it doesn't support fancy stuff like HTTP keep-
alives. */
@@ -37,23 +37,21 @@
struct http_request;
-typedef enum http_client_flags
-{
+typedef enum http_client_flags {
HTTPC_STREAMING = 1,
HTTPC_EOF = 2,
HTTPC_CHUNKED = 4,
-
+
/* Let's reserve 0x1000000+ for lib users. */
} http_client_flags_t;
/* Your callback function should look like this: */
-typedef void (*http_input_function)( struct http_request * );
+typedef void (*http_input_function)(struct http_request *);
/* This structure will be filled in by the http_dorequest* functions, and
it will be passed to the callback function. Use the data field to add
your own data. */
-struct http_request
-{
+struct http_request {
char *request; /* The request to send to the server. */
int request_length; /* Its size. */
short status_code; /* The numeric HTTP status code. (Or -1
@@ -64,25 +62,25 @@ struct http_request
int body_size; /* The number of bytes in reply_body. */
short redir_ttl; /* You can set it to 0 if you don't want
http_client to follow them. */
-
+
http_client_flags_t flags;
-
+
http_input_function func;
gpointer data;
-
+
/* Please don't touch the things down here, you shouldn't need them. */
void *ssl;
int fd;
-
+
int inpa;
int bytes_written;
int bytes_read;
int content_length; /* "Content-Length:" header or -1 */
-
+
/* Used in streaming mode. Caller should read from reply_body. */
char *sbuf;
size_t sblen;
-
+
/* Chunked encoding only. Raw chunked stream is decoded from here. */
char *cbuf;
size_t cblen;
@@ -92,9 +90,10 @@ struct http_request
version is probably only useful if you want to do POST requests or if
you want to add some extra headers. As you can see, HTTPS connections
are also supported (using ssl_client). */
-struct http_request *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );
-struct http_request *http_dorequest_url( char *url_string, http_input_function func, gpointer data );
+struct http_request *http_dorequest(char *host, int port, int ssl, char *request, http_input_function func,
+ gpointer data);
+struct http_request *http_dorequest_url(char *url_string, http_input_function func, gpointer data);
/* For streaming connections only; flushes len bytes at the start of the buffer. */
-void http_flush_bytes( struct http_request *req, size_t len );
-void http_close( struct http_request *req );
+void http_flush_bytes(struct http_request *req, size_t len);
+void http_close(struct http_request *req);
diff --git a/lib/ini.c b/lib/ini.c
index 3819e3da..4dbdec64 100644
--- a/lib/ini.c
+++ b/lib/ini.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2008 Wilmer van der Gaast and others *
@@ -25,109 +25,101 @@
#define BITLBEE_CORE
#include "bitlbee.h"
-ini_t *ini_open( char *file )
+ini_t *ini_open(char *file)
{
int fd;
ini_t *ini = NULL;
struct stat fi;
-
- if( ( fd = open( file, O_RDONLY ) ) != -1 &&
- fstat( fd, &fi ) == 0 &&
+
+ 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 )
- {
- memset( ini, 0, sizeof( ini_t ) );
+ (ini = g_malloc(sizeof(ini_t) + fi.st_size + 1)) &&
+ read(fd, ini->file, fi.st_size) == fi.st_size) {
+ 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 );
-
+
+ close(fd);
+
return ini;
}
- if( fd >= 0 )
- close( fd );
-
- ini_close( ini );
+ if (fd >= 0) {
+ close(fd);
+ }
+
+ 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 )
+static char *ini_strip_whitespace(char *in)
{
char *e;
- while( g_ascii_isspace( *in ) )
+ while (g_ascii_isspace(*in)) {
in++;
+ }
- e = in + strlen( in ) - 1;
- while( e > in && g_ascii_isspace( *e ) )
+ e = in + strlen(in) - 1;
+ while (e > in && g_ascii_isspace(*e)) {
e--;
+ }
e[1] = 0;
-
+
return in;
}
-int ini_read( ini_t *file )
+int ini_read(ini_t *file)
{
char *s;
-
- while( file->cur && file->cur < file->file + file->size )
- {
+
+ while (file->cur && file->cur < file->file + file->size) {
char *e, *next;
-
+
file->line++;
/* Find the end of line */
- if( ( e = strchr( file->cur, '\n' ) ) != NULL )
- {
+ if ((e = strchr(file->cur, '\n')) != NULL) {
*e = 0;
next = e + 1;
- }
- else
- {
+ } else {
/* No more lines. */
- e = file->cur + strlen( file->cur );
+ e = file->cur + strlen(file->cur);
next = NULL;
}
-
+
/* Comment? */
- if( ( s = strchr( file->cur, '#' ) ) != NULL )
+ if ((s = strchr(file->cur, '#')) != NULL) {
*s = 0;
-
- file->cur = ini_strip_whitespace( file->cur );
-
- if( *file->cur == '[' )
- {
+ }
+
+ file->cur = ini_strip_whitespace(file->cur);
+
+ if (*file->cur == '[') {
file->cur++;
- if( ( s = strchr( file->cur, ']' ) ) != NULL )
- {
+ if ((s = strchr(file->cur, ']')) != NULL) {
*s = 0;
file->c_section = file->cur;
}
- }
- else if( ( s = strchr( file->cur, '=' ) ) != NULL )
- {
+ } 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 )
- {
+ 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
- {
+ } else {
file->section = file->c_section;
}
-
+
file->cur = next;
return 1;
}
@@ -135,11 +127,11 @@ int ini_read( ini_t *file )
file->cur = next;
}
-
+
return 0;
}
-void ini_close( ini_t *file )
+void ini_close(ini_t *file)
{
- g_free( file );
+ g_free(file);
}
diff --git a/lib/ini.h b/lib/ini.h
index 290b8cc9..bfd4c21b 100644
--- a/lib/ini.h
+++ b/lib/ini.h
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2004 Wilmer van der Gaast and others *
@@ -26,8 +26,7 @@
#ifndef _INI_H
#define _INI_H
-typedef struct
-{
+typedef struct {
int line;
char *c_section;
char *section;
@@ -38,8 +37,8 @@ typedef struct
char file[];
} ini_t;
-ini_t *ini_open( char *file );
-int ini_read( ini_t *file );
-void ini_close( ini_t *file );
+ini_t *ini_open(char *file);
+int ini_read(ini_t *file);
+void ini_close(ini_t *file);
#endif
diff --git a/lib/json.c b/lib/json.c
index 2e0c50c1..cbd6eaad 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -38,9 +38,9 @@
#endif
#ifdef __cplusplus
- const struct _json_value json_value_none; /* zero-d by ctor */
+const struct _json_value json_value_none; /* zero-d by ctor */
#else
- const struct _json_value json_value_none = { 0 };
+const struct _json_value json_value_none = { 0 };
#endif
#include <stdio.h>
@@ -50,933 +50,923 @@
typedef unsigned int json_uchar;
-static unsigned char hex_value (json_char c)
+static unsigned char hex_value(json_char c)
{
- if (g_ascii_isdigit(c))
- return c - '0';
-
- switch (c) {
- case 'a': case 'A': return 0x0A;
- case 'b': case 'B': return 0x0B;
- case 'c': case 'C': return 0x0C;
- case 'd': case 'D': return 0x0D;
- case 'e': case 'E': return 0x0E;
- case 'f': case 'F': return 0x0F;
- default: return 0xFF;
- }
+ if (g_ascii_isdigit(c)) {
+ return c - '0';
+ }
+
+ switch (c) {
+ case 'a': case 'A': return 0x0A;
+ case 'b': case 'B': return 0x0B;
+ case 'c': case 'C': return 0x0C;
+ case 'd': case 'D': return 0x0D;
+ case 'e': case 'E': return 0x0E;
+ case 'f': case 'F': return 0x0F;
+ default: return 0xFF;
+ }
}
-typedef struct
-{
- unsigned long used_memory;
+typedef struct {
+ unsigned long used_memory;
- unsigned int uint_max;
- unsigned long ulong_max;
+ unsigned int uint_max;
+ unsigned long ulong_max;
- json_settings settings;
- int first_pass;
+ json_settings settings;
+ int first_pass;
} json_state;
-static void * default_alloc (size_t size, int zero, void * user_data)
+static void * default_alloc(size_t size, int zero, void * user_data)
{
- return zero ? calloc (1, size) : malloc (size);
+ return zero ? calloc(1, size) : malloc(size);
}
-static void default_free (void * ptr, void * user_data)
+static void default_free(void * ptr, void * user_data)
{
- free (ptr);
+ free(ptr);
}
-static void * json_alloc (json_state * state, unsigned long size, int zero)
+static void * json_alloc(json_state * state, unsigned long size, int zero)
{
- if ((state->ulong_max - state->used_memory) < size)
- return 0;
+ if ((state->ulong_max - state->used_memory) < size) {
+ return 0;
+ }
- if (state->settings.max_memory
- && (state->used_memory += size) > state->settings.max_memory)
- {
- return 0;
- }
+ if (state->settings.max_memory
+ && (state->used_memory += size) > state->settings.max_memory) {
+ return 0;
+ }
- return state->settings.mem_alloc (size, zero, state->settings.user_data);
+ return state->settings.mem_alloc(size, zero, state->settings.user_data);
}
static int new_value
- (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
+ (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
{
- json_value * value;
- int values_size;
+ json_value * value;
+ int values_size;
- if (!state->first_pass)
- {
- value = *top = *alloc;
- *alloc = (*alloc)->_reserved.next_alloc;
+ if (!state->first_pass) {
+ value = *top = *alloc;
+ *alloc = (*alloc)->_reserved.next_alloc;
- if (!*root)
- *root = value;
+ if (!*root) {
+ *root = value;
+ }
- switch (value->type)
- {
- case json_array:
+ switch (value->type) {
+ case json_array:
- if (! (value->u.array.values = (json_value **) json_alloc
- (state, value->u.array.length * sizeof (json_value *), 0)) )
- {
- return 0;
- }
+ if (!(value->u.array.values = (json_value **) json_alloc
+ (state, value->u.array.length * sizeof(json_value *),
+ 0))) {
+ return 0;
+ }
- value->u.array.length = 0;
- break;
+ value->u.array.length = 0;
+ break;
- case json_object:
+ case json_object:
- values_size = sizeof (*value->u.object.values) * value->u.object.length;
+ values_size = sizeof(*value->u.object.values) * value->u.object.length;
- if (! ((*(void **) &value->u.object.values) = json_alloc
- (state, values_size + ((unsigned long) value->u.object.values), 0)) )
- {
- return 0;
- }
+ if (!((*(void **) &value->u.object.values) = json_alloc
+ (state, values_size +
+ ((unsigned long) value->u.object.values),
+ 0))) {
+ return 0;
+ }
- value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
+ value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
- value->u.object.length = 0;
- break;
+ value->u.object.length = 0;
+ break;
- case json_string:
+ case json_string:
- if (! (value->u.string.ptr = (json_char *) json_alloc
- (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
- {
- return 0;
- }
+ if (!(value->u.string.ptr = (json_char *) json_alloc
+ (state, (value->u.string.length + 1) * sizeof(json_char),
+ 0))) {
+ return 0;
+ }
- value->u.string.length = 0;
- break;
+ value->u.string.length = 0;
+ break;
- default:
- break;
- };
+ default:
+ break;
+ }
+ ;
- return 1;
- }
+ return 1;
+ }
- value = (json_value *) json_alloc (state, sizeof (json_value), 1);
+ value = (json_value *) json_alloc(state, sizeof(json_value), 1);
- if (!value)
- return 0;
+ if (!value) {
+ return 0;
+ }
- if (!*root)
- *root = value;
+ if (!*root) {
+ *root = value;
+ }
- value->type = type;
- value->parent = *top;
+ value->type = type;
+ value->parent = *top;
- if (*alloc)
- (*alloc)->_reserved.next_alloc = value;
+ if (*alloc) {
+ (*alloc)->_reserved.next_alloc = value;
+ }
- *alloc = *top = value;
+ *alloc = *top = value;
- return 1;
+ return 1;
}
#define e_off \
- ((int) (i - cur_line_begin))
+ ((int) (i - cur_line_begin))
#define whitespace \
- case '\n': ++ cur_line; cur_line_begin = i; \
- case ' ': case '\t': case '\r'
+case '\n': ++cur_line; cur_line_begin = i; \
+case ' ': case '\t': case '\r'
#define string_add(b) \
- do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
+ do { if (!state.first_pass) { string [string_length] = b; } ++string_length; } while (0);
static const long
- flag_next = 1 << 0,
- flag_reproc = 1 << 1,
- flag_need_comma = 1 << 2,
- flag_seek_value = 1 << 3,
- flag_escaped = 1 << 4,
- flag_string = 1 << 5,
- flag_need_colon = 1 << 6,
- flag_done = 1 << 7,
- flag_num_negative = 1 << 8,
- flag_num_zero = 1 << 9,
- flag_num_e = 1 << 10,
- flag_num_e_got_sign = 1 << 11,
- flag_num_e_negative = 1 << 12,
- flag_line_comment = 1 << 13,
- flag_block_comment = 1 << 14;
-
-json_value * json_parse_ex (json_settings * settings,
- const json_char * json,
- size_t length,
- char * error_buf)
+ flag_next = 1 << 0,
+ flag_reproc = 1 << 1,
+ flag_need_comma = 1 << 2,
+ flag_seek_value = 1 << 3,
+ flag_escaped = 1 << 4,
+ flag_string = 1 << 5,
+ flag_need_colon = 1 << 6,
+ flag_done = 1 << 7,
+ flag_num_negative = 1 << 8,
+ flag_num_zero = 1 << 9,
+ flag_num_e = 1 << 10,
+ flag_num_e_got_sign = 1 << 11,
+ flag_num_e_negative = 1 << 12,
+ flag_line_comment = 1 << 13,
+ flag_block_comment = 1 << 14;
+
+json_value * json_parse_ex(json_settings * settings,
+ const json_char * json,
+ size_t length,
+ char * error_buf)
{
- json_char error [json_error_max];
- unsigned int cur_line;
- const json_char * cur_line_begin, * i, * end;
- json_value * top, * root, * alloc = 0;
- json_state state = { 0 };
- long flags;
- long num_digits = 0, num_e = 0;
- json_int_t num_fraction = 0;
-
- /* Skip UTF-8 BOM
- */
- if (length >= 3 && ((unsigned char) json [0]) == 0xEF
- && ((unsigned char) json [1]) == 0xBB
- && ((unsigned char) json [2]) == 0xBF)
- {
- json += 3;
- length -= 3;
- }
-
- error[0] = '\0';
- end = (json + length);
-
- memcpy (&state.settings, settings, sizeof (json_settings));
-
- if (!state.settings.mem_alloc)
- state.settings.mem_alloc = default_alloc;
-
- if (!state.settings.mem_free)
- state.settings.mem_free = default_free;
-
- memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
- memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
-
- state.uint_max -= 8; /* limit of how much can be added before next check */
- state.ulong_max -= 8;
-
- for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
- {
- json_uchar uchar;
- unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
- json_char * string = 0;
- unsigned int string_length = 0;
-
- top = root = 0;
- flags = flag_seek_value;
-
- cur_line = 1;
- cur_line_begin = json;
-
- for (i = json ;; ++ i)
- {
- json_char b = (i == end ? 0 : *i);
-
- if (flags & flag_string)
- {
- if (!b)
- { sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
- goto e_failed;
- }
-
- if (string_length > state.uint_max)
- goto e_overflow;
-
- if (flags & flag_escaped)
- {
- flags &= ~ flag_escaped;
-
- switch (b)
- {
- case 'b': string_add ('\b'); break;
- case 'f': string_add ('\f'); break;
- case 'n': string_add ('\n'); break;
- case 'r': string_add ('\r'); break;
- case 't': string_add ('\t'); break;
- case 'u':
-
- if (end - i < 4 ||
- (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
- || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
- {
- sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
- goto e_failed;
- }
-
- uc_b1 = (uc_b1 << 4) | uc_b2;
- uc_b2 = (uc_b3 << 4) | uc_b4;
- uchar = (uc_b1 << 8) | uc_b2;
-
- if ((uchar & 0xF800) == 0xD800) {
- json_uchar uchar2;
-
- if (end - i < 6 || (*++ i) != '\\' || (*++ i) != 'u' ||
- (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
- || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
- {
- sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
- goto e_failed;
- }
-
- uc_b1 = (uc_b1 << 4) | uc_b2;
- uc_b2 = (uc_b3 << 4) | uc_b4;
- uchar2 = (uc_b1 << 8) | uc_b2;
-
- uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
- }
-
- if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
- {
- string_add ((json_char) uchar);
- break;
- }
-
- if (uchar <= 0x7FF)
- {
- if (state.first_pass)
- string_length += 2;
- else
- { string [string_length ++] = 0xC0 | (uchar >> 6);
- string [string_length ++] = 0x80 | (uchar & 0x3F);
- }
-
- break;
- }
-
- if (uchar <= 0xFFFF) {
- if (state.first_pass)
- string_length += 3;
- else
- { string [string_length ++] = 0xE0 | (uchar >> 12);
- string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
- string [string_length ++] = 0x80 | (uchar & 0x3F);
- }
-
- break;
- }
-
- if (state.first_pass)
- string_length += 4;
- else
- { string [string_length ++] = 0xF0 | (uchar >> 18);
- string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
- string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
- string [string_length ++] = 0x80 | (uchar & 0x3F);
- }
-
- break;
-
- default:
- string_add (b);
- };
-
- continue;
- }
-
- if (b == '\\')
- {
- flags |= flag_escaped;
- continue;
- }
-
- if (b == '"')
- {
- if (!state.first_pass)
- string [string_length] = 0;
-
- flags &= ~ flag_string;
- string = 0;
-
- switch (top->type)
- {
- case json_string:
-
- top->u.string.length = string_length;
- flags |= flag_next;
-
- break;
-
- case json_object:
-
- if (state.first_pass)
- (*(json_char **) &top->u.object.values) += string_length + 1;
- else
- {
- top->u.object.values [top->u.object.length].name
- = (json_char *) top->_reserved.object_mem;
-
- top->u.object.values [top->u.object.length].name_length
- = string_length;
-
- (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
- }
-
- flags |= flag_seek_value | flag_need_colon;
- continue;
-
- default:
- break;
- };
- }
- else
- {
- string_add (b);
- continue;
- }
- }
-
- if (state.settings.settings & json_enable_comments)
- {
- if (flags & (flag_line_comment | flag_block_comment))
- {
- if (flags & flag_line_comment)
- {
- if (b == '\r' || b == '\n' || !b)
- {
- flags &= ~ flag_line_comment;
- -- i; /* so null can be reproc'd */
- }
-
- continue;
- }
-
- if (flags & flag_block_comment)
- {
- if (!b)
- { sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off);
- goto e_failed;
- }
-
- if (b == '*' && i < (end - 1) && i [1] == '/')
- {
- flags &= ~ flag_block_comment;
- ++ i; /* skip closing sequence */
- }
-
- continue;
- }
- }
- else if (b == '/')
- {
- if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
- {
- sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off);
- goto e_failed;
- }
-
- if (++ i == end)
- { sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off);
- goto e_failed;
- }
-
- switch (b = *i)
- {
- case '/':
- flags |= flag_line_comment;
- continue;
-
- case '*':
- flags |= flag_block_comment;
- continue;
-
- default:
- sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b);
- goto e_failed;
- };
- }
- }
-
- if (flags & flag_done)
- {
- if (!b)
- break;
-
- switch (b)
- {
- whitespace:
- continue;
-
- default:
- sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
- goto e_failed;
- };
- }
-
- if (flags & flag_seek_value)
- {
- switch (b)
- {
- whitespace:
- continue;
-
- case ']':
-
- if (top->type == json_array)
- flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
- else
- { sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off);
- goto e_failed;
- }
-
- break;
-
- default:
-
- if (flags & flag_need_comma)
- {
- if (b == ',')
- { flags &= ~ flag_need_comma;
- continue;
- }
- else
- { sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b);
- goto e_failed;
- }
- }
-
- if (flags & flag_need_colon)
- {
- if (b == ':')
- { flags &= ~ flag_need_colon;
- continue;
- }
- else
- { sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b);
- goto e_failed;
- }
- }
-
- flags &= ~ flag_seek_value;
-
- switch (b)
- {
- case '{':
-
- if (!new_value (&state, &top, &root, &alloc, json_object))
- goto e_alloc_failure;
-
- continue;
-
- case '[':
-
- if (!new_value (&state, &top, &root, &alloc, json_array))
- goto e_alloc_failure;
-
- flags |= flag_seek_value;
- continue;
-
- case '"':
-
- if (!new_value (&state, &top, &root, &alloc, json_string))
- goto e_alloc_failure;
-
- flags |= flag_string;
-
- string = top->u.string.ptr;
- string_length = 0;
-
- continue;
-
- case 't':
-
- if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
- goto e_unknown_value;
-
- if (!new_value (&state, &top, &root, &alloc, json_boolean))
- goto e_alloc_failure;
-
- top->u.boolean = 1;
-
- flags |= flag_next;
- break;
-
- case 'f':
-
- if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
- goto e_unknown_value;
+ json_char error [json_error_max];
+ unsigned int cur_line;
+ const json_char * cur_line_begin, * i, * end;
+ json_value * top, * root, * alloc = 0;
+ json_state state = { 0 };
+ long flags;
+ long num_digits = 0, num_e = 0;
+ json_int_t num_fraction = 0;
+
+ /* Skip UTF-8 BOM
+ */
+ if (length >= 3 && ((unsigned char) json [0]) == 0xEF
+ && ((unsigned char) json [1]) == 0xBB
+ && ((unsigned char) json [2]) == 0xBF) {
+ json += 3;
+ length -= 3;
+ }
+
+ error[0] = '\0';
+ end = (json + length);
+
+ memcpy(&state.settings, settings, sizeof(json_settings));
+
+ if (!state.settings.mem_alloc) {
+ state.settings.mem_alloc = default_alloc;
+ }
+
+ if (!state.settings.mem_free) {
+ state.settings.mem_free = default_free;
+ }
+
+ memset(&state.uint_max, 0xFF, sizeof(state.uint_max));
+ memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max));
+
+ state.uint_max -= 8; /* limit of how much can be added before next check */
+ state.ulong_max -= 8;
+
+ for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass) {
+ json_uchar uchar;
+ unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
+ json_char * string = 0;
+ unsigned int string_length = 0;
+
+ top = root = 0;
+ flags = flag_seek_value;
+
+ cur_line = 1;
+ cur_line_begin = json;
+
+ for (i = json;; ++i) {
+ json_char b = (i == end ? 0 : *i);
+
+ if (flags & flag_string) {
+ if (!b) {
+ sprintf(error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
+ goto e_failed;
+ }
+
+ if (string_length > state.uint_max) {
+ goto e_overflow;
+ }
+
+ if (flags & flag_escaped) {
+ flags &= ~flag_escaped;
+
+ switch (b) {
+ case 'b': string_add('\b'); break;
+ case 'f': string_add('\f'); break;
+ case 'n': string_add('\n'); break;
+ case 'r': string_add('\r'); break;
+ case 't': string_add('\t'); break;
+ case 'u':
+
+ if (end - i < 4 ||
+ (uc_b1 = hex_value(*++i)) == 0xFF || (uc_b2 = hex_value(*++i)) ==
+ 0xFF
+ || (uc_b3 = hex_value(*++i)) == 0xFF || (uc_b4 = hex_value(*++i)) ==
+ 0xFF) {
+ sprintf(error, "Invalid character value `%c` (at %d:%d)", b,
+ cur_line, e_off);
+ goto e_failed;
+ }
+
+ uc_b1 = (uc_b1 << 4) | uc_b2;
+ uc_b2 = (uc_b3 << 4) | uc_b4;
+ uchar = (uc_b1 << 8) | uc_b2;
+
+ if ((uchar & 0xF800) == 0xD800) {
+ json_uchar uchar2;
+
+ if (end - i < 6 || (*++i) != '\\' || (*++i) != 'u' ||
+ (uc_b1 = hex_value(*++i)) == 0xFF ||
+ (uc_b2 = hex_value(*++i)) == 0xFF
+ || (uc_b3 = hex_value(*++i)) == 0xFF ||
+ (uc_b4 = hex_value(*++i)) == 0xFF) {
+ sprintf(error,
+ "Invalid character value `%c` (at %d:%d)", b,
+ cur_line, e_off);
+ goto e_failed;
+ }
+
+ uc_b1 = (uc_b1 << 4) | uc_b2;
+ uc_b2 = (uc_b3 << 4) | uc_b4;
+ uchar2 = (uc_b1 << 8) | uc_b2;
+
+ uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
+ }
+
+ if (sizeof(json_char) >= sizeof(json_uchar) || (uchar <= 0x7F)) {
+ string_add((json_char) uchar);
+ break;
+ }
+
+ if (uchar <= 0x7FF) {
+ if (state.first_pass) {
+ string_length += 2;
+ } else { string [string_length++] = 0xC0 |
+ (uchar >>
+ 6);
+ string [string_length++] = 0x80 |
+ (uchar &
+ 0x3F); }
+
+ break;
+ }
+
+ if (uchar <= 0xFFFF) {
+ if (state.first_pass) {
+ string_length += 3;
+ } else { string [string_length++] = 0xE0 |
+ (uchar >>
+ 12);
+ string [string_length++] = 0x80 |
+ ((uchar
+ >> 6) &
+ 0x3F);
+ string [string_length++] = 0x80 |
+ (uchar &
+ 0x3F); }
+
+ break;
+ }
+
+ if (state.first_pass) {
+ string_length += 4;
+ } else { string [string_length++] = 0xF0 | (uchar >> 18);
+ string [string_length++] = 0x80 |
+ ((uchar >>
+ 12) & 0x3F);
+ string [string_length++] = 0x80 |
+ ((uchar >>
+ 6) & 0x3F);
+ string [string_length++] = 0x80 |
+ (uchar & 0x3F); }
+
+ break;
+
+ default:
+ string_add(b);
+ }
+ ;
+
+ continue;
+ }
+
+ if (b == '\\') {
+ flags |= flag_escaped;
+ continue;
+ }
+
+ if (b == '"') {
+ if (!state.first_pass) {
+ string [string_length] = 0;
+ }
+
+ flags &= ~flag_string;
+ string = 0;
+
+ switch (top->type) {
+ case json_string:
+
+ top->u.string.length = string_length;
+ flags |= flag_next;
+
+ break;
+
+ case json_object:
+
+ if (state.first_pass) {
+ (*(json_char **) &top->u.object.values) += string_length + 1;
+ } else {
+ top->u.object.values [top->u.object.length].name
+ = (json_char *) top->_reserved.object_mem;
+
+ top->u.object.values [top->u.object.length].name_length
+ = string_length;
+
+ (*(json_char **) &top->_reserved.object_mem) += string_length +
+ 1;
+ }
+
+ flags |= flag_seek_value | flag_need_colon;
+ continue;
+
+ default:
+ break;
+ }
+ ;
+ } else {
+ string_add(b);
+ continue;
+ }
+ }
+
+ if (state.settings.settings & json_enable_comments) {
+ if (flags & (flag_line_comment | flag_block_comment)) {
+ if (flags & flag_line_comment) {
+ if (b == '\r' || b == '\n' || !b) {
+ flags &= ~flag_line_comment;
+ --i; /* so null can be reproc'd */
+ }
+
+ continue;
+ }
+
+ if (flags & flag_block_comment) {
+ if (!b) {
+ sprintf(error, "%d:%d: Unexpected EOF in block comment",
+ cur_line, e_off);
+ goto e_failed;
+ }
+
+ if (b == '*' && i < (end - 1) && i [1] == '/') {
+ flags &= ~flag_block_comment;
+ ++i; /* skip closing sequence */
+ }
+
+ continue;
+ }
+ } else if (b == '/') {
+ if (!(flags & (flag_seek_value | flag_done)) && top->type != json_object) {
+ sprintf(error, "%d:%d: Comment not allowed here", cur_line, e_off);
+ goto e_failed;
+ }
+
+ if (++i == end) {
+ sprintf(error, "%d:%d: EOF unexpected", cur_line, e_off);
+ goto e_failed;
+ }
+
+ switch (b = *i) {
+ case '/':
+ flags |= flag_line_comment;
+ continue;
+
+ case '*':
+ flags |= flag_block_comment;
+ continue;
+
+ default:
+ sprintf(error, "%d:%d: Unexpected `%c` in comment opening sequence",
+ cur_line, e_off, b);
+ goto e_failed;
+ }
+ ;
+ }
+ }
+
+ if (flags & flag_done) {
+ if (!b) {
+ break;
+ }
+
+ switch (b) {
+whitespace:
+ continue;
+
+ default:
+ sprintf(error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
+ goto e_failed;
+ }
+ ;
+ }
+
+ if (flags & flag_seek_value) {
+ switch (b) {
+whitespace:
+ continue;
+
+ case ']':
+
+ if (top->type == json_array) {
+ flags = (flags & ~(flag_need_comma | flag_seek_value)) | flag_next;
+ } else { sprintf(error, "%d:%d: Unexpected ]", cur_line, e_off);
+ goto e_failed; }
+
+ break;
+
+ default:
+
+ if (flags & flag_need_comma) {
+ if (b == ',') {
+ flags &= ~flag_need_comma;
+ continue;
+ } else { sprintf(error, "%d:%d: Expected , before %c", cur_line, e_off,
+ b);
+ goto e_failed; }
+ }
+
+ if (flags & flag_need_colon) {
+ if (b == ':') {
+ flags &= ~flag_need_colon;
+ continue;
+ } else { sprintf(error, "%d:%d: Expected : before %c", cur_line, e_off,
+ b);
+ goto e_failed; }
+ }
+
+ flags &= ~flag_seek_value;
- if (!new_value (&state, &top, &root, &alloc, json_boolean))
- goto e_alloc_failure;
-
- flags |= flag_next;
- break;
+ switch (b) {
+ case '{':
- case 'n':
+ if (!new_value(&state, &top, &root, &alloc, json_object)) {
+ goto e_alloc_failure;
+ }
+
+ continue;
- if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
- goto e_unknown_value;
+ case '[':
- if (!new_value (&state, &top, &root, &alloc, json_null))
- goto e_alloc_failure;
+ if (!new_value(&state, &top, &root, &alloc, json_array)) {
+ goto e_alloc_failure;
+ }
+
+ flags |= flag_seek_value;
+ continue;
+
+ case '"':
+
+ if (!new_value(&state, &top, &root, &alloc, json_string)) {
+ goto e_alloc_failure;
+ }
+
+ flags |= flag_string;
+
+ string = top->u.string.ptr;
+ string_length = 0;
- flags |= flag_next;
- break;
+ continue;
+
+ case 't':
- default:
+ if ((end - i) < 3 || *(++i) != 'r' || *(++i) != 'u' || *(++i) != 'e') {
+ goto e_unknown_value;
+ }
- if (g_ascii_isdigit (b) || b == '-')
- {
- if (!new_value (&state, &top, &root, &alloc, json_integer))
- goto e_alloc_failure;
+ if (!new_value(&state, &top, &root, &alloc, json_boolean)) {
+ goto e_alloc_failure;
+ }
- if (!state.first_pass)
- {
- while (g_ascii_isdigit (b) || b == '+' || b == '-'
- || b == 'e' || b == 'E' || b == '.')
- {
- if ( (++ i) == end)
- {
- b = 0;
- break;
- }
+ top->u.boolean = 1;
- b = *i;
- }
+ flags |= flag_next;
+ break;
- flags |= flag_next | flag_reproc;
- break;
- }
+ case 'f':
- flags &= ~ (flag_num_negative | flag_num_e |
- flag_num_e_got_sign | flag_num_e_negative |
- flag_num_zero);
+ if ((end - i) < 4 || *(++i) != 'a' || *(++i) != 'l' || *(++i) != 's' ||
+ *(++i) != 'e') {
+ goto e_unknown_value;
+ }
- num_digits = 0;
- num_fraction = 0;
- num_e = 0;
+ if (!new_value(&state, &top, &root, &alloc, json_boolean)) {
+ goto e_alloc_failure;
+ }
- if (b != '-')
- {
- flags |= flag_reproc;
- break;
- }
+ flags |= flag_next;
+ break;
- flags |= flag_num_negative;
- continue;
- }
- else
- { sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
- goto e_failed;
- }
- };
- };
- }
- else
- {
- switch (top->type)
- {
- case json_object:
-
- switch (b)
- {
- whitespace:
- continue;
-
- case '"':
-
- if (flags & flag_need_comma)
- {
- sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off);
- goto e_failed;
- }
-
- flags |= flag_string;
-
- string = (json_char *) top->_reserved.object_mem;
- string_length = 0;
-
- break;
-
- case '}':
-
- flags = (flags & ~ flag_need_comma) | flag_next;
- break;
-
- case ',':
-
- if (flags & flag_need_comma)
- {
- flags &= ~ flag_need_comma;
- break;
- }
-
- default:
-
- sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
- goto e_failed;
- };
-
- break;
-
- case json_integer:
- case json_double:
-
- if (g_ascii_isdigit (b))
- {
- ++ num_digits;
-
- if (top->type == json_integer || flags & flag_num_e)
- {
- if (! (flags & flag_num_e))
- {
- if (flags & flag_num_zero)
- { sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
- goto e_failed;
- }
-
- if (num_digits == 1 && b == '0')
- flags |= flag_num_zero;
- }
- else
- {
- flags |= flag_num_e_got_sign;
- num_e = (num_e * 10) + (b - '0');
- continue;
- }
-
- top->u.integer = (top->u.integer * 10) + (b - '0');
- continue;
- }
-
- num_fraction = (num_fraction * 10) + (b - '0');
- continue;
- }
-
- if (b == '+' || b == '-')
- {
- if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
- {
- flags |= flag_num_e_got_sign;
-
- if (b == '-')
- flags |= flag_num_e_negative;
-
- continue;
- }
- }
- else if (b == '.' && top->type == json_integer)
- {
- if (!num_digits)
- { sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
- goto e_failed;
- }
-
- top->type = json_double;
- top->u.dbl = (double) top->u.integer;
-
- num_digits = 0;
- continue;
- }
-
- if (! (flags & flag_num_e))
- {
- if (top->type == json_double)
- {
- if (!num_digits)
- { sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
- goto e_failed;
- }
-
- top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits));
- }
-
- if (b == 'e' || b == 'E')
- {
- flags |= flag_num_e;
-
- if (top->type == json_integer)
- {
- top->type = json_double;
- top->u.dbl = (double) top->u.integer;
- }
-
- num_digits = 0;
- flags &= ~ flag_num_zero;
-
- continue;
- }
- }
- else
- {
- if (!num_digits)
- { sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
- goto e_failed;
- }
-
- top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
- }
-
- if (flags & flag_num_negative)
- {
- if (top->type == json_integer)
- top->u.integer = - top->u.integer;
- else
- top->u.dbl = - top->u.dbl;
- }
-
- flags |= flag_next | flag_reproc;
- break;
-
- default:
- break;
- };
- }
-
- if (flags & flag_reproc)
- {
- flags &= ~ flag_reproc;
- -- i;
- }
-
- if (flags & flag_next)
- {
- flags = (flags & ~ flag_next) | flag_need_comma;
-
- if (!top->parent)
- {
- /* root value done */
-
- flags |= flag_done;
- continue;
- }
-
- if (top->parent->type == json_array)
- flags |= flag_seek_value;
-
- if (!state.first_pass)
- {
- json_value * parent = top->parent;
-
- switch (parent->type)
- {
- case json_object:
-
- parent->u.object.values
- [parent->u.object.length].value = top;
-
- break;
-
- case json_array:
-
- parent->u.array.values
- [parent->u.array.length] = top;
+ case 'n':
- break;
-
- default:
- break;
- };
- }
+ if ((end - i) < 3 || *(++i) != 'u' || *(++i) != 'l' || *(++i) != 'l') {
+ goto e_unknown_value;
+ }
- if ( (++ top->parent->u.array.length) > state.uint_max)
- goto e_overflow;
-
- top = top->parent;
+ if (!new_value(&state, &top, &root, &alloc, json_null)) {
+ goto e_alloc_failure;
+ }
- continue;
- }
- }
+ flags |= flag_next;
+ break;
- alloc = root;
- }
+ default:
- return root;
+ if (g_ascii_isdigit(b) || b == '-') {
+ if (!new_value(&state, &top, &root, &alloc, json_integer)) {
+ goto e_alloc_failure;
+ }
-e_unknown_value:
+ if (!state.first_pass) {
+ while (g_ascii_isdigit(b) || b == '+' || b == '-'
+ || b == 'e' || b == 'E' || b == '.') {
+ if ((++i) == end) {
+ b = 0;
+ break;
+ }
- sprintf (error, "%d:%d: Unknown value", cur_line, e_off);
- goto e_failed;
+ b = *i;
+ }
-e_alloc_failure:
+ flags |= flag_next | flag_reproc;
+ break;
+ }
- strcpy (error, "Memory allocation failure");
- goto e_failed;
+ flags &= ~(flag_num_negative | flag_num_e |
+ flag_num_e_got_sign | flag_num_e_negative |
+ flag_num_zero);
-e_overflow:
+ num_digits = 0;
+ num_fraction = 0;
+ num_e = 0;
- sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
- goto e_failed;
+ if (b != '-') {
+ flags |= flag_reproc;
+ break;
+ }
-e_failed:
+ flags |= flag_num_negative;
+ continue;
+ } else { sprintf(error, "%d:%d: Unexpected %c when seeking value",
+ cur_line, e_off, b);
+ goto e_failed; }
+ }
+ ;
+ }
+ ;
+ } else {
+ switch (top->type) {
+ case json_object:
+
+ switch (b) {
+whitespace:
+ continue;
+
+ case '"':
+
+ if (flags & flag_need_comma) {
+ sprintf(error, "%d:%d: Expected , before \"", cur_line, e_off);
+ goto e_failed;
+ }
+
+ flags |= flag_string;
+
+ string = (json_char *) top->_reserved.object_mem;
+ string_length = 0;
+
+ break;
+
+ case '}':
+
+ flags = (flags & ~flag_need_comma) | flag_next;
+ break;
+
+ case ',':
+
+ if (flags & flag_need_comma) {
+ flags &= ~flag_need_comma;
+ break;
+ }
+
+ default:
+
+ sprintf(error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
+ goto e_failed;
+ }
+ ;
+
+ break;
+
+ case json_integer:
+ case json_double:
+
+ if (g_ascii_isdigit(b)) {
+ ++num_digits;
+
+ if (top->type == json_integer || flags & flag_num_e) {
+ if (!(flags & flag_num_e)) {
+ if (flags & flag_num_zero) {
+ sprintf(error,
+ "%d:%d: Unexpected `0` before `%c`",
+ cur_line, e_off, b);
+ goto e_failed;
+ }
+
+ if (num_digits == 1 && b == '0') {
+ flags |= flag_num_zero;
+ }
+ } else {
+ flags |= flag_num_e_got_sign;
+ num_e = (num_e * 10) + (b - '0');
+ continue;
+ }
+
+ top->u.integer = (top->u.integer * 10) + (b - '0');
+ continue;
+ }
+
+ num_fraction = (num_fraction * 10) + (b - '0');
+ continue;
+ }
+
+ if (b == '+' || b == '-') {
+ if ((flags & flag_num_e) && !(flags & flag_num_e_got_sign)) {
+ flags |= flag_num_e_got_sign;
+
+ if (b == '-') {
+ flags |= flag_num_e_negative;
+ }
+
+ continue;
+ }
+ } else if (b == '.' && top->type == json_integer) {
+ if (!num_digits) {
+ sprintf(error, "%d:%d: Expected digit before `.`", cur_line,
+ e_off);
+ goto e_failed;
+ }
+
+ top->type = json_double;
+ top->u.dbl = (double) top->u.integer;
+
+ num_digits = 0;
+ continue;
+ }
+
+ if (!(flags & flag_num_e)) {
+ if (top->type == json_double) {
+ if (!num_digits) {
+ sprintf(error, "%d:%d: Expected digit after `.`",
+ cur_line, e_off);
+ goto e_failed;
+ }
+
+ top->u.dbl += ((double) num_fraction) /
+ (pow(10, (double) num_digits));
+ }
+
+ if (b == 'e' || b == 'E') {
+ flags |= flag_num_e;
+
+ if (top->type == json_integer) {
+ top->type = json_double;
+ top->u.dbl = (double) top->u.integer;
+ }
+
+ num_digits = 0;
+ flags &= ~flag_num_zero;
+
+ continue;
+ }
+ } else {
+ if (!num_digits) {
+ sprintf(error, "%d:%d: Expected digit after `e`", cur_line,
+ e_off);
+ goto e_failed;
+ }
+
+ top->u.dbl *=
+ pow(10,
+ (double) (flags & flag_num_e_negative ? -num_e : num_e));
+ }
+
+ if (flags & flag_num_negative) {
+ if (top->type == json_integer) {
+ top->u.integer = -top->u.integer;
+ } else {
+ top->u.dbl = -top->u.dbl;
+ }
+ }
+
+ flags |= flag_next | flag_reproc;
+ break;
+
+ default:
+ break;
+ }
+ ;
+ }
+
+ if (flags & flag_reproc) {
+ flags &= ~flag_reproc;
+ --i;
+ }
+
+ if (flags & flag_next) {
+ flags = (flags & ~flag_next) | flag_need_comma;
+
+ if (!top->parent) {
+ /* root value done */
+
+ flags |= flag_done;
+ continue;
+ }
+
+ if (top->parent->type == json_array) {
+ flags |= flag_seek_value;
+ }
+
+ if (!state.first_pass) {
+ json_value * parent = top->parent;
+
+ switch (parent->type) {
+ case json_object:
+
+ parent->u.object.values
+ [parent->u.object.length].value = top;
+
+ break;
+
+ case json_array:
+
+ parent->u.array.values
+ [parent->u.array.length] = top;
- if (error_buf)
- {
- if (*error)
- strcpy (error_buf, error);
- else
- strcpy (error_buf, "Unknown error");
- }
+ break;
- if (state.first_pass)
- alloc = root;
+ default:
+ break;
+ }
+ ;
+ }
- while (alloc)
- {
- top = alloc->_reserved.next_alloc;
- state.settings.mem_free (alloc, state.settings.user_data);
- alloc = top;
- }
+ if ((++top->parent->u.array.length) > state.uint_max) {
+ goto e_overflow;
+ }
- if (!state.first_pass)
- json_value_free_ex (&state.settings, root);
+ top = top->parent;
- return 0;
+ continue;
+ }
+ }
+
+ alloc = root;
+ }
+
+ return root;
+
+e_unknown_value:
+
+ sprintf(error, "%d:%d: Unknown value", cur_line, e_off);
+ goto e_failed;
+
+e_alloc_failure:
+
+ strcpy(error, "Memory allocation failure");
+ goto e_failed;
+
+e_overflow:
+
+ sprintf(error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
+ goto e_failed;
+
+e_failed:
+
+ if (error_buf) {
+ if (*error) {
+ strcpy(error_buf, error);
+ } else {
+ strcpy(error_buf, "Unknown error");
+ }
+ }
+
+ if (state.first_pass) {
+ alloc = root;
+ }
+
+ while (alloc) {
+ top = alloc->_reserved.next_alloc;
+ state.settings.mem_free(alloc, state.settings.user_data);
+ alloc = top;
+ }
+
+ if (!state.first_pass) {
+ json_value_free_ex(&state.settings, root);
+ }
+
+ return 0;
}
-json_value * json_parse (const json_char * json, size_t length)
+json_value * json_parse(const json_char * json, size_t length)
{
- json_settings settings = { 0 };
- return json_parse_ex (&settings, json, length, 0);
+ json_settings settings = { 0 };
+
+ return json_parse_ex(&settings, json, length, 0);
}
-void json_value_free_ex (json_settings * settings, json_value * value)
+void json_value_free_ex(json_settings * settings, json_value * value)
{
- json_value * cur_value;
+ json_value * cur_value;
- if (!value)
- return;
+ if (!value) {
+ return;
+ }
- value->parent = 0;
+ value->parent = 0;
- while (value)
- {
- switch (value->type)
- {
- case json_array:
+ while (value) {
+ switch (value->type) {
+ case json_array:
- if (!value->u.array.length)
- {
- settings->mem_free (value->u.array.values, settings->user_data);
- break;
- }
+ if (!value->u.array.length) {
+ settings->mem_free(value->u.array.values, settings->user_data);
+ break;
+ }
- value = value->u.array.values [-- value->u.array.length];
- continue;
+ value = value->u.array.values [--value->u.array.length];
+ continue;
- case json_object:
+ case json_object:
- if (!value->u.object.length)
- {
- settings->mem_free (value->u.object.values, settings->user_data);
- break;
- }
+ if (!value->u.object.length) {
+ settings->mem_free(value->u.object.values, settings->user_data);
+ break;
+ }
- value = value->u.object.values [-- value->u.object.length].value;
- continue;
+ value = value->u.object.values [--value->u.object.length].value;
+ continue;
- case json_string:
+ case json_string:
- settings->mem_free (value->u.string.ptr, settings->user_data);
- break;
+ settings->mem_free(value->u.string.ptr, settings->user_data);
+ break;
- default:
- break;
- };
+ default:
+ break;
+ }
+ ;
- cur_value = value;
- value = value->parent;
- settings->mem_free (cur_value, settings->user_data);
- }
+ cur_value = value;
+ value = value->parent;
+ settings->mem_free(cur_value, settings->user_data);
+ }
}
-void json_value_free (json_value * value)
+void json_value_free(json_value * value)
{
- json_settings settings = { 0 };
- settings.mem_free = default_free;
- json_value_free_ex (&settings, value);
+ json_settings settings = { 0 };
+
+ settings.mem_free = default_free;
+ json_value_free_ex(&settings, value);
}
diff --git a/lib/json.h b/lib/json.h
index cf9f0dd5..2077fb21 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -50,220 +50,211 @@
#include <string.h>
- extern "C"
- {
+extern "C"
+{
#endif
-typedef struct
-{
- unsigned long max_memory;
- int settings;
+typedef struct {
+ unsigned long max_memory;
+ int settings;
- /* Custom allocator support (leave null to use malloc/free)
- */
+ /* Custom allocator support (leave null to use malloc/free)
+ */
- void * (* mem_alloc) (size_t, int zero, void * user_data);
- void (* mem_free) (void *, void * user_data);
+ void * (*mem_alloc)(size_t, int zero, void * user_data);
+ void (* mem_free)(void *, void * user_data);
- void * user_data; /* will be passed to mem_alloc and mem_free */
+ void * user_data; /* will be passed to mem_alloc and mem_free */
} json_settings;
#define json_enable_comments 0x01
-typedef enum
-{
- json_none,
- json_object,
- json_array,
- json_integer,
- json_double,
- json_string,
- json_boolean,
- json_null
+typedef enum {
+ json_none,
+ json_object,
+ json_array,
+ json_integer,
+ json_double,
+ json_string,
+ json_boolean,
+ json_null
} json_type;
extern const struct _json_value json_value_none;
-typedef struct _json_value
-{
- struct _json_value * parent;
+typedef struct _json_value {
+ struct _json_value * parent;
- json_type type;
+ json_type type;
- union
- {
- int boolean;
- json_int_t integer;
- double dbl;
+ union {
+ int boolean;
+ json_int_t integer;
+ double dbl;
- struct
- {
- unsigned int length;
- json_char * ptr; /* null terminated */
+ struct {
+ unsigned int length;
+ json_char * ptr; /* null terminated */
- } string;
+ } string;
- struct
- {
- unsigned int length;
+ struct {
+ unsigned int length;
- struct
- {
- json_char * name;
- unsigned int name_length;
+ struct {
+ json_char * name;
+ unsigned int name_length;
- struct _json_value * value;
+ struct _json_value * value;
- } * values;
+ } * values;
- #if defined(__cplusplus) && __cplusplus >= 201103L
- decltype(values) begin () const
- { return values;
- }
- decltype(values) end () const
- { return values + length;
- }
- #endif
+ #if defined(__cplusplus) && __cplusplus >= 201103L
+ decltype(values) begin() const
+ { return values; }
+ decltype(values) end() const
+ { return values + length; }
+ #endif
- } object;
+ } object;
- struct
- {
- unsigned int length;
- struct _json_value ** values;
+ struct {
+ unsigned int length;
+ struct _json_value ** values;
- #if defined(__cplusplus) && __cplusplus >= 201103L
- decltype(values) begin () const
- { return values;
- }
- decltype(values) end () const
- { return values + length;
- }
- #endif
+ #if defined(__cplusplus) && __cplusplus >= 201103L
+ decltype(values) begin() const
+ { return values; }
+ decltype(values) end() const
+ { return values + length; }
+ #endif
- } array;
+ } array;
- } u;
+ } u;
- union
- {
- struct _json_value * next_alloc;
- void * object_mem;
+ union {
+ struct _json_value * next_alloc;
+ void * object_mem;
- } _reserved;
+ } _reserved;
- /* Some C++ operator sugar */
+ /* Some C++ operator sugar */
#ifdef __cplusplus
- public:
-
- inline _json_value ()
- { memset (this, 0, sizeof (_json_value));
- }
-
- inline const struct _json_value &operator [] (int index) const
- {
- if (type != json_array || index < 0
- || ((unsigned int) index) >= u.array.length)
- {
- return json_value_none;
- }
-
- return *u.array.values [index];
- }
-
- inline const struct _json_value &operator [] (const char * index) const
- {
- if (type != json_object)
- return json_value_none;
-
- for (unsigned int i = 0; i < u.object.length; ++ i)
- if (!strcmp (u.object.values [i].name, index))
- return *u.object.values [i].value;
-
- return json_value_none;
- }
-
- inline operator const char * () const
- {
- switch (type)
- {
- case json_string:
- return u.string.ptr;
-
- default:
- return "";
- };
- }
-
- inline operator json_int_t () const
- {
- switch (type)
- {
- case json_integer:
- return u.integer;
-
- case json_double:
- return (json_int_t) u.dbl;
-
- default:
- return 0;
- };
- }
-
- inline operator bool () const
- {
- if (type != json_boolean)
- return false;
-
- return u.boolean != 0;
- }
-
- inline operator double () const
- {
- switch (type)
- {
- case json_integer:
- return (double) u.integer;
-
- case json_double:
- return u.dbl;
-
- default:
- return 0;
- };
- }
+public:
+
+ inline _json_value ()
+ {
+ memset(this, 0, sizeof(_json_value));
+ }
+
+ inline const struct _json_value &operator [](int index) const
+ {
+ if (type != json_array || index < 0
+ || ((unsigned int)index) >= u.array.length) {
+ return json_value_none;
+ }
+
+ return *u.array.values [index];
+ }
+
+ inline const struct _json_value &operator [](const char * index) const
+ {
+ if (type != json_object) {
+ return json_value_none;
+ }
+
+ for (unsigned int i = 0; i < u.object.length; ++i) {
+ if (!strcmp(u.object.values [i].name, index)) {
+ return *u.object.values [i].value;
+ }
+ }
+
+ return json_value_none;
+ }
+
+ inline operator const char *() const
+ {
+ switch (type) {
+ case json_string:
+ return u.string.ptr;
+
+ default:
+ return "";
+ }
+ ;
+ }
+
+ inline operator json_int_t() const
+ {
+ switch (type) {
+ case json_integer:
+ return u.integer;
+
+ case json_double:
+ return (json_int_t)u.dbl;
+
+ default:
+ return 0;
+ }
+ ;
+ }
+
+ inline operator bool() const
+ {
+ if (type != json_boolean) {
+ return false;
+ }
+
+ return u.boolean != 0;
+ }
+
+ inline operator double() const
+ {
+ switch (type) {
+ case json_integer:
+ return (double)u.integer;
+
+ case json_double:
+ return u.dbl;
+
+ default:
+ return 0;
+ }
+ ;
+ }
#endif
} json_value;
-json_value * json_parse (const json_char * json,
- size_t length);
+json_value * json_parse(const json_char * json,
+ size_t length);
#define json_error_max 128
-json_value * json_parse_ex (json_settings * settings,
- const json_char * json,
- size_t length,
- char * error);
+json_value * json_parse_ex(json_settings * settings,
+ const json_char * json,
+ size_t length,
+ char * error);
-void json_value_free (json_value *);
+void json_value_free(json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
-void json_value_free_ex (json_settings * settings,
- json_value *);
+void json_value_free_ex(json_settings * settings,
+ json_value *);
#ifdef __cplusplus
- } /* extern "C" */
+} /* extern "C" */
#endif
#endif
diff --git a/lib/json_util.c b/lib/json_util.c
index ff1d5bb9..b4f5078a 100644
--- a/lib/json_util.c
+++ b/lib/json_util.c
@@ -27,36 +27,41 @@
#include "json_util.h"
-json_value *json_o_get( const json_value *obj, const json_char *name )
-{
+json_value *json_o_get(const json_value *obj, const json_char *name)
+{
int i;
-
- if( !obj || obj->type != json_object )
+
+ if (!obj || obj->type != json_object) {
return NULL;
+ }
- for( i = 0; i < obj->u.object.length; ++ i)
- if( strcmp( obj->u.object.values[i].name, name ) == 0 )
+ for (i = 0; i < obj->u.object.length; ++i) {
+ if (strcmp(obj->u.object.values[i].name, name) == 0) {
return obj->u.object.values[i].value;
+ }
+ }
return NULL;
}
-const char *json_o_str( const json_value *obj, const json_char *name )
-{
- json_value *ret = json_o_get( obj, name );
-
- if( ret && ret->type == json_string )
+const char *json_o_str(const json_value *obj, const json_char *name)
+{
+ json_value *ret = json_o_get(obj, name);
+
+ if (ret && ret->type == json_string) {
return ret->u.string.ptr;
- else
+ } else {
return NULL;
+ }
}
-char *json_o_strdup( const json_value *obj, const json_char *name )
+char *json_o_strdup(const json_value *obj, const json_char *name)
{
- json_value *ret = json_o_get( obj, name );
-
- if( ret && ret->type == json_string && ret->u.string.ptr )
- return g_memdup( ret->u.string.ptr, ret->u.string.length + 1 );
- else
+ json_value *ret = json_o_get(obj, name);
+
+ if (ret && ret->type == json_string && ret->u.string.ptr) {
+ return g_memdup(ret->u.string.ptr, ret->u.string.length + 1);
+ } else {
return NULL;
+ }
}
diff --git a/lib/json_util.h b/lib/json_util.h
index 7eb49515..363efc89 100644
--- a/lib/json_util.h
+++ b/lib/json_util.h
@@ -25,11 +25,11 @@
#define JSON_O_FOREACH(o, k, v) \
char *k; json_value *v; int __i; \
- for( __i = 0; ( __i < (o)->u.object.length ) && \
- ( k = (o)->u.object.values[__i].name ) && \
- ( v = (o)->u.object.values[__i].value ); \
- __i ++ )
+ for (__i = 0; (__i < (o)->u.object.length) && \
+ (k = (o)->u.object.values[__i].name) && \
+ (v = (o)->u.object.values[__i].value); \
+ __i ++)
-json_value *json_o_get( const json_value *obj, const json_char *name );
-const char *json_o_str( const json_value *obj, const json_char *name );
-char *json_o_strdup( const json_value *obj, const json_char *name );
+json_value *json_o_get(const json_value *obj, const json_char *name);
+const char *json_o_str(const json_value *obj, const json_char *name);
+char *json_o_strdup(const json_value *obj, const json_char *name);
diff --git a/lib/md5.c b/lib/md5.c
index 22c7871f..9bc7e57f 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -18,6 +18,7 @@ void md5_append(md5_state_t *ctx, const guint8 *buf, unsigned int len)
void md5_finish(md5_state_t *ctx, guint8 digest[MD5_HASH_SIZE])
{
gsize digest_len = MD5_HASH_SIZE;
+
g_checksum_get_digest(*ctx, digest, &digest_len);
g_checksum_free(*ctx);
}
@@ -27,6 +28,7 @@ void md5_finish(md5_state_t *ctx, guint8 digest[MD5_HASH_SIZE])
void md5_digest_keep(md5_state_t *ctx, guint8 digest[MD5_HASH_SIZE])
{
md5_state_t copy = g_checksum_copy(*ctx);
+
md5_finish(&copy, digest);
}
diff --git a/lib/misc.c b/lib/misc.c
index 43322cab..74e28bfb 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -54,9 +54,11 @@ void strip_linefeed(gchar *text)
int i, j;
gchar *text2 = g_malloc(strlen(text) + 1);
- for (i = 0, j = 0; text[i]; i++)
- if (text[i] != '\r')
+ for (i = 0, j = 0; text[i]; i++) {
+ if (text[i] != '\r') {
text2[j++] = text[i];
+ }
+ }
text2[j] = '\0';
strcpy(text, text2);
@@ -74,47 +76,47 @@ time_t get_time(int year, int month, int day, int hour, int min, int sec)
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60;
-
+
return mktime(&tm);
}
-time_t mktime_utc( struct tm *tp )
+time_t mktime_utc(struct tm *tp)
{
struct tm utc;
time_t res, tres;
-
+
tp->tm_isdst = -1;
- res = mktime( tp );
+ res = mktime(tp);
/* Problem is, mktime() just gave us the GMT timestamp for the
given local time... While the given time WAS NOT local. So
we should fix this now.
-
+
Now I could choose between messing with environment variables
(kludgy) or using timegm() (not portable)... Or doing the
following, which I actually prefer...
-
+
tzset() may also work but in other places I actually want to
use local time.
-
+
FFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUU!! */
- gmtime_r( &res, &utc );
+ gmtime_r(&res, &utc);
utc.tm_isdst = -1;
- if( utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min )
+ if (utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min) {
/* Sweet! We're in UTC right now... */
return res;
-
- tres = mktime( &utc );
+ }
+
+ tres = mktime(&utc);
res += res - tres;
-
+
/* Yes, this is a hack. And it will go wrong around DST changes.
BUT this is more likely to be threadsafe than messing with
environment variables, and possibly more portable... */
-
+
return res;
}
-typedef struct htmlentity
-{
+typedef struct htmlentity {
char code[7];
char is[3];
} htmlentity_t;
@@ -150,322 +152,330 @@ static const htmlentity_t ent[] =
{ "", "" }
};
-void strip_html( char *in )
+void strip_html(char *in)
{
char *start = in;
- char out[strlen(in)+1];
+ char out[strlen(in) + 1];
char *s = out, *cs;
int i, matched;
int taglen;
-
- memset( out, 0, sizeof( out ) );
-
- while( *in )
- {
- if( *in == '<' && ( g_ascii_isalpha( *(in+1) ) || *(in+1) == '/' ) )
- {
+
+ memset(out, 0, sizeof(out));
+
+ while (*in) {
+ if (*in == '<' && (g_ascii_isalpha(*(in + 1)) || *(in + 1) == '/')) {
/* If in points at a < and in+1 points at a letter or a slash, this is probably
a HTML-tag. Try to find a closing > and continue there. If the > can't be
found, assume that it wasn't a HTML-tag after all. */
-
+
cs = in;
-
- while( *in && *in != '>' )
- in ++;
-
+
+ while (*in && *in != '>') {
+ in++;
+ }
+
taglen = in - cs - 1; /* not <0 because the above loop runs at least once */
- if( *in )
- {
- if( g_strncasecmp( cs+1, "b", taglen) == 0 )
+ if (*in) {
+ if (g_strncasecmp(cs + 1, "b", taglen) == 0) {
*(s++) = '\x02';
- else if( g_strncasecmp( cs+1, "/b", taglen) == 0 )
+ } else if (g_strncasecmp(cs + 1, "/b", taglen) == 0) {
*(s++) = '\x02';
- else if( g_strncasecmp( cs+1, "i", taglen) == 0 )
+ } else if (g_strncasecmp(cs + 1, "i", taglen) == 0) {
*(s++) = '\x1f';
- else if( g_strncasecmp( cs+1, "/i", taglen) == 0 )
+ } else if (g_strncasecmp(cs + 1, "/i", taglen) == 0) {
*(s++) = '\x1f';
- else if( g_strncasecmp( cs+1, "br", taglen) == 0 )
+ } else if (g_strncasecmp(cs + 1, "br", taglen) == 0) {
*(s++) = '\n';
- in ++;
- }
- else
- {
+ }
+ in++;
+ } else {
in = cs;
*(s++) = *(in++);
}
- }
- else if( *in == '&' )
- {
+ } else if (*in == '&') {
cs = ++in;
- while( *in && g_ascii_isalpha( *in ) )
- in ++;
-
- if( *in == ';' ) in ++;
+ while (*in && g_ascii_isalpha(*in)) {
+ in++;
+ }
+
+ if (*in == ';') {
+ in++;
+ }
matched = 0;
-
- for( i = 0; *ent[i].code; i ++ )
- if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 )
- {
+
+ for (i = 0; *ent[i].code; i++) {
+ if (g_strncasecmp(ent[i].code, cs, strlen(ent[i].code)) == 0) {
int j;
-
- for( j = 0; ent[i].is[j]; j ++ )
+
+ for (j = 0; ent[i].is[j]; j++) {
*(s++) = ent[i].is[j];
-
+ }
+
matched = 1;
break;
}
+ }
/* None of the entities were matched, so return the string */
- if( !matched )
- {
+ if (!matched) {
in = cs - 1;
*(s++) = *(in++);
}
- }
- else
- {
+ } else {
*(s++) = *(in++);
}
}
-
- strcpy( start, out );
+
+ strcpy(start, out);
}
-char *escape_html( const char *html )
+char *escape_html(const char *html)
{
const char *c = html;
GString *ret;
char *str;
-
- if( html == NULL )
- return( NULL );
-
- ret = g_string_new( "" );
-
- while( *c )
- {
- switch( *c )
- {
- case '&':
- ret = g_string_append( ret, "&amp;" );
- break;
- case '<':
- ret = g_string_append( ret, "&lt;" );
- break;
- case '>':
- ret = g_string_append( ret, "&gt;" );
- break;
- case '"':
- ret = g_string_append( ret, "&quot;" );
- break;
- default:
- ret = g_string_append_c( ret, *c );
+
+ if (html == NULL) {
+ return(NULL);
+ }
+
+ ret = g_string_new("");
+
+ while (*c) {
+ switch (*c) {
+ case '&':
+ ret = g_string_append(ret, "&amp;");
+ break;
+ case '<':
+ ret = g_string_append(ret, "&lt;");
+ break;
+ case '>':
+ ret = g_string_append(ret, "&gt;");
+ break;
+ case '"':
+ ret = g_string_append(ret, "&quot;");
+ break;
+ default:
+ ret = g_string_append_c(ret, *c);
}
- c ++;
+ c++;
}
-
+
str = ret->str;
- g_string_free( ret, FALSE );
- return( str );
+ g_string_free(ret, FALSE);
+ return(str);
}
/* Decode%20a%20file%20name */
-void http_decode( char *s )
+void http_decode(char *s)
{
char *t;
int i, j, k;
-
- t = g_new( char, strlen( s ) + 1 );
-
- for( i = j = 0; s[i]; i ++, j ++ )
- {
- if( s[i] == '%' )
- {
- if( sscanf( s + i + 1, "%2x", &k ) )
- {
+
+ t = g_new(char, strlen(s) + 1);
+
+ for (i = j = 0; s[i]; i++, j++) {
+ if (s[i] == '%') {
+ if (sscanf(s + i + 1, "%2x", &k)) {
t[j] = k;
i += 2;
- }
- else
- {
+ } else {
*t = 0;
break;
}
- }
- else
- {
+ } else {
t[j] = s[i];
}
}
t[j] = 0;
-
- strcpy( s, t );
- g_free( t );
+
+ strcpy(s, t);
+ g_free(t);
}
/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */
/* This fuction is safe, but make sure you call it safely as well! */
-void http_encode( char *s )
+void http_encode(char *s)
{
- char t[strlen(s)+1];
+ char t[strlen(s) + 1];
int i, j;
-
- strcpy( t, s );
- for( i = j = 0; t[i]; i ++, j ++ )
- {
+
+ strcpy(t, s);
+ for (i = j = 0; t[i]; i++, j++) {
/* Warning: g_ascii_isalnum() is locale-aware, so don't use it here! */
- if( ( t[i] >= 'A' && t[i] <= 'Z' ) ||
- ( t[i] >= 'a' && t[i] <= 'z' ) ||
- ( t[i] >= '0' && t[i] <= '9' ) ||
- strchr( "._-~", t[i] ) )
- {
+ if ((t[i] >= 'A' && t[i] <= 'Z') ||
+ (t[i] >= 'a' && t[i] <= 'z') ||
+ (t[i] >= '0' && t[i] <= '9') ||
+ strchr("._-~", t[i])) {
s[j] = t[i];
- }
- else
- {
- sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
+ } else {
+ sprintf(s + j, "%%%02X", ((unsigned char *) t)[i]);
j += 2;
}
}
s[j] = 0;
}
-/* Strip newlines from a string. Modifies the string passed to it. */
-char *strip_newlines( char *source )
+/* Strip newlines from a string. Modifies the string passed to it. */
+char *strip_newlines(char *source)
{
- int i;
+ int i;
- for( i = 0; source[i] != '\0'; i ++ )
- if( source[i] == '\n' || source[i] == '\r' )
+ for (i = 0; source[i] != '\0'; i++) {
+ if (source[i] == '\n' || source[i] == '\r') {
source[i] = ' ';
-
+ }
+ }
+
return source;
}
/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */
-char *ipv6_wrap( char *src )
+char *ipv6_wrap(char *src)
{
static char dst[64];
int i;
-
- for( i = 0; src[i]; i ++ )
- if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
+
+ for (i = 0; src[i]; i++) {
+ if ((src[i] < '0' || src[i] > '9') && src[i] != '.') {
break;
-
+ }
+ }
+
/* Hmm, it's not even an IP... */
- if( src[i] )
+ if (src[i]) {
return src;
-
- g_snprintf( dst, sizeof( dst ), "::ffff:%s", src );
-
+ }
+
+ g_snprintf(dst, sizeof(dst), "::ffff:%s", src);
+
return dst;
}
/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */
-char *ipv6_unwrap( char *src )
+char *ipv6_unwrap(char *src)
{
int i;
-
- if( g_strncasecmp( src, "::ffff:", 7 ) != 0 )
+
+ if (g_strncasecmp(src, "::ffff:", 7) != 0) {
return src;
-
- for( i = 7; src[i]; i ++ )
- if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
+ }
+
+ for (i = 7; src[i]; i++) {
+ if ((src[i] < '0' || src[i] > '9') && src[i] != '.') {
break;
-
+ }
+ }
+
/* Hmm, it's not even an IP... */
- if( src[i] )
+ if (src[i]) {
return src;
-
- return ( src + 7 );
+ }
+
+ return (src + 7);
}
/* Convert from one charset to another.
-
+
from_cs, to_cs: Source and destination charsets
src, dst: Source and destination strings
size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though.
maxbuf: Maximum number of bytes to write to dst
-
+
Returns the number of bytes written to maxbuf or -1 on an error.
*/
-signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf )
+signed int do_iconv(char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf)
{
GIConv cd;
size_t res;
size_t inbytesleft, outbytesleft;
char *inbuf = src;
char *outbuf = dst;
-
- cd = g_iconv_open( to_cs, from_cs );
- if( cd == (GIConv) -1 )
+
+ cd = g_iconv_open(to_cs, from_cs);
+ if (cd == (GIConv) - 1) {
return -1;
-
- inbytesleft = size ? size : strlen( src );
+ }
+
+ inbytesleft = size ? size : strlen(src);
outbytesleft = maxbuf - 1;
- res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
+ res = g_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
*outbuf = '\0';
- g_iconv_close( cd );
-
- if( res != 0 )
+ g_iconv_close(cd);
+
+ if (res != 0) {
return -1;
- else
+ } else {
return outbuf - dst;
+ }
}
/* A wrapper for /dev/urandom.
* If /dev/urandom is not present or not usable, it calls abort()
* to prevent bitlbee from working without a decent entropy source */
-void random_bytes( unsigned char *buf, int count )
+void random_bytes(unsigned char *buf, int count)
{
int fd;
- if( ( ( fd = open( "/dev/urandom", O_RDONLY ) ) == -1 ) ||
- ( read( fd, buf, count ) == -1 ) )
- {
- log_message( LOGLVL_ERROR, "/dev/urandom not present - aborting" );
+
+ if (((fd = open("/dev/urandom", O_RDONLY)) == -1) ||
+ (read(fd, buf, count) == -1)) {
+ log_message(LOGLVL_ERROR, "/dev/urandom not present - aborting");
abort();
}
- close( fd );
+ close(fd);
}
-int is_bool( char *value )
+int is_bool(char *value)
{
- if( *value == 0 )
+ if (*value == 0) {
return 0;
-
- if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
+ }
+
+ if ((g_strcasecmp(value,
+ "true") == 0) || (g_strcasecmp(value, "yes") == 0) || (g_strcasecmp(value, "on") == 0)) {
return 1;
- if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
+ }
+ if ((g_strcasecmp(value,
+ "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) {
return 1;
-
- while( *value )
- if( !g_ascii_isdigit( *value ) )
+ }
+
+ while (*value) {
+ if (!g_ascii_isdigit(*value)) {
return 0;
- else
- value ++;
-
+ } else {
+ value++;
+ }
+ }
+
return 1;
}
-int bool2int( char *value )
+int bool2int(char *value)
{
int i;
-
- if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
+
+ if ((g_strcasecmp(value,
+ "true") == 0) || (g_strcasecmp(value, "yes") == 0) || (g_strcasecmp(value, "on") == 0)) {
return 1;
- if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
+ }
+ if ((g_strcasecmp(value,
+ "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) {
return 0;
-
- if( sscanf( value, "%d", &i ) == 1 )
+ }
+
+ if (sscanf(value, "%d", &i) == 1) {
return i;
-
+ }
+
return 0;
}
-struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )
-{
+struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain)
+{
struct ns_srv_reply **replies = NULL;
+
#ifdef HAVE_RESOLV_A
struct ns_srv_reply *reply = NULL;
char name[1024];
@@ -474,148 +484,148 @@ struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )
ns_msg nsh;
ns_rr rr;
int n, len, size;
-
- g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
-
- if( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( querybuf ) ) ) <= 0 )
+
+ g_snprintf(name, sizeof(name), "_%s._%s.%s", service, protocol, domain);
+
+ if ((size = res_query(name, ns_c_in, ns_t_srv, querybuf, sizeof(querybuf))) <= 0) {
return NULL;
-
- if( ns_initparse( querybuf, size, &nsh ) != 0 )
+ }
+
+ if (ns_initparse(querybuf, size, &nsh) != 0) {
return NULL;
-
+ }
+
n = 0;
- while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 )
- {
+ while (ns_parserr(&nsh, ns_s_an, n, &rr) == 0) {
char name[NS_MAXDNAME];
- if( ns_rr_rdlen( rr ) < 7)
- break;
+ if (ns_rr_rdlen(rr) < 7) {
+ break;
+ }
- buf = ns_rr_rdata( rr );
-
- if( dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1 )
+ buf = ns_rr_rdata(rr);
+
+ if (dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1) {
break;
+ }
len = strlen(name) + 1;
-
- reply = g_malloc( sizeof( struct ns_srv_reply ) + len );
- memcpy( reply->name, name, len );
-
- reply->prio = ( buf[0] << 8 ) | buf[1];
- reply->weight = ( buf[2] << 8 ) | buf[3];
- reply->port = ( buf[4] << 8 ) | buf[5];
-
- n ++;
- replies = g_renew( struct ns_srv_reply *, replies, n + 1 );
- replies[n-1] = reply;
- }
- if( replies )
+
+ reply = g_malloc(sizeof(struct ns_srv_reply) + len);
+ memcpy(reply->name, name, len);
+
+ reply->prio = (buf[0] << 8) | buf[1];
+ reply->weight = (buf[2] << 8) | buf[3];
+ reply->port = (buf[4] << 8) | buf[5];
+
+ n++;
+ replies = g_renew(struct ns_srv_reply *, replies, n + 1);
+ replies[n - 1] = reply;
+ }
+ if (replies) {
replies[n] = NULL;
+ }
#endif
-
+
return replies;
}
-void srv_free( struct ns_srv_reply **srv )
+void srv_free(struct ns_srv_reply **srv)
{
int i;
-
- if( srv == NULL )
+
+ if (srv == NULL) {
return;
-
- for( i = 0; srv[i]; i ++ )
- g_free( srv[i] );
- g_free( srv );
+ }
+
+ for (i = 0; srv[i]; i++) {
+ g_free(srv[i]);
+ }
+ g_free(srv);
}
/* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */
-char *word_wrap( const char *msg, int line_len )
+char *word_wrap(const char *msg, int line_len)
{
- GString *ret = g_string_sized_new( strlen( msg ) + 16 );
-
- while( strlen( msg ) > line_len )
- {
+ GString *ret = g_string_sized_new(strlen(msg) + 16);
+
+ while (strlen(msg) > line_len) {
int i;
-
+
/* First try to find out if there's a newline already. Don't
want to add more splits than necessary. */
- for( i = line_len; i > 0 && msg[i] != '\n'; i -- );
- if( msg[i] == '\n' )
- {
- g_string_append_len( ret, msg, i + 1 );
+ for (i = line_len; i > 0 && msg[i] != '\n'; i--) {
+ ;
+ }
+ if (msg[i] == '\n') {
+ g_string_append_len(ret, msg, i + 1);
msg += i + 1;
continue;
}
-
- for( i = line_len; i > 0; i -- )
- {
- if( msg[i] == '-' )
- {
- g_string_append_len( ret, msg, i + 1 );
- g_string_append_c( ret, '\n' );
+
+ for (i = line_len; i > 0; i--) {
+ if (msg[i] == '-') {
+ g_string_append_len(ret, msg, i + 1);
+ g_string_append_c(ret, '\n');
msg += i + 1;
break;
- }
- else if( msg[i] == ' ' )
- {
- g_string_append_len( ret, msg, i );
- g_string_append_c( ret, '\n' );
+ } else if (msg[i] == ' ') {
+ g_string_append_len(ret, msg, i);
+ g_string_append_c(ret, '\n');
msg += i + 1;
break;
}
}
- if( i == 0 )
- {
- g_string_append_len( ret, msg, line_len );
- g_string_append_c( ret, '\n' );
+ if (i == 0) {
+ g_string_append_len(ret, msg, line_len);
+ g_string_append_c(ret, '\n');
msg += line_len;
}
}
- g_string_append( ret, msg );
-
- return g_string_free( ret, FALSE );
+ g_string_append(ret, msg);
+
+ return g_string_free(ret, FALSE);
}
-gboolean ssl_sockerr_again( void *ssl )
+gboolean ssl_sockerr_again(void *ssl)
{
- if( ssl )
+ if (ssl) {
return ssl_errno == SSL_AGAIN;
- else
+ } else {
return sockerr_again();
+ }
}
/* Returns values: -1 == Failure (base64-decoded to something unexpected)
0 == Okay
1 == Password doesn't match the hash. */
-int md5_verify_password( char *password, char *hash )
+int md5_verify_password(char *password, char *hash)
{
md5_byte_t *pass_dec = NULL;
md5_byte_t pass_md5[16];
md5_state_t md5_state;
int ret = -1, i;
-
- if( base64_decode( hash, &pass_dec ) == 21 )
- {
- md5_init( &md5_state );
- md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) );
- md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */
- md5_finish( &md5_state, pass_md5 );
-
- for( i = 0; i < 16; i ++ )
- {
- if( pass_dec[i] != pass_md5[i] )
- {
+
+ if (base64_decode(hash, &pass_dec) == 21) {
+ md5_init(&md5_state);
+ md5_append(&md5_state, (md5_byte_t *) password, strlen(password));
+ md5_append(&md5_state, (md5_byte_t *) pass_dec + 16, 5); /* Hmmm, salt! */
+ md5_finish(&md5_state, pass_md5);
+
+ for (i = 0; i < 16; i++) {
+ if (pass_dec[i] != pass_md5[i]) {
ret = 1;
break;
}
}
-
+
/* If we reached the end of the loop, it was a match! */
- if( i == 16 )
+ if (i == 16) {
ret = 0;
+ }
}
-
- g_free( pass_dec );
+
+ g_free(pass_dec);
return ret;
}
@@ -623,119 +633,125 @@ int md5_verify_password( char *password, char *hash )
/* Split commands (root-style, *not* IRC-style). Handles "quoting of"
white\ space in 'various ways'. Returns a NULL-terminated static
char** so watch out with nested use! Definitely not thread-safe. */
-char **split_command_parts( char *command, int limit )
+char **split_command_parts(char *command, int limit)
{
- static char *cmd[IRC_MAX_ARGS+1];
+ static char *cmd[IRC_MAX_ARGS + 1];
char *s, q = 0;
int k;
-
- memset( cmd, 0, sizeof( cmd ) );
+
+ memset(cmd, 0, sizeof(cmd));
cmd[0] = command;
k = 1;
- for( s = command; *s && k < IRC_MAX_ARGS; s ++ )
- {
- if( *s == ' ' && !q )
- {
+ for (s = command; *s && k < IRC_MAX_ARGS; s++) {
+ if (*s == ' ' && !q) {
*s = 0;
- while( *++s == ' ' );
- if( k != limit && (*s == '"' || *s == '\'') )
- {
+ while (*++s == ' ') {
+ ;
+ }
+ if (k != limit && (*s == '"' || *s == '\'')) {
q = *s;
- s ++;
+ s++;
}
- if( *s )
- {
+ if (*s) {
cmd[k++] = s;
if (limit && k > limit) {
break;
}
- s --;
- }
- else
- {
+ s--;
+ } else {
break;
}
- }
- else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
- {
+ } else if (*s == '\\' && ((!q && s[1]) || (q && q == s[1]))) {
char *cpy;
-
- for( cpy = s; *cpy; cpy ++ )
+
+ for (cpy = s; *cpy; cpy++) {
cpy[0] = cpy[1];
- }
- else if( *s == q )
- {
+ }
+ } else if (*s == q) {
q = *s = 0;
}
}
-
+
/* Full zero-padding for easier argc checking. */
- while( k <= IRC_MAX_ARGS )
+ while (k <= IRC_MAX_ARGS) {
cmd[k++] = NULL;
-
+ }
+
return cmd;
}
-char *get_rfc822_header( const char *text, const char *header, int len )
+char *get_rfc822_header(const char *text, const char *header, int len)
{
- int hlen = strlen( header ), i;
+ int hlen = strlen(header), i;
const char *ret;
-
- if( text == NULL )
+
+ if (text == NULL) {
return NULL;
-
- if( len == 0 )
- len = strlen( text );
-
+ }
+
+ if (len == 0) {
+ len = strlen(text);
+ }
+
i = 0;
- while( ( i + hlen ) < len )
- {
+ while ((i + hlen) < len) {
/* Maybe this is a bit over-commented, but I just hate this part... */
- if( g_strncasecmp( text + i, header, hlen ) == 0 )
- {
+ if (g_strncasecmp(text + i, header, hlen) == 0) {
/* Skip to the (probable) end of the header */
i += hlen;
-
+
/* Find the first non-[: \t] character */
- while( i < len && ( text[i] == ':' || text[i] == ' ' || text[i] == '\t' ) ) i ++;
-
+ while (i < len && (text[i] == ':' || text[i] == ' ' || text[i] == '\t')) {
+ i++;
+ }
+
/* Make sure we're still inside the string */
- if( i >= len ) return( NULL );
-
+ if (i >= len) {
+ return(NULL);
+ }
+
/* Save the position */
ret = text + i;
-
+
/* Search for the end of this line */
- while( i < len && text[i] != '\r' && text[i] != '\n' ) i ++;
-
+ while (i < len && text[i] != '\r' && text[i] != '\n') {
+ i++;
+ }
+
/* Make sure we're still inside the string */
- if( i >= len ) return( NULL );
-
+ if (i >= len) {
+ return(NULL);
+ }
+
/* Copy the found data */
- return( g_strndup( ret, text + i - ret ) );
+ return(g_strndup(ret, text + i - ret));
}
-
+
/* This wasn't the header we were looking for, skip to the next line. */
- while( i < len && ( text[i] != '\r' && text[i] != '\n' ) ) i ++;
- while( i < len && ( text[i] == '\r' || text[i] == '\n' ) ) i ++;
-
+ while (i < len && (text[i] != '\r' && text[i] != '\n')) {
+ i++;
+ }
+ while (i < len && (text[i] == '\r' || text[i] == '\n')) {
+ i++;
+ }
+
/* End of headers? */
- if( ( i >= 4 && strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ) ||
- ( i >= 2 && ( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||
- strncmp( text + i - 2, "\r\r", 2 ) == 0 ) ) )
- {
+ if ((i >= 4 && strncmp(text + i - 4, "\r\n\r\n", 4) == 0) ||
+ (i >= 2 && (strncmp(text + i - 2, "\n\n", 2) == 0 ||
+ strncmp(text + i - 2, "\r\r", 2) == 0))) {
break;
}
}
-
+
return NULL;
}
/* Takes a string, truncates it where it's safe, returns the new length */
-int truncate_utf8( char *string, int maxlen )
+int truncate_utf8(char *string, int maxlen)
{
char *end;
- g_utf8_validate( (const gchar *) string, maxlen, (const gchar **) &end );
+
+ g_utf8_validate((const gchar *) string, maxlen, (const gchar **) &end);
*end = '\0';
return end - string;
}
diff --git a/lib/misc.h b/lib/misc.h
index bf587332..39be4548 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -29,8 +29,7 @@
#include <gmodule.h>
#include <time.h>
-struct ns_srv_reply
-{
+struct ns_srv_reply {
int prio;
int weight;
int port;
@@ -44,22 +43,22 @@ struct ns_srv_reply
#define NS_INT32SZ 4
#define NS_GET16(s, cp) do { \
- register const unsigned char *t_cp = (const unsigned char*)(cp); \
- (s) = ((guint16)t_cp[0] << 8) \
- | ((guint16)t_cp[1]) \
- ; \
- (cp) += NS_INT16SZ; \
-} while(0)
+ register const unsigned char *t_cp = (const unsigned char *) (cp); \
+ (s) = ((guint16) t_cp[0] << 8) \
+ | ((guint16) t_cp[1]) \
+ ; \
+ (cp) += NS_INT16SZ; \
+} while (0)
#define NS_GET32(s, cp) do { \
- register const unsigned char *t_cp = (const unsigned char*)(cp); \
- (s) = ((guint16)t_cp[0] << 24) \
- | ((guint16)t_cp[1] << 16) \
- | ((guint16)t_cp[2] << 8) \
- | ((guint16)t_cp[3]) \
- ; \
- (cp) += NS_INT32SZ; \
-} while(0)
+ register const unsigned char *t_cp = (const unsigned char *) (cp); \
+ (s) = ((guint16) t_cp[0] << 24) \
+ | ((guint16) t_cp[1] << 16) \
+ | ((guint16) t_cp[2] << 8) \
+ | ((guint16) t_cp[3]) \
+ ; \
+ (cp) += NS_INT32SZ; \
+} while (0)
#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
#define ns_rr_rdata(rr) ((rr).rdata + 0)
@@ -83,11 +82,10 @@ typedef enum __ns_sect {
ns_s_ns = 2,
ns_s_ud = 2,
ns_s_ar = 3,
- ns_s_max =4
+ ns_s_max = 4
} ns_sect;
-typedef struct __ns_msg
-{
+typedef struct __ns_msg {
const unsigned char* _msg;
const unsigned char* _eom;
guint16 _id;
@@ -118,37 +116,37 @@ typedef enum __ns_type {
#endif /* NAMESER_HAS_NS_INITPARSE */
-G_MODULE_EXPORT void strip_linefeed( gchar *text );
-G_MODULE_EXPORT char *add_cr( char *text );
+G_MODULE_EXPORT void strip_linefeed(gchar *text);
+G_MODULE_EXPORT char *add_cr(char *text);
G_MODULE_EXPORT char *strip_newlines(char *source);
-G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
-G_MODULE_EXPORT time_t mktime_utc( struct tm *tp );
-double gettime( void );
+G_MODULE_EXPORT time_t get_time(int year, int month, int day, int hour, int min, int sec);
+G_MODULE_EXPORT time_t mktime_utc(struct tm *tp);
+double gettime(void);
-G_MODULE_EXPORT void strip_html( char *msg );
-G_MODULE_EXPORT char *escape_html( const char *html );
-G_MODULE_EXPORT void http_decode( char *s );
-G_MODULE_EXPORT void http_encode( char *s );
+G_MODULE_EXPORT void strip_html(char *msg);
+G_MODULE_EXPORT char *escape_html(const char *html);
+G_MODULE_EXPORT void http_decode(char *s);
+G_MODULE_EXPORT void http_encode(char *s);
-G_MODULE_EXPORT char *ipv6_wrap( char *src );
-G_MODULE_EXPORT char *ipv6_unwrap( char *src );
+G_MODULE_EXPORT char *ipv6_wrap(char *src);
+G_MODULE_EXPORT char *ipv6_unwrap(char *src);
-G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
+G_MODULE_EXPORT signed int do_iconv(char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf);
-G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );
+G_MODULE_EXPORT void random_bytes(unsigned char *buf, int count);
-G_MODULE_EXPORT int is_bool( char *value );
-G_MODULE_EXPORT int bool2int( char *value );
+G_MODULE_EXPORT int is_bool(char *value);
+G_MODULE_EXPORT int bool2int(char *value);
-G_MODULE_EXPORT struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain );
-G_MODULE_EXPORT void srv_free( struct ns_srv_reply **srv );
+G_MODULE_EXPORT struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain);
+G_MODULE_EXPORT void srv_free(struct ns_srv_reply **srv);
-G_MODULE_EXPORT char *word_wrap( const char *msg, int line_len );
-G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );
-G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
-G_MODULE_EXPORT char **split_command_parts( char *command, int limit );
-G_MODULE_EXPORT char *get_rfc822_header( const char *text, const char *header, int len );
-G_MODULE_EXPORT int truncate_utf8( char *string, int maxlen );
+G_MODULE_EXPORT char *word_wrap(const char *msg, int line_len);
+G_MODULE_EXPORT gboolean ssl_sockerr_again(void *ssl);
+G_MODULE_EXPORT int md5_verify_password(char *password, char *hash);
+G_MODULE_EXPORT char **split_command_parts(char *command, int limit);
+G_MODULE_EXPORT char *get_rfc822_header(const char *text, const char *header, int len);
+G_MODULE_EXPORT int truncate_utf8(char *string, int maxlen);
#endif
diff --git a/lib/ns_parse.c b/lib/ns_parse.c
index 0462b67e..7f7a1bd2 100644
--- a/lib/ns_parse.c
+++ b/lib/ns_parse.c
@@ -38,7 +38,7 @@
/* Forward. */
-static void setsection(ns_msg *msg, ns_sect sect);
+static void setsection(ns_msg *msg, ns_sect sect);
/* Macros. */
@@ -46,135 +46,156 @@ static void setsection(ns_msg *msg, ns_sect sect);
#define RETERR(err) do { errno = (err); return (-1); } while (0)
#else
#define RETERR(err) \
- do { errno = (err); if (errno == errno) return (-1); } while (0)
+ do { errno = (err); if (errno == errno) { return (-1); } } while (0)
#endif
-#define PARSE_FMT_PRESO 0 /* Parse using presentation-format names */
-#define PARSE_FMT_WIRE 1 /* Parse using network-format names */
+#define PARSE_FMT_PRESO 0 /* Parse using presentation-format names */
+#define PARSE_FMT_WIRE 1 /* Parse using network-format names */
/* Public. */
/* These need to be in the same order as the nres.h:ns_flag enum. */
struct _ns_flagdata _ns_flagdata[16] = {
- { 0x8000, 15 }, /*%< qr. */
- { 0x7800, 11 }, /*%< opcode. */
- { 0x0400, 10 }, /*%< aa. */
- { 0x0200, 9 }, /*%< tc. */
- { 0x0100, 8 }, /*%< rd. */
- { 0x0080, 7 }, /*%< ra. */
- { 0x0040, 6 }, /*%< z. */
- { 0x0020, 5 }, /*%< ad. */
- { 0x0010, 4 }, /*%< cd. */
- { 0x000f, 0 }, /*%< rcode. */
- { 0x0000, 0 }, /*%< expansion (1/6). */
- { 0x0000, 0 }, /*%< expansion (2/6). */
- { 0x0000, 0 }, /*%< expansion (3/6). */
- { 0x0000, 0 }, /*%< expansion (4/6). */
- { 0x0000, 0 }, /*%< expansion (5/6). */
- { 0x0000, 0 }, /*%< expansion (6/6). */
+ { 0x8000, 15 }, /*%< qr. */
+ { 0x7800, 11 }, /*%< opcode. */
+ { 0x0400, 10 }, /*%< aa. */
+ { 0x0200, 9 }, /*%< tc. */
+ { 0x0100, 8 }, /*%< rd. */
+ { 0x0080, 7 }, /*%< ra. */
+ { 0x0040, 6 }, /*%< z. */
+ { 0x0020, 5 }, /*%< ad. */
+ { 0x0010, 4 }, /*%< cd. */
+ { 0x000f, 0 }, /*%< rcode. */
+ { 0x0000, 0 }, /*%< expansion (1/6). */
+ { 0x0000, 0 }, /*%< expansion (2/6). */
+ { 0x0000, 0 }, /*%< expansion (3/6). */
+ { 0x0000, 0 }, /*%< expansion (4/6). */
+ { 0x0000, 0 }, /*%< expansion (5/6). */
+ { 0x0000, 0 }, /*%< expansion (6/6). */
};
-int ns_msg_getflag(ns_msg handle, int flag) {
+int ns_msg_getflag(ns_msg handle, int flag)
+{
return(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift);
}
int
-ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count)
+{
const u_char *optr = ptr;
- for ((void)NULL; count > 0; count--) {
+ for ((void) NULL; count > 0; count--) {
int b, rdlength;
b = dn_skipname(ptr, eom);
- if (b < 0)
+ if (b < 0) {
RETERR(EMSGSIZE);
- ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+ }
+ ptr += b /*Name*/ + NS_INT16SZ /*Type*/ + NS_INT16SZ /*Class*/;
if (section != ns_s_qd) {
- if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
+ if (ptr + NS_INT32SZ + NS_INT16SZ > eom) {
RETERR(EMSGSIZE);
- ptr += NS_INT32SZ/*TTL*/;
+ }
+ ptr += NS_INT32SZ /*TTL*/;
NS_GET16(rdlength, ptr);
- ptr += rdlength/*RData*/;
+ ptr += rdlength /*RData*/;
}
}
- if (ptr > eom)
+ if (ptr > eom) {
RETERR(EMSGSIZE);
+ }
return (ptr - optr);
}
int
-ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle)
+{
const u_char *eom = msg + msglen;
int i;
handle->_msg = msg;
handle->_eom = eom;
- if (msg + NS_INT16SZ > eom)
+ if (msg + NS_INT16SZ > eom) {
RETERR(EMSGSIZE);
+ }
NS_GET16(handle->_id, msg);
- if (msg + NS_INT16SZ > eom)
+ if (msg + NS_INT16SZ > eom) {
RETERR(EMSGSIZE);
+ }
NS_GET16(handle->_flags, msg);
for (i = 0; i < ns_s_max; i++) {
- if (msg + NS_INT16SZ > eom)
+ if (msg + NS_INT16SZ > eom) {
RETERR(EMSGSIZE);
+ }
NS_GET16(handle->_counts[i], msg);
}
- for (i = 0; i < ns_s_max; i++)
- if (handle->_counts[i] == 0)
+ for (i = 0; i < ns_s_max; i++) {
+ if (handle->_counts[i] == 0) {
handle->_sections[i] = NULL;
- else {
- int b = ns_skiprr(msg, eom, (ns_sect)i,
- handle->_counts[i]);
+ } else {
+ int b = ns_skiprr(msg, eom, (ns_sect) i,
+ handle->_counts[i]);
- if (b < 0)
+ if (b < 0) {
return (-1);
+ }
handle->_sections[i] = msg;
msg += b;
}
- if (msg != eom)
+ }
+ if (msg != eom) {
RETERR(EMSGSIZE);
+ }
setsection(handle, ns_s_max);
return (0);
}
int
-ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
+{
int b;
int tmp;
/* Make section right. */
tmp = section;
- if (tmp < 0 || section >= ns_s_max)
+ if (tmp < 0 || section >= ns_s_max) {
RETERR(ENODEV);
- if (section != handle->_sect)
+ }
+ if (section != handle->_sect) {
setsection(handle, section);
+ }
/* Make rrnum right. */
- if (rrnum == -1)
+ if (rrnum == -1) {
rrnum = handle->_rrnum;
- if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+ }
+ if (rrnum < 0 || rrnum >= handle->_counts[(int) section]) {
RETERR(ENODEV);
- if (rrnum < handle->_rrnum)
+ }
+ if (rrnum < handle->_rrnum) {
setsection(handle, section);
+ }
if (rrnum > handle->_rrnum) {
b = ns_skiprr(handle->_msg_ptr, handle->_eom, section,
- rrnum - handle->_rrnum);
+ rrnum - handle->_rrnum);
- if (b < 0)
+ if (b < 0) {
return (-1);
+ }
handle->_msg_ptr += b;
handle->_rrnum = rrnum;
}
/* Do the parse. */
b = dn_expand(handle->_msg, handle->_eom,
- handle->_msg_ptr, rr->name, NS_MAXDNAME);
- if (b < 0)
+ handle->_msg_ptr, rr->name, NS_MAXDNAME);
+ if (b < 0) {
return (-1);
+ }
handle->_msg_ptr += b;
- if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
+ if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) {
RETERR(EMSGSIZE);
+ }
NS_GET16(rr->type, handle->_msg_ptr);
NS_GET16(rr->rr_class, handle->_msg_ptr);
if (section == ns_s_qd) {
@@ -182,17 +203,20 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
rr->rdlength = 0;
rr->rdata = NULL;
} else {
- if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
+ if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) {
RETERR(EMSGSIZE);
+ }
NS_GET32(rr->ttl, handle->_msg_ptr);
NS_GET16(rr->rdlength, handle->_msg_ptr);
- if (handle->_msg_ptr + rr->rdlength > handle->_eom)
+ if (handle->_msg_ptr + rr->rdlength > handle->_eom) {
RETERR(EMSGSIZE);
+ }
rr->rdata = handle->_msg_ptr;
handle->_msg_ptr += rr->rdlength;
}
- if (++handle->_rrnum > handle->_counts[(int)section])
- setsection(handle, (ns_sect)((int)section + 1));
+ if (++handle->_rrnum > handle->_counts[(int) section]) {
+ setsection(handle, (ns_sect) ((int) section + 1));
+ }
/* All done. */
return (0);
@@ -201,14 +225,15 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
/* Private. */
static void
-setsection(ns_msg *msg, ns_sect sect) {
+setsection(ns_msg *msg, ns_sect sect)
+{
msg->_sect = sect;
if (sect == ns_s_max) {
msg->_rrnum = -1;
msg->_msg_ptr = NULL;
} else {
msg->_rrnum = 0;
- msg->_msg_ptr = msg->_sections[(int)sect];
+ msg->_msg_ptr = msg->_sections[(int) sect];
}
}
diff --git a/lib/oauth.c b/lib/oauth.c
index 54c272c8..f15a7135 100644
--- a/lib/oauth.c
+++ b/lib/oauth.c
@@ -34,396 +34,395 @@
#define HMAC_BLOCK_SIZE 64
-static char *oauth_sign( const char *method, const char *url,
- const char *params, struct oauth_info *oi )
+static char *oauth_sign(const char *method, const char *url,
+ const char *params, struct oauth_info *oi)
{
uint8_t hash[SHA1_HASH_SIZE];
- GString *payload = g_string_new( "" );
+ GString *payload = g_string_new("");
char *key;
char *s;
-
- key = g_strdup_printf( "%s&%s", oi->sp->consumer_secret, oi->token_secret ? oi->token_secret : "" );
-
- g_string_append_printf( payload, "%s&", method );
-
- s = g_new0( char, strlen( url ) * 3 + 1 );
- strcpy( s, url );
- http_encode( s );
- g_string_append_printf( payload, "%s&", s );
- g_free( s );
-
- s = g_new0( char, strlen( params ) * 3 + 1 );
- strcpy( s, params );
- http_encode( s );
- g_string_append( payload, s );
- g_free( s );
-
- sha1_hmac( key, 0, payload->str, 0, hash );
-
- g_free( key );
- g_string_free( payload, TRUE );
-
- /* base64_encode + HTTP escape it (both consumers
+
+ key = g_strdup_printf("%s&%s", oi->sp->consumer_secret, oi->token_secret ? oi->token_secret : "");
+
+ g_string_append_printf(payload, "%s&", method);
+
+ s = g_new0(char, strlen(url) * 3 + 1);
+ strcpy(s, url);
+ http_encode(s);
+ g_string_append_printf(payload, "%s&", s);
+ g_free(s);
+
+ s = g_new0(char, strlen(params) * 3 + 1);
+ strcpy(s, params);
+ http_encode(s);
+ g_string_append(payload, s);
+ g_free(s);
+
+ sha1_hmac(key, 0, payload->str, 0, hash);
+
+ g_free(key);
+ g_string_free(payload, TRUE);
+
+ /* base64_encode + HTTP escape it (both consumers
need it that away) and we're done. */
- s = base64_encode( hash, SHA1_HASH_SIZE );
- s = g_realloc( s, strlen( s ) * 3 + 1 );
- http_encode( s );
-
+ s = base64_encode(hash, SHA1_HASH_SIZE);
+ s = g_realloc(s, strlen(s) * 3 + 1);
+ http_encode(s);
+
return s;
}
static char *oauth_nonce()
{
unsigned char bytes[21];
- random_bytes( bytes, sizeof( bytes ) );
- return base64_encode( bytes, sizeof( bytes ) );
+
+ random_bytes(bytes, sizeof(bytes));
+ return base64_encode(bytes, sizeof(bytes));
}
-void oauth_params_add( GSList **params, const char *key, const char *value )
+void oauth_params_add(GSList **params, const char *key, const char *value)
{
char *item;
-
- if( !key || !value )
+
+ if (!key || !value) {
return;
-
- item = g_strdup_printf( "%s=%s", key, value );
- *params = g_slist_insert_sorted( *params, item, (GCompareFunc) strcmp );
+ }
+
+ item = g_strdup_printf("%s=%s", key, value);
+ *params = g_slist_insert_sorted(*params, item, (GCompareFunc) strcmp);
}
-void oauth_params_del( GSList **params, const char *key )
+void oauth_params_del(GSList **params, const char *key)
{
- int key_len = strlen( key );
+ int key_len = strlen(key);
GSList *l, *n;
-
- if( params == NULL )
+
+ if (params == NULL) {
return;
-
- for( l = *params; l; l = n )
- {
+ }
+
+ for (l = *params; l; l = n) {
n = l->next;
-
- if( strncmp( (char*) l->data, key, key_len ) == 0 &&
- ((char*)l->data)[key_len] == '=' )
- {
- g_free( l->data );
- *params = g_slist_remove( *params, l->data );
+
+ if (strncmp((char *) l->data, key, key_len) == 0 &&
+ ((char *) l->data)[key_len] == '=') {
+ g_free(l->data);
+ *params = g_slist_remove(*params, l->data);
}
}
}
-void oauth_params_set( GSList **params, const char *key, const char *value )
+void oauth_params_set(GSList **params, const char *key, const char *value)
{
- oauth_params_del( params, key );
- oauth_params_add( params, key, value );
+ oauth_params_del(params, key);
+ oauth_params_add(params, key, value);
}
-const char *oauth_params_get( GSList **params, const char *key )
+const char *oauth_params_get(GSList **params, const char *key)
{
- int key_len = strlen( key );
+ int key_len = strlen(key);
GSList *l;
-
- if( params == NULL )
+
+ if (params == NULL) {
return NULL;
-
- for( l = *params; l; l = l->next )
- {
- if( strncmp( (char*) l->data, key, key_len ) == 0 &&
- ((char*)l->data)[key_len] == '=' )
- return (const char*) l->data + key_len + 1;
}
-
+
+ for (l = *params; l; l = l->next) {
+ if (strncmp((char *) l->data, key, key_len) == 0 &&
+ ((char *) l->data)[key_len] == '=') {
+ return (const char *) l->data + key_len + 1;
+ }
+ }
+
return NULL;
}
-void oauth_params_parse( GSList **params, char *in )
+void oauth_params_parse(GSList **params, char *in)
{
char *amp, *eq, *s;
-
- while( in && *in )
- {
- eq = strchr( in, '=' );
- if( !eq )
+
+ while (in && *in) {
+ eq = strchr(in, '=');
+ if (!eq) {
break;
-
+ }
+
*eq = '\0';
- if( ( amp = strchr( eq + 1, '&' ) ) )
+ if ((amp = strchr(eq + 1, '&'))) {
*amp = '\0';
-
- s = g_strdup( eq + 1 );
- http_decode( s );
- oauth_params_add( params, in, s );
- g_free( s );
-
+ }
+
+ s = g_strdup(eq + 1);
+ http_decode(s);
+ oauth_params_add(params, in, s);
+ g_free(s);
+
*eq = '=';
- if( amp == NULL )
+ if (amp == NULL) {
break;
-
+ }
+
*amp = '&';
in = amp + 1;
}
}
-void oauth_params_free( GSList **params )
+void oauth_params_free(GSList **params)
{
- while( params && *params )
- {
- g_free( (*params)->data );
- *params = g_slist_remove( *params, (*params)->data );
+ while (params && *params) {
+ g_free((*params)->data);
+ *params = g_slist_remove(*params, (*params)->data);
}
}
-char *oauth_params_string( GSList *params )
+char *oauth_params_string(GSList *params)
{
GSList *l;
- GString *str = g_string_new( "" );
-
- for( l = params; l; l = l->next )
- {
+ GString *str = g_string_new("");
+
+ for (l = params; l; l = l->next) {
char *s, *eq;
-
- s = g_malloc( strlen( l->data ) * 3 + 1 );
- strcpy( s, l->data );
- if( ( eq = strchr( s, '=' ) ) )
- http_encode( eq + 1 );
- g_string_append( str, s );
- g_free( s );
-
- if( l->next )
- g_string_append_c( str, '&' );
+
+ s = g_malloc(strlen(l->data) * 3 + 1);
+ strcpy(s, l->data);
+ if ((eq = strchr(s, '='))) {
+ http_encode(eq + 1);
+ }
+ g_string_append(str, s);
+ g_free(s);
+
+ if (l->next) {
+ g_string_append_c(str, '&');
+ }
}
-
- return g_string_free( str, FALSE );
+
+ return g_string_free(str, FALSE);
}
-void oauth_info_free( struct oauth_info *info )
+void oauth_info_free(struct oauth_info *info)
{
- if( info )
- {
- g_free( info->auth_url );
- g_free( info->request_token );
- g_free( info->token );
- g_free( info->token_secret );
- oauth_params_free( &info->params );
- g_free( info );
+ if (info) {
+ g_free(info->auth_url);
+ g_free(info->request_token);
+ g_free(info->token);
+ g_free(info->token_secret);
+ oauth_params_free(&info->params);
+ g_free(info);
}
}
-static void oauth_add_default_params( GSList **params, const struct oauth_service *sp )
+static void oauth_add_default_params(GSList **params, const struct oauth_service *sp)
{
char *s;
-
- oauth_params_set( params, "oauth_consumer_key", sp->consumer_key );
- oauth_params_set( params, "oauth_signature_method", "HMAC-SHA1" );
-
- s = g_strdup_printf( "%d", (int) time( NULL ) );
- oauth_params_set( params, "oauth_timestamp", s );
- g_free( s );
-
+
+ oauth_params_set(params, "oauth_consumer_key", sp->consumer_key);
+ oauth_params_set(params, "oauth_signature_method", "HMAC-SHA1");
+
+ s = g_strdup_printf("%d", (int) time(NULL));
+ oauth_params_set(params, "oauth_timestamp", s);
+ g_free(s);
+
s = oauth_nonce();
- oauth_params_set( params, "oauth_nonce", s );
- g_free( s );
-
- oauth_params_set( params, "oauth_version", "1.0" );
+ oauth_params_set(params, "oauth_nonce", s);
+ g_free(s);
+
+ oauth_params_set(params, "oauth_version", "1.0");
}
-static void *oauth_post_request( const char *url, GSList **params_, http_input_function func, struct oauth_info *oi )
+static void *oauth_post_request(const char *url, GSList **params_, http_input_function func, struct oauth_info *oi)
{
GSList *params = NULL;
char *s, *params_s, *post;
void *req;
url_t url_p;
-
- if( !url_set( &url_p, url ) )
- {
- oauth_params_free( params_ );
+
+ if (!url_set(&url_p, url)) {
+ oauth_params_free(params_);
return NULL;
}
-
- if( params_ )
+
+ if (params_) {
params = *params_;
-
- oauth_add_default_params( &params, oi->sp );
-
- params_s = oauth_params_string( params );
- oauth_params_free( &params );
-
- s = oauth_sign( "POST", url, params_s, oi );
- post = g_strdup_printf( "%s&oauth_signature=%s", params_s, s );
- g_free( params_s );
- g_free( s );
-
- s = g_strdup_printf( "POST %s HTTP/1.0\r\n"
- "Host: %s\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "Content-Length: %zd\r\n"
- "\r\n"
- "%s", url_p.file, url_p.host, strlen( post ), post );
- g_free( post );
-
- req = http_dorequest( url_p.host, url_p.port, url_p.proto == PROTO_HTTPS,
- s, func, oi );
- g_free( s );
-
+ }
+
+ oauth_add_default_params(&params, oi->sp);
+
+ params_s = oauth_params_string(params);
+ oauth_params_free(&params);
+
+ s = oauth_sign("POST", url, params_s, oi);
+ post = g_strdup_printf("%s&oauth_signature=%s", params_s, s);
+ g_free(params_s);
+ g_free(s);
+
+ s = g_strdup_printf("POST %s HTTP/1.0\r\n"
+ "Host: %s\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: %zd\r\n"
+ "\r\n"
+ "%s", url_p.file, url_p.host, strlen(post), post);
+ g_free(post);
+
+ req = http_dorequest(url_p.host, url_p.port, url_p.proto == PROTO_HTTPS,
+ s, func, oi);
+ g_free(s);
+
return req;
}
-static void oauth_request_token_done( struct http_request *req );
+static void oauth_request_token_done(struct http_request *req);
-struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data )
+struct oauth_info *oauth_request_token(const struct oauth_service *sp, oauth_cb func, void *data)
{
- struct oauth_info *st = g_new0( struct oauth_info, 1 );
+ struct oauth_info *st = g_new0(struct oauth_info, 1);
GSList *params = NULL;
-
+
st->func = func;
st->data = data;
st->sp = sp;
-
- oauth_params_add( &params, "oauth_callback", "oob" );
-
- if( !oauth_post_request( sp->url_request_token, &params, oauth_request_token_done, st ) )
- {
- oauth_info_free( st );
+
+ oauth_params_add(&params, "oauth_callback", "oob");
+
+ if (!oauth_post_request(sp->url_request_token, &params, oauth_request_token_done, st)) {
+ oauth_info_free(st);
return NULL;
}
-
+
return st;
}
-static void oauth_request_token_done( struct http_request *req )
+static void oauth_request_token_done(struct http_request *req)
{
struct oauth_info *st = req->data;
-
+
st->http = req;
-
- if( req->status_code == 200 )
- {
+
+ if (req->status_code == 200) {
GSList *params = NULL;
-
- st->auth_url = g_strdup_printf( "%s?%s", st->sp->url_authorize, req->reply_body );
- oauth_params_parse( &params, req->reply_body );
- st->request_token = g_strdup( oauth_params_get( &params, "oauth_token" ) );
- st->token_secret = g_strdup( oauth_params_get( &params, "oauth_token_secret" ) );
- oauth_params_free( &params );
+
+ st->auth_url = g_strdup_printf("%s?%s", st->sp->url_authorize, req->reply_body);
+ oauth_params_parse(&params, req->reply_body);
+ st->request_token = g_strdup(oauth_params_get(&params, "oauth_token"));
+ st->token_secret = g_strdup(oauth_params_get(&params, "oauth_token_secret"));
+ oauth_params_free(&params);
}
-
+
st->stage = OAUTH_REQUEST_TOKEN;
- st->func( st );
+ st->func(st);
}
-static void oauth_access_token_done( struct http_request *req );
+static void oauth_access_token_done(struct http_request *req);
-gboolean oauth_access_token( const char *pin, struct oauth_info *st )
+gboolean oauth_access_token(const char *pin, struct oauth_info *st)
{
GSList *params = NULL;
-
- oauth_params_add( &params, "oauth_token", st->request_token );
- oauth_params_add( &params, "oauth_verifier", pin );
-
- return oauth_post_request( st->sp->url_access_token, &params, oauth_access_token_done, st ) != NULL;
+
+ oauth_params_add(&params, "oauth_token", st->request_token);
+ oauth_params_add(&params, "oauth_verifier", pin);
+
+ return oauth_post_request(st->sp->url_access_token, &params, oauth_access_token_done, st) != NULL;
}
-static void oauth_access_token_done( struct http_request *req )
+static void oauth_access_token_done(struct http_request *req)
{
struct oauth_info *st = req->data;
-
+
st->http = req;
-
- if( req->status_code == 200 )
- {
- oauth_params_parse( &st->params, req->reply_body );
- st->token = g_strdup( oauth_params_get( &st->params, "oauth_token" ) );
- g_free( st->token_secret );
- st->token_secret = g_strdup( oauth_params_get( &st->params, "oauth_token_secret" ) );
+
+ if (req->status_code == 200) {
+ oauth_params_parse(&st->params, req->reply_body);
+ st->token = g_strdup(oauth_params_get(&st->params, "oauth_token"));
+ g_free(st->token_secret);
+ st->token_secret = g_strdup(oauth_params_get(&st->params, "oauth_token_secret"));
}
-
+
st->stage = OAUTH_ACCESS_TOKEN;
- if( st->func( st ) )
- {
+ if (st->func(st)) {
/* Don't need these anymore, but keep the rest. */
- g_free( st->auth_url );
+ g_free(st->auth_url);
st->auth_url = NULL;
- g_free( st->request_token );
+ g_free(st->request_token);
st->request_token = NULL;
- oauth_params_free( &st->params );
+ oauth_params_free(&st->params);
}
}
-char *oauth_http_header( struct oauth_info *oi, const char *method, const char *url, char *args )
+char *oauth_http_header(struct oauth_info *oi, const char *method, const char *url, char *args)
{
GSList *params = NULL, *l;
char *sig = NULL, *params_s, *s;
GString *ret = NULL;
-
- oauth_params_add( &params, "oauth_token", oi->token );
- oauth_add_default_params( &params, oi->sp );
-
+
+ oauth_params_add(&params, "oauth_token", oi->token);
+ oauth_add_default_params(&params, oi->sp);
+
/* Start building the OAuth header. 'key="value", '... */
- ret = g_string_new( "OAuth " );
- for( l = params; l; l = l->next )
- {
+ ret = g_string_new("OAuth ");
+ for (l = params; l; l = l->next) {
char *kv = l->data;
- char *eq = strchr( kv, '=' );
- char esc[strlen(kv)*3+1];
-
- if( eq == NULL )
+ char *eq = strchr(kv, '=');
+ char esc[strlen(kv) * 3 + 1];
+
+ if (eq == NULL) {
break; /* WTF */
-
- strcpy( esc, eq + 1 );
- http_encode( esc );
-
- g_string_append_len( ret, kv, eq - kv + 1 );
- g_string_append_c( ret, '"' );
- g_string_append( ret, esc );
- g_string_append( ret, "\", " );
+
+ }
+ strcpy(esc, eq + 1);
+ http_encode(esc);
+
+ g_string_append_len(ret, kv, eq - kv + 1);
+ g_string_append_c(ret, '"');
+ g_string_append(ret, esc);
+ g_string_append(ret, "\", ");
}
-
+
/* Now, before generating the signature, add GET/POST arguments to params
since they should be included in the base signature string (but not in
the HTTP header). */
- if( args )
- oauth_params_parse( &params, args );
- if( ( s = strchr( url, '?' ) ) )
- {
- s = g_strdup( s + 1 );
- oauth_params_parse( &params, s );
- g_free( s );
+ if (args) {
+ oauth_params_parse(&params, args);
+ }
+ if ((s = strchr(url, '?'))) {
+ s = g_strdup(s + 1);
+ oauth_params_parse(&params, s);
+ g_free(s);
}
-
+
/* Append the signature and we're done! */
- params_s = oauth_params_string( params );
- sig = oauth_sign( method, url, params_s, oi );
- g_string_append_printf( ret, "oauth_signature=\"%s\"", sig );
- g_free( params_s );
-
- oauth_params_free( &params );
- g_free( sig );
-
- return ret ? g_string_free( ret, FALSE ) : NULL;
+ params_s = oauth_params_string(params);
+ sig = oauth_sign(method, url, params_s, oi);
+ g_string_append_printf(ret, "oauth_signature=\"%s\"", sig);
+ g_free(params_s);
+
+ oauth_params_free(&params);
+ g_free(sig);
+
+ return ret ? g_string_free(ret, FALSE) : NULL;
}
-char *oauth_to_string( struct oauth_info *oi )
+char *oauth_to_string(struct oauth_info *oi)
{
GSList *params = NULL;
char *ret;
-
- oauth_params_add( &params, "oauth_token", oi->token );
- oauth_params_add( &params, "oauth_token_secret", oi->token_secret );
- ret = oauth_params_string( params );
- oauth_params_free( &params );
-
+
+ oauth_params_add(&params, "oauth_token", oi->token);
+ oauth_params_add(&params, "oauth_token_secret", oi->token_secret);
+ ret = oauth_params_string(params);
+ oauth_params_free(&params);
+
return ret;
}
-struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp )
+struct oauth_info *oauth_from_string(char *in, const struct oauth_service *sp)
{
- struct oauth_info *oi = g_new0( struct oauth_info, 1 );
+ struct oauth_info *oi = g_new0(struct oauth_info, 1);
GSList *params = NULL;
-
- oauth_params_parse( &params, in );
- oi->token = g_strdup( oauth_params_get( &params, "oauth_token" ) );
- oi->token_secret = g_strdup( oauth_params_get( &params, "oauth_token_secret" ) );
- oauth_params_free( &params );
+
+ oauth_params_parse(&params, in);
+ oi->token = g_strdup(oauth_params_get(&params, "oauth_token"));
+ oi->token_secret = g_strdup(oauth_params_get(&params, "oauth_token_secret"));
+ oauth_params_free(&params);
oi->sp = sp;
-
+
return oi;
}
diff --git a/lib/oauth.h b/lib/oauth.h
index 50adc95c..c9115d57 100644
--- a/lib/oauth.h
+++ b/lib/oauth.h
@@ -27,73 +27,70 @@ struct oauth_info;
/* Callback function called twice during the access token request process.
Return FALSE if something broke and the process must be aborted. */
-typedef gboolean (*oauth_cb)( struct oauth_info * );
+typedef gboolean (*oauth_cb)(struct oauth_info *);
-typedef enum
-{
+typedef enum {
OAUTH_INIT,
OAUTH_REQUEST_TOKEN,
OAUTH_ACCESS_TOKEN,
} oauth_stage_t;
-struct oauth_info
-{
+struct oauth_info {
oauth_stage_t stage;
const struct oauth_service *sp;
-
+
oauth_cb func;
void *data;
-
+
struct http_request *http;
-
+
char *auth_url;
char *request_token;
-
+
char *token;
char *token_secret;
GSList *params;
};
-struct oauth_service
-{
+struct oauth_service {
char *url_request_token;
char *url_access_token;
char *url_authorize;
-
+
char *consumer_key;
char *consumer_secret;
};
-/* http://oauth.net/core/1.0a/#auth_step1 (section 6.1)
+/* http://oauth.net/core/1.0a/#auth_step1 (section 6.1)
Request an initial anonymous token which can be used to construct an
authorization URL for the user. This is passed to the callback function
in a struct oauth_info. */
-struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data );
+struct oauth_info *oauth_request_token(const struct oauth_service *sp, oauth_cb func, void *data);
/* http://oauth.net/core/1.0a/#auth_step3 (section 6.3)
The user gets a PIN or so which we now exchange for the final access
token. This is passed to the callback function in the same
struct oauth_info. */
-gboolean oauth_access_token( const char *pin, struct oauth_info *st );
+gboolean oauth_access_token(const char *pin, struct oauth_info *st);
/* http://oauth.net/core/1.0a/#anchor12 (section 7)
Generate an OAuth Authorization: HTTP header. access_token should be
saved/fetched using the functions above. args can be a string with
whatever's going to be in the POST body of the request. GET args will
automatically be grabbed from url. */
-char *oauth_http_header( struct oauth_info *oi, const char *method, const char *url, char *args );
+char *oauth_http_header(struct oauth_info *oi, const char *method, const char *url, char *args);
/* Shouldn't normally be required unless the process is aborted by the user. */
-void oauth_info_free( struct oauth_info *info );
+void oauth_info_free(struct oauth_info *info);
/* Convert to and back from strings, for easier saving. */
-char *oauth_to_string( struct oauth_info *oi );
-struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp );
+char *oauth_to_string(struct oauth_info *oi);
+struct oauth_info *oauth_from_string(char *in, const struct oauth_service *sp);
/* For reading misc. data. */
-void oauth_params_add( GSList **params, const char *key, const char *value );
-void oauth_params_parse( GSList **params, char *in );
-void oauth_params_free( GSList **params );
-char *oauth_params_string( GSList *params );
-void oauth_params_set( GSList **params, const char *key, const char *value );
-const char *oauth_params_get( GSList **params, const char *key );
+void oauth_params_add(GSList **params, const char *key, const char *value);
+void oauth_params_parse(GSList **params, char *in);
+void oauth_params_free(GSList **params);
+char *oauth_params_string(GSList *params);
+void oauth_params_set(GSList **params, const char *key, const char *value);
+const char *oauth_params_get(GSList **params, const char *key);
diff --git a/lib/oauth2.c b/lib/oauth2.c
index b66197ba..d6cf9a53 100644
--- a/lib/oauth2.c
+++ b/lib/oauth2.c
@@ -27,14 +27,14 @@
a pretty nice standard called OAuth 1.0a. That, and the fact that they
use JSON. Wait, no, Facebook's version doesn't use JSON. For some of its
responses.
-
+
Apparently too many people were too retarded to comprehend the elementary
bits of crypto in OAuth 1.0a (took me one afternoon to implement) so
the standard was replaced with what comes down to a complicated scheme
around what's really just application-specific passwords.
-
+
And then a bunch of mostly incompatible implementations. Great work, guys.
-
+
http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ */
#include <glib.h>
@@ -45,150 +45,148 @@
#include "json_util.h"
#include "url.h"
-char *oauth2_url( const struct oauth2_service *sp )
+char *oauth2_url(const struct oauth2_service *sp)
{
- return g_strconcat( sp->auth_url,
- "?scope=", sp->scope,
- "&response_type=code"
- "&redirect_uri=", sp->redirect_url,
- "&client_id=", sp->consumer_key,
- NULL );
+ return g_strconcat(sp->auth_url,
+ "?scope=", sp->scope,
+ "&response_type=code"
+ "&redirect_uri=", sp->redirect_url,
+ "&client_id=", sp->consumer_key,
+ NULL);
}
-struct oauth2_access_token_data
-{
+struct oauth2_access_token_data {
oauth2_token_callback func;
gpointer data;
};
-static void oauth2_access_token_done( struct http_request *req );
+static void oauth2_access_token_done(struct http_request *req);
-int oauth2_access_token( const struct oauth2_service *sp,
- const char *auth_type, const char *auth,
- oauth2_token_callback func, gpointer data )
+int oauth2_access_token(const struct oauth2_service *sp,
+ const char *auth_type, const char *auth,
+ oauth2_token_callback func, gpointer data)
{
GSList *args = NULL;
char *args_s, *s;
url_t url_p;
struct http_request *req;
struct oauth2_access_token_data *cb_data;
-
- if( !url_set( &url_p, sp->token_url ) )
+
+ if (!url_set(&url_p, sp->token_url)) {
return 0;
-
- oauth_params_add( &args, "client_id", sp->consumer_key );
- oauth_params_add( &args, "client_secret", sp->consumer_secret );
- oauth_params_add( &args, "grant_type", auth_type );
- if( strcmp( auth_type, OAUTH2_AUTH_CODE ) == 0 )
- {
- oauth_params_add( &args, "redirect_uri", sp->redirect_url );
- oauth_params_add( &args, "code", auth );
}
- else
- {
- oauth_params_add( &args, "refresh_token", auth );
+
+ oauth_params_add(&args, "client_id", sp->consumer_key);
+ oauth_params_add(&args, "client_secret", sp->consumer_secret);
+ oauth_params_add(&args, "grant_type", auth_type);
+ if (strcmp(auth_type, OAUTH2_AUTH_CODE) == 0) {
+ oauth_params_add(&args, "redirect_uri", sp->redirect_url);
+ oauth_params_add(&args, "code", auth);
+ } else {
+ oauth_params_add(&args, "refresh_token", auth);
}
- args_s = oauth_params_string( args );
- oauth_params_free( &args );
-
- s = g_strdup_printf( "POST %s HTTP/1.0\r\n"
- "Host: %s\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "Content-Length: %zd\r\n"
- "\r\n"
- "%s", url_p.file, url_p.host, strlen( args_s ), args_s );
- g_free( args_s );
-
- cb_data = g_new0( struct oauth2_access_token_data, 1 );
+ args_s = oauth_params_string(args);
+ oauth_params_free(&args);
+
+ s = g_strdup_printf("POST %s HTTP/1.0\r\n"
+ "Host: %s\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: %zd\r\n"
+ "\r\n"
+ "%s", url_p.file, url_p.host, strlen(args_s), args_s);
+ g_free(args_s);
+
+ cb_data = g_new0(struct oauth2_access_token_data, 1);
cb_data->func = func;
cb_data->data = data;
-
- req = http_dorequest( url_p.host, url_p.port, url_p.proto == PROTO_HTTPS,
- s, oauth2_access_token_done, cb_data );
-
- g_free( s );
-
- if( req == NULL )
- g_free( cb_data );
-
+
+ req = http_dorequest(url_p.host, url_p.port, url_p.proto == PROTO_HTTPS,
+ s, oauth2_access_token_done, cb_data);
+
+ g_free(s);
+
+ if (req == NULL) {
+ g_free(cb_data);
+ }
+
return req != NULL;
}
-static char* oauth2_parse_error( json_value *e )
+static char* oauth2_parse_error(json_value *e)
{
/* This does a reasonable job with some of the flavours of error
responses I've seen. Because apparently it's not standardised. */
-
- if( e->type == json_object )
- {
+
+ if (e->type == json_object) {
/* Facebook style */
- const char *msg = json_o_str( e, "message" );
- const char *type = json_o_str( e, "type" );
- json_value *code_o = json_o_get( e, "code" );
+ const char *msg = json_o_str(e, "message");
+ const char *type = json_o_str(e, "type");
+ json_value *code_o = json_o_get(e, "code");
int code = 0;
-
- if( code_o && code_o->type == json_integer )
+
+ if (code_o && code_o->type == json_integer) {
code = code_o->u.integer;
-
- return g_strdup_printf( "Error %d: %s", code, msg ? msg : type ? type : "Unknown error" );
- }
- else if( e->type == json_string )
- {
- return g_strdup( e->u.string.ptr );
+ }
+
+ return g_strdup_printf("Error %d: %s", code, msg ? msg : type ? type : "Unknown error");
+ } else if (e->type == json_string) {
+ return g_strdup(e->u.string.ptr);
}
return NULL;
}
-static void oauth2_access_token_done( struct http_request *req )
+static void oauth2_access_token_done(struct http_request *req)
{
struct oauth2_access_token_data *cb_data = req->data;
char *atoken = NULL, *rtoken = NULL, *error = NULL;
char *content_type;
-
- if( getenv( "BITLBEE_DEBUG" ) && req->reply_body )
- printf( "%s\n", req->reply_body );
-
- content_type = get_rfc822_header( req->reply_headers, "Content-Type", 0 );
-
- if( content_type && ( strstr( content_type, "application/json" ) ||
- strstr( content_type, "text/javascript" ) ) )
- {
- json_value *js = json_parse( req->reply_body, req->body_size );
- if( js && js->type == json_object )
- {
- JSON_O_FOREACH( js, k, v )
- {
- if( strcmp( k, "error" ) == 0 )
- error = oauth2_parse_error( v );
- if( v->type != json_string )
+
+ if (getenv("BITLBEE_DEBUG") && req->reply_body) {
+ printf("%s\n", req->reply_body);
+ }
+
+ content_type = get_rfc822_header(req->reply_headers, "Content-Type", 0);
+
+ if (content_type && (strstr(content_type, "application/json") ||
+ strstr(content_type, "text/javascript"))) {
+ json_value *js = json_parse(req->reply_body, req->body_size);
+ if (js && js->type == json_object) {
+ JSON_O_FOREACH(js, k, v){
+ if (strcmp(k, "error") == 0) {
+ error = oauth2_parse_error(v);
+ }
+ if (v->type != json_string) {
continue;
- if( strcmp( k, "access_token" ) == 0 )
- atoken = g_strdup( v->u.string.ptr );
- if( strcmp( k, "refresh_token" ) == 0 )
- rtoken = g_strdup( v->u.string.ptr );
+ }
+ if (strcmp(k, "access_token") == 0) {
+ atoken = g_strdup(v->u.string.ptr);
+ }
+ if (strcmp(k, "refresh_token") == 0) {
+ rtoken = g_strdup(v->u.string.ptr);
+ }
}
}
- json_value_free( js );
- }
- else
- {
+ json_value_free(js);
+ } else {
/* Facebook use their own odd format here, seems to be URL-encoded. */
GSList *p_in = NULL;
-
- oauth_params_parse( &p_in, req->reply_body );
- atoken = g_strdup( oauth_params_get( &p_in, "access_token" ) );
- rtoken = g_strdup( oauth_params_get( &p_in, "refresh_token" ) );
- oauth_params_free( &p_in );
+
+ oauth_params_parse(&p_in, req->reply_body);
+ atoken = g_strdup(oauth_params_get(&p_in, "access_token"));
+ rtoken = g_strdup(oauth_params_get(&p_in, "refresh_token"));
+ oauth_params_free(&p_in);
}
- if( getenv( "BITLBEE_DEBUG" ) )
- printf( "Extracted atoken=%s rtoken=%s\n", atoken, rtoken );
- if( !atoken && !rtoken && !error )
- error = g_strdup( "Unusable response" );
-
- cb_data->func( cb_data->data, atoken, rtoken, error );
- g_free( content_type );
- g_free( atoken );
- g_free( rtoken );
- g_free( error );
- g_free( cb_data );
+ if (getenv("BITLBEE_DEBUG")) {
+ printf("Extracted atoken=%s rtoken=%s\n", atoken, rtoken);
+ }
+ if (!atoken && !rtoken && !error) {
+ error = g_strdup("Unusable response");
+ }
+
+ cb_data->func(cb_data->data, atoken, rtoken, error);
+ g_free(content_type);
+ g_free(atoken);
+ g_free(rtoken);
+ g_free(error);
+ g_free(cb_data);
}
diff --git a/lib/oauth2.h b/lib/oauth2.h
index b3811f49..4d6abdb1 100644
--- a/lib/oauth2.h
+++ b/lib/oauth2.h
@@ -24,11 +24,10 @@
/* Implementation mostly based on my experience with writing the previous OAuth
module, and from http://code.google.com/apis/accounts/docs/OAuth2.html . */
-typedef void (*oauth2_token_callback)( gpointer data, const char *atoken,
- const char *rtoken, const char *error );
+typedef void (*oauth2_token_callback)(gpointer data, const char *atoken,
+ const char *rtoken, const char *error);
-struct oauth2_service
-{
+struct oauth2_service {
char *auth_url;
char *token_url;
char *redirect_url;
@@ -42,10 +41,10 @@ struct oauth2_service
/* Generate a URL the user should open in his/her browser to get an
authorization code. */
-char *oauth2_url( const struct oauth2_service *sp );
+char *oauth2_url(const struct oauth2_service *sp);
/* Exchanges an auth code or refresh token for an access token.
auth_type is one of the two OAUTH2_AUTH_.. constants above. */
-int oauth2_access_token( const struct oauth2_service *sp,
- const char *auth_type, const char *auth,
- oauth2_token_callback func, gpointer data );
+int oauth2_access_token(const struct oauth2_service *sp,
+ const char *auth_type, const char *auth,
+ oauth2_token_callback func, gpointer data);
diff --git a/lib/proxy.c b/lib/proxy.c
index 2e0dc2cf..66621ebc 100644
--- a/lib/proxy.c
+++ b/lib/proxy.c
@@ -67,8 +67,9 @@ static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition
struct PHB *phb = data;
socklen_t len;
int error = ETIMEDOUT;
+
len = sizeof(error);
-
+
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) {
if ((phb->gai_cur = phb->gai_cur->ai_next)) {
int new_fd;
@@ -86,9 +87,9 @@ static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition
closesocket(source);
b_event_remove(phb->inpa);
phb->inpa = 0;
- if( phb->proxy_func )
+ if (phb->proxy_func) {
phb->proxy_func(phb->proxy_data, -1, B_EV_IO_READ);
- else {
+ } else {
phb->func(phb->data, -1, B_EV_IO_READ);
g_free(phb);
}
@@ -98,13 +99,13 @@ static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition
sock_make_blocking(source);
b_event_remove(phb->inpa);
phb->inpa = 0;
- if( phb->proxy_func )
+ if (phb->proxy_func) {
phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);
- else {
+ } else {
phb->func(phb->data, source, B_EV_IO_READ);
g_free(phb);
}
-
+
return FALSE;
}
@@ -112,62 +113,62 @@ static int proxy_connect_none(const char *host, unsigned short port_, struct PHB
{
struct sockaddr_in me;
int fd = -1;
-
- if (phb->gai_cur == NULL)
- {
+
+ if (phb->gai_cur == NULL) {
int ret;
char port[6];
struct addrinfo hints;
-
+
g_snprintf(port, sizeof(port), "%d", port_);
-
+
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
-
- if (!(ret = getaddrinfo(host, port, &hints, &phb->gai)))
+
+ if (!(ret = getaddrinfo(host, port, &hints, &phb->gai))) {
phb->gai_cur = phb->gai;
- else
+ } else {
event_debug("gai(): %s\n", gai_strerror(ret));
+ }
}
-
- for (; phb->gai_cur; phb->gai_cur = phb->gai_cur->ai_next)
- {
+
+ for (; phb->gai_cur; phb->gai_cur = phb->gai_cur->ai_next) {
if ((fd = socket(phb->gai_cur->ai_family, phb->gai_cur->ai_socktype, phb->gai_cur->ai_protocol)) < 0) {
- event_debug( "socket failed: %d\n", errno);
+ event_debug("socket failed: %d\n", errno);
continue;
}
sock_make_nonblocking(fd);
- if (global.conf->iface_out)
- {
+ if (global.conf->iface_out) {
me.sin_family = AF_INET;
me.sin_port = 0;
- me.sin_addr.s_addr = inet_addr( global.conf->iface_out );
-
- if (bind(fd, (struct sockaddr *) &me, sizeof(me)) != 0)
+ me.sin_addr.s_addr = inet_addr(global.conf->iface_out);
+
+ if (bind(fd, (struct sockaddr *) &me, sizeof(me)) != 0) {
event_debug("bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out);
+ }
}
event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port_, fd);
-
+
if (connect(fd, phb->gai_cur->ai_addr, phb->gai_cur->ai_addrlen) < 0 && !sockerr_again()) {
- event_debug( "connect failed: %s\n", strerror(errno));
+ event_debug("connect failed: %s\n", strerror(errno));
closesocket(fd);
fd = -1;
continue;
} else {
phb->inpa = b_input_add(fd, B_EV_IO_WRITE, gaim_io_connected, phb);
phb->fd = fd;
-
+
break;
}
}
-
- if(fd < 0 && host)
+
+ if (fd < 0 && host) {
g_free(phb);
+ }
return fd;
}
@@ -187,11 +188,12 @@ static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
b_event_remove(phb->inpa);
- while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
- if (inputline[pos - 1] == '\n')
+ while ((pos < sizeof(inputline) - 1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
+ if (inputline[pos - 1] == '\n') {
nlc++;
- else if (inputline[pos - 1] != '\r')
+ } else if (inputline[pos - 1] != '\r') {
nlc = 0;
+ }
}
inputline[pos] = '\0';
@@ -207,7 +209,7 @@ static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
phb->func(phb->data, -1, B_EV_IO_READ);
g_free(phb->host);
g_free(phb);
-
+
return FALSE;
}
@@ -217,8 +219,10 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond
struct PHB *phb = data;
socklen_t len;
int error = ETIMEDOUT;
- if (phb->inpa > 0)
+
+ if (phb->inpa > 0) {
b_event_remove(phb->inpa);
+ }
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
close(source);
@@ -230,7 +234,7 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond
sock_make_blocking(source);
g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port,
- phb->host, phb->port);
+ phb->host, phb->port);
if (send(source, cmd, strlen(cmd), 0) < 0) {
close(source);
phb->func(phb->data, -1, B_EV_IO_READ);
@@ -265,7 +269,7 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond
}
phb->inpa = b_input_add(source, B_EV_IO_READ, http_canread, phb);
-
+
return FALSE;
}
@@ -275,8 +279,8 @@ static int proxy_connect_http(const char *host, unsigned short port, struct PHB
phb->port = port;
phb->proxy_func = http_canwrite;
phb->proxy_data = phb;
-
- return( proxy_connect_none( proxyhost, proxyport, phb ) );
+
+ return(proxy_connect_none(proxyhost, proxyport, phb));
}
@@ -301,7 +305,7 @@ static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)
phb->func(phb->data, -1, B_EV_IO_READ);
g_free(phb->host);
g_free(phb);
-
+
return FALSE;
}
@@ -312,8 +316,10 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
struct PHB *phb = data;
socklen_t len;
int error = ETIMEDOUT;
- if (phb->inpa > 0)
+
+ if (phb->inpa > 0) {
b_event_remove(phb->inpa);
+ }
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
close(source);
@@ -337,10 +343,10 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
packet[1] = 1;
packet[2] = phb->port >> 8;
packet[3] = phb->port & 0xff;
- packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
- packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
- packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
- packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
+ packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
+ packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
+ packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
+ packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
packet[8] = 0;
if (write(source, packet, 9) != 9) {
close(source);
@@ -351,7 +357,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
}
phb->inpa = b_input_add(source, B_EV_IO_READ, s4_canread, phb);
-
+
return FALSE;
}
@@ -361,8 +367,8 @@ static int proxy_connect_socks4(const char *host, unsigned short port, struct PH
phb->port = port;
phb->proxy_func = s4_canwrite;
phb->proxy_data = phb;
-
- return( proxy_connect_none( proxyhost, proxyport, phb ) );
+
+ return(proxy_connect_none(proxyhost, proxyport, phb));
}
@@ -393,7 +399,7 @@ static gboolean s5_canread_again(gpointer data, gint source, b_input_condition c
phb->func(phb->data, source, B_EV_IO_READ);
g_free(phb->host);
g_free(phb);
-
+
return FALSE;
}
@@ -402,11 +408,11 @@ 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 */
- buf[3] = 0x03; /* address type -- host name */
+ buf[1] = 0x01; /* CONNECT */
+ buf[2] = 0x00; /* reserved */
+ buf[3] = 0x03; /* address type -- host name */
buf[4] = hlen;
memcpy(buf + 5, phb->host, hlen);
buf[5 + strlen(phb->host)] = phb->port >> 8;
@@ -447,7 +453,7 @@ static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)
}
s5_sendconnect(phb, source);
-
+
return FALSE;
}
@@ -476,7 +482,7 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
if (buf[1] == 0x02) {
unsigned int i = strlen(proxyuser), j = strlen(proxypass);
- buf[0] = 0x01; /* version 1 */
+ buf[0] = 0x01; /* version 1 */
buf[1] = i;
memcpy(buf + 2, proxyuser, i);
buf[2 + i] = j;
@@ -493,7 +499,7 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
} else {
s5_sendconnect(phb, source);
}
-
+
return FALSE;
}
@@ -504,8 +510,10 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
struct PHB *phb = data;
socklen_t len;
int error = ETIMEDOUT;
- if (phb->inpa > 0)
+
+ if (phb->inpa > 0) {
b_event_remove(phb->inpa);
+ }
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
close(source);
@@ -517,11 +525,11 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
sock_make_blocking(source);
i = 0;
- buf[0] = 0x05; /* SOCKS version 5 */
+ buf[0] = 0x05; /* SOCKS version 5 */
if (proxyuser[0]) {
- buf[1] = 0x02; /* two methods */
- buf[2] = 0x00; /* no authentication */
- buf[3] = 0x02; /* username/password authentication */
+ buf[1] = 0x02; /* two methods */
+ buf[2] = 0x00; /* no authentication */
+ buf[3] = 0x02; /* username/password authentication */
i = 4;
} else {
buf[1] = 0x01;
@@ -538,7 +546,7 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
}
phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread, phb);
-
+
return FALSE;
}
@@ -548,8 +556,8 @@ static int proxy_connect_socks5(const char *host, unsigned short port, struct PH
phb->port = port;
phb->proxy_func = s5_canwrite;
phb->proxy_data = phb;
-
- return( proxy_connect_none( proxyhost, proxyport, phb ) );
+
+ return(proxy_connect_none(proxyhost, proxyport, phb));
}
@@ -558,24 +566,25 @@ static int proxy_connect_socks5(const char *host, unsigned short port, struct PH
int proxy_connect(const char *host, int port, b_event_handler func, gpointer data)
{
struct PHB *phb;
-
+
if (!host || port <= 0 || !func || strlen(host) > 128) {
return -1;
}
-
+
phb = g_new0(struct PHB, 1);
phb->func = func;
phb->data = data;
-
- if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0)
+
+ if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) {
return proxy_connect_none(host, port, phb);
- else if (proxytype == PROXY_HTTP)
+ } else if (proxytype == PROXY_HTTP) {
return proxy_connect_http(host, port, phb);
- else if (proxytype == PROXY_SOCKS4)
+ } else if (proxytype == PROXY_SOCKS4) {
return proxy_connect_socks4(host, port, phb);
- else if (proxytype == PROXY_SOCKS5)
+ } else if (proxytype == PROXY_SOCKS5) {
return proxy_connect_socks5(host, port, phb);
-
+ }
+
g_free(phb);
return -1;
}
diff --git a/lib/proxy.h b/lib/proxy.h
index b84b37ff..9688aaa6 100644
--- a/lib/proxy.h
+++ b/lib/proxy.h
@@ -21,7 +21,7 @@
/* this is the export part of the proxy.c file. it does a little
prototype-ing stuff and redefine some net function to mask them
- with some kind of transparent layer */
+ with some kind of transparent layer */
#ifndef _PROXY_H_
#define _PROXY_H_
@@ -41,8 +41,8 @@
#define PROXY_SOCKS5 3
extern char proxyhost[128];
-extern int proxyport;
-extern int proxytype;
+extern int proxyport;
+extern int proxytype;
extern char proxyuser[128];
extern char proxypass[128];
diff --git a/lib/sha1.c b/lib/sha1.c
index 68418c5f..7f442205 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -16,6 +16,7 @@ void sha1_append(sha1_state_t *ctx, const guint8 * message_array, guint len)
void sha1_finish(sha1_state_t *ctx, guint8 digest[SHA1_HASH_SIZE])
{
gsize digest_len = SHA1_HASH_SIZE;
+
g_checksum_get_digest(*ctx, digest, &digest_len);
g_checksum_free(*ctx);
}
@@ -27,71 +28,74 @@ void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t pay
{
sha1_state_t sha1;
guint8 hash[SHA1_HASH_SIZE];
- guint8 key[HMAC_BLOCK_SIZE+1];
+ guint8 key[HMAC_BLOCK_SIZE + 1];
int i;
-
- if( key_len == 0 )
- key_len = strlen( key_ );
- if( payload_len == 0 )
- payload_len = strlen( payload );
-
+
+ if (key_len == 0) {
+ key_len = strlen(key_);
+ }
+ if (payload_len == 0) {
+ payload_len = strlen(payload);
+ }
+
/* Create K. If our current key is >64 chars we have to hash it,
otherwise just pad. */
- memset( key, 0, HMAC_BLOCK_SIZE + 1 );
- if( key_len > HMAC_BLOCK_SIZE )
- {
- sha1_init( &sha1 );
- sha1_append( &sha1, (guint8*) key_, key_len );
- sha1_finish( &sha1, key );
- }
- else
- {
- memcpy( key, key_, key_len );
+ memset(key, 0, HMAC_BLOCK_SIZE + 1);
+ if (key_len > HMAC_BLOCK_SIZE) {
+ sha1_init(&sha1);
+ sha1_append(&sha1, (guint8 *) key_, key_len);
+ sha1_finish(&sha1, key);
+ } else {
+ memcpy(key, key_, key_len);
}
-
+
/* Inner part: H(K XOR 0x36, text) */
- sha1_init( &sha1 );
- for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
+ sha1_init(&sha1);
+ for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
key[i] ^= 0x36;
- sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
- sha1_append( &sha1, (const guint8*) payload, payload_len );
- sha1_finish( &sha1, hash );
-
+ }
+ sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
+ sha1_append(&sha1, (const guint8 *) payload, payload_len);
+ sha1_finish(&sha1, hash);
+
/* Final result: H(K XOR 0x5C, inner stuff) */
- sha1_init( &sha1 );
- for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
+ sha1_init(&sha1);
+ for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
key[i] ^= 0x36 ^ 0x5c;
- sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
- sha1_append( &sha1, hash, SHA1_HASH_SIZE );
- sha1_finish( &sha1, digest );
+ }
+ sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
+ sha1_append(&sha1, hash, SHA1_HASH_SIZE);
+ sha1_finish(&sha1, digest);
}
/* I think this follows the scheme described on:
http://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
My random data comes from a SHA1 generator but hey, it's random enough for
me, and RFC 4122 looks way more complicated than I need this to be.
-
+
Returns a value that must be free()d. */
-char *sha1_random_uuid( sha1_state_t * context )
+char *sha1_random_uuid(sha1_state_t * context)
{
guint8 dig[SHA1_HASH_SIZE];
- char *ret = g_new0( char, 40 ); /* 36 chars + \0 */
+ char *ret = g_new0(char, 40); /* 36 chars + \0 */
int i, p;
-
+
sha1_finish(context, dig);
- for( p = i = 0; i < 16; i ++ )
- {
- if( i == 4 || i == 6 || i == 8 || i == 10 )
+ for (p = i = 0; i < 16; i++) {
+ if (i == 4 || i == 6 || i == 8 || i == 10) {
ret[p++] = '-';
- if( i == 6 )
- dig[i] = ( dig[i] & 0x0f ) | 0x40;
- if( i == 8 )
- dig[i] = ( dig[i] & 0x30 ) | 0x80;
-
- sprintf( ret + p, "%02x", dig[i] );
+ }
+ if (i == 6) {
+ dig[i] = (dig[i] & 0x0f) | 0x40;
+ }
+ if (i == 8) {
+ dig[i] = (dig[i] & 0x30) | 0x80;
+ }
+
+ sprintf(ret + p, "%02x", dig[i]);
p += 2;
}
ret[p] = '\0';
-
+
return ret;
}
diff --git a/lib/ssl_client.h b/lib/ssl_client.h
index d23d21f0..d2e12534 100644
--- a/lib/ssl_client.h
+++ b/lib/ssl_client.h
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2004 Wilmer van der Gaast and others *
@@ -56,39 +56,39 @@ typedef gboolean (*ssl_input_function)(gpointer, int, void*, b_input_condition);
/* Perform any global initialization the SSL library might need. */
-G_MODULE_EXPORT void ssl_init( void );
+G_MODULE_EXPORT void ssl_init(void);
/* Connect to host:port, call the given function when the connection is
ready to be used for SSL traffic. This is all done asynchronously, no
blocking I/O! (Except for the DNS lookups, for now...) */
-G_MODULE_EXPORT void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data );
+G_MODULE_EXPORT void *ssl_connect(char *host, int port, gboolean verify, ssl_input_function func, gpointer data);
/* Start an SSL session on an existing fd. Useful for STARTTLS functionality,
for example in Jabber. */
-G_MODULE_EXPORT void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data );
+G_MODULE_EXPORT void *ssl_starttls(int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data);
/* Obviously you need special read/write functions to read 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 int ssl_read(void *conn, char *buf, int len);
+G_MODULE_EXPORT int ssl_write(void *conn, const char *buf, int len);
/* Now needed by most SSL libs. See for more info:
http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
http://www.openssl.org/docs/ssl/SSL_pending.html
-
+
Required because OpenSSL empties the TCP buffer completely but doesn't
necessarily give us all the unencrypted data. Or maybe you didn't ask
for all of it because your buffer is too small.
-
+
Returns 0 if there's nothing left, 1 if there's more data. */
-G_MODULE_EXPORT int ssl_pending( void *conn );
+G_MODULE_EXPORT int ssl_pending(void *conn);
/* Abort the SSL connection and disconnect the socket. Do not use close()
directly, both the SSL library and the peer will be unhappy! */
-G_MODULE_EXPORT void ssl_disconnect( void *conn_ );
+G_MODULE_EXPORT void ssl_disconnect(void *conn_);
/* Get the fd for this connection, you will usually need it for event
handling. */
-G_MODULE_EXPORT int ssl_getfd( void *conn );
+G_MODULE_EXPORT int ssl_getfd(void *conn);
/* This function returns B_EV_IO_READ/WRITE. With SSL connections it's
possible that something has to be read while actually were trying to
@@ -96,10 +96,11 @@ G_MODULE_EXPORT int ssl_getfd( void *conn );
SSL operation returned SSL_AGAIN, *always* use this function when
adding an event handler to the queue. (And it should perform exactly
the same action as the handler that just received the SSL_AGAIN.) */
-G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
+G_MODULE_EXPORT b_input_condition ssl_getdirection(void *conn);
/* Converts a verification bitfield passed to ssl_input_function into
a more useful string. Or NULL if it had no useful bits set. */
-G_MODULE_EXPORT char *ssl_verify_strerror( int code );
+G_MODULE_EXPORT char *ssl_verify_strerror(int code);
-G_MODULE_EXPORT size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res);
+G_MODULE_EXPORT size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input,
+ size_t input_len, const unsigned char *iv, unsigned char **res);
diff --git a/lib/ssl_gnutls.c b/lib/ssl_gnutls.c
index fade7de2..749b00b6 100644
--- a/lib/ssl_gnutls.c
+++ b/lib/ssl_gnutls.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -49,8 +49,7 @@ gnutls_certificate_credentials_t xcred;
#define SSLDEBUG 0
-struct scd
-{
+struct scd {
ssl_input_function func;
gpointer data;
int fd;
@@ -58,117 +57,117 @@ struct scd
int inpa;
char *hostname;
gboolean verify;
-
+
gnutls_session_t session;
};
static GHashTable *session_cache;
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
-static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond);
+static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond);
+static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond);
-static void ssl_deinit( void );
+static void ssl_deinit(void);
-static void ssl_log( int level, const char *line )
+static void ssl_log(int level, const char *line)
{
- printf( "%d %s", level, line );
+ printf("%d %s", level, line);
}
-void ssl_init( void )
+void ssl_init(void)
{
- if( initialized )
+ if (initialized) {
return;
-
+ }
+
gnutls_global_init();
- gnutls_certificate_allocate_credentials( &xcred );
- if( global.conf->cafile )
- {
- gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM );
-
+ gnutls_certificate_allocate_credentials(&xcred);
+ if (global.conf->cafile) {
+ gnutls_certificate_set_x509_trust_file(xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM);
+
/* Not needed in GnuTLS 2.11+ (enabled by default there) so
don't do it (resets possible other defaults). */
- if( !gnutls_check_version( "2.11" ) )
- gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );
+ if (!gnutls_check_version("2.11")) {
+ gnutls_certificate_set_verify_flags(xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+ }
}
initialized = TRUE;
-
- gnutls_global_set_log_function( ssl_log );
+
+ gnutls_global_set_log_function(ssl_log);
/*
gnutls_global_set_log_level( 3 );
*/
-
- session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
-
- atexit( ssl_deinit );
+
+ session_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+ atexit(ssl_deinit);
}
-static void ssl_deinit( void )
+static void ssl_deinit(void)
{
gnutls_global_deinit();
- gnutls_certificate_free_credentials( xcred );
- g_hash_table_destroy( session_cache );
+ gnutls_certificate_free_credentials(xcred);
+ g_hash_table_destroy(session_cache);
session_cache = NULL;
}
-void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data )
+void *ssl_connect(char *host, int port, gboolean verify, ssl_input_function func, gpointer data)
{
- struct scd *conn = g_new0( struct scd, 1 );
-
+ struct scd *conn = g_new0(struct scd, 1);
+
conn->func = func;
conn->data = data;
conn->inpa = -1;
- conn->hostname = g_strdup( host );
+ conn->hostname = g_strdup(host);
conn->verify = verify && global.conf->cafile;
- conn->fd = proxy_connect( host, port, ssl_connected, conn );
-
- if( conn->fd < 0 )
- {
- g_free( conn );
+ conn->fd = proxy_connect(host, port, ssl_connected, conn);
+
+ if (conn->fd < 0) {
+ g_free(conn);
return NULL;
}
-
+
return conn;
}
-void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data )
+void *ssl_starttls(int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data)
{
- struct scd *conn = g_new0( struct scd, 1 );
-
+ struct scd *conn = g_new0(struct scd, 1);
+
conn->fd = fd;
conn->func = func;
conn->data = data;
conn->inpa = -1;
- conn->hostname = g_strdup( hostname );
-
+ conn->hostname = g_strdup(hostname);
+
/* For now, SSL verification is globally enabled by setting the cafile
setting in bitlbee.conf. Commented out by default because probably
not everyone has this file in the same place and plenty of folks
may not have the cert of their private Jabber server in it. */
conn->verify = verify && global.conf->cafile;
-
+
/* This function should be called via a (short) timeout instead of
directly from here, because these SSL calls are *supposed* to be
*completely* asynchronous and not ready yet when this function
(or *_connect, for examle) returns. Also, errors are reported via
the callback function, not via this function's return value.
-
+
In short, doing things like this makes the rest of the code a lot
simpler. */
-
- b_timeout_add( 1, ssl_starttls_real, conn );
-
+
+ b_timeout_add(1, ssl_starttls_real, conn);
+
return conn;
}
-static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
-
- return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );
+
+ return ssl_connected(conn, conn->fd, B_EV_IO_WRITE);
}
-static int verify_certificate_callback( gnutls_session_t session )
+static int verify_certificate_callback(gnutls_session_t session)
{
unsigned int status;
const gnutls_datum_t *cert_list;
@@ -177,317 +176,328 @@ static int verify_certificate_callback( gnutls_session_t session )
int verifyret = 0;
gnutls_x509_crt_t cert;
struct scd *conn;
-
- conn = gnutls_session_get_ptr( session );
- gnutlsret = gnutls_certificate_verify_peers2( session, &status );
- if( gnutlsret < 0 )
+ conn = gnutls_session_get_ptr(session);
+
+ gnutlsret = gnutls_certificate_verify_peers2(session, &status);
+ if (gnutlsret < 0) {
return VERIFY_CERT_ERROR;
+ }
- if( status & GNUTLS_CERT_INVALID )
+ if (status & GNUTLS_CERT_INVALID) {
verifyret |= VERIFY_CERT_INVALID;
+ }
- if( status & GNUTLS_CERT_REVOKED )
+ if (status & GNUTLS_CERT_REVOKED) {
verifyret |= VERIFY_CERT_REVOKED;
+ }
- if( status & GNUTLS_CERT_SIGNER_NOT_FOUND )
+ if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
verifyret |= VERIFY_CERT_SIGNER_NOT_FOUND;
+ }
- if( status & GNUTLS_CERT_SIGNER_NOT_CA )
+ if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
verifyret |= VERIFY_CERT_SIGNER_NOT_CA;
+ }
- if( status & GNUTLS_CERT_INSECURE_ALGORITHM )
+ if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
verifyret |= VERIFY_CERT_INSECURE_ALGORITHM;
+ }
#ifdef GNUTLS_CERT_NOT_ACTIVATED
/* Amusingly, the GnuTLS function used above didn't check for expiry
until GnuTLS 2.8 or so. (See CVE-2009-1417) */
- if( status & GNUTLS_CERT_NOT_ACTIVATED )
+ if (status & GNUTLS_CERT_NOT_ACTIVATED) {
verifyret |= VERIFY_CERT_NOT_ACTIVATED;
+ }
- if( status & GNUTLS_CERT_EXPIRED )
+ if (status & GNUTLS_CERT_EXPIRED) {
verifyret |= VERIFY_CERT_EXPIRED;
+ }
#endif
- if( gnutls_certificate_type_get( session ) != GNUTLS_CRT_X509 || gnutls_x509_crt_init( &cert ) < 0 )
+ if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509 || gnutls_x509_crt_init(&cert) < 0) {
return VERIFY_CERT_ERROR;
+ }
- cert_list = gnutls_certificate_get_peers( session, &cert_list_size );
- if( cert_list == NULL || gnutls_x509_crt_import( cert, &cert_list[0], GNUTLS_X509_FMT_DER ) < 0 )
+ cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
+ if (cert_list == NULL || gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) {
return VERIFY_CERT_ERROR;
+ }
- if( !gnutls_x509_crt_check_hostname( cert, conn->hostname ) )
- {
+ if (!gnutls_x509_crt_check_hostname(cert, conn->hostname)) {
verifyret |= VERIFY_CERT_INVALID;
verifyret |= VERIFY_CERT_WRONG_HOSTNAME;
}
- gnutls_x509_crt_deinit( cert );
+ gnutls_x509_crt_deinit(cert);
return verifyret;
}
-struct ssl_session
-{
+struct ssl_session {
size_t size;
char data[];
};
-static void ssl_cache_add( struct scd *conn )
+static void ssl_cache_add(struct scd *conn)
{
size_t data_size = 0;
struct ssl_session *data;
char *hostname;
-
- if( !conn->hostname ||
- gnutls_session_get_data( conn->session, NULL, &data_size ) != 0 )
+
+ if (!conn->hostname ||
+ gnutls_session_get_data(conn->session, NULL, &data_size) != 0) {
return;
-
- data = g_malloc( sizeof( struct ssl_session ) + data_size );
- if( gnutls_session_get_data( conn->session, data->data, &data_size ) != 0 )
- {
- g_free( data );
+ }
+
+ data = g_malloc(sizeof(struct ssl_session) + data_size);
+ if (gnutls_session_get_data(conn->session, data->data, &data_size) != 0) {
+ g_free(data);
return;
}
-
- hostname = g_strdup( conn->hostname );
- g_hash_table_insert( session_cache, hostname, data );
+
+ hostname = g_strdup(conn->hostname);
+ g_hash_table_insert(session_cache, hostname, data);
}
-static void ssl_cache_resume( struct scd *conn )
+static void ssl_cache_resume(struct scd *conn)
{
struct ssl_session *data;
-
- if( conn->hostname &&
- ( data = g_hash_table_lookup( session_cache, conn->hostname ) ) )
- {
- gnutls_session_set_data( conn->session, data->data, data->size );
- g_hash_table_remove( session_cache, conn->hostname );
+
+ if (conn->hostname &&
+ (data = g_hash_table_lookup(session_cache, conn->hostname))) {
+ gnutls_session_set_data(conn->session, data->data, data->size);
+ g_hash_table_remove(session_cache, conn->hostname);
}
}
-char *ssl_verify_strerror( int code )
+char *ssl_verify_strerror(int code)
{
- GString *ret = g_string_new( "" );
-
- if( code & VERIFY_CERT_REVOKED )
- g_string_append( ret, "certificate has been revoked, " );
- if( code & VERIFY_CERT_SIGNER_NOT_FOUND )
- g_string_append( ret, "certificate hasn't got a known issuer, " );
- if( code & VERIFY_CERT_SIGNER_NOT_CA )
- g_string_append( ret, "certificate's issuer is not a CA, " );
- if( code & VERIFY_CERT_INSECURE_ALGORITHM )
- g_string_append( ret, "certificate uses an insecure algorithm, " );
- if( code & VERIFY_CERT_NOT_ACTIVATED )
- g_string_append( ret, "certificate has not been activated, " );
- if( code & VERIFY_CERT_EXPIRED )
- g_string_append( ret, "certificate has expired, " );
- if( code & VERIFY_CERT_WRONG_HOSTNAME )
- g_string_append( ret, "certificate hostname mismatch, " );
-
- if( ret->len == 0 )
- {
- g_string_free( ret, TRUE );
- return NULL;
+ GString *ret = g_string_new("");
+
+ if (code & VERIFY_CERT_REVOKED) {
+ g_string_append(ret, "certificate has been revoked, ");
+ }
+ if (code & VERIFY_CERT_SIGNER_NOT_FOUND) {
+ g_string_append(ret, "certificate hasn't got a known issuer, ");
+ }
+ if (code & VERIFY_CERT_SIGNER_NOT_CA) {
+ g_string_append(ret, "certificate's issuer is not a CA, ");
+ }
+ if (code & VERIFY_CERT_INSECURE_ALGORITHM) {
+ g_string_append(ret, "certificate uses an insecure algorithm, ");
+ }
+ if (code & VERIFY_CERT_NOT_ACTIVATED) {
+ g_string_append(ret, "certificate has not been activated, ");
}
- else
- {
- g_string_truncate( ret, ret->len - 2 );
- return g_string_free( ret, FALSE );
+ if (code & VERIFY_CERT_EXPIRED) {
+ g_string_append(ret, "certificate has expired, ");
+ }
+ if (code & VERIFY_CERT_WRONG_HOSTNAME) {
+ g_string_append(ret, "certificate hostname mismatch, ");
+ }
+
+ if (ret->len == 0) {
+ g_string_free(ret, TRUE);
+ return NULL;
+ } else {
+ g_string_truncate(ret, ret->len - 2);
+ return g_string_free(ret, FALSE);
}
}
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
-
- if( source == -1 )
- {
- conn->func( conn->data, 0, NULL, cond );
- g_free( conn );
+
+ if (source == -1) {
+ conn->func(conn->data, 0, NULL, cond);
+ g_free(conn);
return FALSE;
}
-
+
ssl_init();
-
- gnutls_init( &conn->session, GNUTLS_CLIENT );
- gnutls_session_set_ptr( conn->session, (void *) conn );
+
+ gnutls_init(&conn->session, GNUTLS_CLIENT);
+ gnutls_session_set_ptr(conn->session, (void *) conn);
#if GNUTLS_VERSION_NUMBER < 0x020c00
- gnutls_transport_set_lowat( conn->session, 0 );
+ gnutls_transport_set_lowat(conn->session, 0);
#endif
- gnutls_set_default_priority( conn->session );
- gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred );
- if( conn->hostname && !g_ascii_isdigit( conn->hostname[0] ) )
- gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS,
- conn->hostname, strlen( conn->hostname ) );
-
- sock_make_nonblocking( conn->fd );
- gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd );
-
- ssl_cache_resume( conn );
-
- return ssl_handshake( data, source, cond );
+ gnutls_set_default_priority(conn->session);
+ gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, xcred);
+ if (conn->hostname && !g_ascii_isdigit(conn->hostname[0])) {
+ gnutls_server_name_set(conn->session, GNUTLS_NAME_DNS,
+ conn->hostname, strlen(conn->hostname));
+ }
+
+ sock_make_nonblocking(conn->fd);
+ gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd);
+
+ ssl_cache_resume(conn);
+
+ return ssl_handshake(data, source, cond);
}
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
int st, stver;
-
+
/* This function returns false, so avoid calling b_event_remove again */
conn->inpa = -1;
-
- if( ( st = gnutls_handshake( conn->session ) ) < 0 )
- {
- if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
- {
- conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ),
- ssl_handshake, data );
- }
- else
- {
- conn->func( conn->data, 0, NULL, cond );
-
- gnutls_deinit( conn->session );
- closesocket( conn->fd );
-
- g_free( conn );
- }
- }
- else
- {
- if( conn->verify && ( stver = verify_certificate_callback( conn->session ) ) != 0 )
- {
- conn->func( conn->data, stver, NULL, cond );
- gnutls_deinit( conn->session );
- closesocket( conn->fd );
+ if ((st = gnutls_handshake(conn->session)) < 0) {
+ if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) {
+ conn->inpa = b_input_add(conn->fd, ssl_getdirection(conn),
+ ssl_handshake, data);
+ } else {
+ conn->func(conn->data, 0, NULL, cond);
+
+ gnutls_deinit(conn->session);
+ closesocket(conn->fd);
- g_free( conn );
+ g_free(conn);
}
- else
- {
+ } else {
+ if (conn->verify && (stver = verify_certificate_callback(conn->session)) != 0) {
+ conn->func(conn->data, stver, NULL, cond);
+
+ gnutls_deinit(conn->session);
+ closesocket(conn->fd);
+
+ g_free(conn);
+ } else {
/* For now we can't handle non-blocking perfectly everywhere... */
- sock_make_blocking( conn->fd );
-
- ssl_cache_add( conn );
+ sock_make_blocking(conn->fd);
+
+ ssl_cache_add(conn);
conn->established = TRUE;
- conn->func( conn->data, 0, conn, cond );
+ conn->func(conn->data, 0, conn, cond);
}
}
-
+
return FALSE;
}
-int ssl_read( void *conn, char *buf, int len )
+int ssl_read(void *conn, char *buf, int len)
{
int st;
-
- if( !((struct scd*)conn)->established )
- {
+
+ if (!((struct scd*) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
-
- st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len );
-
+
+ st = gnutls_record_recv(((struct scd*) conn)->session, buf, len);
+
ssl_errno = SSL_OK;
- if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+ if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) {
ssl_errno = SSL_AGAIN;
-
- if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st );
-
+ }
+
+ if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) {
+ len = write(2, buf, st);
+ }
+
return st;
}
-int ssl_write( void *conn, const char *buf, int len )
+int ssl_write(void *conn, const char *buf, int len)
{
int st;
-
- if( !((struct scd*)conn)->established )
- {
+
+ if (!((struct scd*) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
-
- st = gnutls_record_send( ((struct scd*)conn)->session, buf, len );
-
+
+ st = gnutls_record_send(((struct scd*) conn)->session, buf, len);
+
ssl_errno = SSL_OK;
- if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+ if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) {
ssl_errno = SSL_AGAIN;
-
- if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st );
-
+ }
+
+ if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) {
+ len = write(2, buf, st);
+ }
+
return st;
}
-int ssl_pending( void *conn )
+int ssl_pending(void *conn)
{
- if( conn == NULL )
+ if (conn == NULL) {
return 0;
-
- if( !((struct scd*)conn)->established )
- {
+ }
+
+ if (!((struct scd*) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return 0;
}
#if GNUTLS_VERSION_NUMBER >= 0x03000d && GNUTLS_VERSION_NUMBER <= 0x030012
- if( ssl_errno == SSL_AGAIN )
+ if (ssl_errno == SSL_AGAIN) {
return 0;
+ }
#endif
-
- return gnutls_record_check_pending( ((struct scd*)conn)->session ) != 0;
+
+ return gnutls_record_check_pending(((struct scd*) conn)->session) != 0;
}
-void ssl_disconnect( void *conn_ )
+void ssl_disconnect(void *conn_)
{
struct scd *conn = conn_;
-
- if( conn->inpa != -1 )
- b_event_remove( conn->inpa );
-
- if( conn->established )
- gnutls_bye( conn->session, GNUTLS_SHUT_WR );
-
- closesocket( conn->fd );
-
- if( conn->session )
- gnutls_deinit( conn->session );
- g_free( conn->hostname );
- g_free( conn );
+
+ if (conn->inpa != -1) {
+ b_event_remove(conn->inpa);
+ }
+
+ if (conn->established) {
+ gnutls_bye(conn->session, GNUTLS_SHUT_WR);
+ }
+
+ closesocket(conn->fd);
+
+ if (conn->session) {
+ gnutls_deinit(conn->session);
+ }
+ g_free(conn->hostname);
+ g_free(conn);
}
-int ssl_getfd( void *conn )
+int ssl_getfd(void *conn)
{
- return( ((struct scd*)conn)->fd );
+ return(((struct scd*) conn)->fd);
}
-b_input_condition ssl_getdirection( void *conn )
+b_input_condition ssl_getdirection(void *conn)
{
- return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ?
- B_EV_IO_WRITE : B_EV_IO_READ );
+ return(gnutls_record_get_direction(((struct scd*) conn)->session) ?
+ B_EV_IO_WRITE : B_EV_IO_READ);
}
-size_t ssl_des3_encrypt( const unsigned char *key, size_t key_len, const unsigned char *input,
- size_t input_len, const unsigned char *iv, unsigned char **res )
+size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input,
+ size_t input_len, const unsigned char *iv, unsigned char **res)
{
gcry_cipher_hd_t gcr;
gcry_error_t st;
-
+
ssl_init();
-
- *res = g_malloc( input_len );
- st = gcry_cipher_open( &gcr, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0 ) ||
- gcry_cipher_setkey( gcr, key, key_len ) ||
- gcry_cipher_setiv( gcr, iv, 8 ) ||
- gcry_cipher_encrypt( gcr, *res, input_len, input, input_len );
-
- gcry_cipher_close( gcr );
-
- if( st == 0 )
+
+ *res = g_malloc(input_len);
+ st = gcry_cipher_open(&gcr, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0) ||
+ gcry_cipher_setkey(gcr, key, key_len) ||
+ gcry_cipher_setiv(gcr, iv, 8) ||
+ gcry_cipher_encrypt(gcr, *res, input_len, input, input_len);
+
+ gcry_cipher_close(gcr);
+
+ if (st == 0) {
return input_len;
-
- g_free( *res );
+ }
+
+ g_free(*res);
return 0;
}
diff --git a/lib/ssl_nss.c b/lib/ssl_nss.c
index 00a574f7..09e50f3f 100644
--- a/lib/ssl_nss.c
+++ b/lib/ssl_nss.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -59,12 +59,12 @@ struct scd {
};
static gboolean ssl_connected(gpointer data, gint source,
- b_input_condition cond);
+ b_input_condition cond);
static gboolean ssl_starttls_real(gpointer data, gint source,
- b_input_condition cond);
+ b_input_condition cond);
static SECStatus nss_auth_cert(void *arg, PRFileDesc * socket, PRBool checksig,
- PRBool isserver)
+ PRBool isserver)
{
return SECSuccess;
}
@@ -73,8 +73,9 @@ static SECStatus nss_bad_cert(void *arg, PRFileDesc * socket)
{
PRErrorCode err;
- if (!arg)
+ if (!arg) {
return SECFailure;
+ }
*(PRErrorCode *) arg = err = PORT_GetError();
@@ -113,7 +114,7 @@ void ssl_init(void)
}
void *ssl_connect(char *host, int port, gboolean verify,
- ssl_input_function func, gpointer data)
+ ssl_input_function func, gpointer data)
{
struct scd *conn = g_new0(struct scd, 1);
@@ -136,7 +137,7 @@ void *ssl_connect(char *host, int port, gboolean verify,
}
static gboolean ssl_starttls_real(gpointer data, gint source,
- b_input_condition cond)
+ b_input_condition cond)
{
struct scd *conn = data;
@@ -144,7 +145,7 @@ static gboolean ssl_starttls_real(gpointer data, gint source,
}
void *ssl_starttls(int fd, char *hostname, gboolean verify,
- ssl_input_function func, gpointer data)
+ ssl_input_function func, gpointer data)
{
struct scd *conn = g_new0(struct scd, 1);
@@ -174,7 +175,7 @@ void *ssl_starttls(int fd, char *hostname, gboolean verify,
}
static gboolean ssl_connected(gpointer data, gint source,
- b_input_condition cond)
+ b_input_condition cond)
{
struct scd *conn = data;
@@ -182,28 +183,31 @@ static gboolean ssl_connected(gpointer data, gint source,
if (conn->verify) {
conn->func(conn->data, 1, NULL, cond);
- if (source >= 0)
+ if (source >= 0) {
closesocket(source);
+ }
g_free(conn->hostname);
g_free(conn);
return FALSE;
}
- if (source == -1)
+ if (source == -1) {
goto ssl_connected_failure;
+ }
/* Until we find out how to handle non-blocking I/O with NSS... */
sock_make_blocking(conn->fd);
conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
- if (!conn->prfd)
+ if (!conn->prfd) {
goto ssl_connected_failure;
+ }
SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
SSL_BadCertHook(conn->prfd, (SSLBadCertHandler) nss_bad_cert, NULL);
SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate) nss_auth_cert,
- (void *)CERT_GetDefaultCertDB());
+ (void *) CERT_GetDefaultCertDB());
SSL_SetURL(conn->prfd, conn->hostname);
SSL_ResetHandshake(conn->prfd, PR_FALSE);
@@ -215,14 +219,16 @@ static gboolean ssl_connected(gpointer data, gint source,
conn->func(conn->data, 0, conn, cond);
return FALSE;
- ssl_connected_failure:
+ssl_connected_failure:
conn->func(conn->data, 0, NULL, cond);
- if (conn->prfd)
+ if (conn->prfd) {
PR_Close(conn->prfd);
- if (source >= 0)
+ }
+ if (source >= 0) {
closesocket(source);
+ }
g_free(conn->hostname);
g_free(conn);
@@ -234,20 +240,22 @@ int ssl_read(void *conn, char *buf, int len)
int st;
PRErrorCode PR_err;
- if (!((struct scd *)conn)->established) {
+ if (!((struct scd *) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
- st = PR_Read(((struct scd *)conn)->prfd, buf, len);
+ st = PR_Read(((struct scd *) conn)->prfd, buf, len);
PR_err = PR_GetError();
ssl_errno = SSL_OK;
- if (PR_err == PR_WOULD_BLOCK_ERROR)
+ if (PR_err == PR_WOULD_BLOCK_ERROR) {
ssl_errno = SSL_AGAIN;
+ }
- if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0)
+ if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) {
len = write(STDERR_FILENO, buf, st);
+ }
return st;
}
@@ -257,26 +265,28 @@ int ssl_write(void *conn, const char *buf, int len)
int st;
PRErrorCode PR_err;
- if (!((struct scd *)conn)->established) {
+ if (!((struct scd *) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
- st = PR_Write(((struct scd *)conn)->prfd, buf, len);
+ st = PR_Write(((struct scd *) conn)->prfd, buf, len);
PR_err = PR_GetError();
ssl_errno = SSL_OK;
- if (PR_err == PR_WOULD_BLOCK_ERROR)
+ if (PR_err == PR_WOULD_BLOCK_ERROR) {
ssl_errno = SSL_AGAIN;
+ }
- if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0)
+ if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) {
len = write(2, buf, st);
+ }
return st;
}
int ssl_pending(void *conn)
{
- struct scd *c = (struct scd *)conn;
+ struct scd *c = (struct scd *) conn;
if (c == NULL) {
return 0;
@@ -292,8 +302,9 @@ void ssl_disconnect(void *conn_)
// When we swich to NSS_Init, we should have here
// NSS_Shutdown();
- if (conn->prfd)
+ if (conn->prfd) {
PR_Close(conn->prfd);
+ }
g_free(conn->hostname);
g_free(conn);
@@ -301,7 +312,7 @@ void ssl_disconnect(void *conn_)
int ssl_getfd(void *conn)
{
- return (((struct scd *)conn)->fd);
+ return (((struct scd *) conn)->fd);
}
b_input_condition ssl_getdirection(void *conn)
@@ -313,13 +324,13 @@ b_input_condition ssl_getdirection(void *conn)
char *ssl_verify_strerror(int code)
{
return
- g_strdup
- ("SSL certificate verification not supported by BitlBee NSS code.");
+ g_strdup
+ ("SSL certificate verification not supported by BitlBee NSS code.");
}
size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
- const unsigned char *input, size_t input_len,
- const unsigned char *iv, unsigned char **res)
+ const unsigned char *input, size_t input_len,
+ const unsigned char *iv, unsigned char **res)
{
#define CIPHER_MECH CKM_DES3_CBC
#define MAX_OUTPUT_LEN 72
@@ -341,45 +352,45 @@ size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
ssl_init();
}
- keyItem.data = (unsigned char *)key;
+ keyItem.data = (unsigned char *) key;
keyItem.len = key_len;
slot = PK11_GetBestSlot(CIPHER_MECH, NULL);
if (slot == NULL) {
fprintf(stderr, "PK11_GetBestSlot failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
symKey =
- PK11_ImportSymKey(slot, CIPHER_MECH, PK11_OriginUnwrap, CKA_ENCRYPT,
- &keyItem, NULL);
+ PK11_ImportSymKey(slot, CIPHER_MECH, PK11_OriginUnwrap, CKA_ENCRYPT,
+ &keyItem, NULL);
if (symKey == NULL) {
fprintf(stderr, "PK11_ImportSymKey failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
- ivItem.data = (unsigned char *)iv;
+ ivItem.data = (unsigned char *) iv;
/* See msn_soap_passport_sso_handle_response in protocols/msn/soap.c */
ivItem.len = 8;
secParam = PK11_ParamFromIV(CIPHER_MECH, &ivItem);
if (secParam == NULL) {
fprintf(stderr, "PK11_ParamFromIV failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
ctx =
- PK11_CreateContextBySymKey(CIPHER_MECH, CKA_ENCRYPT, symKey,
- secParam);
+ PK11_CreateContextBySymKey(CIPHER_MECH, CKA_ENCRYPT, symKey,
+ secParam);
if (ctx == NULL) {
fprintf(stderr, "PK11_CreateContextBySymKey failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
@@ -387,10 +398,10 @@ size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
*res = g_new0(unsigned char, MAX_OUTPUT_LEN);
rv = PK11_CipherOp(ctx, *res, &len1, MAX_OUTPUT_LEN,
- (unsigned char *)input, input_len);
+ (unsigned char *) input, input_len);
if (rv != SECSuccess) {
fprintf(stderr, "PK11_CipherOp failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
@@ -398,25 +409,29 @@ size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
assert(len1 <= MAX_OUTPUT_LEN);
rv = PK11_DigestFinal(ctx, *res + len1, &len2,
- (unsigned int)MAX_OUTPUT_LEN - len1);
+ (unsigned int) MAX_OUTPUT_LEN - len1);
if (rv != SECSuccess) {
fprintf(stderr, "PK11_DigestFinal failed (err %d)\n",
- PR_GetError());
+ PR_GetError());
rc = 0;
goto out;
}
rc = len1 + len2;
- out:
- if (ctx)
+out:
+ if (ctx) {
PK11_DestroyContext(ctx, PR_TRUE);
- if (symKey)
+ }
+ if (symKey) {
PK11_FreeSymKey(symKey);
- if (secParam)
+ }
+ if (secParam) {
SECITEM_FreeItem(secParam, PR_TRUE);
- if (slot)
+ }
+ if (slot) {
PK11_FreeSlot(slot);
+ }
return rc;
}
diff --git a/lib/ssl_openssl.c b/lib/ssl_openssl.c
index 63937380..c286d509 100644
--- a/lib/ssl_openssl.c
+++ b/lib/ssl_openssl.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2002-2012 Wilmer van der Gaast and others *
@@ -39,263 +39,270 @@ int ssl_errno = 0;
static gboolean initialized = FALSE;
-struct scd
-{
+struct scd {
ssl_input_function func;
gpointer data;
int fd;
gboolean established;
gboolean verify;
char *hostname;
-
+
int inpa;
- int lasterr; /* Necessary for SSL_get_error */
+ int lasterr; /* Necessary for SSL_get_error */
SSL *ssl;
};
static SSL_CTX *ssl_ctx;
-static void ssl_conn_free( struct scd *conn );
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
-static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+static void ssl_conn_free(struct scd *conn);
+static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond);
+static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond);
+static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond);
-void ssl_init( void )
+void ssl_init(void)
{
const SSL_METHOD *meth;
-
+
SSL_library_init();
-
+
meth = TLSv1_client_method();
- ssl_ctx = SSL_CTX_new( meth );
-
+ ssl_ctx = SSL_CTX_new(meth);
+
initialized = TRUE;
}
-void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data )
+void *ssl_connect(char *host, int port, gboolean verify, ssl_input_function func, gpointer data)
{
- struct scd *conn = g_new0( struct scd, 1 );
-
- conn->fd = proxy_connect( host, port, ssl_connected, conn );
- if( conn->fd < 0 )
- {
- ssl_conn_free( conn );
+ struct scd *conn = g_new0(struct scd, 1);
+
+ conn->fd = proxy_connect(host, port, ssl_connected, conn);
+ if (conn->fd < 0) {
+ ssl_conn_free(conn);
return NULL;
}
-
+
conn->func = func;
conn->data = data;
conn->inpa = -1;
- conn->hostname = g_strdup( host );
-
+ conn->hostname = g_strdup(host);
+
return conn;
}
-void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data )
+void *ssl_starttls(int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data)
{
- struct scd *conn = g_new0( struct scd, 1 );
-
+ struct scd *conn = g_new0(struct scd, 1);
+
conn->fd = fd;
conn->func = func;
conn->data = data;
conn->inpa = -1;
conn->verify = verify && global.conf->cafile;
- conn->hostname = g_strdup( hostname );
-
+ conn->hostname = g_strdup(hostname);
+
/* This function should be called via a (short) timeout instead of
directly from here, because these SSL calls are *supposed* to be
*completely* asynchronous and not ready yet when this function
(or *_connect, for examle) returns. Also, errors are reported via
the callback function, not via this function's return value.
-
+
In short, doing things like this makes the rest of the code a lot
simpler. */
-
- b_timeout_add( 1, ssl_starttls_real, conn );
-
+
+ b_timeout_add(1, ssl_starttls_real, conn);
+
return conn;
}
-static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
-
- return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );
+
+ return ssl_connected(conn, conn->fd, B_EV_IO_WRITE);
}
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
-
- if( conn->verify )
- {
+
+ if (conn->verify) {
/* Right now we don't have any verification functionality for OpenSSL. */
- conn->func( conn->data, 1, NULL, cond );
- if( source >= 0 ) closesocket( source );
- ssl_conn_free( conn );
+ conn->func(conn->data, 1, NULL, cond);
+ if (source >= 0) {
+ closesocket(source);
+ }
+ ssl_conn_free(conn);
return FALSE;
}
- if( source == -1 )
+ if (source == -1) {
goto ssl_connected_failure;
-
- if( !initialized )
- {
+ }
+
+ if (!initialized) {
ssl_init();
}
-
-
- if( ssl_ctx == NULL )
+
+
+ if (ssl_ctx == NULL) {
goto ssl_connected_failure;
-
- conn->ssl = SSL_new( ssl_ctx );
- if( conn->ssl == NULL )
+ }
+
+ conn->ssl = SSL_new(ssl_ctx);
+ if (conn->ssl == NULL) {
goto ssl_connected_failure;
-
+ }
+
/* We can do at least the handshake with non-blocking I/O */
- sock_make_nonblocking( conn->fd );
- SSL_set_fd( conn->ssl, conn->fd );
-
- if( conn->hostname && !g_ascii_isdigit( conn->hostname[0] ) )
- SSL_set_tlsext_host_name( conn->ssl, conn->hostname );
-
- return ssl_handshake( data, source, cond );
+ sock_make_nonblocking(conn->fd);
+ SSL_set_fd(conn->ssl, conn->fd);
+
+ if (conn->hostname && !g_ascii_isdigit(conn->hostname[0])) {
+ SSL_set_tlsext_host_name(conn->ssl, conn->hostname);
+ }
+
+ return ssl_handshake(data, source, cond);
ssl_connected_failure:
- conn->func( conn->data, 0, NULL, cond );
- ssl_disconnect( conn );
+ conn->func(conn->data, 0, NULL, cond);
+ ssl_disconnect(conn);
return FALSE;
-}
+}
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
+static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond)
{
struct scd *conn = data;
int st;
-
- 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 )
- {
- conn->func( conn->data, 0, NULL, cond );
- ssl_disconnect( conn );
+
+ 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) {
+ conn->func(conn->data, 0, NULL, cond);
+ ssl_disconnect(conn);
return FALSE;
}
-
- conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data );
+
+ 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, 0, conn, cond );
+ sock_make_blocking(conn->fd); /* For now... */
+ conn->func(conn->data, 0, conn, cond);
return FALSE;
}
-int ssl_read( void *conn, char *buf, int len )
+int ssl_read(void *conn, char *buf, int len)
{
int st;
-
- if( !((struct scd*)conn)->established )
- {
+
+ if (!((struct scd*) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
-
- st = SSL_read( ((struct scd*)conn)->ssl, buf, len );
-
+
+ st = SSL_read(((struct scd*) conn)->ssl, buf, len);
+
ssl_errno = SSL_OK;
- if( st <= 0 )
- {
- ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
- if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
+ if (st <= 0) {
+ ((struct scd*) conn)->lasterr = SSL_get_error(((struct scd*) conn)->ssl, st);
+ if (((struct scd*) conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*) conn)->lasterr ==
+ SSL_ERROR_WANT_WRITE) {
ssl_errno = SSL_AGAIN;
+ }
}
-
- if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
-
+
+ if (0 && getenv("BITLBEE_DEBUG") && st > 0) {
+ write(1, buf, st);
+ }
+
return st;
}
-int ssl_write( void *conn, const char *buf, int len )
+int ssl_write(void *conn, const char *buf, int len)
{
int st;
-
- if( !((struct scd*)conn)->established )
- {
+
+ if (!((struct scd*) conn)->established) {
ssl_errno = SSL_NOHANDSHAKE;
return -1;
}
-
- st = SSL_write( ((struct scd*)conn)->ssl, buf, len );
-
- if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
-
+
+ st = SSL_write(((struct scd*) conn)->ssl, buf, len);
+
+ if (0 && getenv("BITLBEE_DEBUG") && st > 0) {
+ write(1, buf, st);
+ }
+
ssl_errno = SSL_OK;
- if( st <= 0 )
- {
- ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
- if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
+ if (st <= 0) {
+ ((struct scd*) conn)->lasterr = SSL_get_error(((struct scd*) conn)->ssl, st);
+ if (((struct scd*) conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*) conn)->lasterr ==
+ SSL_ERROR_WANT_WRITE) {
ssl_errno = SSL_AGAIN;
+ }
}
-
+
return st;
}
-int ssl_pending( void *conn )
+int ssl_pending(void *conn)
{
- return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ?
- SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0;
+ return (((struct scd*) conn) && ((struct scd*) conn)->established) ?
+ SSL_pending(((struct scd*) conn)->ssl) > 0 : 0;
}
-static void ssl_conn_free( struct scd *conn )
+static void ssl_conn_free(struct scd *conn)
{
- SSL_free( conn->ssl );
- g_free( conn->hostname );
- g_free( conn );
-
+ SSL_free(conn->ssl);
+ g_free(conn->hostname);
+ g_free(conn);
+
}
-void ssl_disconnect( void *conn_ )
+void ssl_disconnect(void *conn_)
{
struct scd *conn = conn_;
-
- if( conn->inpa != -1 )
- b_event_remove( conn->inpa );
-
- if( conn->established )
- SSL_shutdown( conn->ssl );
-
- closesocket( conn->fd );
-
- ssl_conn_free( conn );
+
+ if (conn->inpa != -1) {
+ b_event_remove(conn->inpa);
+ }
+
+ if (conn->established) {
+ SSL_shutdown(conn->ssl);
+ }
+
+ closesocket(conn->fd);
+
+ ssl_conn_free(conn);
}
-int ssl_getfd( void *conn )
+int ssl_getfd(void *conn)
{
- return( ((struct scd*)conn)->fd );
+ return(((struct scd*) conn)->fd);
}
-b_input_condition ssl_getdirection( void *conn )
+b_input_condition ssl_getdirection(void *conn)
{
- return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ );
+ return(((struct scd*) conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ);
}
-char *ssl_verify_strerror( int code )
+char *ssl_verify_strerror(int code)
{
- return g_strdup( "SSL certificate verification not supported by BitlBee OpenSSL code." );
+ return g_strdup("SSL certificate verification not supported by BitlBee OpenSSL code.");
}
-size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res)
+size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len,
+ const unsigned char *iv, unsigned char **res)
{
- int output_length = 0;
+ int output_length = 0;
EVP_CIPHER_CTX ctx;
-
+
*res = g_new0(unsigned char, 72);
-
+
/* Don't set key or IV because we will modify the parameters */
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1);
@@ -305,8 +312,8 @@ size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1);
EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len);
EVP_CipherFinal_ex(&ctx, *res, &output_length);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_cleanup(&ctx);
//EVP_cleanup();
-
+
return output_length;
}
diff --git a/lib/url.c b/lib/url.c
index 1c7ff656..38515669 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2001-2005 Wilmer van der Gaast and others *
@@ -26,84 +26,74 @@
#include "url.h"
/* Convert an URL to a url_t structure */
-int url_set( url_t *url, const char *set_url )
+int url_set(url_t *url, const char *set_url)
{
- char s[MAX_STRING+1];
+ char s[MAX_STRING + 1];
char *i;
-
- memset( url, 0, sizeof( url_t ) );
- memset( s, 0, sizeof( s ) );
-
+
+ memset(url, 0, sizeof(url_t));
+ memset(s, 0, sizeof(s));
+
/* protocol:// */
- if( ( i = strstr( set_url, "://" ) ) == NULL )
- {
+ if ((i = strstr(set_url, "://")) == NULL) {
url->proto = PROTO_DEFAULT;
- strncpy( s, set_url, MAX_STRING );
- }
- else
- {
- if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
+ strncpy(s, set_url, MAX_STRING);
+ } else {
+ if (g_strncasecmp(set_url, "http", i - set_url) == 0) {
url->proto = PROTO_HTTP;
- else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
+ } else if (g_strncasecmp(set_url, "https", i - set_url) == 0) {
url->proto = PROTO_HTTPS;
- else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 )
+ } else if (g_strncasecmp(set_url, "socks4", i - set_url) == 0) {
url->proto = PROTO_SOCKS4;
- else if( g_strncasecmp( set_url, "socks5", i - set_url ) == 0 )
+ } else if (g_strncasecmp(set_url, "socks5", i - set_url) == 0) {
url->proto = PROTO_SOCKS5;
- else
+ } else {
return 0;
-
- strncpy( s, i + 3, MAX_STRING );
+ }
+
+ strncpy(s, i + 3, MAX_STRING);
}
-
+
/* Split */
- if( ( i = strchr( s, '/' ) ) == NULL )
- {
- strcpy( url->file, "/" );
- }
- else
- {
- strncpy( url->file, i, MAX_STRING );
+ if ((i = strchr(s, '/')) == NULL) {
+ strcpy(url->file, "/");
+ } else {
+ strncpy(url->file, i, MAX_STRING);
*i = 0;
}
- strncpy( url->host, s, MAX_STRING );
-
+ strncpy(url->host, s, MAX_STRING);
+
/* Check for username in host field */
- if( strrchr( url->host, '@' ) != NULL )
- {
- strncpy( url->user, url->host, MAX_STRING );
- i = strrchr( url->user, '@' );
+ if (strrchr(url->host, '@') != NULL) {
+ strncpy(url->user, url->host, MAX_STRING);
+ i = strrchr(url->user, '@');
*i = 0;
- strcpy( url->host, i + 1 );
+ strcpy(url->host, i + 1);
*url->pass = 0;
}
/* If not: Fill in defaults */
- else
- {
+ else {
*url->user = *url->pass = 0;
}
-
+
/* Password? */
- if( ( i = strchr( url->user, ':' ) ) != NULL )
- {
+ if ((i = strchr(url->user, ':')) != NULL) {
*i = 0;
- strcpy( url->pass, i + 1 );
+ strcpy(url->pass, i + 1);
}
/* Port number? */
- if( ( i = strchr( url->host, ':' ) ) != NULL )
- {
+ if ((i = strchr(url->host, ':')) != NULL) {
*i = 0;
- sscanf( i + 1, "%d", &url->port );
- }
- else
- {
- if( url->proto == PROTO_HTTP )
+ sscanf(i + 1, "%d", &url->port);
+ } else {
+ if (url->proto == PROTO_HTTP) {
url->port = 80;
- else if( url->proto == PROTO_HTTPS )
+ } else if (url->proto == PROTO_HTTPS) {
url->port = 443;
- else if( url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS5 )
+ } else if (url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS5) {
url->port = 1080;
+ }
}
-
- return( url->port > 0 );
+
+ return(url->port > 0);
}
diff --git a/lib/url.h b/lib/url.h
index d49d3365..4caf13d7 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -1,4 +1,4 @@
- /********************************************************************\
+/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
* Copyright 2001-2004 Wilmer van der Gaast and others *
@@ -31,14 +31,13 @@
#define PROTO_SOCKS5 4
#define PROTO_DEFAULT PROTO_HTTP
-typedef struct url
-{
+typedef struct url {
int proto;
int port;
- char host[MAX_STRING+1];
- char file[MAX_STRING+1];
- char user[MAX_STRING+1];
- char pass[MAX_STRING+1];
+ char host[MAX_STRING + 1];
+ char file[MAX_STRING + 1];
+ char user[MAX_STRING + 1];
+ char pass[MAX_STRING + 1];
} url_t;
-int url_set( url_t *url, const char *set_url );
+int url_set(url_t *url, const char *set_url);
diff --git a/lib/xmltree.c b/lib/xmltree.c
index 6253d760..a98c91e1 100644
--- a/lib/xmltree.c
+++ b/lib/xmltree.c
@@ -32,74 +32,74 @@
#define g_strcasecmp g_ascii_strcasecmp
#define g_strncasecmp g_ascii_strncasecmp
-static void xt_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error )
+static void xt_start_element(GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names,
+ const gchar **attr_values, gpointer data, GError **error)
{
struct xt_parser *xt = data;
- struct xt_node *node = g_new0( struct xt_node, 1 ), *nt;
+ struct xt_node *node = g_new0(struct xt_node, 1), *nt;
int i;
-
+
node->parent = xt->cur;
- node->name = g_strdup( element_name );
-
+ node->name = g_strdup(element_name);
+
/* First count the number of attributes */
- for( i = 0; attr_names[i]; i ++ );
-
+ for (i = 0; attr_names[i]; i++) {
+ ;
+ }
+
/* Then allocate a NULL-terminated array. */
- node->attr = g_new0( struct xt_attr, i + 1 );
-
+ node->attr = g_new0(struct xt_attr, i + 1);
+
/* And fill it, saving one variable by starting at the end. */
- for( i --; i >= 0; i -- )
- {
- node->attr[i].key = g_strdup( attr_names[i] );
- node->attr[i].value = g_strdup( attr_values[i] );
+ for (i--; i >= 0; i--) {
+ node->attr[i].key = g_strdup(attr_names[i]);
+ node->attr[i].value = g_strdup(attr_values[i]);
}
-
+
/* Add it to the linked list of children nodes, if we have a current
node yet. */
- if( xt->cur )
- {
- if( xt->cur->children )
- {
- for( nt = xt->cur->children; nt->next; nt = nt->next );
+ if (xt->cur) {
+ if (xt->cur->children) {
+ for (nt = xt->cur->children; nt->next; nt = nt->next) {
+ ;
+ }
nt->next = node;
- }
- else
- {
+ } else {
xt->cur->children = node;
}
- }
- else if( xt->root )
- {
+ } else if (xt->root) {
/* ERROR situation: A second root-element??? */
}
-
+
/* Now this node will be the new current node. */
xt->cur = node;
/* And maybe this is the root? */
- if( xt->root == NULL )
+ if (xt->root == NULL) {
xt->root = node;
+ }
}
-static void xt_text( GMarkupParseContext *ctx, const gchar *text, gsize text_len, gpointer data, GError **error )
+static void xt_text(GMarkupParseContext *ctx, const gchar *text, gsize text_len, gpointer data, GError **error)
{
struct xt_parser *xt = data;
struct xt_node *node = xt->cur;
-
- if( node == NULL )
+
+ if (node == NULL) {
return;
-
+ }
+
/* FIXME: Does g_renew also OFFICIALLY accept NULL arguments? */
- node->text = g_renew( char, node->text, node->text_len + text_len + 1 );
- memcpy( node->text + node->text_len, text, text_len );
+ node->text = g_renew(char, node->text, node->text_len + text_len + 1);
+ memcpy(node->text + node->text_len, text, text_len);
node->text_len += text_len;
/* Zero termination is always nice to have. */
node->text[node->text_len] = 0;
}
-static void xt_end_element( GMarkupParseContext *ctx, const gchar *element_name, gpointer data, GError **error )
+static void xt_end_element(GMarkupParseContext *ctx, const gchar *element_name, gpointer data, GError **error)
{
struct xt_parser *xt = data;
-
+
xt->cur->flags |= XT_COMPLETE;
xt->cur = xt->cur->parent;
}
@@ -113,29 +113,29 @@ GMarkupParser xt_parser_funcs =
NULL
};
-struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data )
+struct xt_parser *xt_new(const struct xt_handler_entry *handlers, gpointer data)
{
- struct xt_parser *xt = g_new0( struct xt_parser, 1 );
-
+ struct xt_parser *xt = g_new0(struct xt_parser, 1);
+
xt->data = data;
xt->handlers = handlers;
- xt_reset( xt );
-
+ xt_reset(xt);
+
return xt;
}
/* Reset the parser, flush everything we have so far. For example, we need
this for XMPP when doing TLS/SASL to restart the stream. */
-void xt_reset( struct xt_parser *xt )
+void xt_reset(struct xt_parser *xt)
{
- if( xt->parser )
- g_markup_parse_context_free( xt->parser );
-
- xt->parser = g_markup_parse_context_new( &xt_parser_funcs, 0, xt, NULL );
-
- if( xt->root )
- {
- xt_free_node( xt->root );
+ if (xt->parser) {
+ g_markup_parse_context_free(xt->parser);
+ }
+
+ xt->parser = g_markup_parse_context_new(&xt_parser_funcs, 0, xt, NULL);
+
+ if (xt->root) {
+ xt_free_node(xt->root);
xt->root = NULL;
xt->cur = NULL;
}
@@ -143,395 +143,397 @@ void xt_reset( struct xt_parser *xt )
/* Feed the parser, don't execute any handler. Returns -1 on errors, 0 on
end-of-stream and 1 otherwise. */
-int xt_feed( struct xt_parser *xt, const char *text, int text_len )
+int xt_feed(struct xt_parser *xt, const char *text, int text_len)
{
- if( !g_markup_parse_context_parse( xt->parser, text, text_len, &xt->gerr ) )
- {
+ if (!g_markup_parse_context_parse(xt->parser, text, text_len, &xt->gerr)) {
return -1;
}
-
- return !( xt->root && xt->root->flags & XT_COMPLETE );
+
+ return !(xt->root && xt->root->flags & XT_COMPLETE);
}
/* Find completed nodes and see if a handler has to be called. Passing
a node isn't necessary if you want to start at the root, just pass
NULL. This second argument is needed for recursive calls. */
-int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth )
+int xt_handle(struct xt_parser *xt, struct xt_node *node, int depth)
{
struct xt_node *c;
xt_status st;
int i;
-
- if( xt->root == NULL )
+
+ if (xt->root == NULL) {
return 1;
-
- if( node == NULL )
- return xt_handle( xt, xt->root, depth );
-
- if( depth != 0 )
- for( c = node->children; c; c = c->next )
- if( !xt_handle( xt, c, depth > 0 ? depth - 1 : depth ) )
+ }
+
+ if (node == NULL) {
+ return xt_handle(xt, xt->root, depth);
+ }
+
+ if (depth != 0) {
+ for (c = node->children; c; c = c->next) {
+ if (!xt_handle(xt, c, depth > 0 ? depth - 1 : depth)) {
return 0;
-
- if( node->flags & XT_COMPLETE && !( node->flags & XT_SEEN ) )
- {
- if( xt->handlers ) for( i = 0; xt->handlers[i].func; i ++ )
- {
- /* This one is fun! \o/ */
-
- /* If handler.name == NULL it means it should always match. */
- if( ( xt->handlers[i].name == NULL ||
- /* If it's not, compare. There should always be a name. */
- g_strcasecmp( xt->handlers[i].name, node->name ) == 0 ) &&
- /* If handler.parent == NULL, it's a match. */
- ( xt->handlers[i].parent == NULL ||
- /* If there's a parent node, see if the name matches. */
- ( node->parent ? g_strcasecmp( xt->handlers[i].parent, node->parent->name ) == 0 :
- /* If there's no parent, the handler should mention <root> as a parent. */
- strcmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )
- {
- st = xt->handlers[i].func( node, xt->data );
-
- if( st == XT_ABORT )
- return 0;
- else if( st != XT_NEXT )
- break;
}
}
-
+ }
+
+ if (node->flags & XT_COMPLETE && !(node->flags & XT_SEEN)) {
+ if (xt->handlers) {
+ for (i = 0; xt->handlers[i].func; i++) {
+ /* This one is fun! \o/ */
+
+ /* If handler.name == NULL it means it should always match. */
+ if ((xt->handlers[i].name == NULL ||
+ /* If it's not, compare. There should always be a name. */
+ g_strcasecmp(xt->handlers[i].name, node->name) == 0) &&
+ /* If handler.parent == NULL, it's a match. */
+ (xt->handlers[i].parent == NULL ||
+ /* If there's a parent node, see if the name matches. */
+ (node->parent ? g_strcasecmp(xt->handlers[i].parent, node->parent->name) == 0 :
+ /* If there's no parent, the handler should mention <root> as a parent. */
+ strcmp(xt->handlers[i].parent, "<root>") == 0))) {
+ st = xt->handlers[i].func(node, xt->data);
+
+ if (st == XT_ABORT) {
+ return 0;
+ } else if (st != XT_NEXT) {
+ break;
+ }
+ }
+ }
+ }
+
node->flags |= XT_SEEN;
}
-
+
return 1;
}
/* Garbage collection: Cleans up all nodes that are handled. Useful for
streams because there's no reason to keep a complete packet history
in memory. */
-void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth )
+void xt_cleanup(struct xt_parser *xt, struct xt_node *node, int depth)
{
struct xt_node *c, *prev;
-
- if( !xt || !xt->root )
+
+ if (!xt || !xt->root) {
return;
-
- if( node == NULL )
- {
- xt_cleanup( xt, xt->root, depth );
+ }
+
+ if (node == NULL) {
+ xt_cleanup(xt, xt->root, depth);
return;
}
-
- if( node->flags & XT_SEEN && node == xt->root )
- {
- xt_free_node( xt->root );
+
+ if (node->flags & XT_SEEN && node == xt->root) {
+ xt_free_node(xt->root);
xt->root = xt->cur = NULL;
/* xt->cur should be NULL already, BTW... */
-
+
return;
}
-
+
/* c contains the current node, prev the previous node (or NULL).
I admit, this one's pretty horrible. */
- for( c = node->children, prev = NULL; c; prev = c, c = c ? c->next : node->children )
- {
- if( c->flags & XT_SEEN )
- {
+ for (c = node->children, prev = NULL; c; prev = c, c = c ? c->next : node->children) {
+ if (c->flags & XT_SEEN) {
/* Remove the node from the linked list. */
- if( prev )
+ if (prev) {
prev->next = c->next;
- else
+ } else {
node->children = c->next;
-
- xt_free_node( c );
-
+ }
+
+ xt_free_node(c);
+
/* Since the for loop wants to get c->next, make sure
c points at something that exists (and that c->next
will actually be the next item we should check). c
can be NULL now, if we just removed the first item.
That explains the ? thing in for(). */
c = prev;
- }
- else
- {
+ } else {
/* This node can't be cleaned up yet, but maybe a
subnode can. */
- if( depth != 0 )
- xt_cleanup( xt, c, depth > 0 ? depth - 1 : depth );
+ if (depth != 0) {
+ xt_cleanup(xt, c, depth > 0 ? depth - 1 : depth);
+ }
}
}
}
-struct xt_node *xt_from_string( const char *in, int len )
+struct xt_node *xt_from_string(const char *in, int len)
{
struct xt_parser *parser;
struct xt_node *ret = NULL;
-
- if( len == 0 )
- len = strlen( in );
-
- parser = xt_new( NULL, NULL );
- xt_feed( parser, in, len );
- if( parser->cur == NULL )
- {
+
+ if (len == 0) {
+ len = strlen(in);
+ }
+
+ parser = xt_new(NULL, NULL);
+ xt_feed(parser, in, len);
+ if (parser->cur == NULL) {
ret = parser->root;
parser->root = NULL;
}
- xt_free( parser );
-
+ xt_free(parser);
+
return ret;
}
-static void xt_to_string_real( struct xt_node *node, GString *str, int indent )
+static void xt_to_string_real(struct xt_node *node, GString *str, int indent)
{
char *buf;
struct xt_node *c;
int i;
-
- if( indent > 1 )
- g_string_append_len( str, "\n\t\t\t\t\t\t\t\t",
- indent < 8 ? indent : 8 );
-
- g_string_append_printf( str, "<%s", node->name );
-
- for( i = 0; node->attr[i].key; i ++ )
- {
- buf = g_markup_printf_escaped( " %s=\"%s\"", node->attr[i].key, node->attr[i].value );
- g_string_append( str, buf );
- g_free( buf );
- }
-
- if( node->text == NULL && node->children == NULL )
- {
- g_string_append( str, "/>" );
+
+ if (indent > 1) {
+ g_string_append_len(str, "\n\t\t\t\t\t\t\t\t",
+ indent < 8 ? indent : 8);
+ }
+
+ g_string_append_printf(str, "<%s", node->name);
+
+ for (i = 0; node->attr[i].key; i++) {
+ buf = g_markup_printf_escaped(" %s=\"%s\"", node->attr[i].key, node->attr[i].value);
+ g_string_append(str, buf);
+ g_free(buf);
+ }
+
+ if (node->text == NULL && node->children == NULL) {
+ g_string_append(str, "/>");
return;
}
-
- g_string_append( str, ">" );
- if( node->text_len > 0 )
- {
- buf = g_markup_escape_text( node->text, node->text_len );
- g_string_append( str, buf );
- g_free( buf );
- }
-
- for( c = node->children; c; c = c->next )
- xt_to_string_real( c, str, indent ? indent + 1 : 0 );
-
- if( indent > 0 && node->children )
- g_string_append_len( str, "\n\t\t\t\t\t\t\t\t",
- indent < 8 ? indent : 8 );
-
- g_string_append_printf( str, "</%s>", node->name );
+
+ g_string_append(str, ">");
+ if (node->text_len > 0) {
+ buf = g_markup_escape_text(node->text, node->text_len);
+ g_string_append(str, buf);
+ g_free(buf);
+ }
+
+ for (c = node->children; c; c = c->next) {
+ xt_to_string_real(c, str, indent ? indent + 1 : 0);
+ }
+
+ if (indent > 0 && node->children) {
+ g_string_append_len(str, "\n\t\t\t\t\t\t\t\t",
+ indent < 8 ? indent : 8);
+ }
+
+ g_string_append_printf(str, "</%s>", node->name);
}
-char *xt_to_string( struct xt_node *node )
+char *xt_to_string(struct xt_node *node)
{
GString *ret;
-
- ret = g_string_new( "" );
- xt_to_string_real( node, ret, 0 );
- return g_string_free( ret, FALSE );
+
+ ret = g_string_new("");
+ xt_to_string_real(node, ret, 0);
+ return g_string_free(ret, FALSE);
}
/* WITH indentation! */
-char *xt_to_string_i( struct xt_node *node )
+char *xt_to_string_i(struct xt_node *node)
{
GString *ret;
-
- ret = g_string_new( "" );
- xt_to_string_real( node, ret, 1 );
- return g_string_free( ret, FALSE );
+
+ ret = g_string_new("");
+ xt_to_string_real(node, ret, 1);
+ return g_string_free(ret, FALSE);
}
-void xt_print( struct xt_node *node )
+void xt_print(struct xt_node *node)
{
- char *str = xt_to_string_i( node );
- fprintf( stderr, "%s", str );
- g_free( str );
+ char *str = xt_to_string_i(node);
+
+ fprintf(stderr, "%s", str);
+ g_free(str);
}
-struct xt_node *xt_dup( struct xt_node *node )
+struct xt_node *xt_dup(struct xt_node *node)
{
- struct xt_node *dup = g_new0( struct xt_node, 1 );
+ struct xt_node *dup = g_new0(struct xt_node, 1);
struct xt_node *c, *dc = NULL;
int i;
-
+
/* Let's NOT copy the parent element here BTW! Only do it for children. */
-
- dup->name = g_strdup( node->name );
+
+ dup->name = g_strdup(node->name);
dup->flags = node->flags;
- if( node->text )
- {
- dup->text = g_memdup( node->text, node->text_len + 1 );
+ if (node->text) {
+ dup->text = g_memdup(node->text, node->text_len + 1);
dup->text_len = node->text_len;
}
-
+
/* Count the number of attributes and allocate the new array. */
- for( i = 0; node->attr[i].key; i ++ );
- dup->attr = g_new0( struct xt_attr, i + 1 );
-
+ for (i = 0; node->attr[i].key; i++) {
+ ;
+ }
+ dup->attr = g_new0(struct xt_attr, i + 1);
+
/* Copy them all! */
- for( i --; i >= 0; i -- )
- {
- dup->attr[i].key = g_strdup( node->attr[i].key );
- dup->attr[i].value = g_strdup( node->attr[i].value );
+ for (i--; i >= 0; i--) {
+ dup->attr[i].key = g_strdup(node->attr[i].key);
+ dup->attr[i].value = g_strdup(node->attr[i].value);
}
-
+
/* This nice mysterious loop takes care of the children. */
- for( c = node->children; c; c = c->next )
- {
- if( dc == NULL )
- dc = dup->children = xt_dup( c );
- else
- dc = ( dc->next = xt_dup( c ) );
-
+ for (c = node->children; c; c = c->next) {
+ if (dc == NULL) {
+ dc = dup->children = xt_dup(c);
+ } else {
+ dc = (dc->next = xt_dup(c));
+ }
+
dc->parent = dup;
}
-
+
return dup;
}
/* Frees a node. This doesn't clean up references to itself from parents! */
-void xt_free_node( struct xt_node *node )
+void xt_free_node(struct xt_node *node)
{
int i;
-
- if( !node )
+
+ if (!node) {
return;
-
- g_free( node->name );
- g_free( node->text );
-
- for( i = 0; node->attr[i].key; i ++ )
- {
- g_free( node->attr[i].key );
- g_free( node->attr[i].value );
- }
- g_free( node->attr );
-
- while( node->children )
- {
+ }
+
+ g_free(node->name);
+ g_free(node->text);
+
+ for (i = 0; node->attr[i].key; i++) {
+ g_free(node->attr[i].key);
+ g_free(node->attr[i].value);
+ }
+ g_free(node->attr);
+
+ while (node->children) {
struct xt_node *next = node->children->next;
-
- xt_free_node( node->children );
+
+ xt_free_node(node->children);
node->children = next;
}
-
- g_free( node );
+
+ g_free(node);
}
-void xt_free( struct xt_parser *xt )
+void xt_free(struct xt_parser *xt)
{
- if( !xt )
+ if (!xt) {
return;
-
- if( xt->root )
- xt_free_node( xt->root );
-
- g_markup_parse_context_free( xt->parser );
-
- g_free( xt );
+ }
+
+ if (xt->root) {
+ xt_free_node(xt->root);
+ }
+
+ g_markup_parse_context_free(xt->parser);
+
+ g_free(xt);
}
/* To find a node's child with a specific name, pass the node's children
list, not the node itself! The reason you have to do this by hand: So
that you can also use this function as a find-next. */
-struct xt_node *xt_find_node( struct xt_node *node, const char *name )
+struct xt_node *xt_find_node(struct xt_node *node, const char *name)
{
- while( node )
- {
+ while (node) {
char *colon;
-
- if( g_strcasecmp( node->name, name ) == 0 ||
- ( ( colon = strchr( node->name, ':' ) ) &&
- g_strcasecmp( colon + 1, name ) == 0 ) )
+
+ if (g_strcasecmp(node->name, name) == 0 ||
+ ((colon = strchr(node->name, ':')) &&
+ g_strcasecmp(colon + 1, name) == 0)) {
break;
-
+ }
+
node = node->next;
}
-
+
return node;
}
/* More advanced than the one above, understands something like
../foo/bar to find a subnode bar of a node foo which is a child
of node's parent. Pass the node directly, not its list of children. */
-struct xt_node *xt_find_path( struct xt_node *node, const char *name )
+struct xt_node *xt_find_path(struct xt_node *node, const char *name)
{
- while( name && *name && node )
- {
+ while (name && *name && node) {
char *colon, *slash;
int n;
-
- if( ( slash = strchr( name, '/' ) ) )
+
+ if ((slash = strchr(name, '/'))) {
n = slash - name;
- else
- n = strlen( name );
-
- if( strncmp( name, "..", n ) == 0 )
- {
- node = node->parent;
+ } else {
+ n = strlen(name);
}
- else
- {
+
+ if (strncmp(name, "..", n) == 0) {
+ node = node->parent;
+ } else {
node = node->children;
-
- while( node )
- {
- if( g_strncasecmp( node->name, name, n ) == 0 ||
- ( ( colon = strchr( node->name, ':' ) ) &&
- g_strncasecmp( colon + 1, name, n ) == 0 ) )
+
+ while (node) {
+ if (g_strncasecmp(node->name, name, n) == 0 ||
+ ((colon = strchr(node->name, ':')) &&
+ g_strncasecmp(colon + 1, name, n) == 0)) {
break;
-
+ }
+
node = node->next;
}
}
-
+
name = slash ? slash + 1 : NULL;
}
-
+
return node;
}
-char *xt_find_attr( struct xt_node *node, const char *key )
+char *xt_find_attr(struct xt_node *node, const char *key)
{
int i;
char *colon;
-
- if( !node )
+
+ if (!node) {
return NULL;
-
- for( i = 0; node->attr[i].key; i ++ )
- if( g_strcasecmp( node->attr[i].key, key ) == 0 )
+ }
+
+ for (i = 0; node->attr[i].key; i++) {
+ if (g_strcasecmp(node->attr[i].key, key) == 0) {
break;
-
+ }
+ }
+
/* This is an awful hack that only takes care of namespace prefixes
inside a tag. Since IMHO excessive namespace usage in XMPP is
massive overkill anyway (this code exists for almost four years
now and never really missed it): Meh. */
- if( !node->attr[i].key && strcmp( key, "xmlns" ) == 0 &&
- ( colon = strchr( node->name, ':' ) ) )
- {
+ if (!node->attr[i].key && strcmp(key, "xmlns") == 0 &&
+ (colon = strchr(node->name, ':'))) {
*colon = '\0';
- for( i = 0; node->attr[i].key; i ++ )
- if( strncmp( node->attr[i].key, "xmlns:", 6 ) == 0 &&
- strcmp( node->attr[i].key + 6, node->name ) == 0 )
+ for (i = 0; node->attr[i].key; i++) {
+ if (strncmp(node->attr[i].key, "xmlns:", 6) == 0 &&
+ strcmp(node->attr[i].key + 6, node->name) == 0) {
break;
+ }
+ }
*colon = ':';
}
-
+
return node->attr[i].value;
}
-struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value )
+struct xt_node *xt_find_node_by_attr(struct xt_node *xt, const char *tag, const char *key, const char *value)
{
struct xt_node *c;
char *s;
- for( c = xt; ( c = xt_find_node( c, tag ) ); c = c->next )
- {
- if( ( s = xt_find_attr( c, key ) ) && strcmp( s, value ) == 0 )
- {
+ for (c = xt; (c = xt_find_node(c, tag)); c = c->next) {
+ if ((s = xt_find_attr(c, key)) && strcmp(s, value) == 0) {
return c;
}
}
@@ -541,164 +543,159 @@ struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const
/* Strip a few non-printable characters that aren't allowed in XML streams
(and upset some XMPP servers for example). */
-void xt_strip_text( char *in )
+void xt_strip_text(char *in)
{
char *out = in;
static const char nonprint[32] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 0..7 */
0, 1, 1, 0, 0, 1, 0, 0, /* 9 (tab), 10 (\n), 13 (\r) */
};
-
- if( !in )
+
+ if (!in) {
return;
+ }
- while( *in )
- {
- if( (unsigned int) *in >= ' ' || nonprint[(unsigned int) *in] )
- *out ++ = *in;
- in ++;
+ while (*in) {
+ if ((unsigned int) *in >= ' ' || nonprint[(unsigned int) *in]) {
+ *out++ = *in;
+ }
+ in++;
}
*out = *in;
}
-struct xt_node *xt_new_node( char *name, const 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;
-
- node = g_new0( struct xt_node, 1 );
- node->name = g_strdup( name );
+
+ node = g_new0(struct xt_node, 1);
+ node->name = g_strdup(name);
node->children = children;
- node->attr = g_new0( struct xt_attr, 1 );
-
- if( text )
- {
- node->text = g_strdup( text );
- xt_strip_text( node->text );
- node->text_len = strlen( node->text );
- }
-
- for( c = children; c; c = c->next )
- {
- if( c->parent != NULL )
- {
+ node->attr = g_new0(struct xt_attr, 1);
+
+ if (text) {
+ node->text = g_strdup(text);
+ xt_strip_text(node->text);
+ node->text_len = strlen(node->text);
+ }
+
+ for (c = children; c; c = c->next) {
+ if (c->parent != NULL) {
/* ERROR CONDITION: They seem to have a parent already??? */
}
-
+
c->parent = node;
}
-
+
return node;
}
-void xt_add_child( struct xt_node *parent, struct xt_node *child )
+void xt_add_child(struct xt_node *parent, struct xt_node *child)
{
struct xt_node *node;
-
+
/* This function can actually be used to add more than one child, so
do handle this properly. */
- for( node = child; node; node = node->next )
- {
- if( node->parent != NULL )
- {
+ for (node = child; node; node = node->next) {
+ if (node->parent != NULL) {
/* ERROR CONDITION: They seem to have a parent already??? */
}
-
+
node->parent = parent;
}
-
- if( parent->children == NULL )
- {
+
+ if (parent->children == NULL) {
parent->children = child;
- }
- else
- {
- for( node = parent->children; node->next; node = node->next );
+ } else {
+ for (node = parent->children; node->next; node = node->next) {
+ ;
+ }
node->next = child;
}
}
/* Same, but at the beginning. */
-void xt_insert_child( struct xt_node *parent, struct xt_node *child )
+void xt_insert_child(struct xt_node *parent, struct xt_node *child)
{
struct xt_node *node, *last = NULL;
-
- if( child == NULL )
+
+ if (child == NULL) {
return; /* BUG */
-
- for( node = child; node; node = node->next )
- {
- if( node->parent != NULL )
- {
+
+ }
+ for (node = child; node; node = node->next) {
+ if (node->parent != NULL) {
/* ERROR CONDITION: They seem to have a parent already??? */
}
-
+
node->parent = parent;
last = node;
}
-
+
last->next = parent->children;
parent->children = child;
}
-void xt_add_attr( struct xt_node *node, const char *key, const char *value )
+void xt_add_attr(struct xt_node *node, const char *key, const char *value)
{
int i;
-
+
/* Now actually it'd be nice if we can also change existing attributes
(which actually means this function doesn't have the right name).
So let's find out if we have this attribute already... */
- for( i = 0; node->attr[i].key; i ++ )
- if( strcmp( node->attr[i].key, key ) == 0 )
+ for (i = 0; node->attr[i].key; i++) {
+ if (strcmp(node->attr[i].key, key) == 0) {
break;
-
- if( node->attr[i].key == NULL )
- {
- /* If not, allocate space for a new attribute. */
- node->attr = g_renew( struct xt_attr, node->attr, i + 2 );
- node->attr[i].key = g_strdup( key );
- node->attr[i+1].key = NULL;
+ }
}
- else
- {
+
+ if (node->attr[i].key == NULL) {
+ /* If not, allocate space for a new attribute. */
+ node->attr = g_renew(struct xt_attr, node->attr, i + 2);
+ node->attr[i].key = g_strdup(key);
+ node->attr[i + 1].key = NULL;
+ } else {
/* Otherwise, free the old value before setting the new one. */
- g_free( node->attr[i].value );
+ g_free(node->attr[i].value);
}
-
- node->attr[i].value = g_strdup( value );
+
+ node->attr[i].value = g_strdup(value);
}
-int xt_remove_attr( struct xt_node *node, const char *key )
+int xt_remove_attr(struct xt_node *node, const char *key)
{
int i, last;
-
- for( i = 0; node->attr[i].key; i ++ )
- if( strcmp( node->attr[i].key, key ) == 0 )
+
+ for (i = 0; node->attr[i].key; i++) {
+ if (strcmp(node->attr[i].key, key) == 0) {
break;
-
+ }
+ }
+
/* If we didn't find the attribute... */
- if( node->attr[i].key == NULL )
+ if (node->attr[i].key == NULL) {
return 0;
-
- g_free( node->attr[i].key );
- g_free( node->attr[i].value );
-
+ }
+
+ g_free(node->attr[i].key);
+ g_free(node->attr[i].value);
+
/* If it's the last, this is easy: */
- if( node->attr[i+1].key == NULL )
- {
+ if (node->attr[i + 1].key == NULL) {
node->attr[i].key = node->attr[i].value = NULL;
- }
- else /* It's also pretty easy, actually. */
- {
+ } else { /* It's also pretty easy, actually. */
/* Find the last item. */
- for( last = i + 1; node->attr[last+1].key; last ++ );
-
+ for (last = i + 1; node->attr[last + 1].key; last++) {
+ ;
+ }
+
node->attr[i] = node->attr[last];
node->attr[last].key = NULL;
node->attr[last].value = NULL;
}
-
+
/* Let's not bother with reallocating memory here. It takes time and
most packets don't stay in memory for long anyway. */
-
+
return 1;
}
diff --git a/lib/xmltree.h b/lib/xmltree.h
index af13b859..85b10983 100644
--- a/lib/xmltree.h
+++ b/lib/xmltree.h
@@ -24,79 +24,73 @@
#ifndef _XMLTREE_H
#define _XMLTREE_H
-typedef enum
-{
- XT_COMPLETE = 1, /* </tag> reached */
- XT_SEEN = 2, /* Handler called (or not defined) */
+typedef enum {
+ XT_COMPLETE = 1, /* </tag> reached */
+ XT_SEEN = 2, /* Handler called (or not defined) */
} xt_flags;
-typedef enum
-{
- XT_ABORT, /* Abort, don't handle the rest anymore */
- XT_HANDLED, /* Handled this tag properly, go to the next one */
- XT_NEXT /* Try if there's another matching handler */
+typedef enum {
+ XT_ABORT, /* Abort, don't handle the rest anymore */
+ XT_HANDLED, /* Handled this tag properly, go to the next one */
+ XT_NEXT /* Try if there's another matching handler */
} xt_status;
-struct xt_attr
-{
+struct xt_attr {
char *key, *value;
};
-struct xt_node
-{
+struct xt_node {
struct xt_node *parent;
struct xt_node *children;
-
+
char *name;
struct xt_attr *attr;
char *text;
int text_len;
-
+
struct xt_node *next;
xt_flags flags;
};
-typedef xt_status (*xt_handler_func) ( struct xt_node *node, gpointer data );
+typedef xt_status (*xt_handler_func) (struct xt_node *node, gpointer data);
-struct xt_handler_entry
-{
+struct xt_handler_entry {
char *name, *parent;
xt_handler_func func;
};
-struct xt_parser
-{
+struct xt_parser {
GMarkupParseContext *parser;
struct xt_node *root;
struct xt_node *cur;
-
+
const struct xt_handler_entry *handlers;
gpointer data;
-
+
GError *gerr;
};
-struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data );
-void xt_reset( struct xt_parser *xt );
-int xt_feed( struct xt_parser *xt, const char *text, int text_len );
-int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth );
-void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth );
-struct xt_node *xt_from_string( const char *in, int text_len );
-char *xt_to_string( struct xt_node *node );
-char *xt_to_string_i( struct xt_node *node );
-void xt_print( struct xt_node *node );
-struct xt_node *xt_dup( struct xt_node *node );
-void xt_free_node( struct xt_node *node );
-void xt_free( struct xt_parser *xt );
-struct xt_node *xt_find_node( struct xt_node *node, const char *name );
-struct xt_node *xt_find_path( struct xt_node *node, const char *name );
-char *xt_find_attr( struct xt_node *node, const char *key );
-struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value );
+struct xt_parser *xt_new(const struct xt_handler_entry *handlers, gpointer data);
+void xt_reset(struct xt_parser *xt);
+int xt_feed(struct xt_parser *xt, const char *text, int text_len);
+int xt_handle(struct xt_parser *xt, struct xt_node *node, int depth);
+void xt_cleanup(struct xt_parser *xt, struct xt_node *node, int depth);
+struct xt_node *xt_from_string(const char *in, int text_len);
+char *xt_to_string(struct xt_node *node);
+char *xt_to_string_i(struct xt_node *node);
+void xt_print(struct xt_node *node);
+struct xt_node *xt_dup(struct xt_node *node);
+void xt_free_node(struct xt_node *node);
+void xt_free(struct xt_parser *xt);
+struct xt_node *xt_find_node(struct xt_node *node, const char *name);
+struct xt_node *xt_find_path(struct xt_node *node, const char *name);
+char *xt_find_attr(struct xt_node *node, const char *key);
+struct xt_node *xt_find_node_by_attr(struct xt_node *xt, const char *tag, const char *key, const char *value);
-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_insert_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 );
+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_insert_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);
#endif