about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorMichael Vetter <jubalh@iodoru.org>2020-07-23 14:21:27 +0200
committerMichael Vetter <jubalh@iodoru.org>2020-07-23 14:21:27 +0200
commit8852db03d623f1920814fc8ff2c822a6353dd6e3 (patch)
treeef8a6a7017e444258302658f6adc2f218f68e419 /src
parent5db840e0cc35070b9219c166d496a03f44dc6ea8 (diff)
downloadprofani-tty-8852db03d623f1920814fc8ff2c822a6353dd6e3.tar.gz
Parse stanza-id
Add stable stanza IDs to ProfMessage struct.

We parse this for 1:1 messages (MUC needs to be done too).

<stanza-id> for live messages
<result id="x"> for MAM messages

Regards MAM: https://github.com/profanity-im/profanity/issues/660
Regards Stable IDs: https://github.com/profanity-im/profanity/issues/1207
Diffstat (limited to 'src')
-rw-r--r--src/xmpp/message.c39
-rw-r--r--src/xmpp/stanza.h2
-rw-r--r--src/xmpp/xmpp.h5
3 files changed, 40 insertions, 6 deletions
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index f9940204..28b126a6 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -85,7 +85,7 @@ static void _handle_muc_private_message(xmpp_stanza_t* const stanza);
 static void _handle_conference(xmpp_stanza_t* const stanza);
 static void _handle_captcha(xmpp_stanza_t* const stanza);
 static void _handle_receipt_received(xmpp_stanza_t* const stanza);
-static void _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon);
+static void _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, const char *result_id);
 static void _handle_ox_chat(xmpp_stanza_t* const stanza, ProfMessage* message, gboolean is_mam);
 static xmpp_stanza_t* _handle_carbons(xmpp_stanza_t* const stanza);
 static void _send_message_stanza(xmpp_stanza_t* const stanza);
@@ -232,7 +232,7 @@ _message_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* con
         }
 
         if (msg_stanza) {
-            _handle_chat(msg_stanza, FALSE, is_carbon);
+            _handle_chat(msg_stanza, FALSE, is_carbon, NULL);
         }
     } else {
         // none of the allowed types
@@ -281,6 +281,7 @@ message_init(void)
     message->to_jid = NULL;
     message->id = NULL;
     message->originid = NULL;
+    message->stanzaid = NULL;
     message->replace_id = NULL;
     message->body = NULL;
     message->encrypted = NULL;
@@ -313,6 +314,10 @@ message_free(ProfMessage* message)
         xmpp_free(ctx, message->originid);
     }
 
+    if (message->stanzaid) {
+        xmpp_free(ctx, message->stanzaid);
+    }
+
     if (message->replace_id) {
         xmpp_free(ctx, message->replace_id);
     }
@@ -1217,7 +1222,7 @@ _handle_carbons(xmpp_stanza_t* const stanza)
 }
 
 static void
-_handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon)
+_handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, const char *result_id)
 {
     // some clients send the mucuser namespace with private messages
     // if the namespace exists, and the stanza contains a body element, assume its a private message
@@ -1280,6 +1285,26 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon)
         message->id = strdup(id);
     }
 
+    if (is_mam) {
+        // MAM has XEP-0359 stanza-id as <result id="">
+        if (result_id) {
+            message->stanzaid = strdup(result_id);
+        } else {
+            log_warning("MAM received with no result id");
+        }
+    } else {
+        // live messages use XEP-0359 <stanza-id>
+        // TODO: add to muc too
+        char* stanzaid = NULL;
+        xmpp_stanza_t* stanzaidst = stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_STANZA_ID, STANZA_NS_STABLE_ID);
+        if (stanzaidst) {
+            stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
+            if (stanzaid) {
+                message->stanzaid = strdup(stanzaid);
+            }
+        }
+    }
+
     // replace id for XEP-0308: Last Message Correction
     xmpp_stanza_t* replace_id_stanza = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_LAST_MESSAGE_CORRECTION);
     if (replace_id_stanza) {
@@ -1379,7 +1404,7 @@ _handle_ox_chat(xmpp_stanza_t* const stanza, ProfMessage* message, gboolean is_m
 static gboolean
 _handle_mam(xmpp_stanza_t* const stanza)
 {
-    xmpp_stanza_t* result = stanza_get_child_by_name_and_ns(stanza, "result", STANZA_NS_MAM2);
+    xmpp_stanza_t* result = stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_RESULT, STANZA_NS_MAM2);
     if (!result) {
         return FALSE;
     }
@@ -1390,8 +1415,12 @@ _handle_mam(xmpp_stanza_t* const stanza)
         return FALSE;
     }
 
+    // <result xmlns='urn:xmpp:mam:2' queryid='f27' id='5d398-28273-f7382'>
+    // same as <stanza-id> from XEP-0359 for live messages
+    const char* result_id = xmpp_stanza_get_id(result);
+
     xmpp_stanza_t* message_stanza = xmpp_stanza_get_child_by_ns(forwarded, "jabber:client");
-    _handle_chat(message_stanza, TRUE, FALSE);
+    _handle_chat(message_stanza, TRUE, FALSE, result_id);
 
     return TRUE;
 }
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index a51ee3c6..51d69873 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -110,6 +110,8 @@
 #define STANZA_NAME_COMMAND          "command"
 #define STANZA_NAME_CONFIGURE        "configure"
 #define STANZA_NAME_ORIGIN_ID        "origin-id"
+#define STANZA_NAME_STANZA_ID        "stanza-id"
+#define STANZA_NAME_RESULT           "result"
 #define STANZA_NAME_MINIMIZE         "minimize"
 
 // error conditions
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index da98048a..9bd72aec 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -155,7 +155,10 @@ typedef struct prof_message_t
     char* originid;
     /* <replace id> XEP-0308 LMC */
     char* replace_id;
-    /* for MAM we will need archive_id (stanza-id in XEP-0359) (see database.c) */
+    /* stanza-id from XEP 0359. Used for MAM. archive_id in our database (see database.c)
+     * coming in as <stanza-id> for live messages
+     * coming in as <result id=""> for MAM messages*/
+    char *stanzaid;
     /* The raw body from xmpp message, either plaintext or OTR encrypted text */
     char* body;
     /* The encrypted message as for PGP */