| 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 |