From 3e1ef92cecad385c64c2398355d90225ac54440c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 9 Mar 2010 13:13:50 +0000 Subject: Fixed a compiler warning for an ugliness that fortunately shouldn't have caused any issues except with broken protocol modules. --- protocols/nogaim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 3d2cff5c..603905ab 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -1072,7 +1072,7 @@ static char *imc_away_state_find( GList *gcm, char *away, char **message ); int imc_away_send_update( struct im_connection *ic ) { - char *away, *msg; + char *away, *msg = NULL; away = set_getstr( &ic->acc->set, "away" ) ? : set_getstr( &ic->irc->set, "away" ); -- cgit v1.2.3 From 75ec2c8398afde059e3a2403ca8907229d3720de Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 10 Mar 2010 23:58:47 +0000 Subject: Fixed an "off-by -1" bug in msn_findheader() that could probably be triggered by incoming messages without headers. --- protocols/msn/msn_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index 6b12217b..668a8b8a 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -170,9 +170,9 @@ char *msn_findheader( char *text, char *header, int len ) while( i < len && ( text[i] == '\r' || text[i] == '\n' ) ) i ++; /* End of headers? */ - if( strncmp( text + i - 2, "\n\n", 2 ) == 0 || - strncmp( text + i - 4, "\r\n\r\n", 4 ) == 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; } -- cgit v1.2.3 From 547c94cf6b3654997ef2570d398468af75380b26 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 12 Mar 2010 22:32:55 +0000 Subject: Merging in some code from libyahoo2-trunk that deals better with (initial) status updates and cleans up some stale stuff. --- protocols/yahoo/libyahoo2.c | 340 +++++++++++++++++++------------------------- 1 file changed, 146 insertions(+), 194 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 721f4b7c..f043baf5 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -854,55 +854,6 @@ static int is_same_bud(const void * a, const void * b) { return strcmp(subject->id, object->id); } -static YList * bud_str2list(char *rawlist) -{ - YList * l = NULL; - - char **lines; - char **split; - char **buddies; - char **tmp, **bud; - - lines = y_strsplit(rawlist, "\n", -1); - for (tmp = lines; *tmp; tmp++) { - struct yahoo_buddy *newbud; - - split = y_strsplit(*tmp, ":", 2); - if (!split) - continue; - if (!split[0] || !split[1]) { - y_strfreev(split); - continue; - } - buddies = y_strsplit(split[1], ",", -1); - - for (bud = buddies; bud && *bud; bud++) { - newbud = y_new0(struct yahoo_buddy, 1); - newbud->id = strdup(*bud); - newbud->group = strdup(split[0]); - - if(y_list_find_custom(l, newbud, is_same_bud)) { - FREE(newbud->id); - FREE(newbud->group); - FREE(newbud); - continue; - } - - newbud->real_name = NULL; - - l = y_list_append(l, newbud); - - NOTICE(("Added buddy %s to group %s", newbud->id, newbud->group)); - } - - y_strfreev(buddies); - y_strfreev(split); - } - y_strfreev(lines); - - return l; -} - static char * getcookie(char *rawcookie) { char * cookie=NULL; @@ -1359,140 +1310,165 @@ static void yahoo_process_message(struct yahoo_input_data *yid, struct yahoo_pac y_list_free(messages); } - -static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_status(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { YList *l; struct yahoo_data *yd = yid->yd; - struct user - { - char *name; /* 7 name */ - int state; /* 10 state */ - int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ - int mobile; /* 60 mobile */ - char *msg; /* 19 custom status message */ - int away; /* 47 away (or invisible)*/ - int buddy_session; /* 11 state */ - int f17; /* 17 in chat? then what about flags? */ - int idle; /* 137 seconds idle */ - int f138; /* 138 state */ - char *f184; /* 184 state */ - int f192; /* 192 state */ - int f10001; /* 10001 state */ - int f10002; /* 10002 state */ - int f198; /* 198 state */ - char *f197; /* 197 state */ - char *f205; /* 205 state */ - int f213; /* 213 state */ + struct user { + char *name; /* 7 name */ + int state; /* 10 state */ + int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ + int mobile; /* 60 mobile */ + char *msg; /* 19 custom status message */ + int away; /* 47 away (or invisible) */ + int buddy_session; /* 11 state */ + int f17; /* 17 in chat? then what about flags? */ + int idle; /* 137 seconds idle */ + int f138; /* 138 state */ + char *f184; /* 184 state */ + int f192; /* 192 state */ + int f10001; /* 10001 state */ + int f10002; /* 10002 state */ + int f198; /* 198 state */ + char *f197; /* 197 state */ + char *f205; /* 205 state */ + int f213; /* 213 state */ } *u; YList *users = 0; - + if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_DUPL, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_DUPL, NULL); return; } + u = NULL; + for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; switch (pair->key) { - case 0: /* we won't actually do anything with this */ + case 300: /* Begin buddy */ + if (!strcmp(pair->value, "315") && !u) { + u = y_new0(struct user, 1); + } + break; + case 301: /* End buddy */ + if (!strcmp(pair->value, "315") && u) { + users = y_list_prepend(users, u); + u = NULL; + } + break; + case 0: /* we won't actually do anything with this */ NOTICE(("key %d:%s", pair->key, pair->value)); break; - case 1: /* we don't get the full buddy list here. */ + case 1: /* we don't get the full buddy list here. */ if (!yd->logged_in) { - yd->logged_in = TRUE; - if(yd->current_status < 0) + yd->logged_in = 1; + if (yd->current_status < 0) yd->current_status = yd->initial_status; - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd-> + client_id, YAHOO_LOGIN_OK, NULL); } break; - case 8: /* how many online buddies we have */ + case 8: /* how many online buddies we have */ NOTICE(("key %d:%s", pair->key, pair->value)); break; - case 7: /* the current buddy */ - u = y_new0(struct user, 1); + case 7: /* the current buddy */ + if (!u) { + /* This will only happen in case of a single level message */ + u = y_new0(struct user, 1); + users = y_list_prepend(users, u); + } u->name = pair->value; - users = y_list_prepend(users, u); break; - case 10: /* state */ - ((struct user*)users->data)->state = strtol(pair->value, NULL, 10); + case 10: /* state */ + u->state = strtol(pair->value, NULL, 10); break; - case 19: /* custom status message */ - ((struct user*)users->data)->msg = pair->value; + case 19: /* custom status message */ + u->msg = pair->value; break; - case 47: /* is it an away message or not */ - ((struct user*)users->data)->away = atoi(pair->value); + case 47: /* is it an away message or not. Not applicable for YMSG16 anymore */ + u->away = atoi(pair->value); break; - case 137: /* seconds idle */ - ((struct user*)users->data)->idle = atoi(pair->value); + case 137: /* seconds idle */ + u->idle = atoi(pair->value); break; - case 11: /* this is the buddy's session id */ - ((struct user*)users->data)->buddy_session = atoi(pair->value); + case 11: /* this is the buddy's session id */ + u->buddy_session = atoi(pair->value); break; - case 17: /* in chat? */ - ((struct user*)users->data)->f17 = atoi(pair->value); + case 17: /* in chat? */ + u->f17 = atoi(pair->value); break; - case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ - ((struct user*)users->data)->flags = atoi(pair->value); + case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ + u->flags = atoi(pair->value); break; - case 60: /* SMS -> 1 MOBILE USER */ + case 60: /* SMS -> 1 MOBILE USER */ /* sometimes going offline makes this 2, but invisible never sends it */ - ((struct user*)users->data)->mobile = atoi(pair->value); + u->mobile = atoi(pair->value); break; case 138: - ((struct user*)users->data)->f138 = atoi(pair->value); + u->f138 = atoi(pair->value); break; case 184: - ((struct user*)users->data)->f184 = pair->value; + u->f184 = pair->value; break; case 192: - ((struct user*)users->data)->f192 = atoi(pair->value); + u->f192 = atoi(pair->value); break; case 10001: - ((struct user*)users->data)->f10001 = atoi(pair->value); + u->f10001 = atoi(pair->value); break; case 10002: - ((struct user*)users->data)->f10002 = atoi(pair->value); + u->f10002 = atoi(pair->value); break; case 198: - ((struct user*)users->data)->f198 = atoi(pair->value); + u->f198 = atoi(pair->value); break; case 197: - ((struct user*)users->data)->f197 = pair->value; + u->f197 = pair->value; break; case 205: - ((struct user*)users->data)->f205 = pair->value; + u->f205 = pair->value; break; case 213: - ((struct user*)users->data)->f213 = atoi(pair->value); + u->f213 = atoi(pair->value); break; - case 16: /* Custom error message */ - YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, pair->value, 0, E_CUSTOM); + case 16: /* Custom error message */ + YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, + pair->value, 0, E_CUSTOM); break; default: - WARNING(("unknown status key %d:%s", pair->key, pair->value)); + WARNING(("unknown status key %d:%s", pair->key, + pair->value)); break; } } - + while (users) { YList *t = users; struct user *u = users->data; if (u->name != NULL) { - if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */ - YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); + if (pkt->service == + YAHOO_SERVICE_LOGOFF + /*|| u->flags == 0 No flags for YMSG16 */ ) { + YAHOO_CALLBACK(ext_yahoo_status_changed) (yd-> + client_id, u->name, + YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); } else { /* Key 47 always seems to be 1 for YMSG16 */ - if(!u->state) + if (!u->state) u->away = 0; else u->away = 1; - YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile); + YAHOO_CALLBACK(ext_yahoo_status_changed) (yd-> + client_id, u->name, u->state, u->msg, + u->away, u->idle, u->mobile); } } @@ -1502,7 +1478,8 @@ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_pack } } -static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_buddy_list(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; YList *l; @@ -1514,34 +1491,29 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; - switch(pair->key) { + switch (pair->key) { case 300: case 301: case 302: + break; /* Separators. Our logic does not need them */ case 303: - if ( 315 == atoi(pair->value) ) + if (318 == atoi(pair->value)) last_packet = 1; break; case 65: - g_free(cur_group); cur_group = strdup(pair->value); break; case 7: newbud = y_new0(struct yahoo_buddy, 1); newbud->id = strdup(pair->value); - if (cur_group) { + if (cur_group) newbud->group = strdup(cur_group); - } else { - YList *last; - struct yahoo_buddy *lastbud; - - for (last = yd->buddies; last && last->next; last = last->next); - if (last) { - lastbud = last->data; - newbud->group = strdup(lastbud->group); - } else { - newbud->group = strdup("Buddies"); - } + else { + struct yahoo_buddy *lastbud = + (struct yahoo_buddy *)y_list_nth(yd-> + buddies, + y_list_length(yd->buddies) - 1)->data; + newbud->group = strdup(lastbud->group); } yd->buddies = y_list_append(yd->buddies, newbud); @@ -1549,106 +1521,86 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ break; } } - - g_free(cur_group); /* we could be getting multiple packets here */ - if (last_packet) + if (pkt->hash && !last_packet) return; - YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); + YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, yd->buddies); - /*** We login at the very end of the packet communication */ + /* Logged in */ if (!yd->logged_in) { - yd->logged_in = TRUE; - if(yd->current_status < 0) + yd->logged_in = 1; + if (yd->current_status < 0) yd->current_status = yd->initial_status; - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_OK, NULL); + + /* + yahoo_set_away(yd->client_id, yd->initial_status, NULL, + (yd->initial_status == YAHOO_STATUS_AVAILABLE) ? 0 : 1); + + yahoo_get_yab(yd->client_id); + */ } + } -static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_list(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; YList *l; - if (!yd->logged_in) { - yd->logged_in = TRUE; - if(yd->current_status < 0) - yd->current_status = yd->initial_status; - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); - } - + /* we could be getting multiple packets here */ for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; - switch(pair->key) { - case 87: /* buddies */ - if(!yd->rawbuddylist) - yd->rawbuddylist = strdup(pair->value); - else { - yd->rawbuddylist = y_string_append(yd->rawbuddylist, pair->value); - } - break; - - case 88: /* ignore list */ - if(!yd->ignorelist) - yd->ignorelist = strdup("Ignore:"); - yd->ignorelist = y_string_append(yd->ignorelist, pair->value); - break; - - case 89: /* identities */ + switch (pair->key) { + case 89: /* identities */ { - char **identities = y_strsplit(pair->value, ",", -1); - int i; - for(i=0; identities[i]; i++) - yd->identities = y_list_append(yd->identities, + char **identities = + y_strsplit(pair->value, ",", -1); + int i; + for (i = 0; identities[i]; i++) + yd->identities = + y_list_append(yd->identities, strdup(identities[i])); - y_strfreev(identities); + y_strfreev(identities); } - YAHOO_CALLBACK(ext_yahoo_got_identities)(yd->client_id, yd->identities); + YAHOO_CALLBACK(ext_yahoo_got_identities) (yd->client_id, + yd->identities); break; - case 59: /* cookies */ - if(yd->ignorelist) { - yd->ignore = bud_str2list(yd->ignorelist); - FREE(yd->ignorelist); - YAHOO_CALLBACK(ext_yahoo_got_ignore)(yd->client_id, yd->ignore); - } - if(yd->rawbuddylist) { - yd->buddies = bud_str2list(yd->rawbuddylist); - FREE(yd->rawbuddylist); - YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); - } - - if(pair->value[0]=='Y') { + case 59: /* cookies */ + if (pair->value[0] == 'Y') { FREE(yd->cookie_y); FREE(yd->login_cookie); yd->cookie_y = getcookie(pair->value); yd->login_cookie = getlcookie(yd->cookie_y); - } else if(pair->value[0]=='T') { + } else if (pair->value[0] == 'T') { FREE(yd->cookie_t); yd->cookie_t = getcookie(pair->value); - } else if(pair->value[0]=='C') { + } else if (pair->value[0] == 'C') { FREE(yd->cookie_c); yd->cookie_c = getcookie(pair->value); - } - - if(yd->cookie_y && yd->cookie_t) - YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); + } break; - case 3: /* my id */ - case 90: /* 1 */ - case 100: /* 0 */ - case 101: /* NULL */ - case 102: /* NULL */ - case 93: /* 86400/1440 */ + case 3: /* my id */ + case 90: /* 1 */ + case 100: /* 0 */ + case 101: /* NULL */ + case 102: /* NULL */ + case 93: /* 86400/1440 */ break; } } + + if (yd->cookie_y && yd->cookie_t) /* We don't get cookie_c anymore */ + YAHOO_CALLBACK(ext_yahoo_got_cookies) (yd->client_id); } static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_packet *pkt) -- cgit v1.2.3 From 70533795ac441b82e40b0cf4b8709994be7ac5ce Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 12 Mar 2010 23:02:29 +0000 Subject: Yahoo! status updates (at least initial ones, I assume) can be too long to fit into one packet. Yahoo! servers will split them up, and not necessarily on buddy boundaries. Trying to handle this a little bit better now. (Sadly I can't test this myself, I can only see this causing troubles on testing sometimes.) --- protocols/yahoo/libyahoo2.c | 35 ++++++++++------------------------- protocols/yahoo/yahoo2_types.h | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 25 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index f043baf5..57c32e2d 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -1316,26 +1316,7 @@ static void yahoo_process_status(struct yahoo_input_data *yid, YList *l; struct yahoo_data *yd = yid->yd; - struct user { - char *name; /* 7 name */ - int state; /* 10 state */ - int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ - int mobile; /* 60 mobile */ - char *msg; /* 19 custom status message */ - int away; /* 47 away (or invisible) */ - int buddy_session; /* 11 state */ - int f17; /* 17 in chat? then what about flags? */ - int idle; /* 137 seconds idle */ - int f138; /* 138 state */ - char *f184; /* 184 state */ - int f192; /* 192 state */ - int f10001; /* 10001 state */ - int f10002; /* 10002 state */ - int f198; /* 198 state */ - char *f197; /* 197 state */ - char *f205; /* 205 state */ - int f213; /* 213 state */ - } *u; + struct yahoo_process_status_entry *u; YList *users = 0; @@ -1345,7 +1326,11 @@ static void yahoo_process_status(struct yahoo_input_data *yid, return; } - u = NULL; + /* Status updates may be spread accross multiple packets and not + even on buddy boundaries, so keeping some state is important. + So, continue where we left off, and only add a user entry to + the list once it's complete (301-315 End buddy). */ + u = yd->half_user; for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; @@ -1353,13 +1338,13 @@ static void yahoo_process_status(struct yahoo_input_data *yid, switch (pair->key) { case 300: /* Begin buddy */ if (!strcmp(pair->value, "315") && !u) { - u = y_new0(struct user, 1); + u = yd->half_user = y_new0(struct yahoo_process_status_entry, 1); } break; case 301: /* End buddy */ if (!strcmp(pair->value, "315") && u) { users = y_list_prepend(users, u); - u = NULL; + u = yd->half_user = NULL; } break; case 0: /* we won't actually do anything with this */ @@ -1380,7 +1365,7 @@ static void yahoo_process_status(struct yahoo_input_data *yid, case 7: /* the current buddy */ if (!u) { /* This will only happen in case of a single level message */ - u = y_new0(struct user, 1); + u = y_new0(struct yahoo_process_status_entry, 1); users = y_list_prepend(users, u); } u->name = pair->value; @@ -1450,7 +1435,7 @@ static void yahoo_process_status(struct yahoo_input_data *yid, while (users) { YList *t = users; - struct user *u = users->data; + struct yahoo_process_status_entry *u = users->data; if (u->name != NULL) { if (pkt->service == diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index 3507e13a..f05acb3c 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -195,6 +195,8 @@ struct yahoo_data { char *ignorelist; void *server_settings; + + struct yahoo_process_status_entry *half_user; }; struct yab { @@ -260,6 +262,27 @@ struct yahoo_chat_member { char *location; }; +struct yahoo_process_status_entry { + char *name; /* 7 name */ + int state; /* 10 state */ + int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ + int mobile; /* 60 mobile */ + char *msg; /* 19 custom status message */ + int away; /* 47 away (or invisible) */ + int buddy_session; /* 11 state */ + int f17; /* 17 in chat? then what about flags? */ + int idle; /* 137 seconds idle */ + int f138; /* 138 state */ + char *f184; /* 184 state */ + int f192; /* 192 state */ + int f10001; /* 10001 state */ + int f10002; /* 10002 state */ + int f198; /* 198 state */ + char *f197; /* 197 state */ + char *f205; /* 205 state */ + int f213; /* 213 state */ +}; + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 1be0d260da62542dd27b8a6f5d367a2e79191a8d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 13 Mar 2010 00:12:07 +0000 Subject: Fixed handling of contact lists where at least the first contact is not in any group yet. Crashing is not the right solution. --- protocols/yahoo/libyahoo2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 57c32e2d..5b2ff44e 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -1493,13 +1493,14 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, newbud->id = strdup(pair->value); if (cur_group) newbud->group = strdup(cur_group); - else { + else if (yd->buddies) { struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth(yd-> buddies, y_list_length(yd->buddies) - 1)->data; newbud->group = strdup(lastbud->group); - } + } else + newbud->group = strdup("Buddies"); yd->buddies = y_list_append(yd->buddies, newbud); -- cgit v1.2.3 From 286b28eabf39d98d642c73c34a16a599e61dfc99 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 13 Mar 2010 01:02:47 +0000 Subject: Added nick_source account setting to allow using full name fields for generating nicknames instead of just the handle. --- protocols/nogaim.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 603905ab..6ee89e29 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -447,6 +447,7 @@ struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ) void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ) { user_t *u = user_findhandle( ic, handle ); + char *set; if( !u || !realname ) return; @@ -459,6 +460,23 @@ void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ) if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) ) imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname ); } + + set = set_getstr( &ic->acc->set, "nick_source" ); + if( strcmp( set, "handle" ) != 0 ) + { + char *name = g_strdup( realname ); + + if( strcmp( set, "first_name" ) == 0 ) + { + int i; + for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {} + name[i] = '\0'; + } + + imcb_buddy_nick_hint( ic, handle, name ); + + g_free( name ); + } } void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group ) -- cgit v1.2.3 From af7f046b85694db45d670054e28960e4a0d79232 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Mar 2010 16:56:00 +0000 Subject: Don't send a stream start after starttls since it upsets certain jabberd's including Zimbra's. Thanks to jMCg and balzar in #bitlbee for helping with figuring this out. --- protocols/jabber/io.c | 8 +++++--- protocols/jabber/jabber.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 10efad37..9534ff1a 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -440,6 +440,7 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) imcb_log( ic, "Converting stream to TLS" ); + jd->flags |= JFLAG_STARTTLS_DONE; jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, ic ); return XT_HANDLED; @@ -530,9 +531,10 @@ gboolean jabber_start_stream( struct im_connection *ic ) if( jd->r_inpa <= 0 ) jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, ic ); - greet = g_strdup_printf( "" - "", jd->server ); + greet = g_strdup_printf( "%s", + ( jd->flags & JFLAG_STARTTLS_DONE ) ? "" : "", + jd->server ); st = jabber_write( ic, greet, strlen( greet ) ); diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 7bb66e0e..a6cceb5a 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -45,6 +45,7 @@ typedef enum JFLAG_WANT_TYPING = 32, /* Set if we ever sent a typing notification, this activates all XEP-85 related code. */ JFLAG_XMLCONSOLE = 64, /* If the user added an xmlconsole buddy. */ + JFLAG_STARTTLS_DONE = 128, /* If a plaintext session was converted to TLS. */ } jabber_flags_t; typedef enum -- cgit v1.2.3 From 8fb1263325c6839b792c352283abac3f63142fa2 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Mar 2010 17:45:33 +0000 Subject: Don't send bind and session requests at the same time when logging in because some very picky jabberd's don't like it. (Fixes Bug #569) --- protocols/jabber/io.c | 30 +++++++----------------------- protocols/jabber/iq.c | 31 +++++++++++++++++++++++++------ protocols/jabber/jabber.h | 4 ++-- 3 files changed, 34 insertions(+), 31 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 9534ff1a..4a790f27 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -374,39 +374,23 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) } if( ( c = xt_find_node( node->children, "bind" ) ) ) - { - reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) ); - xt_add_attr( reply, "xmlns", XMLNS_BIND ); - reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); - - if( !jabber_write_packet( ic, reply ) ) - return XT_ABORT; - - jd->flags |= JFLAG_WAIT_BIND; - } + jd->flags |= JFLAG_WANT_BIND; if( ( c = xt_find_node( node->children, "session" ) ) ) - { - reply = xt_new_node( "session", NULL, NULL ); - xt_add_attr( reply, "xmlns", XMLNS_SESSION ); - reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); - - if( !jabber_write_packet( ic, reply ) ) - return XT_ABORT; - - jd->flags |= JFLAG_WAIT_SESSION; - } + jd->flags |= JFLAG_WANT_SESSION; /* This flag is already set if we authenticated via SASL, so now we can resume the session in the new stream, if we don't have to bind/initialize the session. */ - if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) + if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 ) { if( !jabber_get_roster( ic ) ) return XT_ABORT; } + else if( jd->flags & JFLAG_AUTHENTICATED ) + { + return jabber_pkt_bind_sess( ic, NULL, NULL ); + } return XT_HANDLED; } diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 875b5c81..21e52da6 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -297,24 +297,43 @@ static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { struct jabber_data *jd = ic->proto_data; - struct xt_node *c; + struct xt_node *c, *reply = NULL; char *s; - if( ( c = xt_find_node( node->children, "bind" ) ) ) + if( node && ( c = xt_find_node( node->children, "bind" ) ) ) { c = xt_find_node( c->children, "jid" ); if( c && c->text_len && ( s = strchr( c->text, '/' ) ) && strcmp( s + 1, set_getstr( &ic->acc->set, "resource" ) ) != 0 ) imcb_log( ic, "Server changed session resource string to `%s'", s + 1 ); - jd->flags &= ~JFLAG_WAIT_BIND; + jd->flags &= ~JFLAG_WANT_BIND; } - else + else if( node && ( c = xt_find_node( node->children, "session" ) ) ) + { + jd->flags &= ~JFLAG_WANT_SESSION; + } + + if( jd->flags & JFLAG_WANT_BIND ) { - jd->flags &= ~JFLAG_WAIT_SESSION; + reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) ); + xt_add_attr( reply, "xmlns", XMLNS_BIND ); + } + else if( jd->flags & JFLAG_WANT_SESSION ) + { + reply = xt_new_node( "session", NULL, NULL ); + xt_add_attr( reply, "xmlns", XMLNS_SESSION ); } - if( ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) + if( reply != NULL ) + { + reply = jabber_make_packet( "iq", "set", NULL, reply ); + jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); + + if( !jabber_write_packet( ic, reply ) ) + return XT_ABORT; + } + else if( ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 ) { if( !jabber_get_roster( ic ) ) return XT_ABORT; diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index a6cceb5a..8e3bf036 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -39,9 +39,9 @@ typedef enum JFLAG_AUTHENTICATED = 2, /* Set when we're successfully authenticatd. */ JFLAG_STREAM_RESTART = 4, /* Set when we want to restart the stream (after SASL or TLS). */ - JFLAG_WAIT_SESSION = 8, /* Set if we sent a tag and need a reply + JFLAG_WANT_SESSION = 8, /* Set if the server wants a tag before we continue. */ - JFLAG_WAIT_BIND = 16, /* ... for tag. */ + JFLAG_WANT_BIND = 16, /* ... for tag. */ JFLAG_WANT_TYPING = 32, /* Set if we ever sent a typing notification, this activates all XEP-85 related code. */ JFLAG_XMLCONSOLE = 64, /* If the user added an xmlconsole buddy. */ -- cgit v1.2.3 From c6ca3ee33e27feefb8cae0dc1d55a7239baf43cb Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Mar 2010 17:49:24 +0000 Subject: Some const/etc cleanups submitted by domen@coderock.org back in bug #431. --- protocols/jabber/jabber.h | 1 + protocols/msn/msn.c | 4 ++++ protocols/msn/msn.h | 6 +++--- protocols/nogaim.c | 16 ++++++++-------- protocols/nogaim.h | 17 ++++++++--------- 5 files changed, 24 insertions(+), 20 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 904bf0c4..61238a30 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -28,6 +28,7 @@ #include "xmltree.h" #include "bitlbee.h" +#include "md5.h" extern GSList *jabber_connections; diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index a2e8519a..09670dfa 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -26,6 +26,10 @@ #include "nogaim.h" #include "msn.h" +int msn_chat_id; +GSList *msn_connections; +GSList *msn_switchboards; + static char *msn_set_display_name( set_t *set, char *value ); static void msn_init( account_t *acc ) diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 63759303..16e5ab52 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -132,7 +132,7 @@ struct msn_handler_data #define STATUS_SB_IM_SPARE 4 /* Make one-to-one conversation switchboard available again, invite failed. */ #define STATUS_SB_CHAT_SPARE 8 /* Same, but also for groupchats (not used yet). */ -int msn_chat_id; +extern int msn_chat_id; extern const struct msn_away_state msn_away_state_list[]; extern const struct msn_status_code msn_status_code_list[]; @@ -141,8 +141,8 @@ extern const struct msn_status_code msn_status_code_list[]; is down already (for example, when an impatient user disabled the connection), the callback should check whether it's still listed here before doing *anything* else. */ -GSList *msn_connections; -GSList *msn_switchboards; +extern GSList *msn_connections; +extern GSList *msn_switchboards; /* ns.c */ gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 7466e93a..62669aaf 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -351,7 +351,7 @@ void imcb_ask( struct im_connection *ic, char *msg, void *data, /* list.c */ -void imcb_add_buddy( struct im_connection *ic, char *handle, char *group ) +void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) { user_t *u; char nick[MAX_NICK_LENGTH+1], *s; @@ -425,7 +425,7 @@ struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ) return( b ); } -void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ) +void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname ) { user_t *u = user_findhandle( ic, handle ); @@ -442,7 +442,7 @@ void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ) } } -void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group ) +void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) { user_t *u; @@ -627,7 +627,7 @@ void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, } } -void imcb_buddy_msg( struct im_connection *ic, char *handle, char *msg, uint32_t flags, time_t sent_at ) +void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ) { irc_t *irc = ic->irc; char *wrapped; @@ -694,7 +694,7 @@ void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) } } -struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle ) +struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) { struct groupchat *c; @@ -760,7 +760,7 @@ void imcb_chat_free( struct groupchat *c ) } } -void imcb_chat_msg( struct groupchat *c, char *who, char *msg, uint32_t flags, time_t sent_at ) +void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ) { struct im_connection *ic = c->ic; char *wrapped; @@ -832,7 +832,7 @@ void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at /* buddy_chat.c */ -void imcb_chat_add_buddy( struct groupchat *b, char *handle ) +void imcb_chat_add_buddy( struct groupchat *b, const char *handle ) { user_t *u = user_findhandle( b->ic, handle ); int me = 0; @@ -867,7 +867,7 @@ void imcb_chat_add_buddy( struct groupchat *b, char *handle ) } /* This function is one BIG hack... :-( EREWRITE */ -void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason ) +void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ) { user_t *u; int me = 0; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 9fe843b5..ee5d7a30 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -42,7 +42,6 @@ #include "account.h" #include "proxy.h" #include "query.h" -#include "md5.h" #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ @@ -263,10 +262,10 @@ G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const /* This function should be called for each handle which are visible to the * user, usually after a login, or if the user added a buddy and the IM * server confirms that the add was successful. Don't forget to do this! */ -G_MODULE_EXPORT void imcb_add_buddy( struct im_connection *ic, char *handle, char *group ); -G_MODULE_EXPORT void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group ); +G_MODULE_EXPORT void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ); +G_MODULE_EXPORT void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ); G_MODULE_EXPORT struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ); -G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ); +G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname ); G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick ); /* Buddy activity */ @@ -277,7 +276,7 @@ G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, char *handl G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ); /* Not implemented yet! */ G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle ); /* Call when a handle says something. 'flags' and 'sent_at may be just 0. */ -G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, char *handle, char *msg, uint32_t flags, time_t sent_at ); +G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ); G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ); G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle ); @@ -289,12 +288,12 @@ G_MODULE_EXPORT void imcb_chat_invited( struct im_connection *ic, char *handle, * - After you have a groupchat pointer, you should add the handles, finally * the user her/himself. At that point the group chat will be visible to the * user, too. */ -G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle ); -G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle ); +G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); +G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, const char *handle ); /* To remove a handle from a group chat. Reason can be NULL. */ -G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason ); +G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ); /* To tell BitlBee 'who' said 'msg' in 'c'. 'flags' and 'sent_at' can be 0. */ -G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, char *who, char *msg, uint32_t flags, time_t sent_at ); +G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ); /* System messages specific to a groupchat, so they can be displayed in the right context. */ G_MODULE_EXPORT void imcb_chat_log( struct groupchat *c, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); /* To tell BitlBee 'who' changed the topic of 'c' to 'topic'. */ -- cgit v1.2.3 From 90cd6c4780c7e42a0b7caff5d3a2ba1e0bd3f308 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Mar 2010 18:22:43 +0000 Subject: Allow disabling certain IM protocols at runtime, patch from misc@mandriva.org, bug #381. --- protocols/nogaim.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 75c2139b..9c6daeaf 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -97,7 +97,19 @@ GList *protocols = NULL; void register_protocol (struct prpl *p) { - protocols = g_list_append(protocols, p); + int i; + gboolean refused = global.conf->protocols != NULL; + + for (i = 0; global.conf->protocols && global.conf->protocols[i]; i++) + { + if (g_strcasecmp(p->name, global.conf->protocols[i]) == 0) + refused = FALSE; + } + + if (refused) + log_message(LOGLVL_WARNING, "Protocol %s disabled\n", p->name); + else + protocols = g_list_append(protocols, p); } struct prpl *find_protocol(const char *name) -- cgit v1.2.3 From 21d48d977b35d35d0ad86b3ccd051dae0d1fe055 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Mar 2010 20:19:10 +0000 Subject: Fix for bug #536: No longer fail on corrupted USR responses with certain Unicode characters in the friendly name. --- protocols/msn/ns.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index d05d8e0d..d78d753a 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -228,19 +228,26 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) return( 0 ); } } - else if( num_parts == 7 && strcmp( cmd[2], "OK" ) == 0 ) + else if( num_parts >= 7 && strcmp( cmd[2], "OK" ) == 0 ) { set_t *s; - http_decode( cmd[4] ); - - strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) ); - ic->displayname[sizeof(ic->displayname)-1] = 0; - - if( ( s = set_find( &ic->acc->set, "display_name" ) ) ) + if( num_parts == 7 ) { - g_free( s->value ); - s->value = g_strdup( cmd[4] ); + http_decode( cmd[4] ); + + strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) ); + ic->displayname[sizeof(ic->displayname)-1] = 0; + + if( ( s = set_find( &ic->acc->set, "display_name" ) ) ) + { + g_free( s->value ); + s->value = g_strdup( cmd[4] ); + } + } + else + { + imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); } imcb_log( ic, "Authenticated, getting buddy list" ); -- cgit v1.2.3