summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/settings.h1
-rw-r--r--src/daemon/main.c19
-rw-r--r--src/daemon/purple.c61
-rw-r--r--src/daemon/settings.c3
-rw-r--r--src/daemon/settings_private.h1
5 files changed, 72 insertions, 13 deletions
diff --git a/include/settings.h b/include/settings.h
index c7655ba..e2e9644 100644
--- a/include/settings.h
+++ b/include/settings.h
@@ -38,5 +38,6 @@ char *setting_progname(void);
char *setting_im_user(void);
char *setting_im_password(void);
char *setting_im_proto(void);
+void settings_cleanup(void);
#endif /* USURPATION_SETTINGS_H */
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 41e798b..94e59fd 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -21,11 +21,18 @@
#include <unistd.h>
#include <time.h>
+#include <stdlib.h>
#include <stdio.h>
#include "settings.h"
#include "net.h"
#include "purple.h"
+static struct _state {
+ int nd;
+} _progstate;
+
+void cleanup(void);
+
/* the logic is a placeholder right now */
int main(int argc, char **argv)
{
@@ -34,8 +41,9 @@ int main(int argc, char **argv)
printf("Usurpation daemon version %s starting\n", version);
+ atexit(cleanup);
settings_init();
- net_init(setting_port()); /* TODO: get port from settings. */
+ _progstate.nd = net_init(setting_port());
if (purple_init() && setting_verbose()) {
fprintf(stderr, "libpurple initialization failed\n");
}
@@ -52,4 +60,13 @@ int main(int argc, char **argv)
/* noop */
}
+
+ return 0;
+}
+
+void cleanup(void)
+{
+ purple_close();
+ net_close(_progstate.nd);
+ settings_cleanup();
}
diff --git a/src/daemon/purple.c b/src/daemon/purple.c
index 6b73774..882ea61 100644
--- a/src/daemon/purple.c
+++ b/src/daemon/purple.c
@@ -120,6 +120,35 @@ static void pthread_mutex_unlock_thunk(void *arg)
(void) pthread_mutex_unlock(mutex);
}
+static void purple_account_destroy_thunk(void *arg)
+{
+ PurpleAccount *account = arg;
+
+ purple_account_destroy(account);
+}
+
+static void purple_core_destroy(void *arg)
+{
+ (void) arg;
+
+ purple_timeout_add(0, purple_core_quit_cb, NULL);
+}
+
+static void g_main_loop_unref_thunk(void *arg)
+{
+ GMainLoop *loop = arg;
+
+ g_main_loop_unref(loop);
+}
+
+static void g_main_loop_quit_thunk(void *arg)
+{
+ GMainLoop *loop = arg;
+
+ g_main_loop_quit(loop);
+}
+
+
static void *purple_spawn(void *disregard)
{
GMainLoop *loop;
@@ -131,16 +160,21 @@ static void *purple_spawn(void *disregard)
(void) disregard;
pthread_cleanup_push(pthread_mutex_unlock_thunk, &state.mutex);
- pthread_cleanup_push(free, progname);
- pthread_cleanup_push(free, user);
- pthread_cleanup_push(free, password);
- pthread_cleanup_push(free, proto);
progname = setting_progname();
+ pthread_cleanup_push(free, progname);
+
user = setting_im_user();
+ pthread_cleanup_push(free, user);
+
password = setting_im_password();
+ pthread_cleanup_push(free, password);
+
proto = setting_im_proto();
+ pthread_cleanup_push(free, proto);
+
loop = g_main_loop_new(NULL, FALSE);
+ pthread_cleanup_push(g_main_loop_unref_thunk, loop);
/* avoid an unholy army of libpurple's DNS resolver process zombies */
signal(SIGCHLD, SIG_IGN);
@@ -158,22 +192,31 @@ static void *purple_spawn(void *disregard)
purple_core_set_ui_ops(&core_uiops);
purple_eventloop_set_ui_ops(&eventloops);
- purple_core_init(setting_progname());
+ purple_core_init(progname);
purple_prefs_load();
- state.account = purple_account_new(setting_im_user(), setting_im_proto());
- purple_account_set_password(state.account, setting_im_password());
- purple_account_set_enabled(state.account, setting_progname(), TRUE);
+ pthread_cleanup_push(purple_core_destroy, NULL);
+
+ state.account = purple_account_new(user, proto);
+ purple_account_set_password(state.account, password);
+ purple_account_set_enabled(state.account, progname, TRUE);
+
+ pthread_cleanup_push(purple_account_destroy_thunk, state.account);
g_main_loop_run(loop);
+ pthread_cleanup_push(g_main_loop_quit_thunk, loop);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
- return NULL;
+ pthread_exit(NULL);
}
/*
diff --git a/src/daemon/settings.c b/src/daemon/settings.c
index 5809139..5314fef 100644
--- a/src/daemon/settings.c
+++ b/src/daemon/settings.c
@@ -38,7 +38,6 @@
*/
void settings_init(void)
{
- atexit(free_strings);
unset_flag(flag_daemonize);
settings.port = 6996;
settings.verboselevel = USURP_VERBOSITY;
@@ -220,7 +219,7 @@ static void set_im_proto(const void * const arg)
settings.im_proto = strdup(a);
}
-static void free_strings(void)
+void settings_cleanup(void)
{
free(settings.progname);
free(settings.im_user);
diff --git a/src/daemon/settings_private.h b/src/daemon/settings_private.h
index 3e091ab..69ed25a 100644
--- a/src/daemon/settings_private.h
+++ b/src/daemon/settings_private.h
@@ -48,7 +48,6 @@ static void set_flag(unsigned int flag);
static void unset_flag(unsigned int flag);
static int setting_readconf(const char * const path);
static int setting_handle_config_entry(const char * const entry, const char * const value);
-static void free_strings(void);
static void set_daemonize(const void * const arg);
static void set_port(const void * const arg);