Example #1
0
void IRCDProto::Parse(const Anope::string &buffer, Anope::string &source, Anope::string &command, std::vector<Anope::string> &params)
{
	spacesepstream sep(buffer);

	if (buffer[0] == ':')
	{
		sep.GetToken(source);
		source.erase(0, 1);
	}

	sep.GetToken(command);
	
	for (Anope::string token; sep.GetToken(token);)
	{
		if (token[0] == ':')
		{
			if (!sep.StreamEnd())
				params.push_back(token.substr(1) + " " + sep.GetRemaining());
			else
				params.push_back(token.substr(1));
			break;
		}
		else
			params.push_back(token);
	}
}
Example #2
0
void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message)
{
	Anope::string versionstr;
	if (bi != StatServ)
		return;
	if (message[0] == '\1' && message[message.length() - 1] == '\1')
	{
		if (message.substr(0, 9).equals_ci("\1VERSION "))
		{
			if (u->HasExt("CTCPVERSION"))
				return;
			u->Extend<bool>("CTCPVERSION");

			versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
			if (versionstr.empty())
				return;
			query = "UPDATE `" + prefix + "user` "
				"SET version=@version@ "
				"WHERE nick=@nick@";
			query.SetValue("version", versionstr);
			query.SetValue("nick", u->nick);
			this->RunQuery(query);
		}
	}
}
Example #3
0
	static Anope::string Unescape(const Anope::string &string)
	{
		Anope::string ret = string;
		for (int i = 0; special[i].character.empty() == false; ++i)
			if (!special[i].replace.empty())
				ret = ret.replace_all_cs(special[i].replace, special[i].character);

		for (size_t i, last = 0; (i = string.find("&#", last)) != Anope::string::npos;)
		{
			last = i + 1;

			size_t end = string.find(';', i);
			if (end == Anope::string::npos)
				break;

			Anope::string ch = string.substr(i + 2, end - (i + 2));

			if (ch.empty())
				continue;

			long l;
			if (!ch.empty() && ch[0] == 'x')
				l = strtol(ch.substr(1).c_str(), NULL, 16);
			else
				l = strtol(ch.c_str(), NULL, 10);

			if (l > 0 && l < 256)
				ret = ret.replace_all_cs("&#" + ch + ";", Anope::string(l));
		}

		return ret;
	}
Example #4
0
/** The following comes from InspIRCd to get the full path of the Anope executable
 */
static Anope::string GetFullProgDir(const Anope::string &argv0)
{
	char buffer[PATH_MAX];
#ifdef _WIN32
	/* Windows has specific API calls to get the EXE path that never fail.
	 * For once, Windows has something of use, compared to the POSIX code
	 * for this, this is positively neato.
	 */
	if (GetModuleFileName(NULL, buffer, PATH_MAX))
	{
		Anope::string fullpath = buffer;
		Anope::string::size_type n = fullpath.rfind("\\");
		Anope::ServicesBin = fullpath.substr(n + 1, fullpath.length());
		return fullpath.substr(0, n);
	}
#else
	// Get the current working directory
	if (getcwd(buffer, PATH_MAX))
	{
		Anope::string remainder = argv0;

		Anope::ServicesBin = remainder;
		Anope::string::size_type n = Anope::ServicesBin.rfind("/");
		Anope::string fullpath;
		if (Anope::ServicesBin[0] == '/')
			fullpath = Anope::ServicesBin.substr(0, n);
		else
			fullpath = Anope::string(buffer) + "/" + Anope::ServicesBin.substr(0, n);
		Anope::ServicesBin = Anope::ServicesBin.substr(n + 1, remainder.length());
		return fullpath;
	}
#endif
	return "/";
}
Example #5
0
cidr::cidr(const Anope::string &ip)
{
	bool ipv6 = ip.find(':') != Anope::string::npos;
	size_t sl = ip.find_last_of('/');

	if (sl == Anope::string::npos)
	{
		this->cidr_ip = ip;
		this->cidr_len = ipv6 ? 128 : 32;
		this->addr.pton(ipv6 ? AF_INET6 : AF_INET, ip);
	}
	else
	{
		Anope::string real_ip = ip.substr(0, sl);
		Anope::string cidr_range = ip.substr(sl + 1);

		this->cidr_ip = real_ip;
		this->cidr_len = ipv6 ? 128 : 32;
		try
		{
			if (cidr_range.is_pos_number_only())
				this->cidr_len = convertTo<unsigned int>(cidr_range);
		}
		catch (const ConvertException &) { }
		this->addr.pton(ipv6 ? AF_INET6 : AF_INET, real_ip);
	}
}
Example #6
0
NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(true), desc(descending)
{
	Anope::string error;
	commasepstream sep(list);
	Anope::string token;

	sep.GetToken(token);
	if (token.empty())
		token = list;
	do
	{
		size_t t = token.find('-');

		if (t == Anope::string::npos)
		{
			unsigned num = convertTo<unsigned>(token, error, false);
			if (error.empty())
				numbers.insert(num);
			else
			{
				if (!this->InvalidRange(list))
				{
					is_valid = false;
					return;
				}
			}
		}
		else
		{
			Anope::string error2;
			unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false);
			unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false);
			if (error.empty() && error2.empty())
			{
				for (unsigned i = num1; i <= num2; ++i)
					numbers.insert(i);
			}
			else
			{
				if (!this->InvalidRange(list))
				{
					is_valid = false;
					return;
				}
			}
		}
	} while (sep.GetToken(token));
}
Example #7
0
/**
 * Checks whether we have a valid, common e-mail address.
 * This is NOT entirely RFC compliant, and won't be so, because I said
 * *common* cases. ;) It is very unlikely that e-mail addresses that
 * are really being used will fail the check.
 *
 * @param email Email to Validate
 * @return bool
 */
bool MailValidate(const Anope::string &email)
{
	bool has_period = false;

	static char specials[] = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '};

	if (email.empty())
		return false;
	Anope::string copy = email;

	size_t at = copy.find('@');
	if (at == Anope::string::npos)
		return false;
	Anope::string domain = copy.substr(at + 1);
	copy = copy.substr(0, at);

	/* Don't accept empty copy or domain. */
	if (copy.empty() || domain.empty())
		return false;

	/* Check for forbidden characters in the name */
	for (unsigned i = 0, end = copy.length(); i < end; ++i)
	{
		if (copy[i] <= 31 || copy[i] >= 127)
			return false;
		for (unsigned int j = 0; j < 13; ++j)
			if (copy[i] == specials[j])
				return false;
	}

	/* Check for forbidden characters in the domain */
	for (unsigned i = 0, end = domain.length(); i < end; ++i)
	{
		if (domain[i] <= 31 || domain[i] >= 127)
			return false;
		for (unsigned int j = 0; j < 13; ++j)
			if (domain[i] == specials[j])
				return false;
		if (domain[i] == '.')
		{
			if (!i || i == end - 1)
				return false;
			has_period = true;
		}
	}

	return has_period;
}
Example #8
0
	static bool GetData(Anope::string &content, Anope::string &tag, Anope::string &data)
	{
		if (content.empty())
			return false;

		Anope::string prev, cur;
		bool istag;

		do
		{
			prev = cur;
			cur.clear();

			int len = 0;
			istag = false;

			if (content[0] == '<')
			{
				len = content.find_first_of('>');
				istag = true;
			}
			else if (content[0] != '>')
			{
				len = content.find_first_of('<');
			}

			if (len)
			{
				if (istag)
				{
					cur = content.substr(1, len - 1);
					content.erase(0, len + 1);
					while (!content.empty() && content[0] == ' ')
						content.erase(content.begin());
				}
				else
				{
					cur = content.substr(0,len);
					content.erase(0, len);
				}
			}
		}
		while (istag && !content.empty());

		tag = Unescape(prev);
		data = Unescape(cur);
		return !istag && !data.empty();
	}
Example #9
0
void plexus::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost)
{
	Anope::string sid = uid.substr(0, 3);
	Server *s = Server::Find(sid);

	Uplink::Send(Me, "ENCAP", s ? s->GetName() : sid, "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc);
}
Example #10
0
	Anope::string GetAttribute(const Anope::string &command)
	{
		size_t sp = command.rfind(' ');
		if (sp != Anope::string::npos)
			return command.substr(sp + 1);
		return command;
	}
Example #11
0
	/* strip dots from username, and remove anything after the first + */
	Anope::string CleanMail(const Anope::string &email)
	{
		size_t host = email.find('@');
		if (host == Anope::string::npos)
			return email;

		Anope::string username = email.substr(0, host);
		username = username.replace_all_cs(".", "");

		size_t sz = username.find('+');
		if (sz != Anope::string::npos)
			username = username.substr(0, sz);

		Anope::string cleaned = username + email.substr(host);
		logger.Debug("cleaned {0} to {1}", email, cleaned);
		return cleaned;
	}
Example #12
0
	void DoAdd(CommandSource &source, ChanServ::Channel *ci, const Anope::string &word)
	{
		size_t pos = word.rfind(' ');
		BadWordType bwtype = BW_ANY;
		Anope::string realword = word;

		if (pos != Anope::string::npos)
		{
			Anope::string opt = word.substr(pos + 1);
			if (!opt.empty())
			{
				if (opt.equals_ci("SINGLE"))
					bwtype = BW_SINGLE;
				else if (opt.equals_ci("START"))
					bwtype = BW_START;
				else if (opt.equals_ci("END"))
					bwtype = BW_END;
			}
			realword = word.substr(0, pos);
		}

		unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax");
		if (badwords->GetBadWordCount(ci) >= badwordsmax)
		{
			source.Reply(_("Sorry, you can only have \002{0}\002 bad words entries on a channel."), badwordsmax);
			return;
		}

		bool casesensitive = Config->GetModule(this->module)->Get<bool>("casesensitive");

		for (BadWord *bw : badwords->GetBadWords(ci))
			if ((casesensitive && realword.equals_cs(bw->GetWord())) || (!casesensitive && realword.equals_ci(bw->GetWord())))
			{
				source.Reply(_("\002{0}\002 already exists in \002{1}\002 bad words list."), bw->GetWord(), ci->GetName());
				return;
			}

		bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
		Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword;
		badwords->AddBadWord(ci, realword, bwtype);

		source.Reply(_("\002{0}\002 added to \002{1}\002 bad words list."), realword, ci->GetName());
	}
Example #13
0
/**
 * Is the given nick a network service
 * @param nick to check
 * @param int Check if botserv bots
 * @return int
 */
bool nickIsServices(const Anope::string &tempnick, bool bot)
{
	if (tempnick.empty())
		return false;

	Anope::string nick = tempnick;

	size_t at = nick.find('@');
	if (at != Anope::string::npos)
	{
		Anope::string servername = nick.substr(at + 1);
		if (!servername.equals_ci(Config->ServerName))
			return false;
		nick = nick.substr(0, at);
	}

	BotInfo *bi = findbot(nick);
	if (bi)
		return bot ? true : bi->HasFlag(BI_CORE);
	return false;
}
Example #14
0
	bool IsValid(const Anope::string &value) const
	{
		try
		{
			Anope::string rest;
			if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
				return true;
		}
		catch (const ConvertException &) { }

		return false;
	}
Example #15
0
void Message::Mode::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
	Anope::string buf;
	for (unsigned i = 1; i < params.size(); ++i)
		buf += " " + params[i];

	if (IRCD->IsChannelValid(params[0]))
	{
		Channel *c = Channel::Find(params[0]);

		if (c)
			c->SetModesInternal(source, buf.substr(1), 0);
	}
	else
	{
		User *u = User::Find(params[0]);

		if (u)
			u->SetModesInternal(source, "%s", buf.substr(1).c_str());
	}
}
Example #16
0
	void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &chans)
	{
		std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();
		Anope::string delchans;
		Anope::string notfoundchans;
		commasepstream sep(chans);

		for (Anope::string chan; sep.GetToken(chan);)
		{
			unsigned i = 0;
			for (; i < channels.size(); ++i)
				if (channels[i]->GetChannel().equals_ci(chan))
					break;

			if (i == channels.size())
				notfoundchans += chan + ", ";
			else
			{
				delete channels[i];
				delchans += chan + ", ";
			}
		}

		if (!notfoundchans.empty())
		{
			notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2);
			source.Reply(_("\002{0}\002 was not found on the auto join list of \002{1}\002."), notfoundchans, nc->GetDisplay());
		}

		if (delchans.empty())
			return;

		delchans = delchans.substr(0, delchans.length() - 2);
		Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->GetDisplay();
		source.Reply(_("\002{0}\002 was removed from the auto join list of \002{1}\002."), delchans, nc->GetDisplay());
	}
Example #17
0
/** Called on startup to organize our starting arguments in a better way
 * and check for errors
 * @param ac number of args
 * @param av args
 */
static void ParseCommandLineArguments(int ac, char **av)
{
	for (int i = 1; i < ac; ++i)
	{
		Anope::string option = av[i];
		Anope::string param;
		while (!option.empty() && option[0] == '-')
			option.erase(option.begin());
		size_t t = option.find('=');
		if (t != Anope::string::npos)
		{
			param = option.substr(t + 1);
			option.erase(t);
		}

		if (option.empty())
			continue;

		CommandLineArguments.push_back(std::make_pair(option, param));
	}
}
Example #18
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
		if (Anope::ReadOnly)
		{
			source.Reply(_("Services are in read-only mode."));
			return;
		}

		User *u = source.GetUser();
		NickServ::Nick *na = NickServ::FindNick(source.GetNick());
		if (!na || na->GetAccount() != source.GetAccount())
		{
			source.Reply(_("Access denied.")); //XXX with nonickownership this should be allowed.
			return;
		}

		if (source.GetAccount()->HasFieldS("UNCONFIRMED"))
		{
			source.Reply(_("You must confirm your account before you may request a vhost."));
			return;
		}

		Anope::string rawhostmask = params[0];

		Anope::string user, host;
		size_t a = rawhostmask.find('@');

		if (a == Anope::string::npos)
			host = rawhostmask;
		else
		{
			user = rawhostmask.substr(0, a);
			host = rawhostmask.substr(a + 1);
		}

		if (host.empty())
		{
			this->OnSyntaxError(source, "");
			return;
		}

		if (!user.empty())
		{
			if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
			{
				source.Reply(_("The username \002{0}\002 is too long, please use a username shorter than %d characters."), Config->GetBlock("networkinfo")->Get<unsigned>("userlen"));
				return;
			}

			if (!IRCD->CanSetVIdent)
			{
				source.Reply(_("Vhosts may not contain a username."));
				return;
			}

			if (!IRCD->IsIdentValid(user))
			{
				source.Reply(_("The requested username is not valid."));
				return;
			}
		}

		if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
		{
			source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
			return;
		}

		if (!IRCD->IsHostValid(host))
		{
			source.Reply(_("The requested hostname is not valid."));
			return;
		}

		time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
		if (Config->GetModule(this->GetOwner())->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
		{
			source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay);
			u->lastmemosend = Anope::CurTime;
			return;
		}

		HostRequest *req = Serialize::New<HostRequest *>();
		req->SetNick(na);
		req->SetIdent(user);
		req->SetHost(host);
		req->SetTime(Anope::CurTime);

		source.Reply(_("Your vhost has been requested."));
		this->SendMemos(source, user, host);
		Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
	}
Example #19
0
void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
	const Anope::string &receiver = params[0];
	Anope::string message = params[1];

	User *u = source.GetUser();

	if (IRCD->IsChannelValid(receiver))
	{
		Channel *c = Channel::Find(receiver);
		if (c)
		{
			EventManager::Get()->Dispatch(&Event::Privmsg::OnPrivmsg, u, c, message);
		}
	}
	else
	{
		/* If a server is specified (nick@server format), make sure it matches
		 * us, and strip it off. */
		Anope::string botname = receiver;
		size_t s = receiver.find('@');
		bool nick_only = false;
		if (s != Anope::string::npos)
		{
			Anope::string servername(receiver.begin() + s + 1, receiver.end());
			botname = botname.substr(0, s);
			nick_only = true;
			if (!servername.equals_ci(Me->GetName()))
				return;
		}
		else if (!IRCD->RequiresID && Config->UseStrictPrivmsg)
		{
			ServiceBot *bi = ServiceBot::Find(receiver);
			if (!bi)
				return;
			Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
			u->SendMessage(bi, _("\"/msg %s\" is no longer supported.  Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str());
			return;
		}

		ServiceBot *bi = ServiceBot::Find(botname, nick_only);

		if (bi)
		{
			if (message[0] == '\1' && message[message.length() - 1] == '\1')
			{
				if (message.substr(0, 6).equals_ci("\1PING "))
				{
					Anope::string buf = message;
					buf.erase(buf.begin());
					buf.erase(buf.end() - 1);
					IRCD->SendCTCP(bi, u->nick, "%s", buf.c_str());
				}
				else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
				{
					Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
					IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
				}
				return;
			}

			EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotPrivmsg::OnBotPrivmsg, u, bi, message);
			if (MOD_RESULT == EVENT_STOP)
				return;

			bi->OnMessage(u, message);
		}
	}

	return;
}
Example #20
0
bool IRCdMessage::OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> &params)
{
	const Anope::string &receiver = params.size() > 0 ? params[0] : "";
	Anope::string message = params.size() > 1 ? params[1] : "";

	/* Messages from servers can happen on some IRCds, check for . */
	if (source.empty() || receiver.empty() || message.empty() || source.find('.') != Anope::string::npos)
		return true;

	User *u = finduser(source);

	if (!u)
	{
		Log() << message << ": user record for " << source << " not found";

		BotInfo *bi = findbot(receiver);
		if (bi)
			ircdproto->SendMessage(bi, source, "%s", "Internal error - unable to process request.");

		return true;
	}

	if (receiver[0] == '#')
	{
		Channel *c = findchan(receiver);
		if (c)
		{
			FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message));
		}
	}
	else
	{
		/* If a server is specified (nick@server format), make sure it matches
		 * us, and strip it off. */
		Anope::string botname = receiver;
		size_t s = receiver.find('@');
		if (s != Anope::string::npos)
		{
			Anope::string servername(receiver.begin() + s + 1, receiver.end());
			botname = botname.substr(0, s);
			if (!servername.equals_ci(Config->ServerName))
				return true;
		}
		else if (Config->UseStrictPrivMsg)
		{
			BotInfo *bi = findbot(receiver);
			if (!bi)
				return true;
			Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source;
			u->SendMessage(bi, _("\"/msg %s\" is no longer supported.  Use \"/msg %s@%s\" or \"/%s\" instead."), receiver.c_str(), receiver.c_str(), Config->ServerName.c_str(), receiver.c_str());
			return true;
		}

		BotInfo *bi = findbot(botname);

		if (bi)
		{
			EventReturn MOD_RESULT;
			FOREACH_RESULT(I_OnBotPrivmsg, OnBotPrivmsg(u, bi, message));
			if (MOD_RESULT == EVENT_STOP)
				return true;

			if (message[0] == '\1' && message[message.length() - 1] == '\1')
			{
				if (message.substr(0, 6).equals_ci("\1PING "))
				{
					Anope::string buf = message;
					buf.erase(buf.begin());
					buf.erase(buf.end() - 1);
					ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str());
				}
				else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
				{
					Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
					ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str());
				}
				return true;
			}
			
			bi->OnMessage(u, message);
		}
	}

	return true;
}
Example #21
0
	EventReturn OnLoadDatabase() override
	{
		const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<Anope::string>("database", "anope.db");

		std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
		if (!fd.is_open())
		{
			Log(this) << "Unable to open " << db_name << " for reading!";
			return EVENT_STOP;
		}

		Serialize::TypeBase *type = nullptr;
		Serialize::Object *obj = nullptr;
		for (Anope::string buf; std::getline(fd, buf.str());)
		{
			if (buf.find("OBJECT ") == 0)
			{
				Anope::string t = buf.substr(7);
				if (obj)
					Log(LOG_DEBUG) << "obj != null but got OBJECT";
				if (type)
					Log(LOG_DEBUG) << "type != null but got OBJECT";
				type = Serialize::TypeBase::Find(t);
				obj = nullptr;
			}
			else if (buf.find("ID ") == 0)
			{
				if (!type || obj)
					continue;

				try
				{
					Serialize::ID id = convertTo<Serialize::ID>(buf.substr(3));
					obj = type->Require(id);
				}
				catch (const ConvertException &)
				{
					Log(LOG_DEBUG) << "Unable to parse object id " << buf.substr(3);
				}
			}
			else if (buf.find("DATA ") == 0)
			{
				if (!type)
					continue;

				if (!obj)
					obj = type->Create();

				size_t sp = buf.find(' ', 5); // Skip DATA
				if (sp == Anope::string::npos)
					continue;

				Anope::string key = buf.substr(5, sp - 5), value = buf.substr(sp + 1);

				Serialize::FieldBase *field = type->GetField(key);
				if (field)
					field->UnserializeFromString(obj, value);
			}
			else if (buf.find("END") == 0)
			{
				type = nullptr;
				obj = nullptr;
			}
		}

		fd.close();

		loaded = true;
		return EVENT_STOP;
	}
Example #22
0
int main(int ac, char **av, char **envp)
{
	BinaryDir = GetFullProgDir(av[0]);
	if (BinaryDir[BinaryDir.length() - 1] == '.')
		BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2);

#ifdef _WIN32
	Anope::string::size_type n = BinaryDir.rfind('\\');
#else
	Anope::string::size_type n = BinaryDir.rfind('/');
#endif
	Anope::ServicesDir = BinaryDir.substr(0, n);

#ifdef _WIN32
	/* Clean out the module runtime directory prior to running, just in case files were left behind during a previous run */
	ModuleManager::CleanupRuntimeDirectory();

	OnStartup();
#endif

	try
	{
		/* General initialization first */
		Anope::Init(ac, av);
	}
	catch (const CoreException &ex)
	{
		Anope::Logger.Log(ex.GetReason());
		return -1;
	}

	try
	{
		Uplink::Connect();
	}
	catch (const SocketException &ex)
	{
		Anope::Logger.Terminal(_("Unable to connect to uplink #{0} ({1}:{2}): {3}"), Anope::CurrentUplink + 1, Config->Uplinks[Anope::CurrentUplink].host, Config->Uplinks[Anope::CurrentUplink].port, ex.GetReason());
	}

	/* Set up timers */
	time_t last_check = Anope::CurTime;
	ExpireTimer expireTimer(Config->GetBlock("options")->Get<time_t>("expiretimeout", "30m"));
	Uplink::PingTimer pingTimer(30);

	/*** Main loop. ***/
	while (!Anope::Quitting)
	{
		Anope::Logger.Debug2("Top of main loop");

		/* Process timers */
		if (Anope::CurTime - last_check >= Config->TimeoutCheck)
		{
			TimerManager::TickTimers(Anope::CurTime);
			last_check = Anope::CurTime;
		}

		/* Process the socket engine */
		SocketEngine::Process();

		if (Anope::Signal)
			Anope::HandleSignal();
	}

	if (Anope::Restarting)
	{
		EventManager::Get()->Dispatch(&Event::Restart::OnRestart);
	}
	else
	{
		EventManager::Get()->Dispatch(&Event::Shutdown::OnShutdown);
	}

	if (Anope::QuitReason.empty())
		Anope::QuitReason = "Terminating, reason unknown";
	Anope::Logger.Log(Anope::QuitReason);

	delete UplinkSock;

	ModuleManager::UnloadAll();
	SocketEngine::Shutdown();
	for (Module *m; (m = ModuleManager::FindFirstOf(PROTOCOL)) != NULL;)
		ModuleManager::UnloadModule(m, NULL);

#ifdef _WIN32
	ModuleManager::CleanupRuntimeDirectory();

	OnShutdown();
#endif

	if (Anope::Restarting)
	{
		chdir(BinaryDir.c_str());
		Anope::string sbin = "./" + Anope::ServicesBin;
		av[0] = const_cast<char *>(sbin.c_str());
		execve(Anope::ServicesBin.c_str(), av, envp);
		Anope::Logger.Log("Restart failed");
		Anope::ReturnValue = -1;
	}

	return Anope::ReturnValue;
}
Example #23
0
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
{
	Anope::string n, u, h;

	size_t at = fh.find('@');
	if (at != Anope::string::npos)
	{
		this->host = fh.substr(at + 1);

		const Anope::string &nu = fh.substr(0, at);

		size_t ex = nu.find('!');
		if (ex != Anope::string::npos)
		{
			this->user = nu.substr(ex + 1);
			this->nick = nu.substr(0, ex);
		}
		else
			this->user = nu;
	}
	else
	{
		if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos)
			this->host = fh;
		else
			this->nick = fh;
	}
	
	at = this->host.find('#');
	if (at != Anope::string::npos)
	{
		this->real = this->host.substr(at + 1);
		this->host = this->host.substr(0, at);
	}
	
	/* If the mask is all *'s it will match anything, so just clear it */
	if (this->nick.find_first_not_of("*") == Anope::string::npos)
		this->nick.clear();
	
	if (this->user.find_first_not_of("*") == Anope::string::npos)
		this->user.clear();
	
	if (this->host.find_first_not_of("*") == Anope::string::npos)
		this->host.clear();
	else
	{
		/* Host might be a CIDR range */
		size_t sl = this->host.find_last_of('/');
		if (sl != Anope::string::npos)
		{
			const Anope::string &cidr_ip = this->host.substr(0, sl),
						&cidr_range = this->host.substr(sl + 1);

			sockaddrs addr(cidr_ip);

			try
			{
				if (addr.valid() && cidr_range.is_pos_number_only())
				{
					this->cidr_len = convertTo<unsigned short>(cidr_range);
					/* If we got here, cidr_len is a valid number.
					 * If cidr_len is >32 (or 128) it is handled later in
					 * cidr::match
					 */

					this->host = cidr_ip;

					Log(LOG_DEBUG) << "Ban " << m << " has cidr " << this->cidr_len;
				}
			}
			catch (const ConvertException &) { }
		}
	}

	if (this->real.find_first_not_of("*") == Anope::string::npos)
		this->real.clear();
}
Example #24
0
/** Main process routine
 * @param buffer A raw line from the uplink to do things with
 */
void process(const Anope::string &buffer)
{
	/* If debugging, log the buffer */
	Log(LOG_RAWIO) << "Received: " << buffer;

	/* Strip all extra spaces */
	Anope::string buf = buffer;
	buf = buf.replace_all_cs("  ", " ");

	if (buf.empty())
		return;

	Anope::string source;
	if (buf[0] == ':')
	{
		size_t space = buf.find_first_of(" ");
		if (space == Anope::string::npos)
			return;
		source = buf.substr(1, space - 1);
		buf = buf.substr(space + 1);
		if (source.empty() || buf.empty())
			return;
	}

	spacesepstream buf_sep(buf);
	Anope::string buf_token;

	Anope::string command = buf;
	if (buf_sep.GetToken(buf_token))
		command = buf_token;
	
	std::vector<Anope::string> params;
	while (buf_sep.GetToken(buf_token))
	{
		if (buf_token[0] == ':')
		{
			if (!buf_sep.StreamEnd())
				params.push_back(buf_token.substr(1) + " " + buf_sep.GetRemaining());
			else
				params.push_back(buf_token.substr(1));
			break;
		}
		else
			params.push_back(buf_token);
	}

	if (protocoldebug)
	{
		Log() << "Source : " << (source.empty() ? "No source" : source);
		Log() << "Command: " << command;

		if (params.empty())
			Log() << "No params";
		else
			for (unsigned i = 0; i < params.size(); ++i)
				Log() << "params " << i << ": " << params[i];
	}

	std::vector<Message *> messages = Anope::FindMessage(command);

	if (!messages.empty())
	{
		bool retVal = true;

		for (std::vector<Message *>::iterator it = messages.begin(), it_end = messages.end(); retVal == true && it != it_end; ++it)
		{
			Message *m = *it;

			if (m->func)
				retVal = m->func(source, params);
		}
	}
	else
		Log(LOG_DEBUG) << "unknown message from server (" << buffer << ")";
}
Example #25
0
	void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) override
	{
		Server *s = Server::Find(uid.substr(0, 3));
		Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", "*", "*", acc);
	}
Example #26
0
void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Replacements &r)
{
	int fd = open((template_base + "/" + this->file_name).c_str(), O_RDONLY);
	if (fd < 0)
	{
		Log(LOG_NORMAL, "httpd") << "Error serving file " << page_name << " (" << (template_base + "/" + this->file_name) << "): " << strerror(errno);

		client->SendError(HTTP_PAGE_NOT_FOUND, "Page not found");
		return;
	}

	Anope::string buf;

	int i;
	char buffer[BUFSIZE];
	while ((i = read(fd, buffer, sizeof(buffer) - 1)) > 0)
	{
		buffer[i] = 0;
		buf += buffer;
	}

	close(fd);

	Anope::string finished;

	bool escaped = false;
	for (unsigned j = 0; j < buf.length(); ++j)
	{
		if (buf[j] == '\\' && j + 1 < buf.length() && (buf[j + 1] == '{' || buf[j + 1] == '}'))
			escaped = true;
		else if (buf[j] == '{' && !escaped)
		{
			size_t f = buf.substr(j).find('}');
			if (f == Anope::string::npos)
				break;
			const Anope::string &content = buf.substr(j + 1, f - 1);

			if (content.find("IF ") == 0)
			{
				std::vector<Anope::string> tokens;
				spacesepstream(content).GetTokens(tokens);

				if (tokens.size() == 4 && tokens[1] == "EQ")
				{
					Anope::string first = FindReplacement(r, tokens[2]), second = FindReplacement(r, tokens[3]);
					if (first.empty())
						first = tokens[2];
					if (second.empty())
						second = tokens[3];

					bool stackok = IfStack.empty() || IfStack.top();
					IfStack.push(stackok && first == second);
				}
				else if (tokens.size() == 3 && tokens[1] == "EXISTS")
				{
					bool stackok = IfStack.empty() || IfStack.top();
					IfStack.push(stackok && r.count(tokens[2]) > 0);
				}
				else
					Log() << "Invalid IF in web template " << this->file_name;
			}
			else if (content == "ELSE")
			{
				if (IfStack.empty())
					Log() << "Invalid ELSE with no stack in web template" << this->file_name;
				else
				{
					bool old = IfStack.top();
					IfStack.pop(); // Pop off previous if()
					bool stackok = IfStack.empty() || IfStack.top();
					IfStack.push(stackok && !old); // Push back the opposite of what was popped
				}
			}
			else if (content == "END IF")
			{
				if (IfStack.empty())
					Log() << "END IF with empty stack?";
				else
					IfStack.pop();
			}
			else if (content.find("FOR ") == 0)
			{
				std::vector<Anope::string> tokens;
				spacesepstream(content).GetTokens(tokens);

				if (tokens.size() != 4 || tokens[2] != "IN")
					Log() << "Invalid FOR in web template " << this->file_name;
				else
				{
					std::vector<Anope::string> temp_variables, real_variables;
					commasepstream(tokens[1]).GetTokens(temp_variables);
					commasepstream(tokens[3]).GetTokens(real_variables);

					if (temp_variables.size() != real_variables.size())
						Log() << "Invalid FOR in web template " << this->file_name << " variable mismatch";
					else
						ForLoop::Stack.push_back(ForLoop(j + f, r, temp_variables, real_variables));
				}
			}
			else if (content == "END FOR")
			{
				if (ForLoop::Stack.empty())
					Log() << "END FOR with empty stack?";
				else
				{
					ForLoop &fl = ForLoop::Stack.back();
					if (fl.finished(r))
						ForLoop::Stack.pop_back();
					else
					{
						fl.increment(r);
						if (fl.finished(r))
							ForLoop::Stack.pop_back();
						else
						{
							j = fl.start; // Move pointer back to start of the loop
							continue; // To prevent skipping over this block which doesn't exist anymore
						}
					}
				}
			}
			else if (content.find("INCLUDE ") == 0)
			{
				std::vector<Anope::string> tokens;
				spacesepstream(content).GetTokens(tokens);

				if (tokens.size() != 2)
					Log() << "Invalid INCLUDE in web template " << this->file_name;
				else
				{
					if (!finished.empty())
					{
						reply.Write(finished); // Write out what we have currently so we insert this files contents here
						finished.clear();
					}

					TemplateFileServer tfs(tokens[1]);
					tfs.Serve(server, page_name, client, message, reply, r);
				}
			}
			else
			{
				// If the if stack is empty or we are in a true statement
				bool ifok = IfStack.empty() || IfStack.top();
				bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r);

				if (ifok && forok)
				{
					const Anope::string &replacement = FindReplacement(r, content.substr(0, f - 1));
					finished += replacement;
				}
			}

			j += f; // Skip over this whole block
		}
		else
		{
			escaped = false;

			// If the if stack is empty or we are in a true statement
			bool ifok = IfStack.empty() || IfStack.top();
			bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r);

			if (ifok && forok)
				finished += buf[j];
		}
	}

	if (!finished.empty())
		reply.Write(finished);
}
Example #27
0
	void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) override
	{
		Server *s = Server::Find(uid.substr(0, 3));
		UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * * * " << acc;
	}
Example #28
0
	void DoAdd(CommandSource &source, NickServ::Account *nc, const Anope::string &chans, const Anope::string &keys)
	{
		std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();

		Anope::string addedchans;
		Anope::string alreadyadded;
		Anope::string invalidkey;
		commasepstream ksep(keys, true);
		commasepstream csep(chans);
		for (Anope::string chan, key; csep.GetToken(chan);)
		{
			ksep.GetToken(key);

			unsigned i = 0;
			for (; i < channels.size(); ++i)
				if (channels[i]->GetChannel().equals_ci(chan))
					break;

			if (channels.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax"))
			{
				source.Reply(_("Sorry, the maximum of \002{0}\002 auto join entries has been reached."), Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax"));
				return;
			}

			if (i != channels.size())
				alreadyadded += chan + ", ";
			else if (IRCD->IsChannelValid(chan) == false)
	 			source.Reply(_("\002{0}\002 isn't a valid channel."), chan);
			else
			{
				Channel *c = Channel::Find(chan);
				Anope::string k;
				if (c && c->GetParam("KEY", k) && key != k)
				{
					invalidkey += chan + ", ";
					continue;
				}

				AutoJoin *entry = Serialize::New<AutoJoin *>();
				entry->SetOwner(nc);
				entry->SetChannel(chan);
				entry->SetKey(key);

				addedchans += chan + ", ";
			}
		}

		if (!alreadyadded.empty())
		{
			alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2);
			source.Reply(_("\002{0}\002 is already on the auto join list of \002{1}\002."), alreadyadded, nc->GetDisplay());
		}

		if (!invalidkey.empty())
		{
			invalidkey = invalidkey.substr(0, invalidkey.length() - 2);
			source.Reply(_("\002{0}\002 had an invalid key specified, and was ignored."), invalidkey);
		}

		if (addedchans.empty())
			return;

		addedchans = addedchans.substr(0, addedchans.length() - 2);
		Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->GetDisplay();
		source.Reply(_("\002{0}\002 added to the auto join list of \002{1}\002."), addedchans, nc->GetDisplay());
	}