Did most of //TODO
authorMyhailo Danylenko <isbear@ukrpost.net>
Sat, 31 Oct 2009 14:08:09 +0200
changeset 1 434f4b4ff37b
parent 0 1f40c28a4cc8
child 2 59145167eea0
Did most of //TODO
disco.c
--- 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: */