about summary refs log tree commit diff stats
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/connection.c5
-rw-r--r--src/xmpp/iq.c20
-rw-r--r--src/xmpp/message.c38
-rw-r--r--src/xmpp/stanza.c38
-rw-r--r--src/xmpp/stanza.h8
-rw-r--r--src/xmpp/xmpp.h2
6 files changed, 111 insertions, 0 deletions
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 915525e4..34fba22d 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -466,6 +466,11 @@ _connection_handler(xmpp_conn_t * const conn,
 
         roster_request();
         bookmark_request();
+
+        if (prefs_get_boolean(PREF_CARBONS)){
+            iq_enable_carbons();
+        }
+        
         jabber_conn.conn_status = JABBER_CONNECTED;
 
         if (prefs_get_reconnect() != 0) {
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index bc12b780..90b87676 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -153,6 +153,26 @@ iq_room_list_request(gchar *conferencejid)
 }
 
 void
+iq_enable_carbons()
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_enable_carbons(ctx);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+void
+iq_disable_carbons()
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_disable_carbons(ctx);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+void
 iq_disco_info_request(gchar *jid)
 {
     xmpp_conn_t * const conn = connection_get_conn();
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index e96c1a74..4f341f6a 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -423,6 +423,44 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         return 1;
     }
 
+    // check if carbon message
+    xmpp_stanza_t *received = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); 
+    if(received != NULL){
+        xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(received, STANZA_NS_FORWARD);
+        xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);
+
+        xmpp_ctx_t *ctx = connection_get_ctx();
+
+        gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO);
+        gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM);
+
+        Jid *jid_from = jid_create(from);
+        Jid *jid_to = jid_create(to);
+        Jid *my_jid = jid_create(jabber_get_fulljid());
+
+        // check for and deal with message
+        xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY);
+        if (body != NULL) {
+            char *message = xmpp_stanza_get_text(body);
+            if (message != NULL) {
+                // if we are the recipient, treat as standard incoming message
+                if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){
+                    handle_incoming_message(jid_from->barejid, jid_from->resourcepart, message);
+                }
+                // else treat as a sent message
+                else{
+                    handle_carbon(jid_to->barejid, message);
+                }
+                xmpp_free(ctx, message);
+            }
+        }
+
+        jid_destroy(jid_from);
+        jid_destroy(jid_to);
+        jid_destroy(my_jid);
+        return 1;
+    }
+
     // ignore handled namespaces
     xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
     xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 4f1d412d..b0d7de86 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -199,6 +199,44 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid,
 #endif
 
 xmpp_stanza_t *
+stanza_enable_carbons(xmpp_ctx_t *ctx){
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    char *id = create_unique_id(NULL);
+
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);   
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
+    xmpp_stanza_t *carbons_enable = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(carbons_enable, STANZA_NAME_ENABLE);
+    xmpp_stanza_set_ns(carbons_enable, STANZA_NS_CARBONS);
+
+    xmpp_stanza_add_child(iq, carbons_enable);
+
+    return iq;
+}
+
+xmpp_stanza_t *
+stanza_disable_carbons(xmpp_ctx_t *ctx){
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    char *id = create_unique_id(NULL);
+
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);   
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
+    xmpp_stanza_t *carbons_disable = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(carbons_disable, STANZA_NAME_DISABLE);
+    xmpp_stanza_set_ns(carbons_disable, STANZA_NS_CARBONS);
+
+    xmpp_stanza_add_child(iq, carbons_disable);
+
+    return iq;
+}
+
+xmpp_stanza_t *
 stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state)
 {
     xmpp_stanza_t *msg, *chat_state;
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 84282401..e4f3ce57 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -77,6 +77,8 @@
 #define STANZA_NAME_VALUE "value"
 #define STANZA_NAME_DESTROY "destroy"
 #define STANZA_NAME_ACTOR "actor"
+#define STANZA_NAME_ENABLE "enable"
+#define STANZA_NAME_DISABLE "disable"
 
 // error conditions
 #define STANZA_NAME_BAD_REQUEST "bad-request"
@@ -154,6 +156,8 @@
 #define STANZA_NS_CONFERENCE "jabber:x:conference"
 #define STANZA_NS_CAPTCHA "urn:xmpp:captcha"
 #define STANZA_NS_PUBSUB "http://jabber.org/protocol/pubsub"
+#define STANZA_NS_CARBONS "urn:xmpp:carbons:2"
+#define STANZA_NS_FORWARD "urn:xmpp:forward:0"
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
@@ -178,6 +182,10 @@ typedef enum {
 
 xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx);
 
+xmpp_stanza_t * stanza_enable_carbons(xmpp_ctx_t *ctx);
+
+xmpp_stanza_t * stanza_disable_carbons(xmpp_ctx_t *ctx);
+
 xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx,
     const char * const fulljid, const char * const state);
 
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index a004a4bf..1fc32665 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -172,6 +172,8 @@ void presence_update(resource_presence_t status, const char * const msg,
 gboolean presence_sub_request_exists(const char * const bare_jid);
 
 // iq functions
+void iq_enable_carbons();
+void iq_disable_carbons();
 void iq_send_software_version(const char * const fulljid);
 void iq_room_list_request(gchar *conferencejid);
 void iq_disco_info_request(gchar *jid);