Exemplo n.º 1
0
static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::string& key, XLineFactory* make)
{
	insp::flat_set<std::string> configlines;

	ConfigTagList tags = conf->ConfTags(tag);
	for(ConfigIter i = tags.first; i != tags.second; ++i)
	{
		ConfigTag* ctag = i->second;
		std::string mask;
		if (!ctag->readString(key, mask))
			throw CoreException("<"+tag+":"+key+"> missing at " + ctag->getTagLocation());
		std::string reason = ctag->getString("reason", "<Config>");
		XLine* xl = make->Generate(ServerInstance->Time(), 0, "<Config>", reason, mask);
		xl->from_config = true;
		configlines.insert(xl->Displayable());
		if (!ServerInstance->XLines->AddLine(xl, NULL))
			delete xl;
	}

	ServerInstance->XLines->ExpireRemovedConfigLines(make->GetType(), configlines);
}
Exemplo n.º 2
0
	bool WriteDatabase()
	{
		/*
		 * We need to perform an atomic write so as not to f**k things up.
		 * So, let's write to a temporary file, flush it, then rename the file..
		 * Technically, that means that this can block, but I have *never* seen that.
		 *     -- w00t
		 */
		ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Opening temporary database");
		std::string xlinenewdbpath = xlinedbpath + ".new";
		std::ofstream stream(xlinenewdbpath.c_str());
		if (!stream.is_open())
		{
			ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Cannot create database! %s (%d)", strerror(errno), errno);
			ServerInstance->SNO->WriteToSnoMask('a', "database: cannot create new db: %s (%d)", strerror(errno), errno);
			return false;
		}

		ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Opened. Writing..");

		/*
		 * Now, much as I hate writing semi-unportable formats, additional
		 * xline types may not have a conf tag, so let's just write them.
		 * In addition, let's use a file version, so we can maintain some
		 * semblance of backwards compatibility for reading on startup..
		 * 		-- w00t
		 */
		stream << "VERSION 1" << std::endl;

		// Now, let's write.
		std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();
		for (std::vector<std::string>::const_iterator it = types.begin(); it != types.end(); ++it)
		{
			XLineLookup* lookup = ServerInstance->XLines->GetAll(*it);
			if (!lookup)
				continue; // Not possible as we just obtained the list from XLineManager

			for (LookupIter i = lookup->begin(); i != lookup->end(); ++i)
			{
				XLine* line = i->second;
				stream << "LINE " << line->type << " " << line->Displayable() << " "
					<< ServerInstance->Config->ServerName << " " << line->set_time << " "
					<< line->duration << " " << line->reason << std::endl;
			}
		}

		ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Finished writing XLines. Checking for error..");

		if (stream.fail())
		{
			ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "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(xlinedbpath.c_str()))
		{
			ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "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;
		}
#endif
		// Use rename to move temporary to new db - this is guarenteed not to f**k up, even in case of a crash.
		if (rename(xlinenewdbpath.c_str(), xlinedbpath.c_str()) < 0)
		{
			ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "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);
			return false;
		}

		return true;
	}