| 95 if(!jb) |
95 if(!jb) |
| 96 return NULL; |
96 return NULL; |
| 97 |
97 |
| 98 for(l = jb->resources; l; l = l->next) |
98 for(l = jb->resources; l; l = l->next) |
| 99 { |
99 { |
| 100 if(!jbr && !resource) { |
100 JabberBuddyResource *tmp = (JabberBuddyResource *) l->data; |
| 101 jbr = l->data; |
101 if (!jbr && !resource) { |
| 102 } else if(!resource) { |
102 jbr = tmp; |
| 103 if(((JabberBuddyResource *)l->data)->priority > jbr->priority) |
103 } else if (!resource) { |
| 104 jbr = l->data; |
104 if (tmp->priority > jbr->priority) |
| 105 else if(((JabberBuddyResource *)l->data)->priority == jbr->priority) { |
105 jbr = tmp; |
| |
106 else if (tmp->priority == jbr->priority) { |
| 106 /* Determine if this resource is more available than the one we've currently chosen */ |
107 /* Determine if this resource is more available than the one we've currently chosen */ |
| 107 switch(((JabberBuddyResource *)l->data)->state) { |
108 switch(tmp->state) { |
| 108 case JABBER_BUDDY_STATE_ONLINE: |
109 case JABBER_BUDDY_STATE_ONLINE: |
| 109 case JABBER_BUDDY_STATE_CHAT: |
110 case JABBER_BUDDY_STATE_CHAT: |
| 110 /* This resource is online/chatty. Prefer to one which isn't either. */ |
111 /* This resource is online/chatty. Prefer to one which isn't either. */ |
| 111 if ((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT)) |
112 if (((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT)) |
| 112 jbr = l->data; |
113 || (jbr->idle && !tmp->idle) |
| |
114 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) |
| |
115 jbr = tmp; |
| 113 break; |
116 break; |
| 114 case JABBER_BUDDY_STATE_AWAY: |
117 case JABBER_BUDDY_STATE_AWAY: |
| 115 case JABBER_BUDDY_STATE_DND: |
118 case JABBER_BUDDY_STATE_DND: |
| 116 /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */ |
119 /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */ |
| 117 if ((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || |
120 if (((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || |
| 118 (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
121 (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 119 jbr = l->data; |
122 || (jbr->idle && !tmp->idle) |
| |
123 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) |
| |
124 jbr = tmp; |
| 120 break; |
125 break; |
| 121 case JABBER_BUDDY_STATE_XA: |
126 case JABBER_BUDDY_STATE_XA: |
| 122 /* This resource is extended away. That's better than unavailable or unknown. */ |
127 /* This resource is extended away. That's better than unavailable or unknown. */ |
| 123 if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
128 if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 124 jbr = l->data; |
129 jbr = tmp; |
| 125 break; |
130 break; |
| 126 case JABBER_BUDDY_STATE_UNAVAILABLE: |
131 case JABBER_BUDDY_STATE_UNAVAILABLE: |
| 127 /* This resource is unavailable. That's better than unknown. */ |
132 /* This resource is unavailable. That's better than unknown. */ |
| 128 if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
133 if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 129 jbr = l->data; |
134 jbr = tmp; |
| 130 break; |
135 break; |
| 131 case JABBER_BUDDY_STATE_UNKNOWN: |
136 case JABBER_BUDDY_STATE_UNKNOWN: |
| 132 case JABBER_BUDDY_STATE_ERROR: |
137 case JABBER_BUDDY_STATE_ERROR: |
| 133 /* These are never preferable. */ |
138 /* These are never preferable. */ |
| 134 break; |
139 break; |
| 135 } |
140 } |
| 136 } |
141 } |
| 137 } else if(((JabberBuddyResource *)l->data)->name) { |
142 } else if(tmp->name) { |
| 138 if(!strcmp(((JabberBuddyResource *)l->data)->name, resource)) { |
143 if(!strcmp(tmp->name, resource)) { |
| 139 jbr = l->data; |
144 jbr = tmp; |
| 140 break; |
145 break; |
| 141 } |
146 } |
| 142 } |
147 } |
| 143 } |
148 } |
| 144 |
149 |
| 1426 if((query = xmlnode_get_child(packet, "query"))) { |
1431 if((query = xmlnode_get_child(packet, "query"))) { |
| 1427 seconds = xmlnode_get_attrib(query, "seconds"); |
1432 seconds = xmlnode_get_attrib(query, "seconds"); |
| 1428 if(seconds) { |
1433 if(seconds) { |
| 1429 char *end = NULL; |
1434 char *end = NULL; |
| 1430 long sec = strtol(seconds, &end, 10); |
1435 long sec = strtol(seconds, &end, 10); |
| 1431 if(end != seconds) { |
1436 JabberBuddy *jb = NULL; |
| |
1437 char *resource = NULL; |
| |
1438 char *buddy_name = NULL; |
| |
1439 JabberBuddyResource *jbr = NULL; |
| |
1440 |
| |
1441 if(end != seconds) { |
| 1432 JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); |
1442 JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); |
| 1433 if(jbir) { |
1443 if(jbir) { |
| 1434 jbir->idle_seconds = sec; |
1444 jbir->idle_seconds = sec; |
| 1435 } |
1445 } |
| 1436 } |
1446 } |
| |
1447 /* Update the idle time of the buddy resource, if we got it. |
| |
1448 This will correct the value when a server doesn't mark |
| |
1449 delayed presence and we got the presence when signing on */ |
| |
1450 jb = jabber_buddy_find(js, from, FALSE); |
| |
1451 if (jb) { |
| |
1452 resource = jabber_get_resource(from); |
| |
1453 buddy_name = jabber_get_bare_jid(from); |
| |
1454 /* if the resource already has an idle time set, we |
| |
1455 must have gotten it originally from a presence. In |
| |
1456 this case we update it. Otherwise don't update it, to |
| |
1457 avoid setting an idle and not getting informed about |
| |
1458 the resource getting unidle */ |
| |
1459 if (resource && buddy_name) { |
| |
1460 jbr = jabber_buddy_find_resource(jb, resource); |
| |
1461 |
| |
1462 if (jbr->idle) { |
| |
1463 if (sec) { |
| |
1464 jbr->idle = time(NULL) - sec; |
| |
1465 } else { |
| |
1466 jbr->idle = 0; |
| |
1467 } |
| |
1468 |
| |
1469 if (jbr == |
| |
1470 jabber_buddy_find_resource(jb, NULL)) { |
| |
1471 purple_prpl_got_user_idle(js->gc->account, |
| |
1472 buddy_name, jbr->idle, jbr->idle); |
| |
1473 } |
| |
1474 } |
| |
1475 } |
| |
1476 g_free(resource); |
| |
1477 g_free(buddy_name); |
| |
1478 } |
| 1437 } |
1479 } |
| 1438 } |
1480 } |
| 1439 } |
1481 } |
| 1440 g_free(resource_name); |
1482 g_free(resource_name); |
| 1441 } |
1483 } |