diff options
-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-- | protocols/oscar/im.c | 2 |
9 files changed, 115 insertions, 43 deletions
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 e181438c..c793d9d4 100644 --- a/protocols/http_client.c +++ b/protocols/http_client.c @@ -156,6 +156,8 @@ static void http_connected( gpointer data, int source, GaimInputCondition cond ) return; error: + req->status_string = g_strdup( "Error while writing HTTP request" ); + req->func( req ); g_free( req->request ); @@ -215,6 +217,7 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co { 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,5 +446,6 @@ cleanup: g_free( req->request ); g_free( req->reply_headers ); + g_free( req->status_string ); g_free( req ); } 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 90d525ef..523de0ae 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -649,8 +649,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 234be1d6..34b0a30a 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -522,14 +522,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 ) { @@ -552,6 +552,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 }, diff --git a/protocols/oscar/im.c b/protocols/oscar/im.c index c829d409..7cccabc7 100644 --- a/protocols/oscar/im.c +++ b/protocols/oscar/im.c @@ -1468,7 +1468,7 @@ static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod case AIM_MTYPE_AUTOFFC: case 0x9c: /* ICQ 5 seems to send this */ aim_send_im_ch2_statusmessage(sess, userinfo->sn, args->cookie, - gc->away, sess->aim_icq_state, dc); + gc->away ? gc->away : "", sess->aim_icq_state, dc); break; } |