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