summaryrefslogtreecommitdiff
path: root/modules/commands/hs_request.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-08-05 05:35:31 -0400
committerAdam <Adam@anope.org>2011-08-05 05:35:31 -0400
commite66063e6304538d34c40460ca0aa2be5ddb6bdec (patch)
treef50fe31097160f8f794669809e4f4ef87f477672 /modules/commands/hs_request.cpp
parent9ec18a3b020932eee6242c878149c484f49b13cb (diff)
Rewrote the example configurations and split them
up into seperate files for each pseudo client. Also reorganized how the modules are stored, and made most of the old "extra" modules "core"
Diffstat (limited to 'modules/commands/hs_request.cpp')
-rw-r--r--modules/commands/hs_request.cpp424
1 files changed, 424 insertions, 0 deletions
diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp
new file mode 100644
index 000000000..7686794f5
--- /dev/null
+++ b/modules/commands/hs_request.cpp
@@ -0,0 +1,424 @@
+/* hs_request.c - Add request and activate functionality to HostServ,
+ *
+ *
+ * (C) 2003-2011 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Based on the original module by Rob <rob@anope.org>
+ * Included in the Anope module pack since Anope 1.7.11
+ * Anope Coder: GeniusDex <geniusdex@anope.org>
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Send bug reports to the Anope Coder instead of the module
+ * author, because any changes since the inclusion into anope
+ * are not supported by the original author.
+ */
+
+#include "module.h"
+#include "memoserv.h"
+
+static bool HSRequestMemoUser = false;
+static bool HSRequestMemoOper = false;
+
+void my_add_host_request(const Anope::string &nick, const Anope::string &vIdent, const Anope::string &vhost, const Anope::string &creator, time_t tmp_time);
+void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
+
+struct HostRequest
+{
+ Anope::string ident;
+ Anope::string host;
+ time_t time;
+};
+
+typedef std::map<Anope::string, HostRequest *, std::less<ci::string> > RequestMap;
+RequestMap Requests;
+
+class CommandHSRequest : public Command
+{
+ bool isvalidchar(char c)
+ {
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
+ return true;
+ return false;
+ }
+
+ public:
+ CommandHSRequest(Module *creator) : Command(creator, "hostserv/request", 1, 1)
+ {
+ this->SetDesc(_("Request a vHost for your nick"));
+ this->SetSyntax(_("vhost"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ User *u = source.u;
+
+ 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->UserLen)
+ {
+ source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen);
+ return;
+ }
+ else if (!ircd->vident)
+ {
+ source.Reply(HOST_NO_VIDENT);
+ return;
+ }
+ for (Anope::string::iterator s = user.begin(), s_end = user.end(); s != s_end; ++s)
+ if (!isvalidchar(*s))
+ {
+ source.Reply(HOST_SET_IDENT_ERROR);
+ return;
+ }
+ }
+
+ if (host.length() > Config->HostLen)
+ {
+ source.Reply(HOST_SET_TOOLONG, Config->HostLen);
+ return;
+ }
+
+ if (!isValidHost(host, 3))
+ {
+ source.Reply(HOST_SET_ERROR);
+ return;
+ }
+
+ if (HSRequestMemoOper && Config->MSSendDelay > 0 && u && u->lastmemosend + Config->MSSendDelay > Anope::CurTime)
+ {
+ source.Reply(_("Please wait %d seconds before requesting a new vHost"), Config->MSSendDelay);
+ u->lastmemosend = Anope::CurTime;
+ return;
+ }
+ my_add_host_request(u->nick, user, host, u->nick, Anope::CurTime);
+
+ source.Reply(_("Your vHost has been requested"));
+ req_send_memos(source, user, host);
+ Log(LOG_COMMAND, u, this, NULL) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
+
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Request the given vHost to be actived for your nick by the\n"
+ "network administrators. Please be patient while your request\n"
+ "is being considered."));
+ return true;
+ }
+};
+
+class CommandHSActivate : public Command
+{
+ public:
+ CommandHSActivate(Module *creator) : Command(creator, "hostserv/activate", 1, 1)
+ {
+ this->SetDesc(_("Approve the requested vHost of a user"));
+ this->SetSyntax(_("\037nick\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ User *u = source.u;
+
+ const Anope::string &nick = params[0];
+
+ NickAlias *na = findnick(nick);
+ if (na)
+ {
+ RequestMap::iterator it = Requests.find(na->nick);
+ if (it != Requests.end())
+ {
+ na->hostinfo.SetVhost(it->second->ident, it->second->host, u->nick, it->second->time);
+ FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
+
+ if (HSRequestMemoUser && memoserv)
+ memoserv->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
+
+ source.Reply(_("vHost for %s has been activated"), na->nick.c_str());
+ Log(LOG_COMMAND, u, this, NULL) << "for " << na->nick << " for vhost " << (!it->second->ident.empty() ? it->second->ident + "@" : "") << it->second->host;
+ delete it->second;
+ Requests.erase(it);
+ }
+ else
+ source.Reply(_("No request for nick %s found."), nick.c_str());
+ }
+ else
+ source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
+
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Activate the requested vHost for the given nick."));
+ if (HSRequestMemoUser)
+ source.Reply(_("A memo informing the user will also be sent."));
+
+ return true;
+ }
+};
+
+class CommandHSReject : public Command
+{
+ public:
+ CommandHSReject(Module *creator) : Command(creator, "hostserv/reject", 1, 2)
+ {
+ this->SetDesc(_("Reject the requested vHost of a user"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ User *u = source.u;
+
+ const Anope::string &nick = params[0];
+ const Anope::string &reason = params.size() > 1 ? params[1] : "";
+
+ RequestMap::iterator it = Requests.find(nick);
+ if (it != Requests.end())
+ {
+ delete it->second;
+ Requests.erase(it);
+
+ if (HSRequestMemoUser && memoserv)
+ {
+ Anope::string message;
+ if (!reason.empty())
+ message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
+ else
+ message = _("[auto memo] Your requested vHost has been rejected.");
+
+ memoserv->Send(Config->HostServ, nick, message, true);
+ }
+
+ source.Reply(_("vHost for %s has been rejected"), nick.c_str());
+ Log(LOG_COMMAND, u, this, NULL) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "") << ")";
+ }
+ else
+ source.Reply(_("No request for nick %s found."), nick.c_str());
+
+ return;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Reject the requested vHost for the given nick."));
+ if (HSRequestMemoUser)
+ source.Reply(_("A memo informing the user will also be sent."));
+
+ return true;
+ }
+};
+
+class HSListBase : public Command
+{
+ protected:
+ void DoList(CommandSource &source)
+ {
+ int counter = 1;
+ int from = 0, to = 0;
+ unsigned display_counter = 0;
+
+ for (RequestMap::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end; ++it)
+ {
+ HostRequest *hr = it->second;
+ if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax)
+ {
+ ++display_counter;
+ if (!hr->ident.empty())
+ source.Reply(_("#%d Nick:\002%s\002, vhost:\002%s\002@\002%s\002 (%s - %s)"), counter, it->first.c_str(), hr->ident.c_str(), hr->host.c_str(), it->first.c_str(), do_strftime(hr->time).c_str());
+ else
+ source.Reply(_("#%d Nick:\002%s\002, vhost:\002%s\002 (%s - %s)"), counter, it->first.c_str(), hr->host.c_str(), it->first.c_str(), do_strftime(hr->time).c_str());
+ }
+ ++counter;
+ }
+ source.Reply(_("Displayed all records (Count: \002%d\002)"), display_counter);
+
+ return;
+ }
+ public:
+ HSListBase(Module *creator, const Anope::string &cmd, int min, int max) : Command(creator, cmd, min, max)
+ {
+ }
+};
+
+class CommandHSWaiting : public HSListBase
+{
+ public:
+ CommandHSWaiting(Module *creator) : HSListBase(creator, "hostserv/waiting", 0, 0)
+ {
+ this->SetDesc(_("Retrieves the vhost requests"));
+ this->SetSyntax("");
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ return this->DoList(source);
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("This command retrieves the vhost requests"));
+
+ return true;
+ }
+};
+
+class HSRequest : public Module
+{
+ CommandHSRequest commandhsrequest;
+ CommandHSActivate commandhsactive;
+ CommandHSReject commandhsreject;
+ CommandHSWaiting commandhswaiting;
+
+ public:
+ HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED),
+ commandhsrequest(this), commandhsactive(this), commandhsreject(this), commandhswaiting(this)
+ {
+ this->SetAuthor("Anope");
+
+ ModuleManager::RegisterService(&commandhsrequest);
+ ModuleManager::RegisterService(&commandhsactive);
+ ModuleManager::RegisterService(&commandhsreject);
+ ModuleManager::RegisterService(&commandhswaiting);
+
+ Implementation i[] = { I_OnDelNick, I_OnDatabaseRead, I_OnDatabaseWrite, I_OnReload };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+
+ this->OnReload();
+ }
+
+ ~HSRequest()
+ {
+ /* Clean up all open host requests */
+ while (!Requests.empty())
+ {
+ delete Requests.begin()->second;
+ Requests.erase(Requests.begin());
+ }
+ }
+
+ void OnDelNick(NickAlias *na)
+ {
+ RequestMap::iterator it = Requests.find(na->nick);
+
+ if (it != Requests.end())
+ {
+ delete it->second;
+ Requests.erase(it);
+ }
+ }
+
+ EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
+ {
+ if (params[0].equals_ci("HS_REQUEST") && params.size() >= 5)
+ {
+ Anope::string vident = params[2].equals_ci("(null)") ? "" : params[2];
+ my_add_host_request(params[1], vident, params[3], params[1], params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnDatabaseWrite(void (*Write)(const Anope::string &))
+ {
+ for (RequestMap::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end; ++it)
+ {
+ HostRequest *hr = it->second;
+ std::stringstream buf;
+ buf << "HS_REQUEST " << it->first << " " << (hr->ident.empty() ? "(null)" : hr->ident) << " " << hr->host << " " << hr->time;
+ Write(buf.str());
+ }
+ }
+
+ void OnReload()
+ {
+ ConfigReader config;
+ HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
+ HSRequestMemoOper = config.ReadFlag("hs_request", "memooper", "no", 0);
+
+ Log(LOG_DEBUG) << "[hs_request] Set config vars: MemoUser=" << HSRequestMemoUser << " MemoOper=" << HSRequestMemoOper;
+ }
+};
+
+void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
+{
+ Anope::string host;
+ std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end;
+
+ if (!vIdent.empty())
+ host = vIdent + "@" + vHost;
+ else
+ host = vHost;
+
+ if (HSRequestMemoOper == 1 && memoserv)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
+ {
+ Oper *o = Config->Opers[i];
+
+ NickAlias *na = findnick(o->name);
+ if (!na)
+ continue;
+
+ Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.u->GetMask().c_str());
+
+ memoserv->Send(Config->HostServ, na->nick, message, true);
+ }
+}
+
+void my_add_host_request(const Anope::string &nick, const Anope::string &vIdent, const Anope::string &vhost, const Anope::string &creator, time_t tmp_time)
+{
+ HostRequest *hr = new HostRequest;
+ hr->ident = vIdent;
+ hr->host = vhost;
+ hr->time = tmp_time;
+ RequestMap::iterator it = Requests.find(nick);
+ if (it != Requests.end())
+ {
+ delete it->second;
+ Requests.erase(it);
+ }
+ Requests.insert(std::make_pair(nick, hr));
+}
+
+void my_load_config()
+{
+ ConfigReader config;
+ HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
+ HSRequestMemoOper = config.ReadFlag("hs_request", "memooper", "no", 0);
+
+ Log(LOG_DEBUG) << "[hs_request] Set config vars: MemoUser=" << HSRequestMemoUser << " MemoOper=" << HSRequestMemoOper;
+}
+
+MODULE_INIT(HSRequest)