about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorPaul Fariello <paul@fariello.eu>2018-03-21 18:00:11 +0100
committerPaul Fariello <paul@fariello.eu>2018-09-05 13:42:28 +0200
commitca022ec75e12d28e6ce71447fe877b90518de310 (patch)
tree3110d9b72805ba0a9d3ab3c17a0ead21a745cbcb /src
parent82f77a92858cc265b83a064907b8f778962bd7a9 (diff)
downloadprofani-tty-ca022ec75e12d28e6ce71447fe877b90518de310.tar.gz
Add command command
Initial commit to test commands API
Diffstat (limited to 'src')
-rw-r--r--src/command/cmd_defs.c15
-rw-r--r--src/command/cmd_funcs.c23
-rw-r--r--src/command/cmd_funcs.h1
-rw-r--r--src/xmpp/iq.c22
-rw-r--r--src/xmpp/stanza.c22
-rw-r--r--src/xmpp/stanza.h4
-rw-r--r--src/xmpp/xmpp.h2
7 files changed, 89 insertions, 0 deletions
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 418155c4..c3ab395d 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2298,6 +2298,21 @@ static struct cmd_t command_defs[] =
         CMD_EXAMPLES(
             "/export /path/to/output.csv",
             "/export ~/contacts.csv")
+    },
+
+    { "/command",
+        parse_args, 1, 1, NULL,
+        CMD_NOSUBFUNCS
+        CMD_MAINFUNC(cmd_command)
+        CMD_NOTAGS
+        CMD_SYN(
+            "/command <cmd>")
+        CMD_DESC(
+            "Execute an ad hoc command")
+        CMD_ARGS(
+            { "<cmd>", "Command to be executed" })
+        CMD_EXAMPLES(
+            "/command ping")
     }
 };
 
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index c8aa22b4..048bdd6c 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -7469,6 +7469,29 @@ cmd_encwarn(ProfWin *window, const char *const command, gchar **args)
     return TRUE;
 }
 
+gboolean
+cmd_command(ProfWin *window, const char *const command, gchar **args)
+{
+    jabber_conn_status_t conn_status = connection_get_status();
+
+    if (conn_status != JABBER_CONNECTED) {
+        cons_show("You are not currently connected.");
+        return TRUE;
+    }
+
+    if (args[0] == NULL && connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) {
+        cons_show("Server does not support ad hoc commands.");
+        return TRUE;
+    }
+
+    ProfMucWin *mucwin = (ProfMucWin*)window;
+
+    iq_send_command(mucwin->roomjid, args[0]);
+
+    cons_show("Execute %s...", args[0]);
+    return TRUE;
+}
+
 static gboolean
 _cmd_execute(ProfWin *window, const char *const command, const char *const inp)
 {
diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h
index 0bbf338e..089d8227 100644
--- a/src/command/cmd_funcs.h
+++ b/src/command/cmd_funcs.h
@@ -158,6 +158,7 @@ gboolean cmd_script(ProfWin *window, const char *const command, gchar **args);
 gboolean cmd_export(ProfWin *window, const char *const command, gchar **args);
 gboolean cmd_charset(ProfWin *window, const char *const command, gchar **args);
 gboolean cmd_console(ProfWin *window, const char *const command, gchar **args);
+gboolean cmd_command(ProfWin *window, const char *const command, gchar **args);
 
 gboolean cmd_plugins(ProfWin *window, const char *const command, gchar **args);
 gboolean cmd_plugins_sourcepath(ProfWin *window, const char *const command, gchar **args);
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 0a5c100d..33400912 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -120,6 +120,7 @@ static int _caps_response_for_jid_id_handler(xmpp_stanza_t *const stanza, void *
 static int _caps_response_legacy_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
 static int _auto_pong_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
 static int _room_list_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
+static int _command_response_handler(xmpp_stanza_t *const stanza, void *const userdata);
 
 static void _iq_free_room_data(ProfRoomInfoData *roominfo);
 static void _iq_free_affiliation_set(ProfPrivilegeSet *affiliation_set);
@@ -696,6 +697,19 @@ iq_send_ping(const char *const target)
     xmpp_stanza_release(iq);
 }
 
+void
+iq_send_command(const char *const target, const char *const command)
+{
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_command_iq(ctx, target, command);
+    const char *id = xmpp_stanza_get_id(iq);
+
+    iq_id_handler_add(id, _command_response_handler, free, strdup(command));
+
+    iq_send_stanza(iq);
+    xmpp_stanza_release(iq);
+}
+
 static void
 _error_handler(xmpp_stanza_t *const stanza)
 {
@@ -1012,6 +1026,14 @@ _room_list_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
 }
 
 static int
+_command_response_handler(xmpp_stanza_t *const stanza, void *const userdata)
+{
+    cons_show("Plop", NULL);
+
+    return 0;
+}
+
+static int
 _enable_carbons_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
 {
     const char *type = xmpp_stanza_get_type(stanza);
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 82189ddd..ef4f8af4 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -2038,6 +2038,28 @@ stanza_parse_presence(xmpp_stanza_t *stanza, int *err)
     return result;
 }
 
+xmpp_stanza_t*
+stanza_create_command_iq(xmpp_ctx_t *ctx, const char *const target,
+    const char *const node)
+{
+    char *id = create_unique_id("command");
+    xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
+    free(id);
+    xmpp_stanza_set_to(iq, target);
+
+    xmpp_stanza_t *command = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(command, STANZA_NAME_COMMAND);
+
+    xmpp_stanza_set_ns(command, STANZA_NS_COMMAND);
+    xmpp_stanza_set_attribute(command, "node", node);
+    xmpp_stanza_set_attribute(command, "action", "execute");
+
+    xmpp_stanza_add_child(iq, command);
+    xmpp_stanza_release(command);
+
+    return iq;
+}
+
 static void
 _stanza_add_unique_id(xmpp_stanza_t *stanza, char *prefix)
 {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index bd161616..40461637 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -99,6 +99,7 @@
 #define STANZA_NAME_PUT "put"
 #define STANZA_NAME_GET "get"
 #define STANZA_NAME_URL "url"
+#define STANZA_NAME_COMMAND "command"
 
 // error conditions
 #define STANZA_NAME_BAD_REQUEST "bad-request"
@@ -186,6 +187,7 @@
 #define STANZA_NS_HTTP_UPLOAD "urn:xmpp:http:upload"
 #define STANZA_NS_X_OOB "jabber:x:oob"
 #define STANZA_NS_BLOCKING "urn:xmpp:blocking"
+#define STANZA_NS_COMMAND "http://jabber.org/protocol/commands"
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
@@ -278,6 +280,8 @@ xmpp_stanza_t* stanza_create_room_subject_message(xmpp_ctx_t *ctx, const char *c
 xmpp_stanza_t* stanza_create_room_kick_iq(xmpp_ctx_t *const ctx, const char *const room, const char *const nick,
     const char *const reason);
 
+xmpp_stanza_t* stanza_create_command_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node);
+
 int stanza_get_idle_time(xmpp_stanza_t *const stanza);
 
 void stanza_attach_priority(xmpp_ctx_t *const ctx, xmpp_stanza_t *const presence, const int pri);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index d4a29196..2e7d1a25 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -60,6 +60,7 @@
 #define XMPP_FEATURE_RECEIPTS "urn:xmpp:receipts"
 #define XMPP_FEATURE_LASTACTIVITY "jabber:iq:last"
 #define XMPP_FEATURE_MUC "http://jabber.org/protocol/muc"
+#define XMPP_FEATURE_COMMANDS "http://jabber.org/protocol/commands"
 
 typedef enum {
     JABBER_CONNECTING,
@@ -182,6 +183,7 @@ void iq_room_role_set(const char *const room, const char *const nick, char *role
 void iq_room_role_list(const char * const room, char *role);
 void iq_autoping_check(void);
 void iq_http_upload_request(HTTPUpload *upload);
+void iq_send_command(const char *const target, const char *const command);
 
 EntityCapabilities* caps_lookup(const char *const jid);
 void caps_close(void);