diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/command/commands.c | 31 | ||||
-rw-r--r-- | src/log.h | 2 | ||||
-rw-r--r-- | src/profanity.c | 372 | ||||
-rw-r--r-- | src/profanity.h | 56 | ||||
-rw-r--r-- | src/roster_list.c | 128 | ||||
-rw-r--r-- | src/roster_list.h | 6 | ||||
-rw-r--r-- | src/server_events.c | 375 | ||||
-rw-r--r-- | src/server_events.h | 76 | ||||
-rw-r--r-- | src/xmpp/connection.c | 13 | ||||
-rw-r--r-- | src/xmpp/iq.c | 9 | ||||
-rw-r--r-- | src/xmpp/message.c | 29 | ||||
-rw-r--r-- | src/xmpp/presence.c | 27 | ||||
-rw-r--r-- | src/xmpp/roster.c | 23 | ||||
-rw-r--r-- | src/xmpp/roster.h | 3 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 2 | ||||
-rw-r--r-- | tests/test_roster_list.c | 104 |
17 files changed, 630 insertions, 627 deletions
diff --git a/Makefile.am b/Makefile.am index e1905ad8..c9e4d9db 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,6 +25,7 @@ core_sources = \ src/xmpp/capabilities.h src/xmpp/connection.h \ src/xmpp/roster.c src/xmpp/roster.h \ src/xmpp/bookmark.c src/xmpp/bookmark.h \ + src/server_events.c src/server_events.h \ src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \ src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \ src/ui/console.c src/ui/notifier.c \ diff --git a/src/command/commands.c b/src/command/commands.c index 87cf7996..257abe61 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -402,7 +402,13 @@ cmd_disconnect(gchar **args, struct cmd_help_t help) { if (jabber_get_connection_status() == JABBER_CONNECTED) { char *jid = strdup(jabber_get_fulljid()); - prof_handle_disconnect(jid); + cons_show("%s logged out successfully.", jid); + jabber_disconnect(); + roster_clear(); + muc_clear_invites(); + chat_sessions_clear(); + ui_disconnected(); + ui_current_page_off(); free(jid); } else { cons_show("You are not currently connected."); @@ -1004,7 +1010,13 @@ cmd_group(gchar **args, struct cmd_help_t help) return TRUE; } - roster_add_to_group(group, barejid); + if (p_contact_in_group(pcontact, group)) { + const char *display_name = p_contact_name_or_jid(pcontact); + ui_contact_already_in_group(display_name, group); + ui_current_page_off(); + } else { + roster_send_add_to_group(group, pcontact); + } return TRUE; } @@ -1030,7 +1042,13 @@ cmd_group(gchar **args, struct cmd_help_t help) return TRUE; } - roster_remove_from_group(group, barejid); + if (!p_contact_in_group(pcontact, group)) { + const char *display_name = p_contact_name_or_jid(pcontact); + ui_contact_not_in_group(display_name, group); + ui_current_page_off(); + } else { + roster_send_remove_from_group(group, pcontact); + } return TRUE; } @@ -1067,7 +1085,7 @@ cmd_roster(gchar **args, struct cmd_help_t help) char *jid = args[1]; char *name = args[2]; - roster_add_new(jid, name); + roster_send_add_new(jid, name); return TRUE; } @@ -1105,7 +1123,10 @@ cmd_roster(gchar **args, struct cmd_help_t help) return TRUE; } - roster_change_name(jid, name); + const char *barejid = p_contact_barejid(contact); + roster_change_name(contact, name); + GSList *groups = p_contact_groups(contact); + roster_send_name_change(barejid, name, groups); if (name == NULL) { cons_show("Nickname for %s removed.", jid); diff --git a/src/log.h b/src/log.h index 25cbd1bb..3d0b3bae 100644 --- a/src/log.h +++ b/src/log.h @@ -23,6 +23,8 @@ #ifndef LOG_H #define LOG_H +#include "glib.h" + // log levels typedef enum { PROF_LEVEL_DEBUG, diff --git a/src/profanity.c b/src/profanity.c index 486402e3..b4149d3a 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -118,349 +118,6 @@ prof_run(const int disable_tls, char *log_level, char *account_name) } void -prof_handle_typing(char *from) -{ - ui_contact_typing(from); - ui_current_page_off(); -} - -void -prof_handle_incoming_message(char *from, char *message, gboolean priv) -{ - ui_incoming_msg(from, message, NULL, priv); - ui_current_page_off(); - - if (prefs_get_boolean(PREF_CHLOG) && !priv) { - Jid *from_jid = jid_create(from); - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, NULL); - jid_destroy(jidp); - jid_destroy(from_jid); - } -} - -void -prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, - gboolean priv) -{ - ui_incoming_msg(from, message, &tv_stamp, priv); - ui_current_page_off(); - - if (prefs_get_boolean(PREF_CHLOG) && !priv) { - Jid *from_jid = jid_create(from); - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, &tv_stamp); - jid_destroy(jidp); - jid_destroy(from_jid); - } -} - -void -prof_handle_duck_result(const char * const result) -{ - ui_duck_result(result); - ui_current_page_off(); -} - -void -prof_handle_already_in_group(const char * const contact, - const char * const group) -{ - ui_contact_already_in_group(contact, group); - ui_current_page_off(); -} - -void -prof_handle_not_in_group(const char * const contact, - const char * const group) -{ - ui_contact_not_in_group(contact, group); - ui_current_page_off(); -} - -void -prof_handle_group_add(const char * const contact, - const char * const group) -{ - ui_group_added(contact, group); - ui_current_page_off(); -} - -void -prof_handle_group_remove(const char * const contact, - const char * const group) -{ - ui_group_removed(contact, group); - ui_current_page_off(); -} - -void -prof_handle_error_message(const char *from, const char *err_msg) -{ - ui_handle_error_message(from, err_msg); - - if (g_strcmp0(err_msg, "conflict") == 0) { - // remove the room from muc - Jid *room_jid = jid_create(from); - if (!muc_get_roster_received(room_jid->barejid)) { - muc_leave_room(room_jid->barejid); - } - jid_destroy(room_jid); - } -} - -void -prof_handle_subscription(const char *from, jabber_subscr_t type) -{ - switch (type) { - case PRESENCE_SUBSCRIBE: - /* TODO: auto-subscribe if needed */ - cons_show("Received authorization request from %s", from); - log_info("Received authorization request from %s", from); - ui_print_system_msg_from_recipient(from, "Authorization request, type '/sub allow' to accept or '/sub deny' to reject"); - ui_current_page_off(); - if (prefs_get_boolean(PREF_NOTIFY_SUB)) { - notify_subscription(from); - } - break; - case PRESENCE_SUBSCRIBED: - cons_show("Subscription received from %s", from); - log_info("Subscription received from %s", from); - ui_print_system_msg_from_recipient(from, "Subscribed"); - ui_current_page_off(); - break; - case PRESENCE_UNSUBSCRIBED: - cons_show("%s deleted subscription", from); - log_info("%s deleted subscription", from); - ui_print_system_msg_from_recipient(from, "Unsubscribed"); - ui_current_page_off(); - break; - default: - /* unknown type */ - break; - } -} - -void -prof_handle_roster_add(const char * const barejid, const char * const name) -{ - ui_roster_add(barejid, name); - ui_current_page_off(); -} - -void -prof_handle_roster_remove(const char * const barejid) -{ - ui_roster_remove(barejid); - ui_current_page_off(); -} - -void -prof_handle_login_account_success(char *account_name) -{ - ProfAccount *account = accounts_get_account(account_name); - resource_presence_t resource_presence = accounts_get_login_presence(account->name); - contact_presence_t contact_presence = contact_presence_from_resource_presence(resource_presence); - cons_show_login_success(account); - title_bar_set_status(contact_presence); - log_info("%s logged in successfully", account->jid); - ui_current_page_off(); - status_bar_print_message(account->jid); - status_bar_refresh(); - - accounts_free_account(account); -} - -void -prof_handle_gone(const char * const from) -{ - ui_recipient_gone(from); - ui_current_page_off(); -} - -void -prof_handle_failed_login(void) -{ - cons_show_error("Login failed."); - log_info("Login failed"); - ui_current_page_off(); -} - -void -prof_handle_lost_connection(void) -{ - cons_show_error("Lost connection."); - roster_clear(); - muc_clear_invites(); - chat_sessions_clear(); - ui_disconnected(); - ui_current_page_off(); -} - -void -prof_handle_disconnect(const char * const jid) -{ - cons_show("%s logged out successfully.", jid); - jabber_disconnect(); - roster_clear(); - muc_clear_invites(); - chat_sessions_clear(); - ui_disconnected(); - ui_current_page_off(); -} - -void -prof_handle_room_history(const char * const room_jid, const char * const nick, - GTimeVal tv_stamp, const char * const message) -{ - ui_room_history(room_jid, nick, tv_stamp, message); - ui_current_page_off(); -} - -void -prof_handle_room_message(const char * const room_jid, const char * const nick, - const char * const message) -{ - ui_room_message(room_jid, nick, message); - ui_current_page_off(); - - if (prefs_get_boolean(PREF_GRLOG)) { - Jid *jid = jid_create(jabber_get_fulljid()); - groupchat_log_chat(jid->barejid, room_jid, nick, message); - jid_destroy(jid); - } -} - -void -prof_handle_room_subject(const char * const room_jid, const char * const subject) -{ - ui_room_subject(room_jid, subject); - ui_current_page_off(); -} - -void -prof_handle_room_broadcast(const char *const room_jid, - const char * const message) -{ - ui_room_broadcast(room_jid, message); - ui_current_page_off(); -} - -void -prof_handle_room_roster_complete(const char * const room) -{ - muc_set_roster_received(room); - GList *roster = muc_get_roster(room); - ui_room_roster(room, roster, NULL); - ui_current_page_off(); -} - -void -prof_handle_room_member_presence(const char * const room, - const char * const nick, const char * const show, - const char * const status, const char * const caps_str) -{ - gboolean updated = muc_add_to_roster(room, nick, show, status, caps_str); - - if (updated) { - ui_room_member_presence(room, nick, show, status); - ui_current_page_off(); - } -} - -void -prof_handle_room_member_online(const char * const room, const char * const nick, - const char * const show, const char * const status, - const char * const caps_str) -{ - muc_add_to_roster(room, nick, show, status, caps_str); - ui_room_member_online(room, nick, show, status); - ui_current_page_off(); -} - -void -prof_handle_room_member_offline(const char * const room, const char * const nick, - const char * const show, const char * const status) -{ - muc_remove_from_roster(room, nick); - ui_room_member_offline(room, nick); - ui_current_page_off(); -} - -void -prof_handle_leave_room(const char * const room) -{ - muc_leave_room(room); -} - -void prof_handle_room_invite(jabber_invite_t invite_type, - const char * const invitor, const char * const room, - const char * const reason) -{ - Jid *room_jid = jid_create(room); - if (!muc_room_is_active(room_jid) && !muc_invites_include(room)) { - cons_show_room_invite(invitor, room, reason); - muc_add_invite(room); - ui_current_page_off(); - } - jid_destroy(room_jid); -} - -void -prof_handle_contact_online(char *contact, Resource *resource, - GDateTime *last_activity) -{ - gboolean updated = roster_update_presence(contact, resource, last_activity); - - if (updated && prefs_get_boolean(PREF_STATUSES)) { - PContact result = roster_get_contact(contact); - if (p_contact_subscription(result) != NULL) { - if (strcmp(p_contact_subscription(result), "none") != 0) { - const char *show = string_from_resource_presence(resource->presence); - ui_contact_online(contact, resource->name, show, resource->status, last_activity); - ui_current_page_off(); - } - } - } -} - -void -prof_handle_contact_offline(char *contact, char *resource, char *status) -{ - gboolean updated = roster_contact_offline(contact, resource, status); - - if (resource != NULL && updated && prefs_get_boolean(PREF_STATUSES)) { - Jid *jid = jid_create_from_bare_and_resource(contact, resource); - PContact result = roster_get_contact(contact); - if (p_contact_subscription(result) != NULL) { - if (strcmp(p_contact_subscription(result), "none") != 0) { - ui_contact_offline(jid->fulljid, "offline", status); - ui_current_page_off(); - } - } - jid_destroy(jid); - } -} - -void -prof_handle_room_member_nick_change(const char * const room, - const char * const old_nick, const char * const nick) -{ - ui_room_member_nick_change(room, old_nick, nick); - ui_current_page_off(); -} - -void -prof_handle_room_nick_change(const char * const room, - const char * const nick) -{ - ui_room_nick_change(room, nick); - ui_current_page_off(); -} - -void prof_handle_idle(void) { jabber_conn_status_t status = jabber_get_connection_status(); @@ -509,35 +166,6 @@ prof_handle_activity(void) } } -void -prof_handle_version_result(const char * const jid, const char * const presence, - const char * const name, const char * const version, const char * const os) -{ - cons_show_software_version(jid, presence, name, version, os); - ui_current_page_off(); -} - -void -prof_handle_room_list(GSList *rooms, const char *conference_node) -{ - cons_show_room_list(rooms, conference_node); - ui_current_page_off(); -} - -void -prof_handle_disco_items(GSList *items, const char *jid) -{ - cons_show_disco_items(items, jid); - ui_current_page_off(); -} - -void -prof_handle_disco_info(const char *from, GSList *identities, GSList *features) -{ - cons_show_disco_info(from, identities, features); - ui_current_page_off(); -} - /* * Take a line of input and process it, return TRUE if profanity is to * continue, FALSE otherwise diff --git a/src/profanity.h b/src/profanity.h index 3dac6c3e..c55e6c47 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -28,63 +28,7 @@ void prof_run(const int disable_tls, char *log_level, char *account_name); -void prof_handle_login_success(const char *jid, const char *altdomain); -void prof_handle_login_account_success(char *account_name); -void prof_handle_lost_connection(void); -void prof_handle_disconnect(const char * const jid); -void prof_handle_failed_login(void); -void prof_handle_typing(char *from); -void prof_handle_contact_online(char *contact, Resource *resource, - GDateTime *last_activity); -void prof_handle_contact_offline(char *contact, char *show, char *status); -void prof_handle_incoming_message(char *from, char *message, gboolean priv); -void prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, - gboolean priv); -void prof_handle_error_message(const char *from, const char *err_msg); -void prof_handle_subscription(const char *from, jabber_subscr_t type); -void prof_handle_roster(GSList *roster); -void prof_handle_gone(const char * const from); -void prof_handle_room_history(const char * const room_jid, - const char * const nick, GTimeVal tv_stamp, const char * const message); -void prof_handle_room_message(const char * const room_jid, const char * const nick, - const char * const message); -void prof_handle_room_subject(const char * const room_jid, - const char * const subject); -void prof_handle_room_roster_complete(const char * const room); -void prof_handle_room_member_online(const char * const room, - const char * const nick, const char * const show, const char * const status, - const char * const caps_str); -void prof_handle_room_member_offline(const char * const room, - const char * const nick, const char * const show, const char * const status); -void prof_handle_room_member_presence(const char * const room, - const char * const nick, const char * const show, - const char * const status, const char * const caps_str); -void prof_handle_leave_room(const char * const room); -void prof_handle_room_member_nick_change(const char * const room, - const char * const old_nick, const char * const nick); -void prof_handle_room_nick_change(const char * const room, - const char * const nick); -void prof_handle_room_broadcast(const char *const room_jid, - const char * const message); -void prof_handle_room_invite(jabber_invite_t invite_type, - const char * const invitor, const char * const room, - const char * const reason); void prof_handle_idle(void); void prof_handle_activity(void); -void prof_handle_version_result(const char * const jid, - const char * const presence, const char * const name, - const char * const version, const char * const os); -void prof_handle_room_list(GSList *rooms, const char *conference_node); -void prof_handle_disco_items(GSList *items, const char *jid); -void prof_handle_disco_info(const char *from, GSList *identities, - GSList *features); -void prof_handle_duck_help(const char * const result); -void prof_handle_duck_result(const char * const result); -void prof_handle_roster_add(const char * const barejid, const char * const name); -void prof_handle_roster_remove(const char * const barejid); -void prof_handle_already_in_group(const char * const contact, const char * const group); -void prof_handle_not_in_group(const char * const contact, const char * const group); -void prof_handle_group_add(const char * const contact, const char * const group); -void prof_handle_group_remove(const char * const contact, const char * const group); #endif diff --git a/src/roster_list.c b/src/roster_list.c index fa00437b..1341320f 100644 --- a/src/roster_list.c +++ b/src/roster_list.c @@ -30,8 +30,6 @@ #include "contact.h" #include "jid.h" #include "tools/autocomplete.h" -#include "xmpp/xmpp.h" -#include "profanity.h" // nicknames static Autocomplete name_ac; @@ -157,21 +155,19 @@ roster_free(void) } void -roster_change_name(const char * const barejid, const char * const new_name) +roster_change_name(PContact contact, const char * const new_name) { - PContact contact = g_hash_table_lookup(contacts, barejid); - const char * current_name = NULL; + assert(contact != NULL); + + const char *current_name = NULL; + const char *barejid = p_contact_barejid(contact); + if (p_contact_name(contact) != NULL) { current_name = strdup(p_contact_name(contact)); } - if (contact != NULL) { - p_contact_set_name(contact, new_name); - _replace_name(current_name, new_name, barejid); - - GSList *groups = p_contact_groups(contact); - roster_send_name_change(barejid, new_name, groups); - } + p_contact_set_name(contact, new_name); + _replace_name(current_name, new_name, barejid); } void @@ -204,60 +200,51 @@ roster_update(const char * const barejid, const char * const name, GSList *groups, const char * const subscription, gboolean pending_out) { PContact contact = g_hash_table_lookup(contacts, barejid); + assert(contact != NULL); - if (contact == NULL) { - roster_add(barejid, name, groups, subscription, pending_out, FALSE); - } else { - p_contact_set_subscription(contact, subscription); - p_contact_set_pending_out(contact, pending_out); + p_contact_set_subscription(contact, subscription); + p_contact_set_pending_out(contact, pending_out); - const char * const new_name = name; - const char * current_name = NULL; - if (p_contact_name(contact) != NULL) { - current_name = strdup(p_contact_name(contact)); - } + const char * const new_name = name; + const char * current_name = NULL; + if (p_contact_name(contact) != NULL) { + current_name = strdup(p_contact_name(contact)); + } - p_contact_set_name(contact, new_name); - p_contact_set_groups(contact, groups); - _replace_name(current_name, new_name, barejid); + p_contact_set_name(contact, new_name); + p_contact_set_groups(contact, groups); + _replace_name(current_name, new_name, barejid); - // add groups - while (groups != NULL) { - autocomplete_add(groups_ac, groups->data); - groups = g_slist_next(groups); - } + // add groups + while (groups != NULL) { + autocomplete_add(groups_ac, groups->data); + groups = g_slist_next(groups); } } gboolean roster_add(const char * const barejid, const char * const name, GSList *groups, - const char * const subscription, gboolean pending_out, gboolean from_initial) + const char * const subscription, gboolean pending_out) { - gboolean added = FALSE; PContact contact = g_hash_table_lookup(contacts, barejid); + if (contact != NULL) { + return FALSE; + } - if (contact == NULL) { - contact = p_contact_new(barejid, name, groups, subscription, NULL, - pending_out); - - // add groups - while (groups != NULL) { - autocomplete_add(groups_ac, groups->data); - groups = g_slist_next(groups); - } - - g_hash_table_insert(contacts, strdup(barejid), contact); - autocomplete_add(barejid_ac, barejid); - _add_name_and_barejid(name, barejid); + contact = p_contact_new(barejid, name, groups, subscription, NULL, + pending_out); - if (!from_initial) { - prof_handle_roster_add(barejid, name); - } - - added = TRUE; + // add groups + while (groups != NULL) { + autocomplete_add(groups_ac, groups->data); + groups = g_slist_next(groups); } - return added; + g_hash_table_insert(contacts, strdup(barejid), contact); + autocomplete_add(barejid_ac, barejid); + _add_name_and_barejid(name, barejid); + + return TRUE; } char * @@ -337,45 +324,6 @@ roster_get_group(const char * const group) return result; } -void -roster_add_to_group(const char * const group, const char * const barejid) -{ - PContact contact = g_hash_table_lookup(contacts, barejid); - - if (contact != NULL) { - if (p_contact_in_group(contact, group)) { - if (p_contact_name(contact) != NULL) { - prof_handle_already_in_group(p_contact_name(contact), group); - } else { - prof_handle_already_in_group(p_contact_barejid(contact), group); - } - return; - } - - roster_send_add_to_group(group, contact); - - } -} - -void -roster_remove_from_group(const char * const group, const char * const barejid) -{ - PContact contact = g_hash_table_lookup(contacts, barejid); - - if (contact != NULL) { - if (!p_contact_in_group(contact, group)) { - if (p_contact_name(contact) != NULL) { - prof_handle_not_in_group(p_contact_name(contact), group); - } else { - prof_handle_not_in_group(p_contact_barejid(contact), group); - } - return; - } - - roster_send_remove_from_group(group, contact); - } -} - GSList * roster_get_groups(void) { diff --git a/src/roster_list.h b/src/roster_list.h index 9382081b..58490609 100644 --- a/src/roster_list.h +++ b/src/roster_list.h @@ -37,12 +37,12 @@ gboolean roster_contact_offline(const char * const barejid, void roster_reset_search_attempts(void); void roster_init(void); void roster_free(void); -void roster_change_name(const char * const barejid, const char * const new_name); +void roster_change_name(PContact contact, const char * const new_name); void roster_remove(const char * const name, const char * const barejid); void roster_update(const char * const barejid, const char * const name, GSList *groups, const char * const subscription, gboolean pending_out); gboolean roster_add(const char * const barejid, const char * const name, GSList *groups, - const char * const subscription, gboolean pending_out, gboolean from_initial); + const char * const subscription, gboolean pending_out); char * roster_barejid_from_name(const char * const name); GSList * roster_get_contacts(void); gboolean roster_has_pending_subscriptions(void); @@ -50,8 +50,6 @@ char * roster_find_contact(char *search_str); char * roster_find_resource(char *search_str); GSList * roster_get_group(const char * const group); GSList * roster_get_groups(void); -void roster_add_to_group(const char * const group, const char * const barejid); -void roster_remove_from_group(const char * const group, const char * const barejid); char * roster_find_group(char *search_str); char * roster_find_jid(char *search_str); diff --git a/src/server_events.c b/src/server_events.c new file mode 100644 index 00000000..ac940c86 --- /dev/null +++ b/src/server_events.c @@ -0,0 +1,375 @@ +/* + * server_events.c + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include "chat_session.h" +#include "log.h" +#include "muc.h" +#include "config/preferences.h" +#include "roster_list.h" +#include "ui/ui.h" + +void +handle_error_message(const char *from, const char *err_msg) +{ + ui_handle_error_message(from, err_msg); + + if (g_strcmp0(err_msg, "conflict") == 0) { + // remove the room from muc + Jid *room_jid = jid_create(from); + if (!muc_get_roster_received(room_jid->barejid)) { + muc_leave_room(room_jid->barejid); + } + jid_destroy(room_jid); + } +} + +void +handle_login_account_success(char *account_name) +{ + ProfAccount *account = accounts_get_account(account_name); + resource_presence_t resource_presence = accounts_get_login_presence(account->name); + contact_presence_t contact_presence = contact_presence_from_resource_presence(resource_presence); + cons_show_login_success(account); + title_bar_set_status(contact_presence); + log_info("%s logged in successfully", account->jid); + ui_current_page_off(); + status_bar_print_message(account->jid); + status_bar_refresh(); + + accounts_free_account(account); +} + +void +handle_lost_connection(void) +{ + cons_show_error("Lost connection."); + roster_clear(); + muc_clear_invites(); + chat_sessions_clear(); + ui_disconnected(); + ui_current_page_off(); +} + +void +handle_failed_login(void) +{ + cons_show_error("Login failed."); + log_info("Login failed"); + ui_current_page_off(); +} + +void +handle_software_version_result(const char * const jid, const char * const presence, + const char * const name, const char * const version, const char * const os) +{ + cons_show_software_version(jid, presence, name, version, os); + ui_current_page_off(); +} + +void +handle_disco_info(const char *from, GSList *identities, GSList *features) +{ + cons_show_disco_info(from, identities, features); + ui_current_page_off(); +} + +void +handle_room_list(GSList *rooms, const char *conference_node) +{ + cons_show_room_list(rooms, conference_node); + ui_current_page_off(); +} + +void +handle_disco_items(GSList *items, const char *jid) +{ + cons_show_disco_items(items, jid); + ui_current_page_off(); +} + +void +handle_room_invite(jabber_invite_t invite_type, + const char * const invitor, const char * const room, + const char * const reason) +{ + Jid *room_jid = jid_create(room); + if (!muc_room_is_active(room_jid) && !muc_invites_include(room)) { + cons_show_room_invite(invitor, room, reason); + muc_add_invite(room); + ui_current_page_off(); + } + jid_destroy(room_jid); +} + +void +handle_room_broadcast(const char *const room_jid, + const char * const message) +{ + ui_room_broadcast(room_jid, message); + ui_current_page_off(); +} + +void +handle_room_subject(const char * const room_jid, const char * const subject) +{ + ui_room_subject(room_jid, subject); + ui_current_page_off(); +} + +void +handle_room_history(const char * const room_jid, const char * const nick, + GTimeVal tv_stamp, const char * const message) +{ + ui_room_history(room_jid, nick, tv_stamp, message); + ui_current_page_off(); +} + +void +handle_room_message(const char * const room_jid, const char * const nick, + const char * const message) +{ + ui_room_message(room_jid, nick, message); + ui_current_page_off(); + + if (prefs_get_boolean(PREF_GRLOG)) { + Jid *jid = jid_create(jabber_get_fulljid()); + groupchat_log_chat(jid->barejid, room_jid, nick, message); + jid_destroy(jid); + } +} + +void +handle_duck_result(const char * const result) +{ + ui_duck_result(result); + ui_current_page_off(); +} + +void +handle_incoming_message(char *from, char *message, gboolean priv) +{ + ui_incoming_msg(from, message, NULL, priv); + ui_current_page_off(); + + if (prefs_get_boolean(PREF_CHLOG) && !priv) { + Jid *from_jid = jid_create(from); + const char *jid = jabber_get_fulljid(); + Jid *jidp = jid_create(jid); + chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, NULL); + jid_destroy(jidp); + jid_destroy(from_jid); + } +} + +void +handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, + gboolean priv) +{ + ui_incoming_msg(from, message, &tv_stamp, priv); + ui_current_page_off(); + + if (prefs_get_boolean(PREF_CHLOG) && !priv) { + Jid *from_jid = jid_create(from); + const char *jid = jabber_get_fulljid(); + Jid *jidp = jid_create(jid); + chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, &tv_stamp); + jid_destroy(jidp); + jid_destroy(from_jid); + } +} + +void +handle_typing(char *from) +{ + ui_contact_typing(from); + ui_current_page_off(); +} + +void +handle_gone(const char * const from) +{ + ui_recipient_gone(from); + ui_current_page_off(); +} + +void +handle_subscription(const char *from, jabber_subscr_t type) +{ + switch (type) { + case PRESENCE_SUBSCRIBE: + /* TODO: auto-subscribe if needed */ + cons_show("Received authorization request from %s", from); + log_info("Received authorization request from %s", from); + ui_print_system_msg_from_recipient(from, "Authorization request, type '/sub allow' to accept or '/sub deny' to reject"); + ui_current_page_off(); + if (prefs_get_boolean(PREF_NOTIFY_SUB)) { + notify_subscription(from); + } + break; + case PRESENCE_SUBSCRIBED: + cons_show("Subscription received from %s", from); + log_info("Subscription received from %s", from); + ui_print_system_msg_from_recipient(from, "Subscribed"); + ui_current_page_off(); + break; + case PRESENCE_UNSUBSCRIBED: + cons_show("%s deleted subscription", from); + log_info("%s deleted subscription", from); + ui_print_system_msg_from_recipient(from, "Unsubscribed"); + ui_current_page_off(); + break; + default: + /* unknown type */ + break; + } +} + +void +handle_contact_offline(char *contact, char *resource, char *status) +{ + gboolean updated = roster_contact_offline(contact, resource, status); + + if (resource != NULL && updated && prefs_get_boolean(PREF_STATUSES)) { + Jid *jid = jid_create_from_bare_and_resource(contact, resource); + PContact result = roster_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + ui_contact_offline(jid->fulljid, "offline", status); + ui_current_page_off(); + } + } + jid_destroy(jid); + } +} + +void +handle_contact_online(char *contact, Resource *resource, + GDateTime *last_activity) +{ + gboolean updated = roster_update_presence(contact, resource, last_activity); + + if (updated && prefs_get_boolean(PREF_STATUSES)) { + PContact result = roster_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + const char *show = string_from_resource_presence(resource->presence); + ui_contact_online(contact, resource->name, show, resource->status, last_activity); + ui_current_page_off(); + } + } + } +} + +void +handle_leave_room(const char * const room) +{ + muc_leave_room(room); +} + +void +handle_room_nick_change(const char * const room, + const char * const nick) +{ + ui_room_nick_change(room, nick); + ui_current_page_off(); +} + +void +handle_room_roster_complete(const char * const room) +{ + muc_set_roster_received(room); + GList *roster = muc_get_roster(room); + ui_room_roster(room, roster, NULL); + ui_current_page_off(); +} + +void +handle_room_member_presence(const char * const room, + const char * const nick, const char * const show, + const char * const status, const char * const caps_str) +{ + gboolean updated = muc_add_to_roster(room, nick, show, status, caps_str); + + if (updated) { + ui_room_member_presence(room, nick, show, status); + ui_current_page_off(); + } +} + +void +handle_room_member_online(const char * const room, const char * const nick, + const char * const show, const char * const status, + const char * const caps_str) +{ + muc_add_to_roster(room, nick, show, status, caps_str); + ui_room_member_online(room, nick, show, status); + ui_current_page_off(); +} + +void +handle_room_member_offline(const char * const room, const char * const nick, + const char * const show, const char * const status) +{ + muc_remove_from_roster(room, nick); + ui_room_member_offline(room, nick); + ui_current_page_off(); +} + +void +handle_room_member_nick_change(const char * const room, + const char * const old_nick, const char * const nick) +{ + ui_room_member_nick_change(room, old_nick, nick); + ui_current_page_off(); +} + +void +handle_group_add(const char * const contact, + const char * const group) +{ + ui_group_added(contact, group); + ui_current_page_off(); +} + +void +handle_group_remove(const char * const contact, + const char * const group) +{ + ui_group_removed(contact, group); + ui_current_page_off(); +} + +void +handle_roster_remove(const char * const barejid) +{ + ui_roster_remove(barejid); + ui_current_page_off(); +} + +void +handle_roster_add(const char * const barejid, const char * const name) +{ + ui_roster_add(barejid, name); + ui_current_page_off(); +} diff --git a/src/server_events.h b/src/server_events.h new file mode 100644 index 00000000..ce3c3b49 --- /dev/null +++ b/src/server_events.h @@ -0,0 +1,76 @@ +/* + * server_events.h + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef SERVER_EVENTS_H +#define SERVER_EVENTS_H + +void handle_error_message(const char *from, const char *err_msg); +void handle_login_account_success(char *account_name); +void handle_lost_connection(void); +void handle_failed_login(void); +void handle_software_version_result(const char * const jid, const char * const presence, + const char * const name, const char * const version, const char * const os); +void handle_disco_info(const char *from, GSList *identities, GSList *features); +void handle_room_list(GSList *rooms, const char *conference_node); +void handle_disco_items(GSList *items, const char *jid); +void handle_room_invite(jabber_invite_t invite_type, + const char * const invitor, const char * const room, + const char * const reason); +void handle_room_broadcast(const char *const room_jid, + const char * const message); +void handle_room_subject(const char * const room_jid, const char * const subject); +void handle_room_history(const char * const room_jid, const char * const nick, + GTimeVal tv_stamp, const char * const message); +void handle_room_message(const char * const room_jid, const char * const nick, + const char * const message); +void handle_duck_result(const char * const result); +void handle_incoming_message(char *from, char *message, gboolean priv); +void handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, + gboolean priv); +void handle_typing(char *from); +void handle_gone(const char * const from); +void handle_subscription(const char *from, jabber_subscr_t type); +void handle_contact_offline(char *contact, char *resource, char *status); +void handle_contact_online(char *contact, Resource *resource, + GDateTime *last_activity); +void handle_leave_room(const char * const room); +void handle_room_nick_change(const char * const room, + const char * const nick); +void handle_room_roster_complete(const char * const room); +void handle_room_member_presence(const char * const room, + const char * const nick, const char * const show, + const char * const status, const char * const caps_str); +void handle_room_member_online(const char * const room, const char * const nick, + const char * const show, const char * const status, + const char * const caps_str); +void handle_room_member_offline(const char * const room, const char * const nick, + const char * const show, const char * const status); +void handle_room_member_nick_change(const char * const room, + const char * const old_nick, const char * const nick); +void handle_group_add(const char * const contact, + const char * const group); +void handle_group_remove(const char * const contact, + const char * const group); +void handle_roster_remove(const char * const barejid); +void handle_roster_add(const char * const barejid, const char * const name); + +#endif diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index f38da800..ad447767 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -33,6 +33,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "server_events.h" #include "xmpp/bookmark.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" @@ -349,7 +350,7 @@ connection_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (text_stanza != NULL) { err_msg = xmpp_stanza_get_text(text_stanza); if (err_msg != NULL) { - prof_handle_error_message(from, err_msg); + handle_error_message(from, err_msg); xmpp_free(ctx, err_msg); } @@ -364,7 +365,7 @@ connection_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } else { err_msg = xmpp_stanza_get_name(err_cond); - prof_handle_error_message(from, err_msg); + handle_error_message(from, err_msg); // TODO : process 'type' attribute from <error/> [RFC6120, 8.3.2] } @@ -462,7 +463,7 @@ _connection_handler(xmpp_conn_t * const conn, // logged in with account if (saved_account.name != NULL) { log_debug("Connection handler: logged in with account name: %s", saved_account.name); - prof_handle_login_account_success(saved_account.name); + handle_login_account_success(saved_account.name); // logged in without account, use details to create new account } else { @@ -470,7 +471,7 @@ _connection_handler(xmpp_conn_t * const conn, accounts_add(saved_details.name, saved_details.altdomain); accounts_set_jid(saved_details.name, saved_details.jid); - prof_handle_login_account_success(saved_details.name); + handle_login_account_success(saved_details.name); saved_account.name = strdup(saved_details.name); saved_account.passwd = strdup(saved_details.passwd); @@ -511,7 +512,7 @@ _connection_handler(xmpp_conn_t * const conn, // lost connection for unkown reason if (jabber_conn.conn_status == JABBER_CONNECTED) { log_debug("Connection handler: Lost connection for unknown reason"); - prof_handle_lost_connection(); + handle_lost_connection(); if (prefs_get_reconnect() != 0) { assert(reconnect_timer == NULL); reconnect_timer = g_timer_new(); @@ -528,7 +529,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"); - prof_handle_failed_login(); + handle_failed_login(); _connection_free_saved_account(); _connection_free_saved_details(); _connection_free_session_data(); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 369d7f7e..3e598c10 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -35,6 +35,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "server_events.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" @@ -173,7 +174,7 @@ _iq_handle_version_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza Resource *resource = p_contact_get_resource(contact, jidp->resourcepart); const char *presence = string_from_resource_presence(resource->presence); - prof_handle_version_result(jid, presence, name_str, version_str, os_str); + handle_software_version_result(jid, presence, name_str, version_str, os_str); jid_destroy(jidp); @@ -402,7 +403,7 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan child = xmpp_stanza_get_next(child); } - prof_handle_disco_info(from, identities, features); + handle_disco_info(from, identities, features); g_slist_free_full(features, free); g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); } @@ -558,9 +559,9 @@ _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const sta } if (g_strcmp0(id, "confreq") == 0) { - prof_handle_room_list(items, from); + handle_room_list(items, from); } else if (g_strcmp0(id, "discoitemsreq") == 0) { - prof_handle_disco_items(items, from); + handle_disco_items(items, from); } g_slist_free_full(items, (GDestroyNotify)_item_destroy); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 482a3965..09e1fdc2 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -30,6 +30,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "server_events.h" #include "xmpp/connection.h" #include "xmpp/message.h" #include "xmpp/roster.h" @@ -222,7 +223,7 @@ _conference_message_handler(xmpp_conn_t * const conn, reason = xmpp_stanza_get_text(reason_st); } - prof_handle_room_invite(INVITE_MEDIATED, invitor, room, reason); + handle_room_invite(INVITE_MEDIATED, invitor, room, reason); jid_destroy(jidp); if (reason != NULL) { xmpp_free(ctx, reason); @@ -243,7 +244,7 @@ _conference_message_handler(xmpp_conn_t * const conn, reason = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_REASON); - prof_handle_room_invite(INVITE_DIRECT, invitor, room, reason); + handle_room_invite(INVITE_DIRECT, invitor, room, reason); jid_destroy(jidp); @@ -253,7 +254,7 @@ _conference_message_handler(xmpp_conn_t * const conn, if (body != NULL) { char *message = xmpp_stanza_get_text(body); if (message != NULL) { - prof_handle_room_broadcast(from, message); + handle_room_broadcast(from, message); xmpp_free(ctx, message); } } @@ -279,7 +280,7 @@ _groupchat_message_handler(xmpp_conn_t * const conn, if (subject != NULL) { message = xmpp_stanza_get_text(subject); if (message != NULL) { - prof_handle_room_subject(jid->barejid, message); + handle_room_subject(jid->barejid, message); xmpp_free(ctx, message); } @@ -292,7 +293,7 @@ _groupchat_message_handler(xmpp_conn_t * const conn, if (body != NULL) { message = xmpp_stanza_get_text(body); if (message != NULL) { - prof_handle_room_broadcast(room_jid, message); + handle_room_broadcast(room_jid, message); xmpp_free(ctx, message); } } @@ -326,9 +327,9 @@ _groupchat_message_handler(xmpp_conn_t * const conn, message = xmpp_stanza_get_text(body); if (message != NULL) { if (delayed) { - prof_handle_room_history(jid->barejid, jid->resourcepart, tv_stamp, message); + handle_room_history(jid->barejid, jid->resourcepart, tv_stamp, message); } else { - prof_handle_room_message(jid->barejid, jid->resourcepart, message); + handle_room_message(jid->barejid, jid->resourcepart, message); } xmpp_free(ctx, message); } @@ -353,7 +354,7 @@ _chat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (body != NULL) { char *message = xmpp_stanza_get_text(body); if (message != NULL) { - prof_handle_duck_result(message); + handle_duck_result(message); xmpp_free(ctx, message); } } @@ -373,9 +374,9 @@ _chat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *message = xmpp_stanza_get_text(body); if (message != NULL) { if (delayed) { - prof_handle_delayed_message(jid->str, message, tv_stamp, TRUE); + handle_delayed_message(jid->str, message, tv_stamp, TRUE); } else { - prof_handle_incoming_message(jid->str, message, TRUE); + handle_incoming_message(jid->str, message, TRUE); } xmpp_free(ctx, message); } @@ -407,10 +408,10 @@ _chat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (recipient_supports && (!delayed)) { if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL) { if (prefs_get_boolean(PREF_NOTIFY_TYPING) || prefs_get_boolean(PREF_INTYPE)) { - prof_handle_typing(jid->barejid); + handle_typing(jid->barejid); } } else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL) { - prof_handle_gone(jid->barejid); + handle_gone(jid->barejid); } else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL) { // do something } else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL) { @@ -426,9 +427,9 @@ _chat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *message = xmpp_stanza_get_text(body); if (message != NULL) { if (delayed) { - prof_handle_delayed_message(jid->barejid, message, tv_stamp, FALSE); + handle_delayed_message(jid->barejid, message, tv_stamp, FALSE); } else { - prof_handle_incoming_message(jid->barejid, message, FALSE); + handle_incoming_message(jid->barejid, message, FALSE); } xmpp_free(ctx, message); } diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 3ca2f63e..164e309e 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -32,6 +32,7 @@ #include "log.h" #include "muc.h" #include "profanity.h" +#include "server_events.h" #include "xmpp/capabilities.h" #include "xmpp/connection.h" #include "xmpp/stanza.h" @@ -336,7 +337,7 @@ _unsubscribed_handler(xmpp_conn_t * const conn, Jid *from_jid = jid_create(from); log_debug("Unsubscribed presence handler fired for %s", from); - prof_handle_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED); + handle_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED); autocomplete_remove(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -352,7 +353,7 @@ _subscribed_handler(xmpp_conn_t * const conn, Jid *from_jid = jid_create(from); log_debug("Subscribed presence handler fired for %s", from); - prof_handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED); + handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED); autocomplete_remove(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -372,7 +373,7 @@ _subscribe_handler(xmpp_conn_t * const conn, return 1; } - prof_handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); + handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); autocomplete_add(sub_requests_ac, from_jid->barejid); jid_destroy(from_jid); @@ -400,11 +401,11 @@ _unavailable_handler(xmpp_conn_t * const conn, if (strcmp(my_jid->barejid, from_jid->barejid) !=0) { if (from_jid->resourcepart != NULL) { - prof_handle_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); + handle_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); // hack for servers that do not send full jid with unavailable presence } else { - prof_handle_contact_offline(from_jid->barejid, "__prof_default", status_str); + handle_contact_offline(from_jid->barejid, "__prof_default", status_str); } } else { if (from_jid->resourcepart != NULL) { @@ -499,7 +500,7 @@ _available_handler(xmpp_conn_t * const conn, // contact presence } else { - prof_handle_contact_online(from_jid->barejid, resource, + handle_contact_online(from_jid->barejid, resource, last_activity); } @@ -615,17 +616,17 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (new_nick != NULL) { muc_set_room_pending_nick_change(room, new_nick); } else { - prof_handle_leave_room(room); + handle_leave_room(room); } // handle self nick change } else if (muc_is_room_pending_nick_change(room)) { muc_complete_room_nick_change(room, nick); - prof_handle_room_nick_change(room, nick); + handle_room_nick_change(room, nick); // handle roster complete } else if (!muc_get_roster_received(room)) { - prof_handle_room_roster_complete(room); + handle_room_roster_complete(room); } @@ -653,7 +654,7 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, free(new_nick); } } else { - prof_handle_room_member_offline(room, nick, "offline", status_str); + handle_room_member_offline(room, nick, "offline", status_str); } } else { char *show_str = stanza_get_show(stanza, "online"); @@ -664,13 +665,13 @@ _room_presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (old_nick != NULL) { muc_add_to_roster(room, nick, show_str, status_str, caps_key); - prof_handle_room_member_nick_change(room, old_nick, nick); + handle_room_member_nick_change(room, old_nick, nick); free(old_nick); } else { if (!muc_nick_in_roster(room, nick)) { - prof_handle_room_member_online(room, nick, show_str, status_str, caps_key); + handle_room_member_online(room, nick, show_str, status_str, caps_key); } else { - prof_handle_room_member_presence(room, nick, show_str, status_str, caps_key); + handle_room_member_presence(room, nick, show_str, status_str, caps_key); } } } diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index e84de155..a70436e7 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -29,6 +29,7 @@ #include "log.h" #include "profanity.h" +#include "server_events.h" #include "tools/autocomplete.h" #include "xmpp/connection.h" #include "xmpp/roster.h" @@ -82,7 +83,7 @@ roster_request(void) } static void -_roster_add_new(const char * const barejid, const char * const name) +_roster_send_add_new(const char * const barejid, const char * const name) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); @@ -149,7 +150,7 @@ _group_add_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, { if (userdata != NULL) { GroupData *data = userdata; - prof_handle_group_add(data->name, data->group); + handle_group_add(data->name, data->group); free(data->name); free(data->group); free(userdata); @@ -196,7 +197,7 @@ _group_remove_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, { if (userdata != NULL) { GroupData *data = userdata; - prof_handle_group_remove(data->name, data->group); + handle_group_remove(data->name, data->group); free(data->name); free(data->group); free(userdata); @@ -240,7 +241,7 @@ _roster_handle_push(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, roster_remove(name, barejid); - prof_handle_roster_remove(barejid); + handle_roster_remove(barejid); // otherwise update local roster } else { @@ -254,7 +255,15 @@ _roster_handle_push(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, GSList *groups = _get_groups_from_item(item); // update the local roster - roster_update(barejid, name, groups, sub, pending_out); + PContact contact = roster_get_contact(barejid); + if (contact == NULL) { + gboolean added = roster_add(barejid, name, groups, sub, pending_out); + if (added) { + handle_roster_add(barejid, name); + } + } else { + roster_update(barejid, name, groups, sub, pending_out); + } } return 1; @@ -288,7 +297,7 @@ _roster_handle_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, GSList *groups = _get_groups_from_item(item); - gboolean added = roster_add(barejid, name, groups, sub, pending_out, TRUE); + gboolean added = roster_add(barejid, name, groups, sub, pending_out); if (!added) { log_warning("Attempt to add contact twice: %s", barejid); @@ -327,7 +336,7 @@ _get_groups_from_item(xmpp_stanza_t *item) void roster_init_module(void) { - roster_add_new = _roster_add_new; + roster_send_add_new = _roster_send_add_new; roster_send_remove = _roster_send_remove; roster_send_name_change = _roster_send_name_change; roster_send_add_to_group = _roster_send_add_to_group; diff --git a/src/xmpp/roster.h b/src/xmpp/roster.h index 1faaba86..5fde0a2b 100644 --- a/src/xmpp/roster.h +++ b/src/xmpp/roster.h @@ -26,7 +26,4 @@ void roster_add_handlers(void); void roster_request(void); -void roster_update(const char * const barejid, const char * const name, - GSList *groups, const char * const subscription, gboolean pending_out); - #endif diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 90b17e59..87cde006 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -141,7 +141,7 @@ void (*bookmark_autocomplete_reset)(void); void (*roster_send_name_change)(const char * const barejid, const char * const new_name, GSList *groups); void (*roster_send_add_to_group)(const char * const group, PContact contact); void (*roster_send_remove_from_group)(const char * const group, PContact contact); -void (*roster_add_new)(const char * const barejid, const char * const name); +void (*roster_send_add_new)(const char * const barejid, const char * const name); void (*roster_send_remove)(const char * const barejid); #endif diff --git a/tests/test_roster_list.c b/tests/test_roster_list.c index 104921ba..a5612072 100644 --- a/tests/test_roster_list.c +++ b/tests/test_roster_list.c @@ -20,7 +20,7 @@ void empty_list_when_none_added(void **state) void contains_one_element(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); assert_int_equal(1, g_slist_length(list)); roster_free(); @@ -29,7 +29,7 @@ void contains_one_element(void **state) void first_element_correct(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact james = list->data; @@ -40,8 +40,8 @@ void first_element_correct(void **state) void contains_two_elements(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); assert_int_equal(2, g_slist_length(list)); @@ -51,8 +51,8 @@ void contains_two_elements(void **state) void first_and_second_elements_correct(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact first = list->data; @@ -66,9 +66,9 @@ void first_and_second_elements_correct(void **state) void contains_three_elements(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); assert_int_equal(3, g_slist_length(list)); @@ -78,9 +78,9 @@ void contains_three_elements(void **state) void first_three_elements_correct(void **state) { roster_init(); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); + roster_add("Bob", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("James", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact bob = list->data; PContact dave = (g_slist_next(list))->data; @@ -95,10 +95,10 @@ void first_three_elements_correct(void **state) void add_twice_at_beginning_adds_once(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact first = list->data; PContact second = (g_slist_next(list))->data; @@ -114,10 +114,10 @@ void add_twice_at_beginning_adds_once(void **state) void add_twice_in_middle_adds_once(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact first = list->data; PContact second = (g_slist_next(list))->data; @@ -133,10 +133,10 @@ void add_twice_in_middle_adds_once(void **state) void add_twice_at_end_adds_once(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); + roster_add("James", NULL, NULL, NULL, FALSE); GSList *list = roster_get_contacts(); PContact first = list->data; PContact second = (g_slist_next(list))->data; @@ -152,9 +152,9 @@ void add_twice_at_end_adds_once(void **state) void find_first_exists(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *search = (char *) malloc(2 * sizeof(char)); strcpy(search, "B"); @@ -169,9 +169,9 @@ void find_first_exists(void **state) void find_second_exists(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *result = roster_find_contact("Dav"); assert_string_equal("Dave", result); @@ -182,9 +182,9 @@ void find_second_exists(void **state) void find_third_exists(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *result = roster_find_contact("Ja"); assert_string_equal("James", result); @@ -195,9 +195,9 @@ void find_third_exists(void **state) void find_returns_null(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *result = roster_find_contact("Mike"); assert_null(result); @@ -215,9 +215,9 @@ void find_on_empty_returns_null(void **state) void find_twice_returns_second_when_two_match(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamie", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Jamie", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *result1 = roster_find_contact("Jam"); char *result2 = roster_find_contact(result1); @@ -230,16 +230,16 @@ void find_twice_returns_second_when_two_match(void **state) void find_five_times_finds_fifth(void **state) { roster_init(); - roster_add("Jama", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamb", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Mike", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Dave", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamm", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamn", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Matt", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamo", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamy", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamz", NULL, NULL, NULL, FALSE, TRUE); + roster_add("Jama", NULL, NULL, NULL, FALSE); + roster_add("Jamb", NULL, NULL, NULL, FALSE); + roster_add("Mike", NULL, NULL, NULL, FALSE); + roster_add("Dave", NULL, NULL, NULL, FALSE); + roster_add("Jamm", NULL, NULL, NULL, FALSE); + roster_add("Jamn", NULL, NULL, NULL, FALSE); + roster_add("Matt", NULL, NULL, NULL, FALSE); + roster_add("Jamo", NULL, NULL, NULL, FALSE); + roster_add("Jamy", NULL, NULL, NULL, FALSE); + roster_add("Jamz", NULL, NULL, NULL, FALSE); char *result1 = roster_find_contact("Jam"); char *result2 = roster_find_contact(result1); @@ -258,9 +258,9 @@ void find_five_times_finds_fifth(void **state) void find_twice_returns_first_when_two_match_and_reset(void **state) { roster_init(); - roster_add("James", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Jamie", NULL, NULL, NULL, FALSE, TRUE); - roster_add("Bob", NULL, NULL, NULL, FALSE, TRUE); + roster_add("James", NULL, NULL, NULL, FALSE); + roster_add("Jamie", NULL, NULL, NULL, FALSE); + roster_add("Bob", NULL, NULL, NULL, FALSE); char *result1 = roster_find_contact("Jam"); roster_reset_search_attempts(); |