From cad70ba453a7877b64c0f23a4b4f34db9d1a0957 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Wed, 2 Aug 2017 21:47:21 +0200
Subject: Re-add a removed (by mistake) pointer null check

---
 src/xmpp/biboumi_adhoc_commands.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index 60af506..65f9966 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -409,7 +409,7 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
           else if (field->get_tag("var") == "pass" && value)
             options.col<Database::Pass>() = value->get_inner();
 
-          else if (field->get_tag("var") == "after_connect_command")
+          else if (field->get_tag("var") == "after_connect_command" && value)
             options.col<Database::AfterConnectionCommand>() = value->get_inner();
 
           else if (field->get_tag("var") == "username" && value)
-- 
cgit v1.2.3


From 655151d88a6ab948949b73682c3a76a0274eb10c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sat, 26 Aug 2017 13:51:15 +0200
Subject: Cache the encoding_in database value, to avoid doing a query for each
 message

---
 src/xmpp/biboumi_adhoc_commands.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index 65f9966..d78dc98 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -430,7 +430,7 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
             options.col<Database::EncodingIn>() = value->get_inner();
 
         }
-
+      Database::invalidate_encoding_in_cache();
       options.save(Database::db);
 
       command_node.delete_all_children();
@@ -599,7 +599,7 @@ bool handle_irc_channel_configuration_form(XmppComponent& xmpp_component, const
                 }
 
             }
-
+          Database::invalidate_encoding_in_cache(requester.bare(), iid.get_server(), iid.get_local());
           options.save(Database::db);
         }
       return true;
-- 
cgit v1.2.3


From 25243f53c2479e2fda0f1a05d1589c8214b70b4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 27 Aug 2017 14:32:29 +0200
Subject: =?UTF-8?q?In=20fixed=20mode,=20server=20messages=20come=20from=20?=
 =?UTF-8?q?biboumi=E2=80=99s=20hostname=20directly?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Instead of irc.example.com@biboumi, because that’s actually user named
“irc.example.com”, in that case.
And that fixes the raw messages in fixed mode.

fix #3286
---
 src/xmpp/biboumi_component.cpp | 5 ++++-
 src/xmpp/xmpp_component.cpp    | 7 ++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 0e1d270..6cddeb4 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -281,6 +281,7 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
     {
       if (body && !body->get_inner().empty())
         {
+          const auto fixed_irc_server = Config::get("fixed_irc_server", "");
           // a message for nick!server
           if (iid.type == Iid::Type::User && !iid.get_local().empty())
             {
@@ -296,9 +297,11 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
               bridge->set_preferred_from_jid(user_iid.get_local(), to_str);
             }
           else if (iid.type == Iid::Type::Server)
+            bridge->send_raw_message(iid.get_server(), body->get_inner());
+          else if (iid.type == Iid::Type::None && !fixed_irc_server.empty())
             { // Message sent to the server JID
               // Convert the message body into a raw IRC message
-              bridge->send_raw_message(iid.get_server(), body->get_inner());
+              bridge->send_raw_message(fixed_irc_server, body->get_inner());
             }
         }
     }
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 42a5392..24a85d7 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -277,7 +277,12 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con
     if (fulljid)
       message["from"] = from;
     else
-      message["from"] = from + "@" + this->served_hostname;
+      {
+        if (!from.empty())
+          message["from"] = from + "@" + this->served_hostname;
+        else
+          message["from"] = this->served_hostname;
+      }
     if (!type.empty())
       message["type"] = type;
     XmlSubNode body_node(message, "body");
-- 
cgit v1.2.3


From fcaffb9e778ad5962e69dc23c1fc91eb59a27945 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 27 Aug 2017 22:30:44 +0200
Subject: Add support for the "history" node on MUC join

Supports the "seconds", "maxstanzas", "since" and "maxchars" (but only =0)
attributes.

fix #3270
---
 src/xmpp/biboumi_component.cpp | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 6cddeb4..7c5b059 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -24,6 +24,7 @@
 
 #include <database/database.hpp>
 #include <bridge/result_set_management.hpp>
+#include <bridge/history_limit.hpp>
 
 using namespace std::string_literals;
 
@@ -155,8 +156,33 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
             bridge->send_irc_nick_change(iid, to.resource, from.resource);
           const XmlNode* x = stanza.get_child("x", MUC_NS);
           const XmlNode* password = x ? x->get_child("password", MUC_NS): nullptr;
+          const XmlNode* history = x ? x->get_child("history", MUC_NS): nullptr;
+          HistoryLimit history_limit;
+          if (history)
+            {
+              // TODO implement the "seconds"
+              const auto seconds = history->get_tag("seconds");
+              if (!seconds.empty())
+                {
+                  const auto now = std::chrono::system_clock::now();
+                  std::time_t timestamp = std::chrono::system_clock::to_time_t(now);
+                  int int_seconds = std::atoi(seconds.data());
+                  timestamp -= int_seconds;
+                  history_limit.since = utils::to_string(timestamp);
+                }
+              const auto since = history->get_tag("since");
+              if (!since.empty())
+                history_limit.since = since;
+              const auto maxstanzas = history->get_tag("maxstanzas");
+              if (!maxstanzas.empty())
+                history_limit.stanzas = std::atoi(maxstanzas.data());
+              // Ignore any other value, because this is too complex to implement,
+              // so I won’t do it.
+              if (history->get_tag("maxchars") == "0")
+                history_limit.stanzas = 0;
+            }
           bridge->join_irc_channel(iid, to.resource, password ? password->get_inner(): "",
-                                   from.resource);
+                                   from.resource, history_limit);
         }
       else if (type == "unavailable")
         {
-- 
cgit v1.2.3


From 98227db6ad005c2e73445ce10e13484cb0568d2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 27 Aug 2017 22:41:05 +0200
Subject: Remove a forgotten and useless comment

[skip-ci]
---
 src/xmpp/biboumi_component.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 7c5b059..0b2bba0 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -160,7 +160,6 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
           HistoryLimit history_limit;
           if (history)
             {
-              // TODO implement the "seconds"
               const auto seconds = history->get_tag("seconds");
               if (!seconds.empty())
                 {
-- 
cgit v1.2.3


From bfcf29451787d10c747ad79cb3fd177ac86e9cf1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sat, 9 Sep 2017 17:09:17 +0200
Subject: Add the persistent_by_default configuration option

fix #3293
---
 src/xmpp/biboumi_adhoc_commands.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index d78dc98..bcdac39 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -159,7 +159,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
     {
       XmlSubNode value(persistent, "value");
       value.set_name("value");
-      if (options.col<Database::Persistent>())
+      if (options.col<Database::GlobalPersistent>())
         value.set_inner("true");
       else
         value.set_inner("false");
@@ -193,7 +193,7 @@ void ConfigureGlobalStep2(XmppComponent& xmpp_component, AdhocSession& session,
             }
           else if (field->get_tag("var") == "persistent" &&
                    value)
-            options.col<Database::Persistent>() = to_bool(value->get_inner());
+            options.col<Database::GlobalPersistent>() = to_bool(value->get_inner());
         }
 
       options.save(Database::db);
-- 
cgit v1.2.3


From 1c3d4f6f5fdf5829e931770523251abe9522914b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Thu, 21 Sep 2017 21:57:01 +0200
Subject: Remove a redundant Body definition

---
 src/xmpp/body.hpp | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'src/xmpp')

diff --git a/src/xmpp/body.hpp b/src/xmpp/body.hpp
index 068d1a4..f693cdd 100644
--- a/src/xmpp/body.hpp
+++ b/src/xmpp/body.hpp
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <tuple>
+#include <memory>
+
+class XmlNode;
 
 namespace Xmpp
 {
-- 
cgit v1.2.3


From 24dc05dd979264143223e166faa032e75f986b21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 3 Dec 2017 16:28:38 +0100
Subject: Run some of the ci tests against a postgresql docker container

---
 src/xmpp/biboumi_component.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 0b2bba0..51ca78d 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -1080,6 +1080,9 @@ void BiboumiComponent::on_irc_client_connected(const std::string& irc_hostname,
   const auto local_jid = irc_hostname + "@" + this->served_hostname;
   if (Database::has_roster_item(local_jid, jid))
     this->send_presence_to_contact(local_jid, jid, "");
+#else
+  (void)irc_hostname;
+  (void)jid;
 #endif
 }
 
@@ -1089,6 +1092,9 @@ void BiboumiComponent::on_irc_client_disconnected(const std::string& irc_hostnam
   const auto local_jid = irc_hostname + "@" + this->served_hostname;
   if (Database::has_roster_item(local_jid, jid))
     this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, "unavailable");
+#else
+  (void)irc_hostname;
+  (void)jid;
 #endif
 }
 
-- 
cgit v1.2.3


From 37340e593ffb61eaccc444a1efdb3aa6f784a14a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Tue, 26 Dec 2017 19:52:41 +0100
Subject: Add a <x muc#user> node on outgoing private MUC messages

See https://xmpp.org/extensions/xep-0045.html#privatemessage

fix #3321
---
 src/xmpp/xmpp_component.cpp | 8 +++++++-
 src/xmpp/xmpp_component.hpp | 3 ++-
 2 files changed, 9 insertions(+), 2 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 24a85d7..c44b990 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -269,7 +269,8 @@ void* XmppComponent::get_receive_buffer(const size_t size) const
 }
 
 void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to,
-                                 const std::string& type, const bool fulljid, const bool nocopy)
+                                 const std::string& type, const bool fulljid, const bool nocopy,
+                                 const bool muc_private)
 {
   Stanza message("message");
   {
@@ -301,6 +302,11 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con
         XmlSubNode nocopy(message, "no-copy");
         nocopy["xmlns"] = "urn:xmpp:hints";
       }
+    if (muc_private)
+      {
+        XmlSubNode x(message, "x");
+        x["xmlns"] = MUC_USER_NS;
+      }
   }
   this->send_stanza(message);
 }
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 22d5c48..2bbbe3b 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -112,7 +112,8 @@ public:
    * server-part of the JID and must be added.
    */
   void send_message(const std::string& from, Xmpp::body&& body, const std::string& to,
-                    const std::string& type, const bool fulljid, const bool nocopy=false);
+                    const std::string& type, const bool fulljid, const bool nocopy=false,
+                    const bool muc_private=false);
   /**
    * Send a join from a new participant
    */
-- 
cgit v1.2.3


From 131ef9946fff0f5cfd794203e819df931b72600f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Tue, 26 Dec 2017 20:21:18 +0100
Subject: Include the <fin><set><first/><last/></></> nodes in the MAM iq
 result

fix #3322
---
 src/xmpp/biboumi_component.cpp | 19 ++++++++++++++++++-
 src/xmpp/xmpp_component.cpp    |  4 +++-
 src/xmpp/xmpp_component.hpp    |  2 +-
 3 files changed, 22 insertions(+), 3 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 51ca78d..a998fbe 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -725,7 +725,24 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
           if (!line.col<Database::Nick>().empty())
             this->send_archived_message(line, to.full(), from.full(), query_id);
         }
-        this->send_iq_result_full_jid(id, from.full(), to.full());
+        {
+          auto fin_ptr = std::make_unique<XmlNode>("fin");
+          {
+            XmlNode& fin = *(fin_ptr.get());
+            fin["xmlns"] = MAM_NS;
+            XmlSubNode set(fin, "set");
+            set["xmlns"] = RSM_NS;
+            if (!lines.empty())
+              {
+                XmlSubNode first(set, "first");
+                first["index"] = "0";
+                first.set_inner(lines[0].col<Database::Uuid>());
+                XmlSubNode last(set, "last");
+                last.set_inner(lines[lines.size() - 1].col<Database::Uuid>());
+              }
+          }
+          this->send_iq_result_full_jid(id, from.full(), to.full(), std::move(fin_ptr));
+        }
         return true;
       }
   return false;
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index c44b990..8f6826e 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -640,13 +640,15 @@ void XmppComponent::send_iq_version_request(const std::string& from,
   this->send_stanza(iq);
 }
 
-void XmppComponent::send_iq_result_full_jid(const std::string& id, const std::string& to_jid, const std::string& from_full_jid)
+void XmppComponent::send_iq_result_full_jid(const std::string& id, const std::string& to_jid, const std::string& from_full_jid, std::unique_ptr<XmlNode> inner)
 {
   Stanza iq("iq");
   iq["from"] = from_full_jid;
   iq["to"] = to_jid;
   iq["id"] = id;
   iq["type"] = "result";
+  if (inner)
+    iq.add_child(std::move(inner));
   this->send_stanza(iq);
 }
 
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 2bbbe3b..3950863 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -203,7 +203,7 @@ public:
    */
   void send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from);
   void send_iq_result_full_jid(const std::string& id, const std::string& to_jid,
-                               const std::string& from_full_jid);
+                               const std::string& from_full_jid, std::unique_ptr<XmlNode> inner=nullptr);
 
   void handle_handshake(const Stanza& stanza);
   void handle_error(const Stanza& stanza);
-- 
cgit v1.2.3


From 2d9f516d1d36bbdd4b114dd3652bbeaebd2fa379 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Wed, 27 Dec 2017 19:23:28 +0100
Subject: =?UTF-8?q?Don=E2=80=99t=20answer=20to=20some=20requests=20towards?=
 =?UTF-8?q?=20MUC=20participants?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

These requests are only meant to be received by the room itself. The
participant must answer with not-implemented instead.

fix #3323
---
 src/xmpp/biboumi_component.cpp | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index a998fbe..e6eca3b 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -444,8 +444,13 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
           {
             if (iid.type == Iid::Type::Server)
               adhoc_handler = &this->irc_server_adhoc_commands_handler;
-            else
+            else if (iid.type == Iid::Type::Channel && to.resource.empty())
               adhoc_handler = &this->irc_channel_adhoc_commands_handler;
+            else
+              {
+                error_name = "feature-not-implemented";
+                return;
+              }
           }
           // Execute the command, if any, and get a result XmlNode that we
           // insert in our response
@@ -495,7 +500,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
                     stanza_error.disable();
                 }
             }
-          else if (iid.type == Iid::Type::Channel)
+          else if (iid.type == Iid::Type::Channel && to.resource.empty())
             {
               if (node.empty())
                 {
@@ -554,7 +559,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
                                                  this->irc_server_adhoc_commands_handler);
                   stanza_error.disable();
                 }
-              else if (iid.type == Iid::Type::Channel)
+              else if (iid.type == Iid::Type::Channel && to.resource.empty())
                 {               // Get the channel's adhoc commands
                   this->send_adhoc_commands_list(id, from, to_str,
                                                  (Config::get("admin", "") ==
@@ -562,6 +567,8 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
                                                  this->irc_channel_adhoc_commands_handler);
                   stanza_error.disable();
                 }
+              else // “to” is a MUC user, not the room itself
+                error_name = "feature-not-implemented";
             }
           else if (node.empty() && iid.type == Iid::Type::Server)
             { // Disco on an IRC server: get the list of channels
@@ -784,7 +791,7 @@ bool BiboumiComponent::handle_room_configuration_form_request(const std::string&
 {
   Iid iid(to.local, {'#', '&'});
 
-  if (iid.type != Iid::Type::Channel)
+  if (iid.type != Iid::Type::Channel || !to.resource.empty())
     return false;
 
   Stanza iq("iq");
@@ -806,7 +813,7 @@ bool BiboumiComponent::handle_room_configuration_form(const XmlNode& query, cons
 {
   Iid iid(to.local, {'#', '&'});
 
-  if (iid.type != Iid::Type::Channel)
+  if (iid.type != Iid::Type::Channel || !to.resource.empty())
     return false;
 
   Jid requester(from);
-- 
cgit v1.2.3


From 8409e50c1a28cc87799a8d9c67a90abf250ff6d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Wed, 27 Dec 2017 19:36:36 +0100
Subject: Fix a subtle iid parsing error in the adhoc code

---
 src/xmpp/biboumi_component.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index e6eca3b..8775869 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -436,7 +436,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
 
           // Depending on the 'to' jid in the request, we use one adhoc
           // command handler or an other
-          Iid iid(to.local, {});
+          Iid iid(to.local, {'#', '&'});
           AdhocCommandsHandler* adhoc_handler;
           if (to.local.empty())
             adhoc_handler = &this->adhoc_commands_handler;
-- 
cgit v1.2.3


From f371d9ca46578a722d2ce0d4a88ea35f64dd1d1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Thu, 18 Jan 2018 19:34:56 +0100
Subject: xep-0106 escape the JIDs listed in a disco#items server query

fix #3325
---
 src/xmpp/biboumi_component.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 8775869..a0e52e6 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -7,6 +7,7 @@
 #include <xmpp/adhoc_command.hpp>
 #include <xmpp/biboumi_adhoc_commands.hpp>
 #include <bridge/list_element.hpp>
+#include <utils/encoding.hpp>
 #include <config/config.hpp>
 #include <utils/time.hpp>
 #include <xmpp/jid.hpp>
@@ -1010,7 +1011,9 @@ void BiboumiComponent::send_iq_room_list_result(const std::string& id, const std
     for (auto it = begin; it != end; ++it)
       {
         XmlSubNode item(query, "item");
-        item["jid"] = it->channel + "@" + this->served_hostname;
+        std::string channel_name = it->channel;
+        xep0106::encode(channel_name);
+        item["jid"] = channel_name + "@" + this->served_hostname;
       }
 
     if ((rs_info.max >= 0 || !rs_info.after.empty() || !rs_info.before.empty()))
-- 
cgit v1.2.3


From 06271729e33300cebbd7222f50a2b38905e33cae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Mon, 22 Jan 2018 20:57:34 +0100
Subject: Fix a crash happening when a user cancels a non-existing ad-hoc
 session

---
 src/xmpp/adhoc_commands_handler.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/adhoc_commands_handler.cpp b/src/xmpp/adhoc_commands_handler.cpp
index e4dcd5c..bb48781 100644
--- a/src/xmpp/adhoc_commands_handler.cpp
+++ b/src/xmpp/adhoc_commands_handler.cpp
@@ -83,7 +83,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co
               XmlSubNode next(actions, "next");
             }
         }
-      else if (action == "cancel")
+      else if (session_it != this->sessions.end() && action == "cancel")
         {
           this->sessions.erase(session_it);
           command_node["status"] = "canceled";
-- 
cgit v1.2.3


From 442f46c4acf728e7a189327598a0ea3d33010d82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 28 Jan 2018 14:15:34 +0100
Subject: And an other conversion warning

---
 src/xmpp/xmpp_component.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 8f6826e..053fc3e 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -22,6 +22,7 @@
 #include <biboumi.h>
 #ifdef SYSTEMD_FOUND
 # include <systemd/sd-daemon.h>
+#include <database/database.hpp>
 #endif
 
 using namespace std::string_literals;
@@ -398,7 +399,7 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
   this->send_stanza(message);
 }
 
-void XmppComponent::send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body_txt, const std::string& jid_to, std::time_t timestamp)
+void XmppComponent::send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body_txt, const std::string& jid_to, Database::time_point::rep timestamp)
 {
   Stanza message("message");
   message["to"] = jid_to;
-- 
cgit v1.2.3


From 7403c397edb14ba93d014ab10e13a97c817ff0b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 28 Jan 2018 14:20:21 +0100
Subject: Correctly include the database header

---
 src/xmpp/xmpp_component.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 053fc3e..88baf6e 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -4,6 +4,7 @@
 #include <logger/logger.hpp>
 
 #include <xmpp/xmpp_component.hpp>
+#include <database/database.hpp>
 #include <config/config.hpp>
 #include <utils/system.hpp>
 #include <utils/time.hpp>
@@ -22,7 +23,6 @@
 #include <biboumi.h>
 #ifdef SYSTEMD_FOUND
 # include <systemd/sd-daemon.h>
-#include <database/database.hpp>
 #endif
 
 using namespace std::string_literals;
-- 
cgit v1.2.3


From 17f2cb5c93e2c86f68cda97fed43fb617bd75ff1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Mon, 29 Jan 2018 21:11:20 +0100
Subject: =?UTF-8?q?Do=20not=20forget=20the=20complete=3D'true'=20attribute?=
 =?UTF-8?q?=20in=20MAM=E2=80=99s=20result=20iq?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/xmpp/biboumi_component.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index a0e52e6..ee8a502 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -738,6 +738,7 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
           {
             XmlNode& fin = *(fin_ptr.get());
             fin["xmlns"] = MAM_NS;
+            fin["complete"] = "true";
             XmlSubNode set(fin, "set");
             set["xmlns"] = RSM_NS;
             if (!lines.empty())
-- 
cgit v1.2.3


From cb831788942b49a28bd79fd62dbdc3d00f15b227 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Tue, 30 Jan 2018 09:07:21 +0100
Subject: Add the complete='true' attribute only when appropriate

---
 src/xmpp/biboumi_component.cpp | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index ee8a502..dd66aca 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -721,13 +721,25 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
             if (max)
               limit = std::atoi(max->get_inner().data());
           }
-        // If the archive is really big, and the client didn’t specify any
-        // limit, we avoid flooding it: we set an arbitrary max limit.
-        if (limit == -1 && start.empty() && end.empty())
+        // Do send more than 100 messages, even if the client asked for more,
+        // or if it didn’t specify any limit.
+        // 101 is just a trick to know if there are more available messages.
+        // If our query returns 101 message, we know it’s incomplete, but we
+        // still send only 100
+        if ((limit == -1 && start.empty() && end.empty())
+            || limit > 100)
+          limit = 101;
+        log_debug("limit: ", limit);
+        auto lines = Database::get_muc_logs(from.bare(), iid.get_local(), iid.get_server(), limit, start, end);
+        bool complete = true;
+        if (lines.size() > 100)
           {
-            limit = 100;
+            log_debug("incomplete");
+            complete = false;
+            log_debug("size of lines before erase: ", lines.size());
+            lines.erase(lines.begin(), std::prev(lines.end(), 100));
+            log_debug("size of lines after erase: ", lines.size());
           }
-        const auto lines = Database::get_muc_logs(from.bare(), iid.get_local(), iid.get_server(), limit, start, end);
         for (const Database::MucLogLine& line: lines)
         {
           if (!line.col<Database::Nick>().empty())
@@ -738,7 +750,8 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
           {
             XmlNode& fin = *(fin_ptr.get());
             fin["xmlns"] = MAM_NS;
-            fin["complete"] = "true";
+            if (complete)
+              fin["complete"] = "true";
             XmlSubNode set(fin, "set");
             set["xmlns"] = RSM_NS;
             if (!lines.empty())
-- 
cgit v1.2.3


From 58fd68916636df2372f8187b375245ef5922833a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Tue, 30 Jan 2018 09:14:26 +0100
Subject: Add a ifndef USE_DATABASE guard around send_history_message

---
 src/xmpp/xmpp_component.cpp | 3 ++-
 src/xmpp/xmpp_component.hpp | 4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 88baf6e..9be9e34 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -4,7 +4,6 @@
 #include <logger/logger.hpp>
 
 #include <xmpp/xmpp_component.hpp>
-#include <database/database.hpp>
 #include <config/config.hpp>
 #include <utils/system.hpp>
 #include <utils/time.hpp>
@@ -399,6 +398,7 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
   this->send_stanza(message);
 }
 
+#ifdef USE_DATABASE
 void XmppComponent::send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body_txt, const std::string& jid_to, Database::time_point::rep timestamp)
 {
   Stanza message("message");
@@ -422,6 +422,7 @@ void XmppComponent::send_history_message(const std::string& muc_name, const std:
 
   this->send_stanza(message);
 }
+#endif
 
 void XmppComponent::send_muc_leave(const std::string& muc_name, const std::string& nick, Xmpp::body&& message,
                                    const std::string& jid_to, const bool self, const bool user_requested)
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 3950863..cef26c1 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -1,8 +1,10 @@
 #pragma once
 
+#include "biboumi.h"
 
 #include <xmpp/adhoc_commands_handler.hpp>
 #include <network/tcp_client_socket_handler.hpp>
+#include <database/database.hpp>
 #include <xmpp/xmpp_parser.hpp>
 #include <xmpp/body.hpp>
 
@@ -133,11 +135,13 @@ public:
    */
   void send_muc_message(const std::string& muc_name, const std::string& nick, Xmpp::body&& body, const std::string& jid_to,
                         std::string uuid);
+#ifdef USE_DATABASE
   /**
    * Send a message, with a <delay/> element, part of a MUC history
    */
   void send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body,
                             const std::string& jid_to, const std::time_t timestamp);
+#endif
   /**
    * Send an unavailable presence for this nick
    */
-- 
cgit v1.2.3


From 369da19d41142a20235372f3bfbe180e41008b95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Tue, 30 Jan 2018 09:16:12 +0100
Subject: Remove the debug logs from previous commit

---
 src/xmpp/biboumi_component.cpp | 4 ----
 1 file changed, 4 deletions(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index dd66aca..481ebb9 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -729,16 +729,12 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
         if ((limit == -1 && start.empty() && end.empty())
             || limit > 100)
           limit = 101;
-        log_debug("limit: ", limit);
         auto lines = Database::get_muc_logs(from.bare(), iid.get_local(), iid.get_server(), limit, start, end);
         bool complete = true;
         if (lines.size() > 100)
           {
-            log_debug("incomplete");
             complete = false;
-            log_debug("size of lines before erase: ", lines.size());
             lines.erase(lines.begin(), std::prev(lines.end(), 100));
-            log_debug("size of lines after erase: ", lines.size());
           }
         for (const Database::MucLogLine& line: lines)
         {
-- 
cgit v1.2.3


From d7cf736adb4837c55d8112160cd4718e549ebaaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 4 Feb 2018 11:02:56 +0100
Subject: Fix argument types in declaration of send_history_message

---
 src/xmpp/xmpp_component.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/xmpp')

diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index cef26c1..1daa6fb 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -140,7 +140,7 @@ public:
    * Send a message, with a <delay/> element, part of a MUC history
    */
   void send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body,
-                            const std::string& jid_to, const std::time_t timestamp);
+                            const std::string& jid_to, Database::time_point::rep timestamp);
 #endif
   /**
    * Send an unavailable presence for this nick
-- 
cgit v1.2.3