diff options
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/bookmark.c | 245 | ||||
-rw-r--r-- | src/xmpp/bookmark.h | 22 | ||||
-rw-r--r-- | src/xmpp/capabilities.c | 58 | ||||
-rw-r--r-- | src/xmpp/connection.c | 2 | ||||
-rw-r--r-- | src/xmpp/iq.c | 36 | ||||
-rw-r--r-- | src/xmpp/message.c | 7 | ||||
-rw-r--r-- | src/xmpp/presence.c | 89 | ||||
-rw-r--r-- | src/xmpp/roster.c | 2 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 65 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 6 |
10 files changed, 461 insertions, 71 deletions
diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c new file mode 100644 index 00000000..92e6d7e8 --- /dev/null +++ b/src/xmpp/bookmark.c @@ -0,0 +1,245 @@ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <strophe.h> + +#include "log.h" +#include "muc.h" +#include "ui/ui.h" +#include "xmpp/connection.h" +#include "xmpp/stanza.h" +#include "xmpp/xmpp.h" +#include "xmpp/bookmark.h" + +#define BOOKMARK_TIMEOUT 5000 +/* TODO: replace with a preference */ +#define BOOKMARK_AUTOJOIN_MAX 5 + +static int autojoin_count; + +static Autocomplete bookmark_ac; +static GList *bookmark_list; + +static int _bookmark_handle_result(xmpp_conn_t * const conn, + xmpp_stanza_t * const stanza, void * const userdata); +static int _bookmark_handle_delete(xmpp_conn_t * const conn, + void * const userdata); +static void _bookmark_item_destroy(gpointer item); + +void +bookmark_request(void) +{ + char *id; + xmpp_conn_t *conn = connection_get_conn(); + xmpp_ctx_t *ctx = connection_get_ctx(); + xmpp_stanza_t *iq; + + id = get_unique_id(); + if (!id) { + return; + } + + autojoin_count = 0; + if (bookmark_ac != NULL) { + autocomplete_free(bookmark_ac); + } + bookmark_ac = autocomplete_new(); + if (bookmark_list != NULL) { + g_list_free_full(bookmark_list, _bookmark_item_destroy); + bookmark_list = NULL; + } + + xmpp_timed_handler_add(conn, _bookmark_handle_delete, BOOKMARK_TIMEOUT, id); + xmpp_id_handler_add(conn, _bookmark_handle_result, id, id); + + iq = stanza_create_storage_bookmarks(ctx); + xmpp_stanza_set_id(iq, id); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + +void +bookmark_add(const char *jid, const char *nick, gboolean autojoin) +{ + /* TODO: send request */ + /* TODO: manage bookmark_list */ + + /* this may be command for modifying */ + autocomplete_remove(bookmark_ac, jid); + autocomplete_add(bookmark_ac, strdup(jid)); +} + +void +bookmark_remove(const char *jid, gboolean autojoin) +{ + /* TODO: manage bookmark_list */ + if (autojoin) { + /* TODO: just set autojoin=0 */ + } else { + /* TODO: send request */ + autocomplete_remove(bookmark_ac, jid); + } +} + +const GList * +bookmark_get_list(void) +{ + return bookmark_list; +} + +char * +bookmark_find(char *search_str) +{ + return autocomplete_complete(bookmark_ac, search_str); +} + +void +bookmark_autocomplete_reset(void) +{ + if (bookmark_ac != NULL) { + autocomplete_reset(bookmark_ac); + } +} + +static int +_bookmark_handle_result(xmpp_conn_t * const conn, + xmpp_stanza_t * const stanza, void * const userdata) +{ + xmpp_ctx_t *ctx = connection_get_ctx(); + char *id = (char *)userdata; + xmpp_stanza_t *ptr; + xmpp_stanza_t *nick; + char *name; + char *jid; + char *autojoin; + gboolean autojoin_val; + Jid *my_jid; + Bookmark *item; + + xmpp_timed_handler_delete(conn, _bookmark_handle_delete); + g_free(id); + + name = xmpp_stanza_get_name(stanza); + if (!name || strcmp(name, STANZA_NAME_IQ) != 0) { + return 0; + } + + ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); + if (!ptr) { + return 0; + } + ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE); + if (!ptr) { + return 0; + } + + if (bookmark_ac == NULL) { + bookmark_ac = autocomplete_new(); + } + my_jid = jid_create(jabber_get_fulljid()); + + ptr = xmpp_stanza_get_children(ptr); + while (ptr) { + name = xmpp_stanza_get_name(ptr); + if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) { + ptr = xmpp_stanza_get_next(ptr); + continue; + } + jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID); + if (!jid) { + ptr = xmpp_stanza_get_next(ptr); + continue; + } + + log_debug("Handle bookmark for %s", jid); + + name = NULL; + nick = xmpp_stanza_get_child_by_name(ptr, "nick"); + if (nick) { + char *tmp; + tmp = xmpp_stanza_get_text(nick); + if (tmp) { + name = strdup(tmp); + xmpp_free(ctx, tmp); + } + } + + autojoin = xmpp_stanza_get_attribute(ptr, "autojoin"); + if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) { + autojoin_val = TRUE; + } else { + autojoin_val = FALSE; + } + + autocomplete_add(bookmark_ac, strdup(jid)); + item = malloc(sizeof(*item)); + item->jid = strdup(jid); + item->nick = name; + item->autojoin = autojoin_val; + bookmark_list = g_list_append(bookmark_list, item); + + + /* TODO: preference whether autojoin */ + if (autojoin_val) { + if (autojoin_count < BOOKMARK_AUTOJOIN_MAX) { + Jid *room_jid; + + ++autojoin_count; + + if (name == NULL) { + name = my_jid->localpart; + } + + log_debug("Autojoin %s with nick=%s", jid, name); + room_jid = jid_create_from_bare_and_resource(jid, name); + if (!muc_room_is_active(room_jid)) { + presence_join_room(room_jid); + /* TODO: this should be removed after fixing #195 */ + ui_room_join(room_jid); + } + jid_destroy(room_jid); + } else { + log_debug("Rejected autojoin %s (maximum has been reached)", jid); + } + } + + ptr = xmpp_stanza_get_next(ptr); + } + + jid_destroy(my_jid); + + return 0; +} + +static int +_bookmark_handle_delete(xmpp_conn_t * const conn, + void * const userdata) +{ + char *id = (char *)userdata; + + assert(id != NULL); + + log_debug("Timeout for handler with id=%s", id); + + xmpp_id_handler_delete(conn, _bookmark_handle_result, id); + g_free(id); + + return 0; +} + +static void +_bookmark_item_destroy(gpointer item) +{ + Bookmark *p = (Bookmark *)item; + + if (p == NULL) { + return; + } + + free(p->jid); + free(p->nick); + free(p); +} diff --git a/src/xmpp/bookmark.h b/src/xmpp/bookmark.h new file mode 100644 index 00000000..e15b6eab --- /dev/null +++ b/src/xmpp/bookmark.h @@ -0,0 +1,22 @@ + +#ifndef BOOKMARK_H +#define BOOKMARK_H + +#include <glib.h> + +struct bookmark_t { + char *jid; + char *nick; + gboolean autojoin; +}; + +typedef struct bookmark_t Bookmark; + +void bookmark_request(void); +void bookmark_add(const char *jid, const char *nick, gboolean autojoin); +void bookmark_remove(const char *jid, gboolean autojoin); +const GList *bookmark_get_list(void); +char *bookmark_find(char *search_str); +void bookmark_autocomplete_reset(void); + +#endif diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c index 10aa8a38..2b0a12e5 100644 --- a/src/xmpp/capabilities.c +++ b/src/xmpp/capabilities.c @@ -122,7 +122,7 @@ caps_create_sha1_str(xmpp_stanza_t * const query) GSList *form_names = NULL; DataForm *form = NULL; FormField *field = NULL; - GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)stanza_destroy_form); + GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)stanza_destroy_form); GString *s = g_string_new(""); @@ -134,18 +134,18 @@ caps_create_sha1_str(xmpp_stanza_t * const query) lang = xmpp_stanza_get_attribute(child, "xml:lang"); name = xmpp_stanza_get_attribute(child, "name"); - GString *identity_str = g_string_new(g_strdup(category)); + GString *identity_str = g_string_new(category); g_string_append(identity_str, "/"); if (type != NULL) { - g_string_append(identity_str, g_strdup(type)); + g_string_append(identity_str, type); } g_string_append(identity_str, "/"); if (lang != NULL) { - g_string_append(identity_str, g_strdup(lang)); + g_string_append(identity_str, lang); } g_string_append(identity_str, "/"); if (name != NULL) { - g_string_append(identity_str, g_strdup(name)); + g_string_append(identity_str, name); } g_string_append(identity_str, "<"); identities = g_slist_insert_sorted(identities, g_strdup(identity_str->str), (GCompareFunc)octet_compare); @@ -156,8 +156,8 @@ caps_create_sha1_str(xmpp_stanza_t * const query) } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_X) == 0) { if (strcmp(xmpp_stanza_get_ns(child), STANZA_NS_DATA) == 0) { form = stanza_create_form(child); - form_names = g_slist_insert_sorted(form_names, strdup(form->form_type), (GCompareFunc)octet_compare); - g_hash_table_insert(forms, strdup(form->form_type), form); + form_names = g_slist_insert_sorted(form_names, g_strdup(form->form_type), (GCompareFunc)octet_compare); + g_hash_table_insert(forms, g_strdup(form->form_type), form); } } child = xmpp_stanza_get_next(child); @@ -165,13 +165,13 @@ caps_create_sha1_str(xmpp_stanza_t * const query) GSList *curr = identities; while (curr != NULL) { - g_string_append(s, strdup(curr->data)); + g_string_append(s, curr->data); curr = g_slist_next(curr); } curr = features; while (curr != NULL) { - g_string_append(s, strdup(curr->data)); + g_string_append(s, curr->data); g_string_append(s, "<"); curr = g_slist_next(curr); } @@ -179,17 +179,17 @@ caps_create_sha1_str(xmpp_stanza_t * const query) curr = form_names; while (curr != NULL) { form = g_hash_table_lookup(forms, curr->data); - g_string_append(s, strdup(form->form_type)); + g_string_append(s, form->form_type); g_string_append(s, "<"); GSList *curr_field = form->fields; while (curr_field != NULL) { field = curr_field->data; - g_string_append(s, strdup(field->var)); + g_string_append(s, field->var); g_string_append(s, "<"); GSList *curr_value = field->values; while (curr_value != NULL) { - g_string_append(s, strdup(curr_value->data)); + g_string_append(s, curr_value->data); g_string_append(s, "<"); curr_value = g_slist_next(curr_value); } @@ -215,10 +215,10 @@ caps_create_sha1_str(xmpp_stanza_t * const query) char *result = g_base64_encode(md_value, md_len); g_string_free(s, TRUE); - g_slist_free_full(identities, free); - g_slist_free_full(features, free); - g_slist_free_full(form_names, free); - //g_hash_table_destroy(forms); + g_slist_free_full(identities, g_free); + g_slist_free_full(features, g_free); + g_slist_free_full(form_names, g_free); + g_hash_table_destroy(forms); return result; } @@ -280,13 +280,14 @@ caps_create_query_response_stanza(xmpp_ctx_t * const ctx) xmpp_stanza_add_child(query, feature_version); xmpp_stanza_add_child(query, feature_ping); - xmpp_stanza_release(identity); + xmpp_stanza_release(feature_ping); + xmpp_stanza_release(feature_version); xmpp_stanza_release(feature_muc); - xmpp_stanza_release(feature_discoinfo); xmpp_stanza_release(feature_discoitems); - xmpp_stanza_release(feature_caps); - xmpp_stanza_release(feature_version); + xmpp_stanza_release(feature_discoinfo); xmpp_stanza_release(feature_chatstates); + xmpp_stanza_release(feature_caps); + xmpp_stanza_release(identity); return query; } @@ -301,17 +302,16 @@ static void _caps_destroy(Capabilities *caps) { if (caps != NULL) { - FREE_SET_NULL(caps->category); - FREE_SET_NULL(caps->type); - FREE_SET_NULL(caps->name); - FREE_SET_NULL(caps->software); - FREE_SET_NULL(caps->software_version); - FREE_SET_NULL(caps->os); - FREE_SET_NULL(caps->os_version); + free(caps->category); + free(caps->type); + free(caps->name); + free(caps->software); + free(caps->software_version); + free(caps->os); + free(caps->os_version); if (caps->features != NULL) { g_slist_free_full(caps->features, free); - caps->features = NULL; } - FREE_SET_NULL(caps); + free(caps); } } diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 85ddfa45..5040aa91 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -33,6 +33,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "xmpp/bookmark.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" #include "xmpp/iq.h" @@ -494,6 +495,7 @@ _connection_handler(xmpp_conn_t * const conn, } roster_request(); + bookmark_request(); jabber_conn.conn_status = JABBER_CONNECTED; if (prefs_get_reconnect() != 0) { diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 48b561f0..5de84056 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -247,6 +247,12 @@ _iq_handle_version_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, xmpp_send(conn, response); + g_free(version_str); + xmpp_stanza_release(name_txt); + xmpp_stanza_release(version_txt); + xmpp_stanza_release(name); + xmpp_stanza_release(version); + xmpp_stanza_release(query); xmpp_stanza_release(response); } @@ -302,6 +308,7 @@ _iq_handle_discoinfo_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, xmpp_stanza_add_child(response, query); xmpp_send(conn, response); + xmpp_stanza_release(query); xmpp_stanza_release(response); } @@ -312,10 +319,10 @@ static void _identity_destroy(DiscoIdentity *identity) { if (identity != NULL) { - FREE_SET_NULL(identity->name); - FREE_SET_NULL(identity->type); - FREE_SET_NULL(identity->category); - FREE_SET_NULL(identity); + free(identity->name); + free(identity->type); + free(identity->category); + free(identity); } } @@ -323,9 +330,9 @@ static void _item_destroy(DiscoItem *item) { if (item != NULL) { - FREE_SET_NULL(item->jid); - FREE_SET_NULL(item->name); - FREE_SET_NULL(item); + free(item->jid); + free(item->name); + free(item); } } @@ -411,12 +418,13 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan log_info("Generated sha-1 does not match given:"); log_info("Generated : %s", generated_sha1); log_info("Given : %s", given_sha1); - FREE_SET_NULL(generated_sha1); + g_free(generated_sha1); g_strfreev(split); + free(caps_key); return 1; } - FREE_SET_NULL(generated_sha1); + g_free(generated_sha1); g_strfreev(split); // non supported hash, or legacy caps @@ -429,14 +437,12 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan // already cached if (caps_contains(caps_key)) { log_info("Client info already cached."); + free(caps_key); return 1; } log_debug("Client info not cached"); - DataForm *form = NULL; - FormField *formField = NULL; - const char *category = NULL; const char *type = NULL; const char *name = NULL; @@ -455,7 +461,8 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); if (softwareinfo != NULL) { - form = stanza_create_form(softwareinfo); + DataForm *form = stanza_create_form(softwareinfo); + FormField *formField = NULL; if (g_strcmp0(form->form_type, STANZA_DATAFORM_SOFTWARE) == 0) { GSList *field = form->fields; @@ -475,6 +482,8 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan field = g_slist_next(field); } } + + stanza_destroy_form(form); } xmpp_stanza_t *child = xmpp_stanza_get_children(query); @@ -489,7 +498,6 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan caps_add(caps_key, category, type, name, software, software_version, os, os_version, features); - //stanza_destroy_form(form); free(caps_key); } diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 29d11958..19b4df49 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -212,6 +212,9 @@ _conference_message_handler(xmpp_conn_t * const conn, } Jid *jidp = jid_create(invitor_jid); + if (jidp == NULL) { + return 1; + } invitor = jidp->barejid; xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(invite, STANZA_NAME_REASON); @@ -233,6 +236,9 @@ _conference_message_handler(xmpp_conn_t * const conn, } Jid *jidp = jid_create(from); + if (jidp == NULL) { + return 1; + } invitor = jidp->barejid; reason = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_REASON); @@ -274,6 +280,7 @@ _groupchat_message_handler(xmpp_conn_t * const conn, message = xmpp_stanza_get_text(subject); if (message != NULL) { prof_handle_room_subject(jid->barejid, message); + xmpp_free(ctx, message); } jid_destroy(jid); diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index c05ba198..ec439871 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -156,14 +156,23 @@ presence_sub_request_find(char * search_str) gboolean presence_sub_request_exists(const char * const bare_jid) { - GSList *requests = autocomplete_get_list(sub_requests_ac); + gboolean result = FALSE; + GSList *requests_p = autocomplete_get_list(sub_requests_ac); + GSList *requests = requests_p; + while (requests != NULL) { if (strcmp(requests->data, bare_jid) == 0) { - return TRUE; + result = TRUE; + break; } requests = g_slist_next(requests); } - return FALSE; + + if (requests_p != NULL) { + g_slist_free_full(requests_p, free); + } + + return result; } void @@ -220,20 +229,28 @@ presence_update(const resource_presence_t presence_type, const char * const msg, static void _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence) { - GList *rooms = muc_get_active_room_list(); + GList *rooms_p = muc_get_active_room_list(); + GList *rooms = rooms_p; + while (rooms != NULL) { const char *room = rooms->data; const char *nick = muc_get_room_nick(room); - char *full_room_jid = create_fulljid(room, nick); - xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, full_room_jid); - log_debug("Sending presence to room: %s", full_room_jid); - xmpp_send(conn, presence); - free(full_room_jid); + if (nick != NULL) { + char *full_room_jid = create_fulljid(room, nick); + + xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, full_room_jid); + log_debug("Sending presence to room: %s", full_room_jid); + xmpp_send(conn, presence); + free(full_room_jid); + } rooms = g_list_next(rooms); } - g_list_free(rooms); + + if (rooms_p != NULL) { + g_list_free(rooms_p); + } } void @@ -347,9 +364,13 @@ _subscribe_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - Jid *from_jid = jid_create(from); log_debug("Subscribe presence handler fired for %s", from); + Jid *from_jid = jid_create(from); + if (from_jid == NULL) { + return 1; + } + prof_handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); autocomplete_add(sub_requests_ac, strdup(from_jid->barejid)); @@ -368,6 +389,11 @@ _unavailable_handler(xmpp_conn_t * const conn, Jid *my_jid = jid_create(jid); Jid *from_jid = jid_create(from); + if (my_jid == NULL || from_jid == NULL) { + jid_destroy(my_jid); + jid_destroy(from_jid); + return 1; + } char *status_str = stanza_get_status(stanza, NULL); @@ -385,7 +411,7 @@ _unavailable_handler(xmpp_conn_t * const conn, } } - FREE_SET_NULL(status_str); + free(status_str); jid_destroy(my_jid); jid_destroy(from_jid); @@ -420,6 +446,11 @@ _available_handler(xmpp_conn_t * const conn, Jid *my_jid = jid_create(jid); Jid *from_jid = jid_create(from); + if (my_jid == NULL || from_jid == NULL) { + jid_destroy(my_jid); + jid_destroy(from_jid); + return 1; + } char *show_str = stanza_get_show(stanza, "online"); char *status_str = stanza_get_status(stanza, NULL); @@ -462,7 +493,7 @@ _available_handler(xmpp_conn_t * const conn, } // self presence - if (strcmp(my_jid->barejid, from_jid->barejid) ==0) { + if (strcmp(my_jid->barejid, from_jid->barejid) == 0) { connection_add_available_resource(resource); // contact presence @@ -471,8 +502,9 @@ _available_handler(xmpp_conn_t * const conn, last_activity); } - FREE_SET_NULL(status_str); - FREE_SET_NULL(show_str); + free(caps_key); + free(status_str); + free(show_str); jid_destroy(my_jid); jid_destroy(from_jid); @@ -515,6 +547,10 @@ _get_caps_key(xmpp_stanza_t * const stanza) log_debug("Presence contains capabilities."); + if (node == NULL) { + return NULL; + } + // xep-0115 if ((hash_type != NULL) && (strcmp(hash_type, "sha-1") == 0)) { log_debug("Hash type %s supported.", hash_type); @@ -544,6 +580,8 @@ _get_caps_key(xmpp_stanza_t * const stanza) g_string_free(id_str, TRUE); } + g_free(node); + return caps_key; } @@ -556,10 +594,11 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } - const char *jid = xmpp_conn_get_jid(conn); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - Jid *my_jid = jid_create(jid); Jid *from_jid = jid_create(from); + if (from_jid == NULL || from_jid->resourcepart == NULL) { + return 1; + } char *room = from_jid->barejid; char *nick = from_jid->resourcepart; @@ -592,7 +631,7 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // handle presence from room members } else { char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); - char *show_str, *status_str; + char *status_str; char *caps_key = NULL; if (stanza_contains_caps(stanza)) { @@ -608,12 +647,15 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // handle nickname change if (stanza_is_room_nick_change(stanza)) { char *new_nick = stanza_get_new_nick(stanza); - muc_set_roster_pending_nick_change(room, new_nick, nick); + if (new_nick != NULL) { + muc_set_roster_pending_nick_change(room, new_nick, nick); + free(new_nick); + } } else { prof_handle_room_member_offline(room, nick, "offline", status_str); } } else { - show_str = stanza_get_show(stanza, "online"); + char *show_str = stanza_get_show(stanza, "online"); if (!muc_get_roster_received(room)) { muc_add_to_roster(room, nick, show_str, status_str, caps_key); } else { @@ -622,6 +664,7 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (old_nick != NULL) { muc_add_to_roster(room, nick, show_str, status_str, caps_key); prof_handle_room_member_nick_change(room, old_nick, nick); + free(old_nick); } else { if (!muc_nick_in_roster(room, nick)) { prof_handle_room_member_online(room, nick, show_str, status_str, caps_key); @@ -631,13 +674,13 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } } - FREE_SET_NULL(show_str); + free(show_str); } - FREE_SET_NULL(status_str); + free(status_str); + free(caps_key); } - jid_destroy(my_jid); jid_destroy(from_jid); return 1; diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index ed72d502..b31a2725 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -567,7 +567,7 @@ _roster_handle_push(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, while (resources != NULL) { GString *fulljid = g_string_new(strdup(barejid)); g_string_append(fulljid, "/"); - g_string_append(fulljid, strdup(resources->data)); + g_string_append(fulljid, resources->data); autocomplete_remove(fulljid_ac, fulljid->str); g_string_free(fulljid, TRUE); resources = g_list_next(resources); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index e470c3b0..7d7a0949 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -35,6 +35,63 @@ static int _field_compare(FormField *f1, FormField *f2); +#if 0 +xmpp_stanza_t * +stanza_create_storage_bookmarks(xmpp_ctx_t *ctx) +{ + xmpp_stanza_t *iq, *pubsub, *items; + + /* TODO: check pointers for NULL */ + iq = xmpp_stanza_new(ctx); + pubsub = xmpp_stanza_new(ctx); + items = xmpp_stanza_new(ctx); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_GET); + + xmpp_stanza_set_name(pubsub, STANZA_NAME_PUBSUB); + xmpp_stanza_set_ns(pubsub, STANZA_NS_PUBSUB); + + xmpp_stanza_set_name(items, STANZA_NAME_ITEMS); + xmpp_stanza_set_attribute(items, "node", "storage:bookmarks"); + + xmpp_stanza_add_child(pubsub, items); + xmpp_stanza_add_child(iq, pubsub); + xmpp_stanza_release(items); + xmpp_stanza_release(pubsub); + + return iq; +} +#endif + +xmpp_stanza_t * +stanza_create_storage_bookmarks(xmpp_ctx_t *ctx) +{ + xmpp_stanza_t *iq, *query, *storage; + + /* TODO: check pointers for NULL */ + iq = xmpp_stanza_new(ctx); + query = xmpp_stanza_new(ctx); + storage = xmpp_stanza_new(ctx); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_GET); + xmpp_stanza_set_ns(iq, "jabber:client"); + + xmpp_stanza_set_name(query, STANZA_NAME_QUERY); + xmpp_stanza_set_ns(query, "jabber:iq:private"); + + xmpp_stanza_set_name(storage, STANZA_NAME_STORAGE); + xmpp_stanza_set_ns(storage, "storage:bookmarks"); + + xmpp_stanza_add_child(query, storage); + xmpp_stanza_add_child(iq, query); + xmpp_stanza_release(storage); + xmpp_stanza_release(query); + + return iq; +} + xmpp_stanza_t * stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const recipient, const char * const state) @@ -85,7 +142,7 @@ stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, xmpp_stanza_set_name(chat_state, state); xmpp_stanza_set_ns(chat_state, STANZA_NS_CHATSTATES); xmpp_stanza_add_child(msg, chat_state); - xmpp_stanza_release(chat_state); + xmpp_stanza_release(chat_state); } return msg; @@ -815,12 +872,11 @@ void stanza_destroy_form(DataForm *form) { if (form != NULL) { - FREE_SET_NULL(form->form_type); if (form->fields != NULL) { GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; - FREE_SET_NULL(field->var); + free(field->var); if ((field->values) != NULL) { g_slist_free_full(field->values, free); } @@ -829,6 +885,7 @@ stanza_destroy_form(DataForm *form) g_slist_free_full(form->fields, free); } + free(form->form_type); free(form); } } @@ -916,7 +973,7 @@ stanza_attach_caps(xmpp_ctx_t * const ctx, xmpp_stanza_t * const presence) xmpp_stanza_add_child(presence, caps); xmpp_stanza_release(caps); xmpp_stanza_release(query); - FREE_SET_NULL(sha1); + g_free(sha1); } const char * diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index ad777f24..108b0806 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -52,6 +52,9 @@ #define STANZA_NAME_INVITE "invite" #define STANZA_NAME_REASON "reason" #define STANZA_NAME_GROUP "group" +#define STANZA_NAME_PUBSUB "pubsub" +#define STANZA_NAME_STORAGE "storage" +#define STANZA_NAME_CONFERENCE "conference" #define STANZA_TYPE_CHAT "chat" #define STANZA_TYPE_GROUPCHAT "groupchat" @@ -100,6 +103,7 @@ #define STANZA_NS_VERSION "jabber:iq:version" #define STANZA_NS_CONFERENCE "jabber:x:conference" #define STANZA_NS_CAPTCHA "urn:xmpp:captcha" +#define STANZA_NS_PUBSUB "http://jabber.org/protocol/pubsub" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -113,6 +117,8 @@ typedef struct data_form_t { GSList *fields; } DataForm; +xmpp_stanza_t* stanza_create_storage_bookmarks(xmpp_ctx_t *ctx); + xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const recipient, const char * const state); |