libpurple/protocols/jabber/disco.c

branch
soc.2008.xmpp
changeset 23586
e495a4623f76
parent 21688
a16385b34219
child 23587
1691c5361029
equal deleted inserted replaced
23494:7a29afecb9dc 23586:e495a4623f76
77 77
78 78
79 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) { 79 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) {
80 const char *from = xmlnode_get_attrib(packet, "from"); 80 const char *from = xmlnode_get_attrib(packet, "from");
81 const char *type = xmlnode_get_attrib(packet, "type"); 81 const char *type = xmlnode_get_attrib(packet, "type");
82
83 if(!from || !type) 82 if(!from || !type)
84 return; 83 return;
85 84
86 if(!strcmp(type, "get")) { 85 if(!strcmp(type, "get")) {
87 xmlnode *query, *identity, *feature; 86 xmlnode *query, *identity, *feature;
88 JabberIq *iq; 87 JabberIq *iq;
89 88
90 xmlnode *in_query; 89 xmlnode *in_query;
91 const char *node = NULL; 90 const char *node = NULL;
91 const char *node_uri = NULL;
92
93 // create custom caps node URI
94 node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_hash(), NULL);
92 95
93 if((in_query = xmlnode_get_child(packet, "query"))) { 96 if((in_query = xmlnode_get_child(packet, "query"))) {
94 node = xmlnode_get_attrib(in_query, "node"); 97 node = xmlnode_get_attrib(in_query, "node");
95 } 98 }
96 99
104 query = xmlnode_get_child(iq->node, "query"); 107 query = xmlnode_get_child(iq->node, "query");
105 108
106 if(node) 109 if(node)
107 xmlnode_set_attrib(query, "node", node); 110 xmlnode_set_attrib(query, "node", node);
108 111
109 if(!node || !strcmp(node, CAPS0115_NODE "#" VERSION)) { 112
110 identity = xmlnode_new_child(query, "identity"); 113 if(!node || !strcmp(node, node_uri)) {
111 xmlnode_set_attrib(identity, "category", "client"); 114 GList *identities;
112 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console, 115 for(identities = jabber_identities; identities; identities = identities->next) {
113 * handheld, pc, phone, 116 JabberIdentity *ident = (JabberIdentity*)identities->data;
114 * web */ 117 identity = xmlnode_new_child(query, "identity");
115 xmlnode_set_attrib(identity, "name", PACKAGE); 118 xmlnode_set_attrib(identity, "category", ident->category);
116 119 xmlnode_set_attrib(identity, "type", ident->type);
117 SUPPORT_FEATURE("jabber:iq:last") 120 if (ident->name != 0) xmlnode_set_attrib(identity, "name", ident->name);
118 SUPPORT_FEATURE("jabber:iq:oob") 121 }
119 SUPPORT_FEATURE("jabber:iq:time") 122 GList *features;
120 SUPPORT_FEATURE("xmpp:urn:time") 123 for(features = jabber_features; features; features = features->next) {
121 SUPPORT_FEATURE("jabber:iq:version") 124 JabberFeature *feat = (JabberFeature*)features->data;
122 SUPPORT_FEATURE("jabber:x:conference") 125 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->namespace) == TRUE) {
123 SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") 126 feature = xmlnode_new_child(query, "feature");
124 SUPPORT_FEATURE("http://jabber.org/protocol/disco#info") 127 xmlnode_set_attrib(feature, "var", feat->namespace);
125 SUPPORT_FEATURE("http://jabber.org/protocol/disco#items") 128 }
126 #if 0
127 SUPPORT_FEATURE("http://jabber.org/protocol/ibb")
128 #endif
129 SUPPORT_FEATURE("http://jabber.org/protocol/muc")
130 SUPPORT_FEATURE("http://jabber.org/protocol/muc#user")
131 SUPPORT_FEATURE("http://jabber.org/protocol/si")
132 SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer")
133 SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im")
134 SUPPORT_FEATURE("urn:xmpp:ping")
135 SUPPORT_FEATURE("http://www.xmpp.org/extensions/xep-0199.html#ns")
136
137 if(!node) { /* non-caps disco#info, add all enabled extensions */
138 GList *features;
139 for(features = jabber_features; features; features = features->next) {
140 JabberFeature *feat = (JabberFeature*)features->data;
141 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->shortname, feat->namespace) == TRUE)
142 SUPPORT_FEATURE(feat->namespace);
143 }
144 } 129 }
145 } else { 130 } else {
146 const char *ext = NULL; 131 xmlnode *error, *inf;
147 unsigned pos;
148 unsigned nodelen = strlen(node);
149 unsigned capslen = strlen(CAPS0115_NODE);
150 /* do a basic plausability check */
151 if(nodelen > capslen+1) {
152 /* verify that the string is CAPS0115#<ext> and get the pointer to the ext part */
153 for(pos = 0; pos < capslen+1; ++pos) {
154 if(pos == capslen) {
155 if(node[pos] == '#')
156 ext = &node[pos+1];
157 else
158 break;
159 } else if(node[pos] != CAPS0115_NODE[pos])
160 break;
161 }
162 132
163 if(ext != NULL) { 133 /* XXX: gross hack, implement jabber_iq_set_type or something */
164 /* look for that ext */ 134 xmlnode_set_attrib(iq->node, "type", "error");
165 GList *features; 135 iq->type = JABBER_IQ_ERROR;
166 for(features = jabber_features; features; features = features->next) {
167 JabberFeature *feat = (JabberFeature*)features->data;
168 if(!strcmp(feat->shortname, ext)) {
169 SUPPORT_FEATURE(feat->namespace);
170 break;
171 }
172 }
173 if(features == NULL)
174 ext = NULL;
175 }
176 }
177 136
178 if(ext == NULL) { 137 error = xmlnode_new_child(query, "error");
179 xmlnode *error, *inf; 138 xmlnode_set_attrib(error, "code", "404");
180 139 xmlnode_set_attrib(error, "type", "cancel");
181 /* XXX: gross hack, implement jabber_iq_set_type or something */ 140 inf = xmlnode_new_child(error, "item-not-found");
182 xmlnode_set_attrib(iq->node, "type", "error"); 141 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas");
183 iq->type = JABBER_IQ_ERROR; 142 }
184 143 g_free(node_uri);
185 error = xmlnode_new_child(query, "error");
186 xmlnode_set_attrib(error, "code", "404");
187 xmlnode_set_attrib(error, "type", "cancel");
188 inf = xmlnode_new_child(error, "item-not-found");
189 xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas");
190 }
191 }
192
193 jabber_iq_send(iq); 144 jabber_iq_send(iq);
194 } else if(!strcmp(type, "result")) { 145 } else if(!strcmp(type, "result")) {
195 xmlnode *query = xmlnode_get_child(packet, "query"); 146 xmlnode *query = xmlnode_get_child(packet, "query");
196 xmlnode *child; 147 xmlnode *child;
197 JabberID *jid; 148 JabberID *jid;

mercurial