about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c54
-rw-r--r--src/xmpp/iq.c42
-rw-r--r--src/xmpp/presence.c6
-rw-r--r--src/xmpp/stanza.c6
-rw-r--r--src/xmpp/stanza.h2
-rw-r--r--src/xmpp/xmpp.h2
6 files changed, 92 insertions, 20 deletions
diff --git a/src/command/command.c b/src/command/command.c
index b5f8fe40..037b0a3d 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -102,6 +102,7 @@ static gboolean _cmd_close(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_clear(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_join(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_rooms(gchar **args, struct cmd_help_t help);
+static gboolean _cmd_disco(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_set_beep(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_set_notify(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_set_log(gchar **args, struct cmd_help_t help);
@@ -337,10 +338,10 @@ static struct cmd_t main_commands[] =
 
     { "/rooms",
         _cmd_rooms, parse_args, 0, 1,
-        { "/rooms [conference-node]", "List chat rooms.",
-        { "/rooms [conference-node]",
-          "------------------------",
-          "List the chat rooms available at the specified conference node",
+        { "/rooms [conference-service]", "List chat rooms.",
+        { "/rooms [conference-service]",
+          "---------------------------",
+          "List the chat rooms available at the specified conference service",
           "If no argument is supplied, the domainpart of the current logged in JID is used,",
           "with a prefix of 'conference'.",
           "",
@@ -348,6 +349,24 @@ static struct cmd_t main_commands[] =
           "Example : /rooms (if logged in as me@server.org, is equivalent to /rooms conference.server.org)",
           NULL } } },
 
+    { "/disco",
+        _cmd_disco, parse_args, 2, 2,
+        { "/disco command entity", "Service discovery.",
+        { "/disco command entity",
+          "---------------------",
+          "Find out information about an entities supported services.",
+          "Command may be one of:",
+          "info: List protocols and features supported by an entity.",
+          "items: List items associated with an entity.",
+          "",
+          "The entity must be a Jabber ID.",
+          "",
+          "Example : /disco info myserver.org",
+          "Example : /disco items myserver.org",
+          "Example : /disco items conference.jabber.org",
+          "Example : /disco info myfriend@server.com/laptop",
+          NULL } } },
+
     { "/nick",
         _cmd_nick, parse_args_with_freetext, 1, 1,
         { "/nick nickname", "Change nickname in chat room.",
@@ -717,6 +736,7 @@ static Autocomplete titlebar_ac;
 static Autocomplete theme_ac;
 static Autocomplete theme_load_ac;
 static Autocomplete account_ac;
+static Autocomplete disco_ac;
 
 /*
  * Initialise command autocompleter and history
@@ -779,6 +799,10 @@ cmd_init(void)
     autocomplete_add(theme_ac, strdup("list"));
     autocomplete_add(theme_ac, strdup("set"));
 
+    disco_ac = autocomplete_new();
+    autocomplete_add(disco_ac, strdup("info"));
+    autocomplete_add(disco_ac, strdup("items"));
+
     account_ac = autocomplete_new();
     autocomplete_add(account_ac, strdup("list"));
     autocomplete_add(account_ac, strdup("show"));
@@ -834,6 +858,7 @@ cmd_close(void)
         autocomplete_free(theme_load_ac);
     }
     autocomplete_free(account_ac);
+    autocomplete_free(disco_ac);
 }
 
 // Command autocompletion functions
@@ -896,6 +921,7 @@ cmd_reset_autocomplete()
         theme_load_ac = NULL;
     }
     autocomplete_reset(account_ac);
+    autocomplete_reset(disco_ac);
 }
 
 GSList *
@@ -1056,6 +1082,7 @@ _cmd_complete_parameters(char *input, int *size)
     _parameter_autocomplete_with_ac(input, size, "/who", who_ac);
     _parameter_autocomplete_with_ac(input, size, "/prefs", prefs_ac);
     _parameter_autocomplete_with_ac(input, size, "/log", log_ac);
+    _parameter_autocomplete_with_ac(input, size, "/disco", disco_ac);
 
     _notify_autocomplete(input, size);
     _autoaway_autocomplete(input, size);
@@ -2095,6 +2122,25 @@ _cmd_rooms(gchar **args, struct cmd_help_t help)
 }
 
 static gboolean
+_cmd_disco(gchar **args, struct cmd_help_t help)
+{
+    jabber_conn_status_t conn_status = jabber_get_connection_status();
+
+    if (conn_status != JABBER_CONNECTED) {
+        cons_show("You are currenlty connect.");
+        return TRUE;
+    }
+
+    if (g_strcmp0(args[0], "info") == 0) {
+        iq_disco_info_request(args[1]);
+    } else {
+        iq_disco_items_request(args[1]);
+    }
+
+    return TRUE;
+}
+
+static gboolean
 _cmd_nick(gchar **args, struct cmd_help_t help)
 {
     jabber_conn_status_t conn_status = jabber_get_connection_status();
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 67db8d22..7470abeb 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -99,6 +99,26 @@ iq_room_list_request(gchar *conferencejid)
 }
 
 void
+iq_disco_info_request(gchar *jid)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, "discoinforeq", jid, NULL);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+void
+iq_disco_items_request(gchar *jid)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq", jid);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+void
 iq_send_software_version(const char * const fulljid)
 {
     xmpp_conn_t * const conn = connection_get_conn();
@@ -353,7 +373,9 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan
     log_debug("Recieved diso#info response");
     const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
 
-    if ((id != NULL) && (g_str_has_prefix(id, "disco"))) {
+    if ((id != NULL) && (g_strcmp0(id, "discoinforeq") == 0)) {
+        cons_show("GOT DISO INFO RESULT");
+    } else if ((id != NULL) && (g_str_has_prefix(id, "disco"))) {
         log_debug("Response to query: %s", id);
         xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
         char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
@@ -457,18 +479,15 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan
 
         //stanza_destroy_form(form);
         free(caps_key);
-
-        return 1;
-    } else {
-        return 1;
     }
+
+    return 1;
 }
 
 static int
 _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     void * const userdata)
 {
-    GSList *rooms = NULL;
 
     log_debug("Recieved diso#items response");
     const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
@@ -476,8 +495,9 @@ _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const sta
 
     if ((id != NULL) && (g_strcmp0(id, "confreq") == 0)) {
         log_debug("Response to query: %s", id);
-
+        GSList *rooms = NULL;
         xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
+
         if (query != NULL) {
             xmpp_stanza_t *child = xmpp_stanza_get_children(query);
             while (child != NULL) {
@@ -492,10 +512,12 @@ _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const sta
                 child = xmpp_stanza_get_next(child);
             }
         }
-    }
 
-    prof_handle_room_list(rooms, from);
-    g_slist_free_full(rooms, free);
+        prof_handle_room_list(rooms, from);
+        g_slist_free_full(rooms, free);
+    } else if ((id != NULL) && (g_strcmp0(id, "discoitemsreq") == 0)) {
+        cons_show("GOT DISO ITEMS RESULT");
+    }
 
     return 1;
 }
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 8c5240e6..ae3af79b 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -484,7 +484,7 @@ _get_caps_key(xmpp_stanza_t * const stanza)
                     log_debug("Node string: %s.", node);
                     if (!caps_contains(caps_key)) {
                         log_debug("Capabilities not cached for '%s', sending discovery IQ.", caps_key);
-                        xmpp_stanza_t *iq = stanza_create_disco_iq(ctx, "disco", from, node);
+                        xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, "disco", from, node);
                         xmpp_send(conn, iq);
                         xmpp_stanza_release(iq);
                     } else {
@@ -509,7 +509,7 @@ _get_caps_key(xmpp_stanza_t * const stanza)
                         log_debug("Capabilities not cached for '%s', sending discovery IQ.", from);
                         GString *id = g_string_new("disco_");
                         g_string_append(id, from_hash_str);
-                        xmpp_stanza_t *iq = stanza_create_disco_iq(ctx, id->str, from, node);
+                        xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id->str, from, node);
                         xmpp_send(conn, iq);
                         xmpp_stanza_release(iq);
                         g_string_free(id, TRUE);
@@ -538,7 +538,7 @@ _get_caps_key(xmpp_stanza_t * const stanza)
                     log_debug("Capabilities not cached for '%s', sending discovery IQ.", from);
                     GString *id = g_string_new("disco_");
                     g_string_append(id, from_hash_str);
-                    xmpp_stanza_t *iq = stanza_create_disco_iq(ctx, id->str, from, node);
+                    xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id->str, from, node);
                     xmpp_send(conn, iq);
                     xmpp_stanza_release(iq);
                     g_string_free(id, TRUE);
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 34f9d784..7b6778e3 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -178,7 +178,7 @@ stanza_create_roster_iq(xmpp_ctx_t *ctx)
 }
 
 xmpp_stanza_t *
-stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id, const char * const to,
+stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const id, const char * const to,
     const char * const node)
 {
     xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
@@ -190,7 +190,9 @@ stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id, const char * cons
     xmpp_stanza_t *query = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
     xmpp_stanza_set_ns(query, XMPP_NS_DISCO_INFO);
-    xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node);
+    if (node != NULL) {
+        xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node);
+    }
 
     xmpp_stanza_add_child(iq, query);
     xmpp_stanza_release(query);
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 18f9b045..d6fb777a 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -126,7 +126,7 @@ xmpp_stanza_t* stanza_create_presence(xmpp_ctx_t * const ctx);
 
 xmpp_stanza_t* stanza_create_roster_iq(xmpp_ctx_t *ctx);
 xmpp_stanza_t* stanza_create_ping_iq(xmpp_ctx_t *ctx);
-xmpp_stanza_t* stanza_create_disco_iq(xmpp_ctx_t *ctx, const char * const id,
+xmpp_stanza_t* stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const id,
     const char * const to, const char * const node);
 
 gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index ba8c1a2f..16e293a4 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -93,6 +93,8 @@ void presence_update(resource_presence_t status, const char * const msg,
 // iq functions
 void iq_send_software_version(const char * const fulljid);
 void iq_room_list_request(gchar *conferencejid);
+void iq_disco_info_request(gchar *jid);
+void iq_disco_items_request(gchar *jid);
 
 // caps functions
 Capabilities* caps_get(const char * const caps_str);