about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c38
-rw-r--r--src/contact.c139
-rw-r--r--src/contact.h9
-rw-r--r--src/contact_list.c13
-rw-r--r--src/contact_list.h3
-rw-r--r--src/muc.c4
-rw-r--r--src/profanity.c2
-rw-r--r--src/resource.c30
-rw-r--r--src/resource.h2
-rw-r--r--src/ui/windows.c125
-rw-r--r--src/xmpp/iq.c2
-rw-r--r--src/xmpp/presence.c4
12 files changed, 212 insertions, 159 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 73c8b07a..648ab64c 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -1561,7 +1561,7 @@ _cmd_who(gchar **args, struct cmd_help_t help)
 
                     win_show_room_roster(room, filtered, "unavailable");
 
-                // online, show all status that indicate online
+                // online, available resources
                 } else if (strcmp("online", presence) == 0) {
                     GList *filtered = NULL;
 
@@ -1575,7 +1575,7 @@ _cmd_who(gchar **args, struct cmd_help_t help)
 
                     win_show_room_roster(room, filtered, "online");
 
-                // online, show all status that indicate online
+                // offline, no available resources
                 } else if (strcmp("offline", presence) == 0) {
                     GList *filtered = NULL;
 
@@ -1621,9 +1621,7 @@ _cmd_who(gchar **args, struct cmd_help_t help)
 
                     while (list != NULL) {
                         PContact contact = list->data;
-                        const char * const contact_presence = (p_contact_presence(contact));
-                        if ((strcmp(contact_presence, "online") == 0)
-                                || (strcmp(contact_presence, "chat") == 0)) {
+                        if (p_contact_is_available(contact)) {
                             filtered = g_slist_append(filtered, contact);
                         }
                         list = g_slist_next(list);
@@ -1638,11 +1636,7 @@ _cmd_who(gchar **args, struct cmd_help_t help)
 
                     while (list != NULL) {
                         PContact contact = list->data;
-                        const char * const contact_presence = (p_contact_presence(contact));
-                        if ((strcmp(contact_presence, "offline") == 0)
-                                || (strcmp(contact_presence, "away") == 0)
-                                || (strcmp(contact_presence, "dnd") == 0)
-                                || (strcmp(contact_presence, "xa") == 0)) {
+                        if (!p_contact_is_available(contact)) {
                             filtered = g_slist_append(filtered, contact);
                         }
                         list = g_slist_next(list);
@@ -1650,19 +1644,29 @@ _cmd_who(gchar **args, struct cmd_help_t help)
 
                     cons_show_contacts(filtered);
 
-                // online, show all status that indicate online
+                // online, available resources
                 } else if (strcmp("online", presence) == 0) {
                     cons_show("Contacts (%s):", presence);
                     GSList *filtered = NULL;
 
                     while (list != NULL) {
                         PContact contact = list->data;
-                        const char * const contact_presence = (p_contact_presence(contact));
-                        if ((strcmp(contact_presence, "online") == 0)
-                                || (strcmp(contact_presence, "away") == 0)
-                                || (strcmp(contact_presence, "dnd") == 0)
-                                || (strcmp(contact_presence, "xa") == 0)
-                                || (strcmp(contact_presence, "chat") == 0)) {
+                        if (p_contact_has_available_resource(contact)) {
+                            filtered = g_slist_append(filtered, contact);
+                        }
+                        list = g_slist_next(list);
+                    }
+
+                    cons_show_contacts(filtered);
+
+                // offline, no available resources
+                } else if (strcmp("online", presence) == 0) {
+                    cons_show("Contacts (%s):", presence);
+                    GSList *filtered = NULL;
+
+                    while (list != NULL) {
+                        PContact contact = list->data;
+                        if (!p_contact_has_available_resource(contact)) {
                             filtered = g_slist_append(filtered, contact);
                         }
                         list = g_slist_next(list);
diff --git a/src/contact.c b/src/contact.c
index ece79ca9..b63ff408 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -34,6 +34,7 @@ struct p_contact_t {
     char *barejid;
     char *name;
     char *subscription;
+    char *offline_message;
     gboolean pending_out;
     GDateTime *last_activity;
     GHashTable *available_resources;
@@ -41,7 +42,8 @@ struct p_contact_t {
 
 PContact
 p_contact_new(const char * const barejid, const char * const name,
-    const char * const subscription, gboolean pending_out)
+    const char * const subscription, const char * const offline_message,
+    gboolean pending_out)
 {
     PContact contact = malloc(sizeof(struct p_contact_t));
     contact->barejid = strdup(barejid);
@@ -57,6 +59,11 @@ p_contact_new(const char * const barejid, const char * const name,
     else
         contact->subscription = strdup("none");
 
+    if (offline_message != NULL)
+        contact->offline_message = strdup(offline_message);
+    else
+        contact->offline_message = NULL;
+
     contact->pending_out = pending_out;
     contact->last_activity = NULL;
 
@@ -101,6 +108,7 @@ p_contact_free(PContact contact)
     FREE_SET_NULL(contact->barejid);
     FREE_SET_NULL(contact->name);
     FREE_SET_NULL(contact->subscription);
+    FREE_SET_NULL(contact->offline_message);
 
     if (contact->last_activity != NULL) {
         g_date_time_unref(contact->last_activity);
@@ -123,40 +131,33 @@ p_contact_name(const PContact contact)
     return contact->name;
 }
 
-static resource_presence_t
-_highest_presence(resource_presence_t first, resource_presence_t second)
+static Resource *
+_highest_presence(Resource *first, Resource *second)
 {
-    if (first == RESOURCE_CHAT) {
+    if (first->presence == RESOURCE_CHAT) {
         return first;
-    } else if (second == RESOURCE_CHAT) {
+    } else if (second->presence == RESOURCE_CHAT) {
         return second;
-    } else if (first == RESOURCE_ONLINE) {
+    } else if (first->presence == RESOURCE_ONLINE) {
         return first;
-    } else if (second == RESOURCE_ONLINE) {
+    } else if (second->presence == RESOURCE_ONLINE) {
         return second;
-    } else if (first == RESOURCE_AWAY) {
+    } else if (first->presence == RESOURCE_AWAY) {
         return first;
-    } else if (second == RESOURCE_AWAY) {
+    } else if (second->presence == RESOURCE_AWAY) {
         return second;
-    } else if (first == RESOURCE_XA) {
+    } else if (first->presence == RESOURCE_XA) {
         return first;
-    } else if (second == RESOURCE_XA) {
+    } else if (second->presence == RESOURCE_XA) {
         return second;
     } else {
         return first;
     }
 }
 
-const char *
-p_contact_presence(const PContact contact)
+Resource *
+_get_most_available_resource(PContact contact)
 {
-    assert(contact != NULL);
-
-    // no available resources, offline
-    if (g_hash_table_size(contact->available_resources) == 0) {
-        return "offline";
-    }
-
     // find resource with highest priority, if more than one,
     // use highest availability, in the following order:
     //      chat
@@ -165,36 +166,55 @@ p_contact_presence(const PContact contact)
     //      xa
     //      dnd
     GList *resources = g_hash_table_get_values(contact->available_resources);
-    Resource *resource = resources->data;
-    int highest_priority = resource->priority;
-    resource_presence_t presence = resource->presence;
+    Resource *current = resources->data;
+    Resource *highest = current;
     resources = g_list_next(resources);
     while (resources != NULL) {
-        resource = resources->data;
+        current = resources->data;
 
         // priority is same as current highest, choose presence
-        if (resource->priority == highest_priority) {
-            presence = _highest_presence(presence, resource->presence);
+        if (current->priority == highest->priority) {
+            highest = _highest_presence(highest, current);
 
         // priority higher than current highest, set new presence
-        } else if (resource->priority > highest_priority) {
-            highest_priority = resource->priority;
-            presence = resource->presence;
+        } else if (current->priority > highest->priority) {
+            highest = current;
         }
 
         resources = g_list_next(resources);
     }
 
-    return string_from_resource_presence(presence);
+    return highest;
 }
 
 const char *
-p_contact_status(const PContact contact, const char * const resource)
+p_contact_presence(const PContact contact)
 {
     assert(contact != NULL);
-    assert(resource != NULL);
-    Resource *resourcep = g_hash_table_lookup(contact->available_resources, "default");
-    return resourcep->status;
+
+    // no available resources, offline
+    if (g_hash_table_size(contact->available_resources) == 0) {
+        return "offline";
+    }
+
+    Resource *resource = _get_most_available_resource(contact);
+
+    return string_from_resource_presence(resource->presence);
+}
+
+const char *
+p_contact_status(const PContact contact)
+{
+    assert(contact != NULL);
+
+    // no available resources, use offline message
+    if (g_hash_table_size(contact->available_resources) == 0) {
+        return contact->offline_message;
+    }
+
+    Resource *resource = _get_most_available_resource(contact);
+
+    return resource->status;
 }
 
 const char *
@@ -215,15 +235,12 @@ p_contact_last_activity(const PContact contact)
     return contact->last_activity;
 }
 
-const char *
-p_contact_caps_str(const PContact contact)
+GList *
+p_contact_get_available_resources(const PContact contact)
 {
-    if (g_hash_table_size(contact->available_resources) == 0) {
-        return NULL;
-    } else {
-        Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-        return resource->caps_str;
-    }
+    assert(contact != NULL);
+
+    return g_hash_table_get_values(contact->available_resources);
 }
 
 gboolean
@@ -234,18 +251,14 @@ p_contact_is_available(const PContact contact)
         return FALSE;
     }
 
-    // if any resource is CHAT or ONLINE, available
-    GList *resources = g_hash_table_get_values(contact->available_resources);
-    while (resources != NULL) {
-        Resource *resource = resources->data;
-        resource_presence_t presence = resource->presence;
-        if ((presence == RESOURCE_ONLINE) || (presence == RESOURCE_CHAT)) {
-            return TRUE;
-        }
-        resources = g_list_next(resources);
+    // if most available resource is CHAT or ONLINE, available
+    Resource *most_available = _get_most_available_resource(contact);
+    if ((most_available->presence == RESOURCE_ONLINE) ||
+        (most_available->presence == RESOURCE_CHAT)) {
+        return TRUE;
+    } else {
+        return FALSE;
     }
-
-    return FALSE;
 }
 
 gboolean
@@ -261,16 +274,6 @@ p_contact_set_presence(const PContact contact, Resource *resource)
 }
 
 void
-p_contact_set_status(const PContact contact, const char * const status)
-{
-    Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-    FREE_SET_NULL(resource->status);
-    if (status != NULL) {
-        resource->status = strdup(status);
-    }
-}
-
-void
 p_contact_set_subscription(const PContact contact, const char * const subscription)
 {
     FREE_SET_NULL(contact->subscription);
@@ -297,13 +300,3 @@ p_contact_set_last_activity(const PContact contact, GDateTime *last_activity)
         contact->last_activity = g_date_time_ref(last_activity);
     }
 }
-
-void
-p_contact_set_caps_str(const PContact contact, const char * const caps_str)
-{
-    Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-    FREE_SET_NULL(resource->caps_str);
-    if (caps_str != NULL) {
-        resource->caps_str = strdup(caps_str);
-    }
-}
diff --git a/src/contact.h b/src/contact.h
index 91bc1024..beba5725 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -28,7 +28,8 @@
 typedef struct p_contact_t *PContact;
 
 PContact p_contact_new(const char * const barejid, const char * const name,
-    const char * const subscription, gboolean pending_out);
+    const char * const subscription, const char * const offline_message,
+    gboolean pending_out);
 PContact p_contact_new_subscription(const char * const barejid,
     const char * const subscription, gboolean pending_out);
 void p_contact_add_resource(PContact contact, Resource *resource);
@@ -37,17 +38,17 @@ void p_contact_free(PContact contact);
 const char* p_contact_barejid(PContact contact);
 const char* p_contact_name(PContact contact);
 const char* p_contact_presence(PContact contact);
-const char* p_contact_status(PContact contact, const char * const resource);
+const char* p_contact_status(PContact contact);
 const char* p_contact_subscription(const PContact contact);
-const char* p_contact_caps_str(const PContact contact);
+GList * p_contact_get_available_resources(const PContact contact);
 GDateTime* p_contact_last_activity(const PContact contact);
 gboolean p_contact_pending_out(const PContact contact);
 void p_contact_set_presence(const PContact contact, Resource *resource);
 void p_contact_set_status(const PContact contact, const char * const status);
 void p_contact_set_subscription(const PContact contact, const char * const subscription);
-void p_contact_set_caps_str(const PContact contact, const char * const caps_str);
 void p_contact_set_pending_out(const PContact contact, gboolean pending_out);
 void p_contact_set_last_activity(const PContact contact, GDateTime *last_activity);
 gboolean p_contact_is_available(const PContact contact);
+gboolean p_contact_has_available_resource(const PContact contact);
 
 #endif
diff --git a/src/contact_list.c b/src/contact_list.c
index ad00a4c3..be454cb7 100644
--- a/src/contact_list.c
+++ b/src/contact_list.c
@@ -65,13 +65,15 @@ contact_list_reset_search_attempts(void)
 
 gboolean
 contact_list_add(const char * const barejid, const char * const name,
-    const char * const subscription, gboolean pending_out)
+    const char * const subscription, const char * const offline_message,
+    gboolean pending_out)
 {
     gboolean added = FALSE;
     PContact contact = g_hash_table_lookup(contacts, barejid);
 
     if (contact == NULL) {
-        contact = p_contact_new(barejid, name, subscription, pending_out);
+        contact = p_contact_new(barejid, name, subscription, offline_message,
+            pending_out);
         g_hash_table_insert(contacts, strdup(barejid), contact);
         autocomplete_add(ac, strdup(barejid));
         added = TRUE;
@@ -114,8 +116,11 @@ contact_list_contact_offline(const char * const barejid,
     if (contact == NULL) {
         return FALSE;
     }
-
-    return p_contact_remove_resource(contact, resource);
+    if (resource == NULL) {
+        return TRUE;
+    } else {
+        return p_contact_remove_resource(contact, resource);
+    }
 }
 
 void
diff --git a/src/contact_list.h b/src/contact_list.h
index 581d6f66..eb15a6ab 100644
--- a/src/contact_list.h
+++ b/src/contact_list.h
@@ -33,7 +33,8 @@ void contact_list_free(void);
 void contact_list_reset_search_attempts(void);
 void contact_list_remove(const char * const barejid);
 gboolean contact_list_add(const char * const barejid, const char * const name,
-    const char * const subscription, gboolean pending_out);
+    const char * const subscription, const char * const offline_message,
+    gboolean pending_out);
 gboolean contact_list_update_presence(const char * const barejid,
     Resource *resource, GDateTime *last_activity);
 void contact_list_update_subscription(const char * const barejid,
diff --git a/src/muc.c b/src/muc.c
index 778b2ce3..dfa3f194 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -217,10 +217,10 @@ muc_add_to_roster(const char * const room, const char * const nick,
             updated = TRUE;
             autocomplete_add(chat_room->nick_ac, strdup(nick));
         } else if ((g_strcmp0(p_contact_presence(old), show) != 0) ||
-                    (g_strcmp0(p_contact_status(old, nick), status) != 0)) {
+                    (g_strcmp0(p_contact_status(old), status) != 0)) {
             updated = TRUE;
         }
-        PContact contact = p_contact_new(nick, NULL, NULL, FALSE);
+        PContact contact = p_contact_new(nick, NULL, NULL, NULL, FALSE);
         resource_presence_t resource_presence = resource_presence_from_string(show);
         Resource *resource = resource_new(nick, resource_presence, status, 0, caps_str);
         p_contact_set_presence(contact, resource);
diff --git a/src/profanity.c b/src/profanity.c
index d294a266..0052679b 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -339,7 +339,7 @@ prof_handle_contact_offline(char *contact, char *resource, char *status)
 {
     gboolean updated = contact_list_contact_offline(contact, resource, status);
 
-    if (updated) {
+    if (resource != NULL && updated) {
         PContact result = contact_list_get_contact(contact);
         if (p_contact_subscription(result) != NULL) {
             if (strcmp(p_contact_subscription(result), "none") != 0) {
diff --git a/src/resource.c b/src/resource.c
index 3ec664ec..0a7838f3 100644
--- a/src/resource.c
+++ b/src/resource.c
@@ -49,6 +49,36 @@ Resource * resource_new(const char * const name, resource_presence_t presence,
     return new_resource;
 }
 
+int
+resource_compare_availability(Resource *first, Resource *second)
+{
+    if (first->priority > second->priority) {
+        return -1;
+    } else if (first->priority < second->priority) {
+        return 1;
+    } else { // priorities equal
+        if (first->presence == RESOURCE_CHAT) {
+            return -1;
+        } else if (second->presence == RESOURCE_CHAT) {
+            return 1;
+        } else if (first->presence == RESOURCE_ONLINE) {
+            return -1;
+        } else if (second->presence == RESOURCE_ONLINE) {
+            return 1;
+        } else if (first->presence == RESOURCE_AWAY) {
+            return -1;
+        } else if (second->presence == RESOURCE_AWAY) {
+            return 1;
+        } else if (first->presence == RESOURCE_XA) {
+            return -1;
+        } else if (second->presence == RESOURCE_XA) {
+            return 1;
+        } else {
+            return -1;
+        }
+    }
+}
+
 void resource_destroy(Resource *resource)
 {
     assert(resource != NULL);
diff --git a/src/resource.h b/src/resource.h
index 534153e4..1db5dc0f 100644
--- a/src/resource.h
+++ b/src/resource.h
@@ -37,4 +37,6 @@ Resource * resource_new(const char * const name, resource_presence_t presence,
     const char * const status, const int priority, const char * const caps_str);
 void resource_destroy(Resource *resource);
 
+int resource_compare_availability(Resource *first, Resource *second);
+
 #endif
diff --git a/src/ui/windows.c b/src/ui/windows.c
index 2b269223..d23257ba 100644
--- a/src/ui/windows.c
+++ b/src/ui/windows.c
@@ -2405,9 +2405,9 @@ _win_show_info(WINDOW *win, PContact pcontact)
     const char *barejid = p_contact_barejid(pcontact);
     const char *name = p_contact_name(pcontact);
     const char *presence = p_contact_presence(pcontact);
-    const char *status = p_contact_status(pcontact);
     const char *sub = p_contact_subscription(pcontact);
-    const char *caps_str = p_contact_caps_str(pcontact);
+    GList *resources = p_contact_get_available_resources(pcontact);
+    GList *ordered_resources = NULL;
     GDateTime *last_activity = p_contact_last_activity(pcontact);
 
     _win_show_time(win, '-');
@@ -2418,22 +2418,12 @@ _win_show_info(WINDOW *win, PContact pcontact)
     if (name != NULL) {
         wprintw(win, " (%s)", name);
     }
-    wprintw(win, ":\n");
-    _presence_colour_off(win, presence);
-
-    _win_show_time(win, '-');
-    wprintw(win, "Presence      : ");
-    _presence_colour_on(win, presence);
-    wprintw(win, "%s", presence);
-    if (status != NULL) {
-        wprintw(win, ", \"%s\"", status);
-    }
-    wprintw(win, "\n");
     _presence_colour_off(win, presence);
+    wprintw(win, ":\n");
 
     if (sub != NULL) {
         _win_show_time(win, '-');
-        wprintw(win, "Subscription  : %s\n", sub);
+        wprintw(win, "Subscription: %s\n", sub);
     }
 
     if (last_activity != NULL) {
@@ -2441,7 +2431,7 @@ _win_show_info(WINDOW *win, PContact pcontact)
         GTimeSpan span = g_date_time_difference(now, last_activity);
 
         _win_show_time(win, '-');
-        wprintw(win, "Last activity : ");
+        wprintw(win, "Last activity: ");
 
         int hours = span / G_TIME_SPAN_HOUR;
         span = span - hours * G_TIME_SPAN_HOUR;
@@ -2461,53 +2451,80 @@ _win_show_info(WINDOW *win, PContact pcontact)
         g_date_time_unref(now);
     }
 
-    if (caps_str != NULL) {
-        Capabilities *caps = caps_get(caps_str);
-        if (caps != NULL) {
-            // show identity
-            if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
-                _win_show_time(win, '-');
-                wprintw(win, "Identity      : ");
-                if (caps->name != NULL) {
-                    wprintw(win, "%s", caps->name);
-                    if ((caps->category != NULL) || (caps->type != NULL)) {
-                        wprintw(win, " ");
+    if (resources != NULL) {
+        _win_show_time(win, '-');
+        wprintw(win, "Resources:\n");
+
+        // sort in order of availabiltiy
+        while (resources != NULL) {
+            Resource *resource = resources->data;
+            ordered_resources = g_list_insert_sorted(ordered_resources,
+                resource, (GCompareFunc)resource_compare_availability);
+            resources = g_list_next(resources);
+        }
+    }
+
+    while (ordered_resources != NULL) {
+        Resource *resource = ordered_resources->data;
+        const char *resource_presence = string_from_resource_presence(resource->presence);
+        _win_show_time(win, '-');
+        _presence_colour_on(win, resource_presence);
+        wprintw(win, "  %s (%d), %s", resource->name, resource->priority, resource_presence);
+        if (resource->status != NULL) {
+            wprintw(win, ", \"%s\"", resource->status);
+        }
+        wprintw(win, "\n");
+        _presence_colour_off(win, resource_presence);
+
+        if (resource->caps_str != NULL) {
+            Capabilities *caps = caps_get(resource->caps_str);
+            if (caps != NULL) {
+                // show identity
+                if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
+                    _win_show_time(win, '-');
+                    wprintw(win, "    Identity: ");
+                    if (caps->name != NULL) {
+                        wprintw(win, "%s", caps->name);
+                        if ((caps->category != NULL) || (caps->type != NULL)) {
+                            wprintw(win, " ");
+                        }
+                    }
+                    if (caps->type != NULL) {
+                        wprintw(win, "%s", caps->type);
+                        if (caps->category != NULL) {
+                            wprintw(win, " ");
+                        }
                     }
-                }
-                if (caps->type != NULL) {
-                    wprintw(win, "%s", caps->type);
                     if (caps->category != NULL) {
-                        wprintw(win, " ");
+                        wprintw(win, "%s", caps->category);
                     }
+                    wprintw(win, "\n");
                 }
-                if (caps->category != NULL) {
-                    wprintw(win, "%s", caps->category);
+                if (caps->software != NULL) {
+                    _win_show_time(win, '-');
+                    wprintw(win, "    Software: %s", caps->software);
+                }
+                if (caps->software_version != NULL) {
+                    wprintw(win, ", %s", caps->software_version);
+                }
+                if ((caps->software != NULL) || (caps->software_version != NULL)) {
+                    wprintw(win, "\n");
+                }
+                if (caps->os != NULL) {
+                    _win_show_time(win, '-');
+                    wprintw(win, "    OS: %s", caps->os);
+                }
+                if (caps->os_version != NULL) {
+                    wprintw(win, ", %s", caps->os_version);
+                }
+                if ((caps->os != NULL) || (caps->os_version != NULL)) {
+                    wprintw(win, "\n");
                 }
-                wprintw(win, "\n");
-            }
-            if (caps->software != NULL) {
-                _win_show_time(win, '-');
-                wprintw(win, "Software      : %s", caps->software);
-            }
-            if (caps->software_version != NULL) {
-                wprintw(win, ", %s", caps->software_version);
-            }
-            if ((caps->software != NULL) || (caps->software_version != NULL)) {
-                wprintw(win, "\n");
-            }
-            if (caps->os != NULL) {
-                _win_show_time(win, '-');
-                wprintw(win, "OS            : %s", caps->os);
-            }
-            if (caps->os_version != NULL) {
-                wprintw(win, ", %s\n", caps->os_version);
-            }
-            if ((caps->os != NULL) || (caps->os_version != NULL)) {
-                wprintw(win, "\n");
             }
         }
-    }
 
+        ordered_resources = g_list_next(ordered_resources);
+    }
 }
 
 void
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 525c7cf3..9d0b43e9 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -144,7 +144,7 @@ _iq_handle_roster_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
                 pending_out = TRUE;
             }
 
-            gboolean added = contact_list_add(barejid, name, sub, pending_out);
+            gboolean added = contact_list_add(barejid, name, sub, NULL, pending_out);
 
             if (!added) {
                 log_warning("Attempt to add contact twice: %s", barejid);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 5773e349..4d152a20 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -342,7 +342,7 @@ _unavailable_handler(xmpp_conn_t * const conn,
         status_str = NULL;
 
     if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
-        prof_handle_contact_offline(from_jid->barejid, "default", status_str);
+        prof_handle_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str);
     }
 
     jid_destroy(my_jid);
@@ -422,7 +422,7 @@ _available_handler(xmpp_conn_t * const conn,
     if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
         // create the resource
         resource_presence_t presence = resource_presence_from_string(show_str);
-        Resource *resource = resource_new("default", presence,
+        Resource *resource = resource_new(from_jid->resourcepart, presence,
             status_str, priority, caps_key);
         prof_handle_contact_online(from_jid->barejid, resource, last_activity);
     }