Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/disco.c @ 26528:882748e27f9d
propagate from branch 'im.pidgin.pidgin' (head 58b2ba106e563fcd0984b9438aa427f1d61e25e9)
to branch 'im.pidgin.cpw.darkrain42.xmpp.bosh' (head 66b3abfbbc6c37e976677819dd23987db9d3b083)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 04 Apr 2009 03:15:59 +0000 |
parents | e23a74d7c97c 2597de135090 |
children | 1ecbda91458a |
comparison
equal
deleted
inserted
replaced
26515:c08719989149 | 26528:882748e27f9d |
---|---|
97 xmlnode *query, *identity, *feature; | 97 xmlnode *query, *identity, *feature; |
98 JabberIq *iq; | 98 JabberIq *iq; |
99 | 99 |
100 xmlnode *in_query; | 100 xmlnode *in_query; |
101 const char *node = NULL; | 101 const char *node = NULL; |
102 char *node_uri = NULL; | |
103 | |
104 /* create custom caps node URI */ | |
105 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL); | |
102 | 106 |
103 if((in_query = xmlnode_get_child(packet, "query"))) { | 107 if((in_query = xmlnode_get_child(packet, "query"))) { |
104 node = xmlnode_get_attrib(in_query, "node"); | 108 node = xmlnode_get_attrib(in_query, "node"); |
105 } | 109 } |
106 | 110 |
121 xmlnode_set_attrib(identity, "category", "client"); | 125 xmlnode_set_attrib(identity, "category", "client"); |
122 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, | 126 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, |
123 * handheld, pc, phone, | 127 * handheld, pc, phone, |
124 * web */ | 128 * web */ |
125 xmlnode_set_attrib(identity, "name", PACKAGE); | 129 xmlnode_set_attrib(identity, "name", PACKAGE); |
126 | 130 } |
127 SUPPORT_FEATURE("jabber:iq:last") | 131 |
128 SUPPORT_FEATURE("jabber:iq:oob") | 132 if(!node || !strcmp(node, node_uri)) { |
129 SUPPORT_FEATURE("jabber:iq:time") | 133 GList *features, *identities; |
130 SUPPORT_FEATURE("xmpp:urn:time") | 134 for(identities = jabber_identities; identities; identities = identities->next) { |
131 SUPPORT_FEATURE("jabber:iq:version") | 135 JabberIdentity *ident = (JabberIdentity*)identities->data; |
132 SUPPORT_FEATURE("jabber:x:conference") | 136 identity = xmlnode_new_child(query, "identity"); |
133 SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") | 137 xmlnode_set_attrib(identity, "category", ident->category); |
134 SUPPORT_FEATURE("http://jabber.org/protocol/disco#info") | 138 xmlnode_set_attrib(identity, "type", ident->type); |
135 SUPPORT_FEATURE("http://jabber.org/protocol/disco#items") | 139 if (ident->lang) |
136 SUPPORT_FEATURE("http://jabber.org/protocol/ibb"); | 140 xmlnode_set_attrib(identity, "xml:lang", ident->lang); |
137 SUPPORT_FEATURE("http://jabber.org/protocol/muc") | 141 if (ident->name) |
138 SUPPORT_FEATURE("http://jabber.org/protocol/muc#user") | 142 xmlnode_set_attrib(identity, "name", ident->name); |
139 SUPPORT_FEATURE("http://jabber.org/protocol/si") | 143 } |
140 SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer") | 144 for(features = jabber_features; features; features = features->next) { |
141 SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im") | 145 JabberFeature *feat = (JabberFeature*)features->data; |
142 SUPPORT_FEATURE("urn:xmpp:ping") | 146 if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) { |
143 SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0199.html#ns") | 147 feature = xmlnode_new_child(query, "feature"); |
144 | 148 xmlnode_set_attrib(feature, "var", feat->namespace); |
145 if(!node) { /* non-caps disco#info, add all enabled extensions */ | 149 } |
146 GList *features; | |
147 for(features = jabber_features; features; features = features->next) { | |
148 JabberFeature *feat = (JabberFeature*)features->data; | |
149 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->shortname, feat->namespace) == TRUE) | |
150 SUPPORT_FEATURE(feat->namespace); | |
151 } | |
152 } | 150 } |
153 #ifdef USE_VV | 151 #ifdef USE_VV |
154 } else if (node && !strcmp(node, CAPS0115_NODE "#voice-v1")) { | 152 } else if (node && !strcmp(node, CAPS0115_NODE "#voice-v1")) { |
155 SUPPORT_FEATURE("http://www.google.com/xmpp/protocol/session"); | 153 SUPPORT_FEATURE("http://www.google.com/xmpp/protocol/session"); |
156 SUPPORT_FEATURE("http://www.google.com/xmpp/protocol/voice/v1"); | 154 SUPPORT_FEATURE("http://www.google.com/xmpp/protocol/voice/v1"); |
159 SUPPORT_FEATURE(JINGLE_APP_RTP_SUPPORT_VIDEO); | 157 SUPPORT_FEATURE(JINGLE_APP_RTP_SUPPORT_VIDEO); |
160 SUPPORT_FEATURE(JINGLE_TRANSPORT_RAWUDP); | 158 SUPPORT_FEATURE(JINGLE_TRANSPORT_RAWUDP); |
161 SUPPORT_FEATURE(JINGLE_TRANSPORT_ICEUDP); | 159 SUPPORT_FEATURE(JINGLE_TRANSPORT_ICEUDP); |
162 #endif | 160 #endif |
163 } else { | 161 } else { |
164 const char *ext = NULL; | 162 xmlnode *error, *inf; |
165 unsigned pos; | 163 |
166 unsigned nodelen = strlen(node); | 164 /* XXX: gross hack, implement jabber_iq_set_type or something */ |
167 unsigned capslen = strlen(CAPS0115_NODE); | 165 xmlnode_set_attrib(iq->node, "type", "error"); |
168 /* do a basic plausability check */ | 166 iq->type = JABBER_IQ_ERROR; |
169 if(nodelen > capslen+1) { | 167 |
170 /* verify that the string is CAPS0115#<ext> and get the pointer to the ext part */ | 168 error = xmlnode_new_child(query, "error"); |
171 for(pos = 0; pos < capslen+1; ++pos) { | 169 xmlnode_set_attrib(error, "code", "404"); |
172 if(pos == capslen) { | 170 xmlnode_set_attrib(error, "type", "cancel"); |
173 if(node[pos] == '#') | 171 inf = xmlnode_new_child(error, "item-not-found"); |
174 ext = &node[pos+1]; | 172 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
175 else | 173 } |
176 break; | 174 g_free(node_uri); |
177 } else if(node[pos] != CAPS0115_NODE[pos]) | |
178 break; | |
179 } | |
180 | |
181 if(ext != NULL) { | |
182 /* look for that ext */ | |
183 GList *features; | |
184 for(features = jabber_features; features; features = features->next) { | |
185 JabberFeature *feat = (JabberFeature*)features->data; | |
186 if(!strcmp(feat->shortname, ext)) { | |
187 SUPPORT_FEATURE(feat->namespace); | |
188 break; | |
189 } | |
190 } | |
191 if(features == NULL) | |
192 ext = NULL; | |
193 } | |
194 } | |
195 | |
196 if(ext == NULL) { | |
197 xmlnode *error, *inf; | |
198 | |
199 /* XXX: gross hack, implement jabber_iq_set_type or something */ | |
200 xmlnode_set_attrib(iq->node, "type", "error"); | |
201 iq->type = JABBER_IQ_ERROR; | |
202 | |
203 error = xmlnode_new_child(query, "error"); | |
204 xmlnode_set_attrib(error, "code", "404"); | |
205 xmlnode_set_attrib(error, "type", "cancel"); | |
206 inf = xmlnode_new_child(error, "item-not-found"); | |
207 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); | |
208 } | |
209 } | |
210 | |
211 jabber_iq_send(iq); | 175 jabber_iq_send(iq); |
212 } else if(!strcmp(type, "result")) { | 176 } else if(!strcmp(type, "result")) { |
213 xmlnode *query = xmlnode_get_child(packet, "query"); | 177 xmlnode *query = xmlnode_get_child(packet, "query"); |
214 xmlnode *child; | 178 xmlnode *child; |
215 JabberID *jid; | 179 JabberID *jid; |
358 if (!(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) { | 322 if (!(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) { |
359 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ | 323 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ |
360 jabber_roster_request(js); | 324 jabber_roster_request(js); |
361 } | 325 } |
362 | 326 |
363 /* Send initial presence; this will trigger receipt of presence for contacts on the roster */ | |
364 jabber_presence_send(js->gc->account, NULL); | |
365 | |
366 if (js->server_caps & JABBER_CAP_ADHOC) { | 327 if (js->server_caps & JABBER_CAP_ADHOC) { |
367 /* The server supports ad-hoc commands, so let's request the list */ | 328 /* The server supports ad-hoc commands, so let's request the list */ |
368 jabber_adhoc_server_get_list(js); | 329 jabber_adhoc_server_get_list(js); |
369 } | 330 } |
370 | 331 |