about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2016-06-08 23:25:51 +0100
committerJames Booth <boothj5@gmail.com>2016-06-08 23:25:51 +0100
commit3a3933eff6e59b0d29a22961802a2ef311b1d64e (patch)
tree09b15d8ebad8ce552d8dfeb156b5ec0230cc6418
parentd79364358a6e222d6e0530a8072c53313e55b044 (diff)
downloadprofani-tty-3a3933eff6e59b0d29a22961802a2ef311b1d64e.tar.gz
Add ProfIdFreeCallback to free stale id handlers on connect
-rw-r--r--src/xmpp/blocking.c6
-rw-r--r--src/xmpp/bookmark.c2
-rw-r--r--src/xmpp/iq.c97
-rw-r--r--src/xmpp/iq.h3
-rw-r--r--src/xmpp/roster.c19
5 files changed, 86 insertions, 41 deletions
diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c
index a272b0c9..92e7dffc 100644
--- a/src/xmpp/blocking.c
+++ b/src/xmpp/blocking.c
@@ -76,7 +76,7 @@ blocking_request(void)
     }
     blocked_ac = autocomplete_new();
 
-    iq_id_handler_add(id, _blocklist_result_handler, NULL);
+    iq_id_handler_add(id, _blocklist_result_handler, NULL, NULL);
 
     iq = stanza_create_blocked_list_request(ctx);
     xmpp_stanza_set_id(iq, id);
@@ -135,7 +135,7 @@ blocked_add(char *jid)
     xmpp_stanza_add_child(iq, block);
     xmpp_stanza_release(block);
 
-    iq_id_handler_add(id, _block_add_result_handler, strdup(jid));
+    iq_id_handler_add(id, _block_add_result_handler, free, strdup(jid));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -174,7 +174,7 @@ blocked_remove(char *jid)
     xmpp_stanza_add_child(iq, block);
     xmpp_stanza_release(block);
 
-    iq_id_handler_add(id, _block_remove_result_handler, strdup(jid));
+    iq_id_handler_add(id, _block_remove_result_handler, free, strdup(jid));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c
index 8c859a92..6fbe1903 100644
--- a/src/xmpp/bookmark.c
+++ b/src/xmpp/bookmark.c
@@ -87,7 +87,7 @@ bookmark_request(void)
         bookmark_list = NULL;
     }
 
-    iq_id_handler_add(id, _bookmark_result_id_handler, id);
+    iq_id_handler_add(id, _bookmark_result_id_handler, free, id);
 
     iq = stanza_create_bookmarks_storage_request(ctx);
     xmpp_stanza_set_id(iq, id);
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index c87b45a4..8f49a0d6 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -78,9 +78,15 @@ typedef struct p_room_info_data_t {
 
 typedef struct p_id_handle_t {
     ProfIdCallback func;
+    ProfIdFreeCallback free_func;
     void *userdata;
 } ProfIdHandler;
 
+typedef struct privilege_set_t {
+    char *item;
+    char *privilege;
+} ProfPrivilegeSet;
+
 static int _iq_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
 
 static void _error_handler(xmpp_stanza_t *const stanza);
@@ -113,6 +119,9 @@ static int _caps_response_for_jid_id_handler(xmpp_stanza_t *const stanza, void *
 static int _caps_response_legacy_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
 static int _auto_pong_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
 
+static void _iq_free_room_data(ProfRoomInfoData *roominfo);
+static void _iq_free_affiliation_set(ProfPrivilegeSet *affiliation_set);
+
 // scheduled
 static int _autoping_timed_send(xmpp_conn_t *const conn, void *const userdata);
 
@@ -209,16 +218,27 @@ iq_handlers_init(void)
     }
 
     if (id_handlers) {
+        GList *keys = g_hash_table_get_keys(id_handlers);
+        GList *curr = keys;
+        while (curr) {
+            ProfIdHandler *handler = g_hash_table_lookup(id_handlers, curr->data);
+            if (handler->free_func && handler->userdata) {
+                handler->free_func(handler->userdata);
+            }
+            curr = g_list_next(curr);
+        }
+        g_list_free(keys);
         g_hash_table_destroy(id_handlers);
     }
     id_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
 }
 
 void
-iq_id_handler_add(const char *const id, ProfIdCallback func, void *userdata)
+iq_id_handler_add(const char *const id, ProfIdCallback func, ProfIdFreeCallback free_func, void *userdata)
 {
     ProfIdHandler *handler = malloc(sizeof(ProfIdHandler));
     handler->func = func;
+    handler->free_func = free_func;
     handler->userdata = userdata;
 
     g_hash_table_insert(id_handlers, strdup(id), handler);
@@ -287,7 +307,7 @@ iq_enable_carbons(void)
     xmpp_stanza_t *iq = stanza_enable_carbons(ctx);
     const char *id = xmpp_stanza_get_id(iq);
 
-    iq_id_handler_add(id, _enable_carbons_id_handler, NULL);
+    iq_id_handler_add(id, _enable_carbons_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -300,7 +320,7 @@ iq_disable_carbons(void)
     xmpp_stanza_t *iq = stanza_disable_carbons(ctx);
     const char *id = xmpp_stanza_get_id(iq);
 
-    iq_id_handler_add(id, _disable_carbons_id_handler, NULL);
+    iq_id_handler_add(id, _disable_carbons_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -318,7 +338,8 @@ iq_http_upload_request(HTTPUpload *upload)
     xmpp_ctx_t * const ctx = connection_get_ctx();
     char *id = create_unique_id("http_upload_request");
     xmpp_stanza_t *iq = stanza_create_http_upload_request(ctx, id, jid, upload);
-    iq_id_handler_add(id, _http_upload_response_id_handler, upload);
+    // TODO add free func
+    iq_id_handler_add(id, _http_upload_response_id_handler, NULL, upload);
     free(id);
 
     iq_send_stanza(iq);
@@ -334,7 +355,7 @@ iq_disco_info_request(gchar *jid)
     char *id = create_unique_id("disco_info");
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, jid, NULL);
 
-    iq_id_handler_add(id, _disco_info_response_id_handler, NULL);
+    iq_id_handler_add(id, _disco_info_response_id_handler, NULL, NULL);
 
     free(id);
 
@@ -349,7 +370,7 @@ iq_disco_info_request_onconnect(gchar *jid)
     char *id = create_unique_id("disco_info_onconnect");
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, jid, NULL);
 
-    iq_id_handler_add(id, _disco_info_response_id_handler_onconnect, NULL);
+    iq_id_handler_add(id, _disco_info_response_id_handler_onconnect, NULL, NULL);
 
     free(id);
 
@@ -364,7 +385,7 @@ iq_last_activity_request(gchar *jid)
     char *id = create_unique_id("lastactivity");
     xmpp_stanza_t *iq = stanza_create_last_activity_iq(ctx, id, jid);
 
-    iq_id_handler_add(id, _last_activity_response_id_handler, NULL);
+    iq_id_handler_add(id, _last_activity_response_id_handler, NULL, NULL);
 
     free(id);
 
@@ -383,7 +404,7 @@ iq_room_info_request(const char *const room, gboolean display_result)
     cb_data->room = strdup(room);
     cb_data->display = display_result;
 
-    iq_id_handler_add(id, _room_info_response_id_handler, cb_data);
+    iq_id_handler_add(id, _room_info_response_id_handler, (ProfIdFreeCallback)_iq_free_room_data, cb_data);
 
     free(id);
 
@@ -411,7 +432,7 @@ iq_send_caps_request_for_jid(const char *const to, const char *const id,
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
     g_string_free(node_str, TRUE);
 
-    iq_id_handler_add(id, _caps_response_for_jid_id_handler, strdup(to));
+    iq_id_handler_add(id, _caps_response_for_jid_id_handler, free, strdup(to));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -437,7 +458,7 @@ iq_send_caps_request(const char *const to, const char *const id,
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
     g_string_free(node_str, TRUE);
 
-    iq_id_handler_add(id, _caps_response_id_handler, NULL);
+    iq_id_handler_add(id, _caps_response_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -462,7 +483,7 @@ iq_send_caps_request_legacy(const char *const to, const char *const id,
     g_string_printf(node_str, "%s#%s", node, ver);
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
 
-    iq_id_handler_add(id, _caps_response_legacy_id_handler, node_str->str);
+    iq_id_handler_add(id, _caps_response_legacy_id_handler, g_free, node_str->str);
     g_string_free(node_str, FALSE);
 
     iq_send_stanza(iq);
@@ -494,7 +515,7 @@ iq_send_software_version(const char *const fulljid)
     xmpp_stanza_t *iq = stanza_create_software_version_iq(ctx, fulljid);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _version_result_id_handler, strdup(fulljid));
+    iq_id_handler_add(id, _version_result_id_handler, free, strdup(fulljid));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -516,7 +537,7 @@ iq_destroy_room(const char *const room_jid)
     xmpp_stanza_t *iq = stanza_create_instant_room_destroy_iq(ctx, room_jid);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _destroy_room_result_id_handler, NULL);
+    iq_id_handler_add(id, _destroy_room_result_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -529,7 +550,7 @@ iq_request_room_config_form(const char *const room_jid)
     xmpp_stanza_t *iq = stanza_create_room_config_request_iq(ctx, room_jid);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _room_config_id_handler, NULL);
+    iq_id_handler_add(id, _room_config_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -542,7 +563,7 @@ iq_submit_room_config(const char *const room, DataForm *form)
     xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _room_config_submit_id_handler, NULL);
+    iq_id_handler_add(id, _room_config_submit_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -564,7 +585,7 @@ iq_room_affiliation_list(const char *const room, char *affiliation)
     xmpp_stanza_t *iq = stanza_create_room_affiliation_list_iq(ctx, room, affiliation);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _room_affiliation_list_result_id_handler, strdup(affiliation));
+    iq_id_handler_add(id, _room_affiliation_list_result_id_handler, free, strdup(affiliation));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -577,17 +598,12 @@ iq_room_kick_occupant(const char *const room, const char *const nick, const char
     xmpp_stanza_t *iq = stanza_create_room_kick_iq(ctx, room, nick, reason);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _room_kick_result_id_handler, strdup(nick));
+    iq_id_handler_add(id, _room_kick_result_id_handler, free, strdup(nick));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
 }
 
-struct privilege_set_t {
-    char *item;
-    char *privilege;
-};
-
 void
 iq_room_affiliation_set(const char *const room, const char *const jid, char *affiliation,
     const char *const reason)
@@ -597,11 +613,11 @@ iq_room_affiliation_set(const char *const room, const char *const jid, char *aff
 
     const char *id = xmpp_stanza_get_id(iq);
 
-    struct privilege_set_t *affiliation_set = malloc(sizeof(struct privilege_set_t));
+    ProfPrivilegeSet *affiliation_set = malloc(sizeof(struct privilege_set_t));
     affiliation_set->item = strdup(jid);
     affiliation_set->privilege = strdup(affiliation);
 
-    iq_id_handler_add(id, _room_affiliation_set_result_id_handler, affiliation_set);
+    iq_id_handler_add(id, _room_affiliation_set_result_id_handler, (ProfIdFreeCallback)_iq_free_affiliation_set, affiliation_set);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -616,11 +632,11 @@ iq_room_role_set(const char *const room, const char *const nick, char *role,
 
     const char *id = xmpp_stanza_get_id(iq);
 
-    struct privilege_set_t *role_set = malloc(sizeof(struct privilege_set_t));
+    struct privilege_set_t *role_set = malloc(sizeof(ProfPrivilegeSet));
     role_set->item = strdup(nick);
     role_set->privilege = strdup(role);
 
-    iq_id_handler_add(id, _room_role_set_result_id_handler, role_set);
+    iq_id_handler_add(id, _room_role_set_result_id_handler, (ProfIdFreeCallback)_iq_free_affiliation_set, role_set);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -633,7 +649,7 @@ iq_room_role_list(const char *const room, char *role)
     xmpp_stanza_t *iq = stanza_create_room_role_list_iq(ctx, room, role);
 
     const char *id = xmpp_stanza_get_id(iq);
-    iq_id_handler_add(id, _room_role_list_result_id_handler, strdup(role));
+    iq_id_handler_add(id, _room_role_list_result_id_handler, free, strdup(role));
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -647,7 +663,7 @@ iq_send_ping(const char *const target)
     const char *id = xmpp_stanza_get_id(iq);
 
     GDateTime *now = g_date_time_new_now_local();
-    iq_id_handler_add(id, _manual_pong_id_handler, now);
+    iq_id_handler_add(id, _manual_pong_id_handler, (ProfIdFreeCallback)g_date_time_unref, now);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -961,7 +977,7 @@ _autoping_timed_send(xmpp_conn_t *const conn, void *const userdata)
     log_debug("Autoping: Sending ping request: %s", id);
 
     // add pong handler
-    iq_id_handler_add(id, _auto_pong_id_handler, ctx);
+    iq_id_handler_add(id, _auto_pong_id_handler, NULL, NULL);
 
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
@@ -1426,7 +1442,7 @@ _room_affiliation_set_result_id_handler(xmpp_stanza_t *const stanza, void *const
     const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
     const char *type = xmpp_stanza_get_type(stanza);
     const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
-    struct privilege_set_t *affiliation_set = (struct privilege_set_t *)userdata;
+    ProfPrivilegeSet *affiliation_set = (ProfPrivilegeSet*)userdata;
 
     if (id) {
         log_debug("IQ affiliation set handler fired, id: %s.", id);
@@ -1458,7 +1474,7 @@ _room_role_set_result_id_handler(xmpp_stanza_t *const stanza, void *const userda
     const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
     const char *type = xmpp_stanza_get_type(stanza);
     const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
-    struct privilege_set_t *role_set = (struct privilege_set_t *)userdata;
+    ProfPrivilegeSet *role_set = (ProfPrivilegeSet*)userdata;
 
     if (id) {
         log_debug("IQ role set handler fired, id: %s.", id);
@@ -2052,4 +2068,23 @@ iq_send_stanza(xmpp_stanza_t *const stanza)
         xmpp_send_raw_string(conn, "%s", text);
     }
     xmpp_free(connection_get_ctx(), text);
+
+}
+static void
+_iq_free_room_data(ProfRoomInfoData *roominfo)
+{
+    if (roominfo) {
+        free(roominfo->room);
+        free(roominfo);
+    }
+}
+
+static void
+_iq_free_affiliation_set(ProfPrivilegeSet *affiliation_set)
+{
+    if (affiliation_set) {
+        free(affiliation_set->item);
+        free(affiliation_set->privilege);
+        free(affiliation_set);
+    }
 }
diff --git a/src/xmpp/iq.h b/src/xmpp/iq.h
index 2b7a6c6d..b460003d 100644
--- a/src/xmpp/iq.h
+++ b/src/xmpp/iq.h
@@ -36,10 +36,11 @@
 #define XMPP_IQ_H
 
 typedef int(*ProfIdCallback)(xmpp_stanza_t *const stanza, void *const userdata);
+typedef void(*ProfIdFreeCallback)(void *userdata);
 
 void iq_handlers_init(void);
 void iq_send_stanza(xmpp_stanza_t *const stanza);
-void iq_id_handler_add(const char *const id, ProfIdCallback func, void *userdata);
+void iq_id_handler_add(const char *const id, ProfIdCallback func, ProfIdFreeCallback free_func, void *userdata);
 void iq_disco_info_request_onconnect(gchar *jid);
 void iq_disco_items_request_onconnect(gchar *jid);
 void iq_send_caps_request(const char *const to, const char *const id, const char *const node, const char *const ver);
diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c
index 95d4223e..2420c307 100644
--- a/src/xmpp/roster.c
+++ b/src/xmpp/roster.c
@@ -73,6 +73,7 @@ typedef struct _group_data {
 // id handlers
 static int _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
 static int _group_remove_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
+static void _free_group_data(GroupData *data);
 
 // helper functions
 GSList* _get_groups_from_item(xmpp_stanza_t *item);
@@ -139,7 +140,7 @@ roster_send_add_to_group(const char *const group, PContact contact)
     }
 
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    iq_id_handler_add(unique_id, _group_add_id_handler, data);
+    iq_id_handler_add(unique_id, _group_add_id_handler, (ProfIdFreeCallback)_free_group_data, data);
     xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),
         p_contact_name(contact), new_groups);
     iq_send_stanza(iq);
@@ -153,9 +154,7 @@ _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
     if (userdata) {
         GroupData *data = userdata;
         ui_group_added(data->name, data->group);
-        free(data->name);
-        free(data->group);
-        free(userdata);
+        _free_group_data(data);
     }
     return 0;
 }
@@ -184,7 +183,7 @@ roster_send_remove_from_group(const char *const group, PContact contact)
         data->name = strdup(p_contact_barejid(contact));
     }
 
-    iq_id_handler_add(unique_id, _group_remove_id_handler, data);
+    iq_id_handler_add(unique_id, _group_remove_id_handler, (ProfIdFreeCallback)_free_group_data, data);
     xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),
         p_contact_name(contact), new_groups);
     iq_send_stanza(iq);
@@ -336,3 +335,13 @@ _get_groups_from_item(xmpp_stanza_t *item)
 
     return groups;
 }
+
+static void
+_free_group_data(GroupData *data)
+{
+    if (data) {
+        free(data->group);
+        free(data->name);
+        free(data);
+    }
+}