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.c41
-rw-r--r--src/contact.c66
-rw-r--r--src/contact.h8
-rw-r--r--src/contact_list.c10
-rw-r--r--src/contact_list.h5
-rw-r--r--src/jabber.c83
-rw-r--r--src/jabber.h1
-rw-r--r--src/profanity.c32
-rw-r--r--src/profanity.h5
-rw-r--r--src/windows.c30
10 files changed, 143 insertions, 138 deletions
diff --git a/src/command.c b/src/command.c
index c9110e4b..f8c5b1e9 100644
--- a/src/command.c
+++ b/src/command.c
@@ -718,8 +718,9 @@ _cmd_sub(const char * const inp, struct cmd_help_t help)
         char *user, *lower;
         user = strndup(inp+5, strlen(inp)-5);
         lower = g_utf8_strdown(user, -1);
-    
+
         jabber_subscribe(lower);
+        cons_show("Sent subscription request to %s.", user);
 
         result = TRUE;
     }
@@ -824,16 +825,16 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
 
         // get show
         strtok(inp_cpy, " ");
-        char *show = strtok(NULL, " ");
+        char *presence = strtok(NULL, " ");
 
         // bad arg
-        if ((show != NULL)
-                && (strcmp(show, "online") != 0)
-                && (strcmp(show, "offline") != 0)
-                && (strcmp(show, "away") != 0)
-                && (strcmp(show, "chat") != 0)
-                && (strcmp(show, "xa") != 0)
-                && (strcmp(show, "dnd") != 0)) {
+        if ((presence != NULL)
+                && (strcmp(presence, "online") != 0)
+                && (strcmp(presence, "offline") != 0)
+                && (strcmp(presence, "away") != 0)
+                && (strcmp(presence, "chat") != 0)
+                && (strcmp(presence, "xa") != 0)
+                && (strcmp(presence, "dnd") != 0)) {
             cons_show("Usage: %s", help.usage);
 
         // valid arg
@@ -841,23 +842,23 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
             GSList *list = get_contact_list();
 
             // no arg, show all contacts
-            if (show == NULL) {
+            if (presence == NULL) {
                 cons_show("All contacts:");
                 cons_show_contacts(list);
 
             // online, show all status that indicate online
-            } else if (strcmp("online", show) == 0) {
-                cons_show("Contacts (%s):", show);
+            } 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_show = (p_contact_show(contact));
-                    if ((strcmp(contact_show, "online") == 0)
-                            || (strcmp(contact_show, "away") == 0)
-                            || (strcmp(contact_show, "dnd") == 0)
-                            || (strcmp(contact_show, "xa") == 0)
-                            || (strcmp(contact_show, "chat") == 0)) {
+                    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)) {
                         filtered = g_slist_append(filtered, contact);
                     }
                     list = g_slist_next(list);
@@ -867,12 +868,12 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
 
             // show specific status
             } else {
-                cons_show("Contacts (%s):", show);
+                cons_show("Contacts (%s):", presence);
                 GSList *filtered = NULL;
 
                 while (list != NULL) {
                     PContact contact = list->data;
-                    if (strcmp(p_contact_show(contact), show) == 0) {
+                    if (strcmp(p_contact_presence(contact), presence) == 0) {
                         filtered = g_slist_append(filtered, contact);
                     }
                     list = g_slist_next(list);
diff --git a/src/contact.c b/src/contact.c
index 12a2e500..d217f4c8 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -28,22 +28,31 @@
 #include "contact.h"
 
 struct p_contact_t {
+    char *jid;
     char *name;
-    char *show;
+    char *presence;
     char *status;
+    char *subscription;
 };
 
 PContact
-p_contact_new(const char * const name, const char * const show,
-    const char * const status)
+p_contact_new(const char * const jid, const char * const name,
+    const char * const presence, const char * const status,
+    const char * const subscription)
 {
     PContact contact = malloc(sizeof(struct p_contact_t));
-    contact->name = strdup(name);
+    contact->jid = strdup(jid);
 
-    if (show == NULL || (strcmp(show, "") == 0))
-        contact->show = strdup("online");
+    if (name != NULL) {
+        contact->name = strdup(name);
+    } else {
+        contact->name = NULL;
+    }
+
+    if (presence == NULL || (strcmp(presence, "") == 0))
+        contact->presence = strdup("online");
     else
-        contact->show = strdup(show);
+        contact->presence = strdup(presence);
 
     if (status != NULL)
         contact->status = strdup(status);
@@ -57,8 +66,15 @@ PContact
 p_contact_copy(PContact contact)
 {
     PContact copy = malloc(sizeof(struct p_contact_t));
-    copy->name = strdup(contact->name);
-    copy->show = strdup(contact->show);
+    copy->jid = strdup(contact->jid);
+
+    if (contact->name != NULL) {
+        copy->name = strdup(contact->name);
+    } else {
+        copy->name = NULL;
+    }
+
+    copy->presence = strdup(contact->presence);
 
     if (contact->status != NULL)
         copy->status = strdup(contact->status);
@@ -71,12 +87,21 @@ p_contact_copy(PContact contact)
 void
 p_contact_free(PContact contact)
 {
-    free(contact->name);
+    if (contact->jid != NULL) {
+        free(contact->jid);
+        contact->jid = NULL;
+    }
 
-    if (contact->show != NULL) {
-        free(contact->show);
-        contact->show = 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;
@@ -87,15 +112,21 @@ p_contact_free(PContact contact)
 }
 
 const char *
+p_contact_jid(const PContact contact)
+{
+    return contact->jid;
+}
+
+const char *
 p_contact_name(const PContact contact)
 {
     return contact->name;
 }
 
 const char *
-p_contact_show(const PContact contact)
+p_contact_presence(const PContact contact)
 {
-    return contact->show;
+    return contact->presence;
 }
 
 const char *
@@ -107,9 +138,10 @@ p_contact_status(const PContact contact)
 int
 p_contacts_equal_deep(const PContact c1, const PContact c2)
 {
+    int jid_eq = (g_strcmp0(c1->jid, c2->jid) == 0);
     int name_eq = (g_strcmp0(c1->name, c2->name) == 0);
-    int show_eq = (g_strcmp0(c1->show, c2->show) == 0);
+    int presence_eq = (g_strcmp0(c1->presence, c2->presence) == 0);
     int status_eq = (g_strcmp0(c1->status, c2->status) == 0);
 
-    return (name_eq && show_eq && status_eq);
+    return (jid_eq && name_eq && presence_eq && status_eq);
 }
diff --git a/src/contact.h b/src/contact.h
index 8f778ca9..45c9780f 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -25,12 +25,14 @@
 
 typedef struct p_contact_t *PContact;
 
-PContact p_contact_new(const char * const name, const char * const show,
-    const char * const status);
+PContact p_contact_new(const char * const jid, const char * const name,
+    const char * const presence, const char * const status,
+    const char * const subscription);
 PContact p_contact_copy(PContact contact);
 void p_contact_free(PContact contact);
+const char * p_contact_jid(PContact contact);
 const char * p_contact_name(PContact contact);
-const char * p_contact_show(PContact contact);
+const char * p_contact_presence(PContact contact);
 const char * p_contact_status(PContact contact);
 int p_contacts_equal_deep(const PContact c1, const PContact c2);
 
diff --git a/src/contact_list.c b/src/contact_list.c
index e266e25e..81611818 100644
--- a/src/contact_list.c
+++ b/src/contact_list.c
@@ -30,7 +30,7 @@ static PAutocomplete ac;
 void
 contact_list_init(void)
 {
-    ac = p_obj_autocomplete_new((PStrFunc)p_contact_name,
+    ac = p_obj_autocomplete_new((PStrFunc)p_contact_jid,
                             (PCopyFunc)p_contact_copy,
                             (PEqualDeepFunc)p_contacts_equal_deep,
                             (GDestroyNotify)p_contact_free);
@@ -55,10 +55,12 @@ contact_list_remove(const char * const name)
 }
 
 gboolean
-contact_list_add(const char * const name, const char * const show,
-    const char * const status)
+contact_list_add(const char * const jid, const char * const name,
+    const char * const presence, const char * const status,
+    const char * const subscription)
 {
-    return p_autocomplete_add(ac, p_contact_new(name, show, status));
+    return p_autocomplete_add(ac, p_contact_new(jid, name, presence, status,
+        subscription));
 }
 
 GSList *
diff --git a/src/contact_list.h b/src/contact_list.h
index bc239111..e76a2ec9 100644
--- a/src/contact_list.h
+++ b/src/contact_list.h
@@ -30,8 +30,9 @@
 void contact_list_init(void);
 void contact_list_clear(void);
 void contact_list_reset_search_attempts(void);
-gboolean contact_list_add(const char * const name, const char * const show,
-    const char * const status);
+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 contact_list_remove(const char * const name);
 GSList * get_contact_list(void);
 char * contact_list_find_contact(char *search_str);
diff --git a/src/jabber.c b/src/jabber.c
index f3e3fa27..f9c4f0c7 100644
--- a/src/jabber.c
+++ b/src/jabber.c
@@ -26,6 +26,7 @@
 #include <strophe.h>
 
 #include "common.h"
+#include "contact_list.h"
 #include "jabber.h"
 #include "log.h"
 #include "preferences.h"
@@ -49,6 +50,8 @@ static void _xmpp_file_logger(void * const userdata,
     const char * const msg);
 static xmpp_log_t * _xmpp_get_file_logger();
 
+static void _jabber_roster_request(void);
+
 // XMPP event handlers
 static void _connection_handler(xmpp_conn_t * const conn,
     const xmpp_conn_event_t status, const int error,
@@ -165,26 +168,6 @@ jabber_send(const char * const msg, const char * const recipient)
 }
 
 void
-jabber_roster_request(void)
-{
-    xmpp_stanza_t *iq, *query;
-
-    iq = xmpp_stanza_new(jabber_conn.ctx);
-    xmpp_stanza_set_name(iq, "iq");
-    xmpp_stanza_set_type(iq, "get");
-    xmpp_stanza_set_id(iq, "roster");
-
-    query = xmpp_stanza_new(jabber_conn.ctx);
-    xmpp_stanza_set_name(query, "query");
-    xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
-
-    xmpp_stanza_add_child(iq, query);
-    xmpp_stanza_release(query);
-    xmpp_send(jabber_conn.conn, iq);
-    xmpp_stanza_release(iq);
-}
-
-void
 jabber_subscribe(const char * const recipient)
 {
     xmpp_stanza_t *presence;
@@ -192,7 +175,7 @@ jabber_subscribe(const char * const recipient)
     presence = xmpp_stanza_new(jabber_conn.ctx);
     xmpp_stanza_set_name(presence, "presence");
     xmpp_stanza_set_type(presence, "subscribe");
-    xmpp_stanza_set_attribute(presence, "to", recipient); 
+    xmpp_stanza_set_attribute(presence, "to", recipient);
     xmpp_send(jabber_conn.conn, presence);
     xmpp_stanza_release(presence);
 }
@@ -266,6 +249,26 @@ jabber_free_resources(void)
     xmpp_shutdown();
 }
 
+static void
+_jabber_roster_request(void)
+{
+    xmpp_stanza_t *iq, *query;
+
+    iq = xmpp_stanza_new(jabber_conn.ctx);
+    xmpp_stanza_set_name(iq, "iq");
+    xmpp_stanza_set_type(iq, "get");
+    xmpp_stanza_set_id(iq, "roster");
+
+    query = xmpp_stanza_new(jabber_conn.ctx);
+    xmpp_stanza_set_name(query, "query");
+    xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
+
+    xmpp_stanza_add_child(iq, query);
+    xmpp_stanza_release(query);
+    xmpp_send(jabber_conn.conn, iq);
+    xmpp_stanza_release(iq);
+}
+
 static int
 _message_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata)
@@ -333,20 +336,14 @@ _connection_handler(xmpp_conn_t * const conn,
         const char *jid = xmpp_conn_get_jid(conn);
         prof_handle_login_success(jid);
 
-        xmpp_stanza_t* pres;
         xmpp_handler_add(conn, _message_handler, NULL, "message", NULL, ctx);
         xmpp_handler_add(conn, _presence_handler, NULL, "presence", NULL, ctx);
         xmpp_id_handler_add(conn, _roster_handler, "roster", ctx);
         xmpp_timed_handler_add(conn, _ping_timed_handler, PING_INTERVAL, ctx);
 
-        pres = xmpp_stanza_new(ctx);
-        xmpp_stanza_set_name(pres, "presence");
-        xmpp_send(conn, pres);
-        xmpp_stanza_release(pres);
-
+        _jabber_roster_request();
         jabber_conn.conn_status = JABBER_CONNECTED;
         jabber_conn.presence = PRESENCE_ONLINE;
-        jabber_roster_request();
     } else {
 
         // received close stream response from server after disconnect
@@ -375,6 +372,7 @@ static int
 _roster_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata)
 {
+    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
     xmpp_stanza_t *query, *item;
     char *type = xmpp_stanza_get_type(stanza);
 
@@ -382,27 +380,29 @@ _roster_handler(xmpp_conn_t * const conn,
         log_error("Roster query failed");
     else {
         query = xmpp_stanza_get_child_by_name(stanza, "query");
-        GSList *roster = NULL;
         item = xmpp_stanza_get_children(query);
 
         while (item != NULL) {
-            const char *name = xmpp_stanza_get_attribute(item, "name");
             const char *jid = xmpp_stanza_get_attribute(item, "jid");
+            const char *name = xmpp_stanza_get_attribute(item, "name");
+            const char *sub = xmpp_stanza_get_attribute(item, "subscription");
 
-            jabber_roster_entry *entry = malloc(sizeof(jabber_roster_entry));
+            if (sub != NULL) {
+                if (strcmp(sub, "none") != 0) {
 
-            if (name != NULL) {
-                entry->name = strdup(name);
-            } else {
-                entry->name = NULL;
-            }
-            entry->jid = strdup(jid);
+                contact_list_add(jid, name, "offline", NULL, sub);
 
-            roster = g_slist_append(roster, entry);
+                }
+            }
             item = xmpp_stanza_get_next(item);
         }
-
-        prof_handle_roster(roster);
+/*
+        xmpp_stanza_t* pres;
+        pres = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(pres, "presence");
+        xmpp_send(conn, pres);
+        xmpp_stanza_release(pres);
+*/
     }
 
     return 1;
@@ -449,13 +449,14 @@ _presence_handler(xmpp_conn_t * const conn,
     char *type = xmpp_stanza_get_attribute(stanza, "type");
 
     if (type != NULL) {
+        // allow all subscription requests for now
         if (strcmp(type, "subscribe") == 0) {
             xmpp_stanza_t *presence;
 
             presence = xmpp_stanza_new(jabber_conn.ctx);
             xmpp_stanza_set_name(presence, "presence");
             xmpp_stanza_set_type(presence, "subscribed");
-            xmpp_stanza_set_attribute(presence, "to", short_from); 
+            xmpp_stanza_set_attribute(presence, "to", short_from);
             xmpp_send(jabber_conn.conn, presence);
             xmpp_stanza_release(presence);
             return 1;
diff --git a/src/jabber.h b/src/jabber.h
index f1ca99e5..726fb1a5 100644
--- a/src/jabber.h
+++ b/src/jabber.h
@@ -44,7 +44,6 @@ void jabber_init(const int disable_tls);
 jabber_conn_status_t jabber_connect(const char * const user,
     const char * const passwd);
 void jabber_disconnect(void);
-void jabber_roster_request(void);
 void jabber_process_events(void);
 void jabber_subscribe(const char * const recipient);
 void jabber_send(const char * const msg, const char * const recipient);
diff --git a/src/profanity.c b/src/profanity.c
index 71c11be0..2953c4ba 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -41,7 +41,6 @@
 static log_level_t _get_log_level(char *log_level);
 static gboolean _process_input(char *inp);
 static void _create_config_directory();
-static void _free_roster_entry(jabber_roster_entry *entry);
 static void _init(const int disable_tls, char *log_level);
 static void _shutdown(void);
 
@@ -166,7 +165,7 @@ prof_handle_failed_login(void)
 void
 prof_handle_contact_online(char *contact, char *show, char *status)
 {
-    gboolean result = contact_list_add(contact, show, status);
+    gboolean result = contact_list_add(contact, NULL, show, status, NULL);
     if (result) {
         win_contact_online(contact, show, status);
     }
@@ -176,30 +175,13 @@ prof_handle_contact_online(char *contact, char *show, char *status)
 void
 prof_handle_contact_offline(char *contact, char *show, char *status)
 {
-    gboolean result = contact_list_add(contact, "offline", status);
+    gboolean result = contact_list_add(contact, NULL, "offline", status, NULL);
     if (result) {
         win_contact_offline(contact, show, status);
     }
     win_page_off();
 }
 
-void
-prof_handle_roster(GSList *roster)
-{
-    while (roster != NULL) {
-        jabber_roster_entry *entry = roster->data;
-
-        // if contact not in contact list add them as offline
-        if (contact_list_find_contact(entry->jid) == NULL) {
-            contact_list_add(entry->jid, "offline", NULL);
-        }
-
-        roster = g_slist_next(roster);
-    }
-
-    g_slist_free_full(roster, (GDestroyNotify)_free_roster_entry);
-}
-
 static void
 _create_config_directory(void)
 {
@@ -209,16 +191,6 @@ _create_config_directory(void)
     g_string_free(dir, TRUE);
 }
 
-static void
-_free_roster_entry(jabber_roster_entry *entry)
-{
-    if (entry->name != NULL) {
-        free(entry->name);
-        entry->name = NULL;
-    }
-    free(entry->jid);
-}
-
 static log_level_t
 _get_log_level(char *log_level)
 {
diff --git a/src/profanity.h b/src/profanity.h
index 430148e2..a67fb2df 100644
--- a/src/profanity.h
+++ b/src/profanity.h
@@ -23,11 +23,6 @@
 #ifndef PROFANITY_H
 #define PROFANITY_H
 
-typedef struct roster_entry_t {
-    char *name;
-    char *jid;
-} jabber_roster_entry;
-
 void prof_run(const int disable_tls, char *log_level);
 
 void prof_handle_login_success(const char *jid);
diff --git a/src/windows.c b/src/windows.c
index f1c8f0fe..276d1eb8 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -427,8 +427,8 @@ win_show_outgoing_msg(const char * const from, const char * const to,
         }
 
         if (contact != NULL) {
-            if (strcmp(p_contact_show(contact), "offline") == 0) {
-                const char const *show = p_contact_show(contact);
+            if (strcmp(p_contact_presence(contact), "offline") == 0) {
+                const char const *show = p_contact_presence(contact);
                 const char const *status = p_contact_status(contact);
                 _show_status_string(win, to, show, status, "--", "offline");
             }
@@ -703,41 +703,41 @@ cons_show_contacts(GSList *list)
 
     while(curr) {
         PContact contact = curr->data;
-        const char *show = p_contact_show(contact);
+        const char *presence = p_contact_presence(contact);
 
         _win_show_time(_cons_win);
 
-        if (strcmp(show, "online") == 0) {
+        if (strcmp(presence, "online") == 0) {
             wattron(_cons_win, COLOUR_ONLINE);
-        } else if (strcmp(show, "away") == 0) {
+        } else if (strcmp(presence, "away") == 0) {
             wattron(_cons_win, COLOUR_AWAY);
-        } else if (strcmp(show, "chat") == 0) {
+        } else if (strcmp(presence, "chat") == 0) {
             wattron(_cons_win, COLOUR_CHAT);
-        } else if (strcmp(show, "dnd") == 0) {
+        } else if (strcmp(presence, "dnd") == 0) {
             wattron(_cons_win, COLOUR_DND);
-        } else if (strcmp(show, "xa") == 0) {
+        } else if (strcmp(presence, "xa") == 0) {
             wattron(_cons_win, COLOUR_XA);
         } else {
             wattron(_cons_win, COLOUR_OFFLINE);
         }
 
-        wprintw(_cons_win, "%s", p_contact_name(contact));
-        wprintw(_cons_win, " is %s", show);
+        wprintw(_cons_win, "%s", p_contact_jid(contact));
+        wprintw(_cons_win, " is %s", presence);
 
         if (p_contact_status(contact))
             wprintw(_cons_win, ", \"%s\"", p_contact_status(contact));
 
         wprintw(_cons_win, "\n");
 
-        if (strcmp(show, "online") == 0) {
+        if (strcmp(presence, "online") == 0) {
             wattroff(_cons_win, COLOUR_ONLINE);
-        } else if (strcmp(show, "away") == 0) {
+        } else if (strcmp(presence, "away") == 0) {
             wattroff(_cons_win, COLOUR_AWAY);
-        } else if (strcmp(show, "chat") == 0) {
+        } else if (strcmp(presence, "chat") == 0) {
             wattroff(_cons_win, COLOUR_CHAT);
-        } else if (strcmp(show, "dnd") == 0) {
+        } else if (strcmp(presence, "dnd") == 0) {
             wattroff(_cons_win, COLOUR_DND);
-        } else if (strcmp(show, "xa") == 0) {
+        } else if (strcmp(presence, "xa") == 0) {
             wattroff(_cons_win, COLOUR_XA);
         } else {
             wattroff(_cons_win, COLOUR_OFFLINE);