about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/xmpp/iq.c63
-rw-r--r--src/xmpp/stanza.c27
-rw-r--r--src/xmpp/stanza.h6
3 files changed, 87 insertions, 9 deletions
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index d1797a72..5012d1a5 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -108,6 +108,12 @@ typedef struct command_config_data_t
     char* command;
 } CommandConfigData;
 
+typedef struct mam_rsm_userdata
+{
+    char* barejid;
+    char* datestr;
+} MamRsmUserdata;
+
 static int _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata);
 
 static void _error_handler(xmpp_stanza_t* const stanza);
@@ -142,6 +148,7 @@ static int _auto_pong_id_handler(xmpp_stanza_t* const stanza, void* const userda
 static int _room_list_id_handler(xmpp_stanza_t* const stanza, void* const userdata);
 static int _command_list_result_handler(xmpp_stanza_t* const stanza, void* const userdata);
 static int _command_exec_response_handler(xmpp_stanza_t* const stanza, void* const userdata);
+static int _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata);
 
 static void _iq_free_room_data(ProfRoomInfoData* roominfo);
 static void _iq_free_affiliation_set(ProfPrivilegeSet* affiliation_set);
@@ -2543,27 +2550,69 @@ void
 iq_mam_request(ProfChatWin* win)
 {
     if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) {
-        log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_PING);
+        log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2);
         cons_show_error("Server doesn't support MAM.");
         return;
     }
 
     xmpp_ctx_t* const ctx = connection_get_ctx();
-    char* id = connection_create_stanza_id();
 
     GDateTime* now = g_date_time_new_now_utc();
-    GDateTime* timestamp = g_date_time_add_days(now, -1);
+    GDateTime* timestamp = g_date_time_add_days(now, -7);
     g_date_time_unref(now);
     gchar* datestr = g_date_time_format(timestamp, "%FT%TZ");
-    xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, datestr);
+    xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, datestr, NULL);
+
+    MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata));
+    data->datestr = strdup(datestr);
+    data->barejid = strdup(win->barejid);
+
+    iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data);
+
     g_free(datestr);
     g_date_time_unref(timestamp);
 
-    //    iq_id_handler_add(id, _http_upload_response_id_handler, NULL, upload);
-    free(id);
-
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
 
     return;
 }
+
+static int
+_mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata)
+{
+    const char* type = xmpp_stanza_get_type(stanza);
+    if (g_strcmp0(type, "error") == 0) {
+        char* error_message = stanza_get_error_message(stanza);
+        cons_show_error("Server error: %s", error_message);
+        log_debug("MAM Error: %s", error_message);
+        free(error_message);
+    } else if (g_strcmp0(type, "result") == 0) {
+        xmpp_stanza_t* fin = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_FIN, STANZA_NS_MAM2);
+        if (fin) {
+            xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM);
+            if (set) {
+                char *lastid = NULL;
+                xmpp_stanza_t* last =  xmpp_stanza_get_child_by_name(set, STANZA_NAME_LAST);
+                if (last) {
+                    lastid = xmpp_stanza_get_text(last);
+                }
+
+                // 4.3.2. send same stanza with set,max stanza
+                xmpp_ctx_t* const ctx = connection_get_ctx();
+
+                MamRsmUserdata* data = (MamRsmUserdata*)userdata;
+                xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->datestr, lastid);
+                free(data->barejid);
+                free(data->datestr);
+                free(data);
+                free(lastid);
+
+                iq_send_stanza(iq);
+                xmpp_stanza_release(iq);
+            }
+        }
+    }
+
+    return 0;
+}
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index fbbbfc9c..06615aa9 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -2615,7 +2615,7 @@ stanza_attach_correction(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza, const char* con
 }
 
 xmpp_stanza_t*
-stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate)
+stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char *const lastid)
 {
     char* id = connection_create_stanza_id();
     xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
@@ -2674,6 +2674,23 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s
 
     xmpp_stanza_add_child(field_start, value_start);
 
+    // 4.3.2 set/rsm
+    xmpp_stanza_t *after, *after_text, *set;
+    if (lastid) {
+        set = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(set, STANZA_TYPE_SET);
+        xmpp_stanza_set_ns(set, STANZA_NS_RSM);
+
+        after = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(after, STANZA_NAME_AFTER);
+
+        after_text = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_text(after_text, lastid);
+
+        xmpp_stanza_add_child(after, after_text);
+        xmpp_stanza_add_child(set, after);
+    }
+
     // add and release
     xmpp_stanza_add_child(iq, query);
     xmpp_stanza_add_child(query, x);
@@ -2681,6 +2698,14 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s
     xmpp_stanza_add_child(x, field_with);
     xmpp_stanza_add_child(x, field_start);
 
+    if (lastid) {
+        xmpp_stanza_add_child(query, after);
+
+        xmpp_stanza_release(after_text);
+        xmpp_stanza_release(after);
+        xmpp_stanza_release(set);
+    }
+
     xmpp_stanza_release(mam_text);
     xmpp_stanza_release(with_text);
     xmpp_stanza_release(date_text);
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 95cdc29b..e35b4bcc 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -113,6 +113,9 @@
 #define STANZA_NAME_STANZA_ID        "stanza-id"
 #define STANZA_NAME_RESULT           "result"
 #define STANZA_NAME_MINIMIZE         "minimize"
+#define STANZA_NAME_FIN              "fin"
+#define STANZA_NAME_LAST             "last"
+#define STANZA_NAME_AFTER            "after"
 
 // error conditions
 #define STANZA_NAME_BAD_REQUEST             "bad-request"
@@ -220,6 +223,7 @@
 #define STANZA_NS_LAST_MESSAGE_CORRECTION "urn:xmpp:message-correct:0"
 #define STANZA_NS_MAM2                    "urn:xmpp:mam:2"
 #define STANZA_NS_EXT_GAJIM_BOOKMARKS     "xmpp:gajim.org/bookmarks"
+#define STANZA_NS_RSM                     "http://jabber.org/protocol/rsm"
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
@@ -377,6 +381,6 @@ void stanza_free_caps(XMPPCaps* caps);
 
 xmpp_stanza_t* stanza_create_avatar_retrieve_data_request(xmpp_ctx_t* ctx, const char* stanza_id, const char* const item_id, const char* const jid);
 
-xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate);
+xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char *const lastid);
 
 #endif