From 79c92656f996cbd2621c6c1cd240d73991f9debd Mon Sep 17 00:00:00 2001 From: James Booth Date: Sat, 19 Jan 2013 23:52:50 +0000 Subject: [PATCH] Added retrieval of caps string from presence --- src/contact.c | 82 ++++++++++++++++++---------------------------- src/contact.h | 2 ++ src/contact_list.c | 16 +++++---- src/contact_list.h | 2 +- src/jabber.c | 16 ++++++++- src/profanity.c | 10 +++--- src/profanity.h | 2 +- src/stanza.c | 16 +++++++++ src/stanza.h | 5 +++ 9 files changed, 86 insertions(+), 65 deletions(-) diff --git a/src/contact.c b/src/contact.c index ef4b807d..2d8e89c5 100644 --- a/src/contact.c +++ b/src/contact.c @@ -25,6 +25,7 @@ #include +#include "common.h" #include "contact.h" struct p_contact_t { @@ -33,6 +34,7 @@ struct p_contact_t { char *presence; char *status; char *subscription; + char *caps_str; gboolean pending_out; GDateTime *last_activity; }; @@ -67,8 +69,8 @@ p_contact_new(const char * const jid, const char * const name, contact->subscription = strdup("none");; contact->pending_out = pending_out; - contact->last_activity = NULL; + contact->caps_str = NULL; return contact; } @@ -76,37 +78,18 @@ p_contact_new(const char * const jid, const char * const name, void p_contact_free(PContact contact) { - if (contact->jid != NULL) { - free(contact->jid); - contact->jid = NULL; - } - - if (contact->name != NULL) { - free(contact->name); - contact->name = NULL; - } - - if (contact->presence != NULL) { - free(contact->presence); - contact->presence = NULL; - } - - if (contact->status != NULL) { - free(contact->status); - contact->status = NULL; - } - - if (contact->subscription != NULL) { - free(contact->subscription); - contact->subscription = NULL; - } + FREE_SET_NULL(contact->jid); + FREE_SET_NULL(contact->name); + FREE_SET_NULL(contact->presence); + FREE_SET_NULL(contact->status); + FREE_SET_NULL(contact->subscription); + FREE_SET_NULL(contact->caps_str); if (contact->last_activity != NULL) { g_date_time_unref(contact->last_activity); } - free(contact); - contact = NULL; + FREE_SET_NULL(contact); } const char * @@ -151,17 +134,17 @@ p_contact_last_activity(const PContact contact) return contact->last_activity; } +const char * +p_contact_caps_str(const PContact contact) +{ + return contact->caps_str; +} + void p_contact_set_presence(const PContact contact, const char * const presence) { - if (contact->presence != NULL) { - free(contact->presence); - contact->presence = NULL; - } - - if (presence == NULL) { - contact->presence = NULL; - } else { + FREE_SET_NULL(contact->presence); + if (presence != NULL) { contact->presence = strdup(presence); } } @@ -169,14 +152,8 @@ p_contact_set_presence(const PContact contact, const char * const presence) void p_contact_set_status(const PContact contact, const char * const status) { - if (contact->status != NULL) { - free(contact->status); - contact->status = NULL; - } - - if (status == NULL) { - contact->status = NULL; - } else { + FREE_SET_NULL(contact->status); + if (status != NULL) { contact->status = strdup(status); } } @@ -184,14 +161,8 @@ p_contact_set_status(const PContact contact, const char * const status) void p_contact_set_subscription(const PContact contact, const char * const subscription) { - if (contact->subscription != NULL) { - free(contact->subscription); - contact->subscription = NULL; - } - - if (subscription == NULL) { - contact->subscription = strdup("none"); - } else { + FREE_SET_NULL(contact->subscription); + if (subscription != NULL) { contact->subscription = strdup(subscription); } } @@ -214,3 +185,12 @@ 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) +{ + FREE_SET_NULL(contact->caps_str); + if (caps_str != NULL) { + contact->caps_str = strdup(caps_str); + } +} diff --git a/src/contact.h b/src/contact.h index a2842976..a0115cfb 100644 --- a/src/contact.h +++ b/src/contact.h @@ -34,11 +34,13 @@ const char* p_contact_name(PContact contact); const char* p_contact_presence(PContact contact); const char* p_contact_status(PContact contact); const char* p_contact_subscription(const PContact contact); +const char* p_contact_caps_str(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, const char * const presence); 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); diff --git a/src/contact_list.c b/src/contact_list.c index 2c9bc220..2c96ca29 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -87,9 +87,9 @@ contact_list_remove(const char * const jid) gboolean contact_list_update_contact(const char * const jid, const char * const presence, - const char * const status, GDateTime *last_activity) + const char * const status, GDateTime *last_activity, const char * const caps_str) { - gboolean changed = FALSE; + gboolean presence_changed = FALSE; PContact contact = g_hash_table_lookup(contacts, jid); if (contact == NULL) { @@ -98,20 +98,24 @@ contact_list_update_contact(const char * const jid, const char * const presence, if (g_strcmp0(p_contact_presence(contact), presence) != 0) { p_contact_set_presence(contact, presence); - changed = TRUE; + presence_changed = TRUE; } if (g_strcmp0(p_contact_status(contact), status) != 0) { p_contact_set_status(contact, status); - changed = TRUE; + presence_changed = TRUE; } if (!_datetimes_equal(p_contact_last_activity(contact), last_activity)) { p_contact_set_last_activity(contact, last_activity); - changed = TRUE; + presence_changed = TRUE; } - return changed; + if (g_strcmp0(p_contact_caps_str(contact), caps_str) != 0) { + p_contact_set_caps_str(contact, caps_str); + } + + return presence_changed; } void diff --git a/src/contact_list.h b/src/contact_list.h index da95aeac..43350631 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -36,7 +36,7 @@ gboolean contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription, gboolean pending_out); gboolean contact_list_update_contact(const char * const jid, const char * const presence, - const char * const status, GDateTime *last_activity); + const char * const status, GDateTime *last_activity, const char * const caps_str); void contact_list_update_subscription(const char * const jid, const char * const subscription, gboolean pending_out); gboolean contact_list_has_pending_subscriptions(void); diff --git a/src/jabber.c b/src/jabber.c index 2d69ebec..a85ecbed 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -1055,6 +1055,20 @@ _presence_handler(xmpp_conn_t * const conn, g_date_time_unref(now); } + char *caps_str = NULL; + xmpp_stanza_t *caps = stanza_get_caps(stanza); + if (caps != NULL) { + char *node = xmpp_stanza_get_attribute(caps, STANZA_ATTR_NODE); + char *ver = xmpp_stanza_get_attribute(caps, STANZA_ATTR_VER); + + if ((node != NULL) && (ver != NULL)) { + GString *caps_gstr = g_string_new(node); + g_string_append(caps_gstr, ver); + caps_str = caps_gstr->str; + g_string_free(caps_gstr, FALSE); + } + } + xmpp_stanza_t *status = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_STATUS); if (status != NULL) status_str = xmpp_stanza_get_text(status); @@ -1069,7 +1083,7 @@ _presence_handler(xmpp_conn_t * const conn, show_str = "online"; if (strcmp(my_jid->barejid, from_jid->barejid) !=0) { - prof_handle_contact_online(from_jid->barejid, show_str, status_str, last_activity); + prof_handle_contact_online(from_jid->barejid, show_str, status_str, last_activity, caps_str); } } else if (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0) { if (strcmp(my_jid->barejid, from_jid->barejid) !=0) { diff --git a/src/profanity.c b/src/profanity.c index 91d8be78..a8e80870 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -347,11 +347,11 @@ prof_handle_leave_room(const char * const room) void prof_handle_contact_online(char *contact, char *show, char *status, - GDateTime *last_activity) + GDateTime *last_activity, char *caps_str) { - gboolean updated = contact_list_update_contact(contact, show, status, last_activity); + gboolean presence_changed = contact_list_update_contact(contact, show, status, last_activity, caps_str); - if (updated) { + if (presence_changed) { PContact result = contact_list_get_contact(contact); if (p_contact_subscription(result) != NULL) { if (strcmp(p_contact_subscription(result), "none") != 0) { @@ -365,9 +365,9 @@ prof_handle_contact_online(char *contact, char *show, char *status, void prof_handle_contact_offline(char *contact, char *show, char *status) { - gboolean updated = contact_list_update_contact(contact, "offline", status, NULL); + gboolean presence_changed = contact_list_update_contact(contact, "offline", status, NULL, NULL); - if (updated) { + if (presence_changed) { 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/profanity.h b/src/profanity.h index 69f4adf5..1bc825e8 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -34,7 +34,7 @@ void prof_handle_disconnect(const char * const jid); void prof_handle_failed_login(void); void prof_handle_typing(char *from); void prof_handle_contact_online(char *contact, char *show, char *status, - GDateTime *last_activity); + GDateTime *last_activity, char *caps_str); void prof_handle_contact_offline(char *contact, char *show, char *status); void prof_handle_incoming_message(char *from, char *message, gboolean priv); void prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, diff --git a/src/stanza.c b/src/stanza.c index 7bf9414a..aa75abe3 100644 --- a/src/stanza.c +++ b/src/stanza.c @@ -391,3 +391,19 @@ stanza_get_idle_time(xmpp_stanza_t * const stanza) return result; } } + +xmpp_stanza_t * +stanza_get_caps(xmpp_stanza_t * const stanza) +{ + xmpp_stanza_t *caps = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_C); + + if (caps == NULL) { + return NULL; + } + + if (strcmp(xmpp_stanza_get_ns(caps), STANZA_NS_CAPS) != 0) { + return NULL; + } + + return caps; +} diff --git a/src/stanza.h b/src/stanza.h index a0a22908..98383293 100644 --- a/src/stanza.h +++ b/src/stanza.h @@ -47,6 +47,7 @@ #define STANZA_NAME_TEXT "text" #define STANZA_NAME_SUBJECT "subject" #define STANZA_NAME_ITEM "item" +#define STANZA_NAME_C "c" #define STANZA_TYPE_CHAT "chat" #define STANZA_TYPE_GROUPCHAT "groupchat" @@ -72,6 +73,8 @@ #define STANZA_ATTR_ASK "ask" #define STANZA_ATTR_ID "id" #define STANZA_ATTR_SECONDS "seconds" +#define STANZA_ATTR_NODE "node" +#define STANZA_ATTR_VER "ver" #define STANZA_TEXT_AWAY "away" #define STANZA_TEXT_DND "dnd" @@ -82,6 +85,7 @@ #define STANZA_NS_CHATSTATES "http://jabber.org/protocol/chatstates" #define STANZA_NS_MUC "http://jabber.org/protocol/muc" #define STANZA_NS_MUC_USER "http://jabber.org/protocol/muc#user" +#define STANZA_NS_CAPS "http://jabber.org/protocol/caps" #define STANZA_NS_PING "urn:xmpp:ping" #define STANZA_NS_LASTACTIVITY "jabber:iq:last" @@ -118,5 +122,6 @@ gboolean stanza_is_room_nick_change(xmpp_stanza_t * const stanza); char* stanza_get_new_nick(xmpp_stanza_t * const stanza); int stanza_get_idle_time(xmpp_stanza_t * const stanza); +xmpp_stanza_t * stanza_get_caps(xmpp_stanza_t * const stanza); #endif