]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_permchannels.cpp
Allow configuring whether SETNAME sends snotices and is oper-only.
[user/henk/code/inspircd.git] / src / modules / m_permchannels.cpp
index a0b3284e3acd49354cdbf3ce950594811f1049e9..a7be6df0886c90eba45991170f78d4c00969edcf 100644 (file)
@@ -34,7 +34,7 @@ class PermChannel : public ModeHandler
                oper = true;
        }
 
-       ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding)
+       ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
        {
                if (adding == channel->IsModeSet(this))
                        return MODEACTION_DENY;
@@ -57,7 +57,7 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list
         * So, let's write to a temporary file, flush it, then rename the file..
         *     -- w00t
         */
-       
+
        // If the user has not specified a configuration file then we don't write one.
        if (permchannelsconf.empty())
                return true;
@@ -66,15 +66,16 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list
        std::ofstream stream(permchannelsnewconf.c_str());
        if (!stream.is_open())
        {
-               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot create database! %s (%d)", strerror(errno), errno);
-               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot create new db: %s (%d)", strerror(errno), errno);
+               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot create database \"%s\"! %s (%d)", permchannelsnewconf.c_str(), strerror(errno), errno);
+               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot create new permchan db \"%s\": %s (%d)", permchannelsnewconf.c_str(), strerror(errno), errno);
                return false;
        }
-       
+
        stream << "# This file is automatically generated by m_permchannels. Any changes will be overwritten." << std::endl
                << "<config format=\"xml\">" << std::endl;
 
-       for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
+       const chan_hash& chans = ServerInstance->GetChans();
+       for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); ++i)
        {
                Channel* chan = i->second;
                if (!chan->IsModeSet(permchanmode))
@@ -136,25 +137,20 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list
 
        if (stream.fail())
        {
-               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot write to new database! %s (%d)", strerror(errno), errno);
-               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot write to new db: %s (%d)", strerror(errno), errno);
+               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot write to new database \"%s\"! %s (%d)", permchannelsnewconf.c_str(), strerror(errno), errno);
+               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot write to new permchan db \"%s\": %s (%d)", permchannelsnewconf.c_str(), strerror(errno), errno);
                return false;
        }
        stream.close();
 
 #ifdef _WIN32
-       if (remove(permchannelsconf.c_str()))
-       {
-               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot remove old database! %s (%d)", strerror(errno), errno);
-               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot remove old database: %s (%d)", strerror(errno), errno);
-               return false;
-       }
+       remove(permchannelsconf.c_str());
 #endif
        // Use rename to move temporary to new db - this is guarenteed not to fuck up, even in case of a crash.
        if (rename(permchannelsnewconf.c_str(), permchannelsconf.c_str()) < 0)
        {
-               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot move new to old database! %s (%d)", strerror(errno), errno);
-               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot replace old with new db: %s (%d)", strerror(errno), errno);
+               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot replace old database \"%s\" with new database \"%s\"! %s (%d)", permchannelsconf.c_str(), permchannelsnewconf.c_str(), strerror(errno), errno);
+               ServerInstance->SNO->WriteToSnoMask('a', "database: cannot replace old permchan db \"%s\" with new db \"%s\": %s (%d)", permchannelsconf.c_str(), permchannelsnewconf.c_str(), strerror(errno), errno);
                return false;
        }
 
@@ -165,44 +161,23 @@ class ModulePermanentChannels : public Module
 {
        PermChannel p;
        bool dirty;
+       bool loaded;
        bool save_listmodes;
 public:
 
-       ModulePermanentChannels() : p(this), dirty(false)
+       ModulePermanentChannels()
+               : p(this), dirty(false), loaded(false)
        {
        }
 
-       CullResult cull()
-       {
-               /*
-                * DelMode can't remove the +P mode on empty channels, or it will break
-                * merging modes with remote servers. Remove the empty channels now as
-                * we know this is not the case.
-                */
-               chan_hash::iterator iter = ServerInstance->chanlist->begin();
-               while (iter != ServerInstance->chanlist->end())
-               {
-                       Channel* c = iter->second;
-                       if (c->GetUserCounter() == 0)
-                       {
-                               chan_hash::iterator at = iter;
-                               iter++;
-                               FOREACH_MOD(OnChannelDelete, (c));
-                               ServerInstance->chanlist->erase(at);
-                               ServerInstance->GlobalCulls.AddItem(c);
-                       }
-                       else
-                               iter++;
-               }
-               ServerInstance->Modes->DelMode(&p);
-               return Module::cull();
-       }
-
        void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
        {
                ConfigTag* tag = ServerInstance->Config->ConfValue("permchanneldb");
                permchannelsconf = tag->getString("filename");
                save_listmodes = tag->getBool("listmodes");
+
+               if (!permchannelsconf.empty())
+                       permchannelsconf = ServerInstance->Config->Paths.PrependConfig(permchannelsconf);
        }
 
        void LoadDatabase()
@@ -231,17 +206,17 @@ public:
                                time_t TS = tag->getInt("ts", ServerInstance->Time(), 1);
                                c = new Channel(channel, TS);
 
-                               unsigned int topicset = tag->getInt("topicts");
-                               c->topic = tag->getString("topic");
+                               time_t topicset = tag->getInt("topicts", 0);
+                               std::string topic = tag->getString("topic");
 
-                               if ((topicset != 0) || (!c->topic.empty()))
+                               if ((topicset != 0) || (!topic.empty()))
                                {
                                        if (topicset == 0)
                                                topicset = ServerInstance->Time();
-                                       c->topicset = topicset;
-                                       c->setby = tag->getString("topicsetby");
-                                       if (c->setby.empty())
-                                               c->setby = ServerInstance->Config->ServerName;
+                                       std::string topicsetby = tag->getString("topicsetby");
+                                       if (topicsetby.empty())
+                                               topicsetby = ServerInstance->Config->ServerName;
+                                       c->SetTopic(ServerInstance->FakeClient, topic, topicset, &topicsetby);
                                }
 
                                ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Added %s with topic %s", channel.c_str(), c->topic.c_str());
@@ -261,7 +236,7 @@ public:
                                        ModeHandler* mode = ServerInstance->Modes->FindMode(*n, MODETYPE_CHANNEL);
                                        if (mode)
                                        {
-                                               if (mode->GetNumParams(true))
+                                               if (mode->NeedsParam(true))
                                                        list.GetToken(par);
                                                else
                                                        par.clear();
@@ -269,13 +244,17 @@ public:
                                                mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true);
                                        }
                                }
+
+                               // We always apply the permchannels mode to permanent channels.
+                               par.clear();
+                               p.OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true);
                        }
                }
        }
 
-       ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string &param, bool adding, int pcnt) CXX11_OVERRIDE
+       ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding) CXX11_OVERRIDE
        {
-               if (chan && (chan->IsModeSet(p) || mode == p.GetModeChar()))
+               if (chan && (chan->IsModeSet(p) || mh == &p))
                        dirty = true;
 
                return MOD_RES_PASSTHRU;
@@ -294,15 +273,13 @@ public:
                dirty = false;
        }
 
-       void Prioritize()
+       void Prioritize() CXX11_OVERRIDE
        {
                // XXX: Load the DB here because the order in which modules are init()ed at boot is
                // alphabetical, this means we must wait until all modules have done their init()
                // to be able to set the modes they provide (e.g.: m_stripcolor is inited after us)
                // Prioritize() is called after all module initialization is complete, consequently
                // all modes are available now
-
-               static bool loaded = false;
                if (loaded)
                        return;