| 96 if(!jb) |
96 if(!jb) |
| 97 return NULL; |
97 return NULL; |
| 98 |
98 |
| 99 for(l = jb->resources; l; l = l->next) |
99 for(l = jb->resources; l; l = l->next) |
| 100 { |
100 { |
| 101 if(!jbr && !resource) { |
101 JabberBuddyResource *tmp = (JabberBuddyResource *) l->data; |
| 102 jbr = l->data; |
102 if (!jbr && !resource) { |
| 103 } else if(!resource) { |
103 jbr = tmp; |
| 104 if(((JabberBuddyResource *)l->data)->priority > jbr->priority) |
104 } else if (!resource) { |
| 105 jbr = l->data; |
105 if (tmp->priority > jbr->priority) |
| 106 else if(((JabberBuddyResource *)l->data)->priority == jbr->priority) { |
106 jbr = tmp; |
| |
107 else if (tmp->priority == jbr->priority) { |
| 107 /* Determine if this resource is more available than the one we've currently chosen */ |
108 /* Determine if this resource is more available than the one we've currently chosen */ |
| 108 switch(((JabberBuddyResource *)l->data)->state) { |
109 switch(tmp->state) { |
| 109 case JABBER_BUDDY_STATE_ONLINE: |
110 case JABBER_BUDDY_STATE_ONLINE: |
| 110 case JABBER_BUDDY_STATE_CHAT: |
111 case JABBER_BUDDY_STATE_CHAT: |
| 111 /* This resource is online/chatty. Prefer to one which isn't either. */ |
112 /* This resource is online/chatty. Prefer to one which isn't either. */ |
| 112 if ((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT)) |
113 if (((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT)) |
| 113 jbr = l->data; |
114 || (jbr->idle && !tmp->idle) |
| |
115 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) |
| |
116 jbr = tmp; |
| 114 break; |
117 break; |
| 115 case JABBER_BUDDY_STATE_AWAY: |
118 case JABBER_BUDDY_STATE_AWAY: |
| 116 case JABBER_BUDDY_STATE_DND: |
119 case JABBER_BUDDY_STATE_DND: |
| 117 /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */ |
120 /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */ |
| 118 if ((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || |
121 if (((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || |
| 119 (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
122 (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 120 jbr = l->data; |
123 || (jbr->idle && !tmp->idle) |
| |
124 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) |
| |
125 jbr = tmp; |
| 121 break; |
126 break; |
| 122 case JABBER_BUDDY_STATE_XA: |
127 case JABBER_BUDDY_STATE_XA: |
| 123 /* This resource is extended away. That's better than unavailable or unknown. */ |
128 /* This resource is extended away. That's better than unavailable or unknown. */ |
| 124 if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
129 if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 125 jbr = l->data; |
130 jbr = tmp; |
| 126 break; |
131 break; |
| 127 case JABBER_BUDDY_STATE_UNAVAILABLE: |
132 case JABBER_BUDDY_STATE_UNAVAILABLE: |
| 128 /* This resource is unavailable. That's better than unknown. */ |
133 /* This resource is unavailable. That's better than unknown. */ |
| 129 if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
134 if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) |
| 130 jbr = l->data; |
135 jbr = tmp; |
| 131 break; |
136 break; |
| 132 case JABBER_BUDDY_STATE_UNKNOWN: |
137 case JABBER_BUDDY_STATE_UNKNOWN: |
| 133 case JABBER_BUDDY_STATE_ERROR: |
138 case JABBER_BUDDY_STATE_ERROR: |
| 134 /* These are never preferable. */ |
139 /* These are never preferable. */ |
| 135 break; |
140 break; |
| 136 } |
141 } |
| 137 } |
142 } |
| 138 } else if(((JabberBuddyResource *)l->data)->name) { |
143 } else if(tmp->name) { |
| 139 if(!strcmp(((JabberBuddyResource *)l->data)->name, resource)) { |
144 if(!strcmp(tmp->name, resource)) { |
| 140 jbr = l->data; |
145 jbr = tmp; |
| 141 break; |
146 break; |
| 142 } |
147 } |
| 143 } |
148 } |
| 144 } |
149 } |
| 145 |
150 |
| 1636 if((query = xmlnode_get_child(packet, "query"))) { |
1641 if((query = xmlnode_get_child(packet, "query"))) { |
| 1637 seconds = xmlnode_get_attrib(query, "seconds"); |
1642 seconds = xmlnode_get_attrib(query, "seconds"); |
| 1638 if(seconds) { |
1643 if(seconds) { |
| 1639 char *end = NULL; |
1644 char *end = NULL; |
| 1640 long sec = strtol(seconds, &end, 10); |
1645 long sec = strtol(seconds, &end, 10); |
| 1641 if(end != seconds) { |
1646 JabberBuddy *jb = NULL; |
| |
1647 char *resource = NULL; |
| |
1648 char *buddy_name = NULL; |
| |
1649 JabberBuddyResource *jbr = NULL; |
| |
1650 |
| |
1651 if(end != seconds) { |
| 1642 JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); |
1652 JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); |
| 1643 if(jbir) { |
1653 if(jbir) { |
| 1644 jbir->idle_seconds = sec; |
1654 jbir->idle_seconds = sec; |
| 1645 } |
1655 } |
| 1646 } |
1656 } |
| |
1657 /* Update the idle time of the buddy resource, if we got it. |
| |
1658 This will correct the value when a server doesn't mark |
| |
1659 delayed presence and we got the presence when signing on */ |
| |
1660 jb = jabber_buddy_find(js, from, FALSE); |
| |
1661 if (jb) { |
| |
1662 resource = jabber_get_resource(from); |
| |
1663 buddy_name = jabber_get_bare_jid(from); |
| |
1664 /* if the resource already has an idle time set, we |
| |
1665 must have gotten it originally from a presence. In |
| |
1666 this case we update it. Otherwise don't update it, to |
| |
1667 avoid setting an idle and not getting informed about |
| |
1668 the resource getting unidle */ |
| |
1669 if (resource && buddy_name) { |
| |
1670 jbr = jabber_buddy_find_resource(jb, resource); |
| |
1671 |
| |
1672 if (jbr->idle) { |
| |
1673 if (sec) { |
| |
1674 jbr->idle = time(NULL) - sec; |
| |
1675 } else { |
| |
1676 jbr->idle = 0; |
| |
1677 } |
| |
1678 |
| |
1679 if (jbr == |
| |
1680 jabber_buddy_find_resource(jb, NULL)) { |
| |
1681 purple_prpl_got_user_idle(js->gc->account, |
| |
1682 buddy_name, jbr->idle, jbr->idle); |
| |
1683 } |
| |
1684 } |
| |
1685 } |
| |
1686 g_free(resource); |
| |
1687 g_free(buddy_name); |
| |
1688 } |
| 1647 } |
1689 } |
| 1648 } |
1690 } |
| 1649 } |
1691 } |
| 1650 g_free(resource_name); |
1692 g_free(resource_name); |
| 1651 } |
1693 } |