The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

fmode.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #include "inspircd.h"
00015 #include "xline.h"
00016 
00017 #include "m_spanningtree/treesocket.h"
00018 #include "m_spanningtree/treeserver.h"
00019 #include "m_spanningtree/utils.h"
00020 
00021 /* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */
00022 
00023 
00025 bool TreeSocket::ForceMode(const std::string &source, std::deque<std::string> &params)
00026 {
00027         /* Chances are this is a 1.0 FMODE without TS */
00028         if (params.size() < 3)
00029         {
00030                 /* No modes were in the command, probably a channel with no modes set on it */
00031                 return true;
00032         }
00033 
00034         bool smode = false;
00035         std::string sourceserv;
00036 
00037         /* Are we dealing with an FMODE from a user, or from a server? */
00038         User* who = this->ServerInstance->FindNick(source);
00039         if (who)
00040         {
00041                 /* FMODE from a user, set sourceserv to the users server name */
00042                 sourceserv = who->server;
00043         }
00044         else
00045         {
00046                 /* FMODE from a server, use a fake user to receive mode feedback */
00047                 who = this->ServerInstance->FakeClient;
00048                 smode = true;                   /* Setting this flag tells us it is a server mode*/
00049                 sourceserv = source;    /* Set sourceserv to the actual source string */
00050         }
00051         std::vector<std::string> modelist;
00052         time_t TS = 0;
00053         for (unsigned int q = 0; (q < params.size()) && (q < 64); q++)
00054         {
00055                 if (q == 1)
00056                 {
00057                         /* The timestamp is in this position.
00058                          * We don't want to pass that up to the
00059                          * server->client protocol!
00060                          */
00061                         TS = atoi(params[q].c_str());
00062                 }
00063                 else
00064                 {
00065                         /* Everything else is fine to append to the modelist */
00066                         modelist.push_back(params[q]);
00067                 }
00068 
00069         }
00070         /* Extract the TS value of the object, either User or Channel */
00071         User* dst = this->ServerInstance->FindNick(params[0]);
00072         Channel* chan = NULL;
00073         time_t ourTS = 0;
00074 
00075         if (dst)
00076         {
00077                 ourTS = dst->age;
00078         }
00079         else
00080         {
00081                 chan = this->ServerInstance->FindChan(params[0]);
00082                 if (chan)
00083                 {
00084                         ourTS = chan->age;
00085                 }
00086                 else
00087                         /* Oops, channel doesnt exist! */
00088                         return true;
00089         }
00090 
00091         if (!TS)
00092         {
00093                 ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"*** BUG? *** TS of 0 sent to FMODE. Are some services authors smoking craq, or is it 1970 again?. Dropped.");
00094                 ServerInstance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FMODE with a TS of zero. Total craq. Mode was dropped.", sourceserv.c_str());
00095                 return true;
00096         }
00097 
00098         /* TS is equal or less: Merge the mode changes into ours and pass on.
00099          */
00100         if (TS <= ourTS)
00101         {
00102                 if (smode)
00103                 {
00104                         this->ServerInstance->SendMode(modelist, who);
00105                 }
00106                 else
00107                 {
00108                         this->ServerInstance->CallCommandHandler("MODE", modelist, who);
00109                 }
00110                 /* HOT POTATO! PASS IT ON! */
00111                 Utils->DoOneToAllButSender(source,"FMODE",params,sourceserv);
00112         }
00113         /* If the TS is greater than ours, we drop the mode and dont pass it anywhere.
00114          */
00115         return true;
00116 }
00117 
00118