diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command/cmd_ac.c | 24 | ||||
-rw-r--r-- | src/command/cmd_defs.c | 6 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 5 | ||||
-rw-r--r-- | src/profanity.c | 3 | ||||
-rw-r--r-- | src/xmpp/form.c | 1 | ||||
-rw-r--r-- | src/xmpp/message.c | 46 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 73 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 8 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 1 |
9 files changed, 155 insertions, 12 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 40c8d7ed..a2d949eb 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -206,7 +206,8 @@ static Autocomplete rooms_list_ac; static Autocomplete rooms_cache_ac; static Autocomplete affiliation_ac; static Autocomplete role_ac; -static Autocomplete privilege_cmd_ac; +static Autocomplete affiliation_cmd_ac; +static Autocomplete role_cmd_ac; static Autocomplete subject_ac; static Autocomplete form_ac; static Autocomplete form_field_multi_ac; @@ -752,9 +753,14 @@ cmd_ac_init(void) autocomplete_add(role_ac, "visitor"); autocomplete_add(role_ac, "none"); - privilege_cmd_ac = autocomplete_new(); - autocomplete_add(privilege_cmd_ac, "list"); - autocomplete_add(privilege_cmd_ac, "set"); + affiliation_cmd_ac = autocomplete_new(); + autocomplete_add(affiliation_cmd_ac, "list"); + autocomplete_add(affiliation_cmd_ac, "request"); + autocomplete_add(affiliation_cmd_ac, "set"); + + role_cmd_ac = autocomplete_new(); + autocomplete_add(role_cmd_ac, "list"); + autocomplete_add(role_cmd_ac, "set"); subject_ac = autocomplete_new(); autocomplete_add(subject_ac, "set"); @@ -1300,7 +1306,8 @@ cmd_ac_reset(ProfWin* window) autocomplete_reset(rooms_cache_ac); autocomplete_reset(affiliation_ac); autocomplete_reset(role_ac); - autocomplete_reset(privilege_cmd_ac); + autocomplete_reset(affiliation_cmd_ac); + autocomplete_reset(role_cmd_ac); autocomplete_reset(subject_ac); autocomplete_reset(form_ac); autocomplete_reset(form_field_multi_ac); @@ -1457,7 +1464,8 @@ cmd_ac_uninit(void) autocomplete_free(rooms_cache_ac); autocomplete_free(affiliation_ac); autocomplete_free(role_ac); - autocomplete_free(privilege_cmd_ac); + autocomplete_free(affiliation_cmd_ac); + autocomplete_free(role_cmd_ac); autocomplete_free(subject_ac); autocomplete_free(form_ac); autocomplete_free(form_field_multi_ac); @@ -3106,7 +3114,7 @@ _affiliation_autocomplete(ProfWin* window, const char* const input, gboolean pre return result; } - result = autocomplete_param_with_ac(input, "/affiliation", privilege_cmd_ac, TRUE, previous); + result = autocomplete_param_with_ac(input, "/affiliation", affiliation_cmd_ac, TRUE, previous); if (result) { return result; } @@ -3156,7 +3164,7 @@ _role_autocomplete(ProfWin* window, const char* const input, gboolean previous) return result; } - result = autocomplete_param_with_ac(input, "/role", privilege_cmd_ac, TRUE, previous); + result = autocomplete_param_with_ac(input, "/role", role_cmd_ac, TRUE, previous); if (result) { return result; } diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 49a2a7db..55f58b49 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -694,13 +694,15 @@ static struct cmd_t command_defs[] = { CMD_TAG_GROUPCHAT) CMD_SYN( "/affiliation set <affiliation> <jid> [<reason>]", - "/affiliation list [<affiliation>]") + "/affiliation list [<affiliation>]", + "/affiliation request") CMD_DESC( "Manage room affiliations. " "Affiliation may be one of owner, admin, member, outcast or none.") CMD_ARGS( { "set <affiliation> <jid> [<reason>]", "Set the affiliation of user with jid, with an optional reason." }, - { "list [<affiliation>]", "List all users with the specified affiliation, or all if none specified." }) + { "list [<affiliation>]", "List all users with the specified affiliation, or all if none specified." }, + { "request", "Request voice."}) CMD_NOEXAMPLES }, diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 6faa64b8..657850e2 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -4161,6 +4161,11 @@ cmd_affiliation(ProfWin* window, const char* const command, gchar** args) } } + if (g_strcmp0(cmd, "request") == 0) { + message_request_voice(mucwin->roomjid); + return TRUE; + } + cons_bad_cmd_usage(command); return TRUE; } diff --git a/src/profanity.c b/src/profanity.c index c15146b4..eb829bad 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -91,12 +91,13 @@ static void _shutdown(void); static void _connect_default(const char* const account); pthread_mutex_t lock; -static gboolean cont = TRUE; static gboolean force_quit = FALSE; void prof_run(char* log_level, char* account_name, char* config_file, char* log_file, char* theme_name) { + gboolean cont = TRUE; + _init(log_level, config_file, log_file, theme_name); plugins_on_start(); _connect_default(account_name); diff --git a/src/xmpp/form.c b/src/xmpp/form.c index a1fa31d4..dc8c583c 100644 --- a/src/xmpp/form.c +++ b/src/xmpp/form.c @@ -447,6 +447,7 @@ form_tag_exists(DataForm* form, const char* const tag) GList* curr = tags; while (curr) { if (g_strcmp0(curr->data, tag) == 0) { + g_list_free(tags); return TRUE; } curr = g_list_next(curr); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index ab899407..54be543c 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -64,6 +64,7 @@ #include "xmpp/stanza.h" #include "xmpp/connection.h" #include "xmpp/xmpp.h" +#include "xmpp/form.h" #ifdef HAVE_OMEMO #include "xmpp/omemo.h" @@ -91,6 +92,7 @@ static xmpp_stanza_t* _handle_carbons(xmpp_stanza_t* const stanza); static void _send_message_stanza(xmpp_stanza_t* const stanza); static gboolean _handle_mam(xmpp_stanza_t* const stanza); static void _handle_pubsub(xmpp_stanza_t* const stanza, xmpp_stanza_t* const event); +static gboolean _handle_form(xmpp_stanza_t* const stanza); #ifdef HAVE_LIBGPGME static xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text); @@ -170,6 +172,11 @@ _message_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* con } else if (type == NULL || g_strcmp0(type, STANZA_TYPE_CHAT) != 0 || g_strcmp0(type, STANZA_TYPE_NORMAL) != 0) { // type: chat, normal (==NULL) + // XEP-0045: Multi-User Chat 8.6 Voice Requests + if (_handle_form(stanza)) { + return 1; + } + // XEP-0313: Message Archive Management if (_handle_mam(stanza)) { return 1; @@ -249,6 +256,33 @@ _message_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* con } void +message_muc_submit_voice_approve(ProfConfWin* confwin) +{ + xmpp_ctx_t* const ctx = connection_get_ctx(); + xmpp_stanza_t* message = stanza_create_approve_voice(ctx, NULL, confwin->roomjid, NULL, confwin->form); + + _send_message_stanza(message); + xmpp_stanza_release(message); +} + +static gboolean +_handle_form(xmpp_stanza_t* const stanza) +{ + xmpp_stanza_t* result = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_X, STANZA_NS_DATA); + if (!result) { + return FALSE; + } + + const char* const stanza_from = xmpp_stanza_get_from(stanza); + + DataForm* form = form_create(result); + ProfConfWin* confwin = (ProfConfWin*)wins_new_config(stanza_from, form, message_muc_submit_voice_approve, NULL, NULL); + confwin_handle_configuration(confwin, form); + + return TRUE; +} + +void message_handlers_init(void) { xmpp_conn_t* const conn = connection_get_conn(); @@ -1560,3 +1594,15 @@ _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text return signcrypt; } #endif // HAVE_LIBGPGME + +void +message_request_voice(const char* const roomjid) +{ + xmpp_ctx_t* const ctx = connection_get_ctx(); + xmpp_stanza_t* stanza = stanza_request_voice(ctx, roomjid); + + log_debug("Requesting voice in %s", roomjid); + + _send_message_stanza(stanza); + xmpp_stanza_release(stanza); +} diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 86bd0d91..32892311 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2755,3 +2755,76 @@ stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* cons return iq; } + +xmpp_stanza_t* +stanza_request_voice(xmpp_ctx_t* ctx, const char* const room) +{ + char* id = connection_create_stanza_id(); + xmpp_stanza_t* message = xmpp_message_new(ctx, NULL, room, id); + free(id); + + xmpp_stanza_t* request_voice_st = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(request_voice_st, STANZA_NAME_X); + xmpp_stanza_set_type(request_voice_st, STANZA_TYPE_SUBMIT); + xmpp_stanza_set_ns(request_voice_st, STANZA_NS_DATA); + + xmpp_stanza_t* form_type = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(form_type, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(form_type, STANZA_ATTR_VAR, "FORM_TYPE"); + + xmpp_stanza_t* value_request = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(value_request, STANZA_NAME_VALUE); + + xmpp_stanza_t* request_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(request_text, STANZA_NS_VOICEREQUEST); + + xmpp_stanza_add_child(value_request, request_text); + xmpp_stanza_release(request_text); + + xmpp_stanza_add_child(form_type, value_request); + xmpp_stanza_release(value_request); + + xmpp_stanza_add_child(request_voice_st, form_type); + xmpp_stanza_release(form_type); + + xmpp_stanza_t* request_role = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(request_role, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(request_role, STANZA_ATTR_VAR, "muc#role"); + xmpp_stanza_set_attribute(request_role, STANZA_ATTR_TYPE, "list-single"); + xmpp_stanza_set_attribute(request_role, STANZA_ATTR_LABEL, "Requested role"); + + xmpp_stanza_t* value_role = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(value_role, STANZA_NAME_VALUE); + + xmpp_stanza_t* role_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(role_text, "participant"); + + xmpp_stanza_add_child(value_role, role_text); + xmpp_stanza_release(role_text); + + xmpp_stanza_add_child(request_role, value_role); + xmpp_stanza_release(value_role); + + xmpp_stanza_add_child(request_voice_st, request_role); + xmpp_stanza_release(request_role); + + xmpp_stanza_add_child(message, request_voice_st); + xmpp_stanza_release(request_voice_st); + + return message; +} + +xmpp_stanza_t* +stanza_create_approve_voice(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form) +{ + char* stid = connection_create_stanza_id(); + xmpp_stanza_t* message = xmpp_message_new(ctx, NULL, jid, stid); + free(stid); + + xmpp_stanza_t* x = form_create_submission(form); + + xmpp_stanza_add_child(message, x); + xmpp_stanza_release(x); + + return message; +} diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 35f38055..0115942a 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -158,6 +158,7 @@ #define STANZA_TYPE_SET "set" #define STANZA_TYPE_ERROR "error" #define STANZA_TYPE_RESULT "result" +#define STANZA_TYPE_SUBMIT "submit" #define STANZA_ATTR_TO "to" #define STANZA_ATTR_FROM "from" @@ -186,6 +187,7 @@ #define STANZA_ATTR_FILENAME "filename" #define STANZA_ATTR_SIZE "size" #define STANZA_ATTR_CONTENTTYPE "content-type" +#define STANZA_ATTR_LABEL "label" #define STANZA_TEXT_AWAY "away" #define STANZA_TEXT_DND "dnd" @@ -233,6 +235,7 @@ #define STANZA_NS_EXT_GAJIM_BOOKMARKS "xmpp:gajim.org/bookmarks" #define STANZA_NS_RSM "http://jabber.org/protocol/rsm" #define STANZA_NS_REGISTER "jabber:iq:register" +#define STANZA_NS_VOICEREQUEST "http://jabber.org/protocol/muc#request" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -338,7 +341,6 @@ xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t* ctx, const cha void stanza_attach_publish_options_va(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, int count, ...); void stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value); - xmpp_stanza_t* stanza_create_omemo_devicelist_request(xmpp_ctx_t* ctx, const char* const id, const char* const jid); xmpp_stanza_t* stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t* ctx, const char* const jid); xmpp_stanza_t* stanza_create_omemo_devicelist_publish(xmpp_ctx_t* ctx, GList* const ids); @@ -396,4 +398,8 @@ xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, cons xmpp_stanza_t* stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* const password); +xmpp_stanza_t* stanza_request_voice(xmpp_ctx_t* ctx, const char* const room); + +xmpp_stanza_t* stanza_create_approve_voice(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form); + #endif diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index d4d32836..5f4efece 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -214,6 +214,7 @@ void message_send_composing(const char* const jid); void message_send_paused(const char* const jid); void message_send_gone(const char* const jid); void message_send_invite(const char* const room, const char* const contact, const char* const reason); +void message_request_voice(const char* const roomjid); bool message_is_sent_by_us(const ProfMessage* const message, bool checkOID); |