diff options
-rw-r--r-- | include/commands.h | 2 | ||||
-rw-r--r-- | src/commands.cpp | 88 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 83 |
3 files changed, 134 insertions, 39 deletions
diff --git a/include/commands.h b/include/commands.h index b1c5be45d..6690d16c0 100644 --- a/include/commands.h +++ b/include/commands.h @@ -91,4 +91,6 @@ bool is_uline(const char* server); */ long duration(const char* str); +void do_whois(userrec* user, userrec* dest,unsigned long signon, unsigned long idle, char* nick); + #endif diff --git a/src/commands.cpp b/src/commands.cpp index a01f3a844..bc144dd51 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -824,61 +824,71 @@ void handle_time(char **parameters, int pcnt, userrec *user) void handle_whois(char **parameters, int pcnt, userrec *user) { userrec *dest; - - if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0)) - return; + if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0)) + return; dest = Find(parameters[0]); if (dest) { - // bug found by phidjit - were able to whois an incomplete connection if it had sent a NICK or USER - if (dest->registered == 7) + do_whois(user,dest,0,0,parameters[0]); + } + else + { + /* no such nick/channel */ + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + } +} + +void do_whois(userrec* user, userrec* dest,unsigned long signon, unsigned long idle, char* nick) +{ + // bug found by phidjit - were able to whois an incomplete connection if it had sent a NICK or USER + if (dest->registered == 7) + { + WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname); + if ((user == dest) || (strchr(user->modes,'o'))) { - WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname); - if ((user == dest) || (strchr(user->modes,'o'))) - { - WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip); - } - char* cl = chlist(dest,user); - if (*cl) - { - WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl); - } - WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str()); - if (*dest->awaymsg) + WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip); + } + char* cl = chlist(dest,user); + if (*cl) + { + WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl); + } + WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str()); + if (*dest->awaymsg) + { + WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg); + } + if (strchr(dest->modes,'o')) + { + if (*dest->oper) { - WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg); + WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Network); } - if (strchr(dest->modes,'o')) + else { - if (*dest->oper) - { - WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Network); - } - else - { - WriteServ(user->fd,"313 %s %s :is opered but has an unknown type",user->nick, dest->nick); - } + WriteServ(user->fd,"313 %s %s :is opered but has an unknown type",user->nick, dest->nick); } + } + if ((!signon) && (!idle)) + { FOREACH_MOD OnWhois(user,dest); - if (!strcasecmp(user->server,dest->server)) - { - // idle time and signon line can only be sent if youre on the same server (according to RFC) - WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, abs((dest->idle_lastmsg)-TIME), dest->signon); - } - - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, dest->nick); + } + if (!strcasecmp(user->server,dest->server)) + { + // idle time and signon line can only be sent if youre on the same server (according to RFC) + WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, abs((dest->idle_lastmsg)-TIME), dest->signon); } else { - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, idle, signon); } + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, dest->nick); } else { - /* no such nick/channel */ - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, nick); + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, nick); } } diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index edc5fa16e..5d08926f7 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -31,6 +31,7 @@ using namespace std; #include "users.h" #include "channels.h" #include "modules.h" +#include "commands.h" #include "socket.h" #include "helperfuncs.h" #include "inspircd.h" @@ -1360,6 +1361,55 @@ class TreeSocket : public InspSocket } return true; } + + bool Whois(std::string prefix, std::deque<std::string> ¶ms) + { + if (params.size() < 1) + return true; + userrec* u = Srv->FindNick(prefix); + if (u) + { + // an incoming request + if (params.size() == 1) + { + if (std::string(u->server) == Srv->GetServerName()) + { + char signon[MAXBUF]; + char idle[MAXBUF]; + snprintf(signon,MAXBUF,"%lu",(unsigned long)u->signon); + snprintf(idle,MAXBUF,"%lu",(unsigned long)abs((u->idle_lastmsg)-time(NULL))); + std::deque<std::string> par; + par.push_back(u->nick); + par.push_back(signon); + par.push_back(idle); + DoOneToMany(params[0],"IDLE",par); + } + else + { + DoOneToAllButSender(prefix,"IDLE",params,u->server); + } + } + else if (params.size() == 3) + { + if (std::string(u->server) == Srv->GetServerName()) + { + // an incoming reply to a whois we sent out + std::string nick_whoised = prefix; + std::string who_did_the_whois = params[0]; + unsigned long signon = atoi(params[1].c_str()); + unsigned long idle = atoi(params[2].c_str()); + userrec* who_to_send_to = Srv->FindNick(who_did_the_whois); + if (who_to_send_to) + do_whois(who_to_send_to,u,signon,idle,(char*)nick_whoised.c_str()); + } + else + { + DoOneToAllButSender(prefix,"IDLE",params,u->server); + } + } + } + return true; + } bool LocalPing(std::string prefix, std::deque<std::string> ¶ms) { @@ -1731,6 +1781,10 @@ class TreeSocket : public InspSocket } return this->ForceNick(prefix,params); } + else if (command == "IDLE") + { + return this->Whois(prefix,params); + } else if (command == "SVSJOIN") { if (prefix == "") @@ -2214,6 +2268,27 @@ class ModuleSpanningTree : public Module return 1; } + int HandleRemoteWhois(char** parameters, int pcnt, userrec* user) + { + if ((std::string(user->server) == Srv->GetServerName()) && (pcnt > 1)) + { + if (Srv->FindNick(parameters[1])) + { + std::deque<std::string> params; + params.push_back(parameters[1]); + DoOneToMany(user->nick,"IDLE",params); + return 1; + } + else + { + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[1]); + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[1]); + return 1; + } + } + return 0; + } + void DoPingChecks(time_t curtime) { for (unsigned int j = 0; j < TreeRoot->ChildCount(); j++) @@ -2348,6 +2423,14 @@ class ModuleSpanningTree : public Module this->HandleLinks(parameters,pcnt,user); return 1; } + else if (command == "WHOIS") + { + if (pcnt > 1) + { + // remote whois + return this->HandleRemoteWhois(parameters,pcnt,user); + } + } else if ((command == "VERSION") && (pcnt > 0)) { this->HandleVersion(parameters,pcnt,user); |