about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2013-05-19 02:07:01 +0100
committerJames Booth <boothj5@gmail.com>2013-05-19 02:07:01 +0100
commitd300e8e763420e826578d1c6395b29a9ca6db8d9 (patch)
tree2a549cf065e3054c825eea23feac3ee8c509f953 /src
parent905571bfb741630c6e82382d1750a4797e18e3db (diff)
downloadprofani-tty-d300e8e763420e826578d1c6395b29a9ca6db8d9.tar.gz
Added /roster command with nick option to change handle
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c40
-rw-r--r--src/contact.c33
-rw-r--r--src/contact.h3
-rw-r--r--src/xmpp/roster.c26
-rw-r--r--src/xmpp/roster.h2
-rw-r--r--src/xmpp/stanza.c23
-rw-r--r--src/xmpp/stanza.h3
-rw-r--r--src/xmpp/xmpp.h1
8 files changed, 102 insertions, 29 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 673a1956..281c303f 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -139,6 +139,7 @@ static gboolean _cmd_nick(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_theme(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_status(gchar **args, struct cmd_help_t help);
 static gboolean _cmd_duck(gchar **args, struct cmd_help_t help);
+static gboolean _cmd_roster(gchar **args, struct cmd_help_t help);
 
 /*
  * The commands are broken down into three groups:
@@ -272,6 +273,17 @@ static struct cmd_t main_commands[] =
           "Example : /msg \"My Friend\" Hi, how are you?",
           NULL } } },
 
+    { "/roster",
+        _cmd_roster, parse_args_with_freetext, 3, 3,
+        { "/roster nick jid handle", "Add or change a contacts handle.",
+        { "/roster nick jid handle",
+          "-----------------------",
+          "Change the nickname (handle) associated with a contact in your roster."
+          "",
+          "Example : /roster nick bob.smith@server.com bobby",
+          "Example : /roster nick myfriend@chat.org My Friend",
+          NULL } } },
+
     { "/info",
         _cmd_info, parse_args, 0, 1,
         { "/info [jid|nick]", "Show basic information about a contact, or room member.",
@@ -1972,6 +1984,34 @@ _cmd_msg(gchar **args, struct cmd_help_t help)
 }
 
 static gboolean
+_cmd_roster(gchar **args, struct cmd_help_t help)
+{
+    if (strcmp(args[0], "nick") != 0) {
+        cons_show("Usage: %s", help.usage);
+        return TRUE;
+    } else {
+        char *jid = args[1];
+        char *handle = args[2];
+        jabber_conn_status_t conn_status = jabber_get_connection_status();
+
+        if (conn_status != JABBER_CONNECTED) {
+            cons_show("You are not currently connected.");
+            return TRUE;
+        }
+
+        // contact does not exist
+        PContact contact = roster_get_contact(jid);
+        if (contact == NULL) {
+            cons_show("Contact not found in roster: %s", jid);
+            return TRUE;
+        }
+
+        roster_change_handle(jid, handle);
+        return TRUE;
+    }
+}
+
+static gboolean
 _cmd_duck(gchar **args, struct cmd_help_t help)
 {
     char *query = args[0];
diff --git a/src/contact.c b/src/contact.c
index 6a8dc7d3..32313fcb 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -73,33 +73,20 @@ p_contact_new(const char * const barejid, const char * const name,
     return contact;
 }
 
-gboolean
-p_contact_remove_resource(PContact contact, const char * const resource)
+void
+p_contact_set_name(const PContact contact, const char * const name)
 {
-    return g_hash_table_remove(contact->available_resources, resource);
+    if (contact->name != NULL) {
+        FREE_SET_NULL(contact->name);
+    }
+
+    contact->name = strdup(name);
 }
 
-PContact
-p_contact_new_subscription(const char * const barejid,
-    const char * const subscription, gboolean pending_out)
+gboolean
+p_contact_remove_resource(PContact contact, const char * const resource)
 {
-    PContact contact = malloc(sizeof(struct p_contact_t));
-    contact->barejid = strdup(barejid);
-
-    contact->name = NULL;
-
-    if (subscription != NULL)
-        contact->subscription = strdup(subscription);
-    else
-        contact->subscription = strdup("none");
-
-    contact->pending_out = pending_out;
-    contact->last_activity = NULL;
-
-    contact->available_resources = g_hash_table_new_full(g_str_hash, g_str_equal, free,
-        (GDestroyNotify)resource_destroy);
-
-    return contact;
+    return g_hash_table_remove(contact->available_resources, resource);
 }
 
 void
diff --git a/src/contact.h b/src/contact.h
index 13b97043..5915fbbf 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -30,8 +30,6 @@ typedef struct p_contact_t *PContact;
 PContact p_contact_new(const char * const barejid, const char * const name,
     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);
 gboolean p_contact_remove_resource(PContact contact, const char * const resource);
 void p_contact_free(PContact contact);
@@ -45,6 +43,7 @@ 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_name(const PContact contact, const char * const name);
 void p_contact_set_subscription(const PContact contact, const char * const subscription);
 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/xmpp/roster.c b/src/xmpp/roster.c
index 15ac5621..2d66f4a0 100644
--- a/src/xmpp/roster.c
+++ b/src/xmpp/roster.c
@@ -79,6 +79,7 @@ _roster_handle_set(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     }
 
     const char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
+    const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
     const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
     if (g_strcmp0(sub, "remove") == 0) {
         roster_remove(jid);
@@ -91,7 +92,7 @@ _roster_handle_set(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         pending_out = TRUE;
     }
 
-    roster_update_subscription(jid, sub, pending_out);
+    roster_update(jid, name, sub, pending_out);
 
     return 1;
 }
@@ -238,17 +239,36 @@ roster_contact_offline(const char * const barejid,
 }
 
 void
-roster_update_subscription(const char * const barejid,
+roster_change_handle(const char * const barejid, const char * const handle)
+{
+    PContact contact = g_hash_table_lookup(contacts, barejid);
+
+    if (contact != NULL) {
+        p_contact_set_name(contact, handle);
+    }
+
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_roster_set(ctx, barejid, handle);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+void
+roster_update(const char * const barejid, const char * const name,
     const char * const subscription, gboolean pending_out)
 {
     PContact contact = g_hash_table_lookup(contacts, barejid);
 
     if (contact == NULL) {
-        contact = p_contact_new_subscription(barejid, subscription, pending_out);
+        contact = p_contact_new(barejid, name, subscription, NULL, pending_out);
         g_hash_table_insert(contacts, strdup(barejid), contact);
     } else {
         p_contact_set_subscription(contact, subscription);
         p_contact_set_pending_out(contact, pending_out);
+        if (name != NULL) {
+            p_contact_set_name(contact, name);
+        }
     }
 }
 
diff --git a/src/xmpp/roster.h b/src/xmpp/roster.h
index 1b1860a3..1b16763f 100644
--- a/src/xmpp/roster.h
+++ b/src/xmpp/roster.h
@@ -27,7 +27,7 @@ void roster_add_handlers(void);
 void roster_request(void);
 
 void roster_remove(const char * const barejid);
-void roster_update_subscription(const char * const barejid,
+void roster_update(const char * const barejid, const char * const name,
     const char * const subscription, gboolean pending_out);
 
 #endif
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 528f2055..b368dd7f 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -90,6 +90,29 @@ stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient,
 }
 
 xmpp_stanza_t *
+stanza_create_roster_set(xmpp_ctx_t *ctx, const char * const jid,
+    const char * const handle)
+{
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);
+
+    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
+    xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
+
+    xmpp_stanza_t *item = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(item, STANZA_NAME_ITEM);
+    xmpp_stanza_set_attribute(item, STANZA_ATTR_JID, jid);
+    xmpp_stanza_set_attribute(item, STANZA_ATTR_NAME, handle);
+
+    xmpp_stanza_add_child(query, item);
+    xmpp_stanza_add_child(iq, query);
+
+    return iq;
+}
+
+xmpp_stanza_t *
 stanza_create_invite(xmpp_ctx_t *ctx, const char * const room,
     const char * const contact, const char * const reason)
 {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 8fb21deb..a79be3cd 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -177,4 +177,7 @@ xmpp_stanza_t * stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char * const
 char * stanza_get_status(xmpp_stanza_t *stanza, char *def);
 char * stanza_get_show(xmpp_stanza_t *stanza, char *def);
 
+xmpp_stanza_t * stanza_create_roster_set(xmpp_ctx_t *ctx, const char * const jid,
+    const char * const handle);
+
 #endif
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index adab4f50..1f3558a9 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -140,5 +140,6 @@ char * roster_find_resource(char *search_str);
 gboolean roster_add(const char * const barejid, const char * const name,
     const char * const subscription, const char * const offline_message,
     gboolean pending_out);
+void roster_change_handle(const char * const barejid, const char * const handle);
 
 #endif