~singpolyma/biboumi

ref: e8e592d1ace5413a1e7d8b59b9467c78d8d68ea9 biboumi/src/main.cpp -rw-r--r-- 2.8 KiB
e8e592d1 — Florent Le Coz Remove disconnected IrcClients 9 years ago
                                                                                
ccebe901 Florent Le Coz
f0d9273d Florent Le Coz
3afb63a6 Florent Le Coz
bf7b05ef Florent Le Coz
f0d9273d Florent Le Coz
bf7b05ef Florent Le Coz
3afb63a6 Florent Le Coz
bf7b05ef Florent Le Coz
b60cbda4 Florent Le Coz
3afb63a6 Florent Le Coz
f0d9273d Florent Le Coz
64c1b28c Florent Le Coz
f0d9273d Florent Le Coz
b60cbda4 Florent Le Coz
f0d9273d Florent Le Coz
b60cbda4 Florent Le Coz
f0d9273d Florent Le Coz
b60cbda4 Florent Le Coz
f0d9273d Florent Le Coz
b60cbda4 Florent Le Coz
df59a091 Florent Le Coz
ccebe901 Florent Le Coz
b60cbda4 Florent Le Coz
f0d9273d Florent Le Coz
ccebe901 Florent Le Coz
3afb63a6 Florent Le Coz
e8e592d1 Florent Le Coz
3afb63a6 Florent Le Coz
64c1b28c Florent Le Coz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <xmpp/xmpp_component.hpp>
#include <network/poller.hpp>
#include <config/config.hpp>
#include <logger/logger.hpp>

#include <iostream>
#include <memory>
#include <atomic>

#include <signal.h>

// A flag set by the SIGINT signal handler.
volatile std::atomic<bool> stop(false);
// A flag indicating that we are wanting to exit the process. i.e: if this
// flag is set and all connections are closed, we can exit properly.
static bool exiting = false;

/**
 * Provide an helpful message to help the user write a minimal working
 * configuration file.
 */
int config_help(const std::string& missing_option)
{
  if (!missing_option.empty())
    std::cerr << "Error: empty value for option " << missing_option << "." << std::endl;
  std::cerr <<
    "Please provide a configuration file filled like this:\n\n"
    "hostname=irc.example.com\npassword=S3CR3T"
            << std::endl;
  return 1;
}

static void sigint_handler(int, siginfo_t*, void*)
{
  stop = true;
}

int main(int ac, char** av)
{
  if (ac > 1)
    Config::filename = av[1];
  Config::file_must_exist = true;
  std::cerr << "Using configuration file: " << Config::filename << std::endl;

  std::string password;
  try { // The file must exist
    password = Config::get("password", "");
  }
  catch (const std::ios::failure& e) {
    return config_help("");
  }
  const std::string hostname = Config::get("hostname", "");
  if (password.empty())
    return config_help("password");
  if (hostname.empty())
    return config_help("hostname");
  std::shared_ptr<XmppComponent> xmpp_component =
    std::make_shared<XmppComponent>(hostname, password);

  Poller p;
  p.add_socket_handler(xmpp_component);
  if (!xmpp_component->start())
  {
    log_info("Exiting");
    return -1;
  }

  // Install the signals used to exit the process cleanly, or reload the
  // config
  sigset_t mask;
  sigemptyset(&mask);
  struct sigaction on_sig;
  on_sig.sa_sigaction = &sigint_handler;
  on_sig.sa_mask = mask;
  // we want to catch that signal only once.
  // Sending SIGINT again will "force" an exit
  on_sig.sa_flags = SA_RESETHAND;
  sigaction(SIGINT, &on_sig, nullptr);
  sigaction(SIGTERM, &on_sig, nullptr);

  const std::chrono::milliseconds timeout(-1);
  while (p.poll(timeout) != -1 || !exiting)
  {
    // Check for empty irc_clients (not connected, or with no joined
    // channel) and remove them
    xmpp_component->clean();
    if (stop)
    {
      log_info("Signal received, exiting...");
      exiting = true;
      stop = false;
      xmpp_component->shutdown();
    }
    // If the only existing connection is the one to the XMPP component:
    // close the XMPP stream.
    if (exiting && p.size() == 1 && xmpp_component->is_document_open())
      xmpp_component->close_document();
  }
  log_info("All connection cleanely closed, have a nice day.");
  return 0;
}