annotate irccdctl/main.cpp @ 514:16b9ebfd3f08

Irccd: get rid of fs.hpp, closes #594
author David Demelier <markand@malikania.fr>
date Tue, 24 Oct 2017 12:52:20 +0200
parents 928a40398dec
children e03521cf207b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * main.cpp -- irccd controller main
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
394
c6fbb6e0e06d Happy new year!
David Demelier <markand@malikania.fr>
parents: 387
diff changeset
4 * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr>
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
19 #include <unordered_map>
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
20
477
bf201d09ee6a Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents: 453
diff changeset
21 #include <boost/filesystem.hpp>
489
349fe29d86d5 Tests: switch to Boost, closes #680
David Demelier <markand@malikania.fr>
parents: 488
diff changeset
22 #include <boost/timer/timer.hpp>
477
bf201d09ee6a Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents: 453
diff changeset
23
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
24 #include "alias.hpp"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
25 #include "cli.hpp"
340
0f14931a76c1 Irccdctl: reenable
David Demelier <markand@malikania.fr>
parents: 256
diff changeset
26 #include "client.hpp"
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
27 #include "ini.hpp"
340
0f14931a76c1 Irccdctl: reenable
David Demelier <markand@malikania.fr>
parents: 256
diff changeset
28 #include "irccdctl.hpp"
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
29 #include "logger.hpp"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
30 #include "options.hpp"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
31 #include "system.hpp"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
32 #include "util.hpp"
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
34 using namespace std::string_literals;
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 using namespace irccd;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
37 namespace {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
38
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
39 std::vector<std::unique_ptr<Cli>> commands;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
40 std::unordered_map<std::string, Alias> aliases;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
41 std::unique_ptr<Client> client;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
42 std::unique_ptr<Irccdctl> irccdctl;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
43 net::Address address;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
44
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
45 void usage()
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
46 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
47 bool first = true;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
48
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
49 for (const auto &cmd : commands) {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
50 log::warning() << (first ? "usage: " : " ") << sys::program_name() << " "
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
51 << cmd->usage() << std::endl;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
52 first = false;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
53 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
54
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
55 std::exit(1);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
56 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
57
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
58 void help()
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
59 {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
60 log::warning() << "usage: " << sys::program_name() << " [options...] <command> [command-options...] [command-args...]\n\n";
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
61 log::warning() << "General options:\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
62 log::warning() << "\t-c, --config file\tspecify the configuration file\n";
357
c50769df3493 Irccdctl: improve help summary
David Demelier <markand@malikania.fr>
parents: 355
diff changeset
63 log::warning() << "\t --help\t\tshow this help\n";
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
64 log::warning() << "\t-t, --type type\t\tspecify connection type\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
65 log::warning() << "\t-v, --verbose\t\tbe verbose\n\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
66 log::warning() << "Available options for type ip and ipv6 (-t, --type):\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
67 log::warning() << "\t-h, --host address\tconnect to the specified address\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
68 log::warning() << "\t-p, --port port\t\tuse the specified port number\n\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
69 log::warning() << "Available options for type unix (-t, --type):\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
70 log::warning() << "\t-P, --path file\t\tconnect to the specified socket file\n\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
71 log::warning() << "Available commands:\n";
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
72
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
73 for (const auto &cmd : commands)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
74 log::warning() << "\t" << std::left << std::setw(32)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
75 << cmd->name() << cmd->summary() << std::endl;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
76
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
77 log::warning() << "\nFor more information on a command, type " << sys::program_name() << " help <command>" << std::endl;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
78 std::exit(1);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
79 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
80
352
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
81 void help(const std::string &command)
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
82 {
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
83 auto it = std::find_if(commands.begin(), commands.end(), [&] (const auto &c) {
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
84 return c->name() == command;
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
85 });
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
86
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
87 if (it == commands.end()) {
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
88 log::warning() << "no command named " << command << std::endl;
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
89 } else {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
90 log::warning() << "usage: " << sys::program_name() << " " << (*it)->usage() << "\n" << std::endl;
352
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
91 log::warning() << (*it)->help() << std::endl;
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
92 }
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
93
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
94 std::exit(1);
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
95 }
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
96
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
97 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
98 * Configuration file parsing.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
99 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
100 */
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
101
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
102 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
103 * readConnectIp
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
104 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
105 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
106 * Extract IP connection information from the config file.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
107 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
108 * [connect]
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
109 * type = "ip"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
110 * host = "ip or hostname"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
111 * port = "port number or service"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
112 * domain = "ipv4 or ipv6" (Optional, default: ipv4)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
113 * ssl = true | false
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
114 */
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
115 void readConnectIp(const ini::section &sc)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
116 {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
117 ini::section::const_iterator it;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
118 std::string host, port;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
119
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
120 if ((it = sc.find("host")) == sc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
121 throw std::invalid_argument("missing host parameter");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
122
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
123 host = it->value();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
124
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
125 if ((it = sc.find("port")) == sc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
126 throw std::invalid_argument("missing port parameter");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
127
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
128 port = it->value();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
129
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
130 int domain = AF_INET;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
131
428
ce1903f4bdb7 Fix #637: check for domain and family options
David Demelier <markand@malikania.fr>
parents: 394
diff changeset
132 if ((it = sc.find("domain")) != sc.end() || (it = sc.find("family")) != sc.end()) {
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
133 if (it->value() == "ipv6") {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
134 domain = AF_INET6;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
135 } else if (it->value() == "ipv4") {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
136 domain = AF_INET;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
137 } else {
428
ce1903f4bdb7 Fix #637: check for domain and family options
David Demelier <markand@malikania.fr>
parents: 394
diff changeset
138 throw std::invalid_argument("invalid family: " + it->value());
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
139 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
140 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
141
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
142 address = net::resolveOne(host, port, domain, SOCK_STREAM);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
143
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
144 if ((it = sc.find("ssl")) != sc.end() && util::is_boolean(it->value()))
513
928a40398dec CMake: split options and conditions, closes #716
David Demelier <markand@malikania.fr>
parents: 498
diff changeset
145 #if defined(HAVE_SSL)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
146 client = std::make_unique<TlsClient>();
387
94b18a90e8f7 Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents: 372
diff changeset
147 #else
94b18a90e8f7 Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents: 372
diff changeset
148 throw std::runtime_error("SSL disabled");
94b18a90e8f7 Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents: 372
diff changeset
149 #endif
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
150 else
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
151 client = std::make_unique<Client>();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
152 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
153
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
154 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
155 * readConnectLocal
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
156 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
157 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
158 * Extract local connection for Unix.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
159 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
160 * [connect]
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
161 * type = "unix"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
162 * path = "path to socket file"
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
163 */
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
164 void readConnectLocal(const ini::section &sc)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
165 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
166 #if !defined(IRCCD_SYSTEM_WINDOWS)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
167 auto it = sc.find("path");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
168
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
169 if (it == sc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
170 throw std::invalid_argument("missing path parameter");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
171
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
172 address = net::local::create(it->value());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
173 client = std::make_unique<Client>();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
174 #else
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
175 (void)sc;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
176
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
177 throw std::invalid_argument("unix connection not supported on Windows");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
178 #endif
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
179 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
180
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
181 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
182 * readConnect
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
183 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
184 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
185 * Generic function for reading the [connect] section.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
186 */
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
187 void readConnect(const ini::section &sc)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
188 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
189 auto it = sc.find("type");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
190
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
191 if (it == sc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
192 throw std::invalid_argument("missing type parameter");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
193
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
194 if (it->value() == "ip") {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
195 readConnectIp(sc);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
196 } else if (it->value() == "unix") {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
197 readConnectLocal(sc);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
198 } else {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
199 throw std::invalid_argument("invalid type given: " + it->value());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
200 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
201
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
202 auto password = sc.find("password");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
203
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
204 if (password != sc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
205 client->setPassword(password->value());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
206 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
207
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
208 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
209 * readGeneral
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
210 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
211 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
212 * Read the general section.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
213 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
214 * [general]
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
215 * verbose = true
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
216 */
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
217 void readGeneral(const ini::section &sc)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
218 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
219 auto verbose = sc.find("verbose");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
220
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
221 if (verbose != sc.end())
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
222 log::set_verbose(util::is_boolean(verbose->value()));
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
223 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
224
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
225 /*
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
226 * readAlias
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
227 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
228 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
229 * Read aliases for irccdctl.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
230 *
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
231 * [alias.<name>]
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
232 * cmd1 = ( "command", "arg1, "...", "argn" )
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
233 * cmd2 = ( "command", "arg1, "...", "argn" )
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
234 */
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
235 Alias readAlias(const ini::section &sc, const std::string &name)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
236 {
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
237 Alias alias(name);
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
238
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
239 /*
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
240 * Each defined option is a command that the user can call. The name is
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
241 * unused and serves as documentation purpose.
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
242 */
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
243 for (const auto &option : sc) {
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
244 /*
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
245 * Iterate over the arguments which are usually a list and the first
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
246 * argument is a command name.
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
247 */
494
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
248 if (option.size() == 1 && option[0].empty())
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
249 throw std::runtime_error(util::sprintf("alias %s: missing command name in '%s'", name, option.key()));
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
250
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
251 std::string command = option[0];
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
252 std::vector<AliasArg> args(option.begin() + 1, option.end());
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
253
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
254 alias.emplace_back(std::move(command), std::move(args));
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
255 }
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
256
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
257 return alias;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
258 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
259
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
260 void read(const std::string &path)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 {
207
6635b9187d71 Irccd: switch to 4 spaces indent, #518
David Demelier <markand@malikania.fr>
parents: 95
diff changeset
262 try {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
263 ini::document doc = ini::read_file(path);
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
264 ini::document::const_iterator it;
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
266 if (!client && (it = doc.find("connect")) != doc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
267 readConnect(*it);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
268 if ((it = doc.find("general")) != doc.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
269 readGeneral(*it);
372
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
270
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
271 // [alias.*] sections.
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
272 for (const auto& sc : doc) {
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
273 if (sc.key().compare(0, 6, "alias.") == 0) {
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
274 auto name = sc.key().substr(6);
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
275 auto alias = readAlias(sc, name);
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
276
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
277 aliases.emplace(std::move(name), std::move(alias));
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
278 }
6a7850696b86 Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents: 359
diff changeset
279 }
207
6635b9187d71 Irccd: switch to 4 spaces indent, #518
David Demelier <markand@malikania.fr>
parents: 95
diff changeset
280 } catch (const std::exception &ex) {
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
281 log::warning() << path << ": " << ex.what() << std::endl;
207
6635b9187d71 Irccd: switch to 4 spaces indent, #518
David Demelier <markand@malikania.fr>
parents: 95
diff changeset
282 }
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 }
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
284
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
285 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
286 * Command line parsing.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
287 * -------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
288 */
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
289
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
290 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
291 * parseConnectIp
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
292 * ------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
293 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
294 * Parse internet connection from command line.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
295 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
296 * -t ip | ipv6
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
297 * -h host or ip
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
298 * -p port
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
299 */
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
300 void parseConnectIp(const option::result &options)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
301 {
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
302 option::result::const_iterator it;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
303
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
304 // Host (-h or --host).
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
305 std::string host;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
306
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
307 if ((it = options.find("-h")) == options.end() && (it = options.find("--host")) == options.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
308 throw std::invalid_argument("missing host argument (-h or --host)");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
309 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
310
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
311 host = it->second;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
312
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
313 // Port (-p or --port).
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
314 std::string port;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
315
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
316 if ((it = options.find("-p")) == options.end() && (it = options.find("--port")) == options.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
317 throw std::invalid_argument("missing port argument (-p or --port)");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
318 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
319
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
320 port = it->second;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
321
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
322 // Domain
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
323 int domain = AF_INET;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
324
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
325 if ((it = options.find("-t")) != options.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
326 domain = it->second == "ipv6" ? AF_INET6 : AF_INET;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
327 } else if ((it = options.find("--type")) != options.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
328 domain = it->second == "ipv6" ? AF_INET6: AF_INET;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
329 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
330
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
331 address = net::resolveOne(host, port, domain, SOCK_STREAM);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
332 client = std::make_unique<Client>();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
333 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
334
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
335 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
336 * parseConnectLocal
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
337 * ------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
338 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
339 * Parse local connection.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
340 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
341 * -P file
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
342 */
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
343 void parseConnectLocal(const option::result &options)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
344 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
345 #if !defined(IRCCD_SYSTEM_WINDOWS)
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
346 option::result::const_iterator it;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
347
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
348 if ((it = options.find("-P")) == options.end() && (it = options.find("--path")) == options.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
349 throw std::invalid_argument("missing path parameter (-P or --path)");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
350
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
351 address = net::local::create(it->second, false);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
352 client = std::make_unique<Client>();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
353 #else
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
354 (void)options;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
355
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
356 throw std::invalid_argument("unix connection not supported on Windows");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
357 #endif
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
358 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
359
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
360 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
361 * parseConnect
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
362 * ------------------------------------------------------------------
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
363 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
364 * Generic parsing of command line option for connection.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
365 */
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
366 void parseConnect(const option::result &options)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
367 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
368 assert(options.count("-t") > 0 || options.count("--type") > 0);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
369
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
370 auto it = options.find("-t");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
371
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
372 if (it == options.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
373 it = options.find("--type");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
374 if (it->second == "ip" || it->second == "ipv6")
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
375 return parseConnectIp(options);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
376 if (it->second == "unix")
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
377 return parseConnectLocal(options);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
378
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
379 throw std::invalid_argument("invalid type given: " + it->second);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
380 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
381
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
382 option::result parse(int &argc, char **&argv)
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
383 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
384 // 1. Parse command line options.
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
385 option::options def{
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
386 { "-c", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
387 { "--config", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
388 { "-h", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
389 { "--help", false },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
390 { "--host", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
391 { "-p", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
392 { "--port", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
393 { "-P", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
394 { "--path", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
395 { "-t", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
396 { "--type", true },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
397 { "-v", false },
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
398 { "--verbose", false }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
399 };
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
400
498
fbd80bfcf58d Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents: 494
diff changeset
401 option::result result;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
402
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
403 try {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
404 result = option::read(argc, argv, def);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
405
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
406 if (result.count("--help") != 0) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
407 usage();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
408 // NOTREACHED
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
409 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
410
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
411 if (result.count("-v") != 0 || result.count("--verbose") != 0) {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
412 log::set_verbose(true);
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
413 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
414 } catch (const std::exception &ex) {
494
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
415 log::warning() << "irccdctl: " << ex.what() << std::endl;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
416 usage();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
417 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
418
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
419 return result;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
420 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
421
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
422 void exec(std::vector<std::string>);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
423
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
424 void exec(const Alias &alias, std::vector<std::string> argsCopy)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
425 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
426 std::vector<nlohmann::json> values;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
427
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
428 for (const AliasCommand &cmd : alias) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
429 std::vector<std::string> args(argsCopy);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
430 std::vector<std::string> cmdArgs;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
431 std::vector<std::string>::size_type toremove = 0;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
432
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
433 // 1. Append command name before.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
434 cmdArgs.push_back(cmd.command());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
435
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
436 for (const auto &arg : cmd.args()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
437 if (arg.isPlaceholder()) {
494
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
438 if (args.size() < arg.index() + 1)
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
439 throw std::invalid_argument(util::sprintf("missing argument for placeholder %d", arg.index()));
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
440
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
441 cmdArgs.push_back(args[arg.index()]);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
442
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
443 if (arg.index() + 1 > toremove) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
444 toremove = arg.index() + 1;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
445 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
446 } else {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
447 cmdArgs.push_back(arg.value());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
448 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
449 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
450
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
451 assert(toremove <= args.size());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
452
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
453 // 2. Remove the arguments that been placed in placeholders.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
454 args.erase(args.begin(), args.begin() + toremove);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
455
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
456 // 3. Now append the rest of arguments.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
457 std::copy(args.begin(), args.end(), std::back_inserter(cmdArgs));
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
458
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
459 // 4. Finally try to execute.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
460 exec(cmdArgs);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
461 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
462 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
463
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
464 void exec(std::vector<std::string> args)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
465 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
466 assert(args.size() > 0);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
467
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
468 auto name = args[0];
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
469 auto alias = aliases.find(name);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
470
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
471 // Remove name.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
472 args.erase(args.begin());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
473
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
474 if (alias != aliases.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
475 exec(alias->second, args);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
476 } else {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
477 auto cmd = std::find_if(commands.begin(), commands.end(), [&] (auto &it) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
478 return it->name() == name;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
479 });
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
480
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
481 if (cmd != commands.end()) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
482 (*cmd)->exec(*irccdctl, args);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
483 } else {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
484 throw std::invalid_argument("no alias or command named " + name);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
485 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
486 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
487 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
488
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
489 void init(int &argc, char **&argv)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
490 {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
491 sys::set_program_name("irccdctl");
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
492 net::init();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
493
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
494 --argc;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
495 ++argv;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
496
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
497 commands.push_back(std::make_unique<cli::PluginConfigCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
498 commands.push_back(std::make_unique<cli::PluginInfoCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
499 commands.push_back(std::make_unique<cli::PluginListCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
500 commands.push_back(std::make_unique<cli::PluginLoadCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
501 commands.push_back(std::make_unique<cli::PluginReloadCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
502 commands.push_back(std::make_unique<cli::PluginUnloadCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
503 commands.push_back(std::make_unique<cli::ServerChannelMode>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
504 commands.push_back(std::make_unique<cli::ServerChannelNoticeCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
505 commands.push_back(std::make_unique<cli::ServerConnectCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
506 commands.push_back(std::make_unique<cli::ServerDisconnectCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
507 commands.push_back(std::make_unique<cli::ServerInfoCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
508 commands.push_back(std::make_unique<cli::ServerInviteCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
509 commands.push_back(std::make_unique<cli::ServerJoinCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
510 commands.push_back(std::make_unique<cli::ServerKickCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
511 commands.push_back(std::make_unique<cli::ServerListCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
512 commands.push_back(std::make_unique<cli::ServerMeCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
513 commands.push_back(std::make_unique<cli::ServerMessageCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
514 commands.push_back(std::make_unique<cli::ServerModeCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
515 commands.push_back(std::make_unique<cli::ServerNickCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
516 commands.push_back(std::make_unique<cli::ServerNoticeCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
517 commands.push_back(std::make_unique<cli::ServerPartCli>());
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
518 commands.push_back(std::make_unique<cli::ServerReconnectCli>());
355
ace71e2b8e2a Irccd: add server-topic support again
David Demelier <markand@malikania.fr>
parents: 354
diff changeset
519 commands.push_back(std::make_unique<cli::ServerTopicCli>());
452
2170aa0e38aa Irccdctl: implement rule-add
David Demelier <markand@malikania.fr>
parents: 451
diff changeset
520 commands.push_back(std::make_unique<cli::RuleAddCli>());
453
acb2d4990249 Irccdctl: implement rule-edit
David Demelier <markand@malikania.fr>
parents: 452
diff changeset
521 commands.push_back(std::make_unique<cli::RuleEditCli>());
448
9be4f8a5cf1a Irccdctl: implement rule-list
David Demelier <markand@malikania.fr>
parents: 428
diff changeset
522 commands.push_back(std::make_unique<cli::RuleListCli>());
449
9968eac538e6 Irccdctl: implement rule-info
David Demelier <markand@malikania.fr>
parents: 448
diff changeset
523 commands.push_back(std::make_unique<cli::RuleInfoCli>());
451
1fdedd2977d2 Irccdctl: implement rule-move
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
524 commands.push_back(std::make_unique<cli::RuleMoveCli>());
450
c8c68d4bf555 Irccdctl: implement rule-remove
David Demelier <markand@malikania.fr>
parents: 449
diff changeset
525 commands.push_back(std::make_unique<cli::RuleRemoveCli>());
359
6d598fea2689 Irccdctl: put back watch missing, closes #591
David Demelier <markand@malikania.fr>
parents: 357
diff changeset
526 commands.push_back(std::make_unique<cli::WatchCli>());
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
527 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
528
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
529 } // !namespace
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
530
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
531 int main(int argc, char **argv)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
532 {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
533 init(argc, argv);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
534
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
535 // 1. Read command line arguments.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
536 auto result = parse(argc, argv);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
537
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
538 /*
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
539 * 2. Open optional config by command line or by searching it
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
540 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
541 * The connection to irccd is searched in the following order :
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
542 *
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
543 * 1. From the command line if specified
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
544 * 2. From the configuration file specified by -c
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
545 * 3. From the configuration file searched through directories
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
546 */
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
547 try {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
548 if (result.count("-t") > 0 || result.count("--type") > 0)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
549 parseConnect(result);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
550
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
551 auto it = result.find("-c");
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
552
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
553 if (it != result.end() || (it = result.find("--config")) != result.end())
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
554 read(it->second);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
555 else {
486
0b156b82b8c1 Irccd: rework of paths, closes #611
David Demelier <markand@malikania.fr>
parents: 477
diff changeset
556 for (const auto& path : sys::config_filenames("irccdctl.conf")) {
477
bf201d09ee6a Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents: 453
diff changeset
557 boost::system::error_code ec;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
558
477
bf201d09ee6a Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents: 453
diff changeset
559 if (boost::filesystem::exists(path, ec) && !ec) {
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
560 read(path);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
561 break;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
562 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
563 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
564 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
565 } catch (const std::exception &ex) {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
566 log::warning() << sys::program_name() << ": " << ex.what() << std::endl;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
567 std::exit(1);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
568 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
569
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
570 if (argc <= 0) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
571 usage();
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
572 // NOTREACHED
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
573 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
574 if (std::strcmp(argv[0], "help") == 0) {
352
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
575 if (argc >= 2)
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
576 help(argv[1]);
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
577 else
aab46e17cb27 Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents: 348
diff changeset
578 help();
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
579 // NOTREACHED
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
580 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
581
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
582 if (!client) {
494
9fcdd3c9cd33 Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents: 489
diff changeset
583 log::warning("irccdctl: no connection specified");
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
584 std::exit(1);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
585 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
586
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
587 irccdctl = std::make_unique<Irccdctl>(std::move(client));
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
588 irccdctl->client().onDisconnect.connect([&] (auto reason) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
589 log::warning() << "connection lost to irccd: " << reason << std::endl;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
590 });
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
591 irccdctl->client().onConnect.connect([&] (auto info) {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
592 log::info() << "connected to irccd "
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
593 << info.major << "."
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
594 << info.minor << "."
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
595 << info.patch << std::endl;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
596 });
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
597 irccdctl->client().connect(address);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
598
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
599 // Build a vector of arguments.
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
600 std::vector<std::string> args;
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
601
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
602 for (int i = 0; i < argc; ++i)
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
603 args.push_back(argv[i]);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
604
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
605 try {
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
606 exec(args);
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
607 } catch (const std::exception &ex) {
488
7e273b7f4f92 Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents: 486
diff changeset
608 std::cerr << sys::program_name() << ": unrecoverable error: " << ex.what() << std::endl;
348
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
609 }
24b1709093e7 Irccdctl: resurrect
David Demelier <markand@malikania.fr>
parents: 346
diff changeset
610 }