diff options
author | Will Song <incertia9474@gmail.com> | 2015-05-29 19:53:37 -0500 |
---|---|---|
committer | Will Song <incertia9474@gmail.com> | 2015-05-29 19:53:37 -0500 |
commit | 9463c6719036957c8468e1363a48afbfe751fd3e (patch) | |
tree | aed6ccd050fc182a0d4d111bef6f743d28a42a73 /src/xmpp | |
parent | 7f436d614b11d72893d856f1c3d817ab34b0b9eb (diff) | |
parent | 304e08a9c0bfa27ed84dc1ff0a2e2d32b36529f8 (diff) | |
download | profani-tty-9463c6719036957c8468e1363a48afbfe751fd3e.tar.gz |
fix conflicts
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/bookmark.c | 26 | ||||
-rw-r--r-- | src/xmpp/bookmark.h | 2 | ||||
-rw-r--r-- | src/xmpp/capabilities.c | 46 | ||||
-rw-r--r-- | src/xmpp/capabilities.h | 2 | ||||
-rw-r--r-- | src/xmpp/connection.c | 43 | ||||
-rw-r--r-- | src/xmpp/connection.h | 2 | ||||
-rw-r--r-- | src/xmpp/form.c | 4 | ||||
-rw-r--r-- | src/xmpp/form.h | 2 | ||||
-rw-r--r-- | src/xmpp/iq.c | 407 | ||||
-rw-r--r-- | src/xmpp/iq.h | 2 | ||||
-rw-r--r-- | src/xmpp/message.c | 559 | ||||
-rw-r--r-- | src/xmpp/message.h | 2 | ||||
-rw-r--r-- | src/xmpp/presence.c | 107 | ||||
-rw-r--r-- | src/xmpp/presence.h | 2 | ||||
-rw-r--r-- | src/xmpp/roster.c | 109 | ||||
-rw-r--r-- | src/xmpp/roster.h | 2 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 200 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 23 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 11 |
19 files changed, 1035 insertions, 516 deletions
diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c index 94adabea..68e66569 100644 --- a/src/xmpp/bookmark.c +++ b/src/xmpp/bookmark.c @@ -1,7 +1,7 @@ /* * bookmark.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -42,7 +42,7 @@ #include "common.h" #include "log.h" #include "muc.h" -#include "server_events.h" +#include "event/server_events.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" #include "xmpp/xmpp.h" @@ -74,7 +74,7 @@ bookmark_request(void) autocomplete_free(bookmark_ac); bookmark_ac = autocomplete_new(); - if (bookmark_list != NULL) { + if (bookmark_list) { g_list_free_full(bookmark_list, _bookmark_item_destroy); bookmark_list = NULL; } @@ -96,12 +96,12 @@ bookmark_add(const char *jid, const char *nick, const char *password, const char } else { Bookmark *item = malloc(sizeof(*item)); item->jid = strdup(jid); - if (nick != NULL) { + if (nick) { item->nick = strdup(nick); } else { item->nick = NULL; } - if (password != NULL) { + if (password) { item->password = strdup(password); } else { item->password = NULL; @@ -136,15 +136,15 @@ bookmark_update(const char *jid, const char *nick, const char *password, const c return FALSE; } else { Bookmark *bm = found->data; - if (nick != NULL) { + if (nick) { free(bm->nick); bm->nick = strdup(nick); } - if (password != NULL) { + if (password) { free(bm->password); bm->password = strdup(password); } - if (autojoin_str != NULL) { + if (autojoin_str) { if (g_strcmp0(autojoin_str, "on") == 0) { bm->autojoin = TRUE; } else if (g_strcmp0(autojoin_str, "off") == 0) { @@ -228,7 +228,7 @@ bookmark_find(const char * const search_str) void bookmark_autocomplete_reset(void) { - if (bookmark_ac != NULL) { + if (bookmark_ac) { autocomplete_reset(bookmark_ac); } } @@ -413,14 +413,14 @@ _send_bookmarks(void) xmpp_stanza_set_ns(storage, "storage:bookmarks"); GList *curr = bookmark_list; - while (curr != NULL) { + while (curr) { Bookmark *bookmark = curr->data; xmpp_stanza_t *conference = xmpp_stanza_new(ctx); xmpp_stanza_set_name(conference, STANZA_NAME_CONFERENCE); xmpp_stanza_set_attribute(conference, STANZA_ATTR_JID, bookmark->jid); Jid *jidp = jid_create(bookmark->jid); - if (jidp->localpart != NULL) { + if (jidp->localpart) { xmpp_stanza_set_attribute(conference, STANZA_ATTR_NAME, jidp->localpart); } jid_destroy(jidp); @@ -431,7 +431,7 @@ _send_bookmarks(void) xmpp_stanza_set_attribute(conference, STANZA_ATTR_AUTOJOIN, "false"); } - if (bookmark->nick != NULL) { + if (bookmark->nick) { xmpp_stanza_t *nick_st = xmpp_stanza_new(ctx); xmpp_stanza_set_name(nick_st, STANZA_NAME_NICK); xmpp_stanza_t *nick_text = xmpp_stanza_new(ctx); @@ -443,7 +443,7 @@ _send_bookmarks(void) xmpp_stanza_release(nick_st); } - if (bookmark->password != NULL) { + if (bookmark->password) { xmpp_stanza_t *password_st = xmpp_stanza_new(ctx); xmpp_stanza_set_name(password_st, STANZA_NAME_PASSWORD); xmpp_stanza_t *password_text = xmpp_stanza_new(ctx); diff --git a/src/xmpp/bookmark.h b/src/xmpp/bookmark.h index f9392182..c8de8147 100644 --- a/src/xmpp/bookmark.h +++ b/src/xmpp/bookmark.h @@ -1,7 +1,7 @@ /* * bookmark.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c index 164313e1..56475da1 100644 --- a/src/xmpp/capabilities.c +++ b/src/xmpp/capabilities.c @@ -1,7 +1,7 @@ /* * capabilities.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -154,56 +154,56 @@ _caps_by_ver(const char * const ver) char *category = g_key_file_get_string(cache, ver, "category", NULL); if (category) { - new_caps->category = strdup(category); + new_caps->category = category; } else { new_caps->category = NULL; } char *type = g_key_file_get_string(cache, ver, "type", NULL); if (type) { - new_caps->type = strdup(type); + new_caps->type = type; } else { new_caps->type = NULL; } char *name = g_key_file_get_string(cache, ver, "name", NULL); if (name) { - new_caps->name = strdup(name); + new_caps->name = name; } else { new_caps->name = NULL; } char *software = g_key_file_get_string(cache, ver, "software", NULL); if (software) { - new_caps->software = strdup(software); + new_caps->software = software; } else { new_caps->software = NULL; } char *software_version = g_key_file_get_string(cache, ver, "software_version", NULL); if (software_version) { - new_caps->software_version = strdup(software_version); + new_caps->software_version = software_version; } else { new_caps->software_version = NULL; } char *os = g_key_file_get_string(cache, ver, "os", NULL); if (os) { - new_caps->os = strdup(os); + new_caps->os = os; } else { new_caps->os = NULL; } char *os_version = g_key_file_get_string(cache, ver, "os_version", NULL); if (os_version) { - new_caps->os_version = strdup(os_version); + new_caps->os_version = os_version; } else { new_caps->os_version = NULL; } gsize features_len = 0; gchar **features = g_key_file_get_string_list(cache, ver, "features", &features_len, NULL); - if (features != NULL && features_len > 0) { + if (features && features_len > 0) { GSList *features_list = NULL; int i; for (i = 0; i < features_len; i++) { @@ -395,16 +395,16 @@ caps_create(xmpp_stanza_t *query) GSList *features = NULL; xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); - if (softwareinfo != NULL) { + if (softwareinfo) { DataForm *form = form_create(softwareinfo); FormField *formField = NULL; char *form_type = form_get_form_type_field(form); if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) { GSList *field = form->fields; - while (field != NULL) { + while (field) { formField = field->data; - if (formField->values != NULL) { + if (formField->values) { if (strcmp(formField->var, "software") == 0) { software = strdup(formField->values->data); } else if (strcmp(formField->var, "software_version") == 0) { @@ -424,7 +424,7 @@ caps_create(xmpp_stanza_t *query) xmpp_stanza_t *child = xmpp_stanza_get_children(query); GSList *identity_stanzas = NULL; - while (child != NULL) { + while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) { features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var"))); } @@ -490,42 +490,42 @@ caps_create(xmpp_stanza_t *query) Capabilities *new_caps = malloc(sizeof(struct capabilities_t)); - if (category != NULL) { + if (category) { new_caps->category = strdup(category); } else { new_caps->category = NULL; } - if (type != NULL) { + if (type) { new_caps->type = strdup(type); } else { new_caps->type = NULL; } - if (name != NULL) { + if (name) { new_caps->name = strdup(name); } else { new_caps->name = NULL; } - if (software != NULL) { + if (software) { new_caps->software = software; } else { new_caps->software = NULL; } - if (software_version != NULL) { + if (software_version) { new_caps->software_version = software_version; } else { new_caps->software_version = NULL; } - if (os != NULL) { + if (os) { new_caps->os = os; } else { new_caps->os = NULL; } - if (os_version != NULL) { + if (os_version) { new_caps->os_version = os_version; } else { new_caps->os_version = NULL; } - if (features != NULL) { + if (features) { new_caps->features = features; } else { new_caps->features = NULL; @@ -635,7 +635,7 @@ caps_close(void) void caps_destroy(Capabilities *caps) { - if (caps != NULL) { + if (caps) { free(caps->category); free(caps->type); free(caps->name); @@ -643,7 +643,7 @@ caps_destroy(Capabilities *caps) free(caps->software_version); free(caps->os); free(caps->os_version); - if (caps->features != NULL) { + if (caps->features) { g_slist_free_full(caps->features, free); } free(caps); diff --git a/src/xmpp/capabilities.h b/src/xmpp/capabilities.h index 692ac49d..85f1d989 100644 --- a/src/xmpp/capabilities.h +++ b/src/xmpp/capabilities.h @@ -1,7 +1,7 @@ /* * capabilities.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 915525e4..70d49b7c 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -1,7 +1,7 @@ /* * connection.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -45,7 +45,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" -#include "server_events.h" +#include "event/server_events.h" #include "xmpp/bookmark.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" @@ -129,11 +129,11 @@ jabber_connect_with_account(const ProfAccount * const account) log_info("Connecting using account: %s", account->name); // save account name and password for reconnect - if (saved_account.name != NULL) { + if (saved_account.name) { free(saved_account.name); } saved_account.name = strdup(account->name); - if (saved_account.passwd != NULL) { + if (saved_account.passwd) { free(saved_account.passwd); } saved_account.passwd = strdup(account->password); @@ -157,7 +157,7 @@ jabber_connect_with_details(const char * const jid, // save details for reconnect, remember name for account creating on success saved_details.name = strdup(jid); saved_details.passwd = strdup(passwd); - if (altdomain != NULL) { + if (altdomain) { saved_details.altdomain = strdup(altdomain); } else { saved_details.altdomain = NULL; @@ -199,11 +199,11 @@ jabber_disconnect(void) _connection_free_saved_account(); _connection_free_saved_details(); _connection_free_session_data(); - if (jabber_conn.conn != NULL) { + if (jabber_conn.conn) { xmpp_conn_release(jabber_conn.conn); jabber_conn.conn = NULL; } - if (jabber_conn.ctx != NULL) { + if (jabber_conn.ctx) { xmpp_ctx_free(jabber_conn.ctx); jabber_conn.ctx = NULL; } @@ -238,7 +238,7 @@ jabber_process_events(void) break; case JABBER_DISCONNECTED: reconnect_sec = prefs_get_reconnect(); - if ((reconnect_sec != 0) && (reconnect_timer != NULL)) { + if ((reconnect_sec != 0) && reconnect_timer) { int elapsed_sec = g_timer_elapsed(reconnect_timer, NULL); if (elapsed_sec > reconnect_sec) { _jabber_reconnect(); @@ -302,7 +302,7 @@ void connection_set_presence_message(const char * const message) { FREE_SET_NULL(jabber_conn.presence_message); - if (message != NULL) { + if (message) { jabber_conn.presence_message = strdup(message); } } @@ -371,15 +371,15 @@ _jabber_connect(const char * const fulljid, const char * const passwd, jid_destroy(jid); log_info("Connecting as %s", fulljid); - if (jabber_conn.log != NULL) { + if (jabber_conn.log) { free(jabber_conn.log); } jabber_conn.log = _xmpp_get_file_logger(); - if (jabber_conn.conn != NULL) { + if (jabber_conn.conn) { xmpp_conn_release(jabber_conn.conn); } - if (jabber_conn.ctx != NULL) { + if (jabber_conn.ctx) { xmpp_ctx_free(jabber_conn.ctx); } jabber_conn.ctx = xmpp_ctx_new(NULL, jabber_conn.log); @@ -436,9 +436,9 @@ _connection_handler(xmpp_conn_t * const conn, log_debug("Connection handler: XMPP_CONN_CONNECT"); // logged in with account - if (saved_account.name != NULL) { + if (saved_account.name) { log_debug("Connection handler: logged in with account name: %s", saved_account.name); - handle_login_account_success(saved_account.name); + sv_ev_login_account_success(saved_account.name); // logged in without account, use details to create new account } else { @@ -446,7 +446,7 @@ _connection_handler(xmpp_conn_t * const conn, accounts_add(saved_details.name, saved_details.altdomain, saved_details.port); accounts_set_jid(saved_details.name, saved_details.jid); - handle_login_account_success(saved_details.name); + sv_ev_login_account_success(saved_details.name); saved_account.name = strdup(saved_details.name); saved_account.passwd = strdup(saved_details.passwd); @@ -466,10 +466,15 @@ _connection_handler(xmpp_conn_t * const conn, roster_request(); bookmark_request(); + + if (prefs_get_boolean(PREF_CARBONS)){ + iq_enable_carbons(); + } + jabber_conn.conn_status = JABBER_CONNECTED; if (prefs_get_reconnect() != 0) { - if (reconnect_timer != NULL) { + if (reconnect_timer) { g_timer_destroy(reconnect_timer); reconnect_timer = NULL; } @@ -481,7 +486,7 @@ _connection_handler(xmpp_conn_t * const conn, // lost connection for unknown reason if (jabber_conn.conn_status == JABBER_CONNECTED) { log_debug("Connection handler: Lost connection for unknown reason"); - handle_lost_connection(); + sv_ev_lost_connection(); if (prefs_get_reconnect() != 0) { assert(reconnect_timer == NULL); reconnect_timer = g_timer_new(); @@ -498,7 +503,7 @@ _connection_handler(xmpp_conn_t * const conn, log_debug("Connection handler: Login failed"); if (reconnect_timer == NULL) { log_debug("Connection handler: No reconnect timer"); - handle_failed_login(); + sv_ev_failed_login(); _connection_free_saved_account(); _connection_free_saved_details(); _connection_free_session_data(); @@ -558,7 +563,7 @@ _xmpp_file_logger(void * const userdata, const xmpp_log_level_t level, log_level_t prof_level = _get_log_level(level); log_msg(prof_level, area, msg); if ((g_strcmp0(area, "xmpp") == 0) || (g_strcmp0(area, "conn")) == 0) { - handle_xmpp_stanza(msg); + sv_ev_xmpp_stanza(msg); } } diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index f9e2cf22..63f7cde0 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -1,7 +1,7 @@ /* * connection.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/form.c b/src/xmpp/form.c index 1facc754..e6213b64 100644 --- a/src/xmpp/form.c +++ b/src/xmpp/form.c @@ -1,7 +1,7 @@ /* * form.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -211,7 +211,7 @@ form_create(xmpp_stanza_t * const form_stanza) field->var = _get_attr(field_stanza, "var"); - if (field->type_t != FIELD_HIDDEN && field->var != NULL) { + if (field->type_t != FIELD_HIDDEN && field->var) { GString *tag = g_string_new(""); g_string_printf(tag, "field%d", tag_num++); g_hash_table_insert(form->var_to_tag, strdup(field->var), strdup(tag->str)); diff --git a/src/xmpp/form.h b/src/xmpp/form.h index fa14e1c5..86cd4b7b 100644 --- a/src/xmpp/form.h +++ b/src/xmpp/form.h @@ -1,7 +1,7 @@ /* * form.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 7fedf0ed..18abad36 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1,7 +1,7 @@ /* * iq.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -47,8 +47,9 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "ui/ui.h" #include "config/preferences.h" -#include "server_events.h" +#include "event/server_events.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" @@ -58,48 +59,35 @@ #define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_IQ, type, ctx) -static int _error_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _ping_get_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _version_get_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _disco_info_get_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _disco_info_response_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _version_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _disco_items_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _disco_items_get_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _destroy_room_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_config_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_config_submit_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_affiliation_list_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_affiliation_set_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_role_set_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_role_list_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _room_kick_result_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _manual_pong_handler(xmpp_conn_t *const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _ping_timed_handler(xmpp_conn_t * const conn, - void * const userdata); -static int _caps_response_handler(xmpp_conn_t *const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _caps_response_handler_for_jid(xmpp_conn_t *const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _caps_response_handler_legacy(xmpp_conn_t *const conn, - xmpp_stanza_t * const stanza, void * const userdata); +typedef struct p_room_info_data_t { + char *room; + gboolean display; +} ProfRoomInfoData; + +static int _error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _destroy_room_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_affiliation_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_affiliation_set_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_role_set_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_role_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _enable_carbons_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _disable_carbons_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _ping_timed_handler(xmpp_conn_t * const conn, void * const userdata); +static int _caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata); void iq_add_handlers(void) @@ -153,6 +141,34 @@ iq_room_list_request(gchar *conferencejid) } void +iq_enable_carbons() +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_enable_carbons(ctx); + char *id = xmpp_stanza_get_id(iq); + + xmpp_id_handler_add(conn, _enable_carbons_handler, id, NULL); + + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + +void +iq_disable_carbons() +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_disable_carbons(ctx); + char *id = xmpp_stanza_get_id(iq); + + xmpp_id_handler_add(conn, _disable_carbons_handler, id, NULL); + + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + +void iq_disco_info_request(gchar *jid) { xmpp_conn_t * const conn = connection_get_conn(); @@ -169,14 +185,18 @@ iq_disco_info_request(gchar *jid) } void -iq_room_info_request(gchar *room) +iq_room_info_request(const char * const room, gboolean display_result) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); char *id = create_unique_id("room_disco_info"); xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, room, NULL); - xmpp_id_handler_add(conn, _disco_info_response_handler, id, room); + ProfRoomInfoData *cb_data = malloc(sizeof(ProfRoomInfoData)); + cb_data->room = strdup(room); + cb_data->display = display_result; + + xmpp_id_handler_add(conn, _room_info_response_handler, id, cb_data); free(id); @@ -456,7 +476,7 @@ _error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); char *error_msg = stanza_get_error_message(stanza); - if (id != NULL) { + if (id) { log_debug("IQ error handler fired, id: %s, error: %s", id, error_msg); log_error("IQ error received, id: %s, error: %s", id, error_msg); } else { @@ -476,13 +496,13 @@ _pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, char *id = xmpp_stanza_get_id(stanza); char *type = xmpp_stanza_get_type(stanza); - if (id != NULL) { + if (id) { log_debug("IQ pong handler fired, id: %s.", id); } else { log_debug("IQ pong handler fired."); } - if (id != NULL && type != NULL) { + if (id && type) { // show warning if error if (strcmp(type, STANZA_TYPE_ERROR) == 0) { char *error_msg = stanza_get_error_message(stanza); @@ -491,12 +511,13 @@ _pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, // turn off autoping if error type is 'cancel' xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); - if (error != NULL) { + if (error) { char *errtype = xmpp_stanza_get_type(error); - if (errtype != NULL) { + if (errtype) { if (strcmp(errtype, "cancel") == 0) { log_warning("Server ping (id=%s) error type 'cancel', disabling autoping.", id); - handle_autoping_cancel(); + prefs_set_autoping(0); + cons_show_error("Server ping not supported, autoping disabled."); xmpp_timed_handler_delete(conn, _ping_timed_handler); } } @@ -586,12 +607,14 @@ static int _caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata) { + char *jid = (char *)userdata; const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); char *type = xmpp_stanza_get_type(stanza); // ignore non result if ((g_strcmp0(type, "get") == 0) || (g_strcmp0(type, "set") == 0)) { + free(jid); return 1; } @@ -604,6 +627,7 @@ _caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t * const st const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (!from) { log_info("No from attribute"); + free(jid); return 0; } @@ -612,25 +636,29 @@ _caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t * const st char *error_message = stanza_get_error_message(stanza); log_warning("Error received for capabilities response from %s: ", from, error_message); free(error_message); + free(jid); return 0; } if (query == NULL) { log_warning("No query element found."); + free(jid); return 0; } char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE); if (node == NULL) { log_warning("No node attribute found"); + free(jid); return 0; } - char *jid = (char *)userdata; log_info("Associating capabilities with: %s", jid); Capabilities *capabilities = caps_create(query); caps_add_by_jid(jid, capabilities); + free(jid); + return 0; } @@ -640,10 +668,12 @@ _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const sta { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); + char *expected_node = (char *)userdata; char *type = xmpp_stanza_get_type(stanza); // ignore non result if ((g_strcmp0(type, "get") == 0) || (g_strcmp0(type, "set") == 0)) { + free(expected_node); return 1; } @@ -656,6 +686,7 @@ _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const sta const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (!from) { log_info("No from attribute"); + free(expected_node); return 0; } @@ -664,22 +695,23 @@ _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const sta char *error_message = stanza_get_error_message(stanza); log_warning("Error received for capabilities response from %s: ", from, error_message); free(error_message); + free(expected_node); return 0; } if (query == NULL) { log_warning("No query element found."); + free(expected_node); return 0; } char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE); if (node == NULL) { log_warning("No node attribute found"); + free(expected_node); return 0; } - char *expected_node = (char *)userdata; - // nodes match if (g_strcmp0(expected_node, node) == 0) { log_info("Legacy capabilities, nodes match %s", node); @@ -704,6 +736,36 @@ _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const sta } static int +_enable_carbons_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) +{ + char *type = xmpp_stanza_get_type(stanza); + if (g_strcmp0(type, "error") == 0) { + char *error_message = stanza_get_error_message(stanza); + cons_show_error("Server error enabling message carbons: %s", error_message); + log_debug("Error enabling carbons: %s", error_message); + } else { + log_debug("Message carbons enabled."); + } + + return 0; +} + +static int +_disable_carbons_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) +{ + char *type = xmpp_stanza_get_type(stanza); + if (g_strcmp0(type, "error") == 0) { + char *error_message = stanza_get_error_message(stanza); + cons_show_error("Server error disabling message carbons: %s", error_message); + log_debug("Error disabling carbons: %s", error_message); + } else { + log_debug("Message carbons disabled."); + } + + return 0; +} + +static int _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata) { @@ -714,7 +776,12 @@ _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_ping_error_result(from, error_message); + if (!error_message) { + cons_show_error("Error returned from pinging %s.", from); + } else { + cons_show_error("Error returned from pinging %s: %s.", from, error_message); + } + free(error_message); g_date_time_unref(sent); return 0; @@ -728,7 +795,11 @@ _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, g_date_time_unref(sent); g_date_time_unref(now); - handle_ping_result(from, elapsed_millis); + if (from == NULL) { + cons_show("Ping response from server: %dms.", elapsed_millis); + } else { + cons_show("Ping response from %s: %dms.", from, elapsed_millis); + } return 0; } @@ -759,7 +830,7 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, { char *id = xmpp_stanza_get_id(stanza); - if (id != NULL) { + if (id) { log_debug("IQ version result handler fired, id: %s.", id); } else { log_debug("IQ version result handler fired."); @@ -784,13 +855,13 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, xmpp_stanza_t *version = xmpp_stanza_get_child_by_name(query, "version"); xmpp_stanza_t *os = xmpp_stanza_get_child_by_name(query, "os"); - if (name != NULL) { + if (name) { name_str = xmpp_stanza_get_text(name); } - if (version != NULL) { + if (version) { version_str = xmpp_stanza_get_text(version); } - if (os != NULL) { + if (os) { os_str = xmpp_stanza_get_text(os); } @@ -805,7 +876,7 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, presence = string_from_resource_presence(resource->presence); } - handle_software_version_result(jid, presence, name_str, version_str, os_str); + cons_show_software_version(jid, presence, name_str, version_str, os_str); jid_destroy(jidp); @@ -821,7 +892,7 @@ _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *to = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TO); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (id != NULL) { + if (id) { log_debug("IQ ping get handler fired, id: %s.", id); } else { log_debug("IQ ping get handler fired."); @@ -837,7 +908,7 @@ _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, xmpp_stanza_set_attribute(pong, STANZA_ATTR_FROM, to); xmpp_stanza_set_attribute(pong, STANZA_ATTR_TYPE, STANZA_TYPE_RESULT); - if (id != NULL) { + if (id) { xmpp_stanza_set_attribute(pong, STANZA_ATTR_ID, id); } @@ -855,16 +926,16 @@ _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (id != NULL) { + if (id) { log_debug("IQ version get handler fired, id: %s.", id); } else { log_debug("IQ version get handler fired."); } - if (from != NULL) { + if (from) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); - if (id != NULL) { + if (id) { xmpp_stanza_set_id(response, id); } xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); @@ -923,13 +994,13 @@ _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (id != NULL) { + if (id) { log_debug("IQ disco items get handler fired, id: %s.", id); } else { log_debug("IQ disco items get handler fired."); } - if (from != NULL) { + if (from) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); @@ -960,20 +1031,20 @@ _disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); - if (id != NULL) { + if (id) { log_debug("IQ disco info get handler fired, id: %s.", id); } else { log_debug("IQ disco info get handler fired."); } - if (from != NULL) { + if (from) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); xmpp_stanza_set_type(response, STANZA_TYPE_RESULT); xmpp_stanza_t *query = caps_create_query_response_stanza(ctx); - if (node_str != NULL) { + if (node_str) { xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node_str); } xmpp_stanza_add_child(response, query); @@ -992,7 +1063,7 @@ _destroy_room_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); - if (id != NULL) { + if (id) { log_debug("IQ destroy room result handler fired, id: %s.", id); } else { log_debug("IQ destroy room result handler fired."); @@ -1002,7 +1073,7 @@ _destroy_room_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta if (from == NULL) { log_error("No from attribute for IQ destroy room result"); } else { - handle_room_destroy(from); + sv_ev_room_destroy(from); } return 0; @@ -1016,7 +1087,7 @@ _room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, const char *type = xmpp_stanza_get_type(stanza); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (id != NULL) { + if (id) { log_debug("IQ room config handler fired, id: %s.", id); } else { log_debug("IQ room config handler fired."); @@ -1025,40 +1096,40 @@ _room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_configuration_form_error(from, error_message); + ui_handle_room_configuration_form_error(from, error_message); free(error_message); return 0; } if (from == NULL) { log_warning("No from attribute for IQ config request result"); - handle_room_configuration_form_error(from, "No from attribute for room cofig response."); + ui_handle_room_configuration_form_error(from, "No from attribute for room cofig response."); return 0; } xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (query == NULL) { log_warning("No query element found parsing room config response"); - handle_room_configuration_form_error(from, "No query element found parsing room config response"); + ui_handle_room_configuration_form_error(from, "No query element found parsing room config response"); return 0; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); if (x == NULL) { log_warning("No x element found with %s namespace parsing room config response", STANZA_NS_DATA); - handle_room_configuration_form_error(from, "No form configuration options available"); + ui_handle_room_configuration_form_error(from, "No form configuration options available"); return 0; } char *form_type = xmpp_stanza_get_attribute(x, STANZA_ATTR_TYPE); if (g_strcmp0(form_type, "form") != 0) { log_warning("x element not of type 'form' parsing room config response"); - handle_room_configuration_form_error(from, "Form not of type 'form' parsing room config response."); + ui_handle_room_configuration_form_error(from, "Form not of type 'form' parsing room config response."); return 0; } DataForm *form = form_create(x); - handle_room_configure(from, form); + ui_handle_room_configuration(from, form); return 0; } @@ -1071,7 +1142,7 @@ static int _room_affiliation_set_result_handler(xmpp_conn_t * const conn, xmpp_s const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); struct privilege_set_t *affiliation_set = (struct privilege_set_t *)userdata; - if (id != NULL) { + if (id) { log_debug("IQ affiliation set handler fired, id: %s.", id); } else { log_debug("IQ affiliation set handler fired."); @@ -1080,7 +1151,8 @@ static int _room_affiliation_set_result_handler(xmpp_conn_t * const conn, xmpp_s // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_affiliation_set_error(from, affiliation_set->item, affiliation_set->privilege, error_message); + log_debug("Error setting affiliation %s list for room %s, user %s: %s", affiliation_set->privilege, from, affiliation_set->item, error_message); + ui_handle_room_affiliation_set_error(from, affiliation_set->item, affiliation_set->privilege, error_message); free(error_message); } @@ -1099,7 +1171,7 @@ static int _room_role_set_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); struct privilege_set_t *role_set = (struct privilege_set_t *)userdata; - if (id != NULL) { + if (id) { log_debug("IQ role set handler fired, id: %s.", id); } else { log_debug("IQ role set handler fired."); @@ -1108,7 +1180,8 @@ static int _room_role_set_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_role_set_error(from, role_set->item, role_set->privilege, error_message); + log_debug("Error setting role %s list for room %s, user %s: %s", role_set->privilege, from, role_set->item, error_message); + ui_handle_room_role_set_error(from, role_set->item, role_set->privilege, error_message); free(error_message); } @@ -1127,7 +1200,7 @@ _room_affiliation_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *affiliation = (char *)userdata; - if (id != NULL) { + if (id) { log_debug("IQ affiliation list result handler fired, id: %s.", id); } else { log_debug("IQ affiliation list result handler fired."); @@ -1136,7 +1209,8 @@ _room_affiliation_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_affiliation_list_result_error(from, affiliation, error_message); + log_debug("Error retrieving %s list for room %s: %s", affiliation, from, error_message); + ui_handle_room_affiliation_list_error(from, affiliation, error_message); free(error_message); free(affiliation); return 0; @@ -1158,7 +1232,8 @@ _room_affiliation_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * } } - handle_room_affiliation_list(from, affiliation, jids); + muc_jid_autocomplete_add_all(from, jids); + ui_handle_room_affiliation_list(from, affiliation, jids); free(affiliation); g_slist_free(jids); @@ -1173,7 +1248,7 @@ _room_role_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const s const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *role = (char *)userdata; - if (id != NULL) { + if (id) { log_debug("IQ role list result handler fired, id: %s.", id); } else { log_debug("IQ role list result handler fired."); @@ -1182,7 +1257,8 @@ _room_role_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const s // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_role_list_result_error(from, role, error_message); + log_debug("Error retrieving %s list for room %s: %s", role, from, error_message); + ui_handle_room_role_list_error(from, role, error_message); free(error_message); free(role); return 0; @@ -1204,7 +1280,7 @@ _room_role_list_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const s } } - handle_room_role_list(from, role, nicks); + ui_handle_room_role_list(from, role, nicks); free(role); g_slist_free(nicks); @@ -1219,7 +1295,7 @@ _room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan const char *type = xmpp_stanza_get_type(stanza); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (id != NULL) { + if (id) { log_debug("IQ room config submit handler fired, id: %s.", id); } else { log_debug("IQ room config submit handler fired."); @@ -1228,12 +1304,12 @@ _room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_config_submit_result_error(from, error_message); + ui_handle_room_config_submit_result_error(from, error_message); free(error_message); return 0; } - handle_room_config_submit_result(from); + ui_handle_room_config_submit_result(from); return 0; } @@ -1246,7 +1322,7 @@ _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *nick = (char *)userdata; - if (id != NULL) { + if (id) { log_debug("IQ kick result handler fired, id: %s.", id); } else { log_debug("IQ kick result handler fired."); @@ -1255,7 +1331,7 @@ _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - handle_room_kick_result_error(from, nick, error_message); + ui_handle_room_kick_error(from, nick, error_message); free(error_message); free(nick); return 0; @@ -1269,7 +1345,7 @@ _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza static void _identity_destroy(DiscoIdentity *identity) { - if (identity != NULL) { + if (identity) { free(identity->name); free(identity->type); free(identity->category); @@ -1280,7 +1356,7 @@ _identity_destroy(DiscoIdentity *identity) static void _item_destroy(DiscoItem *item) { - if (item != NULL) { + if (item) { free(item->jid); free(item->name); free(item); @@ -1288,32 +1364,104 @@ _item_destroy(DiscoItem *item) } static int +_room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, + void * const userdata) +{ + const char *type = xmpp_stanza_get_type(stanza); + ProfRoomInfoData *cb_data = (ProfRoomInfoData *)userdata; + log_info("Received diso#info response for room: %s", cb_data->room); + + // handle error responses + if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { + if (cb_data->display) { + char *error_message = stanza_get_error_message(stanza); + ui_handle_room_info_error(cb_data->room, error_message); + free(error_message); + } + free(cb_data->room); + free(cb_data); + return 0; + } + + xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); + + if (query) { + xmpp_stanza_t *child = xmpp_stanza_get_children(query); + GSList *identities = NULL; + GSList *features = NULL; + while (child) { + const char *stanza_name = xmpp_stanza_get_name(child); + if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) { + const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR); + if (var) { + features = g_slist_append(features, strdup(var)); + } + } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) { + const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); + const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE); + const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY); + + if (name || category || type) { + DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t)); + + if (name) { + identity->name = strdup(name); + } else { + identity->name = NULL; + } + if (category) { + identity->category = strdup(category); + } else { + identity->category = NULL; + } + if (type) { + identity->type = strdup(type); + } else { + identity->type = NULL; + } + + identities = g_slist_append(identities, identity); + } + } + + child = xmpp_stanza_get_next(child); + } + + muc_set_features(cb_data->room, features); + if (cb_data->display) { + ui_show_room_disco_info(cb_data->room, identities, features); + } + + g_slist_free_full(features, free); + g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); + } + + free(cb_data->room); + free(cb_data); + + return 0; +} + +static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); const char *type = xmpp_stanza_get_type(stanza); - char *room = NULL; - if (userdata) { - room = (char *) userdata; - log_info("Received diso#info response for room: %s", room); + if (from) { + log_info("Received diso#info response from: %s", from); } else { - room = NULL; - if (from) { - log_info("Received diso#info response from: %s", from); - } else { - log_info("Received diso#info response"); - } + log_info("Received diso#info response"); } // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - if (room) { - handle_room_info_error(room, error_message); + if (from) { + cons_show_error("Service discovery failed for %s: %s", from, error_message); } else { - handle_disco_info_error(from, error_message); + cons_show_error("Service discovery failed: %s", error_message); } free(error_message); return 0; @@ -1321,15 +1469,15 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); - if (query != NULL) { + if (query) { xmpp_stanza_t *child = xmpp_stanza_get_children(query); GSList *identities = NULL; GSList *features = NULL; - while (child != NULL) { + while (child) { const char *stanza_name = xmpp_stanza_get_name(child); if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) { const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR); - if (var != NULL) { + if (var) { features = g_slist_append(features, strdup(var)); } } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) { @@ -1337,20 +1485,20 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE); const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY); - if ((name != NULL) || (category != NULL) || (type != NULL)) { + if (name || category || type) { DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t)); - if (name != NULL) { + if (name) { identity->name = strdup(name); } else { identity->name = NULL; } - if (category != NULL) { + if (category) { identity->category = strdup(category); } else { identity->category = NULL; } - if (type != NULL) { + if (type) { identity->type = strdup(type); } else { identity->type = NULL; @@ -1363,16 +1511,13 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta child = xmpp_stanza_get_next(child); } - if (room) { - handle_room_disco_info(room, identities, features); - } else { - handle_disco_info(from, identities, features); - } + cons_show_disco_info(from, identities, features); g_slist_free_full(features, free); g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); } - return 1; + + return 0; } static int @@ -1389,17 +1534,17 @@ _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan log_debug("Response to query: %s", id); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); - if (query != NULL) { + if (query) { xmpp_stanza_t *child = xmpp_stanza_get_children(query); - while (child != NULL) { + while (child) { const char *stanza_name = xmpp_stanza_get_name(child); - if ((stanza_name != NULL) && (g_strcmp0(stanza_name, STANZA_NAME_ITEM) == 0)) { + if (stanza_name && (g_strcmp0(stanza_name, STANZA_NAME_ITEM) == 0)) { const char *item_jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); - if (item_jid != NULL) { + if (item_jid) { DiscoItem *item = malloc(sizeof(struct disco_item_t)); item->jid = strdup(item_jid); const char *item_name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); - if (item_name != NULL) { + if (item_name) { item->name = strdup(item_name); } else { item->name = NULL; @@ -1414,9 +1559,9 @@ _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan } if (g_strcmp0(id, "confreq") == 0) { - handle_room_list(items, from); + cons_show_room_list(items, from); } else if (g_strcmp0(id, "discoitemsreq") == 0) { - handle_disco_items(items, from); + cons_show_disco_items(items, from); } g_slist_free_full(items, (GDestroyNotify)_item_destroy); diff --git a/src/xmpp/iq.h b/src/xmpp/iq.h index 8c803ab5..d3a22fe4 100644 --- a/src/xmpp/iq.h +++ b/src/xmpp/iq.h @@ -1,7 +1,7 @@ /* * iq.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/message.c b/src/xmpp/message.c index e96c1a74..bc702199 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -1,7 +1,7 @@ /* * message.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -42,7 +42,8 @@ #include "log.h" #include "muc.h" #include "profanity.h" -#include "server_events.h" +#include "ui/ui.h" +#include "event/server_events.h" #include "xmpp/connection.h" #include "xmpp/message.h" #include "xmpp/roster.h" @@ -52,18 +53,13 @@ #define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_MESSAGE, type, ctx) -static int _groupchat_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _chat_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _muc_user_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _conference_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _captcha_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); -static int _message_error_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata); +static int _groupchat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _captcha_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _receipt_received_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); void message_add_handlers(void) @@ -77,34 +73,89 @@ message_add_handlers(void) HANDLE(STANZA_NS_MUC_USER, NULL, _muc_user_handler); HANDLE(STANZA_NS_CONFERENCE, NULL, _conference_handler); HANDLE(STANZA_NS_CAPTCHA, NULL, _captcha_handler); + HANDLE(STANZA_NS_RECEIPTS, NULL, _receipt_received_handler); } -void +char * message_send_chat(const char * const barejid, const char * const msg) { - xmpp_stanza_t *message; xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); ChatSession *session = chat_session_get(barejid); + char *state = NULL; + char *jid = NULL; + if (session) { + if (prefs_get_boolean(PREF_STATES) && session->send_states) { + state = STANZA_NAME_ACTIVE; + } + Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource); + jid = strdup(jidp->fulljid); + jid_destroy(jidp); + + } else { + if (prefs_get_boolean(PREF_STATES)) { + state = STANZA_NAME_ACTIVE; + } + jid = strdup(barejid); + } + + char *id = create_unique_id("msg"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg); + free(jid); + + if (state) { + stanza_attach_state(ctx, message, state); + } + if (prefs_get_boolean(PREF_RECEIPTS_REQUEST)) { + stanza_attach_receipt_request(ctx, message); + } + + xmpp_send(conn, message); + xmpp_stanza_release(message); + + return id; +} + +char * +message_send_chat_encrypted(const char * const barejid, const char * const msg) +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + + ChatSession *session = chat_session_get(barejid); + char *state = NULL; + char *jid = NULL; if (session) { - char *state = NULL; if (prefs_get_boolean(PREF_STATES) && session->send_states) { state = STANZA_NAME_ACTIVE; } Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource); - message = stanza_create_message(ctx, jidp->fulljid, STANZA_TYPE_CHAT, msg, state); + jid = strdup(jidp->fulljid); jid_destroy(jidp); } else { - char *state = NULL; if (prefs_get_boolean(PREF_STATES)) { state = STANZA_NAME_ACTIVE; } - message = stanza_create_message(ctx, barejid, STANZA_TYPE_CHAT, msg, state); + jid = strdup(barejid); + } + + char *id = create_unique_id("msg"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, barejid, STANZA_TYPE_CHAT, msg); + free(jid); + + if (state) { + stanza_attach_state(ctx, message, state); + } + stanza_attach_carbons_private(ctx, message); + if (prefs_get_boolean(PREF_RECEIPTS_REQUEST)) { + stanza_attach_receipt_request(ctx, message); } xmpp_send(conn, message); xmpp_stanza_release(message); + + return id; } void @@ -112,7 +163,9 @@ message_send_private(const char * const fulljid, const char * const msg) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *message = stanza_create_message(ctx, fulljid, STANZA_TYPE_CHAT, msg, NULL); + char *id = create_unique_id("prv"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, fulljid, STANZA_TYPE_CHAT, msg); + free(id); xmpp_send(conn, message); xmpp_stanza_release(message); @@ -123,7 +176,9 @@ message_send_groupchat(const char * const roomjid, const char * const msg) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *message = stanza_create_message(ctx, roomjid, STANZA_TYPE_GROUPCHAT, msg, NULL); + char *id = create_unique_id("muc"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, roomjid, STANZA_TYPE_GROUPCHAT, msg); + free(id); xmpp_send(conn, message); xmpp_stanza_release(message); @@ -146,7 +201,18 @@ message_send_invite(const char * const roomjid, const char * const contact, { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - xmpp_stanza_t *stanza = stanza_create_invite(ctx, roomjid, contact, reason); + xmpp_stanza_t *stanza; + + + muc_member_type_t member_type = muc_member_type(roomjid); + if (member_type == MUC_MEMBER_TYPE_PUBLIC) { + log_debug("Sending direct invite to %s, for %s", contact, roomjid); + char *password = muc_password(roomjid); + stanza = stanza_create_invite(ctx, roomjid, contact, reason, password); + } else { + log_debug("Sending mediated invite to %s, for %s", contact, roomjid); + stanza = stanza_create_mediated_invite(ctx, roomjid, contact, reason); + } xmpp_send(conn, stanza); xmpp_stanza_release(stanza); @@ -196,14 +262,13 @@ message_send_gone(const char * const jid) } static int -_message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *id = xmpp_stanza_get_id(stanza); char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); char *type = NULL; - if (error_stanza != NULL) { + if (error_stanza) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } @@ -211,15 +276,15 @@ _message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *err_msg = stanza_get_error_message(stanza); GString *log_msg = g_string_new("message stanza error received"); - if (id != NULL) { + if (id) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } - if (jid != NULL) { + if (jid) { g_string_append(log_msg, " from="); g_string_append(log_msg, jid); } - if (type != NULL) { + if (type) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } @@ -230,7 +295,16 @@ _message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, g_string_free(log_msg, TRUE); - handle_message_error(jid, type, err_msg); + if (!jid) { + ui_handle_error(err_msg); + } else if (type && (strcmp(type, "cancel") == 0)) { + log_info("Recipient %s not found: %s", jid, err_msg); + Jid *jidp = jid_create(jid); + chat_session_remove(jidp->barejid); + jid_destroy(jidp); + } else { + ui_handle_recipient_error(jid, err_msg); + } free(err_msg); @@ -238,113 +312,120 @@ _message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } static int -_muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_stanza_t *xns_muc_user = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); char *room = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (room == NULL) { + if (!room) { log_warning("Message received with no from attribute, ignoring"); return 1; } // XEP-0045 xmpp_stanza_t *invite = xmpp_stanza_get_child_by_name(xns_muc_user, STANZA_NAME_INVITE); - if (invite != NULL) { - char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM); - if (invitor_jid == NULL) { - log_warning("Chat room invite received with no from attribute"); - return 1; - } + if (!invite) { + return 1; + } - Jid *jidp = jid_create(invitor_jid); - if (jidp == NULL) { - return 1; - } - char *invitor = jidp->barejid; + char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM); + if (!invitor_jid) { + log_warning("Chat room invite received with no from attribute"); + return 1; + } - char *reason = NULL; - xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(invite, STANZA_NAME_REASON); - if (reason_st != NULL) { - reason = xmpp_stanza_get_text(reason_st); - } + Jid *jidp = jid_create(invitor_jid); + if (!jidp) { + return 1; + } + char *invitor = jidp->barejid; - handle_room_invite(INVITE_MEDIATED, invitor, room, reason); - jid_destroy(jidp); - if (reason != NULL) { - xmpp_free(ctx, reason); - } + char *reason = NULL; + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(invite, STANZA_NAME_REASON); + if (reason_st) { + reason = xmpp_stanza_get_text(reason_st); + } + + char *password = NULL; + xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(xns_muc_user, STANZA_NAME_PASSWORD); + if (password_st) { + password = xmpp_stanza_get_text(password_st); + } + + sv_ev_room_invite(INVITE_MEDIATED, invitor, room, reason, password); + jid_destroy(jidp); + if (reason) { + xmpp_free(ctx, reason); + } + if (password) { + xmpp_free(ctx, password); } return 1; } static int -_conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *xns_conference = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); - char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - char *room = NULL; - char *invitor = NULL; - char *reason = NULL; - if (from == NULL) { + char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); + if (!from) { log_warning("Message received with no from attribute, ignoring"); return 1; } - // XEP-0429 - room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID); - if (room == NULL) { + Jid *jidp = jid_create(from); + if (!jidp) { return 1; } - Jid *jidp = jid_create(from); - if (jidp == NULL) { + // XEP-0249 + char *room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID); + if (!room) { return 1; } - invitor = jidp->barejid; - reason = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_REASON); - - handle_room_invite(INVITE_DIRECT, invitor, room, reason); + char *reason = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_REASON); + char *password = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_PASSWORD); + sv_ev_room_invite(INVITE_DIRECT, jidp->barejid, room, reason, password); jid_destroy(jidp); return 1; } static int -_captcha_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_captcha_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = connection_get_ctx(); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (from == NULL) { + if (!from) { log_warning("Message received with no from attribute, ignoring"); return 1; } // XEP-0158 xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); - if (body != NULL) { - char *message = xmpp_stanza_get_text(body); - if (message != NULL) { - handle_room_broadcast(from, message); - xmpp_free(ctx, message); - } + if (!body) { + return 1; } + char *message = xmpp_stanza_get_text(body); + if (!message) { + return 1; + } + + sv_ev_room_broadcast(from, message); + xmpp_free(ctx, message); + return 1; } static int -_groupchat_handler(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza, void * const userdata) +_groupchat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = connection_get_ctx(); char *message = NULL; @@ -353,9 +434,9 @@ _groupchat_handler(xmpp_conn_t * const conn, // handle room subject xmpp_stanza_t *subject = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_SUBJECT); - if (subject != NULL) { + if (subject) { message = xmpp_stanza_get_text(subject); - handle_room_subject(jid->barejid, jid->resourcepart, message); + sv_ev_room_subject(jid->barejid, jid->resourcepart, message); xmpp_free(ctx, message); jid_destroy(jid); @@ -363,16 +444,22 @@ _groupchat_handler(xmpp_conn_t * const conn, } // handle room broadcasts - if (jid->resourcepart == NULL) { + if (!jid->resourcepart) { xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); - if (body != NULL) { - message = xmpp_stanza_get_text(body); - if (message != NULL) { - handle_room_broadcast(room_jid, message); - xmpp_free(ctx, message); - } + if (!body) { + jid_destroy(jid); + return 1; } + message = xmpp_stanza_get_text(body); + if (!message) { + jid_destroy(jid); + return 1; + } + + sv_ev_room_broadcast(room_jid, message); + xmpp_free(ctx, message); + jid_destroy(jid); return 1; } @@ -390,32 +477,191 @@ _groupchat_handler(xmpp_conn_t * const conn, return 1; } + xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); + + // check for and deal with message + if (!body) { + jid_destroy(jid); + return 1; + } + + message = xmpp_stanza_get_text(body); + if (!message) { + jid_destroy(jid); + return 1; + } + // determine if the notifications happened whilst offline GTimeVal tv_stamp; gboolean delayed = stanza_get_delay(stanza, &tv_stamp); + if (delayed) { + sv_ev_room_history(jid->barejid, jid->resourcepart, tv_stamp, message); + } else { + sv_ev_room_message(jid->barejid, jid->resourcepart, message); + } + + xmpp_free(ctx, message); + jid_destroy(jid); + + return 1; +} + +void +_message_send_receipt(const char * const fulljid, const char * const message_id) +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *message = xmpp_stanza_new(ctx); + char *id = create_unique_id("receipt"); + xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE); + xmpp_stanza_set_id(message, id); + xmpp_stanza_set_attribute(message, STANZA_ATTR_TO, fulljid); + + xmpp_stanza_t *receipt = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(receipt, "received"); + xmpp_stanza_set_ns(receipt, STANZA_NS_RECEIPTS); + xmpp_stanza_set_attribute(receipt, STANZA_ATTR_ID, message_id); + + xmpp_stanza_add_child(message, receipt); + xmpp_stanza_release(receipt); + + xmpp_send(conn, message); + xmpp_stanza_release(message); +} + +static int +_receipt_received_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) +{ + xmpp_stanza_t *receipt = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); + char *name = xmpp_stanza_get_name(receipt); + if (g_strcmp0(name, "received") != 0) { + return 1; + } + + char *id = xmpp_stanza_get_attribute(receipt, STANZA_ATTR_ID); + if (!id) { + return 1; + } + + char *fulljid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); + if (!fulljid) { + return 1; + } + + Jid *jidp = jid_create(fulljid); + sv_ev_message_receipt(jidp->barejid, id); + jid_destroy(jidp); + + return 1; +} + +void +_receipt_request_handler(xmpp_stanza_t * const stanza) +{ + if (!prefs_get_boolean(PREF_RECEIPTS_SEND)) { + return; + } + + char *id = xmpp_stanza_get_id(stanza); + if (!id) { + return; + } + + xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); + if (!receipts) { + return; + } + + char *receipts_name = xmpp_stanza_get_name(receipts); + if (g_strcmp0(receipts_name, "request") != 0) { + return; + } + + gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); + Jid *jid = jid_create(from); + _message_send_receipt(jid->fulljid, id); + jid_destroy(jid); +} + +void +_private_chat_handler(xmpp_stanza_t * const stanza, const char * const fulljid) +{ xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); + if (!body) { + return; + } - // check for and deal with message - if (body != NULL) { - message = xmpp_stanza_get_text(body); - if (message != NULL) { - if (delayed) { - handle_room_history(jid->barejid, jid->resourcepart, tv_stamp, message); - } else { - handle_room_message(jid->barejid, jid->resourcepart, message); + char *message = xmpp_stanza_get_text(body); + if (!message) { + return; + } + + GTimeVal tv_stamp; + gboolean delayed = stanza_get_delay(stanza, &tv_stamp); + if (delayed) { + sv_ev_delayed_private_message(fulljid, message, tv_stamp); + } else { + sv_ev_incoming_private_message(fulljid, message); + } + + xmpp_ctx_t *ctx = connection_get_ctx(); + xmpp_free(ctx, message); +} + +static gboolean +_handle_carbons(xmpp_stanza_t * const stanza) +{ + xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); + if (!carbons) { + return FALSE; + } + + char *name = xmpp_stanza_get_name(carbons); + if ((g_strcmp0(name, "received") == 0) || (g_strcmp0(name, "sent")) == 0) { + xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD); + xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE); + + xmpp_ctx_t *ctx = connection_get_ctx(); + + gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO); + gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM); + + // happens when receive a carbon of a self sent message + if (!to) to = from; + + Jid *jid_from = jid_create(from); + Jid *jid_to = jid_create(to); + Jid *my_jid = jid_create(jabber_get_fulljid()); + + // check for and deal with message + xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY); + if (body) { + char *message = xmpp_stanza_get_text(body); + if (message) { + // if we are the recipient, treat as standard incoming message + if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){ + sv_ev_incoming_message(jid_from->barejid, jid_from->resourcepart, message); + } + // else treat as a sent message + else{ + sv_ev_carbon(jid_to->barejid, message); + } + xmpp_free(ctx, message); } - xmpp_free(ctx, message); } - } - jid_destroy(jid); + jid_destroy(jid_from); + jid_destroy(jid_to); + jid_destroy(my_jid); - return 1; + return TRUE; + } + + return FALSE; } static int -_chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { // ignore if type not chat or absent char *type = xmpp_stanza_get_type(stanza); @@ -423,6 +669,12 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } + // check if carbon message + gboolean res = _handle_carbons(stanza); + if (res) { + return 1; + } + // ignore handled namespaces xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); @@ -431,76 +683,57 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } - xmpp_ctx_t *ctx = connection_get_ctx(); gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - Jid *jid = jid_create(from); // private message from chat room use full jid (room/nick) if (muc_active(jid->barejid)) { - // determine if the notifications happened whilst offline - GTimeVal tv_stamp; - gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - - // check for and deal with message - xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); - if (body != NULL) { - char *message = xmpp_stanza_get_text(body); - if (message != NULL) { - if (delayed) { - handle_delayed_private_message(jid->str, message, tv_stamp); - } else { - handle_incoming_private_message(jid->str, message); - } - xmpp_free(ctx, message); - } - } - - jid_destroy(jid); + _private_chat_handler(stanza, jid->fulljid); return 1; + } // standard chat message, use jid without resource - } else { - // determine if the notifications happened whilst offline - GTimeVal tv_stamp; - gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - - // check for and deal with message - xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); - if (body != NULL) { - char *message = xmpp_stanza_get_text(body); - if (message != NULL) { - if (delayed) { - handle_delayed_message(jid->barejid, message, tv_stamp); - } else { - handle_incoming_message(jid->barejid, jid->resourcepart, message); - } - xmpp_free(ctx, message); - } - } + GTimeVal tv_stamp; + gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - // handle chat sessions and states - if (!delayed && jid->resourcepart) { - gboolean gone = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL; - gboolean typing = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL; - gboolean paused = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL; - gboolean inactive = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL; - if (gone) { - handle_gone(jid->barejid, jid->resourcepart); - } else if (typing) { - handle_typing(jid->barejid, jid->resourcepart); - } else if (paused) { - handle_paused(jid->barejid, jid->resourcepart); - } else if (inactive) { - handle_inactive(jid->barejid, jid->resourcepart); - } else if (stanza_contains_chat_state(stanza)) { - handle_activity(jid->barejid, jid->resourcepart, TRUE); + xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); + if (body) { + char *message = xmpp_stanza_get_text(body); + if (message) { + if (delayed) { + sv_ev_delayed_message(jid->barejid, message, tv_stamp); } else { - handle_activity(jid->barejid, jid->resourcepart, FALSE); + sv_ev_incoming_message(jid->barejid, jid->resourcepart, message); } + + _receipt_request_handler(stanza); + + xmpp_ctx_t *ctx = connection_get_ctx(); + xmpp_free(ctx, message); } + } - jid_destroy(jid); - return 1; + // handle chat sessions and states + if (!delayed && jid->resourcepart) { + gboolean gone = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL; + gboolean typing = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL; + gboolean paused = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL; + gboolean inactive = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL; + if (gone) { + sv_ev_gone(jid->barejid, jid->resourcepart); + } else if (typing) { + sv_ev_typing(jid->barejid, jid->resourcepart); + } else if (paused) { + sv_ev_paused(jid->barejid, jid->resourcepart); + } else if (inactive) { + sv_ev_inactive(jid->barejid, jid->resourcepart); + } else if (stanza_contains_chat_state(stanza)) { + sv_ev_activity(jid->barejid, jid->resourcepart, TRUE); + } else { + sv_ev_activity(jid->barejid, jid->resourcepart, FALSE); + } } -} \ No newline at end of file + + jid_destroy(jid); + return 1; +} diff --git a/src/xmpp/message.h b/src/xmpp/message.h index b3410dc9..6fbc27bd 100644 --- a/src/xmpp/message.h +++ b/src/xmpp/message.h @@ -1,7 +1,7 @@ /* * message.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 65384a0d..e46730e3 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -1,7 +1,7 @@ /* * presence.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -44,7 +44,8 @@ #include "log.h" #include "muc.h" #include "profanity.h" -#include "server_events.h" +#include "ui/ui.h" +#include "event/server_events.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" @@ -170,7 +171,7 @@ presence_sub_request_exists(const char * const bare_jid) GSList *requests_p = autocomplete_create_list(sub_requests_ac); GSList *requests = requests_p; - while (requests != NULL) { + while (requests) { if (strcmp(requests->data, bare_jid) == 0) { result = TRUE; break; @@ -178,7 +179,7 @@ presence_sub_request_exists(const char * const bare_jid) requests = g_slist_next(requests); } - if (requests_p != NULL) { + if (requests_p) { g_slist_free_full(requests_p, free); } @@ -192,27 +193,22 @@ presence_reset_sub_request_search(void) } void -presence_update(const resource_presence_t presence_type, const char * const msg, - const int idle) +presence_send(const resource_presence_t presence_type, const char * const msg, const int idle) { if (jabber_get_connection_status() != JABBER_CONNECTED) { log_warning("Error setting presence, not connected."); return; } - if (msg != NULL) { - log_debug("Updating presence: %s, \"%s\"", - string_from_resource_presence(presence_type), msg); + if (msg) { + log_debug("Updating presence: %s, \"%s\"", string_from_resource_presence(presence_type), msg); } else { - log_debug("Updating presence: %s", - string_from_resource_presence(presence_type)); + log_debug("Updating presence: %s", string_from_resource_presence(presence_type)); } xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_conn_t * const conn = connection_get_conn(); - const int pri = - accounts_get_priority_for_presence_type(jabber_get_account_name(), - presence_type); + const int pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), presence_type); const char *show = stanza_get_presence_string_from_type(presence_type); connection_set_presence_message(msg); @@ -245,11 +241,11 @@ _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence) GList *rooms_p = muc_rooms(); GList *rooms = rooms_p; - while (rooms != NULL) { + while (rooms) { const char *room = rooms->data; const char *nick = muc_nick(room); - if (nick != NULL) { + if (nick) { char *full_room_jid = create_fulljid(room, nick); xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, full_room_jid); @@ -261,7 +257,7 @@ _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence) rooms = g_list_next(rooms); } - if (rooms_p != NULL) { + if (rooms_p) { g_list_free(rooms_p); } } @@ -333,7 +329,7 @@ presence_leave_chat_room(const char * const room_jid) xmpp_conn_t *conn = connection_get_conn(); char *nick = muc_nick(room_jid); - if (nick != NULL) { + if (nick) { xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, nick); xmpp_send(conn, presence); @@ -350,11 +346,11 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); char *xmlns = NULL; - if (x != NULL) { + if (x) { xmlns = xmpp_stanza_get_ns(x); } char *type = NULL; - if (error_stanza != NULL) { + if (error_stanza) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } @@ -364,7 +360,7 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *error_cond = NULL; xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS); - if (reason_st != NULL) { + if (reason_st) { error_cond = xmpp_stanza_get_name(reason_st); } if (error_cond == NULL) { @@ -372,7 +368,10 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond); - handle_room_join_error(fulljid->barejid, error_cond); + if (muc_active(fulljid->barejid)) { + muc_leave(fulljid->barejid); + } + ui_handle_room_join_error(fulljid->barejid, error_cond); jid_destroy(fulljid); return 1; } @@ -381,15 +380,15 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *err_msg = stanza_get_error_message(stanza); GString *log_msg = g_string_new("presence stanza error received"); - if (id != NULL) { + if (id) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } - if (from != NULL) { + if (from) { g_string_append(log_msg, " from="); g_string_append(log_msg, from); } - if (type != NULL) { + if (type) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } @@ -400,7 +399,11 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, g_string_free(log_msg, TRUE); - handle_presence_error(from, type, err_msg); + if (from) { + ui_handle_recipient_error(from, err_msg); + } else { + ui_handle_error(err_msg); + } free(err_msg); @@ -416,7 +419,7 @@ _unsubscribed_handler(xmpp_conn_t * const conn, Jid *from_jid = jid_create(from); log_debug("Unsubscribed presence handler fired for %s", from); - handle_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED); + sv_ev_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED); autocomplete_remove(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -432,7 +435,7 @@ _subscribed_handler(xmpp_conn_t * const conn, Jid *from_jid = jid_create(from); log_debug("Subscribed presence handler fired for %s", from); - handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED); + sv_ev_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED); autocomplete_remove(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -452,7 +455,7 @@ _subscribe_handler(xmpp_conn_t * const conn, return 1; } - handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); + sv_ev_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); autocomplete_add(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -464,6 +467,8 @@ static int _unavailable_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { + ui_input_nonblocking(TRUE); + const char *jid = xmpp_conn_get_jid(conn); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); log_debug("Unavailable presence handler fired for %s", from); @@ -479,15 +484,15 @@ _unavailable_handler(xmpp_conn_t * const conn, char *status_str = stanza_get_status(stanza, NULL); if (strcmp(my_jid->barejid, from_jid->barejid) !=0) { - if (from_jid->resourcepart != NULL) { - handle_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); + if (from_jid->resourcepart) { + sv_ev_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); // hack for servers that do not send full jid with unavailable presence } else { - handle_contact_offline(from_jid->barejid, "__prof_default", status_str); + sv_ev_contact_offline(from_jid->barejid, "__prof_default", status_str); } } else { - if (from_jid->resourcepart != NULL) { + if (from_jid->resourcepart) { connection_remove_available_resource(from_jid->resourcepart); } } @@ -517,7 +522,7 @@ _handle_caps(char *jid, XMPPCaps *caps) } } - // unsupported hash, xep-0115, assoiciate with JID, no cache + // unsupported hash, xep-0115, associate with JID, no cache } else if (caps->hash) { log_info("Hash %s not supported: %s, sending service discovery request", caps->hash, jid); char *id = create_unique_id("caps"); @@ -539,6 +544,8 @@ static int _available_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { + ui_input_nonblocking(TRUE); + // handler still fires if error if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) { return 1; @@ -596,7 +603,7 @@ _available_handler(xmpp_conn_t * const conn, if (g_strcmp0(xmpp_presence->jid->barejid, my_jid->barejid) == 0) { connection_add_available_resource(resource); } else { - handle_contact_online(xmpp_presence->jid->barejid, resource, xmpp_presence->last_activity); + sv_ev_contact_online(xmpp_presence->jid->barejid, resource, xmpp_presence->last_activity); } jid_destroy(my_jid); @@ -611,7 +618,7 @@ _send_caps_request(char *node, char *caps_key, char *id, char *from) xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_conn_t *conn = connection_get_conn(); - if (node != NULL) { + if (node) { log_debug("Node string: %s.", node); if (!caps_contains(caps_key)) { log_debug("Capabilities not cached for '%s', sending discovery IQ.", from); @@ -629,6 +636,8 @@ _send_caps_request(char *node, char *caps_key, char *id, char *from) static int _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { + ui_input_nonblocking(TRUE); + char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); @@ -682,27 +691,27 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * char *new_jid = stanza_get_muc_destroy_alternative_room(stanza); char *password = stanza_get_muc_destroy_alternative_password(stanza); char *reason = stanza_get_muc_destroy_reason(stanza); - handle_room_destroyed(room, new_jid, password, reason); + sv_ev_room_destroyed(room, new_jid, password, reason); free(password); free(reason); // kicked from room - } else if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) { + } else if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0)) { char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_room_kicked(room, actor, reason); + sv_ev_room_kicked(room, actor, reason); free(reason); // banned from room - } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) { + } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0)) { char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_room_banned(room, actor, reason); + sv_ev_room_banned(room, actor, reason); free(reason); // normal exit } else { - handle_leave_room(room); + sv_ev_leave_room(room); } g_slist_free_full(status_codes, free); @@ -713,7 +722,7 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * gboolean config_required = stanza_muc_requires_config(stanza); char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_muc_self_online(room, nick, config_required, role, affiliation, actor, reason, jid, show_str, status_str); + sv_ev_muc_self_online(room, nick, config_required, role, affiliation, actor, reason, jid, show_str, status_str); } // handle presence from room members @@ -732,22 +741,22 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER); // kicked from room - if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) { + if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0)) { char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_room_occupent_kicked(room, nick, actor, reason); + sv_ev_room_occupent_kicked(room, nick, actor, reason); free(reason); // banned from room - } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) { + } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0)) { char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_room_occupent_banned(room, nick, actor, reason); + sv_ev_room_occupent_banned(room, nick, actor, reason); free(reason); // normal exit } else { - handle_room_occupant_offline(room, nick, "offline", status_str); + sv_ev_room_occupant_offline(room, nick, "offline", status_str); } g_slist_free_full(status_codes, free); @@ -765,7 +774,7 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * char *actor = stanza_get_actor(stanza); char *reason = stanza_get_reason(stanza); - handle_muc_occupant_online(room, nick, jid, role, affiliation, actor, reason, show_str, status_str); + sv_ev_muc_occupant_online(room, nick, jid, role, affiliation, actor, reason, show_str, status_str); } } diff --git a/src/xmpp/presence.h b/src/xmpp/presence.h index e704aea0..90b83473 100644 --- a/src/xmpp/presence.h +++ b/src/xmpp/presence.h @@ -1,7 +1,7 @@ /* * presence.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index 3449c8d5..5c9fa5d4 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -1,7 +1,7 @@ /* * roster.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -41,7 +41,9 @@ #include "log.h" #include "profanity.h" -#include "server_events.h" +#include "ui/ui.h" +#include "event/server_events.h" +#include "event/client_events.h" #include "tools/autocomplete.h" #include "xmpp/connection.h" #include "xmpp/roster.h" @@ -131,7 +133,7 @@ roster_send_add_to_group(const char * const group, PContact contact) { GSList *groups = p_contact_groups(contact); GSList *new_groups = NULL; - while (groups != NULL) { + while (groups) { new_groups = g_slist_append(new_groups, strdup(groups->data)); groups = g_slist_next(groups); } @@ -141,7 +143,7 @@ roster_send_add_to_group(const char * const group, PContact contact) char *unique_id = create_unique_id(NULL); GroupData *data = malloc(sizeof(GroupData)); data->group = strdup(group); - if (p_contact_name(contact) != NULL) { + if (p_contact_name(contact)) { data->name = strdup(p_contact_name(contact)); } else { data->name = strdup(p_contact_barejid(contact)); @@ -161,9 +163,9 @@ static int _group_add_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { - if (userdata != NULL) { + if (userdata) { GroupData *data = userdata; - handle_group_add(data->name, data->group); + ui_group_added(data->name, data->group); free(data->name); free(data->group); free(userdata); @@ -176,7 +178,7 @@ roster_send_remove_from_group(const char * const group, PContact contact) { GSList *groups = p_contact_groups(contact); GSList *new_groups = NULL; - while (groups != NULL) { + while (groups) { if (strcmp(groups->data, group) != 0) { new_groups = g_slist_append(new_groups, strdup(groups->data)); } @@ -190,7 +192,7 @@ roster_send_remove_from_group(const char * const group, PContact contact) char *unique_id = create_unique_id(NULL); GroupData *data = malloc(sizeof(GroupData)); data->group = strdup(group); - if (p_contact_name(contact) != NULL) { + if (p_contact_name(contact)) { data->name = strdup(p_contact_name(contact)); } else { data->name = strdup(p_contact_barejid(contact)); @@ -208,9 +210,9 @@ static int _group_remove_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { - if (userdata != NULL) { + if (userdata) { GroupData *data = userdata; - handle_group_remove(data->name, data->group); + ui_group_removed(data->name, data->group); free(data->name); free(data->group); free(userdata); @@ -234,13 +236,14 @@ _roster_set_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, // if from attribute exists and it is not current users barejid, ignore push Jid *my_jid = jid_create(jabber_get_fulljid()); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if ((from != NULL) && (strcmp(from, my_jid->barejid) != 0)) { + if (from && (strcmp(from, my_jid->barejid) != 0)) { jid_destroy(my_jid); return 1; } jid_destroy(my_jid); const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); + gchar *barejid_lower = g_utf8_strdown(barejid, -1); const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); @@ -254,83 +257,83 @@ _roster_set_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (g_strcmp0(sub, "remove") == 0) { // remove barejid and name if (name == NULL) { - name = barejid; + name = barejid_lower; } - - roster_remove(name, barejid); - - handle_roster_remove(barejid); + roster_remove(name, barejid_lower); + ui_roster_remove(barejid_lower); // otherwise update local roster } else { // check for pending out subscriptions gboolean pending_out = FALSE; - if ((ask != NULL) && (strcmp(ask, "subscribe") == 0)) { + if (ask && (strcmp(ask, "subscribe") == 0)) { pending_out = TRUE; } GSList *groups = _get_groups_from_item(item); // update the local roster - PContact contact = roster_get_contact(barejid); + PContact contact = roster_get_contact(barejid_lower); if (contact == NULL) { - gboolean added = roster_add(barejid, name, groups, sub, pending_out); + gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out); if (added) { - handle_roster_add(barejid, name); + ui_roster_add(barejid_lower, name); } } else { - handle_roster_update(barejid, name, groups, sub, pending_out); + sv_ev_roster_update(barejid_lower, name, groups, sub, pending_out); } } + g_free(barejid_lower); + return 1; } static int -_roster_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata) +_roster_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); + if (g_strcmp0(id, "roster") != 0) { + return 1; + } + // handle initial roster response - if (g_strcmp0(id, "roster") == 0) { - xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); - xmpp_stanza_t *item = xmpp_stanza_get_children(query); - - while (item != NULL) { - const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); - const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); - const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); - - // do not set nickname to empty string, set to NULL instead - if (name && (strlen(name) == 0)) { - name = NULL; - } + xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); + xmpp_stanza_t *item = xmpp_stanza_get_children(query); - gboolean pending_out = FALSE; - const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); - if (g_strcmp0(ask, "subscribe") == 0) { - pending_out = TRUE; - } + while (item) { + const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); + gchar *barejid_lower = g_utf8_strdown(barejid, -1); + const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); + const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); - GSList *groups = _get_groups_from_item(item); + // do not set nickname to empty string, set to NULL instead + if (name && (strlen(name) == 0)) name = NULL; - gboolean added = roster_add(barejid, name, groups, sub, pending_out); + gboolean pending_out = FALSE; + const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); + if (g_strcmp0(ask, "subscribe") == 0) { + pending_out = TRUE; + } - if (!added) { - log_warning("Attempt to add contact twice: %s", barejid); - } + GSList *groups = _get_groups_from_item(item); - item = xmpp_stanza_get_next(item); + gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out); + if (!added) { + log_warning("Attempt to add contact twice: %s", barejid_lower); } - handle_roster_received(); - - resource_presence_t conn_presence = accounts_get_login_presence(jabber_get_account_name()); - presence_update(conn_presence, NULL, 0); + g_free(barejid_lower); + item = xmpp_stanza_get_next(item); } + sv_ev_roster_received(); + + resource_presence_t conn_presence = accounts_get_login_presence(jabber_get_account_name()); + cl_ev_presence_send(conn_presence, NULL, 0); + return 1; } @@ -340,10 +343,10 @@ _get_groups_from_item(xmpp_stanza_t *item) GSList *groups = NULL; xmpp_stanza_t *group_element = xmpp_stanza_get_children(item); - while (group_element != NULL) { + while (group_element) { if (strcmp(xmpp_stanza_get_name(group_element), STANZA_NAME_GROUP) == 0) { char *groupname = xmpp_stanza_get_text(group_element); - if (groupname != NULL) { + if (groupname) { groups = g_slist_append(groups, groupname); } } diff --git a/src/xmpp/roster.h b/src/xmpp/roster.h index c29a674a..68811a5c 100644 --- a/src/xmpp/roster.h +++ b/src/xmpp/roster.h @@ -1,7 +1,7 @@ /* * roster.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 4f1d412d..1f25239b 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -1,7 +1,7 @@ /* * stanza.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -141,7 +141,7 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid, xmpp_stanza_set_attribute(conference, STANZA_ATTR_AUTOJOIN, "false"); } - if (nick != NULL) { + if (nick) { xmpp_stanza_t *nick_st = xmpp_stanza_new(ctx); xmpp_stanza_set_name(nick_st, STANZA_NAME_NICK); xmpp_stanza_set_text(nick_st, nick); @@ -199,6 +199,44 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid, #endif xmpp_stanza_t * +stanza_enable_carbons(xmpp_ctx_t *ctx){ + xmpp_stanza_t *iq = xmpp_stanza_new(ctx); + char *id = create_unique_id("carbons"); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_SET); + xmpp_stanza_set_id(iq, id); + free(id); + + xmpp_stanza_t *carbons_enable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(carbons_enable, STANZA_NAME_ENABLE); + xmpp_stanza_set_ns(carbons_enable, STANZA_NS_CARBONS); + + xmpp_stanza_add_child(iq, carbons_enable); + + return iq; +} + +xmpp_stanza_t * +stanza_disable_carbons(xmpp_ctx_t *ctx){ + xmpp_stanza_t *iq = xmpp_stanza_new(ctx); + char *id = create_unique_id("carbons"); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_SET); + xmpp_stanza_set_id(iq, id); + free(id); + + xmpp_stanza_t *carbons_disable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(carbons_disable, STANZA_NAME_DISABLE); + xmpp_stanza_set_ns(carbons_disable, STANZA_NS_CARBONS); + + xmpp_stanza_add_child(iq, carbons_disable); + + return iq; +} + +xmpp_stanza_t * stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state) { xmpp_stanza_t *msg, *chat_state; @@ -244,9 +282,44 @@ stanza_create_room_subject_message(xmpp_ctx_t *ctx, const char * const room, con } xmpp_stanza_t * -stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, - const char * const type, const char * const message, - const char * const state) +stanza_attach_state(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza, const char * const state) +{ + xmpp_stanza_t *chat_state = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(chat_state, state); + xmpp_stanza_set_ns(chat_state, STANZA_NS_CHATSTATES); + xmpp_stanza_add_child(stanza, chat_state); + xmpp_stanza_release(chat_state); + + return stanza; +} + +xmpp_stanza_t * +stanza_attach_carbons_private(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza) +{ + xmpp_stanza_t *private_carbon = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(private_carbon, "private"); + xmpp_stanza_set_ns(private_carbon, STANZA_NS_CARBONS); + xmpp_stanza_add_child(stanza, private_carbon); + xmpp_stanza_release(private_carbon); + + return stanza; +} + +xmpp_stanza_t * +stanza_attach_receipt_request(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza) +{ + xmpp_stanza_t *receipet_request = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(receipet_request, "request"); + xmpp_stanza_set_ns(receipet_request, STANZA_NS_RECEIPTS); + xmpp_stanza_add_child(stanza, receipet_request); + xmpp_stanza_release(receipet_request); + + return stanza; +} + +xmpp_stanza_t * +stanza_create_message(xmpp_ctx_t *ctx, char *id, const char * const recipient, + const char * const type, const char * const message) { xmpp_stanza_t *msg, *body, *text; @@ -254,9 +327,7 @@ stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, xmpp_stanza_set_name(msg, STANZA_NAME_MESSAGE); xmpp_stanza_set_type(msg, type); xmpp_stanza_set_attribute(msg, STANZA_ATTR_TO, recipient); - char *id = create_unique_id(NULL); xmpp_stanza_set_id(msg, id); - free(id); body = xmpp_stanza_new(ctx); xmpp_stanza_set_name(body, STANZA_NAME_BODY); @@ -268,14 +339,6 @@ stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, xmpp_stanza_add_child(msg, body); xmpp_stanza_release(body); - if (state != NULL) { - xmpp_stanza_t *chat_state = xmpp_stanza_new(ctx); - 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); - } - return msg; } @@ -311,7 +374,7 @@ stanza_create_roster_set(xmpp_ctx_t *ctx, const char * const id, xmpp_stanza_t *iq = xmpp_stanza_new(ctx); xmpp_stanza_set_name(iq, STANZA_NAME_IQ); xmpp_stanza_set_type(iq, STANZA_TYPE_SET); - if (id != NULL) { + if (id) { xmpp_stanza_set_id(iq, id); } @@ -323,13 +386,13 @@ stanza_create_roster_set(xmpp_ctx_t *ctx, const char * const id, xmpp_stanza_set_name(item, STANZA_NAME_ITEM); xmpp_stanza_set_attribute(item, STANZA_ATTR_JID, jid); - if (handle != NULL) { + if (handle) { xmpp_stanza_set_attribute(item, STANZA_ATTR_NAME, handle); } else { xmpp_stanza_set_attribute(item, STANZA_ATTR_NAME, ""); } - while (groups != NULL) { + while (groups) { xmpp_stanza_t *group = xmpp_stanza_new(ctx); xmpp_stanza_t *groupname = xmpp_stanza_new(ctx); xmpp_stanza_set_name(group, STANZA_NAME_GROUP); @@ -351,7 +414,7 @@ stanza_create_roster_set(xmpp_ctx_t *ctx, const char * const id, xmpp_stanza_t * stanza_create_invite(xmpp_ctx_t *ctx, const char * const room, - const char * const contact, const char * const reason) + const char * const contact, const char * const reason, const char * const password) { xmpp_stanza_t *message, *x; @@ -367,10 +430,53 @@ stanza_create_invite(xmpp_ctx_t *ctx, const char * const room, xmpp_stanza_set_ns(x, STANZA_NS_CONFERENCE); xmpp_stanza_set_attribute(x, STANZA_ATTR_JID, room); - if (reason != NULL) { + if (reason) { xmpp_stanza_set_attribute(x, STANZA_ATTR_REASON, reason); } + if (password) { + xmpp_stanza_set_attribute(x, STANZA_ATTR_PASSWORD, password); + } + + xmpp_stanza_add_child(message, x); + xmpp_stanza_release(x); + + return message; +} + +xmpp_stanza_t * +stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room, + const char * const contact, const char * const reason) +{ + xmpp_stanza_t *message, *x, *invite; + + message = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE); + xmpp_stanza_set_attribute(message, STANZA_ATTR_TO, room); + char *id = create_unique_id(NULL); + xmpp_stanza_set_id(message, id); + free(id); + + x = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(x, STANZA_NAME_X); + xmpp_stanza_set_ns(x, STANZA_NS_MUC_USER); + + invite = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(invite, STANZA_NAME_INVITE); + xmpp_stanza_set_attribute(invite, STANZA_ATTR_TO, contact); + + if (reason) { + xmpp_stanza_t *reason_st = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(reason_st, STANZA_NAME_REASON); + xmpp_stanza_t *reason_txt = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(reason_txt, reason); + xmpp_stanza_add_child(reason_st, reason_txt); + xmpp_stanza_release(reason_txt); + xmpp_stanza_add_child(invite, reason_st); + xmpp_stanza_release(reason_st); + } + xmpp_stanza_add_child(x, invite); + xmpp_stanza_release(invite); xmpp_stanza_add_child(message, x); xmpp_stanza_release(x); @@ -393,7 +499,7 @@ stanza_create_room_join_presence(xmpp_ctx_t * const ctx, xmpp_stanza_set_ns(x, STANZA_NS_MUC); // if a password was given - if (passwd != NULL) { + if (passwd) { xmpp_stanza_t *pass = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pass, "password"); xmpp_stanza_t *text = xmpp_stanza_new(ctx); @@ -787,7 +893,7 @@ stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const id, const char * xmpp_stanza_t *query = xmpp_stanza_new(ctx); xmpp_stanza_set_name(query, STANZA_NAME_QUERY); xmpp_stanza_set_ns(query, XMPP_NS_DISCO_INFO); - if (node != NULL) { + if (node) { xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node); } @@ -858,7 +964,7 @@ stanza_create_ping_iq(xmpp_ctx_t *ctx, const char * const target) xmpp_stanza_t *iq = xmpp_stanza_new(ctx); xmpp_stanza_set_name(iq, STANZA_NAME_IQ); xmpp_stanza_set_type(iq, STANZA_TYPE_GET); - if (target != NULL) { + if (target) { xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, target); } char *id = create_unique_id("ping"); @@ -881,11 +987,11 @@ stanza_get_delay(xmpp_stanza_t * const stanza, GTimeVal *tv_stamp) { // first check for XEP-0203 delayed delivery xmpp_stanza_t *delay = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_DELAY); - if (delay != NULL) { + if (delay) { char *xmlns = xmpp_stanza_get_attribute(delay, STANZA_ATTR_XMLNS); - if ((xmlns != NULL) && (strcmp(xmlns, "urn:xmpp:delay") == 0)) { + if (xmlns && (strcmp(xmlns, "urn:xmpp:delay") == 0)) { char *stamp = xmpp_stanza_get_attribute(delay, STANZA_ATTR_STAMP); - if ((stamp != NULL) && (g_time_val_from_iso8601(stamp, tv_stamp))) { + if (stamp && (g_time_val_from_iso8601(stamp, tv_stamp))) { return TRUE; } } @@ -894,11 +1000,11 @@ stanza_get_delay(xmpp_stanza_t * const stanza, GTimeVal *tv_stamp) // otherwise check for XEP-0091 legacy delayed delivery // stanp format : CCYYMMDDThh:mm:ss xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); - if (x != NULL) { + if (x) { char *xmlns = xmpp_stanza_get_attribute(x, STANZA_ATTR_XMLNS); - if ((xmlns != NULL) && (strcmp(xmlns, "jabber:x:delay") == 0)) { + if (xmlns && (strcmp(xmlns, "jabber:x:delay") == 0)) { char *stamp = xmpp_stanza_get_attribute(x, STANZA_ATTR_STAMP); - if ((stamp != NULL) && (g_time_val_from_iso8601(stamp, tv_stamp))) { + if (stamp && (g_time_val_from_iso8601(stamp, tv_stamp))) { return TRUE; } } @@ -914,17 +1020,17 @@ stanza_get_status(xmpp_stanza_t *stanza, char *def) xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS); - if (status != NULL) { + if (status) { // xmpp_free and free may be different functions so convert all to // libc malloc char *s1, *s2 = NULL; s1 = xmpp_stanza_get_text(status); - if (s1 != NULL) { + if (s1) { s2 = strdup(s1); xmpp_free(ctx, s1); } return s2; - } else if (def != NULL) { + } else if (def) { return strdup(def); } else { return NULL; @@ -938,17 +1044,17 @@ stanza_get_show(xmpp_stanza_t *stanza, char *def) xmpp_stanza_t *show = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_SHOW); - if (show != NULL) { + if (show) { // xmpp_free and free may be different functions so convert all to // libc malloc char *s1, *s2 = NULL; s1 = xmpp_stanza_get_text(show); - if (s1 != NULL) { + if (s1) { s2 = strdup(s1); xmpp_free(ctx, s1); } return s2; - } else if (def != NULL) { + } else if (def) { return strdup(def); } else { return NULL; @@ -984,7 +1090,7 @@ stanza_muc_requires_config(xmpp_stanza_t * const stanza) // muc user namespaced x element xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); - if (x != NULL) { + if (x) { // check for item element with owner affiliation xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, "item"); @@ -998,7 +1104,7 @@ stanza_muc_requires_config(xmpp_stanza_t * const stanza) // check for status code 201 xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); - while (x_children != NULL) { + while (x_children) { if (g_strcmp0(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (g_strcmp0(code, "201") == 0) { @@ -1240,11 +1346,11 @@ stanza_is_room_nick_change(xmpp_stanza_t * const stanza) // muc user namespaced x element xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); - if (x != NULL) { + if (x) { // check for status child element with 303 code xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); - while (x_children != NULL) { + while (x_children) { if (g_strcmp0(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (g_strcmp0(code, "303") == 0) { @@ -1268,7 +1374,7 @@ stanza_get_new_nick(xmpp_stanza_t * const stanza) xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); - while (x_children != NULL) { + while (x_children) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_ITEM) == 0) { char *nick = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_NICK); if (nick) { @@ -1382,9 +1488,9 @@ stanza_get_error_message(xmpp_stanza_t *stanza) xmpp_stanza_t *text_stanza = xmpp_stanza_get_child_by_name(error_stanza, STANZA_NAME_TEXT); // check for text - if (text_stanza != NULL) { + if (text_stanza) { gchar *err_msg = xmpp_stanza_get_text(text_stanza); - if (err_msg != NULL) { + if (err_msg) { char *result = strdup(err_msg); xmpp_free(ctx, err_msg); return result; @@ -1419,7 +1525,7 @@ stanza_get_error_message(xmpp_stanza_t *stanza) int i; for (i = 0; i < ARRAY_SIZE(defined_conditions); i++) { xmpp_stanza_t *cond_stanza = xmpp_stanza_get_child_by_name(error_stanza, defined_conditions[i]); - if (cond_stanza != NULL) { + if (cond_stanza) { char *result = strdup(xmpp_stanza_get_name(cond_stanza)); return result; } @@ -1456,7 +1562,7 @@ void stanza_attach_show(xmpp_ctx_t * const ctx, xmpp_stanza_t * const presence, const char * const show) { - if (show != NULL) { + if (show) { xmpp_stanza_t *show_stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(show_stanza, STANZA_NAME_SHOW); xmpp_stanza_t *text = xmpp_stanza_new(ctx); @@ -1472,7 +1578,7 @@ void stanza_attach_status(xmpp_ctx_t * const ctx, xmpp_stanza_t * const presence, const char * const status) { - if (status != NULL) { + if (status) { xmpp_stanza_t *status_stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(status_stanza, STANZA_NAME_STATUS); xmpp_stanza_t *text = xmpp_stanza_new(ctx); @@ -1619,9 +1725,9 @@ stanza_parse_presence(xmpp_stanza_t *stanza, int *err) result->priority = 0; xmpp_stanza_t *priority_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PRIORITY); - if (priority_stanza != NULL) { + if (priority_stanza) { char *priority_str = xmpp_stanza_get_text(priority_stanza); - if (priority_str != NULL) { + if (priority_str) { result->priority = atoi(priority_str); } free(priority_str); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 84282401..89dbda57 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -1,7 +1,7 @@ /* * stanza.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -77,6 +77,8 @@ #define STANZA_NAME_VALUE "value" #define STANZA_NAME_DESTROY "destroy" #define STANZA_NAME_ACTOR "actor" +#define STANZA_NAME_ENABLE "enable" +#define STANZA_NAME_DISABLE "disable" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -133,6 +135,7 @@ #define STANZA_ATTR_CATEGORY "category" #define STANZA_ATTR_REASON "reason" #define STANZA_ATTR_AUTOJOIN "autojoin" +#define STANZA_ATTR_PASSWORD "password" #define STANZA_TEXT_AWAY "away" #define STANZA_TEXT_DND "dnd" @@ -154,6 +157,9 @@ #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_NS_CARBONS "urn:xmpp:carbons:2" +#define STANZA_NS_FORWARD "urn:xmpp:forward:0" +#define STANZA_NS_RECEIPTS "urn:xmpp:receipts" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -178,12 +184,19 @@ typedef enum { xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx); +xmpp_stanza_t * stanza_enable_carbons(xmpp_ctx_t *ctx); + +xmpp_stanza_t * stanza_disable_carbons(xmpp_ctx_t *ctx); + xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state); -xmpp_stanza_t* stanza_create_message(xmpp_ctx_t *ctx, - const char * const recipient, const char * const type, - const char * const message, const char * const state); +xmpp_stanza_t * stanza_attach_state(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza, const char * const state); +xmpp_stanza_t * stanza_attach_carbons_private(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza); +xmpp_stanza_t * stanza_attach_receipt_request(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza); + +xmpp_stanza_t* stanza_create_message(xmpp_ctx_t *ctx, char *id, + const char * const recipient, const char * const type, const char * const message); xmpp_stanza_t* stanza_create_room_join_presence(xmpp_ctx_t * const ctx, const char * const full_room_jid, const char * const passwd); @@ -202,6 +215,8 @@ xmpp_stanza_t* stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char * const i const char * const to, const char * const node); xmpp_stanza_t* stanza_create_invite(xmpp_ctx_t *ctx, const char * const room, + const char * const contact, const char * const reason, const char * const password); +xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const room, const char * const contact, const char * const reason); gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index a004a4bf..398c9f46 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -1,7 +1,7 @@ /* * xmpp.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -145,7 +145,8 @@ char* jabber_get_account_name(void); GList * jabber_get_available_resources(void); // message functions -void message_send_chat(const char * const barejid, const char * const msg); +char* message_send_chat(const char * const barejid, const char * const msg); +char* message_send_chat_encrypted(const char * const barejid, const char * const msg); void message_send_private(const char * const fulljid, const char * const msg); void message_send_groupchat(const char * const roomjid, const char * const msg); void message_send_groupchat_subject(const char * const roomjid, const char * const subject); @@ -167,11 +168,13 @@ char * presence_sub_request_find(const char * const search_str); void presence_join_room(char *room, char *nick, char * passwd); void presence_change_room_nick(const char * const room, const char * const nick); void presence_leave_chat_room(const char * const room_jid); -void presence_update(resource_presence_t status, const char * const msg, +void presence_send(resource_presence_t status, const char * const msg, int idle); gboolean presence_sub_request_exists(const char * const bare_jid); // iq functions +void iq_enable_carbons(); +void iq_disable_carbons(); void iq_send_software_version(const char * const fulljid); void iq_room_list_request(gchar *conferencejid); void iq_disco_info_request(gchar *jid); @@ -189,7 +192,7 @@ void iq_send_caps_request_for_jid(const char * const to, const char * const id, const char * const node, const char * const ver); void iq_send_caps_request_legacy(const char * const to, const char * const id, const char * const node, const char * const ver); -void iq_room_info_request(gchar *room); +void iq_room_info_request(const char * const room, gboolean display_result); void iq_room_affiliation_list(const char * const room, char *affiliation); void iq_room_affiliation_set(const char * const room, const char * const jid, char *affiliation, const char * const reason); |