summaryrefslogtreecommitdiff
path: root/src/modules/m_permchannels.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/m_permchannels.cpp')
-rw-r--r--src/modules/m_permchannels.cpp74
1 files changed, 21 insertions, 53 deletions
diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp
index 41477ba35..ff1a35ba9 100644
--- a/src/modules/m_permchannels.cpp
+++ b/src/modules/m_permchannels.cpp
@@ -19,6 +19,7 @@
#include "inspircd.h"
+#include <fstream>
/* $ModDesc: Provides support for channel mode +P to provide permanent channels */
@@ -26,79 +27,47 @@
static std::string permchannelsconf;
static bool WriteDatabase()
{
- FILE *f;
-
- if (permchannelsconf.empty())
- {
- // Fake success.
- return true;
- }
-
- std::string tempname = permchannelsconf + ".tmp";
-
/*
* We need to perform an atomic write so as not to fuck things up.
- * So, let's write to a temporary file, flush and sync the FD, then rename the file..
- * -- w00t
+ * So, let's write to a temporary file, flush it, then rename the file..
+ * -- w00t
*/
- f = fopen(tempname.c_str(), "w");
- if (!f)
+
+ // If the user has not specified a configuration file then we don't write one.
+ if (permchannelsconf.empty())
+ return true;
+
+ std::string permchannelsnewconf = permchannelsconf + ".tmp";
+ std::ofstream stream(permchannelsnewconf.c_str());
+ if (!stream.is_open())
{
ServerInstance->Logs->Log("m_permchannels", LOG_DEFAULT, "permchannels: Cannot create database! %s (%d)", strerror(errno), errno);
ServerInstance->SNO->WriteToSnoMask('a', "database: cannot create new db: %s (%d)", 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;
- fputs("# Permchannels DB\n# This file is autogenerated; any changes will be overwritten!\n<config format=\"compat\">\n", f);
- // Now, let's write.
for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
{
Channel* chan = i->second;
if (!chan->IsModeSet('P'))
continue;
- char line[1024];
- const char* items[] =
- {
- "<permchannels channel=",
- chan->name.c_str(),
- " topic=",
- chan->topic.c_str(),
- " modes=",
- chan->ChanModes(true),
- ">\n"
- };
-
- int lpos = 0, item = 0, ipos = 0;
- while (lpos < 1022 && item < 7)
- {
- char c = items[item][ipos++];
- if (c == 0)
- {
- // end of this string; hop to next string, insert a quote
- item++;
- ipos = 0;
- c = '"';
- }
- else if (c == '\\' || c == '"')
- {
- line[lpos++] = '\\';
- }
- line[lpos++] = c;
- }
- line[--lpos] = 0;
- fputs(line, f);
+ stream << "<permchannels channel=\"" << ServerConfig::Escape(chan->name)
+ << "\" topic=\"" << ServerConfig::Escape(chan->topic)
+ << "\" modes=\"" << ServerConfig::Escape(chan->ChanModes(true))
+ << "\">" << std::endl;
}
- int write_error = 0;
- write_error = ferror(f);
- write_error |= fclose(f);
- if (write_error)
+ if (stream.fail())
{
ServerInstance->Logs->Log("m_permchannels", LOG_DEFAULT, "permchannels: 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);
return false;
}
+ stream.close();
#ifdef _WIN32
if (remove(permchannelsconf.c_str()))
@@ -109,7 +78,7 @@ static bool WriteDatabase()
}
#endif
// Use rename to move temporary to new db - this is guarenteed not to fuck up, even in case of a crash.
- if (rename(tempname.c_str(), permchannelsconf.c_str()) < 0)
+ if (rename(permchannelsnewconf.c_str(), permchannelsconf.c_str()) < 0)
{
ServerInstance->Logs->Log("m_permchannels", LOG_DEFAULT, "permchannels: 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);
@@ -120,7 +89,6 @@ static bool WriteDatabase()
}
-
/** Handles the +P channel mode
*/
class PermChannel : public ModeHandler