libpurple/protocols/jabber/roster.c

changeset 23975
8ee397f04ca9
parent 23961
0a9e9676f7b5
child 24199
8606cb4e94f5
equal deleted inserted replaced
23974:621f7b2123c9 23975:8ee397f04ca9
29 #include "roster.h" 29 #include "roster.h"
30 #include "iq.h" 30 #include "iq.h"
31 31
32 #include <string.h> 32 #include <string.h>
33 33
34 /*
35 * This boolean was added to eliminate a heinous bug where we would
36 * get into a loop with the server and move a buddy back and forth
37 * from one group to another.
38 *
39 * The sequence goes something like this:
40 * 1. Our resource and another resource both approve an authorization
41 * request at the exact same time. We put the buddy in group A and
42 * the other resource put the buddy in group B.
43 * 2. The server receives the roster add for group B and sends us a
44 * roster push.
45 * 3. We receive this roster push and modify our local blist. This
46 * triggers us to send a roster add for group B.
47 * 4. The server recieves our earlier roster add for group A and sends
48 * us a roster push.
49 * 5. We receive this roster push and modify our local blist. This
50 * triggers us to send a roster add for group A.
51 * 6. The server receives our earlier roster add for group B and sends
52 * us a roster push.
53 * (repeat steps 3 through 6 ad infinitum)
54 *
55 * This boolean is used to short-circuit the sending of a roster add
56 * when we receive a roster push.
57 *
58 * See these bug reports:
59 * http://trac.adiumx.com/ticket/8834
60 * http://developer.pidgin.im/ticket/5484
61 * http://developer.pidgin.im/ticket/6188
62 */
63 static gboolean parsing_from_server = FALSE;
64
65 void jabber_roster_request(JabberStream *js) 34 void jabber_roster_request(JabberStream *js)
66 { 35 {
67 JabberIq *iq; 36 JabberIq *iq;
68 37
69 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:roster"); 38 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:roster");
197 166
198 query = xmlnode_get_child(packet, "query"); 167 query = xmlnode_get_child(packet, "query");
199 if(!query) 168 if(!query)
200 return; 169 return;
201 170
202 parsing_from_server = TRUE; 171 js->currently_parsing_roster_push = TRUE;
203 172
204 for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item)) 173 for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item))
205 { 174 {
206 const char *jid, *name, *subscription, *ask; 175 const char *jid, *name, *subscription, *ask;
207 JabberBuddy *jb; 176 JabberBuddy *jb;
281 } 250 }
282 add_purple_buddies_to_groups(js, jid, name, groups); 251 add_purple_buddies_to_groups(js, jid, name, groups);
283 } 252 }
284 } 253 }
285 254
286 parsing_from_server = FALSE; 255 js->currently_parsing_roster_push = FALSE;
287 256
288 /* if we're just now parsing the roster for the first time, 257 /* if we're just now parsing the roster for the first time,
289 * then now would be the time to send our initial presence */ 258 * then now would be the time to send our initial presence */
290 if(!js->roster_parsed) { 259 if(!js->roster_parsed) {
291 js->roster_parsed = TRUE; 260 js->roster_parsed = TRUE;
301 PurpleGroup *g; 270 PurpleGroup *g;
302 GSList *groups = NULL, *l; 271 GSList *groups = NULL, *l;
303 JabberIq *iq; 272 JabberIq *iq;
304 xmlnode *query, *item, *group; 273 xmlnode *query, *item, *group;
305 274
306 if (parsing_from_server) 275 if (js->currently_parsing_roster_push)
307 return; 276 return;
308 277
309 if(!(b = purple_find_buddy(js->gc->account, name))) 278 if(!(b = purple_find_buddy(js->gc->account, name)))
310 return; 279 return;
311 280

mercurial