diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | src/command/command.c | 20 | ||||
-rw-r--r-- | src/command/commands.c | 117 | ||||
-rw-r--r-- | src/muc.c | 599 | ||||
-rw-r--r-- | src/muc.h | 116 | ||||
-rw-r--r-- | src/roster_list.c | 2 | ||||
-rw-r--r-- | src/server_events.c | 54 | ||||
-rw-r--r-- | src/server_events.h | 9 | ||||
-rw-r--r-- | src/tools/autocomplete.c | 48 | ||||
-rw-r--r-- | src/tools/autocomplete.h | 2 | ||||
-rw-r--r-- | src/ui/console.c | 9 | ||||
-rw-r--r-- | src/ui/core.c | 53 | ||||
-rw-r--r-- | src/ui/notifier.c | 2 | ||||
-rw-r--r-- | src/ui/ui.h | 4 | ||||
-rw-r--r-- | src/ui/window.c | 81 | ||||
-rw-r--r-- | src/ui/window.h | 3 | ||||
-rw-r--r-- | src/xmpp/bookmark.c | 14 | ||||
-rw-r--r-- | src/xmpp/iq.c | 13 | ||||
-rw-r--r-- | src/xmpp/message.c | 4 | ||||
-rw-r--r-- | src/xmpp/presence.c | 76 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 22 | ||||
-rw-r--r-- | tests/test_autocomplete.c | 12 | ||||
-rw-r--r-- | tests/test_muc.c | 38 | ||||
-rw-r--r-- | tests/test_muc.h | 8 | ||||
-rw-r--r-- | tests/testsuite.c | 8 |
25 files changed, 766 insertions, 550 deletions
diff --git a/.gitignore b/.gitignore index 91cb1cd1..b5980f6a 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,8 @@ push-all.sh .codelite/ Profanity.project Profanity.workspace +profanity.project +profanity.workspace pageing.txt cppcheck.out gitpushall.sh diff --git a/src/command/command.c b/src/command/command.c index b579fdcf..bea6cbcd 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -307,12 +307,13 @@ static struct cmd_t command_defs[] = { "/room", cmd_room, parse_args, 1, 1, NULL, - { "/room accept|destroy|config", "Room configuration.", - { "/room accept|destroy|config", - "---------------------------", + { "/room accept|destroy|config|info", "Room configuration.", + { "/room accept|destroy|config|info", + "--------------------------------", "accept - Accept default room configuration.", "destroy - Reject default room configuration.", "config - Edit room configuration.", + "info - Show room details.", NULL } } }, { "/form", @@ -1226,6 +1227,7 @@ cmd_init(void) autocomplete_add(room_ac, "accept"); autocomplete_add(room_ac, "destroy"); autocomplete_add(room_ac, "config"); + autocomplete_add(room_ac, "info"); form_ac = autocomplete_new(); autocomplete_add(form_ac, "submit"); @@ -1257,9 +1259,7 @@ cmd_uninit(void) autocomplete_free(autoaway_mode_ac); autocomplete_free(autoconnect_ac); autocomplete_free(theme_ac); - if (theme_load_ac != NULL) { - autocomplete_free(theme_load_ac); - } + autocomplete_free(theme_load_ac); autocomplete_free(account_ac); autocomplete_free(account_set_ac); autocomplete_free(account_clear_ac); @@ -1356,7 +1356,7 @@ void cmd_reset_autocomplete() { roster_reset_search_attempts(); - muc_reset_invites_ac(); + muc_invites_reset_ac(); accounts_reset_all_search(); accounts_reset_enabled_search(); prefs_reset_boolean_choice(); @@ -1370,7 +1370,7 @@ cmd_reset_autocomplete() if (ui_current_win_type() == WIN_MUC) { char *recipient = ui_current_recipient(); - muc_reset_autocomplete(recipient); + muc_autocomplete_reset(recipient); } autocomplete_reset(who_ac); @@ -1605,7 +1605,7 @@ _cmd_complete_parameters(char *input, int *size) // autocomplete nickname in chat rooms if (ui_current_win_type() == WIN_MUC) { char *recipient = ui_current_recipient(); - Autocomplete nick_ac = muc_get_roster_ac(recipient); + Autocomplete nick_ac = muc_roster_ac(recipient); if (nick_ac != NULL) { gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ; @@ -1655,7 +1655,7 @@ _cmd_complete_parameters(char *input, int *size) gchar *invite_choices[] = { "/decline", "/join" }; for (i = 0; i < ARRAY_SIZE(invite_choices); i++) { result = autocomplete_param_with_func(input, size, invite_choices[i], - muc_find_invite); + muc_invites_find); if (result != NULL) { ui_replace_input(input, result, size); g_free(result); diff --git a/src/command/commands.c b/src/command/commands.c index 045ad00a..2b8a0d2c 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -476,7 +476,7 @@ cmd_disconnect(gchar **args, struct cmd_help_t help) cons_show("%s logged out successfully.", jid); jabber_disconnect(); roster_clear(); - muc_clear_invites(); + muc_invites_clear(); chat_sessions_clear(); ui_disconnected(); free(jid); @@ -726,7 +726,7 @@ static void _who_room(const char * const presence) { char *room = ui_current_recipient(); - GList *list = muc_get_roster(room); + GList *list = muc_roster(room); // no arg, show all contacts if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) { @@ -737,9 +737,9 @@ _who_room(const char * const presence) GList *filtered = NULL; while (list != NULL) { - PContact contact = list->data; - if (p_contact_is_available(contact)) { - filtered = g_list_append(filtered, contact); + Occupant *occupant = list->data; + if (muc_occupant_available(occupant)) { + filtered = g_list_append(filtered, occupant); } list = g_list_next(list); } @@ -751,51 +751,24 @@ _who_room(const char * const presence) GList *filtered = NULL; while (list != NULL) { - PContact contact = list->data; - if (!p_contact_is_available(contact)) { - filtered = g_list_append(filtered, contact); + Occupant *occupant = list->data; + if (!muc_occupant_available(occupant)) { + filtered = g_list_append(filtered, occupant); } list = g_list_next(list); } ui_room_roster(room, filtered, "unavailable"); - // online, available resources - } else if (strcmp("online", presence) == 0) { - GList *filtered = NULL; - - while (list != NULL) { - PContact contact = list->data; - if (p_contact_has_available_resource(contact)) { - filtered = g_list_append(filtered, contact); - } - list = g_list_next(list); - } - - ui_room_roster(room, filtered, "online"); - - // offline, no available resources - } else if (strcmp("offline", presence) == 0) { - GList *filtered = NULL; - - while (list != NULL) { - PContact contact = list->data; - if (!p_contact_has_available_resource(contact)) { - filtered = g_list_append(filtered, contact); - } - list = g_list_next(list); - } - - ui_room_roster(room, filtered, "offline"); - // show specific status } else { GList *filtered = NULL; while (list != NULL) { - PContact contact = list->data; - if (strcmp(p_contact_presence(contact), presence) == 0) { - filtered = g_list_append(filtered, contact); + Occupant *occupant = list->data; + const char *presence_str = string_from_resource_presence(occupant->presence); + if (strcmp(presence_str, presence) == 0) { + filtered = g_list_append(filtered, occupant); } list = g_list_next(list); } @@ -1048,7 +1021,7 @@ cmd_msg(gchar **args, struct cmd_help_t help) if (win_type == WIN_MUC) { char *room_name = ui_current_recipient(); - if (muc_nick_in_roster(room_name, usr)) { + if (muc_roster_contains_nick(room_name, usr)) { GString *full_jid = g_string_new(room_name); g_string_append(full_jid, "/"); g_string_append(full_jid, usr); @@ -1464,6 +1437,7 @@ cmd_info(gchar **args, struct cmd_help_t help) jabber_conn_status_t conn_status = jabber_get_connection_status(); win_type_t win_type = ui_current_win_type(); PContact pcontact = NULL; + Occupant *occupant = NULL; if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); @@ -1473,28 +1447,34 @@ cmd_info(gchar **args, struct cmd_help_t help) switch (win_type) { case WIN_MUC: - if (usr != NULL) { - ui_info_room(usr); + if (usr) { + char *room = ui_current_recipient(); + occupant = muc_roster_item(room, usr); + if (occupant) { + ui_info_room(room, occupant); + } else { + ui_current_print_line("No such occupant \"%s\" in room.", usr); + } } else { ui_current_print_line("You must specify a nickname."); } break; case WIN_CHAT: - if (usr != NULL) { + if (usr) { ui_current_print_line("No parameter required when in chat."); } else { ui_info(); } break; case WIN_PRIVATE: - if (usr != NULL) { + if (usr) { ui_current_print_line("No parameter required when in chat."); } else { ui_info_private(); } break; case WIN_CONSOLE: - if (usr != NULL) { + if (usr) { char *usr_jid = roster_barejid_from_name(usr); if (usr_jid == NULL) { usr_jid = usr; @@ -1522,6 +1502,7 @@ cmd_caps(gchar **args, struct cmd_help_t help) jabber_conn_status_t conn_status = jabber_get_connection_status(); win_type_t win_type = ui_current_win_type(); PContact pcontact = NULL; + Occupant *occupant = NULL; if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); @@ -1533,11 +1514,10 @@ cmd_caps(gchar **args, struct cmd_help_t help) case WIN_MUC: if (args[0] != NULL) { char *room = ui_current_recipient(); - pcontact = muc_get_participant(room, args[0]); - if (pcontact != NULL) { + occupant = muc_roster_item(room, args[0]); + if (occupant) { Jid *jidp = jid_create_from_bare_and_resource(room, args[0]); - Resource *resource = p_contact_get_resource(pcontact, args[0]); - cons_show_caps(jidp->fulljid, resource); + cons_show_caps(jidp->fulljid, occupant->presence); jid_destroy(jidp); } else { cons_show("No such participant \"%s\" in room.", args[0]); @@ -1562,7 +1542,7 @@ cmd_caps(gchar **args, struct cmd_help_t help) if (resource == NULL) { cons_show("Could not find resource %s, for contact %s", jid->barejid, jid->resourcepart); } else { - cons_show_caps(jid->fulljid, resource); + cons_show_caps(jid->fulljid, resource->presence); } } } @@ -1578,9 +1558,8 @@ cmd_caps(gchar **args, struct cmd_help_t help) char *recipient = ui_current_recipient(); Jid *jid = jid_create(recipient); if (jid) { - pcontact = muc_get_participant(jid->barejid, jid->resourcepart); - Resource *resource = p_contact_get_resource(pcontact, jid->resourcepart); - cons_show_caps(jid->resourcepart, resource); + occupant = muc_roster_item(jid->barejid, jid->resourcepart); + cons_show_caps(jid->resourcepart, occupant->presence); jid_destroy(jid); } } @@ -1598,7 +1577,7 @@ cmd_software(gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); win_type_t win_type = ui_current_win_type(); - PContact pcontact = NULL; + Occupant *occupant = NULL; char *recipient; if (conn_status != JABBER_CONNECTED) { @@ -1611,8 +1590,8 @@ cmd_software(gchar **args, struct cmd_help_t help) case WIN_MUC: if (args[0] != NULL) { recipient = ui_current_recipient(); - pcontact = muc_get_participant(recipient, args[0]); - if (pcontact != NULL) { + occupant = muc_roster_item(recipient, args[0]); + if (occupant) { Jid *jid = jid_create_from_bare_and_resource(recipient, args[0]); iq_send_software_version(jid->fulljid); jid_destroy(jid); @@ -1715,10 +1694,10 @@ cmd_join(gchar **args, struct cmd_help_t help) nick = account->muc_nick; } - if (!muc_room_is_active(room)) { + if (!muc_active(room)) { presence_join_room(room, nick, passwd); - muc_join_room(room, nick, passwd, FALSE); - } else if (muc_get_roster_received(room)) { + muc_join(room, nick, passwd, FALSE); + } else if (muc_roster_complete(room)) { ui_room_join(room, TRUE); } @@ -1767,7 +1746,7 @@ cmd_invite(gchar **args, struct cmd_help_t help) gboolean cmd_invites(gchar **args, struct cmd_help_t help) { - GSList *invites = muc_get_invites(); + GSList *invites = muc_invites(); cons_show_room_invites(invites); g_slist_free_full(invites, g_free); return TRUE; @@ -1776,10 +1755,10 @@ cmd_invites(gchar **args, struct cmd_help_t help) gboolean cmd_decline(gchar **args, struct cmd_help_t help) { - if (!muc_invites_include(args[0])) { + if (!muc_invites_contain(args[0])) { cons_show("No such invite exists."); } else { - muc_remove_invite(args[0]); + muc_invites_remove(args[0]); cons_show("Declined invite to %s.", args[0]); } @@ -2083,7 +2062,8 @@ cmd_room(gchar **args, struct cmd_help_t help) if ((g_strcmp0(args[0], "accept") != 0) && (g_strcmp0(args[0], "destroy") != 0) && - (g_strcmp0(args[0], "config") != 0)) { + (g_strcmp0(args[0], "config") != 0) && + (g_strcmp0(args[0], "info") != 0)) { cons_show("Usage: %s", help.usage); return TRUE; } @@ -2097,6 +2077,13 @@ cmd_room(gchar **args, struct cmd_help_t help) ui_index = 0; } + if (g_strcmp0(args[0], "info") == 0) { + char *role = muc_role_str(room); + char *affiliation = muc_affiliation_str(room); + ui_current_print_line("Affiliation: %s, Role: %s", affiliation, role); + return TRUE; + } + if (g_strcmp0(args[0], "accept") == 0) { gboolean requires_config = muc_requires_config(room); if (!requires_config) { @@ -2171,8 +2158,8 @@ cmd_bookmark(gchar **args, struct cmd_help_t help) // default to current nickname, password, and autojoin "on" if (cmd == NULL) { char *jid = ui_current_recipient(); - char *nick = muc_get_room_nick(jid); - char *password = muc_get_room_password(jid); + char *nick = muc_nick(jid); + char *password = muc_password(jid); gboolean added = bookmark_add(jid, nick, password, "on"); if (added) { ui_current_print_formatted_line('!', 0, "Bookmark added for %s.", jid); diff --git a/src/muc.c b/src/muc.c index 3c937670..6c48f342 100644 --- a/src/muc.c +++ b/src/muc.c @@ -42,10 +42,13 @@ #include "jid.h" #include "tools/autocomplete.h" #include "ui/ui.h" +#include "muc.h" typedef struct _muc_room_t { char *room; // e.g. test@conference.server char *nick; // e.g. Some User + muc_role_t role; + muc_affiliation_t affiliation; char *password; char *subject; char *autocomplete_prefix; @@ -63,54 +66,60 @@ GHashTable *rooms = NULL; Autocomplete invite_ac; static void _free_room(ChatRoom *room); -static gint _compare_participants(PContact a, PContact b); +static gint _compare_occupants(Occupant *a, Occupant *b); +static muc_role_t _role_from_string(const char * const role); +static muc_affiliation_t _affiliation_from_string(const char * const affiliation); +static char* _role_to_string(muc_role_t role); +static char* _affiliation_to_string(muc_affiliation_t affiliation); +static Occupant* _muc_occupant_new(const char *const nick, muc_role_t role, muc_affiliation_t affiliation, + resource_presence_t presence, const char * const status); +static void _occupant_free(Occupant *occupant); void muc_init(void) { invite_ac = autocomplete_new(); + rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_room); } void muc_close(void) { autocomplete_free(invite_ac); - if (rooms != NULL) { - g_hash_table_destroy(rooms); - rooms = NULL; - } + g_hash_table_destroy(rooms); + rooms = NULL; } void -muc_add_invite(char *room) +muc_invites_add(const char * const room) { autocomplete_add(invite_ac, room); } void -muc_remove_invite(char *room) +muc_invites_remove(const char * const room) { autocomplete_remove(invite_ac, room); } gint -muc_invite_count(void) +muc_invites_count(void) { return autocomplete_length(invite_ac); } GSList * -muc_get_invites(void) +muc_invites(void) { - return autocomplete_get_list(invite_ac); + return autocomplete_create_list(invite_ac); } gboolean -muc_invites_include(const char * const room) +muc_invites_contain(const char * const room) { - GSList *invites = autocomplete_get_list(invite_ac); + GSList *invites = autocomplete_create_list(invite_ac); GSList *curr = invites; - while (curr != NULL) { + while (curr) { if (strcmp(curr->data, room) == 0) { g_slist_free_full(invites, g_free); return TRUE; @@ -119,44 +128,39 @@ muc_invites_include(const char * const room) } } g_slist_free_full(invites, g_free); + return FALSE; } void -muc_reset_invites_ac(void) +muc_invites_reset_ac(void) { autocomplete_reset(invite_ac); } char * -muc_find_invite(char *search_str) +muc_invites_find(char *search_str) { return autocomplete_complete(invite_ac, search_str, TRUE); } void -muc_clear_invites(void) +muc_invites_clear(void) { autocomplete_clear(invite_ac); } -/* - * Join the chat room with the specified nickname - */ void -muc_join_room(const char * const room, const char * const nick, +muc_join(const char * const room, const char * const nick, const char * const password, gboolean autojoin) { - if (rooms == NULL) { - rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)_free_room); - } - ChatRoom *new_room = malloc(sizeof(ChatRoom)); new_room->room = strdup(room); new_room->nick = strdup(nick); + new_room->role = MUC_ROLE_NONE; + new_room->affiliation = MUC_AFFILIATION_NONE; new_room->autocomplete_prefix = NULL; - if (password != NULL) { + if (password) { new_room->password = strdup(password); } else { new_room->password = NULL; @@ -164,11 +168,9 @@ muc_join_room(const char * const room, const char * const nick, new_room->subject = NULL; new_room->pending_broadcasts = NULL; new_room->pending_config = FALSE; - new_room->roster = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)p_contact_free); + new_room->roster = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_occupant_free); new_room->nick_ac = autocomplete_new(); - new_room->nick_changes = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); + new_room->nick_changes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); new_room->roster_received = FALSE; new_room->pending_nick_change = FALSE; new_room->autojoin = autojoin; @@ -176,80 +178,49 @@ muc_join_room(const char * const room, const char * const nick, g_hash_table_insert(rooms, strdup(room), new_room); } -/* - * Leave the room - */ void -muc_leave_room(const char * const room) +muc_leave(const char * const room) { - if (rooms != NULL) { - g_hash_table_remove(rooms, room); - } + g_hash_table_remove(rooms, room); } gboolean muc_requires_config(const char * const room) { - if (rooms == NULL) { - return FALSE; - } - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room == NULL) { + if (chat_room) { + return chat_room->pending_config; + } else { return FALSE; } - return chat_room->pending_config; } void muc_set_requires_config(const char * const room, gboolean val) { - if (rooms == NULL) { - return; - } - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room == NULL) { - return; + if (chat_room) { + chat_room->pending_config = val; } - - chat_room->pending_config = val; - return; } /* * Returns TRUE if the user is currently in the room */ gboolean -muc_room_is_active(const char * const room) +muc_active(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return TRUE; - } else { - return FALSE; - } - } else { - return FALSE; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + return (chat_room != NULL); } gboolean -muc_room_is_autojoin(const char * const room) +muc_autojoin(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return chat_room->autojoin; - } else { - return FALSE; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return chat_room->autojoin; } else { return FALSE; } @@ -258,72 +229,53 @@ muc_room_is_autojoin(const char * const room) void muc_set_subject(const char * const room, const char * const subject) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - if (chat_room->subject != NULL) { - free(chat_room->subject); - } - chat_room->subject = strdup(subject); - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + free(chat_room->subject); + chat_room->subject = strdup(subject); } } char * -muc_get_subject(const char * const room) +muc_subject(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return chat_room->subject; - } else { - return NULL; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return chat_room->subject; } else { return NULL; } } void -muc_add_pending_broadcast(const char * const room, const char * const message) +muc_pending_broadcasts_add(const char * const room, const char * const message) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - chat_room->pending_broadcasts = g_list_append(chat_room->pending_broadcasts, strdup(message)); - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + chat_room->pending_broadcasts = g_list_append(chat_room->pending_broadcasts, strdup(message)); } } GList * -muc_get_pending_broadcasts(const char * const room) +muc_pending_broadcasts(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return chat_room->pending_broadcasts; - } else { - return NULL; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return chat_room->pending_broadcasts; } else { return NULL; } } char * -muc_get_old_nick(const char * const room, const char * const new_nick) +muc_old_nick(const char * const room, const char * const new_nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if ((chat_room != NULL) && (chat_room->pending_nick_change)) { + if (chat_room && chat_room->pending_nick_change) { return g_hash_table_lookup(chat_room->nick_changes, new_nick); + } else { + return NULL; } - - return NULL; } /* @@ -331,11 +283,10 @@ muc_get_old_nick(const char * const room, const char * const new_nick) * and is awaiting the response */ void -muc_set_room_pending_nick_change(const char * const room, const char * const new_nick) +muc_nick_change_start(const char * const room, const char * const new_nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { chat_room->pending_nick_change = TRUE; g_hash_table_insert(chat_room->nick_changes, strdup(new_nick), strdup(chat_room->nick)); } @@ -346,11 +297,10 @@ muc_set_room_pending_nick_change(const char * const room, const char * const new * nick change */ gboolean -muc_is_room_pending_nick_change(const char * const room) +muc_nick_change_pending(const char * const room) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { return chat_room->pending_nick_change; } else { return FALSE; @@ -362,11 +312,10 @@ muc_is_room_pending_nick_change(const char * const room) * the service has responded */ void -muc_complete_room_nick_change(const char * const room, const char * const nick) +muc_nick_change_complete(const char * const room, const char * const nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { free(chat_room->nick); chat_room->nick = strdup(nick); chat_room->pending_nick_change = FALSE; @@ -380,13 +329,9 @@ muc_complete_room_nick_change(const char * const room, const char * const nick) * modified or freed. */ GList * -muc_get_active_room_list(void) +muc_rooms(void) { - if (rooms != NULL) { - return g_hash_table_get_keys(rooms); - } else { - return NULL; - } + return g_hash_table_get_keys(rooms); } /* @@ -394,16 +339,11 @@ muc_get_active_room_list(void) * The nickname is owned by the chat room and should not be modified or freed */ char * -muc_get_room_nick(const char * const room) +muc_nick(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return chat_room->nick; - } else { - return NULL; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return chat_room->nick; } else { return NULL; } @@ -414,16 +354,11 @@ muc_get_room_nick(const char * const room) * The password is owned by the chat room and should not be modified or freed */ char * -muc_get_room_password(const char * const room) +muc_password(const char * const room) { - if (rooms != NULL) { - ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - return chat_room->password; - } else { - return NULL; - } + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return chat_room->password; } else { return NULL; } @@ -433,47 +368,44 @@ muc_get_room_password(const char * const room) * Returns TRUE if the specified nick exists in the room's roster */ gboolean -muc_nick_in_roster(const char * const room, const char * const nick) +muc_roster_contains_nick(const char * const room, const char * const nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - PContact contact = g_hash_table_lookup(chat_room->roster, nick); - if (contact != NULL) { - return TRUE; - } else { - return FALSE; - } + if (chat_room) { + Occupant *occupant = g_hash_table_lookup(chat_room->roster, nick); + return (occupant != NULL); + } else { + return FALSE; } - - return FALSE; } /* * Add a new chat room member to the room's roster */ gboolean -muc_add_to_roster(const char * const room, const char * const nick, - const char * const show, const char * const status) +muc_roster_add(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, const char * const status) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); gboolean updated = FALSE; + resource_presence_t new_presence = resource_presence_from_string(show); - if (chat_room != NULL) { - PContact old = g_hash_table_lookup(chat_room->roster, nick); + if (chat_room) { + Occupant *old = g_hash_table_lookup(chat_room->roster, nick); - if (old == NULL) { + if (!old) { updated = TRUE; autocomplete_add(chat_room->nick_ac, nick); - } else if ((g_strcmp0(p_contact_presence(old), show) != 0) || - (g_strcmp0(p_contact_status(old), status) != 0)) { + } else if (old->presence != new_presence || + (g_strcmp0(old->status, status) != 0)) { updated = TRUE; } - PContact contact = p_contact_new(nick, NULL, NULL, NULL, NULL, FALSE); - resource_presence_t resource_presence = resource_presence_from_string(show); - Resource *resource = resource_new(nick, resource_presence, status, 0); - p_contact_set_presence(contact, resource); - g_hash_table_replace(chat_room->roster, strdup(nick), contact); + + resource_presence_t presence = resource_presence_from_string(show); + muc_role_t role_t = _role_from_string(role); + muc_affiliation_t affiliation_t = _affiliation_from_string(affiliation); + Occupant *occupant = _muc_occupant_new(nick, role_t, affiliation_t, presence, status); + g_hash_table_replace(chat_room->roster, strdup(nick), occupant); } return updated; @@ -483,27 +415,25 @@ muc_add_to_roster(const char * const room, const char * const nick, * Remove a room member from the room's roster */ void -muc_remove_from_roster(const char * const room, const char * const nick) +muc_roster_remove(const char * const room, const char * const nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { g_hash_table_remove(chat_room->roster, nick); autocomplete_remove(chat_room->nick_ac, nick); } } -PContact -muc_get_participant(const char * const room, const char * const nick) +Occupant * +muc_roster_item(const char * const room, const char * const nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { - PContact participant = g_hash_table_lookup(chat_room->roster, nick); - return participant; + if (chat_room) { + Occupant *occupant = g_hash_table_lookup(chat_room->roster, nick); + return occupant; + } else { + return NULL; } - - return NULL; } /* @@ -511,11 +441,10 @@ muc_get_participant(const char * const room, const char * const nick) * The list is owned by the room and must not be mofified or freed */ GList * -muc_get_roster(const char * const room) +muc_roster(const char * const room) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { GList *result = NULL; GHashTableIter iter; gpointer key; @@ -523,7 +452,7 @@ muc_get_roster(const char * const room) g_hash_table_iter_init(&iter, chat_room->roster); while (g_hash_table_iter_next(&iter, &key, &value)) { - result = g_list_insert_sorted(result, value, (GCompareFunc)_compare_participants); + result = g_list_insert_sorted(result, value, (GCompareFunc)_compare_occupants); } return result; @@ -536,11 +465,10 @@ muc_get_roster(const char * const room) * Return a Autocomplete representing the room member's in the roster */ Autocomplete -muc_get_roster_ac(const char * const room) +muc_roster_ac(const char * const room) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { return chat_room->nick_ac; } else { return NULL; @@ -551,11 +479,10 @@ muc_get_roster_ac(const char * const room) * Set to TRUE when the rooms roster has been fully received */ void -muc_set_roster_received(const char * const room) +muc_roster_set_complete(const char * const room) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { chat_room->roster_received = TRUE; } } @@ -564,30 +491,34 @@ muc_set_roster_received(const char * const room) * Returns TRUE id the rooms roster has been fully received */ gboolean -muc_get_roster_received(const char * const room) +muc_roster_complete(const char * const room) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { return chat_room->roster_received; } else { return FALSE; } } +gboolean +muc_occupant_available(Occupant *occupant) +{ + return (occupant->presence == RESOURCE_ONLINE || occupant->presence == RESOURCE_CHAT); +} + /* * Remove the old_nick from the roster, and flag that a pending nickname change * is in progress */ void -muc_set_roster_pending_nick_change(const char * const room, +muc_roster_nick_change_start(const char * const room, const char * const new_nick, const char * const old_nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { g_hash_table_insert(chat_room->nick_changes, strdup(new_nick), strdup(old_nick)); - muc_remove_from_roster(room, old_nick); + muc_roster_remove(room, old_nick); } } @@ -598,14 +529,13 @@ muc_set_roster_pending_nick_change(const char * const room, * the caller */ char * -muc_complete_roster_nick_change(const char * const room, +muc_roster_nick_change_complete(const char * const room, const char * const nick) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); - - if (chat_room != NULL) { + if (chat_room) { char *old_nick = g_hash_table_lookup(chat_room->nick_changes, nick); - if (old_nick != NULL) { + if (old_nick) { char *old_nick_cpy = strdup(old_nick); g_hash_table_remove(chat_room->nick_changes, nick); @@ -619,96 +549,113 @@ muc_complete_roster_nick_change(const char * const room, void muc_autocomplete(char *input, int *size) { - if (rooms == NULL) { - return; - } - char *recipient = ui_current_recipient(); ChatRoom *chat_room = g_hash_table_lookup(rooms, recipient); - if (chat_room == NULL) { - return; - } + if (chat_room && chat_room->nick_ac) { + input[*size] = '\0'; + char *search_str = NULL; - if (chat_room->nick_ac == NULL) { - return; - } - - input[*size] = '\0'; - char *search_str = NULL; - - gchar *last_space = g_strrstr(input, " "); - if (last_space == NULL) { - search_str = input; - if (chat_room->autocomplete_prefix == NULL) { - chat_room->autocomplete_prefix = strdup(""); - } - } else { - search_str = last_space+1; - if (chat_room->autocomplete_prefix == NULL) { - chat_room->autocomplete_prefix = g_strndup(input, search_str - input); + gchar *last_space = g_strrstr(input, " "); + if (!last_space) { + search_str = input; + if (!chat_room->autocomplete_prefix) { + chat_room->autocomplete_prefix = strdup(""); + } + } else { + search_str = last_space+1; + if (!chat_room->autocomplete_prefix) { + chat_room->autocomplete_prefix = g_strndup(input, search_str - input); + } } - } - char *result = autocomplete_complete(chat_room->nick_ac, search_str, FALSE); - if (result != NULL) { - GString *replace_with = g_string_new(chat_room->autocomplete_prefix); - g_string_append(replace_with, result); - if (last_space == NULL || (*(last_space+1) == '\0')) { - g_string_append(replace_with, ": "); + char *result = autocomplete_complete(chat_room->nick_ac, search_str, FALSE); + if (result) { + GString *replace_with = g_string_new(chat_room->autocomplete_prefix); + g_string_append(replace_with, result); + if (!last_space || (*(last_space+1) == '\0')) { + g_string_append(replace_with, ": "); + } + ui_replace_input(input, replace_with->str, size); + g_string_free(replace_with, TRUE); + g_free(result); } - ui_replace_input(input, replace_with->str, size); - g_string_free(replace_with, TRUE); - g_free(result); } - - return; } void -muc_reset_autocomplete(const char * const room) +muc_autocomplete_reset(const char * const room) { - if (rooms == NULL) { - return; + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + if (chat_room->nick_ac) { + autocomplete_reset(chat_room->nick_ac); + } + + if (chat_room->autocomplete_prefix) { + free(chat_room->autocomplete_prefix); + chat_room->autocomplete_prefix = NULL; + } } +} +char * +muc_role_str(const char * const room) +{ ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return _role_to_string(chat_room->role); + } else { + return "none"; + } +} - if (chat_room == NULL) { - return; +void +muc_set_role(const char * const room, const char * const role) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + chat_room->role = _role_from_string(role); } +} - if (chat_room->nick_ac != NULL) { - autocomplete_reset(chat_room->nick_ac); +char * +muc_affiliation_str(const char * const room) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return _affiliation_to_string(chat_room->affiliation); + } else { + return "none"; } +} - if (chat_room->autocomplete_prefix != NULL) { - free(chat_room->autocomplete_prefix); - chat_room->autocomplete_prefix = NULL; +void +muc_set_affiliation(const char * const room, const char * const affiliation) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + chat_room->affiliation = _affiliation_from_string(affiliation); } } static void _free_room(ChatRoom *room) { - if (room != NULL) { + if (room) { free(room->room); free(room->nick); free(room->subject); free(room->password); - if (room->autocomplete_prefix != NULL) { - free(room->autocomplete_prefix); - } - if (room->roster != NULL) { + free(room->autocomplete_prefix); + if (room->roster) { g_hash_table_destroy(room->roster); } - if (room->nick_ac != NULL) { - autocomplete_free(room->nick_ac); - } - if (room->nick_changes != NULL) { + autocomplete_free(room->nick_ac); + if (room->nick_changes) { g_hash_table_destroy(room->nick_changes); } - if (room->pending_broadcasts != NULL) { + if (room->pending_broadcasts) { g_list_free_full(room->pending_broadcasts, free); } free(room); @@ -716,10 +663,10 @@ _free_room(ChatRoom *room) } static -gint _compare_participants(PContact a, PContact b) +gint _compare_occupants(Occupant *a, Occupant *b) { - const char * utf8_str_a = p_contact_barejid(a); - const char * utf8_str_b = p_contact_barejid(b); + const char * utf8_str_a = a->nick; + const char * utf8_str_b = b->nick; gchar *key_a = g_utf8_collate_key(utf8_str_a, -1); gchar *key_b = g_utf8_collate_key(utf8_str_b, -1); @@ -731,3 +678,133 @@ gint _compare_participants(PContact a, PContact b) return result; } + +static muc_role_t +_role_from_string(const char * const role) +{ + if (role) { + if (g_strcmp0(role, "visitor") == 0) { + return MUC_ROLE_VISITOR; + } else if (g_strcmp0(role, "participant") == 0) { + return MUC_ROLE_PARTICIPANT; + } else if (g_strcmp0(role, "moderator") == 0) { + return MUC_ROLE_MODERATOR; + } else { + return MUC_ROLE_NONE; + } + } else { + return MUC_ROLE_NONE; + } +} + +static char * +_role_to_string(muc_role_t role) +{ + char *result = NULL; + + switch (role) { + case MUC_ROLE_NONE: + result = "none"; + break; + case MUC_ROLE_VISITOR: + result = "visitor"; + break; + case MUC_ROLE_PARTICIPANT: + result = "participant"; + break; + case MUC_ROLE_MODERATOR: + result = "moderator"; + break; + default: + result = "none"; + break; + } + + return result; +} + +static muc_affiliation_t +_affiliation_from_string(const char * const affiliation) +{ + if (affiliation) { + if (g_strcmp0(affiliation, "outcast") == 0) { + return MUC_AFFILIATION_OUTCAST; + } else if (g_strcmp0(affiliation, "member") == 0) { + return MUC_AFFILIATION_MEMBER; + } else if (g_strcmp0(affiliation, "admin") == 0) { + return MUC_AFFILIATION_ADMIN; + } else if (g_strcmp0(affiliation, "owner") == 0) { + return MUC_AFFILIATION_OWNER; + } else { + return MUC_AFFILIATION_NONE; + } + } else { + return MUC_AFFILIATION_NONE; + } +} + +static char * +_affiliation_to_string(muc_affiliation_t affiliation) +{ + char *result = NULL; + + switch (affiliation) { + case MUC_AFFILIATION_NONE: + result = "none"; + break; + case MUC_AFFILIATION_OUTCAST: + result = "outcast"; + break; + case MUC_AFFILIATION_MEMBER: + result = "member"; + break; + case MUC_AFFILIATION_ADMIN: + result = "admin"; + break; + case MUC_AFFILIATION_OWNER: + result = "owner"; + break; + default: + result = "none"; + break; + } + + return result; +} + +static Occupant* +_muc_occupant_new(const char *const nick, muc_role_t role, muc_affiliation_t affiliation, resource_presence_t presence, + const char * const status) +{ + Occupant *occupant = malloc(sizeof(Occupant)); + + if (nick) { + occupant->nick = strdup(nick); + } else { + occupant->nick = NULL; + } + + occupant->presence = presence; + + if (status) { + occupant->status = strdup(status); + } else { + occupant->status = NULL; + } + + occupant->role = role; + occupant->affiliation = affiliation; + + return occupant; +} + +static void +_occupant_free(Occupant *occupant) +{ + if (occupant) { + free(occupant->nick); + free(occupant->status); + free(occupant); + occupant = NULL; + } +} \ No newline at end of file diff --git a/src/muc.h b/src/muc.h index 722e4a17..3bf836ee 100644 --- a/src/muc.h +++ b/src/muc.h @@ -41,56 +41,88 @@ #include "jid.h" #include "tools/autocomplete.h" +typedef enum { + MUC_ROLE_NONE, + MUC_ROLE_VISITOR, + MUC_ROLE_PARTICIPANT, + MUC_ROLE_MODERATOR +} muc_role_t; + +typedef enum { + MUC_AFFILIATION_NONE, + MUC_AFFILIATION_OUTCAST, + MUC_AFFILIATION_MEMBER, + MUC_AFFILIATION_ADMIN, + MUC_AFFILIATION_OWNER +} muc_affiliation_t; + +typedef struct _muc_occupant_t { + char *nick; + muc_role_t role; + muc_affiliation_t affiliation; + resource_presence_t presence; + char *status; +} Occupant; + void muc_init(void); void muc_close(void); -void muc_join_room(const char * const room, const char * const nick, - const char * const password, gboolean autojoin); -void muc_leave_room(const char * const room); -gboolean muc_room_is_active(const char * const room); -gboolean muc_room_is_autojoin(const char * const room); -GList* muc_get_active_room_list(void); -char* muc_get_room_nick(const char * const room); -char* muc_get_room_password(const char * const room); - -void muc_set_room_pending_nick_change(const char * const room, const char * const new_nick); -gboolean muc_is_room_pending_nick_change(const char * const room); -void muc_complete_room_nick_change(const char * const room, - const char * const nick); -char * muc_get_old_nick(const char * const room, const char * const new_nick); - -gboolean muc_add_to_roster(const char * const room, const char * const nick, - const char * const show, const char * const status); -void muc_remove_from_roster(const char * const room, const char * const nick); -GList * muc_get_roster(const char * const room); -Autocomplete muc_get_roster_ac(const char * const room); -gboolean muc_nick_in_roster(const char * const room, const char * const nick); -PContact muc_get_participant(const char * const room, const char * const nick); -void muc_set_roster_received(const char * const room); -gboolean muc_get_roster_received(const char * const room); - -void muc_set_roster_pending_nick_change(const char * const room, - const char * const new_nick, const char * const old_nick); -char* muc_complete_roster_nick_change(const char * const room, - const char * const nick); - -void muc_add_invite(const char *room); -void muc_remove_invite(const char * const room); -gint muc_invite_count(void); -GSList* muc_get_invites(void); -gboolean muc_invites_include(const char * const room); -void muc_reset_invites_ac(void); -char* muc_find_invite(char *search_str); -void muc_clear_invites(void); + +void muc_join(const char * const room, const char * const nick, const char * const password, gboolean autojoin); +void muc_leave(const char * const room); + +gboolean muc_active(const char * const room); +gboolean muc_autojoin(const char * const room); + +GList* muc_rooms(void); + +char* muc_nick(const char * const room); +char* muc_password(const char * const room); + +void muc_nick_change_start(const char * const room, const char * const new_nick); +void muc_nick_change_complete(const char * const room, const char * const nick); +gboolean muc_nick_change_pending(const char * const room); +char* muc_old_nick(const char * const room, const char * const new_nick); + +gboolean muc_roster_contains_nick(const char * const room, const char * const nick); +gboolean muc_roster_complete(const char * const room); +gboolean muc_roster_add(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, + const char * const status); +void muc_roster_remove(const char * const room, const char * const nick); +void muc_roster_set_complete(const char * const room); +GList * muc_roster(const char * const room); +Autocomplete muc_roster_ac(const char * const room); +Occupant* muc_roster_item(const char * const room, const char * const nick); + +gboolean muc_occupant_available(Occupant *occupant); + +void muc_roster_nick_change_start(const char * const room, const char * const new_nick, const char * const old_nick); +char* muc_roster_nick_change_complete(const char * const room, const char * const nick); + +void muc_invites_add(const char * const room); +void muc_invites_remove(const char * const room); +gint muc_invites_count(void); +GSList* muc_invites(void); +gboolean muc_invites_contain(const char * const room); +void muc_invites_reset_ac(void); +char* muc_invites_find(char *search_str); +void muc_invites_clear(void); void muc_set_subject(const char * const room, const char * const subject); -char * muc_get_subject(const char * const room); -void muc_add_pending_broadcast(const char * const room, const char * const message); -GList * muc_get_pending_broadcasts(const char * const room); +char* muc_subject(const char * const room); + +void muc_pending_broadcasts_add(const char * const room, const char * const message); +GList * muc_pending_broadcasts(const char * const room); void muc_autocomplete(char *input, int *size); -void muc_reset_autocomplete(const char * const room); +void muc_autocomplete_reset(const char * const room); gboolean muc_requires_config(const char * const room); void muc_set_requires_config(const char * const room, gboolean val); +void muc_set_role(const char * const room, const char * const role); +void muc_set_affiliation(const char * const room, const char * const affiliation); +char *muc_role_str(const char * const room); +char *muc_affiliation_str(const char * const room); + #endif diff --git a/src/roster_list.c b/src/roster_list.c index aba90d34..f7c865f9 100644 --- a/src/roster_list.c +++ b/src/roster_list.c @@ -339,7 +339,7 @@ roster_get_group(const char * const group) GSList * roster_get_groups(void) { - return autocomplete_get_list(groups_ac); + return autocomplete_create_list(groups_ac); } char * diff --git a/src/server_events.c b/src/server_events.c index f89385c6..4755f3fa 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -54,8 +54,8 @@ void handle_room_join_error(const char * const room, const char * const err) { - if (muc_room_is_active(room)) { - muc_leave_room(room); + if (muc_active(room)) { + muc_leave(room); } ui_handle_room_join_error(room, err); } @@ -109,11 +109,11 @@ handle_login_account_success(char *account_name) ui_handle_login_account_success(account); // attempt to rejoin rooms with passwords - GList *curr = muc_get_active_room_list(); + GList *curr = muc_rooms(); while (curr != NULL) { - char *password = muc_get_room_password(curr->data); + char *password = muc_password(curr->data); if (password != NULL) { - char *nick = muc_get_room_nick(curr->data); + char *nick = muc_nick(curr->data); presence_join_room(curr->data, nick, password); } curr = g_list_next(curr); @@ -129,7 +129,7 @@ handle_lost_connection(void) { cons_show_error("Lost connection."); roster_clear(); - muc_clear_invites(); + muc_invites_clear(); chat_sessions_clear(); ui_disconnected(); } @@ -181,9 +181,9 @@ handle_room_invite(jabber_invite_t invite_type, const char * const invitor, const char * const room, const char * const reason) { - if (!muc_room_is_active(room) && !muc_invites_include(room)) { + if (!muc_active(room) && !muc_invites_contain(room)) { cons_show_room_invite(invitor, room, reason); - muc_add_invite(room); + muc_invites_add(room); } } @@ -191,10 +191,10 @@ void handle_room_broadcast(const char *const room_jid, const char * const message) { - if (muc_get_roster_received(room_jid)) { + if (muc_roster_complete(room_jid)) { ui_room_broadcast(room_jid, message); } else { - muc_add_pending_broadcast(room_jid, message); + muc_pending_broadcasts_add(room_jid, message); } } @@ -202,7 +202,7 @@ void handle_room_subject(const char * const room_jid, const char * const subject) { muc_set_subject(room_jid, subject); - if (muc_get_roster_received(room_jid)) { + if (muc_roster_complete(room_jid)) { ui_room_subject(room_jid, subject); } } @@ -449,13 +449,14 @@ handle_contact_online(char *barejid, Resource *resource, void handle_leave_room(const char * const room) { - muc_leave_room(room); + muc_leave(room); } void handle_room_nick_change(const char * const room, const char * const nick) { + muc_nick_change_complete(room, nick); ui_room_nick_change(room, nick); } @@ -469,7 +470,7 @@ handle_room_requires_config(const char * const room) void handle_room_destroy(const char * const room) { - muc_leave_room(room); + muc_leave(room); ui_room_destroyed(room); } @@ -500,22 +501,22 @@ handle_room_config_submit_result_error(const char * const room, const char * con void handle_room_roster_complete(const char * const room) { - if (muc_room_is_autojoin(room)) { + if (muc_autojoin(room)) { ui_room_join(room, FALSE); } else { ui_room_join(room, TRUE); } - muc_remove_invite(room); - muc_set_roster_received(room); - GList *roster = muc_get_roster(room); + muc_invites_remove(room); + muc_roster_set_complete(room); + GList *roster = muc_roster(room); ui_room_roster(room, roster, NULL); - char *subject = muc_get_subject(room); + char *subject = muc_subject(room); if (subject != NULL) { ui_room_subject(room, subject); } - GList *pending_broadcasts = muc_get_pending_broadcasts(room); + GList *pending_broadcasts = muc_pending_broadcasts(room); if (pending_broadcasts != NULL) { GList *curr = pending_broadcasts; while (curr != NULL) { @@ -526,11 +527,10 @@ 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) +handle_room_member_presence(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, const char * const status) { - gboolean updated = muc_add_to_roster(room, nick, show, status); + gboolean updated = muc_roster_add(room, nick, role, affiliation, show, status); if (updated) { char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC); @@ -542,10 +542,10 @@ handle_room_member_presence(const char * const room, } void -handle_room_member_online(const char * const room, const char * const nick, - const char * const show, const char * const status) +handle_room_member_online(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, const char * const status) { - muc_add_to_roster(room, nick, show, status); + muc_roster_add(room, nick, role, affiliation, show, status); char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC); if (g_strcmp0(muc_status_pref, "none") != 0) { @@ -558,7 +558,7 @@ 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); + muc_roster_remove(room, nick); char *muc_status_pref = prefs_get_string(PREF_STATUSES_MUC); if (g_strcmp0(muc_status_pref, "none") != 0) { diff --git a/src/server_events.h b/src/server_events.h index 41506cdb..6990e8bf 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -73,11 +73,10 @@ void handle_room_nick_change(const char * const room, void handle_room_requires_config(const char * const room); void handle_room_destroy(const char * const room); 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); -void handle_room_member_online(const char * const room, const char * const nick, - const char * const show, const char * const status); +void handle_room_member_presence(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, const char * const status); +void handle_room_member_online(const char * const room, const char * const nick, const char * const role, + const char * const affiliation, const char * const show, const char * const status); 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, diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index 0fe8f166..486fd2ba 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -62,7 +62,7 @@ autocomplete_new(void) void autocomplete_clear(Autocomplete ac) { - if (ac != NULL) { + if (ac) { g_slist_free_full(ac->items, free); ac->items = NULL; @@ -80,16 +80,18 @@ autocomplete_reset(Autocomplete ac) void autocomplete_free(Autocomplete ac) { - autocomplete_clear(ac); - free(ac); + if (ac) { + autocomplete_clear(ac); + free(ac); + } } gint autocomplete_length(Autocomplete ac) { - if (ac == NULL) { + if (!ac) { return 0; - } else if (ac->items == NULL) { + } else if (!ac->items) { return 0; } else { return g_slist_length(ac->items); @@ -99,25 +101,26 @@ autocomplete_length(Autocomplete ac) void autocomplete_add(Autocomplete ac, const char *item) { - if (ac != NULL) { + if (ac) { char *item_cpy; GSList *curr = g_slist_find_custom(ac->items, item, (GCompareFunc)strcmp); // if item already exists - if (curr != NULL) { + if (curr) { return; } item_cpy = strdup(item); ac->items = g_slist_insert_sorted(ac->items, item_cpy, (GCompareFunc)strcmp); } + return; } void autocomplete_remove(Autocomplete ac, const char * const item) { - if (ac != NULL) { + if (ac) { GSList *curr = g_slist_find_custom(ac->items, item, (GCompareFunc)strcmp); if (!curr) { @@ -137,7 +140,7 @@ autocomplete_remove(Autocomplete ac, const char * const item) } GSList * -autocomplete_get_list(Autocomplete ac) +autocomplete_create_list(Autocomplete ac) { GSList *copy = NULL; GSList *curr = ac->items; @@ -171,36 +174,43 @@ autocomplete_complete(Autocomplete ac, gchar *search_str, gboolean quote) gchar *found = NULL; // no autocomplete to search - if (ac == NULL) + if (!ac) { return NULL; + } // no items to search - if (!ac->items) + if (!ac->items) { return NULL; + } // first search attempt - if (ac->last_found == NULL) { - if (ac->search_str != NULL) { + if (!ac->last_found) { + if (ac->search_str) { FREE_SET_NULL(ac->search_str); } + ac->search_str = strdup(search_str); found = _search_from(ac, ac->items, quote); + return found; // subsequent search attempt } else { // search from here+1 to end found = _search_from(ac, g_slist_next(ac->last_found), quote); - if (found != NULL) + if (found) { return found; + } // search from beginning found = _search_from(ac, ac->items, quote); - if (found != NULL) + if (found) { return found; + } // we found nothing, reset search autocomplete_reset(ac); + return NULL; } } @@ -224,7 +234,7 @@ autocomplete_param_with_func(char *input, int *size, char *command, inp_cpy[(*size) - len] = '\0'; char *found = func(inp_cpy); - if (found != NULL) { + if (found) { auto_msg = g_string_new(command_cpy); g_string_append(auto_msg, found); free(found); @@ -254,7 +264,7 @@ autocomplete_param_with_ac(char *input, int *size, char *command, inp_cpy[(*size) - len] = '\0'; char *found = autocomplete_complete(ac, inp_cpy, quote); - if (found != NULL) { + if (found) { auto_msg = g_string_new(command_cpy); g_string_append(auto_msg, found); free(found); @@ -292,9 +302,9 @@ autocomplete_param_no_with_func(char *input, int *size, char *command, gchar *comp_str = g_strdup(&inp_cpy[strlen(start_str)]); // autocomplete param - if (comp_str != NULL) { + if (comp_str) { char *found = func(comp_str); - if (found != NULL) { + if (found) { result_str = g_string_new(""); g_string_append(result_str, start_str); g_string_append(result_str, found); diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h index 9e2be30c..a029b7ef 100644 --- a/src/tools/autocomplete.h +++ b/src/tools/autocomplete.h @@ -55,7 +55,7 @@ void autocomplete_remove(Autocomplete ac, const char * const item); // find the next item prefixed with search string gchar * autocomplete_complete(Autocomplete ac, gchar *search_str, gboolean quote); -GSList * autocomplete_get_list(Autocomplete ac); +GSList * autocomplete_create_list(Autocomplete ac); gint autocomplete_length(Autocomplete ac); char * autocomplete_param_with_func(char *input, int *size, char *command, diff --git a/src/ui/console.c b/src/ui/console.c index 5c0a4e53..a34ff71d 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -32,6 +32,7 @@ * */ + #include <string.h> #include <stdlib.h> @@ -282,14 +283,14 @@ _cons_show_info(PContact pcontact) } static void -_cons_show_caps(const char * const fulljid, Resource *resource) +_cons_show_caps(const char * const fulljid, resource_presence_t presence) { ProfWin *console = wins_get_console(); cons_show(""); Capabilities *caps = caps_lookup(fulljid); if (caps) { - const char *resource_presence = string_from_resource_presence(resource->presence); + const char *resource_presence = string_from_resource_presence(presence); int presence_colour = win_presence_colour(resource_presence); win_save_vprint(console, '-', NULL, NO_EOL, presence_colour, "", "%s", fulljid); @@ -454,7 +455,7 @@ _cons_show_bookmarks(const GList *list) int presence_colour = 0; - if (muc_room_is_active(item->jid)) { + if (muc_active(item->jid)) { presence_colour = COLOUR_ONLINE; } win_save_vprint(console, '-', NULL, NO_EOL, presence_colour, "", " %s", item->jid); @@ -467,7 +468,7 @@ _cons_show_bookmarks(const GList *list) if (item->password != NULL) { win_save_print(console, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", " (private)"); } - if (muc_room_is_active(item->jid)) { + if (muc_active(item->jid)) { ProfWin *roomwin = wins_get_by_recipient(item->jid); if (roomwin != NULL) { int num = wins_get_num(roomwin); diff --git a/src/ui/core.c b/src/ui/core.c index 18eff596..500e435b 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -1207,7 +1207,7 @@ _ui_new_chat_win(const char * const to) if (window == NULL) { Jid *jid = jid_create(to); - if (muc_room_is_active(jid->barejid)) { + if (muc_active(jid->barejid)) { window = wins_new(to, WIN_PRIVATE); } else { window = wins_new(to, WIN_CHAT); @@ -1324,7 +1324,7 @@ _ui_outgoing_msg(const char * const from, const char * const to, if (window == NULL) { Jid *jid = jid_create(to); - if (muc_room_is_active(jid->barejid)) { + if (muc_active(jid->barejid)) { window = wins_new(to, WIN_PRIVATE); } else { window = wins_new(to, WIN_CHAT); @@ -1377,7 +1377,7 @@ _ui_room_join(const char * const room, gboolean focus) } else { status_bar_active(num); ProfWin *console = wins_get_console(); - char *nick = muc_get_room_nick(room); + char *nick = muc_nick(room); win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "-> Autojoined %s as %s (%d).", room, nick, num); } } @@ -1393,26 +1393,25 @@ _ui_room_roster(const char * const room, GList *roster, const char * const prese if (presence == NULL) { win_save_print(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Room is empty."); } else { - win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "No participants %s.", presence); + win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "No occupants %s.", presence); } } else { int length = g_list_length(roster); if (presence == NULL) { length++; - win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%d participants: ", length); - win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ONLINE, "", "%s", muc_get_room_nick(room)); + win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%d occupants: ", length); + win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, COLOUR_ONLINE, "", "%s", muc_nick(room)); win_save_print(window, '!', NULL, NO_DATE | NO_EOL, 0, "", ", "); } else { win_save_vprint(window, '!', NULL, NO_EOL, COLOUR_ROOMINFO, "", "%d %s: ", length, presence); } while (roster != NULL) { - PContact member = roster->data; - const char *nick = p_contact_barejid(member); - const char *show = p_contact_presence(member); + Occupant *occupant = roster->data; + const char *presence_str = string_from_resource_presence(occupant->presence); - int presence_colour = win_presence_colour(show); - win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, presence_colour, "", "%s", nick); + int presence_colour = win_presence_colour(presence_str); + win_save_vprint(window, '!', NULL, NO_DATE | NO_EOL, presence_colour, "", "%s", occupant->nick); if (roster->next != NULL) { win_save_print(window, '!', NULL, NO_DATE | NO_EOL, 0, "", ", "); @@ -1531,7 +1530,7 @@ _ui_room_message(const char * const room_jid, const char * const nick, log_error("Room message received from %s, but no window open for %s", nick, room_jid); } else { int num = wins_get_num(window); - char *my_nick = muc_get_room_nick(room_jid); + char *my_nick = muc_nick(room_jid); if (strcmp(nick, my_nick) != 0) { if (g_strrstr(message, my_nick) != NULL) { @@ -1566,7 +1565,7 @@ _ui_room_message(const char * const room_jid, const char * const nick, ui_index = 0; } - if (strcmp(nick, muc_get_room_nick(room_jid)) != 0) { + if (strcmp(nick, muc_nick(room_jid)) != 0) { if (prefs_get_boolean(PREF_BEEP)) { beep(); } @@ -1731,11 +1730,11 @@ static void _ui_status_private(void) { Jid *jid = jid_create(ui_current_recipient()); - PContact pcontact = muc_get_participant(jid->barejid, jid->resourcepart); + Occupant *occupant = muc_roster_item(jid->barejid, jid->resourcepart); ProfWin *window = wins_get_current(); - if (pcontact != NULL) { - win_show_contact(window, pcontact); + if (occupant) { + win_show_occupant(window, occupant); } else { win_save_println(window, "Error getting contact info."); } @@ -1747,11 +1746,11 @@ static void _ui_info_private(void) { Jid *jid = jid_create(ui_current_recipient()); - PContact pcontact = muc_get_participant(jid->barejid, jid->resourcepart); + Occupant *occupant = muc_roster_item(jid->barejid, jid->resourcepart); ProfWin *window = wins_get_current(); - if (pcontact != NULL) { - win_show_info(window, pcontact); + if (occupant) { + win_show_occupant_info(window, jid->barejid, occupant); } else { win_save_println(window, "Error getting contact info."); } @@ -1762,27 +1761,21 @@ _ui_info_private(void) static void _ui_status_room(const char * const contact) { - PContact pcontact = muc_get_participant(ui_current_recipient(), contact); + Occupant *occupant = muc_roster_item(ui_current_recipient(), contact); ProfWin *current = wins_get_current(); - if (pcontact != NULL) { - win_show_contact(current, pcontact); + if (occupant) { + win_show_occupant(current, occupant); } else { win_save_vprint(current, '-', NULL, 0, 0, "", "No such participant \"%s\" in room.", contact); } } static void -_ui_info_room(const char * const contact) +_ui_info_room(const char * const room, Occupant *occupant) { - PContact pcontact = muc_get_participant(ui_current_recipient(), contact); ProfWin *current = wins_get_current(); - - if (pcontact != NULL) { - win_show_info(current, pcontact); - } else { - win_save_vprint(current, '-', NULL, 0, 0, "", "No such participant \"%s\" in room.", contact); - } + win_show_occupant_info(current, room, occupant); } static gint diff --git a/src/ui/notifier.c b/src/ui/notifier.c index 6673edb0..81320383 100644 --- a/src/ui/notifier.c +++ b/src/ui/notifier.c @@ -129,7 +129,7 @@ static void _notify_remind(void) { gint unread = ui_unread(); - gint open = muc_invite_count(); + gint open = muc_invites_count(); gint subs = presence_sub_request_count(); GString *text = g_string_new(""); diff --git a/src/ui/ui.h b/src/ui/ui.h index 82327d03..d71a78c1 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -172,7 +172,7 @@ void (*ui_show_lines)(ProfWin *window, const gchar** lines); // contact status functions void (*ui_status_room)(const char * const contact); -void (*ui_info_room)(const char * const contact); +void (*ui_info_room)(const char * const room, Occupant *occupant); void (*ui_status)(void); void (*ui_info)(void); void (*ui_status_private)(void); @@ -234,7 +234,7 @@ void (*cons_show_roster_group)(const char * const group, GSList * list); void (*cons_show_wins)(void); void (*cons_show_status)(const char * const barejid); void (*cons_show_info)(PContact pcontact); -void (*cons_show_caps)(const char * const fulljid, Resource *resource); +void (*cons_show_caps)(const char * const fulljid, resource_presence_t presence); void (*cons_show_themes)(GSList *themes); void (*cons_show_aliases)(GList *aliases); void (*cons_show_login_success)(ProfAccount *account); diff --git a/src/ui/window.c b/src/ui/window.c index b9d2bee4..4a922c59 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -126,6 +126,23 @@ win_presence_colour(const char * const presence) } void +win_show_occupant(ProfWin *window, Occupant *occupant) +{ + const char *presence_str = string_from_resource_presence(occupant->presence); + + int presence_colour = win_presence_colour(presence_str); + + win_save_print(window, '-', NULL, NO_EOL, presence_colour, "", occupant->nick); + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", " is %s", presence_str); + + if (occupant->status) { + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", ", \"%s\"", occupant->status); + } + + win_save_print(window, '-', NULL, NO_DATE, presence_colour, "", ""); +} + +void win_show_contact(ProfWin *window, PContact contact) { const char *barejid = p_contact_barejid(contact); @@ -170,6 +187,70 @@ win_show_contact(ProfWin *window, PContact contact) } void +win_show_occupant_info(ProfWin *window, const char * const room, Occupant *occupant) +{ + const char *presence_str = string_from_resource_presence(occupant->presence); + + int presence_colour = win_presence_colour(presence_str); + + win_save_print(window, '-', NULL, NO_EOL, presence_colour, "", occupant->nick); + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", " is %s", presence_str); + + if (occupant->status) { + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", ", \"%s\"", occupant->status); + } + + win_save_newline(window); + + win_save_vprint(window, '-', NULL, NO_DATE, 0, "", "Role: %s, Affiliation: %s", occupant->role, occupant->affiliation); + + Jid *jidp = jid_create_from_bare_and_resource(room, occupant->nick); + Capabilities *caps = caps_lookup(jidp->fulljid); + + if (caps) { + // show identity + if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) { + win_save_print(window, '-', NULL, NO_EOL, 0, "", " Identity: "); + if (caps->name != NULL) { + win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name); + if ((caps->category != NULL) || (caps->type != NULL)) { + win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " "); + } + } + if (caps->type != NULL) { + win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type); + if (caps->category != NULL) { + win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " "); + } + } + if (caps->category != NULL) { + win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category); + } + win_save_newline(window); + } + if (caps->software != NULL) { + win_save_vprint(window, '-', NULL, NO_EOL, 0, "", " Software: %s", caps->software); + } + if (caps->software_version != NULL) { + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version); + } + if ((caps->software != NULL) || (caps->software_version != NULL)) { + win_save_newline(window); + } + if (caps->os != NULL) { + win_save_vprint(window, '-', NULL, NO_EOL, 0, "", " OS: %s", caps->os); + } + if (caps->os_version != NULL) { + win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version); + } + if ((caps->os != NULL) || (caps->os_version != NULL)) { + win_save_newline(window); + } + caps_destroy(caps); + } +} + +void win_show_info(ProfWin *window, PContact contact) { const char *barejid = p_contact_barejid(contact); diff --git a/src/ui/window.h b/src/ui/window.h index 8150fac9..804ea300 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -44,6 +44,7 @@ #endif #include "contact.h" +#include "muc.h" #include "ui/buffer.h" #include "xmpp/xmpp.h" @@ -85,6 +86,7 @@ void win_update_virtual(ProfWin *window); void win_move_to_end(ProfWin *window); int win_presence_colour(const char * const presence); void win_show_contact(ProfWin *window, PContact contact); +void win_show_occupant(ProfWin *window, Occupant *occupant); void win_show_status_string(ProfWin *window, const char * const from, const char * const show, const char * const status, GDateTime *last_activity, const char * const pre, @@ -92,6 +94,7 @@ void win_show_status_string(ProfWin *window, const char * const from, void win_print_incoming_message(ProfWin *window, GTimeVal *tv_stamp, const char * const from, const char * const message); void win_show_info(ProfWin *window, PContact contact); +void win_show_occupant_info(ProfWin *window, const char * const room, Occupant *occupant); void win_save_vprint(ProfWin *window, const char show_char, GTimeVal *tstamp, int flags, int attrs, const char * const from, const char * const message, ...); void win_save_print(ProfWin *window, const char show_char, GTimeVal *tstamp, int flags, int attrs, const char * const from, const char * const message); void win_save_println(ProfWin *window, const char * const message); diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c index b4931b8f..b5d495a6 100644 --- a/src/xmpp/bookmark.c +++ b/src/xmpp/bookmark.c @@ -77,9 +77,7 @@ bookmark_request(void) id = strdup("bookmark_init_request"); autojoin_count = 0; - if (bookmark_ac != NULL) { - autocomplete_free(bookmark_ac); - } + autocomplete_free(bookmark_ac); bookmark_ac = autocomplete_new(); if (bookmark_list != NULL) { g_list_free_full(bookmark_list, _bookmark_item_destroy); @@ -180,15 +178,15 @@ _bookmark_join(const char *jid) char *account_name = jabber_get_account_name(); ProfAccount *account = accounts_get_account(account_name); Bookmark *item = found->data; - if (!muc_room_is_active(item->jid)) { + if (!muc_active(item->jid)) { char *nick = item->nick; if (nick == NULL) { nick = account->muc_nick; } presence_join_room(item->jid, nick, item->password); - muc_join_room(item->jid, nick, item->password, FALSE); + muc_join(item->jid, nick, item->password, FALSE); account_free(account); - } else if (muc_get_roster_received(item->jid)) { + } else if (muc_roster_complete(item->jid)) { ui_room_join(item->jid, TRUE); } return TRUE; @@ -345,9 +343,9 @@ _bookmark_handle_result(xmpp_conn_t * const conn, log_debug("Autojoin %s with nick=%s", jid, name); room_jid = jid_create_from_bare_and_resource(jid, name); - if (!muc_room_is_active(room_jid->barejid)) { + if (!muc_active(room_jid->barejid)) { presence_join_room(jid, name, password); - muc_join_room(jid, name, password, TRUE); + muc_join(jid, name, password, TRUE); } jid_destroy(room_jid); account_free(account); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 4a354a23..10355332 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -493,16 +493,17 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, os_str = xmpp_stanza_get_text(os); } - PContact contact; Jid *jidp = jid_create(jid); - if (muc_room_is_active(jidp->barejid)) { - contact = muc_get_participant(jidp->barejid, jidp->resourcepart); + const char *presence = NULL; + if (muc_active(jidp->barejid)) { + Occupant *occupant = muc_roster_item(jidp->barejid, jidp->resourcepart); + presence = string_from_resource_presence(occupant->presence); } else { - contact = roster_get_contact(jidp->barejid); + PContact contact = roster_get_contact(jidp->barejid); + Resource *resource = p_contact_get_resource(contact, jidp->resourcepart); + presence = string_from_resource_presence(resource->presence); } - Resource *resource = p_contact_get_resource(contact, jidp->resourcepart); - const char *presence = string_from_resource_presence(resource->presence); handle_software_version_result(jid, presence, name_str, version_str, os_str); jid_destroy(jidp); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 0e80f9b5..f3940067 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -392,7 +392,7 @@ _groupchat_handler(xmpp_conn_t * const conn, } // room not active in profanity - if (!muc_room_is_active(jid->barejid)) { + if (!muc_active(jid->barejid)) { log_error("Message received for inactive chat room: %s", jid->str); jid_destroy(jid); return 1; @@ -444,7 +444,7 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; // private message from chat room use full jid (room/nick) - } else if (muc_room_is_active(jid->barejid)) { + } else if (muc_active(jid->barejid)) { // determine if the notifications happened whilst offline GTimeVal tv_stamp; gboolean delayed = stanza_get_delay(stanza, &tv_stamp); diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 54c9d68c..cfbf18fe 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -142,7 +142,7 @@ _presence_subscription(const char * const jid, const jabber_subscr_t action) static GSList * _presence_get_subscription_requests(void) { - return autocomplete_get_list(sub_requests_ac); + return autocomplete_create_list(sub_requests_ac); } static gint @@ -167,7 +167,7 @@ static gboolean _presence_sub_request_exists(const char * const bare_jid) { gboolean result = FALSE; - GSList *requests_p = autocomplete_get_list(sub_requests_ac); + GSList *requests_p = autocomplete_create_list(sub_requests_ac); GSList *requests = requests_p; while (requests != NULL) { @@ -242,12 +242,12 @@ _presence_update(const resource_presence_t presence_type, const char * const msg static void _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence) { - GList *rooms_p = muc_get_active_room_list(); + GList *rooms_p = muc_rooms(); GList *rooms = rooms_p; while (rooms != NULL) { const char *room = rooms->data; - const char *nick = muc_get_room_nick(room); + const char *nick = muc_nick(room); if (nick != NULL) { char *full_room_jid = create_fulljid(room, nick); @@ -331,7 +331,7 @@ _presence_leave_chat_room(const char * const room_jid) log_debug("Sending room leave presence to: %s", room_jid); xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_conn_t *conn = connection_get_conn(); - char *nick = muc_get_room_nick(room_jid); + char *nick = muc_nick(room_jid); if (nick != NULL) { xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, @@ -697,27 +697,43 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *new_nick = stanza_get_new_nick(stanza); + // self unavailable if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // leave room if not self nick change if (new_nick != NULL) { - muc_set_room_pending_nick_change(from_room, new_nick); + muc_nick_change_start(from_room, new_nick); } else { handle_leave_room(from_room); } - // handle self nick change - } else if (muc_is_room_pending_nick_change(from_room)) { - muc_complete_room_nick_change(from_room, from_nick); - handle_room_nick_change(from_room, from_nick); + // self online + } else { + + // handle self nick change + if (muc_nick_change_pending(from_room)) { + handle_room_nick_change(from_room, from_nick); - // handle roster complete - } else if (!muc_get_roster_received(from_room)) { - handle_room_roster_complete(from_room); + // handle roster complete + } else if (!muc_roster_complete(from_room)) { + handle_room_roster_complete(from_room); - // room configuration required - if (stanza_muc_requires_config(stanza)) { - handle_room_requires_config(from_room); + // room configuration required + if (stanza_muc_requires_config(stanza)) { + handle_room_requires_config(from_room); + } + } + + // set own affiliation and role + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM); + if (item) { + char *role = xmpp_stanza_get_attribute(item, "role"); + muc_set_role(from_room, role); + char *affiliation = xmpp_stanza_get_attribute(item, "affiliation"); + muc_set_affiliation(from_room, affiliation); + } } } @@ -736,7 +752,7 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (stanza_is_room_nick_change(stanza)) { char *new_nick = stanza_get_new_nick(stanza); if (new_nick != NULL) { - muc_set_roster_pending_nick_change(from_room, new_nick, from_nick); + muc_roster_nick_change_start(from_room, new_nick, from_nick); free(new_nick); } } else { @@ -750,20 +766,32 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, } char *show_str = stanza_get_show(stanza, "online"); - if (!muc_get_roster_received(from_room)) { - muc_add_to_roster(from_room, from_nick, show_str, status_str); + char *role = NULL; + char *affiliation = NULL; + + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM); + if (item) { + role = xmpp_stanza_get_attribute(item, "role"); + affiliation = xmpp_stanza_get_attribute(item, "affiliation"); + } + } + + if (!muc_roster_complete(from_room)) { + muc_roster_add(from_room, from_nick, role, affiliation, show_str, status_str); } else { - char *old_nick = muc_complete_roster_nick_change(from_room, from_nick); + char *old_nick = muc_roster_nick_change_complete(from_room, from_nick); if (old_nick != NULL) { - muc_add_to_roster(from_room, from_nick, show_str, status_str); + muc_roster_add(from_room, from_nick, role, affiliation, show_str, status_str); handle_room_member_nick_change(from_room, old_nick, from_nick); free(old_nick); } else { - if (!muc_nick_in_roster(from_room, from_nick)) { - handle_room_member_online(from_room, from_nick, show_str, status_str); + if (!muc_roster_contains_nick(from_room, from_nick)) { + handle_room_member_online(from_room, from_nick, role, affiliation, show_str, status_str); } else { - handle_room_member_presence(from_room, from_nick, show_str, status_str); + handle_room_member_presence(from_room, from_nick, role, affiliation, show_str, status_str); } } } diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 2d99c0f0..ff31bc65 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -822,11 +822,11 @@ stanza_is_muc_self_presence(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 110 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, "110") == 0) { @@ -838,9 +838,9 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // check for item child element with jid property xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM); - if (item != NULL) { + if (item) { char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); - if (jid != NULL) { + if (jid) { if (g_str_has_prefix(self_jid, jid)) { return TRUE; } @@ -849,21 +849,21 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // check if 'from' attribute identifies this user char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (from != NULL) { + if (from) { Jid *from_jid = jid_create(from); - if (muc_room_is_active(from_jid->barejid)) { - char *nick = muc_get_room_nick(from_jid->barejid); + if (muc_active(from_jid->barejid)) { + char *nick = muc_nick(from_jid->barejid); if (g_strcmp0(from_jid->resourcepart, nick) == 0) { return TRUE; } } // check if a new nickname maps to a pending nick change for this user - if (muc_is_room_pending_nick_change(from_jid->barejid)) { + if (muc_nick_change_pending(from_jid->barejid)) { char *new_nick = from_jid->resourcepart; - if (new_nick != NULL) { - char *nick = muc_get_room_nick(from_jid->barejid); - char *old_nick = muc_get_old_nick(from_jid->barejid, new_nick); + if (new_nick) { + char *nick = muc_nick(from_jid->barejid); + char *old_nick = muc_old_nick(from_jid->barejid, new_nick); if (g_strcmp0(old_nick, nick) == 0) { return TRUE; } diff --git a/tests/test_autocomplete.c b/tests/test_autocomplete.c index 4fdd4e4d..f6ef8653 100644 --- a/tests/test_autocomplete.c +++ b/tests/test_autocomplete.c @@ -31,11 +31,12 @@ void find_after_create(void **state) void get_after_create_returns_null(void **state) { Autocomplete ac = autocomplete_new(); - GSList *result = autocomplete_get_list(ac); + GSList *result = autocomplete_create_list(ac); assert_null(result); autocomplete_clear(ac); + g_slist_free_full(result, g_free); } void add_one_and_complete(void **state) @@ -79,11 +80,12 @@ void add_two_adds_two(void **state) Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); autocomplete_add(ac, "Help"); - GSList *result = autocomplete_get_list(ac); + GSList *result = autocomplete_create_list(ac); assert_int_equal(2, g_slist_length(result)); autocomplete_clear(ac); + g_slist_free_full(result, g_free); } void add_two_same_adds_one(void **state) @@ -91,11 +93,12 @@ void add_two_same_adds_one(void **state) Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); autocomplete_add(ac, "Hello"); - GSList *result = autocomplete_get_list(ac); + GSList *result = autocomplete_create_list(ac); assert_int_equal(1, g_slist_length(result)); autocomplete_clear(ac); + g_slist_free_full(result, g_free); } void add_two_same_updates(void **state) @@ -103,7 +106,7 @@ void add_two_same_updates(void **state) Autocomplete ac = autocomplete_new(); autocomplete_add(ac, "Hello"); autocomplete_add(ac, "Hello"); - GSList *result = autocomplete_get_list(ac); + GSList *result = autocomplete_create_list(ac); GSList *first = g_slist_nth(result, 0); @@ -112,4 +115,5 @@ void add_two_same_updates(void **state) assert_string_equal("Hello", str); autocomplete_clear(ac); + g_slist_free_full(result, g_free); } diff --git a/tests/test_muc.c b/tests/test_muc.c index be7279a5..5566c17e 100644 --- a/tests/test_muc.c +++ b/tests/test_muc.c @@ -16,12 +16,12 @@ void muc_after_test(void **state) muc_close(); } -void test_muc_add_invite(void **state) +void test_muc_invites_add(void **state) { char *room = "room@conf.server"; - muc_add_invite(room); + muc_invites_add(room); - gboolean invite_exists = muc_invites_include(room); + gboolean invite_exists = muc_invites_contain(room); assert_true(invite_exists); } @@ -29,30 +29,30 @@ void test_muc_add_invite(void **state) void test_muc_remove_invite(void **state) { char *room = "room@conf.server"; - muc_add_invite(room); - muc_remove_invite(room); + muc_invites_add(room); + muc_invites_remove(room); - gboolean invite_exists = muc_invites_include(room); + gboolean invite_exists = muc_invites_contain(room); assert_false(invite_exists); } -void test_muc_invite_count_0(void **state) +void test_muc_invites_count_0(void **state) { - int invite_count = muc_invite_count(); + int invite_count = muc_invites_count(); assert_true(invite_count == 0); } -void test_muc_invite_count_5(void **state) +void test_muc_invites_count_5(void **state) { - muc_add_invite("room1@conf.server"); - muc_add_invite("room2@conf.server"); - muc_add_invite("room3@conf.server"); - muc_add_invite("room4@conf.server"); - muc_add_invite("room5@conf.server"); + muc_invites_add("room1@conf.server"); + muc_invites_add("room2@conf.server"); + muc_invites_add("room3@conf.server"); + muc_invites_add("room4@conf.server"); + muc_invites_add("room5@conf.server"); - int invite_count = muc_invite_count(); + int invite_count = muc_invites_count(); assert_true(invite_count == 5); } @@ -61,18 +61,18 @@ void test_muc_room_is_not_active(void **state) { char *room = "room@server.org"; - gboolean room_is_active = muc_room_is_active(room); + gboolean room_is_active = muc_active(room); assert_false(room_is_active); } -void test_muc_room_is_active(void **state) +void test_muc_active(void **state) { char *room = "room@server.org"; char *nick = "bob"; - muc_join_room(room, nick, NULL, FALSE); + muc_join(room, nick, NULL, FALSE); - gboolean room_is_active = muc_room_is_active(room); + gboolean room_is_active = muc_active(room); assert_true(room_is_active); } diff --git a/tests/test_muc.h b/tests/test_muc.h index 044d547d..8df54a5d 100644 --- a/tests/test_muc.h +++ b/tests/test_muc.h @@ -1,9 +1,9 @@ void muc_before_test(void **state); void muc_after_test(void **state); -void test_muc_add_invite(void **state); +void test_muc_invites_add(void **state); void test_muc_remove_invite(void **state); -void test_muc_invite_count_0(void **state); -void test_muc_invite_count_5(void **state); +void test_muc_invites_count_0(void **state); +void test_muc_invites_count_5(void **state); void test_muc_room_is_not_active(void **state); -void test_muc_room_is_active(void **state); +void test_muc_active(void **state); diff --git a/tests/testsuite.c b/tests/testsuite.c index 3441ceb9..1dcabe73 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -419,12 +419,12 @@ int main(int argc, char* argv[]) { load_preferences, close_preferences), - unit_test_setup_teardown(test_muc_add_invite, muc_before_test, muc_after_test), + unit_test_setup_teardown(test_muc_invites_add, muc_before_test, muc_after_test), unit_test_setup_teardown(test_muc_remove_invite, muc_before_test, muc_after_test), - unit_test_setup_teardown(test_muc_invite_count_0, muc_before_test, muc_after_test), - unit_test_setup_teardown(test_muc_invite_count_5, muc_before_test, muc_after_test), + unit_test_setup_teardown(test_muc_invites_count_0, muc_before_test, muc_after_test), + unit_test_setup_teardown(test_muc_invites_count_5, muc_before_test, muc_after_test), unit_test_setup_teardown(test_muc_room_is_not_active, muc_before_test, muc_after_test), - unit_test_setup_teardown(test_muc_room_is_active, muc_before_test, muc_after_test), + unit_test_setup_teardown(test_muc_active, muc_before_test, muc_after_test), unit_test(cmd_bookmark_shows_message_when_disconnected), unit_test(cmd_bookmark_shows_message_when_disconnecting), |