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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
32
src/log.c
32
src/log.c
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -10,10 +10,6 @@ void
|
||||
accounts_load(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
accounts_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
char*
|
||||
accounts_find_all(const char* const prefix, gboolean previous, void* context)
|
||||
|
||||
@@ -78,10 +78,6 @@ log_stderr_init(log_level_t level)
|
||||
{
|
||||
}
|
||||
void
|
||||
log_stderr_close(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
log_stderr_handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ void
|
||||
omemo_init(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
omemo_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
char*
|
||||
omemo_fingerprint_autocomplete(const char* const search_str, gboolean previous)
|
||||
|
||||
@@ -33,10 +33,6 @@ void
|
||||
otr_init(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
otr_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
char*
|
||||
otr_libotr_version(void)
|
||||
|
||||
@@ -6,10 +6,6 @@ void
|
||||
p_gpg_init(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
p_gpg_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
p_gpg_list_keys(void)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -63,10 +63,6 @@ ui_update(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
ui_close(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
ui_redraw(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user