Changeset 5ebff60 for protocols/jabber/presence.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/presence.c
raf359b4 r5ebff60 24 24 #include "jabber.h" 25 25 26 xt_status jabber_pkt_presence( struct xt_node *node, gpointer data)26 xt_status jabber_pkt_presence(struct xt_node *node, gpointer data) 27 27 { 28 28 struct im_connection *ic = data; 29 char *from = xt_find_attr( node, "from");30 char *type = xt_find_attr( node, "type" );/* NULL should mean the person is online. */29 char *from = xt_find_attr(node, "from"); 30 char *type = xt_find_attr(node, "type"); /* NULL should mean the person is online. */ 31 31 struct xt_node *c, *cap; 32 32 struct jabber_buddy *bud, *send_presence = NULL; 33 33 int is_chat = 0; 34 34 char *s; 35 36 if ( !from )35 36 if (!from) { 37 37 return XT_HANDLED; 38 39 if( ( s = strchr( from, '/' ) ) ) 40 {38 } 39 40 if ((s = strchr(from, '/'))) { 41 41 *s = 0; 42 if ( jabber_chat_by_jid( ic, from ) )42 if (jabber_chat_by_jid(ic, from)) { 43 43 is_chat = 1; 44 } 44 45 *s = '/'; 45 46 } 46 47 if( type == NULL ) 48 { 49 if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) ) 50 { 47 48 if (type == NULL) { 49 if (!(bud = jabber_buddy_by_jid(ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT))) { 51 50 /* 52 51 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); … … 54 53 return XT_HANDLED; 55 54 } 56 57 g_free( bud->away_message);58 if ( ( c = xt_find_node( node->children, "status" ) ) && c->text_len > 0 )59 bud->away_message = g_strdup( c->text);60 else55 56 g_free(bud->away_message); 57 if ((c = xt_find_node(node->children, "status")) && c->text_len > 0) { 58 bud->away_message = g_strdup(c->text); 59 } else { 61 60 bud->away_message = NULL; 62 63 if( ( c = xt_find_node( node->children, "show" ) ) && c->text_len > 0 ) 64 { 65 bud->away_state = (void*) jabber_away_state_by_code( c->text ); 66 } 67 else 68 { 61 } 62 63 if ((c = xt_find_node(node->children, "show")) && c->text_len > 0) { 64 bud->away_state = (void *) jabber_away_state_by_code(c->text); 65 } else { 69 66 bud->away_state = NULL; 70 67 } 71 72 if ( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )73 bud->priority = atoi( c->text);74 else68 69 if ((c = xt_find_node(node->children, "priority")) && c->text_len > 0) { 70 bud->priority = atoi(c->text); 71 } else { 75 72 bud->priority = 0; 76 77 if( bud && ( cap = xt_find_node( node->children, "c" ) ) && 78 ( s = xt_find_attr( cap, "xmlns" ) ) && strcmp( s, XMLNS_CAPS ) == 0 )79 {73 } 74 75 if (bud && (cap = xt_find_node(node->children, "c")) && 76 (s = xt_find_attr(cap, "xmlns")) && strcmp(s, XMLNS_CAPS) == 0) { 80 77 /* This <presence> stanza includes an XEP-0115 81 78 capabilities part. Not too interesting, but we can 82 79 see if it has an ext= attribute. */ 83 s = xt_find_attr( cap, "ext");84 if ( s && ( strstr( s, "cstates" ) || strstr( s, "chatstate" ) ) )80 s = xt_find_attr(cap, "ext"); 81 if (s && (strstr(s, "cstates") || strstr(s, "chatstate"))) { 85 82 bud->flags |= JBFLAG_DOES_XEP85; 86 83 } 84 87 85 /* This field can contain more information like xhtml 88 86 support, but we don't support that ourselves. 89 87 Officially the ext= tag was deprecated, but enough 90 88 clients do send it. 91 89 92 90 (I'm aware that this is not the right way to use 93 91 this field.) See for an explanation of ext=: 94 92 http://www.xmpp.org/extensions/attic/xep-0115-1.3.html*/ 95 93 } 96 97 if( is_chat ) 98 jabber_chat_pkt_presence( ic, bud, node ); 99 else 100 send_presence = jabber_buddy_by_jid( ic, bud->bare_jid, 0 ); 101 } 102 else if( strcmp( type, "unavailable" ) == 0 ) 103 { 104 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 105 { 94 95 if (is_chat) { 96 jabber_chat_pkt_presence(ic, bud, node); 97 } else { 98 send_presence = jabber_buddy_by_jid(ic, bud->bare_jid, 0); 99 } 100 } else if (strcmp(type, "unavailable") == 0) { 101 if ((bud = jabber_buddy_by_jid(ic, from, 0)) == NULL) { 106 102 /* 107 103 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); … … 109 105 return XT_HANDLED; 110 106 } 111 107 112 108 /* Handle this before we delete the JID. */ 113 if( is_chat ) 114 { 115 jabber_chat_pkt_presence( ic, bud, node ); 116 } 117 118 if( strchr( from, '/' ) == NULL ) 109 if (is_chat) { 110 jabber_chat_pkt_presence(ic, bud, node); 111 } 112 113 if (strchr(from, '/') == NULL) { 119 114 /* Sometimes servers send a type="unavailable" from a 120 115 bare JID, which should mean that suddenly all 121 116 resources for this JID disappeared. */ 122 jabber_buddy_remove_bare( ic, from);123 else124 jabber_buddy_remove( ic, from);125 126 if( is_chat ) 127 {117 jabber_buddy_remove_bare(ic, from); 118 } else { 119 jabber_buddy_remove(ic, from); 120 } 121 122 if (is_chat) { 128 123 /* Nothing else to do for now? */ 129 } 130 else if( ( s = strchr( from, '/' ) ) ) 131 { 124 } else if ((s = strchr(from, '/'))) { 132 125 *s = 0; 133 126 134 127 /* If another resource is still available, send its presence 135 128 information. */ 136 if( ( send_presence = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 137 { 129 if ((send_presence = jabber_buddy_by_jid(ic, from, 0)) == NULL) { 138 130 /* Otherwise, count him/her as offline now. */ 139 imcb_buddy_status( ic, from, 0, NULL, NULL);131 imcb_buddy_status(ic, from, 0, NULL, NULL); 140 132 } 141 133 142 134 *s = '/'; 143 } 144 else 145 { 146 imcb_buddy_status( ic, from, 0, NULL, NULL ); 147 } 148 } 149 else if( strcmp( type, "subscribe" ) == 0 ) 150 { 151 jabber_buddy_ask( ic, from ); 152 } 153 else if( strcmp( type, "subscribed" ) == 0 ) 154 { 135 } else { 136 imcb_buddy_status(ic, from, 0, NULL, NULL); 137 } 138 } else if (strcmp(type, "subscribe") == 0) { 139 jabber_buddy_ask(ic, from); 140 } else if (strcmp(type, "subscribed") == 0) { 155 141 /* Not sure about this one, actually... */ 156 imcb_log( ic, "%s just accepted your authorization request", from ); 157 } 158 else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 ) 159 { 142 imcb_log(ic, "%s just accepted your authorization request", from); 143 } else if (strcmp(type, "unsubscribe") == 0 || strcmp(type, "unsubscribed") == 0) { 160 144 /* Do nothing here. Plenty of control freaks or over-curious 161 145 souls get excited when they can see who still has them in … … 163 147 got the impression that those are the people who get 164 148 removed from many buddy lists for "some" reason... 165 149 166 150 If you're one of those people, this is your chance to write 167 151 your first line of code in C... */ 168 } 169 else if( strcmp( type, "error" ) == 0 ) 170 { 171 return jabber_cache_handle_packet( ic, node ); 172 152 } else if (strcmp(type, "error") == 0) { 153 return jabber_cache_handle_packet(ic, node); 154 173 155 /* 174 156 struct jabber_error *err; 175 157 if( ( c = xt_find_node( node->children, "error" ) ) ) 176 158 { 177 178 179 180 181 159 err = jabber_error_parse( c, XMLNS_STANZA_ERROR ); 160 imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name, 161 err->code, err->text ? ": " : "", 162 err->text ? err->text : "" ); 163 jabber_error_free( err ); 182 164 } */ 183 165 } 184 166 185 if( send_presence ) 186 { 167 if (send_presence) { 187 168 int is_away = 0; 188 169 189 if (send_presence->away_state &&190 strcmp( send_presence->away_state->code, "chat" ) != 0 )170 if (send_presence->away_state && 171 strcmp(send_presence->away_state->code, "chat") != 0) { 191 172 is_away = OPT_AWAY; 192 193 imcb_buddy_status( ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away, 194 is_away ? send_presence->away_state->full_name : NULL, 195 send_presence->away_message ); 196 } 197 173 } 174 175 imcb_buddy_status(ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away, 176 is_away ? send_presence->away_state->full_name : NULL, 177 send_presence->away_message); 178 } 179 198 180 return XT_HANDLED; 199 181 } … … 201 183 /* Whenever presence information is updated, call this function to inform the 202 184 server. */ 203 int presence_send_update( struct im_connection *ic)185 int presence_send_update(struct im_connection *ic) 204 186 { 205 187 struct jabber_data *jd = ic->proto_data; … … 207 189 GSList *l; 208 190 int st; 209 210 node = jabber_make_packet( "presence", NULL, NULL, NULL ); 211 xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) ); 212 if( jd->away_state ) 213 xt_add_child( node, xt_new_node( "show", jd->away_state->code, NULL ) ); 214 if( jd->away_message ) 215 xt_add_child( node, xt_new_node( "status", jd->away_message, NULL ) ); 216 191 192 node = jabber_make_packet("presence", NULL, NULL, NULL); 193 xt_add_child(node, xt_new_node("priority", set_getstr(&ic->acc->set, "priority"), NULL)); 194 if (jd->away_state) { 195 xt_add_child(node, xt_new_node("show", jd->away_state->code, NULL)); 196 } 197 if (jd->away_message) { 198 xt_add_child(node, xt_new_node("status", jd->away_message, NULL)); 199 } 200 217 201 /* This makes the packet slightly bigger, but clients interested in 218 202 capabilities can now cache the discovery info. This reduces the 219 203 usual post-login iq-flood. See XEP-0115. At least libpurple and 220 204 Trillian seem to do this right. */ 221 cap = xt_new_node( "c", NULL, NULL);222 xt_add_attr( cap, "xmlns", XMLNS_CAPS);223 xt_add_attr( cap, "node", "http://bitlbee.org/xmpp/caps");224 xt_add_attr( cap, "ver", BITLBEE_VERSION );/* The XEP wants this hashed, but nobody's doing that. */225 xt_add_child( node, cap);226 227 st = jabber_write_packet( ic, node);228 205 cap = xt_new_node("c", NULL, NULL); 206 xt_add_attr(cap, "xmlns", XMLNS_CAPS); 207 xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps"); 208 xt_add_attr(cap, "ver", BITLBEE_VERSION); /* The XEP wants this hashed, but nobody's doing that. */ 209 xt_add_child(node, cap); 210 211 st = jabber_write_packet(ic, node); 212 229 213 /* Have to send this update to all groupchats too, the server won't 230 214 do this automatically. */ 231 for( l = ic->groupchats; l && st; l = l->next ) 232 { 215 for (l = ic->groupchats; l && st; l = l->next) { 233 216 struct groupchat *c = l->data; 234 217 struct jabber_chat *jc = c->data; 235 236 xt_add_attr( node, "to", jc->my_full_jid);237 st = jabber_write_packet( ic, node);238 } 239 240 xt_free_node( node);218 219 xt_add_attr(node, "to", jc->my_full_jid); 220 st = jabber_write_packet(ic, node); 221 } 222 223 xt_free_node(node); 241 224 return st; 242 225 } 243 226 244 227 /* Send a subscribe/unsubscribe request to a buddy. */ 245 int presence_send_request( struct im_connection *ic, char *handle, char *request)228 int presence_send_request(struct im_connection *ic, char *handle, char *request) 246 229 { 247 230 struct xt_node *node; 248 231 int st; 249 250 node = jabber_make_packet( "presence", NULL, NULL, NULL);251 xt_add_attr( node, "to", handle);252 xt_add_attr( node, "type", request);253 254 st = jabber_write_packet( ic, node);255 256 xt_free_node( node);232 233 node = jabber_make_packet("presence", NULL, NULL, NULL); 234 xt_add_attr(node, "to", handle); 235 xt_add_attr(node, "type", request); 236 237 st = jabber_write_packet(ic, node); 238 239 xt_free_node(node); 257 240 return st; 258 241 }
Note: See TracChangeset
for help on using the changeset viewer.