anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

hs_set.cpp (5580B)

      1 /* HostServ core functions
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include "module.h"
     13 
     14 class CommandHSSet : public Command
     15 {
     16  public:
     17 	CommandHSSet(Module *creator) : Command(creator, "hostserv/set", 2, 2)
     18 	{
     19 		this->SetDesc(_("Set the vhost of another user"));
     20 		this->SetSyntax(_("\037nick\037 \037hostmask\037"));
     21 	}
     22 
     23 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
     24 	{
     25 		if (Anope::ReadOnly)
     26 		{
     27 			source.Reply(READ_ONLY_MODE);
     28 			return;
     29 		}
     30 
     31 		const Anope::string &nick = params[0];
     32 
     33 		NickAlias *na = NickAlias::Find(nick);
     34 		if (na == NULL)
     35 		{
     36 			source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
     37 			return;
     38 		}
     39 
     40 		Anope::string rawhostmask = params[1];
     41 
     42 		Anope::string user, host;
     43 		size_t a = rawhostmask.find('@');
     44 
     45 		if (a == Anope::string::npos)
     46 			host = rawhostmask;
     47 		else
     48 		{
     49 			user = rawhostmask.substr(0, a);
     50 			host = rawhostmask.substr(a + 1);
     51 		}
     52 
     53 		if (host.empty())
     54 		{
     55 			this->OnSyntaxError(source, "");
     56 			return;
     57 		}
     58 
     59 		if (!user.empty())
     60 		{
     61 			if (!IRCD->CanSetVIdent)
     62 			{
     63 				source.Reply(HOST_NO_VIDENT);
     64 				return;
     65 			}
     66 			else if (!IRCD->IsIdentValid(user))
     67 			{
     68 				source.Reply(HOST_SET_IDENT_ERROR);
     69 				return;
     70 			}
     71 		}
     72 
     73 		if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
     74 		{
     75 			source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
     76 			return;
     77 		}
     78 
     79 		if (!IRCD->IsHostValid(host))
     80 		{
     81 			source.Reply(HOST_SET_ERROR);
     82 			return;
     83 		}
     84 
     85 		Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
     86 
     87 		na->SetVhost(user, host, source.GetNick());
     88 		FOREACH_MOD(OnSetVhost, (na));
     89 		if (!user.empty())
     90 			source.Reply(_("VHost for \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
     91 		else
     92 			source.Reply(_("VHost for \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
     93 	}
     94 
     95 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
     96 	{
     97 		this->SendSyntax(source);
     98 		source.Reply(" ");
     99 		source.Reply(_("Sets the vhost for the given nick to that of the given\n"
    100 				"hostmask.  If your IRCD supports vIdents, then using\n"
    101 				"SET <nick> <ident>@<hostmask> set idents for users as\n"
    102 				"well as vhosts."));
    103 		return true;
    104 	}
    105 };
    106 
    107 class CommandHSSetAll : public Command
    108 {
    109 	void Sync(const NickAlias *na)
    110 	{
    111 		if (!na || !na->HasVhost())
    112 			return;
    113 
    114 		for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
    115 		{
    116 			NickAlias *nick = na->nc->aliases->at(i);
    117 			if (nick)
    118 				nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
    119 		}
    120 	}
    121 
    122  public:
    123 	CommandHSSetAll(Module *creator) : Command(creator, "hostserv/setall", 2, 2)
    124 	{
    125 		this->SetDesc(_("Set the vhost for all nicks in a group"));
    126 		this->SetSyntax(_("\037nick\037 \037hostmask\037"));
    127 	}
    128 
    129 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
    130 	{
    131 		if (Anope::ReadOnly)
    132 		{
    133 			source.Reply(READ_ONLY_MODE);
    134 			return;
    135 		}
    136 
    137 		Anope::string nick = params[0];
    138 
    139 		NickAlias *na = NickAlias::Find(nick);
    140 		if (na == NULL)
    141 		{
    142 			source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
    143 			return;
    144 		}
    145 
    146 		Anope::string rawhostmask = params[1];
    147 
    148 		Anope::string user, host;
    149 		size_t a = rawhostmask.find('@');
    150 
    151 		if (a == Anope::string::npos)
    152 			host = rawhostmask;
    153 		else
    154 		{
    155 			user = rawhostmask.substr(0, a);
    156 			host = rawhostmask.substr(a + 1);
    157 		}
    158 
    159 		if (host.empty())
    160 		{
    161 			this->OnSyntaxError(source, "");
    162 			return;
    163 		}
    164 
    165 		if (!user.empty())
    166 		{
    167 			if (!IRCD->CanSetVIdent)
    168 			{
    169 				source.Reply(HOST_NO_VIDENT);
    170 				return;
    171 			}
    172 			else if (!IRCD->IsIdentValid(user))
    173 			{
    174 				source.Reply(HOST_SET_IDENT_ERROR);
    175 				return;
    176 			}
    177 		}
    178 
    179 		if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
    180 		{
    181 			source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
    182 			return;
    183 		}
    184 
    185 		if (!IRCD->IsHostValid(host))
    186 		{
    187 			source.Reply(HOST_SET_ERROR);
    188 			return;
    189 		}
    190 
    191 		Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
    192 
    193 		na->SetVhost(user, host, source.GetNick());
    194 		this->Sync(na);
    195 		FOREACH_MOD(OnSetVhost, (na));
    196 		if (!user.empty())
    197 			source.Reply(_("VHost for group \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
    198 		else
    199 			source.Reply(_("VHost for group \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
    200 	}
    201 
    202 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    203 	{
    204 		this->SendSyntax(source);
    205 		source.Reply(" ");
    206 		source.Reply(_("Sets the vhost for all nicks in the same group as that\n"
    207 				"of the given nick.  If your IRCD supports vIdents, then\n"
    208 				"using SETALL <nick> <ident>@<hostmask> will set idents\n"
    209 				"for users as well as vhosts.\n"
    210 				"* NOTE, this will not update the vhost for any nicks\n"
    211 				"added to the group after this command was used."));
    212 		return true;
    213 	}
    214 };
    215 
    216 class HSSet : public Module
    217 {
    218 	CommandHSSet commandhsset;
    219 	CommandHSSetAll commandhssetall;
    220 
    221  public:
    222 	HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsset(this), commandhssetall(this)
    223 	{
    224 		if (!IRCD || !IRCD->CanSetVHost)
    225 			throw ModuleException("Your IRCd does not support vhosts");
    226 	}
    227 };
    228 
    229 MODULE_INIT(HSSet)