Exemple #1
0
void User::WriteCommonQuit(const std::string &normal_text, const std::string &oper_text)
{
	char tb1[MAXBUF];
	char tb2[MAXBUF];

	if (this->registered != REG_ALL)
		return;

	already_sent_t uniq_id = ++LocalUser::already_sent_id;

	snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str());
	snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str());
	std::string out1 = tb1;
	std::string out2 = tb2;

	UserChanList include_c(chans);
	std::map<User*,bool> exceptions;

	FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));

	for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
	{
		LocalUser* u = IS_LOCAL(i->first);
		if (u && !u->quitting)
		{
			u->already_sent = uniq_id;
			if (i->second)
				u->Write(IS_OPER(u) ? out2 : out1);
		}
	}
	for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
	{
		const UserMembList* ulist = (*v)->GetUsers();
		for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
		{
			LocalUser* u = IS_LOCAL(i->first);
			if (u && !u->quitting && (u->already_sent != uniq_id))
			{
				u->already_sent = uniq_id;
				u->Write(IS_OPER(u) ? out2 : out1);
			}
		}
	}
}
Exemple #2
0
void User::WriteCommonQuit(const std::string &normal_text, const std::string &oper_text)
{
	if (this->registered != REG_ALL)
		return;

	already_sent_t uniq_id = ++LocalUser::already_sent_id;

	const std::string normalMessage = ":" + this->GetFullHost() + " QUIT :" + normal_text;
	const std::string operMessage = ":" + this->GetFullHost() + " QUIT :" + oper_text;

	IncludeChanList include_c(chans.begin(), chans.end());
	std::map<User*,bool> exceptions;

	FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));

	for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
	{
		LocalUser* u = IS_LOCAL(i->first);
		if (u && !u->quitting)
		{
			u->already_sent = uniq_id;
			if (i->second)
				u->Write(u->IsOper() ? operMessage : normalMessage);
		}
	}
	for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v)
	{
		const UserMembList* ulist = (*v)->chan->GetUsers();
		for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
		{
			LocalUser* u = IS_LOCAL(i->first);
			if (u && (u->already_sent != uniq_id))
			{
				u->already_sent = uniq_id;
				u->Write(u->IsOper() ? operMessage : normalMessage);
			}
		}
	}
}
Exemple #3
0
void User::WriteCommonRaw(const std::string &line, bool include_self)
{
	if (this->registered != REG_ALL || quitting)
		return;

	LocalUser::already_sent_id++;

	IncludeChanList include_c(chans.begin(), chans.end());
	std::map<User*,bool> exceptions;

	exceptions[this] = include_self;

	FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));

	for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
	{
		LocalUser* u = IS_LOCAL(i->first);
		if (u && !u->quitting)
		{
			u->already_sent = LocalUser::already_sent_id;
			if (i->second)
				u->Write(line);
		}
	}
	for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v)
	{
		Channel* c = (*v)->chan;
		const UserMembList* ulist = c->GetUsers();
		for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
		{
			LocalUser* u = IS_LOCAL(i->first);
			if (u && u->already_sent != LocalUser::already_sent_id)
			{
				u->already_sent = LocalUser::already_sent_id;
				u->Write(line);
			}
		}
	}
}
Exemple #4
0
/**
 * This function is called once a second from the mainloop.
 * It is intended to do background checking on all the user structs, e.g.
 * stuff like ping checks, registration timeouts, etc.
 */
void UserManager::DoBackgroundUserStuff()
{
    /*
     * loop over all local users..
     */
    for (LocalUserList::iterator i = local_users.begin(); i != local_users.end(); ++i)
    {
        LocalUser* curr = *i;

        if (curr->quitting)
            continue;

        if (curr->CommandFloodPenalty || curr->eh.getSendQSize())
        {
            unsigned int rate = curr->MyClass->GetCommandRate();
            if (curr->CommandFloodPenalty > rate)
                curr->CommandFloodPenalty -= rate;
            else
                curr->CommandFloodPenalty = 0;
            curr->eh.OnDataReady();
        }

        switch (curr->registered)
        {
        case REG_ALL:
            if (ServerInstance->Time() > curr->nping)
            {
                // This user didn't answer the last ping, remove them
                if (!curr->lastping)
                {
                    time_t time = ServerInstance->Time() - (curr->nping - curr->MyClass->GetPingTime());
                    const std::string message = "Ping timeout: " + ConvToStr(time) + (time == 1 ? " seconds" : " second");
                    this->QuitUser(curr, message);
                    continue;
                }

                curr->Write("PING :" + ServerInstance->Config->ServerName);
                curr->lastping = 0;
                curr->nping = ServerInstance->Time() + curr->MyClass->GetPingTime();
            }
            break;
        case REG_NICKUSER:
            if (AllModulesReportReady(curr))
            {
                /* User has sent NICK/USER, modules are okay, DNS finished. */
                curr->FullConnect();
                continue;
            }
            break;
        }

        if (curr->registered != REG_ALL && (ServerInstance->Time() > (curr->age + curr->MyClass->GetRegTimeout())))
        {
            /*
             * registration timeout -- didnt send USER/NICK/HOST
             * in the time specified in their connection class.
             */
            this->QuitUser(curr, "Registration timeout");
            continue;
        }
    }
}
Exemple #5
0
/**
 * This function is called once a second from the mainloop.
 * It is intended to do background checking on all the user structs, e.g.
 * stuff like ping checks, registration timeouts, etc.
 */
void InspIRCd::DoBackgroundUserStuff()
{
	/*
	 * loop over all local users..
	 */
	LocalUserList::reverse_iterator count2 = this->Users->local_users.rbegin();
	while (count2 != this->Users->local_users.rend())
	{
		LocalUser *curr = *count2;
		count2++;

		if (curr->quitting)
			continue;

		if (curr->CommandFloodPenalty || curr->eh.getSendQSize())
		{
			unsigned int rate = curr->MyClass->GetCommandRate();
			if (curr->CommandFloodPenalty > rate)
				curr->CommandFloodPenalty -= rate;
			else
				curr->CommandFloodPenalty = 0;
			curr->eh.OnDataReady();
		}

		switch (curr->registered)
		{
			case REG_ALL:
				if (Time() > curr->nping)
				{
					// This user didn't answer the last ping, remove them
					if (!curr->lastping)
					{
						time_t time = this->Time() - (curr->nping - curr->MyClass->GetPingTime());
						char message[MAXBUF];
						snprintf(message, MAXBUF, "Ping timeout: %ld second%s", (long)time, time > 1 ? "s" : "");
						curr->lastping = 1;
						curr->nping = Time() + curr->MyClass->GetPingTime();
						this->Users->QuitUser(curr, message);
						continue;
					}

					curr->Write("PING :%s",this->Config->ServerName.c_str());
					curr->lastping = 0;
					curr->nping = Time()  +curr->MyClass->GetPingTime();
				}
				break;
			case REG_NICKUSER:
				if (AllModulesReportReady(curr))
				{
					/* User has sent NICK/USER, modules are okay, DNS finished. */
					curr->FullConnect();
					continue;
				}
				break;
		}

		if (curr->registered != REG_ALL && (Time() > (curr->age + curr->MyClass->GetRegTimeout())))
		{
			/*
			 * registration timeout -- didnt send USER/NICK/HOST
			 * in the time specified in their connection class.
			 */
			this->Users->QuitUser(curr, "Registration timeout");
			continue;
		}
	}
}
Exemple #6
0
void User::DoHostCycle(const std::string &quitline)
{
	char buffer[MAXBUF];

	if (!ServerInstance->Config->CycleHosts)
		return;

	already_sent_t silent_id = ++LocalUser::already_sent_id;
	already_sent_t seen_id = ++LocalUser::already_sent_id;

	UserChanList include_c(chans);
	std::map<User*,bool> exceptions;

	FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));

	for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
	{
		LocalUser* u = IS_LOCAL(i->first);
		if (u && !u->quitting)
		{
			if (i->second)
			{
				u->already_sent = seen_id;
				u->Write(quitline);
			}
			else
			{
				u->already_sent = silent_id;
			}
		}
	}
	for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
	{
		Channel* c = *v;
		snprintf(buffer, MAXBUF, ":%s JOIN %s", GetFullHost().c_str(), c->name.c_str());
		std::string joinline(buffer);
		Membership* memb = c->GetUser(this);
		std::string modeline = memb->modes;
		if (modeline.length() > 0)
		{
			for(unsigned int i=0; i < memb->modes.length(); i++)
				modeline.append(" ").append(nick);
			snprintf(buffer, MAXBUF, ":%s MODE %s +%s",
				ServerInstance->Config->CycleHostsFromUser ? GetFullHost().c_str() : ServerInstance->Config->ServerName.c_str(),
				c->name.c_str(), modeline.c_str());
			modeline = buffer;
		}

		const UserMembList *ulist = c->GetUsers();
		for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
		{
			LocalUser* u = IS_LOCAL(i->first);
			if (u == NULL || u == this)
				continue;
			if (u->already_sent == silent_id)
				continue;

			if (u->already_sent != seen_id)
			{
				u->Write(quitline);
				u->already_sent = seen_id;
			}
			u->Write(joinline);
			if (modeline.length() > 0)
				u->Write(modeline);
		}
	}
}