diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-05-29 01:13:47 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-05-29 01:13:47 +0200 |
commit | 4ff09664d2570be8358a3bde62123cc8e0a17c9e (patch) | |
tree | a5cfc2f235f9a46f737b261186e7926aca202ebe | |
parent | cdca30b360c09399f1e5a2556d83ec997006cd75 (diff) | |
parent | 79b6213c1fa2ffaa102365515551e9f0ea9fdc1a (diff) |
Merging from main/jelmer.
-rwxr-xr-x | configure | 36 | ||||
-rw-r--r-- | doc/README | 2 | ||||
-rw-r--r-- | irc_commands.c | 43 | ||||
-rw-r--r-- | protocols/http_client.c | 58 | ||||
-rw-r--r-- | protocols/http_client.h | 1 | ||||
-rw-r--r-- | protocols/msn/ns.c | 9 | ||||
-rw-r--r-- | protocols/msn/passport.c | 32 | ||||
-rw-r--r-- | protocols/msn/passport.h | 1 | ||||
-rw-r--r-- | protocols/msn/sb.c | 10 | ||||
-rw-r--r-- | protocols/msn/tables.c | 2 | ||||
-rw-r--r-- | util.c | 26 |
11 files changed, 129 insertions, 91 deletions
@@ -168,38 +168,16 @@ if [ -z "$PKG_CONFIG" ]; then PKG_CONFIG=pkg-config fi -GLIB=0 - if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG glib-2.0; then cat<<EOF>>Makefile.settings EFLAGS+=`$PKG_CONFIG --libs glib-2.0 gmodule-2.0` CFLAGS+=`$PKG_CONFIG --cflags glib-2.0 gmodule-2.0` EOF - echo '#define GLIB2' >> config.h - GLIB=2 -elif type glib-config > /dev/null 2> /dev/null; then - cat<<EOF>>Makefile.settings -EFLAGS+=`glib-config --libs` -CFLAGS+=`glib-config --cflags` -EOF - echo '#define GLIB1' >> config.h - GLIB=1 else - echo 'Cannot find glib development libraries, aborting. (Install libglib-dev?)' + echo 'Cannot find glib2 development libraries, aborting. (Install libglib2-dev?)' exit 1; fi -if [ GLIB = 1 -o -r /usr/include/iconv.h ]; then - :; -elif [ -r /usr/local/include/iconv.h ]; then - echo CFLAGS+=-I/usr/local/include >> Makefile.settings -else - echo - echo 'Warning: Could not find iconv.h, you might have to install it and/or modify' - echo 'Makefile.settings to tell where this file is.' -fi - - if [ "$events" = "libevent" ]; then if ! [ -e "${libevent}include/event.h" ]; then echo @@ -223,7 +201,6 @@ else fi echo 'EVENT_HANDLER=events_'$events'.o' >> Makefile.settings - detect_gnutls() { if libgnutls-config --version > /dev/null 2> /dev/null; then @@ -419,18 +396,15 @@ Linux ) GNU/* ) ;; *BSD ) - echo 'EFLAGS+=-liconv' >> Makefile.settings; -;; -SunOS ) - echo 'EFLAGS+=-lresolv -lnsl -lsocket' >> Makefile.settings - echo 'STRIP=\# skip strip' >> Makefile.settings - echo 'EFLAGS+=-liconv' >> Makefile.settings; ;; Darwin ) - echo 'EFLAGS+=-liconv' >> Makefile.settings; ;; IRIX ) ;; +SunOS ) + echo 'EFLAGS+=-lresolv -lnsl -lsocket' >> Makefile.settings + echo 'STRIP=\# skip strip' >> Makefile.settings +;; CYGWIN* ) echo 'Cygwin is not officially supported.' ;; @@ -46,7 +46,7 @@ DEPENDENCIES ============ BitlBee's only real dependency is GLib. This is available on virtually every -platform. Any recent version of GLib (including 1.x versions) will work. +platform. Any recent version of GLib (2.0 or higher) will work. These days, MSN Messenger clients have to connect to the MS Passport servers through HTTPS. BitlBee can use several SSL libraries for this: GnuTLS, NSS diff --git a/irc_commands.c b/irc_commands.c index fe67a534..f80f50f5 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -320,7 +320,7 @@ static void irc_cmd_userhost( irc_t *irc, char **cmd ) static void irc_cmd_ison( irc_t *irc, char **cmd ) { user_t *u; - char buff[IRC_MAX_LINE]; + char buff[IRC_MAX_LINE], *s; int lenleft, i; buff[0] = '\0'; @@ -330,28 +330,41 @@ static void irc_cmd_ison( irc_t *irc, char **cmd ) for( i = 1; cmd[i]; i ++ ) { - if( ( u = user_find( irc, cmd[i] ) ) && u->online ) + char *this, *next; + + this = cmd[i]; + while( *this ) { - /* [SH] Make sure we don't use too much buffer space. */ - lenleft -= strlen( u->nick ) + 1; + if( ( next = strchr( this, ' ' ) ) ) + *next = 0; - if( lenleft < 0 ) + if( ( u = user_find( irc, this ) ) && u->online ) { - break; + lenleft -= strlen( u->nick ) + 1; + + if( lenleft < 0 ) + break; + + strcat( buff, u->nick ); + strcat( buff, " " ); } - /* [SH] Add the nick to the buffer. Note - * that an extra space is always added. Even - * if it's the last nick in the list. Who - * cares? - */ - - strcat( buff, u->nick ); - strcat( buff, " " ); + if( next ) + { + *next = ' '; + this = next + 1; + } + else + { + break; + } } + + /* *sigh* */ + if( lenleft < 0 ) + break; } - /* [WvG] Well, maybe someone cares, so why not remove it? */ if( strlen( buff ) > 0 ) buff[strlen(buff)-1] = '\0'; diff --git a/protocols/http_client.c b/protocols/http_client.c index 1a431e25..b00fcf98 100644 --- a/protocols/http_client.c +++ b/protocols/http_client.c @@ -156,6 +156,8 @@ static gboolean http_connected( gpointer data, int source, b_input_condition con return FALSE; error: + req->status_string = g_strdup( "Error while writing HTTP request" ); + req->func( req ); g_free( req->request ); @@ -215,6 +217,7 @@ static gboolean http_incoming_data( gpointer data, int source, b_input_condition { if( !sockerr_again() ) { + req->status_string = g_strdup( strerror( errno ) ); goto cleanup; } } @@ -242,7 +245,10 @@ got_reply: /* 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" ); goto cleanup; + } /* Zero termination is very convenient. */ req->reply_headers[req->bytes_read] = 0; @@ -263,6 +269,7 @@ got_reply: } else { + req->status_string = g_strdup( "Malformed HTTP reply" ); goto cleanup; } @@ -278,10 +285,31 @@ got_reply: if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL ) { if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 ) + { + req->status_string = g_strdup( "Can't parse status code" ); req->status_code = -1; + } + 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 ); + + /* Just to be sure... */ + if( ( eol = strchr( req->status_string, '\r' ) ) ) + *eol = 0; + if( ( eol = strchr( req->status_string, '\n' ) ) ) + *eol = 0; + } } else { + req->status_string = g_strdup( "Can't locate status code" ); req->status_code = -1; } @@ -290,9 +318,16 @@ got_reply: 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 ); + 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" ); goto cleanup; + } loc += 11; while( *loc == ' ' ) @@ -309,6 +344,8 @@ got_reply: /* 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 recursive redirects" ); + goto cleanup; } else @@ -326,6 +363,7 @@ got_reply: if( !url_set( url, loc ) ) { + req->status_string = g_strdup( "Malformed redirect URL" ); g_free( url ); goto cleanup; } @@ -336,28 +374,18 @@ got_reply: /* So, now I just allocated enough memory, so I'm going to use strcat(), whether you like it or not. :-) */ - /* First, find the GET/POST/whatever from the original request. */ - s = strchr( req->request, ' ' ); - if( s == NULL ) - { - g_free( new_request ); - g_free( url ); - goto cleanup; - } - - *s = 0; - sprintf( new_request, "%s %s HTTP/1.0\r\n", req->request, url->file ); - *s = ' '; + sprintf( new_request, "GET %s HTTP/1.0", url->file ); s = strstr( req->request, "\r\n" ); if( s == NULL ) { + req->status_string = g_strdup( "Error while rebuilding request string" ); g_free( new_request ); g_free( url ); goto cleanup; } - strcat( new_request, s + 2 ); + strcat( new_request, s ); new_host = g_strdup( url->host ); new_port = url->port; new_proto = url->proto; @@ -371,7 +399,7 @@ got_reply: closesocket( req->fd ); req->fd = -1; - req->ssl = 0; + req->ssl = NULL; if( new_proto == PROTO_HTTPS ) { @@ -389,6 +417,7 @@ got_reply: if( error ) { + req->status_string = g_strdup( "Connection problem during redirect" ); g_free( new_request ); goto cleanup; } @@ -417,6 +446,7 @@ cleanup: g_free( req->request ); g_free( req->reply_headers ); + g_free( req->status_string ); g_free( req ); return FALSE; diff --git a/protocols/http_client.h b/protocols/http_client.h index 860cdd86..50ee80cf 100644 --- a/protocols/http_client.h +++ b/protocols/http_client.h @@ -36,6 +36,7 @@ struct http_request char *request; int request_length; int status_code; + char *status_string; char *reply_headers; char *reply_body; int body_size; diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index af3793f2..e4c2b68c 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -655,8 +655,15 @@ static void msn_auth_got_passport_id( struct passport_reply *rep ) if( key == NULL ) { - hide_login_progress( gc, "Error during Passport authentication" ); + char *err; + + err = g_strdup_printf( "Error during Passport authentication (%s)", + rep->error_string ? rep->error_string : "Unknown error" ); + + hide_login_progress( gc, err ); signoff( gc ); + + g_free( err ); } else { diff --git a/protocols/msn/passport.c b/protocols/msn/passport.c index 34703432..dd1d9b6f 100644 --- a/protocols/msn/passport.c +++ b/protocols/msn/passport.c @@ -68,8 +68,7 @@ static int passport_get_id_real( gpointer func, gpointer data, char *header ) return( 0 ); } - reqs = g_malloc( strlen( header ) + strlen( dummy ) + 128 ); - sprintf( reqs, "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); + reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); *dummy = 0; req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep ); @@ -87,13 +86,13 @@ static void passport_get_id_ready( struct http_request *req ) { struct passport_reply *rep = req->data; - if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers ) + if( !g_slist_find( msn_connections, rep->data ) ) { destroy_reply( rep ); return; } - if( req->status_code == 200 ) + if( req->finished && req->reply_headers && req->status_code == 200 ) { char *dummy; @@ -108,6 +107,15 @@ static void passport_get_id_ready( struct http_request *req ) rep->result = g_strdup( dummy ); } + else + { + rep->error_string = g_strdup( "Could not parse Passport server response" ); + } + } + else + { + rep->error_string = g_strdup_printf( "HTTP error: %s", + req->status_string ? req->status_string : "Unknown error" ); } rep->func( rep ); @@ -144,7 +152,6 @@ static char *passport_create_header( char *cookie, char *email, char *pwd ) return( buffer ); } -#define PPR_REQUEST "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n" static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header ) { struct passport_reply *rep = g_new0( struct passport_reply, 1 ); @@ -154,7 +161,7 @@ static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header rep->func = func; rep->header = header; - req = http_dorequest( "nexus.passport.com", 443, 1, PPR_REQUEST, passport_retrieve_dalogin_ready, rep ); + req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep ); if( !req ) destroy_reply( rep ); @@ -168,16 +175,26 @@ static void passport_retrieve_dalogin_ready( struct http_request *req ) char *dalogin; char *urlend; - if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers ) + if( !g_slist_find( msn_connections, rep->data ) ) { destroy_reply( rep ); return; } + if( !req->finished || !req->reply_headers || req->status_code != 200 ) + { + rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s", + req->status_string ? req->status_string : "Unknown error" ); + goto failure; + } + dalogin = strstr( req->reply_headers, "DALogin=" ); if( !dalogin ) + { + rep->error_string = g_strdup( "Parse error while fetching DALogin" ); goto failure; + } dalogin += strlen( "DALogin=" ); urlend = strchr( dalogin, ',' ); @@ -207,5 +224,6 @@ static void destroy_reply( struct passport_reply *rep ) { g_free( rep->result ); g_free( rep->header ); + g_free( rep->error_string ); g_free( rep ); } diff --git a/protocols/msn/passport.h b/protocols/msn/passport.h index f7e6ebb6..9fd81a82 100644 --- a/protocols/msn/passport.h +++ b/protocols/msn/passport.h @@ -38,6 +38,7 @@ struct passport_reply void *data; char *result; char *header; + char *error_string; }; int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ); diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 54e89043..63744cd0 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -528,14 +528,14 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) if( err->flags & STATUS_SB_FATAL ) { msn_sb_destroy( sb ); - return( 0 ); + return 0; } - if( err->flags & STATUS_FATAL ) + else if( err->flags & STATUS_FATAL ) { signoff( gc ); - return( 0 ); + return 0; } - if( err->flags & STATUS_SB_IM_SPARE ) + else if( err->flags & STATUS_SB_IM_SPARE ) { if( sb->who ) { @@ -558,6 +558,8 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) g_slist_free( sb->msgq ); sb->msgq = NULL; } + + /* Do NOT return 0 here, we want to keep this sb. */ } } else diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c index f8e98350..5ba9ea73 100644 --- a/protocols/msn/tables.c +++ b/protocols/msn/tables.c @@ -126,7 +126,7 @@ const struct msn_status_code msn_status_code_list[] = { 800, "Changing too rapidly", 0 }, { 910, "Server is busy", STATUS_FATAL }, - { 911, "Authentication failed", STATUS_FATAL }, + { 911, "Authentication failed", STATUS_SB_FATAL | STATUS_FATAL }, { 912, "Server is busy", STATUS_FATAL }, { 913, "Not allowed when hiding", 0 }, { 914, "Server is unavailable", STATUS_FATAL }, @@ -38,14 +38,6 @@ #include <ctype.h> #include <glib.h> #include <time.h> -#ifdef GLIB2 -#define iconv_t GIConv -#define iconv_open g_iconv_open -#define iconv_close g_iconv_close -#define iconv g_iconv -#else -#include <iconv.h> -#endif void strip_linefeed(gchar *text) { @@ -464,21 +456,21 @@ char *ipv6_unwrap( char *src ) */ signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf ) { - iconv_t cd; + GIConv cd; size_t res; size_t inbytesleft, outbytesleft; char *inbuf = src; char *outbuf = dst; - cd = iconv_open( to_cs, from_cs ); - if( cd == (iconv_t) -1 ) + cd = g_iconv_open( to_cs, from_cs ); + if( cd == (GIConv) -1 ) return( -1 ); inbytesleft = size ? size : strlen( src ); outbytesleft = maxbuf - 1; - res = iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); + res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); *outbuf = '\0'; - iconv_close( cd ); + g_iconv_close( cd ); if( res == (size_t) -1 ) return( -1 ); @@ -488,15 +480,15 @@ signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t si char *set_eval_charset( irc_t *irc, set_t *set, char *value ) { - iconv_t cd; + GIConv cd; if ( g_strncasecmp( value, "none", 4 ) == 0 ) return( value ); - cd = iconv_open( "UTF-8", value ); - if( cd == (iconv_t) -1 ) + cd = g_iconv_open( "UTF-8", value ); + if( cd == (GIConv) -1 ) return( NULL ); - iconv_close( cd ); + g_iconv_close( cd ); return( value ); } |