diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index bf724ee9..c1cc5763 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -1262,6 +1262,10 @@ cmd_sub(ProfWin* window, const char* const command, gchar** args) } auto_jid Jid* jidp = jid_create(jid); + if (!jidp) { + cons_bad_cmd_usage(command); + return TRUE; + } if (jidp == NULL) { cons_show("Malformed JID: %s", jid); @@ -1277,9 +1281,13 @@ cmd_sub(ProfWin* window, const char* const command, gchar** args) cons_show("Deleted/denied subscription for %s", jidp->barejid); log_info("Deleted/denied subscription for %s", jidp->barejid); } else if (strcmp(subcmd, "request") == 0) { - presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBE); - cons_show("Sent subscription request to %s.", jidp->barejid); - log_info("Sent subscription request to %s.", jidp->barejid); + if (equals_our_barejid(jidp->barejid)) { + cons_show("Subscription to yourself is implicit."); + } else { + presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBE); + cons_show("Sent subscription request to %s.", jidp->barejid); + log_info("Sent subscription request to %s.", jidp->barejid); + } } else if (strcmp(subcmd, "show") == 0) { PContact contact = roster_get_contact(jidp->barejid); if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) { diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 5249a1c9..fbcf3874 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -533,8 +533,8 @@ _unavailable_handler(xmpp_stanza_t* const stanza) return; } + auto_char char* status_str = stanza_get_status(stanza, NULL); if (strcmp(my_jid->barejid, from_jid->barejid) != 0) { - auto_char char* status_str = stanza_get_status(stanza, NULL); if (from_jid->resourcepart) { sv_ev_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); @@ -544,6 +544,7 @@ _unavailable_handler(xmpp_stanza_t* const stanza) } } else { if (from_jid->resourcepart) { + sv_ev_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); connection_remove_available_resource(from_jid->resourcepart); } } @@ -639,8 +640,16 @@ _available_handler(xmpp_stanza_t* const stanza) Resource* resource = stanza_resource_from_presence(xmpp_presence); + char* pgpsig = NULL; + xmpp_stanza_t* x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_SIGNED); + if (x) { + pgpsig = xmpp_stanza_get_text(x); + } + if (g_strcmp0(xmpp_presence->jid->barejid, my_jid->barejid) == 0) { connection_add_available_resource(resource); + Resource* resource_for_roster = resource_copy(resource); + sv_ev_contact_online(xmpp_presence->jid->barejid, resource_for_roster, xmpp_presence->last_activity, pgpsig); const char* account_name = session_get_account_name(); int max_sessions = accounts_get_max_sessions(account_name); if (max_sessions > 0) { @@ -704,16 +713,11 @@ _available_handler(xmpp_stanza_t* const stanza) } } } else { - char* pgpsig = NULL; - xmpp_stanza_t* x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_SIGNED); - if (x) { - pgpsig = xmpp_stanza_get_text(x); - } sv_ev_contact_online(xmpp_presence->jid->barejid, resource, xmpp_presence->last_activity, pgpsig); - xmpp_ctx_t* ctx = connection_get_ctx(); - xmpp_free(ctx, pgpsig); } + xmpp_ctx_t* ctx = connection_get_ctx(); + xmpp_free(ctx, pgpsig); stanza_free_presence(xmpp_presence); } diff --git a/src/xmpp/resource.c b/src/xmpp/resource.c index 007a97c0..4d8ef03b 100644 --- a/src/xmpp/resource.c +++ b/src/xmpp/resource.c @@ -99,6 +99,16 @@ resource_destroy(Resource* resource) } } +Resource* +resource_copy(Resource* resource) +{ + if (resource == NULL) { + return NULL; + } + + return resource_new(resource->name, resource->presence, resource->status, resource->priority); +} + gboolean valid_resource_presence_string(const char* const str) { diff --git a/src/xmpp/resource.h b/src/xmpp/resource.h index 41d20511..9a37890f 100644 --- a/src/xmpp/resource.h +++ b/src/xmpp/resource.h @@ -48,6 +48,7 @@ typedef struct resource_t Resource* resource_new(const char* const name, resource_presence_t presence, const char* const status, const int priority); +Resource* resource_copy(Resource* resource); void resource_destroy(Resource* resource); int resource_compare_availability(Resource* first, Resource* second); diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index 3889fcb1..880848ce 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -47,6 +47,7 @@ #include "xmpp/resource.h" #include "xmpp/contact.h" #include "xmpp/jid.h" +#include "xmpp/xmpp.h" typedef struct prof_roster_t { @@ -392,6 +393,19 @@ roster_add(const char* const barejid, const char* const name, GSList* groups, co } g_hash_table_insert(roster->contacts, strdup(barejid), contact); + + if (equals_our_barejid(barejid)) { + GList* resources = connection_get_available_resources(); + GList* curr = resources; + while (curr) { + Resource* res = curr->data; + Resource* res_copy = resource_copy(res); + p_contact_set_presence(contact, res_copy); + curr = g_list_next(curr); + } + g_list_free(resources); + } + autocomplete_add(roster->barejid_ac, barejid); _add_name_and_barejid(name, barejid); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index e2af28b8..20c053be 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -607,3 +607,9 @@ void blocked_ac_reset(void) { } + +GList* +connection_get_available_resources(void) +{ + return NULL; +}