Exemple #1
0
/** Send all XLines we know about */
void TreeSocket::SendXLines()
{
	std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();

	for (std::vector<std::string>::const_iterator it = types.begin(); it != types.end(); ++it)
	{
		/* Expired lines are removed in XLineManager::GetAll() */
		XLineLookup* lookup = ServerInstance->XLines->GetAll(*it);

		/* lookup cannot be NULL in this case but a check won't hurt */
		if (lookup)
		{
			for (LookupIter i = lookup->begin(); i != lookup->end(); ++i)
			{
				/* Is it burstable? this is better than an explicit check for type 'K'.
				 * We break the loop as NONE of the items in this group are worth iterating.
				 */
				if (!i->second->IsBurstable())
					break;

				this->WriteLine(CommandAddLine::Builder(i->second));
			}
		}
	}
}
Exemple #2
0
/** Send all XLines we know about */
void TreeSocket::SendXLines()
{
	char data[MAXBUF];
	const char* sn = ServerInstance->Config->GetSID().c_str();

	std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();

	for (std::vector<std::string>::const_iterator it = types.begin(); it != types.end(); ++it)
	{
		/* Expired lines are removed in XLineManager::GetAll() */
		XLineLookup* lookup = ServerInstance->XLines->GetAll(*it);

		/* lookup cannot be NULL in this case but a check won't hurt */
		if (lookup)
		{
			for (LookupIter i = lookup->begin(); i != lookup->end(); ++i)
			{
				/* Is it burstable? this is better than an explicit check for type 'K'.
				 * We break the loop as NONE of the items in this group are worth iterating.
				 */
				if (!i->second->IsBurstable())
					break;

				snprintf(data,MAXBUF,":%s ADDLINE %s %s %s %lu %lu :%s",sn, it->c_str(), i->second->Displayable(),
						i->second->source.c_str(),
						(unsigned long)i->second->set_time,
						(unsigned long)i->second->duration,
						i->second->reason.c_str());
				this->WriteLine(data);
			}
		}
	}
}
Exemple #3
0
/** Send G, Q, Z and E lines */
void TreeSocket::SendXLines(TreeServer* Current)
{
	char data[MAXBUF];
	std::string n = this->ServerInstance->Config->GetSID();
	const char* sn = n.c_str();

	std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();
	time_t current = ServerInstance->Time();

	for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); ++it)
	{
		XLineLookup* lookup = ServerInstance->XLines->GetAll(*it);

		if (lookup)
		{
			for (LookupIter i = lookup->begin(); i != lookup->end(); ++i)
			{
				/* Is it burstable? this is better than an explicit check for type 'K'.
				 * We break the loop as NONE of the items in this group are worth iterating.
				 */
				if (!i->second->IsBurstable())
					break;

				/* If it's expired, don't bother to burst it
				 */
				if (i->second->duration && current > i->second->expiry)
					continue;

				snprintf(data,MAXBUF,":%s ADDLINE %s %s %s %lu %lu :%s",sn, it->c_str(), i->second->Displayable(),
						i->second->source,
						(unsigned long)i->second->set_time,
						(unsigned long)i->second->duration,
						i->second->reason);
				this->WriteLine(data);
			}
		}
	}
}
	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;
	}