Mercurial > irccd
annotate irccdctl/main.cpp @ 698:ad1ee47165fa
Irccd: create own json_util::document class
For convenience when parsing command arguments, use directly json_util::document
instead of raw nlohmann::json object. This will simplify the process of
decomposing unsafe structures.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 07 May 2018 21:10:12 +0200 |
parents | db9acd7993cd |
children | 91bc29e87399 |
rev | line source |
---|---|
0 | 1 /* |
2 * main.cpp -- irccd controller main | |
3 * | |
628
27587ff92a64
Misc: update copyrights
David Demelier <markand@malikania.fr>
parents:
616
diff
changeset
|
4 * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> |
0 | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
19 #include <irccd/sysconfig.hpp> |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
20 |
693
db9acd7993cd
Misc: many fixes for GCC 8
David Demelier <markand@malikania.fr>
parents:
683
diff
changeset
|
21 #include <iostream> |
348 | 22 #include <unordered_map> |
23 | |
477
bf201d09ee6a
Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents:
453
diff
changeset
|
24 #include <boost/filesystem.hpp> |
bf201d09ee6a
Irccd: use boost::filesystem (fs::exists), #594
David Demelier <markand@malikania.fr>
parents:
453
diff
changeset
|
25 |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
26 #include <irccd/config.hpp> |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
27 #include <irccd/json_util.hpp> |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
28 #include <irccd/options.hpp> |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
29 #include <irccd/socket_connector.hpp> |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
30 #include <irccd/string_util.hpp> |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
31 #include <irccd/system.hpp> |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
32 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
33 #if defined(HAVE_SSL) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
34 # include <irccd/tls_connector.hpp> |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
35 #endif |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
36 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
37 #include <irccd/daemon/transport_server.hpp> |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
38 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
39 #include <irccd/ctl/controller.hpp> |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
40 |
528
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
41 #include "plugin_config_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
42 #include "plugin_info_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
43 #include "plugin_list_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
44 #include "plugin_load_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
45 #include "plugin_reload_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
46 #include "plugin_unload_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
47 #include "rule_add_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
48 #include "rule_edit_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
49 #include "rule_info_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
50 #include "rule_list_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
51 #include "rule_move_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
52 #include "rule_remove_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
53 #include "server_connect_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
54 #include "server_disconnect_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
55 #include "server_info_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
56 #include "server_invite_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
57 #include "server_join_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
58 #include "server_kick_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
59 #include "server_list_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
60 #include "server_me_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
61 #include "server_message_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
62 #include "server_mode_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
63 #include "server_nick_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
64 #include "server_notice_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
65 #include "server_part_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
66 #include "server_reconnect_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
67 #include "server_topic_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
68 #include "watch_cli.hpp" |
9daccaeedcce
Irccdctl: split cli.hpp, closes #726
David Demelier <markand@malikania.fr>
parents:
527
diff
changeset
|
69 |
348 | 70 #include "alias.hpp" |
71 #include "cli.hpp" | |
0 | 72 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
73 using boost::asio::ip::tcp; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
74 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
75 #if !defined(IRCCD_SYSTEM_WINDOWS) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
76 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
77 using boost::asio::local::stream_protocol; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
78 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
79 #endif |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
80 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
81 namespace irccd { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
82 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
83 namespace ctl { |
0 | 84 |
348 | 85 namespace { |
86 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
87 // Main service; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
88 boost::asio::io_service service; |
348 | 89 |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
90 // Global options. |
641
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
91 bool verbose = false; |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
92 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
93 // Connection to instance. |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
94 std::unique_ptr<controller> ctl; |
352
aab46e17cb27
Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents:
348
diff
changeset
|
95 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
96 // List of all commands and alias. |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
97 std::unordered_map<std::string, alias> aliases; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
98 std::unordered_map<std::string, std::unique_ptr<cli>> commands; |
352
aab46e17cb27
Irccdctl: show help usage about command
David Demelier <markand@malikania.fr>
parents:
348
diff
changeset
|
99 |
348 | 100 /* |
101 * Configuration file parsing. | |
102 * ------------------------------------------------------------------- | |
103 */ | |
104 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
105 void usage() |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
106 { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
107 std::exit(1); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
108 } |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
109 |
348 | 110 /* |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
111 * resolve |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
112 * ------------------------------------------------------------------ |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
113 * |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
114 * Block unless host/port has been resolved. |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
115 */ |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
116 std::vector<tcp::endpoint> resolve(const std::string& host, const std::string& name) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
117 { |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
118 std::vector<tcp::endpoint> endpoints; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
119 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
120 tcp::resolver resolver(service); |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
121 tcp::resolver::query query(host, name); |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
122 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
123 for (auto it = resolver.resolve(query); it != tcp::resolver::iterator(); ++it) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
124 endpoints.push_back(*it); |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
125 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
126 return endpoints; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
127 } |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
128 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
129 /* |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
130 * read_connect_ip |
348 | 131 * ------------------------------------------------------------------- |
132 * | |
133 * Extract IP connection information from the config file. | |
134 * | |
135 * [connect] | |
136 * type = "ip" | |
137 * host = "ip or hostname" | |
138 * port = "port number or service" | |
139 * domain = "ipv4 or ipv6" (Optional, default: ipv4) | |
140 * ssl = true | false | |
141 */ | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
142 std::unique_ptr<io::connector> read_connect_ip(const ini::section& sc) |
348 | 143 { |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
144 const auto host = sc.get("host").value(); |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
145 const auto port = sc.get("port").value(); |
348 | 146 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
147 if (host.empty()) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
148 throw transport_error(transport_error::invalid_hostname); |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
149 if (port.empty()) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
150 throw transport_error(transport_error::invalid_port); |
348 | 151 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
152 const auto endpoints = resolve(host, port); |
644
aae6d5a2b28d
Irccd: change how configuration is loaded
David Demelier <markand@malikania.fr>
parents:
641
diff
changeset
|
153 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
154 if (string_util::is_boolean(sc.get("ssl").value())) { |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
155 #if defined(HAVE_SSL) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
156 // TODO: support more parameters. |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
157 boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); |
348 | 158 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
159 return std::make_unique<io::tls_connector<>>(std::move(ctx), service, endpoints); |
387
94b18a90e8f7
Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents:
372
diff
changeset
|
160 #else |
94b18a90e8f7
Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents:
372
diff
changeset
|
161 throw std::runtime_error("SSL disabled"); |
94b18a90e8f7
Misc: fix build without SSL
David Demelier <markand@malikania.fr>
parents:
372
diff
changeset
|
162 #endif |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
163 } |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
164 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
165 return std::make_unique<io::ip_connector>(service, endpoints); |
348 | 166 } |
167 | |
168 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
169 * read_connect_local |
348 | 170 * ------------------------------------------------------------------- |
171 * | |
172 * Extract local connection for Unix. | |
173 * | |
174 * [connect] | |
175 * type = "unix" | |
176 * path = "path to socket file" | |
177 */ | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
178 std::unique_ptr<io::connector> read_connect_local(const ini::section& sc) |
348 | 179 { |
180 #if !defined(IRCCD_SYSTEM_WINDOWS) | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
181 using boost::asio::local::stream_protocol; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
182 |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
183 const auto it = sc.find("path"); |
348 | 184 |
185 if (it == sc.end()) | |
186 throw std::invalid_argument("missing path parameter"); | |
187 | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
188 return std::make_unique<io::local_connector>(service, it->value()); |
348 | 189 #else |
190 (void)sc; | |
191 | |
192 throw std::invalid_argument("unix connection not supported on Windows"); | |
193 #endif | |
194 } | |
195 | |
196 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
197 * read_connect |
348 | 198 * ------------------------------------------------------------------- |
199 * | |
200 * Generic function for reading the [connect] section. | |
201 */ | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
202 void read_connect(const ini::section& sc) |
348 | 203 { |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
204 const auto it = sc.find("type"); |
348 | 205 |
206 if (it == sc.end()) | |
207 throw std::invalid_argument("missing type parameter"); | |
208 | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
209 std::unique_ptr<io::connector> connector; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
210 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
211 if (it->value() == "ip") |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
212 connector = read_connect_ip(sc); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
213 else if (it->value() == "unix") |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
214 connector = read_connect_local(sc); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
215 else |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
216 throw std::invalid_argument(string_util::sprintf("invalid type given: %s", it->value())); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
217 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
218 if (connector) { |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
219 ctl = std::make_unique<controller>(std::move(connector)); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
220 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
221 auto password = sc.find("password"); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
222 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
223 if (password != sc.end()) |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
224 ctl->set_password(password->value()); |
348 | 225 } |
226 } | |
227 | |
228 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
229 * read_general |
348 | 230 * ------------------------------------------------------------------- |
231 * | |
232 * Read the general section. | |
233 * | |
234 * [general] | |
235 * verbose = true | |
236 */ | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
237 void read_general(const ini::section& sc) |
348 | 238 { |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
239 const auto value = sc.find("verbose"); |
348 | 240 |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
241 if (value != sc.end()) |
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
242 verbose = string_util::is_boolean(value->value()); |
348 | 243 } |
244 | |
245 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
246 * read_alias |
348 | 247 * ------------------------------------------------------------------- |
248 * | |
249 * Read aliases for irccdctl. | |
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 * [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
|
252 * 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
|
253 * cmd2 = ( "command", "arg1, "...", "argn" ) |
348 | 254 */ |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
255 alias read_alias(const ini::section& sc, const std::string& name) |
348 | 256 { |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
257 alias alias(name); |
348 | 258 |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
259 /* |
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
260 * 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
|
261 * 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
|
262 */ |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
263 for (const auto& option : sc) { |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
264 /* |
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
265 * 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
|
266 * 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
|
267 */ |
494
9fcdd3c9cd33
Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents:
489
diff
changeset
|
268 if (option.size() == 1 && option[0].empty()) |
584 | 269 throw std::runtime_error(string_util::sprintf("alias %s: missing command name in '%s'", |
270 name, option.key())); | |
348 | 271 |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
272 std::string command = option[0]; |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
273 std::vector<alias_arg> args(option.begin() + 1, option.end()); |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
274 |
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
275 alias.emplace_back(std::move(command), std::move(args)); |
348 | 276 } |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
277 |
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
278 return alias; |
348 | 279 } |
280 | |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
281 void read(const config& cfg) |
0 | 282 { |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
283 ini::document::const_iterator it; |
0 | 284 |
652
e37ac2269ba6
Irccd: style (config) #782
David Demelier <markand@malikania.fr>
parents:
649
diff
changeset
|
285 if (!ctl && (it = cfg.find("connect")) != cfg.end()) |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
286 read_connect(*it); |
652
e37ac2269ba6
Irccd: style (config) #782
David Demelier <markand@malikania.fr>
parents:
649
diff
changeset
|
287 if ((it = cfg.find("general")) != cfg.end()) |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
288 read_general(*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
|
289 |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
290 // [alias.*] sections. |
652
e37ac2269ba6
Irccd: style (config) #782
David Demelier <markand@malikania.fr>
parents:
649
diff
changeset
|
291 for (const auto& sc : cfg) { |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
292 if (sc.key().compare(0, 6, "alias.") == 0) { |
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
293 auto name = sc.key().substr(6); |
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
294 auto alias = read_alias(sc, name); |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
295 |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
296 aliases.emplace(std::move(name), std::move(alias)); |
372
6a7850696b86
Irccdctl: rework a bit how aliases are defined to allow better arguments parsing
David Demelier <markand@malikania.fr>
parents:
359
diff
changeset
|
297 } |
207
6635b9187d71
Irccd: switch to 4 spaces indent, #518
David Demelier <markand@malikania.fr>
parents:
95
diff
changeset
|
298 } |
0 | 299 } |
348 | 300 |
301 /* | |
302 * Command line parsing. | |
303 * ------------------------------------------------------------------- | |
304 */ | |
305 | |
306 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
307 * parse_connect_ip |
348 | 308 * ------------------------------------------------------------------ |
309 * | |
310 * Parse internet connection from command line. | |
311 * | |
312 * -t ip | ipv6 | |
313 * -h host or ip | |
314 * -p port | |
315 */ | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
316 std::unique_ptr<io::connector> parse_connect_ip(const option::result& options) |
348 | 317 { |
498
fbd80bfcf58d
Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents:
494
diff
changeset
|
318 option::result::const_iterator it; |
348 | 319 |
320 // Host (-h or --host). | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
321 if ((it = options.find("-h")) == options.end() && (it = options.find("--host")) == options.end()) |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
322 throw transport_error(transport_error::invalid_hostname); |
348 | 323 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
324 const auto host = it->second; |
348 | 325 |
326 // Port (-p or --port). | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
327 if ((it = options.find("-p")) == options.end() && (it = options.find("--port")) == options.end()) |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
328 throw transport_error(transport_error::invalid_port); |
348 | 329 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
330 const auto port = it->second; |
644
aae6d5a2b28d
Irccd: change how configuration is loaded
David Demelier <markand@malikania.fr>
parents:
641
diff
changeset
|
331 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
332 return std::make_unique<io::ip_connector>(service, resolve(host, port)); |
348 | 333 } |
334 | |
335 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
336 * parse_connect_local |
348 | 337 * ------------------------------------------------------------------ |
338 * | |
339 * Parse local connection. | |
340 * | |
341 * -P file | |
342 */ | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
343 std::unique_ptr<io::connector> parse_connect_local(const option::result& options) |
348 | 344 { |
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 | 347 |
348 if ((it = options.find("-P")) == options.end() && (it = options.find("--path")) == options.end()) | |
349 throw std::invalid_argument("missing path parameter (-P or --path)"); | |
350 | |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
351 return std::make_unique<io::local_connector>(service, it->second); |
348 | 352 #else |
353 (void)options; | |
354 | |
355 throw std::invalid_argument("unix connection not supported on Windows"); | |
356 #endif | |
357 } | |
358 | |
359 /* | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
360 * parse_connect |
348 | 361 * ------------------------------------------------------------------ |
362 * | |
363 * Generic parsing of command line option for connection. | |
364 */ | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
365 void parse_connect(const option::result& options) |
348 | 366 { |
367 assert(options.count("-t") > 0 || options.count("--type") > 0); | |
368 | |
369 auto it = options.find("-t"); | |
370 | |
371 if (it == options.end()) | |
372 it = options.find("--type"); | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
373 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
374 std::unique_ptr<io::connector> connector; |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
375 |
348 | 376 if (it->second == "ip" || it->second == "ipv6") |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
377 connector = parse_connect_ip(options); |
348 | 378 if (it->second == "unix") |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
379 connector = parse_connect_local(options); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
380 else |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
381 throw std::invalid_argument(string_util::sprintf("invalid type given: %s", it->second)); |
348 | 382 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
383 if (connector) |
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
384 ctl = std::make_unique<controller>(std::move(connector)); |
348 | 385 } |
386 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
387 option::result parse(int& argc, char**& argv) |
348 | 388 { |
389 // 1. Parse command line options. | |
498
fbd80bfcf58d
Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents:
494
diff
changeset
|
390 option::options def{ |
348 | 391 { "-c", true }, |
392 { "--config", true }, | |
393 { "-h", true }, | |
394 { "--help", false }, | |
395 { "--host", true }, | |
396 { "-p", true }, | |
397 { "--port", true }, | |
398 { "-P", true }, | |
399 { "--path", true }, | |
400 { "-t", true }, | |
401 { "--type", true }, | |
402 { "-v", false }, | |
403 { "--verbose", false } | |
404 }; | |
405 | |
498
fbd80bfcf58d
Irccd: import new options, closes #713
David Demelier <markand@malikania.fr>
parents:
494
diff
changeset
|
406 option::result result; |
348 | 407 |
408 try { | |
409 result = option::read(argc, argv, def); | |
410 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
411 if (result.count("--help") > 0 || result.count("-h") > 0) |
348 | 412 usage(); |
413 // NOTREACHED | |
414 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
415 if (result.count("-v") != 0 || result.count("--verbose") != 0) |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
416 verbose = true; |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
417 } catch (const std::exception& ex) { |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
418 std::cerr << "irccdctl: " << ex.what() << std::endl; |
348 | 419 usage(); |
420 } | |
421 | |
422 return result; | |
423 } | |
424 | |
425 void exec(std::vector<std::string>); | |
426 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
427 void exec(const alias& alias, std::vector<std::string> args_copy) |
348 | 428 { |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
429 for (const auto& cmd : alias) { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
430 std::vector<std::string> args(args_copy); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
431 std::vector<std::string> cmd_args; |
348 | 432 std::vector<std::string>::size_type toremove = 0; |
433 | |
434 // 1. Append command name before. | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
435 cmd_args.push_back(cmd.command()); |
348 | 436 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
437 for (const auto& arg : cmd.args()) { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
438 if (arg.is_placeholder()) { |
494
9fcdd3c9cd33
Irccd: switch to Boost.Format, closes #577
David Demelier <markand@malikania.fr>
parents:
489
diff
changeset
|
439 if (args.size() < arg.index() + 1) |
584 | 440 throw std::invalid_argument( |
441 string_util::sprintf("missing argument for placeholder %d", arg.index())); | |
348 | 442 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
443 cmd_args.push_back(args[arg.index()]); |
348 | 444 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
445 if (arg.index() + 1 > toremove) |
348 | 446 toremove = arg.index() + 1; |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
447 } else |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
448 cmd_args.push_back(arg.value()); |
348 | 449 } |
450 | |
451 assert(toremove <= args.size()); | |
452 | |
453 // 2. Remove the arguments that been placed in placeholders. | |
454 args.erase(args.begin(), args.begin() + toremove); | |
455 | |
456 // 3. Now append the rest of arguments. | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
457 std::copy(args.begin(), args.end(), std::back_inserter(cmd_args)); |
348 | 458 |
459 // 4. Finally try to execute. | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
460 exec(cmd_args); |
348 | 461 } |
462 } | |
463 | |
464 void exec(std::vector<std::string> args) | |
465 { | |
466 assert(args.size() > 0); | |
467 | |
468 auto name = args[0]; | |
469 auto alias = aliases.find(name); | |
470 | |
471 // Remove name. | |
472 args.erase(args.begin()); | |
473 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
474 if (alias != aliases.end()) |
348 | 475 exec(alias->second, args); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
476 else { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
477 auto cmd = commands.find(name); |
348 | 478 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
479 if (cmd != commands.end()) |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
480 cmd->second->exec(*ctl, args); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
481 else |
348 | 482 throw std::invalid_argument("no alias or command named " + name); |
483 } | |
484 } | |
485 | |
486 void init(int &argc, char **&argv) | |
487 { | |
488
7e273b7f4f92
Irccd: new coding style, closes #576
David Demelier <markand@malikania.fr>
parents:
486
diff
changeset
|
488 sys::set_program_name("irccdctl"); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
489 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
490 -- argc; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
491 ++ argv; |
348 | 492 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
493 auto add = [] (auto c) { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
494 commands.emplace(c->name(), std::move(c)); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
495 }; |
348 | 496 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
497 add(std::make_unique<plugin_config_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
498 add(std::make_unique<plugin_info_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
499 add(std::make_unique<plugin_list_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
500 add(std::make_unique<plugin_load_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
501 add(std::make_unique<plugin_reload_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
502 add(std::make_unique<plugin_unload_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
503 add(std::make_unique<server_connect_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
504 add(std::make_unique<server_disconnect_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
505 add(std::make_unique<server_info_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
506 add(std::make_unique<server_invite_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
507 add(std::make_unique<server_join_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
508 add(std::make_unique<server_kick_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
509 add(std::make_unique<server_list_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
510 add(std::make_unique<server_me_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
511 add(std::make_unique<server_message_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
512 add(std::make_unique<server_mode_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
513 add(std::make_unique<server_nick_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
514 add(std::make_unique<server_notice_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
515 add(std::make_unique<server_part_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
516 add(std::make_unique<server_reconnect_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
517 add(std::make_unique<server_topic_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
518 add(std::make_unique<rule_add_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
519 add(std::make_unique<rule_edit_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
520 add(std::make_unique<rule_list_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
521 add(std::make_unique<rule_info_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
522 add(std::make_unique<rule_move_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
523 add(std::make_unique<rule_remove_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
524 add(std::make_unique<watch_cli>()); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
525 } |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
526 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
527 void do_connect() |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
528 { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
529 ctl->connect([&] (auto code, auto info) { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
530 if (code) |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
531 throw std::system_error(code); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
532 |
641
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
533 if (verbose) { |
698
ad1ee47165fa
Irccd: create own json_util::document class
David Demelier <markand@malikania.fr>
parents:
693
diff
changeset
|
534 const json_util::document doc(info); |
ad1ee47165fa
Irccd: create own json_util::document class
David Demelier <markand@malikania.fr>
parents:
693
diff
changeset
|
535 const auto major = doc.get<int>("/major"); |
ad1ee47165fa
Irccd: create own json_util::document class
David Demelier <markand@malikania.fr>
parents:
693
diff
changeset
|
536 const auto minor = doc.get<int>("/minor"); |
ad1ee47165fa
Irccd: create own json_util::document class
David Demelier <markand@malikania.fr>
parents:
693
diff
changeset
|
537 const auto patch = doc.get<int>("/patch"); |
641
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
538 |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
539 if (!major || !minor || !patch) |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
540 std::cout << "connected to irccd (unknown version)" << std::endl; |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
541 else |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
542 std::cout << string_util::sprintf("connected to irccd %d.%d.%d\n", |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
543 *major, *minor, *patch); |
7e2d0739f37c
Irccd: import json_util from code
David Demelier <markand@malikania.fr>
parents:
628
diff
changeset
|
544 } |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
545 }); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
546 |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
547 service.run(); |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
548 service.reset(); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
549 } |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
550 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
551 void do_exec(int argc, char** argv) |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
552 { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
553 std::vector<std::string> args; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
554 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
555 for (int i = 0; i < argc; ++i) |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
556 args.push_back(argv[i]); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
557 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
558 exec(args); |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
559 service.run(); |
348 | 560 } |
561 | |
562 } // !namespace | |
563 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
564 } // !ctl |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
565 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
566 } // !irccd |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
567 |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
568 int main(int argc, char** argv) |
348 | 569 { |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
570 irccd::ctl::init(argc, argv); |
348 | 571 |
572 // 1. Read command line arguments. | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
573 auto result = irccd::ctl::parse(argc, argv); |
348 | 574 |
575 /* | |
576 * 2. Open optional config by command line or by searching it | |
577 * | |
578 * The connection to irccd is searched in the following order : | |
579 * | |
580 * 1. From the command line if specified | |
581 * 2. From the configuration file specified by -c | |
582 * 3. From the configuration file searched through directories | |
583 */ | |
584 try { | |
585 if (result.count("-t") > 0 || result.count("--type") > 0) | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
586 irccd::ctl::parse_connect(result); |
348 | 587 |
588 auto it = result.find("-c"); | |
589 | |
590 if (it != result.end() || (it = result.find("--config")) != result.end()) | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
591 irccd::ctl::read(it->second); |
348 | 592 else { |
652
e37ac2269ba6
Irccd: style (config) #782
David Demelier <markand@malikania.fr>
parents:
649
diff
changeset
|
593 if (auto conf = irccd::config::search("irccdctl.conf")) |
602
24959a94de96
Irccdctl: use config class, closes #749
David Demelier <markand@malikania.fr>
parents:
599
diff
changeset
|
594 irccd::ctl::read(*conf); |
348 | 595 } |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
596 } catch (const std::exception& ex) { |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
597 std::cerr << "abort: " << ex.what() << std::endl; |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
598 return 1; |
348 | 599 } |
600 | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
601 if (argc <= 0) |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
602 irccd::ctl::usage(); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
603 // NOTREACHED |
348 | 604 |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
605 if (!irccd::ctl::ctl) { |
599
e531f04507aa
Irccd: move logger into libirccd, closes #740
David Demelier <markand@malikania.fr>
parents:
584
diff
changeset
|
606 std::cerr << "abort: no connection specified" << std::endl; |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
607 return 1; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
608 } |
348 | 609 |
610 try { | |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
611 irccd::ctl::do_connect(); |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
612 irccd::ctl::do_exec(argc, argv); |
670
95ac3ace1610
Common: introduce new io code
David Demelier <markand@malikania.fr>
parents:
655
diff
changeset
|
613 } catch (const std::system_error& ex) { |
527
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
614 std::cerr << "abort: " << ex.code().message() << std::endl; |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
615 } catch (const std::exception& ex) { |
a88796ed040a
Irccdctl: switch to Boost.Asio, closes #697
David Demelier <markand@malikania.fr>
parents:
521
diff
changeset
|
616 std::cerr << "abort: " << ex.what() << std::endl; |
348 | 617 } |
618 } |