summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2016-10-09 19:51:39 -0400
committerAdam <Adam@anope.org>2016-10-09 19:51:39 -0400
commite7dd7159b1e1ab5b3edabc44ece5338672f8fbb4 (patch)
tree9517f02ca1c29fa247f6914398f35a44052c22ff
parent8ceca4fd3f9cb82bc93801d5eb682d27b2ad2f54 (diff)
Make vhosts assignable to accounts, not nicks. Allow multiple vhosts per account.
-rw-r--r--data/anope.example.conf1
-rw-r--r--data/hostserv.example.conf52
-rw-r--r--include/module.h1
-rw-r--r--include/modules/hostserv.h48
-rw-r--r--include/modules/nickserv.h4
-rw-r--r--modules/database/old.cpp4
-rw-r--r--modules/hostserv/add.cpp135
-rw-r--r--modules/hostserv/del.cpp77
-rw-r--r--modules/hostserv/group.cpp144
-rw-r--r--modules/hostserv/list.cpp79
-rw-r--r--modules/hostserv/main/hostserv.cpp14
-rw-r--r--modules/hostserv/main/vhost.cpp14
-rw-r--r--modules/hostserv/main/vhost.h4
-rw-r--r--modules/hostserv/main/vhosttype.cpp1
-rw-r--r--modules/hostserv/main/vhosttype.h1
-rw-r--r--modules/hostserv/off.cpp8
-rw-r--r--modules/hostserv/on.cpp44
-rw-r--r--modules/hostserv/request.cpp42
-rw-r--r--modules/hostserv/set.cpp246
-rw-r--r--modules/nickserv/info.cpp18
-rw-r--r--modules/nickserv/main/nick.cpp9
-rw-r--r--modules/nickserv/main/nick.h4
-rw-r--r--modules/nickserv/main/nicktype.cpp1
-rw-r--r--modules/nickserv/main/nicktype.h2
-rw-r--r--modules/operserv/session.cpp1
-rw-r--r--modules/sasl.cpp3
-rw-r--r--modules/webcpanel/pages/hostserv/request.cpp7
-rw-r--r--modules/webcpanel/pages/nickserv/info.cpp7
28 files changed, 414 insertions, 557 deletions
diff --git a/data/anope.example.conf b/data/anope.example.conf
index 1a72403dd..9a0384e6f 100644
--- a/data/anope.example.conf
+++ b/data/anope.example.conf
@@ -759,6 +759,7 @@ log
* chanserv/auspex - Can see any information with /chanserv info
* chanserv/no-register-limit - May register an unlimited number of channels and nicknames
* chanserv/kick - Can kick and ban users from channels through ChanServ
+ * hostsev/auspex - Can view other users vhosts
* memoserv/info - Can see any information with /memoserv info
* memoserv/set-limit - Can set the limit of max stored memos on any user and channel
* memoserv/no-limit - Can send memos through limits and throttles
diff --git a/data/hostserv.example.conf b/data/hostserv.example.conf
index 685eb9722..928261b26 100644
--- a/data/hostserv.example.conf
+++ b/data/hostserv.example.conf
@@ -77,38 +77,34 @@ module
command { service = "HostServ"; name = "HELP"; command = "generic/help"; }
/*
+ * hostserv/add
+ *
+ * Provides the command hostserv/add.
+ *
+ * Used for setting users' vHosts.
+ */
+module { name = "hostserv/add" }
+command { service = "HostServ"; name = "ADD"; command = "hostserv/add"; permission = "hostserv/add"; }
+
+/*
* hostserv/del
*
- * Provides the commands hostserv/del and hostserv/delall.
+ * Provides the command hostserv/del.
*
* Used for removing users' vHosts.
*/
module { name = "hostserv/del" }
command { service = "HostServ"; name = "DEL"; command = "hostserv/del"; permission = "hostserv/del"; }
-command { service = "HostServ"; name = "DELALL"; command = "hostserv/delall"; permission = "hostserv/del"; }
/*
- * hostserv/group
+ * hostserv/info
*
- * Provides the command hostserv/group.
+ * Provides the command hostserv/info.
*
- * Used for grouping one vHost to many nicks.
+ * Used for viewing users' vHosts.
*/
-module
-{
- name = "hostserv/group"
-
- /*
- * Upon nickserv/group, this option syncs the nick's main vHost to the grouped nick.
- */
- syncongroup = false
-
- /*
- * This makes vhosts act as if they are per account.
- */
- synconset = false
-}
-command { service = "HostServ"; name = "GROUP"; command = "hostserv/group"; }
+module { name = "hostserv/info" }
+command { service = "HostServ"; name = "INFO"; command = "hostserv/info"; }
/*
* hostserv/list
@@ -163,17 +159,19 @@ module
#memooper = yes
}
command { service = "HostServ"; name = "REQUEST"; command = "hostserv/request"; }
-command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/activate"; permission = "hostserv/set"; }
-command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; permission = "hostserv/set"; }
-command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/set"; }
+command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/activate"; permission = "hostserv/add"; }
+command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; permission = "hostserv/add"; }
+command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/add"; }
/*
* hostserv/set
*
- * Provides the commands hostserv/set and hostserv/setall.
+ * Provides the commands:
+ * hostserv/set - Dummy help wrappers for the SET commands.
+ * hostserv/set/default - Used for configuring your default vhost.
*
- * Used for setting users' vHosts.
+ * Used for managing vhost settings.
*/
module { name = "hostserv/set" }
-command { service = "HostServ"; name = "SET"; command = "hostserv/set"; permission = "hostserv/set"; }
-command { service = "HostServ"; name = "SETALL"; command = "hostserv/setall"; permission = "hostserv/set"; }
+command { service = "HostServ"; name = "SET"; command = "hostserv/set"; }
+command { service = "HostServ"; name = "SET DEFAULT"; command = "hostserv/set/default"; }
diff --git a/include/module.h b/include/module.h
index 490196f9c..6371eb336 100644
--- a/include/module.h
+++ b/include/module.h
@@ -52,4 +52,5 @@
#include "modules/nickserv.h"
#include "modules/botserv.h"
#include "modules/memoserv.h"
+#include "modules/hostserv.h"
#include "accessgroup.h"
diff --git a/include/modules/hostserv.h b/include/modules/hostserv.h
index 4e6661faa..6934c813e 100644
--- a/include/modules/hostserv.h
+++ b/include/modules/hostserv.h
@@ -45,6 +45,54 @@ namespace HostServ
virtual time_t GetCreated() anope_abstract;
virtual void SetCreated(time_t) anope_abstract;
+
+ virtual bool IsDefault() anope_abstract;
+ virtual void SetDefault(bool) anope_abstract;
+
+ inline Anope::string Mask()
+ {
+ Anope::string ident = GetIdent(), host = GetHost();
+ if (!ident.empty())
+ return ident + "@" + host;
+ else
+ return host;
+ }
};
+
+ /** Find the default vhost for an object, or the first
+ * if there is no default.
+ * @return The object's vhost
+ */
+ inline VHost *FindVHost(Serialize::Object *obj)
+ {
+ VHost *first = nullptr;
+
+ for (VHost *v : obj->GetRefs<VHost *>())
+ {
+ if (first == nullptr)
+ first = v;
+
+ if (v->IsDefault())
+ {
+ first = v;
+ break;
+ }
+ }
+
+ return first;
+ }
+
+ inline VHost *FindVHost(Serialize::Object *obj, const Anope::string &v)
+ {
+ for (VHost *vhost : obj->GetRefs<VHost *>())
+ {
+ if (vhost->Mask().equals_ci(v))
+ {
+ return vhost;
+ }
+ }
+
+ return nullptr;
+ }
}
diff --git a/include/modules/nickserv.h b/include/modules/nickserv.h
index 1ecb2a933..ef06bcb0c 100644
--- a/include/modules/nickserv.h
+++ b/include/modules/nickserv.h
@@ -22,7 +22,6 @@
#include "event.h"
#include "service.h"
#include "serialize.h"
-#include "hostserv.h"
namespace NickServ
{
@@ -169,9 +168,6 @@ namespace NickServ
virtual Account *GetAccount() anope_abstract;
virtual void SetAccount(Account *acc) anope_abstract;
-
- virtual HostServ::VHost *GetVHost() anope_abstract;
- virtual void SetVHost(HostServ::VHost *) anope_abstract;
};
/* A registered account. Each account must have a Nick with the same nick as the
diff --git a/modules/database/old.cpp b/modules/database/old.cpp
index dad711cdb..d63b2c4d8 100644
--- a/modules/database/old.cpp
+++ b/modules/database/old.cpp
@@ -742,14 +742,12 @@ static void LoadVHosts()
if (vhost == nullptr)
continue;
- vhost->SetOwner(na);
+ vhost->SetOwner(na->GetAccount());
vhost->SetIdent(ident);
vhost->SetHost(host);
vhost->SetCreator(creator);
vhost->SetCreated(vtime);
- na->SetVHost(vhost);
-
Log() << "Loaded vhost for " << na->GetNick();
}
diff --git a/modules/hostserv/add.cpp b/modules/hostserv/add.cpp
new file mode 100644
index 000000000..42f457b25
--- /dev/null
+++ b/modules/hostserv/add.cpp
@@ -0,0 +1,135 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+
+class CommandHSAdd : public Command
+{
+ public:
+ CommandHSAdd(Module *creator) : Command(creator, "hostserv/add", 2, 2)
+ {
+ this->SetDesc(_("Adds a vhost to an account"));
+ this->SetSyntax(_("\037account\037 \037hostmask\037"));
+ }
+
+ void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
+ {
+ if (Anope::ReadOnly)
+ {
+ source.Reply(_("Services are in read-only mode."));
+ return;
+ }
+
+ const Anope::string &nick = params[0];
+
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ if (na == NULL)
+ {
+ source.Reply(_("\002{0}\002 isn't registered."), nick);
+ return;
+ }
+
+ Anope::string rawhostmask = params[1];
+
+ 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 (!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;
+ }
+
+ Anope::string mask = (!user.empty() ? user + "@" : "") + host;
+ Log(LOG_ADMIN, source, this) << "to add the vhost " << mask << " to " << na->GetAccount()->GetDisplay();
+
+ HostServ::VHost *vhost = Serialize::New<HostServ::VHost *>();
+ if (vhost == nullptr)
+ {
+ source.Reply(_("Unable to create vhost, is hostserv enabled?"));
+ return;
+ }
+
+ vhost->SetOwner(na->GetAccount());
+ vhost->SetIdent(user);
+ vhost->SetHost(host);
+ vhost->SetCreator(source.GetNick());
+ vhost->SetCreated(Anope::CurTime);
+
+#warning "change event to broadcast account"
+ EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, na);
+ source.Reply(_("Vhost \002{0}\002 added to \002{1}\002."), mask, na->GetAccount()->GetDisplay());
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
+ {
+ source.Reply(_("Adds the vhost \037hostmask\037 to \037account\037."));
+ return true;
+ }
+};
+
+class HSAdd : public Module
+{
+ CommandHSAdd commandhsadd;
+
+ public:
+ HSAdd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
+ , commandhsadd(this)
+ {
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
+ }
+};
+
+MODULE_INIT(HSAdd)
diff --git a/modules/hostserv/del.cpp b/modules/hostserv/del.cpp
index 48a1209fc..4d754ac1b 100644
--- a/modules/hostserv/del.cpp
+++ b/modules/hostserv/del.cpp
@@ -23,10 +23,10 @@
class CommandHSDel : public Command
{
public:
- CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 1)
+ CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 2)
{
- this->SetDesc(_("Delete the vhost of another user"));
- this->SetSyntax(_("\037user\037"));
+ this->SetDesc(_("Delete the vhost of a user"));
+ this->SetSyntax(_("\037user\037 [\037vhost\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
@@ -35,6 +35,8 @@ class CommandHSDel : public Command
source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
const Anope::string &nick = params[0];
+ const Anope::string &host = params.size() > 1 ? params[1] : "";
+
NickServ::Nick *na = NickServ::FindNick(nick);
if (!na)
{
@@ -42,67 +44,42 @@ class CommandHSDel : public Command
return;
}
- HostServ::VHost *vhost = na->GetVHost();
- if (vhost == nullptr)
+ if (!host.empty())
{
- source.Reply(_("\002{0}\002 doesn't have a vhost."), na->GetNick());
- return;
- }
+ HostServ::VHost *vhost = HostServ::FindVHost(na->GetAccount(), host);
- Log(LOG_ADMIN, source, this) << "for user " << na->GetNick();
- EventManager::Get()->Dispatch(&Event::DeleteVhost::OnDeleteVhost, na);
- vhost->Delete();
- source.Reply(_("Vhost for \002{0}\002 has been removed."), na->GetNick());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
- {
- source.Reply(_("Removes the vhost of \037user\037."));
- return true;
- }
-};
-
-class CommandHSDelAll : public Command
-{
- public:
- CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1)
- {
- this->SetDesc(_("Delete the vhost for all nicks in a group"));
- this->SetSyntax(_("\037group\037"));
- }
+ if (vhost == nullptr)
+ {
+ source.Reply(_("\002{0}\002 doesn't have vhost \002{1}\002."), na->GetAccount()->GetDisplay(), host);
+ return;
+ }
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
- {
- if (Anope::ReadOnly)
- source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
+ Log(LOG_ADMIN, source, this) << "on " << na->GetAccount()->GetDisplay() << " to remove vhost " << vhost->Mask();
+ source.Reply(_("Vhost \002{0}\002 for \002{1}\002 has been removed."), vhost->Mask(), na->GetAccount()->GetDisplay());
+ vhost->Delete();
+ return;
+ }
- const Anope::string &nick = params[0];
- NickServ::Nick *na = NickServ::FindNick(nick);
- if (!na)
+ std::vector<HostServ::VHost *> vhosts = na->GetAccount()->GetRefs<HostServ::VHost *>();
+ if (vhosts.empty())
{
- source.Reply(_("\002{0}\002 isn't registered."), nick);
+ source.Reply(_("\002{0}\002 doesn't have a vhost."), na->GetAccount()->GetDisplay());
return;
}
+ Log(LOG_ADMIN, source, this) << "on " << na->GetAccount()->GetDisplay();
+#warning "send account"
EventManager::Get()->Dispatch(&Event::DeleteVhost::OnDeleteVhost, na);
- NickServ::Account *nc = na->GetAccount();
- for (NickServ::Nick *na2 : nc->GetRefs<NickServ::Nick *>())
- {
- HostServ::VHost *vhost = na2->GetVHost();
- if (vhost != nullptr)
- {
- vhost->Delete();
- }
- }
+ for (HostServ::VHost *v : vhosts)
+ v->Delete();
- Log(LOG_ADMIN, source, this) << "for all nicks in group " << nc->GetDisplay();
- source.Reply(_("Vhosts for group \002{0}\002 have been removed."), nc->GetDisplay());
+ source.Reply(_("Vhost(s) for \002{0}\002 has been removed."), na->GetAccount()->GetDisplay());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- source.Reply(_("Removes the vhost of all nicks in the group \037group\037."));
+ source.Reply(_("Removes the vhost of \037user\037."));
return true;
}
};
@@ -110,12 +87,10 @@ class CommandHSDelAll : public Command
class HSDel : public Module
{
CommandHSDel commandhsdel;
- CommandHSDelAll commandhsdelall;
public:
HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, commandhsdel(this)
- , commandhsdelall(this)
{
if (!IRCD || !IRCD->CanSetVHost)
throw ModuleException("Your IRCd does not support vhosts");
diff --git a/modules/hostserv/group.cpp b/modules/hostserv/group.cpp
deleted file mode 100644
index a41dc24db..000000000
--- a/modules/hostserv/group.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Anope IRC Services
- *
- * Copyright (C) 2003-2016 Anope Team <team@anope.org>
- *
- * This file is part of Anope. Anope is free software; you can
- * redistribute it and/or modify it under the terms of the GNU
- * General Public License as published by the Free Software
- * Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see see <http://www.gnu.org/licenses/>.
- */
-
-#include "module.h"
-#include "modules/nickserv/group.h"
-
-class CommandHSGroup : public Command
-{
- bool setting;
-
- public:
- void Sync(NickServ::Nick *na)
- {
- if (setting)
- return;
-
- HostServ::VHost *v = na->GetVHost();
-
- if (v == nullptr)
- return;
-
- setting = true;
- for (NickServ::Nick *nick : na->GetAccount()->GetRefs<NickServ::Nick *>())
- {
- if (nick == na)
- continue;
-
- HostServ::VHost *vhost = Serialize::New<HostServ::VHost *>();
- if (vhost == nullptr)
- continue;
-
- vhost->SetOwner(nick);
- vhost->SetIdent(v->GetIdent());
- vhost->SetHost(v->GetHost());
- vhost->SetCreator(v->GetCreator());
- vhost->SetCreated(Anope::CurTime);
-
- nick->SetVHost(vhost);
-
- EventManager::Get()->Dispatch(&Event::SetVhost::OnSetVhost, nick);
- }
- setting = false;
- }
-
- CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0), setting(false)
- {
- this->SetDesc(_("Syncs the vhost for all nicks in a group"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(_("Services are in read-only mode."));
- return;
- }
-
- NickServ::Nick *na = NickServ::FindNick(source.GetNick());
- if (!na || na->GetAccount() != source.GetAccount())
- {
- source.Reply(_("Access denied."));
- return;
- }
-
- HostServ::VHost *vhost = na->GetVHost();
- if (vhost == nullptr)
- {
- source.Reply(_("There is no vhost assigned to this nickname."));
- return;
- }
-
- this->Sync(na);
- if (!vhost->GetIdent().empty())
- source.Reply(_("All vhosts in the group \002{0}\002 have been set to \002{1}\002@\002{2}\002."), source.nc->GetDisplay(), vhost->GetIdent(), vhost->GetHost());
- else
- source.Reply(_("All vhosts in the group \002{0}\002 have been set to \002{1}\002."), source.nc->GetDisplay(), vhost->GetHost());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
- {
- source.Reply(_("Sets the vhost of all nicks in your group to the vhost of your current nick."));
- return true;
- }
-};
-
-class HSGroup : public Module
- , public EventHook<Event::SetVhost>
- , public EventHook<Event::NickGroup>
-{
- CommandHSGroup commandhsgroup;
- bool syncongroup;
- bool synconset;
-
- public:
- HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
- , EventHook<Event::SetVhost>(this)
- , EventHook<Event::NickGroup>(this)
- , commandhsgroup(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-
- void OnSetVhost(NickServ::Nick *na) override
- {
- if (!synconset)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnNickGroup(User *u, NickServ::Nick *na) override
- {
- if (!syncongroup)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnReload(Configuration::Conf *conf) override
- {
- Configuration::Block *block = conf->GetModule(this);
- syncongroup = block->Get<bool>("syncongroup");
- synconset = block->Get<bool>("synconset");
- }
-};
-
-MODULE_INIT(HSGroup)
diff --git a/modules/hostserv/list.cpp b/modules/hostserv/list.cpp
index 5a2b5238a..cbb69aa85 100644
--- a/modules/hostserv/list.cpp
+++ b/modules/hostserv/list.cpp
@@ -21,6 +21,14 @@
class CommandHSList : public Command
{
+ bool VHostMatches(NickServ::Account *acc, const Anope::string &mask)
+ {
+ for (HostServ::VHost *vhost : acc->GetRefs<HostServ::VHost *>())
+ if (Anope::Match(vhost->GetHost(), mask))
+ return true;
+ return false;
+ }
+
public:
CommandHSList(Module *creator) : Command(creator, "hostserv/list", 0, 1)
{
@@ -63,55 +71,46 @@ class CommandHSList : public Command
unsigned display_counter = 0, listmax = Config->GetModule(this->GetOwner())->Get<unsigned>("listmax", "50");
ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Creator")).AddColumn(_("Created"));
+ list.AddColumn(_("Number")).AddColumn(_("Account")).AddColumn(_("Vhost")).AddColumn(_("Creator")).AddColumn(_("Created"));
- for (NickServ::Nick *na : NickServ::service->GetNickList())
+ for (NickServ::Account *acc : NickServ::service->GetAccountList())
{
- HostServ::VHost *vhost = na->GetVHost();
+ std::vector<HostServ::VHost *> vhosts = acc->GetRefs<HostServ::VHost *>();
- if (vhost == nullptr)
+ if (vhosts.empty())
continue;
- if (!key.empty() && key[0] != '#')
- {
- if ((Anope::Match(na->GetNick(), key) || Anope::Match(vhost->GetHost(), key)) && display_counter < listmax)
- {
- ++display_counter;
+ ++counter;
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->GetNick();
- if (!vhost->GetIdent().empty())
- entry["Vhost"] = vhost->GetIdent() + "@" + vhost->GetHost();
- else
- entry["Vhost"] = vhost->GetHost();
- entry["Creator"] = vhost->GetCreator();
- entry["Created"] = Anope::strftime(vhost->GetCreated(), NULL, true);
- list.AddEntry(entry);
- }
- }
- else
+ if (display_counter >= listmax)
+ continue;
+
+ if (from && to && (counter < from || counter > to))
+ continue;
+
+ if (!key.empty() && !Anope::Match(acc->GetDisplay(), key) && !VHostMatches(acc, key))
+ continue;
+
+ ++display_counter;
+
+ bool first = true;
+ for (HostServ::VHost *vhost : vhosts)
{
- /**
- * List the host if its in the display range, and not more
- * than NSListMax records have been displayed...
- **/
- if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax)
+ ListFormatter::ListEntry entry;
+
+ if (first)
{
- ++display_counter;
- ListFormatter::ListEntry entry;
entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->GetNick();
- if (!vhost->GetIdent().empty())
- entry["Vhost"] = vhost->GetIdent() + "@" + vhost->GetHost();
- else
- entry["Vhost"] = vhost->GetHost();
- entry["Creator"] = vhost->GetCreator();
- entry["Created"] = Anope::strftime(vhost->GetCreated(), NULL, true);
- list.AddEntry(entry);
+ entry["Account"] = acc->GetDisplay();
}
+
+ entry["Vhost"] = vhost->Mask();
+ entry["Creator"] = vhost->GetCreator();
+ entry["Created"] = Anope::strftime(vhost->GetCreated(), NULL, true);
+ list.AddEntry(entry);
+
+ first = false;
}
- ++counter;
}
if (!display_counter)
@@ -139,12 +138,12 @@ class CommandHSList : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
- source.Reply(_("Lists all vhosts. If \037key\037 is specified, only entries whose nick or vhost match the pattern given in \037key\037 are displayed."
+ source.Reply(_("Lists all vhosts. If \037key\037 is specified, only entries whose account or vhost match the pattern given in \037key\037 are displayed."
"If a \037#X-Y\037 style is used, only entries between the range of \002X\002 and \002Y\002 will be displayed.\n"
"\n"
"Examples:\n"
" {0} Rob*\n"
- " Lists all entries with the nick or vhost beginning with \"Rob\"\n"
+ " Lists all entries with the account or vhost beginning with \"Rob\"\n"
"\n"
" {0} #1-3\n"
" Lists the first three entries."),
diff --git a/modules/hostserv/main/hostserv.cpp b/modules/hostserv/main/hostserv.cpp
index ab1617a85..b0c3d04f2 100644
--- a/modules/hostserv/main/hostserv.cpp
+++ b/modules/hostserv/main/hostserv.cpp
@@ -66,14 +66,7 @@ class HostServCore : public Module
if (!IRCD->CanSetVHost)
return;
- NickServ::Nick *na = NickServ::FindNick(u->nick);
- HostServ::VHost *vhost = nullptr;
-
- if (na && na->GetAccount() == u->Account())
- vhost = na->GetVHost();
-
- if (vhost == nullptr)
- vhost = NickServ::FindNick(u->Account()->GetDisplay())->GetVHost();
+ HostServ::VHost *vhost = HostServ::FindVHost(u->Account());
if (vhost == nullptr)
return;
@@ -123,7 +116,10 @@ class HostServCore : public Module
if (u && u->Account() == na->GetAccount())
{
- HostServ::VHost *vhost = na->GetVHost();
+ HostServ::VHost *vhost = HostServ::FindVHost(u->Account());
+
+ if (vhost == nullptr)
+ return;
IRCD->SendVhost(u, vhost->GetIdent(), vhost->GetHost());
diff --git a/modules/hostserv/main/vhost.cpp b/modules/hostserv/main/vhost.cpp
index f7878d53c..635e3a5b4 100644
--- a/modules/hostserv/main/vhost.cpp
+++ b/modules/hostserv/main/vhost.cpp
@@ -1,7 +1,7 @@
/*
* Anope IRC Services
*
- * Copyright (C) 2015-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2016 Anope Team <team@anope.org>
*
* This file is part of Anope. Anope is free software; you can
* redistribute it and/or modify it under the terms of the GNU
@@ -67,4 +67,14 @@ time_t VHostImpl::GetCreated()
void VHostImpl::SetCreated(time_t created)
{
Set(&VHostType::created, created);
-} \ No newline at end of file
+}
+
+bool VHostImpl::IsDefault()
+{
+ return Get(&VHostType::default_);
+}
+
+void VHostImpl::SetDefault(bool default_)
+{
+ Set(&VHostType::default_, default_);
+}
diff --git a/modules/hostserv/main/vhost.h b/modules/hostserv/main/vhost.h
index e0b751899..90ac9140f 100644
--- a/modules/hostserv/main/vhost.h
+++ b/modules/hostserv/main/vhost.h
@@ -30,6 +30,7 @@ class VHostImpl : public HostServ::VHost
Anope::string vhost;
Anope::string creator;
time_t created = 0;
+ bool default_ = false;
public:
using HostServ::VHost::VHost;
@@ -48,5 +49,8 @@ class VHostImpl : public HostServ::VHost
time_t GetCreated() override;
void SetCreated(time_t) override;
+
+ bool IsDefault() override;
+ void SetDefault(bool) override;
};
diff --git a/modules/hostserv/main/vhosttype.cpp b/modules/hostserv/main/vhosttype.cpp
index 3eae8eec3..ee73840bf 100644
--- a/