ircproxy The Ultimate Cyborg |
#include <PrivateTarget.h>
Base class for NoticeTarget and QuestionTarget.
Definition at line 32 of file PrivateTarget.h.
Public Member Functions | |
PrivateTarget (ClientSession &client_session, std::string const &target_name, Network &network) | |
Construct PrivateTarget instance for client session client_session with target name target_name on network network. | |
void | do_names_output (void) |
Generate the NAMES reply for the associated channel. | |
void | handle_command (ClientMessageIn const &msg) |
Decode and handle a command sent to a private target. | |
virtual void | new_client_message_received (ClientMessageIn const &msg) |
Called when a new (client) message is received for this target. | |
Protected Member Functions | |
virtual char const * | channel_modes (void) |
The channel modes for this target, as sent to the client. | |
Private Member Functions | |
virtual void | new_server_message_received (ServerMessageIn const &) |
This is called when a new message targetted at this target is received. |
PrivateTarget::PrivateTarget | ( | ClientSession & | client_session, | |
std::string const & | target_name, | |||
Network & | network | |||
) | [inline] |
Construct PrivateTarget instance for client session client_session with target name target_name on network network.
Definition at line 39 of file PrivateTarget.h.
00039 : 00040 Target(&network), M_client_session(client_session), M_name(target_name) { }
void PrivateTarget::do_names_output | ( | void | ) |
Generate the NAMES reply for the associated channel.
Definition at line 218 of file PrivateTarget.cc.
References ClientSession::client_out_nick(), IdentityReference::identity(), and Identity::server_source().
Referenced by QuestionTarget::create_channel_and_ask_question(), new_client_message_received(), and Identity::notice_target().
00219 { 00220 client_session() << ':' << client_session().identity().server_source() << " 353 " << 00221 client_session().client_out_nick() << " @ " << out_name(client_session()) << 00222 " :@Leandro " << client_session().client_out_nick() << "\r\n"; 00223 client_session() << ':' << client_session().identity().server_source() << " 366 " << 00224 client_session().client_out_nick() << ' ' << out_name(client_session()) << " :End of /NAMES list.\r\n"; 00225 }
void PrivateTarget::handle_command | ( | ClientMessageIn const & | msg | ) |
Decode and handle a command sent to a private target.
Definition at line 61 of file PrivateTarget.cc.
References ASSERT, ClientSession::client_out_nick(), IdentityReference::identity(), is_channel(), MessageIn::param(), and real_nick_accepted.
Referenced by new_client_message_received().
00062 { 00063 // Some convenience variables. 00064 ClientSession& client_session(this->client_session()); 00065 Identity& identity(client_session.identity()); 00066 ServerConnection& server_connection(identity.server_connection()); 00067 // Construct a prefix for possible messages to be sent to the client. 00068 std::string prefix(msg.param(0)); 00069 if (!is_channel(prefix)) 00070 prefix = client_session.client_out_nick(); 00071 prefix = ":Leandro PRIVMSG " + prefix + " :"; 00072 // Tokenize the command line. 00073 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 00074 boost::char_separator<char> sep(" "); 00075 tokenizer tokens(msg.param(1), sep); 00076 tokenizer::iterator tok_iter = tokens.begin(); 00077 if (tok_iter == tokens.end()) // No command at all? 00078 return; 00079 std::string command = *tok_iter; 00080 ++tok_iter; 00081 if (command == "!help") 00082 { 00083 client_session << prefix << "!help : This help text." << "\r\n"; 00084 client_session << prefix << "!server <host> [<port>]: Connect to server <host> at port <port> (default 6667)." << "\r\n"; 00085 #ifdef CWDEBUG 00086 client_session << prefix << "!quit : Send 'QUIT :Received command !quit' to the server socket (debugging)." << "\r\n"; 00087 #endif 00088 } 00089 else if (command == "!server") 00090 { 00091 if (tok_iter == tokens.end()) 00092 { 00093 client_session << prefix << "Usage: !server <host> [<port>] [<vhost>]\r\n"; 00094 return; 00095 } 00096 std::string hostname(*tok_iter); 00097 std::string::size_type pos = hostname.rfind('.'); 00098 std::string domain; 00099 if (pos != std::string::npos) 00100 domain = hostname.substr(hostname.rfind('.', pos - 1) + 1); 00101 ++tok_iter; 00102 unsigned short port = 0; 00103 bool no_vhost_argument_given = true; 00104 struct in_addr vhost = { INADDR_ANY }; 00105 if (tok_iter != tokens.end()) 00106 { 00107 std::string argument(*tok_iter); 00108 ++tok_iter; 00109 if (tok_iter != tokens.end() || argument.find_first_not_of("0123456789") == std::string::npos) 00110 port = atoi(argument.c_str()); 00111 else 00112 { 00113 inet_aton(argument.c_str(), &vhost); 00114 no_vhost_argument_given = false; 00115 } 00116 if (tok_iter != tokens.end()) 00117 { 00118 inet_aton(tok_iter->c_str(), &vhost); 00119 no_vhost_argument_given = false; 00120 } 00121 } 00122 // Do we already know this server? 00123 bool found = false; 00124 networks_type::iterator network_iter; 00125 Network::servers_type::iterator server_found; 00126 for (network_iter = Application::instance().networks().begin(); network_iter != Application::instance().networks().end(); ++network_iter) 00127 { 00128 for (Network::servers_type::iterator server_iter = network_iter->servers().begin(); server_iter != network_iter->servers().end(); ++server_iter) 00129 if (strcasecmp((*server_iter)->hostname().c_str(), hostname.c_str()) == 0) 00130 { 00131 Dout(dc::notice, "Found existing server " << *server_iter); 00132 found = true; 00133 server_found = server_iter; 00134 break; 00135 } 00136 if (found) 00137 break; 00138 } 00139 bool trying_to_switch_network = false; 00140 if (found) 00141 { 00142 // Are we (successfully) connected to a server? 00143 if (server_connection.has_server() && server_connection.state() >= real_nick_accepted) 00144 { 00145 // Is the found server the same server that we are already connected to? 00146 if (server_connection.server() == *server_found) 00147 { 00148 // Are we trying to change port? 00149 if (!port || port == server_connection.server()->port()) 00150 { 00151 // Are we trying to change vhost? 00152 if (no_vhost_argument_given || std::memcmp(&server_connection.server()->vhost(), &vhost, sizeof(vhost)) == 0) 00153 { 00154 // Nothing changed. Refused to reconnect. 00155 static struct in_addr const any = { INADDR_ANY }; 00156 bool print_vhost = !no_vhost_argument_given || std::memcmp(&server_connection.server()->vhost(), &any, sizeof(vhost)) != 0; 00157 client_session << prefix << "You are already connected to " << server_connection.server()->get_irc_name(); 00158 if (port) 00159 client_session << ' '; 00160 else 00161 client_session << " ("; 00162 client_session << "port " << server_connection.server()->port(); 00163 if (print_vhost) 00164 { 00165 if (port && no_vhost_argument_given) 00166 client_session << " ("; 00167 else if (!port && !no_vhost_argument_given) 00168 client_session << ") "; 00169 else 00170 client_session << ' '; 00171 client_session << "using vhost " << server_connection.server()->vhost(); 00172 } 00173 if ((print_vhost && no_vhost_argument_given) || (!print_vhost && !port)) 00174 client_session << ')'; 00175 client_session << "\r\n"; 00176 return; 00177 } 00178 } 00179 if (no_vhost_argument_given) 00180 std::memcpy(&vhost, &server_connection.server()->vhost(), sizeof(vhost)); 00181 } 00182 else if (network_iter->name() != identity.network().name()) // Is the user trying to switch network? 00183 trying_to_switch_network = true; 00184 } 00185 } 00186 else 00187 trying_to_switch_network = identity.network().has_domain() && strcasecmp(identity.network().domain().c_str(), domain.c_str()) != 0; 00188 if (trying_to_switch_network) 00189 { 00190 client_session << prefix << "The identity \"" << identity.key() << 00191 "\" belongs to network \"" << identity.network_name() << "\". You can not switch IRC network.\r\n"; 00192 return; 00193 } 00194 if (!port) 00195 port = 6667; 00196 boost::shared_ptr<Server> new_server; 00197 if (!found) 00198 new_server.reset(NEW(Server(identity.network(), hostname, port, vhost))); 00199 else 00200 { 00201 ASSERT(&(*server_found)->network() == NULL || &identity.network() == &(*server_found)->network()); 00202 ASSERT(!strcasecmp((*server_found)->hostname().c_str(), hostname.c_str())); 00203 new_server = *server_found; 00204 std::memcpy(&new_server->vhost(), &vhost, sizeof(vhost)); 00205 new_server->set_next_port(port); 00206 } 00207 identity.start_secondary_server_connection(new_server); 00208 } 00209 #ifdef CWDEBUG 00210 else if (command == "!quit") 00211 { 00212 client_session << "QUIT :Received command !quit\r\n"; 00213 } 00214 #endif 00215 }
void PrivateTarget::new_client_message_received | ( | ClientMessageIn const & | msg | ) | [virtual] |
Called when a new (client) message is received for this target.
This function handles incoming messages for this target.
Implements Target.
Reimplemented in NoticeTarget, and QuestionTarget.
Definition at line 34 of file PrivateTarget.cc.
References ASSERT, channel_modes(), ClientSession::client_out_nick(), ClientMessageIn::client_session(), ClientSession::del_private_target(), do_names_output(), DoutEntering, handle_command(), IdentityReference::identity(), is_channel(), MessageIn::key(), MessageIn::param(), and Identity::server_source().
Referenced by QuestionTarget::new_client_message_received(), and NoticeTarget::new_client_message_received().
00035 { 00036 DoutEntering(dc::debug, "PrivateTarget::new_client_message_received(" << msg << ") for target \"" << in_name(client_session()) << "\"."); 00037 ASSERT(&client_session() == &msg.client_session()); 00038 switch(msg.key()) 00039 { 00040 using namespace keys; 00041 case MODE: 00042 if (is_channel(in_name(client_session()))) 00043 client_session() << ':' << client_session().identity().server_source() << " 324 " << 00044 client_session().client_out_nick() << ' ' << out_name(client_session()) << " +" << channel_modes() << "\r\n"; 00045 break; 00046 case NAMES: 00047 do_names_output(); 00048 break; 00049 case PART: 00050 client_session().del_private_target(msg.param(0)); 00051 client_session() << ':' << client_session().client_out_nick() << 00052 " PART " << msg.param(0) << "\r\n"; 00053 break; 00054 case PRIVMSG: 00055 handle_command(msg); 00056 break; 00057 } 00058 }
virtual void PrivateTarget::new_server_message_received | ( | ServerMessageIn const & | ) | [inline, private, virtual] |
This is called when a new message targetted at this target is received.
Implements Target.
Definition at line 56 of file PrivateTarget.h.
virtual char const* PrivateTarget::channel_modes | ( | void | ) | [inline, protected, virtual] |
The channel modes for this target, as sent to the client.
Reimplemented in NoticeTarget.
Definition at line 60 of file PrivateTarget.h.
Referenced by new_client_message_received().
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|