Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/disco.c @ 25807:1d1d1829de11
propagate from branch 'im.pidgin.pidgin' (head 42f77b0e8b8ebf5ff3c30d8f8022ac5d289631e8)
to branch 'org.darkrain42.pidgin.xmpp' (head f3aa6c57ecb65ae9dbf729bca259e94f48b87279)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 18 Jan 2009 04:17:50 +0000 |
parents | 0700833f0c5d f462fa160f06 |
children | 6a369035fd20 |
comparison
equal
deleted
inserted
replaced
24964:8a5c0c5c71f9 | 25807:1d1d1829de11 |
---|---|
86 | 86 |
87 | 87 |
88 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) { | 88 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) { |
89 const char *from = xmlnode_get_attrib(packet, "from"); | 89 const char *from = xmlnode_get_attrib(packet, "from"); |
90 const char *type = xmlnode_get_attrib(packet, "type"); | 90 const char *type = xmlnode_get_attrib(packet, "type"); |
91 | |
92 if(!from || !type) | 91 if(!from || !type) |
93 return; | 92 return; |
94 | 93 |
95 if(!strcmp(type, "get")) { | 94 if(!strcmp(type, "get")) { |
96 xmlnode *query, *identity, *feature; | 95 xmlnode *query, *identity, *feature; |
97 JabberIq *iq; | 96 JabberIq *iq; |
98 | 97 |
99 xmlnode *in_query; | 98 xmlnode *in_query; |
100 const char *node = NULL; | 99 const char *node = NULL; |
100 char *node_uri = NULL; | |
101 | |
102 /* create custom caps node URI */ | |
103 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL); | |
101 | 104 |
102 if((in_query = xmlnode_get_child(packet, "query"))) { | 105 if((in_query = xmlnode_get_child(packet, "query"))) { |
103 node = xmlnode_get_attrib(in_query, "node"); | 106 node = xmlnode_get_attrib(in_query, "node"); |
104 } | 107 } |
105 | 108 |
113 query = xmlnode_get_child(iq->node, "query"); | 116 query = xmlnode_get_child(iq->node, "query"); |
114 | 117 |
115 if(node) | 118 if(node) |
116 xmlnode_set_attrib(query, "node", node); | 119 xmlnode_set_attrib(query, "node", node); |
117 | 120 |
118 if(!node || !strcmp(node, CAPS0115_NODE "#" VERSION)) { | 121 |
119 identity = xmlnode_new_child(query, "identity"); | 122 if(!node || !strcmp(node, node_uri)) { |
120 xmlnode_set_attrib(identity, "category", "client"); | 123 GList *features, *identities; |
121 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, | 124 for(identities = jabber_identities; identities; identities = identities->next) { |
122 * handheld, pc, phone, | 125 JabberIdentity *ident = (JabberIdentity*)identities->data; |
123 * web */ | 126 identity = xmlnode_new_child(query, "identity"); |
124 xmlnode_set_attrib(identity, "name", PACKAGE); | 127 xmlnode_set_attrib(identity, "category", ident->category); |
125 | 128 xmlnode_set_attrib(identity, "type", ident->type); |
126 SUPPORT_FEATURE("jabber:iq:last") | 129 if (ident->lang) |
127 SUPPORT_FEATURE("jabber:iq:oob") | 130 xmlnode_set_attrib(identity, "xml:lang", ident->lang); |
128 SUPPORT_FEATURE("jabber:iq:time") | 131 if (ident->name) |
129 SUPPORT_FEATURE("xmpp:urn:time") | 132 xmlnode_set_attrib(identity, "name", ident->name); |
130 SUPPORT_FEATURE("jabber:iq:version") | 133 } |
131 SUPPORT_FEATURE("jabber:x:conference") | 134 for(features = jabber_features; features; features = features->next) { |
132 SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") | 135 JabberFeature *feat = (JabberFeature*)features->data; |
133 SUPPORT_FEATURE("http://jabber.org/protocol/disco#info") | 136 if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) { |
134 SUPPORT_FEATURE("http://jabber.org/protocol/disco#items") | 137 feature = xmlnode_new_child(query, "feature"); |
135 #if 0 | 138 xmlnode_set_attrib(feature, "var", feat->namespace); |
136 SUPPORT_FEATURE("http://jabber.org/protocol/ibb") | 139 } |
137 #endif | |
138 SUPPORT_FEATURE("http://jabber.org/protocol/muc") | |
139 SUPPORT_FEATURE("http://jabber.org/protocol/muc#user") | |
140 SUPPORT_FEATURE("http://jabber.org/protocol/si") | |
141 SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer") | |
142 SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im") | |
143 SUPPORT_FEATURE("urn:xmpp:ping") | |
144 SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0199.html#ns") | |
145 | |
146 if(!node) { /* non-caps disco#info, add all enabled extensions */ | |
147 GList *features; | |
148 for(features = jabber_features; features; features = features->next) { | |
149 JabberFeature *feat = (JabberFeature*)features->data; | |
150 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->shortname, feat->namespace) == TRUE) | |
151 SUPPORT_FEATURE(feat->namespace); | |
152 } | |
153 } | 140 } |
154 } else { | 141 } else { |
155 const char *ext = NULL; | 142 xmlnode *error, *inf; |
156 unsigned pos; | |
157 unsigned nodelen = strlen(node); | |
158 unsigned capslen = strlen(CAPS0115_NODE); | |
159 /* do a basic plausability check */ | |
160 if(nodelen > capslen+1) { | |
161 /* verify that the string is CAPS0115#<ext> and get the pointer to the ext part */ | |
162 for(pos = 0; pos < capslen+1; ++pos) { | |
163 if(pos == capslen) { | |
164 if(node[pos] == '#') | |
165 ext = &node[pos+1]; | |
166 else | |
167 break; | |
168 } else if(node[pos] != CAPS0115_NODE[pos]) | |
169 break; | |
170 } | |
171 | 143 |
172 if(ext != NULL) { | 144 /* XXX: gross hack, implement jabber_iq_set_type or something */ |
173 /* look for that ext */ | 145 xmlnode_set_attrib(iq->node, "type", "error"); |
174 GList *features; | 146 iq->type = JABBER_IQ_ERROR; |
175 for(features = jabber_features; features; features = features->next) { | |
176 JabberFeature *feat = (JabberFeature*)features->data; | |
177 if(!strcmp(feat->shortname, ext)) { | |
178 SUPPORT_FEATURE(feat->namespace); | |
179 break; | |
180 } | |
181 } | |
182 if(features == NULL) | |
183 ext = NULL; | |
184 } | |
185 } | |
186 | 147 |
187 if(ext == NULL) { | 148 error = xmlnode_new_child(query, "error"); |
188 xmlnode *error, *inf; | 149 xmlnode_set_attrib(error, "code", "404"); |
189 | 150 xmlnode_set_attrib(error, "type", "cancel"); |
190 /* XXX: gross hack, implement jabber_iq_set_type or something */ | 151 inf = xmlnode_new_child(error, "item-not-found"); |
191 xmlnode_set_attrib(iq->node, "type", "error"); | 152 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
192 iq->type = JABBER_IQ_ERROR; | 153 } |
193 | 154 g_free(node_uri); |
194 error = xmlnode_new_child(query, "error"); | |
195 xmlnode_set_attrib(error, "code", "404"); | |
196 xmlnode_set_attrib(error, "type", "cancel"); | |
197 inf = xmlnode_new_child(error, "item-not-found"); | |
198 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); | |
199 } | |
200 } | |
201 | |
202 jabber_iq_send(iq); | 155 jabber_iq_send(iq); |
203 } else if(!strcmp(type, "result")) { | 156 } else if(!strcmp(type, "result")) { |
204 xmlnode *query = xmlnode_get_child(packet, "query"); | 157 xmlnode *query = xmlnode_get_child(packet, "query"); |
205 xmlnode *child; | 158 xmlnode *child; |
206 JabberID *jid; | 159 JabberID *jid; |
346 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ | 299 /* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */ |
347 jabber_roster_request(js); | 300 jabber_roster_request(js); |
348 } | 301 } |
349 | 302 |
350 /* Send initial presence; this will trigger receipt of presence for contacts on the roster */ | 303 /* Send initial presence; this will trigger receipt of presence for contacts on the roster */ |
351 jabber_presence_send(js->gc->account, NULL); | 304 jabber_presence_send(js, TRUE); |
352 | 305 |
353 if (js->server_caps & JABBER_CAP_ADHOC) { | 306 if (js->server_caps & JABBER_CAP_ADHOC) { |
354 /* The server supports ad-hoc commands, so let's request the list */ | 307 /* The server supports ad-hoc commands, so let's request the list */ |
355 jabber_adhoc_server_get_list(js); | 308 jabber_adhoc_server_get_list(js); |
356 } | 309 } |