--- a/disco.c Sat Oct 31 01:43:26 2009 +0200
+++ b/disco.c Sat Oct 31 14:08:09 2009 +0200
@@ -29,38 +29,94 @@
#include "utils.h"
#include "xmpp.h"
#include "compl.h"
-
-#define DISCO_INFO_XMLNS ( "http:/" "/jabber.org/protocol/disco#info" )
-#define DISCO_ITEMS_XMLNS ( "http:/" "/jabber.org/protocol/disco#items" )
+#include "xmpp_defines.h"
+#include "screen.h"
+#include "hbuf.h"
-// TODO merge
-static LmHandlerResult disco_info_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer ignore)
+static LmHandlerResult disco_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer udata)
{
+ int info_request = (int) udata;
+
switch (lm_message_get_sub_type (message)) {
case LM_MESSAGE_SUB_TYPE_RESULT:
{
- LmMessageNode *node = lm_message_get_node (message);
- const gchar *from = lm_message_node_get_attribute (node, "from");
- const gchar *rnode;
+ LmMessageNode *node = lm_message_get_node (message);
+ const gchar *from = lm_message_node_get_attribute (node, "from");
+ GString *info;
+
node = lm_message_node_get_child (node, "query");
- // TODO check xmlns
- if (!node)
+
+ // check xmlns
+ if (!node || strcmp (lm_message_node_get_attribute (node, "xmlns"), info_request ? NS_DISCO_INFO : NS_DISCO_ITEMS))
break;
- rnode = lm_message_node_get_attribute (node, "node");
- // TODO print to buddy buffer
- scr_LogPrint (LPRINT_NORMAL, "Service discovery info results for %s (%s):", from, rnode ? rnode : "main");
- for (node = node->children; node; node = node->next) {
- if (!strcasecmp (node->name, "identity")) {
- const gchar *category = lm_message_node_get_attribute (node, "category");
- const gchar *type = lm_message_node_get_attribute (node, "type");
- const gchar *name = lm_message_node_get_attribute (node, "name");
- scr_LogPrint (LPRINT_NORMAL, "Identity: [%s (%s)] %s", category ? category : "none", type ? type : "none", name ? name : "");
- } else if (!strcasecmp (node->name, "feature")) {
- const gchar *var = lm_message_node_get_attribute (node, "var");
- scr_LogPrint (LPRINT_NORMAL, "Feature: [%s]", var ? var : "unset");
+
+ { // header for user message
+ const gchar *rnode = lm_message_node_get_attribute (node, "node");
+
+ // create user message string
+ info = g_string_new (NULL);
+ g_string_printf (info, "Service discovery %s results for %s", info_request ? "info" : "items", from);
+ if (rnode)
+ g_string_append_printf (info, " (%s):", rnode);
+ else
+ g_string_append (info, ":");
+ }
+
+ if (node->children) {
+ // parse request results
+ if (info_request) { // info
+ GString *identities = g_string_new (NULL);
+ GString *features = g_string_new (NULL);
+
+ for (node = node->children; node; node = node->next) {
+ if (!strcasecmp (node->name, "identity")) {
+ const gchar *category = lm_message_node_get_attribute (node, "category");
+ const gchar *type = lm_message_node_get_attribute (node, "type");
+ const gchar *name = lm_message_node_get_attribute (node, "name");
+
+ g_string_append_printf (identities, "\n [%s (%s)] %s", category ? category : "none", type ? type : "none", name ? name : "");
+
+ } else if (!strcasecmp (node->name, "feature")) {
+ const gchar *var = lm_message_node_get_attribute (node, "var");
+
+ g_string_append_printf (features, "\n [%s]", var ? var : "none");
+ }
+ }
+
+ if (identities->str)
+ g_string_append_printf (info, "\n Identities:%s", identities->str);
+ if (features->str)
+ g_string_append_printf (info, "\n Features:%s", features->str);
+
+ g_string_free (identities, TRUE);
+ g_string_free (features, TRUE);
+
+ } else { // items
+ for (node = node->children; node; node = node->next) {
+ const gchar *name = lm_message_node_get_attribute (node, "name");
+ const gchar *jid = lm_message_node_get_attribute (node, "jid");
+ const gchar *inode = lm_message_node_get_attribute (node, "node");
+
+ if (inode)
+ g_string_append_printf (info, "\n [%s (%s)] %s", jid ? jid : "none", inode, name ? name : "");
+ else
+ g_string_append_printf (info, "\n [%s] %s", jid ? jid : "none", name ? name : "");
+ }
}
+ } else
+ g_string_append (info, "\n Empty result.");
+
+ { // print to buddy's buffer
+ gchar *jid = jidtodisp (from);
+
+ // XXX check for message size? conference server lists may be huge...
+ scr_WriteIncomingMessage (jid, info->str, 0, HBB_PREFIX_INFO, 0); // NO conversion from utf-8
+
+ g_free (jid);
}
+
+ g_string_free (info, TRUE);
}
break;
@@ -68,9 +124,10 @@
case LM_MESSAGE_SUB_TYPE_ERROR:
{
- LmMessageNode *node = lm_message_get_node (message);
- const gchar *type;
- const gchar *reason;
+ LmMessageNode *node = lm_message_get_node (message);
+ const gchar *from = lm_message_node_get_attribute (node, "from");
+ const gchar *type;
+ const gchar *reason;
node = lm_message_node_get_child (node, "error");
type = lm_message_node_get_attribute (node, "type");
@@ -79,59 +136,15 @@
else
reason = "undefined";
- scr_LogPrint (LPRINT_LOGNORM, "Service info discovery failed: %s - %s", type, reason);
- }
-
- break;
-
- default:
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
- break;
- }
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
-}
-
-static LmHandlerResult disco_items_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer ignore)
-{
- switch (lm_message_get_sub_type (message)) {
- case LM_MESSAGE_SUB_TYPE_RESULT:
+ { // print to buddy's buffer
+ gchar *jid = jidtodisp (from);
+ gchar *mesg = g_strdup_printf ("Service %s discovery for %s failed: %s - %s", info_request ? "info" : "items", from, type, reason);
- {
- LmMessageNode *node = lm_message_get_node (message);
- const gchar *from = lm_message_node_get_attribute (node, "from");
- const gchar *rnode;
- node = lm_message_node_get_child (node, "query");
- // TODO check xmlns
- if (!node)
- break;
- rnode = lm_message_node_get_attribute (node, "node");
- // TODO print to buddy buffer
- scr_LogPrint (LPRINT_NORMAL, "Service discovery items results for %s (%s):", from, rnode ? rnode : "main");
- for (node = node->children; node; node = node->next) {
- const gchar *name = lm_message_node_get_attribute (node, "name");
- const gchar *jid = lm_message_node_get_attribute (node, "jid");
- scr_LogPrint (LPRINT_NORMAL, " [%s] %s", jid ? jid : "none", name ? name : "");
- }
- }
+ scr_WriteIncomingMessage (jid, mesg, 0, HBB_PREFIX_INFO, 0);
- break;
-
- case LM_MESSAGE_SUB_TYPE_ERROR:
-
- {
- LmMessageNode *node = lm_message_get_node (message);
- const gchar *type;
- const gchar *reason;
-
- node = lm_message_node_get_child (node, "error");
- type = lm_message_node_get_attribute (node, "type");
- if (node->children)
- reason = node->children->name;
- else
- reason = "undefined";
-
- scr_LogPrint (LPRINT_LOGNORM, "Service items discovery failed: %s - %s", type, reason);
+ g_free (mesg);
+ g_free (jid);
+ }
}
break;
@@ -149,9 +162,7 @@
char **args = split_arg (arg, 3, 0);
int info = -1;
- if (!args[0])
- scr_LogPrint (LPRINT_NORMAL, "Subcommand not specified!");
- else if (!strcmp (args[0], "info"))
+ if (!args[0] || !strcmp (args[0], "info"))
info = 1;
else if (!strcmp (args[0], "items"))
info = 0;
@@ -161,37 +172,49 @@
if (info != -1) {
LmMessageHandler *handler;
LmMessage *request;
- LmMessageNode *node;
- const char *to = NULL;
+ char *to = NULL;
char *dnode = NULL;
- if (args[1]) {
- if (strcmp (args[1], "."))
- to = args[1];
+ if (args[0] && args[1]) {
+ if (*args[1] == '.') {
+ if (*(args[1] + 1) == JID_RESOURCE_SEPARATOR) { // allow "./resource" notation
+ char *rest = to_utf8 (args[1] + 1);
+
+ to = g_strdup_printf ("%s%s", CURRENT_JID, rest);
+ g_free (rest);
+ }
+ } else
+ to = to_utf8 (args[1]);
if (args[2])
- dnode = args[2];
+ dnode = to_utf8 (args[2]);
+ }
+ // XXX send to all resources/current resource?
+
+ handler = lm_message_handler_new (disco_handler, (gpointer) info, NULL);
+
+ { // create message
+ LmMessageNode *node;
+
+ request = lm_message_new_with_sub_type (to ? to : CURRENT_JID, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET);
+ node = lm_message_get_node (request);
+ node = lm_message_node_add_child (node, "query", NULL);
+ lm_message_node_set_attribute (node, "xmlns", info ? NS_DISCO_INFO : NS_DISCO_ITEMS);
+ if (dnode)
+ lm_message_node_set_attribute (node, "node", dnode);
}
- if (!to)
- to = CURRENT_JID; // TODO: send to all resources?
-
- handler = lm_message_handler_new (info ? disco_info_handler : disco_items_handler, NULL, NULL);
+ lm_connection_send_with_reply (lconnection, request, handler, NULL);
- request = lm_message_new_with_sub_type (to, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET);
- node = lm_message_get_node (request);
- node = lm_message_node_add_child (node, "query", NULL);
- lm_message_node_set_attribute (node, "xmlns", info ? DISCO_INFO_XMLNS : DISCO_ITEMS_XMLNS);
- if (dnode)
- lm_message_node_set_attribute (node, "node", dnode);
-
- lm_connection_send_with_reply (lconnection, request, handler, NULL);
+ g_free (to);
+ g_free (dnode);
}
}
const gchar *g_module_check_init(GModule *module)
{
- // TODO: completion
+ // TODO completion
+
cmd_add ("disco", "", 0, COMPL_JID, do_disco, NULL);
return NULL;
}
@@ -201,3 +224,4 @@
cmd_del ("disco");
}
+/* vim: se ts=4: */