diff options
Diffstat (limited to 'src')
33 files changed, 724 insertions, 844 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index f0210713..f424d401 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -131,6 +131,7 @@ static char* _executable_autocomplete(ProfWin* window, const char* const input, static char* _lastactivity_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _intype_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _mood_autocomplete(ProfWin* window, const char* const input, gboolean previous); +static char* _strophe_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _adhoc_cmd_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _vcard_autocomplete(ProfWin* window, const char* const input, gboolean previous); @@ -276,6 +277,9 @@ static Autocomplete executable_ac; static Autocomplete intype_ac; static Autocomplete mood_ac; static Autocomplete mood_type_ac; +static Autocomplete strophe_ac; +static Autocomplete strophe_sm_ac; +static Autocomplete strophe_verbosity_ac; static Autocomplete adhoc_cmd_ac; static Autocomplete lastactivity_ac; static Autocomplete vcard_ac; @@ -1098,6 +1102,19 @@ cmd_ac_init(void) autocomplete_add(intype_ac, "console"); autocomplete_add(intype_ac, "titlebar"); + strophe_ac = autocomplete_new(); + autocomplete_add(strophe_ac, "sm"); + autocomplete_add(strophe_ac, "verbosity"); + strophe_sm_ac = autocomplete_new(); + autocomplete_add(strophe_sm_ac, "on"); + autocomplete_add(strophe_sm_ac, "no-resend"); + autocomplete_add(strophe_sm_ac, "off"); + strophe_verbosity_ac = autocomplete_new(); + autocomplete_add(strophe_verbosity_ac, "0"); + autocomplete_add(strophe_verbosity_ac, "1"); + autocomplete_add(strophe_verbosity_ac, "2"); + autocomplete_add(strophe_verbosity_ac, "3"); + mood_ac = autocomplete_new(); autocomplete_add(mood_ac, "set"); autocomplete_add(mood_ac, "clear"); @@ -1298,7 +1315,7 @@ cmd_ac_add_help(const char* const value) } void -cmd_ac_add_cmd(Command* command) +cmd_ac_add_cmd(const Command* command) { autocomplete_add(commands_ac, command->cmd); autocomplete_add(help_ac, command->cmd + 1); @@ -1595,6 +1612,9 @@ cmd_ac_reset(ProfWin* window) autocomplete_reset(intype_ac); autocomplete_reset(mood_ac); autocomplete_reset(mood_type_ac); + autocomplete_reset(strophe_verbosity_ac); + autocomplete_reset(strophe_sm_ac); + autocomplete_reset(strophe_ac); autocomplete_reset(adhoc_cmd_ac); autocomplete_reset(vcard_ac); @@ -2057,6 +2077,7 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ g_hash_table_insert(ac_funcs, "/lastactivity", _lastactivity_autocomplete); g_hash_table_insert(ac_funcs, "/intype", _intype_autocomplete); g_hash_table_insert(ac_funcs, "/mood", _mood_autocomplete); + g_hash_table_insert(ac_funcs, "/strophe", _strophe_autocomplete); g_hash_table_insert(ac_funcs, "/cmd", _adhoc_cmd_autocomplete); g_hash_table_insert(ac_funcs, "/vcard", _vcard_autocomplete); @@ -2360,7 +2381,7 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo char* found = NULL; gboolean result; - gchar** args = parse_args(input, 2, 8, &result); + auto_gcharv gchar** args = parse_args(input, 2, 8, &result); if (result && ((strcmp(args[0], "add") == 0) || (strcmp(args[0], "update") == 0))) { gboolean space_at_end = g_str_has_suffix(input, " "); @@ -2371,7 +2392,6 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -2382,7 +2402,6 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -2392,7 +2411,6 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -2403,7 +2421,6 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -2413,7 +2430,6 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -2424,14 +2440,11 @@ _bookmark_autocomplete(ProfWin* window, const char* const input, gboolean previo found = autocomplete_param_with_func(input, beginning->str, prefs_autocomplete_boolean_choice, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } } - g_strfreev(args); - found = autocomplete_param_with_func(input, "/bookmark remove", bookmark_find, previous, NULL); if (found) { return found; @@ -2633,7 +2646,7 @@ _otr_autocomplete(ProfWin* window, const char* const input, gboolean previous) // /otr policy always user@server.com if (conn_status == JABBER_CONNECTED) { gboolean result; - gchar** args = parse_args(input, 2, 3, &result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &result); if (result && (strcmp(args[0], "policy") == 0)) { GString* beginning = g_string_new("/otr "); g_string_append(beginning, args[0]); @@ -2645,11 +2658,9 @@ _otr_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_func(input, beginning->str, roster_contact_autocomplete, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } - g_strfreev(args); } found = autocomplete_param_with_ac(input, "/otr policy", otr_policy_ac, TRUE, previous); @@ -2697,7 +2708,7 @@ _pgp_autocomplete(ProfWin* window, const char* const input, gboolean previous) } gboolean result; - gchar** args = parse_args(input, 2, 3, &result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &result); if ((strncmp(input, "/pgp", 4) == 0) && (result == TRUE)) { GString* beginning = g_string_new("/pgp "); g_string_append(beginning, args[0]); @@ -2708,11 +2719,9 @@ _pgp_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } - g_strfreev(args); if (conn_status == JABBER_CONNECTED) { found = autocomplete_param_with_func(input, "/pgp setkey", roster_barejid_autocomplete, previous, NULL); @@ -2826,9 +2835,9 @@ _omemo_autocomplete(ProfWin* window, const char* const input, gboolean previous) int num_tokens = count_tokens(input); if (num_tokens == 4) { gboolean result; - gchar** args = parse_args(input, 2, 3, &result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &result); if (result) { - gchar* jid = g_strdup(args[1]); + auto_gchar gchar* jid = g_strdup(args[1]); found = autocomplete_param_no_with_func(input, "/omemo trust", 4, omemo_fingerprint_autocomplete, previous, jid); if (found) { return found; @@ -2853,9 +2862,9 @@ _omemo_autocomplete(ProfWin* window, const char* const input, gboolean previous) int num_tokens = count_tokens(input); if (num_tokens == 4) { gboolean result; - gchar** args = parse_args(input, 2, 3, &result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &result); if (result) { - gchar* jid = g_strdup(args[1]); + auto_gchar gchar* jid = g_strdup(args[1]); found = autocomplete_param_no_with_func(input, "/omemo untrust", 4, omemo_fingerprint_autocomplete, previous, jid); if (found) { return found; @@ -3389,7 +3398,7 @@ _affiliation_autocomplete(ProfWin* window, const char* const input, gboolean pre gboolean parse_result; Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid); - gchar** args = parse_args(input, 2, 3, &parse_result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &parse_result); if ((strncmp(input, "/affiliation", 12) == 0) && (parse_result == TRUE)) { GString* beginning = g_string_new("/affiliation "); @@ -3402,12 +3411,9 @@ _affiliation_autocomplete(ProfWin* window, const char* const input, gboolean pre result = autocomplete_param_with_ac(input, beginning->str, jid_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { - g_strfreev(args); return result; } } - - g_strfreev(args); } result = autocomplete_param_with_ac(input, "/affiliation set", affiliation_ac, TRUE, previous); @@ -3436,7 +3442,7 @@ _role_autocomplete(ProfWin* window, const char* const input, gboolean previous) gboolean parse_result; Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid); - gchar** args = parse_args(input, 2, 3, &parse_result); + auto_gcharv gchar** args = parse_args(input, 2, 3, &parse_result); if ((strncmp(input, "/role", 5) == 0) && (parse_result == TRUE)) { GString* beginning = g_string_new("/role "); @@ -3449,12 +3455,9 @@ _role_autocomplete(ProfWin* window, const char* const input, gboolean previous) result = autocomplete_param_with_ac(input, beginning->str, nick_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { - g_strfreev(args); return result; } } - - g_strfreev(args); } result = autocomplete_param_with_ac(input, "/role set", role_ac, TRUE, previous); @@ -3568,7 +3571,7 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou char* found = NULL; gboolean result = FALSE; - gchar** args = parse_args(input, 1, 9, &result); + auto_gcharv gchar** args = parse_args(input, 1, 9, &result); if (result) { gboolean space_at_end = g_str_has_suffix(input, " "); @@ -3579,7 +3582,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3590,7 +3592,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3600,7 +3601,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3611,7 +3611,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3621,7 +3620,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3632,7 +3630,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3642,7 +3639,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3653,7 +3649,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3667,7 +3662,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, auth_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3678,7 +3672,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, auth_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3689,7 +3682,6 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, auth_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3700,14 +3692,11 @@ _connect_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, auth_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } } - g_strfreev(args); - found = autocomplete_param_with_func(input, "/connect", accounts_find_enabled, previous, NULL); if (found) { return found; @@ -3736,7 +3725,7 @@ _join_autocomplete(ProfWin* window, const char* const input, gboolean previous) char* found = NULL; gboolean result = FALSE; - gchar** args = parse_args(input, 1, 5, &result); + auto_gcharv gchar** args = parse_args(input, 1, 5, &result); if (result) { gboolean space_at_end = g_str_has_suffix(input, " "); @@ -3747,7 +3736,6 @@ _join_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3757,14 +3745,11 @@ _join_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } } - g_strfreev(args); - found = autocomplete_param_with_func(input, "/join", bookmark_find, previous, NULL); return found; @@ -3856,7 +3841,7 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou char* found = NULL; gboolean result = FALSE; - gchar** args = parse_args(input, 2, 4, &result); + auto_gcharv gchar** args = parse_args(input, 2, 4, &result); if (result && (strcmp(args[0], "set") == 0)) { gboolean space_at_end = g_str_has_suffix(input, " "); int num_args = g_strv_length(args); @@ -3866,7 +3851,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, account_set_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3890,7 +3874,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, account_status_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3901,7 +3884,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, tls_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3912,7 +3894,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, auth_property_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3923,7 +3904,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_func(input, beginning->str, _script_autocomplete_func, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3945,7 +3925,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, theme_load_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3957,7 +3936,6 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_func(input, beginning->str, p_gpg_autocomplete_key, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -3970,13 +3948,10 @@ _account_autocomplete(ProfWin* window, const char* const input, gboolean previou found = autocomplete_param_with_ac(input, beginning->str, account_clear_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } - g_strfreev(args); - found = autocomplete_param_with_ac(input, "/account default", account_default_ac, TRUE, previous); if (found) { return found; @@ -4033,7 +4008,7 @@ _rooms_autocomplete(ProfWin* window, const char* const input, gboolean previous) char* found = NULL; gboolean result = FALSE; - gchar** args = parse_args(input, 0, 4, &result); + auto_gcharv gchar** args = parse_args(input, 0, 4, &result); if (result) { gboolean space_at_end = g_str_has_suffix(input, " "); @@ -4041,21 +4016,18 @@ _rooms_autocomplete(ProfWin* window, const char* const input, gboolean previous) if (num_args <= 1) { found = autocomplete_param_with_ac(input, "/rooms", rooms_all_ac, TRUE, previous); if (found) { - g_strfreev(args); return found; } } if ((num_args == 1 && g_strcmp0(args[0], "service") == 0 && space_at_end) || (num_args == 2 && g_strcmp0(args[0], "service") == 0 && !space_at_end)) { found = autocomplete_param_with_func(input, "/rooms service", muc_confserver_find, previous, NULL); if (found) { - g_strfreev(args); return found; } } if ((num_args == 1 && g_strcmp0(args[0], "cache") == 0 && space_at_end) || (num_args == 2 && g_strcmp0(args[0], "cache") == 0 && !space_at_end)) { found = autocomplete_param_with_ac(input, "/rooms cache", rooms_cache_ac, TRUE, previous); if (found) { - g_strfreev(args); return found; } } @@ -4065,7 +4037,6 @@ _rooms_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_ac(input, beginning->str, rooms_list_ac, TRUE, previous); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } @@ -4075,18 +4046,14 @@ _rooms_autocomplete(ProfWin* window, const char* const input, gboolean previous) found = autocomplete_param_with_func(input, beginning->str, muc_confserver_find, previous, NULL); g_string_free(beginning, TRUE); if (found) { - g_strfreev(args); return found; } } if ((num_args >= 2) && g_strcmp0(args[0], "cache") == 0) { - g_strfreev(args); return NULL; } } - g_strfreev(args); - return NULL; } @@ -4353,7 +4320,7 @@ _url_autocomplete(ProfWin* window, const char* const input, gboolean previous) } gboolean arg_result; - gchar** args = parse_args(input, 1, 8, &arg_result); + auto_gcharv gchar** args = parse_args(input, 1, 8, &arg_result); gboolean space_at_end = g_str_has_suffix(input, " "); int num_args = g_strv_length(args); @@ -4366,7 +4333,6 @@ _url_autocomplete(ProfWin* window, const char* const input, gboolean previous) g_free(cmd); } } - g_strfreev(args); } return result; @@ -4443,6 +4409,24 @@ _mood_autocomplete(ProfWin* window, const char* const input, gboolean previous) } static char* +_strophe_autocomplete(ProfWin* window, const char* const input, gboolean previous) +{ + char* result = NULL; + + result = autocomplete_param_with_ac(input, "/strophe sm", strophe_sm_ac, FALSE, previous); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/strophe verbosity", strophe_verbosity_ac, FALSE, previous); + if (result) { + return result; + } + + return autocomplete_param_with_ac(input, "/strophe", strophe_ac, FALSE, previous); +} + +static char* _adhoc_cmd_autocomplete(ProfWin* window, const char* const input, gboolean previous) { char* result = NULL; @@ -4458,7 +4442,7 @@ _vcard_autocomplete(ProfWin* window, const char* const input, gboolean previous) char* result = NULL; gboolean parse_result = FALSE; - gchar** args = parse_args(input, 0, 7, &parse_result); + auto_gcharv gchar** args = parse_args(input, 0, 7, &parse_result); if (parse_result && (g_strcmp0(args[0], "set") == 0)) { gboolean space_at_end = g_str_has_suffix(input, " "); @@ -4480,7 +4464,6 @@ _vcard_autocomplete(ProfWin* window, const char* const input, gboolean previous) result = autocomplete_param_with_ac(input, beginning->str, vcard_set_param_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { - g_strfreev(args); return result; } } else if ((num_args == 3 && space_at_end && is_num && (g_strcmp0(args[2], "type") == 0)) || (num_args == 4 && !space_at_end && is_num && (g_strcmp0(args[2], "type") == 0))) { @@ -4489,7 +4472,6 @@ _vcard_autocomplete(ProfWin* window, const char* const input, gboolean previous) result = autocomplete_param_with_ac(input, beginning->str, vcard_address_type_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { - g_strfreev(args); return result; } } else if ((num_args == 3 && space_at_end && is_num && autocomplete_contains(vcard_togglable_param_ac, args[2])) || (num_args == 4 && !space_at_end && is_num && autocomplete_contains(vcard_togglable_param_ac, args[2]))) { @@ -4498,7 +4480,6 @@ _vcard_autocomplete(ProfWin* window, const char* const input, gboolean previous) result = autocomplete_param_with_ac(input, beginning->str, vcard_toggle_ac, TRUE, previous); g_string_free(beginning, TRUE); if (result) { - g_strfreev(args); return result; } } else { diff --git a/src/command/cmd_ac.h b/src/command/cmd_ac.h index ef715310..ceab49b2 100644 --- a/src/command/cmd_ac.h +++ b/src/command/cmd_ac.h @@ -47,7 +47,7 @@ gboolean cmd_ac_exists(char* cmd); void cmd_ac_add(const char* const value); void cmd_ac_add_help(const char* const value); -void cmd_ac_add_cmd(Command* command); +void cmd_ac_add_cmd(const Command* command); void cmd_ac_add_alias(ProfAlias* alias); void cmd_ac_add_alias_value(char* value); diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 0a2a7440..fb37341d 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -88,31 +88,14 @@ #define CMD_TAG_UI "ui" #define CMD_TAG_PLUGINS "plugins" -#define CMD_MAINFUNC(func) func, -#define CMD_NOMAINFUNC NULL, -#define CMD_SUBFUNCS(...) { __VA_ARGS__, { NULL, NULL } }, -#define CMD_NOSUBFUNCS { { NULL, NULL } }, - -#define CMD_NOTAGS \ - { \ - { NULL }, -#define CMD_TAGS(...) \ - { \ - { __VA_ARGS__, NULL }, -#define CMD_SYN(...) { __VA_ARGS__, NULL }, -#define CMD_DESC(desc) desc, -#define CMD_NOARGS { { NULL, NULL } }, -#define CMD_ARGS(...) { __VA_ARGS__, { NULL, NULL } }, -#define CMD_NOEXAMPLES \ - { \ - NULL \ - } \ - } -#define CMD_EXAMPLES(...) \ - { \ - __VA_ARGS__, NULL \ - } \ - } +#define CMD_PREAMBLE(c, p, min, max, set) .cmd = c, .parser = p, .min_args = min, .max_args = max, .setting_func = set, +#define CMD_MAINFUNC(f) .func = f, +#define CMD_SUBFUNCS(...) .sub_funcs = { __VA_ARGS__, { NULL, NULL } }, +#define CMD_TAGS(...) .help.tags = { __VA_ARGS__, NULL }, +#define CMD_SYN(...) .help.synopsis = { __VA_ARGS__, NULL }, +#define CMD_DESC(d) .help.desc = d, +#define CMD_ARGS(...) .help.args = { __VA_ARGS__, { NULL, NULL } }, +#define CMD_EXAMPLES(...) .help.examples = { __VA_ARGS__, NULL } GHashTable* commands = NULL; @@ -123,12 +106,10 @@ static gboolean _cmd_has_tag(Command* pcmd, const char* const tag); */ // clang-format off -static struct cmd_t command_defs[] = { - { "/help", - parse_args_with_freetext, 0, 2, NULL, - CMD_NOSUBFUNCS +static const struct cmd_t command_defs[] = { + { CMD_PREAMBLE("/help", + parse_args_with_freetext, 0, 2, NULL) CMD_MAINFUNC(cmd_help) - CMD_NOTAGS CMD_SYN( "/help [<area>|<command>|search_all|search_any] [<search_terms>]") CMD_DESC( @@ -149,36 +130,34 @@ static struct cmd_t command_defs[] = { "/help who") }, - { "/about", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/about", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_about) - CMD_NOTAGS CMD_SYN( "/about") CMD_DESC( "Show version and license information.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/connect", - parse_args, 0, 7, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/connect", + parse_args, 0, 7, NULL) CMD_MAINFUNC(cmd_connect) CMD_TAGS( CMD_TAG_CONNECTION) CMD_SYN( "/connect [<account>]", - "/connect <account> [server <server>] [port <port>] [tls force|allow|trust|legacy|disable] [auth default|legacy]") + "/connect <account> [server <server>] [port <port>] [tls force|allow|trust|legacy|disable] [auth default|legacy]", + "/connect <server>") CMD_DESC( "Login to a chat service. " "If no account is specified, the default is used if one is configured. " - "A local account is created with the JID as it's name if it doesn't already exist.") + "A local account is created with the JID as it's name if it doesn't already exist. " + "In case you want to connect to a server via SASL ANONYMOUS (c.f. XEP-0175) you can also do that.") CMD_ARGS( { "<account>", "The local account you wish to connect with, or a JID if connecting for the first time." }, { "server <server>", "Supply a server if it is different to the domain part of your JID." }, { "port <port>", "The port to use if different to the default (5222, or 5223 for SSL)." }, + { "<server>", "Connect to said server in an anonymous way. (Be aware: There aren't many servers that support this.)" }, { "tls force", "Force TLS connection, and fail if one cannot be established, this is default behaviour." }, { "tls allow", "Use TLS for the connection if it is available." }, { "tls trust", "Force TLS connection and trust server's certificate." }, @@ -192,54 +171,52 @@ static struct cmd_t command_defs[] = { "/connect odin@valhalla.edda server talk.google.com", "/connect freyr@vanaheimr.edda port 5678", "/connect me@localhost.test.org server 127.0.0.1 tls disable", - "/connect me@chatty server chatty.com port 5443") + "/connect me@chatty server chatty.com port 5443", + "/connect server.supporting.sasl.anonymous.example") }, - { "/tls", - parse_args, 1, 3, NULL, + { CMD_PREAMBLE("/tls", + parse_args, 1, 3, NULL) CMD_SUBFUNCS( { "certpath", cmd_tls_certpath }, { "trust", cmd_tls_trust }, { "trusted", cmd_tls_trusted }, { "revoke", cmd_tls_revoke }, { "cert", cmd_tls_cert }) - CMD_NOMAINFUNC - CMD_TAGS( - CMD_TAG_CONNECTION, - CMD_TAG_UI) - CMD_SYN( - "/tls allow", - "/tls always", - "/tls deny", - "/tls cert [<fingerprint>]", - "/tls trust", - "/tls trusted", - "/tls revoke <fingerprint>", - "/tls certpath", - "/tls certpath set <path>", - "/tls certpath clear", - "/tls certpath default") - CMD_DESC( - "Handle TLS certificates. ") - CMD_ARGS( - { "allow", "Allow connection to continue with TLS certificate." }, - { "always", "Always allow connections with TLS certificate." }, - { "deny", "Abort connection." }, - { "cert", "Show the current TLS certificate." }, - { "cert <fingerprint>", "Show details of trusted certificate." }, - { "trust", "Add the current TLS certificate to manually trusted certificates." }, - { "trusted", "List summary of manually trusted certificates (with '/tls always' or '/tls trust')." }, - { "revoke <fingerprint>", "Remove a manually trusted certificate." }, - { "certpath", "Show the trusted certificate path." }, - { "certpath set <path>", "Specify filesystem path containing trusted certificates." }, - { "certpath clear", "Clear the trusted certificate path." }, - { "certpath default", "Use default system certificate path, if it can be found." }) - CMD_NOEXAMPLES - }, - - { "/disconnect", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + CMD_TAGS( + CMD_TAG_CONNECTION, + CMD_TAG_UI) + CMD_SYN( + "/tls allow", + "/tls always", + "/tls deny", + "/tls cert [<fingerprint>]", + "/tls trust", + "/tls trusted", + "/tls revoke <fingerprint>", + "/tls certpath", + "/tls certpath set <path>", + "/tls certpath clear", + "/tls certpath default") + CMD_DESC( + "Handle TLS certificates. ") + CMD_ARGS( + { "allow", "Allow connection to continue with TLS certificate." }, + { "always", "Always allow connections with TLS certificate." }, + { "deny", "Abort connection." }, + { "cert", "Show the current TLS certificate." }, + { "cert <fingerprint>", "Show details of trusted certificate." }, + { "trust", "Add the current TLS certificate to manually trusted certificates." }, + { "trusted", "List summary of manually trusted certificates (with '/tls always' or '/tls trust')." }, + { "revoke <fingerprint>", "Remove a manually trusted certificate." }, + { "certpath", "Show the trusted certificate path." }, + { "certpath set <path>", "Specify filesystem path containing trusted certificates." }, + { "certpath clear", "Clear the trusted certificate path." }, + { "certpath default", "Use default system certificate path, if it can be found." }) + }, + + { CMD_PREAMBLE("/disconnect", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_disconnect) CMD_TAGS( CMD_TAG_CONNECTION) @@ -247,13 +224,10 @@ static struct cmd_t command_defs[] = { "/disconnect") CMD_DESC( "Disconnect from the current chat service.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/msg", - parse_args_with_freetext, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/msg", + parse_args_with_freetext, 1, 2, NULL) CMD_MAINFUNC(cmd_msg) CMD_TAGS( CMD_TAG_CHAT) @@ -276,8 +250,8 @@ static struct cmd_t command_defs[] = { "/msg \"My Friend\" Hi, how are you?") }, - { "/roster", - parse_args_with_freetext, 0, 4, NULL, + { CMD_PREAMBLE("/roster", + parse_args_with_freetext, 0, 4, NULL) CMD_SUBFUNCS( { "group", cmd_group }) CMD_MAINFUNC(cmd_roster) @@ -419,9 +393,8 @@ static struct cmd_t command_defs[] = { "/roster group remove colleagues boss@work.com") }, - { "/blocked", - parse_args_with_freetext, 0, 3, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/blocked", + parse_args_with_freetext, 0, 3, NULL) CMD_MAINFUNC(cmd_blocked) CMD_TAGS( CMD_TAG_ROSTER, @@ -447,9 +420,8 @@ static struct cmd_t command_defs[] = { "/blocked add profanity@rooms.dismail.de/spammy-user") }, - { "/info", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/info", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_info) CMD_TAGS( CMD_TAG_ROSTER, @@ -470,9 +442,8 @@ static struct cmd_t command_defs[] = { "/info heimdall") }, - { "/caps", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/caps", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_caps) CMD_TAGS( CMD_TAG_DISCOVERY, @@ -493,9 +464,8 @@ static struct cmd_t command_defs[] = { "/caps aegir") }, - { "/software", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/software", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_software) CMD_TAGS( CMD_TAG_DISCOVERY, @@ -517,12 +487,11 @@ static struct cmd_t command_defs[] = { "/software thor") }, - { "/status", - parse_args, 2, 3, NULL, + { CMD_PREAMBLE("/status", + parse_args, 2, 3, NULL) CMD_SUBFUNCS( { "get", cmd_status_get }, { "set", cmd_status_set }) - CMD_NOMAINFUNC CMD_TAGS( CMD_TAG_CHAT, CMD_TAG_GROUPCHAT) @@ -543,9 +512,8 @@ static struct cmd_t command_defs[] = { "/status set online") }, - { "/resource", - parse_args, 1, 2, &cons_resource_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/resource", + parse_args, 1, 2, &cons_resource_setting) CMD_MAINFUNC(cmd_resource) CMD_TAGS( CMD_TAG_CHAT, @@ -562,12 +530,10 @@ static struct cmd_t command_defs[] = { { "off", "Let the server choose which resource to route messages to." }, { "title on|off", "Show or hide the current resource in the titlebar." }, { "message on|off", "Show or hide the resource when showing an incoming message." }) - CMD_NOEXAMPLES }, - { "/join", - parse_args, 0, 5, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/join", + parse_args, 0, 5, NULL) CMD_MAINFUNC(cmd_join) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -594,9 +560,8 @@ static struct cmd_t command_defs[] = { "/join mychannel") }, - { "/invite", - parse_args_with_freetext, 1, 3, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/invite", + parse_args_with_freetext, 1, 3, NULL) CMD_MAINFUNC(cmd_invite) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -619,9 +584,8 @@ static struct cmd_t command_defs[] = { "/invite list") }, - { "/room", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/room", + parse_args, 1, 1, NULL) CMD_MAINFUNC(cmd_room) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -633,12 +597,10 @@ static struct cmd_t command_defs[] = { { "accept", "Accept default room configuration." }, { "destroy", "Reject default room configuration, and destroy the room." }, { "config", "Edit room configuration." }) - CMD_NOEXAMPLES }, - { "/kick", - parse_args_with_freetext, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/kick", + parse_args_with_freetext, 1, 2, NULL) CMD_MAINFUNC(cmd_kick) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -649,11 +611,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "<nick>", "Nickname of the occupant to kick from the room." }, { "<reason>", "Optional reason for kicking the occupant." }) - CMD_NOEXAMPLES }, + }, - { "/ban", - parse_args_with_freetext, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/ban", + parse_args_with_freetext, 1, 2, NULL) CMD_MAINFUNC(cmd_ban) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -664,12 +625,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "<jid>", "Bare JID of the user to ban from the room." }, { "<reason>", "Optional reason for banning the user." }) - CMD_NOEXAMPLES }, - { "/subject", - parse_args_with_freetext, 0, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/subject", + parse_args_with_freetext, 0, 2, NULL) CMD_MAINFUNC(cmd_subject) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -689,12 +648,10 @@ static struct cmd_t command_defs[] = { { "prepend <text>", "Prepend text to the current room subject, use double quotes if a trailing space is needed." }, { "append <text>", "Append text to the current room subject, use double quotes if a preceding space is needed." }, { "clear", "Clear the room subject." }) - CMD_NOEXAMPLES }, - { "/affiliation", - parse_args_with_freetext, 1, 4, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/affiliation", + parse_args_with_freetext, 1, 4, NULL) CMD_MAINFUNC(cmd_affiliation) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -711,12 +668,10 @@ static struct cmd_t command_defs[] = { { "list [<affiliation>]", "List all users with the specified affiliation, or all if none specified." }, { "request", "Request voice."}, { "register", "Register your nickname with the MUC."}) - CMD_NOEXAMPLES }, - { "/role", - parse_args_with_freetext, 1, 4, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/role", + parse_args_with_freetext, 1, 4, NULL) CMD_MAINFUNC(cmd_role) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -729,12 +684,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "set <role> <nick> [<reason>]", "Set the role of occupant with nick, with an optional reason." }, { "list [<role>]", "List all occupants with the specified role, or all if none specified." }) - CMD_NOEXAMPLES }, - { "/occupants", - parse_args, 1, 3, cons_occupants_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/occupants", + parse_args, 1, 3, cons_occupants_setting) CMD_MAINFUNC(cmd_occupants) CMD_TAGS( CMD_TAG_GROUPCHAT, @@ -769,12 +722,10 @@ static struct cmd_t command_defs[] = { { "header char <char>", "Prefix occupants headers with specified character." }, { "header char none", "Remove occupants header character prefix." }, { "wrap on|off", "Enable or disable line wrapping in occupants panel." }) - CMD_NOEXAMPLES }, - { "/form", - parse_args, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/form", + parse_args, 1, 2, NULL) CMD_MAINFUNC(cmd_form) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -790,12 +741,10 @@ static struct cmd_t command_defs[] = { { "submit", "Submit the current form." }, { "cancel", "Cancel changes to the current form." }, { "help [<tag>]", "Display help for form, or a specific field." }) - CMD_NOEXAMPLES }, - { "/rooms", - parse_args, 0, 4, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/rooms", + parse_args, 0, 4, NULL) CMD_MAINFUNC(cmd_rooms) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -821,8 +770,8 @@ static struct cmd_t command_defs[] = { "/rooms service conference.jabber.org filter \"News Room\"") }, - { "/bookmark", - parse_args, 0, 8, NULL, + { CMD_PREAMBLE("/bookmark", + parse_args, 0, 8, NULL) CMD_SUBFUNCS( { "ignore", cmd_bookmark_ignore }) CMD_MAINFUNC(cmd_bookmark) @@ -866,9 +815,8 @@ static struct cmd_t command_defs[] = { "/bookmark remove room@example.com") }, - { "/disco", - parse_args, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/disco", + parse_args, 1, 2, NULL) CMD_MAINFUNC(cmd_disco) CMD_TAGS( CMD_TAG_DISCOVERY) @@ -889,9 +837,8 @@ static struct cmd_t command_defs[] = { "/disco info odin@valhalla.edda/laptop") }, - { "/sendfile", - parse_args_with_freetext, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/sendfile", + parse_args_with_freetext, 1, 1, NULL) CMD_MAINFUNC(cmd_sendfile) CMD_TAGS( CMD_TAG_CHAT, @@ -907,9 +854,8 @@ static struct cmd_t command_defs[] = { "/sendfile ~/images/sweet_cat.jpg") }, - { "/lastactivity", - parse_args, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/lastactivity", + parse_args, 1, 2, NULL) CMD_MAINFUNC(cmd_lastactivity) CMD_TAGS( CMD_TAG_PRESENCE) @@ -929,9 +875,8 @@ static struct cmd_t command_defs[] = { "/lastactivity get someserver.com") }, - { "/nick", - parse_args_with_freetext, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/nick", + parse_args_with_freetext, 1, 1, NULL) CMD_MAINFUNC(cmd_nick) CMD_TAGS( CMD_TAG_GROUPCHAT) @@ -941,12 +886,10 @@ static struct cmd_t command_defs[] = { "Change your nickname in the current chat room.") CMD_ARGS( { "<nickname>", "Your new nickname." }) - CMD_NOEXAMPLES }, - { "/win", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/win", + parse_args, 1, 1, NULL) CMD_MAINFUNC(cmd_win) CMD_TAGS( CMD_TAG_UI) @@ -980,8 +923,8 @@ static struct cmd_t command_defs[] = { "/win wikipedia") }, - { "/wins", - parse_args, 0, 3, NULL, + { CMD_PREAMBLE("/wins", + parse_args, 0, 3, NULL) CMD_SUBFUNCS( { "unread", cmd_wins_unread }, { "attention", cmd_wins_attention }, @@ -1004,12 +947,10 @@ static struct cmd_t command_defs[] = { { "attention", "List windows that have been marked with the attention flag (alt+v). You can toggle between marked windows with alt+m." }, { "prune", "Close all windows with no unread messages." }, { "swap <source> <target>", "Swap windows, target may be an empty position." }) - CMD_NOEXAMPLES }, - { "/sub", - parse_args, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/sub", + parse_args, 1, 2, NULL) CMD_MAINFUNC(cmd_sub) CMD_TAGS( CMD_TAG_ROSTER) @@ -1037,9 +978,8 @@ static struct cmd_t command_defs[] = { "/sub sent") }, - { "/who", - parse_args, 0, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/who", + parse_args, 0, 2, NULL) CMD_MAINFUNC(cmd_who) CMD_TAGS( CMD_TAG_CHAT, @@ -1070,9 +1010,8 @@ static struct cmd_t command_defs[] = { "/who admin") }, - { "/close", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/close", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_close) CMD_TAGS( CMD_TAG_UI) @@ -1097,12 +1036,10 @@ static struct cmd_t command_defs[] = { { "xmlconsole", "Close the XML Console window if open." }, { "all", "Close all windows." }, { "read", "Close all windows that have no unread messages." }) - CMD_NOEXAMPLES }, - { "/clear", - parse_args, 0, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/clear", + parse_args, 0, 2, NULL) CMD_MAINFUNC(cmd_clear) CMD_TAGS( CMD_TAG_UI) @@ -1120,22 +1057,17 @@ static struct cmd_t command_defs[] = { "/clear persist_history on") }, - { "/quit", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/quit", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_quit) - CMD_NOTAGS - CMD_SYN( + CMD_SYN( "/quit") CMD_DESC( "Logout of any current session, and quit Profanity.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/privileges", - parse_args, 1, 1, &cons_privileges_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/privileges", + parse_args, 1, 1, &cons_privileges_setting) CMD_MAINFUNC(cmd_privileges) CMD_TAGS( CMD_TAG_GROUPCHAT, @@ -1146,12 +1078,10 @@ static struct cmd_t command_defs[] = { "Group occupants panel by role, and show role information in chat rooms.") CMD_ARGS( { "on|off", "Enable or disable privilege information." }) - CMD_NOEXAMPLES }, - { "/charset", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/charset", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_charset) CMD_TAGS( CMD_TAG_UI) @@ -1159,13 +1089,10 @@ static struct cmd_t command_defs[] = { "/charset") CMD_DESC( "Display information about the current character set supported by the terminal. ") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/beep", - parse_args, 1, 1, &cons_beep_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/beep", + parse_args, 1, 1, &cons_beep_setting) CMD_MAINFUNC(cmd_beep) CMD_TAGS( CMD_TAG_UI) @@ -1177,12 +1104,10 @@ static struct cmd_t command_defs[] = { "If the terminal does not support sounds, it may attempt to flash the screen instead.") CMD_ARGS( { "on|off", "Enable or disable terminal bell." }) - CMD_NOEXAMPLES }, - { "/console", - parse_args, 2, 2, &cons_console_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/console", + parse_args, 2, 2, &cons_console_setting) CMD_MAINFUNC(cmd_console) CMD_TAGS( CMD_TAG_UI, @@ -1206,12 +1131,10 @@ static struct cmd_t command_defs[] = { { "private all", "Indicate all new private room messages in the console." }, { "private first", "Indicate only the first private room message in the console." }, { "private none", "Do not show any new private room messages in the console window." }) - CMD_NOEXAMPLES }, - { "/presence", - parse_args, 2, 2, &cons_presence_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/presence", + parse_args, 2, 2, &cons_presence_setting) CMD_MAINFUNC(cmd_presence) CMD_TAGS( CMD_TAG_UI, @@ -1242,9 +1165,8 @@ static struct cmd_t command_defs[] = { "/presence room all") }, - { "/wrap", - parse_args, 1, 1, &cons_wrap_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/wrap", + parse_args, 1, 1, &cons_wrap_setting) CMD_MAINFUNC(cmd_wrap) CMD_TAGS( CMD_TAG_UI) @@ -1254,12 +1176,10 @@ static struct cmd_t command_defs[] = { "Word wrapping.") CMD_ARGS( { "on|off", "Enable or disable word wrapping in the main window." }) - CMD_NOEXAMPLES }, - { "/time", - parse_args, 1, 3, &cons_time_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/time", + parse_args, 1, 3, &cons_time_setting) CMD_MAINFUNC(cmd_time) CMD_TAGS( CMD_TAG_UI) @@ -1304,9 +1224,8 @@ static struct cmd_t command_defs[] = { "/time all set \"%d-%m-%y %H:%M:%S\"") }, - { "/inpblock", - parse_args, 2, 2, &cons_inpblock_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/inpblock", + parse_args, 2, 2, &cons_inpblock_setting) CMD_MAINFUNC(cmd_inpblock) CMD_TAGS( CMD_TAG_UI) @@ -1318,11 +1237,11 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "timeout <millis>", "Time to wait (1-1000) in milliseconds before reading input from the terminal buffer, default: 1000." }, { "dynamic on|off", "Start with 0 millis and dynamically increase up to timeout when no activity, default: on." }) - CMD_NOEXAMPLES }, + }, - { "/titlebar", - parse_args, 1, 2, &cons_titlebar_setting, + { CMD_PREAMBLE("/titlebar", + parse_args, 1, 2, &cons_titlebar_setting) CMD_SUBFUNCS( { "show", cmd_titlebar_show_hide }, { "hide", cmd_titlebar_show_hide }) @@ -1349,9 +1268,8 @@ static struct cmd_t command_defs[] = { "/titlebar hide encwarn") }, - { "/mainwin", - parse_args, 1, 1, &cons_winpos_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/mainwin", + parse_args, 1, 1, &cons_winpos_setting) CMD_MAINFUNC(cmd_mainwin) CMD_TAGS( CMD_TAG_UI) @@ -1363,12 +1281,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "up", "Move the main window up the screen." }, { "down", "Move the main window down the screen." }) - CMD_NOEXAMPLES }, - { "/statusbar", - parse_args, 1, 2, &cons_statusbar_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/statusbar", + parse_args, 1, 2, &cons_statusbar_setting) CMD_MAINFUNC(cmd_statusbar) CMD_TAGS( CMD_TAG_UI) @@ -1405,9 +1321,8 @@ static struct cmd_t command_defs[] = { "/statusbar hide name") }, - { "/inputwin", - parse_args, 1, 1, &cons_winpos_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/inputwin", + parse_args, 1, 1, &cons_winpos_setting) CMD_MAINFUNC(cmd_inputwin) CMD_TAGS( CMD_TAG_UI) @@ -1419,12 +1334,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "up", "Move the input window up the screen." }, { "down", "Move the input window down the screen." }) - CMD_NOEXAMPLES }, - { "/notify", - parse_args_with_freetext, 0, 4, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/notify", + parse_args_with_freetext, 0, 4, NULL) CMD_MAINFUNC(cmd_notify) CMD_TAGS( CMD_TAG_UI, @@ -1497,9 +1410,8 @@ static struct cmd_t command_defs[] = { "/notify invite on") }, - { "/flash", - parse_args, 1, 1, &cons_flash_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/flash", + parse_args, 1, 1, &cons_flash_setting) CMD_MAINFUNC(cmd_flash) CMD_TAGS( CMD_TAG_UI) @@ -1510,12 +1422,10 @@ static struct cmd_t command_defs[] = { "If the terminal doesn't support flashing, it may attempt to beep.") CMD_ARGS( { "on|off", "Enable or disable terminal flash." }) - CMD_NOEXAMPLES }, - { "/tray", - parse_args, 1, 2, &cons_tray_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/tray", + parse_args, 1, 2, &cons_tray_setting) CMD_MAINFUNC(cmd_tray) CMD_TAGS( CMD_TAG_UI) @@ -1529,12 +1439,10 @@ static struct cmd_t command_defs[] = { { "on|off", "Show tray icon." }, { "read on|off", "Show tray icon when no unread messages." }, { "timer <seconds>", "Set tray icon timer, seconds must be between 1-10." }) - CMD_NOEXAMPLES }, - { "/intype", - parse_args, 2, 2, &cons_intype_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/intype", + parse_args, 2, 2, &cons_intype_setting) CMD_MAINFUNC(cmd_intype) CMD_TAGS( CMD_TAG_UI, @@ -1546,12 +1454,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "titlebar on|off", "Enable or disable contact typing messages notification in titlebar." }, { "console on|off", "Enable or disable contact typing messages notification in console window." }) - CMD_NOEXAMPLES }, - { "/splash", - parse_args, 1, 1, &cons_splash_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/splash", + parse_args, 1, 1, &cons_splash_setting) CMD_MAINFUNC(cmd_splash) CMD_TAGS( CMD_TAG_UI) @@ -1561,12 +1467,10 @@ static struct cmd_t command_defs[] = { "Switch on or off the ascii logo on start up and when the /about command is called.") CMD_ARGS( { "on|off", "Enable or disable splash logo." }) - CMD_NOEXAMPLES }, - { "/autoconnect", - parse_args, 1, 2, &cons_autoconnect_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/autoconnect", + parse_args, 1, 2, &cons_autoconnect_setting) CMD_MAINFUNC(cmd_autoconnect) CMD_TAGS( CMD_TAG_CONNECTION) @@ -1584,8 +1488,8 @@ static struct cmd_t command_defs[] = { "/autoconnect off") }, - { "/vcard", - parse_args, 0, 7, NULL, + { CMD_PREAMBLE("/vcard", + parse_args, 0, 7, NULL) CMD_SUBFUNCS( {"add", cmd_vcard_add}, {"remove", cmd_vcard_remove}, @@ -1699,12 +1603,10 @@ static struct cmd_t command_defs[] = { { "remove <index>", "Remove a element in your vCard by index" }, { "refresh", "Refreshes the local copy of the current account's vCard (undoes all your unpublished modifications)" }, { "save", "Save changes to the server" }) - CMD_NOEXAMPLES }, - { "/vercheck", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/vercheck", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_vercheck) CMD_TAGS( CMD_TAG_UI) @@ -1714,12 +1616,10 @@ static struct cmd_t command_defs[] = { "Check for new versions when Profanity starts, and when the /about command is run.") CMD_ARGS( { "on|off", "Enable or disable the version check." }) - CMD_NOEXAMPLES }, - { "/wintitle", - parse_args, 2, 2, &cons_wintitle_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/wintitle", + parse_args, 2, 2, &cons_wintitle_setting) CMD_MAINFUNC(cmd_wintitle) CMD_TAGS( CMD_TAG_UI) @@ -1731,14 +1631,11 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "show on|off", "Show current logged in user, and unread messages as the window title." }, { "goodbye on|off", "Show a message in the title when exiting profanity." }) - CMD_NOEXAMPLES }, - { "/alias", - parse_args_with_freetext, 1, 3, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/alias", + parse_args_with_freetext, 1, 3, NULL) CMD_MAINFUNC(cmd_alias) - CMD_NOTAGS CMD_SYN( "/alias list", "/alias add <name> <value>", @@ -1757,9 +1654,8 @@ static struct cmd_t command_defs[] = { "/alias list") }, - { "/logging", - parse_args, 2, 3, &cons_logging_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/logging", + parse_args, 2, 3, &cons_logging_setting) CMD_MAINFUNC(cmd_logging) CMD_TAGS( CMD_TAG_CHAT) @@ -1778,9 +1674,8 @@ static struct cmd_t command_defs[] = { "/logging group off") }, - { "/states", - parse_args, 1, 1, &cons_states_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/states", + parse_args, 1, 1, &cons_states_setting) CMD_MAINFUNC(cmd_states) CMD_TAGS( CMD_TAG_CHAT) @@ -1790,11 +1685,10 @@ static struct cmd_t command_defs[] = { "Send chat state notifications to recipient during chat sessions, such as typing, paused, active, gone.") CMD_ARGS( { "on|off", "Enable or disable sending of chat state notifications." }) - CMD_NOEXAMPLES }, + }, - { "/pgp", - parse_args, 1, 3, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/pgp", + parse_args, 1, 3, NULL) CMD_MAINFUNC(cmd_pgp) CMD_TAGS( CMD_TAG_CHAT, @@ -1833,8 +1727,8 @@ static struct cmd_t command_defs[] = { // XEP-0373: OpenPGP for XMPP #ifdef HAVE_LIBGPGME - { "/ox", - parse_args, 1, 3, NULL, + { CMD_PREAMBLE("/ox", + parse_args, 1, 3, NULL) CMD_SUBFUNCS( { "log", cmd_ox_log }) CMD_MAINFUNC(cmd_ox) @@ -1875,8 +1769,8 @@ static struct cmd_t command_defs[] = { }, #endif // HAVE_LIBGPGME - { "/otr", - parse_args, 1, 3, NULL, + { CMD_PREAMBLE("/otr", + parse_args, 1, 3, NULL) CMD_SUBFUNCS( { "char", cmd_otr_char }, { "log", cmd_otr_log }, @@ -1893,7 +1787,6 @@ static struct cmd_t command_defs[] = { { "question", cmd_otr_question }, { "answer", cmd_otr_answer }, { "sendfile", cmd_otr_sendfile }) - CMD_NOMAINFUNC CMD_TAGS( CMD_TAG_CHAT, CMD_TAG_UI) @@ -1947,9 +1840,8 @@ static struct cmd_t command_defs[] = { "/otr char *") }, - { "/outtype", - parse_args, 1, 1, &cons_outtype_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/outtype", + parse_args, 1, 1, &cons_outtype_setting) CMD_MAINFUNC(cmd_outtype) CMD_TAGS( CMD_TAG_CHAT) @@ -1959,12 +1851,10 @@ static struct cmd_t command_defs[] = { "Send typing notifications, chat states (/states) will be enabled if this setting is enabled.") CMD_ARGS( { "on|off", "Enable or disable sending typing notifications." }) - CMD_NOEXAMPLES }, - { "/gone", - parse_args, 1, 1, &cons_gone_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/gone", + parse_args, 1, 1, &cons_gone_setting) CMD_MAINFUNC(cmd_gone) CMD_TAGS( CMD_TAG_CHAT) @@ -1975,12 +1865,10 @@ static struct cmd_t command_defs[] = { "Chat states (/states) will be enabled if this setting is set.") CMD_ARGS( { "<minutes>", "Number of minutes of inactivity before sending the 'gone' state, a value of 0 will disable sending this state." }) - CMD_NOEXAMPLES }, - { "/history", - parse_args, 1, 1, &cons_history_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/history", + parse_args, 1, 1, &cons_history_setting) CMD_MAINFUNC(cmd_history) CMD_TAGS( CMD_TAG_UI, @@ -1992,14 +1880,11 @@ static struct cmd_t command_defs[] = { "When history is enabled, previous messages are shown in chat windows.") CMD_ARGS( { "on|off", "Enable or disable showing chat history." }) - CMD_NOEXAMPLES }, - { "/log", - parse_args, 1, 2, &cons_log_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/log", + parse_args, 1, 2, &cons_log_setting) CMD_MAINFUNC(cmd_log) - CMD_NOTAGS CMD_SYN( "/log where", "/log rotate on|off", @@ -2013,13 +1898,11 @@ static struct cmd_t command_defs[] = { { "rotate on|off", "Rotate log, default on. Does not take effect if you specified a filename yourself when starting Profanity." }, { "maxsize <bytes>", "With rotate enabled, specifies the max log size, defaults to 10485760 (10MB)." }, { "shared on|off", "Share logs between all instances, default: on. When off, the process id will be included in the log filename. Does not take effect if you specified a filename yourself when starting Profanity." }, - {"level INFO|DEBUG|WARN|EFFOR", "Set the log level. Default is INFO. Only works with default log file, not with user provided log file during startup via -f." }) - CMD_NOEXAMPLES + {"level INFO|DEBUG|WARN|ERROR", "Set the log level. Default is INFO. Only works with default log file, not with user provided log file during startup via -f." }) }, - { "/carbons", - parse_args, 1, 1, &cons_carbons_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/carbons", + parse_args, 1, 1, &cons_carbons_setting) CMD_MAINFUNC(cmd_carbons) CMD_TAGS( CMD_TAG_CHAT) @@ -2030,12 +1913,10 @@ static struct cmd_t command_defs[] = { "Message carbons ensure that both sides of all conversations are shared with all the user's clients that implement this protocol.") CMD_ARGS( { "on|off", "Enable or disable message carbons." }) - CMD_NOEXAMPLES }, - { "/receipts", - parse_args, 2, 2, &cons_receipts_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/receipts", + parse_args, 2, 2, &cons_receipts_setting) CMD_MAINFUNC(cmd_receipts) CMD_TAGS( CMD_TAG_CHAT) @@ -2047,27 +1928,25 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "request on|off", "Whether or not to request a receipt upon sending a message." }, { "send on|off", "Whether or not to send a receipt if one has been requested with a received message." }) - CMD_NOEXAMPLES }, - { "/reconnect", - parse_args, 1, 1, &cons_reconnect_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/reconnect", + parse_args, 1, 1, &cons_reconnect_setting) CMD_MAINFUNC(cmd_reconnect) CMD_TAGS( CMD_TAG_CONNECTION) CMD_SYN( - "/reconnect <seconds>") + "/reconnect <seconds>", + "/reconnect now") CMD_DESC( - "Set the reconnect attempt interval for when the connection is lost.") + "Set the reconnect attempt interval for when the connection is lost or immediately trigger a reconnect.") CMD_ARGS( - { "<seconds>", "Number of seconds before attempting to reconnect, a value of 0 disables reconnect." }) - CMD_NOEXAMPLES + { "<seconds>", "Number of seconds before attempting to reconnect, a value of 0 disables reconnect." }, + { "now", "Immediately trigger a reconnect." }) }, - { "/autoping", - parse_args, 2, 2, &cons_autoping_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/autoping", + parse_args, 2, 2, &cons_autoping_setting) CMD_MAINFUNC(cmd_autoping) CMD_TAGS( CMD_TAG_CONNECTION) @@ -2079,12 +1958,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "set <seconds>", "Number of seconds between sending pings, a value of 0 disables autoping." }, { "timeout <seconds>", "Seconds to wait for autoping responses, after which the connection is considered broken." }) - CMD_NOEXAMPLES }, - { "/ping", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/ping", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_ping) CMD_TAGS( CMD_TAG_CONNECTION) @@ -2095,12 +1972,10 @@ static struct cmd_t command_defs[] = { "If no JID is supplied, your chat server will be pinged.") CMD_ARGS( { "<jid>", "The Jabber ID to send the ping request to." }) - CMD_NOEXAMPLES }, - { "/autoaway", - parse_args_with_freetext, 2, 3, &cons_autoaway_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/autoaway", + parse_args_with_freetext, 2, 3, &cons_autoaway_setting) CMD_MAINFUNC(cmd_autoaway) CMD_TAGS( CMD_TAG_PRESENCE) @@ -2131,9 +2006,8 @@ static struct cmd_t command_defs[] = { "/autoaway check off") }, - { "/priority", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/priority", + parse_args, 1, 1, NULL) CMD_MAINFUNC(cmd_priority) CMD_TAGS( CMD_TAG_PRESENCE) @@ -2144,11 +2018,10 @@ static struct cmd_t command_defs[] = { "See the /account command for specific priority settings per presence status.") CMD_ARGS( { "<priority>", "Number between -128 and 127, default: 0." }) - CMD_NOEXAMPLES }, - { "/account", - parse_args, 0, 4, NULL, + { CMD_PREAMBLE("/account", + parse_args, 0, 4, NULL) CMD_SUBFUNCS( { "list", cmd_account_list }, { "show", cmd_account_show }, @@ -2260,8 +2133,8 @@ static struct cmd_t command_defs[] = { "/account clear me pgpkeyid") }, - { "/plugins", - parse_args, 0, 3, NULL, + { CMD_PREAMBLE("/plugins", + parse_args, 0, 3, NULL) CMD_SUBFUNCS( { "install", cmd_plugins_install }, { "uninstall", cmd_plugins_uninstall }, @@ -2271,7 +2144,6 @@ static struct cmd_t command_defs[] = { { "reload", cmd_plugins_reload }, { "python_version", cmd_plugins_python_version }) CMD_MAINFUNC(cmd_plugins) - CMD_NOTAGS CMD_SYN( "/plugins", "/plugins install [<path>]", @@ -2301,11 +2173,9 @@ static struct cmd_t command_defs[] = { "/plugins reload wikipedia.py") }, - { "/prefs", - parse_args, 0, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/prefs", + parse_args, 0, 1, NULL) CMD_MAINFUNC(cmd_prefs) - CMD_NOTAGS CMD_SYN( "/prefs [ui|desktop|chat|log|conn|presence|otr|pgp|omemo]") CMD_DESC( @@ -2321,12 +2191,10 @@ static struct cmd_t command_defs[] = { { "otr", "Off The Record preferences." }, { "pgp", "OpenPGP preferences." }, { "omemo", "OMEMO preferences." }) - CMD_NOEXAMPLES }, - { "/theme", - parse_args, 1, 2, &cons_theme_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/theme", + parse_args, 1, 2, &cons_theme_setting) CMD_MAINFUNC(cmd_theme) CMD_TAGS( CMD_TAG_UI) @@ -2349,9 +2217,8 @@ static struct cmd_t command_defs[] = { "/theme load forest") }, - { "/xmlconsole", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/xmlconsole", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_xmlconsole) CMD_TAGS( CMD_TAG_UI) @@ -2359,15 +2226,11 @@ static struct cmd_t command_defs[] = { "/xmlconsole") CMD_DESC( "Open the XML console to view incoming and outgoing XMPP traffic.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/script", - parse_args, 1, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/script", + parse_args, 1, 2, NULL) CMD_MAINFUNC(cmd_script) - CMD_NOTAGS CMD_SYN( "/script run <script>", "/script list", @@ -2385,11 +2248,9 @@ static struct cmd_t command_defs[] = { "/script show somescript") }, - { "/export", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/export", + parse_args, 1, 1, NULL) CMD_MAINFUNC(cmd_export) - CMD_NOTAGS CMD_SYN( "/export <filepath>") CMD_DESC( @@ -2401,13 +2262,11 @@ static struct cmd_t command_defs[] = { "/export ~/contacts.csv") }, - { "/cmd", - parse_args, 1, 3, NULL, + { CMD_PREAMBLE("/cmd", + parse_args, 1, 3, NULL) CMD_SUBFUNCS( { "list", cmd_command_list }, { "exec", cmd_command_exec }) - CMD_NOMAINFUNC - CMD_NOTAGS CMD_SYN( "/cmd list [<jid>]", "/cmd exec <command> [<jid>]") @@ -2421,8 +2280,8 @@ static struct cmd_t command_defs[] = { "/cmd exec ping") }, - { "/omemo", - parse_args, 1, 3, NULL, + { CMD_PREAMBLE("/omemo", + parse_args, 1, 3, NULL) CMD_SUBFUNCS( { "gen", cmd_omemo_gen }, { "log", cmd_omemo_log }, @@ -2436,7 +2295,6 @@ static struct cmd_t command_defs[] = { { "policy", cmd_omemo_policy }, { "clear_device_list", cmd_omemo_clear_device_list }, { "qrcode", cmd_omemo_qrcode }) - CMD_NOMAINFUNC CMD_TAGS( CMD_TAG_CHAT, CMD_TAG_UI) @@ -2478,48 +2336,35 @@ static struct cmd_t command_defs[] = { "/omemo char *") }, - { "/save", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/save", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_save) - CMD_NOTAGS CMD_SYN( "/save") CMD_DESC( "Save preferences to configuration file.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/reload", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/reload", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_reload) - CMD_NOTAGS CMD_SYN( "/reload") CMD_DESC( "Reload preferences from configuration file.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/paste", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/paste", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_paste) - CMD_NOTAGS CMD_SYN( "/paste") CMD_DESC( "Paste clipboard.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/color", - parse_args, 1, 2, &cons_color_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/color", + parse_args, 1, 2, &cons_color_setting) CMD_MAINFUNC(cmd_color) CMD_TAGS( CMD_TAG_UI) @@ -2539,9 +2384,8 @@ static struct cmd_t command_defs[] = { "/color own off") }, - { "/stamp", - parse_args, 0, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/stamp", + parse_args, 0, 2, NULL) CMD_MAINFUNC(cmd_stamp) CMD_TAGS( CMD_TAG_UI) @@ -2561,9 +2405,8 @@ static struct cmd_t command_defs[] = { "/stamp unset incoming") }, - { "/avatar", - parse_args, 2, 2, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/avatar", + parse_args, 2, 2, NULL) CMD_MAINFUNC(cmd_avatar) CMD_TAGS( CMD_TAG_CHAT) @@ -2585,9 +2428,8 @@ static struct cmd_t command_defs[] = { "/avatar get thor@valhalla.edda", "/avatar open freyja@vanaheimr.edda") }, - { "/os", - parse_args, 1, 1, &cons_os_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/os", + parse_args, 1, 1, &cons_os_setting) CMD_MAINFUNC(cmd_os) CMD_TAGS( CMD_TAG_DISCOVERY) @@ -2597,12 +2439,10 @@ static struct cmd_t command_defs[] = { "Choose whether to include the OS name if a user asks for software information (XEP-0092).") CMD_ARGS( { "on|off", "" }) - CMD_NOEXAMPLES }, - { "/correction", - parse_args, 1, 2, &cons_correction_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/correction", + parse_args, 1, 2, &cons_correction_setting) CMD_MAINFUNC(cmd_correction) CMD_TAGS( CMD_TAG_UI, @@ -2618,12 +2458,10 @@ static struct cmd_t command_defs[] = { CMD_ARGS( { "on|off", "Enable/Disable support for last message correction." }, { "char", "Set character that will prefix corrected messages. Default: '+'." }) - CMD_NOEXAMPLES }, - { "/correct", - parse_args_as_one, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/correct", + parse_args_as_one, 1, 1, NULL) CMD_MAINFUNC(cmd_correct) CMD_TAGS( CMD_TAG_CHAT, @@ -2636,12 +2474,10 @@ static struct cmd_t command_defs[] = { "For more information on how to configure corrections, see: /help correction.") CMD_ARGS( { "message", "The corrected message." }) - CMD_NOEXAMPLES }, - { "/slashguard", - parse_args, 1, 1, &cons_slashguard_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/slashguard", + parse_args, 1, 1, &cons_slashguard_setting) CMD_MAINFUNC(cmd_slashguard) CMD_TAGS( CMD_TAG_UI, @@ -2653,12 +2489,10 @@ static struct cmd_t command_defs[] = { "It tries to protect you from typing ' /quit' and similar things in chats.") CMD_ARGS( { "on|off", "Enable or disable slashguard." }) - CMD_NOEXAMPLES }, - { "/serversoftware", - parse_args, 1, 1, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/serversoftware", + parse_args, 1, 1, NULL) CMD_MAINFUNC(cmd_serversoftware) CMD_TAGS( CMD_TAG_DISCOVERY) @@ -2673,15 +2507,14 @@ static struct cmd_t command_defs[] = { "/serversoftware xmpp.vanaheimr.edda") }, - { "/executable", - parse_args, 2, 4, &cons_executable_setting, + { CMD_PREAMBLE("/executable", + parse_args, 2, 4, &cons_executable_setting) CMD_SUBFUNCS( { "avatar", cmd_executable_avatar }, { "urlopen", cmd_executable_urlopen }, { "urlsave", cmd_executable_urlsave }, { "editor", cmd_executable_editor }, { "vcard_photo", cmd_executable_vcard_photo }) - CMD_NOMAINFUNC CMD_TAGS( CMD_TAG_DISCOVERY) CMD_SYN( @@ -2715,12 +2548,11 @@ static struct cmd_t command_defs[] = { "/executable editor set vim") }, - { "/url", - parse_args, 2, 3, NULL, + { CMD_PREAMBLE("/url", + parse_args, 2, 3, NULL) CMD_SUBFUNCS( { "open", cmd_url_open }, { "save", cmd_url_save }) - CMD_NOMAINFUNC CMD_TAGS( CMD_TAG_CHAT, CMD_TAG_GROUPCHAT) @@ -2737,9 +2569,8 @@ static struct cmd_t command_defs[] = { "/url save https://profanity-im.github.io/guide/latest/userguide.html /home/user/Download/") }, - { "/mam", - parse_args, 1, 1, &cons_mam_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/mam", + parse_args, 1, 1, &cons_mam_setting) CMD_MAINFUNC(cmd_mam) CMD_TAGS( CMD_TAG_CHAT) @@ -2751,25 +2582,19 @@ static struct cmd_t command_defs[] = { "We are going to work on this in future releases. So far this setting is mostly here for developers.") CMD_ARGS( { "on|off", "Enable or disable MAM" }) - CMD_NOEXAMPLES }, - { "/changepassword", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/changepassword", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_change_password) - CMD_NOTAGS CMD_SYN( "/changepassword") CMD_DESC( "Change password of logged in account") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/editor", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/editor", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_editor) CMD_TAGS( CMD_TAG_CHAT, @@ -2780,13 +2605,10 @@ static struct cmd_t command_defs[] = { "Spawn external editor to edit message. " "After editing the inputline may appear empty. Press enter to send the text anyways. " "Use /executable to set your favourite editor." ) - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/correct-editor", - parse_args, 0, 0, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/correct-editor", + parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_correct_editor) CMD_TAGS( CMD_TAG_CHAT, @@ -2797,13 +2619,10 @@ static struct cmd_t command_defs[] = { "Spawn external editor to correct and resend the last message (XEP-0308). " "For more information on how to configure corrections, see: /help correction. " "Use /executable to set your favourite editor.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/silence", - parse_args, 1, 1, &cons_silence_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/silence", + parse_args, 1, 1, &cons_silence_setting) CMD_MAINFUNC(cmd_silence) CMD_TAGS( CMD_TAG_CHAT) @@ -2811,13 +2630,10 @@ static struct cmd_t command_defs[] = { "/silence on|off") CMD_DESC( "Let's you silence all message attempts from people who are not in your roster.") - CMD_NOARGS - CMD_NOEXAMPLES }, - { "/register", - parse_args, 2, 6, NULL, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/register", + parse_args, 2, 6, NULL) CMD_MAINFUNC(cmd_register) CMD_TAGS( CMD_TAG_CONNECTION) @@ -2841,9 +2657,8 @@ static struct cmd_t command_defs[] = { "/register someuser my.xmppserv.er port 5443 tls force") }, - { "/mood", - parse_args, 1, 3, &cons_mood_setting, - CMD_NOSUBFUNCS + { CMD_PREAMBLE("/mood", + parse_args, 1, 3, &cons_mood_setting) CMD_MAINFUNC(cmd_mood) CMD_TAGS( CMD_TAG_CHAT) @@ -2862,6 +2677,24 @@ static struct cmd_t command_defs[] = { "/mood set amazed", "/mood clear") }, + + { CMD_PREAMBLE("/strophe", + parse_args, 2, 2, &cons_strophe_setting) + CMD_MAINFUNC(cmd_strophe) + CMD_TAGS( + CMD_TAG_CONNECTION) + CMD_SYN( + "/strophe verbosity 0-3", + "/strophe sm on|no-resend|off") + CMD_DESC( + "Modify libstrophe settings.") + CMD_ARGS( + { "verbosity 0-3", "Set libstrophe verbosity level when log level is 'DEBUG'." }, + { "sm on|no-resend|off", "Enable or disable Stream-Management (SM) as of XEP-0198. The 'no-resend' option enables SM, but won't re-send un-ACK'ed messages on re-connect." }) + CMD_EXAMPLES( + "/strophe verbosity 3", + "/strophe sm no-resend") + }, // NEXT-COMMAND (search helper) }; @@ -2869,8 +2702,8 @@ static struct cmd_t command_defs[] = { static GHashTable* search_index; -char* -_cmd_index(Command* cmd) +static char* +_cmd_index(const Command* cmd) { GString* index_source = g_string_new(""); index_source = g_string_append(index_source, cmd->cmd); @@ -2878,12 +2711,12 @@ _cmd_index(Command* cmd) index_source = g_string_append(index_source, cmd->help.desc); index_source = g_string_append(index_source, " "); - int len = g_strv_length(cmd->help.tags); + int len = g_strv_length((gchar**)cmd->help.tags); for (int i = 0; i < len; i++) { index_source = g_string_append(index_source, cmd->help.tags[i]); index_source = g_string_append(index_source, " "); } - len = g_strv_length(cmd->help.synopsis); + len = g_strv_length((gchar**)cmd->help.synopsis); for (int i = 0; i < len; i++) { index_source = g_string_append(index_source, cmd->help.synopsis[i]); index_source = g_string_append(index_source, " "); @@ -2983,10 +2816,10 @@ cmd_init(void) // load command defs into hash table commands = g_hash_table_new(g_str_hash, g_str_equal); for (unsigned int i = 0; i < ARRAY_SIZE(command_defs); i++) { - Command* pcmd = command_defs + i; + const Command* pcmd = command_defs + i; // add to hash - g_hash_table_insert(commands, pcmd->cmd, pcmd); + g_hash_table_insert(commands, pcmd->cmd, (gpointer)pcmd); // add to search index g_hash_table_insert(search_index, strdup(pcmd->cmd), _cmd_index(pcmd)); @@ -3077,8 +2910,8 @@ command_docgen(void) GList* cmds = NULL; for (unsigned int i = 0; i < ARRAY_SIZE(command_defs); i++) { - Command* pcmd = command_defs + i; - cmds = g_list_insert_sorted(cmds, pcmd, (GCompareFunc)_cmp_command); + const Command* pcmd = command_defs + i; + cmds = g_list_insert_sorted(cmds, (gpointer)pcmd, (GCompareFunc)_cmp_command); } FILE* toc_fragment = fopen("toc_fragment.html", "w"); @@ -3162,8 +2995,8 @@ command_mangen(void) GList* cmds = NULL; for (unsigned int i = 0; i < ARRAY_SIZE(command_defs); i++) { - Command* pcmd = command_defs + i; - cmds = g_list_insert_sorted(cmds, pcmd, (GCompareFunc)_cmp_command); + const Command* pcmd = command_defs + i; + cmds = g_list_insert_sorted(cmds, (gpointer)pcmd, (GCompareFunc)_cmp_command); } create_dir("docs"); diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index da38f405..56a18bdb 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -82,16 +82,17 @@ #include "plugins/plugins.h" #include "ui/ui.h" #include "ui/window_list.h" -#include "xmpp/xmpp.h" +#include "xmpp/avatar.h" +#include "xmpp/chat_session.h" #include "xmpp/connection.h" #include "xmpp/contact.h" -#include "xmpp/roster_list.h" #include "xmpp/jid.h" #include "xmpp/muc.h" -#include "xmpp/chat_session.h" -#include "xmpp/avatar.h" +#include "xmpp/roster_list.h" +#include "xmpp/session.h" #include "xmpp/stanza.h" #include "xmpp/vcard_funcs.h" +#include "xmpp/xmpp.h" #ifdef HAVE_LIBOTR #include "otr/otr.h" @@ -120,8 +121,8 @@ static void _update_presence(const resource_presence_t presence, const char* const show, gchar** args); -static void _cmd_set_boolean_preference(gchar* arg, const char* const command, - const char* const display, preference_t pref); +static gboolean _cmd_set_boolean_preference(gchar* arg, const char* const command, + const char* const display, preference_t pref); static void _who_room(ProfWin* window, const char* const command, gchar** args); static void _who_roster(ProfWin* window, const char* const command, gchar** args); static gboolean _cmd_execute(ProfWin* window, const char* const command, const char* const inp); @@ -6517,9 +6518,8 @@ cmd_log(ProfWin* window, const char* const command, gchar** args) } if (strcmp(subcmd, "level") == 0) { - if (g_strcmp0(value, "INFO") == 0 || g_strcmp0(value, "DEBUG") == 0 || g_strcmp0(value, "WARN") == 0 || g_strcmp0(value, "ERROR") == 0) { - - log_level_t prof_log_level = log_level_from_string(value); + log_level_t prof_log_level; + if (log_level_from_string(value, &prof_log_level) == 0) { log_close(); log_init(prof_log_level, NULL); @@ -6540,8 +6540,9 @@ cmd_reconnect(ProfWin* window, const char* const command, gchar** args) int intval = 0; char* err_msg = NULL; - gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); - if (res) { + if (g_strcmp0(value, "now") == 0) { + session_reconnect_now(); + } else if (strtoi_range(value, &intval, 0, INT_MAX, &err_msg)) { prefs_set_reconnect(intval); if (intval == 0) { cons_show("Reconnect disabled.", intval); @@ -8431,23 +8432,23 @@ _cmd_execute(ProfWin* window, const char* const command, const char* const inp) ui_invalid_command_usage(cmd->cmd, cmd->setting_func); return TRUE; } - if (args[0] && cmd->sub_funcs[0][0]) { + if (args[0] && cmd->sub_funcs[0].cmd) { int i = 0; - while (cmd->sub_funcs[i][0]) { - if (g_strcmp0(args[0], (char*)cmd->sub_funcs[i][0]) == 0) { - gboolean (*func)(ProfWin * window, const char* const command, gchar** args) = cmd->sub_funcs[i][1]; - gboolean result = func(window, command, args); - g_strfreev(args); - return result; + while (cmd->sub_funcs[i].cmd) { + if (g_strcmp0(args[0], (char*)cmd->sub_funcs[i].cmd) == 0) { + result = cmd->sub_funcs[i].func(window, command, args); + goto out; } i++; } } if (!cmd->func) { ui_invalid_command_usage(cmd->cmd, cmd->setting_func); - return TRUE; + result = TRUE; + goto out; } - gboolean result = cmd->func(window, command, args); + result = cmd->func(window, command, args); +out: g_strfreev(args); return result; } else if (plugins_run_command(inp)) { @@ -8580,31 +8581,24 @@ _update_presence(const resource_presence_t resource_presence, } // helper function for boolean preference commands -static void +static gboolean _cmd_set_boolean_preference(gchar* arg, const char* const command, const char* const display, preference_t pref) { if (arg == NULL) { cons_bad_cmd_usage(command); - } else if (strcmp(arg, "on") == 0) { - GString* enabled = g_string_new(display); - g_string_append(enabled, " enabled."); - - cons_show(enabled->str); + return FALSE; + } else if (g_strcmp0(arg, "on") == 0) { + cons_show("%s enabled.", display); prefs_set_boolean(pref, TRUE); - - g_string_free(enabled, TRUE); - } else if (strcmp(arg, "off") == 0) { - GString* disabled = g_string_new(display); - g_string_append(disabled, " disabled."); - - cons_show(disabled->str); + } else if (g_strcmp0(arg, "off") == 0) { + cons_show("%s disabled.", display); prefs_set_boolean(pref, FALSE); - - g_string_free(disabled, TRUE); } else { cons_bad_cmd_usage(command); + return FALSE; } + return TRUE; } gboolean @@ -8894,6 +8888,7 @@ cmd_omemo_fingerprint(ProfWin* window, const char* const command, gchar** args) free(formatted_fingerprint); } + jid_destroy(jid); g_list_free(fingerprints); win_println(window, THEME_DEFAULT, "-", "You can trust it with '/omemo trust <fingerprint>'"); @@ -9857,6 +9852,41 @@ cmd_mood(ProfWin* window, const char* const command, gchar** args) } gboolean +cmd_strophe(ProfWin* window, const char* const command, gchar** args) +{ + if (g_strcmp0(args[0], "verbosity") == 0) { + int verbosity; + auto_gchar gchar* err_msg = NULL; + if (string_to_verbosity(args[1], &verbosity, &err_msg)) { + xmpp_ctx_set_verbosity(connection_get_ctx(), verbosity); + prefs_set_string(PREF_STROPHE_VERBOSITY, args[1]); + return TRUE; + } else { + cons_show(err_msg); + } + } else if (g_strcmp0(args[0], "sm") == 0) { + if (g_strcmp0(args[1], "no-resend") == 0) { + cons_show("Stream Management set to 'no-resend'."); + prefs_set_boolean(PREF_STROPHE_SM_ENABLED, TRUE); + prefs_set_boolean(PREF_STROPHE_SM_RESEND, FALSE); + return TRUE; + } else if (g_strcmp0(args[1], "on") == 0) { + cons_show("Stream Management enabled."); + prefs_set_boolean(PREF_STROPHE_SM_ENABLED, TRUE); + prefs_set_boolean(PREF_STROPHE_SM_RESEND, TRUE); + return TRUE; + } else if (g_strcmp0(args[1], "off") == 0) { + cons_show("Stream Management disabled."); + prefs_set_boolean(PREF_STROPHE_SM_ENABLED, FALSE); + prefs_set_boolean(PREF_STROPHE_SM_RESEND, FALSE); + return TRUE; + } + } + cons_bad_cmd_usage(command); + return FALSE; +} + +gboolean cmd_vcard(ProfWin* window, const char* const command, gchar** args) { if (connection_get_status() != JABBER_CONNECTED) { diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index 597164f3..6d446703 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -68,7 +68,11 @@ typedef struct cmd_t int min_args; int max_args; void (*setting_func)(void); - void* sub_funcs[50][2]; + struct + { + const char* cmd; + gboolean (*func)(ProfWin* window, const char* const command, gchar** args); + } sub_funcs[50]; gboolean (*func)(ProfWin* window, const char* const command, gchar** args); CommandHelp help; } Command; @@ -253,6 +257,7 @@ gboolean cmd_correct_editor(ProfWin* window, const char* const command, gchar** gboolean cmd_silence(ProfWin* window, const char* const command, gchar** args); gboolean cmd_register(ProfWin* window, const char* const command, gchar** args); gboolean cmd_mood(ProfWin* window, const char* const command, gchar** args); +gboolean cmd_strophe(ProfWin* window, const char* const command, gchar** args); gboolean cmd_stamp(ProfWin* window, const char* const command, gchar** args); gboolean cmd_vcard(ProfWin* window, const char* const command, gchar** args); gboolean cmd_vcard_add(ProfWin* window, const char* const command, gchar** args); diff --git a/src/common.c b/src/common.c index d00e096f..7888a1dc 100644 --- a/src/common.c +++ b/src/common.c @@ -70,6 +70,36 @@ struct curl_data_t static size_t _data_callback(void* ptr, size_t size, size_t nmemb, void* data); +void +auto_free_gchar(gchar** str) +{ + if (str == NULL) + return; + g_free(*str); +} + +void +auto_free_gcharv(gchar*** args) +{ + if (args == NULL) + return; + g_strfreev(*args); +} + +void +auto_free_char(char** str) +{ + if (str == NULL) + return; + free(*str); +} + +gboolean +string_to_verbosity(const char* cmd, int* verbosity, gchar** err_msg) +{ + return strtoi_range(cmd, verbosity, 0, 3, err_msg); +} + gboolean create_dir(const char* name) { @@ -136,24 +166,24 @@ str_replace(const char* string, const char* substr, } gboolean -strtoi_range(char* str, int* saveptr, int min, int max, char** err_msg) +strtoi_range(const char* str, int* saveptr, int min, int max, gchar** err_msg) { char* ptr; int val; - + if (str == NULL) { + if (err_msg) + *err_msg = g_strdup_printf("'str' input pointer can not be NULL"); + return FALSE; + } errno = 0; val = (int)strtol(str, &ptr, 0); if (errno != 0 || *str == '\0' || *ptr != '\0') { - GString* err_str = g_string_new(""); - g_string_printf(err_str, "Could not convert \"%s\" to a number.", str); - *err_msg = err_str->str; - g_string_free(err_str, FALSE); + if (err_msg) + *err_msg = g_strdup_printf("Could not convert \"%s\" to a number.", str); return FALSE; } else if (val < min || val > max) { - GString* err_str = g_string_new(""); - g_string_printf(err_str, "Value %s out of range. Must be in %d..%d.", str, min, max); - *err_msg = err_str->str; - g_string_free(err_str, FALSE); + if (err_msg) + *err_msg = g_strdup_printf("Value %s out of range. Must be in %d..%d.", str, min, max); return FALSE; } @@ -598,3 +628,10 @@ unique_filename_from_url(const char* url, const char* path) return unique_filename; } + +void +glib_hash_table_free(GHashTable* hash_table) +{ + g_hash_table_remove_all(hash_table); + g_hash_table_unref(hash_table); +} diff --git a/src/common.h b/src/common.h index 27d1684d..359e313e 100644 --- a/src/common.h +++ b/src/common.h @@ -47,6 +47,13 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +void auto_free_gchar(gchar** str); +#define auto_gchar __attribute__((__cleanup__(auto_free_gchar))) +void auto_free_gcharv(gchar*** args); +#define auto_gcharv __attribute__((__cleanup__(auto_free_gcharv))) +void auto_free_char(char** str); +#define auto_char __attribute__((__cleanup__(auto_free_char))) + // assume malloc stores at most 8 bytes for size of allocated memory // and page size is at least 4KB #define READ_BUF_SIZE 4088 @@ -80,10 +87,12 @@ typedef enum { RESOURCE_XA } resource_presence_t; +gboolean string_to_verbosity(const char* cmd, int* verbosity, gchar** err_msg); + gboolean create_dir(const char* name); gboolean copy_file(const char* const src, const char* const target, const gboolean overwrite_existing); char* str_replace(const char* string, const char* substr, const char* replacement); -gboolean strtoi_range(char* str, int* saveptr, int min, int max, char** err_msg); +gboolean strtoi_range(const char* str, int* saveptr, int min, int max, char** err_msg); int utf8_display_len(const char* const str); char* release_get_latest(void); @@ -109,4 +118,6 @@ gchar** format_call_external_argv(const char* template, const char* url, const c gchar* unique_filename_from_url(const char* url, const char* path); gchar* get_expanded_path(const char* path); +void glib_hash_table_free(GHashTable* hash_table); + #endif diff --git a/src/config/account.c b/src/config/account.c index 238c2ef1..89436f9a 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -49,71 +49,53 @@ #include "xmpp/resource.h" ProfAccount* -account_new(const gchar* const name, const gchar* const jid, - const gchar* const password, const gchar* eval_password, gboolean enabled, const gchar* const server, - int port, const gchar* const resource, const gchar* const last_presence, - const gchar* const login_presence, int priority_online, int priority_chat, - int priority_away, int priority_xa, int priority_dnd, - const gchar* const muc_service, const gchar* const muc_nick, - const gchar* const otr_policy, GList* otr_manual, GList* otr_opportunistic, - GList* otr_always, const gchar* const omemo_policy, GList* omemo_enabled, - GList* omemo_disabled, GList* ox_enabled, GList* pgp_enabled, - const gchar* const pgp_keyid, const char* const startscript, const char* const theme, - gchar* tls_policy, gchar* auth_policy) +account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_password, gboolean enabled, + gchar* server, int port, gchar* resource, gchar* last_presence, gchar* login_presence, + int priority_online, int priority_chat, int priority_away, int priority_xa, int priority_dnd, + gchar* muc_service, gchar* muc_nick, + gchar* otr_policy, GList* otr_manual, GList* otr_opportunistic, GList* otr_always, + gchar* omemo_policy, GList* omemo_enabled, GList* omemo_disabled, + GList* ox_enabled, GList* pgp_enabled, gchar* pgp_keyid, + gchar* startscript, gchar* theme, gchar* tls_policy, gchar* auth_policy) { - ProfAccount* new_account = malloc(sizeof(ProfAccount)); - memset(new_account, 0, sizeof(ProfAccount)); + ProfAccount* new_account = calloc(1, sizeof(ProfAccount)); - new_account->name = strdup(name); + new_account->name = name; if (jid) { - new_account->jid = strdup(jid); + new_account->jid = jid; } else { new_account->jid = strdup(name); } - if (password) { - new_account->password = strdup(password); - } else { - new_account->password = NULL; - } + new_account->password = password; - if (eval_password) { - new_account->eval_password = strdup(eval_password); - } else { - new_account->eval_password = NULL; - } + new_account->eval_password = eval_password; new_account->enabled = enabled; - if (server) { - new_account->server = strdup(server); - } else { - new_account->server = NULL; - } + new_account->server = server; - if (resource) { - new_account->resource = strdup(resource); - } else { - new_account->resource = NULL; - } + new_account->resource = resource; new_account->port = port; if (last_presence == NULL || !valid_resource_presence_string(last_presence)) { new_account->last_presence = strdup("online"); + g_free(last_presence); } else { - new_account->last_presence = strdup(last_presence); + new_account->last_presence = last_presence; } if (login_presence == NULL) { new_account->login_presence = strdup("online"); } else if (strcmp(login_presence, "last") == 0) { - new_account->login_presence = strdup(login_presence); + new_account->login_presence = login_presence; } else if (!valid_resource_presence_string(login_presence)) { new_account->login_presence = strdup("online"); + g_free(login_presence); } else { - new_account->login_presence = strdup(login_presence); + new_account->login_presence = login_presence; } new_account->priority_online = priority_online; @@ -122,72 +104,38 @@ account_new(const gchar* const name, const gchar* const jid, new_account->priority_xa = priority_xa; new_account->priority_dnd = priority_dnd; - if (muc_service) { - new_account->muc_service = strdup(muc_service); - } else { - new_account->muc_service = NULL; - } + new_account->muc_service = muc_service; if (muc_nick == NULL) { Jid* jidp = jid_create(new_account->jid); new_account->muc_nick = strdup(jidp->domainpart); jid_destroy(jidp); } else { - new_account->muc_nick = strdup(muc_nick); + new_account->muc_nick = muc_nick; } - if (otr_policy) { - new_account->otr_policy = strdup(otr_policy); - } else { - new_account->otr_policy = NULL; - } + new_account->otr_policy = otr_policy; new_account->otr_manual = otr_manual; new_account->otr_opportunistic = otr_opportunistic; new_account->otr_always = otr_always; - if (omemo_policy) { - new_account->omemo_policy = strdup(omemo_policy); - } else { - new_account->omemo_policy = NULL; - } - + new_account->omemo_policy = omemo_policy; new_account->omemo_enabled = omemo_enabled; new_account->omemo_disabled = omemo_disabled; new_account->ox_enabled = ox_enabled; new_account->pgp_enabled = pgp_enabled; + new_account->pgp_keyid = pgp_keyid; - if (pgp_keyid != NULL) { - new_account->pgp_keyid = strdup(pgp_keyid); - } else { - new_account->pgp_keyid = NULL; - } + new_account->startscript = startscript; - if (startscript != NULL) { - new_account->startscript = strdup(startscript); - } else { - new_account->startscript = NULL; - } + new_account->theme = theme; - if (theme != NULL) { - new_account->theme = strdup(theme); - } else { - new_account->theme = NULL; - } - - if (tls_policy != NULL) { - new_account->tls_policy = strdup(tls_policy); - } else { - new_account->tls_policy = NULL; - } + new_account->tls_policy = tls_policy; - if (auth_policy != NULL) { - new_account->auth_policy = strdup(auth_policy); - } else { - new_account->auth_policy = NULL; - } + new_account->auth_policy = auth_policy; return new_account; } diff --git a/src/config/account.h b/src/config/account.h index ce49883e..a469e068 100644 --- a/src/config/account.h +++ b/src/config/account.h @@ -73,17 +73,14 @@ typedef struct prof_account_t gchar* auth_policy; } ProfAccount; -ProfAccount* account_new(const gchar* const name, const gchar* const jid, - const gchar* const passord, const gchar* eval_password, gboolean enabled, const gchar* const server, - int port, const gchar* const resource, const gchar* const last_presence, - const gchar* const login_presence, int priority_online, int priority_chat, - int priority_away, int priority_xa, int priority_dnd, - const gchar* const muc_service, const gchar* const muc_nick, - const gchar* const otr_policy, GList* otr_manual, GList* otr_opportunistic, - GList* otr_always, const gchar* const omemo_policy, GList* omemo_enabled, - GList* omemo_disabled, GList* ox_enabled, GList* pgp_enabled, const gchar* const pgp_keyid, - const char* const startscript, const char* const theme, gchar* tls_policy, - gchar* auth_policy); +ProfAccount* account_new(gchar* name, gchar* jid, gchar* password, gchar* eval_password, gboolean enabled, + gchar* server, int port, gchar* resource, gchar* last_presence, gchar* login_presence, + int priority_online, int priority_chat, int priority_away, int priority_xa, int priority_dnd, + gchar* muc_service, gchar* muc_nick, + gchar* otr_policy, GList* otr_manual, GList* otr_opportunistic, GList* otr_always, + gchar* omemo_policy, GList* omemo_enabled, GList* omemo_disabled, + GList* ox_enabled, GList* pgp_enabled, gchar* pgp_keyid, + gchar* startscript, gchar* theme, gchar* tls_policy, gchar* auth_policy); char* account_create_connect_jid(ProfAccount* account); gboolean account_eval_password(ProfAccount* account); void account_free(ProfAccount* account); diff --git a/src/config/accounts.c b/src/config/accounts.c index cf1c1754..9c7eddf9 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -342,7 +342,7 @@ accounts_get_account(const char* const name) gchar* auth_policy = g_key_file_get_string(accounts, name, "auth.policy", NULL); - ProfAccount* new_account = account_new(name, jid, password, eval_password, enabled, + ProfAccount* new_account = account_new(g_strdup(name), jid, password, eval_password, enabled, server, port, resource, last_presence, login_presence, priority_online, priority_chat, priority_away, priority_xa, priority_dnd, muc_service, muc_nick, otr_policy, otr_manual, @@ -350,23 +350,6 @@ accounts_get_account(const char* const name) omemo_disabled, ox_enabled, pgp_enabled, pgp_keyid, startscript, theme, tls_policy, auth_policy); - g_free(jid); - g_free(password); - g_free(eval_password); - g_free(server); - g_free(resource); - g_free(last_presence); - g_free(login_presence); - g_free(muc_service); - g_free(muc_nick); - g_free(otr_policy); - g_free(omemo_policy); - g_free(pgp_keyid); - g_free(startscript); - g_free(theme); - g_free(tls_policy); - g_free(auth_policy); - return new_account; } } diff --git a/src/config/preferences.c b/src/config/preferences.c index de455245..f15952cd 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -533,7 +533,7 @@ prefs_set_boolean(preference_t pref, gboolean value) g_key_file_set_boolean(prefs, group, key, value); } -char* +gchar* prefs_get_string(preference_t pref) { const char* group = _get_group(pref); @@ -553,14 +553,14 @@ prefs_get_string(preference_t pref) } } -char* +gchar* prefs_get_string_with_option(preference_t pref, gchar* option) { const char* group = _get_group(pref); const char* key = _get_key(pref); char* def = _get_default_string(pref); - char* result = g_key_file_get_locale_string(prefs, group, key, option, NULL); + gchar* result = g_key_file_get_locale_string(prefs, group, key, option, NULL); if (result == NULL) { // check for user set default @@ -1869,6 +1869,9 @@ _get_group(preference_t pref) case PREF_CORRECTION_ALLOW: case PREF_MAM: case PREF_SILENCE_NON_ROSTER: + case PREF_STROPHE_VERBOSITY: + case PREF_STROPHE_SM_ENABLED: + case PREF_STROPHE_SM_RESEND: return PREF_GROUP_CONNECTION; case PREF_OTR_LOG: case PREF_OTR_POLICY: @@ -2165,6 +2168,12 @@ _get_key(preference_t pref) return "mood"; case PREF_VCARD_PHOTO_CMD: return "vcard.photo.cmd"; + case PREF_STROPHE_VERBOSITY: + return "strophe.verbosity"; + case PREF_STROPHE_SM_ENABLED: + return "strophe.sm.enabled"; + case PREF_STROPHE_SM_RESEND: + return "strophe.sm.resend"; default: return NULL; } @@ -2217,6 +2226,8 @@ _get_default_boolean(preference_t pref) case PREF_INTYPE_CONSOLE: case PREF_NOTIFY_MENTION_WHOLE_WORD: case PREF_MOOD: + case PREF_STROPHE_SM_ENABLED: + case PREF_STROPHE_SM_RESEND: return TRUE; default: return FALSE; @@ -2316,6 +2327,8 @@ _get_default_string(preference_t pref) return NULL; // Default to built-in method. case PREF_OX_LOG: return "on"; + case PREF_STROPHE_VERBOSITY: + return "0"; default: return NULL; } diff --git a/src/config/preferences.h b/src/config/preferences.h index 95a84865..ca8acea4 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -182,6 +182,9 @@ typedef enum { PREF_NOTIFY_ROOM_OFFLINE, PREF_OX_LOG, PREF_MOOD, + PREF_STROPHE_VERBOSITY, + PREF_STROPHE_SM_ENABLED, + PREF_STROPHE_SM_RESEND, PREF_VCARD_PHOTO_CMD, } preference_t; @@ -329,8 +332,8 @@ void prefs_save_win_placement(ProfWinPlacement* placement); gboolean prefs_get_boolean(preference_t pref); void prefs_set_boolean(preference_t pref, gboolean value); -char* prefs_get_string(preference_t pref); -char* prefs_get_string_with_option(preference_t pref, gchar* option); +gchar* prefs_get_string(preference_t pref); +gchar* prefs_get_string_with_option(preference_t pref, gchar* option); void prefs_set_string(preference_t pref, char* value); void prefs_set_string_with_option(preference_t pref, char* option, char* value); void prefs_set_string_list_with_option(preference_t pref, char* option, const gchar* const* values); diff --git a/src/database.c b/src/database.c index 13946e8d..ce936170 100644 --- a/src/database.c +++ b/src/database.c @@ -57,6 +57,16 @@ static char* _get_db_filename(ProfAccount* account); static prof_msg_type_t _get_message_type_type(const char* const type); static prof_enc_t _get_message_enc_type(const char* const encstr); +#define auto_sqlite __attribute__((__cleanup__(auto_free_sqlite))) + +static void +auto_free_sqlite(gchar** str) +{ + if (str == NULL) + return; + sqlite3_free(*str); +} + static char* _get_db_filename(ProfAccount* account) { @@ -243,7 +253,6 @@ GSList* log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip) { sqlite3_stmt* stmt = NULL; - gchar* query; const char* jid = connection_get_fulljid(); Jid* myjid = jid_create(jid); if (!myjid) @@ -254,7 +263,7 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t gchar* sort2 = !flip ? "ASC" : "DESC"; GDateTime* now = g_date_time_new_now_local(); gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(now); - query = sqlite3_mprintf("SELECT * FROM (SELECT COALESCE(B.`message`, A.`message`) AS message, A.`timestamp`, A.`from_jid`, A.`type`, A.`encryption` from `ChatLogs` AS A LEFT JOIN `ChatLogs` AS B ON A.`stanza_id` = B.`replace_id` WHERE A.`replace_id` = '' AND ((A.`from_jid` = '%q' AND A.`to_jid` = '%q') OR (A.`from_jid` = '%q' AND A.`to_jid` = '%q')) AND A.`timestamp` < '%q' AND (%Q IS NULL OR A.`timestamp` > %Q) ORDER BY A.`timestamp` %s LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_time, start_time, sort1, MESSAGES_TO_RETRIEVE, sort2); + auto_sqlite gchar* query = sqlite3_mprintf("SELECT * FROM (SELECT COALESCE(B.`message`, A.`message`) AS message, A.`timestamp`, A.`from_jid`, A.`type`, A.`encryption` from `ChatLogs` AS A LEFT JOIN `ChatLogs` AS B ON A.`stanza_id` = B.`replace_id` WHERE A.`replace_id` = '' AND ((A.`from_jid` = '%q' AND A.`to_jid` = '%q') OR (A.`from_jid` = '%q' AND A.`to_jid` = '%q')) AND A.`timestamp` < '%q' AND (%Q IS NULL OR A.`timestamp` > %Q) ORDER BY A.`timestamp` %s LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_time, start_time, sort1, MESSAGES_TO_RETRIEVE, sort2); g_date_time_unref(now); g_free(end_date_fmt); @@ -292,7 +301,6 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t history = g_slist_append(history, msg); } sqlite3_finalize(stmt); - sqlite3_free(query); return history; } diff --git a/src/log.c b/src/log.c index 97c1a149..a1b7bb1d 100644 --- a/src/log.c +++ b/src/log.c @@ -233,21 +233,25 @@ log_msg(log_level_t level, const char* const area, const char* const msg) } } -log_level_t -log_level_from_string(char* log_level) +int +log_level_from_string(char* log_level, log_level_t* level) { + int ret = 0; assert(log_level != NULL); + assert(level != NULL); if (strcmp(log_level, "DEBUG") == 0) { - return PROF_LEVEL_DEBUG; + *level = PROF_LEVEL_DEBUG; } else if (strcmp(log_level, "INFO") == 0) { - return PROF_LEVEL_INFO; + *level = PROF_LEVEL_INFO; } else if (strcmp(log_level, "WARN") == 0) { - return PROF_LEVEL_WARN; + *level = PROF_LEVEL_WARN; } else if (strcmp(log_level, "ERROR") == 0) { - return PROF_LEVEL_ERROR; + *level = PROF_LEVEL_ERROR; } else { // default logging is warn - return PROF_LEVEL_WARN; + *level = PROF_LEVEL_WARN; + ret = -1; } + return ret; } const char* diff --git a/src/log.h b/src/log.h index 2a955c90..3bf092b3 100644 --- a/src/log.h +++ b/src/log.h @@ -55,7 +55,7 @@ void log_info(const char* const msg, ...); void log_warning(const char* const msg, ...); void log_error(const char* const msg, ...); void log_msg(log_level_t level, const char* const area, const char* const msg); -log_level_t log_level_from_string(char* log_level); +int log_level_from_string(char* log_level, log_level_t* level); const char* log_string_from_level(log_level_t level); void log_stderr_init(log_level_t level); diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 54a8e8c8..87208e9d 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -83,7 +83,6 @@ static char* _omemo_fingerprint(ec_public_key* identity, gboolean formatted); static unsigned char* _omemo_fingerprint_decode(const char* const fingerprint, size_t* len); static char* _omemo_unformat_fingerprint(const char* const fingerprint_formatted); static void _cache_device_identity(const char* const jid, uint32_t device_id, ec_public_key* identity); -static void _g_hash_table_free(GHashTable* hash_table); static void _acquire_sender_devices_list(void); typedef gboolean (*OmemoDeviceListHandler)(const char* const jid, GList* device_list); @@ -221,7 +220,7 @@ omemo_on_connect(ProfAccount* account) .get_local_registration_id = get_local_registration_id, .save_identity = save_identity, .is_trusted_identity = is_trusted_identity, - .destroy_func = NULL, + .destroy_func = (void (*)(void*))identity_key_store_destroy, .user_data = &omemo_ctx.identity_key_store }; signal_protocol_store_context_set_identity_key_store(omemo_ctx.store, &identity_key_store); @@ -229,7 +228,7 @@ omemo_on_connect(ProfAccount* account) loaded = FALSE; omemo_ctx.device_list = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)g_list_free); omemo_ctx.device_list_handler = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); - omemo_ctx.known_devices = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_g_hash_table_free); + omemo_ctx.known_devices = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)glib_hash_table_free); gchar* omemo_dir = files_file_in_account_data_path(DIR_OMEMO, account->jid, NULL); if (!omemo_dir) { @@ -306,9 +305,11 @@ omemo_on_disconnect(void) return; } - _g_hash_table_free(omemo_ctx.signed_pre_key_store); - _g_hash_table_free(omemo_ctx.pre_key_store); - _g_hash_table_free(omemo_ctx.device_list_handler); + glib_hash_table_free(omemo_ctx.signed_pre_key_store); + glib_hash_table_free(omemo_ctx.pre_key_store); + glib_hash_table_free(omemo_ctx.known_devices); + glib_hash_table_free(omemo_ctx.device_list_handler); + glib_hash_table_free(omemo_ctx.device_list); g_string_free(omemo_ctx.identity_filename, TRUE); g_key_file_free(omemo_ctx.identity_keyfile); @@ -316,9 +317,18 @@ omemo_on_disconnect(void) g_key_file_free(omemo_ctx.trust_keyfile); g_string_free(omemo_ctx.sessions_filename, TRUE); g_key_file_free(omemo_ctx.sessions_keyfile); - _g_hash_table_free(omemo_ctx.session_store); + glib_hash_table_free(omemo_ctx.session_store); g_string_free(omemo_ctx.known_devices_filename, TRUE); g_key_file_free(omemo_ctx.known_devices_keyfile); + + signal_protocol_store_context_destroy(omemo_ctx.store); + ec_public_key* pub = ratchet_identity_key_pair_get_public(omemo_ctx.identity_key_pair); + ec_private_key* priv = ratchet_identity_key_pair_get_private(omemo_ctx.identity_key_pair); + ratchet_identity_key_pair_destroy((signal_type_base*)omemo_ctx.identity_key_pair); + ec_private_key_destroy((signal_type_base*)priv); + ec_public_key_destroy((signal_type_base*)pub); + + signal_context_destroy(omemo_ctx.signal); } void @@ -564,7 +574,8 @@ omemo_set_device_list(const char* const from, GList* device_list) } // OMEMO trustmode ToFu - if (g_strcmp0(prefs_get_string(PREF_OMEMO_TRUST_MODE), "firstusage") == 0) { + auto_gchar gchar* trust_mode = prefs_get_string(PREF_OMEMO_TRUST_MODE); + if (g_strcmp0(trust_mode, "firstusage") == 0) { log_debug("[OMEMO] Checking firstusage state for %s", jid->barejid); GHashTable* trusted = g_hash_table_lookup(omemo_ctx.identity_key_store.trusted, jid->barejid); if (trusted) { @@ -660,20 +671,26 @@ omemo_start_device_session(const char* const jid, uint32_t device_id, const unsigned char* const identity_key_raw, size_t identity_key_len) { log_debug("[OMEMO] Starting device session for %s with device %d", jid, device_id); - signal_protocol_address address = { + signal_protocol_address jid_address = { .name = jid, .name_len = strlen(jid), .device_id = device_id, }; + signal_protocol_address* address = NULL; + session_pre_key_bundle* bundle = NULL; + ec_public_key* prekey_public = NULL; + ec_public_key* signed_prekey = NULL; + session_builder* builder = NULL; ec_public_key* identity_key; curve_decode_point(&identity_key, identity_key_raw, identity_key_len, omemo_ctx.signal); _cache_device_identity(jid, device_id, identity_key); - gboolean trusted = is_trusted_identity(&address, (uint8_t*)identity_key_raw, identity_key_len, &omemo_ctx.identity_key_store); + gboolean trusted = is_trusted_identity(&jid_address, (uint8_t*)identity_key_raw, identity_key_len, &omemo_ctx.identity_key_store); log_debug("[OMEMO] Trust %s (%d): %d", jid, device_id, trusted); - if ((g_strcmp0(prefs_get_string(PREF_OMEMO_TRUST_MODE), "blind") == 0) && !trusted) { + auto_gchar gchar* trust_mode = prefs_get_string(PREF_OMEMO_TRUST_MODE); + if ((g_strcmp0(trust_mode, "blind") == 0) && !trusted) { char* fp = _omemo_fingerprint(identity_key, TRUE); cons_show("Blind trust for %s device %d (%s)", jid, device_id, fp); omemo_trust(jid, fp); @@ -686,18 +703,15 @@ omemo_start_device_session(const char* const jid, uint32_t device_id, goto out; } - if (!contains_session(&address, omemo_ctx.session_store)) { - log_debug("[OMEMO] There is no Session for %s ( %d) ,... building session.", address.name, address.device_id); + if (!contains_session(&jid_address, omemo_ctx.session_store)) { + log_debug("[OMEMO] There is no Session for %s ( %d) ,... building session.", jid_address.name, jid_address.device_id); int res; - session_pre_key_bundle* bundle; - signal_protocol_address* address; address = malloc(sizeof(signal_protocol_address)); address->name = strdup(jid); address->name_len = strlen(jid); address->device_id = device_id; - session_builder* builder; res = session_builder_create(&builder, omemo_ctx.store, address, omemo_ctx.signal); if (res != 0) { log_error("[OMEMO] cannot create session builder for %s device %d", jid, device_id); @@ -709,9 +723,7 @@ omemo_start_device_session(const char* const jid, uint32_t device_id, prekey_index %= g_list_length(prekeys); omemo_key_t* prekey = g_list_nth_data(prekeys, prekey_index); - ec_public_key* prekey_public; curve_decode_point(&prekey_public, prekey->data, prekey->length, omemo_ctx.signal); - ec_public_key* signed_prekey; curve_decode_point(&signed_prekey, signed_prekey_raw, signed_prekey_len, omemo_ctx.signal); res = session_pre_key_bundle_create(&bundle, 0, device_id, prekey->id, prekey_public, signed_prekey_id, signed_prekey, signature, signature_len, identity_key); @@ -732,6 +744,16 @@ omemo_start_device_session(const char* const jid, uint32_t device_id, } out: + if (bundle) + session_pre_key_bundle_destroy((signal_type_base*)bundle); + if (signed_prekey) + ec_public_key_destroy((signal_type_base*)signed_prekey); + if (prekey_public) + ec_public_key_destroy((signal_type_base*)prekey_public); + session_builder_free(builder); + if (address) + free((void*)address->name); + free(address); SIGNAL_UNREF(identity_key); } @@ -1009,6 +1031,7 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid, ec_public_key_serialize(&identity_buffer, their_identity_key); *trusted = is_trusted_identity(&address, signal_buffer_data(identity_buffer), signal_buffer_len(identity_buffer), &omemo_ctx.identity_key_store); + signal_buffer_free(identity_buffer); /* Replace used pre_key in bundle */ uint32_t pre_key_id = pre_key_signal_message_get_pre_key_id(message); @@ -1729,13 +1752,6 @@ _cache_device_identity(const char* const jid, uint32_t device_id, ec_public_key* } static void -_g_hash_table_free(GHashTable* hash_table) -{ - g_hash_table_remove_all(hash_table); - g_hash_table_unref(hash_table); -} - -static void _generate_pre_keys(int count) { unsigned int start; diff --git a/src/omemo/store.c b/src/omemo/store.c index e0fc41ed..3825c95d 100644 --- a/src/omemo/store.c +++ b/src/omemo/store.c @@ -40,12 +40,10 @@ #include "omemo/omemo.h" #include "omemo/store.h" -static void _g_hash_table_free(GHashTable* hash_table); - GHashTable* session_store_new(void) { - return g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_g_hash_table_free); + return g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)glib_hash_table_free); } GHashTable* @@ -63,11 +61,19 @@ signed_pre_key_store_new(void) void identity_key_store_new(identity_key_store_t* identity_key_store) { - identity_key_store->trusted = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)signal_buffer_free); + identity_key_store->trusted = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)glib_hash_table_free); identity_key_store->private = NULL; identity_key_store->public = NULL; } +void +identity_key_store_destroy(identity_key_store_t* identity_key_store) +{ + signal_buffer_bzero_free(identity_key_store->private); + signal_buffer_bzero_free(identity_key_store->public); + glib_hash_table_free(identity_key_store->trusted); +} + int load_session(signal_buffer** record, signal_buffer** user_record, const signal_protocol_address* address, void* user_data) @@ -450,10 +456,3 @@ load_sender_key(signal_buffer** record, signal_buffer** user_record, { return SG_SUCCESS; } - -static void -_g_hash_table_free(GHashTable* hash_table) -{ - g_hash_table_remove_all(hash_table); - g_hash_table_unref(hash_table); -} diff --git a/src/omemo/store.h b/src/omemo/store.h index bafe2576..b6a9a74d 100644 --- a/src/omemo/store.h +++ b/src/omemo/store.h @@ -57,6 +57,7 @@ GHashTable* session_store_new(void); GHashTable* pre_key_store_new(void); GHashTable* signed_pre_key_store_new(void); void identity_key_store_new(identity_key_store_t* identity_key_store); +void identity_key_store_destroy(identity_key_store_t* identity_key_store); /** * Returns a copy of the serialized session record corresponding to the diff --git a/src/profanity.c b/src/profanity.c index 49adc4a0..869ab561 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -175,7 +175,8 @@ _init(char* log_level, char* config_file, char* log_file, char* theme_name) pthread_mutex_lock(&lock); files_create_directories(); - log_level_t prof_log_level = log_level_from_string(log_level); + log_level_t prof_log_level; + log_level_from_string(log_level, &prof_log_level); prefs_load(config_file); log_init(prof_log_level, log_file); log_stderr_init(PROF_LEVEL_ERROR); diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index 9450b98f..2f1acc1f 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -367,34 +367,20 @@ char* autocomplete_param_no_with_func(const char* const input, char* command, int arg_number, autocomplete_func func, gboolean previous, void* context) { if (strncmp(input, command, strlen(command)) == 0) { - GString* result_str = NULL; - // count tokens properly int num_tokens = count_tokens(input); // if correct number of tokens, then candidate for autocompletion of last param if (num_tokens == arg_number) { - gchar* start_str = get_start(input, arg_number); - gchar* comp_str = g_strdup(&input[strlen(start_str)]); + auto_gchar gchar* start_str = get_start(input, arg_number); + auto_gchar gchar* comp_str = g_strdup(&input[strlen(start_str)]); // autocomplete param if (comp_str) { - char* found = func(comp_str, previous, context); + auto_gchar gchar* found = func(comp_str, previous, context); if (found) { - result_str = g_string_new(""); - g_string_append(result_str, start_str); - g_string_append(result_str, found); - - free(start_str); - free(comp_str); - - char* result = result_str->str; - g_string_free(result_str, FALSE); - - return result; + return g_strdup_printf("%s%s", start_str, found); } - } else { - free(start_str); } } } @@ -418,14 +404,12 @@ autocomplete_remove_older_than_max_reverse(Autocomplete ac, int maxsize) static gchar* _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction) { - gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL); - gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1); - g_free(search_str_ascii); + auto_gchar gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL); + auto_gchar gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1); while (curr) { - gchar* curr_ascii = g_str_to_ascii(curr->data, NULL); - gchar* curr_lower = g_ascii_strdown(curr_ascii, -1); - g_free(curr_ascii); + auto_gchar gchar* curr_ascii = g_str_to_ascii(curr->data, NULL); + auto_gchar gchar* curr_lower = g_ascii_strdown(curr_ascii, -1); // match found if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { @@ -435,27 +419,13 @@ _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction // if contains space, quote before returning if (quote && g_strrstr(curr->data, " ")) { - GString* quoted = g_string_new("\""); - g_string_append(quoted, curr->data); - g_string_append(quoted, "\""); - - gchar* result = quoted->str; - g_string_free(quoted, FALSE); - - g_free(search_str_lower); - g_free(curr_lower); - return result; - + return g_strdup_printf("\"%s\"", (gchar*)curr->data); // otherwise just return the string } else { - g_free(search_str_lower); - g_free(curr_lower); return strdup(curr->data); } } - g_free(curr_lower); - if (direction == PREVIOUS) { curr = g_list_previous(curr); } else { @@ -463,6 +433,5 @@ _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction } } - g_free(search_str_lower); return NULL; } diff --git a/src/tools/editor.c b/src/tools/editor.c index 4ac88a95..350fb5b1 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -56,7 +56,7 @@ get_message_from_editor(gchar* message, gchar** returned_message) gchar* filename = NULL; GError* glib_error = NULL; - char* jid = connection_get_barejid(); + auto_char char* jid = connection_get_barejid(); if (jid) { filename = files_file_in_account_data_path(DIR_EDITOR, jid, "compose.md"); } else { diff --git a/src/ui/console.c b/src/ui/console.c index 5937a42a..b1720415 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -2311,6 +2311,7 @@ cons_show_connection_prefs(void) cons_autoping_setting(); cons_autoconnect_setting(); cons_rooms_cache_setting(); + cons_strophe_setting(); cons_alert(NULL); } @@ -2994,3 +2995,18 @@ cons_mood_setting(void) cons_show("Display user mood (/mood) : OFF"); } } + +void +cons_strophe_setting(void) +{ + const char* sm_setting = "OFF"; + if (prefs_get_boolean(PREF_STROPHE_SM_ENABLED)) { + if (prefs_get_boolean(PREF_STROPHE_SM_RESEND)) { + sm_setting = "ON"; + } else { + sm_setting = "NO-RESEND"; + } + } + cons_show("XEP-0198 Stream-Management : %s", sm_setting); + cons_show("libstrophe Verbosity : %s", prefs_get_string(PREF_STROPHE_VERBOSITY)); +} diff --git a/src/ui/ui.h b/src/ui/ui.h index 94d1c716..d9534ed5 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -341,6 +341,7 @@ void cons_slashguard_setting(void); void cons_mam_setting(void); void cons_silence_setting(void); void cons_mood_setting(void); +void cons_strophe_setting(void); void cons_show_contact_online(PContact contact, Resource* resource, GDateTime* last_activity); void cons_show_contact_offline(PContact contact, char* resource, char* status); void cons_theme_properties(void); diff --git a/src/ui/window.c b/src/ui/window.c index 18445f57..9d7b779e 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1470,7 +1470,7 @@ win_print_outgoing(ProfWin* window, const char* show_char, const char* const id, if (replace_id) { _win_correct(window, message, id, replace_id, myjid); } else { - char* outgoing_str = prefs_get_string(PREF_OUTGOING_STAMP); + auto_char gchar* outgoing_str = prefs_get_string(PREF_OUTGOING_STAMP); _win_printf(window, show_char, 0, timestamp, 0, THEME_TEXT_ME, outgoing_str, myjid, id, "%s", message); } diff --git a/src/xmpp/chat_session.c b/src/xmpp/chat_session.c index f62f090c..56a782f1 100644 --- a/src/xmpp/chat_session.c +++ b/src/xmpp/chat_session.c @@ -120,11 +120,11 @@ chat_session_get_jid(const char* const barejid) return jid; } -char* +const char* chat_session_get_state(const char* const barejid) { ChatSession* session = chat_session_get(barejid); - char* state = NULL; + const char* state = NULL; if (session) { if (prefs_get_boolean(PREF_STATES) && session->send_states) { state = STANZA_NAME_ACTIVE; diff --git a/src/xmpp/chat_session.h b/src/xmpp/chat_session.h index e0144874..619750e4 100644 --- a/src/xmpp/chat_session.h +++ b/src/xmpp/chat_session.h @@ -59,7 +59,7 @@ void chat_session_recipient_paused(const char* const barejid, const char* const void chat_session_recipient_gone(const char* const barejid, const char* const resource); void chat_session_recipient_inactive(const char* const barejid, const char* const resource); char* chat_session_get_jid(const char* const barejid); -char* chat_session_get_state(const char* const barejid); +const char* chat_session_get_state(const char* const barejid); void chat_session_remove(const char* const barejid); diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 2de4a842..d57a1376 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -140,6 +140,14 @@ connection_init(void) conn.requested_features = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); conn.xmpp_ctx = xmpp_ctx_new(&prof_mem, &prof_log); + auto_gchar gchar* v = prefs_get_string(PREF_STROPHE_VERBOSITY); + auto_gchar gchar* err_msg = NULL; + int verbosity; + if (string_to_verbosity(v, &verbosity, &err_msg)) { + xmpp_ctx_set_verbosity(conn.xmpp_ctx, verbosity); + } else { + cons_show(err_msg); + } conn.xmpp_conn = xmpp_conn_new(conn.xmpp_ctx); _random_bytes_init(); @@ -1000,13 +1008,15 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status // lost connection for unknown reason if (conn.conn_status == JABBER_CONNECTED) { - int send_queue_len = xmpp_conn_send_queue_len(conn.xmpp_conn); - log_debug("Connection handler: Lost connection for unknown reason"); - conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn); - if (send_queue_len > 0) { - conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages)); - for (int n = 0; n < send_queue_len && conn.queued_messages[n]; ++n) { - conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST); + if (prefs_get_boolean(PREF_STROPHE_SM_ENABLED)) { + int send_queue_len = xmpp_conn_send_queue_len(conn.xmpp_conn); + log_debug("Connection handler: Lost connection for unknown reason"); + conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn); + if (send_queue_len > 0 && prefs_get_boolean(PREF_STROPHE_SM_RESEND)) { + conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages)); + for (int n = 0; n < send_queue_len && conn.queued_messages[n]; ++n) { + conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST); + } } } session_lost_connection(); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 4d0ee281..89511176 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2187,6 +2187,7 @@ _room_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdata identity->name = strdup(name); ProfMucWin* mucwin = wins_get_muc(cb_data->room); if (mucwin) { + free(mucwin->room_name); mucwin->room_name = strdup(name); } } else { @@ -2607,6 +2608,8 @@ _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) return 0; } +static const gchar* mam_timestamp_format_string = "%FT%T.%f%:z"; + void iq_mam_request_older(ProfChatWin* win) { @@ -2623,7 +2626,7 @@ iq_mam_request_older(ProfChatWin* win) // If first message found if (first_msg->timestamp) { firstid = first_msg->stanzaid; - enddate = g_date_time_format(first_msg->timestamp, "%FT%T.%f%:z"); + enddate = g_date_time_format(first_msg->timestamp, mam_timestamp_format_string); } else { return; } @@ -2647,6 +2650,8 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2); + g_date_time_unref(startdate); + g_date_time_unref(enddate); return; } @@ -2656,18 +2661,18 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) gboolean fetch_next = FALSE; if (startdate) { - startdate_str = g_date_time_format(startdate, "%FT%T.%f%:z"); + startdate_str = g_date_time_format(startdate, mam_timestamp_format_string); fetch_next = TRUE; g_date_time_unref(startdate); - } else if (!enddate) { - GDateTime* now = g_date_time_new_now_utc(); - enddate_str = g_date_time_format(now, "%FT%T.%f%:z"); - g_date_time_unref(now); } if (enddate) { - enddate_str = g_date_time_format(enddate, "%FT%T.%f%:z"); + enddate_str = g_date_time_format(enddate, mam_timestamp_format_string); g_date_time_unref(enddate); + } else { + GDateTime* now = g_date_time_new_now_utc(); + enddate_str = g_date_time_format(now, mam_timestamp_format_string); + g_date_time_unref(now); } xmpp_ctx_t* const ctx = connection_get_ctx(); @@ -2695,15 +2700,15 @@ void iq_mam_request(ProfChatWin* win, GDateTime* enddate) { ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); - GDateTime* startdate = last_msg->timestamp ? g_date_time_add_seconds(last_msg->timestamp, 0) : NULL; // copy timestamp + GDateTime* startdate = g_date_time_add_seconds(last_msg->timestamp, 0); message_free(last_msg); // Save request for later if disco items haven't been received yet if (!received_disco_items) { LateDeliveryUserdata* cur_del_data = malloc(sizeof(LateDeliveryUserdata)); cur_del_data->win = win; - cur_del_data->enddate = enddate; - cur_del_data->startdate = startdate; + cur_del_data->enddate = g_date_time_ref(enddate); + cur_del_data->startdate = g_date_time_ref(startdate); late_delivery_windows = g_slist_append(late_delivery_windows, cur_del_data); } diff --git a/src/xmpp/jid.c b/src/xmpp/jid.c index 33c3d19f..af0a606b 100644 --- a/src/xmpp/jid.c +++ b/src/xmpp/jid.c @@ -76,6 +76,7 @@ jid_create(const gchar* const str) result->resourcepart = NULL; result->barejid = NULL; result->fulljid = NULL; + result->refcnt = 1; gchar* atp = g_utf8_strchr(trimmed, -1, '@'); gchar* slashp = g_utf8_strchr(trimmed, -1, '/'); @@ -120,11 +121,29 @@ jid_create_from_bare_and_resource(const char* const barejid, const char* const r } void +jid_auto_destroy(Jid** jid) +{ + if (jid == NULL) + return; + jid_destroy(*jid); +} + +void +jid_ref(Jid* jid) +{ + jid->refcnt++; +} + +void jid_destroy(Jid* jid) { if (jid == NULL) { return; } + if (jid->refcnt > 1) { + jid->refcnt--; + return; + } g_free(jid->str); g_free(jid->localpart); diff --git a/src/xmpp/jid.h b/src/xmpp/jid.h index dae6cb2d..e55ea0c7 100644 --- a/src/xmpp/jid.h +++ b/src/xmpp/jid.h @@ -40,6 +40,7 @@ struct jid_t { + unsigned int refcnt; char* str; char* localpart; char* domainpart; @@ -53,6 +54,10 @@ typedef struct jid_t Jid; Jid* jid_create(const gchar* const str); Jid* jid_create_from_bare_and_resource(const char* const barejid, const char* const resource); void jid_destroy(Jid* jid); +void jid_ref(Jid* jid); + +void jid_auto_destroy(Jid** str); +#define auto_jid __attribute__((__cleanup__(jid_auto_destroy))) gboolean jid_is_valid_room_form(Jid* jid); char* create_fulljid(const char* const barejid, const char* const resource); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 306b9be7..bc716b24 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -424,7 +424,7 @@ message_send_chat(const char* const barejid, const char* const msg, const char* { xmpp_ctx_t* const ctx = connection_get_ctx(); - char* state = chat_session_get_state(barejid); + const char* state = chat_session_get_state(barejid); char* jid = chat_session_get_jid(barejid); char* id = connection_create_stanza_id(); @@ -459,7 +459,7 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean { xmpp_ctx_t* const ctx = connection_get_ctx(); - char* state = chat_session_get_state(barejid); + const char* state = chat_session_get_state(barejid); char* jid = chat_session_get_jid(barejid); char* id = connection_create_stanza_id(); @@ -468,7 +468,7 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean char* account_name = session_get_account_name(); ProfAccount* account = accounts_get_account(account_name); if (account->pgp_keyid) { - Jid* jidp = jid_create(jid); + auto_jid Jid* jidp = jid_create(jid); char* encrypted = p_gpg_encrypt(jidp->barejid, msg, account->pgp_keyid); if (encrypted) { message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id); @@ -487,7 +487,6 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id); xmpp_message_set_body(message, msg); } - jid_destroy(jidp); } else { message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id); xmpp_message_set_body(message, msg); @@ -525,12 +524,11 @@ message_send_chat_ox(const char* const barejid, const char* const msg, gboolean #ifdef HAVE_LIBGPGME xmpp_ctx_t* const ctx = connection_get_ctx(); - char* state = chat_session_get_state(barejid); - char* jid = chat_session_get_jid(barejid); + const char* state = chat_session_get_state(barejid); + auto_char char* jid = chat_session_get_jid(barejid); char* id = connection_create_stanza_id(); xmpp_stanza_t* message = NULL; - Jid* jidp = jid_create(jid); char* account_name = session_get_account_name(); ProfAccount* account = accounts_get_account(account_name); @@ -561,8 +559,6 @@ message_send_chat_ox(const char* const barejid, const char* const msg, gboolean xmpp_stanza_to_text(message, &c, &s); account_free(account); - jid_destroy(jidp); - free(jid); if (state) { stanza_attach_state(ctx, message, state); @@ -589,7 +585,7 @@ message_send_chat_otr(const char* const barejid, const char* const msg, gboolean { xmpp_ctx_t* const ctx = connection_get_ctx(); - char* state = chat_session_get_state(barejid); + const char* state = chat_session_get_state(barejid); char* jid = chat_session_get_jid(barejid); char* id = connection_create_stanza_id(); @@ -627,7 +623,7 @@ message_send_chat_omemo(const char* const jid, uint32_t sid, GList* keys, const unsigned char* const ciphertext, size_t ciphertext_len, gboolean request_receipt, gboolean muc, const char* const replace_id) { - char* state = chat_session_get_state(jid); + const char* state = chat_session_get_state(jid); xmpp_ctx_t* const ctx = connection_get_ctx(); char* id; xmpp_stanza_t* message; @@ -888,10 +884,9 @@ _handle_error(xmpp_stanza_t* const stanza) ui_handle_error(err_msg); } else { if (type && (strcmp(type, "cancel") == 0)) { - Jid* jidp = jid_create(jid); + auto_jid Jid* jidp = jid_create(jid); if (jidp) { chat_session_remove(jidp->barejid); - jid_destroy(jidp); } } ui_handle_recipient_error(jid, err_msg); @@ -928,7 +923,7 @@ _handle_muc_user(xmpp_stanza_t* const stanza) return; } - Jid* jidp = jid_create(invitor_jid); + auto_jid Jid* jidp = jid_create(invitor_jid); if (!jidp) { return; } @@ -947,7 +942,6 @@ _handle_muc_user(xmpp_stanza_t* const stanza) } sv_ev_room_invite(INVITE_MEDIATED, invitor, room, reason, password); - jid_destroy(jidp); if (reason) { xmpp_free(ctx, reason); } @@ -974,7 +968,7 @@ _handle_conference(xmpp_stanza_t* const stanza) return; } - Jid* jidp = jid_create(from); + auto_jid Jid* jidp = jid_create(from); if (!jidp) { return; } @@ -984,7 +978,6 @@ _handle_conference(xmpp_stanza_t* const stanza) const char* password = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_PASSWORD); sv_ev_room_invite(INVITE_DIRECT, jidp->barejid, room, reason, password); - jid_destroy(jidp); } } @@ -1040,7 +1033,7 @@ _handle_groupchat(xmpp_stanza_t* const stanza) if (!room_jid) { return; } - Jid* from_jid = jid_create(room_jid); + auto_jid Jid* from_jid = jid_create(room_jid); if (!from_jid) { return; } @@ -1053,7 +1046,6 @@ _handle_groupchat(xmpp_stanza_t* const stanza) sv_ev_room_subject(from_jid->barejid, from_jid->resourcepart, subject_text); xmpp_free(ctx, subject_text); - jid_destroy(from_jid); return; } @@ -1084,31 +1076,28 @@ _handle_groupchat(xmpp_stanza_t* const stanza) } } - jid_destroy(from_jid); return; } sv_ev_room_broadcast(room_jid, broadcast); xmpp_free(ctx, broadcast); - jid_destroy(from_jid); return; } if (!jid_is_valid_room_form(from_jid)) { log_error("Invalid room JID: %s", from_jid->str); - jid_destroy(from_jid); return; } // room not active in profanity if (!muc_active(from_jid->barejid)) { log_error("Message received for inactive chat room: %s", from_jid->str); - jid_destroy(from_jid); return; } ProfMessage* message = message_init(); + jid_ref(from_jid); message->from_jid = from_jid; message->type = PROF_MSG_TYPE_MUC; @@ -1234,13 +1223,12 @@ _handle_receipt_received(xmpp_stanza_t* const stanza) return; } - Jid* jidp = jid_create(fulljid); + auto_jid Jid* jidp = jid_create(fulljid); if (!jidp) { return; } sv_ev_message_receipt(jidp->barejid, id); - jid_destroy(jidp); } } @@ -1268,10 +1256,9 @@ _receipt_request_handler(xmpp_stanza_t* const stanza) const gchar* from = xmpp_stanza_get_from(stanza); if (from) { - Jid* jid = jid_create(from); + auto_jid Jid* jid = jid_create(from); if (jid) { _message_send_receipt(jid->fulljid, id); - jid_destroy(jid); } } } @@ -1388,7 +1375,7 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c if (!from) { return; } - Jid* jid = jid_create(from); + auto_jid Jid* jid = jid_create(from); if (!jid) { return; } @@ -1396,13 +1383,13 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c // private message from chat room use full jid (room/nick) if (muc_active(jid->barejid)) { _handle_muc_private_message(stanza); - jid_destroy(jid); return; } // standard chat message, use jid without resource ProfMessage* message = message_init(); message->is_mam = is_mam; + jid_ref(jid); message->from_jid = jid; const gchar* to = xmpp_stanza_get_to(stanza); if (to) { @@ -1761,9 +1748,8 @@ _should_ignore_based_on_silence(xmpp_stanza_t* const stanza) { if (prefs_get_boolean(PREF_SILENCE_NON_ROSTER)) { const char* const from = xmpp_stanza_get_from(stanza); - Jid* from_jid = jid_create(from); + auto_jid Jid* from_jid = jid_create(from); PContact contact = roster_get_contact(from_jid->barejid); - jid_destroy(from_jid); if (!contact) { log_debug("[Silence] Ignoring message from: %s", from); return TRUE; diff --git a/src/xmpp/session.c b/src/xmpp/session.c index 3bec1ab2..c4ea3f24 100644 --- a/src/xmpp/session.c +++ b/src/xmpp/session.c @@ -96,8 +96,6 @@ static activity_state_t activity_state; static resource_presence_t saved_presence; static char* saved_status; -static void _session_reconnect(void); - static void _session_free_internals(void); static void _session_free_saved_details(void); @@ -268,12 +266,12 @@ session_process_events(void) if ((reconnect_sec != 0) && reconnect_timer) { int elapsed_sec = g_timer_elapsed(reconnect_timer, NULL); if (elapsed_sec > reconnect_sec) { - _session_reconnect(); + session_reconnect_now(); } } break; case JABBER_RECONNECT: - _session_reconnect(); + session_reconnect_now(); break; default: break; @@ -307,7 +305,7 @@ _receive_mood(xmpp_stanza_t* const stanza, void* const userdata) const char* m = xmpp_stanza_get_name(c); xmpp_stanza_t* t = xmpp_stanza_get_child_by_name(mood, STANZA_NAME_TEXT); if (t) { - const char* text = xmpp_stanza_get_text(t); + auto_char char* text = xmpp_stanza_get_text(t); cons_show("Mood from %s %s (%s)", from, m, text); } else { cons_show("Mood from %s %s", from, m); @@ -557,8 +555,8 @@ session_reconnect(gchar* altdomain, unsigned short altport) reconnect.altport = altport; } -static void -_session_reconnect(void) +void +session_reconnect_now(void) { // reconnect with account. ProfAccount* account = accounts_get_account(saved_account.name); diff --git a/src/xmpp/session.h b/src/xmpp/session.h index d8565fa4..e6facb93 100644 --- a/src/xmpp/session.h +++ b/src/xmpp/session.h @@ -47,5 +47,6 @@ void session_init_activity(void); void session_check_autoaway(void); void session_reconnect(gchar* altdomain, unsigned short altport); +void session_reconnect_now(void); #endif |