Exemple #1
1
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
		const Anope::string &target = params[0];
		const Anope::string &modes = params[1];

		Reference<Channel> c = Channel::Find(target);
		if (!c)
			source.Reply(_("Channel \002{0}\002 doesn't exist."), target);
		else if (c->bouncy_modes)
			source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
		else if (modes.equals_ci("CLEAR"))
		{
			bool all = params.size() > 2 && params[2].equals_ci("ALL");

			const Channel::ModeList chmodes = c->GetModes();
			for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end && c; ++it)
				c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false);

			if (!c)
			{
				source.Reply(_("Modes cleared on %s and the channel destroyed."), target.c_str());
				return;
			}

			if (all)
			{
				for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
				{
					ChanUserContainer *uc = it->second;

					if (uc->user->HasMode("OPER"))
						continue;

					for (size_t i = uc->status.Modes().length(); i > 0; --i)
						c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i - 1]), uc->user->GetUID(), false);
				}

				source.Reply(_("All modes cleared on \002{0}\002."), c->name);
			}
			else
				source.Reply(_("Non-status modes cleared on \002{0}\002."), c->name);
		}
		else
		{
			spacesepstream sep(modes + (params.size() > 2 ? " " + params[2] : ""));
			Anope::string mode;
			int add = 1;
			Anope::string log_modes, log_params;

			sep.GetToken(mode);
			for (unsigned i = 0; i < mode.length() && c; ++i)
			{
				char ch = mode[i];

				if (ch == '+')
				{
					add = 1;
					log_modes += "+";
					continue;
				}
				else if (ch == '-')
				{
					add = 0;
					log_modes += "-";
					continue;
				}

				ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
				if (!cm)
					continue;

				Anope::string param, param_log;
				if (cm->type != MODE_REGULAR)
				{
					if (cm->type == MODE_PARAM && !add && anope_dynamic_static_cast<ChannelModeParam *>(cm)->minus_no_arg)
						;
					else if (!sep.GetToken(param))
						continue;

					param_log = param;

					if (cm->type == MODE_STATUS)
					{
						User *targ = User::Find(param, true);
						if (targ == NULL || c->FindUser(targ) == NULL)
							continue;
						param = targ->GetUID();
					}
				}

				log_modes += cm->mchar;
				if (!param.empty())
					log_params += " " + param_log;

				if (add)
					c->SetMode(source.service, cm, param, false);
				else
					c->RemoveMode(source.service, cm, param, false);
			}

			if (!log_modes.replace_all_cs("+", "").replace_all_cs("-", "").empty())
				Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << (c ? c->name : target);
		}
	}
	void DoStats(CommandSource &source, const bool is_global, const std::vector<Anope::string> &params)
	{
		Anope::string display, channel;

		/*
		 * possible parameters are:
		 *   stats [channel] [nick]
		 *   stats [channel]
		 *   stats [nick]
		 *   stats
		 */

		switch (params.size())
		{
			case 2:
				channel = params[0];
				display = params[1];
				break;
			case 1:
				if (params[0][0] == '#')
					channel = params[0];
				else
				{
					if (NickAlias *na = NickAlias::Find(params[0]))
						display = na->nc->display;
					else
					{
						source.Reply(_("%s not found."), params[0].c_str());
						return;
					}
				}
				break;
		}

		if (display.empty())
			display = source.nc->display;

		try
		{
			SQL::Query query;
			query = "SELECT letters, words, line, smileys_happy+smileys_sad+smileys_other as smileys,"
				"actions FROM `" + prefix + "chanstats` "
				"WHERE `nick` = @nick@ AND `chan` = @channel@ AND `type` = 'total';";
			if (is_global || channel.empty())
				query.SetValue("channel", "");
			else
				query.SetValue("channel", channel);
			query.SetValue("nick", display);
			SQL::Result res = this->RunQuery(query);

			if (res.Rows() > 0)
			{
				if (is_global)
					source.Reply(_("Network stats for %s:"), display.c_str());
				else
					source.Reply(_("Channel stats for %s on %s:"), display.c_str(), channel.c_str());

				source.Reply(_("letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"),
						res.Get(0, "letters").c_str(), res.Get(0, "words").c_str(),
						res.Get(0, "line").c_str(), res.Get(0, "smileys").c_str(),
						res.Get(0, "actions").c_str());
			}
			else
				source.Reply(_("No stats for %s."), display.c_str());
		}
		catch (const SQL::Exception &ex)
		{
			Log(LOG_DEBUG) << ex.GetReason();
		}

	}
Exemple #3
0
 void Run(CommandSource &source, const std::vector<Flux::string> &params)
 {
     source.Reply("My PID is: \2%i\2", (int)getpid());
     Log(source.u, this) << "command to get navn's PID " << getpid();
 }
Exemple #4
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		if (subcommand.empty())
		{
			CommandInfo *help = source.service->FindCommand("generic/help");
			if (!help)
				return false;
			source.Reply(_("Sets various memo options. \037option\037 can be one of:\n"
			               "\n"
			               "    NOTIFY      Changes when you will be notified about\n"
			               "                new memos (only for nicknames)\n"
			               "    LIMIT       Sets the maximum number of memos you can\n"
			               "                receive\n"
			               "\n"
			               "Type \002{0}{1} {2} {3} \037option\037\002 for more information on a specific option."),
			               Config->StrictPrivmsg, source.service->nick, help->cname, source.command);
		}
		else if (subcommand.equals_ci("NOTIFY"))
			source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
			               "\n"
			               "Changes when you will be notified about new memos:\n"
			               "\n"
			               "    ON      You will be notified of memos when you log on,\n"
			               "            when you unset /AWAY, and when they are sent\n"
			               "            to you.\n"
			               "\n"
			               "    LOGON   You will only be notified of memos when you log\n"
			               "            on or when you unset /AWAY.\n"
			               "\n"
			               "    NEW     You will only be notified of memos when they\n"
			               "            are sent to you.\n"
			               "\n"
			               "    MAIL    You will be notified of memos by email as well as\n"
			               "            any other settings you have.\n"
			               "\n"
			               "    NOMAIL  You will not be notified of memos by email.\n"
			               "\n"
			               "    OFF     You will not receive any notification of memos.\n"
			               "\n"
			               "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
		else if (subcommand.equals_ci("LIMIT"))
		{
			int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
			if (source.IsServicesOper())
				source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
				               "\n"
				               "Sets the maximum number of memos a user or channel is allowed to have."
				               "  Setting the limit to 0 prevents the user from receiving any memos; setting it to \002NONE\002 allows the user to receive and keep as many memos as they want."
				               "  If you do not give a nickname or channel, your own limit is set.\n"
				               "\n"
				               "Adding \002HARD\002 prevents the user from changing the limit."
				               " Not adding \002HARD\002 has the opposite effect, allowing the user to change the limit, even if a previous limit was set.\n"
				               " \n"
				               "This use of the \002{0} LIMIT\002 command is limited to \002Services Operators\002."
				               " Other users may only enter a limit for themselves or a channel on which they have the \002MEMO\002 privilege on, may not remove their limit, may not set a limit above {1}, and may not set a hard limit."),
				               source.command, max_memos);
			else
				source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
				               "\n"
				              "Sets the maximum number of memos you, or the given channel, are allowed to have."
				              " If you set this to 0, no one will be able to send any memos to you."
				              "However, you cannot set this any higher than {0}."), max_memos);
		}
		else
			return false;

		return true;
	}
Exemple #5
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
		const Anope::string &channel = params[0];

		ChanServ::Channel *ci = ChanServ::Find(channel);
		if (ci == NULL)
		{
			source.Reply(_("Channel \002{0}\002 isn't registered."), channel);
			return;
		}

		if (!source.AccessFor(ci).HasPriv("SET") && !source.HasOverridePriv("chanserv/administration"))
		{
			source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "SET", ci->GetName());
			return;
		}

		if (params.size() == 1)
		{
			std::vector<LogSetting *> ls = ci->GetRefs<LogSetting *>();
			if (ls.empty())
			{
				source.Reply(_("There currently are no logging configurations for \002{0}\002."), ci->GetName());
				return;
			}

			ListFormatter list(source.GetAccount());
			list.AddColumn(_("Number")).AddColumn(_("Service")).AddColumn(_("Command")).AddColumn(_("Method")).AddColumn("");

			for (unsigned i = 0; i < ls.size(); ++i)
			{
				LogSetting *log = ls[i];

				ListFormatter::ListEntry entry;
				entry["Number"] = stringify(i + 1);
				entry["Service"] = log->GetCommandService();
				entry["Command"] = !log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName();
				entry["Method"] = log->GetMethod();
				entry[""] = log->GetExtra();
				list.AddEntry(entry);
			}

			source.Reply(_("Log list for \002{0}\002:"), ci->GetName());

			std::vector<Anope::string> replies;
			list.Process(replies);

			for (unsigned i = 0; i < replies.size(); ++i)
				source.Reply(replies[i]);
		}
		else if (params.size() > 2)
		{
			if (Anope::ReadOnly)
			{
				source.Reply(_("Services are in read-only mode."));
				return;
			}

			const Anope::string &command = params[1];
			const Anope::string &method = params[2];
			const Anope::string &extra = params.size() > 3 ? params[3] : "";

			size_t sl = command.find('/');
			if (sl == Anope::string::npos)
			{
				source.Reply(_("\002{0}\002 is not a valid command."), command);
				return;
			}

			Anope::string service = command.substr(0, sl),
				command_name = command.substr(sl + 1);
			ServiceBot *bi = ServiceBot::Find(service, true);

			Anope::string service_name;

			/* Allow either a command name or a service name. */
			if (bi && bi->commands.count(command_name))
			{
				/* Get service name from command */
				service_name = bi->commands[command_name].name;
			}
			else if (ServiceReference<Command>(command.lower()))
			{
				/* This is the service name, don't use any specific command */
				service_name = command;
				bi = NULL;
				command_name.clear();
			}
			else
			{
				source.Reply(_("\002{0}\002 is not a valid command."), command);
				return;
			}

			if (!method.equals_ci("MESSAGE") && !method.equals_ci("NOTICE") && !method.equals_ci("MEMO"))
			{
				source.Reply(_("\002%s\002 is not a valid logging method."));
				return;
			}

			for (unsigned i = 0; i < extra.length(); ++i)
				if (ModeManager::GetStatusChar(extra[i]) == 0)
				{
					source.Reply(_("\002%c\002 is an unknown status mode."), extra[i]);
					return;
				}

			std::vector<LogSetting *> ls = ci->GetRefs<LogSetting *>();
			for (unsigned i = ls.size(); i > 0; --i)
			{
				LogSetting *log = ls[i - 1];

				if (log->GetServiceName() == service_name && log->GetMethod().equals_ci(method) && command_name.equals_ci(log->GetCommandName()))
				{
					if (log->GetExtra() == extra)
					{
						logger.Command(source, ci, _("{source} used {command} on {channel} to remove logging for {0} with method {1}"),
							command, method + (extra.empty() ? "" : (" " + extra)));

						source.Reply(_("Logging for command \002{0}\002 on \002{1}\002 with log method \002{2}{3}{4}\002 has been removed."),
								!log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName(),
								!log->GetCommandService().empty() ? log->GetCommandService() : "any service", method, extra.empty() ? "" : " ", extra);
						log->Delete();
					}
					else
					{
						log->SetExtra(extra);

						logger.Command(source, ci, _("{source} used {command} on {channel} to change logging for {0} to method {1}"),
							command, method + (extra.empty() ? "" : (" " + extra)));

						source.Reply(_("Logging changed for command \002{0}\002 on \002{1}\002, now using log method \002{2}{3}{4]\002."),
								!log->GetCommandName().empty() ? log->GetCommandName() : log->GetServiceName(),
								!log->GetCommandService().empty() ? log->GetCommandService() : "any service", method, extra.empty() ? "" : " ", extra);
					}
					return;
				}
			}

			LogSetting *log = Serialize::New<LogSetting *>();
			log->SetChannel(ci);
			log->SetServiceName(service_name);
			if (bi)
				log->SetCommandService(bi->nick);
			log->SetCommandName(command_name);
			log->SetMethod(method);
			log->SetExtra(extra);
			log->SetCreated(Anope::CurTime);
			log->SetCreator(source.GetNick());

			logger.Command(source, ci,
					_("{source} used {command} on {channel} to log {0} to method {1}"), command, method + (extra.empty() ? "" : (" " + extra)));

			source.Reply(_("Logging is now active for command \002{0}\002 on \002{1}\002, using log method \002{2}{3}{4}\002."),
					!command_name.empty() ? command_name : service_name, bi ? bi->nick : "any service", method, extra.empty() ? "" : " ", extra);
		}
		else
		{
			this->OnSyntaxError(source, "");
		}
	}
Exemple #6
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Deactivates your vhost."));
		return true;
	}
Exemple #7
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Causes Services to shut down"));
		return true;
	}
Exemple #8
0
	bool Show(CommandSource &source, const Anope::string &what) const
	{
		return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
	}
Exemple #9
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
		const Anope::string &chan = params[0];

		User *u = source.GetUser();
		Channel *c = Channel::Find(chan);

		if (!c)
		{
			source.Reply(_("Channel \002{0}\002 doesn't exist."), chan);
			return;
		}

		ChanServ::Channel *ci = c->ci;
		if (!ci)
		{
			source.Reply(_("Channel \002{0}\002 isn't registered."), c->name);
			return;
		}

		if (!source.AccessFor(ci).HasPriv("INVITE") && !source.HasCommand("chanserv/invite"))
		{
			source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "INVITE", ci->GetName());
			return;
		}

		User *u2;
		if (params.size() == 1)
			u2 = u;
		else
			u2 = User::Find(params[1], true);

		if (!u2)
		{
			source.Reply(_("\002{0}\002 isn't currently online."), params.size() > 1 ? params[1] : source.GetNick());
			return;
		}

		if (c->FindUser(u2))
		{
			if (u2 == u)
				source.Reply(_("You are already in \002{0}\002!"), c->name);
			else
				source.Reply(_("\002{0}\002 is already in \002{1}\002!"), u2->nick, c->name);

			return;
		}

		bool override = !source.AccessFor(ci).HasPriv("INVITE");

		IRCD->SendInvite(ci->WhoSends(), c, u2);
		if (u2 != u)
		{
			source.Reply(_("\002{0}\002 has been invited to \002{1}\002."), u2->nick, c->name);
			u2->SendMessage(ci->WhoSends(), _("You have been invited to \002{0}\002 by \002{1}\002."), c->name, source.GetNick());
			Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
		}
Exemple #10
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());
	}
Exemple #11
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Allows Services Operators to change modes for any user. Parameters are the same as for the standard /MODE command."));
		return true;
	}
Exemple #12
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params)
	{
		const Anope::string &chan = params[0];
		const Anope::string &chdesc = params.size() > 1 ? params[1] : "";

		User *u = source.u;
		Channel *c = findchan(params[0]);
		ChannelInfo *ci = cs_findchan(params[0]);

		if (readonly)
			source.Reply(_("Sorry, channel registration is temporarily disabled."));
		else if (u->Account()->HasFlag(NI_UNCONFIRMED))
			source.Reply(_("You must confirm your account before you can register a channel."));
		else if (chan[0] == '&')
			source.Reply(_("Local channels cannot be registered."));
		else if (chan[0] != '#')
			source.Reply(CHAN_SYMBOL_REQUIRED);
		else if (!ircdproto->IsChannelValid(chan))
			source.Reply(CHAN_X_INVALID, chan.c_str());
		else if (ci)
			source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
		else if (c && !c->HasUserStatus(u, CMODE_OP))
			source.Reply(_("You must be a channel operator to register the channel."));
		else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
			source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
		else
		{
			ci = new ChannelInfo(chan);
			ci->SetFounder(u->Account());
			if (!chdesc.empty())
				ci->desc = chdesc;

			ci->mode_locks = def_mode_locks;
			for (ChannelInfo::ModeList::iterator it = ci->mode_locks.begin(), it_end = ci->mode_locks.end(); it != it_end; ++it)
			{
				it->second.setter = u->nick;
				it->second.ci = ci;
			}

			if (c && !c->topic.empty())
			{
				ci->last_topic = c->topic;
				ci->last_topic_setter = c->topic_setter;
				ci->last_topic_time = c->topic_time;
			}
			else
				ci->last_topic_setter = source.owner->nick;

			Log(LOG_COMMAND, u, this, ci);
			source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str());

			/* Implement new mode lock */
			if (c)
			{
				check_modes(c);

				ChannelMode *cm;
				if (u->FindChannel(c) != NULL)
				{
					/* On most ircds you do not receive the admin/owner mode till its registered */
					if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
						c->SetMode(NULL, cm, u->nick);
					else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
						c->RemoveMode(NULL, cm, u->nick);
				}

				/* Mark the channel as persistent */
				if (c->HasMode(CMODE_PERM))
					ci->SetFlag(CI_PERSIST);
				/* Persist may be in def cflags, set it here */
				else if (ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM)))
					c->SetMode(NULL, CMODE_PERM);
			}

			FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci));
		}
		return;
	}
Exemple #13
0
	void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
	{
		const Anope::string &mask = params.size() > 1 ? params[1] : "";

		if (session_service->GetExceptions().empty())
		{
			source.Reply(_("The session exception list is empty."));
			return;
		}

		if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
		{
			class ExceptionListCallback : public NumberList
			{
				ListFormatter &list;
			 public:
				ExceptionListCallback(ListFormatter &_list, const Anope::string &numlist) : NumberList(numlist, false), list(_list)
				{
				}

				void HandleNumber(unsigned Number)
				{
					if (!Number || Number > session_service->GetExceptions().size())
						return;

					Exception *e = session_service->GetExceptions()[Number - 1];

					ListFormatter::ListEntry entry;
					entry["Number"] = stringify(Number);
					entry["Mask"] = e->mask;
					entry["By"] = e->who;
					entry["Created"] = do_strftime(e->time);
					entry["Limit"] = stringify(e->limit);
					entry["Reason"] = e->reason;
					this->list.addEntry(entry);
				}
			}
			nl_list(list, mask);
			nl_list.Process();
		}
		else
		{
			for (unsigned i = 0, end = session_service->GetExceptions().size(); i < end; ++i)
			{
				Exception *e = session_service->GetExceptions()[i];
				if (mask.empty() || Anope::Match(e->mask, mask))
				{
					ListFormatter::ListEntry entry;
					entry["Number"] = stringify(i + 1);
					entry["Mask"] = e->mask;
					entry["By"] = e->who;
					entry["Created"] = do_strftime(e->time);
					entry["Limit"] = stringify(e->limit);
					entry["Reason"] = e->reason;
					list.addEntry(entry);
				}
			}
		}

		if (list.isEmpty())
			source.Reply(_("No matching entries on session-limit exception list."));
		else
		{
			source.Reply(_("Current Session Limit Exception list:"));
		
			std::vector<Anope::string> replies;
			list.Process(replies);

			for (unsigned i = 0; i < replies.size(); ++i)
				source.Reply(replies[i]);
		}
	}
Exemple #14
0
	void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
	{
		User *u = source.u;
		Anope::string mask, expiry, limitstr;
		unsigned last_param = 3;

		mask = params.size() > 1 ? params[1] : "";
		if (!mask.empty() && mask[0] == '+')
		{
			expiry = mask;
			mask = params.size() > 2 ? params[2] : "";
			last_param = 4;
		}

		limitstr = params.size() > last_param - 1 ? params[last_param - 1] : "";

		if (params.size() <= last_param)
		{
			this->OnSyntaxError(source, "ADD");
			return;
		}

		Anope::string reason = params[last_param];
		if (last_param == 3 && params.size() > 4)
			reason += " " + params[4];
		if (reason.empty())
		{
			this->OnSyntaxError(source, "ADD");
			return;
		}

		time_t expires = !expiry.empty() ? dotime(expiry) : Config->ExceptionExpiry;
		if (expires < 0)
		{
			source.Reply(BAD_EXPIRY_TIME);
			return;
		}
		else if (expires > 0)
			expires += Anope::CurTime;

		int limit = -1;
		try
		{
			limit = convertTo<int>(limitstr);
		}
		catch (const ConvertException &) { }

		if (limit < 0 || limit > static_cast<int>(Config->MaxSessionLimit))
		{
			source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), Config->MaxSessionLimit);
			return;
		}
		else
		{
			if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
			{
				source.Reply(_("Invalid hostmask. Only real hostmasks are valid, as exceptions are not matched against nicks or usernames."));
				return;
			}

			for (std::vector<Exception *>::iterator it = session_service->GetExceptions().begin(), it_end = session_service->GetExceptions().end(); it != it_end; ++it)
			{
				Exception *e = *it;
				if (e->mask.equals_ci(mask))
				{
					if (e->limit != limit)
					{
						e->limit = limit;
						source.Reply(_("Exception for \002%s\002 has been updated to %d."), mask.c_str(), e->limit);
					}
					else
						source.Reply(_("\002%s\002 already exists on the EXCEPTION list."), mask.c_str());
					return;
				}
			}

			Exception *exception = new Exception();
			exception->mask = mask;
			exception->limit = limit;
			exception->reason = reason;
			exception->time = Anope::CurTime;
			exception->who = u->nick;
			exception->expires = expires;

			EventReturn MOD_RESULT;
			FOREACH_RESULT(I_OnExceptionAdd, OnExceptionAdd(exception));
			if (MOD_RESULT == EVENT_STOP)
				delete exception;
			else
			{
				session_service->AddException(exception);
				source.Reply(_("Session limit for \002%s\002 set to \002%d\002."), mask.c_str(), limit);
				if (readonly)
					source.Reply(READ_ONLY_MODE);
			}
		}

		return;
	}
Exemple #15
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Suspends \037account\037, which prevents it from being used while keeping all the data for it."
		               " If an expiry is given the account will be unsuspended after that period of time, otherwise the default expiry from the configuration is used.")); // XXX
		return true;
	}
Exemple #16
0
void Command::OnServHelp(CommandSource &source)
{
	source.Reply("    %-14s %s", source.command.c_str(), Language::Translate(source.nc, this->GetDesc(source).c_str()));
}
Exemple #17
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Unsuspends \037account\037, which allows it to be used again."));
		return true;
	}
Exemple #18
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
		if (!this->fs)
			return;

		const Anope::string &command = params[0];
		const Anope::string &subcommand = params.size() > 1 ? params[1] : "";

		ForbidType ftype = FT_SIZE;
		if (subcommand.equals_ci("NICK"))
			ftype = FT_NICK;
		else if (subcommand.equals_ci("CHAN"))
			ftype = FT_CHAN;
		else if (subcommand.equals_ci("EMAIL"))
			ftype = FT_EMAIL;
		else if (subcommand.equals_ci("REGISTER"))
			ftype = FT_REGISTER;

		if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE)
		{
			const Anope::string &expiry = params[2][0] == '+' ? params[2] : "";
			const Anope::string &entry = !expiry.empty() ? params[3] : params[2];
			Anope::string reason;
			if (expiry.empty())
				reason = params[3] + " ";
			if (params.size() > 4)
				reason += params[4];
			reason.trim();

			if (entry.replace_all_cs("?*", "").empty())
			{
				source.Reply(_("The mask must contain at least one non wildcard character."));
				return;
			}

			time_t expiryt = 0;

			if (!expiry.empty())
			{
				expiryt = Anope::DoTime(expiry);
				if (expiryt == -1)
				{
					source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
					return;
				}
				else if (expiryt)
					expiryt += Anope::CurTime;
			}

			NickServ::Nick *target = NickServ::FindNick(entry);
			if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->GetAccount()->IsServicesOper())
			{
				source.Reply(_("Access denied."));
				return;
			}

			ForbidData *d = this->fs->FindForbid(entry, ftype);
			bool created = false;
			if (d == NULL)
			{
				d = Serialize::New<ForbidData *>();
				created = true;
			}

			d->SetMask(entry);
			d->SetCreator(source.GetNick());
			d->SetReason(reason);
			d->SetCreated(Anope::CurTime);
			d->SetExpires(expiryt);
			d->SetType(ftype);

			if (Anope::ReadOnly)
				source.Reply(_("Services are in read-only mode. Any changes made may not persist."));

			Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand;
			source.Reply(_("Added a forbid on \002{0}\002 of type \002{1}\002 to expire on \002{2}\002."), entry, subcommand.lower(), expiryt ? Anope::strftime(expiryt, source.GetAccount()) : "never");

			/* apply forbid */
			switch (ftype)
			{
				case FT_NICK:
				{
					int na_matches = 0;

					for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
						this->OnUserNickChange(it->second);

					for (auto it = NickServ::service->GetNickList().begin(); it != NickServ::service->GetNickList().end();)
					{
						NickServ::Nick *na = *it;
						++it;

						d = this->fs->FindForbid(na->GetNick(), FT_NICK);
						if (d == NULL)
							continue;

						++na_matches;

						delete na;
					}

					source.Reply(_("\002{0}\002 nickname(s) dropped."), na_matches);
					break;
				}
				case FT_CHAN:
				{
					int chan_matches = 0, ci_matches = 0;

					for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
					{
						Channel *c = it->second;
						++it;

						d = this->fs->FindForbid(c->name, FT_CHAN);
						if (d == NULL)
							continue;

						ServiceBot *OperServ = Config->GetClient("OperServ");
						if (IRCD->CanSQLineChannel && OperServ)
						{
							time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
#warning "xline allocated on stack"
#if 0
							XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->GetReason());
							IRCD->SendSQLine(NULL, &x);
#endif
						}
						else if (ChanServ::service)
						{
							ChanServ::service->Hold(c);
						}

						++chan_matches;

						for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
						{
							User *u = cit->first;
							++cit;

							if (u->server == Me || u->HasMode("OPER"))
								continue;

							reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: \002%s\002")), d->GetReason().c_str());

							c->Kick(source.service, u, "%s", reason.c_str());
						}
					}

					for (auto it = ChanServ::service->GetChannels().begin(); it != ChanServ::service->GetChannels().end();)
					{
						ChanServ::Channel *ci = it->second;
						++it;

						d = this->fs->FindForbid(ci->GetName(), FT_CHAN);
						if (d == NULL)
							continue;

						++ci_matches;

						delete ci;
					}

					source.Reply(_("\002{0}\002 channel(s) cleared, and \002{1}\002 channel(s) dropped."), chan_matches, ci_matches);

					break;
				}
				default:
					break;
			}

		}
		else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE)
		{
			const Anope::string &entry = params[2];

			ForbidData *d = this->fs->FindForbid(entry, ftype);
			if (d == nullptr)
			{
				source.Reply(_("Forbid on \002{0}\002 was not found."), entry);
				return;
			}

			if (Anope::ReadOnly)
				source.Reply(_("Services are in read-only mode. Any changes made may not persist."));

			Log(LOG_ADMIN, source, this) << "to remove forbid on " << d->GetMask() << " of type " << subcommand;
			source.Reply(_("\002{0}\002 deleted from the \002{1}\002 forbid list."), d->GetMask(), subcommand);
			d->Delete();
		}
		else if (command.equals_ci("LIST"))
		{
			const std::vector<ForbidData *> &forbids = this->fs->GetForbids();
			if (forbids.empty())
			{
				source.Reply(_("Forbid list is empty."));
				return;
			}

			ListFormatter list(source.GetAccount());
			list.AddColumn(_("Mask")).AddColumn(_("Type")).AddColumn(_("Creator")).AddColumn(_("Expires")).AddColumn(_("Reason"));

			unsigned shown = 0;
			for (unsigned i = 0; i < forbids.size(); ++i)
			{
				ForbidData *d = forbids[i];

				if (ftype != FT_SIZE && ftype != d->GetType())
					continue;

				Anope::string stype;
				if (d->GetType() == FT_NICK)
					stype = "NICK";
				else if (d->GetType() == FT_CHAN)
					stype = "CHAN";
				else if (d->GetType() == FT_EMAIL)
					stype = "EMAIL";
				else if (d->GetType() == FT_REGISTER)
					stype = "REGISTER";
				else
					continue;

				ListFormatter::ListEntry entry;
				entry["Mask"] = d->GetMask();
				entry["Type"] = stype;
				entry["Creator"] = d->GetCreator();
				entry["Expires"] = d->GetExpires() ? Anope::strftime(d->GetExpires(), NULL, true).c_str() : Language::Translate(source.GetAccount(), _("Never"));
				entry["Reason"] = d->GetReason();
				list.AddEntry(entry);
				++shown;
			}

			if (!shown)
			{
				source.Reply(_("There are no forbids of type \002{0}\002."), subcommand.upper());
				return;
			}

			source.Reply(_("Forbid list:"));

			std::vector<Anope::string> replies;
			list.Process(replies);

			for (unsigned i = 0; i < replies.size(); ++i)
				source.Reply(replies[i]);

			if (shown >= forbids.size())
				source.Reply(_("End of forbid list."));
			else
				source.Reply(_("End of forbid list - \002{0}\002/\002{1}\002 entries shown."), shown, forbids.size());
		}
		else
			this->OnSyntaxError(source, command);
	}
Exemple #19
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params)
	{
		const Anope::string &subcommand = params[0];

		if (subcommand.equals_ci("ADD") && params.size() > 2)
		{
			const Anope::string &oper = params[1];
			const Anope::string &otype = params[2];

			NickAlias *na = findnick(oper);
			if (na == NULL)
				source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
			else if (na->nc->o)
				source.Reply(_("Nick \2%s\2 is already an operator."), na->nick.c_str());
			else
			{
				OperType *ot = OperType::Find(otype);
				if (ot == NULL)
					source.Reply(_("Oper type \2%s\2 has not been configured."), otype.c_str());
				else
				{
					na->nc->o = new MyOper(na->nc->display, ot);

					Log(LOG_ADMIN, source.u, this) << "ADD " << na->nick << " as type " << ot->GetName();
					source.Reply("%s (%s) added to the \2%s\2 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str());
				}
			}
		}
		else if (subcommand.equals_ci("DEL") && params.size() > 1)
		{
			const Anope::string &oper = params[1];

			NickAlias *na = findnick(oper);
			if (na == NULL)
				source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
			else if (!na->nc || !na->nc->o)
				source.Reply(_("Nick \2%s\2 is not a services operator."), oper.c_str());
			else
			{
				delete na->nc->o;
				na->nc->o = NULL;

				Log(LOG_ADMIN, source.u, this) << "DEL " << na->nick;
				source.Reply(_("Oper privileges removed from %s (%s)."), na->nick.c_str(), na->nc->display.c_str());
			}
		}
		else if (subcommand.equals_ci("LIST"))
		{
			source.Reply(_("Name     Type"));
			for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
			{
				NickCore *nc = it->second;

				if (!nc->o)
					continue;

				source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str());
				if (nc->o->config)
					source.Reply(_("   This oper is configured in the configuration file."));
				for (std::list<User *>::iterator uit = nc->Users.begin(); uit != nc->Users.end(); ++uit)
				{
					User *u = *uit;
					source.Reply(_("   %s is online using this oper block."), u->nick.c_str());
				}
			}
		}
		else if (subcommand.equals_ci("INFO") && params.size() > 1)
		{
			Anope::string fulltype = params[1];
			if (params.size() > 2)
				fulltype += " " + params[2];
			OperType *ot = OperType::Find(fulltype);
			if (ot == NULL)	
				source.Reply(_("Oper type \2%s\2 has not been configured."), fulltype.c_str());
			else
			{
				if (ot->GetCommands().empty())
					source.Reply(_("Opertype \2%s\2 has no allowed commands."), ot->GetName().c_str());
				else
				{
					source.Reply(_("Available commands for \2%s\2:"), ot->GetName().c_str());
					Anope::string buf;
					std::list<Anope::string> cmds = ot->GetCommands();
					for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it)
					{
						buf += *it + " ";
						if (buf.length() > 400)
						{
							source.Reply("%s", buf.c_str());
							buf.clear();
						}
					}
					if (!buf.empty())
					{
						source.Reply("%s", buf.c_str());
						buf.clear();
					}
				}
				if (ot->GetPrivs().empty())
					source.Reply(_("Opertype \2%s\2 has no allowed privileges."), ot->GetName().c_str());
				else
				{
					source.Reply(_("Available privileges for \2%s\2:"), ot->GetName().c_str());
					Anope::string buf;
					std::list<Anope::string> privs = ot->GetPrivs();
					for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it)
					{
						buf += *it + " ";
						if (buf.length() > 400)
						{
							source.Reply("%s", buf.c_str());
							buf.clear();
						}
					}
					if (!buf.empty())
					{
						source.Reply("%s", buf.c_str());
						buf.clear();
					}
				}
				if (!ot->modes.empty())
					source.Reply(_("Opertype \2%s\2 receives modes \2%s\2 once identifying."), ot->GetName().c_str(), ot->modes.c_str());
			}
		}
		else
			this->OnSyntaxError(source, subcommand);

		return;
	}
Exemple #20
0
	EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
	{
		if (command->GetName() == "nickserv/info" && params.size() > 0)
		{
			ForbidData *d = this->forbid_service.FindForbid(params[0], FT_NICK);
			if (d != NULL)
			{
				if (source.IsOper())
					source.Reply(_("Nick \002%s\002 is forbidden by %s: %s"), params[0], d->GetCreator(), d->GetReason());
				else
					source.Reply(_("Nick \002%s\002 is forbidden."), params[0]);
				return EVENT_STOP;
			}
		}
		else if (command->GetName() == "chanserv/info" && params.size() > 0)
		{
			ForbidData *d = this->forbid_service.FindForbid(params[0], FT_CHAN);
			if (d != NULL)
			{
				if (source.IsOper())
					source.Reply(_("Channel \002%s\002 is forbidden by %s: %s"), params[0], d->GetCreator(), d->GetReason());
				else
					source.Reply(_("Channel \002%s\002 is forbidden."), params[0]);
				return EVENT_STOP;
			}
		}
		else if (source.IsOper())
			return EVENT_CONTINUE;
		else if (command->GetName() == "nickserv/register" && params.size() > 1)
		{
			ForbidData *d = this->forbid_service.FindForbid(source.GetNick(), FT_REGISTER);
			if (d != NULL)
			{
				source.Reply(_("\002{0}\002 may not be registered."), source.GetNick());
				return EVENT_STOP;
			}

			d = this->forbid_service.FindForbid(params[1], FT_EMAIL);
			if (d != NULL)
			{
				source.Reply(_("Your email address is not allowed, choose a different one."));
				return EVENT_STOP;
			}
		}
		else if (command->GetName() == "nickserv/set/email" && params.size() > 0)
		{
			ForbidData *d = this->forbid_service.FindForbid(params[0], FT_EMAIL);
			if (d != NULL)
			{
				source.Reply(_("Your email address is not allowed, choose a different one."));
				return EVENT_STOP;
			}
		}
		else if (command->GetName() == "chanserv/register" && !params.empty())
		{
			ForbidData *d = this->forbid_service.FindForbid(params[0], FT_REGISTER);
			if (d != NULL)
			{
				source.Reply(_("Channel \002{0}\002 is currently suspended."), params[0]);
				return EVENT_STOP;
			}
		}

		return EVENT_CONTINUE;
	}
Exemple #21
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{

		Anope::string param = !params.empty() ? params[0] : "", chan;
		ChanServ::Channel *ci = NULL;
		MemoServ::MemoInfo *mi;

		if (!param.empty() && param[0] == '#')
		{
			chan = param;
			param = params.size() > 1 ? params[1] : "";

			ci = ChanServ::Find(chan);
			if (!ci)
			{
				source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
				return;
			}

			if (!source.AccessFor(ci).HasPriv("MEMO"))
			{
				source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
				return;
			}

			mi = ci->GetMemos();
		}
		else
		{
			mi = source.nc->GetMemos();
		}

		if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW"))
		{
			this->OnSyntaxError(source);
			return;
		}

		if (!mi)
			return;

		auto memos = mi->GetMemos();

		if (!memos.size())
		{
			if (!chan.empty())
				source.Reply(_("\002{0}\002 has no memos."), chan);
			else
				source.Reply(_("You have no memos."));
			return;
		}

		ListFormatter list(source.GetAccount());

		list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time"));

		if (!param.empty() && isdigit(param[0]))
		{
			NumberList(param, false,
				[&](unsigned int number)
				{
					if (!number || number > memos.size())
						return;

					MemoServ::Memo *m = mi->GetMemo(number - 1);

					ListFormatter::ListEntry entry;
					entry["Number"] = (m->GetUnread() ? "* " : "  ") + stringify(number);
					entry["Sender"] = m->GetSender();
					entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount());
					list.AddEntry(entry);
				},
				[]{});
		}
		else
		{
			if (!param.empty())
			{
				unsigned i, end;
				for (i = 0, end = memos.size(); i < end; ++i)
					if (mi->GetMemo(i)->GetUnread())
						break;
				if (i == end)
				{
					if (!chan.empty())
						source.Reply(_("\002{0}\002 has no new memos."), chan);
					else
						source.Reply(_("You have no new memos."));
					return;
				}
			}

			for (unsigned i = 0, end = memos.size(); i < end; ++i)
			{
				if (!param.empty() && !mi->GetMemo(i)->GetUnread())
					continue;

				MemoServ::Memo *m = mi->GetMemo(i);

				ListFormatter::ListEntry entry;
				entry["Number"] = (m->GetUnread() ? "* " : "  ") + stringify(i + 1);
				entry["Sender"] = m->GetSender();
				entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount());
				list.AddEntry(entry);
			}
		}

		std::vector<Anope::string> replies;
		list.Process(replies);

		source.Reply(_("Memos for \002{0}\002:"), ci ? ci->GetName().c_str() : source.GetNick().c_str());
		for (unsigned i = 0; i < replies.size(); ++i)
			source.Reply(replies[i]);
	}
Exemple #22
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Tells services to jupiter a server -- that is, to create a fake \"server\" connected to Services which prevents the real server of that name from connecting."
		               "  The jupe may be removed using a standard \002SQUIT\002. If a reason is given, it is placed in the server information field; otherwise, the server information field will contain the text \"Juped by <nick>\", showing the nickname of the person who jupitered the server."));
		return true;
	}
Exemple #23
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{

		MemoServ::MemoInfo *mi;
		ChanServ::Channel *ci = NULL;
		Anope::string numstr = params[0], chan;

		if (!numstr.empty() && numstr[0] == '#')
		{
			chan = numstr;
			numstr = params.size() > 1 ? params[1] : "";

			ci = ChanServ::Find(chan);
			if (!ci)
			{
				source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
				return;
			}

			if (!source.AccessFor(ci).HasPriv("MEMO"))
			{
				source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
				return;
			}

			mi = ci->GetMemos();
		}
		else
			mi = source.nc->GetMemos();

		if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && !numstr.is_number_only()))
		{
			this->OnSyntaxError(source, numstr);
			return;
		}

		if (!mi)
			return;

		auto memos = mi->GetMemos();

		if (memos.empty())
		{
			if (!chan.empty())
				source.Reply(_("\002{0}\002 has no memos."), chan);
			else
				source.Reply(_("You have no memos."));
			return;
		}

		int i, end;

		if (numstr.equals_ci("NEW"))
		{
			int readcount = 0;
			for (i = 0, end = memos.size(); i < end; ++i)
				if (mi->GetMemo(i)->GetUnread())
				{
					DoRead(source, mi, ci, i);
					++readcount;
				}
			if (!readcount)
			{
				if (!chan.empty())
					source.Reply(_("\002{0}\002 has no new memos."), chan);
				else
					source.Reply(_("You have no new memos."));
			}
		}
		else if (numstr.equals_ci("LAST"))
		{
			for (i = 0, end = memos.size() - 1; i < end; ++i);
			DoRead(source, mi, ci, i);
		}
		else /* number[s] */
		{
			NumberList(numstr, false,
				[&](unsigned int number)
				{
					if (!number || number > memos.size())
						return;

					DoRead(source, mi, ci, number - 1);
				},
				[]{});
		}
	}
Exemple #24
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{
#warning "this is completely disabled"
#if 0
		if (!MemoServ::service)
			return;

		if (Anope::ReadOnly && !source.IsOper())
		{
			source.Reply(_("Sorry, memo sending is temporarily disabled."));
			return;
		}

		const Anope::string &nick = params[0];
		const Anope::string &text = params[1];
		const NickServ::Nick *na = NULL;

		/* prevent user from rsend to themselves */
		if ((na = NickServ::FindNick(nick)) && na->GetAccount() == source.GetAccount())
		{
			source.Reply(_("You can not request a receipt when sending a memo to yourself."));
			return;
		}

		if (Config->GetModule(this->GetOwner())->Get<bool>("operonly") && !source.IsServicesOper())
			source.Reply(_("Access denied. This command is for operators only."));
		else
		{
			MemoServ::MemoServService::MemoResult result = MemoServ::service->Send(source.GetNick(), nick, text);
			if (result == MemoServ::MemoServService::MEMO_INVALID_TARGET)
				source.Reply(_("\002{0}\002 isn't registered."), nick);
			else if (result == MemoServ::MemoServService::MEMO_TOO_FAST)
				source.Reply(_("Please wait \002{0}\002 seconds before using the \002{1}\002 command again."), Config->GetModule("memoserv/main")->Get<time_t>("senddelay"), source.command);
			else if (result == MemoServ::MemoServService::MEMO_TARGET_FULL)
				source.Reply(_("Sorry, \002{0}\002 currently has too many memos and cannot receive more."), nick);
			else
			{
				source.Reply(_("Memo sent to \002{0}\002."), nick);

				bool ischan, isregistered;
				MemoServ::MemoInfo *mi = MemoServ::service->GetMemoInfo(nick, ischan, isregistered, false);
				if (mi == NULL)
					throw CoreException("NULL mi in ms_rsend");
				MemoServ::Memo *m = (mi->memos->size() ? mi->GetMemo(mi->memos->size() - 1) : NULL);
				if (m != NULL)
					m->receipt = true;
			}
		}
#endif
	}
Exemple #25
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("Causes Services to reload the configuration file."));
		return true;
	}
Exemple #26
0
	void DoClear(CommandSource &source, ChannelInfo *ci)
	{
		ci->Shrink("cs_entrymsg");
		source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
	}
Exemple #27
0
	void DoLimit(CommandSource &source, const std::vector<Anope::string> &params, MemoServ::MemoInfo *mi)
	{

		Anope::string p1 = params[1];
		Anope::string p2 = params.size() > 2 ? params[2] : "";
		Anope::string p3 = params.size() > 3 ? params[3] : "";
		Anope::string user, chan;
		int16_t limit;
		NickServ::Account *nc = source.nc;
		ChanServ::Channel *ci = NULL;
		bool is_servadmin = source.HasPriv("memoserv/set-limit");

		if (p1[0] == '#')
		{
			chan = p1;
			p1 = p2;
			p2 = p3;
			p3 = params.size() > 4 ? params[4] : "";

			ci = ChanServ::Find(chan);
			if (!ci)
			{
				source.Reply(_("Channel \002{0}\002 isn't registered."), chan);
				return;
			}

			if (!is_servadmin && !source.AccessFor(ci).HasPriv("MEMO"))
			{
				source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName());
				return;
			}
			mi = ci->GetMemos();
		}
		if (is_servadmin)
		{
			if (!p2.empty() && !p2.equals_ci("HARD") && chan.empty())
			{
				NickServ::Nick *na;
				if (!(na = NickServ::FindNick(p1)))
				{
					source.Reply(_("\002{0}\002 isn't registered."), p1);
					return;
				}
				user = p1;
				mi = na->GetAccount()->GetMemos();
				nc = na->GetAccount();
				p1 = p2;
				p2 = p3;
			}
			else if (p1.empty() || (!p1.is_pos_number_only() && !p1.equals_ci("NONE")) || (!p2.empty() && !p2.equals_ci("HARD")))
			{
				this->OnSyntaxError(source, "");
				return;
			}
			if (!chan.empty())
			{
				if (!p2.empty())
					ci->SetS<bool>("MEMO_HARDMAX", true);
				else
					ci->UnsetS<bool>("MEMO_HARDMAX");
			}
			else
			{
				if (!p2.empty())
					nc->SetS<bool>("MEMO_HARDMAX", true);
				else
					nc->UnsetS<bool>("MEMO_HARDMAX");
			}
			limit = -1;
			try
			{
				limit = convertTo<int16_t>(p1);
			}
			catch (const ConvertException &) { }
		}
		else
		{
			if (p1.empty() || !p2.empty() || !isdigit(p1[0]))
			{
				this->OnSyntaxError(source, "");
				return;
			}
			if (!chan.empty() && ci->HasFieldS("MEMO_HARDMAX"))
			{
				source.Reply(_("The memo limit for \002{0}\002 may not be changed."), chan);
				return;
			}
			if (chan.empty() && nc->HasFieldS("MEMO_HARDMAX"))
			{
				source.Reply(_("You are not permitted to change your memo limit."));
				return;
			}
			int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
			limit = -1;
			try
			{
				limit = convertTo<int16_t>(p1);
			}
			catch (const ConvertException &) { }
			/* The first character is a digit, but we could still go negative
			 * from overflow... watch out! */
			if (limit < 0 || (max_memos > 0 && limit > max_memos))
			{
				if (!chan.empty())
					source.Reply(_("You cannot set the memo limit for \002{0}\002 higher than \002{1}\002."), chan, max_memos);
				else
					source.Reply(_("You cannot set your memo limit higher than \002{0}\002."), max_memos);
				return;
			}
		}
		mi->SetMemoMax(limit);
		if (limit > 0)
		{
			if (chan.empty() && nc == source.nc)
				source.Reply(_("Your memo limit has been set to \002{0}\002."), limit);
			else
				source.Reply(_("Memo limit for \002{0}\002 set to \002{1}\002."), !chan.empty() ? chan : user, limit);
		}
		else if (!limit)
		{
			if (chan.empty() && nc == source.nc)
				source.Reply(_("You will no longer be able to receive memos."));
			else
				source.Reply(_("Memo limit for \002{0}\002 set to \0020\002."), !chan.empty() ? chan : user);
		}
		else
		{
			if (chan.empty() && nc == source.nc)
				source.Reply(_("Your memo limit has been disabled."));
			else
				source.Reply(_("Memo limit \002disabled\002 for \002{0}\002."), !chan.empty() ? chan : user);
		}
	}
Exemple #28
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
	{

		const Anope::string &nick = params[0];
		Anope::string expiry = params[1];
		Anope::string reason = params.size() > 2 ? params[2] : "";
		time_t expiry_secs = Config->GetModule(this->GetOwner())->Get<time_t>("suspendexpire");

		if (Anope::ReadOnly)
			source.Reply(_("Services are in read-only mode. Any changes made may not persist."));

		if (expiry[0] != '+')
		{
			reason = expiry + " " + reason;
			reason.trim();
			expiry.clear();
		}
		else
		{
			expiry_secs = Anope::DoTime(expiry);
			if (expiry_secs == -1)
			{
				source.Reply(_("Invalid expiry time \002{0}\002."), expiry);
				return;
			}
		}

		NickServ::Nick *na = NickServ::FindNick(nick);
		if (!na)
		{
			source.Reply(_("\002{0}\002 isn't registered."), nick);
			return;
		}

		if (Config->GetModule("nickserv/main")->Get<bool>("secureadmins", "yes") && na->GetAccount()->GetOper())
		{
			source.Reply(_("You may not suspend other Services Operators' nicknames."));
			return;
		}

		NSSuspendInfo *si = na->GetAccount()->GetRef<NSSuspendInfo *>();
		if (!si)
		{
			source.Reply(_("\002%s\002 is already suspended."), na->GetAccount()->GetDisplay().c_str());
			return;
		}

		NickServ::Account *nc = na->GetAccount();

		si = Serialize::New<NSSuspendInfo *>();
		si->SetAccount(nc);
		si->SetBy(source.GetNick());
		si->SetReason(reason);
		si->SetWhen(Anope::CurTime);
		si->SetExpires(expiry_secs ? expiry_secs + Anope::CurTime : 0);

		for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>())
		{
			na2->SetLastQuit(reason);

			User *u2 = User::Find(na2->GetNick(), true);
			if (u2)
			{
				u2->Logout();
				if (NickServ::service)
					NickServ::service->Collide(u2, na2);
			}
		}

		Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
		source.Reply(_("\002{0}\002 is now suspended."), na->GetNick());

		EventManager::Get()->Dispatch(&Event::NickSuspend::OnNickSuspend, na);
	}
Exemple #29
0
 void Run(CommandSource &source, const std::vector<Flux::string> &params)
 {
    source.Reply("Rehashing Configuration file");
    Log(source.u, this) << "to rehash the configuration";
    Rehash();
 }
Exemple #30
0
	bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
	{
		source.Reply(_("\002{0} SET\002 kills all operators from the given \002server\002 and prevents operators from opering up on the given server."
		               " \002{0} REVOKE\002 removes this restriction."));
		return true;
	}