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/chat_session.c4
-rw-r--r--src/xmpp/chat_session.h2
-rw-r--r--src/xmpp/connection.c24
-rw-r--r--src/xmpp/iq.c25
-rw-r--r--src/xmpp/jid.c19
-rw-r--r--src/xmpp/jid.h5
-rw-r--r--src/xmpp/message.c48
-rw-r--r--src/xmpp/session.c12
-rw-r--r--src/xmpp/session.h1
9 files changed, 82 insertions, 58 deletions
diff --git a/src/xmpp/chat_session.c b/src/xmpp/chat_session.c
index f62f090c..56a782f1 100644
--- a/src/xmpp/chat_session.c
+++ b/src/xmpp/chat_session.c
@@ -120,11 +120,11 @@ chat_session_get_jid(const char* const barejid)
     return jid;
 }
 
-char*
+const char*
 chat_session_get_state(const char* const barejid)
 {
     ChatSession* session = chat_session_get(barejid);
-    char* state = NULL;
+    const char* state = NULL;
     if (session) {
         if (prefs_get_boolean(PREF_STATES) && session->send_states) {
             state = STANZA_NAME_ACTIVE;
diff --git a/src/xmpp/chat_session.h b/src/xmpp/chat_session.h
index e0144874..619750e4 100644
--- a/src/xmpp/chat_session.h
+++ b/src/xmpp/chat_session.h
@@ -59,7 +59,7 @@ void chat_session_recipient_paused(const char* const barejid, const char* const
 void chat_session_recipient_gone(const char* const barejid, const char* const resource);
 void chat_session_recipient_inactive(const char* const barejid, const char* const resource);
 char* chat_session_get_jid(const char* const barejid);
-char* chat_session_get_state(const char* const barejid);
+const char* chat_session_get_state(const char* const barejid);
 
 void chat_session_remove(const char* const barejid);
 
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 2de4a842..d57a1376 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -140,6 +140,14 @@ connection_init(void)
     conn.requested_features = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
 
     conn.xmpp_ctx = xmpp_ctx_new(&prof_mem, &prof_log);
+    auto_gchar gchar* v = prefs_get_string(PREF_STROPHE_VERBOSITY);
+    auto_gchar gchar* err_msg = NULL;
+    int verbosity;
+    if (string_to_verbosity(v, &verbosity, &err_msg)) {
+        xmpp_ctx_set_verbosity(conn.xmpp_ctx, verbosity);
+    } else {
+        cons_show(err_msg);
+    }
     conn.xmpp_conn = xmpp_conn_new(conn.xmpp_ctx);
 
     _random_bytes_init();
@@ -1000,13 +1008,15 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status
 
         // lost connection for unknown reason
         if (conn.conn_status == JABBER_CONNECTED) {
-            int send_queue_len = xmpp_conn_send_queue_len(conn.xmpp_conn);
-            log_debug("Connection handler: Lost connection for unknown reason");
-            conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn);
-            if (send_queue_len > 0) {
-                conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages));
-                for (int n = 0; n < send_queue_len && conn.queued_messages[n]; ++n) {
-                    conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST);
+            if (prefs_get_boolean(PREF_STROPHE_SM_ENABLED)) {
+                int send_queue_len = xmpp_conn_send_queue_len(conn.xmpp_conn);
+                log_debug("Connection handler: Lost connection for unknown reason");
+                conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn);
+                if (send_queue_len > 0 && prefs_get_boolean(PREF_STROPHE_SM_RESEND)) {
+                    conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages));
+                    for (int n = 0; n < send_queue_len && conn.queued_messages[n]; ++n) {
+                        conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST);
+                    }
                 }
             }
             session_lost_connection();
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 4d0ee281..89511176 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -2187,6 +2187,7 @@ _room_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdata
                             identity->name = strdup(name);
                             ProfMucWin* mucwin = wins_get_muc(cb_data->room);
                             if (mucwin) {
+                                free(mucwin->room_name);
                                 mucwin->room_name = strdup(name);
                             }
                         } else {
@@ -2607,6 +2608,8 @@ _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata)
     return 0;
 }
 
+static const gchar* mam_timestamp_format_string = "%FT%T.%f%:z";
+
 void
 iq_mam_request_older(ProfChatWin* win)
 {
@@ -2623,7 +2626,7 @@ iq_mam_request_older(ProfChatWin* win)
     // If first message found
     if (first_msg->timestamp) {
         firstid = first_msg->stanzaid;
-        enddate = g_date_time_format(first_msg->timestamp, "%FT%T.%f%:z");
+        enddate = g_date_time_format(first_msg->timestamp, mam_timestamp_format_string);
     } else {
         return;
     }
@@ -2647,6 +2650,8 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate)
     if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) {
         log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2);
         cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2);
+        g_date_time_unref(startdate);
+        g_date_time_unref(enddate);
         return;
     }
 
@@ -2656,18 +2661,18 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate)
     gboolean fetch_next = FALSE;
 
     if (startdate) {
-        startdate_str = g_date_time_format(startdate, "%FT%T.%f%:z");
+        startdate_str = g_date_time_format(startdate, mam_timestamp_format_string);
         fetch_next = TRUE;
         g_date_time_unref(startdate);
-    } else if (!enddate) {
-        GDateTime* now = g_date_time_new_now_utc();
-        enddate_str = g_date_time_format(now, "%FT%T.%f%:z");
-        g_date_time_unref(now);
     }
 
     if (enddate) {
-        enddate_str = g_date_time_format(enddate, "%FT%T.%f%:z");
+        enddate_str = g_date_time_format(enddate, mam_timestamp_format_string);
         g_date_time_unref(enddate);
+    } else {
+        GDateTime* now = g_date_time_new_now_utc();
+        enddate_str = g_date_time_format(now, mam_timestamp_format_string);
+        g_date_time_unref(now);
     }
 
     xmpp_ctx_t* const ctx = connection_get_ctx();
@@ -2695,15 +2700,15 @@ void
 iq_mam_request(ProfChatWin* win, GDateTime* enddate)
 {
     ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE);
-    GDateTime* startdate = last_msg->timestamp ? g_date_time_add_seconds(last_msg->timestamp, 0) : NULL; // copy timestamp
+    GDateTime* startdate = g_date_time_add_seconds(last_msg->timestamp, 0);
     message_free(last_msg);
 
     // Save request for later if disco items haven't been received yet
     if (!received_disco_items) {
         LateDeliveryUserdata* cur_del_data = malloc(sizeof(LateDeliveryUserdata));
         cur_del_data->win = win;
-        cur_del_data->enddate = enddate;
-        cur_del_data->startdate = startdate;
+        cur_del_data->enddate = g_date_time_ref(enddate);
+        cur_del_data->startdate = g_date_time_ref(startdate);
         late_delivery_windows = g_slist_append(late_delivery_windows, cur_del_data);
     }
 
diff --git a/src/xmpp/jid.c b/src/xmpp/jid.c
index 33c3d19f..af0a606b 100644
--- a/src/xmpp/jid.c
+++ b/src/xmpp/jid.c
@@ -76,6 +76,7 @@ jid_create(const gchar* const str)
     result->resourcepart = NULL;
     result->barejid = NULL;
     result->fulljid = NULL;
+    result->refcnt = 1;
 
     gchar* atp = g_utf8_strchr(trimmed, -1, '@');
     gchar* slashp = g_utf8_strchr(trimmed, -1, '/');
@@ -120,11 +121,29 @@ jid_create_from_bare_and_resource(const char* const barejid, const char* const r
 }
 
 void
+jid_auto_destroy(Jid** jid)
+{
+    if (jid == NULL)
+        return;
+    jid_destroy(*jid);
+}
+
+void
+jid_ref(Jid* jid)
+{
+    jid->refcnt++;
+}
+
+void
 jid_destroy(Jid* jid)
 {
     if (jid == NULL) {
         return;
     }
+    if (jid->refcnt > 1) {
+        jid->refcnt--;
+        return;
+    }
 
     g_free(jid->str);
     g_free(jid->localpart);
diff --git a/src/xmpp/jid.h b/src/xmpp/jid.h
index dae6cb2d..e55ea0c7 100644
--- a/src/xmpp/jid.h
+++ b/src/xmpp/jid.h
@@ -40,6 +40,7 @@
 
 struct jid_t
 {
+    unsigned int refcnt;
     char* str;
     char* localpart;
     char* domainpart;
@@ -53,6 +54,10 @@ typedef struct jid_t Jid;
 Jid* jid_create(const gchar* const str);
 Jid* jid_create_from_bare_and_resource(const char* const barejid, const char* const resource);
 void jid_destroy(Jid* jid);
+void jid_ref(Jid* jid);
+
+void jid_auto_destroy(Jid** str);
+#define auto_jid __attribute__((__cleanup__(jid_auto_destroy)))
 
 gboolean jid_is_valid_room_form(Jid* jid);
 char* create_fulljid(const char* const barejid, const char* const resource);
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index 306b9be7..bc716b24 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -424,7 +424,7 @@ message_send_chat(const char* const barejid, const char* const msg, const char*
 {
     xmpp_ctx_t* const ctx = connection_get_ctx();
 
-    char* state = chat_session_get_state(barejid);
+    const char* state = chat_session_get_state(barejid);
     char* jid = chat_session_get_jid(barejid);
     char* id = connection_create_stanza_id();
 
@@ -459,7 +459,7 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean
 {
     xmpp_ctx_t* const ctx = connection_get_ctx();
 
-    char* state = chat_session_get_state(barejid);
+    const char* state = chat_session_get_state(barejid);
     char* jid = chat_session_get_jid(barejid);
     char* id = connection_create_stanza_id();
 
@@ -468,7 +468,7 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean
     char* account_name = session_get_account_name();
     ProfAccount* account = accounts_get_account(account_name);
     if (account->pgp_keyid) {
-        Jid* jidp = jid_create(jid);
+        auto_jid Jid* jidp = jid_create(jid);
         char* encrypted = p_gpg_encrypt(jidp->barejid, msg, account->pgp_keyid);
         if (encrypted) {
             message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id);
@@ -487,7 +487,6 @@ message_send_chat_pgp(const char* const barejid, const char* const msg, gboolean
             message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id);
             xmpp_message_set_body(message, msg);
         }
-        jid_destroy(jidp);
     } else {
         message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id);
         xmpp_message_set_body(message, msg);
@@ -525,12 +524,11 @@ message_send_chat_ox(const char* const barejid, const char* const msg, gboolean
 #ifdef HAVE_LIBGPGME
     xmpp_ctx_t* const ctx = connection_get_ctx();
 
-    char* state = chat_session_get_state(barejid);
-    char* jid = chat_session_get_jid(barejid);
+    const char* state = chat_session_get_state(barejid);
+    auto_char char* jid = chat_session_get_jid(barejid);
     char* id = connection_create_stanza_id();
 
     xmpp_stanza_t* message = NULL;
-    Jid* jidp = jid_create(jid);
 
     char* account_name = session_get_account_name();
     ProfAccount* account = accounts_get_account(account_name);
@@ -561,8 +559,6 @@ message_send_chat_ox(const char* const barejid, const char* const msg, gboolean
     xmpp_stanza_to_text(message, &c, &s);
 
     account_free(account);
-    jid_destroy(jidp);
-    free(jid);
 
     if (state) {
         stanza_attach_state(ctx, message, state);
@@ -589,7 +585,7 @@ message_send_chat_otr(const char* const barejid, const char* const msg, gboolean
 {
     xmpp_ctx_t* const ctx = connection_get_ctx();
 
-    char* state = chat_session_get_state(barejid);
+    const char* state = chat_session_get_state(barejid);
     char* jid = chat_session_get_jid(barejid);
     char* id = connection_create_stanza_id();
 
@@ -627,7 +623,7 @@ message_send_chat_omemo(const char* const jid, uint32_t sid, GList* keys,
                         const unsigned char* const ciphertext, size_t ciphertext_len,
                         gboolean request_receipt, gboolean muc, const char* const replace_id)
 {
-    char* state = chat_session_get_state(jid);
+    const char* state = chat_session_get_state(jid);
     xmpp_ctx_t* const ctx = connection_get_ctx();
     char* id;
     xmpp_stanza_t* message;
@@ -888,10 +884,9 @@ _handle_error(xmpp_stanza_t* const stanza)
         ui_handle_error(err_msg);
     } else {
         if (type && (strcmp(type, "cancel") == 0)) {
-            Jid* jidp = jid_create(jid);
+            auto_jid Jid* jidp = jid_create(jid);
             if (jidp) {
                 chat_session_remove(jidp->barejid);
-                jid_destroy(jidp);
             }
         }
         ui_handle_recipient_error(jid, err_msg);
@@ -928,7 +923,7 @@ _handle_muc_user(xmpp_stanza_t* const stanza)
         return;
     }
 
-    Jid* jidp = jid_create(invitor_jid);
+    auto_jid Jid* jidp = jid_create(invitor_jid);
     if (!jidp) {
         return;
     }
@@ -947,7 +942,6 @@ _handle_muc_user(xmpp_stanza_t* const stanza)
     }
 
     sv_ev_room_invite(INVITE_MEDIATED, invitor, room, reason, password);
-    jid_destroy(jidp);
     if (reason) {
         xmpp_free(ctx, reason);
     }
@@ -974,7 +968,7 @@ _handle_conference(xmpp_stanza_t* const stanza)
             return;
         }
 
-        Jid* jidp = jid_create(from);
+        auto_jid Jid* jidp = jid_create(from);
         if (!jidp) {
             return;
         }
@@ -984,7 +978,6 @@ _handle_conference(xmpp_stanza_t* const stanza)
         const char* password = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_PASSWORD);
 
         sv_ev_room_invite(INVITE_DIRECT, jidp->barejid, room, reason, password);
-        jid_destroy(jidp);
     }
 }
 
@@ -1040,7 +1033,7 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
     if (!room_jid) {
         return;
     }
-    Jid* from_jid = jid_create(room_jid);
+    auto_jid Jid* from_jid = jid_create(room_jid);
     if (!from_jid) {
         return;
     }
@@ -1053,7 +1046,6 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
         sv_ev_room_subject(from_jid->barejid, from_jid->resourcepart, subject_text);
         xmpp_free(ctx, subject_text);
 
-        jid_destroy(from_jid);
         return;
     }
 
@@ -1084,31 +1076,28 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
                 }
             }
 
-            jid_destroy(from_jid);
             return;
         }
 
         sv_ev_room_broadcast(room_jid, broadcast);
         xmpp_free(ctx, broadcast);
 
-        jid_destroy(from_jid);
         return;
     }
 
     if (!jid_is_valid_room_form(from_jid)) {
         log_error("Invalid room JID: %s", from_jid->str);
-        jid_destroy(from_jid);
         return;
     }
 
     // room not active in profanity
     if (!muc_active(from_jid->barejid)) {
         log_error("Message received for inactive chat room: %s", from_jid->str);
-        jid_destroy(from_jid);
         return;
     }
 
     ProfMessage* message = message_init();
+    jid_ref(from_jid);
     message->from_jid = from_jid;
     message->type = PROF_MSG_TYPE_MUC;
 
@@ -1234,13 +1223,12 @@ _handle_receipt_received(xmpp_stanza_t* const stanza)
             return;
         }
 
-        Jid* jidp = jid_create(fulljid);
+        auto_jid Jid* jidp = jid_create(fulljid);
         if (!jidp) {
             return;
         }
 
         sv_ev_message_receipt(jidp->barejid, id);
-        jid_destroy(jidp);
     }
 }
 
@@ -1268,10 +1256,9 @@ _receipt_request_handler(xmpp_stanza_t* const stanza)
 
     const gchar* from = xmpp_stanza_get_from(stanza);
     if (from) {
-        Jid* jid = jid_create(from);
+        auto_jid Jid* jid = jid_create(from);
         if (jid) {
             _message_send_receipt(jid->fulljid, id);
-            jid_destroy(jid);
         }
     }
 }
@@ -1388,7 +1375,7 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c
     if (!from) {
         return;
     }
-    Jid* jid = jid_create(from);
+    auto_jid Jid* jid = jid_create(from);
     if (!jid) {
         return;
     }
@@ -1396,13 +1383,13 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c
     // private message from chat room use full jid (room/nick)
     if (muc_active(jid->barejid)) {
         _handle_muc_private_message(stanza);
-        jid_destroy(jid);
         return;
     }
 
     // standard chat message, use jid without resource
     ProfMessage* message = message_init();
     message->is_mam = is_mam;
+    jid_ref(jid);
     message->from_jid = jid;
     const gchar* to = xmpp_stanza_get_to(stanza);
     if (to) {
@@ -1761,9 +1748,8 @@ _should_ignore_based_on_silence(xmpp_stanza_t* const stanza)
 {
     if (prefs_get_boolean(PREF_SILENCE_NON_ROSTER)) {
         const char* const from = xmpp_stanza_get_from(stanza);
-        Jid* from_jid = jid_create(from);
+        auto_jid Jid* from_jid = jid_create(from);
         PContact contact = roster_get_contact(from_jid->barejid);
-        jid_destroy(from_jid);
         if (!contact) {
             log_debug("[Silence] Ignoring message from: %s", from);
             return TRUE;
diff --git a/src/xmpp/session.c b/src/xmpp/session.c
index 3bec1ab2..c4ea3f24 100644
--- a/src/xmpp/session.c
+++ b/src/xmpp/session.c
@@ -96,8 +96,6 @@ static activity_state_t activity_state;
 static resource_presence_t saved_presence;
 static char* saved_status;
 
-static void _session_reconnect(void);
-
 static void _session_free_internals(void);
 static void _session_free_saved_details(void);
 
@@ -268,12 +266,12 @@ session_process_events(void)
         if ((reconnect_sec != 0) && reconnect_timer) {
             int elapsed_sec = g_timer_elapsed(reconnect_timer, NULL);
             if (elapsed_sec > reconnect_sec) {
-                _session_reconnect();
+                session_reconnect_now();
             }
         }
         break;
     case JABBER_RECONNECT:
-        _session_reconnect();
+        session_reconnect_now();
         break;
     default:
         break;
@@ -307,7 +305,7 @@ _receive_mood(xmpp_stanza_t* const stanza, void* const userdata)
                         const char* m = xmpp_stanza_get_name(c);
                         xmpp_stanza_t* t = xmpp_stanza_get_child_by_name(mood, STANZA_NAME_TEXT);
                         if (t) {
-                            const char* text = xmpp_stanza_get_text(t);
+                            auto_char char* text = xmpp_stanza_get_text(t);
                             cons_show("Mood from %s %s (%s)", from, m, text);
                         } else {
                             cons_show("Mood from %s %s", from, m);
@@ -557,8 +555,8 @@ session_reconnect(gchar* altdomain, unsigned short altport)
     reconnect.altport = altport;
 }
 
-static void
-_session_reconnect(void)
+void
+session_reconnect_now(void)
 {
     // reconnect with account.
     ProfAccount* account = accounts_get_account(saved_account.name);
diff --git a/src/xmpp/session.h b/src/xmpp/session.h
index d8565fa4..e6facb93 100644
--- a/src/xmpp/session.h
+++ b/src/xmpp/session.h
@@ -47,5 +47,6 @@ void session_init_activity(void);
 void session_check_autoaway(void);
 
 void session_reconnect(gchar* altdomain, unsigned short altport);
+void session_reconnect_now(void);
 
 #endif