pidgin/plugins/disco/xmppdisco.c

branch
soc.2013.gobjectification.plugins
changeset 36692
324db2a53c4c
parent 36637
9b0109ae118d
parent 34935
686fa55b0deb
child 36754
8250d6be8c02
equal deleted inserted replaced
36691:92122af1f083 36692:324db2a53c4c
54 PurplePlugin *my_plugin = NULL; 54 PurplePlugin *my_plugin = NULL;
55 static GHashTable *iq_callbacks = NULL; 55 static GHashTable *iq_callbacks = NULL;
56 static gboolean iq_listening = FALSE; 56 static gboolean iq_listening = FALSE;
57 57
58 typedef void (*XmppIqCallback)(PurpleConnection *pc, const char *type, 58 typedef void (*XmppIqCallback)(PurpleConnection *pc, const char *type,
59 const char *id, const char *from, xmlnode *iq, 59 const char *id, const char *from, PurpleXmlNode *iq,
60 gpointer data); 60 gpointer data);
61 61
62 struct item_data { 62 struct item_data {
63 PidginDiscoList *list; 63 PidginDiscoList *list;
64 XmppDiscoService *parent; 64 XmppDiscoService *parent;
114 return FALSE; 114 return FALSE;
115 } 115 }
116 116
117 static gboolean 117 static gboolean
118 xmpp_iq_received(PurpleConnection *pc, const char *type, const char *id, 118 xmpp_iq_received(PurpleConnection *pc, const char *type, const char *id,
119 const char *from, xmlnode *iq) 119 const char *from, PurpleXmlNode *iq)
120 { 120 {
121 struct xmpp_iq_cb_data *cb_data; 121 struct xmpp_iq_cb_data *cb_data;
122 122
123 cb_data = g_hash_table_lookup(iq_callbacks, id); 123 cb_data = g_hash_table_lookup(iq_callbacks, id);
124 if (!cb_data) 124 if (!cb_data)
160 160
161 static void 161 static void
162 xmpp_disco_info_do(PurpleConnection *pc, gpointer cbdata, const char *jid, 162 xmpp_disco_info_do(PurpleConnection *pc, gpointer cbdata, const char *jid,
163 const char *node, XmppIqCallback cb) 163 const char *node, XmppIqCallback cb)
164 { 164 {
165 xmlnode *iq, *query; 165 PurpleXmlNode *iq, *query;
166 char *id = generate_next_id(); 166 char *id = generate_next_id();
167 167
168 iq = xmlnode_new("iq"); 168 iq = purple_xmlnode_new("iq");
169 xmlnode_set_attrib(iq, "type", "get"); 169 purple_xmlnode_set_attrib(iq, "type", "get");
170 xmlnode_set_attrib(iq, "to", jid); 170 purple_xmlnode_set_attrib(iq, "to", jid);
171 xmlnode_set_attrib(iq, "id", id); 171 purple_xmlnode_set_attrib(iq, "id", id);
172 172
173 query = xmlnode_new_child(iq, "query"); 173 query = purple_xmlnode_new_child(iq, "query");
174 xmlnode_set_namespace(query, NS_DISCO_INFO); 174 purple_xmlnode_set_namespace(query, NS_DISCO_INFO);
175 if (node) 175 if (node)
176 xmlnode_set_attrib(query, "node", node); 176 purple_xmlnode_set_attrib(query, "node", node);
177 177
178 /* Steals id */ 178 /* Steals id */
179 xmpp_iq_register_callback(pc, id, cbdata, cb); 179 xmpp_iq_register_callback(pc, id, cbdata, cb);
180 180
181 purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode", 181 purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode",
182 pc, &iq); 182 pc, &iq);
183 if (iq != NULL) 183 if (iq != NULL)
184 xmlnode_free(iq); 184 purple_xmlnode_free(iq);
185 } 185 }
186 186
187 static void 187 static void
188 xmpp_disco_items_do(PurpleConnection *pc, gpointer cbdata, const char *jid, 188 xmpp_disco_items_do(PurpleConnection *pc, gpointer cbdata, const char *jid,
189 const char *node, XmppIqCallback cb) 189 const char *node, XmppIqCallback cb)
190 { 190 {
191 xmlnode *iq, *query; 191 PurpleXmlNode *iq, *query;
192 char *id = generate_next_id(); 192 char *id = generate_next_id();
193 193
194 iq = xmlnode_new("iq"); 194 iq = purple_xmlnode_new("iq");
195 xmlnode_set_attrib(iq, "type", "get"); 195 purple_xmlnode_set_attrib(iq, "type", "get");
196 xmlnode_set_attrib(iq, "to", jid); 196 purple_xmlnode_set_attrib(iq, "to", jid);
197 xmlnode_set_attrib(iq, "id", id); 197 purple_xmlnode_set_attrib(iq, "id", id);
198 198
199 query = xmlnode_new_child(iq, "query"); 199 query = purple_xmlnode_new_child(iq, "query");
200 xmlnode_set_namespace(query, NS_DISCO_ITEMS); 200 purple_xmlnode_set_namespace(query, NS_DISCO_ITEMS);
201 if (node) 201 if (node)
202 xmlnode_set_attrib(query, "node", node); 202 purple_xmlnode_set_attrib(query, "node", node);
203 203
204 /* Steals id */ 204 /* Steals id */
205 xmpp_iq_register_callback(pc, id, cbdata, cb); 205 xmpp_iq_register_callback(pc, id, cbdata, cb);
206 206
207 purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode", 207 purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode",
208 pc, &iq); 208 pc, &iq);
209 if (iq != NULL) 209 if (iq != NULL)
210 xmlnode_free(iq); 210 purple_xmlnode_free(iq);
211 } 211 }
212 212
213 static XmppDiscoServiceType 213 static XmppDiscoServiceType
214 disco_service_type_from_identity(xmlnode *identity) 214 disco_service_type_from_identity(PurpleXmlNode *identity)
215 { 215 {
216 const char *category, *type; 216 const char *category, *type;
217 217
218 if (!identity) 218 if (!identity)
219 return XMPP_DISCO_SERVICE_TYPE_OTHER; 219 return XMPP_DISCO_SERVICE_TYPE_OTHER;
220 220
221 category = xmlnode_get_attrib(identity, "category"); 221 category = purple_xmlnode_get_attrib(identity, "category");
222 type = xmlnode_get_attrib(identity, "type"); 222 type = purple_xmlnode_get_attrib(identity, "type");
223 223
224 if (!category) 224 if (!category)
225 return XMPP_DISCO_SERVICE_TYPE_OTHER; 225 return XMPP_DISCO_SERVICE_TYPE_OTHER;
226 226
227 if (g_str_equal(category, "conference")) 227 if (g_str_equal(category, "conference"))
273 return str; 273 return str;
274 } 274 }
275 275
276 static void 276 static void
277 got_info_cb(PurpleConnection *pc, const char *type, const char *id, 277 got_info_cb(PurpleConnection *pc, const char *type, const char *id,
278 const char *from, xmlnode *iq, gpointer data) 278 const char *from, PurpleXmlNode *iq, gpointer data)
279 { 279 {
280 struct item_data *item_data = data; 280 struct item_data *item_data = data;
281 PidginDiscoList *list = item_data->list; 281 PidginDiscoList *list = item_data->list;
282 xmlnode *query; 282 PurpleXmlNode *query;
283 283
284 --list->fetch_count; 284 --list->fetch_count;
285 285
286 if (!list->in_progress) 286 if (!list->in_progress)
287 goto out; 287 goto out;
288 288
289 if (g_str_equal(type, "result") && 289 if (g_str_equal(type, "result") &&
290 (query = xmlnode_get_child(iq, "query"))) { 290 (query = purple_xmlnode_get_child(iq, "query"))) {
291 xmlnode *identity = xmlnode_get_child(query, "identity"); 291 PurpleXmlNode *identity = purple_xmlnode_get_child(query, "identity");
292 XmppDiscoService *service; 292 XmppDiscoService *service;
293 xmlnode *feature; 293 PurpleXmlNode *feature;
294 294
295 service = g_new0(XmppDiscoService, 1); 295 service = g_new0(XmppDiscoService, 1);
296 service->list = item_data->list; 296 service->list = item_data->list;
297 purple_debug_info("xmppdisco", "parent for %s is %p\n", from, item_data->parent); 297 purple_debug_info("xmppdisco", "parent for %s is %p\n", from, item_data->parent);
298 service->parent = item_data->parent; 298 service->parent = item_data->parent;
320 320
321 if (item_data->name) { 321 if (item_data->name) {
322 service->description = item_data->name; 322 service->description = item_data->name;
323 item_data->name = NULL; 323 item_data->name = NULL;
324 } else if (identity) 324 } else if (identity)
325 service->description = g_strdup(xmlnode_get_attrib(identity, "name")); 325 service->description = g_strdup(purple_xmlnode_get_attrib(identity, "name"));
326 326
327 /* TODO: Overlap with service->name a bit */ 327 /* TODO: Overlap with service->name a bit */
328 service->jid = g_strdup(from); 328 service->jid = g_strdup(from);
329 329
330 for (feature = xmlnode_get_child(query, "feature"); feature; 330 for (feature = purple_xmlnode_get_child(query, "feature"); feature;
331 feature = xmlnode_get_next_twin(feature)) { 331 feature = purple_xmlnode_get_next_twin(feature)) {
332 const char *var; 332 const char *var;
333 if (!(var = xmlnode_get_attrib(feature, "var"))) 333 if (!(var = purple_xmlnode_get_attrib(feature, "var")))
334 continue; 334 continue;
335 335
336 if (g_str_equal(var, NS_REGISTER)) 336 if (g_str_equal(var, NS_REGISTER))
337 service->flags |= XMPP_DISCO_REGISTER; 337 service->flags |= XMPP_DISCO_REGISTER;
338 else if (g_str_equal(var, NS_DISCO_ITEMS)) 338 else if (g_str_equal(var, NS_DISCO_ITEMS))
343 } 343 }
344 } 344 }
345 345
346 if (service->type == XMPP_DISCO_SERVICE_TYPE_GATEWAY) 346 if (service->type == XMPP_DISCO_SERVICE_TYPE_GATEWAY)
347 service->gateway_type = g_strdup(disco_type_from_string( 347 service->gateway_type = g_strdup(disco_type_from_string(
348 xmlnode_get_attrib(identity, "type"))); 348 purple_xmlnode_get_attrib(identity, "type")));
349 349
350 pidgin_disco_add_service(list, service, service->parent); 350 pidgin_disco_add_service(list, service, service->parent);
351 } 351 }
352 352
353 out: 353 out:
360 pidgin_disco_list_unref(list); 360 pidgin_disco_list_unref(list);
361 } 361 }
362 362
363 static void 363 static void
364 got_items_cb(PurpleConnection *pc, const char *type, const char *id, 364 got_items_cb(PurpleConnection *pc, const char *type, const char *id,
365 const char *from, xmlnode *iq, gpointer data) 365 const char *from, PurpleXmlNode *iq, gpointer data)
366 { 366 {
367 struct item_data *item_data = data; 367 struct item_data *item_data = data;
368 PidginDiscoList *list = item_data->list; 368 PidginDiscoList *list = item_data->list;
369 xmlnode *query; 369 PurpleXmlNode *query;
370 gboolean has_items = FALSE; 370 gboolean has_items = FALSE;
371 371
372 --list->fetch_count; 372 --list->fetch_count;
373 373
374 if (!list->in_progress) 374 if (!list->in_progress)
375 goto out; 375 goto out;
376 376
377 if (g_str_equal(type, "result") && 377 if (g_str_equal(type, "result") &&
378 (query = xmlnode_get_child(iq, "query"))) { 378 (query = purple_xmlnode_get_child(iq, "query"))) {
379 xmlnode *item; 379 PurpleXmlNode *item;
380 380
381 for (item = xmlnode_get_child(query, "item"); item; 381 for (item = purple_xmlnode_get_child(query, "item"); item;
382 item = xmlnode_get_next_twin(item)) { 382 item = purple_xmlnode_get_next_twin(item)) {
383 const char *jid = xmlnode_get_attrib(item, "jid"); 383 const char *jid = purple_xmlnode_get_attrib(item, "jid");
384 const char *name = xmlnode_get_attrib(item, "name"); 384 const char *name = purple_xmlnode_get_attrib(item, "name");
385 const char *node = xmlnode_get_attrib(item, "node"); 385 const char *node = purple_xmlnode_get_attrib(item, "node");
386 386
387 has_items = TRUE; 387 has_items = TRUE;
388 388
389 if (item_data->parent->type == XMPP_DISCO_SERVICE_TYPE_CHAT) { 389 if (item_data->parent->type == XMPP_DISCO_SERVICE_TYPE_CHAT) {
390 /* This is a hacky first-order approximation. Any MUC 390 /* This is a hacky first-order approximation. Any MUC
430 pidgin_disco_list_unref(list); 430 pidgin_disco_list_unref(list);
431 } 431 }
432 432
433 static void 433 static void
434 server_items_cb(PurpleConnection *pc, const char *type, const char *id, 434 server_items_cb(PurpleConnection *pc, const char *type, const char *id,
435 const char *from, xmlnode *iq, gpointer data) 435 const char *from, PurpleXmlNode *iq, gpointer data)
436 { 436 {
437 struct item_data *cb_data = data; 437 struct item_data *cb_data = data;
438 PidginDiscoList *list = cb_data->list; 438 PidginDiscoList *list = cb_data->list;
439 xmlnode *query; 439 PurpleXmlNode *query;
440 440
441 g_free(cb_data); 441 g_free(cb_data);
442 --list->fetch_count; 442 --list->fetch_count;
443 443
444 if (g_str_equal(type, "result") && 444 if (g_str_equal(type, "result") &&
445 (query = xmlnode_get_child(iq, "query"))) { 445 (query = purple_xmlnode_get_child(iq, "query"))) {
446 xmlnode *item; 446 PurpleXmlNode *item;
447 447
448 for (item = xmlnode_get_child(query, "item"); item; 448 for (item = purple_xmlnode_get_child(query, "item"); item;
449 item = xmlnode_get_next_twin(item)) { 449 item = purple_xmlnode_get_next_twin(item)) {
450 const char *jid = xmlnode_get_attrib(item, "jid"); 450 const char *jid = purple_xmlnode_get_attrib(item, "jid");
451 const char *name = xmlnode_get_attrib(item, "name"); 451 const char *name = purple_xmlnode_get_attrib(item, "name");
452 const char *node = xmlnode_get_attrib(item, "node"); 452 const char *node = purple_xmlnode_get_attrib(item, "node");
453 struct item_data *item_data; 453 struct item_data *item_data;
454 454
455 if (!jid) 455 if (!jid)
456 continue; 456 continue;
457 457
472 pidgin_disco_list_unref(list); 472 pidgin_disco_list_unref(list);
473 } 473 }
474 474
475 static void 475 static void
476 server_info_cb(PurpleConnection *pc, const char *type, const char *id, 476 server_info_cb(PurpleConnection *pc, const char *type, const char *id,
477 const char *from, xmlnode *iq, gpointer data) 477 const char *from, PurpleXmlNode *iq, gpointer data)
478 { 478 {
479 struct item_data *cb_data = data; 479 struct item_data *cb_data = data;
480 PidginDiscoList *list = cb_data->list; 480 PidginDiscoList *list = cb_data->list;
481 xmlnode *query; 481 PurpleXmlNode *query;
482 xmlnode *error; 482 PurpleXmlNode *error;
483 gboolean items = FALSE; 483 gboolean items = FALSE;
484 484
485 --list->fetch_count; 485 --list->fetch_count;
486 486
487 if (g_str_equal(type, "result") && 487 if (g_str_equal(type, "result") &&
488 (query = xmlnode_get_child(iq, "query"))) { 488 (query = purple_xmlnode_get_child(iq, "query"))) {
489 xmlnode *feature; 489 PurpleXmlNode *feature;
490 490
491 for (feature = xmlnode_get_child(query, "feature"); feature; 491 for (feature = purple_xmlnode_get_child(query, "feature"); feature;
492 feature = xmlnode_get_next_twin(feature)) { 492 feature = purple_xmlnode_get_next_twin(feature)) {
493 const char *var = xmlnode_get_attrib(feature, "var"); 493 const char *var = purple_xmlnode_get_attrib(feature, "var");
494 if (purple_strequal(var, NS_DISCO_ITEMS)) { 494 if (purple_strequal(var, NS_DISCO_ITEMS)) {
495 items = TRUE; 495 items = TRUE;
496 break; 496 break;
497 } 497 }
498 } 498 }
506 pidgin_disco_list_set_in_progress(list, FALSE); 506 pidgin_disco_list_set_in_progress(list, FALSE);
507 g_free(cb_data); 507 g_free(cb_data);
508 } 508 }
509 } 509 }
510 else { 510 else {
511 error = xmlnode_get_child(iq, "error"); 511 error = purple_xmlnode_get_child(iq, "error");
512 if (xmlnode_get_child(error, "remote-server-not-found") 512 if (purple_xmlnode_get_child(error, "remote-server-not-found")
513 || xmlnode_get_child(error, "jid-malformed")) { 513 || purple_xmlnode_get_child(error, "jid-malformed")) {
514 purple_notify_error(my_plugin, _("Error"), 514 purple_notify_error(my_plugin, _("Error"),
515 _("Server does not exist"), 515 _("Server does not exist"),
516 NULL); 516 NULL);
517 } 517 }
518 else { 518 else {
565 service->expanded = TRUE; 565 service->expanded = TRUE;
566 } 566 }
567 567
568 void xmpp_disco_service_register(XmppDiscoService *service) 568 void xmpp_disco_service_register(XmppDiscoService *service)
569 { 569 {
570 xmlnode *iq, *query; 570 PurpleXmlNode *iq, *query;
571 char *id = generate_next_id(); 571 char *id = generate_next_id();
572 572
573 iq = xmlnode_new("iq"); 573 iq = purple_xmlnode_new("iq");
574 xmlnode_set_attrib(iq, "type", "get"); 574 purple_xmlnode_set_attrib(iq, "type", "get");
575 xmlnode_set_attrib(iq, "to", service->jid); 575 purple_xmlnode_set_attrib(iq, "to", service->jid);
576 xmlnode_set_attrib(iq, "id", id); 576 purple_xmlnode_set_attrib(iq, "id", id);
577 577
578 query = xmlnode_new_child(iq, "query"); 578 query = purple_xmlnode_new_child(iq, "query");
579 xmlnode_set_namespace(query, NS_REGISTER); 579 purple_xmlnode_set_namespace(query, NS_REGISTER);
580 580
581 purple_signal_emit(purple_connection_get_protocol(service->list->pc), 581 purple_signal_emit(purple_connection_get_protocol(service->list->pc),
582 "jabber-sending-xmlnode", service->list->pc, &iq); 582 "jabber-sending-xmlnode", service->list->pc, &iq);
583 if (iq != NULL) 583 if (iq != NULL)
584 xmlnode_free(iq); 584 purple_xmlnode_free(iq);
585 g_free(id); 585 g_free(id);
586 } 586 }
587 587
588 static void 588 static void
589 create_dialog(PurplePluginAction *action) 589 create_dialog(PurplePluginAction *action)

mercurial