From ca022ec75e12d28e6ce71447fe877b90518de310 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 21 Mar 2018 18:00:11 +0100 Subject: Add command command Initial commit to test commands API --- src/command/cmd_defs.c | 15 +++++++++++++++ src/command/cmd_funcs.c | 23 +++++++++++++++++++++++ src/command/cmd_funcs.h | 1 + src/xmpp/iq.c | 22 ++++++++++++++++++++++ src/xmpp/stanza.c | 22 ++++++++++++++++++++++ src/xmpp/stanza.h | 4 ++++ src/xmpp/xmpp.h | 2 ++ 7 files changed, 89 insertions(+) (limited to 'src') 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_DESC( + "Execute an ad hoc command") + CMD_ARGS( + { "", "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) { @@ -1011,6 +1025,14 @@ _room_list_id_handler(xmpp_stanza_t *const stanza, void *const userdata) return 0; } +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) { 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); -- cgit 1.4.1-2-gfad0 From c9f6a78f574ce2a90ae7871a08a5ddcfb9ab7270 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Thu, 22 Mar 2018 04:47:52 +0220 Subject: Add command subcommands: list and exec Also handle list result --- src/command/cmd_defs.c | 21 ++++++---- src/command/cmd_funcs.c | 29 ++++++++++++-- src/command/cmd_funcs.h | 3 +- src/ui/ui.h | 2 + src/ui/window.c | 28 +++++++++++++ src/xmpp/iq.c | 85 +++++++++++++++++++++++++++++++++++----- src/xmpp/stanza.c | 7 +++- src/xmpp/stanza.h | 4 +- src/xmpp/xmpp.h | 3 +- tests/unittests/xmpp/stub_xmpp.c | 2 + 10 files changed, 158 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index c3ab395d..14e49b47 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2300,19 +2300,24 @@ static struct cmd_t command_defs[] = "/export ~/contacts.csv") }, - { "/command", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS - CMD_MAINFUNC(cmd_command) + { "/cmd", + parse_args, 1, 3, NULL, + CMD_SUBFUNCS( + { "list", cmd_command_list }, + { "exec", cmd_command_exec }) + CMD_NOMAINFUNC CMD_NOTAGS CMD_SYN( - "/command ") + "/otr list", + "/otr exec ") CMD_DESC( - "Execute an ad hoc command") + "Execute ad hoc commands.") CMD_ARGS( - { "", "Command to be executed" }) + { "list", "List supported ad hoc commands." }, + { "exec ", "Execute a command." }) CMD_EXAMPLES( - "/command ping") + "/cmd list", + "/cmd exec ping") } }; diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 048bdd6c..2e606ef5 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7470,7 +7470,7 @@ cmd_encwarn(ProfWin *window, const char *const command, gchar **args) } gboolean -cmd_command(ProfWin *window, const char *const command, gchar **args) +cmd_command_list(ProfWin *window, const char *const command, gchar **args) { jabber_conn_status_t conn_status = connection_get_status(); @@ -7479,14 +7479,37 @@ cmd_command(ProfWin *window, const char *const command, gchar **args) return TRUE; } - if (args[0] == NULL && connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) { + if (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]); + iq_command_list(mucwin->roomjid); + + cons_show("List available ad hoc commands"); + return TRUE; +} + +gboolean +cmd_command_exec(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 (connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) { + cons_show("Server does not support ad hoc commands."); + return TRUE; + } + + ProfMucWin *mucwin = (ProfMucWin*)window; + + iq_command_exec(mucwin->roomjid, args[0]); cons_show("Execute %s...", args[0]); return TRUE; diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index 089d8227..5b909fed 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -158,7 +158,8 @@ 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_command_list(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_command_exec(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/ui/ui.h b/src/ui/ui.h index d344f855..f1d8161f 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -377,6 +377,8 @@ void win_show_info(ProfWin *window, PContact contact); void win_clear(ProfWin *window); char* win_get_tab_identifier(ProfWin *window); char* win_to_string(ProfWin *window); +void win_command_list_error(ProfWin *window, const char *const error); +void win_handle_command_list(ProfWin *window, GSList *cmds); // desktop notifications void notifier_initialise(void); diff --git a/src/ui/window.c b/src/ui/window.c index 5543707d..3ba6b387 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1724,3 +1724,31 @@ win_sub_newline_lazy(WINDOW *win) wmove(win, cury+1, 0); } } + +void +win_command_list_error(ProfWin *window, const char *const error) +{ + assert(window != NULL); + + win_println(window, THEME_ERROR, '!', "Error retrieving command list: %s", error); +} + +void +win_handle_command_list(ProfWin *window, GSList *cmds) +{ + assert(window != NULL); + + if (cmds) { + win_println(window, THEME_DEFAULT, '!', "Ad hoc commands:"); + GSList *curr_cmd = cmds; + while (curr_cmd) { + const char *cmd = curr_cmd->data; + win_println(window, THEME_DEFAULT, '!', " %s", cmd); + curr_cmd = g_slist_next(curr_cmd); + } + win_println(window, THEME_DEFAULT, '!', ""); + } else { + win_println(window, THEME_DEFAULT, '!', "No commands found"); + win_println(window, THEME_DEFAULT, '!', ""); + } +} diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 33400912..ad7ef54d 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -120,7 +120,8 @@ 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 int _command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata); +static int _command_exec_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); @@ -320,7 +321,7 @@ iq_room_list_request(gchar *conferencejid, gchar *filter) xmpp_ctx_t * const ctx = connection_get_ctx(); char *id = connection_create_stanza_id("confreq"); - xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, conferencejid); + xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, conferencejid, NULL); iq_id_handler_add(id, _room_list_id_handler, NULL, filter); @@ -522,7 +523,7 @@ void iq_disco_items_request(gchar *jid) { xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq", jid); + xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq", jid, NULL); iq_send_stanza(iq); xmpp_stanza_release(iq); } @@ -531,7 +532,7 @@ void iq_disco_items_request_onconnect(gchar *jid) { xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq_onconnect", jid); + xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq_onconnect", jid, NULL); iq_send_stanza(iq); xmpp_stanza_release(iq); } @@ -698,13 +699,26 @@ iq_send_ping(const char *const target) } void -iq_send_command(const char *const target, const char *const command) +iq_command_list(const char *const target) { xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *iq = stanza_create_command_iq(ctx, target, command); + const char *id = connection_create_stanza_id("cmdlist"); + xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, target, STANZA_NS_COMMAND); + + iq_id_handler_add(id, _command_list_result_handler, NULL, NULL); + + iq_send_stanza(iq); + xmpp_stanza_release(iq); +} + +void +iq_command_exec(const char *const target, const char *const command) +{ + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_create_command_exec_iq(ctx, target, command); const char *id = xmpp_stanza_get_id(iq); - iq_id_handler_add(id, _command_response_handler, free, strdup(command)); + iq_id_handler_add(id, _command_exec_response_handler, free, strdup(command)); iq_send_stanza(iq); xmpp_stanza_release(iq); @@ -1026,9 +1040,62 @@ _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) +_command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata) +{ + const char *id = xmpp_stanza_get_id(stanza); + const char *type = xmpp_stanza_get_type(stanza); + char *from = strdup(xmpp_stanza_get_from(stanza)); + + if (id) { + log_debug("IQ command list result handler fired, id: %s.", id); + } else { + log_debug("IQ command list result handler fired."); + } + + // handle error responses + if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { + char *error_message = stanza_get_error_message(stanza); + log_debug("Error retrieving command list for %s: %s", from, error_message); + ProfWin *win = wins_get_by_string(from); + if (win) { + win_command_list_error(win, error_message); + } + free(error_message); + free(from); + return 0; + } + + GSList *cmds = NULL; + + xmpp_stanza_t *query = xmpp_stanza_get_child_by_ns(stanza, XMPP_NS_DISCO_ITEMS); + if (query) { + xmpp_stanza_t *child = xmpp_stanza_get_children(query); + while (child) { + const char *name = xmpp_stanza_get_name(child); + if (g_strcmp0(name, "item") == 0) { + const char *node = xmpp_stanza_get_attribute(child, STANZA_ATTR_NODE); + if (node) { + cmds = g_slist_insert_sorted(cmds, (gpointer)node, (GCompareFunc)g_strcmp0); + } + } + child = xmpp_stanza_get_next(child); + } + } + + ProfWin *win = wins_get_by_string(from); + if (win) { + win_handle_command_list(win, cmds); + } + g_slist_free(cmds); + free(from); + + return 0; +} + +static int +_command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata) { - cons_show("Plop", NULL); + cons_show("%s", NULL, __func__); return 0; } diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index ef4f8af4..cc842ff6 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -924,7 +924,7 @@ stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char *const id, const char *c xmpp_stanza_t* stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, - const char *const jid) + const char *const jid, const char *const node) { xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id); xmpp_stanza_set_to(iq, jid); @@ -932,6 +932,9 @@ stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, xmpp_stanza_t *query = xmpp_stanza_new(ctx); xmpp_stanza_set_name(query, STANZA_NAME_QUERY); xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS); + if (node) { + xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node); + } xmpp_stanza_add_child(iq, query); xmpp_stanza_release(query); @@ -2039,7 +2042,7 @@ stanza_parse_presence(xmpp_stanza_t *stanza, int *err) } xmpp_stanza_t* -stanza_create_command_iq(xmpp_ctx_t *ctx, const char *const target, +stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node) { char *id = create_unique_id("command"); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 40461637..a3cf2c4c 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -280,7 +280,7 @@ 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); +xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node); int stanza_get_idle_time(xmpp_stanza_t *const stanza); @@ -296,7 +296,7 @@ EntityCapabilities* stanza_create_caps_from_query_element(xmpp_stanza_t *query); const char* stanza_get_presence_string_from_type(resource_presence_t presence_type); xmpp_stanza_t* stanza_create_software_version_iq(xmpp_ctx_t *ctx, const char *const fulljid); -xmpp_stanza_t* stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, const char *const jid); +xmpp_stanza_t* stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, const char *const jid, const char *const node); char* stanza_get_status(xmpp_stanza_t *stanza, char *def); char* stanza_get_show(xmpp_stanza_t *stanza, char *def); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 2e7d1a25..c0e1477d 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -183,7 +183,8 @@ 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); +void iq_command_list(const char *const target); +void iq_command_exec(const char *const target, const char *const command); EntityCapabilities* caps_lookup(const char *const jid); void caps_close(void); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 45db6649..5590a8e1 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -205,6 +205,8 @@ void iq_room_role_list(const char * const room, char *role) {} void iq_last_activity_request(gchar *jid) {} void iq_autoping_check(void) {} void iq_rooms_cache_clear(void) {} +void iq_command_list(const char *const target) {} +void iq_command_exec(const char *const target, const char *const command) {} // caps functions void caps_add_feature(char *feature) {} -- cgit 1.4.1-2-gfad0 From 925cd488c1397c960bc1eec0e441f073d887162e Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Thu, 22 Mar 2018 22:21:15 +0220 Subject: Handle simple execution Tested with ping from biboumi --- src/command/cmd_funcs.c | 4 ++-- src/ui/ui.h | 1 + src/ui/window.c | 7 +++++++ src/xmpp/iq.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- src/xmpp/stanza.c | 2 +- src/xmpp/stanza.h | 1 + 6 files changed, 60 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 2e606ef5..dc112d85 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7509,9 +7509,9 @@ cmd_command_exec(ProfWin *window, const char *const command, gchar **args) ProfMucWin *mucwin = (ProfMucWin*)window; - iq_command_exec(mucwin->roomjid, args[0]); + iq_command_exec(mucwin->roomjid, args[1]); - cons_show("Execute %s...", args[0]); + cons_show("Execute %s...", args[1]); return TRUE; } diff --git a/src/ui/ui.h b/src/ui/ui.h index f1d8161f..fa8f948a 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -379,6 +379,7 @@ char* win_get_tab_identifier(ProfWin *window); char* win_to_string(ProfWin *window); void win_command_list_error(ProfWin *window, const char *const error); void win_handle_command_list(ProfWin *window, GSList *cmds); +void win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value); // desktop notifications void notifier_initialise(void); diff --git a/src/ui/window.c b/src/ui/window.c index 3ba6b387..f38127d7 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1752,3 +1752,10 @@ win_handle_command_list(ProfWin *window, GSList *cmds) win_println(window, THEME_DEFAULT, '!', ""); } } + +void +win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value) +{ + assert(window != NULL); + win_println(window, THEME_DEFAULT, '!', value); +} diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index ad7ef54d..8702d1a1 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1095,7 +1095,54 @@ _command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata) static int _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata) { - cons_show("%s", NULL, __func__); + const char *id = xmpp_stanza_get_id(stanza); + const char *type = xmpp_stanza_get_type(stanza); + char *from = strdup(xmpp_stanza_get_from(stanza)); + const char *const command = userdata; + + if (id) { + log_debug("IQ command exec response handler fired, id: %s.", id); + } else { + log_debug("IQ command exec response handler fired."); + } + + // handle error responses + if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { + char *error_message = stanza_get_error_message(stanza); + log_debug("Error executing command %s for %s: %s", command, from, error_message); + ProfWin *win = wins_get_by_string(from); + if (win) { + win_command_list_error(win, error_message); + } + free(error_message); + free(from); + return 0; + } + + xmpp_stanza_t *cmd = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_COMMAND); + if (!cmd) { + /* TODO */ + } + + ProfWin *win = wins_get_by_string(from); + + const char *status = xmpp_stanza_get_attribute(cmd, STANZA_ATTR_STATUS); + if (g_strcmp0(status, "completed") == 0) { + if (win) { + xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note"); + if (note) { + const char *type = xmpp_stanza_get_attribute(note, "type"); + const char *value = xmpp_stanza_get_text(note); + win_handle_command_exec_result_note(win, type, value); + } + } + } else if (g_strcmp0(status, "executing") == 0) { + } else if (g_strcmp0(status, "canceled") == 0) { + } else { + /* TODO */ + } + + free(from); return 0; } diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index cc842ff6..537fbf96 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2045,7 +2045,7 @@ xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node) { - char *id = create_unique_id("command"); + char *id = connection_create_stanza_id("cmdexec"); xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); free(id); xmpp_stanza_set_to(iq, target); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index a3cf2c4c..5f8203a2 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -157,6 +157,7 @@ #define STANZA_ATTR_REASON "reason" #define STANZA_ATTR_AUTOJOIN "autojoin" #define STANZA_ATTR_PASSWORD "password" +#define STANZA_ATTR_STATUS "status" #define STANZA_TEXT_AWAY "away" #define STANZA_TEXT_DND "dnd" -- cgit 1.4.1-2-gfad0 From 40eee1caabde94cc6bab82e9c583d4c1cc45c4c6 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Fri, 23 Mar 2018 21:09:48 +0220 Subject: Add command exec error handling --- src/ui/ui.h | 1 + src/ui/window.c | 15 +++++++++++++++ src/xmpp/iq.c | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/ui.h b/src/ui/ui.h index fa8f948a..6988d882 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -378,6 +378,7 @@ void win_clear(ProfWin *window); char* win_get_tab_identifier(ProfWin *window); char* win_to_string(ProfWin *window); void win_command_list_error(ProfWin *window, const char *const error); +void win_command_exec_error(ProfWin *window, const char *const command, const char *const error, ...); void win_handle_command_list(ProfWin *window, GSList *cmds); void win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value); diff --git a/src/ui/window.c b/src/ui/window.c index f38127d7..a6f65d1b 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1733,6 +1733,21 @@ win_command_list_error(ProfWin *window, const char *const error) win_println(window, THEME_ERROR, '!', "Error retrieving command list: %s", error); } +void +win_command_exec_error(ProfWin *window, const char *const command, const char *const error, ...) +{ + assert(window != NULL); + va_list arg; + va_start(arg, error); + GString *msg = g_string_new(NULL); + g_string_vprintf(msg, error, arg); + + win_println(window, THEME_ERROR, '!', "Error executing command %s: %s", command, msg); + + g_string_free(msg, TRUE); + va_end(arg); +} + void win_handle_command_list(ProfWin *window, GSList *cmds) { diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 8702d1a1..dd856298 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1112,7 +1112,7 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata log_debug("Error executing command %s for %s: %s", command, from, error_message); ProfWin *win = wins_get_by_string(from); if (win) { - win_command_list_error(win, error_message); + win_command_exec_error(win, command, error_message); } free(error_message); free(from); -- cgit 1.4.1-2-gfad0 From 7123e94e82e1408b9abab1a9043617f58d396849 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Fri, 23 Mar 2018 21:10:10 +0220 Subject: Add support for form edition in command execution Also change wins_get_by_string prototype in order to handle const str. --- src/ui/window_list.c | 2 +- src/ui/window_list.h | 2 +- src/xmpp/iq.c | 31 ++++++++++++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/window_list.c b/src/ui/window_list.c index 798f4e41..e408a2ac 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -364,7 +364,7 @@ wins_get_by_num(int i) } ProfWin* -wins_get_by_string(char *str) +wins_get_by_string(const char *str) { if (g_strcmp0(str, "console") == 0) { ProfWin *conswin = wins_get_console(); diff --git a/src/ui/window_list.h b/src/ui/window_list.h index 68e72739..ba62ad32 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -68,7 +68,7 @@ ProfWin* wins_get_current(void); void wins_set_current_by_num(int i); ProfWin* wins_get_by_num(int i); -ProfWin* wins_get_by_string(char *str); +ProfWin* wins_get_by_string(const char *str); ProfWin* wins_get_next(void); ProfWin* wins_get_previous(void); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index dd856298..f5bacddd 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1097,7 +1097,7 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata { const char *id = xmpp_stanza_get_id(stanza); const char *type = xmpp_stanza_get_type(stanza); - char *from = strdup(xmpp_stanza_get_from(stanza)); + const char *from = xmpp_stanza_get_from(stanza); const char *const command = userdata; if (id) { @@ -1115,7 +1115,6 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata win_command_exec_error(win, command, error_message); } free(error_message); - free(from); return 0; } @@ -1136,13 +1135,31 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata win_handle_command_exec_result_note(win, type, value); } } - } else if (g_strcmp0(status, "executing") == 0) { - } else if (g_strcmp0(status, "canceled") == 0) { - } else { - /* TODO */ + return 0; } - free(from); + if (g_strcmp0(status, "executing") == 0) { + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA); + if (x == NULL) { + /* TODO */ + return 0; + } + + const char *form_type = xmpp_stanza_get_type(x); + if (g_strcmp0(form_type, "form") != 0) { + /* TODO */ + return 0; + } + + DataForm *form = form_create(x); + ProfMucConfWin *confwin = (ProfMucConfWin*)wins_new_muc_config(from, form); + mucconfwin_handle_configuration(confwin, form); + } + + if (g_strcmp0(status, "canceled") == 0) { + } + + /* TODO */ return 0; } -- cgit 1.4.1-2-gfad0 From a952776b899dd29056ad6779b14dab75a4125924 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 11 Apr 2018 22:17:50 +0520 Subject: Rename mucconf wins into conf wins Configuration windows are now being used by both muc and cmd. --- Makefile.am | 2 +- src/command/cmd_ac.c | 16 +- src/command/cmd_defs.c | 8 +- src/command/cmd_funcs.c | 80 ++++----- src/config/preferences.c | 10 +- src/config/preferences.h | 2 +- src/config/theme.c | 2 +- src/ui/confwin.c | 348 +++++++++++++++++++++++++++++++++++++++ src/ui/console.c | 10 +- src/ui/core.c | 20 +-- src/ui/mucconfwin.c | 348 --------------------------------------- src/ui/statusbar.c | 2 +- src/ui/ui.h | 16 +- src/ui/win_types.h | 6 +- src/ui/window.c | 34 ++-- src/ui/window_list.c | 16 +- src/ui/window_list.h | 4 +- src/xmpp/iq.c | 8 +- tests/functionaltests/proftest.c | 4 +- tests/unittests/test_cmd_pgp.c | 4 +- tests/unittests/test_cmd_pgp.h | 2 +- tests/unittests/ui/stub_ui.c | 12 +- tests/unittests/unittests.c | 2 +- theme_template | 2 +- themes/bios | 2 +- themes/boothj5 | 2 +- themes/boothj5_laptop | 2 +- themes/boothj5_slack | 2 +- themes/complex | 2 +- themes/simple | 2 +- 30 files changed, 485 insertions(+), 485 deletions(-) create mode 100644 src/ui/confwin.c delete mode 100644 src/ui/mucconfwin.c (limited to 'src') diff --git a/Makefile.am b/Makefile.am index fd278140..222b4905 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,7 @@ core_sources = \ src/ui/chatwin.c \ src/ui/mucwin.c \ src/ui/privwin.c \ - src/ui/mucconfwin.c \ + src/ui/confwin.c \ src/ui/xmlwin.c \ src/command/cmd_defs.h src/command/cmd_defs.c \ src/command/cmd_funcs.h src/command/cmd_funcs.c \ diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index f9d5a22a..7a340e7f 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -664,7 +664,7 @@ cmd_ac_init(void) autocomplete_add(time_ac, "console"); autocomplete_add(time_ac, "chat"); autocomplete_add(time_ac, "muc"); - autocomplete_add(time_ac, "mucconfig"); + autocomplete_add(time_ac, "config"); autocomplete_add(time_ac, "private"); autocomplete_add(time_ac, "xml"); autocomplete_add(time_ac, "statusbar"); @@ -1107,8 +1107,8 @@ cmd_ac_reset(ProfWin *window) muc_jid_autocomplete_reset(mucwin->roomjid); } - if (window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + if (window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)window; assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); if (confwin->form) { form_reset_autocompleters(confwin->form); @@ -2349,13 +2349,13 @@ _inpblock_autocomplete(ProfWin *window, const char *const input, gboolean previo static char* _form_autocomplete(ProfWin *window, const char *const input, gboolean previous) { - if (window->type != WIN_MUC_CONFIG) { + if (window->type != WIN_CONFIG) { return NULL; } char *found = NULL; - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + ProfConfWin *confwin = (ProfConfWin*)window; DataForm *form = confwin->form; if (form) { found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE, previous); @@ -2375,13 +2375,13 @@ _form_autocomplete(ProfWin *window, const char *const input, gboolean previous) static char* _form_field_autocomplete(ProfWin *window, const char *const input, gboolean previous) { - if (window->type != WIN_MUC_CONFIG) { + if (window->type != WIN_CONFIG) { return NULL; } char *found = NULL; - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + ProfConfWin *confwin = (ProfConfWin*)window; DataForm *form = confwin->form; if (form == NULL) { return NULL; @@ -2510,7 +2510,7 @@ _time_autocomplete(ProfWin *window, const char *const input, gboolean previous) return found; } - found = autocomplete_param_with_ac(input, "/time mucconfig", time_format_ac, TRUE, previous); + found = autocomplete_param_with_ac(input, "/time config", time_format_ac, TRUE, previous); if (found) { return found; } diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 14e49b47..407ba69d 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1265,8 +1265,8 @@ static struct cmd_t command_defs[] = CMD_TAGS( CMD_TAG_UI) CMD_SYN( - "/time console|chat|muc|mucconfig|private|xml set ", - "/time console|chat|muc|mucconfig|private|xml off", + "/time console|chat|muc|config|private|xml set ", + "/time console|chat|muc|config|private|xml off", "/time statusbar set ", "/time statusbar off", "/time lastactivity set ") @@ -1283,8 +1283,8 @@ static struct cmd_t command_defs[] = { "chat off", "Do not show time in chat windows." }, { "muc set ", "Set time format for chat room windows." }, { "muc off", "Do not show time in chat room windows." }, - { "mucconfig set ", "Set time format for chat room config windows." }, - { "mucconfig off", "Do not show time in chat room config windows." }, + { "config set ", "Set time format for chat room config windows." }, + { "config off", "Do not show time in chat room config windows." }, { "private set ", "Set time format for private chat windows." }, { "private off", "Do not show time in private chat windows." }, { "xml set ", "Set time format for XML console window." }, diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index dc112d85..6f1d7d51 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3632,11 +3632,11 @@ cmd_decline(ProfWin *window, const char *const command, gchar **args) gboolean cmd_form_field(ProfWin *window, char *tag, gchar **args) { - if (window->type != WIN_MUC_CONFIG) { + if (window->type != WIN_CONFIG) { return TRUE; } - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + ProfConfWin *confwin = (ProfConfWin*)window; DataForm *form = confwin->form; if (form) { if (!form_tag_exists(form, tag)) { @@ -3657,14 +3657,14 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) if (g_strcmp0(value, "on") == 0) { form_set_value(form, tag, "1"); win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else if (g_strcmp0(value, "off") == 0) { form_set_value(form, tag, "0"); win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); } break; @@ -3675,24 +3675,24 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) value = args[0]; if (value == NULL) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); } else { form_set_value(form, tag, value); win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } break; case FIELD_LIST_SINGLE: value = args[0]; if ((value == NULL) || !form_field_contains_option(form, tag, value)) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); } else { form_set_value(form, tag, value); win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } break; @@ -3703,32 +3703,32 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) } if ((g_strcmp0(cmd, "add") != 0) && (g_strcmp0(cmd, "remove"))) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } if (value == NULL) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } if (g_strcmp0(cmd, "add") == 0) { form_add_value(form, tag, value); win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); break; } if (g_strcmp0(args[0], "remove") == 0) { if (!g_str_has_prefix(value, "val")) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } if (strlen(value) < 4) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } @@ -3736,7 +3736,7 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) int index = strtol(&value[3], NULL, 10); if ((index < 1) || (index > form_get_value_count(form, tag))) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } @@ -3744,7 +3744,7 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) removed = form_remove_text_multi_value(form, tag, index); if (removed) { win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "Could not remove %s from %s", value, tag); } @@ -3757,13 +3757,13 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) } if ((g_strcmp0(cmd, "add") != 0) && (g_strcmp0(cmd, "remove"))) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } if (value == NULL) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } @@ -3773,13 +3773,13 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) added = form_add_unique_value(form, tag, value); if (added) { win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "Value %s already selected for %s", value, tag); } } else { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); } break; @@ -3790,13 +3790,13 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) removed = form_remove_value(form, tag, value); if (removed) { win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "Value %s is not currently set for %s", value, tag); } } else { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); } } @@ -3808,13 +3808,13 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) } if ((g_strcmp0(cmd, "add") != 0) && (g_strcmp0(cmd, "remove"))) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } if (value == NULL) { win_println(window, THEME_DEFAULT, '-', "Invalid command, usage:"); - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); win_println(window, THEME_DEFAULT, '-', ""); break; } @@ -3822,7 +3822,7 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) added = form_add_unique_value(form, tag, value); if (added) { win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "JID %s already exists in %s", value, tag); } @@ -3832,7 +3832,7 @@ cmd_form_field(ProfWin *window, char *tag, gchar **args) removed = form_remove_value(form, tag, value); if (removed) { win_println(window, THEME_DEFAULT, '-', "Field updated..."); - mucconfwin_show_form_field(confwin, form, tag); + confwin_show_form_field(confwin, form, tag); } else { win_println(window, THEME_DEFAULT, '-', "Field %s does not contain %s", tag, value); } @@ -3857,7 +3857,7 @@ cmd_form(ProfWin *window, const char *const command, gchar **args) return TRUE; } - if (window->type != WIN_MUC_CONFIG) { + if (window->type != WIN_CONFIG) { cons_show("Command '/form' does not apply to this window."); return TRUE; } @@ -3870,20 +3870,20 @@ cmd_form(ProfWin *window, const char *const command, gchar **args) return TRUE; } - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + ProfConfWin *confwin = (ProfConfWin*)window; assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); if (g_strcmp0(args[0], "show") == 0) { - mucconfwin_show_form(confwin); + confwin_show_form(confwin); return TRUE; } if (g_strcmp0(args[0], "help") == 0) { char *tag = args[1]; if (tag) { - mucconfwin_field_help(confwin, tag); + confwin_field_help(confwin, tag); } else { - mucconfwin_form_help(confwin); + confwin_form_help(confwin); gchar **help_text = NULL; Command *command = cmd_get("/form"); @@ -4264,7 +4264,7 @@ cmd_room(ProfWin *window, const char *const command, gchar **args) } if (g_strcmp0(args[0], "config") == 0) { - ProfMucConfWin *confwin = wins_get_muc_conf(mucwin->roomjid); + ProfConfWin *confwin = wins_get_conf(mucwin->roomjid); if (confwin) { ui_focus_win((ProfWin*)confwin); @@ -5159,20 +5159,20 @@ cmd_time(ProfWin *window, const char *const command, gchar **args) cons_bad_cmd_usage(command); return TRUE; } - } else if (g_strcmp0(args[0], "mucconfig") == 0) { + } else if (g_strcmp0(args[0], "config") == 0) { if (args[1] == NULL) { - char *format = prefs_get_string(PREF_TIME_MUCCONFIG); - cons_show("MUC config time format: '%s'.", format); + char *format = prefs_get_string(PREF_TIME_CONFIG); + cons_show("config time format: '%s'.", format); prefs_free_string(format); return TRUE; } else if (g_strcmp0(args[1], "set") == 0 && args[2] != NULL) { - prefs_set_string(PREF_TIME_MUCCONFIG, args[2]); - cons_show("MUC config time format set to '%s'.", args[2]); + prefs_set_string(PREF_TIME_CONFIG, args[2]); + cons_show("config time format set to '%s'.", args[2]); wins_resize_all(); return TRUE; } else if (g_strcmp0(args[1], "off") == 0) { - prefs_set_string(PREF_TIME_MUCCONFIG, "off"); - cons_show("MUC config time display disabled."); + prefs_set_string(PREF_TIME_CONFIG, "off"); + cons_show("config time display disabled."); wins_resize_all(); return TRUE; } else { @@ -7518,7 +7518,7 @@ cmd_command_exec(ProfWin *window, const char *const command, gchar **args) static gboolean _cmd_execute(ProfWin *window, const char *const command, const char *const inp) { - if (g_str_has_prefix(command, "/field") && window->type == WIN_MUC_CONFIG) { + if (g_str_has_prefix(command, "/field") && window->type == WIN_CONFIG) { gboolean result = FALSE; gchar **args = parse_args_with_freetext(inp, 1, 2, &result); if (!result) { diff --git a/src/config/preferences.c b/src/config/preferences.c index e62c552c..bf4a6ab1 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -123,7 +123,7 @@ prefs_load(void) g_key_file_set_string(prefs, PREF_GROUP_UI, "time.console", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.chat", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.muc", val); - g_key_file_set_string(prefs, PREF_GROUP_UI, "time.mucconfig", val); + g_key_file_set_string(prefs, PREF_GROUP_UI, "time.config", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.private", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.xmlconsole", val); g_key_file_remove_key(prefs, PREF_GROUP_UI, "time", NULL); @@ -1567,7 +1567,7 @@ _get_group(preference_t pref) case PREF_TIME_CONSOLE: case PREF_TIME_CHAT: case PREF_TIME_MUC: - case PREF_TIME_MUCCONFIG: + case PREF_TIME_CONFIG: case PREF_TIME_PRIVATE: case PREF_TIME_XMLCONSOLE: case PREF_TIME_STATUSBAR: @@ -1777,8 +1777,8 @@ _get_key(preference_t pref) return "time.chat"; case PREF_TIME_MUC: return "time.muc"; - case PREF_TIME_MUCCONFIG: - return "time.mucconfig"; + case PREF_TIME_CONFIG: + return "time.config"; case PREF_TIME_PRIVATE: return "time.private"; case PREF_TIME_XMLCONSOLE: @@ -1967,7 +1967,7 @@ _get_default_string(preference_t pref) return "%H:%M:%S"; case PREF_TIME_MUC: return "%H:%M:%S"; - case PREF_TIME_MUCCONFIG: + case PREF_TIME_CONFIG: return "%H:%M:%S"; case PREF_TIME_PRIVATE: return "%H:%M:%S"; diff --git a/src/config/preferences.h b/src/config/preferences.h index bafe4a1f..e882e248 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -92,7 +92,7 @@ typedef enum { PREF_TIME_CONSOLE, PREF_TIME_CHAT, PREF_TIME_MUC, - PREF_TIME_MUCCONFIG, + PREF_TIME_CONFIG, PREF_TIME_PRIVATE, PREF_TIME_XMLCONSOLE, PREF_TIME_STATUSBAR, diff --git a/src/config/theme.c b/src/config/theme.c index 13f9cc2b..ad8a2d0e 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -413,7 +413,7 @@ _load_preferences(void) _set_string_preference("time.console", PREF_TIME_CONSOLE); _set_string_preference("time.chat", PREF_TIME_CHAT); _set_string_preference("time.muc", PREF_TIME_MUC); - _set_string_preference("time.mucconfig", PREF_TIME_MUCCONFIG); + _set_string_preference("time.config", PREF_TIME_CONFIG); _set_string_preference("time.private", PREF_TIME_PRIVATE); _set_string_preference("time.xmlconsole", PREF_TIME_XMLCONSOLE); _set_string_preference("time.statusbar", PREF_TIME_STATUSBAR); diff --git a/src/ui/confwin.c b/src/ui/confwin.c new file mode 100644 index 00000000..73c12a59 --- /dev/null +++ b/src/ui/confwin.c @@ -0,0 +1,348 @@ +/* + * confwin.c + * + * Copyright (C) 2012 - 2018 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#include +#include + +#include "ui/ui.h" +#include "ui/window.h" +#include "ui/win_types.h" +#include "ui/window_list.h" + +static void _confwin_form_field(ProfWin *window, char *tag, FormField *field); + +void +confwin_show_form(ProfConfWin *confwin) +{ + ProfWin *window = (ProfWin*) confwin; + if (confwin->form->title) { + win_print(window, THEME_DEFAULT, '-', "Form title: "); + win_appendln(window, THEME_DEFAULT, "%s", confwin->form->title); + } else { + win_println(window, THEME_DEFAULT, '-', "Configuration for room %s.", confwin->roomjid); + } + win_println(window, THEME_DEFAULT, '-', ""); + + confwin_form_help(confwin); + + GSList *fields = confwin->form->fields; + GSList *curr_field = fields; + while (curr_field) { + FormField *field = curr_field->data; + + if ((g_strcmp0(field->type, "fixed") == 0) && field->values) { + if (field->values) { + char *value = field->values->data; + win_println(window, THEME_DEFAULT, '-', "%s", value); + } + } else if (g_strcmp0(field->type, "hidden") != 0 && field->var) { + char *tag = g_hash_table_lookup(confwin->form->var_to_tag, field->var); + _confwin_form_field(window, tag, field); + } + + curr_field = g_slist_next(curr_field); + } +} + +void +confwin_show_form_field(ProfConfWin *confwin, DataForm *form, char *tag) +{ + assert(confwin != NULL); + + FormField *field = form_get_field_by_tag(form, tag); + ProfWin *window = (ProfWin*)confwin; + _confwin_form_field(window, tag, field); + win_println(window, THEME_DEFAULT, '-', ""); +} + +void +confwin_handle_configuration(ProfConfWin *confwin, DataForm *form) +{ + assert(confwin != NULL); + + ProfWin *window = (ProfWin*)confwin; + ui_focus_win(window); + + confwin_show_form(confwin); + + win_println(window, THEME_DEFAULT, '-', ""); + win_println(window, THEME_DEFAULT, '-', "Use '/form submit' to save changes."); + win_println(window, THEME_DEFAULT, '-', "Use '/form cancel' to cancel changes."); + win_println(window, THEME_DEFAULT, '-', "See '/form help' for more information."); + win_println(window, THEME_DEFAULT, '-', ""); +} + +void +confwin_field_help(ProfConfWin *confwin, char *tag) +{ + assert(confwin != NULL); + + ProfWin *window = (ProfWin*) confwin; + FormField *field = form_get_field_by_tag(confwin->form, tag); + if (field) { + win_print(window, THEME_DEFAULT, '-', "%s", field->label); + if (field->required) { + win_appendln(window, THEME_DEFAULT, " (Required):"); + } else { + win_appendln(window, THEME_DEFAULT, ":"); + } + if (field->description) { + win_println(window, THEME_DEFAULT, '-', " Description : %s", field->description); + } + win_println(window, THEME_DEFAULT, '-', " Type : %s", field->type); + + int num_values = 0; + GSList *curr_option = NULL; + FormOption *option = NULL; + + switch (field->type_t) { + case FIELD_TEXT_SINGLE: + case FIELD_TEXT_PRIVATE: + win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is any text"); + break; + case FIELD_TEXT_MULTI: + num_values = form_get_value_count(confwin->form, tag); + win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is any text"); + if (num_values > 0) { + win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : between 'val1' and 'val%d'", num_values); + } + break; + case FIELD_BOOLEAN: + win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is either 'on' or 'off'"); + break; + case FIELD_LIST_SINGLE: + win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is one of"); + curr_option = field->options; + while (curr_option) { + option = curr_option->data; + win_println(window, THEME_DEFAULT, '-', " %s", option->value); + curr_option = g_slist_next(curr_option); + } + break; + case FIELD_LIST_MULTI: + win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); + win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is one of"); + curr_option = field->options; + while (curr_option) { + option = curr_option->data; + win_println(window, THEME_DEFAULT, '-', " %s", option->value); + curr_option = g_slist_next(curr_option); + } + break; + case FIELD_JID_SINGLE: + win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is a valid Jabber ID"); + break; + case FIELD_JID_MULTI: + win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); + win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); + win_println(window, THEME_DEFAULT, '-', " Where : is a valid Jabber ID"); + break; + case FIELD_FIXED: + case FIELD_UNKNOWN: + case FIELD_HIDDEN: + default: + break; + } + } else { + win_println(window, THEME_DEFAULT, '-', "No such field %s", tag); + } +} + +void +confwin_form_help(ProfConfWin *confwin) +{ + assert(confwin != NULL); + + if (confwin->form->instructions) { + ProfWin *window = (ProfWin*) confwin; + win_println(window, THEME_DEFAULT, '-', "Supplied instructions:"); + win_println(window, THEME_DEFAULT, '-', "%s", confwin->form->instructions); + win_println(window, THEME_DEFAULT, '-', ""); + } +} + +static void +_confwin_form_field(ProfWin *window, char *tag, FormField *field) +{ + win_print(window, THEME_AWAY, '-', "[%s] ", tag); + win_append(window, THEME_DEFAULT, "%s", field->label); + if (field->required) { + win_append(window, THEME_DEFAULT, " (required): "); + } else { + win_append(window, THEME_DEFAULT, ": "); + } + + GSList *values = field->values; + GSList *curr_value = values; + + switch (field->type_t) { + case FIELD_HIDDEN: + break; + case FIELD_TEXT_SINGLE: + if (curr_value) { + char *value = curr_value->data; + if (value) { + if (g_strcmp0(field->var, "muc#roomconfig_roomsecret") == 0) { + win_append(window, THEME_ONLINE, "[hidden]"); + } else { + win_append(window, THEME_ONLINE, "%s", value); + } + } + } + win_newline(window); + break; + case FIELD_TEXT_PRIVATE: + if (curr_value) { + char *value = curr_value->data; + if (value) { + win_append(window, THEME_ONLINE, "[hidden]"); + } + } + win_newline(window); + break; + case FIELD_TEXT_MULTI: + win_newline(window); + int index = 1; + while (curr_value) { + char *value = curr_value->data; + GString *val_tag = g_string_new(""); + g_string_printf(val_tag, "val%d", index++); + win_println(window, THEME_ONLINE, '-', " [%s] %s", val_tag->str, value); + g_string_free(val_tag, TRUE); + curr_value = g_slist_next(curr_value); + } + break; + case FIELD_BOOLEAN: + if (curr_value == NULL) { + win_appendln(window, THEME_OFFLINE, "FALSE"); + } else { + char *value = curr_value->data; + if (value == NULL) { + win_appendln(window, THEME_OFFLINE, "FALSE"); + } else { + if (g_strcmp0(value, "0") == 0) { + win_appendln(window, THEME_OFFLINE, "FALSE"); + } else { + win_appendln(window, THEME_ONLINE, "TRUE"); + } + } + } + break; + case FIELD_LIST_SINGLE: + if (curr_value) { + win_newline(window); + char *value = curr_value->data; + GSList *options = field->options; + GSList *curr_option = options; + while (curr_option) { + FormOption *option = curr_option->data; + if (g_strcmp0(option->value, value) == 0) { + win_println(window, THEME_ONLINE, '-', " [%s] %s", option->value, option->label); + } else { + win_println(window, THEME_OFFLINE, '-', " [%s] %s", option->value, option->label); + } + curr_option = g_slist_next(curr_option); + } + } + break; + case FIELD_LIST_MULTI: + if (curr_value) { + win_newline(window); + GSList *options = field->options; + GSList *curr_option = options; + while (curr_option) { + FormOption *option = curr_option->data; + if (g_slist_find_custom(curr_value, option->value, (GCompareFunc)g_strcmp0)) { + win_println(window, THEME_ONLINE, '-', " [%s] %s", option->value, option->label); + } else { + win_println(window, THEME_OFFLINE, '-', " [%s] %s", option->value, option->label); + } + curr_option = g_slist_next(curr_option); + } + } + break; + case FIELD_JID_SINGLE: + if (curr_value) { + char *value = curr_value->data; + if (value) { + win_append(window, THEME_ONLINE, "%s", value); + } + } + win_newline(window); + break; + case FIELD_JID_MULTI: + win_newline(window); + while (curr_value) { + char *value = curr_value->data; + win_println(window, THEME_ONLINE, '-', " %s", value); + curr_value = g_slist_next(curr_value); + } + break; + case FIELD_FIXED: + if (curr_value) { + char *value = curr_value->data; + if (value) { + win_append(window, THEME_DEFAULT, "%s", value); + } + } + win_newline(window); + break; + default: + break; + } +} + +char* +confwin_get_string(ProfConfWin *confwin) +{ + assert(confwin != NULL); + + GString *res = g_string_new(""); + + char *title = win_get_title((ProfWin*)confwin); + g_string_append(res, title); + free(title); + + char *resstr = res->str; + g_string_free(res, FALSE); + + return resstr; +} diff --git a/src/ui/console.c b/src/ui/console.c index 9bead705..f5c0379b 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1282,12 +1282,12 @@ cons_time_setting(void) cons_show("Time MUC (/time) : %s", pref_time_muc); prefs_free_string(pref_time_muc); - char *pref_time_mucconf = prefs_get_string(PREF_TIME_MUCCONFIG); - if (g_strcmp0(pref_time_mucconf, "off") == 0) - cons_show("Time MUC config (/time) : OFF"); + char *pref_time_conf = prefs_get_string(PREF_TIME_CONFIG); + if (g_strcmp0(pref_time_conf, "off") == 0) + cons_show("Time config (/time) : OFF"); else - cons_show("Time MUC config (/time) : %s", pref_time_mucconf); - prefs_free_string(pref_time_mucconf); + cons_show("Time config (/time) : %s", pref_time_conf); + prefs_free_string(pref_time_conf); char *pref_time_private = prefs_get_string(PREF_TIME_PRIVATE); if (g_strcmp0(pref_time_private, "off") == 0) diff --git a/src/ui/core.c b/src/ui/core.c index 5246d06a..da4e6469 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -632,8 +632,8 @@ ui_win_has_unsaved_form(int num) { ProfWin *window = wins_get_by_num(num); - if (window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + if (window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)window; assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); return confwin->form->modified; } else { @@ -651,13 +651,13 @@ ui_focus_win(ProfWin *window) } ProfWin *old_current = wins_get_current(); - if (old_current->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)old_current; + if (old_current->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)old_current; cmd_ac_remove_form_fields(confwin->form); } - if (window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + if (window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)window; cmd_ac_add_form_fields(confwin->form); } @@ -681,8 +681,8 @@ void ui_close_win(int index) { ProfWin *window = wins_get_by_num(index); - if (window && window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + if (window && window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)window; if (confwin->form) { cmd_ac_remove_form_fields(confwin->form); } @@ -1135,7 +1135,7 @@ ui_handle_room_config_submit_result(const char *const roomjid) GString *form_recipient = g_string_new(roomjid); g_string_append(form_recipient, " config"); - form_window = (ProfWin*) wins_get_muc_conf(form_recipient->str); + form_window = (ProfWin*) wins_get_conf(form_recipient->str); g_string_free(form_recipient, TRUE); if (form_window) { @@ -1167,7 +1167,7 @@ ui_handle_room_config_submit_result_error(const char *const roomjid, const char GString *form_recipient = g_string_new(roomjid); g_string_append(form_recipient, " config"); - form_window = (ProfWin*) wins_get_muc_conf(form_recipient->str); + form_window = (ProfWin*) wins_get_conf(form_recipient->str); g_string_free(form_recipient, TRUE); if (form_window) { diff --git a/src/ui/mucconfwin.c b/src/ui/mucconfwin.c deleted file mode 100644 index 7a658a1e..00000000 --- a/src/ui/mucconfwin.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * mucconfwin.c - * - * Copyright (C) 2012 - 2018 James Booth - * - * This file is part of Profanity. - * - * Profanity is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Profanity is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Profanity. If not, see . - * - * In addition, as a special exception, the copyright holders give permission to - * link the code of portions of this program with the OpenSSL library under - * certain conditions as described in each individual source file, and - * distribute linked combinations including the two. - * - * You must obey the GNU General Public License in all respects for all of the - * code used other than OpenSSL. If you modify file(s) with this exception, you - * may extend this exception to your version of the file(s), but you are not - * obligated to do so. If you do not wish to do so, delete this exception - * statement from your version. If you delete this exception statement from all - * source files in the program, then also delete it here. - * - */ - -#include -#include - -#include "ui/ui.h" -#include "ui/window.h" -#include "ui/win_types.h" -#include "ui/window_list.h" - -static void _mucconfwin_form_field(ProfWin *window, char *tag, FormField *field); - -void -mucconfwin_show_form(ProfMucConfWin *confwin) -{ - ProfWin *window = (ProfWin*) confwin; - if (confwin->form->title) { - win_print(window, THEME_DEFAULT, '-', "Form title: "); - win_appendln(window, THEME_DEFAULT, "%s", confwin->form->title); - } else { - win_println(window, THEME_DEFAULT, '-', "Configuration for room %s.", confwin->roomjid); - } - win_println(window, THEME_DEFAULT, '-', ""); - - mucconfwin_form_help(confwin); - - GSList *fields = confwin->form->fields; - GSList *curr_field = fields; - while (curr_field) { - FormField *field = curr_field->data; - - if ((g_strcmp0(field->type, "fixed") == 0) && field->values) { - if (field->values) { - char *value = field->values->data; - win_println(window, THEME_DEFAULT, '-', "%s", value); - } - } else if (g_strcmp0(field->type, "hidden") != 0 && field->var) { - char *tag = g_hash_table_lookup(confwin->form->var_to_tag, field->var); - _mucconfwin_form_field(window, tag, field); - } - - curr_field = g_slist_next(curr_field); - } -} - -void -mucconfwin_show_form_field(ProfMucConfWin *confwin, DataForm *form, char *tag) -{ - assert(confwin != NULL); - - FormField *field = form_get_field_by_tag(form, tag); - ProfWin *window = (ProfWin*)confwin; - _mucconfwin_form_field(window, tag, field); - win_println(window, THEME_DEFAULT, '-', ""); -} - -void -mucconfwin_handle_configuration(ProfMucConfWin *confwin, DataForm *form) -{ - assert(confwin != NULL); - - ProfWin *window = (ProfWin*)confwin; - ui_focus_win(window); - - mucconfwin_show_form(confwin); - - win_println(window, THEME_DEFAULT, '-', ""); - win_println(window, THEME_DEFAULT, '-', "Use '/form submit' to save changes."); - win_println(window, THEME_DEFAULT, '-', "Use '/form cancel' to cancel changes."); - win_println(window, THEME_DEFAULT, '-', "See '/form help' for more information."); - win_println(window, THEME_DEFAULT, '-', ""); -} - -void -mucconfwin_field_help(ProfMucConfWin *confwin, char *tag) -{ - assert(confwin != NULL); - - ProfWin *window = (ProfWin*) confwin; - FormField *field = form_get_field_by_tag(confwin->form, tag); - if (field) { - win_print(window, THEME_DEFAULT, '-', "%s", field->label); - if (field->required) { - win_appendln(window, THEME_DEFAULT, " (Required):"); - } else { - win_appendln(window, THEME_DEFAULT, ":"); - } - if (field->description) { - win_println(window, THEME_DEFAULT, '-', " Description : %s", field->description); - } - win_println(window, THEME_DEFAULT, '-', " Type : %s", field->type); - - int num_values = 0; - GSList *curr_option = NULL; - FormOption *option = NULL; - - switch (field->type_t) { - case FIELD_TEXT_SINGLE: - case FIELD_TEXT_PRIVATE: - win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is any text"); - break; - case FIELD_TEXT_MULTI: - num_values = form_get_value_count(confwin->form, tag); - win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is any text"); - if (num_values > 0) { - win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : between 'val1' and 'val%d'", num_values); - } - break; - case FIELD_BOOLEAN: - win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is either 'on' or 'off'"); - break; - case FIELD_LIST_SINGLE: - win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is one of"); - curr_option = field->options; - while (curr_option) { - option = curr_option->data; - win_println(window, THEME_DEFAULT, '-', " %s", option->value); - curr_option = g_slist_next(curr_option); - } - break; - case FIELD_LIST_MULTI: - win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); - win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is one of"); - curr_option = field->options; - while (curr_option) { - option = curr_option->data; - win_println(window, THEME_DEFAULT, '-', " %s", option->value); - curr_option = g_slist_next(curr_option); - } - break; - case FIELD_JID_SINGLE: - win_println(window, THEME_DEFAULT, '-', " Set : /%s ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is a valid Jabber ID"); - break; - case FIELD_JID_MULTI: - win_println(window, THEME_DEFAULT, '-', " Add : /%s add ", tag); - win_println(window, THEME_DEFAULT, '-', " Remove : /%s remove ", tag); - win_println(window, THEME_DEFAULT, '-', " Where : is a valid Jabber ID"); - break; - case FIELD_FIXED: - case FIELD_UNKNOWN: - case FIELD_HIDDEN: - default: - break; - } - } else { - win_println(window, THEME_DEFAULT, '-', "No such field %s", tag); - } -} - -void -mucconfwin_form_help(ProfMucConfWin *confwin) -{ - assert(confwin != NULL); - - if (confwin->form->instructions) { - ProfWin *window = (ProfWin*) confwin; - win_println(window, THEME_DEFAULT, '-', "Supplied instructions:"); - win_println(window, THEME_DEFAULT, '-', "%s", confwin->form->instructions); - win_println(window, THEME_DEFAULT, '-', ""); - } -} - -static void -_mucconfwin_form_field(ProfWin *window, char *tag, FormField *field) -{ - win_print(window, THEME_AWAY, '-', "[%s] ", tag); - win_append(window, THEME_DEFAULT, "%s", field->label); - if (field->required) { - win_append(window, THEME_DEFAULT, " (required): "); - } else { - win_append(window, THEME_DEFAULT, ": "); - } - - GSList *values = field->values; - GSList *curr_value = values; - - switch (field->type_t) { - case FIELD_HIDDEN: - break; - case FIELD_TEXT_SINGLE: - if (curr_value) { - char *value = curr_value->data; - if (value) { - if (g_strcmp0(field->var, "muc#roomconfig_roomsecret") == 0) { - win_append(window, THEME_ONLINE, "[hidden]"); - } else { - win_append(window, THEME_ONLINE, "%s", value); - } - } - } - win_newline(window); - break; - case FIELD_TEXT_PRIVATE: - if (curr_value) { - char *value = curr_value->data; - if (value) { - win_append(window, THEME_ONLINE, "[hidden]"); - } - } - win_newline(window); - break; - case FIELD_TEXT_MULTI: - win_newline(window); - int index = 1; - while (curr_value) { - char *value = curr_value->data; - GString *val_tag = g_string_new(""); - g_string_printf(val_tag, "val%d", index++); - win_println(window, THEME_ONLINE, '-', " [%s] %s", val_tag->str, value); - g_string_free(val_tag, TRUE); - curr_value = g_slist_next(curr_value); - } - break; - case FIELD_BOOLEAN: - if (curr_value == NULL) { - win_appendln(window, THEME_OFFLINE, "FALSE"); - } else { - char *value = curr_value->data; - if (value == NULL) { - win_appendln(window, THEME_OFFLINE, "FALSE"); - } else { - if (g_strcmp0(value, "0") == 0) { - win_appendln(window, THEME_OFFLINE, "FALSE"); - } else { - win_appendln(window, THEME_ONLINE, "TRUE"); - } - } - } - break; - case FIELD_LIST_SINGLE: - if (curr_value) { - win_newline(window); - char *value = curr_value->data; - GSList *options = field->options; - GSList *curr_option = options; - while (curr_option) { - FormOption *option = curr_option->data; - if (g_strcmp0(option->value, value) == 0) { - win_println(window, THEME_ONLINE, '-', " [%s] %s", option->value, option->label); - } else { - win_println(window, THEME_OFFLINE, '-', " [%s] %s", option->value, option->label); - } - curr_option = g_slist_next(curr_option); - } - } - break; - case FIELD_LIST_MULTI: - if (curr_value) { - win_newline(window); - GSList *options = field->options; - GSList *curr_option = options; - while (curr_option) { - FormOption *option = curr_option->data; - if (g_slist_find_custom(curr_value, option->value, (GCompareFunc)g_strcmp0)) { - win_println(window, THEME_ONLINE, '-', " [%s] %s", option->value, option->label); - } else { - win_println(window, THEME_OFFLINE, '-', " [%s] %s", option->value, option->label); - } - curr_option = g_slist_next(curr_option); - } - } - break; - case FIELD_JID_SINGLE: - if (curr_value) { - char *value = curr_value->data; - if (value) { - win_append(window, THEME_ONLINE, "%s", value); - } - } - win_newline(window); - break; - case FIELD_JID_MULTI: - win_newline(window); - while (curr_value) { - char *value = curr_value->data; - win_println(window, THEME_ONLINE, '-', " %s", value); - curr_value = g_slist_next(curr_value); - } - break; - case FIELD_FIXED: - if (curr_value) { - char *value = curr_value->data; - if (value) { - win_append(window, THEME_DEFAULT, "%s", value); - } - } - win_newline(window); - break; - default: - break; - } -} - -char* -mucconfwin_get_string(ProfMucConfWin *confwin) -{ - assert(confwin != NULL); - - GString *res = g_string_new(""); - - char *title = win_get_title((ProfWin*)confwin); - g_string_append(res, title); - free(title); - - char *resstr = res->str; - g_string_free(res, FALSE); - - return resstr; -} diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index ac1d7498..5d860440 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -544,7 +544,7 @@ _display_name(StatusBarTab *tab) } else { fullname = strdup(tab->identifier); } - } else if (tab->window_type == WIN_MUC_CONFIG) { + } else if (tab->window_type == WIN_CONFIG) { char *pref = prefs_get_string(PREF_STATUSBAR_ROOM); GString *display_str = g_string_new(""); if (g_strcmp0("room", pref) == 0) { diff --git a/src/ui/ui.h b/src/ui/ui.h index 6988d882..573fdfcc 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -217,13 +217,13 @@ void privwin_room_kicked(ProfPrivateWin *privwin, const char *const actor, const void privwin_room_banned(ProfPrivateWin *privwin, const char *const actor, const char *const reason); void privwin_room_joined(ProfPrivateWin *privwin); -// MUC room config window -void mucconfwin_handle_configuration(ProfMucConfWin *confwin, DataForm *form); -void mucconfwin_show_form(ProfMucConfWin *confwin); -void mucconfwin_show_form_field(ProfMucConfWin *confwin, DataForm *form, char *tag); -void mucconfwin_form_help(ProfMucConfWin *confwin); -void mucconfwin_field_help(ProfMucConfWin *confwin, char *tag); -char* mucconfwin_get_string(ProfMucConfWin *confwin); +// room config window +void confwin_handle_configuration(ProfConfWin *confwin, DataForm *form); +void confwin_show_form(ProfConfWin *confwin); +void confwin_show_form_field(ProfConfWin *confwin, DataForm *form, char *tag); +void confwin_form_help(ProfConfWin *confwin); +void confwin_field_help(ProfConfWin *confwin, char *tag); +char* confwin_get_string(ProfConfWin *confwin); // xml console void xmlwin_show(ProfXMLWin *xmlwin, const char *const msg); @@ -346,7 +346,7 @@ ProfWin* win_create_console(void); ProfWin* win_create_xmlconsole(void); ProfWin* win_create_chat(const char *const barejid); ProfWin* win_create_muc(const char *const roomjid); -ProfWin* win_create_muc_config(const char *const title, DataForm *form); +ProfWin* win_create_config(const char *const title, DataForm *form); ProfWin* win_create_private(const char *const fulljid); ProfWin* win_create_plugin(const char *const plugin_name, const char *const tag); void win_update_virtual(ProfWin *window); diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 7fa75b34..28a785bf 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -128,7 +128,7 @@ typedef enum { WIN_CONSOLE, WIN_CHAT, WIN_MUC, - WIN_MUC_CONFIG, + WIN_CONFIG, WIN_PRIVATE, WIN_XML, WIN_PLUGIN @@ -172,12 +172,12 @@ typedef struct prof_muc_win_t { char *message_char; } ProfMucWin; -typedef struct prof_mucconf_win_t { +typedef struct prof_conf_win_t { ProfWin window; char *roomjid; DataForm *form; unsigned long memcheck; -} ProfMucConfWin; +} ProfConfWin; typedef struct prof_private_win_t { ProfWin window; diff --git a/src/ui/window.c b/src/ui/window.c index a6f65d1b..16cd9490 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -203,10 +203,10 @@ win_create_muc(const char *const roomjid) } ProfWin* -win_create_muc_config(const char *const roomjid, DataForm *form) +win_create_config(const char *const roomjid, DataForm *form) { - ProfMucConfWin *new_win = malloc(sizeof(ProfMucConfWin)); - new_win->window.type = WIN_MUC_CONFIG; + ProfConfWin *new_win = malloc(sizeof(ProfConfWin)); + new_win->window.type = WIN_CONFIG; new_win->window.layout = _win_create_simple_layout(); new_win->roomjid = strdup(roomjid); new_win->form = form; @@ -289,8 +289,8 @@ win_get_title(ProfWin *window) assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); return strdup(mucwin->roomjid); } - if (window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*) window; + if (window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*) window; assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); GString *title = g_string_new(confwin->roomjid); g_string_append(title, " config"); @@ -338,10 +338,10 @@ win_get_tab_identifier(ProfWin *window) ProfMucWin *mucwin = (ProfMucWin*)window; return strdup(mucwin->roomjid); } - case WIN_MUC_CONFIG: + case WIN_CONFIG: { - ProfMucConfWin *mucconfwin = (ProfMucConfWin*)window; - return strdup(mucconfwin->roomjid); + ProfConfWin *confwin = (ProfConfWin*)window; + return strdup(confwin->roomjid); } case WIN_PRIVATE: { @@ -383,10 +383,10 @@ win_to_string(ProfWin *window) ProfMucWin *mucwin = (ProfMucWin*)window; return mucwin_get_string(mucwin); } - case WIN_MUC_CONFIG: + case WIN_CONFIG: { - ProfMucConfWin *mucconfwin = (ProfMucConfWin*)window; - return mucconfwin_get_string(mucconfwin); + ProfConfWin *confwin = (ProfConfWin*)window; + return confwin_get_string(confwin); } case WIN_PRIVATE: { @@ -491,11 +491,11 @@ win_free(ProfWin* window) free(mucwin->message_char); break; } - case WIN_MUC_CONFIG: + case WIN_CONFIG: { - ProfMucConfWin *mucconf = (ProfMucConfWin*)window; - free(mucconf->roomjid); - form_destroy(mucconf->form); + ProfConfWin *conf = (ProfConfWin*)window; + free(conf->roomjid); + form_destroy(conf->form); break; } case WIN_PRIVATE: @@ -1389,8 +1389,8 @@ _win_print(ProfWin *window, const char show_char, int pad_indent, GDateTime *tim case WIN_MUC: time_pref = prefs_get_string(PREF_TIME_MUC); break; - case WIN_MUC_CONFIG: - time_pref = prefs_get_string(PREF_TIME_MUCCONFIG); + case WIN_CONFIG: + time_pref = prefs_get_string(PREF_TIME_CONFIG); break; case WIN_PRIVATE: time_pref = prefs_get_string(PREF_TIME_PRIVATE); diff --git a/src/ui/window_list.c b/src/ui/window_list.c index e408a2ac..d386f1dd 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -139,16 +139,16 @@ wins_get_chat_unsubscribed(void) return result; } -ProfMucConfWin* -wins_get_muc_conf(const char *const roomjid) +ProfConfWin* +wins_get_conf(const char *const roomjid) { GList *values = g_hash_table_get_values(windows); GList *curr = values; while (curr) { ProfWin *window = curr->data; - if (window->type == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; + if (window->type == WIN_CONFIG) { + ProfConfWin *confwin = (ProfConfWin*)window; if (g_strcmp0(confwin->roomjid, roomjid) == 0) { g_list_free(values); return confwin; @@ -584,7 +584,7 @@ wins_close_by_num(int i) autocomplete_remove(wins_close_ac, pluginwin->tag); break; } - case WIN_MUC_CONFIG: + case WIN_CONFIG: default: break; } @@ -657,12 +657,12 @@ wins_new_muc(const char *const roomjid) } ProfWin* -wins_new_muc_config(const char *const roomjid, DataForm *form) +wins_new_config(const char *const roomjid, DataForm *form) { GList *keys = g_hash_table_get_keys(windows); int result = _wins_get_next_available_num(keys); g_list_free(keys); - ProfWin *newwin = win_create_muc_config(roomjid, form); + ProfWin *newwin = win_create_config(roomjid, form); g_hash_table_insert(windows, GINT_TO_POINTER(result), newwin); return newwin; } @@ -812,7 +812,7 @@ wins_get_prune_wins(void) ProfWin *window = curr->data; if (win_unread(window) == 0 && window->type != WIN_MUC && - window->type != WIN_MUC_CONFIG && + window->type != WIN_CONFIG && window->type != WIN_XML && window->type != WIN_CONSOLE) { result = g_slist_append(result, window); diff --git a/src/ui/window_list.h b/src/ui/window_list.h index ba62ad32..0309fe00 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -42,7 +42,7 @@ void wins_init(void); ProfWin* wins_new_xmlconsole(void); ProfWin* wins_new_chat(const char *const barejid); ProfWin* wins_new_muc(const char *const roomjid); -ProfWin* wins_new_muc_config(const char *const roomjid, DataForm *form); +ProfWin* wins_new_config(const char *const roomjid, DataForm *form); ProfWin* wins_new_private(const char *const fulljid); ProfWin* wins_new_plugin(const char *const plugin_name, const char *const tag); @@ -56,7 +56,7 @@ ProfWin* wins_get_console(void); ProfChatWin* wins_get_chat(const char *const barejid); GList* wins_get_chat_unsubscribed(void); ProfMucWin* wins_get_muc(const char *const roomjid); -ProfMucConfWin* wins_get_muc_conf(const char *const roomjid); +ProfConfWin* wins_get_conf(const char *const roomjid); ProfPrivateWin* wins_get_private(const char *const fulljid); ProfPluginWin* wins_get_plugin(const char *const tag); ProfXMLWin* wins_get_xmlconsole(void); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index f5bacddd..60c19b88 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1152,8 +1152,8 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata } DataForm *form = form_create(x); - ProfMucConfWin *confwin = (ProfMucConfWin*)wins_new_muc_config(from, form); - mucconfwin_handle_configuration(confwin, form); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form); + confwin_handle_configuration(confwin, form); } if (g_strcmp0(status, "canceled") == 0) { @@ -1693,8 +1693,8 @@ _room_config_id_handler(xmpp_stanza_t *const stanza, void *const userdata) } DataForm *form = form_create(x); - ProfMucConfWin *confwin = (ProfMucConfWin*)wins_new_muc_config(from, form); - mucconfwin_handle_configuration(confwin, form); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form); + confwin_handle_configuration(confwin, form); return 0; } diff --git a/tests/functionaltests/proftest.c b/tests/functionaltests/proftest.c index 90121249..9d5c2fe2 100644 --- a/tests/functionaltests/proftest.c +++ b/tests/functionaltests/proftest.c @@ -183,8 +183,8 @@ init_prof_test(void **state) assert_true(prof_output_exact("Chat time display disabled.")); prof_input("/time muc off"); assert_true(prof_output_exact("MUC time display disabled.")); - prof_input("/time mucconfig off"); - assert_true(prof_output_exact("MUC config time display disabled.")); + prof_input("/time config off"); + assert_true(prof_output_exact("config time display disabled.")); prof_input("/time private off"); assert_true(prof_output_exact("Private chat time display disabled.")); prof_input("/time xml off"); diff --git a/tests/unittests/test_cmd_pgp.c b/tests/unittests/test_cmd_pgp.c index b2a1aa7e..0754773a 100644 --- a/tests/unittests/test_cmd_pgp.c +++ b/tests/unittests/test_cmd_pgp.c @@ -79,9 +79,9 @@ void cmd_pgp_start_shows_message_when_no_arg_in_muc(void **state) cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_MUC); } -void cmd_pgp_start_shows_message_when_no_arg_in_mucconf(void **state) +void cmd_pgp_start_shows_message_when_no_arg_in_conf(void **state) { - cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_MUC_CONFIG); + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_CONFIG); } void cmd_pgp_start_shows_message_when_no_arg_in_private(void **state) diff --git a/tests/unittests/test_cmd_pgp.h b/tests/unittests/test_cmd_pgp.h index 0d681a4a..d6082ecb 100644 --- a/tests/unittests/test_cmd_pgp.h +++ b/tests/unittests/test_cmd_pgp.h @@ -8,7 +8,7 @@ void cmd_pgp_start_shows_message_when_connecting(void **state); void cmd_pgp_start_shows_message_when_undefined(void **state); void cmd_pgp_start_shows_message_when_no_arg_in_console(void **state); void cmd_pgp_start_shows_message_when_no_arg_in_muc(void **state); -void cmd_pgp_start_shows_message_when_no_arg_in_mucconf(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_conf(void **state); void cmd_pgp_start_shows_message_when_no_arg_in_private(void **state); void cmd_pgp_start_shows_message_when_no_arg_in_xmlconsole(void **state); #else diff --git a/tests/unittests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c index 420653e1..cee0ddd9 100644 --- a/tests/unittests/ui/stub_ui.c +++ b/tests/unittests/ui/stub_ui.c @@ -250,7 +250,7 @@ void ui_handle_error(const char * const err_msg) void ui_clear_win_title(void) {} void ui_goodbye_title(void) {} -void mucconfwin_handle_configuration(ProfMucConfWin *confwin, DataForm *form) {} +void confwin_handle_configuration(ProfConfWin *confwin, DataForm *form) {} void ui_handle_room_configuration_form_error(const char * const roomjid, const char * const message) {} void ui_handle_room_config_submit_result(const char * const roomjid) {} void ui_handle_room_config_submit_result_error(const char * const roomjid, const char * const message) {} @@ -263,10 +263,10 @@ void mucwin_role_set_error(ProfMucWin *mucwin, const char * const nick, const ch void mucwin_role_list_error(ProfMucWin *mucwin, const char * const role, const char * const error) {} void mucwin_handle_role_list(ProfMucWin *mucwin, const char * const role, GSList *nicks) {} void mucwin_kick_error(ProfMucWin *mucwin, const char * const nick, const char * const error) {} -void mucconfwin_show_form(ProfMucConfWin *confwin) {} -void mucconfwin_show_form_field(ProfMucConfWin *confwin, DataForm *form, char *tag) {} -void mucconfwin_form_help(ProfMucConfWin *confwin) {} -void mucconfwin_field_help(ProfMucConfWin *confwin, char *tag) {} +void confwin_show_form(ProfConfWin *confwin) {} +void confwin_show_form_field(ProfConfWin *confwin, DataForm *form, char *tag) {} +void confwin_form_help(ProfConfWin *confwin) {} +void confwin_field_help(ProfConfWin *confwin, char *tag) {} void ui_show_lines(ProfWin *window, gchar** lines) {} void ui_redraw_all_room_rosters(void) {} void ui_show_all_room_rosters(void) {} @@ -494,7 +494,7 @@ ProfWin* win_create_muc(const char * const roomjid) { return NULL; } -ProfWin* win_create_muc_config(const char * const title, DataForm *form) +ProfWin* win_create_config(const char * const title, DataForm *form) { return NULL; } diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index 4e3e149e..a2da1c2a 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -557,7 +557,7 @@ int main(int argc, char* argv[]) { unit_test(cmd_pgp_start_shows_message_when_connecting), unit_test(cmd_pgp_start_shows_message_when_no_arg_in_console), unit_test(cmd_pgp_start_shows_message_when_no_arg_in_muc), - unit_test(cmd_pgp_start_shows_message_when_no_arg_in_mucconf), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_conf), unit_test(cmd_pgp_start_shows_message_when_no_arg_in_private), unit_test(cmd_pgp_start_shows_message_when_no_arg_in_xmlconsole), #else diff --git a/theme_template b/theme_template index 2afadf3f..4b5d5dac 100644 --- a/theme_template +++ b/theme_template @@ -84,7 +84,7 @@ wrap= time.console= time.chat= time.muc= -time.mucconfig= +time.config= time.private= time.xmlconsole= time.lastactivity= diff --git a/themes/bios b/themes/bios index a0a36eb8..aded8473 100644 --- a/themes/bios +++ b/themes/bios @@ -85,7 +85,7 @@ wrap=true time.console=%H:%M:%S time.chat=%d/%m/%y %H:%M:%S time.muc=%d/%m/%y %H:%M:%S -time.mucconfig=off +time.config=off time.private=%d/%m/%y %H:%M:%S time.xmlconsole=%H:%M:%S time.statusbar=%H:%M:%S diff --git a/themes/boothj5 b/themes/boothj5 index 80566b5e..bbac89a6 100644 --- a/themes/boothj5 +++ b/themes/boothj5 @@ -85,7 +85,7 @@ wrap=true time.console=%H:%M:%S time.chat=%d/%m/%y %H:%M:%S time.muc=%d/%m/%y %H:%M:%S -time.mucconfig=off +time.config=off time.private=%d/%m/%y %H:%M:%S time.xmlconsole=%H:%M:%S time.statusbar=%H:%M:%S diff --git a/themes/boothj5_laptop b/themes/boothj5_laptop index d7512f62..4ca185fc 100644 --- a/themes/boothj5_laptop +++ b/themes/boothj5_laptop @@ -85,7 +85,7 @@ wrap=true time.console=%H:%M:%S time.chat=%H:%M:%S time.muc=%H:%M:%S -time.mucconfig=off +time.config=off time.private=%H:%M:%S time.xmlconsole=off time.statusbar=%H:%M:%S diff --git a/themes/boothj5_slack b/themes/boothj5_slack index 792fdef2..b8efb132 100644 --- a/themes/boothj5_slack +++ b/themes/boothj5_slack @@ -85,7 +85,7 @@ wrap=true time.console=%H:%M:%S time.chat=%d/%m/%y %H:%M:%S time.muc=%d/%m/%y %H:%M:%S -time.mucconfig=off +time.config=off time.private=%d/%m/%y %H:%M:%S time.xmlconsole=%H:%M:%S time.statusbar=%H:%M:%S diff --git a/themes/complex b/themes/complex index 65e09337..2f68537c 100644 --- a/themes/complex +++ b/themes/complex @@ -6,7 +6,7 @@ wrap=true time.console=%d/%m/%y %H:%M:%S time.chat=%d/%m/%y %H:%M:%S time.muc=%d/%m/%y %H:%M:%S -time.mucconfig=%d/%m/%y %H:%M:%S +time.config=%d/%m/%y %H:%M:%S time.private=%d/%m/%y %H:%M:%S time.xmlconsole=%d/%m/%y %H:%M:%S time.statusbar=%H:%M:%S diff --git a/themes/simple b/themes/simple index b26eebf3..64390bb9 100644 --- a/themes/simple +++ b/themes/simple @@ -6,7 +6,7 @@ wrap=true time.console=off time.chat=off time.muc=off -time.mucconfig=off +time.config=off time.private=off time.xmlconsole=off time.statusbar=off -- cgit 1.4.1-2-gfad0 From b11d3a79df49970b4563bbd40c4db3f53c99dfeb Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 30 May 2018 20:45:06 +0320 Subject: Add conf win callback --- src/command/cmd_funcs.c | 4 +-- src/ui/ui.h | 3 +- src/ui/win_types.h | 9 ++++-- src/ui/window.c | 11 ++++++- src/ui/window_list.c | 4 +-- src/ui/window_list.h | 2 +- src/xmpp/iq.c | 68 +++++++++++++++++++++++----------------- src/xmpp/xmpp.h | 4 +-- tests/unittests/xmpp/stub_xmpp.c | 4 +-- 9 files changed, 67 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 6f1d7d51..475a81b4 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3899,11 +3899,11 @@ cmd_form(ProfWin *window, const char *const command, gchar **args) } if (g_strcmp0(args[0], "submit") == 0) { - iq_submit_room_config(confwin->roomjid, confwin->form); + confwin->submit(confwin); } if (g_strcmp0(args[0], "cancel") == 0) { - iq_room_config_cancel(confwin->roomjid); + confwin->cancel(confwin); } if ((g_strcmp0(args[0], "submit") == 0) || (g_strcmp0(args[0], "cancel") == 0)) { diff --git a/src/ui/ui.h b/src/ui/ui.h index 573fdfcc..1bcc20fc 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -346,7 +346,7 @@ ProfWin* win_create_console(void); ProfWin* win_create_xmlconsole(void); ProfWin* win_create_chat(const char *const barejid); ProfWin* win_create_muc(const char *const roomjid); -ProfWin* win_create_config(const char *const title, DataForm *form); +ProfWin* win_create_config(const char *const title, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel); ProfWin* win_create_private(const char *const fulljid); ProfWin* win_create_plugin(const char *const plugin_name, const char *const tag); void win_update_virtual(ProfWin *window); @@ -380,6 +380,7 @@ char* win_to_string(ProfWin *window); void win_command_list_error(ProfWin *window, const char *const error); void win_command_exec_error(ProfWin *window, const char *const command, const char *const error, ...); void win_handle_command_list(ProfWin *window, GSList *cmds); +void win_handle_command_exec_status(ProfWin *window, const char *const type, const char *const value); void win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value); // desktop notifications diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 28a785bf..c9dc623b 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -172,12 +172,17 @@ typedef struct prof_muc_win_t { char *message_char; } ProfMucWin; -typedef struct prof_conf_win_t { +typedef struct prof_conf_win_t ProfConfWin; +typedef void (*ProfConfWinCallback)(ProfConfWin *); + +struct prof_conf_win_t { ProfWin window; char *roomjid; DataForm *form; unsigned long memcheck; -} ProfConfWin; + ProfConfWinCallback submit; + ProfConfWinCallback cancel; +}; typedef struct prof_private_win_t { ProfWin window; diff --git a/src/ui/window.c b/src/ui/window.c index 16cd9490..f34e354e 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -203,13 +203,15 @@ win_create_muc(const char *const roomjid) } ProfWin* -win_create_config(const char *const roomjid, DataForm *form) +win_create_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel) { ProfConfWin *new_win = malloc(sizeof(ProfConfWin)); new_win->window.type = WIN_CONFIG; new_win->window.layout = _win_create_simple_layout(); new_win->roomjid = strdup(roomjid); new_win->form = form; + new_win->submit = submit; + new_win->cancel = cancel; new_win->memcheck = PROFCONFWIN_MEMCHECK; @@ -1768,6 +1770,13 @@ win_handle_command_list(ProfWin *window, GSList *cmds) } } +void +win_handle_command_exec_status(ProfWin *window, const char *const command, const char *const value) +{ + assert(window != NULL); + win_println(window, THEME_DEFAULT, '!', "%s %s", command, value); +} + void win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value) { diff --git a/src/ui/window_list.c b/src/ui/window_list.c index d386f1dd..8f886b54 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -657,12 +657,12 @@ wins_new_muc(const char *const roomjid) } ProfWin* -wins_new_config(const char *const roomjid, DataForm *form) +wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel) { GList *keys = g_hash_table_get_keys(windows); int result = _wins_get_next_available_num(keys); g_list_free(keys); - ProfWin *newwin = win_create_config(roomjid, form); + ProfWin *newwin = win_create_config(roomjid, form, submit, cancel); g_hash_table_insert(windows, GINT_TO_POINTER(result), newwin); return newwin; } diff --git a/src/ui/window_list.h b/src/ui/window_list.h index 0309fe00..f427a6d7 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -42,7 +42,7 @@ void wins_init(void); ProfWin* wins_new_xmlconsole(void); ProfWin* wins_new_chat(const char *const barejid); ProfWin* wins_new_muc(const char *const roomjid); -ProfWin* wins_new_config(const char *const roomjid, DataForm *form); +ProfWin* wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel); ProfWin* wins_new_private(const char *const fulljid); ProfWin* wins_new_plugin(const char *const plugin_name, const char *const tag); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 60c19b88..8e7ecc0b 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -586,10 +586,10 @@ iq_request_room_config_form(const char *const room_jid) } void -iq_submit_room_config(const char *const room, DataForm *form) +iq_submit_room_config(ProfConfWin *confwin) { xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form); + xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, confwin->roomjid, confwin->form); const char *id = xmpp_stanza_get_id(iq); iq_id_handler_add(id, _room_config_submit_id_handler, NULL, NULL); @@ -599,10 +599,10 @@ iq_submit_room_config(const char *const room, DataForm *form) } void -iq_room_config_cancel(const char *const room_jid) +iq_room_config_cancel(ProfConfWin *confwin) { xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, room_jid); + xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, confwin->roomjid); iq_send_stanza(iq); xmpp_stanza_release(iq); } @@ -1106,61 +1106,71 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata log_debug("IQ command exec response handler fired."); } + ProfWin *win = wins_get_by_string(from); + if (win == NULL) { + /* No more window associated with this command. + * Fallback to console. */ + win = wins_get_console(); + } + // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); log_debug("Error executing command %s for %s: %s", command, from, error_message); - ProfWin *win = wins_get_by_string(from); - if (win) { - win_command_exec_error(win, command, error_message); - } + win_command_exec_error(win, command, error_message); free(error_message); return 0; } xmpp_stanza_t *cmd = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_COMMAND); if (!cmd) { - /* TODO */ + log_error("No command element for command response"); + win_command_exec_error(win, command, "Malformed command response"); + return 0; } - ProfWin *win = wins_get_by_string(from); const char *status = xmpp_stanza_get_attribute(cmd, STANZA_ATTR_STATUS); if (g_strcmp0(status, "completed") == 0) { - if (win) { - xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note"); - if (note) { - const char *type = xmpp_stanza_get_attribute(note, "type"); - const char *value = xmpp_stanza_get_text(note); - win_handle_command_exec_result_note(win, type, value); - } + win_handle_command_exec_status(win, command, "completed"); + xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note"); + if (note) { + const char *type = xmpp_stanza_get_attribute(note, "type"); + const char *value = xmpp_stanza_get_text(note); + win_handle_command_exec_result_note(win, type, value); } - return 0; - } + } else if (g_strcmp0(status, "executing") == 0) { + win_handle_command_exec_status(win, command, "executing"); - if (g_strcmp0(status, "executing") == 0) { + /* Looking for a jabber:x:data type form */ xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA); if (x == NULL) { - /* TODO */ return 0; } const char *form_type = xmpp_stanza_get_type(x); if (g_strcmp0(form_type, "form") != 0) { - /* TODO */ + log_error("Unsupported payload in command response"); + win_command_exec_error(win, command, "Unsupported command response"); return 0; } DataForm *form = form_create(x); - ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL); confwin_handle_configuration(confwin, form); + } else if (g_strcmp0(status, "canceled") == 0) { + win_handle_command_exec_status(win, command, "canceled"); + xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note"); + if (note) { + const char *type = xmpp_stanza_get_attribute(note, "type"); + const char *value = xmpp_stanza_get_text(note); + win_handle_command_exec_result_note(win, type, value); + } + } else { + log_error("Unsupported command status %s", status); + win_command_exec_error(win, command, "Malformed command response"); } - if (g_strcmp0(status, "canceled") == 0) { - } - - /* TODO */ - return 0; } @@ -1693,7 +1703,7 @@ _room_config_id_handler(xmpp_stanza_t *const stanza, void *const userdata) } DataForm *form = form_create(x); - ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_room_config, iq_room_config_cancel); confwin_handle_configuration(confwin, form); return 0; diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index c0e1477d..44acd97e 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -171,8 +171,8 @@ void iq_set_autoping(int seconds); void iq_confirm_instant_room(const char *const room_jid); void iq_destroy_room(const char *const room_jid); void iq_request_room_config_form(const char *const room_jid); -void iq_submit_room_config(const char *const room, DataForm *form); -void iq_room_config_cancel(const char *const room_jid); +void iq_submit_room_config(ProfConfWin *confwin); +void iq_room_config_cancel(ProfConfWin *confwin); void iq_send_ping(const char *const target); void iq_room_info_request(const char *const room, gboolean display_result); void iq_room_affiliation_list(const char *const room, char *affiliation); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 5590a8e1..67263339 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -185,8 +185,8 @@ void iq_http_upload_request(HTTPUpload *upload) {} void iq_confirm_instant_room(const char * const room_jid) {} void iq_destroy_room(const char * const room_jid) {} void iq_request_room_config_form(const char * const room_jid) {} -void iq_submit_room_config(const char * const room, DataForm *form) {} -void iq_room_config_cancel(const char * const room_jid) {} +void iq_submit_room_config(ProfConfWin *confwin) {} +void iq_room_config_cancel(ProfConfWin *confwin) {} void iq_send_ping(const char * const target) {} void iq_send_caps_request(const char * const to, const char * const id, const char * const node, const char * const ver) {} -- cgit 1.4.1-2-gfad0 From 233e076be95baf13a23e9dbefac208d424a57e5d Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 20 Jun 2018 19:30:44 +0320 Subject: Add support for command config execution --- src/ui/ui.h | 2 +- src/ui/win_types.h | 1 + src/ui/window.c | 3 ++- src/ui/window_list.c | 4 ++-- src/ui/window_list.h | 2 +- src/xmpp/iq.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/xmpp/stanza.c | 25 +++++++++++++++++++++++++ src/xmpp/stanza.h | 1 + tests/unittests/ui/stub_ui.c | 2 +- 9 files changed, 75 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/ui.h b/src/ui/ui.h index 1bcc20fc..136a5e98 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -346,7 +346,7 @@ ProfWin* win_create_console(void); ProfWin* win_create_xmlconsole(void); ProfWin* win_create_chat(const char *const barejid); ProfWin* win_create_muc(const char *const roomjid); -ProfWin* win_create_config(const char *const title, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel); +ProfWin* win_create_config(const char *const title, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata); ProfWin* win_create_private(const char *const fulljid); ProfWin* win_create_plugin(const char *const plugin_name, const char *const tag); void win_update_virtual(ProfWin *window); diff --git a/src/ui/win_types.h b/src/ui/win_types.h index c9dc623b..eb453cd0 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -182,6 +182,7 @@ struct prof_conf_win_t { unsigned long memcheck; ProfConfWinCallback submit; ProfConfWinCallback cancel; + const void *userdata; }; typedef struct prof_private_win_t { diff --git a/src/ui/window.c b/src/ui/window.c index f34e354e..5ad354f2 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -203,7 +203,7 @@ win_create_muc(const char *const roomjid) } ProfWin* -win_create_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel) +win_create_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata) { ProfConfWin *new_win = malloc(sizeof(ProfConfWin)); new_win->window.type = WIN_CONFIG; @@ -212,6 +212,7 @@ win_create_config(const char *const roomjid, DataForm *form, ProfConfWinCallback new_win->form = form; new_win->submit = submit; new_win->cancel = cancel; + new_win->userdata = userdata; new_win->memcheck = PROFCONFWIN_MEMCHECK; diff --git a/src/ui/window_list.c b/src/ui/window_list.c index 8f886b54..a12dc7cb 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -657,12 +657,12 @@ wins_new_muc(const char *const roomjid) } ProfWin* -wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel) +wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata) { GList *keys = g_hash_table_get_keys(windows); int result = _wins_get_next_available_num(keys); g_list_free(keys); - ProfWin *newwin = win_create_config(roomjid, form, submit, cancel); + ProfWin *newwin = win_create_config(roomjid, form, submit, cancel, userdata); g_hash_table_insert(windows, GINT_TO_POINTER(result), newwin); return newwin; } diff --git a/src/ui/window_list.h b/src/ui/window_list.h index f427a6d7..b47ee79f 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -42,7 +42,7 @@ void wins_init(void); ProfWin* wins_new_xmlconsole(void); ProfWin* wins_new_chat(const char *const barejid); ProfWin* wins_new_muc(const char *const roomjid); -ProfWin* wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel); +ProfWin* wins_new_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata); ProfWin* wins_new_private(const char *const fulljid); ProfWin* wins_new_plugin(const char *const plugin_name, const char *const tag); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 8e7ecc0b..337701bc 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -88,6 +88,11 @@ typedef struct privilege_set_t { char *privilege; } ProfPrivilegeSet; +typedef struct command_config_data_t { + char *sessionid; + char *command; +} CommandConfigData; + static int _iq_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _error_handler(xmpp_stanza_t *const stanza); @@ -724,6 +729,36 @@ iq_command_exec(const char *const target, const char *const command) xmpp_stanza_release(iq); } +void +iq_submit_command_config(ProfConfWin *confwin) +{ + xmpp_ctx_t * const ctx = connection_get_ctx(); + CommandConfigData *data = (CommandConfigData *)confwin->userdata; + xmpp_stanza_t *iq = stanza_create_command_config_submit_iq(ctx, confwin->roomjid, data->command, data->sessionid, confwin->form); + + const char *id = xmpp_stanza_get_id(iq); + iq_id_handler_add(id, _command_exec_response_handler, NULL, NULL); + + iq_send_stanza(iq); + xmpp_stanza_release(iq); + free(data->sessionid); + free(data->command); + free(data); +} + +void +iq_cancel_command_config(ProfConfWin *confwin) +{ + xmpp_ctx_t * const ctx = connection_get_ctx(); + CommandConfigData *data = (CommandConfigData *)confwin->userdata; + xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, confwin->roomjid); + iq_send_stanza(iq); + xmpp_stanza_release(iq); + free(data->sessionid); + free(data->command); + free(data); +} + static void _error_handler(xmpp_stanza_t *const stanza) { @@ -1098,7 +1133,7 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata const char *id = xmpp_stanza_get_id(stanza); const char *type = xmpp_stanza_get_type(stanza); const char *from = xmpp_stanza_get_from(stanza); - const char *const command = userdata; + char *command = userdata; if (id) { log_debug("IQ command exec response handler fired, id: %s.", id); @@ -1156,7 +1191,10 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata } DataForm *form = form_create(x); - ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL); + CommandConfigData *data = malloc(sizeof(CommandConfigData)); + data->sessionid = strdup(xmpp_stanza_get_attribute(cmd, "sessionid")); + data->command = command; + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_command_config, iq_cancel_command_config, data); confwin_handle_configuration(confwin, form); } else if (g_strcmp0(status, "canceled") == 0) { win_handle_command_exec_status(win, command, "canceled"); @@ -1703,7 +1741,7 @@ _room_config_id_handler(xmpp_stanza_t *const stanza, void *const userdata) } DataForm *form = form_create(x); - ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_room_config, iq_room_config_cancel); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_room_config, iq_room_config_cancel, NULL); confwin_handle_configuration(confwin, form); return 0; diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 537fbf96..68919710 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2063,6 +2063,31 @@ stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, return iq; } +xmpp_stanza_t* +stanza_create_command_config_submit_iq(xmpp_ctx_t *ctx, const char *const room, + const char *const node, const char *const sessionid, DataForm *form) +{ + char *id = connection_create_stanza_id("commandconf_submit"); + xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id); + free(id); + xmpp_stanza_set_to(iq, room); + + 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, "sessionid", sessionid); + + xmpp_stanza_t *x = form_create_submission(form); + xmpp_stanza_add_child(command, x); + xmpp_stanza_release(x); + + 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 5f8203a2..696f60da 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -282,6 +282,7 @@ xmpp_stanza_t* stanza_create_room_kick_iq(xmpp_ctx_t *const ctx, const char *con const char *const reason); xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node); +xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t *ctx, const char *const room, const char *const node, const char *const sessionid, DataForm *form); int stanza_get_idle_time(xmpp_stanza_t *const stanza); diff --git a/tests/unittests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c index cee0ddd9..855dca22 100644 --- a/tests/unittests/ui/stub_ui.c +++ b/tests/unittests/ui/stub_ui.c @@ -494,7 +494,7 @@ ProfWin* win_create_muc(const char * const roomjid) { return NULL; } -ProfWin* win_create_config(const char * const title, DataForm *form) +ProfWin* win_create_config(const char *const title, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata) { return NULL; } -- cgit 1.4.1-2-gfad0 From 71c9cbf8a8e8b3925f11756603ad6cb4b9828350 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 25 Jun 2018 08:22:58 +0320 Subject: Conform to Section 3.2.2.1 of XML Schema Part 2: Datatypes In accordance with Section 3.2.2.1 of XML Schema Part 2: Datatypes, the allowable lexical representations for the xs:boolean datatype are the strings "0" and "false" for the concept 'false' and the strings "1" and "true" for the concept 'true'; implementations MUST support both styles of lexical representation. --- src/ui/confwin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/confwin.c b/src/ui/confwin.c index 73c12a59..80937f7d 100644 --- a/src/ui/confwin.c +++ b/src/ui/confwin.c @@ -258,7 +258,7 @@ _confwin_form_field(ProfWin *window, char *tag, FormField *field) if (value == NULL) { win_appendln(window, THEME_OFFLINE, "FALSE"); } else { - if (g_strcmp0(value, "0") == 0) { + if (g_strcmp0(value, "0") == 0 || g_strcmp0(value, "false") == 0) { win_appendln(window, THEME_OFFLINE, "FALSE"); } else { win_appendln(window, THEME_ONLINE, "TRUE"); -- cgit 1.4.1-2-gfad0 From e555e41eaf97bb40a41bbb25f1cc68cf537f9fd5 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 2 Jul 2018 07:23:46 +0320 Subject: Fix cmd command synopsis --- src/command/cmd_defs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 407ba69d..deffd954 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2308,8 +2308,8 @@ static struct cmd_t command_defs[] = CMD_NOMAINFUNC CMD_NOTAGS CMD_SYN( - "/otr list", - "/otr exec ") + "/cmd list", + "/cmd exec ") CMD_DESC( "Execute ad hoc commands.") CMD_ARGS( -- cgit 1.4.1-2-gfad0 From ec5fc3612fd46cc3661f5ec6988e54900f271447 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 2 Jul 2018 08:10:01 +0320 Subject: Allow to use cmd without being in a window --- src/command/cmd_defs.c | 4 ++-- src/command/cmd_funcs.c | 17 ++++++++++++----- src/xmpp/iq.c | 6 ++++-- 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index deffd954..b3bfa22d 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2308,8 +2308,8 @@ static struct cmd_t command_defs[] = CMD_NOMAINFUNC CMD_NOTAGS CMD_SYN( - "/cmd list", - "/cmd exec ") + "/cmd list []", + "/cmd exec []") CMD_DESC( "Execute ad hoc commands.") CMD_ARGS( diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 475a81b4..f067d67a 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7484,9 +7484,12 @@ cmd_command_list(ProfWin *window, const char *const command, gchar **args) return TRUE; } - ProfMucWin *mucwin = (ProfMucWin*)window; - - iq_command_list(mucwin->roomjid); + char *jid = args[1]; + if (jid == NULL) { + ProfMucWin *mucwin = (ProfMucWin*)window; + jid = mucwin->roomjid; + } + iq_command_list(jid); cons_show("List available ad hoc commands"); return TRUE; @@ -7507,9 +7510,13 @@ cmd_command_exec(ProfWin *window, const char *const command, gchar **args) return TRUE; } - ProfMucWin *mucwin = (ProfMucWin*)window; + char *jid = args[2]; + if (jid == NULL) { + ProfMucWin *mucwin = (ProfMucWin*)window; + jid = mucwin->roomjid; + } - iq_command_exec(mucwin->roomjid, args[1]); + iq_command_exec(jid, args[1]); cons_show("Execute %s...", args[1]); return TRUE; diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 337701bc..9204f196 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1118,9 +1118,11 @@ _command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata) } ProfWin *win = wins_get_by_string(from); - if (win) { - win_handle_command_list(win, cmds); + if (win == NULL) { + win = wins_get_console(); } + + win_handle_command_list(win, cmds); g_slist_free(cmds); free(from); -- cgit 1.4.1-2-gfad0 From afd4fc4ea1e29f9a390b62d84afb181a5aa78b1f Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 11:40:37 +0200 Subject: Fix bad english sentence --- src/command/cmd_funcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index f067d67a..cd996309 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -204,7 +204,7 @@ cmd_tls_trust(ProfWin *window, const char *const command, gchar **args) #ifdef HAVE_LIBMESODE jabber_conn_status_t conn_status = connection_get_status(); if (conn_status != JABBER_CONNECTED) { - cons_show("You are not currently connected."); + cons_show("You are currently not connected."); return TRUE; } if (!connection_is_secured()) { -- cgit 1.4.1-2-gfad0 From 1d3baa99a7fb1e5e479536197a165f3c13a87af0 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 12:23:57 +0200 Subject: Ensure cmd commands are run on the right type of window --- src/command/cmd_funcs.c | 57 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index cd996309..d45fde81 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -7486,9 +7486,34 @@ cmd_command_list(ProfWin *window, const char *const command, gchar **args) char *jid = args[1]; if (jid == NULL) { - ProfMucWin *mucwin = (ProfMucWin*)window; - jid = mucwin->roomjid; + switch (window->type) { + case WIN_MUC: + { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + jid = mucwin->roomjid; + break; + } + case WIN_CHAT: + { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + jid = chatwin->barejid; + break; + } + case WIN_PRIVATE: + { + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); + jid = privatewin->fulljid; + break; + } + default: + cons_show("Cannot send ad hoc commands."); + return TRUE; + } } + iq_command_list(jid); cons_show("List available ad hoc commands"); @@ -7512,8 +7537,32 @@ cmd_command_exec(ProfWin *window, const char *const command, gchar **args) char *jid = args[2]; if (jid == NULL) { - ProfMucWin *mucwin = (ProfMucWin*)window; - jid = mucwin->roomjid; + switch (window->type) { + case WIN_MUC: + { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + jid = mucwin->roomjid; + break; + } + case WIN_CHAT: + { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + jid = chatwin->barejid; + break; + } + case WIN_PRIVATE: + { + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); + jid = privatewin->fulljid; + break; + } + default: + cons_show("Cannot send ad hoc commands."); + return TRUE; + } } iq_command_exec(jid, args[1]); -- cgit 1.4.1-2-gfad0 From 4d703c7eb0cf06c962aec030e65b25d4e1295067 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 12:29:31 +0200 Subject: Fix description for config commands --- src/command/cmd_defs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index b3bfa22d..83f3e405 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1283,8 +1283,8 @@ static struct cmd_t command_defs[] = { "chat off", "Do not show time in chat windows." }, { "muc set ", "Set time format for chat room windows." }, { "muc off", "Do not show time in chat room windows." }, - { "config set ", "Set time format for chat room config windows." }, - { "config off", "Do not show time in chat room config windows." }, + { "config set ", "Set time format for config windows." }, + { "config off", "Do not show time in config windows." }, { "private set ", "Set time format for private chat windows." }, { "private off", "Do not show time in private chat windows." }, { "xml set ", "Set time format for XML console window." }, -- cgit 1.4.1-2-gfad0 From 771d90c7660c5fdcb9fd01d7072d2e30cfed36fb Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 12:30:30 +0200 Subject: Fix comment about config windows --- src/ui/ui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/ui.h b/src/ui/ui.h index 136a5e98..f608483d 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -217,7 +217,7 @@ void privwin_room_kicked(ProfPrivateWin *privwin, const char *const actor, const void privwin_room_banned(ProfPrivateWin *privwin, const char *const actor, const char *const reason); void privwin_room_joined(ProfPrivateWin *privwin); -// room config window +// config window void confwin_handle_configuration(ProfConfWin *confwin, DataForm *form); void confwin_show_form(ProfConfWin *confwin); void confwin_show_form_field(ProfConfWin *confwin, DataForm *form, char *tag); -- cgit 1.4.1-2-gfad0 From db1ffae3bd80f52d98fae62c297a16b999df4057 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 14:17:26 +0200 Subject: Fix command exec error output --- src/ui/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/window.c b/src/ui/window.c index 5ad354f2..be89d295 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1745,7 +1745,7 @@ win_command_exec_error(ProfWin *window, const char *const command, const char *c GString *msg = g_string_new(NULL); g_string_vprintf(msg, error, arg); - win_println(window, THEME_ERROR, '!', "Error executing command %s: %s", command, msg); + win_println(window, THEME_ERROR, '!', "Error executing command %s: %s", command, msg->str); g_string_free(msg, TRUE); va_end(arg); -- cgit 1.4.1-2-gfad0 From 3c709726107e4b20452aa794501a7c0c143c6f85 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 5 Sep 2018 14:37:26 +0200 Subject: Add default jid for cmd commands on WIN_CONSOLE --- src/command/cmd_funcs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index d45fde81..f8c9d9e2 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -70,6 +70,7 @@ #include "ui/ui.h" #include "ui/window_list.h" #include "xmpp/xmpp.h" +#include "xmpp/connection.h" #include "xmpp/contact.h" #include "xmpp/roster_list.h" #include "xmpp/jid.h" @@ -7508,6 +7509,11 @@ cmd_command_list(ProfWin *window, const char *const command, gchar **args) jid = privatewin->fulljid; break; } + case WIN_CONSOLE: + { + jid = connection_get_domain(); + break; + } default: cons_show("Cannot send ad hoc commands."); return TRUE; @@ -7559,6 +7565,11 @@ cmd_command_exec(ProfWin *window, const char *const command, gchar **args) jid = privatewin->fulljid; break; } + case WIN_CONSOLE: + { + jid = connection_get_domain(); + break; + } default: cons_show("Cannot send ad hoc commands."); return TRUE; -- cgit 1.4.1-2-gfad0 From b7556b4e414c5fd1652b1401e38298e7ba71313d Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 10 Sep 2018 11:30:46 +0200 Subject: Add missing command name for completion log --- src/xmpp/iq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 9204f196..d155a574 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -737,7 +737,7 @@ iq_submit_command_config(ProfConfWin *confwin) xmpp_stanza_t *iq = stanza_create_command_config_submit_iq(ctx, confwin->roomjid, data->command, data->sessionid, confwin->form); const char *id = xmpp_stanza_get_id(iq); - iq_id_handler_add(id, _command_exec_response_handler, NULL, NULL); + iq_id_handler_add(id, _command_exec_response_handler, free, strdup(data->command)); iq_send_stanza(iq); xmpp_stanza_release(iq); -- cgit 1.4.1-2-gfad0 From 6de60e7efc75d3eaa8e8d6b3676d3ee115ba0bd8 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 10 Sep 2018 12:28:28 +0200 Subject: Add support for ad-hoc response with forms --- src/command/cmd_funcs.c | 4 ++-- src/xmpp/iq.c | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index f8c9d9e2..42f85182 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3899,11 +3899,11 @@ cmd_form(ProfWin *window, const char *const command, gchar **args) return TRUE; } - if (g_strcmp0(args[0], "submit") == 0) { + if (g_strcmp0(args[0], "submit") == 0 && confwin->submit != NULL) { confwin->submit(confwin); } - if (g_strcmp0(args[0], "cancel") == 0) { + if (g_strcmp0(args[0], "cancel") == 0 && confwin->cancel != NULL) { confwin->cancel(confwin); } diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index d155a574..3b5f1990 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1176,6 +1176,12 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata const char *value = xmpp_stanza_get_text(note); win_handle_command_exec_result_note(win, type, value); } + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA); + if (x) { + DataForm *form = form_create(x); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL, NULL); + confwin_handle_configuration(confwin, form); + } } else if (g_strcmp0(status, "executing") == 0) { win_handle_command_exec_status(win, command, "executing"); -- cgit 1.4.1-2-gfad0 From 371b64a8422b13e76b2d2af9f3f481351117f119 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 10 Sep 2018 12:46:18 +0200 Subject: Don't show submit help on form if there is no submit callback Could be missleading for user. --- src/ui/confwin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/confwin.c b/src/ui/confwin.c index 80937f7d..9791e5cf 100644 --- a/src/ui/confwin.c +++ b/src/ui/confwin.c @@ -97,7 +97,9 @@ confwin_handle_configuration(ProfConfWin *confwin, DataForm *form) confwin_show_form(confwin); win_println(window, THEME_DEFAULT, '-', ""); - win_println(window, THEME_DEFAULT, '-', "Use '/form submit' to save changes."); + if (confwin->submit != NULL) { + win_println(window, THEME_DEFAULT, '-', "Use '/form submit' to save changes."); + } win_println(window, THEME_DEFAULT, '-', "Use '/form cancel' to cancel changes."); win_println(window, THEME_DEFAULT, '-', "See '/form help' for more information."); win_println(window, THEME_DEFAULT, '-', ""); -- cgit 1.4.1-2-gfad0 From 01428eb85855ea9dd148118ca35a0e20f42cd5ce Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Mon, 10 Sep 2018 13:09:23 +0200 Subject: Add special handling for xep-0133 get-user-roster --- src/xmpp/iq.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 3b5f1990..dde803cb 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1178,9 +1178,48 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata } xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA); if (x) { - DataForm *form = form_create(x); - ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL, NULL); - confwin_handle_configuration(confwin, form); + xmpp_stanza_t *roster = xmpp_stanza_get_child_by_ns(x, XMPP_NS_ROSTER); + if (roster) { + /* Special handling of xep-0133 roster in response */ + GSList *list = NULL; + xmpp_stanza_t *child = xmpp_stanza_get_children(roster); + while (child) { + const char *barejid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); + gchar *barejid_lower = g_utf8_strdown(barejid, -1); + const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); + const char *sub = xmpp_stanza_get_attribute(child, STANZA_ATTR_SUBSCRIPTION); + const char *ask = xmpp_stanza_get_attribute(child, STANZA_ATTR_ASK); + + GSList *groups = NULL; + xmpp_stanza_t *group_element = xmpp_stanza_get_children(child); + + while (group_element) { + if (strcmp(xmpp_stanza_get_name(group_element), STANZA_NAME_GROUP) == 0) { + char *groupname = xmpp_stanza_get_text(group_element); + if (groupname) { + groups = g_slist_append(groups, groupname); + } + } + group_element = xmpp_stanza_get_next(group_element); + } + + gboolean pending_out = FALSE; + if (ask && (strcmp(ask, "subscribe") == 0)) { + pending_out = TRUE; + } + + PContact contact = p_contact_new(barejid_lower, name, groups, sub, NULL, pending_out); + list = g_slist_append(list, contact); + child = xmpp_stanza_get_next(child); + } + + cons_show_roster(list); + g_slist_free(list); + } else { + DataForm *form = form_create(x); + ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL, NULL); + confwin_handle_configuration(confwin, form); + } } } else if (g_strcmp0(status, "executing") == 0) { win_handle_command_exec_status(win, command, "executing"); -- cgit 1.4.1-2-gfad0 From 2e0bc27bf0d19f07fa60a48dfd8189edb4462f54 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 26 Sep 2018 12:32:56 +0200 Subject: Make _get_groups_from_item and roster _compare_* public In order to avoid duplication with xep 0133 support in command execution --- src/xmpp/iq.c | 14 ++------------ src/xmpp/roster.c | 9 +++------ src/xmpp/roster.h | 1 + src/xmpp/roster_list.c | 24 +++++++++++------------- src/xmpp/roster_list.h | 2 ++ 5 files changed, 19 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index dde803cb..e5a74fc4 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1191,17 +1191,7 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata const char *ask = xmpp_stanza_get_attribute(child, STANZA_ATTR_ASK); GSList *groups = NULL; - xmpp_stanza_t *group_element = xmpp_stanza_get_children(child); - - while (group_element) { - if (strcmp(xmpp_stanza_get_name(group_element), STANZA_NAME_GROUP) == 0) { - char *groupname = xmpp_stanza_get_text(group_element); - if (groupname) { - groups = g_slist_append(groups, groupname); - } - } - group_element = xmpp_stanza_get_next(group_element); - } + groups = roster_get_groups_from_item(child); gboolean pending_out = FALSE; if (ask && (strcmp(ask, "subscribe") == 0)) { @@ -1209,7 +1199,7 @@ _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata } PContact contact = p_contact_new(barejid_lower, name, groups, sub, NULL, pending_out); - list = g_slist_append(list, contact); + list = g_slist_insert_sorted(list, contact, (GCompareFunc)roster_compare_name); child = xmpp_stanza_get_next(child); } diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index 4fa70052..994269ec 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -75,9 +75,6 @@ static int _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userda static int _group_remove_id_handler(xmpp_stanza_t *const stanza, void *const userdata); static void _free_group_data(GroupData *data); -// helper functions -GSList* _get_groups_from_item(xmpp_stanza_t *item); - void roster_request(void) { @@ -254,7 +251,7 @@ roster_set_handler(xmpp_stanza_t *const stanza) pending_out = TRUE; } - GSList *groups = _get_groups_from_item(item); + GSList *groups = roster_get_groups_from_item(item); // update the local roster PContact contact = roster_get_contact(barejid_lower); @@ -301,7 +298,7 @@ roster_result_handler(xmpp_stanza_t *const stanza) pending_out = TRUE; } - GSList *groups = _get_groups_from_item(item); + GSList *groups = roster_get_groups_from_item(item); gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out); if (!added) { @@ -318,7 +315,7 @@ roster_result_handler(xmpp_stanza_t *const stanza) } GSList* -_get_groups_from_item(xmpp_stanza_t *item) +roster_get_groups_from_item(xmpp_stanza_t *item) { GSList *groups = NULL; xmpp_stanza_t *group_element = xmpp_stanza_get_children(item); diff --git a/src/xmpp/roster.h b/src/xmpp/roster.h index 15614377..be710561 100644 --- a/src/xmpp/roster.h +++ b/src/xmpp/roster.h @@ -38,5 +38,6 @@ void roster_request(void); void roster_set_handler(xmpp_stanza_t *const stanza); void roster_result_handler(xmpp_stanza_t *const stanza); +GSList* roster_get_groups_from_item(xmpp_stanza_t *const item); #endif diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index a2c5653d..71c86ff5 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -73,8 +73,6 @@ static gboolean _key_equals(void *key1, void *key2); static gboolean _datetimes_equal(GDateTime *dt1, GDateTime *dt2); static void _replace_name(const char *const current_name, const char *const new_name, const char *const barejid); static void _add_name_and_barejid(const char *const name, const char *const barejid); -static gint _compare_name(PContact a, PContact b); -static gint _compare_presence(PContact a, PContact b); void roster_create(void) @@ -397,7 +395,7 @@ roster_get_contacts_by_presence(const char *const presence) while (g_hash_table_iter_next(&iter, &key, &value)) { PContact contact = (PContact)value; if (g_strcmp0(p_contact_presence(contact), presence) == 0) { - result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_name); + result = g_slist_insert_sorted(result, value, (GCompareFunc)roster_compare_name); } } @@ -417,9 +415,9 @@ roster_get_contacts(roster_ord_t order) GCompareFunc cmp_func; if (order == ROSTER_ORD_PRESENCE) { - cmp_func = (GCompareFunc) _compare_presence; + cmp_func = (GCompareFunc) roster_compare_presence; } else { - cmp_func = (GCompareFunc) _compare_name; + cmp_func = (GCompareFunc) roster_compare_name; } g_hash_table_iter_init(&iter, roster->contacts); @@ -444,7 +442,7 @@ roster_get_contacts_online(void) g_hash_table_iter_init(&iter, roster->contacts); while (g_hash_table_iter_next(&iter, &key, &value)) { if(strcmp(p_contact_presence(value), "offline")) - result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_name); + result = g_slist_insert_sorted(result, value, (GCompareFunc)roster_compare_name); } // return all contact structs @@ -499,9 +497,9 @@ roster_get_group(const char *const group, roster_ord_t order) GCompareFunc cmp_func; if (order == ROSTER_ORD_PRESENCE) { - cmp_func = (GCompareFunc) _compare_presence; + cmp_func = (GCompareFunc) roster_compare_presence; } else { - cmp_func = (GCompareFunc) _compare_name; + cmp_func = (GCompareFunc) roster_compare_name; } g_hash_table_iter_init(&iter, roster->contacts); @@ -605,8 +603,8 @@ _add_name_and_barejid(const char *const name, const char *const barejid) } } -static gint -_compare_name(PContact a, PContact b) +gint +roster_compare_name(PContact a, PContact b) { const char * utf8_str_a = NULL; const char * utf8_str_b = NULL; @@ -645,8 +643,8 @@ _get_presence_weight(const char *presence) } } -static gint -_compare_presence(PContact a, PContact b) +gint +roster_compare_presence(PContact a, PContact b) { const char *presence_a = p_contact_presence(a); const char *presence_b = p_contact_presence(b); @@ -663,6 +661,6 @@ _compare_presence(PContact a, PContact b) // otherwise order by name } else { - return _compare_name(a, b); + return roster_compare_name(a, b); } } diff --git a/src/xmpp/roster_list.h b/src/xmpp/roster_list.h index a0b01625..b7484c04 100644 --- a/src/xmpp/roster_list.h +++ b/src/xmpp/roster_list.h @@ -70,5 +70,7 @@ char* roster_group_autocomplete(const char *const search_str, gboolean previous) char* roster_barejid_autocomplete(const char *const search_str, gboolean previous); GSList* roster_get_contacts_by_presence(const char *const presence); char* roster_get_msg_display_name(const char *const barejid, const char *const resource); +gint roster_compare_name(PContact a, PContact b); +gint roster_compare_presence(PContact a, PContact b); #endif -- cgit 1.4.1-2-gfad0