]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_chanlog.cpp
Use Utils->ServerUser instead of ServerInstance->FakeClient in m_spanningtree
[user/henk/code/inspircd.git] / src / modules / m_chanlog.cpp
index afc8c5225233225255ca437585678d8d433aacc7..18d13ecdf8bfe222607c0775c3db43c7d36f96d9 100644 (file)
@@ -2,8 +2,8 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
  *            the file COPYING for details.
 
 #include "inspircd.h"
 
-class ChannelLogStream : public LogStream
-{
- private:
-       std::string channel;
-
- public:
-       ChannelLogStream(InspIRCd *Instance, int loglevel, const std::string &chan) : LogStream(Instance, loglevel), channel(chan)
-       {
-       }
-
-       virtual void OnLog(int loglevel, const std::string &type, const std::string &msg)
-       {
-               Channel *c = ServerInstance->FindChan(channel);
-
-               if (loglevel < this->loglvl) return;
-
-               if (c)
-               {
-                       // So this won't work remotely. Oh well.
-                       c->WriteChannelWithServ(ServerInstance->Config->ServerName, "PRIVMSG %s :\2%s\2: %s", c->name, type.c_str(), msg.c_str());
-               }
-       }
-};
-
-/* $ModDesc: Logs output to a channel instead of / as well as a file. */
+/* $ModDesc: Logs snomask output to channel(s). */
 
 class ModuleChanLog : public Module
 {
  private:
-       std::vector<ChannelLogStream*> cls;
+       /*
+        * Multimap so people can redirect a snomask to multiple channels.
+        */
+       std::multimap<char, std::string> logstreams;
+
  public:
        ModuleChanLog(InspIRCd* Me) : Module(Me)
        {
+               Implementation eventlist[] = { I_OnRehash, I_OnSendSnotice };
+               ServerInstance->Modules->Attach(eventlist, this, 2);
+
+               OnRehash(NULL, "");
        }
 
        virtual ~ModuleChanLog()
        {
-               std::vector<ChannelLogStream*>::iterator i;
-               while ((i = cls.begin()) != cls.end())
-               {
-                       ServerInstance->Logs->DelLogStream(*i);
-                       cls.erase(i);
-               }
        }
 
-       virtual void OnReadConfig(ServerConfig* sc, ConfigReader* Conf)
+       virtual void OnRehash(User *user, const std::string &parameter)
        {
-               /* Since the CloseLogs prior to this hook just wiped out our logstreams for us, we just need to wipe the vector. */
-               std::vector<ChannelLogStream*>().swap(cls);
-               int index, max = Conf->Enumerate("log");
-               cls.reserve(max);
-               for (index = 0; index < max; ++index)
+               ConfigReader MyConf(ServerInstance);
+               std::string snomasks;
+               std::string channel;
+
+               logstreams.clear();
+
+               for (int i = 0; i < MyConf.Enumerate("chanlog"); i++)
                {
-                       std::string method = Conf->ReadValue("log", "method", index);
-                       if (method != "file") continue;
-                       std::string type = Conf->ReadValue("log", "type", index);
-                       std::string level = Conf->ReadValue("log", "level", index);
-                       int loglevel = DEFAULT;
-                       if (level == "debug")
-                       {
-                               loglevel = DEBUG;
-                               ServerInstance->Config->debugging = true;
-                       }
-                       else if (level == "verbose")
-                       {
-                               loglevel = VERBOSE;
-                       }
-                       else if (level == "default")
+                       channel = MyConf.ReadValue("chanlog", "channel", i);
+                       snomasks = MyConf.ReadValue("chanlog", "snomasks", i);
+
+                       if (channel.empty() || snomasks.empty())
                        {
-                               loglevel = DEFAULT;
+                               ServerInstance->Logs->Log("m_chanlog", DEFAULT, "Malformed chanlog tag, ignoring");
+                               continue;
                        }
-                       else if (level == "sparse")
+
+                       for (std::string::const_iterator it = snomasks.begin(); it != snomasks.end(); it++)
                        {
-                               loglevel = SPARSE;
+                               logstreams.insert(std::make_pair(*it, channel));
+                               ServerInstance->Logs->Log("m_chanlog", DEFAULT, "Logging %c to %s", *it, channel.c_str());
                        }
-                       else if (level == "none")
+               }
+
+       }
+
+       virtual int OnSendSnotice(char &sno, std::string &desc, const std::string &msg)
+       {
+               std::multimap<char, std::string>::const_iterator it = logstreams.find(sno);
+               char buf[MAXBUF];
+
+               if (it == logstreams.end())
+                       return 0;
+
+               snprintf(buf, MAXBUF, "\2%s\2: %s", desc.c_str(), msg.c_str());
+
+               while (it != logstreams.end())
+               {
+                       if (it->first != sno)
                        {
-                               loglevel = NONE;
+                               it++;
+                               continue;
                        }
-                       std::string target = Conf->ReadValue("log", "target", index);
-                       ChannelLogStream* c = new ChannelLogStream(ServerInstance, loglevel, target);
-                       irc::commasepstream css(type);
-                       std::string tok;
-                       while (css.GetToken(tok))
+
+                       Channel *c = ServerInstance->FindChan(it->second);
+                       if (c)
                        {
-                               ServerInstance->Logs->AddLogType(tok, c, true);
+                               c->WriteChannelWithServ(ServerInstance->Config->ServerName, "PRIVMSG %s :%s", c->name.c_str(), buf);
+                               ServerInstance->PI->SendChannelPrivmsg(c, 0, buf);
                        }
-                       cls.push_back(c);
+
+                       it++;
                }
+
+               return 0;
        }
 
        virtual Version GetVersion()
        {
-               return Version(1,1,0,1,VF_VENDOR,API_VERSION);
+               return Version("$Id$", VF_VENDOR,API_VERSION);
        }
 };
 
 
 MODULE_INIT(ModuleChanLog)
 
+
+
+
+
+
+
+
+
+/*
+ * This is for the "old" chanlog module which intercepted messages going to the logfile..
+ * I don't consider it all that useful, and it's quite dangerous if setup incorrectly, so
+ * this is defined out but left intact in case someone wants to develop it further someday.
+ *
+ * -- w00t (aug 23rd, 2008)
+ */
+#define OLD_CHANLOG 0
+
+#if OLD_CHANLOG
+class ChannelLogStream : public LogStream
+{
+ private:
+       std::string channel;
+
+ public:
+       ChannelLogStream(InspIRCd *Instance, int loglevel, const std::string &chan) : LogStream(Instance, loglevel), channel(chan)
+       {
+       }
+
+       virtual void OnLog(int loglevel, const std::string &type, const std::string &msg)
+       {
+               Channel *c = ServerInstance->FindChan(channel);
+               static bool Logging = false;
+
+               if (loglevel < this->loglvl)
+                       return;
+
+               if (Logging)
+                       return;
+
+               if (c)
+               {
+                       Logging = true; // this avoids (rare chance) loops with logging server IO on networks
+                       char buf[MAXBUF];
+                       snprintf(buf, MAXBUF, "\2%s\2: %s", type.c_str(), msg.c_str());
+
+                       c->WriteChannelWithServ(ServerInstance->Config->ServerName, "PRIVMSG %s :%s", c->name.c_str(), buf);
+                       ServerInstance->PI->SendChannelPrivmsg(c, 0, buf);
+                       Logging = false;
+               }
+       }
+};
+#endif
+