ircproxy  The Ultimate Cyborg

PrivateTarget Class Reference

#include <PrivateTarget.h>

Inheritance diagram for PrivateTarget:

Target NoticeTarget QuestionTarget

List of all members.


Detailed Description

A fake channel that is used for communication between user and ircproxy.

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.

Constructor & Destructor Documentation

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) { }


Member Function Documentation

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.

00056 { }

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().

00060 { return "nt"; }


The documentation for this class was generated from the following files:

Copyright © 2005-2007 Carlo Wood.  All rights reserved.