Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/disco.c @ 25987:c4fd9222dda1
propagate from branch 'im.pidgin.pidgin' (head 303af74a38e7b313d4fb0be4d4054a16cb13d819)
to branch 'im.pidgin.cpw.darkrain42.xmpp.bosh' (head 650d82b8a5f0c8860804dd8004cd54badea48e1e)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 07 Mar 2009 01:59:40 +0000 |
parents | 5f9a24d1c25e 6a369035fd20 |
children | 2597de135090 |
comparison
equal
deleted
inserted
replaced
25464:0e93bbb7f5ca | 25987:c4fd9222dda1 |
---|---|
96 xmlnode *query, *identity, *feature; | 96 xmlnode *query, *identity, *feature; |
97 JabberIq *iq; | 97 JabberIq *iq; |
98 | 98 |
99 xmlnode *in_query; | 99 xmlnode *in_query; |
100 const char *node = NULL; | 100 const char *node = NULL; |
101 char *node_uri = NULL; | |
102 | |
103 /* create custom caps node URI */ | |
104 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL); | |
101 | 105 |
102 if((in_query = xmlnode_get_child(packet, "query"))) { | 106 if((in_query = xmlnode_get_child(packet, "query"))) { |
103 node = xmlnode_get_attrib(in_query, "node"); | 107 node = xmlnode_get_attrib(in_query, "node"); |
104 } | 108 } |
105 | 109 |
121 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, | 125 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, |
122 * handheld, pc, phone, | 126 * handheld, pc, phone, |
123 * web */ | 127 * web */ |
124 xmlnode_set_attrib(identity, "name", PACKAGE); | 128 xmlnode_set_attrib(identity, "name", PACKAGE); |
125 | 129 |
126 SUPPORT_FEATURE("jabber:iq:last") | 130 if(!node || !strcmp(node, node_uri)) { |
127 SUPPORT_FEATURE("jabber:iq:oob") | 131 GList *features, *identities; |
128 SUPPORT_FEATURE("jabber:iq:time") | 132 for(identities = jabber_identities; identities; identities = identities->next) { |
129 SUPPORT_FEATURE("xmpp:urn:time") | 133 JabberIdentity *ident = (JabberIdentity*)identities->data; |
130 SUPPORT_FEATURE("jabber:iq:version") | 134 identity = xmlnode_new_child(query, "identity"); |
131 SUPPORT_FEATURE("jabber:x:conference") | 135 xmlnode_set_attrib(identity, "category", ident->category); |
132 SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") | 136 xmlnode_set_attrib(identity, "type", ident->type); |
133 SUPPORT_FEATURE("http://jabber.org/protocol/disco#info") | 137 if (ident->lang) |
134 SUPPORT_FEATURE("http://jabber.org/protocol/disco#items") | 138 xmlnode_set_attrib(identity, "xml:lang", ident->lang); |
135 SUPPORT_FEATURE("http://jabber.org/protocol/ibb"); | 139 if (ident->name) |
136 SUPPORT_FEATURE("http://jabber.org/protocol/muc") | 140 xmlnode_set_attrib(identity, "name", ident->name); |
137 SUPPORT_FEATURE("http://jabber.org/protocol/muc#user") | 141 } |
138 SUPPORT_FEATURE("http://jabber.org/protocol/si") | 142 for(features = jabber_features; features; features = features->next) { |
139 SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer") | 143 JabberFeature *feat = (JabberFeature*)features->data; |
140 SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im") | 144 if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) { |
141 SUPPORT_FEATURE("urn:xmpp:ping") | 145 feature = xmlnode_new_child(query, "feature"); |
142 SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0199.html#ns") | 146 xmlnode_set_attrib(feature, "var", feat->namespace); |
143 | 147 } |
144 if(!node) { /* non-caps disco#info, add all enabled extensions */ | |
145 GList *features; | |
146 for(features = jabber_features; features; features = features->next) { | |
147 JabberFeature *feat = (JabberFeature*)features->data; | |
148 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->shortname, feat->namespace) == TRUE) | |
149 SUPPORT_FEATURE(feat->namespace); | |
150 } | |
151 } | 148 } |
152 } else { | 149 } else { |
153 const char *ext = NULL; | 150 xmlnode *error, *inf; |
154 unsigned pos; | 151 |
155 unsigned nodelen = strlen(node); | 152 /* XXX: gross hack, implement jabber_iq_set_type or something */ |
156 unsigned capslen = strlen(CAPS0115_NODE); | 153 xmlnode_set_attrib(iq->node, "type", "error"); |
157 /* do a basic plausability check */ | 154 iq->type = JABBER_IQ_ERROR; |
158 if(nodelen > capslen+1) { | 155 |
159 /* verify that the string is CAPS0115#<ext> and get the pointer to the ext part */ | 156 error = xmlnode_new_child(query, "error"); |
160 for(pos = 0; pos < capslen+1; ++pos) { | 157 xmlnode_set_attrib(error, "code", "404"); |
161 if(pos == capslen) { | 158 xmlnode_set_attrib(error, "type", "cancel"); |
162 if(node[pos] == '#') | 159 inf = xmlnode_new_child(error, "item-not-found"); |
163 ext = &node[pos+1]; | 160 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
164 else | 161 } |
165 break; | 162 g_free(node_uri); |
166 } else if(node[pos] != CAPS0115_NODE[pos]) | |
167 break; | |
168 } | |
169 | |
170 if(ext != NULL) { | |
171 /* look for that ext */ | |
172 GList *features; | |
173 for(features = jabber_features; features; features = features->next) { | |
174 JabberFeature *feat = (JabberFeature*)features->data; | |
175 if(!strcmp(feat->shortname, ext)) { | |
176 SUPPORT_FEATURE(feat->namespace); | |
177 break; | |
178 } | |
179 } | |
180 if(features == NULL) | |
181 ext = NULL; | |
182 } | |
183 } | |
184 | |
185 if(ext == NULL) { | |
186 xmlnode *error, *inf; | |
187 | |
188 /* XXX: gross hack, implement jabber_iq_set_type or something */ | |
189 xmlnode_set_attrib(iq->node, "type", "error"); | |
190 iq->type = JABBER_IQ_ERROR; | |
191 | |
192 error = xmlnode_new_child(query, "error"); | |
193 xmlnode_set_attrib(error, "code", "404"); | |
194 xmlnode_set_attrib(error, "type", "cancel"); | |
195 inf = xmlnode_new_child(error, "item-not-found"); | |
196 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); | |
197 } | |
198 } | |
199 | |
200 jabber_iq_send(iq); | 163 jabber_iq_send(iq); |
201 } else if(!strcmp(type, "result")) { | 164 } else if(!strcmp(type, "result")) { |
202 xmlnode *query = xmlnode_get_child(packet, "query"); | 165 xmlnode *query = xmlnode_get_child(packet, "query"); |
203 xmlnode *child; | 166 xmlnode *child; |
204 JabberID *jid; | 167 JabberID *jid; |
347 if (!(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) { | 310 if (!(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) { |
348 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ | 311 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ |
349 jabber_roster_request(js); | 312 jabber_roster_request(js); |
350 } | 313 } |
351 | 314 |
352 /* Send initial presence; this will trigger receipt of presence for contacts on the roster */ | |
353 jabber_presence_send(js->gc->account, NULL); | |
354 | |
355 if (js->server_caps & JABBER_CAP_ADHOC) { | 315 if (js->server_caps & JABBER_CAP_ADHOC) { |
356 /* The server supports ad-hoc commands, so let's request the list */ | 316 /* The server supports ad-hoc commands, so let's request the list */ |
357 jabber_adhoc_server_get_list(js); | 317 jabber_adhoc_server_get_list(js); |
358 } | 318 } |
359 | 319 |