Introduce our own shutdown callback mechanism.

Instead of adding stuff to `_shutdown()`, we can now register a shutdown
routine from the respective `init()` function of our modules.

This also has the advantage, that we're sure they're called in reverse
order from how the initialization happened.

I didn't simply use `atexit()` because POSIX says that the number of
possible callbacks is limited (min 32) and I was not sure whether
we will maybe extend this number at one point.

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
Steffen Jaeckel
2025-03-07 11:44:31 +01:00
parent 662a0be633
commit c5a131ee46
39 changed files with 321 additions and 327 deletions

View File

@@ -73,12 +73,25 @@ static void _chat_log_chat(const char* const login, const char* const other, con
chat_log_direction_t direction, GDateTime* timestamp, const char* const resourcepart);
static void _groupchat_log_chat(const gchar* const login, const gchar* const room, const gchar* const nick,
const gchar* const msg);
void
chat_log_init(void)
_chatlog_close(void)
{
g_hash_table_destroy(logs);
g_hash_table_destroy(groupchat_logs);
}
void
chatlog_init(void)
{
log_info("Initialising chat logs");
prof_add_shutdown_routine(_chatlog_close);
logs = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, free,
(GDestroyNotify)_free_chat_log);
groupchat_logs = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, free,
(GDestroyNotify)_free_chat_log);
}
void
@@ -295,14 +308,6 @@ _chat_log_chat(const char* const login, const char* const other, const char* msg
g_date_time_unref(timestamp);
}
void
groupchat_log_init(void)
{
log_info("Initialising groupchat logs");
groupchat_logs = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, free,
(GDestroyNotify)_free_chat_log);
}
void
groupchat_log_msg_out(const gchar* const room, const gchar* const msg)
{
@@ -391,13 +396,6 @@ _groupchat_log_chat(const gchar* const login, const gchar* const room, const gch
g_date_time_unref(dt_tmp);
}
void
chat_log_close(void)
{
g_hash_table_destroy(logs);
g_hash_table_destroy(groupchat_logs);
}
static char*
_get_log_filename(const char* const other, const char* const login, GDateTime* dt, gboolean is_room)
{

View File

@@ -45,7 +45,7 @@ typedef enum {
PROF_OUT_LOG
} chat_log_direction_t;
void chat_log_init(void);
void chatlog_init(void);
void chat_log_msg_out(const char* const barejid, const char* const msg, const char* resource);
void chat_log_otr_msg_out(const char* const barejid, const char* const msg, const char* resource);
@@ -57,8 +57,6 @@ void chat_log_otr_msg_in(ProfMessage* message);
void chat_log_pgp_msg_in(ProfMessage* message);
void chat_log_omemo_msg_in(ProfMessage* message);
void chat_log_close(void);
void groupchat_log_init(void);
void groupchat_log_msg_out(const gchar* const room, const gchar* const msg);

View File

@@ -2840,6 +2840,14 @@ cmd_search_index_all(char* term)
return results;
}
static void
_cmd_uninit(void)
{
cmd_ac_uninit();
g_hash_table_destroy(commands);
g_hash_table_destroy(search_index);
}
/*
* Initialise command autocompleter and history
*/
@@ -2848,6 +2856,8 @@ cmd_init(void)
{
log_info("Initialising commands");
prof_add_shutdown_routine(_cmd_uninit);
cmd_ac_init();
search_index = g_hash_table_new_full(g_str_hash, g_str_equal, free, g_free);
@@ -2878,14 +2888,6 @@ cmd_init(void)
prefs_free_aliases(aliases);
}
void
cmd_uninit(void)
{
cmd_ac_uninit();
g_hash_table_destroy(commands);
g_hash_table_destroy(search_index);
}
gboolean
cmd_valid_tag(const char* const str)
{

View File

@@ -42,7 +42,6 @@
#include "ui/ui.h"
void cmd_init(void);
void cmd_uninit(void);
Command* cmd_get(const char* const command);
GList* cmd_get_ordered(const char* const tag);

View File

@@ -196,5 +196,6 @@ gchar* get_expanded_path(const char* path);
char* basename_from_url(const char* url);
gchar* prof_get_version(void);
void prof_add_shutdown_routine(void (*routine)(void));
#endif

View File

@@ -61,10 +61,22 @@ static Autocomplete enabled_ac;
static void _save_accounts(void);
static void
_accounts_close(void)
{
autocomplete_free(all_ac);
autocomplete_free(enabled_ac);
free_keyfile(&accounts_prof_keyfile);
accounts = NULL;
}
void
accounts_load(void)
{
log_info("Loading accounts");
prof_add_shutdown_routine(_accounts_close);
all_ac = autocomplete_new();
enabled_ac = autocomplete_new();
load_data_keyfile(&accounts_prof_keyfile, FILE_ACCOUNTS);
@@ -82,15 +94,6 @@ accounts_load(void)
}
}
void
accounts_close(void)
{
autocomplete_free(all_ac);
autocomplete_free(enabled_ac);
free_keyfile(&accounts_prof_keyfile);
accounts = NULL;
}
char*
accounts_find_enabled(const char* const prefix, gboolean previous, void* context)
{

View File

@@ -42,7 +42,6 @@
#include "config/account.h"
void accounts_load(void);
void accounts_close(void);
char* accounts_find_all(const char* const prefix, gboolean previous, void* context);
char* accounts_find_enabled(const char* const prefix, gboolean previous, void* context);

View File

@@ -66,6 +66,28 @@ static void _theme_list_dir(const gchar* const dir, GSList** result);
static GString* _theme_find(const char* const theme_name);
static gboolean _theme_load_file(const char* const theme_name);
static void
_theme_close(void)
{
color_pair_cache_free();
if (theme) {
g_key_file_free(theme);
theme = NULL;
}
if (theme_loc) {
g_string_free(theme_loc, TRUE);
theme_loc = NULL;
}
if (bold_items) {
g_hash_table_destroy(bold_items);
bold_items = NULL;
}
if (defaults) {
g_hash_table_destroy(defaults);
defaults = NULL;
}
}
void
theme_init(const char* const theme_name)
{
@@ -77,6 +99,8 @@ theme_init(const char* const theme_name)
}
}
prof_add_shutdown_routine(_theme_close);
defaults = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
// Set default colors
@@ -248,28 +272,6 @@ theme_list(void)
return result;
}
void
theme_close(void)
{
color_pair_cache_free();
if (theme) {
g_key_file_free(theme);
theme = NULL;
}
if (theme_loc) {
g_string_free(theme_loc, TRUE);
theme_loc = NULL;
}
if (bold_items) {
g_hash_table_destroy(bold_items);
bold_items = NULL;
}
if (defaults) {
g_hash_table_destroy(defaults);
defaults = NULL;
}
}
void
theme_init_colours(void)
{

View File

@@ -56,10 +56,25 @@ static Autocomplete certs_ac;
static char* current_fp;
static void
_tlscerts_close(void)
{
free_keyfile(&tlscerts_prof_keyfile);
tlscerts = NULL;
free(current_fp);
current_fp = NULL;
autocomplete_free(certs_ac);
}
void
tlscerts_init(void)
{
log_info("Loading TLS certificates");
prof_add_shutdown_routine(_tlscerts_close);
load_data_keyfile(&tlscerts_prof_keyfile, FILE_TLSCERTS);
tlscerts = tlscerts_prof_keyfile.keyfile;
@@ -356,18 +371,6 @@ tlscerts_free(TLSCertificate* cert)
}
}
void
tlscerts_close(void)
{
free_keyfile(&tlscerts_prof_keyfile);
tlscerts = NULL;
free(current_fp);
current_fp = NULL;
autocomplete_free(certs_ac);
}
static void
_save_tlscerts(void)
{

View File

@@ -96,6 +96,4 @@ char* tlscerts_complete(const char* const prefix, gboolean previous, void* conte
void tlscerts_reset_ac(void);
void tlscerts_close(void);
#endif

View File

@@ -313,6 +313,21 @@ log_stderr_nonblock_set(int fd)
return rc;
}
static void
_log_stderr_close(void)
{
if (!stderr_inited)
return;
/* handle remaining logs before close */
log_stderr_handler();
stderr_inited = 0;
free(stderr_buf);
g_string_free(stderr_msg, TRUE);
close(stderr_pipe[0]);
close(stderr_pipe[1]);
}
void
log_stderr_init(log_level_t level)
{
@@ -337,6 +352,8 @@ log_stderr_init(log_level_t level)
stderr_level = level;
stderr_inited = 1;
prof_add_shutdown_routine(_log_stderr_close);
if (stderr_buf == NULL || stderr_msg == NULL) {
errno = ENOMEM;
goto err_free;
@@ -354,18 +371,3 @@ err:
stderr_inited = 0;
log_error("Unable to init stderr log handler: %s", strerror(errno));
}
void
log_stderr_close(void)
{
if (!stderr_inited)
return;
/* handle remaining logs before close */
log_stderr_handler();
stderr_inited = 0;
free(stderr_buf);
g_string_free(stderr_msg, TRUE);
close(stderr_pipe[0]);
close(stderr_pipe[1]);
}

View File

@@ -59,7 +59,6 @@ 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);
void log_stderr_close(void);
void log_stderr_handler(void);
#endif

View File

@@ -116,10 +116,23 @@ static struct omemo_static_data
GHashTable* fingerprint_ac;
} omemo_static_data;
static void
_omemo_close(void)
{
if (omemo_static_data.fingerprint_ac) {
g_hash_table_destroy(omemo_static_data.fingerprint_ac);
omemo_static_data.fingerprint_ac = NULL;
}
pthread_mutex_destroy(&omemo_static_data.lock);
}
void
omemo_init(void)
{
log_info("[OMEMO] initialising");
prof_add_shutdown_routine(_omemo_close);
if (omemo_crypto_init() != 0) {
cons_show("Error initializing OMEMO crypto: gcry_check_version() failed");
}
@@ -131,16 +144,6 @@ omemo_init(void)
omemo_static_data.fingerprint_ac = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)autocomplete_free);
}
void
omemo_close(void)
{
if (omemo_static_data.fingerprint_ac) {
g_hash_table_destroy(omemo_static_data.fingerprint_ac);
omemo_static_data.fingerprint_ac = NULL;
}
pthread_mutex_destroy(&omemo_static_data.lock);
}
void
omemo_on_connect(ProfAccount* account)
{

View File

@@ -61,7 +61,6 @@ typedef struct omemo_key
} omemo_key_t;
void omemo_init(void);
void omemo_close(void);
void omemo_on_connect(ProfAccount* account);
void omemo_on_disconnect(void);
void omemo_generate_crypto_materials(ProfAccount* account);

View File

@@ -166,12 +166,24 @@ otr_start_query(void)
return otrlib_start_query();
}
static void
_otr_shutdown(void)
{
if (jid) {
free(jid);
jid = NULL;
}
otrlib_shutdown();
}
void
otr_init(void)
{
log_info("Initialising OTR");
OTRL_INIT;
prof_add_shutdown_routine(_otr_shutdown);
jid = NULL;
ops.policy = cb_policy;
@@ -187,16 +199,6 @@ otr_init(void)
data_loaded = FALSE;
}
void
otr_shutdown(void)
{
if (jid) {
free(jid);
jid = NULL;
}
otrlib_shutdown();
}
void
otr_poll(void)
{

View File

@@ -66,7 +66,6 @@ OtrlMessageAppOps* otr_messageops(void);
GHashTable* otr_smpinitators(void);
void otr_init(void);
void otr_shutdown(void);
char* otr_libotr_version(void);
char* otr_start_query(void);
void otr_poll(void);

View File

@@ -111,25 +111,8 @@ _p_gpg_passphrase_cb(void* hook, const char* uid_hint, const char* passphrase_in
return 0;
}
void
p_gpg_init(void)
{
libversion = gpgme_check_version(NULL);
log_debug("GPG: Found gpgme version: %s", libversion);
gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
pubkeys = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_p_gpg_free_pubkeyid);
key_ac = autocomplete_new();
GHashTable* keys = p_gpg_list_keys();
p_gpg_free_keys(keys);
passphrase = NULL;
passphrase_attempt = NULL;
}
void
p_gpg_close(void)
static void
_p_gpg_close(void)
{
if (pubkeys) {
g_hash_table_destroy(pubkeys);
@@ -153,6 +136,25 @@ p_gpg_close(void)
}
}
void
p_gpg_init(void)
{
libversion = gpgme_check_version(NULL);
log_debug("GPG: Found gpgme version: %s", libversion);
gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
prof_add_shutdown_routine(_p_gpg_close);
pubkeys = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_p_gpg_free_pubkeyid);
key_ac = autocomplete_new();
GHashTable* keys = p_gpg_list_keys();
p_gpg_free_keys(keys);
passphrase = NULL;
passphrase_attempt = NULL;
}
void
p_gpg_on_connect(const char* const barejid)
{
@@ -208,7 +210,7 @@ p_gpg_on_connect(const char* const barejid)
void
p_gpg_on_disconnect(void)
{
p_gpg_close();
_p_gpg_close();
pubkeys = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_p_gpg_free_pubkeyid);
key_ac = autocomplete_new();
}

View File

@@ -55,7 +55,6 @@ typedef struct pgp_pubkeyid_t
} ProfPGPPubKeyId;
void p_gpg_init(void);
void p_gpg_close(void);
void p_gpg_on_connect(const char* const barejid);
void p_gpg_on_disconnect(void);
GHashTable* p_gpg_list_keys(void);

View File

@@ -65,9 +65,49 @@
static GHashTable* plugins;
static void
_plugins_shutdown(void)
{
GList* values = g_hash_table_get_values(plugins);
GList *curr = values, *next;
while (curr) {
next = g_list_next(curr);
#ifdef HAVE_PYTHON
if (curr && ((ProfPlugin*)curr->data)->lang == LANG_PYTHON) {
python_plugin_destroy(curr->data);
curr = NULL;
}
#endif
#ifdef HAVE_C
if (curr && ((ProfPlugin*)curr->data)->lang == LANG_C) {
c_plugin_destroy(curr->data);
curr = NULL;
}
#endif
curr = next;
}
g_list_free(values);
#ifdef HAVE_PYTHON
python_shutdown();
#endif
#ifdef HAVE_C
c_shutdown();
#endif
autocompleters_destroy();
plugin_themes_close();
plugin_settings_close();
callbacks_close();
disco_close();
g_hash_table_destroy(plugins);
plugins = NULL;
}
void
plugins_init(void)
{
prof_add_shutdown_routine(_plugins_shutdown);
plugins = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
callbacks_init();
autocompleters_init();
@@ -421,21 +461,8 @@ plugins_close_win(const char* const plugin_name, const char* const tag)
callbacks_remove_win(plugin_name, tag);
}
void
plugins_on_start(void)
{
GList* values = g_hash_table_get_values(plugins);
GList* curr = values;
while (curr) {
ProfPlugin* plugin = curr->data;
plugin->on_start_func(plugin);
curr = g_list_next(curr);
}
g_list_free(values);
}
void
plugins_on_shutdown(void)
static void
_plugins_on_shutdown(void)
{
GList* values = g_hash_table_get_values(plugins);
GList* curr = values;
@@ -447,6 +474,20 @@ plugins_on_shutdown(void)
g_list_free(values);
}
void
plugins_on_start(void)
{
prof_add_shutdown_routine(_plugins_on_shutdown);
GList* values = g_hash_table_get_values(plugins);
GList* curr = values;
while (curr) {
ProfPlugin* plugin = curr->data;
plugin->on_start_func(plugin);
curr = g_list_next(curr);
}
g_list_free(values);
}
void
plugins_on_connect(const char* const account_name, const char* const fulljid)
{
@@ -924,42 +965,3 @@ plugins_get_disco_features(void)
{
return disco_get_features();
}
void
plugins_shutdown(void)
{
GList* values = g_hash_table_get_values(plugins);
GList *curr = values, *next;
while (curr) {
next = g_list_next(curr);
#ifdef HAVE_PYTHON
if (curr && ((ProfPlugin*)curr->data)->lang == LANG_PYTHON) {
python_plugin_destroy(curr->data);
curr = NULL;
}
#endif
#ifdef HAVE_C
if (curr && ((ProfPlugin*)curr->data)->lang == LANG_C) {
c_plugin_destroy(curr->data);
curr = NULL;
}
#endif
curr = next;
}
g_list_free(values);
#ifdef HAVE_PYTHON
python_shutdown();
#endif
#ifdef HAVE_C
c_shutdown();
#endif
autocompleters_destroy();
plugin_themes_close();
plugin_settings_close();
callbacks_close();
disco_close();
g_hash_table_destroy(plugins);
plugins = NULL;
}

View File

@@ -113,7 +113,6 @@ GSList* plugins_unloaded_list(void);
GList* plugins_loaded_list(void);
char* plugins_autocomplete(const char* const input, gboolean previous);
void plugins_reset_autocomplete(void);
void plugins_shutdown(void);
void plugins_free_install_result(PluginsInstallResult* result);
@@ -129,7 +128,6 @@ gboolean plugins_reload(const char* const name, GString* error_message);
void plugins_reload_all(void);
void plugins_on_start(void);
void plugins_on_shutdown(void);
void plugins_on_connect(const char* const account_name, const char* const fulljid);
void plugins_on_disconnect(const char* const account_name, const char* const fulljid);

View File

@@ -220,8 +220,7 @@ _init(char* log_level, char* config_file, char* log_file, char* theme_name)
auto_gchar gchar* prof_version = prof_get_version();
log_info("Starting Profanity (%s)…", prof_version);
chat_log_init();
groupchat_log_init();
chatlog_init();
accounts_load();
if (theme_name) {
@@ -261,6 +260,47 @@ _init(char* log_level, char* config_file, char* log_file, char* theme_name)
ui_resize();
}
static GList* shutdown_routines = NULL;
/* We have to encapsulate the function pointer, since the C standard does not guarantee
* that a void* can be converted to a function* and vice-versa.
*/
struct shutdown_routine
{
void (*routine)(void);
};
static gint
_cmp_shutdown_routine(const struct shutdown_routine* a, const struct shutdown_routine* b)
{
return a->routine != b->routine;
}
void
prof_add_shutdown_routine(void (*routine)(void))
{
struct shutdown_routine this = { .routine = routine };
if (g_list_find_custom(shutdown_routines, &this, (GCompareFunc)_cmp_shutdown_routine)) {
return;
}
struct shutdown_routine* r = malloc(sizeof *r);
r->routine = routine;
shutdown_routines = g_list_prepend(shutdown_routines, r);
}
static void
_call_and_free_shutdown_routine(struct shutdown_routine* r)
{
r->routine();
free(r);
}
void
prof_shutdown(void)
{
g_list_free_full(shutdown_routines, (GDestroyNotify)_call_and_free_shutdown_routine);
}
static void
_shutdown(void)
{
@@ -276,30 +316,9 @@ _shutdown(void)
if (conn_status == JABBER_CONNECTED) {
cl_ev_disconnect();
}
#ifdef HAVE_GTK
tray_shutdown();
#endif
session_shutdown();
plugins_on_shutdown();
muc_close();
caps_close();
#ifdef HAVE_LIBOTR
otr_shutdown();
#endif
#ifdef HAVE_LIBGPGME
p_gpg_close();
#endif
#ifdef HAVE_OMEMO
omemo_close();
#endif
chat_log_close();
theme_close();
accounts_close();
tlscerts_close();
log_stderr_close();
plugins_shutdown();
cmd_uninit();
ui_close();
prof_shutdown();
/* Prefs and logs have to be closed in swapped order, so they're no using the automatic
* shutdown mechanism. */
prefs_close();
log_close();
}

View File

@@ -89,10 +89,26 @@ static Display* display;
static void _ui_draw_term_title(void);
static void
_ui_close(void)
{
g_timer_destroy(ui_idle_time);
endwin();
notifier_uninit();
cons_clear_alerts();
wins_destroy();
inp_close();
status_bar_close();
free_title_bar();
delwin(main_scr);
delscreen(set_term(NULL));
}
void
ui_init(void)
{
log_info("Initialising UI");
prof_add_shutdown_routine(_ui_close);
main_scr = initscr();
nonl();
cbreak();
@@ -180,21 +196,6 @@ ui_reset_idle_time(void)
g_timer_start(ui_idle_time);
}
void
ui_close(void)
{
g_timer_destroy(ui_idle_time);
endwin();
notifier_uninit();
cons_clear_alerts();
wins_destroy();
inp_close();
status_bar_close();
free_title_bar();
delwin(main_scr);
delscreen(set_term(NULL));
}
void
ui_resize(void)
{

View File

@@ -153,9 +153,21 @@ _tray_change_icon(gpointer data)
return TRUE;
}
static void
_tray_shutdown(void)
{
if (gtk_ready && prefs_get_boolean(PREF_TRAY)) {
tray_disable();
}
g_string_free(icon_filename, TRUE);
g_string_free(icon_msg_filename, TRUE);
gtk_main_quit();
}
void
tray_init(void)
{
prof_add_shutdown_routine(_tray_shutdown);
_get_icons();
gtk_ready = gtk_init_check(0, NULL);
log_debug("Env is GTK-ready: %s", gtk_ready ? "true" : "false");
@@ -179,17 +191,6 @@ tray_update(void)
}
}
void
tray_shutdown(void)
{
if (gtk_ready && prefs_get_boolean(PREF_TRAY)) {
tray_disable();
}
g_string_free(icon_filename, TRUE);
g_string_free(icon_msg_filename, TRUE);
gtk_main_quit();
}
void
tray_set_timer(int interval)
{

View File

@@ -39,7 +39,6 @@
#ifdef HAVE_GTK
void tray_init(void);
void tray_update(void);
void tray_shutdown(void);
void tray_enable(void);
void tray_disable(void);

View File

@@ -62,7 +62,6 @@
void ui_init(void);
void ui_load_colours(void);
void ui_update(void);
void ui_close(void);
void ui_redraw(void);
void ui_resize(void);
void ui_focus_win(ProfWin* window);

View File

@@ -69,10 +69,26 @@ static EntityCapabilities* _caps_by_ver(const char* const ver);
static EntityCapabilities* _caps_by_jid(const char* const jid);
static EntityCapabilities* _caps_copy(EntityCapabilities* caps);
static void
_caps_close(void)
{
free_keyfile(&caps_prof_keyfile);
cache = NULL;
g_hash_table_destroy(jid_to_ver);
g_hash_table_destroy(jid_to_caps);
g_free(cache_loc);
cache_loc = NULL;
g_hash_table_destroy(prof_features);
prof_features = NULL;
}
void
caps_init(void)
{
log_info("Loading capabilities cache");
prof_add_shutdown_routine(_caps_close);
load_data_keyfile(&caps_prof_keyfile, FILE_CAPSCACHE);
cache = caps_prof_keyfile.keyfile;
@@ -339,19 +355,6 @@ caps_reset_ver(void)
}
}
void
caps_close(void)
{
free_keyfile(&caps_prof_keyfile);
cache = NULL;
g_hash_table_destroy(jid_to_ver);
g_hash_table_destroy(jid_to_caps);
g_free(cache_loc);
cache_loc = NULL;
g_hash_table_destroy(prof_features);
prof_features = NULL;
}
static EntityCapabilities*
_caps_by_ver(const char* const ver)
{

View File

@@ -91,17 +91,8 @@ static Occupant* _muc_occupant_new(const char* const nick, const char* const jid
muc_affiliation_t affiliation, resource_presence_t presence, const char* const status);
static void _occupant_free(Occupant* occupant);
void
muc_init(void)
{
invite_ac = autocomplete_new();
confservers_ac = autocomplete_new();
rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_room);
invite_passwords = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
}
void
muc_close(void)
static void
_muc_close(void)
{
autocomplete_free(invite_ac);
autocomplete_free(confservers_ac);
@@ -113,6 +104,16 @@ muc_close(void)
confservers_ac = NULL;
}
void
muc_init(void)
{
prof_add_shutdown_routine(_muc_close);
invite_ac = autocomplete_new();
confservers_ac = autocomplete_new();
rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_room);
invite_passwords = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
}
void
muc_confserver_add(const char* const server)
{

View File

@@ -82,7 +82,6 @@ typedef struct _muc_occupant_t
} Occupant;
void muc_init(void);
void muc_close(void);
void muc_join(const char* const room, const char* const nick, const char* const password, gboolean autojoin);
void muc_leave(const char* const room);

View File

@@ -99,10 +99,25 @@ static char* saved_status;
static void _session_free_internals(void);
static void _session_free_saved_details(void);
static void
_session_shutdown(void)
{
_session_free_internals();
chat_sessions_clear();
presence_sub_requests_destroy();
connection_shutdown();
if (saved_status) {
free(saved_status);
}
}
void
session_init(void)
{
log_info("Initialising XMPP");
prof_add_shutdown_routine(_session_shutdown);
connection_init();
presence_sub_requests_init();
caps_init();
@@ -227,20 +242,6 @@ session_disconnect(void)
connection_set_disconnected();
}
void
session_shutdown(void)
{
_session_free_internals();
chat_sessions_clear();
presence_sub_requests_destroy();
connection_shutdown();
if (saved_status) {
free(saved_status);
}
}
void
session_process_events(void)
{

View File

@@ -183,7 +183,6 @@ jabber_conn_status_t session_connect_with_details(const char* const jid, const c
jabber_conn_status_t session_connect_with_account(const ProfAccount* const account);
void session_disconnect(void);
void session_shutdown(void);
void session_process_events(void);
const char* session_get_account_name(void);
void session_reconnect_now(void);
@@ -275,7 +274,6 @@ void iq_muc_register_nick(const char* const roomjid);
void autoping_timer_extend(void);
EntityCapabilities* caps_lookup(const char* const jid);
void caps_close(void);
void caps_destroy(EntityCapabilities* caps);
void caps_reset_ver(void);
void caps_add_feature(char* feature);

View File

@@ -27,7 +27,7 @@
#include <xmpp/xmpp.h>
void
chat_log_init(void)
chatlog_init(void)
{
}
@@ -65,11 +65,6 @@ chat_log_omemo_msg_in(ProfMessage* message)
{
}
void
chat_log_close(void)
{
}
void
groupchat_log_init(void)
{

View File

@@ -10,10 +10,6 @@ void
accounts_load(void)
{
}
void
accounts_close(void)
{
}
char*
accounts_find_all(const char* const prefix, gboolean previous, void* context)

View File

@@ -78,10 +78,6 @@ log_stderr_init(log_level_t level)
{
}
void
log_stderr_close(void)
{
}
void
log_stderr_handler(void)
{
}

View File

@@ -7,10 +7,6 @@ void
omemo_init(void)
{
}
void
omemo_close(void)
{
}
char*
omemo_fingerprint_autocomplete(const char* const search_str, gboolean previous)

View File

@@ -33,10 +33,6 @@ void
otr_init(void)
{
}
void
otr_shutdown(void)
{
}
char*
otr_libotr_version(void)

View File

@@ -6,10 +6,6 @@ void
p_gpg_init(void)
{
}
void
p_gpg_close(void)
{
}
GHashTable*
p_gpg_list_keys(void)

View File

@@ -17,6 +17,9 @@
#include "plugins/plugins.h"
#include "ui/window_list.h"
void prof_shutdown(void);
void
console_shows_online_presence_when_set_online(void** state)
{
@@ -35,7 +38,7 @@ console_shows_online_presence_when_set_online(void** state)
sv_ev_contact_online(barejid, resource, NULL, NULL);
roster_destroy();
plugins_shutdown();
prof_shutdown();
}
void
@@ -56,7 +59,7 @@ console_shows_online_presence_when_set_all(void** state)
sv_ev_contact_online(barejid, resource, NULL, NULL);
roster_destroy();
plugins_shutdown();
prof_shutdown();
}
void
@@ -77,7 +80,7 @@ console_shows_dnd_presence_when_set_all(void** state)
sv_ev_contact_online(barejid, resource, NULL, NULL);
roster_destroy();
plugins_shutdown();
prof_shutdown();
}
void
@@ -103,7 +106,7 @@ handle_offline_removes_chat_session(void** state)
roster_destroy();
chat_sessions_clear();
plugins_shutdown();
prof_shutdown();
}
void

View File

@@ -63,10 +63,6 @@ ui_update(void)
{
}
void
ui_close(void)
{
}
void
ui_redraw(void)
{
}

View File

@@ -47,10 +47,6 @@ session_disconnect(void)
{
}
void
session_shutdown(void)
{
}
void
session_process_events(void)
{
}
@@ -477,11 +473,6 @@ caps_lookup(const char* const jid)
return NULL;
}
void
caps_close(void)
{
}
void
caps_destroy(EntityCapabilities* caps)
{