~singpolyma/biboumi

7e2427148e9023483f266cd3ac4e167d50320796 — Florent Le Coz 6 years ago 8ddbe8d
Use references instead of raw pointer, to store the “parent” object

In Bridge and IrcClient
M src/bridge/bridge.cpp => src/bridge/bridge.cpp +31 -31
@@ 14,7 14,7 @@ using namespace std::string_literals;

static const char* action_prefix = "\01ACTION ";

Bridge::Bridge(const std::string& user_jid, BiboumiComponent* xmpp, std::shared_ptr<Poller> poller):
Bridge::Bridge(const std::string& user_jid, BiboumiComponent& xmpp, std::shared_ptr<Poller> poller):
  user_jid(user_jid),
  xmpp(xmpp),
  poller(poller)


@@ 105,7 105,7 @@ IrcClient* Bridge::make_irc_client(const std::string& hostname, const std::strin
                                std::make_shared<IrcClient>(this->poller, hostname,
                                                            nickname, username,
                                                            realname, jid.domain,
                                                            this));
                                                            *this));
      std::shared_ptr<IrcClient> irc = this->irc_clients.at(hostname);
      return irc.get();
    }


@@ 172,7 172,7 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
{
  if (iid.get_server().empty())
    {
      this->xmpp->send_stanza_error("message", this->user_jid, std::to_string(iid), "",
      this->xmpp.send_stanza_error("message", this->user_jid, std::to_string(iid), "",
                                    "cancel", "remote-server-not-found",
                                    std::to_string(iid) + " is not a valid channel name. "
                                    "A correct room jid is of the form: #<chan>%<server>",


@@ 205,7 205,7 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
        irc->send_channel_message(iid.get_local(), action_prefix + line.substr(4) + "\01");
      else
        irc->send_channel_message(iid.get_local(), line);
      this->xmpp->send_muc_message(std::to_string(iid), irc->get_own_nick(),
      this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(),
                                   this->make_xmpp_body(line), this->user_jid);
    }
}


@@ 278,7 278,7 @@ void Bridge::send_private_message(const Iid& iid, const std::string& body, const
{
  if (iid.get_local().empty() || iid.get_server().empty())
    {
      this->xmpp->send_stanza_error("message", this->user_jid, std::to_string(iid), "",
      this->xmpp.send_stanza_error("message", this->user_jid, std::to_string(iid), "",
                                    "cancel", "remote-server-not-found",
                                    std::to_string(iid) + " is not a valid channel name. "
                                    "A correct room jid is of the form: #<chan>%<server>",


@@ 336,7 336,7 @@ void Bridge::send_irc_channel_list_request(const Iid& iid, const std::string& iq
          std::string text;
          if (message.arguments.size() >= 2)
            text = message.arguments[1];
          this->xmpp->send_stanza_error("iq", to_jid, std::to_string(iid), iq_id,
          this->xmpp.send_stanza_error("iq", to_jid, std::to_string(iid), iq_id,
                                        "wait", "service-unavailable", text, false);
          return true;
        }


@@ 349,7 349,7 @@ void Bridge::send_irc_channel_list_request(const Iid& iid, const std::string& iq
        }
      else if (message.command == "323" || message.command == "RPL_LISTEND")
        { // Send the iq response with the content of the list
          this->xmpp->send_iq_room_list_result(iq_id, to_jid, std::to_string(iid), list);
          this->xmpp.send_iq_room_list_result(iq_id, to_jid, std::to_string(iid), list);
          return true;
        }
      return false;


@@ 374,7 374,7 @@ void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std:
          const std::string chan_name_later = utils::tolower(message.arguments[0]);
          if (target_later != target || chan_name_later != iid.get_local())
            return false;
          this->xmpp->send_iq_result(iq_id, to_jid, std::to_string(iid));
          this->xmpp.send_iq_result(iq_id, to_jid, std::to_string(iid));
        }
      else if (message.command == "401" && message.arguments.size() >= 2)
        {


@@ 384,7 384,7 @@ void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std:
          std::string error_message = "No such nick";
          if (message.arguments.size() >= 3)
            error_message = message.arguments[2];
          this->xmpp->send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "item-not-found",
          this->xmpp.send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "item-not-found",
                                        error_message, false);
        }
      else if (message.command == "482" && message.arguments.size() >= 2)


@@ 395,7 395,7 @@ void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std:
          std::string error_message = "You're not channel operator";
          if (message.arguments.size() >= 3)
            error_message = message.arguments[2];
          this->xmpp->send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "not-allowed",
          this->xmpp.send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "not-allowed",
                                        error_message, false);
        }
      return true;


@@ 441,7 441,7 @@ void Bridge::send_irc_user_ping_request(const std::string& irc_hostname, const s
          if (id != iq_id)
            return false;
          Jid jid(from_jid);
          this->xmpp->send_iq_result(iq_id, to_jid, jid.local);
          this->xmpp.send_iq_result(iq_id, to_jid, jid.local);
          return true;
        }
      if (message.command == "401" && message.arguments[1] == nick)


@@ 449,7 449,7 @@ void Bridge::send_irc_user_ping_request(const std::string& irc_hostname, const s
          std::string error_message = "No such nick";
          if (message.arguments.size() >= 3)
            error_message = message.arguments[2];
          this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "service-unavailable",
          this->xmpp.send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "service-unavailable",
                                        error_message, true);
          return true;
        }


@@ 467,13 467,13 @@ void Bridge::send_irc_participant_ping_request(const Iid& iid, const std::string
  IrcChannel* chan = irc->get_channel(iid.get_local());
  if (!chan->joined)
    {
      this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "not-allowed",
      this->xmpp.send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "not-allowed",
                                    "", true);
      return;
    }
  if (chan->get_self()->nick != nick && !chan->find_user(nick))
    {
      this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "item-not-found",
      this->xmpp.send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "item-not-found",
                                    "Recipient not in room", true);
      return;
    }


@@ 487,9 487,9 @@ void Bridge::on_gateway_ping(const std::string& irc_hostname, const std::string&
{
  Jid jid(from_jid);
  if (irc_hostname.empty() || this->find_irc_client(irc_hostname))
    this->xmpp->send_iq_result(iq_id, to_jid, jid.local);
    this->xmpp.send_iq_result(iq_id, to_jid, jid.local);
  else
    this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "service-unavailable",
    this->xmpp.send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "service-unavailable",
                                  "", true);
}



@@ 511,7 511,7 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
        {
          // remove the "\01VERSION " and the "\01" parts from the string
          const std::string version = message.arguments[1].substr(9, message.arguments[1].size() - 10);
          this->xmpp->send_version(iq_id, to_jid, from_jid, version);
          this->xmpp.send_version(iq_id, to_jid, from_jid, version);
          return true;
        }
      if (message.command == "401" && message.arguments.size() >= 2


@@ 520,7 520,7 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
          std::string error_message = "No such nick";
          if (message.arguments.size() >= 3)
            error_message = message.arguments[2];
          this->xmpp->send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "item-not-found",
          this->xmpp.send_stanza_error("iq", to_jid, from_jid, iq_id, "cancel", "item-not-found",
                                        error_message, true);
          return true;
        }


@@ 532,7 532,7 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
void Bridge::send_message(const Iid& iid, const std::string& nick, const std::string& body, const bool muc)
{
  if (muc)
    this->xmpp->send_muc_message(std::to_string(iid), nick,
    this->xmpp.send_muc_message(std::to_string(iid), nick,
                                 this->make_xmpp_body(body), this->user_jid);
  else
    {


@@ 544,7 544,7 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st
          target = it->second;
          fulljid = true;
        }
      this->xmpp->send_message(target, this->make_xmpp_body(body),
      this->xmpp.send_message(target, this->make_xmpp_body(body),
                               this->user_jid, "chat", fulljid);
    }
}


@@ 553,12 553,12 @@ void Bridge::send_presence_error(const Iid& iid, const std::string& nick,
                                 const std::string& type, const std::string& condition,
                                 const std::string& error_code, const std::string& text)
{
  this->xmpp->send_presence_error(std::to_string(iid), nick, this->user_jid, type, condition, error_code, text);
  this->xmpp.send_presence_error(std::to_string(iid), nick, this->user_jid, type, condition, error_code, text);
}

void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self)
{
  this->xmpp->send_muc_leave(std::to_string(iid), std::move(nick), this->make_xmpp_body(message), this->user_jid, self);
  this->xmpp.send_muc_leave(std::to_string(iid), std::move(nick), this->make_xmpp_body(message), this->user_jid, self);
  IrcClient* irc = this->find_irc_client(iid.get_server());
  if (irc && irc->number_of_joined_channels() == 0)
    irc->send_quit_command("");


@@ 574,7 574,7 @@ void Bridge::send_nick_change(Iid&& iid,
  std::string role;
  std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);

  this->xmpp->send_nick_change(std::to_string(iid),
  this->xmpp.send_nick_change(std::to_string(iid),
                               old_nick, new_nick, affiliation, role, this->user_jid, self);
}



@@ 590,7 590,7 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho
    }
  else
    body = msg;
  this->xmpp->send_message(from, this->make_xmpp_body(body), this->user_jid, "chat");
  this->xmpp.send_message(from, this->make_xmpp_body(body), this->user_jid, "chat");
}

void Bridge::send_user_join(const std::string& hostname,


@@ 603,13 603,13 @@ void Bridge::send_user_join(const std::string& hostname,
  std::string role;
  std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);

  this->xmpp->send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host,
  this->xmpp.send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host,
                             affiliation, role, this->user_jid, self);
}

void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string& topic)
{
  this->xmpp->send_topic(chan_name + utils::empty_if_fixed_server("%" + hostname), this->make_xmpp_body(topic), this->user_jid);
  this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server("%" + hostname), this->make_xmpp_body(topic), this->user_jid);
}

std::string Bridge::get_own_nick(const Iid& iid)


@@ 627,12 627,12 @@ size_t Bridge::active_clients() const

void Bridge::kick_muc_user(Iid&& iid, const std::string& target, const std::string& reason, const std::string& author)
{
  this->xmpp->kick_user(std::to_string(iid), target, reason, author, this->user_jid);
  this->xmpp.kick_user(std::to_string(iid), target, reason, author, this->user_jid);
}

void Bridge::send_nickname_conflict_error(const Iid& iid, const std::string& nickname)
{
  this->xmpp->send_presence_error(std::to_string(iid), nickname, this->user_jid, "cancel", "conflict", "409", "");
  this->xmpp.send_presence_error(std::to_string(iid), nickname, this->user_jid, "cancel", "conflict", "409", "");
}

void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& target, const char mode)


@@ 641,12 641,12 @@ void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& tar
  std::string affiliation;

  std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(mode);
  this->xmpp->send_affiliation_role_change(std::to_string(iid), target, affiliation, role, this->user_jid);
  this->xmpp.send_affiliation_role_change(std::to_string(iid), target, affiliation, role, this->user_jid);
}

void Bridge::send_iq_version_request(const std::string& nick, const std::string& hostname)
{
  this->xmpp->send_iq_version_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid);
  this->xmpp.send_iq_version_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid);
}

void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string& hostname,


@@ 655,7 655,7 @@ void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string& 
  // Use revstr because the forwarded ping to target XMPP user must not be
  // the same that the request iq, but we also need to get it back easily
  // (revstr again)
  this->xmpp->send_ping_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid, utils::revstr(id));
  this->xmpp.send_ping_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid, utils::revstr(id));
}

void Bridge::set_preferred_from_jid(const std::string& nick, const std::string& full_jid)

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +3 -5
@@ 33,7 33,7 @@ using irc_responder_callback_t = std::function<bool(const std::string& irc_hostn
class Bridge
{
public:
  explicit Bridge(const std::string& user_jid, BiboumiComponent* xmpp, std::shared_ptr<Poller> poller);
  explicit Bridge(const std::string& user_jid, BiboumiComponent& xmpp, std::shared_ptr<Poller> poller);
  ~Bridge();
  /**
   * QUIT all connected IRC servers.


@@ 216,11 216,9 @@ private:
   */
  std::unordered_map<std::string, std::shared_ptr<IrcClient>> irc_clients;
  /**
   * A raw pointer, because we do not own it, the XMPP component owns us,
   * but we still need to communicate with it, when sending messages from
   * IRC to XMPP.
   * To communicate back with the XMPP component
   */
  BiboumiComponent* xmpp;
  BiboumiComponent& xmpp;
  /**
   * Poller, to give it the IrcClients that we spawn, to make it manage
   * their sockets.

M src/irc/irc_client.cpp => src/irc/irc_client.cpp +37 -37
@@ 27,7 27,7 @@ using namespace std::chrono_literals;
IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
                     const std::string& nickname, const std::string& username,
                     const std::string& realname, const std::string& user_hostname,
                     Bridge* bridge):
                     Bridge& bridge):
  TCPSocketHandler(poller),
  hostname(hostname),
  user_hostname(user_hostname),


@@ 48,7 48,7 @@ IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname
                              "To disconnect from the IRC server, leave this room and all "
                              "other IRC channels of that server.";
#ifdef USE_DATABASE
  auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(),
  auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
                                                  this->get_hostname());
  std::vector<std::string> ports = utils::split(options.ports, ';', false);
  for (auto it = ports.rbegin(); it != ports.rend(); ++it)


@@ 72,7 72,7 @@ IrcClient::~IrcClient()
{
  // This event may or may not exist (if we never got connected, it
  // doesn't), but it's ok
  TimedEventsManager::instance().cancel("PING"s + this->hostname + this->bridge->get_jid());
  TimedEventsManager::instance().cancel("PING"s + this->hostname + this->bridge.get_jid());
}

void IrcClient::start()


@@ 83,7 83,7 @@ void IrcClient::start()
  bool tls;
  std::tie(port, tls) = this->ports_to_try.top();
  this->ports_to_try.pop();
  this->bridge->send_xmpp_message(this->hostname, "", "Connecting to "s +
  this->bridge.send_xmpp_message(this->hostname, "", "Connecting to "s +
                                  this->hostname + ":" + port + " (" +
                                  (tls ? "encrypted" : "not encrypted") + ")");



@@ 94,7 94,7 @@ void IrcClient::start()

void IrcClient::on_connection_failed(const std::string& reason)
{
  this->bridge->send_xmpp_message(this->hostname, "",
  this->bridge.send_xmpp_message(this->hostname, "",
                                  "Connection failed: "s + reason);

  if (this->hostname_resolution_failed)


@@ 107,7 107,7 @@ void IrcClient::on_connection_failed(const std::string& reason)
      for (const auto& tuple: this->channels_to_join)
        {
          Iid iid(std::get<0>(tuple) + "%" + this->hostname);
          this->bridge->send_presence_error(iid, this->current_nick,
          this->bridge.send_presence_error(iid, this->current_nick,
                                            "cancel", "item-not-found",
                                            "", reason);
        }


@@ 152,7 152,7 @@ void IrcClient::on_connected()
    }

#ifdef USE_DATABASE
  auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(),
  auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
                                                  this->get_hostname());
  if (!options.pass.value().empty())
    this->send_pass_command(options.pass.value());


@@ 258,7 258,7 @@ void IrcClient::parse_in_buffer(const size_t)
          this->on_unknown_message(message);
        }
      // Try to find a waiting_iq, which response will be triggered by this IrcMessage
      this->bridge->trigger_on_irc_message(this->hostname, message);
      this->bridge.trigger_on_irc_message(this->hostname, message);
    }
}



@@ 413,7 413,7 @@ void IrcClient::forward_server_message(const IrcMessage& message)
  const std::string from = message.prefix;
  const std::string body = message.arguments[1];

  this->bridge->send_xmpp_message(this->hostname, from, body);
  this->bridge.send_xmpp_message(this->hostname, from, body);
}

void IrcClient::on_notice(const IrcMessage& message)


@@ 438,11 438,11 @@ void IrcClient::on_notice(const IrcMessage& message)
      if (this->nicks_to_treat_as_private.find(nick) !=
          this->nicks_to_treat_as_private.end())
        { // We previously sent a message to that nick)
          this->bridge->send_message({nick + "!" + this->hostname}, nick, body,
          this->bridge.send_message({nick + "!" + this->hostname}, nick, body,
                                     false);
        }
      else
        this->bridge->send_xmpp_message(this->hostname, from, body);
        this->bridge.send_xmpp_message(this->hostname, from, body);
    }
  else
    {


@@ 494,7 494,7 @@ void IrcClient::on_isupport_message(const IrcMessage& message)

void IrcClient::send_gateway_message(const std::string& message, const std::string& from)
{
  this->bridge->send_xmpp_message(this->hostname, from, message);
  this->bridge.send_xmpp_message(this->hostname, from, message);
}

void IrcClient::set_and_forward_user_list(const IrcMessage& message)


@@ 507,7 507,7 @@ void IrcClient::set_and_forward_user_list(const IrcMessage& message)
      const IrcUser* user = channel->add_user(nick, this->prefix_to_mode);
      if (user->nick != channel->get_self()->nick)
        {
          this->bridge->send_user_join(this->hostname, chan_name, user,
          this->bridge.send_user_join(this->hostname, chan_name, user,
                                       user->get_most_significant_mode(this->sorted_user_modes),
                                       false);
        }


@@ 533,7 533,7 @@ void IrcClient::on_channel_join(const IrcMessage& message)
  else
    {
      const IrcUser* user = channel->add_user(nick, this->prefix_to_mode);
      this->bridge->send_user_join(this->hostname, chan_name, user,
      this->bridge.send_user_join(this->hostname, chan_name, user,
                                   user->get_most_significant_mode(this->sorted_user_modes),
                                   false);
    }


@@ 559,16 559,16 @@ void IrcClient::on_channel_message(const IrcMessage& message)
  if (!body.empty() && body[0] == '\01')
    {
      if (body.substr(1, 6) == "ACTION")
        this->bridge->send_message(iid, nick,
        this->bridge.send_message(iid, nick,
                  "/me"s + body.substr(7, body.size() - 8), muc);
      else if (body.substr(1, 8) == "VERSION\01")
        this->bridge->send_iq_version_request(nick, this->hostname);
        this->bridge.send_iq_version_request(nick, this->hostname);
      else if (body.substr(1, 5) == "PING ")
        this->bridge->send_xmpp_ping_request(utils::tolower(nick), this->hostname,
        this->bridge.send_xmpp_ping_request(utils::tolower(nick), this->hostname,
                                             body.substr(6, body.size() - 7));
    }
  else
    this->bridge->send_message(iid, nick, body, muc);
    this->bridge.send_message(iid, nick, body, muc);
}

void IrcClient::on_rpl_liststart(const IrcMessage&)


@@ 599,7 599,7 @@ void IrcClient::on_motd_line(const IrcMessage& message)

void IrcClient::send_motd(const IrcMessage&)
{
  this->bridge->send_xmpp_message(this->hostname, "", this->motd);
  this->bridge.send_xmpp_message(this->hostname, "", this->motd);
}

void IrcClient::on_topic_received(const IrcMessage& message)


@@ 608,7 608,7 @@ void IrcClient::on_topic_received(const IrcMessage& message)
  IrcChannel* channel = this->get_channel(chan_name);
  channel->topic = message.arguments[message.arguments.size() - 1];
  if (channel->joined)
    this->bridge->send_topic(this->hostname, chan_name, channel->topic);
    this->bridge.send_topic(this->hostname, chan_name, channel->topic);
}

void IrcClient::on_channel_completely_joined(const IrcMessage& message)


@@ 616,10 616,10 @@ void IrcClient::on_channel_completely_joined(const IrcMessage& message)
  const std::string chan_name = utils::tolower(message.arguments[1]);
  IrcChannel* channel = this->get_channel(chan_name);
  channel->joined = true;
  this->bridge->send_user_join(this->hostname, chan_name, channel->get_self(),
  this->bridge.send_user_join(this->hostname, chan_name, channel->get_self(),
                               channel->get_self()->get_most_significant_mode(this->sorted_user_modes),
                               true);
  this->bridge->send_topic(this->hostname, chan_name, channel->topic);
  this->bridge.send_topic(this->hostname, chan_name, channel->topic);
}

void IrcClient::on_erroneous_nickname(const IrcMessage& message)


@@ 639,7 639,7 @@ void IrcClient::on_nickname_conflict(const IrcMessage& message)
    iid.set_local(it->first);
    iid.set_server(this->hostname);
    iid.is_channel = true;
    this->bridge->send_nickname_conflict_error(iid, nickname);
    this->bridge.send_nickname_conflict_error(iid, nickname);
  }
}



@@ 656,7 656,7 @@ void IrcClient::on_nickname_change_too_fast(const IrcMessage& message)
    iid.set_local(it->first);
    iid.set_server(this->hostname);
    iid.is_channel = true;
    this->bridge->send_presence_error(iid, nickname,
    this->bridge.send_presence_error(iid, nickname,
                                      "cancel", "not-acceptable",
                                      "", txt);
  }


@@ 674,14 674,14 @@ void IrcClient::on_welcome_message(const IrcMessage& message)
  this->current_nick = message.arguments[0];
  this->welcomed = true;
#ifdef USE_DATABASE
  auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(),
  auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
                                                  this->get_hostname());
  if (!options.afterConnectionCommand.value().empty())
    this->send_raw(options.afterConnectionCommand.value());
#endif
  // Install a repeated events to regularly send a PING
  TimedEventsManager::instance().add_event(TimedEvent(240s, std::bind(&IrcClient::send_ping_command, this),
                                                      "PING"s + this->hostname + this->bridge->get_jid()));
                                                      "PING"s + this->hostname + this->bridge.get_jid()));
  for (const auto& tuple: this->channels_to_join)
    this->send_join_command(std::get<0>(tuple), std::get<1>(tuple));
  this->channels_to_join.clear();


@@ 725,7 725,7 @@ void IrcClient::on_part(const IrcMessage& message)
        // channel pointer is now invalid
        channel = nullptr;
      }
      this->bridge->send_muc_leave(std::move(iid), std::move(nick), std::move(txt), self);
      this->bridge.send_muc_leave(std::move(iid), std::move(nick), std::move(txt), self);
    }
}



@@ 743,7 743,7 @@ void IrcClient::on_error(const IrcMessage& message)
    if (!channel->joined)
      continue;
    std::string own_nick = channel->get_self()->nick;
    this->bridge->send_muc_leave(std::move(iid), std::move(own_nick), leave_message, true);
    this->bridge.send_muc_leave(std::move(iid), std::move(own_nick), leave_message, true);
  }
  this->channels.clear();
  this->send_gateway_message("ERROR: "s + leave_message);


@@ 767,7 767,7 @@ void IrcClient::on_quit(const IrcMessage& message)
          iid.set_local(chan_name);
          iid.set_server(this->hostname);
          iid.is_channel = true;
          this->bridge->send_muc_leave(std::move(iid), std::move(nick), txt, false);
          this->bridge.send_muc_leave(std::move(iid), std::move(nick), txt, false);
        }
    }
}


@@ 789,7 789,7 @@ void IrcClient::on_nick(const IrcMessage& message)
          iid.is_channel = true;
          const bool self = channel->get_self()->nick == old_nick;
          const char user_mode = user->get_most_significant_mode(this->sorted_user_modes);
          this->bridge->send_nick_change(std::move(iid), old_nick, new_nick, user_mode, self);
          this->bridge.send_nick_change(std::move(iid), old_nick, new_nick, user_mode, self);
          user->nick = new_nick;
          if (self)
            {


@@ 815,7 815,7 @@ void IrcClient::on_kick(const IrcMessage& message)
  iid.set_local(chan_name);
  iid.set_server(this->hostname);
  iid.is_channel = true;
  this->bridge->kick_muc_user(std::move(iid), target, reason, author.nick);
  this->bridge.kick_muc_user(std::move(iid), target, reason, author.nick);
}

void IrcClient::on_mode(const IrcMessage& message)


@@ 846,7 846,7 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
          mode_arguments += message.arguments[i];
        }
    }
  this->bridge->send_message(iid, "", "Mode "s + iid.get_local() +
  this->bridge.send_message(iid, "", "Mode "s + iid.get_local() +
                                      " [" + mode_arguments + "] by " + user.nick,
                             true);
  const IrcChannel* channel = this->get_channel(iid.get_local());


@@ 917,13 917,13 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
  for (const IrcUser* u: modified_users)
    {
      char most_significant_mode = u->get_most_significant_mode(this->sorted_user_modes);
      this->bridge->send_affiliation_role_change(iid, u->nick, most_significant_mode);
      this->bridge.send_affiliation_role_change(iid, u->nick, most_significant_mode);
    }
}

void IrcClient::on_user_mode(const IrcMessage& message)
{
  this->bridge->send_xmpp_message(this->hostname, "",
  this->bridge.send_xmpp_message(this->hostname, "",
                                  "User mode for "s + message.arguments[0] +
                                  " is [" + message.arguments[1] + "]");
}


@@ 940,7 940,7 @@ void IrcClient::on_unknown_message(const IrcMessage& message)
      if (it + 1 != message.arguments.end())
        ss << " ";
    }
  this->bridge->send_xmpp_message(this->hostname, from, ss.str());
  this->bridge.send_xmpp_message(this->hostname, from, ss.str());
}

size_t IrcClient::number_of_joined_channels() const


@@ 963,14 963,14 @@ void IrcClient::leave_dummy_channel(const std::string& exit_message)
  this->dummy_channel.joined = false;
  this->dummy_channel.joining = false;
  this->dummy_channel.remove_all_users();
  this->bridge->send_muc_leave(Iid("%"s + this->hostname), std::string(this->current_nick), exit_message, true);
  this->bridge.send_muc_leave(Iid("%"s + this->hostname), std::string(this->current_nick), exit_message, true);
}

#ifdef BOTAN_FOUND
bool IrcClient::abort_on_invalid_cert() const
{
#ifdef USE_DATABASE
  auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(), this->hostname);
  auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), this->hostname);
  return options.verifyCert.value();
#endif
  return true;

M src/irc/irc_client.hpp => src/irc/irc_client.hpp +3 -3
@@ 29,7 29,7 @@ public:
  explicit IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
                     const std::string& nickname, const std::string& username,
                     const std::string& realname, const std::string& user_hostname,
                     Bridge* bridge);
                     Bridge& bridge);
  ~IrcClient();
  /**
   * Connect to the IRC server


@@ 281,9 281,9 @@ private:
   */
  std::string current_nick;
  /**
   * Raw pointer because the bridge owns us.
   * To communicate back with the bridge
   */
  Bridge* bridge;
  Bridge& bridge;
  /**
   * The list of joined channels, indexed by name
   */

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +1 -1
@@ 488,7 488,7 @@ Bridge* BiboumiComponent::get_user_bridge(const std::string& user_jid)
    }
  catch (const std::out_of_range& exception)
    {
      this->bridges.emplace(user_jid, std::make_unique<Bridge>(user_jid, this, this->poller));
      this->bridges.emplace(user_jid, std::make_unique<Bridge>(user_jid, *this, this->poller));
      return this->bridges.at(user_jid).get();
    }
}