]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Move src/commands/cmd_*.cpp to src/coremods[/core_*]/
authorAttila Molnar <attilamolnar@hush.com>
Wed, 5 Mar 2014 14:41:06 +0000 (15:41 +0100)
committerAttila Molnar <attilamolnar@hush.com>
Wed, 5 Mar 2014 14:41:06 +0000 (15:41 +0100)
100 files changed:
src/commands/cmd_admin.cpp [deleted file]
src/commands/cmd_away.cpp [deleted file]
src/commands/cmd_commands.cpp [deleted file]
src/commands/cmd_connect.cpp [deleted file]
src/commands/cmd_die.cpp [deleted file]
src/commands/cmd_dns.cpp [deleted file]
src/commands/cmd_eline.cpp [deleted file]
src/commands/cmd_gline.cpp [deleted file]
src/commands/cmd_hostname_lookup.cpp [deleted file]
src/commands/cmd_info.cpp [deleted file]
src/commands/cmd_invite.cpp [deleted file]
src/commands/cmd_ison.cpp [deleted file]
src/commands/cmd_join.cpp [deleted file]
src/commands/cmd_kick.cpp [deleted file]
src/commands/cmd_kill.cpp [deleted file]
src/commands/cmd_kline.cpp [deleted file]
src/commands/cmd_links.cpp [deleted file]
src/commands/cmd_list.cpp [deleted file]
src/commands/cmd_loadmodule.cpp [deleted file]
src/commands/cmd_lusers.cpp [deleted file]
src/commands/cmd_mode.cpp [deleted file]
src/commands/cmd_modules.cpp [deleted file]
src/commands/cmd_motd.cpp [deleted file]
src/commands/cmd_names.cpp [deleted file]
src/commands/cmd_nick.cpp [deleted file]
src/commands/cmd_oper.cpp [deleted file]
src/commands/cmd_part.cpp [deleted file]
src/commands/cmd_pass.cpp [deleted file]
src/commands/cmd_ping.cpp [deleted file]
src/commands/cmd_pong.cpp [deleted file]
src/commands/cmd_privmsg.cpp [deleted file]
src/commands/cmd_qline.cpp [deleted file]
src/commands/cmd_quit.cpp [deleted file]
src/commands/cmd_rehash.cpp [deleted file]
src/commands/cmd_reloadmodule.cpp [deleted file]
src/commands/cmd_restart.cpp [deleted file]
src/commands/cmd_server.cpp [deleted file]
src/commands/cmd_squit.cpp [deleted file]
src/commands/cmd_stats.cpp [deleted file]
src/commands/cmd_time.cpp [deleted file]
src/commands/cmd_topic.cpp [deleted file]
src/commands/cmd_unloadmodule.cpp [deleted file]
src/commands/cmd_user.cpp [deleted file]
src/commands/cmd_userhost.cpp [deleted file]
src/commands/cmd_version.cpp [deleted file]
src/commands/cmd_wallops.cpp [deleted file]
src/commands/cmd_who.cpp [deleted file]
src/commands/cmd_whois.cpp [deleted file]
src/commands/cmd_whowas.cpp [deleted file]
src/commands/cmd_zline.cpp [deleted file]
src/coremods/core_channel/cmd_invite.cpp [new file with mode: 0644]
src/coremods/core_channel/cmd_join.cpp [new file with mode: 0644]
src/coremods/core_channel/cmd_kick.cpp [new file with mode: 0644]
src/coremods/core_channel/cmd_names.cpp [new file with mode: 0644]
src/coremods/core_channel/cmd_topic.cpp [new file with mode: 0644]
src/coremods/core_connect.cpp [new file with mode: 0644]
src/coremods/core_dns.cpp [new file with mode: 0644]
src/coremods/core_hostname_lookup.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_admin.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_commands.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_info.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_modules.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_motd.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_time.cpp [new file with mode: 0644]
src/coremods/core_info/cmd_version.cpp [new file with mode: 0644]
src/coremods/core_ison.cpp [new file with mode: 0644]
src/coremods/core_links.cpp [new file with mode: 0644]
src/coremods/core_list.cpp [new file with mode: 0644]
src/coremods/core_loadmodule.cpp [new file with mode: 0644]
src/coremods/core_lusers.cpp [new file with mode: 0644]
src/coremods/core_oper/cmd_die.cpp [new file with mode: 0644]
src/coremods/core_oper/cmd_kill.cpp [new file with mode: 0644]
src/coremods/core_oper/cmd_oper.cpp [new file with mode: 0644]
src/coremods/core_oper/cmd_rehash.cpp [new file with mode: 0644]
src/coremods/core_oper/cmd_restart.cpp [new file with mode: 0644]
src/coremods/core_privmsg.cpp [new file with mode: 0644]
src/coremods/core_reloadmodule.cpp [new file with mode: 0644]
src/coremods/core_server.cpp [new file with mode: 0644]
src/coremods/core_squit.cpp [new file with mode: 0644]
src/coremods/core_stats.cpp [new file with mode: 0644]
src/coremods/core_unloadmodule.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_away.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_mode.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_nick.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_part.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_pass.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_ping.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_pong.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_quit.cpp [new file with mode: 0644]
src/coremods/core_user/cmd_user.cpp [new file with mode: 0644]
src/coremods/core_userhost.cpp [new file with mode: 0644]
src/coremods/core_wallops.cpp [new file with mode: 0644]
src/coremods/core_who.cpp [new file with mode: 0644]
src/coremods/core_whois.cpp [new file with mode: 0644]
src/coremods/core_whowas.cpp [new file with mode: 0644]
src/coremods/core_xline/cmd_eline.cpp [new file with mode: 0644]
src/coremods/core_xline/cmd_gline.cpp [new file with mode: 0644]
src/coremods/core_xline/cmd_kline.cpp [new file with mode: 0644]
src/coremods/core_xline/cmd_qline.cpp [new file with mode: 0644]
src/coremods/core_xline/cmd_zline.cpp [new file with mode: 0644]

diff --git a/src/commands/cmd_admin.cpp b/src/commands/cmd_admin.cpp
deleted file mode 100644 (file)
index 1f694bf..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /ADMIN.
- */
-class CommandAdmin : public Command
-{
- public:
-       /** Constructor for admin.
-        */
-       CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0)
-       {
-               Penalty = 2;
-               syntax = "[<servername>]";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() > 0)
-                       return ROUTE_UNICAST(parameters[0]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-/** Handle /ADMIN
- */
-CmdResult CommandAdmin::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
-               return CMD_SUCCESS;
-       user->SendText(":%s %03d %s :Administrative info for %s", ServerInstance->Config->ServerName.c_str(),
-               RPL_ADMINME, user->nick.c_str(),ServerInstance->Config->ServerName.c_str());
-       if (!ServerInstance->Config->AdminName.empty())
-               user->SendText(":%s %03d %s :Name     - %s", ServerInstance->Config->ServerName.c_str(),
-                       RPL_ADMINLOC1, user->nick.c_str(), ServerInstance->Config->AdminName.c_str());
-       user->SendText(":%s %03d %s :Nickname - %s", ServerInstance->Config->ServerName.c_str(),
-               RPL_ADMINLOC2, user->nick.c_str(), ServerInstance->Config->AdminNick.c_str());
-       user->SendText(":%s %03d %s :E-Mail   - %s", ServerInstance->Config->ServerName.c_str(),
-               RPL_ADMINEMAIL, user->nick.c_str(), ServerInstance->Config->AdminEmail.c_str());
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandAdmin)
diff --git a/src/commands/cmd_away.cpp b/src/commands/cmd_away.cpp
deleted file mode 100644 (file)
index 4f61cec..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /AWAY.
- */
-class CommandAway : public Command
-{
- public:
-       /** Constructor for away.
-        */
-       CommandAway ( Module* parent) : Command(parent,"AWAY",0,0) { syntax = "[<message>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-/** Handle /AWAY
- */
-CmdResult CommandAway::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       ModResult MOD_RESULT;
-
-       if ((parameters.size()) && (!parameters[0].empty()))
-       {
-               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, parameters[0]));
-
-               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
-                       return CMD_FAILURE;
-
-               user->awaytime = ServerInstance->Time();
-               user->awaymsg.assign(parameters[0], 0, ServerInstance->Config->Limits.MaxAway);
-
-               user->WriteNumeric(RPL_NOWAWAY, ":You have been marked as being away");
-       }
-       else
-       {
-               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, ""));
-
-               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
-                       return CMD_FAILURE;
-
-               user->awaymsg.clear();
-               user->WriteNumeric(RPL_UNAWAY, ":You are no longer marked as being away");
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandAway)
diff --git a/src/commands/cmd_commands.cpp b/src/commands/cmd_commands.cpp
deleted file mode 100644 (file)
index 3f0ab99..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /COMMANDS.
- */
-class CommandCommands : public Command
-{
- public:
-       /** Constructor for commands.
-        */
-       CommandCommands(Module* parent) : Command(parent,"COMMANDS",0,0)
-       {
-               Penalty = 3;
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /COMMANDS
- */
-CmdResult CommandCommands::Handle (const std::vector<std::string>&, User *user)
-{
-       std::vector<std::string> list;
-       list.reserve(ServerInstance->Parser->cmdlist.size());
-       for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++)
-       {
-               // Don't show S2S commands to users
-               if (i->second->flags_needed == FLAG_SERVERONLY)
-                       continue;
-
-               Module* src = i->second->creator;
-               list.push_back(InspIRCd::Format(":%s %03d %s :%s %s %d %d", ServerInstance->Config->ServerName.c_str(),
-                       RPL_COMMANDS, user->nick.c_str(), i->second->name.c_str(), src->ModuleSourceFile.c_str(),
-                       i->second->min_params, i->second->Penalty));
-       }
-       sort(list.begin(), list.end());
-       for(unsigned int i=0; i < list.size(); i++)
-               user->Write(list[i]);
-       user->WriteNumeric(RPL_COMMANDSEND, ":End of COMMANDS list");
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandCommands)
diff --git a/src/commands/cmd_connect.cpp b/src/commands/cmd_connect.cpp
deleted file mode 100644 (file)
index 59e7487..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /CONNECT.
- */
-class CommandConnect : public Command
-{
- public:
-       /** Constructor for connect.
-        */
-       CommandConnect ( Module* parent) : Command(parent,"CONNECT",1) { flags_needed = 'o'; syntax = "<servername> [<remote-server>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/*
- * This is handled by the server linking module, if necessary. Do not remove this stub.
- */
-
-/** Handle /CONNECT
- */
-CmdResult CommandConnect::Handle (const std::vector<std::string>&, User *user)
-{
-       user->WriteServ( "NOTICE %s :Look into loading a linking module (like m_spanningtree) if you want this to do anything useful.", user->nick.c_str());
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandConnect)
diff --git a/src/commands/cmd_die.cpp b/src/commands/cmd_die.cpp
deleted file mode 100644 (file)
index 63e4c59..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /DIE.
- */
-class CommandDie : public Command
-{
- public:
-       /** Constructor for die.
-        */
-       CommandDie ( Module* parent) : Command(parent,"DIE",1) { flags_needed = 'o'; syntax = "<password>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-#include "exitcodes.h"
-
-/** Handle /DIE
- */
-CmdResult CommandDie::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (ServerInstance->PassCompare(user, ServerInstance->Config->diepass, parameters[0], ServerInstance->Config->powerhash))
-       {
-               {
-                       std::string diebuf = "*** DIE command from " + user->GetFullHost() + ". Terminating.";
-                       ServerInstance->Logs->Log("COMMAND", LOG_SPARSE, diebuf);
-                       ServerInstance->SendError(diebuf);
-               }
-
-               ServerInstance->Exit(EXIT_STATUS_DIE);
-       }
-       else
-       {
-               ServerInstance->Logs->Log("COMMAND", LOG_SPARSE, "Failed /DIE command from %s", user->GetFullRealHost().c_str());
-               ServerInstance->SNO->WriteGlobalSno('a', "Failed DIE Command from %s.", user->GetFullRealHost().c_str());
-               return CMD_FAILURE;
-       }
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandDie)
diff --git a/src/commands/cmd_dns.cpp b/src/commands/cmd_dns.cpp
deleted file mode 100644 (file)
index 7b93c7b..0000000
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2013 Adam <Adam@anope.org>
- *   Copyright (C) 2003-2013 Anope Team <team@anope.org>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "inspircd.h"
-#include "modules/dns.h"
-#include <iostream>
-#include <fstream>
-
-#ifdef _WIN32
-#include <Iphlpapi.h>
-#pragma comment(lib, "Iphlpapi.lib")
-#endif
-
-using namespace DNS;
-
-/** A full packet sent or recieved to/from the nameserver
- */
-class Packet : public Query
-{
-       void PackName(unsigned char* output, unsigned short output_size, unsigned short& pos, const std::string& name)
-       {
-               if (pos + name.length() + 2 > output_size)
-                       throw Exception("Unable to pack name");
-
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Packing name " + name);
-
-               irc::sepstream sep(name, '.');
-               std::string token;
-
-               while (sep.GetToken(token))
-               {
-                       output[pos++] = token.length();
-                       memcpy(&output[pos], token.data(), token.length());
-                       pos += token.length();
-               }
-
-               output[pos++] = 0;
-       }
-
-       std::string UnpackName(const unsigned char* input, unsigned short input_size, unsigned short& pos)
-       {
-               std::string name;
-               unsigned short pos_ptr = pos, lowest_ptr = input_size;
-               bool compressed = false;
-
-               if (pos_ptr >= input_size)
-                       throw Exception("Unable to unpack name - no input");
-
-               while (input[pos_ptr] > 0)
-               {
-                       unsigned short offset = input[pos_ptr];
-
-                       if (offset & POINTER)
-                       {
-                               if ((offset & POINTER) != POINTER)
-                                       throw Exception("Unable to unpack name - bogus compression header");
-                               if (pos_ptr + 1 >= input_size)
-                                       throw Exception("Unable to unpack name - bogus compression header");
-
-                               /* Place pos at the second byte of the first (farthest) compression pointer */
-                               if (compressed == false)
-                               {
-                                       ++pos;
-                                       compressed = true;
-                               }
-
-                               pos_ptr = (offset & LABEL) << 8 | input[pos_ptr + 1];
-
-                               /* Pointers can only go back */
-                               if (pos_ptr >= lowest_ptr)
-                                       throw Exception("Unable to unpack name - bogus compression pointer");
-                               lowest_ptr = pos_ptr;
-                       }
-                       else
-                       {
-                               if (pos_ptr + offset + 1 >= input_size)
-                                       throw Exception("Unable to unpack name - offset too large");
-                               if (!name.empty())
-                                       name += ".";
-                               for (unsigned i = 1; i <= offset; ++i)
-                                       name += input[pos_ptr + i];
-
-                               pos_ptr += offset + 1;
-                               if (compressed == false)
-                                       /* Move up pos */
-                                       pos = pos_ptr;
-                       }
-               }
-
-               /* +1 pos either to one byte after the compression pointer or one byte after the ending \0 */
-               ++pos;
-
-               if (name.empty())
-                       throw Exception("Unable to unpack name - no name");
-
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Unpack name " + name);
-
-               return name;
-       }
-
-       Question UnpackQuestion(const unsigned char* input, unsigned short input_size, unsigned short& pos)
-       {
-               Question question;
-
-               question.name = this->UnpackName(input, input_size, pos);
-
-               if (pos + 4 > input_size)
-                       throw Exception("Unable to unpack question");
-
-               question.type = static_cast<QueryType>(input[pos] << 8 | input[pos + 1]);
-               pos += 2;
-
-               question.qclass = input[pos] << 8 | input[pos + 1];
-               pos += 2;
-
-               return question;
-       }
-
-       ResourceRecord UnpackResourceRecord(const unsigned char* input, unsigned short input_size, unsigned short& pos)
-       {
-               ResourceRecord record = static_cast<ResourceRecord>(this->UnpackQuestion(input, input_size, pos));
-
-               if (pos + 6 > input_size)
-                       throw Exception("Unable to unpack resource record");
-
-               record.ttl = (input[pos] << 24) | (input[pos + 1] << 16) | (input[pos + 2] << 8) | input[pos + 3];
-               pos += 4;
-
-               //record.rdlength = input[pos] << 8 | input[pos + 1];
-               pos += 2;
-
-               switch (record.type)
-               {
-                       case QUERY_A:
-                       {
-                               if (pos + 4 > input_size)
-                                       throw Exception("Unable to unpack resource record");
-
-                               irc::sockets::sockaddrs addrs;
-                               memset(&addrs, 0, sizeof(addrs));
-
-                               addrs.in4.sin_family = AF_INET;
-                               addrs.in4.sin_addr.s_addr = input[pos] | (input[pos + 1] << 8) | (input[pos + 2] << 16)  | (input[pos + 3] << 24);
-                               pos += 4;
-
-                               record.rdata = addrs.addr();
-                               break;
-                       }
-                       case QUERY_AAAA:
-                       {
-                               if (pos + 16 > input_size)
-                                       throw Exception("Unable to unpack resource record");
-
-                               irc::sockets::sockaddrs addrs;
-                               memset(&addrs, 0, sizeof(addrs));
-
-                               addrs.in6.sin6_family = AF_INET6;
-                               for (int j = 0; j < 16; ++j)
-                                       addrs.in6.sin6_addr.s6_addr[j] = input[pos + j];
-                               pos += 16;
-
-                               record.rdata = addrs.addr();
-
-                               break;
-                       }
-                       case QUERY_CNAME:
-                       case QUERY_PTR:
-                       {
-                               record.rdata = this->UnpackName(input, input_size, pos);
-                               break;
-                       }
-                       default:
-                               break;
-               }
-
-               if (!record.name.empty() && !record.rdata.empty())
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: " + record.name + " -> " + record.rdata);
-
-               return record;
-       }
-
- public:
-       static const int POINTER = 0xC0;
-       static const int LABEL = 0x3F;
-       static const int HEADER_LENGTH = 12;
-
-       /* ID for this packet */
-       unsigned short id;
-       /* Flags on the packet */
-       unsigned short flags;
-
-       Packet() : id(0), flags(0)
-       {
-       }
-
-       void Fill(const unsigned char* input, const unsigned short len)
-       {
-               if (len < HEADER_LENGTH)
-                       throw Exception("Unable to fill packet");
-
-               unsigned short packet_pos = 0;
-
-               this->id = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               if (this->id >= MAX_REQUEST_ID)
-                       throw Exception("Query ID too large?");
-
-               this->flags = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               unsigned short qdcount = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               unsigned short ancount = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               unsigned short nscount = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               unsigned short arcount = (input[packet_pos] << 8) | input[packet_pos + 1];
-               packet_pos += 2;
-
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: qdcount: " + ConvToStr(qdcount) + " ancount: " + ConvToStr(ancount) + " nscount: " + ConvToStr(nscount) + " arcount: " + ConvToStr(arcount));
-
-               for (unsigned i = 0; i < qdcount; ++i)
-                       this->questions.push_back(this->UnpackQuestion(input, len, packet_pos));
-
-               for (unsigned i = 0; i < ancount; ++i)
-                       this->answers.push_back(this->UnpackResourceRecord(input, len, packet_pos));
-       }
-
-       unsigned short Pack(unsigned char* output, unsigned short output_size)
-       {
-               if (output_size < HEADER_LENGTH)
-                       throw Exception("Unable to pack packet");
-
-               unsigned short pos = 0;
-
-               output[pos++] = this->id >> 8;
-               output[pos++] = this->id & 0xFF;
-               output[pos++] = this->flags >> 8;
-               output[pos++] = this->flags & 0xFF;
-               output[pos++] = this->questions.size() >> 8;
-               output[pos++] = this->questions.size() & 0xFF;
-               output[pos++] = this->answers.size() >> 8;
-               output[pos++] = this->answers.size() & 0xFF;
-               output[pos++] = 0;
-               output[pos++] = 0;
-               output[pos++] = 0;
-               output[pos++] = 0;
-
-               for (unsigned i = 0; i < this->questions.size(); ++i)
-               {
-                       Question& q = this->questions[i];
-
-                       if (q.type == QUERY_PTR)
-                       {
-                               irc::sockets::sockaddrs ip;
-                               irc::sockets::aptosa(q.name, 0, ip);
-
-                               if (q.name.find(':') != std::string::npos)
-                               {
-                                       static const char* const hex = "0123456789abcdef";
-                                       char reverse_ip[128];
-                                       unsigned reverse_ip_count = 0;
-                                       for (int j = 15; j >= 0; --j)
-                                       {
-                                               reverse_ip[reverse_ip_count++] = hex[ip.in6.sin6_addr.s6_addr[j] & 0xF];
-                                               reverse_ip[reverse_ip_count++] = '.';
-                                               reverse_ip[reverse_ip_count++] = hex[ip.in6.sin6_addr.s6_addr[j] >> 4];
-                                               reverse_ip[reverse_ip_count++] = '.';
-                                       }
-                                       reverse_ip[reverse_ip_count++] = 0;
-
-                                       q.name = reverse_ip;
-                                       q.name += "ip6.arpa";
-                               }
-                               else
-                               {
-                                       unsigned long forward = ip.in4.sin_addr.s_addr;
-                                       ip.in4.sin_addr.s_addr = forward << 24 | (forward & 0xFF00) << 8 | (forward & 0xFF0000) >> 8 | forward >> 24;
-
-                                       q.name = ip.addr() + ".in-addr.arpa";
-                               }
-                       }
-
-                       this->PackName(output, output_size, pos, q.name);
-
-                       if (pos + 4 >= output_size)
-                               throw Exception("Unable to pack packet");
-
-                       short s = htons(q.type);
-                       memcpy(&output[pos], &s, 2);
-                       pos += 2;
-
-                       s = htons(q.qclass);
-                       memcpy(&output[pos], &s, 2);
-                       pos += 2;
-               }
-
-               for (unsigned int i = 0; i < answers.size(); i++)
-               {
-                       ResourceRecord& rr = answers[i];
-
-                       this->PackName(output, output_size, pos, rr.name);
-
-                       if (pos + 8 >= output_size)
-                               throw Exception("Unable to pack packet");
-
-                       short s = htons(rr.type);
-                       memcpy(&output[pos], &s, 2);
-                       pos += 2;
-
-                       s = htons(rr.qclass);
-                       memcpy(&output[pos], &s, 2);
-                       pos += 2;
-
-                       long l = htonl(rr.ttl);
-                       memcpy(&output[pos], &l, 4);
-                       pos += 4;
-
-                       switch (rr.type)
-                       {
-                               case QUERY_A:
-                               {
-                                       if (pos + 6 > output_size)
-                                               throw Exception("Unable to pack packet");
-
-                                       irc::sockets::sockaddrs a;
-                                       irc::sockets::aptosa(rr.rdata, 0, a);
-
-                                       s = htons(4);
-                                       memcpy(&output[pos], &s, 2);
-                                       pos += 2;
-
-                                       memcpy(&output[pos], &a.in4.sin_addr, 4);
-                                       pos += 4;
-                                       break;
-                               }
-                               case QUERY_AAAA:
-                               {
-                                       if (pos + 18 > output_size)
-                                               throw Exception("Unable to pack packet");
-
-                                       irc::sockets::sockaddrs a;
-                                       irc::sockets::aptosa(rr.rdata, 0, a);
-
-                                       s = htons(16);
-                                       memcpy(&output[pos], &s, 2);
-                                       pos += 2;
-
-                                       memcpy(&output[pos], &a.in6.sin6_addr, 16);
-                                       pos += 16;
-                                       break;
-                               }
-                               case QUERY_CNAME:
-                               case QUERY_PTR:
-                               {
-                                       if (pos + 2 >= output_size)
-                                               throw Exception("Unable to pack packet");
-
-                                       unsigned short packet_pos_save = pos;
-                                       pos += 2;
-
-                                       this->PackName(output, output_size, pos, rr.rdata);
-
-                                       s = htons(pos - packet_pos_save - 2);
-                                       memcpy(&output[packet_pos_save], &s, 2);
-                                       break;
-                               }
-                               default:
-                                       break;
-                       }
-               }
-
-               return pos;
-       }
-};
-
-class MyManager : public Manager, public Timer, public EventHandler
-{
-       typedef TR1NS::unordered_map<Question, Query, Question::hash> cache_map;
-       cache_map cache;
-
-       irc::sockets::sockaddrs myserver;
-
-       static bool IsExpired(const Query& record, time_t now = ServerInstance->Time())
-       {
-               const ResourceRecord& req = record.answers[0];
-               return (req.created + static_cast<time_t>(req.ttl) < now);
-       }
-
-       /** Check the DNS cache to see if request can be handled by a cached result
-        * @return true if a cached result was found.
-        */
-       bool CheckCache(DNS::Request* req, const DNS::Question& question)
-       {
-               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: cache: Checking cache for " + question.name);
-
-               cache_map::iterator it = this->cache.find(question);
-               if (it == this->cache.end())
-                       return false;
-
-               Query& record = it->second;
-               if (IsExpired(record))
-               {
-                       this->cache.erase(it);
-                       return false;
-               }
-
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: Using cached result for " + question.name);
-               record.cached = true;
-               req->OnLookupComplete(&record);
-               return true;
-       }
-
-       /** Add a record to the dns cache
-        * @param r The record
-        */
-       void AddCache(Query& r)
-       {
-               const ResourceRecord& rr = r.answers[0];
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: added cache for " + rr.name + " -> " + rr.rdata + " ttl: " + ConvToStr(rr.ttl));
-               this->cache[r.questions[0]] = r;
-       }
-
- public:
-       DNS::Request* requests[MAX_REQUEST_ID];
-
-       MyManager(Module* c) : Manager(c), Timer(3600, ServerInstance->Time(), true)
-       {
-               for (int i = 0; i < MAX_REQUEST_ID; ++i)
-                       requests[i] = NULL;
-               ServerInstance->Timers->AddTimer(this);
-       }
-
-       ~MyManager()
-       {
-               for (int i = 0; i < MAX_REQUEST_ID; ++i)
-               {
-                       DNS::Request* request = requests[i];
-                       if (!request)
-                               continue;
-
-                       Query rr(*request);
-                       rr.error = ERROR_UNKNOWN;
-                       request->OnError(&rr);
-
-                       delete request;
-               }
-       }
-
-       void Process(DNS::Request* req)
-       {
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Processing request to lookup " + req->name + " of type " + ConvToStr(req->type) + " to " + this->myserver.addr());
-
-               /* Create an id */
-               unsigned int tries = 0;
-               do
-               {
-                       req->id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID);
-
-                       if (++tries == DNS::MAX_REQUEST_ID*5)
-                       {
-                               // If we couldn't find an empty slot this many times, do a sequential scan as a last
-                               // resort. If an empty slot is found that way, go on, otherwise throw an exception
-                               req->id = 0;
-                               for (int i = 1; i < DNS::MAX_REQUEST_ID; i++)
-                               {
-                                       if (!this->requests[i])
-                                       {
-                                               req->id = i;
-                                               break;
-                                       }
-                               }
-
-                               if (req->id == 0)
-                                       throw Exception("DNS: All ids are in use");
-
-                               break;
-                       }
-               }
-               while (!req->id || this->requests[req->id]);
-
-               this->requests[req->id] = req;
-
-               Packet p;
-               p.flags = QUERYFLAGS_RD;
-               p.id = req->id;
-               p.questions.push_back(*req);
-
-               unsigned char buffer[524];
-               unsigned short len = p.Pack(buffer, sizeof(buffer));
-
-               /* Note that calling Pack() above can actually change the contents of p.questions[0].name, if the query is a PTR,
-                * to contain the value that would be in the DNS cache, which is why this is here.
-                */
-               if (req->use_cache && this->CheckCache(req, p.questions[0]))
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Using cached result");
-                       delete req;
-                       return;
-               }
-
-               if (SocketEngine::SendTo(this, buffer, len, 0, &this->myserver.sa, this->myserver.sa_size()) != len)
-                       throw Exception("DNS: Unable to send query");
-       }
-
-       void RemoveRequest(DNS::Request* req)
-       {
-               this->requests[req->id] = NULL;
-       }
-
-       std::string GetErrorStr(Error e)
-       {
-               switch (e)
-               {
-                       case ERROR_UNLOADED:
-                               return "Module is unloading";
-                       case ERROR_TIMEDOUT:
-                               return "Request timed out";
-                       case ERROR_NOT_AN_ANSWER:
-                       case ERROR_NONSTANDARD_QUERY:
-                       case ERROR_FORMAT_ERROR:
-                               return "Malformed answer";
-                       case ERROR_SERVER_FAILURE:
-                       case ERROR_NOT_IMPLEMENTED:
-                       case ERROR_REFUSED:
-                       case ERROR_INVALIDTYPE:
-                               return "Nameserver failure";
-                       case ERROR_DOMAIN_NOT_FOUND:
-                       case ERROR_NO_RECORDS:
-                               return "Domain not found";
-                       case ERROR_NONE:
-                       case ERROR_UNKNOWN:
-                       default:
-                               return "Unknown error";
-               }
-       }
-
-       void HandleEvent(EventType et, int)
-       {
-               if (et == EVENT_ERROR)
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: UDP socket got an error event");
-                       return;
-               }
-
-               unsigned char buffer[524];
-               irc::sockets::sockaddrs from;
-               socklen_t x = sizeof(from);
-
-               int length = SocketEngine::RecvFrom(this, buffer, sizeof(buffer), 0, &from.sa, &x);
-
-               if (length < Packet::HEADER_LENGTH)
-                       return;
-
-               Packet recv_packet;
-
-               try
-               {
-                       recv_packet.Fill(buffer, length);
-               }
-               catch (Exception& ex)
-               {
-                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, ex.GetReason());
-                       return;
-               }
-
-               if (myserver != from)
-               {
-                       std::string server1 = from.str();
-                       std::string server2 = myserver.str();
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Got a result from the wrong server! Bad NAT or DNS forging attempt? '%s' != '%s'",
-                               server1.c_str(), server2.c_str());
-                       return;
-               }
-
-               DNS::Request* request = this->requests[recv_packet.id];
-               if (request == NULL)
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Received an answer for something we didn't request");
-                       return;
-               }
-
-               if (recv_packet.flags & QUERYFLAGS_OPCODE)
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Received a nonstandard query");
-                       ServerInstance->stats->statsDnsBad++;
-                       recv_packet.error = ERROR_NONSTANDARD_QUERY;
-                       request->OnError(&recv_packet);
-               }
-               else if (recv_packet.flags & QUERYFLAGS_RCODE)
-               {
-                       Error error = ERROR_UNKNOWN;
-
-                       switch (recv_packet.flags & QUERYFLAGS_RCODE)
-                       {
-                               case 1:
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: format error");
-                                       error = ERROR_FORMAT_ERROR;
-                                       break;
-                               case 2:
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: server error");
-                                       error = ERROR_SERVER_FAILURE;
-                                       break;
-                               case 3:
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: domain not found");
-                                       error = ERROR_DOMAIN_NOT_FOUND;
-                                       break;
-                               case 4:
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: not implemented");
-                                       error = ERROR_NOT_IMPLEMENTED;
-                                       break;
-                               case 5:
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: refused");
-                                       error = ERROR_REFUSED;
-                                       break;
-                               default:
-                                       break;
-                       }
-
-                       ServerInstance->stats->statsDnsBad++;
-                       recv_packet.error = error;
-                       request->OnError(&recv_packet);
-               }
-               else if (recv_packet.questions.empty() || recv_packet.answers.empty())
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: No resource records returned");
-                       ServerInstance->stats->statsDnsBad++;
-                       recv_packet.error = ERROR_NO_RECORDS;
-                       request->OnError(&recv_packet);
-               }
-               else
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Lookup complete for " + request->name);
-                       ServerInstance->stats->statsDnsGood++;
-                       request->OnLookupComplete(&recv_packet);
-                       this->AddCache(recv_packet);
-               }
-
-               ServerInstance->stats->statsDns++;
-
-               /* Request's destructor removes it from the request map */
-               delete request;
-       }
-
-       bool Tick(time_t now)
-       {
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: purging DNS cache");
-
-               for (cache_map::iterator it = this->cache.begin(); it != this->cache.end(); )
-               {
-                       const Query& query = it->second;
-                       if (IsExpired(query, now))
-                               this->cache.erase(it++);
-                       else
-                               ++it;
-               }
-               return true;
-       }
-
-       void Rehash(const std::string& dnsserver)
-       {
-               if (this->GetFd() > -1)
-               {
-                       SocketEngine::Shutdown(this, 2);
-                       SocketEngine::Close(this);
-
-                       /* Remove expired entries from the cache */
-                       this->Tick(ServerInstance->Time());
-               }
-
-               irc::sockets::aptosa(dnsserver, DNS::PORT, myserver);
-
-               /* Initialize mastersocket */
-               int s = socket(myserver.sa.sa_family, SOCK_DGRAM, 0);
-               this->SetFd(s);
-
-               /* Have we got a socket? */
-               if (this->GetFd() != -1)
-               {
-                       SocketEngine::SetReuse(s);
-                       SocketEngine::NonBlocking(s);
-
-                       irc::sockets::sockaddrs bindto;
-                       memset(&bindto, 0, sizeof(bindto));
-                       bindto.sa.sa_family = myserver.sa.sa_family;
-
-                       if (SocketEngine::Bind(this->GetFd(), bindto) < 0)
-                       {
-                               /* Failed to bind */
-                               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Error binding dns socket - hostnames will NOT resolve");
-                               SocketEngine::Close(this->GetFd());
-                               this->SetFd(-1);
-                       }
-                       else if (!SocketEngine::AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE))
-                       {
-                               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Internal error starting DNS - hostnames will NOT resolve.");
-                               SocketEngine::Close(this->GetFd());
-                               this->SetFd(-1);
-                       }
-               }
-               else
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Error creating DNS socket - hostnames will NOT resolve");
-               }
-       }
-};
-
-class ModuleDNS : public Module
-{
-       MyManager manager;
-       std::string DNSServer;
-
-       void FindDNSServer()
-       {
-#ifdef _WIN32
-               // attempt to look up their nameserver from the system
-               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: <dns:server> not defined, attempting to find a working server in the system settings...");
-
-               PFIXED_INFO pFixedInfo;
-               DWORD dwBufferSize = sizeof(FIXED_INFO);
-               pFixedInfo = (PFIXED_INFO) HeapAlloc(GetProcessHeap(), 0, sizeof(FIXED_INFO));
-
-               if (pFixedInfo)
-               {
-                       if (GetNetworkParams(pFixedInfo, &dwBufferSize) == ERROR_BUFFER_OVERFLOW)
-                       {
-                               HeapFree(GetProcessHeap(), 0, pFixedInfo);
-                               pFixedInfo = (PFIXED_INFO) HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
-                       }
-
-                       if (pFixedInfo)
-                       {
-                               if (GetNetworkParams(pFixedInfo, &dwBufferSize) == NO_ERROR)
-                                       DNSServer = pFixedInfo->DnsServerList.IpAddress.String;
-
-                               HeapFree(GetProcessHeap(), 0, pFixedInfo);
-                       }
-
-                       if (!DNSServer.empty())
-                       {
-                               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "<dns:server> set to '%s' as first active resolver in the system settings.", DNSServer.c_str());
-                               return;
-                       }
-               }
-
-               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "No viable nameserver found! Defaulting to nameserver '127.0.0.1'!");
-#else
-               // attempt to look up their nameserver from /etc/resolv.conf
-               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: <dns:server> not defined, attempting to find working server in /etc/resolv.conf...");
-
-               std::ifstream resolv("/etc/resolv.conf");
-
-               while (resolv >> DNSServer)
-               {
-                       if (DNSServer == "nameserver")
-                       {
-                               resolv >> DNSServer;
-                               if (DNSServer.find_first_not_of("0123456789.") == std::string::npos)
-                               {
-                                       ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "<dns:server> set to '%s' as first resolver in /etc/resolv.conf.",DNSServer.c_str());
-                                       return;
-                               }
-                       }
-               }
-
-               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "/etc/resolv.conf contains no viable nameserver entries! Defaulting to nameserver '127.0.0.1'!");
-#endif
-               DNSServer = "127.0.0.1";
-       }
-
- public:
-       ModuleDNS() : manager(this)
-       {
-       }
-
-       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
-       {
-               std::string oldserver = DNSServer;
-               DNSServer = ServerInstance->Config->ConfValue("dns")->getString("server");
-               if (DNSServer.empty())
-                       FindDNSServer();
-
-               if (oldserver != DNSServer)
-                       this->manager.Rehash(DNSServer);
-       }
-
-       void OnUnloadModule(Module* mod)
-       {
-               for (int i = 0; i < MAX_REQUEST_ID; ++i)
-               {
-                       DNS::Request* req = this->manager.requests[i];
-                       if (!req)
-                               continue;
-
-                       if (req->creator == mod)
-                       {
-                               Query rr(*req);
-                               rr.error = ERROR_UNLOADED;
-                               req->OnError(&rr);
-
-                               delete req;
-                       }
-               }
-       }
-
-       Version GetVersion()
-       {
-               return Version("DNS support", VF_CORE|VF_VENDOR);
-       }
-};
-
-MODULE_INIT(ModuleDNS)
-
diff --git a/src/commands/cmd_eline.cpp b/src/commands/cmd_eline.cpp
deleted file mode 100644 (file)
index 509089d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-
-/** Handle /ELINE.
- */
-class CommandEline : public Command
-{
- public:
-       /** Constructor for eline.
-        */
-       CommandEline ( Module* parent) : Command(parent,"ELINE",1,3) { flags_needed = 'o'; syntax = "<ident@host> [<duration> :<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /ELINE
- */
-CmdResult CommandEline::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string target = parameters[0];
-
-       if (parameters.size() >= 3)
-       {
-               IdentHostPair ih;
-               User* find = ServerInstance->FindNick(target);
-               if ((find) && (find->registered == REG_ALL))
-               {
-                       ih.first = "*";
-                       ih.second = find->GetIPString();
-                       target = std::string("*@") + find->GetIPString();
-               }
-               else
-                       ih = ServerInstance->XLines->IdentSplit(target);
-
-               if (ih.first.empty())
-               {
-                       user->WriteNotice("*** Target not found");
-                       return CMD_FAILURE;
-               }
-
-               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
-                       return CMD_FAILURE;
-
-               unsigned long duration = InspIRCd::Duration(parameters[1]);
-               ELine* el = new ELine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
-               if (ServerInstance->XLines->AddLine(el, user))
-               {
-                       if (!duration)
-                       {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent E-line for %s: %s", user->nick.c_str(), target.c_str(), parameters[2].c_str());
-                       }
-                       else
-                       {
-                               time_t c_requires_crap = duration + ServerInstance->Time();
-                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed E-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
-                                               timestr.c_str(), parameters[2].c_str());
-                       }
-               }
-               else
-               {
-                       delete el;
-                       user->WriteNotice("*** E-Line for " + target + " already exists");
-               }
-       }
-       else
-       {
-               if (ServerInstance->XLines->DelLine(target.c_str(), "E", user))
-               {
-                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed E-line on %s",user->nick.c_str(),target.c_str());
-               }
-               else
-               {
-                       user->WriteNotice("*** E-Line " + target + " not found in list, try /stats e");
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandEline)
diff --git a/src/commands/cmd_gline.cpp b/src/commands/cmd_gline.cpp
deleted file mode 100644 (file)
index 18a661b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-
-/** Handle /GLINE.
- */
-class CommandGline : public Command
-{
- public:
-       /** Constructor for gline.
-        */
-       CommandGline (Module* parent) : Command(parent,"GLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-
-/** Handle /GLINE
- */
-CmdResult CommandGline::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string target = parameters[0];
-
-       if (parameters.size() >= 3)
-       {
-               IdentHostPair ih;
-               User* find = ServerInstance->FindNick(target);
-               if ((find) && (find->registered == REG_ALL))
-               {
-                       ih.first = "*";
-                       ih.second = find->GetIPString();
-                       target = std::string("*@") + find->GetIPString();
-               }
-               else
-                       ih = ServerInstance->XLines->IdentSplit(target);
-
-               if (ih.first.empty())
-               {
-                       user->WriteNotice("*** Target not found");
-                       return CMD_FAILURE;
-               }
-
-               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
-                       return CMD_FAILURE;
-
-               else if (target.find('!') != std::string::npos)
-               {
-                       user->WriteNotice("*** G-Line cannot operate on nick!user@host masks");
-                       return CMD_FAILURE;
-               }
-
-               unsigned long duration = InspIRCd::Duration(parameters[1]);
-               GLine* gl = new GLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
-               if (ServerInstance->XLines->AddLine(gl, user))
-               {
-                       if (!duration)
-                       {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent G-line for %s: %s",user->nick.c_str(),target.c_str(), parameters[2].c_str());
-                       }
-                       else
-                       {
-                               time_t c_requires_crap = duration + ServerInstance->Time();
-                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed G-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
-                                               timestr.c_str(), parameters[2].c_str());
-                       }
-
-                       ServerInstance->XLines->ApplyLines();
-               }
-               else
-               {
-                       delete gl;
-                       user->WriteNotice("** G-Line for " + target + " already exists");
-               }
-
-       }
-       else
-       {
-               if (ServerInstance->XLines->DelLine(target.c_str(),"G",user))
-               {
-                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed G-line on %s",user->nick.c_str(),target.c_str());
-               }
-               else
-               {
-                       user->WriteNotice("*** G-Line " + target + " not found in list, try /stats g.");
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandGline)
diff --git a/src/commands/cmd_hostname_lookup.cpp b/src/commands/cmd_hostname_lookup.cpp
deleted file mode 100644 (file)
index c26d3b3..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2013 Adam <Adam@anope.org>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "modules/dns.h"
-
-namespace
-{
-       LocalIntExt* dl;
-       LocalStringExt* ph;
-}
-
-/** Derived from Resolver, and performs user forward/reverse lookups.
- */
-class UserResolver : public DNS::Request
-{
-       /** UUID we are looking up */
-       const std::string uuid;
-
-       /** True if the lookup is forward, false if is a reverse lookup
-        */
-       const bool fwd;
-
- public:
-       /** Create a resolver.
-        * @param mgr DNS Manager
-        * @param me this module
-        * @param user The user to begin lookup on
-        * @param to_resolve The IP or host to resolve
-        * @param qt The query type
-        */
-       UserResolver(DNS::Manager* mgr, Module* me, LocalUser* user, const std::string& to_resolve, DNS::QueryType qt)
-               : DNS::Request(mgr, me, to_resolve, qt)
-               , uuid(user->uuid)
-               , fwd(qt == DNS::QUERY_A || qt == DNS::QUERY_AAAA)
-       {
-       }
-
-       /** Called on successful lookup
-        * if a previous result has already come back.
-        * @param r The finished query
-        */
-       void OnLookupComplete(const DNS::Query* r)
-       {
-               LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
-               if (!bound_user)
-               {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str());
-                       return;
-               }
-
-               const DNS::ResourceRecord& ans_record = r->answers[0];
-
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "DNS result for %s: '%s' -> '%s'", uuid.c_str(), ans_record.name.c_str(), ans_record.rdata.c_str());
-
-               if (!fwd)
-               {
-                       // first half of resolution is done. We now need to verify that the host matches.
-                       ph->set(bound_user, ans_record.rdata);
-
-                       UserResolver* res_forward;
-                       if (bound_user->client_sa.sa.sa_family == AF_INET6)
-                       {
-                               /* IPV6 forward lookup */
-                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_AAAA);
-                       }
-                       else
-                       {
-                               /* IPV4 lookup */
-                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_A);
-                       }
-                       try
-                       {
-                               this->manager->Process(res_forward);
-                       }
-                       catch (DNS::Exception& e)
-                       {
-                               delete res_forward;
-                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
-
-                               bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead.");
-                               dl->set(bound_user, 0);
-                       }
-               }
-               else
-               {
-                       /* Both lookups completed */
-
-                       irc::sockets::sockaddrs* user_ip = &bound_user->client_sa;
-                       bool rev_match = false;
-                       if (user_ip->sa.sa_family == AF_INET6)
-                       {
-                               struct in6_addr res_bin;
-                               if (inet_pton(AF_INET6, ans_record.rdata.c_str(), &res_bin))
-                               {
-                                       rev_match = !memcmp(&user_ip->in6.sin6_addr, &res_bin, sizeof(res_bin));
-                               }
-                       }
-                       else
-                       {
-                               struct in_addr res_bin;
-                               if (inet_pton(AF_INET, ans_record.rdata.c_str(), &res_bin))
-                               {
-                                       rev_match = !memcmp(&user_ip->in4.sin_addr, &res_bin, sizeof(res_bin));
-                               }
-                       }
-
-                       dl->set(bound_user, 0);
-
-                       if (rev_match)
-                       {
-                               std::string* hostname = ph->get(bound_user);
-
-                               if (hostname == NULL)
-                               {
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup");
-                                       bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead.");
-                                       return;
-                               }
-                               else if (hostname->length() < 65)
-                               {
-                                       /* Hostnames starting with : are not a good thing (tm) */
-                                       if ((*hostname)[0] == ':')
-                                               hostname->insert(0, "0");
-
-                                       bound_user->WriteNotice("*** Found your hostname (" + *hostname + (r->cached ? ") -- cached" : ")"));
-                                       bound_user->host.assign(*hostname, 0, 64);
-                                       bound_user->dhost = bound_user->host;
-
-                                       /* Invalidate cache */
-                                       bound_user->InvalidateCache();
-                               }
-                               else
-                               {
-                                       bound_user->WriteNotice("*** Your hostname is longer than the maximum of 64 characters, using your IP address (" + bound_user->GetIPString() + ") instead.");
-                               }
-
-                               ph->unset(bound_user);
-                       }
-                       else
-                       {
-                               bound_user->WriteNotice("*** Your hostname does not match up with your IP address. Sorry, using your IP address (" + bound_user->GetIPString() + ") instead.");
-                       }
-               }
-       }
-
-       /** Called on failed lookup
-        * @param query The errored query
-        */
-       void OnError(const DNS::Query* query)
-       {
-               LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
-               if (bound_user)
-               {
-                       bound_user->WriteNotice("*** Could not resolve your hostname: " + this->manager->GetErrorStr(query->error) + "; using your IP address (" + bound_user->GetIPString() + ") instead.");
-                       dl->set(bound_user, 0);
-                       ServerInstance->stats->statsDnsBad++;
-               }
-       }
-};
-
-class ModuleHostnameLookup : public Module
-{
-       LocalIntExt dnsLookup;
-       LocalStringExt ptrHosts;
-       dynamic_reference<DNS::Manager> DNS;
-
- public:
-       ModuleHostnameLookup()
-               : dnsLookup("dnsLookup", this)
-               , ptrHosts("ptrHosts", this)
-               , DNS(this, "DNS")
-       {
-               dl = &dnsLookup;
-               ph = &ptrHosts;
-       }
-
-       void OnUserInit(LocalUser *user)
-       {
-               if (!DNS || !user->MyClass->resolvehostnames)
-               {
-                       user->WriteNotice("*** Skipping host resolution (disabled by server administrator)");
-                       return;
-               }
-
-               user->WriteNotice("*** Looking up your hostname...");
-
-               UserResolver* res_reverse = new UserResolver(*this->DNS, this, user, user->GetIPString(), DNS::QUERY_PTR);
-               try
-               {
-                       /* If both the reverse and forward queries are cached, the user will be able to pass DNS completely
-                        * before Process() completes, which is why dnsLookup.set() is here, before Process()
-                        */
-                       this->dnsLookup.set(user, 1);
-                       this->DNS->Process(res_reverse);
-               }
-               catch (DNS::Exception& e)
-               {
-                       this->dnsLookup.set(user, 0);
-                       delete res_reverse;
-                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
-                       ServerInstance->stats->statsDnsBad++;
-               }
-       }
-
-       ModResult OnCheckReady(LocalUser* user)
-       {
-               return this->dnsLookup.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
-       }
-
-       Version GetVersion()
-       {
-               return Version("Provides support for DNS lookups on connecting clients", VF_CORE|VF_VENDOR);
-       }
-};
-
-MODULE_INIT(ModuleHostnameLookup)
diff --git a/src/commands/cmd_info.cpp b/src/commands/cmd_info.cpp
deleted file mode 100644 (file)
index 7f1e923..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2011 Jackmcbarn <jackmcbarn@jackmcbarn.no-ip.org>
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /INFO.
- */
-class CommandInfo : public Command
-{
- public:
-       /** Constructor for info.
-        */
-       CommandInfo(Module* parent) : Command(parent,"INFO")
-       {
-               Penalty = 4;
-               syntax = "[<servername>]";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() > 0)
-                       return ROUTE_UNICAST(parameters[0]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-static const char* const lines[] = {
-       "                   -/\\- \2InspIRCd\2 -\\/-",
-       "                 November 2002 - Present",
-       " ",
-       "\2Core Developers\2:",
-       "    Craig Edwards,          Brain,      <brain@inspircd.org>",
-       "    Craig McLure,           Craig,      <craig@inspircd.org>",
-       "    Robin Burchell,         w00t,       <w00t@inspircd.org>",
-       "    Oliver Lupton,          Om,         <om@inspircd.org>",
-       "    John Brooks,            Special,    <special@inspircd.org>",
-       "    Dennis Friis,           peavey,     <peavey@inspircd.org>",
-       "    Thomas Stagner,         aquanight,  <aquanight@inspircd.org>",
-       "    Uli Schlachter,         psychon,    <psychon@inspircd.org>",
-       "    Matt Smith,             dz,         <dz@inspircd.org>",
-       "    Daniel De Graaf,        danieldg,   <danieldg@inspircd.org>",
-       "                            jackmcbarn, <jackmcbarn@inspircd.org>",
-       "    Attila Molnar,          Attila,     <attilamolnar@hush.com>",
-       " ",
-       "\2Regular Contributors\2:",
-       "    Adam           SaberUK",
-       " ",
-       "\2Other Contributors\2:",
-       "    ChrisTX        Shawn           Shutter",
-       " ",
-       "\2Former Contributors\2:",
-       "   dmb             Zaba            skenmy         GreenReaper",
-       "   Dan             Jason           satmd          owine",
-       "   Adremelech      John2           jilles         HiroP",
-       "   eggy            Bricker         AnMaster       djGrrr",
-       "   nenolod         Quension        praetorian     pippijn",
-       "   CC              jamie           typobox43      Burlex (win32)",
-       "   Stskeeps        ThaPrince       BuildSmart     Thunderhacker",
-       "   Skip            LeaChim         Majic          MacGyver",
-       "   Namegduf        Ankit           Phoenix        Taros",
-       " ",
-       "\2Thanks To\2:",
-       "   searchirc.com   irc-junkie.org  Brik           fraggeln",
-       " ",
-       " Best experienced with: \2An IRC client\2",
-       NULL
-};
-
-/** Handle /INFO
- */
-CmdResult CommandInfo::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
-               return CMD_SUCCESS;
-
-       int i=0;
-       while (lines[i])
-               user->SendText(":%s %03d %s :%s", ServerInstance->Config->ServerName.c_str(), RPL_INFO, user->nick.c_str(), lines[i++]);
-       FOREACH_MOD(OnInfo, (user));
-       user->SendText(":%s %03d %s :End of /INFO list", ServerInstance->Config->ServerName.c_str(), RPL_ENDOFINFO, user->nick.c_str());
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandInfo)
diff --git a/src/commands/cmd_invite.cpp b/src/commands/cmd_invite.cpp
deleted file mode 100644 (file)
index 25afc07..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /INVITE.
- */
-class CommandInvite : public Command
-{
- public:
-       /** Constructor for invite.
-        */
-       CommandInvite ( Module* parent) : Command(parent,"INVITE", 0, 0) { Penalty = 4; syntax = "[<nick> <channel>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-/** Handle /INVITE
- */
-CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       ModResult MOD_RESULT;
-
-       if (parameters.size() == 2 || parameters.size() == 3)
-       {
-               User* u;
-               if (IS_LOCAL(user))
-                       u = ServerInstance->FindNickOnly(parameters[0]);
-               else
-                       u = ServerInstance->FindNick(parameters[0]);
-
-               Channel* c = ServerInstance->FindChan(parameters[1]);
-               time_t timeout = 0;
-               if (parameters.size() == 3)
-               {
-                       if (IS_LOCAL(user))
-                               timeout = ServerInstance->Time() + InspIRCd::Duration(parameters[2]);
-                       else
-                               timeout = ConvToInt(parameters[2]);
-               }
-
-               if ((!c) || (!u) || (u->registered != REG_ALL))
-               {
-                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c ? parameters[0].c_str() : parameters[1].c_str());
-                       return CMD_FAILURE;
-               }
-
-               if ((IS_LOCAL(user)) && (!c->HasUser(user)))
-               {
-                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", c->name.c_str());
-                       return CMD_FAILURE;
-               }
-
-               if (c->HasUser(u))
-               {
-                       user->WriteNumeric(ERR_USERONCHANNEL, "%s %s :is already on channel", u->nick.c_str(), c->name.c_str());
-                       return CMD_FAILURE;
-               }
-
-               FIRST_MOD_RESULT(OnUserPreInvite, MOD_RESULT, (user,u,c,timeout));
-
-               if (MOD_RESULT == MOD_RES_DENY)
-               {
-                       return CMD_FAILURE;
-               }
-               else if (MOD_RESULT == MOD_RES_PASSTHRU)
-               {
-                       if (IS_LOCAL(user))
-                       {
-                               unsigned int rank = c->GetPrefixValue(user);
-                               if (rank < HALFOP_VALUE)
-                               {
-                                       // Check whether halfop mode is available and phrase error message accordingly
-                                       ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
-                                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You must be a channel %soperator",
-                                               c->name.c_str(), (mh && mh->name == "halfop" ? "half-" : ""));
-                                       return CMD_FAILURE;
-                               }
-                       }
-               }
-
-               if (IS_LOCAL(u))
-               {
-                       Invitation::Create(c, IS_LOCAL(u), timeout);
-                       u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
-               }
-
-               if (IS_LOCAL(user))
-                       user->WriteNumeric(RPL_INVITING, "%s %s", u->nick.c_str(),c->name.c_str());
-
-               if (ServerInstance->Config->AnnounceInvites != ServerConfig::INVITE_ANNOUNCE_NONE)
-               {
-                       char prefix;
-                       switch (ServerInstance->Config->AnnounceInvites)
-                       {
-                               case ServerConfig::INVITE_ANNOUNCE_OPS:
-                               {
-                                       prefix = '@';
-                                       break;
-                               }
-                               case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
-                               {
-                                       PrefixMode* mh = ServerInstance->Modes->FindPrefixMode('h');
-                                       prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
-                                       break;
-                               }
-                               default:
-                               {
-                                       prefix = 0;
-                                       break;
-                               }
-                       }
-                       c->WriteAllExceptSender(user, true, prefix, "NOTICE %s :*** %s invited %s into the channel", c->name.c_str(), user->nick.c_str(), u->nick.c_str());
-               }
-               FOREACH_MOD(OnUserInvite, (user,u,c,timeout));
-       }
-       else if (IS_LOCAL(user))
-       {
-               // pinched from ircu - invite with not enough parameters shows channels
-               // youve been invited to but haven't joined yet.
-               InviteList& il = IS_LOCAL(user)->GetInviteList();
-               for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i)
-               {
-                       user->WriteNumeric(RPL_INVITELIST, ":%s", (*i)->chan->name.c_str());
-               }
-               user->WriteNumeric(RPL_ENDOFINVITELIST, ":End of INVITE list");
-       }
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandInvite)
diff --git a/src/commands/cmd_ison.cpp b/src/commands/cmd_ison.cpp
deleted file mode 100644 (file)
index c7ead2a..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /ISON.
- */
-class CommandIson : public Command
-{
- public:
-       /** Constructor for ison.
-        */
-       CommandIson ( Module* parent) : Command(parent,"ISON", 1) {
-               syntax = "<nick> {nick}";
-       }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /ISON
- */
-CmdResult CommandIson::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::map<User*,User*> ison_already;
-       User *u;
-       std::string reply = "303 " + user->nick + " :";
-
-       for (unsigned int i = 0; i < parameters.size(); i++)
-       {
-               u = ServerInstance->FindNickOnly(parameters[i]);
-               if (ison_already.find(u) != ison_already.end())
-                       continue;
-
-               if (u)
-               {
-                       reply.append(u->nick).append(" ");
-                       if (reply.length() > 450)
-                       {
-                               user->WriteServ(reply);
-                               reply = "303 " + user->nick + " :";
-                       }
-                       ison_already[u] = u;
-               }
-               else
-               {
-                       if ((i == parameters.size() - 1) && (parameters[i].find(' ') != std::string::npos))
-                       {
-                               /* Its a space seperated list of nicks (RFC1459 says to support this)
-                                */
-                               irc::spacesepstream list(parameters[i]);
-                               std::string item;
-
-                               while (list.GetToken(item))
-                               {
-                                       u = ServerInstance->FindNickOnly(item);
-                                       if (ison_already.find(u) != ison_already.end())
-                                               continue;
-
-                                       if (u)
-                                       {
-                                               reply.append(u->nick).append(" ");
-                                               if (reply.length() > 450)
-                                               {
-                                                       user->WriteServ(reply);
-                                                       reply = "303 " + user->nick + " :";
-                                               }
-                                               ison_already[u] = u;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (!reply.empty())
-               user->WriteServ(reply);
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandIson)
diff --git a/src/commands/cmd_join.cpp b/src/commands/cmd_join.cpp
deleted file mode 100644 (file)
index 1e6e515..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /JOIN.
- */
-class CommandJoin : public SplitCommand
-{
- public:
-       /** Constructor for join.
-        */
-       CommandJoin(Module* parent)
-               : SplitCommand(parent, "JOIN", 1, 2)
-       {
-               syntax = "<channel>{,<channel>} {<key>{,<key>}}";
-               Penalty = 2;
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
-};
-
-/** Handle /JOIN
- */
-CmdResult CommandJoin::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
-{
-       if (parameters.size() > 1)
-       {
-               if (CommandParser::LoopCall(user, this, parameters, 0, 1, false))
-                       return CMD_SUCCESS;
-
-               if (ServerInstance->IsChannel(parameters[0]))
-               {
-                       Channel::JoinUser(user, parameters[0], false, parameters[1]);
-                       return CMD_SUCCESS;
-               }
-       }
-       else
-       {
-               if (CommandParser::LoopCall(user, this, parameters, 0, -1, false))
-                       return CMD_SUCCESS;
-
-               if (ServerInstance->IsChannel(parameters[0]))
-               {
-                       Channel::JoinUser(user, parameters[0]);
-                       return CMD_SUCCESS;
-               }
-       }
-
-       user->WriteNumeric(ERR_NOSUCHCHANNEL, "%s :Invalid channel name", parameters[0].c_str());
-       return CMD_FAILURE;
-}
-
-COMMAND_INIT(CommandJoin)
diff --git a/src/commands/cmd_kick.cpp b/src/commands/cmd_kick.cpp
deleted file mode 100644 (file)
index 01f2039..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /KICK.
- */
-class CommandKick : public Command
-{
- public:
-       /** Constructor for kick.
-        */
-       CommandKick ( Module* parent) : Command(parent,"KICK",2,3) { syntax = "<channel> <nick>{,<nick>} [<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-/** Handle /KICK
- */
-CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string reason;
-       Channel* c = ServerInstance->FindChan(parameters[0]);
-       User* u;
-
-       if (CommandParser::LoopCall(user, this, parameters, 1))
-               return CMD_SUCCESS;
-
-       if (IS_LOCAL(user))
-               u = ServerInstance->FindNickOnly(parameters[1]);
-       else
-               u = ServerInstance->FindNick(parameters[1]);
-
-       if (!u || !c)
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", u ? parameters[0].c_str() : parameters[1].c_str());
-               return CMD_FAILURE;
-       }
-
-       Membership* srcmemb = NULL;
-       if (IS_LOCAL(user))
-       {
-               srcmemb = c->GetUser(user);
-               if (!srcmemb)
-               {
-                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", parameters[0].c_str());
-                       return CMD_FAILURE;
-               }
-
-               if (u->server->IsULine())
-               {
-                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You may not kick a u-lined client", c->name.c_str());
-                       return CMD_FAILURE;
-               }
-       }
-
-       if (parameters.size() > 2)
-       {
-               reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick);
-       }
-       else
-       {
-               reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick);
-       }
-
-       c->KickUser(user, u, reason, srcmemb);
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandKick)
diff --git a/src/commands/cmd_kill.cpp b/src/commands/cmd_kill.cpp
deleted file mode 100644 (file)
index 454bab0..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /KILL.
- */
-class CommandKill : public Command
-{
-       std::string lastuuid;
-       std::string killreason;
-
- public:
-       /** Constructor for kill.
-        */
-       CommandKill ( Module* parent) : Command(parent,"KILL",2,2) {
-               flags_needed = 'o';
-               syntax = "<nickname> <reason>";
-               TRANSLATE2(TR_CUSTOM, TR_CUSTOM);
-       }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               // FindNick() doesn't work here because we quit the target user in Handle() which
-               // removes it from the nicklist, so we check lastuuid: if it's empty then this KILL
-               // was for a local user, otherwise it contains the uuid of the user who was killed.
-               if (lastuuid.empty())
-                       return ROUTE_LOCALONLY;
-               return ROUTE_BROADCAST;
-       }
-
-       void EncodeParameter(std::string& param, int index)
-       {
-               // Manually translate the nick -> uuid (see above), and also the reason (params[1])
-               // because we decorate it if the oper is local and want remote servers to see the
-               // decorated reason not the original.
-               param = ((index == 0) ? lastuuid : killreason);
-       }
-};
-
-/** Handle /KILL
- */
-CmdResult CommandKill::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       /* Allow comma seperated lists of users for /KILL (thanks w00t) */
-       if (CommandParser::LoopCall(user, this, parameters, 0))
-       {
-               // If we got a colon delimited list of nicks then the handler ran for each nick,
-               // and KILL commands were broadcast for remote targets.
-               return CMD_FAILURE;
-       }
-
-       User *u = ServerInstance->FindNick(parameters[0]);
-       if ((u) && (!IS_SERVER(u)))
-       {
-               /*
-                * Here, we need to decide how to munge kill messages. Whether to hide killer, what to show opers, etc.
-                * We only do this when the command is being issued LOCALLY, for remote KILL, we just copy the message we got.
-                *
-                * This conditional is so that we only append the "Killed (" prefix ONCE. If killer is remote, then the kill
-                * just gets processed and passed on, otherwise, if they are local, it gets prefixed. Makes sense :-) -- w00t
-                */
-
-               if (IS_LOCAL(user))
-               {
-                       /*
-                        * Moved this event inside the IS_LOCAL check also, we don't want half the network killing a user
-                        * and the other half not. This would be a bad thing. ;p -- w00t
-                        */
-                       ModResult MOD_RESULT;
-                       FIRST_MOD_RESULT(OnKill, MOD_RESULT, (user, u, parameters[1]));
-
-                       if (MOD_RESULT == MOD_RES_DENY)
-                               return CMD_FAILURE;
-
-                       killreason = "Killed (";
-                       if (!ServerInstance->Config->HideKillsServer.empty())
-                       {
-                               // hidekills is on, use it
-                               killreason += ServerInstance->Config->HideKillsServer;
-                       }
-                       else
-                       {
-                               // hidekills is off, do nothing
-                               killreason += user->nick;
-                       }
-
-                       killreason += " (" + parameters[1] + "))";
-               }
-               else
-               {
-                       /* Leave it alone, remote server has already formatted it */
-                       killreason.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxQuit);
-               }
-
-               /*
-                * Now we need to decide whether or not to send a local or remote snotice. Currently this checking is a little flawed.
-                * No time to fix it right now, so left a note. -- w00t
-                */
-               if (!IS_LOCAL(u))
-               {
-                       // remote kill
-                       if (!user->server->IsULine())
-                               ServerInstance->SNO->WriteToSnoMask('K', "Remote kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
-                       this->lastuuid = u->uuid;
-               }
-               else
-               {
-                       // local kill
-                       /*
-                        * XXX - this isn't entirely correct, servers A - B - C, oper on A, client on C. Oper kills client, A and B will get remote kill
-                        * snotices, C will get a local kill snotice. this isn't accurate, and needs fixing at some stage. -- w00t
-                        */
-                       if (!user->server->IsULine())
-                       {
-                               if (IS_LOCAL(user))
-                                       ServerInstance->SNO->WriteGlobalSno('k',"Local Kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
-                               else
-                                       ServerInstance->SNO->WriteToSnoMask('k',"Local Kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
-                       }
-
-                       ServerInstance->Logs->Log("KILL", LOG_DEFAULT, "LOCAL KILL: %s :%s!%s!%s (%s)", u->nick.c_str(), ServerInstance->Config->ServerName.c_str(), user->dhost.c_str(), user->nick.c_str(), parameters[1].c_str());
-
-                       u->Write(":%s KILL %s :%s!%s!%s (%s)", ServerInstance->Config->HideKillsServer.empty() ? user->GetFullHost().c_str() : ServerInstance->Config->HideKillsServer.c_str(),
-                                       u->nick.c_str(),
-                                       ServerInstance->Config->ServerName.c_str(),
-                                       user->dhost.c_str(),
-                                       ServerInstance->Config->HideKillsServer.empty() ? user->nick.c_str() : ServerInstance->Config->HideKillsServer.c_str(),
-                                       parameters[1].c_str());
-
-                       this->lastuuid.clear();
-               }
-
-               // send the quit out
-               ServerInstance->Users->QuitUser(u, killreason);
-       }
-       else
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandKill)
diff --git a/src/commands/cmd_kline.cpp b/src/commands/cmd_kline.cpp
deleted file mode 100644 (file)
index c6a8c7c..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-
-/** Handle /KLINE.
- */
-class CommandKline : public Command
-{
- public:
-       /** Constructor for kline.
-        */
-       CommandKline ( Module* parent) : Command(parent,"KLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-
-/** Handle /KLINE
- */
-CmdResult CommandKline::Handle (const std::vector<std::string>& parameters, User *user)
-{
-    std::string target = parameters[0];
-
-       if (parameters.size() >= 3)
-       {
-               IdentHostPair ih;
-               User* find = ServerInstance->FindNick(target);
-               if ((find) && (find->registered == REG_ALL))
-               {
-                       ih.first = "*";
-                       ih.second = find->GetIPString();
-                       target = std::string("*@") + find->GetIPString();
-               }
-               else
-                       ih = ServerInstance->XLines->IdentSplit(target);
-
-        if (ih.first.empty())
-        {
-            user->WriteNotice("*** Target not found");
-            return CMD_FAILURE;
-        }
-
-               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
-                       return CMD_FAILURE;
-
-               if (target.find('!') != std::string::npos)
-               {
-                       user->WriteNotice("*** K-Line cannot operate on nick!user@host masks");
-                       return CMD_FAILURE;
-               }
-
-               unsigned long duration = InspIRCd::Duration(parameters[1]);
-               KLine* kl = new KLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
-               if (ServerInstance->XLines->AddLine(kl,user))
-               {
-                       if (!duration)
-                       {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent K-line for %s: %s",user->nick.c_str(),target.c_str(), parameters[2].c_str());
-                       }
-                       else
-                       {
-                               time_t c_requires_crap = duration + ServerInstance->Time();
-                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed K-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
-                                               timestr.c_str(), parameters[2].c_str());
-                       }
-
-                       ServerInstance->XLines->ApplyLines();
-               }
-               else
-               {
-                       delete kl;
-                       user->WriteNotice("*** K-Line for " + target + " already exists");
-               }
-       }
-       else
-       {
-               if (ServerInstance->XLines->DelLine(target.c_str(),"K",user))
-               {
-                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed K-line on %s",user->nick.c_str(),target.c_str());
-               }
-               else
-               {
-                       user->WriteNotice("*** K-Line " + target + " not found in list, try /stats k.");
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandKline)
diff --git a/src/commands/cmd_links.cpp b/src/commands/cmd_links.cpp
deleted file mode 100644 (file)
index 8b44d7a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /LINKS.
- */
-class CommandLinks : public Command
-{
- public:
-       /** Constructor for links.
-        */
-       CommandLinks ( Module* parent) : Command(parent,"LINKS",0,0) { }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /LINKS
- */
-CmdResult CommandLinks::Handle (const std::vector<std::string>&, User *user)
-{
-       user->WriteNumeric(RPL_LINKS, "%s %s :0 %s", ServerInstance->Config->ServerName.c_str(),ServerInstance->Config->ServerName.c_str(),ServerInstance->Config->ServerDesc.c_str());
-       user->WriteNumeric(RPL_ENDOFLINKS, "* :End of /LINKS list.");
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandLinks)
diff --git a/src/commands/cmd_list.cpp b/src/commands/cmd_list.cpp
deleted file mode 100644 (file)
index ceffae4..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /LIST.
- */
-class CommandList : public Command
-{
-       ChanModeReference secretmode;
-       ChanModeReference privatemode;
-
- public:
-       /** Constructor for list.
-        */
-       CommandList(Module* parent)
-               : Command(parent,"LIST", 0, 0)
-               , secretmode(creator, "secret")
-               , privatemode(creator, "private")
-       {
-               Penalty = 5;
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-
-/** Handle /LIST
- */
-CmdResult CommandList::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       int minusers = 0, maxusers = 0;
-
-       user->WriteNumeric(RPL_LISTSTART, "Channel :Users Name");
-
-       /* Work around mIRC suckyness. YOU SUCK, KHALED! */
-       if (parameters.size() == 1)
-       {
-               if (parameters[0][0] == '<')
-               {
-                       maxusers = atoi((parameters[0].c_str())+1);
-               }
-               else if (parameters[0][0] == '>')
-               {
-                       minusers = atoi((parameters[0].c_str())+1);
-               }
-       }
-
-       for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
-       {
-               // attempt to match a glob pattern
-               long users = i->second->GetUserCounter();
-
-               bool too_few = (minusers && (users <= minusers));
-               bool too_many = (maxusers && (users >= maxusers));
-
-               if (too_many || too_few)
-                       continue;
-
-               if (parameters.size() && !parameters[0].empty() && (parameters[0][0] != '<' && parameters[0][0] != '>'))
-               {
-                       if (!InspIRCd::Match(i->second->name, parameters[0]) && !InspIRCd::Match(i->second->topic, parameters[0]))
-                               continue;
-               }
-
-               // if the channel is not private/secret, OR the user is on the channel anyway
-               bool n = (i->second->HasUser(user) || user->HasPrivPermission("channels/auspex"));
-
-               if (!n && i->second->IsModeSet(privatemode))
-               {
-                       /* Channel is +p and user is outside/not privileged */
-                       user->WriteNumeric(RPL_LIST, "* %ld :", users);
-               }
-               else
-               {
-                       if (n || !i->second->IsModeSet(secretmode))
-                       {
-                               /* User is in the channel/privileged, channel is not +s */
-                               user->WriteNumeric(RPL_LIST, "%s %ld :[+%s] %s",i->second->name.c_str(),users,i->second->ChanModes(n),i->second->topic.c_str());
-                       }
-               }
-       }
-       user->WriteNumeric(RPL_LISTEND, ":End of channel list.");
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandList)
diff --git a/src/commands/cmd_loadmodule.cpp b/src/commands/cmd_loadmodule.cpp
deleted file mode 100644 (file)
index 458a8cd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /LOADMODULE.
- */
-class CommandLoadmodule : public Command
-{
- public:
-       /** Constructor for loadmodule.
-        */
-       CommandLoadmodule ( Module* parent) : Command(parent,"LOADMODULE",1,1) { flags_needed='o'; syntax = "<modulename>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /LOADMODULE
- */
-CmdResult CommandLoadmodule::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (ServerInstance->Modules->Load(parameters[0]))
-       {
-               ServerInstance->SNO->WriteGlobalSno('a', "NEW MODULE: %s loaded %s",user->nick.c_str(), parameters[0].c_str());
-               user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module successfully loaded.", parameters[0].c_str());
-               return CMD_SUCCESS;
-       }
-       else
-       {
-               user->WriteNumeric(ERR_CANTLOADMODULE, "%s :%s", parameters[0].c_str(), ServerInstance->Modules->LastError().c_str());
-               return CMD_FAILURE;
-       }
-}
-
-COMMAND_INIT(CommandLoadmodule)
diff --git a/src/commands/cmd_lusers.cpp b/src/commands/cmd_lusers.cpp
deleted file mode 100644 (file)
index e56b1c0..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-struct LusersCounters
-{
-       unsigned int max_local;
-       unsigned int max_global;
-       unsigned int invisible;
-
-       LusersCounters(unsigned int inv)
-               : max_local(ServerInstance->Users->LocalUserCount())
-               , max_global(ServerInstance->Users->RegisteredUserCount())
-               , invisible(inv)
-       {
-       }
-
-       inline void UpdateMaxUsers()
-       {
-               unsigned int current = ServerInstance->Users->LocalUserCount();
-               if (current > max_local)
-                       max_local = current;
-
-               current = ServerInstance->Users->RegisteredUserCount();
-               if (current > max_global)
-                       max_global = current;
-       }
-};
-
-/** Handle /LUSERS.
- */
-class CommandLusers : public Command
-{
-       LusersCounters& counters;
- public:
-       /** Constructor for lusers.
-        */
-       CommandLusers(Module* parent, LusersCounters& Counters)
-               : Command(parent,"LUSERS",0,0), counters(Counters)
-       { }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /LUSERS
- */
-CmdResult CommandLusers::Handle (const std::vector<std::string>&, User *user)
-{
-       unsigned int n_users = ServerInstance->Users->RegisteredUserCount();
-       ProtocolInterface::ServerList serverlist;
-       ServerInstance->PI->GetServerList(serverlist);
-       unsigned int n_serv = serverlist.size();
-       unsigned int n_local_servs = 0;
-       for (ProtocolInterface::ServerList::const_iterator i = serverlist.begin(); i != serverlist.end(); ++i)
-       {
-               if (i->parentname == ServerInstance->Config->ServerName)
-                       n_local_servs++;
-       }
-       // fix for default GetServerList not returning us
-       if (!n_serv)
-               n_serv = 1;
-
-       counters.UpdateMaxUsers();
-
-       user->WriteNumeric(RPL_LUSERCLIENT, ":There are %d users and %d invisible on %d servers",
-                       n_users - counters.invisible, counters.invisible, n_serv);
-
-       if (ServerInstance->Users->OperCount())
-               user->WriteNumeric(RPL_LUSEROP, "%d :operator(s) online", ServerInstance->Users->OperCount());
-
-       if (ServerInstance->Users->UnregisteredUserCount())
-               user->WriteNumeric(RPL_LUSERUNKNOWN, "%d :unknown connections", ServerInstance->Users->UnregisteredUserCount());
-
-       user->WriteNumeric(RPL_LUSERCHANNELS, "%ld :channels formed", ServerInstance->ChannelCount());
-       user->WriteNumeric(RPL_LUSERME, ":I have %d clients and %d servers", ServerInstance->Users->LocalUserCount(),n_local_servs);
-       user->WriteNumeric(RPL_LOCALUSERS, ":Current Local Users: %d  Max: %d", ServerInstance->Users->LocalUserCount(), counters.max_local);
-       user->WriteNumeric(RPL_GLOBALUSERS, ":Current Global Users: %d  Max: %d", n_users, counters.max_global);
-
-       return CMD_SUCCESS;
-}
-
-class InvisibleWatcher : public ModeWatcher
-{
-       unsigned int& invisible;
-public:
-       InvisibleWatcher(Module* mod, unsigned int& Invisible)
-               : ModeWatcher(mod, "invisible", MODETYPE_USER), invisible(Invisible)
-       {
-       }
-
-       void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding)
-       {
-               if (dest->registered != REG_ALL)
-                       return;
-
-               if (adding)
-                       invisible++;
-               else
-                       invisible--;
-       }
-};
-
-class ModuleLusers : public Module
-{
-       UserModeReference invisiblemode;
-       LusersCounters counters;
-       CommandLusers cmd;
-       InvisibleWatcher mw;
-
-       unsigned int CountInvisible()
-       {
-               unsigned int c = 0;
-               for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); ++i)
-               {
-                       User* u = i->second;
-                       if (u->IsModeSet(invisiblemode))
-                               c++;
-               }
-               return c;
-       }
-
- public:
-       ModuleLusers()
-               : invisiblemode(this, "invisible")
-               , counters(CountInvisible())
-               , cmd(this, counters)
-               , mw(this, counters.invisible)
-       {
-       }
-
-       void OnPostConnect(User* user)
-       {
-               counters.UpdateMaxUsers();
-               if (user->IsModeSet(invisiblemode))
-                       counters.invisible++;
-       }
-
-       void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
-       {
-               if (user->IsModeSet(invisiblemode))
-                       counters.invisible--;
-       }
-
-       Version GetVersion()
-       {
-               return Version("LUSERS", VF_VENDOR | VF_CORE);
-       }
-};
-
-MODULE_INIT(ModuleLusers)
diff --git a/src/commands/cmd_mode.cpp b/src/commands/cmd_mode.cpp
deleted file mode 100644 (file)
index d2e9b4f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /MODE.
- */
-class CommandMode : public Command
-{
- public:
-       /** Constructor for mode.
-        */
-       CommandMode ( Module* parent) : Command(parent,"MODE",1) { syntax = "<target> <modes> {<mode-parameters>}"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-
-/** Handle /MODE
- */
-CmdResult CommandMode::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       ServerInstance->Modes->Process(parameters, user, (IS_LOCAL(user) ? ModeParser::MODE_NONE : ModeParser::MODE_LOCALONLY));
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandMode)
diff --git a/src/commands/cmd_modules.cpp b/src/commands/cmd_modules.cpp
deleted file mode 100644 (file)
index 0177439..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /MODULES.
- */
-class CommandModules : public Command
-{
- public:
-       /** Constructor for modules.
-        */
-       CommandModules(Module* parent) : Command(parent,"MODULES",0,0)
-       {
-               Penalty = 4;
-               syntax = "[<servername>]";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() >= 1)
-                       return ROUTE_UNICAST(parameters[0]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-/** Handle /MODULES
- */
-CmdResult CommandModules::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       // Don't ask remote servers about their modules unless the local user asking is an oper
-       // 2.0 asks anyway, so let's handle that the same way
-       bool for_us = (parameters.empty() || parameters[0] == ServerInstance->Config->ServerName);
-       if ((!for_us) || (!IS_LOCAL(user)))
-       {
-               if (!user->IsOper())
-               {
-                       user->WriteNotice("*** You cannot check what modules other servers have loaded.");
-                       return CMD_FAILURE;
-               }
-
-               // From an oper and not for us, forward
-               if (!for_us)
-                       return CMD_SUCCESS;
-       }
-
-       const ModuleManager::ModuleMap& mods = ServerInstance->Modules->GetModules();
-
-       for (ModuleManager::ModuleMap::const_iterator i = mods.begin(); i != mods.end(); ++i)
-       {
-               Module* m = i->second;
-               Version V = m->GetVersion();
-
-               if (IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"))
-               {
-                       std::string flags("SvcC");
-                       int pos = 0;
-                       for (int mult = 1; mult <= VF_OPTCOMMON; mult *= 2, ++pos)
-                               if (!(V.Flags & mult))
-                                       flags[pos] = '-';
-
-#ifdef PURE_STATIC
-                       user->SendText(":%s 702 %s :%p %s %s :%s", ServerInstance->Config->ServerName.c_str(),
-                               user->nick.c_str(), (void*)m, m->ModuleSourceFile.c_str(), flags.c_str(), V.description.c_str());
-#else
-                       std::string srcrev = m->ModuleDLLManager->GetVersion();
-                       user->SendText(":%s 702 %s :%p %s %s :%s - %s", ServerInstance->Config->ServerName.c_str(),
-                               user->nick.c_str(), (void*)m, m->ModuleSourceFile.c_str(), flags.c_str(), V.description.c_str(), srcrev.c_str());
-#endif
-               }
-               else
-               {
-                       user->SendText(":%s 702 %s :%s %s", ServerInstance->Config->ServerName.c_str(),
-                               user->nick.c_str(), m->ModuleSourceFile.c_str(), V.description.c_str());
-               }
-       }
-       user->SendText(":%s 703 %s :End of MODULES list", ServerInstance->Config->ServerName.c_str(), user->nick.c_str());
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandModules)
diff --git a/src/commands/cmd_motd.cpp b/src/commands/cmd_motd.cpp
deleted file mode 100644 (file)
index 71df701..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /MOTD.
- */
-class CommandMotd : public Command
-{
- public:
-       /** Constructor for motd.
-        */
-       CommandMotd ( Module* parent) : Command(parent,"MOTD",0,1) { syntax = "[<servername>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() > 0)
-                       return ROUTE_UNICAST(parameters[0]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-/** Handle /MOTD
- */
-CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
-               return CMD_SUCCESS;
-
-       ConfigTag* tag = NULL;
-       LocalUser* localuser = IS_LOCAL(user);
-       if (localuser)
-               tag = localuser->GetClass()->config;
-       std::string motd_name = tag->getString("motd", "motd");
-       ConfigFileCache::iterator motd = ServerInstance->Config->Files.find(motd_name);
-       if (motd == ServerInstance->Config->Files.end())
-       {
-               user->SendText(":%s %03d %s :Message of the day file is missing.",
-                       ServerInstance->Config->ServerName.c_str(), ERR_NOMOTD, user->nick.c_str());
-               return CMD_SUCCESS;
-       }
-
-       user->SendText(":%s %03d %s :%s message of the day", ServerInstance->Config->ServerName.c_str(),
-               RPL_MOTDSTART, user->nick.c_str(), ServerInstance->Config->ServerName.c_str());
-
-       for (file_cache::iterator i = motd->second.begin(); i != motd->second.end(); i++)
-               user->SendText(":%s %03d %s :- %s", ServerInstance->Config->ServerName.c_str(), RPL_MOTD, user->nick.c_str(), i->c_str());
-
-       user->SendText(":%s %03d %s :End of message of the day.", ServerInstance->Config->ServerName.c_str(), RPL_ENDOFMOTD, user->nick.c_str());
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandMotd)
diff --git a/src/commands/cmd_names.cpp b/src/commands/cmd_names.cpp
deleted file mode 100644 (file)
index 8c8bc58..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /NAMES.
- */
-class CommandNames : public Command
-{
-       ChanModeReference secretmode;
-
- public:
-       /** Constructor for names.
-        */
-       CommandNames(Module* parent)
-               : Command(parent, "NAMES", 0, 0)
-               , secretmode(parent, "secret")
-       {
-               syntax = "{<channel>{,<channel>}}";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle /NAMES
- */
-CmdResult CommandNames::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       Channel* c;
-
-       if (!parameters.size())
-       {
-               user->WriteNumeric(RPL_ENDOFNAMES, "* :End of /NAMES list.");
-               return CMD_SUCCESS;
-       }
-
-       if (CommandParser::LoopCall(user, this, parameters, 0))
-               return CMD_SUCCESS;
-
-       c = ServerInstance->FindChan(parameters[0]);
-       if (c)
-       {
-               if ((c->IsModeSet(secretmode)) && (!c->HasUser(user)))
-               {
-                     user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c->name.c_str());
-                     return CMD_FAILURE;
-               }
-               c->UserList(user);
-       }
-       else
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandNames)
diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp
deleted file mode 100644 (file)
index 486fce7..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /NICK.
- */
-class CommandNick : public Command
-{
- public:
-       /** Constructor for nick.
-        */
-       CommandNick ( Module* parent) : Command(parent,"NICK", 1, 1) { works_before_reg = true; syntax = "<newnick>"; Penalty = 0; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-/** Handle nick changes from users.
- * NOTE: If you are used to ircds based on ircd2.8, and are looking
- * for the client introduction code in here, youre in the wrong place.
- * You need to look in the spanningtree module for this!
- */
-CmdResult CommandNick::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string oldnick = user->nick;
-       std::string newnick = parameters[0];
-
-       // anything except the initial NICK gets a flood penalty
-       if (user->registered == REG_ALL && IS_LOCAL(user))
-               IS_LOCAL(user)->CommandFloodPenalty += 4000;
-
-       if (newnick.empty())
-       {
-               user->WriteNumeric(ERR_ERRONEUSNICKNAME, "* :Erroneous Nickname");
-               return CMD_FAILURE;
-       }
-
-       if (newnick == "0")
-       {
-               newnick = user->uuid;
-       }
-       else if (!ServerInstance->IsNick(newnick))
-       {
-               user->WriteNumeric(ERR_ERRONEUSNICKNAME, "%s :Erroneous Nickname", newnick.c_str());
-               return CMD_FAILURE;
-       }
-
-       if (!user->ChangeNick(newnick, false))
-               return CMD_FAILURE;
-
-       if (user->registered < REG_NICKUSER)
-       {
-               user->registered = (user->registered | REG_NICK);
-               if (user->registered == REG_NICKUSER)
-               {
-                       /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */
-                       ModResult MOD_RESULT;
-                       FIRST_MOD_RESULT(OnUserRegister, MOD_RESULT, (IS_LOCAL(user)));
-                       if (MOD_RESULT == MOD_RES_DENY)
-                               return CMD_FAILURE;
-
-                       // return early to not penalize new users
-                       return CMD_SUCCESS;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandNick)
diff --git a/src/commands/cmd_oper.cpp b/src/commands/cmd_oper.cpp
deleted file mode 100644 (file)
index bd7a350..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /OPER.
- */
-class CommandOper : public SplitCommand
-{
- public:
-       /** Constructor for oper.
-        */
-       CommandOper ( Module* parent) : SplitCommand(parent,"OPER",2,2) { syntax = "<username> <password>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
-};
-
-CmdResult CommandOper::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
-{
-       bool match_login = false;
-       bool match_pass = false;
-       bool match_hosts = false;
-
-       const std::string userHost = user->ident + "@" + user->host;
-       const std::string userIP = user->ident + "@" + user->GetIPString();
-
-       OperIndex::iterator i = ServerInstance->Config->oper_blocks.find(parameters[0]);
-       if (i != ServerInstance->Config->oper_blocks.end())
-       {
-               OperInfo* ifo = i->second;
-               ConfigTag* tag = ifo->oper_block;
-               match_login = true;
-               match_pass = ServerInstance->PassCompare(user, tag->getString("password"), parameters[1], tag->getString("hash"));
-               match_hosts = InspIRCd::MatchMask(tag->getString("host"), userHost, userIP);
-
-               if (match_pass && match_hosts)
-               {
-                       /* found this oper's opertype */
-                       user->Oper(ifo);
-                       return CMD_SUCCESS;
-               }
-       }
-
-       std::string fields;
-       if (!match_login)
-               fields.append("login ");
-       if (!match_pass)
-               fields.append("password ");
-       if (!match_hosts)
-               fields.append("hosts");
-
-       // tell them they suck, and lag them up to help prevent brute-force attacks
-       user->WriteNumeric(ERR_NOOPERHOST, ":Invalid oper credentials");
-       user->CommandFloodPenalty += 10000;
-
-       ServerInstance->SNO->WriteGlobalSno('o', "WARNING! Failed oper attempt by %s using login '%s': The following fields do not match: %s", user->GetFullRealHost().c_str(), parameters[0].c_str(), fields.c_str());
-       ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "OPER: Failed oper attempt by %s using login '%s': The following fields did not match: %s", user->GetFullRealHost().c_str(), parameters[0].c_str(), fields.c_str());
-       return CMD_FAILURE;
-}
-
-COMMAND_INIT(CommandOper)
diff --git a/src/commands/cmd_part.cpp b/src/commands/cmd_part.cpp
deleted file mode 100644 (file)
index f427063..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /PART.
- */
-class CommandPart : public Command
-{
- public:
-       /** Constructor for part.
-        */
-       CommandPart (Module* parent) : Command(parent,"PART", 1, 2) { Penalty = 5; syntax = "<channel>{,<channel>} [<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-CmdResult CommandPart::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string reason;
-
-       if (IS_LOCAL(user))
-       {
-               if (!ServerInstance->Config->FixedPart.empty())
-                       reason = ServerInstance->Config->FixedPart;
-               else if (parameters.size() > 1)
-                       reason = ServerInstance->Config->PrefixPart + parameters[1] + ServerInstance->Config->SuffixPart;
-       }
-       else
-       {
-               if (parameters.size() > 1)
-                       reason = parameters[1];
-       }
-
-       if (CommandParser::LoopCall(user, this, parameters, 0))
-               return CMD_SUCCESS;
-
-       Channel* c = ServerInstance->FindChan(parameters[0]);
-
-       if (c)
-       {
-               c->PartUser(user, reason);
-       }
-       else
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandPart)
diff --git a/src/commands/cmd_pass.cpp b/src/commands/cmd_pass.cpp
deleted file mode 100644 (file)
index 66b2b57..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /PASS.
- */
-class CommandPass : public SplitCommand
-{
- public:
-       /** Constructor for pass.
-        */
-       CommandPass (Module* parent) : SplitCommand(parent,"PASS",1,1) { works_before_reg = true; Penalty = 0; syntax = "<password>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
-};
-
-
-CmdResult CommandPass::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
-{
-       // Check to make sure they haven't registered -- Fix by FCS
-       if (user->registered == REG_ALL)
-       {
-               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You may not reregister");
-               return CMD_FAILURE;
-       }
-       user->password = parameters[0];
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandPass)
diff --git a/src/commands/cmd_ping.cpp b/src/commands/cmd_ping.cpp
deleted file mode 100644 (file)
index 06135f8..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /PING.
- */
-class CommandPing : public Command
-{
- public:
-       /** Constructor for ping.
-        */
-       CommandPing ( Module* parent) : Command(parent,"PING", 1, 2) { Penalty = 0; syntax = "<servername> [:<servername>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandPing::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       user->WriteServ("PONG %s :%s", ServerInstance->Config->ServerName.c_str(), parameters[0].c_str());
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandPing)
diff --git a/src/commands/cmd_pong.cpp b/src/commands/cmd_pong.cpp
deleted file mode 100644 (file)
index 06db926..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /PONG.
- */
-class CommandPong : public Command
-{
- public:
-       /** Constructor for pong.
-        */
-       CommandPong ( Module* parent) : Command(parent,"PONG", 0, 1) { Penalty = 0; syntax = "<ping-text>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandPong::Handle (const std::vector<std::string>&, User *user)
-{
-       // set the user as alive so they survive to next ping
-       if (IS_LOCAL(user))
-               IS_LOCAL(user)->lastping = 1;
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandPong)
diff --git a/src/commands/cmd_privmsg.cpp b/src/commands/cmd_privmsg.cpp
deleted file mode 100644 (file)
index 0cca567..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-namespace
-{
-       const char* MessageTypeString[] = { "PRIVMSG", "NOTICE" };
-}
-
-class MessageCommandBase : public Command
-{
-       ChanModeReference moderatedmode;
-       ChanModeReference noextmsgmode;
-
- public:
-       MessageCommandBase(Module* parent, MessageType mt)
-               : Command(parent, MessageTypeString[mt], 2, 2)
-               , moderatedmode(parent, "moderated")
-               , noextmsgmode(parent, "noextmsg")
-       {
-               syntax = "<target>{,<target>} <message>";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleMessage(const std::vector<std::string>& parameters, User* user, MessageType mt);
-
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (IS_LOCAL(user))
-                       // This is handled by the OnUserMessage hook to split the LoopCall pieces
-                       return ROUTE_LOCALONLY;
-               else
-                       return ROUTE_MESSAGE(parameters[0]);
-       }
-};
-
-CmdResult MessageCommandBase::HandleMessage(const std::vector<std::string>& parameters, User* user, MessageType mt)
-{
-       User *dest;
-       Channel *chan;
-       CUList except_list;
-
-       LocalUser* localuser = IS_LOCAL(user);
-       if (localuser)
-               localuser->idle_lastmsg = ServerInstance->Time();
-
-       if (CommandParser::LoopCall(user, this, parameters, 0))
-               return CMD_SUCCESS;
-
-       if (parameters[0][0] == '$')
-       {
-               if (!user->HasPrivPermission("users/mass-message"))
-                       return CMD_SUCCESS;
-
-               ModResult MOD_RESULT;
-               std::string temp = parameters[1];
-               FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, except_list, mt));
-               if (MOD_RESULT == MOD_RES_DENY)
-                       return CMD_FAILURE;
-
-               const char* text = temp.c_str();
-               const char* servermask = (parameters[0].c_str()) + 1;
-
-               FOREACH_MOD(OnText, (user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, except_list));
-               if (InspIRCd::Match(ServerInstance->Config->ServerName, servermask, NULL))
-               {
-                       user->SendAll(MessageTypeString[mt], "%s", text);
-               }
-               FOREACH_MOD(OnUserMessage, (user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, except_list, mt));
-               return CMD_SUCCESS;
-       }
-       char status = 0;
-       const char* target = parameters[0].c_str();
-
-       if (ServerInstance->Modes->FindPrefix(*target))
-       {
-               status = *target;
-               target++;
-       }
-       if (*target == '#')
-       {
-               chan = ServerInstance->FindChan(target);
-
-               except_list.insert(user);
-
-               if (chan)
-               {
-                       if (localuser && chan->GetPrefixValue(user) < VOICE_VALUE)
-                       {
-                               if (chan->IsModeSet(noextmsgmode) && !chan->HasUser(user))
-                               {
-                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (no external messages)", chan->name.c_str());
-                                       return CMD_FAILURE;
-                               }
-
-                               if (chan->IsModeSet(moderatedmode))
-                               {
-                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (+m)", chan->name.c_str());
-                                       return CMD_FAILURE;
-                               }
-
-                               if (ServerInstance->Config->RestrictBannedUsers)
-                               {
-                                       if (chan->IsBanned(user))
-                                       {
-                                               user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (you're banned)", chan->name.c_str());
-                                               return CMD_FAILURE;
-                                       }
-                               }
-                       }
-                       ModResult MOD_RESULT;
-
-                       std::string temp = parameters[1];
-                       FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, chan, TYPE_CHANNEL, temp, status, except_list, mt));
-                       if (MOD_RESULT == MOD_RES_DENY)
-                               return CMD_FAILURE;
-
-                       const char* text = temp.c_str();
-
-                       /* Check again, a module may have zapped the input string */
-                       if (temp.empty())
-                       {
-                               user->WriteNumeric(ERR_NOTEXTTOSEND, ":No text to send");
-                               return CMD_FAILURE;
-                       }
-
-                       FOREACH_MOD(OnText, (user,chan,TYPE_CHANNEL,text,status,except_list));
-
-                       if (status)
-                       {
-                               if (ServerInstance->Config->UndernetMsgPrefix)
-                               {
-                                       chan->WriteAllExcept(user, false, status, except_list, "%s %c%s :%c %s", MessageTypeString[mt], status, chan->name.c_str(), status, text);
-                               }
-                               else
-                               {
-                                       chan->WriteAllExcept(user, false, status, except_list, "%s %c%s :%s", MessageTypeString[mt], status, chan->name.c_str(), text);
-                               }
-                       }
-                       else
-                       {
-                               chan->WriteAllExcept(user, false, status, except_list, "%s %s :%s", MessageTypeString[mt], chan->name.c_str(), text);
-                       }
-
-                       FOREACH_MOD(OnUserMessage, (user,chan, TYPE_CHANNEL, text, status, except_list, mt));
-               }
-               else
-               {
-                       /* no such nick/channel */
-                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", target);
-                       return CMD_FAILURE;
-               }
-               return CMD_SUCCESS;
-       }
-
-       const char* destnick = parameters[0].c_str();
-
-       if (localuser)
-       {
-               const char* targetserver = strchr(destnick, '@');
-
-               if (targetserver)
-               {
-                       std::string nickonly;
-
-                       nickonly.assign(destnick, 0, targetserver - destnick);
-                       dest = ServerInstance->FindNickOnly(nickonly);
-                       if (dest && strcasecmp(dest->server->GetName().c_str(), targetserver + 1))
-                       {
-                               /* Incorrect server for user */
-                               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-                               return CMD_FAILURE;
-                       }
-               }
-               else
-                       dest = ServerInstance->FindNickOnly(destnick);
-       }
-       else
-               dest = ServerInstance->FindNick(destnick);
-
-       if ((dest) && (dest->registered == REG_ALL))
-       {
-               if (parameters[1].empty())
-               {
-                       user->WriteNumeric(ERR_NOTEXTTOSEND, ":No text to send");
-                       return CMD_FAILURE;
-               }
-
-               if ((dest->IsAway()) && (mt == MSG_PRIVMSG))
-               {
-                       /* auto respond with aweh msg */
-                       user->WriteNumeric(RPL_AWAY, "%s :%s", dest->nick.c_str(), dest->awaymsg.c_str());
-               }
-
-               ModResult MOD_RESULT;
-
-               std::string temp = parameters[1];
-               FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, dest, TYPE_USER, temp, 0, except_list, mt));
-               if (MOD_RESULT == MOD_RES_DENY)
-                       return CMD_FAILURE;
-
-               const char* text = temp.c_str();
-
-               FOREACH_MOD(OnText, (user, dest, TYPE_USER, text, 0, except_list));
-
-               if (IS_LOCAL(dest))
-               {
-                       // direct write, same server
-                       user->WriteTo(dest, "%s %s :%s", MessageTypeString[mt], dest->nick.c_str(), text);
-               }
-
-               FOREACH_MOD(OnUserMessage, (user, dest, TYPE_USER, text, 0, except_list, mt));
-       }
-       else
-       {
-               /* no such nick/channel */
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-       return CMD_SUCCESS;
-}
-
-template<MessageType MT>
-class CommandMessage : public MessageCommandBase
-{
- public:
-       CommandMessage(Module* parent)
-               : MessageCommandBase(parent, MT)
-       {
-       }
-
-       CmdResult Handle(const std::vector<std::string>& parameters, User* user)
-       {
-               return HandleMessage(parameters, user, MT);
-       }
-};
-
-class ModuleCoreMessage : public Module
-{
-       CommandMessage<MSG_PRIVMSG> CommandPrivmsg;
-       CommandMessage<MSG_NOTICE> CommandNotice;
-
- public:
-       ModuleCoreMessage()
-               : CommandPrivmsg(this), CommandNotice(this)
-       {
-       }
-
-       Version GetVersion()
-       {
-               return Version("PRIVMSG, NOTICE", VF_CORE|VF_VENDOR);
-       }
-};
-
-MODULE_INIT(ModuleCoreMessage)
diff --git a/src/commands/cmd_qline.cpp b/src/commands/cmd_qline.cpp
deleted file mode 100644 (file)
index 003aacb..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-
-/** Handle /QLINE.  */
-class CommandQline : public Command
-{
- public:
-       /** Constructor for qline.
-        */
-       CommandQline ( Module* parent) : Command(parent,"QLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<nick> [<duration> :<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param pcnt The number of parameters passed to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-
-CmdResult CommandQline::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() >= 3)
-       {
-               if (ServerInstance->NickMatchesEveryone(parameters[0],user))
-                       return CMD_FAILURE;
-
-               if (parameters[0].find('@') != std::string::npos || parameters[0].find('!') != std::string::npos || parameters[0].find('.') != std::string::npos)
-               {
-                       user->WriteNotice("*** A Q-Line only bans a nick pattern, not a nick!user@host pattern.");
-                       return CMD_FAILURE;
-               }
-
-               unsigned long duration = InspIRCd::Duration(parameters[1]);
-               QLine* ql = new QLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
-               if (ServerInstance->XLines->AddLine(ql,user))
-               {
-                       if (!duration)
-                       {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent Q-line for %s: %s",user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
-                       }
-                       else
-                       {
-                               time_t c_requires_crap = duration + ServerInstance->Time();
-                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed Q-line for %s, expires on %s: %s",user->nick.c_str(),parameters[0].c_str(),
-                                               timestr.c_str(), parameters[2].c_str());
-                       }
-                       ServerInstance->XLines->ApplyLines();
-               }
-               else
-               {
-                       delete ql;
-                       user->WriteNotice("*** Q-Line for " + parameters[0] + " already exists");
-               }
-       }
-       else
-       {
-               if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "Q", user))
-               {
-                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed Q-line on %s",user->nick.c_str(),parameters[0].c_str());
-               }
-               else
-               {
-                       user->WriteNotice("*** Q-Line " + parameters[0] + " not found in list, try /stats q.");
-                       return CMD_FAILURE;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandQline)
diff --git a/src/commands/cmd_quit.cpp b/src/commands/cmd_quit.cpp
deleted file mode 100644 (file)
index 15dc07d..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /QUIT.
- */
-class CommandQuit : public Command
-{
- public:
-       /** Constructor for quit.
-        */
-       CommandQuit ( Module* parent) : Command(parent,"QUIT",0,1) { works_before_reg = true; syntax = "[<message>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
-       }
-};
-
-
-CmdResult CommandQuit::Handle (const std::vector<std::string>& parameters, User *user)
-{
-
-       std::string quitmsg;
-
-       if (IS_LOCAL(user))
-       {
-               if (!ServerInstance->Config->FixedQuit.empty())
-                       quitmsg = ServerInstance->Config->FixedQuit;
-               else
-                       quitmsg = parameters.size() ?
-                               ServerInstance->Config->PrefixQuit + parameters[0] + ServerInstance->Config->SuffixQuit
-                               : "Client exited";
-       }
-       else
-               quitmsg = parameters.size() ? parameters[0] : "Client exited";
-
-       std::string* operquit = ServerInstance->OperQuit.get(user);
-       ServerInstance->Users->QuitUser(user, quitmsg, operquit);
-
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandQuit)
diff --git a/src/commands/cmd_rehash.cpp b/src/commands/cmd_rehash.cpp
deleted file mode 100644 (file)
index f71219f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /REHASH.
- */
-class CommandRehash : public Command
-{
- public:
-       /** Constructor for rehash.
-        */
-       CommandRehash ( Module* parent) : Command(parent,"REHASH",0) { flags_needed = 'o'; Penalty = 2; syntax = "[<servermask>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string param = parameters.size() ? parameters[0] : "";
-
-       FOREACH_MOD(OnPreRehash, (user, param));
-
-       if (param.empty())
-       {
-               // standard rehash of local server
-       }
-       else if (param.find_first_of("*.") != std::string::npos)
-       {
-               // rehash of servers by server name (with wildcard)
-               if (!InspIRCd::Match(ServerInstance->Config->ServerName, parameters[0]))
-               {
-                       // Doesn't match us. PreRehash is already done, nothing left to do
-                       return CMD_SUCCESS;
-               }
-       }
-       else
-       {
-               // parameterized rehash
-
-               // the leading "-" is optional; remove it if present.
-               if (param[0] == '-')
-                       param = param.substr(1);
-
-               FOREACH_MOD(OnModuleRehash, (user, param));
-               return CMD_SUCCESS;
-       }
-
-       // Rehash for me. Try to start the rehash thread
-       if (!ServerInstance->ConfigThread)
-       {
-               std::string m = user->nick + " is rehashing config file " + FileSystem::GetFileName(ServerInstance->ConfigFileName) + " on " + ServerInstance->Config->ServerName;
-               ServerInstance->SNO->WriteGlobalSno('a', m);
-
-               if (IS_LOCAL(user))
-                       user->WriteNumeric(RPL_REHASHING, "%s :Rehashing", FileSystem::GetFileName(ServerInstance->ConfigFileName).c_str());
-               else
-                       ServerInstance->PI->SendUserNotice(user, "*** Rehashing server " + FileSystem::GetFileName(ServerInstance->ConfigFileName));
-
-               /* Don't do anything with the logs here -- logs are restarted
-                * after the config thread has completed.
-                */
-               ServerInstance->Rehash(user->uuid);
-       }
-       else
-       {
-               /*
-                * A rehash is already in progress! ahh shit.
-                * XXX, todo: we should find some way to kill runaway rehashes that are blocking, this is a major problem for unrealircd users
-                */
-               if (IS_LOCAL(user))
-                       user->WriteNotice("*** Could not rehash: A rehash is already in progress.");
-               else
-                       ServerInstance->PI->SendUserNotice(user, "*** Could not rehash: A rehash is already in progress.");
-       }
-
-       // Always return success so spanningtree forwards an incoming REHASH even if we failed
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandRehash)
diff --git a/src/commands/cmd_reloadmodule.cpp b/src/commands/cmd_reloadmodule.cpp
deleted file mode 100644 (file)
index 765c465..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-class CommandReloadmodule : public Command
-{
- public:
-       /** Constructor for reloadmodule.
-        */
-       CommandReloadmodule ( Module* parent) : Command( parent, "RELOADMODULE",1) { flags_needed = 'o'; syntax = "<modulename>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-class ReloadModuleWorker : public HandlerBase1<void, bool>
-{
- public:
-       const std::string name;
-       const std::string uid;
-       ReloadModuleWorker(const std::string& uuid, const std::string& modn)
-               : name(modn), uid(uuid) {}
-       void Call(bool result)
-       {
-               ServerInstance->SNO->WriteGlobalSno('a', "RELOAD MODULE: %s %ssuccessfully reloaded",
-                       name.c_str(), result ? "" : "un");
-               User* user = ServerInstance->FindNick(uid);
-               if (user)
-                       user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module %ssuccessfully reloaded.",
-                               name.c_str(), result ? "" : "un");
-               ServerInstance->GlobalCulls.AddItem(this);
-       }
-};
-
-CmdResult CommandReloadmodule::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters[0] == "cmd_reloadmodule.so")
-       {
-               user->WriteNumeric(RPL_LOADEDMODULE, "%s :You cannot reload cmd_reloadmodule.so (unload and load it)",
-                       parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       Module* m = ServerInstance->Modules->Find(parameters[0]);
-       if (m)
-       {
-               ServerInstance->Modules->Reload(m, new ReloadModuleWorker(user->uuid, parameters[0]));
-               return CMD_SUCCESS;
-       }
-       else
-       {
-               user->WriteNumeric(RPL_LOADEDMODULE, "%s :Could not find module by that name", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-}
-
-COMMAND_INIT(CommandReloadmodule)
diff --git a/src/commands/cmd_restart.cpp b/src/commands/cmd_restart.cpp
deleted file mode 100644 (file)
index 33627b5..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /RESTART
- */
-class CommandRestart : public Command
-{
- public:
-       /** Constructor for restart.
-        */
-       CommandRestart(Module* parent) : Command(parent,"RESTART",1,1) { flags_needed = 'o'; syntax = "<password>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandRestart::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       ServerInstance->Logs->Log("COMMAND", LOG_DEFAULT, "Restart: %s",user->nick.c_str());
-       if (ServerInstance->PassCompare(user, ServerInstance->Config->restartpass, parameters[0], ServerInstance->Config->powerhash))
-       {
-               ServerInstance->SNO->WriteGlobalSno('a', "RESTART command from %s, restarting server.", user->GetFullRealHost().c_str());
-
-               ServerInstance->SendError("Server restarting.");
-
-#ifndef _WIN32
-               /* XXX: This hack sets FD_CLOEXEC on all possible file descriptors, so they're closed if the execv() below succeeds.
-                * Certainly, this is not a nice way to do things and it's slow when the fd limit is high.
-                *
-                * A better solution would be to set the close-on-exec flag for each fd we create (or create them with O_CLOEXEC),
-                * however there is no guarantee that third party libs will do the same.
-                */
-               for (int i = getdtablesize(); --i > 2;)
-               {
-                       int flags = fcntl(i, F_GETFD);
-                       if (flags != -1)
-                               fcntl(i, F_SETFD, flags | FD_CLOEXEC);
-               }
-#endif
-
-               execv(ServerInstance->Config->cmdline.argv[0], ServerInstance->Config->cmdline.argv);
-               ServerInstance->SNO->WriteGlobalSno('a', "Failed RESTART - could not execute '%s' (%s)",
-                       ServerInstance->Config->cmdline.argv[0], strerror(errno));
-       }
-       else
-       {
-               ServerInstance->SNO->WriteGlobalSno('a', "Failed RESTART Command from %s.", user->GetFullRealHost().c_str());
-       }
-       return CMD_FAILURE;
-}
-
-
-COMMAND_INIT(CommandRestart)
diff --git a/src/commands/cmd_server.cpp b/src/commands/cmd_server.cpp
deleted file mode 100644 (file)
index 8c32daf..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /SERVER.
- */
-class CommandServer : public Command
-{
- public:
-       /** Constructor for server.
-        */
-       CommandServer ( Module* parent) : Command(parent,"SERVER") { works_before_reg = true;}
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandServer::Handle (const std::vector<std::string>&, User *user)
-{
-       if (user->registered == REG_ALL)
-       {
-               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You are already registered. (Perhaps your IRC client does not have a /SERVER command).");
-       }
-       else
-       {
-               user->WriteNumeric(ERR_NOTREGISTERED, ":You may not register as a server (servers have separate ports from clients, change your config)");
-       }
-       return CMD_FAILURE;
-}
-
-COMMAND_INIT(CommandServer)
diff --git a/src/commands/cmd_squit.cpp b/src/commands/cmd_squit.cpp
deleted file mode 100644 (file)
index e64f5fc..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /SQUIT.
- */
-class CommandSquit : public Command
-{
- public:
-       /** Constructor for squit.
-        */
-       CommandSquit ( Module* parent) : Command(parent,"SQUIT",1,2) { flags_needed = 'o'; syntax = "<servername> [<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-
-/*
- * This is handled by the server linking module, if necessary. Do not remove this stub.
- */
-
-
-CmdResult CommandSquit::Handle (const std::vector<std::string>&, User *user)
-{
-       user->WriteServ( "NOTICE %s :Look into loading a linking module (like m_spanningtree) if you want this to do anything useful.", user->nick.c_str());
-       return CMD_FAILURE;
-}
-
-COMMAND_INIT(CommandSquit)
diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp
deleted file mode 100644 (file)
index 8e74b83..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-
-#ifdef _WIN32
-#include <psapi.h>
-#pragma comment(lib, "psapi.lib") // For GetProcessMemoryInfo()
-#endif
-
-/** Handle /STATS.
- */
-class CommandStats : public Command
-{
-       void DoStats(char statschar, User* user, string_list &results);
- public:
-       /** Constructor for stats.
-        */
-       CommandStats ( Module* parent) : Command(parent,"STATS",1,2) { syntax = "<stats-symbol> [<servername>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() > 1)
-                       return ROUTE_UNICAST(parameters[1]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-void CommandStats::DoStats(char statschar, User* user, string_list &results)
-{
-       bool isPublic = ServerInstance->Config->UserStats.find(statschar) != std::string::npos;
-       bool isRemoteOper = IS_REMOTE(user) && (user->IsOper());
-       bool isLocalOperWithPrivs = IS_LOCAL(user) && user->HasPrivPermission("servers/auspex");
-
-       if (!isPublic && !isRemoteOper && !isLocalOperWithPrivs)
-       {
-               ServerInstance->SNO->WriteToSnoMask('t',
-                               "%s '%c' denied for %s (%s@%s)",
-                               (IS_LOCAL(user) ? "Stats" : "Remote stats"),
-                               statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
-               results.push_back("481 " + user->nick + " :Permission denied - STATS " + statschar + " requires the servers/auspex priv.");
-               return;
-       }
-
-       ModResult MOD_RESULT;
-       FIRST_MOD_RESULT(OnStats, MOD_RESULT, (statschar, user, results));
-       if (MOD_RESULT == MOD_RES_DENY)
-       {
-               results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report");
-               ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",
-                       (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
-               return;
-       }
-
-       switch (statschar)
-       {
-               /* stats p (show listening ports) */
-               case 'p':
-               {
-                       for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i)
-                       {
-                               ListenSocket* ls = *i;
-                               std::string ip = ls->bind_addr;
-                               if (ip.empty())
-                                       ip.assign("*");
-                               std::string type = ls->bind_tag->getString("type", "clients");
-                               std::string hook = ls->bind_tag->getString("ssl", "plaintext");
-
-                               results.push_back("249 "+user->nick+" :"+ ip + ":"+ConvToStr(ls->bind_port)+
-                                       " (" + type + ", " + hook + ")");
-                       }
-               }
-               break;
-
-               /* These stats symbols must be handled by a linking module */
-               case 'n':
-               case 'c':
-               break;
-
-               case 'i':
-               {
-                       for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
-                       {
-                               ConnectClass* c = *i;
-                               std::stringstream res;
-                               res << "215 " << user->nick << " I " << c->name << ' ';
-                               if (c->type == CC_ALLOW)
-                                       res << '+';
-                               if (c->type == CC_DENY)
-                                       res << '-';
-
-                               if (c->type == CC_NAMED)
-                                       res << '*';
-                               else
-                                       res << c->host;
-
-                               res << ' ' << c->config->getString("port", "*") << ' ';
-
-                               res << c->GetRecvqMax() << ' ' << c->GetSendqSoftMax() << ' ' << c->GetSendqHardMax()
-                                       << ' ' << c->GetCommandRate() << ' ' << c->GetPenaltyThreshold();
-                               if (c->fakelag)
-                                       res << '*';
-                               results.push_back(res.str());
-                       }
-               }
-               break;
-
-               case 'Y':
-               {
-                       int idx = 0;
-                       for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
-                       {
-                               ConnectClass* c = *i;
-                               results.push_back("215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : SocketEngine::GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *");
-                               results.push_back("218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+
-                                               ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout()));
-                               idx++;
-                       }
-               }
-               break;
-
-               case 'P':
-               {
-                       unsigned int idx = 0;
-                       for (std::list<User*>::const_iterator i = ServerInstance->Users->all_opers.begin(); i != ServerInstance->Users->all_opers.end(); ++i)
-                       {
-                               User* oper = *i;
-                               if (!oper->server->IsULine())
-                               {
-                                       LocalUser* lu = IS_LOCAL(oper);
-                                       results.push_back("249 " + user->nick + " :" + oper->nick + " (" + oper->ident + "@" + oper->dhost + ") Idle: " +
-                                                       (lu ? ConvToStr(ServerInstance->Time() - lu->idle_lastmsg) + " secs" : "unavailable"));
-                                       idx++;
-                               }
-                       }
-                       results.push_back("249 "+user->nick+" :"+ConvToStr(idx)+" OPER(s)");
-               }
-               break;
-
-               case 'k':
-                       ServerInstance->XLines->InvokeStats("K",216,user,results);
-               break;
-               case 'g':
-                       ServerInstance->XLines->InvokeStats("G",223,user,results);
-               break;
-               case 'q':
-                       ServerInstance->XLines->InvokeStats("Q",217,user,results);
-               break;
-               case 'Z':
-                       ServerInstance->XLines->InvokeStats("Z",223,user,results);
-               break;
-               case 'e':
-                       ServerInstance->XLines->InvokeStats("E",223,user,results);
-               break;
-               case 'E':
-               {
-                       const SocketEngine::Statistics& stats = SocketEngine::GetStats();
-                       results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(stats.TotalEvents));
-                       results.push_back("249 "+user->nick+" :Read events:  "+ConvToStr(stats.ReadEvents));
-                       results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(stats.WriteEvents));
-                       results.push_back("249 "+user->nick+" :Error events: "+ConvToStr(stats.ErrorEvents));
-                       break;
-               }
-
-               /* stats m (list number of times each command has been used, plus bytecount) */
-               case 'm':
-                       for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++)
-                       {
-                               if (i->second->use_count)
-                               {
-                                       /* RPL_STATSCOMMANDS */
-                                       results.push_back("212 "+user->nick+" "+i->second->name+" "+ConvToStr(i->second->use_count));
-                               }
-                       }
-               break;
-
-               /* stats z (debug and memory info) */
-               case 'z':
-               {
-                       results.push_back("249 "+user->nick+" :Users: "+ConvToStr(ServerInstance->Users->clientlist->size()));
-                       results.push_back("249 "+user->nick+" :Channels: "+ConvToStr(ServerInstance->chanlist->size()));
-                       results.push_back("249 "+user->nick+" :Commands: "+ConvToStr(ServerInstance->Parser->cmdlist.size()));
-
-                       float kbitpersec_in, kbitpersec_out, kbitpersec_total;
-                       char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30];
-
-                       SocketEngine::GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total);
-
-                       snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total);
-                       snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out);
-                       snprintf(kbitpersec_in_s, 30, "%03.5f", kbitpersec_in);
-
-                       results.push_back("249 "+user->nick+" :Bandwidth total:  "+ConvToStr(kbitpersec_total_s)+" kilobits/sec");
-                       results.push_back("249 "+user->nick+" :Bandwidth out:    "+ConvToStr(kbitpersec_out_s)+" kilobits/sec");
-                       results.push_back("249 "+user->nick+" :Bandwidth in:     "+ConvToStr(kbitpersec_in_s)+" kilobits/sec");
-
-#ifndef _WIN32
-                       /* Moved this down here so all the not-windows stuff (look w00tie, I didn't say win32!) is in one ifndef.
-                        * Also cuts out some identical code in both branches of the ifndef. -- Om
-                        */
-                       rusage R;
-
-                       /* Not sure why we were doing '0' with a RUSAGE_SELF comment rather than just using RUSAGE_SELF -- Om */
-                       if (!getrusage(RUSAGE_SELF,&R)) /* RUSAGE_SELF */
-                       {
-                               results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr(R.ru_maxrss)+"K");
-                               results.push_back("249 "+user->nick+" :Signals:          "+ConvToStr(R.ru_nsignals));
-                               results.push_back("249 "+user->nick+" :Page faults:      "+ConvToStr(R.ru_majflt));
-                               results.push_back("249 "+user->nick+" :Swaps:            "+ConvToStr(R.ru_nswap));
-                               results.push_back("249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw));
-
-                               char percent[30];
-
-                               float n_elapsed = (ServerInstance->Time() - ServerInstance->stats->LastSampled.tv_sec) * 1000000
-                                       + (ServerInstance->Time_ns() - ServerInstance->stats->LastSampled.tv_nsec) / 1000;
-                               float n_eaten = ((R.ru_utime.tv_sec - ServerInstance->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - ServerInstance->stats->LastCPU.tv_usec);
-                               float per = (n_eaten / n_elapsed) * 100;
-
-                               snprintf(percent, 30, "%03.5f%%", per);
-                               results.push_back("249 "+user->nick+" :CPU Use (now):    "+percent);
-
-                               n_elapsed = ServerInstance->Time() - ServerInstance->startup_time;
-                               n_eaten = (float)R.ru_utime.tv_sec + R.ru_utime.tv_usec / 100000.0;
-                               per = (n_eaten / n_elapsed) * 100;
-                               snprintf(percent, 30, "%03.5f%%", per);
-                               results.push_back("249 "+user->nick+" :CPU Use (total):  "+percent);
-                       }
-#else
-                       PROCESS_MEMORY_COUNTERS MemCounters;
-                       if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters)))
-                       {
-                               results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K");
-                               results.push_back("249 "+user->nick+" :Pagefile usage:   "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K");
-                               results.push_back("249 "+user->nick+" :Page faults:      "+ConvToStr(MemCounters.PageFaultCount));
-                       }
-
-                       FILETIME CreationTime;
-                       FILETIME ExitTime;
-                       FILETIME KernelTime;
-                       FILETIME UserTime;
-                       LARGE_INTEGER ThisSample;
-                       if(GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime) &&
-                               QueryPerformanceCounter(&ThisSample))
-                       {
-                               KernelTime.dwHighDateTime += UserTime.dwHighDateTime;
-                               KernelTime.dwLowDateTime += UserTime.dwLowDateTime;
-                               double n_eaten = (double)( ( (uint64_t)(KernelTime.dwHighDateTime - ServerInstance->stats->LastCPU.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime - ServerInstance->stats->LastCPU.dwLowDateTime) )/100000;
-                               double n_elapsed = (double)(ThisSample.QuadPart - ServerInstance->stats->LastSampled.QuadPart) / ServerInstance->stats->QPFrequency.QuadPart;
-                               double per = (n_eaten/n_elapsed);
-
-                               char percent[30];
-
-                               snprintf(percent, 30, "%03.5f%%", per);
-                               results.push_back("249 "+user->nick+" :CPU Use (now):    "+percent);
-
-                               n_elapsed = ServerInstance->Time() - ServerInstance->startup_time;
-                               n_eaten = (double)(( (uint64_t)(KernelTime.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime))/100000;
-                               per = (n_eaten / n_elapsed);
-                               snprintf(percent, 30, "%03.5f%%", per);
-                               results.push_back("249 "+user->nick+" :CPU Use (total):  "+percent);
-                       }
-#endif
-               }
-               break;
-
-               case 'T':
-               {
-                       results.push_back("249 "+user->nick+" :accepts "+ConvToStr(ServerInstance->stats->statsAccept)+" refused "+ConvToStr(ServerInstance->stats->statsRefused));
-                       results.push_back("249 "+user->nick+" :unknown commands "+ConvToStr(ServerInstance->stats->statsUnknown));
-                       results.push_back("249 "+user->nick+" :nick collisions "+ConvToStr(ServerInstance->stats->statsCollisions));
-                       results.push_back("249 "+user->nick+" :dns requests "+ConvToStr(ServerInstance->stats->statsDnsGood+ServerInstance->stats->statsDnsBad)+" succeeded "+ConvToStr(ServerInstance->stats->statsDnsGood)+" failed "+ConvToStr(ServerInstance->stats->statsDnsBad));
-                       results.push_back("249 "+user->nick+" :connection count "+ConvToStr(ServerInstance->stats->statsConnects));
-                       results.push_back(InspIRCd::Format("249 %s :bytes sent %5.2fK recv %5.2fK", user->nick.c_str(),
-                               ServerInstance->stats->statsSent / 1024.0, ServerInstance->stats->statsRecv / 1024.0));
-               }
-               break;
-
-               /* stats o */
-               case 'o':
-               {
-                       ConfigTagList tags = ServerInstance->Config->ConfTags("oper");
-                       for(ConfigIter i = tags.first; i != tags.second; ++i)
-                       {
-                               ConfigTag* tag = i->second;
-                               results.push_back("243 "+user->nick+" O "+tag->getString("host")+" * "+
-                                       tag->getString("name") + " " + tag->getString("type")+" 0");
-                       }
-               }
-               break;
-               case 'O':
-               {
-                       for (OperIndex::const_iterator i = ServerInstance->Config->OperTypes.begin(); i != ServerInstance->Config->OperTypes.end(); ++i)
-                       {
-                               OperInfo* tag = i->second;
-                               tag->init();
-                               std::string umodes;
-                               std::string cmodes;
-                               for(char c='A'; c < 'z'; c++)
-                               {
-                                       ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_USER);
-                                       if (mh && mh->NeedsOper() && tag->AllowedUserModes[c - 'A'])
-                                               umodes.push_back(c);
-                                       mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL);
-                                       if (mh && mh->NeedsOper() && tag->AllowedChanModes[c - 'A'])
-                                               cmodes.push_back(c);
-                               }
-                               results.push_back("243 "+user->nick+" O "+tag->name.c_str() + " " + umodes + " " + cmodes);
-                       }
-               }
-               break;
-
-               /* stats l (show user I/O stats) */
-               case 'l':
-                       results.push_back("211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open");
-                       for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
-                       {
-                               LocalUser* i = *n;
-                               results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
-                       }
-               break;
-
-               /* stats L (show user I/O stats with IP addresses) */
-               case 'L':
-                       results.push_back("211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open");
-                       for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
-                       {
-                               LocalUser* i = *n;
-                               results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
-                       }
-               break;
-
-               /* stats u (show server uptime) */
-               case 'u':
-               {
-                       time_t current_time = 0;
-                       current_time = ServerInstance->Time();
-                       time_t server_uptime = current_time - ServerInstance->startup_time;
-                       struct tm* stime;
-                       stime = gmtime(&server_uptime);
-                       /* i dont know who the hell would have an ircd running for over a year nonstop, but
-                        * Craig suggested this, and it seemed a good idea so in it went */
-                       if (stime->tm_year > 70)
-                       {
-                               results.push_back(InspIRCd::Format("242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d",
-                                       user->nick.c_str(), stime->tm_year - 70, stime->tm_yday, stime->tm_hour,
-                                       stime->tm_min, stime->tm_sec));
-                       }
-                       else
-                       {
-                               results.push_back(InspIRCd::Format("242 %s :Server up %d days, %.2d:%.2d:%.2d",
-                                       user->nick.c_str(), stime->tm_yday, stime->tm_hour, stime->tm_min,
-                                       stime->tm_sec));
-                       }
-               }
-               break;
-
-               default:
-               break;
-       }
-
-       results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report");
-       ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",
-               (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
-       return;
-}
-
-CmdResult CommandStats::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() > 1 && parameters[1] != ServerInstance->Config->ServerName)
-               return CMD_SUCCESS;
-       string_list values;
-       char search = parameters[0][0];
-       DoStats(search, user, values);
-
-       const std::string p = ":" + ServerInstance->Config->ServerName + " ";
-       for (size_t i = 0; i < values.size(); i++)
-               user->SendText(p + values[i]);
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandStats)
diff --git a/src/commands/cmd_time.cpp b/src/commands/cmd_time.cpp
deleted file mode 100644 (file)
index 9c46880..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /TIME.
- */
-class CommandTime : public Command
-{
- public:
-       /** Constructor for time.
-        */
-       CommandTime ( Module* parent) : Command(parent,"TIME",0,0) { syntax = "[<servername>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               if (parameters.size() > 0)
-                       return ROUTE_UNICAST(parameters[0]);
-               return ROUTE_LOCALONLY;
-       }
-};
-
-CmdResult CommandTime::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
-               return CMD_SUCCESS;
-
-       time_t local = ServerInstance->Time();
-       struct tm* timeinfo = localtime(&local);
-       const std::string& humanTime = asctime(timeinfo);
-
-       user->SendText(":%s %03d %s %s :%s", ServerInstance->Config->ServerName.c_str(), RPL_TIME, user->nick.c_str(),
-               ServerInstance->Config->ServerName.c_str(), humanTime.c_str());
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandTime)
diff --git a/src/commands/cmd_topic.cpp b/src/commands/cmd_topic.cpp
deleted file mode 100644 (file)
index 2b0f81f..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /TOPIC.
- */
-class CommandTopic : public SplitCommand
-{
-       ChanModeReference secretmode;
-       ChanModeReference topiclockmode;
-
- public:
-       /** Constructor for topic.
-        */
-       CommandTopic(Module* parent)
-               : SplitCommand(parent, "TOPIC", 1, 2)
-               , secretmode(parent, "secret")
-               , topiclockmode(parent, "topiclock")
-       {
-               syntax = "<channel> [<topic>]";
-               Penalty = 2;
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
-};
-
-CmdResult CommandTopic::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user)
-{
-       Channel* c = ServerInstance->FindChan(parameters[0]);
-       if (!c)
-       {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       if (parameters.size() == 1)
-       {
-               if ((c->IsModeSet(secretmode)) && (!c->HasUser(user)))
-               {
-                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c->name.c_str());
-                       return CMD_FAILURE;
-               }
-
-               if (c->topic.length())
-               {
-                       user->WriteNumeric(RPL_TOPIC, "%s :%s", c->name.c_str(), c->topic.c_str());
-                       user->WriteNumeric(RPL_TOPICTIME, "%s %s %lu", c->name.c_str(), c->setby.c_str(), (unsigned long)c->topicset);
-               }
-               else
-               {
-                       user->WriteNumeric(RPL_NOTOPICSET, "%s :No topic is set.", c->name.c_str());
-               }
-               return CMD_SUCCESS;
-       }
-
-       std::string t = parameters[1]; // needed, in case a module wants to change it
-       ModResult res;
-       FIRST_MOD_RESULT(OnPreTopicChange, res, (user,c,t));
-
-       if (res == MOD_RES_DENY)
-               return CMD_FAILURE;
-       if (res != MOD_RES_ALLOW)
-       {
-               if (!c->HasUser(user))
-               {
-                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", c->name.c_str());
-                       return CMD_FAILURE;
-               }
-               if (c->IsModeSet(topiclockmode) && !ServerInstance->OnCheckExemption(user, c, "topiclock").check(c->GetPrefixValue(user) >= HALFOP_VALUE))
-               {
-                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You do not have access to change the topic on this channel", c->name.c_str());
-                       return CMD_FAILURE;
-               }
-       }
-
-       c->SetTopic(user, t);
-       return CMD_SUCCESS;
-}
-
-
-COMMAND_INIT(CommandTopic)
diff --git a/src/commands/cmd_unloadmodule.cpp b/src/commands/cmd_unloadmodule.cpp
deleted file mode 100644 (file)
index 5d11e02..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /UNLOADMODULE.
- */
-class CommandUnloadmodule : public Command
-{
- public:
-       /** Constructor for unloadmodule.
-        */
-       CommandUnloadmodule ( Module* parent) : Command(parent,"UNLOADMODULE",1) { flags_needed = 'o'; syntax = "<modulename>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandUnloadmodule::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       if (!ServerInstance->Config->ConfValue("security")->getBool("allowcoreunload") &&
-               InspIRCd::Match(parameters[0], "cmd_*.so", ascii_case_insensitive_map))
-       {
-               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :You cannot unload core commands!", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       if (parameters[0] == "cmd_unloadmodule.so" || parameters[0] == "cmd_loadmodule.so")
-       {
-               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :You cannot unload module loading commands!", parameters[0].c_str());
-               return CMD_FAILURE;
-       }
-
-       Module* m = ServerInstance->Modules->Find(parameters[0]);
-       if (m && ServerInstance->Modules->Unload(m))
-       {
-               ServerInstance->SNO->WriteGlobalSno('a', "MODULE UNLOADED: %s unloaded %s", user->nick.c_str(), parameters[0].c_str());
-               user->WriteNumeric(RPL_UNLOADEDMODULE, "%s :Module successfully unloaded.", parameters[0].c_str());
-       }
-       else
-       {
-               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :%s", parameters[0].c_str(),
-                       m ? ServerInstance->Modules->LastError().c_str() : "No such module");
-               return CMD_FAILURE;
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandUnloadmodule)
diff --git a/src/commands/cmd_user.cpp b/src/commands/cmd_user.cpp
deleted file mode 100644 (file)
index cec11c1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /USER.
- */
-class CommandUser : public SplitCommand
-{
- public:
-       /** Constructor for user.
-        */
-       CommandUser ( Module* parent) : SplitCommand(parent,"USER",4,4) { works_before_reg = true; Penalty = 0; syntax = "<username> <localhost> <remotehost> <GECOS>"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
-};
-
-CmdResult CommandUser::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
-{
-       /* A user may only send the USER command once */
-       if (!(user->registered & REG_USER))
-       {
-               if (!ServerInstance->IsIdent(parameters[0]))
-               {
-                       /*
-                        * RFC says we must use this numeric, so we do. Let's make it a little more nub friendly though. :)
-                        *  -- Craig, and then w00t.
-                        */
-                       user->WriteNumeric(ERR_NEEDMOREPARAMS, "USER :Your username is not valid");
-                       return CMD_FAILURE;
-               }
-               else
-               {
-                       /*
-                        * The ident field is IDENTMAX+2 in size to account for +1 for the optional
-                        * ~ character, and +1 for null termination, therefore we can safely use up to
-                        * IDENTMAX here.
-                        */
-                       user->ChangeIdent(parameters[0]);
-                       user->fullname.assign(parameters[3].empty() ? "No info" : parameters[3], 0, ServerInstance->Config->Limits.MaxGecos);
-                       user->registered = (user->registered | REG_USER);
-               }
-       }
-       else
-       {
-               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You may not reregister");
-               return CMD_FAILURE;
-       }
-
-       /* parameters 2 and 3 are local and remote hosts, and are ignored */
-       if (user->registered == REG_NICKUSER)
-       {
-               ModResult MOD_RESULT;
-
-               /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */
-               FIRST_MOD_RESULT(OnUserRegister, MOD_RESULT, (user));
-               if (MOD_RESULT == MOD_RES_DENY)
-                       return CMD_FAILURE;
-
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandUser)
diff --git a/src/commands/cmd_userhost.cpp b/src/commands/cmd_userhost.cpp
deleted file mode 100644 (file)
index 541402c..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /USERHOST.
- */
-class CommandUserhost : public Command
-{
- public:
-       /** Constructor for userhost.
-        */
-       CommandUserhost ( Module* parent) : Command(parent,"USERHOST", 1, 5) {
-               syntax = "<nick> {<nick>}";
-       }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string retbuf = "302 " + user->nick + " :";
-
-       for (unsigned int i = 0; i < parameters.size(); i++)
-       {
-               User *u = ServerInstance->FindNickOnly(parameters[i]);
-
-               if ((u) && (u->registered == REG_ALL))
-               {
-                       retbuf = retbuf + u->nick;
-
-                       if (u->IsOper())
-                               retbuf = retbuf + "*";
-
-                       retbuf = retbuf + "=";
-
-                       if (u->IsAway())
-                               retbuf += "-";
-                       else
-                               retbuf += "+";
-
-                       retbuf = retbuf + u->ident + "@";
-
-                       if (user->HasPrivPermission("users/auspex"))
-                       {
-                               retbuf = retbuf + u->host;
-                       }
-                       else
-                       {
-                               retbuf = retbuf + u->dhost;
-                       }
-
-                       retbuf = retbuf + " ";
-               }
-       }
-
-       user->WriteServ(retbuf);
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandUserhost)
diff --git a/src/commands/cmd_version.cpp b/src/commands/cmd_version.cpp
deleted file mode 100644 (file)
index 032d9ea..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /VERSION.
- */
-class CommandVersion : public Command
-{
- public:
-       /** Constructor for version.
-        */
-       CommandVersion ( Module* parent) : Command(parent,"VERSION",0,0) { syntax = "[<servername>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandVersion::Handle (const std::vector<std::string>&, User *user)
-{
-       std::string version = ServerInstance->GetVersionString((user->IsOper()));
-       user->WriteNumeric(RPL_VERSION, ":%s", version.c_str());
-       LocalUser *lu = IS_LOCAL(user);
-       if (lu != NULL)
-       {
-               ServerInstance->ISupport.SendTo(lu);
-       }
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandVersion)
diff --git a/src/commands/cmd_wallops.cpp b/src/commands/cmd_wallops.cpp
deleted file mode 100644 (file)
index 731eaf3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /WALLOPS.
- */
-class CommandWallops : public Command
-{
-       UserModeReference wallopsmode;
-
- public:
-       /** Constructor for wallops.
-        */
-       CommandWallops(Module* parent)
-               : Command(parent, "WALLOPS", 1, 1)
-               , wallopsmode(parent, "wallops")
-       {
-               flags_needed = 'o';
-               syntax = "<any-text>";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
-       {
-               return ROUTE_BROADCAST;
-       }
-};
-
-CmdResult CommandWallops::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string wallop("WALLOPS :");
-       wallop.append(parameters[0]);
-
-       for (LocalUserList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)
-       {
-               User* t = *i;
-               if (t->IsModeSet(wallopsmode))
-                       user->WriteTo(t,wallop);
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandWallops)
diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp
deleted file mode 100644 (file)
index dc39e29..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /WHO.
- */
-class CommandWho : public Command
-{
-       bool CanView(Channel* chan, User* user);
-       bool opt_viewopersonly;
-       bool opt_showrealhost;
-       bool opt_realname;
-       bool opt_mode;
-       bool opt_ident;
-       bool opt_metadata;
-       bool opt_port;
-       bool opt_away;
-       bool opt_local;
-       bool opt_far;
-       bool opt_time;
-       ChanModeReference secretmode;
-       ChanModeReference privatemode;
-       UserModeReference invisiblemode;
-
-       Membership* get_first_visible_channel(User* u)
-       {
-               for (UCListIter i = u->chans.begin(); i != u->chans.end(); ++i)
-               {
-                       Membership* memb = *i;
-                       if (!memb->chan->IsModeSet(secretmode))
-                               return memb;
-               }
-               return NULL;
-       }
-
- public:
-       /** Constructor for who.
-        */
-       CommandWho(Module* parent)
-               : Command(parent, "WHO", 1)
-               , secretmode(parent, "secret")
-               , privatemode(parent, "private")
-               , invisiblemode(parent, "invisible")
-       {
-               syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]";
-       }
-
-       void SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string& initial, Membership* memb, User* u, std::vector<std::string>& whoresults);
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-       bool whomatch(User* cuser, User* user, const char* matchtext);
-};
-
-bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
-{
-       bool match = false;
-       bool positive = false;
-
-       if (user->registered != REG_ALL)
-               return false;
-
-       if (opt_local && !IS_LOCAL(user))
-               return false;
-       else if (opt_far && IS_LOCAL(user))
-               return false;
-
-       if (opt_mode)
-       {
-               for (const char* n = matchtext; *n; n++)
-               {
-                       if (*n == '+')
-                       {
-                               positive = true;
-                               continue;
-                       }
-                       else if (*n == '-')
-                       {
-                               positive = false;
-                               continue;
-                       }
-                       if (user->IsModeSet(*n) != positive)
-                               return false;
-               }
-               return true;
-       }
-       else
-       {
-               /*
-                * This was previously one awesome pile of ugly nested if, when really, it didn't need
-                * to be, since only one condition was ever checked, a chained if works just fine.
-                * -- w00t
-                */
-               if (opt_metadata)
-               {
-                       match = false;
-                       const Extensible::ExtensibleStore& list = user->GetExtList();
-                       for(Extensible::ExtensibleStore::const_iterator i = list.begin(); i != list.end(); ++i)
-                               if (InspIRCd::Match(i->first->name, matchtext))
-                                       match = true;
-               }
-               else if (opt_realname)
-                       match = InspIRCd::Match(user->fullname, matchtext);
-               else if (opt_showrealhost)
-                       match = InspIRCd::Match(user->host, matchtext, ascii_case_insensitive_map);
-               else if (opt_ident)
-                       match = InspIRCd::Match(user->ident, matchtext, ascii_case_insensitive_map);
-               else if (opt_port)
-               {
-                       irc::portparser portrange(matchtext, false);
-                       long portno = -1;
-                       while ((portno = portrange.GetToken()))
-                               if (IS_LOCAL(user) && portno == IS_LOCAL(user)->GetServerPort())
-                               {
-                                       match = true;
-                                       break;
-                               }
-               }
-               else if (opt_away)
-                       match = InspIRCd::Match(user->awaymsg, matchtext);
-               else if (opt_time)
-               {
-                       long seconds = InspIRCd::Duration(matchtext);
-
-                       // Okay, so time matching, we want all users connected `seconds' ago
-                       if (user->age >= ServerInstance->Time() - seconds)
-                               match = true;
-               }
-
-               /*
-                * Once the conditionals have been checked, only check dhost/nick/server
-                * if they didn't match this user -- and only match if we don't find a match.
-                *
-                * This should make things minutely faster, and again, less ugly.
-                * -- w00t
-                */
-               if (!match)
-                       match = InspIRCd::Match(user->dhost, matchtext, ascii_case_insensitive_map);
-
-               if (!match)
-                       match = InspIRCd::Match(user->nick, matchtext);
-
-               /* Don't allow server name matches if HideWhoisServer is enabled, unless the command user has the priv */
-               if (!match && (ServerInstance->Config->HideWhoisServer.empty() || cuser->HasPrivPermission("users/auspex")))
-                       match = InspIRCd::Match(user->server->GetName(), matchtext);
-
-               return match;
-       }
-}
-
-bool CommandWho::CanView(Channel* chan, User* user)
-{
-       if (!user || !chan)
-               return false;
-
-       /* Bug #383 - moved higher up the list, because if we are in the channel
-        * we can see all its users
-        */
-       if (chan->HasUser(user))
-               return true;
-       /* Opers see all */
-       if (user->HasPrivPermission("users/auspex"))
-               return true;
-       /* Cant see inside a +s or a +p channel unless we are a member (see above) */
-       else if (!chan->IsModeSet(secretmode) && !chan->IsModeSet(privatemode))
-               return true;
-
-       return false;
-}
-
-void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string& initial, Membership* memb, User* u, std::vector<std::string>& whoresults)
-{
-       if (!memb)
-               memb = get_first_visible_channel(u);
-
-       std::string wholine = initial + (memb ? memb->chan->name : "*") + " " + u->ident + " " +
-               (opt_showrealhost ? u->host : u->dhost) + " ";
-       if (!ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"))
-               wholine.append(ServerInstance->Config->HideWhoisServer);
-       else
-               wholine.append(u->server->GetName());
-
-       wholine.append(" " + u->nick + " ");
-
-       /* away? */
-       if (u->IsAway())
-       {
-               wholine.append("G");
-       }
-       else
-       {
-               wholine.append("H");
-       }
-
-       /* oper? */
-       if (u->IsOper())
-       {
-               wholine.push_back('*');
-       }
-
-       if (memb)
-               wholine.push_back(memb->GetPrefixChar());
-
-       wholine.append(" :0 " + u->fullname);
-
-       FOREACH_MOD(OnSendWhoLine, (user, parms, u, memb, wholine));
-
-       if (!wholine.empty())
-               whoresults.push_back(wholine);
-}
-
-CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       /*
-        * XXX - RFC says:
-        *   The <name> passed to WHO is matched against users' host, server, real
-        *   name and nickname
-        * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
-        */
-
-       /* WHO options */
-       opt_viewopersonly = false;
-       opt_showrealhost = false;
-       opt_realname = false;
-       opt_mode = false;
-       opt_ident = false;
-       opt_metadata = false;
-       opt_port = false;
-       opt_away = false;
-       opt_local = false;
-       opt_far = false;
-       opt_time = false;
-
-       std::vector<std::string> whoresults;
-       std::string initial = "352 " + user->nick + " ";
-
-       /* Change '0' into '*' so the wildcard matcher can grok it */
-       std::string matchtext = ((parameters[0] == "0") ? "*" : parameters[0]);
-
-       // WHO flags count as a wildcard
-       bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?.") != std::string::npos));
-
-       if (parameters.size() > 1)
-       {
-               for (std::string::const_iterator iter = parameters[1].begin(); iter != parameters[1].end(); ++iter)
-               {
-                       switch (*iter)
-                       {
-                               case 'o':
-                                       opt_viewopersonly = true;
-                                       break;
-                               case 'h':
-                                       if (user->HasPrivPermission("users/auspex"))
-                                               opt_showrealhost = true;
-                                       break;
-                               case 'r':
-                                       opt_realname = true;
-                                       break;
-                               case 'm':
-                                       if (user->HasPrivPermission("users/auspex"))
-                                               opt_mode = true;
-                                       break;
-                               case 'M':
-                                       if (user->HasPrivPermission("users/auspex"))
-                                               opt_metadata = true;
-                                       break;
-                               case 'i':
-                                       opt_ident = true;
-                                       break;
-                               case 'p':
-                                       if (user->HasPrivPermission("users/auspex"))
-                                               opt_port = true;
-                                       break;
-                               case 'a':
-                                       opt_away = true;
-                                       break;
-                               case 'l':
-                                       if (user->HasPrivPermission("users/auspex") || ServerInstance->Config->HideWhoisServer.empty())
-                                               opt_local = true;
-                                       break;
-                               case 'f':
-                                       if (user->HasPrivPermission("users/auspex") || ServerInstance->Config->HideWhoisServer.empty())
-                                               opt_far = true;
-                                       break;
-                               case 't':
-                                       opt_time = true;
-                                       break;
-                       }
-               }
-       }
-
-
-       /* who on a channel? */
-       Channel* ch = ServerInstance->FindChan(matchtext);
-
-       if (ch)
-       {
-               if (CanView(ch,user))
-               {
-                       bool inside = ch->HasUser(user);
-
-                       /* who on a channel. */
-                       const UserMembList *cu = ch->GetUsers();
-
-                       for (UserMembCIter i = cu->begin(); i != cu->end(); i++)
-                       {
-                               /* None of this applies if we WHO ourselves */
-                               if (user != i->first)
-                               {
-                                       /* opers only, please */
-                                       if (opt_viewopersonly && !i->first->IsOper())
-                                               continue;
-
-                                       /* If we're not inside the channel, hide +i users */
-                                       if (i->first->IsModeSet(invisiblemode) && !inside && !user->HasPrivPermission("users/auspex"))
-                                               continue;
-                               }
-
-                               SendWhoLine(user, parameters, initial, i->second, i->first, whoresults);
-                       }
-               }
-       }
-       else
-       {
-               /* Match against wildcard of nick, server or host */
-               if (opt_viewopersonly)
-               {
-                       /* Showing only opers */
-                       for (std::list<User*>::iterator i = ServerInstance->Users->all_opers.begin(); i != ServerInstance->Users->all_opers.end(); i++)
-                       {
-                               User* oper = *i;
-
-                               if (whomatch(user, oper, matchtext.c_str()))
-                               {
-                                       if (!user->SharesChannelWith(oper))
-                                       {
-                                               if (usingwildcards && (!oper->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex")))
-                                                       continue;
-                                       }
-
-                                       SendWhoLine(user, parameters, initial, NULL, oper, whoresults);
-                               }
-                       }
-               }
-               else
-               {
-                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
-                       {
-                               if (whomatch(user, i->second, matchtext.c_str()))
-                               {
-                                       if (!user->SharesChannelWith(i->second))
-                                       {
-                                               if (usingwildcards && (i->second->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex")))
-                                                       continue;
-                                       }
-
-                                       SendWhoLine(user, parameters, initial, NULL, i->second, whoresults);
-                               }
-                       }
-               }
-       }
-       /* Send the results out */
-       for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
-               user->WriteServ(*n);
-       user->WriteNumeric(RPL_ENDOFWHO, "%s :End of /WHO list.", *parameters[0].c_str() ? parameters[0].c_str() : "*");
-
-       // Penalize the user a bit for large queries
-       // (add one unit of penalty per 200 results)
-       if (IS_LOCAL(user))
-               IS_LOCAL(user)->CommandFloodPenalty += whoresults.size() * 5;
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandWho)
diff --git a/src/commands/cmd_whois.cpp b/src/commands/cmd_whois.cpp
deleted file mode 100644 (file)
index bd0b624..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-
-/** Handle /WHOIS.
- */
-class CommandWhois : public SplitCommand
-{
-       ChanModeReference secretmode;
-       ChanModeReference privatemode;
-       UserModeReference snomaskmode;
-
-       void SplitChanList(User* source, User* dest, const std::string& cl);
-       void DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle);
-       std::string ChannelList(User* source, User* dest, bool spy);
-
- public:
-       /** Constructor for whois.
-        */
-       CommandWhois(Module* parent)
-               : SplitCommand(parent, "WHOIS", 1)
-               , secretmode(parent, "secret")
-               , privatemode(parent, "private")
-               , snomaskmode(parent, "snomask")
-       {
-               Penalty = 2;
-               syntax = "<nick>{,<nick>}";
-       }
-
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
-       CmdResult HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target);
-};
-
-std::string CommandWhois::ChannelList(User* source, User* dest, bool spy)
-{
-       std::string list;
-
-       for (UCListIter i = dest->chans.begin(); i != dest->chans.end(); i++)
-       {
-               Membership* memb = *i;
-               Channel* c = memb->chan;
-               /* If the target is the sender, neither +p nor +s is set, or
-                * the channel contains the user, it is not a spy channel
-                */
-               if (spy != (source == dest || !(c->IsModeSet(privatemode) || c->IsModeSet(secretmode)) || c->HasUser(source)))
-               {
-                       list.push_back(memb->GetPrefixChar());
-                       list.append(c->name).push_back(' ');
-               }
-       }
-
-       return list;
-}
-
-void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl)
-{
-       std::string line;
-       std::ostringstream prefix;
-       std::string::size_type start, pos;
-
-       prefix << dest->nick << " :";
-       line = prefix.str();
-       int namelen = ServerInstance->Config->ServerName.length() + 6;
-
-       for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
-       {
-               if (line.length() + namelen + pos - start > 510)
-               {
-                       ServerInstance->SendWhoisLine(source, dest, 319, line);
-                       line = prefix.str();
-               }
-
-               line.append(cl.substr(start, pos - start + 1));
-       }
-
-       if (line.length() != prefix.str().length())
-       {
-               ServerInstance->SendWhoisLine(source, dest, 319, line);
-       }
-}
-
-void CommandWhois::DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle)
-{
-       ServerInstance->SendWhoisLine(user, dest, 311, "%s %s %s * :%s", dest->nick.c_str(), dest->ident.c_str(), dest->dhost.c_str(), dest->fullname.c_str());
-       if (user == dest || user->HasPrivPermission("users/auspex"))
-       {
-               ServerInstance->SendWhoisLine(user, dest, 378, "%s :is connecting from %s@%s %s", dest->nick.c_str(), dest->ident.c_str(), dest->host.c_str(), dest->GetIPString().c_str());
-       }
-
-       std::string cl = ChannelList(user, dest, false);
-       const ServerConfig::OperSpyWhoisState state = user->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE;
-
-       if (state == ServerConfig::SPYWHOIS_SINGLEMSG)
-               cl.append(ChannelList(user, dest, true));
-
-       SplitChanList(user, dest, cl);
-
-       if (state == ServerConfig::SPYWHOIS_SPLITMSG)
-       {
-               std::string scl = ChannelList(user, dest, true);
-               if (scl.length())
-               {
-                       ServerInstance->SendWhoisLine(user, dest, 336, "%s :is on private/secret channels:", dest->nick.c_str());
-                       SplitChanList(user, dest, scl);
-               }
-       }
-       if (user != dest && !ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"))
-       {
-               ServerInstance->SendWhoisLine(user, dest, 312, "%s %s :%s", dest->nick.c_str(), ServerInstance->Config->HideWhoisServer.c_str(), ServerInstance->Config->Network.c_str());
-       }
-       else
-       {
-               ServerInstance->SendWhoisLine(user, dest, 312, "%s %s :%s", dest->nick.c_str(), dest->server->GetName().c_str(), dest->server->GetDesc().c_str());
-       }
-
-       if (dest->IsAway())
-       {
-               ServerInstance->SendWhoisLine(user, dest, 301, "%s :%s", dest->nick.c_str(), dest->awaymsg.c_str());
-       }
-
-       if (dest->IsOper())
-       {
-               if (ServerInstance->Config->GenericOper)
-                       ServerInstance->SendWhoisLine(user, dest, 313, "%s :is an IRC operator", dest->nick.c_str());
-               else
-                       ServerInstance->SendWhoisLine(user, dest, 313, "%s :is %s %s on %s", dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper->name[0]) ? "an" : "a"),dest->oper->name.c_str(), ServerInstance->Config->Network.c_str());
-       }
-
-       if (user == dest || user->HasPrivPermission("users/auspex"))
-       {
-               if (dest->IsModeSet(snomaskmode))
-               {
-                       ServerInstance->SendWhoisLine(user, dest, 379, "%s :is using modes +%s %s", dest->nick.c_str(), dest->FormatModes(), snomaskmode->GetUserParameter(dest).c_str());
-               }
-               else
-               {
-                       ServerInstance->SendWhoisLine(user, dest, 379, "%s :is using modes +%s", dest->nick.c_str(), dest->FormatModes());
-               }
-       }
-
-       FOREACH_MOD(OnWhois, (user,dest));
-
-       /*
-        * We only send these if we've been provided them. That is, if hidewhois is turned off, and user is local, or
-        * if remote whois is queried, too. This is to keep the user hidden, and also since you can't reliably tell remote time. -- w00t
-        */
-       if ((idle) || (signon))
-       {
-               ServerInstance->SendWhoisLine(user, dest, 317, "%s %lu %lu :seconds idle, signon time", dest->nick.c_str(), idle, signon);
-       }
-
-       ServerInstance->SendWhoisLine(user, dest, 318, "%s :End of /WHOIS list.", dest->nick.c_str());
-}
-
-CmdResult CommandWhois::HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target)
-{
-       if (parameters.size() < 2)
-               return CMD_FAILURE;
-
-       User* user = ServerInstance->FindUUID(parameters[0]);
-       if (!user)
-               return CMD_FAILURE;
-
-       unsigned long idle = ConvToInt(parameters.back());
-       DoWhois(user, target, target->signon, idle);
-
-       return CMD_SUCCESS;
-}
-
-CmdResult CommandWhois::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user)
-{
-       User *dest;
-       int userindex = 0;
-       unsigned long idle = 0, signon = 0;
-
-       if (CommandParser::LoopCall(user, this, parameters, 0))
-               return CMD_SUCCESS;
-
-       /*
-        * If 2 paramters are specified (/whois nick nick), ignore the first one like spanningtree
-        * does, and use the second one, otherwise, use the only paramter. -- djGrrr
-        */
-       if (parameters.size() > 1)
-               userindex = 1;
-
-       dest = ServerInstance->FindNickOnly(parameters[userindex]);
-
-       if ((dest) && (dest->registered == REG_ALL))
-       {
-               /*
-                * Okay. Umpteenth attempt at doing this, so let's re-comment...
-                * For local users (/w localuser), we show idletime if hidewhois is disabled
-                * For local users (/w localuser localuser), we always show idletime, hence parameters.size() > 1 check.
-                * For remote users (/w remoteuser), we do NOT show idletime
-                * For remote users (/w remoteuser remoteuser), spanningtree will handle calling do_whois, so we can ignore this case.
-                * Thanks to djGrrr for not being impatient while I have a crap day coding. :p -- w00t
-                */
-               LocalUser* localuser = IS_LOCAL(dest);
-               if (localuser && (ServerInstance->Config->HideWhoisServer.empty() || parameters.size() > 1))
-               {
-                       idle = abs((long)((localuser->idle_lastmsg)-ServerInstance->Time()));
-                       signon = dest->signon;
-               }
-
-               DoWhois(user,dest,signon,idle);
-       }
-       else
-       {
-               /* no such nick/channel */
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", !parameters[userindex].empty() ? parameters[userindex].c_str() : "*");
-               user->WriteNumeric(RPL_ENDOFWHOIS, "%s :End of /WHOIS list.", !parameters[userindex].empty() ? parameters[userindex].c_str() : "*");
-               return CMD_FAILURE;
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandWhois)
diff --git a/src/commands/cmd_whowas.cpp b/src/commands/cmd_whowas.cpp
deleted file mode 100644 (file)
index 0a3a994..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "commands/cmd_whowas.h"
-
-CommandWhowas::CommandWhowas( Module* parent)
-       : Command(parent, "WHOWAS", 1)
-       , GroupSize(0), MaxGroups(0), MaxKeep(0)
-{
-       syntax = "<nick>{,<nick>}";
-       Penalty = 2;
-}
-
-CmdResult CommandWhowas::Handle (const std::vector<std::string>& parameters, User* user)
-{
-       /* if whowas disabled in config */
-       if (this->GroupSize == 0 || this->MaxGroups == 0)
-       {
-               user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :This command has been disabled.", name.c_str());
-               return CMD_FAILURE;
-       }
-
-       whowas_users::iterator i = whowas.find(assign(parameters[0]));
-
-       if (i == whowas.end())
-       {
-               user->WriteNumeric(ERR_WASNOSUCHNICK, "%s :There was no such nickname", parameters[0].c_str());
-       }
-       else
-       {
-               whowas_set* grp = i->second;
-               if (!grp->empty())
-               {
-                       for (whowas_set::iterator ux = grp->begin(); ux != grp->end(); ux++)
-                       {
-                               WhoWasGroup* u = *ux;
-
-                               user->WriteNumeric(RPL_WHOWASUSER, "%s %s %s * :%s", parameters[0].c_str(),
-                                       u->ident.c_str(),u->dhost.c_str(),u->gecos.c_str());
-
-                               if (user->HasPrivPermission("users/auspex"))
-                                       user->WriteNumeric(RPL_WHOWASIP, "%s :was connecting from *@%s",
-                                               parameters[0].c_str(), u->host.c_str());
-
-                               std::string signon = InspIRCd::TimeString(u->signon);
-                               bool hide_server = (!ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"));
-                               user->WriteNumeric(RPL_WHOISSERVER, "%s %s :%s", parameters[0].c_str(), (hide_server ? ServerInstance->Config->HideWhoisServer.c_str() : u->server.c_str()), signon.c_str());
-                       }
-               }
-               else
-               {
-                       user->WriteNumeric(ERR_WASNOSUCHNICK, "%s :There was no such nickname", parameters[0].c_str());
-               }
-       }
-
-       user->WriteNumeric(RPL_ENDOFWHOWAS, "%s :End of WHOWAS", parameters[0].c_str());
-       return CMD_SUCCESS;
-}
-
-std::string CommandWhowas::GetStats()
-{
-       int whowas_size = 0;
-       int whowas_bytes = 0;
-       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
-       {
-               whowas_set* n = i->second;
-               whowas_size += n->size();
-               whowas_bytes += (sizeof(whowas_set) + ( sizeof(WhoWasGroup) * n->size() ) );
-       }
-       return "Whowas entries: " +ConvToStr(whowas_size)+" ("+ConvToStr(whowas_bytes)+" bytes)";
-}
-
-void CommandWhowas::AddToWhoWas(User* user)
-{
-       /* if whowas disabled */
-       if (this->GroupSize == 0 || this->MaxGroups == 0)
-       {
-               return;
-       }
-
-       // Insert nick if it doesn't exist
-       // 'first' will point to the newly inserted element or to the existing element with an equivalent key
-       std::pair<whowas_users::iterator, bool> ret = whowas.insert(std::make_pair(irc::string(user->nick.c_str()), static_cast<whowas_set*>(NULL)));
-
-       if (ret.second) // If inserted
-       {
-               // This nick is new, create a list for it and add the first record to it
-               whowas_set* n = new whowas_set;
-               n->push_back(new WhoWasGroup(user));
-               ret.first->second = n;
-
-               // Add this nick to the fifo too
-               whowas_fifo.push_back(std::make_pair(ServerInstance->Time(), ret.first->first));
-
-               if (whowas.size() > this->MaxGroups)
-               {
-                       // Too many nicks, remove the nick which was inserted the longest time ago from both the map and the fifo
-                       whowas_users::iterator it = whowas.find(whowas_fifo.front().second);
-                       if (it != whowas.end())
-                       {
-                               whowas_set* set = it->second;
-                               for (whowas_set::iterator i = set->begin(); i != set->end(); ++i)
-                                       delete *i;
-
-                               delete set;
-                               whowas.erase(it);
-                       }
-                       whowas_fifo.pop_front();
-               }
-       }
-       else
-       {
-               // We've met this nick before, add a new record to the list
-               whowas_set* set = ret.first->second;
-               set->push_back(new WhoWasGroup(user));
-
-               // If there are too many records for this nick, remove the oldest (front)
-               if (set->size() > this->GroupSize)
-               {
-                       delete set->front();
-                       set->pop_front();
-               }
-       }
-}
-
-/* on rehash, refactor maps according to new conf values */
-void CommandWhowas::Prune()
-{
-       time_t min = ServerInstance->Time() - this->MaxKeep;
-
-       /* first cut the list to new size (maxgroups) and also prune entries that are timed out. */
-       while (!whowas_fifo.empty())
-       {
-               if ((whowas_fifo.size() > this->MaxGroups) || (whowas_fifo.front().first < min))
-               {
-                       whowas_users::iterator iter = whowas.find(whowas_fifo.front().second);
-
-                       /* hopefully redundant integrity check, but added while debugging r6216 */
-                       if (iter == whowas.end())
-                       {
-                               /* this should never happen, if it does maps are corrupt */
-                               ServerInstance->Logs->Log("WHOWAS", LOG_DEFAULT, "BUG: Whowas maps got corrupted! (1)");
-                               return;
-                       }
-
-                       whowas_set* set = iter->second;
-                       for (whowas_set::iterator i = set->begin(); i != set->end(); ++i)
-                               delete *i;
-
-                       delete set;
-                       whowas.erase(iter);
-                       whowas_fifo.pop_front();
-               }
-               else
-                       break;
-       }
-
-       /* Then cut the whowas sets to new size (groupsize) */
-       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
-       {
-               whowas_set* n = i->second;
-               while (n->size() > this->GroupSize)
-               {
-                       delete n->front();
-                       n->pop_front();
-               }
-       }
-}
-
-/* call maintain once an hour to remove expired nicks */
-void CommandWhowas::Maintain()
-{
-       time_t min = ServerInstance->Time() - this->MaxKeep;
-       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
-       {
-               whowas_set* set = i->second;
-               while (!set->empty() && set->front()->signon < min)
-               {
-                       delete set->front();
-                       set->pop_front();
-               }
-       }
-}
-
-CommandWhowas::~CommandWhowas()
-{
-       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
-       {
-               whowas_set* set = i->second;
-               for (whowas_set::iterator j = set->begin(); j != set->end(); ++j)
-                       delete *j;
-
-               delete set;
-       }
-}
-
-WhoWasGroup::WhoWasGroup(User* user) : host(user->host), dhost(user->dhost), ident(user->ident),
-       server(user->server->GetName()), gecos(user->fullname), signon(user->signon)
-{
-}
-
-class ModuleWhoWas : public Module
-{
-       CommandWhowas cmd;
-
- public:
-       ModuleWhoWas() : cmd(this)
-       {
-       }
-
-       void OnGarbageCollect()
-       {
-               // Remove all entries older than MaxKeep
-               cmd.Maintain();
-       }
-
-       void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
-       {
-               cmd.AddToWhoWas(user);
-       }
-
-       ModResult OnStats(char symbol, User* user, string_list &results)
-       {
-               if (symbol == 'z')
-                       results.push_back("249 "+user->nick+" :"+cmd.GetStats());
-
-               return MOD_RES_PASSTHRU;
-       }
-
-       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
-       {
-               ConfigTag* tag = ServerInstance->Config->ConfValue("whowas");
-               unsigned int NewGroupSize = tag->getInt("groupsize", 10, 0, 10000);
-               unsigned int NewMaxGroups = tag->getInt("maxgroups", 10240, 0, 1000000);
-               unsigned int NewMaxKeep = tag->getDuration("maxkeep", 3600, 3600);
-
-               if ((NewGroupSize == cmd.GroupSize) && (NewMaxGroups == cmd.MaxGroups) && (NewMaxKeep == cmd.MaxKeep))
-                       return;
-
-               cmd.GroupSize = NewGroupSize;
-               cmd.MaxGroups = NewMaxGroups;
-               cmd.MaxKeep = NewMaxKeep;
-               cmd.Prune();
-       }
-
-       Version GetVersion()
-       {
-               return Version("WHOWAS", VF_VENDOR);
-       }
-};
-
-MODULE_INIT(ModuleWhoWas)
diff --git a/src/commands/cmd_zline.cpp b/src/commands/cmd_zline.cpp
deleted file mode 100644 (file)
index eda5b2a..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * InspIRCd -- Internet Relay Chat Daemon
- *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2009 Matt Smith <dz@inspircd.org>
- *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
- *
- * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include "inspircd.h"
-#include "xline.h"
-/** Handle /ZLINE.
- */
-class CommandZline : public Command
-{
- public:
-       /** Constructor for zline.
-        */
-       CommandZline ( Module* parent) : Command(parent,"ZLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ipmask> [<duration> :<reason>]"; }
-       /** Handle command.
-        * @param parameters The parameters to the command
-        * @param user The user issuing the command
-        * @return A value from CmdResult to indicate command success or failure.
-        */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
-};
-
-CmdResult CommandZline::Handle (const std::vector<std::string>& parameters, User *user)
-{
-       std::string target = parameters[0];
-
-       if (parameters.size() >= 3)
-       {
-               if (target.find('!') != std::string::npos)
-               {
-                       user->WriteNotice("*** You cannot include a nickname in a zline, a zline must ban only an IP mask");
-                       return CMD_FAILURE;
-               }
-
-               User *u = ServerInstance->FindNick(target);
-
-               if ((u) && (u->registered == REG_ALL))
-               {
-                       target = u->GetIPString();
-               }
-
-               const char* ipaddr = target.c_str();
-
-               if (strchr(ipaddr,'@'))
-               {
-                       while (*ipaddr != '@')
-                               ipaddr++;
-                       ipaddr++;
-               }
-
-               if (ServerInstance->IPMatchesEveryone(ipaddr,user))
-                       return CMD_FAILURE;
-
-               unsigned long duration = InspIRCd::Duration(parameters[1]);
-               ZLine* zl = new ZLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ipaddr);
-               if (ServerInstance->XLines->AddLine(zl,user))
-               {
-                       if (!duration)
-                       {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent Z-line for %s: %s", user->nick.c_str(), ipaddr, parameters[2].c_str());
-                       }
-                       else
-                       {
-                               time_t c_requires_crap = duration + ServerInstance->Time();
-                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed Z-line for %s, expires on %s: %s",user->nick.c_str(),ipaddr,
-                                               timestr.c_str(), parameters[2].c_str());
-                       }
-                       ServerInstance->XLines->ApplyLines();
-               }
-               else
-               {
-                       delete zl;
-                       user->WriteNotice("*** Z-Line for " + std::string(ipaddr) + " already exists");
-               }
-       }
-       else
-       {
-               if (ServerInstance->XLines->DelLine(target.c_str(),"Z",user))
-               {
-                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed Z-line on %s",user->nick.c_str(),target.c_str());
-               }
-               else
-               {
-                       user->WriteNotice("*** Z-Line " + target + " not found in list, try /stats Z.");
-                       return CMD_FAILURE;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-COMMAND_INIT(CommandZline)
diff --git a/src/coremods/core_channel/cmd_invite.cpp b/src/coremods/core_channel/cmd_invite.cpp
new file mode 100644 (file)
index 0000000..25afc07
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /INVITE.
+ */
+class CommandInvite : public Command
+{
+ public:
+       /** Constructor for invite.
+        */
+       CommandInvite ( Module* parent) : Command(parent,"INVITE", 0, 0) { Penalty = 4; syntax = "[<nick> <channel>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+/** Handle /INVITE
+ */
+CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       ModResult MOD_RESULT;
+
+       if (parameters.size() == 2 || parameters.size() == 3)
+       {
+               User* u;
+               if (IS_LOCAL(user))
+                       u = ServerInstance->FindNickOnly(parameters[0]);
+               else
+                       u = ServerInstance->FindNick(parameters[0]);
+
+               Channel* c = ServerInstance->FindChan(parameters[1]);
+               time_t timeout = 0;
+               if (parameters.size() == 3)
+               {
+                       if (IS_LOCAL(user))
+                               timeout = ServerInstance->Time() + InspIRCd::Duration(parameters[2]);
+                       else
+                               timeout = ConvToInt(parameters[2]);
+               }
+
+               if ((!c) || (!u) || (u->registered != REG_ALL))
+               {
+                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c ? parameters[0].c_str() : parameters[1].c_str());
+                       return CMD_FAILURE;
+               }
+
+               if ((IS_LOCAL(user)) && (!c->HasUser(user)))
+               {
+                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", c->name.c_str());
+                       return CMD_FAILURE;
+               }
+
+               if (c->HasUser(u))
+               {
+                       user->WriteNumeric(ERR_USERONCHANNEL, "%s %s :is already on channel", u->nick.c_str(), c->name.c_str());
+                       return CMD_FAILURE;
+               }
+
+               FIRST_MOD_RESULT(OnUserPreInvite, MOD_RESULT, (user,u,c,timeout));
+
+               if (MOD_RESULT == MOD_RES_DENY)
+               {
+                       return CMD_FAILURE;
+               }
+               else if (MOD_RESULT == MOD_RES_PASSTHRU)
+               {
+                       if (IS_LOCAL(user))
+                       {
+                               unsigned int rank = c->GetPrefixValue(user);
+                               if (rank < HALFOP_VALUE)
+                               {
+                                       // Check whether halfop mode is available and phrase error message accordingly
+                                       ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
+                                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You must be a channel %soperator",
+                                               c->name.c_str(), (mh && mh->name == "halfop" ? "half-" : ""));
+                                       return CMD_FAILURE;
+                               }
+                       }
+               }
+
+               if (IS_LOCAL(u))
+               {
+                       Invitation::Create(c, IS_LOCAL(u), timeout);
+                       u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
+               }
+
+               if (IS_LOCAL(user))
+                       user->WriteNumeric(RPL_INVITING, "%s %s", u->nick.c_str(),c->name.c_str());
+
+               if (ServerInstance->Config->AnnounceInvites != ServerConfig::INVITE_ANNOUNCE_NONE)
+               {
+                       char prefix;
+                       switch (ServerInstance->Config->AnnounceInvites)
+                       {
+                               case ServerConfig::INVITE_ANNOUNCE_OPS:
+                               {
+                                       prefix = '@';
+                                       break;
+                               }
+                               case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
+                               {
+                                       PrefixMode* mh = ServerInstance->Modes->FindPrefixMode('h');
+                                       prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
+                                       break;
+                               }
+                               default:
+                               {
+                                       prefix = 0;
+                                       break;
+                               }
+                       }
+                       c->WriteAllExceptSender(user, true, prefix, "NOTICE %s :*** %s invited %s into the channel", c->name.c_str(), user->nick.c_str(), u->nick.c_str());
+               }
+               FOREACH_MOD(OnUserInvite, (user,u,c,timeout));
+       }
+       else if (IS_LOCAL(user))
+       {
+               // pinched from ircu - invite with not enough parameters shows channels
+               // youve been invited to but haven't joined yet.
+               InviteList& il = IS_LOCAL(user)->GetInviteList();
+               for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i)
+               {
+                       user->WriteNumeric(RPL_INVITELIST, ":%s", (*i)->chan->name.c_str());
+               }
+               user->WriteNumeric(RPL_ENDOFINVITELIST, ":End of INVITE list");
+       }
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandInvite)
diff --git a/src/coremods/core_channel/cmd_join.cpp b/src/coremods/core_channel/cmd_join.cpp
new file mode 100644 (file)
index 0000000..1e6e515
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /JOIN.
+ */
+class CommandJoin : public SplitCommand
+{
+ public:
+       /** Constructor for join.
+        */
+       CommandJoin(Module* parent)
+               : SplitCommand(parent, "JOIN", 1, 2)
+       {
+               syntax = "<channel>{,<channel>} {<key>{,<key>}}";
+               Penalty = 2;
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
+};
+
+/** Handle /JOIN
+ */
+CmdResult CommandJoin::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
+{
+       if (parameters.size() > 1)
+       {
+               if (CommandParser::LoopCall(user, this, parameters, 0, 1, false))
+                       return CMD_SUCCESS;
+
+               if (ServerInstance->IsChannel(parameters[0]))
+               {
+                       Channel::JoinUser(user, parameters[0], false, parameters[1]);
+                       return CMD_SUCCESS;
+               }
+       }
+       else
+       {
+               if (CommandParser::LoopCall(user, this, parameters, 0, -1, false))
+                       return CMD_SUCCESS;
+
+               if (ServerInstance->IsChannel(parameters[0]))
+               {
+                       Channel::JoinUser(user, parameters[0]);
+                       return CMD_SUCCESS;
+               }
+       }
+
+       user->WriteNumeric(ERR_NOSUCHCHANNEL, "%s :Invalid channel name", parameters[0].c_str());
+       return CMD_FAILURE;
+}
+
+COMMAND_INIT(CommandJoin)
diff --git a/src/coremods/core_channel/cmd_kick.cpp b/src/coremods/core_channel/cmd_kick.cpp
new file mode 100644 (file)
index 0000000..01f2039
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /KICK.
+ */
+class CommandKick : public Command
+{
+ public:
+       /** Constructor for kick.
+        */
+       CommandKick ( Module* parent) : Command(parent,"KICK",2,3) { syntax = "<channel> <nick>{,<nick>} [<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+/** Handle /KICK
+ */
+CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string reason;
+       Channel* c = ServerInstance->FindChan(parameters[0]);
+       User* u;
+
+       if (CommandParser::LoopCall(user, this, parameters, 1))
+               return CMD_SUCCESS;
+
+       if (IS_LOCAL(user))
+               u = ServerInstance->FindNickOnly(parameters[1]);
+       else
+               u = ServerInstance->FindNick(parameters[1]);
+
+       if (!u || !c)
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", u ? parameters[0].c_str() : parameters[1].c_str());
+               return CMD_FAILURE;
+       }
+
+       Membership* srcmemb = NULL;
+       if (IS_LOCAL(user))
+       {
+               srcmemb = c->GetUser(user);
+               if (!srcmemb)
+               {
+                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", parameters[0].c_str());
+                       return CMD_FAILURE;
+               }
+
+               if (u->server->IsULine())
+               {
+                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You may not kick a u-lined client", c->name.c_str());
+                       return CMD_FAILURE;
+               }
+       }
+
+       if (parameters.size() > 2)
+       {
+               reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick);
+       }
+       else
+       {
+               reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick);
+       }
+
+       c->KickUser(user, u, reason, srcmemb);
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandKick)
diff --git a/src/coremods/core_channel/cmd_names.cpp b/src/coremods/core_channel/cmd_names.cpp
new file mode 100644 (file)
index 0000000..8c8bc58
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /NAMES.
+ */
+class CommandNames : public Command
+{
+       ChanModeReference secretmode;
+
+ public:
+       /** Constructor for names.
+        */
+       CommandNames(Module* parent)
+               : Command(parent, "NAMES", 0, 0)
+               , secretmode(parent, "secret")
+       {
+               syntax = "{<channel>{,<channel>}}";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /NAMES
+ */
+CmdResult CommandNames::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       Channel* c;
+
+       if (!parameters.size())
+       {
+               user->WriteNumeric(RPL_ENDOFNAMES, "* :End of /NAMES list.");
+               return CMD_SUCCESS;
+       }
+
+       if (CommandParser::LoopCall(user, this, parameters, 0))
+               return CMD_SUCCESS;
+
+       c = ServerInstance->FindChan(parameters[0]);
+       if (c)
+       {
+               if ((c->IsModeSet(secretmode)) && (!c->HasUser(user)))
+               {
+                     user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c->name.c_str());
+                     return CMD_FAILURE;
+               }
+               c->UserList(user);
+       }
+       else
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandNames)
diff --git a/src/coremods/core_channel/cmd_topic.cpp b/src/coremods/core_channel/cmd_topic.cpp
new file mode 100644 (file)
index 0000000..2b0f81f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /TOPIC.
+ */
+class CommandTopic : public SplitCommand
+{
+       ChanModeReference secretmode;
+       ChanModeReference topiclockmode;
+
+ public:
+       /** Constructor for topic.
+        */
+       CommandTopic(Module* parent)
+               : SplitCommand(parent, "TOPIC", 1, 2)
+               , secretmode(parent, "secret")
+               , topiclockmode(parent, "topiclock")
+       {
+               syntax = "<channel> [<topic>]";
+               Penalty = 2;
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
+};
+
+CmdResult CommandTopic::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user)
+{
+       Channel* c = ServerInstance->FindChan(parameters[0]);
+       if (!c)
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       if (parameters.size() == 1)
+       {
+               if ((c->IsModeSet(secretmode)) && (!c->HasUser(user)))
+               {
+                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c->name.c_str());
+                       return CMD_FAILURE;
+               }
+
+               if (c->topic.length())
+               {
+                       user->WriteNumeric(RPL_TOPIC, "%s :%s", c->name.c_str(), c->topic.c_str());
+                       user->WriteNumeric(RPL_TOPICTIME, "%s %s %lu", c->name.c_str(), c->setby.c_str(), (unsigned long)c->topicset);
+               }
+               else
+               {
+                       user->WriteNumeric(RPL_NOTOPICSET, "%s :No topic is set.", c->name.c_str());
+               }
+               return CMD_SUCCESS;
+       }
+
+       std::string t = parameters[1]; // needed, in case a module wants to change it
+       ModResult res;
+       FIRST_MOD_RESULT(OnPreTopicChange, res, (user,c,t));
+
+       if (res == MOD_RES_DENY)
+               return CMD_FAILURE;
+       if (res != MOD_RES_ALLOW)
+       {
+               if (!c->HasUser(user))
+               {
+                       user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", c->name.c_str());
+                       return CMD_FAILURE;
+               }
+               if (c->IsModeSet(topiclockmode) && !ServerInstance->OnCheckExemption(user, c, "topiclock").check(c->GetPrefixValue(user) >= HALFOP_VALUE))
+               {
+                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You do not have access to change the topic on this channel", c->name.c_str());
+                       return CMD_FAILURE;
+               }
+       }
+
+       c->SetTopic(user, t);
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandTopic)
diff --git a/src/coremods/core_connect.cpp b/src/coremods/core_connect.cpp
new file mode 100644 (file)
index 0000000..59e7487
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /CONNECT.
+ */
+class CommandConnect : public Command
+{
+ public:
+       /** Constructor for connect.
+        */
+       CommandConnect ( Module* parent) : Command(parent,"CONNECT",1) { flags_needed = 'o'; syntax = "<servername> [<remote-server>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/*
+ * This is handled by the server linking module, if necessary. Do not remove this stub.
+ */
+
+/** Handle /CONNECT
+ */
+CmdResult CommandConnect::Handle (const std::vector<std::string>&, User *user)
+{
+       user->WriteServ( "NOTICE %s :Look into loading a linking module (like m_spanningtree) if you want this to do anything useful.", user->nick.c_str());
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandConnect)
diff --git a/src/coremods/core_dns.cpp b/src/coremods/core_dns.cpp
new file mode 100644 (file)
index 0000000..7b93c7b
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Adam <Adam@anope.org>
+ *   Copyright (C) 2003-2013 Anope Team <team@anope.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "inspircd.h"
+#include "modules/dns.h"
+#include <iostream>
+#include <fstream>
+
+#ifdef _WIN32
+#include <Iphlpapi.h>
+#pragma comment(lib, "Iphlpapi.lib")
+#endif
+
+using namespace DNS;
+
+/** A full packet sent or recieved to/from the nameserver
+ */
+class Packet : public Query
+{
+       void PackName(unsigned char* output, unsigned short output_size, unsigned short& pos, const std::string& name)
+       {
+               if (pos + name.length() + 2 > output_size)
+                       throw Exception("Unable to pack name");
+
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Packing name " + name);
+
+               irc::sepstream sep(name, '.');
+               std::string token;
+
+               while (sep.GetToken(token))
+               {
+                       output[pos++] = token.length();
+                       memcpy(&output[pos], token.data(), token.length());
+                       pos += token.length();
+               }
+
+               output[pos++] = 0;
+       }
+
+       std::string UnpackName(const unsigned char* input, unsigned short input_size, unsigned short& pos)
+       {
+               std::string name;
+               unsigned short pos_ptr = pos, lowest_ptr = input_size;
+               bool compressed = false;
+
+               if (pos_ptr >= input_size)
+                       throw Exception("Unable to unpack name - no input");
+
+               while (input[pos_ptr] > 0)
+               {
+                       unsigned short offset = input[pos_ptr];
+
+                       if (offset & POINTER)
+                       {
+                               if ((offset & POINTER) != POINTER)
+                                       throw Exception("Unable to unpack name - bogus compression header");
+                               if (pos_ptr + 1 >= input_size)
+                                       throw Exception("Unable to unpack name - bogus compression header");
+
+                               /* Place pos at the second byte of the first (farthest) compression pointer */
+                               if (compressed == false)
+                               {
+                                       ++pos;
+                                       compressed = true;
+                               }
+
+                               pos_ptr = (offset & LABEL) << 8 | input[pos_ptr + 1];
+
+                               /* Pointers can only go back */
+                               if (pos_ptr >= lowest_ptr)
+                                       throw Exception("Unable to unpack name - bogus compression pointer");
+                               lowest_ptr = pos_ptr;
+                       }
+                       else
+                       {
+                               if (pos_ptr + offset + 1 >= input_size)
+                                       throw Exception("Unable to unpack name - offset too large");
+                               if (!name.empty())
+                                       name += ".";
+                               for (unsigned i = 1; i <= offset; ++i)
+                                       name += input[pos_ptr + i];
+
+                               pos_ptr += offset + 1;
+                               if (compressed == false)
+                                       /* Move up pos */
+                                       pos = pos_ptr;
+                       }
+               }
+
+               /* +1 pos either to one byte after the compression pointer or one byte after the ending \0 */
+               ++pos;
+
+               if (name.empty())
+                       throw Exception("Unable to unpack name - no name");
+
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Unpack name " + name);
+
+               return name;
+       }
+
+       Question UnpackQuestion(const unsigned char* input, unsigned short input_size, unsigned short& pos)
+       {
+               Question question;
+
+               question.name = this->UnpackName(input, input_size, pos);
+
+               if (pos + 4 > input_size)
+                       throw Exception("Unable to unpack question");
+
+               question.type = static_cast<QueryType>(input[pos] << 8 | input[pos + 1]);
+               pos += 2;
+
+               question.qclass = input[pos] << 8 | input[pos + 1];
+               pos += 2;
+
+               return question;
+       }
+
+       ResourceRecord UnpackResourceRecord(const unsigned char* input, unsigned short input_size, unsigned short& pos)
+       {
+               ResourceRecord record = static_cast<ResourceRecord>(this->UnpackQuestion(input, input_size, pos));
+
+               if (pos + 6 > input_size)
+                       throw Exception("Unable to unpack resource record");
+
+               record.ttl = (input[pos] << 24) | (input[pos + 1] << 16) | (input[pos + 2] << 8) | input[pos + 3];
+               pos += 4;
+
+               //record.rdlength = input[pos] << 8 | input[pos + 1];
+               pos += 2;
+
+               switch (record.type)
+               {
+                       case QUERY_A:
+                       {
+                               if (pos + 4 > input_size)
+                                       throw Exception("Unable to unpack resource record");
+
+                               irc::sockets::sockaddrs addrs;
+                               memset(&addrs, 0, sizeof(addrs));
+
+                               addrs.in4.sin_family = AF_INET;
+                               addrs.in4.sin_addr.s_addr = input[pos] | (input[pos + 1] << 8) | (input[pos + 2] << 16)  | (input[pos + 3] << 24);
+                               pos += 4;
+
+                               record.rdata = addrs.addr();
+                               break;
+                       }
+                       case QUERY_AAAA:
+                       {
+                               if (pos + 16 > input_size)
+                                       throw Exception("Unable to unpack resource record");
+
+                               irc::sockets::sockaddrs addrs;
+                               memset(&addrs, 0, sizeof(addrs));
+
+                               addrs.in6.sin6_family = AF_INET6;
+                               for (int j = 0; j < 16; ++j)
+                                       addrs.in6.sin6_addr.s6_addr[j] = input[pos + j];
+                               pos += 16;
+
+                               record.rdata = addrs.addr();
+
+                               break;
+                       }
+                       case QUERY_CNAME:
+                       case QUERY_PTR:
+                       {
+                               record.rdata = this->UnpackName(input, input_size, pos);
+                               break;
+                       }
+                       default:
+                               break;
+               }
+
+               if (!record.name.empty() && !record.rdata.empty())
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: " + record.name + " -> " + record.rdata);
+
+               return record;
+       }
+
+ public:
+       static const int POINTER = 0xC0;
+       static const int LABEL = 0x3F;
+       static const int HEADER_LENGTH = 12;
+
+       /* ID for this packet */
+       unsigned short id;
+       /* Flags on the packet */
+       unsigned short flags;
+
+       Packet() : id(0), flags(0)
+       {
+       }
+
+       void Fill(const unsigned char* input, const unsigned short len)
+       {
+               if (len < HEADER_LENGTH)
+                       throw Exception("Unable to fill packet");
+
+               unsigned short packet_pos = 0;
+
+               this->id = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               if (this->id >= MAX_REQUEST_ID)
+                       throw Exception("Query ID too large?");
+
+               this->flags = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               unsigned short qdcount = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               unsigned short ancount = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               unsigned short nscount = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               unsigned short arcount = (input[packet_pos] << 8) | input[packet_pos + 1];
+               packet_pos += 2;
+
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: qdcount: " + ConvToStr(qdcount) + " ancount: " + ConvToStr(ancount) + " nscount: " + ConvToStr(nscount) + " arcount: " + ConvToStr(arcount));
+
+               for (unsigned i = 0; i < qdcount; ++i)
+                       this->questions.push_back(this->UnpackQuestion(input, len, packet_pos));
+
+               for (unsigned i = 0; i < ancount; ++i)
+                       this->answers.push_back(this->UnpackResourceRecord(input, len, packet_pos));
+       }
+
+       unsigned short Pack(unsigned char* output, unsigned short output_size)
+       {
+               if (output_size < HEADER_LENGTH)
+                       throw Exception("Unable to pack packet");
+
+               unsigned short pos = 0;
+
+               output[pos++] = this->id >> 8;
+               output[pos++] = this->id & 0xFF;
+               output[pos++] = this->flags >> 8;
+               output[pos++] = this->flags & 0xFF;
+               output[pos++] = this->questions.size() >> 8;
+               output[pos++] = this->questions.size() & 0xFF;
+               output[pos++] = this->answers.size() >> 8;
+               output[pos++] = this->answers.size() & 0xFF;
+               output[pos++] = 0;
+               output[pos++] = 0;
+               output[pos++] = 0;
+               output[pos++] = 0;
+
+               for (unsigned i = 0; i < this->questions.size(); ++i)
+               {
+                       Question& q = this->questions[i];
+
+                       if (q.type == QUERY_PTR)
+                       {
+                               irc::sockets::sockaddrs ip;
+                               irc::sockets::aptosa(q.name, 0, ip);
+
+                               if (q.name.find(':') != std::string::npos)
+                               {
+                                       static const char* const hex = "0123456789abcdef";
+                                       char reverse_ip[128];
+                                       unsigned reverse_ip_count = 0;
+                                       for (int j = 15; j >= 0; --j)
+                                       {
+                                               reverse_ip[reverse_ip_count++] = hex[ip.in6.sin6_addr.s6_addr[j] & 0xF];
+                                               reverse_ip[reverse_ip_count++] = '.';
+                                               reverse_ip[reverse_ip_count++] = hex[ip.in6.sin6_addr.s6_addr[j] >> 4];
+                                               reverse_ip[reverse_ip_count++] = '.';
+                                       }
+                                       reverse_ip[reverse_ip_count++] = 0;
+
+                                       q.name = reverse_ip;
+                                       q.name += "ip6.arpa";
+                               }
+                               else
+                               {
+                                       unsigned long forward = ip.in4.sin_addr.s_addr;
+                                       ip.in4.sin_addr.s_addr = forward << 24 | (forward & 0xFF00) << 8 | (forward & 0xFF0000) >> 8 | forward >> 24;
+
+                                       q.name = ip.addr() + ".in-addr.arpa";
+                               }
+                       }
+
+                       this->PackName(output, output_size, pos, q.name);
+
+                       if (pos + 4 >= output_size)
+                               throw Exception("Unable to pack packet");
+
+                       short s = htons(q.type);
+                       memcpy(&output[pos], &s, 2);
+                       pos += 2;
+
+                       s = htons(q.qclass);
+                       memcpy(&output[pos], &s, 2);
+                       pos += 2;
+               }
+
+               for (unsigned int i = 0; i < answers.size(); i++)
+               {
+                       ResourceRecord& rr = answers[i];
+
+                       this->PackName(output, output_size, pos, rr.name);
+
+                       if (pos + 8 >= output_size)
+                               throw Exception("Unable to pack packet");
+
+                       short s = htons(rr.type);
+                       memcpy(&output[pos], &s, 2);
+                       pos += 2;
+
+                       s = htons(rr.qclass);
+                       memcpy(&output[pos], &s, 2);
+                       pos += 2;
+
+                       long l = htonl(rr.ttl);
+                       memcpy(&output[pos], &l, 4);
+                       pos += 4;
+
+                       switch (rr.type)
+                       {
+                               case QUERY_A:
+                               {
+                                       if (pos + 6 > output_size)
+                                               throw Exception("Unable to pack packet");
+
+                                       irc::sockets::sockaddrs a;
+                                       irc::sockets::aptosa(rr.rdata, 0, a);
+
+                                       s = htons(4);
+                                       memcpy(&output[pos], &s, 2);
+                                       pos += 2;
+
+                                       memcpy(&output[pos], &a.in4.sin_addr, 4);
+                                       pos += 4;
+                                       break;
+                               }
+                               case QUERY_AAAA:
+                               {
+                                       if (pos + 18 > output_size)
+                                               throw Exception("Unable to pack packet");
+
+                                       irc::sockets::sockaddrs a;
+                                       irc::sockets::aptosa(rr.rdata, 0, a);
+
+                                       s = htons(16);
+                                       memcpy(&output[pos], &s, 2);
+                                       pos += 2;
+
+                                       memcpy(&output[pos], &a.in6.sin6_addr, 16);
+                                       pos += 16;
+                                       break;
+                               }
+                               case QUERY_CNAME:
+                               case QUERY_PTR:
+                               {
+                                       if (pos + 2 >= output_size)
+                                               throw Exception("Unable to pack packet");
+
+                                       unsigned short packet_pos_save = pos;
+                                       pos += 2;
+
+                                       this->PackName(output, output_size, pos, rr.rdata);
+
+                                       s = htons(pos - packet_pos_save - 2);
+                                       memcpy(&output[packet_pos_save], &s, 2);
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
+               }
+
+               return pos;
+       }
+};
+
+class MyManager : public Manager, public Timer, public EventHandler
+{
+       typedef TR1NS::unordered_map<Question, Query, Question::hash> cache_map;
+       cache_map cache;
+
+       irc::sockets::sockaddrs myserver;
+
+       static bool IsExpired(const Query& record, time_t now = ServerInstance->Time())
+       {
+               const ResourceRecord& req = record.answers[0];
+               return (req.created + static_cast<time_t>(req.ttl) < now);
+       }
+
+       /** Check the DNS cache to see if request can be handled by a cached result
+        * @return true if a cached result was found.
+        */
+       bool CheckCache(DNS::Request* req, const DNS::Question& question)
+       {
+               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: cache: Checking cache for " + question.name);
+
+               cache_map::iterator it = this->cache.find(question);
+               if (it == this->cache.end())
+                       return false;
+
+               Query& record = it->second;
+               if (IsExpired(record))
+               {
+                       this->cache.erase(it);
+                       return false;
+               }
+
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: Using cached result for " + question.name);
+               record.cached = true;
+               req->OnLookupComplete(&record);
+               return true;
+       }
+
+       /** Add a record to the dns cache
+        * @param r The record
+        */
+       void AddCache(Query& r)
+       {
+               const ResourceRecord& rr = r.answers[0];
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: added cache for " + rr.name + " -> " + rr.rdata + " ttl: " + ConvToStr(rr.ttl));
+               this->cache[r.questions[0]] = r;
+       }
+
+ public:
+       DNS::Request* requests[MAX_REQUEST_ID];
+
+       MyManager(Module* c) : Manager(c), Timer(3600, ServerInstance->Time(), true)
+       {
+               for (int i = 0; i < MAX_REQUEST_ID; ++i)
+                       requests[i] = NULL;
+               ServerInstance->Timers->AddTimer(this);
+       }
+
+       ~MyManager()
+       {
+               for (int i = 0; i < MAX_REQUEST_ID; ++i)
+               {
+                       DNS::Request* request = requests[i];
+                       if (!request)
+                               continue;
+
+                       Query rr(*request);
+                       rr.error = ERROR_UNKNOWN;
+                       request->OnError(&rr);
+
+                       delete request;
+               }
+       }
+
+       void Process(DNS::Request* req)
+       {
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Processing request to lookup " + req->name + " of type " + ConvToStr(req->type) + " to " + this->myserver.addr());
+
+               /* Create an id */
+               unsigned int tries = 0;
+               do
+               {
+                       req->id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID);
+
+                       if (++tries == DNS::MAX_REQUEST_ID*5)
+                       {
+                               // If we couldn't find an empty slot this many times, do a sequential scan as a last
+                               // resort. If an empty slot is found that way, go on, otherwise throw an exception
+                               req->id = 0;
+                               for (int i = 1; i < DNS::MAX_REQUEST_ID; i++)
+                               {
+                                       if (!this->requests[i])
+                                       {
+                                               req->id = i;
+                                               break;
+                                       }
+                               }
+
+                               if (req->id == 0)
+                                       throw Exception("DNS: All ids are in use");
+
+                               break;
+                       }
+               }
+               while (!req->id || this->requests[req->id]);
+
+               this->requests[req->id] = req;
+
+               Packet p;
+               p.flags = QUERYFLAGS_RD;
+               p.id = req->id;
+               p.questions.push_back(*req);
+
+               unsigned char buffer[524];
+               unsigned short len = p.Pack(buffer, sizeof(buffer));
+
+               /* Note that calling Pack() above can actually change the contents of p.questions[0].name, if the query is a PTR,
+                * to contain the value that would be in the DNS cache, which is why this is here.
+                */
+               if (req->use_cache && this->CheckCache(req, p.questions[0]))
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Using cached result");
+                       delete req;
+                       return;
+               }
+
+               if (SocketEngine::SendTo(this, buffer, len, 0, &this->myserver.sa, this->myserver.sa_size()) != len)
+                       throw Exception("DNS: Unable to send query");
+       }
+
+       void RemoveRequest(DNS::Request* req)
+       {
+               this->requests[req->id] = NULL;
+       }
+
+       std::string GetErrorStr(Error e)
+       {
+               switch (e)
+               {
+                       case ERROR_UNLOADED:
+                               return "Module is unloading";
+                       case ERROR_TIMEDOUT:
+                               return "Request timed out";
+                       case ERROR_NOT_AN_ANSWER:
+                       case ERROR_NONSTANDARD_QUERY:
+                       case ERROR_FORMAT_ERROR:
+                               return "Malformed answer";
+                       case ERROR_SERVER_FAILURE:
+                       case ERROR_NOT_IMPLEMENTED:
+                       case ERROR_REFUSED:
+                       case ERROR_INVALIDTYPE:
+                               return "Nameserver failure";
+                       case ERROR_DOMAIN_NOT_FOUND:
+                       case ERROR_NO_RECORDS:
+                               return "Domain not found";
+                       case ERROR_NONE:
+                       case ERROR_UNKNOWN:
+                       default:
+                               return "Unknown error";
+               }
+       }
+
+       void HandleEvent(EventType et, int)
+       {
+               if (et == EVENT_ERROR)
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: UDP socket got an error event");
+                       return;
+               }
+
+               unsigned char buffer[524];
+               irc::sockets::sockaddrs from;
+               socklen_t x = sizeof(from);
+
+               int length = SocketEngine::RecvFrom(this, buffer, sizeof(buffer), 0, &from.sa, &x);
+
+               if (length < Packet::HEADER_LENGTH)
+                       return;
+
+               Packet recv_packet;
+
+               try
+               {
+                       recv_packet.Fill(buffer, length);
+               }
+               catch (Exception& ex)
+               {
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, ex.GetReason());
+                       return;
+               }
+
+               if (myserver != from)
+               {
+                       std::string server1 = from.str();
+                       std::string server2 = myserver.str();
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Got a result from the wrong server! Bad NAT or DNS forging attempt? '%s' != '%s'",
+                               server1.c_str(), server2.c_str());
+                       return;
+               }
+
+               DNS::Request* request = this->requests[recv_packet.id];
+               if (request == NULL)
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Received an answer for something we didn't request");
+                       return;
+               }
+
+               if (recv_packet.flags & QUERYFLAGS_OPCODE)
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Received a nonstandard query");
+                       ServerInstance->stats->statsDnsBad++;
+                       recv_packet.error = ERROR_NONSTANDARD_QUERY;
+                       request->OnError(&recv_packet);
+               }
+               else if (recv_packet.flags & QUERYFLAGS_RCODE)
+               {
+                       Error error = ERROR_UNKNOWN;
+
+                       switch (recv_packet.flags & QUERYFLAGS_RCODE)
+                       {
+                               case 1:
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: format error");
+                                       error = ERROR_FORMAT_ERROR;
+                                       break;
+                               case 2:
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: server error");
+                                       error = ERROR_SERVER_FAILURE;
+                                       break;
+                               case 3:
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: domain not found");
+                                       error = ERROR_DOMAIN_NOT_FOUND;
+                                       break;
+                               case 4:
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: not implemented");
+                                       error = ERROR_NOT_IMPLEMENTED;
+                                       break;
+                               case 5:
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: refused");
+                                       error = ERROR_REFUSED;
+                                       break;
+                               default:
+                                       break;
+                       }
+
+                       ServerInstance->stats->statsDnsBad++;
+                       recv_packet.error = error;
+                       request->OnError(&recv_packet);
+               }
+               else if (recv_packet.questions.empty() || recv_packet.answers.empty())
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: No resource records returned");
+                       ServerInstance->stats->statsDnsBad++;
+                       recv_packet.error = ERROR_NO_RECORDS;
+                       request->OnError(&recv_packet);
+               }
+               else
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: Lookup complete for " + request->name);
+                       ServerInstance->stats->statsDnsGood++;
+                       request->OnLookupComplete(&recv_packet);
+                       this->AddCache(recv_packet);
+               }
+
+               ServerInstance->stats->statsDns++;
+
+               /* Request's destructor removes it from the request map */
+               delete request;
+       }
+
+       bool Tick(time_t now)
+       {
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolver: cache: purging DNS cache");
+
+               for (cache_map::iterator it = this->cache.begin(); it != this->cache.end(); )
+               {
+                       const Query& query = it->second;
+                       if (IsExpired(query, now))
+                               this->cache.erase(it++);
+                       else
+                               ++it;
+               }
+               return true;
+       }
+
+       void Rehash(const std::string& dnsserver)
+       {
+               if (this->GetFd() > -1)
+               {
+                       SocketEngine::Shutdown(this, 2);
+                       SocketEngine::Close(this);
+
+                       /* Remove expired entries from the cache */
+                       this->Tick(ServerInstance->Time());
+               }
+
+               irc::sockets::aptosa(dnsserver, DNS::PORT, myserver);
+
+               /* Initialize mastersocket */
+               int s = socket(myserver.sa.sa_family, SOCK_DGRAM, 0);
+               this->SetFd(s);
+
+               /* Have we got a socket? */
+               if (this->GetFd() != -1)
+               {
+                       SocketEngine::SetReuse(s);
+                       SocketEngine::NonBlocking(s);
+
+                       irc::sockets::sockaddrs bindto;
+                       memset(&bindto, 0, sizeof(bindto));
+                       bindto.sa.sa_family = myserver.sa.sa_family;
+
+                       if (SocketEngine::Bind(this->GetFd(), bindto) < 0)
+                       {
+                               /* Failed to bind */
+                               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Error binding dns socket - hostnames will NOT resolve");
+                               SocketEngine::Close(this->GetFd());
+                               this->SetFd(-1);
+                       }
+                       else if (!SocketEngine::AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE))
+                       {
+                               ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Internal error starting DNS - hostnames will NOT resolve.");
+                               SocketEngine::Close(this->GetFd());
+                               this->SetFd(-1);
+                       }
+               }
+               else
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Error creating DNS socket - hostnames will NOT resolve");
+               }
+       }
+};
+
+class ModuleDNS : public Module
+{
+       MyManager manager;
+       std::string DNSServer;
+
+       void FindDNSServer()
+       {
+#ifdef _WIN32
+               // attempt to look up their nameserver from the system
+               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: <dns:server> not defined, attempting to find a working server in the system settings...");
+
+               PFIXED_INFO pFixedInfo;
+               DWORD dwBufferSize = sizeof(FIXED_INFO);
+               pFixedInfo = (PFIXED_INFO) HeapAlloc(GetProcessHeap(), 0, sizeof(FIXED_INFO));
+
+               if (pFixedInfo)
+               {
+                       if (GetNetworkParams(pFixedInfo, &dwBufferSize) == ERROR_BUFFER_OVERFLOW)
+                       {
+                               HeapFree(GetProcessHeap(), 0, pFixedInfo);
+                               pFixedInfo = (PFIXED_INFO) HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
+                       }
+
+                       if (pFixedInfo)
+                       {
+                               if (GetNetworkParams(pFixedInfo, &dwBufferSize) == NO_ERROR)
+                                       DNSServer = pFixedInfo->DnsServerList.IpAddress.String;
+
+                               HeapFree(GetProcessHeap(), 0, pFixedInfo);
+                       }
+
+                       if (!DNSServer.empty())
+                       {
+                               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "<dns:server> set to '%s' as first active resolver in the system settings.", DNSServer.c_str());
+                               return;
+                       }
+               }
+
+               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "No viable nameserver found! Defaulting to nameserver '127.0.0.1'!");
+#else
+               // attempt to look up their nameserver from /etc/resolv.conf
+               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: <dns:server> not defined, attempting to find working server in /etc/resolv.conf...");
+
+               std::ifstream resolv("/etc/resolv.conf");
+
+               while (resolv >> DNSServer)
+               {
+                       if (DNSServer == "nameserver")
+                       {
+                               resolv >> DNSServer;
+                               if (DNSServer.find_first_not_of("0123456789.") == std::string::npos)
+                               {
+                                       ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "<dns:server> set to '%s' as first resolver in /etc/resolv.conf.",DNSServer.c_str());
+                                       return;
+                               }
+                       }
+               }
+
+               ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "/etc/resolv.conf contains no viable nameserver entries! Defaulting to nameserver '127.0.0.1'!");
+#endif
+               DNSServer = "127.0.0.1";
+       }
+
+ public:
+       ModuleDNS() : manager(this)
+       {
+       }
+
+       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+       {
+               std::string oldserver = DNSServer;
+               DNSServer = ServerInstance->Config->ConfValue("dns")->getString("server");
+               if (DNSServer.empty())
+                       FindDNSServer();
+
+               if (oldserver != DNSServer)
+                       this->manager.Rehash(DNSServer);
+       }
+
+       void OnUnloadModule(Module* mod)
+       {
+               for (int i = 0; i < MAX_REQUEST_ID; ++i)
+               {
+                       DNS::Request* req = this->manager.requests[i];
+                       if (!req)
+                               continue;
+
+                       if (req->creator == mod)
+                       {
+                               Query rr(*req);
+                               rr.error = ERROR_UNLOADED;
+                               req->OnError(&rr);
+
+                               delete req;
+                       }
+               }
+       }
+
+       Version GetVersion()
+       {
+               return Version("DNS support", VF_CORE|VF_VENDOR);
+       }
+};
+
+MODULE_INIT(ModuleDNS)
+
diff --git a/src/coremods/core_hostname_lookup.cpp b/src/coremods/core_hostname_lookup.cpp
new file mode 100644 (file)
index 0000000..c26d3b3
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2013 Adam <Adam@anope.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "modules/dns.h"
+
+namespace
+{
+       LocalIntExt* dl;
+       LocalStringExt* ph;
+}
+
+/** Derived from Resolver, and performs user forward/reverse lookups.
+ */
+class UserResolver : public DNS::Request
+{
+       /** UUID we are looking up */
+       const std::string uuid;
+
+       /** True if the lookup is forward, false if is a reverse lookup
+        */
+       const bool fwd;
+
+ public:
+       /** Create a resolver.
+        * @param mgr DNS Manager
+        * @param me this module
+        * @param user The user to begin lookup on
+        * @param to_resolve The IP or host to resolve
+        * @param qt The query type
+        */
+       UserResolver(DNS::Manager* mgr, Module* me, LocalUser* user, const std::string& to_resolve, DNS::QueryType qt)
+               : DNS::Request(mgr, me, to_resolve, qt)
+               , uuid(user->uuid)
+               , fwd(qt == DNS::QUERY_A || qt == DNS::QUERY_AAAA)
+       {
+       }
+
+       /** Called on successful lookup
+        * if a previous result has already come back.
+        * @param r The finished query
+        */
+       void OnLookupComplete(const DNS::Query* r)
+       {
+               LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
+               if (!bound_user)
+               {
+                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str());
+                       return;
+               }
+
+               const DNS::ResourceRecord& ans_record = r->answers[0];
+
+               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "DNS result for %s: '%s' -> '%s'", uuid.c_str(), ans_record.name.c_str(), ans_record.rdata.c_str());
+
+               if (!fwd)
+               {
+                       // first half of resolution is done. We now need to verify that the host matches.
+                       ph->set(bound_user, ans_record.rdata);
+
+                       UserResolver* res_forward;
+                       if (bound_user->client_sa.sa.sa_family == AF_INET6)
+                       {
+                               /* IPV6 forward lookup */
+                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_AAAA);
+                       }
+                       else
+                       {
+                               /* IPV4 lookup */
+                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_A);
+                       }
+                       try
+                       {
+                               this->manager->Process(res_forward);
+                       }
+                       catch (DNS::Exception& e)
+                       {
+                               delete res_forward;
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
+
+                               bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead.");
+                               dl->set(bound_user, 0);
+                       }
+               }
+               else
+               {
+                       /* Both lookups completed */
+
+                       irc::sockets::sockaddrs* user_ip = &bound_user->client_sa;
+                       bool rev_match = false;
+                       if (user_ip->sa.sa_family == AF_INET6)
+                       {
+                               struct in6_addr res_bin;
+                               if (inet_pton(AF_INET6, ans_record.rdata.c_str(), &res_bin))
+                               {
+                                       rev_match = !memcmp(&user_ip->in6.sin6_addr, &res_bin, sizeof(res_bin));
+                               }
+                       }
+                       else
+                       {
+                               struct in_addr res_bin;
+                               if (inet_pton(AF_INET, ans_record.rdata.c_str(), &res_bin))
+                               {
+                                       rev_match = !memcmp(&user_ip->in4.sin_addr, &res_bin, sizeof(res_bin));
+                               }
+                       }
+
+                       dl->set(bound_user, 0);
+
+                       if (rev_match)
+                       {
+                               std::string* hostname = ph->get(bound_user);
+
+                               if (hostname == NULL)
+                               {
+                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup");
+                                       bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead.");
+                                       return;
+                               }
+                               else if (hostname->length() < 65)
+                               {
+                                       /* Hostnames starting with : are not a good thing (tm) */
+                                       if ((*hostname)[0] == ':')
+                                               hostname->insert(0, "0");
+
+                                       bound_user->WriteNotice("*** Found your hostname (" + *hostname + (r->cached ? ") -- cached" : ")"));
+                                       bound_user->host.assign(*hostname, 0, 64);
+                                       bound_user->dhost = bound_user->host;
+
+                                       /* Invalidate cache */
+                                       bound_user->InvalidateCache();
+                               }
+                               else
+                               {
+                                       bound_user->WriteNotice("*** Your hostname is longer than the maximum of 64 characters, using your IP address (" + bound_user->GetIPString() + ") instead.");
+                               }
+
+                               ph->unset(bound_user);
+                       }
+                       else
+                       {
+                               bound_user->WriteNotice("*** Your hostname does not match up with your IP address. Sorry, using your IP address (" + bound_user->GetIPString() + ") instead.");
+                       }
+               }
+       }
+
+       /** Called on failed lookup
+        * @param query The errored query
+        */
+       void OnError(const DNS::Query* query)
+       {
+               LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
+               if (bound_user)
+               {
+                       bound_user->WriteNotice("*** Could not resolve your hostname: " + this->manager->GetErrorStr(query->error) + "; using your IP address (" + bound_user->GetIPString() + ") instead.");
+                       dl->set(bound_user, 0);
+                       ServerInstance->stats->statsDnsBad++;
+               }
+       }
+};
+
+class ModuleHostnameLookup : public Module
+{
+       LocalIntExt dnsLookup;
+       LocalStringExt ptrHosts;
+       dynamic_reference<DNS::Manager> DNS;
+
+ public:
+       ModuleHostnameLookup()
+               : dnsLookup("dnsLookup", this)
+               , ptrHosts("ptrHosts", this)
+               , DNS(this, "DNS")
+       {
+               dl = &dnsLookup;
+               ph = &ptrHosts;
+       }
+
+       void OnUserInit(LocalUser *user)
+       {
+               if (!DNS || !user->MyClass->resolvehostnames)
+               {
+                       user->WriteNotice("*** Skipping host resolution (disabled by server administrator)");
+                       return;
+               }
+
+               user->WriteNotice("*** Looking up your hostname...");
+
+               UserResolver* res_reverse = new UserResolver(*this->DNS, this, user, user->GetIPString(), DNS::QUERY_PTR);
+               try
+               {
+                       /* If both the reverse and forward queries are cached, the user will be able to pass DNS completely
+                        * before Process() completes, which is why dnsLookup.set() is here, before Process()
+                        */
+                       this->dnsLookup.set(user, 1);
+                       this->DNS->Process(res_reverse);
+               }
+               catch (DNS::Exception& e)
+               {
+                       this->dnsLookup.set(user, 0);
+                       delete res_reverse;
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
+                       ServerInstance->stats->statsDnsBad++;
+               }
+       }
+
+       ModResult OnCheckReady(LocalUser* user)
+       {
+               return this->dnsLookup.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
+       }
+
+       Version GetVersion()
+       {
+               return Version("Provides support for DNS lookups on connecting clients", VF_CORE|VF_VENDOR);
+       }
+};
+
+MODULE_INIT(ModuleHostnameLookup)
diff --git a/src/coremods/core_info/cmd_admin.cpp b/src/coremods/core_info/cmd_admin.cpp
new file mode 100644 (file)
index 0000000..1f694bf
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /ADMIN.
+ */
+class CommandAdmin : public Command
+{
+ public:
+       /** Constructor for admin.
+        */
+       CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0)
+       {
+               Penalty = 2;
+               syntax = "[<servername>]";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() > 0)
+                       return ROUTE_UNICAST(parameters[0]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+/** Handle /ADMIN
+ */
+CmdResult CommandAdmin::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
+               return CMD_SUCCESS;
+       user->SendText(":%s %03d %s :Administrative info for %s", ServerInstance->Config->ServerName.c_str(),
+               RPL_ADMINME, user->nick.c_str(),ServerInstance->Config->ServerName.c_str());
+       if (!ServerInstance->Config->AdminName.empty())
+               user->SendText(":%s %03d %s :Name     - %s", ServerInstance->Config->ServerName.c_str(),
+                       RPL_ADMINLOC1, user->nick.c_str(), ServerInstance->Config->AdminName.c_str());
+       user->SendText(":%s %03d %s :Nickname - %s", ServerInstance->Config->ServerName.c_str(),
+               RPL_ADMINLOC2, user->nick.c_str(), ServerInstance->Config->AdminNick.c_str());
+       user->SendText(":%s %03d %s :E-Mail   - %s", ServerInstance->Config->ServerName.c_str(),
+               RPL_ADMINEMAIL, user->nick.c_str(), ServerInstance->Config->AdminEmail.c_str());
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandAdmin)
diff --git a/src/coremods/core_info/cmd_commands.cpp b/src/coremods/core_info/cmd_commands.cpp
new file mode 100644 (file)
index 0000000..3f0ab99
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /COMMANDS.
+ */
+class CommandCommands : public Command
+{
+ public:
+       /** Constructor for commands.
+        */
+       CommandCommands(Module* parent) : Command(parent,"COMMANDS",0,0)
+       {
+               Penalty = 3;
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /COMMANDS
+ */
+CmdResult CommandCommands::Handle (const std::vector<std::string>&, User *user)
+{
+       std::vector<std::string> list;
+       list.reserve(ServerInstance->Parser->cmdlist.size());
+       for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++)
+       {
+               // Don't show S2S commands to users
+               if (i->second->flags_needed == FLAG_SERVERONLY)
+                       continue;
+
+               Module* src = i->second->creator;
+               list.push_back(InspIRCd::Format(":%s %03d %s :%s %s %d %d", ServerInstance->Config->ServerName.c_str(),
+                       RPL_COMMANDS, user->nick.c_str(), i->second->name.c_str(), src->ModuleSourceFile.c_str(),
+                       i->second->min_params, i->second->Penalty));
+       }
+       sort(list.begin(), list.end());
+       for(unsigned int i=0; i < list.size(); i++)
+               user->Write(list[i]);
+       user->WriteNumeric(RPL_COMMANDSEND, ":End of COMMANDS list");
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandCommands)
diff --git a/src/coremods/core_info/cmd_info.cpp b/src/coremods/core_info/cmd_info.cpp
new file mode 100644 (file)
index 0000000..7f1e923
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2011 Jackmcbarn <jackmcbarn@jackmcbarn.no-ip.org>
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /INFO.
+ */
+class CommandInfo : public Command
+{
+ public:
+       /** Constructor for info.
+        */
+       CommandInfo(Module* parent) : Command(parent,"INFO")
+       {
+               Penalty = 4;
+               syntax = "[<servername>]";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() > 0)
+                       return ROUTE_UNICAST(parameters[0]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+static const char* const lines[] = {
+       "                   -/\\- \2InspIRCd\2 -\\/-",
+       "                 November 2002 - Present",
+       " ",
+       "\2Core Developers\2:",
+       "    Craig Edwards,          Brain,      <brain@inspircd.org>",
+       "    Craig McLure,           Craig,      <craig@inspircd.org>",
+       "    Robin Burchell,         w00t,       <w00t@inspircd.org>",
+       "    Oliver Lupton,          Om,         <om@inspircd.org>",
+       "    John Brooks,            Special,    <special@inspircd.org>",
+       "    Dennis Friis,           peavey,     <peavey@inspircd.org>",
+       "    Thomas Stagner,         aquanight,  <aquanight@inspircd.org>",
+       "    Uli Schlachter,         psychon,    <psychon@inspircd.org>",
+       "    Matt Smith,             dz,         <dz@inspircd.org>",
+       "    Daniel De Graaf,        danieldg,   <danieldg@inspircd.org>",
+       "                            jackmcbarn, <jackmcbarn@inspircd.org>",
+       "    Attila Molnar,          Attila,     <attilamolnar@hush.com>",
+       " ",
+       "\2Regular Contributors\2:",
+       "    Adam           SaberUK",
+       " ",
+       "\2Other Contributors\2:",
+       "    ChrisTX        Shawn           Shutter",
+       " ",
+       "\2Former Contributors\2:",
+       "   dmb             Zaba            skenmy         GreenReaper",
+       "   Dan             Jason           satmd          owine",
+       "   Adremelech      John2           jilles         HiroP",
+       "   eggy            Bricker         AnMaster       djGrrr",
+       "   nenolod         Quension        praetorian     pippijn",
+       "   CC              jamie           typobox43      Burlex (win32)",
+       "   Stskeeps        ThaPrince       BuildSmart     Thunderhacker",
+       "   Skip            LeaChim         Majic          MacGyver",
+       "   Namegduf        Ankit           Phoenix        Taros",
+       " ",
+       "\2Thanks To\2:",
+       "   searchirc.com   irc-junkie.org  Brik           fraggeln",
+       " ",
+       " Best experienced with: \2An IRC client\2",
+       NULL
+};
+
+/** Handle /INFO
+ */
+CmdResult CommandInfo::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
+               return CMD_SUCCESS;
+
+       int i=0;
+       while (lines[i])
+               user->SendText(":%s %03d %s :%s", ServerInstance->Config->ServerName.c_str(), RPL_INFO, user->nick.c_str(), lines[i++]);
+       FOREACH_MOD(OnInfo, (user));
+       user->SendText(":%s %03d %s :End of /INFO list", ServerInstance->Config->ServerName.c_str(), RPL_ENDOFINFO, user->nick.c_str());
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandInfo)
diff --git a/src/coremods/core_info/cmd_modules.cpp b/src/coremods/core_info/cmd_modules.cpp
new file mode 100644 (file)
index 0000000..0177439
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /MODULES.
+ */
+class CommandModules : public Command
+{
+ public:
+       /** Constructor for modules.
+        */
+       CommandModules(Module* parent) : Command(parent,"MODULES",0,0)
+       {
+               Penalty = 4;
+               syntax = "[<servername>]";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() >= 1)
+                       return ROUTE_UNICAST(parameters[0]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+/** Handle /MODULES
+ */
+CmdResult CommandModules::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       // Don't ask remote servers about their modules unless the local user asking is an oper
+       // 2.0 asks anyway, so let's handle that the same way
+       bool for_us = (parameters.empty() || parameters[0] == ServerInstance->Config->ServerName);
+       if ((!for_us) || (!IS_LOCAL(user)))
+       {
+               if (!user->IsOper())
+               {
+                       user->WriteNotice("*** You cannot check what modules other servers have loaded.");
+                       return CMD_FAILURE;
+               }
+
+               // From an oper and not for us, forward
+               if (!for_us)
+                       return CMD_SUCCESS;
+       }
+
+       const ModuleManager::ModuleMap& mods = ServerInstance->Modules->GetModules();
+
+       for (ModuleManager::ModuleMap::const_iterator i = mods.begin(); i != mods.end(); ++i)
+       {
+               Module* m = i->second;
+               Version V = m->GetVersion();
+
+               if (IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"))
+               {
+                       std::string flags("SvcC");
+                       int pos = 0;
+                       for (int mult = 1; mult <= VF_OPTCOMMON; mult *= 2, ++pos)
+                               if (!(V.Flags & mult))
+                                       flags[pos] = '-';
+
+#ifdef PURE_STATIC
+                       user->SendText(":%s 702 %s :%p %s %s :%s", ServerInstance->Config->ServerName.c_str(),
+                               user->nick.c_str(), (void*)m, m->ModuleSourceFile.c_str(), flags.c_str(), V.description.c_str());
+#else
+                       std::string srcrev = m->ModuleDLLManager->GetVersion();
+                       user->SendText(":%s 702 %s :%p %s %s :%s - %s", ServerInstance->Config->ServerName.c_str(),
+                               user->nick.c_str(), (void*)m, m->ModuleSourceFile.c_str(), flags.c_str(), V.description.c_str(), srcrev.c_str());
+#endif
+               }
+               else
+               {
+                       user->SendText(":%s 702 %s :%s %s", ServerInstance->Config->ServerName.c_str(),
+                               user->nick.c_str(), m->ModuleSourceFile.c_str(), V.description.c_str());
+               }
+       }
+       user->SendText(":%s 703 %s :End of MODULES list", ServerInstance->Config->ServerName.c_str(), user->nick.c_str());
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandModules)
diff --git a/src/coremods/core_info/cmd_motd.cpp b/src/coremods/core_info/cmd_motd.cpp
new file mode 100644 (file)
index 0000000..71df701
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /MOTD.
+ */
+class CommandMotd : public Command
+{
+ public:
+       /** Constructor for motd.
+        */
+       CommandMotd ( Module* parent) : Command(parent,"MOTD",0,1) { syntax = "[<servername>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() > 0)
+                       return ROUTE_UNICAST(parameters[0]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+/** Handle /MOTD
+ */
+CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
+               return CMD_SUCCESS;
+
+       ConfigTag* tag = NULL;
+       LocalUser* localuser = IS_LOCAL(user);
+       if (localuser)
+               tag = localuser->GetClass()->config;
+       std::string motd_name = tag->getString("motd", "motd");
+       ConfigFileCache::iterator motd = ServerInstance->Config->Files.find(motd_name);
+       if (motd == ServerInstance->Config->Files.end())
+       {
+               user->SendText(":%s %03d %s :Message of the day file is missing.",
+                       ServerInstance->Config->ServerName.c_str(), ERR_NOMOTD, user->nick.c_str());
+               return CMD_SUCCESS;
+       }
+
+       user->SendText(":%s %03d %s :%s message of the day", ServerInstance->Config->ServerName.c_str(),
+               RPL_MOTDSTART, user->nick.c_str(), ServerInstance->Config->ServerName.c_str());
+
+       for (file_cache::iterator i = motd->second.begin(); i != motd->second.end(); i++)
+               user->SendText(":%s %03d %s :- %s", ServerInstance->Config->ServerName.c_str(), RPL_MOTD, user->nick.c_str(), i->c_str());
+
+       user->SendText(":%s %03d %s :End of message of the day.", ServerInstance->Config->ServerName.c_str(), RPL_ENDOFMOTD, user->nick.c_str());
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandMotd)
diff --git a/src/coremods/core_info/cmd_time.cpp b/src/coremods/core_info/cmd_time.cpp
new file mode 100644 (file)
index 0000000..9c46880
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /TIME.
+ */
+class CommandTime : public Command
+{
+ public:
+       /** Constructor for time.
+        */
+       CommandTime ( Module* parent) : Command(parent,"TIME",0,0) { syntax = "[<servername>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() > 0)
+                       return ROUTE_UNICAST(parameters[0]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+CmdResult CommandTime::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
+               return CMD_SUCCESS;
+
+       time_t local = ServerInstance->Time();
+       struct tm* timeinfo = localtime(&local);
+       const std::string& humanTime = asctime(timeinfo);
+
+       user->SendText(":%s %03d %s %s :%s", ServerInstance->Config->ServerName.c_str(), RPL_TIME, user->nick.c_str(),
+               ServerInstance->Config->ServerName.c_str(), humanTime.c_str());
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandTime)
diff --git a/src/coremods/core_info/cmd_version.cpp b/src/coremods/core_info/cmd_version.cpp
new file mode 100644 (file)
index 0000000..032d9ea
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /VERSION.
+ */
+class CommandVersion : public Command
+{
+ public:
+       /** Constructor for version.
+        */
+       CommandVersion ( Module* parent) : Command(parent,"VERSION",0,0) { syntax = "[<servername>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandVersion::Handle (const std::vector<std::string>&, User *user)
+{
+       std::string version = ServerInstance->GetVersionString((user->IsOper()));
+       user->WriteNumeric(RPL_VERSION, ":%s", version.c_str());
+       LocalUser *lu = IS_LOCAL(user);
+       if (lu != NULL)
+       {
+               ServerInstance->ISupport.SendTo(lu);
+       }
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandVersion)
diff --git a/src/coremods/core_ison.cpp b/src/coremods/core_ison.cpp
new file mode 100644 (file)
index 0000000..c7ead2a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /ISON.
+ */
+class CommandIson : public Command
+{
+ public:
+       /** Constructor for ison.
+        */
+       CommandIson ( Module* parent) : Command(parent,"ISON", 1) {
+               syntax = "<nick> {nick}";
+       }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /ISON
+ */
+CmdResult CommandIson::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::map<User*,User*> ison_already;
+       User *u;
+       std::string reply = "303 " + user->nick + " :";
+
+       for (unsigned int i = 0; i < parameters.size(); i++)
+       {
+               u = ServerInstance->FindNickOnly(parameters[i]);
+               if (ison_already.find(u) != ison_already.end())
+                       continue;
+
+               if (u)
+               {
+                       reply.append(u->nick).append(" ");
+                       if (reply.length() > 450)
+                       {
+                               user->WriteServ(reply);
+                               reply = "303 " + user->nick + " :";
+                       }
+                       ison_already[u] = u;
+               }
+               else
+               {
+                       if ((i == parameters.size() - 1) && (parameters[i].find(' ') != std::string::npos))
+                       {
+                               /* Its a space seperated list of nicks (RFC1459 says to support this)
+                                */
+                               irc::spacesepstream list(parameters[i]);
+                               std::string item;
+
+                               while (list.GetToken(item))
+                               {
+                                       u = ServerInstance->FindNickOnly(item);
+                                       if (ison_already.find(u) != ison_already.end())
+                                               continue;
+
+                                       if (u)
+                                       {
+                                               reply.append(u->nick).append(" ");
+                                               if (reply.length() > 450)
+                                               {
+                                                       user->WriteServ(reply);
+                                                       reply = "303 " + user->nick + " :";
+                                               }
+                                               ison_already[u] = u;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (!reply.empty())
+               user->WriteServ(reply);
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandIson)
diff --git a/src/coremods/core_links.cpp b/src/coremods/core_links.cpp
new file mode 100644 (file)
index 0000000..8b44d7a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /LINKS.
+ */
+class CommandLinks : public Command
+{
+ public:
+       /** Constructor for links.
+        */
+       CommandLinks ( Module* parent) : Command(parent,"LINKS",0,0) { }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /LINKS
+ */
+CmdResult CommandLinks::Handle (const std::vector<std::string>&, User *user)
+{
+       user->WriteNumeric(RPL_LINKS, "%s %s :0 %s", ServerInstance->Config->ServerName.c_str(),ServerInstance->Config->ServerName.c_str(),ServerInstance->Config->ServerDesc.c_str());
+       user->WriteNumeric(RPL_ENDOFLINKS, "* :End of /LINKS list.");
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandLinks)
diff --git a/src/coremods/core_list.cpp b/src/coremods/core_list.cpp
new file mode 100644 (file)
index 0000000..ceffae4
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /LIST.
+ */
+class CommandList : public Command
+{
+       ChanModeReference secretmode;
+       ChanModeReference privatemode;
+
+ public:
+       /** Constructor for list.
+        */
+       CommandList(Module* parent)
+               : Command(parent,"LIST", 0, 0)
+               , secretmode(creator, "secret")
+               , privatemode(creator, "private")
+       {
+               Penalty = 5;
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+
+/** Handle /LIST
+ */
+CmdResult CommandList::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       int minusers = 0, maxusers = 0;
+
+       user->WriteNumeric(RPL_LISTSTART, "Channel :Users Name");
+
+       /* Work around mIRC suckyness. YOU SUCK, KHALED! */
+       if (parameters.size() == 1)
+       {
+               if (parameters[0][0] == '<')
+               {
+                       maxusers = atoi((parameters[0].c_str())+1);
+               }
+               else if (parameters[0][0] == '>')
+               {
+                       minusers = atoi((parameters[0].c_str())+1);
+               }
+       }
+
+       for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
+       {
+               // attempt to match a glob pattern
+               long users = i->second->GetUserCounter();
+
+               bool too_few = (minusers && (users <= minusers));
+               bool too_many = (maxusers && (users >= maxusers));
+
+               if (too_many || too_few)
+                       continue;
+
+               if (parameters.size() && !parameters[0].empty() && (parameters[0][0] != '<' && parameters[0][0] != '>'))
+               {
+                       if (!InspIRCd::Match(i->second->name, parameters[0]) && !InspIRCd::Match(i->second->topic, parameters[0]))
+                               continue;
+               }
+
+               // if the channel is not private/secret, OR the user is on the channel anyway
+               bool n = (i->second->HasUser(user) || user->HasPrivPermission("channels/auspex"));
+
+               if (!n && i->second->IsModeSet(privatemode))
+               {
+                       /* Channel is +p and user is outside/not privileged */
+                       user->WriteNumeric(RPL_LIST, "* %ld :", users);
+               }
+               else
+               {
+                       if (n || !i->second->IsModeSet(secretmode))
+                       {
+                               /* User is in the channel/privileged, channel is not +s */
+                               user->WriteNumeric(RPL_LIST, "%s %ld :[+%s] %s",i->second->name.c_str(),users,i->second->ChanModes(n),i->second->topic.c_str());
+                       }
+               }
+       }
+       user->WriteNumeric(RPL_LISTEND, ":End of channel list.");
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandList)
diff --git a/src/coremods/core_loadmodule.cpp b/src/coremods/core_loadmodule.cpp
new file mode 100644 (file)
index 0000000..458a8cd
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /LOADMODULE.
+ */
+class CommandLoadmodule : public Command
+{
+ public:
+       /** Constructor for loadmodule.
+        */
+       CommandLoadmodule ( Module* parent) : Command(parent,"LOADMODULE",1,1) { flags_needed='o'; syntax = "<modulename>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /LOADMODULE
+ */
+CmdResult CommandLoadmodule::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (ServerInstance->Modules->Load(parameters[0]))
+       {
+               ServerInstance->SNO->WriteGlobalSno('a', "NEW MODULE: %s loaded %s",user->nick.c_str(), parameters[0].c_str());
+               user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module successfully loaded.", parameters[0].c_str());
+               return CMD_SUCCESS;
+       }
+       else
+       {
+               user->WriteNumeric(ERR_CANTLOADMODULE, "%s :%s", parameters[0].c_str(), ServerInstance->Modules->LastError().c_str());
+               return CMD_FAILURE;
+       }
+}
+
+COMMAND_INIT(CommandLoadmodule)
diff --git a/src/coremods/core_lusers.cpp b/src/coremods/core_lusers.cpp
new file mode 100644 (file)
index 0000000..e56b1c0
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+struct LusersCounters
+{
+       unsigned int max_local;
+       unsigned int max_global;
+       unsigned int invisible;
+
+       LusersCounters(unsigned int inv)
+               : max_local(ServerInstance->Users->LocalUserCount())
+               , max_global(ServerInstance->Users->RegisteredUserCount())
+               , invisible(inv)
+       {
+       }
+
+       inline void UpdateMaxUsers()
+       {
+               unsigned int current = ServerInstance->Users->LocalUserCount();
+               if (current > max_local)
+                       max_local = current;
+
+               current = ServerInstance->Users->RegisteredUserCount();
+               if (current > max_global)
+                       max_global = current;
+       }
+};
+
+/** Handle /LUSERS.
+ */
+class CommandLusers : public Command
+{
+       LusersCounters& counters;
+ public:
+       /** Constructor for lusers.
+        */
+       CommandLusers(Module* parent, LusersCounters& Counters)
+               : Command(parent,"LUSERS",0,0), counters(Counters)
+       { }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /LUSERS
+ */
+CmdResult CommandLusers::Handle (const std::vector<std::string>&, User *user)
+{
+       unsigned int n_users = ServerInstance->Users->RegisteredUserCount();
+       ProtocolInterface::ServerList serverlist;
+       ServerInstance->PI->GetServerList(serverlist);
+       unsigned int n_serv = serverlist.size();
+       unsigned int n_local_servs = 0;
+       for (ProtocolInterface::ServerList::const_iterator i = serverlist.begin(); i != serverlist.end(); ++i)
+       {
+               if (i->parentname == ServerInstance->Config->ServerName)
+                       n_local_servs++;
+       }
+       // fix for default GetServerList not returning us
+       if (!n_serv)
+               n_serv = 1;
+
+       counters.UpdateMaxUsers();
+
+       user->WriteNumeric(RPL_LUSERCLIENT, ":There are %d users and %d invisible on %d servers",
+                       n_users - counters.invisible, counters.invisible, n_serv);
+
+       if (ServerInstance->Users->OperCount())
+               user->WriteNumeric(RPL_LUSEROP, "%d :operator(s) online", ServerInstance->Users->OperCount());
+
+       if (ServerInstance->Users->UnregisteredUserCount())
+               user->WriteNumeric(RPL_LUSERUNKNOWN, "%d :unknown connections", ServerInstance->Users->UnregisteredUserCount());
+
+       user->WriteNumeric(RPL_LUSERCHANNELS, "%ld :channels formed", ServerInstance->ChannelCount());
+       user->WriteNumeric(RPL_LUSERME, ":I have %d clients and %d servers", ServerInstance->Users->LocalUserCount(),n_local_servs);
+       user->WriteNumeric(RPL_LOCALUSERS, ":Current Local Users: %d  Max: %d", ServerInstance->Users->LocalUserCount(), counters.max_local);
+       user->WriteNumeric(RPL_GLOBALUSERS, ":Current Global Users: %d  Max: %d", n_users, counters.max_global);
+
+       return CMD_SUCCESS;
+}
+
+class InvisibleWatcher : public ModeWatcher
+{
+       unsigned int& invisible;
+public:
+       InvisibleWatcher(Module* mod, unsigned int& Invisible)
+               : ModeWatcher(mod, "invisible", MODETYPE_USER), invisible(Invisible)
+       {
+       }
+
+       void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding)
+       {
+               if (dest->registered != REG_ALL)
+                       return;
+
+               if (adding)
+                       invisible++;
+               else
+                       invisible--;
+       }
+};
+
+class ModuleLusers : public Module
+{
+       UserModeReference invisiblemode;
+       LusersCounters counters;
+       CommandLusers cmd;
+       InvisibleWatcher mw;
+
+       unsigned int CountInvisible()
+       {
+               unsigned int c = 0;
+               for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); ++i)
+               {
+                       User* u = i->second;
+                       if (u->IsModeSet(invisiblemode))
+                               c++;
+               }
+               return c;
+       }
+
+ public:
+       ModuleLusers()
+               : invisiblemode(this, "invisible")
+               , counters(CountInvisible())
+               , cmd(this, counters)
+               , mw(this, counters.invisible)
+       {
+       }
+
+       void OnPostConnect(User* user)
+       {
+               counters.UpdateMaxUsers();
+               if (user->IsModeSet(invisiblemode))
+                       counters.invisible++;
+       }
+
+       void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
+       {
+               if (user->IsModeSet(invisiblemode))
+                       counters.invisible--;
+       }
+
+       Version GetVersion()
+       {
+               return Version("LUSERS", VF_VENDOR | VF_CORE);
+       }
+};
+
+MODULE_INIT(ModuleLusers)
diff --git a/src/coremods/core_oper/cmd_die.cpp b/src/coremods/core_oper/cmd_die.cpp
new file mode 100644 (file)
index 0000000..63e4c59
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /DIE.
+ */
+class CommandDie : public Command
+{
+ public:
+       /** Constructor for die.
+        */
+       CommandDie ( Module* parent) : Command(parent,"DIE",1) { flags_needed = 'o'; syntax = "<password>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+#include "exitcodes.h"
+
+/** Handle /DIE
+ */
+CmdResult CommandDie::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (ServerInstance->PassCompare(user, ServerInstance->Config->diepass, parameters[0], ServerInstance->Config->powerhash))
+       {
+               {
+                       std::string diebuf = "*** DIE command from " + user->GetFullHost() + ". Terminating.";
+                       ServerInstance->Logs->Log("COMMAND", LOG_SPARSE, diebuf);
+                       ServerInstance->SendError(diebuf);
+               }
+
+               ServerInstance->Exit(EXIT_STATUS_DIE);
+       }
+       else
+       {
+               ServerInstance->Logs->Log("COMMAND", LOG_SPARSE, "Failed /DIE command from %s", user->GetFullRealHost().c_str());
+               ServerInstance->SNO->WriteGlobalSno('a', "Failed DIE Command from %s.", user->GetFullRealHost().c_str());
+               return CMD_FAILURE;
+       }
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandDie)
diff --git a/src/coremods/core_oper/cmd_kill.cpp b/src/coremods/core_oper/cmd_kill.cpp
new file mode 100644 (file)
index 0000000..454bab0
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /KILL.
+ */
+class CommandKill : public Command
+{
+       std::string lastuuid;
+       std::string killreason;
+
+ public:
+       /** Constructor for kill.
+        */
+       CommandKill ( Module* parent) : Command(parent,"KILL",2,2) {
+               flags_needed = 'o';
+               syntax = "<nickname> <reason>";
+               TRANSLATE2(TR_CUSTOM, TR_CUSTOM);
+       }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               // FindNick() doesn't work here because we quit the target user in Handle() which
+               // removes it from the nicklist, so we check lastuuid: if it's empty then this KILL
+               // was for a local user, otherwise it contains the uuid of the user who was killed.
+               if (lastuuid.empty())
+                       return ROUTE_LOCALONLY;
+               return ROUTE_BROADCAST;
+       }
+
+       void EncodeParameter(std::string& param, int index)
+       {
+               // Manually translate the nick -> uuid (see above), and also the reason (params[1])
+               // because we decorate it if the oper is local and want remote servers to see the
+               // decorated reason not the original.
+               param = ((index == 0) ? lastuuid : killreason);
+       }
+};
+
+/** Handle /KILL
+ */
+CmdResult CommandKill::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       /* Allow comma seperated lists of users for /KILL (thanks w00t) */
+       if (CommandParser::LoopCall(user, this, parameters, 0))
+       {
+               // If we got a colon delimited list of nicks then the handler ran for each nick,
+               // and KILL commands were broadcast for remote targets.
+               return CMD_FAILURE;
+       }
+
+       User *u = ServerInstance->FindNick(parameters[0]);
+       if ((u) && (!IS_SERVER(u)))
+       {
+               /*
+                * Here, we need to decide how to munge kill messages. Whether to hide killer, what to show opers, etc.
+                * We only do this when the command is being issued LOCALLY, for remote KILL, we just copy the message we got.
+                *
+                * This conditional is so that we only append the "Killed (" prefix ONCE. If killer is remote, then the kill
+                * just gets processed and passed on, otherwise, if they are local, it gets prefixed. Makes sense :-) -- w00t
+                */
+
+               if (IS_LOCAL(user))
+               {
+                       /*
+                        * Moved this event inside the IS_LOCAL check also, we don't want half the network killing a user
+                        * and the other half not. This would be a bad thing. ;p -- w00t
+                        */
+                       ModResult MOD_RESULT;
+                       FIRST_MOD_RESULT(OnKill, MOD_RESULT, (user, u, parameters[1]));
+
+                       if (MOD_RESULT == MOD_RES_DENY)
+                               return CMD_FAILURE;
+
+                       killreason = "Killed (";
+                       if (!ServerInstance->Config->HideKillsServer.empty())
+                       {
+                               // hidekills is on, use it
+                               killreason += ServerInstance->Config->HideKillsServer;
+                       }
+                       else
+                       {
+                               // hidekills is off, do nothing
+                               killreason += user->nick;
+                       }
+
+                       killreason += " (" + parameters[1] + "))";
+               }
+               else
+               {
+                       /* Leave it alone, remote server has already formatted it */
+                       killreason.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxQuit);
+               }
+
+               /*
+                * Now we need to decide whether or not to send a local or remote snotice. Currently this checking is a little flawed.
+                * No time to fix it right now, so left a note. -- w00t
+                */
+               if (!IS_LOCAL(u))
+               {
+                       // remote kill
+                       if (!user->server->IsULine())
+                               ServerInstance->SNO->WriteToSnoMask('K', "Remote kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
+                       this->lastuuid = u->uuid;
+               }
+               else
+               {
+                       // local kill
+                       /*
+                        * XXX - this isn't entirely correct, servers A - B - C, oper on A, client on C. Oper kills client, A and B will get remote kill
+                        * snotices, C will get a local kill snotice. this isn't accurate, and needs fixing at some stage. -- w00t
+                        */
+                       if (!user->server->IsULine())
+                       {
+                               if (IS_LOCAL(user))
+                                       ServerInstance->SNO->WriteGlobalSno('k',"Local Kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
+                               else
+                                       ServerInstance->SNO->WriteToSnoMask('k',"Local Kill by %s: %s (%s)", user->nick.c_str(), u->GetFullRealHost().c_str(), parameters[1].c_str());
+                       }
+
+                       ServerInstance->Logs->Log("KILL", LOG_DEFAULT, "LOCAL KILL: %s :%s!%s!%s (%s)", u->nick.c_str(), ServerInstance->Config->ServerName.c_str(), user->dhost.c_str(), user->nick.c_str(), parameters[1].c_str());
+
+                       u->Write(":%s KILL %s :%s!%s!%s (%s)", ServerInstance->Config->HideKillsServer.empty() ? user->GetFullHost().c_str() : ServerInstance->Config->HideKillsServer.c_str(),
+                                       u->nick.c_str(),
+                                       ServerInstance->Config->ServerName.c_str(),
+                                       user->dhost.c_str(),
+                                       ServerInstance->Config->HideKillsServer.empty() ? user->nick.c_str() : ServerInstance->Config->HideKillsServer.c_str(),
+                                       parameters[1].c_str());
+
+                       this->lastuuid.clear();
+               }
+
+               // send the quit out
+               ServerInstance->Users->QuitUser(u, killreason);
+       }
+       else
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandKill)
diff --git a/src/coremods/core_oper/cmd_oper.cpp b/src/coremods/core_oper/cmd_oper.cpp
new file mode 100644 (file)
index 0000000..bd7a350
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /OPER.
+ */
+class CommandOper : public SplitCommand
+{
+ public:
+       /** Constructor for oper.
+        */
+       CommandOper ( Module* parent) : SplitCommand(parent,"OPER",2,2) { syntax = "<username> <password>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
+};
+
+CmdResult CommandOper::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
+{
+       bool match_login = false;
+       bool match_pass = false;
+       bool match_hosts = false;
+
+       const std::string userHost = user->ident + "@" + user->host;
+       const std::string userIP = user->ident + "@" + user->GetIPString();
+
+       OperIndex::iterator i = ServerInstance->Config->oper_blocks.find(parameters[0]);
+       if (i != ServerInstance->Config->oper_blocks.end())
+       {
+               OperInfo* ifo = i->second;
+               ConfigTag* tag = ifo->oper_block;
+               match_login = true;
+               match_pass = ServerInstance->PassCompare(user, tag->getString("password"), parameters[1], tag->getString("hash"));
+               match_hosts = InspIRCd::MatchMask(tag->getString("host"), userHost, userIP);
+
+               if (match_pass && match_hosts)
+               {
+                       /* found this oper's opertype */
+                       user->Oper(ifo);
+                       return CMD_SUCCESS;
+               }
+       }
+
+       std::string fields;
+       if (!match_login)
+               fields.append("login ");
+       if (!match_pass)
+               fields.append("password ");
+       if (!match_hosts)
+               fields.append("hosts");
+
+       // tell them they suck, and lag them up to help prevent brute-force attacks
+       user->WriteNumeric(ERR_NOOPERHOST, ":Invalid oper credentials");
+       user->CommandFloodPenalty += 10000;
+
+       ServerInstance->SNO->WriteGlobalSno('o', "WARNING! Failed oper attempt by %s using login '%s': The following fields do not match: %s", user->GetFullRealHost().c_str(), parameters[0].c_str(), fields.c_str());
+       ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "OPER: Failed oper attempt by %s using login '%s': The following fields did not match: %s", user->GetFullRealHost().c_str(), parameters[0].c_str(), fields.c_str());
+       return CMD_FAILURE;
+}
+
+COMMAND_INIT(CommandOper)
diff --git a/src/coremods/core_oper/cmd_rehash.cpp b/src/coremods/core_oper/cmd_rehash.cpp
new file mode 100644 (file)
index 0000000..f71219f
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /REHASH.
+ */
+class CommandRehash : public Command
+{
+ public:
+       /** Constructor for rehash.
+        */
+       CommandRehash ( Module* parent) : Command(parent,"REHASH",0) { flags_needed = 'o'; Penalty = 2; syntax = "[<servermask>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string param = parameters.size() ? parameters[0] : "";
+
+       FOREACH_MOD(OnPreRehash, (user, param));
+
+       if (param.empty())
+       {
+               // standard rehash of local server
+       }
+       else if (param.find_first_of("*.") != std::string::npos)
+       {
+               // rehash of servers by server name (with wildcard)
+               if (!InspIRCd::Match(ServerInstance->Config->ServerName, parameters[0]))
+               {
+                       // Doesn't match us. PreRehash is already done, nothing left to do
+                       return CMD_SUCCESS;
+               }
+       }
+       else
+       {
+               // parameterized rehash
+
+               // the leading "-" is optional; remove it if present.
+               if (param[0] == '-')
+                       param = param.substr(1);
+
+               FOREACH_MOD(OnModuleRehash, (user, param));
+               return CMD_SUCCESS;
+       }
+
+       // Rehash for me. Try to start the rehash thread
+       if (!ServerInstance->ConfigThread)
+       {
+               std::string m = user->nick + " is rehashing config file " + FileSystem::GetFileName(ServerInstance->ConfigFileName) + " on " + ServerInstance->Config->ServerName;
+               ServerInstance->SNO->WriteGlobalSno('a', m);
+
+               if (IS_LOCAL(user))
+                       user->WriteNumeric(RPL_REHASHING, "%s :Rehashing", FileSystem::GetFileName(ServerInstance->ConfigFileName).c_str());
+               else
+                       ServerInstance->PI->SendUserNotice(user, "*** Rehashing server " + FileSystem::GetFileName(ServerInstance->ConfigFileName));
+
+               /* Don't do anything with the logs here -- logs are restarted
+                * after the config thread has completed.
+                */
+               ServerInstance->Rehash(user->uuid);
+       }
+       else
+       {
+               /*
+                * A rehash is already in progress! ahh shit.
+                * XXX, todo: we should find some way to kill runaway rehashes that are blocking, this is a major problem for unrealircd users
+                */
+               if (IS_LOCAL(user))
+                       user->WriteNotice("*** Could not rehash: A rehash is already in progress.");
+               else
+                       ServerInstance->PI->SendUserNotice(user, "*** Could not rehash: A rehash is already in progress.");
+       }
+
+       // Always return success so spanningtree forwards an incoming REHASH even if we failed
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandRehash)
diff --git a/src/coremods/core_oper/cmd_restart.cpp b/src/coremods/core_oper/cmd_restart.cpp
new file mode 100644 (file)
index 0000000..33627b5
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /RESTART
+ */
+class CommandRestart : public Command
+{
+ public:
+       /** Constructor for restart.
+        */
+       CommandRestart(Module* parent) : Command(parent,"RESTART",1,1) { flags_needed = 'o'; syntax = "<password>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandRestart::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       ServerInstance->Logs->Log("COMMAND", LOG_DEFAULT, "Restart: %s",user->nick.c_str());
+       if (ServerInstance->PassCompare(user, ServerInstance->Config->restartpass, parameters[0], ServerInstance->Config->powerhash))
+       {
+               ServerInstance->SNO->WriteGlobalSno('a', "RESTART command from %s, restarting server.", user->GetFullRealHost().c_str());
+
+               ServerInstance->SendError("Server restarting.");
+
+#ifndef _WIN32
+               /* XXX: This hack sets FD_CLOEXEC on all possible file descriptors, so they're closed if the execv() below succeeds.
+                * Certainly, this is not a nice way to do things and it's slow when the fd limit is high.
+                *
+                * A better solution would be to set the close-on-exec flag for each fd we create (or create them with O_CLOEXEC),
+                * however there is no guarantee that third party libs will do the same.
+                */
+               for (int i = getdtablesize(); --i > 2;)
+               {
+                       int flags = fcntl(i, F_GETFD);
+                       if (flags != -1)
+                               fcntl(i, F_SETFD, flags | FD_CLOEXEC);
+               }
+#endif
+
+               execv(ServerInstance->Config->cmdline.argv[0], ServerInstance->Config->cmdline.argv);
+               ServerInstance->SNO->WriteGlobalSno('a', "Failed RESTART - could not execute '%s' (%s)",
+                       ServerInstance->Config->cmdline.argv[0], strerror(errno));
+       }
+       else
+       {
+               ServerInstance->SNO->WriteGlobalSno('a', "Failed RESTART Command from %s.", user->GetFullRealHost().c_str());
+       }
+       return CMD_FAILURE;
+}
+
+
+COMMAND_INIT(CommandRestart)
diff --git a/src/coremods/core_privmsg.cpp b/src/coremods/core_privmsg.cpp
new file mode 100644 (file)
index 0000000..0cca567
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+namespace
+{
+       const char* MessageTypeString[] = { "PRIVMSG", "NOTICE" };
+}
+
+class MessageCommandBase : public Command
+{
+       ChanModeReference moderatedmode;
+       ChanModeReference noextmsgmode;
+
+ public:
+       MessageCommandBase(Module* parent, MessageType mt)
+               : Command(parent, MessageTypeString[mt], 2, 2)
+               , moderatedmode(parent, "moderated")
+               , noextmsgmode(parent, "noextmsg")
+       {
+               syntax = "<target>{,<target>} <message>";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleMessage(const std::vector<std::string>& parameters, User* user, MessageType mt);
+
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (IS_LOCAL(user))
+                       // This is handled by the OnUserMessage hook to split the LoopCall pieces
+                       return ROUTE_LOCALONLY;
+               else
+                       return ROUTE_MESSAGE(parameters[0]);
+       }
+};
+
+CmdResult MessageCommandBase::HandleMessage(const std::vector<std::string>& parameters, User* user, MessageType mt)
+{
+       User *dest;
+       Channel *chan;
+       CUList except_list;
+
+       LocalUser* localuser = IS_LOCAL(user);
+       if (localuser)
+               localuser->idle_lastmsg = ServerInstance->Time();
+
+       if (CommandParser::LoopCall(user, this, parameters, 0))
+               return CMD_SUCCESS;
+
+       if (parameters[0][0] == '$')
+       {
+               if (!user->HasPrivPermission("users/mass-message"))
+                       return CMD_SUCCESS;
+
+               ModResult MOD_RESULT;
+               std::string temp = parameters[1];
+               FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, except_list, mt));
+               if (MOD_RESULT == MOD_RES_DENY)
+                       return CMD_FAILURE;
+
+               const char* text = temp.c_str();
+               const char* servermask = (parameters[0].c_str()) + 1;
+
+               FOREACH_MOD(OnText, (user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, except_list));
+               if (InspIRCd::Match(ServerInstance->Config->ServerName, servermask, NULL))
+               {
+                       user->SendAll(MessageTypeString[mt], "%s", text);
+               }
+               FOREACH_MOD(OnUserMessage, (user, (void*)parameters[0].c_str(), TYPE_SERVER, text, 0, except_list, mt));
+               return CMD_SUCCESS;
+       }
+       char status = 0;
+       const char* target = parameters[0].c_str();
+
+       if (ServerInstance->Modes->FindPrefix(*target))
+       {
+               status = *target;
+               target++;
+       }
+       if (*target == '#')
+       {
+               chan = ServerInstance->FindChan(target);
+
+               except_list.insert(user);
+
+               if (chan)
+               {
+                       if (localuser && chan->GetPrefixValue(user) < VOICE_VALUE)
+                       {
+                               if (chan->IsModeSet(noextmsgmode) && !chan->HasUser(user))
+                               {
+                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (no external messages)", chan->name.c_str());
+                                       return CMD_FAILURE;
+                               }
+
+                               if (chan->IsModeSet(moderatedmode))
+                               {
+                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (+m)", chan->name.c_str());
+                                       return CMD_FAILURE;
+                               }
+
+                               if (ServerInstance->Config->RestrictBannedUsers)
+                               {
+                                       if (chan->IsBanned(user))
+                                       {
+                                               user->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (you're banned)", chan->name.c_str());
+                                               return CMD_FAILURE;
+                                       }
+                               }
+                       }
+                       ModResult MOD_RESULT;
+
+                       std::string temp = parameters[1];
+                       FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, chan, TYPE_CHANNEL, temp, status, except_list, mt));
+                       if (MOD_RESULT == MOD_RES_DENY)
+                               return CMD_FAILURE;
+
+                       const char* text = temp.c_str();
+
+                       /* Check again, a module may have zapped the input string */
+                       if (temp.empty())
+                       {
+                               user->WriteNumeric(ERR_NOTEXTTOSEND, ":No text to send");
+                               return CMD_FAILURE;
+                       }
+
+                       FOREACH_MOD(OnText, (user,chan,TYPE_CHANNEL,text,status,except_list));
+
+                       if (status)
+                       {
+                               if (ServerInstance->Config->UndernetMsgPrefix)
+                               {
+                                       chan->WriteAllExcept(user, false, status, except_list, "%s %c%s :%c %s", MessageTypeString[mt], status, chan->name.c_str(), status, text);
+                               }
+                               else
+                               {
+                                       chan->WriteAllExcept(user, false, status, except_list, "%s %c%s :%s", MessageTypeString[mt], status, chan->name.c_str(), text);
+                               }
+                       }
+                       else
+                       {
+                               chan->WriteAllExcept(user, false, status, except_list, "%s %s :%s", MessageTypeString[mt], chan->name.c_str(), text);
+                       }
+
+                       FOREACH_MOD(OnUserMessage, (user,chan, TYPE_CHANNEL, text, status, except_list, mt));
+               }
+               else
+               {
+                       /* no such nick/channel */
+                       user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", target);
+                       return CMD_FAILURE;
+               }
+               return CMD_SUCCESS;
+       }
+
+       const char* destnick = parameters[0].c_str();
+
+       if (localuser)
+       {
+               const char* targetserver = strchr(destnick, '@');
+
+               if (targetserver)
+               {
+                       std::string nickonly;
+
+                       nickonly.assign(destnick, 0, targetserver - destnick);
+                       dest = ServerInstance->FindNickOnly(nickonly);
+                       if (dest && strcasecmp(dest->server->GetName().c_str(), targetserver + 1))
+                       {
+                               /* Incorrect server for user */
+                               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+                               return CMD_FAILURE;
+                       }
+               }
+               else
+                       dest = ServerInstance->FindNickOnly(destnick);
+       }
+       else
+               dest = ServerInstance->FindNick(destnick);
+
+       if ((dest) && (dest->registered == REG_ALL))
+       {
+               if (parameters[1].empty())
+               {
+                       user->WriteNumeric(ERR_NOTEXTTOSEND, ":No text to send");
+                       return CMD_FAILURE;
+               }
+
+               if ((dest->IsAway()) && (mt == MSG_PRIVMSG))
+               {
+                       /* auto respond with aweh msg */
+                       user->WriteNumeric(RPL_AWAY, "%s :%s", dest->nick.c_str(), dest->awaymsg.c_str());
+               }
+
+               ModResult MOD_RESULT;
+
+               std::string temp = parameters[1];
+               FIRST_MOD_RESULT(OnUserPreMessage, MOD_RESULT, (user, dest, TYPE_USER, temp, 0, except_list, mt));
+               if (MOD_RESULT == MOD_RES_DENY)
+                       return CMD_FAILURE;
+
+               const char* text = temp.c_str();
+
+               FOREACH_MOD(OnText, (user, dest, TYPE_USER, text, 0, except_list));
+
+               if (IS_LOCAL(dest))
+               {
+                       // direct write, same server
+                       user->WriteTo(dest, "%s %s :%s", MessageTypeString[mt], dest->nick.c_str(), text);
+               }
+
+               FOREACH_MOD(OnUserMessage, (user, dest, TYPE_USER, text, 0, except_list, mt));
+       }
+       else
+       {
+               /* no such nick/channel */
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+       return CMD_SUCCESS;
+}
+
+template<MessageType MT>
+class CommandMessage : public MessageCommandBase
+{
+ public:
+       CommandMessage(Module* parent)
+               : MessageCommandBase(parent, MT)
+       {
+       }
+
+       CmdResult Handle(const std::vector<std::string>& parameters, User* user)
+       {
+               return HandleMessage(parameters, user, MT);
+       }
+};
+
+class ModuleCoreMessage : public Module
+{
+       CommandMessage<MSG_PRIVMSG> CommandPrivmsg;
+       CommandMessage<MSG_NOTICE> CommandNotice;
+
+ public:
+       ModuleCoreMessage()
+               : CommandPrivmsg(this), CommandNotice(this)
+       {
+       }
+
+       Version GetVersion()
+       {
+               return Version("PRIVMSG, NOTICE", VF_CORE|VF_VENDOR);
+       }
+};
+
+MODULE_INIT(ModuleCoreMessage)
diff --git a/src/coremods/core_reloadmodule.cpp b/src/coremods/core_reloadmodule.cpp
new file mode 100644 (file)
index 0000000..765c465
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+class CommandReloadmodule : public Command
+{
+ public:
+       /** Constructor for reloadmodule.
+        */
+       CommandReloadmodule ( Module* parent) : Command( parent, "RELOADMODULE",1) { flags_needed = 'o'; syntax = "<modulename>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+class ReloadModuleWorker : public HandlerBase1<void, bool>
+{
+ public:
+       const std::string name;
+       const std::string uid;
+       ReloadModuleWorker(const std::string& uuid, const std::string& modn)
+               : name(modn), uid(uuid) {}
+       void Call(bool result)
+       {
+               ServerInstance->SNO->WriteGlobalSno('a', "RELOAD MODULE: %s %ssuccessfully reloaded",
+                       name.c_str(), result ? "" : "un");
+               User* user = ServerInstance->FindNick(uid);
+               if (user)
+                       user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module %ssuccessfully reloaded.",
+                               name.c_str(), result ? "" : "un");
+               ServerInstance->GlobalCulls.AddItem(this);
+       }
+};
+
+CmdResult CommandReloadmodule::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters[0] == "cmd_reloadmodule.so")
+       {
+               user->WriteNumeric(RPL_LOADEDMODULE, "%s :You cannot reload cmd_reloadmodule.so (unload and load it)",
+                       parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       Module* m = ServerInstance->Modules->Find(parameters[0]);
+       if (m)
+       {
+               ServerInstance->Modules->Reload(m, new ReloadModuleWorker(user->uuid, parameters[0]));
+               return CMD_SUCCESS;
+       }
+       else
+       {
+               user->WriteNumeric(RPL_LOADEDMODULE, "%s :Could not find module by that name", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+}
+
+COMMAND_INIT(CommandReloadmodule)
diff --git a/src/coremods/core_server.cpp b/src/coremods/core_server.cpp
new file mode 100644 (file)
index 0000000..8c32daf
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /SERVER.
+ */
+class CommandServer : public Command
+{
+ public:
+       /** Constructor for server.
+        */
+       CommandServer ( Module* parent) : Command(parent,"SERVER") { works_before_reg = true;}
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandServer::Handle (const std::vector<std::string>&, User *user)
+{
+       if (user->registered == REG_ALL)
+       {
+               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You are already registered. (Perhaps your IRC client does not have a /SERVER command).");
+       }
+       else
+       {
+               user->WriteNumeric(ERR_NOTREGISTERED, ":You may not register as a server (servers have separate ports from clients, change your config)");
+       }
+       return CMD_FAILURE;
+}
+
+COMMAND_INIT(CommandServer)
diff --git a/src/coremods/core_squit.cpp b/src/coremods/core_squit.cpp
new file mode 100644 (file)
index 0000000..e64f5fc
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /SQUIT.
+ */
+class CommandSquit : public Command
+{
+ public:
+       /** Constructor for squit.
+        */
+       CommandSquit ( Module* parent) : Command(parent,"SQUIT",1,2) { flags_needed = 'o'; syntax = "<servername> [<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+
+/*
+ * This is handled by the server linking module, if necessary. Do not remove this stub.
+ */
+
+
+CmdResult CommandSquit::Handle (const std::vector<std::string>&, User *user)
+{
+       user->WriteServ( "NOTICE %s :Look into loading a linking module (like m_spanningtree) if you want this to do anything useful.", user->nick.c_str());
+       return CMD_FAILURE;
+}
+
+COMMAND_INIT(CommandSquit)
diff --git a/src/coremods/core_stats.cpp b/src/coremods/core_stats.cpp
new file mode 100644 (file)
index 0000000..8e74b83
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+
+#ifdef _WIN32
+#include <psapi.h>
+#pragma comment(lib, "psapi.lib") // For GetProcessMemoryInfo()
+#endif
+
+/** Handle /STATS.
+ */
+class CommandStats : public Command
+{
+       void DoStats(char statschar, User* user, string_list &results);
+ public:
+       /** Constructor for stats.
+        */
+       CommandStats ( Module* parent) : Command(parent,"STATS",1,2) { syntax = "<stats-symbol> [<servername>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               if (parameters.size() > 1)
+                       return ROUTE_UNICAST(parameters[1]);
+               return ROUTE_LOCALONLY;
+       }
+};
+
+void CommandStats::DoStats(char statschar, User* user, string_list &results)
+{
+       bool isPublic = ServerInstance->Config->UserStats.find(statschar) != std::string::npos;
+       bool isRemoteOper = IS_REMOTE(user) && (user->IsOper());
+       bool isLocalOperWithPrivs = IS_LOCAL(user) && user->HasPrivPermission("servers/auspex");
+
+       if (!isPublic && !isRemoteOper && !isLocalOperWithPrivs)
+       {
+               ServerInstance->SNO->WriteToSnoMask('t',
+                               "%s '%c' denied for %s (%s@%s)",
+                               (IS_LOCAL(user) ? "Stats" : "Remote stats"),
+                               statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
+               results.push_back("481 " + user->nick + " :Permission denied - STATS " + statschar + " requires the servers/auspex priv.");
+               return;
+       }
+
+       ModResult MOD_RESULT;
+       FIRST_MOD_RESULT(OnStats, MOD_RESULT, (statschar, user, results));
+       if (MOD_RESULT == MOD_RES_DENY)
+       {
+               results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report");
+               ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",
+                       (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
+               return;
+       }
+
+       switch (statschar)
+       {
+               /* stats p (show listening ports) */
+               case 'p':
+               {
+                       for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i)
+                       {
+                               ListenSocket* ls = *i;
+                               std::string ip = ls->bind_addr;
+                               if (ip.empty())
+                                       ip.assign("*");
+                               std::string type = ls->bind_tag->getString("type", "clients");
+                               std::string hook = ls->bind_tag->getString("ssl", "plaintext");
+
+                               results.push_back("249 "+user->nick+" :"+ ip + ":"+ConvToStr(ls->bind_port)+
+                                       " (" + type + ", " + hook + ")");
+                       }
+               }
+               break;
+
+               /* These stats symbols must be handled by a linking module */
+               case 'n':
+               case 'c':
+               break;
+
+               case 'i':
+               {
+                       for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
+                       {
+                               ConnectClass* c = *i;
+                               std::stringstream res;
+                               res << "215 " << user->nick << " I " << c->name << ' ';
+                               if (c->type == CC_ALLOW)
+                                       res << '+';
+                               if (c->type == CC_DENY)
+                                       res << '-';
+
+                               if (c->type == CC_NAMED)
+                                       res << '*';
+                               else
+                                       res << c->host;
+
+                               res << ' ' << c->config->getString("port", "*") << ' ';
+
+                               res << c->GetRecvqMax() << ' ' << c->GetSendqSoftMax() << ' ' << c->GetSendqHardMax()
+                                       << ' ' << c->GetCommandRate() << ' ' << c->GetPenaltyThreshold();
+                               if (c->fakelag)
+                                       res << '*';
+                               results.push_back(res.str());
+                       }
+               }
+               break;
+
+               case 'Y':
+               {
+                       int idx = 0;
+                       for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
+                       {
+                               ConnectClass* c = *i;
+                               results.push_back("215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : SocketEngine::GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *");
+                               results.push_back("218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+
+                                               ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout()));
+                               idx++;
+                       }
+               }
+               break;
+
+               case 'P':
+               {
+                       unsigned int idx = 0;
+                       for (std::list<User*>::const_iterator i = ServerInstance->Users->all_opers.begin(); i != ServerInstance->Users->all_opers.end(); ++i)
+                       {
+                               User* oper = *i;
+                               if (!oper->server->IsULine())
+                               {
+                                       LocalUser* lu = IS_LOCAL(oper);
+                                       results.push_back("249 " + user->nick + " :" + oper->nick + " (" + oper->ident + "@" + oper->dhost + ") Idle: " +
+                                                       (lu ? ConvToStr(ServerInstance->Time() - lu->idle_lastmsg) + " secs" : "unavailable"));
+                                       idx++;
+                               }
+                       }
+                       results.push_back("249 "+user->nick+" :"+ConvToStr(idx)+" OPER(s)");
+               }
+               break;
+
+               case 'k':
+                       ServerInstance->XLines->InvokeStats("K",216,user,results);
+               break;
+               case 'g':
+                       ServerInstance->XLines->InvokeStats("G",223,user,results);
+               break;
+               case 'q':
+                       ServerInstance->XLines->InvokeStats("Q",217,user,results);
+               break;
+               case 'Z':
+                       ServerInstance->XLines->InvokeStats("Z",223,user,results);
+               break;
+               case 'e':
+                       ServerInstance->XLines->InvokeStats("E",223,user,results);
+               break;
+               case 'E':
+               {
+                       const SocketEngine::Statistics& stats = SocketEngine::GetStats();
+                       results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(stats.TotalEvents));
+                       results.push_back("249 "+user->nick+" :Read events:  "+ConvToStr(stats.ReadEvents));
+                       results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(stats.WriteEvents));
+                       results.push_back("249 "+user->nick+" :Error events: "+ConvToStr(stats.ErrorEvents));
+                       break;
+               }
+
+               /* stats m (list number of times each command has been used, plus bytecount) */
+               case 'm':
+                       for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++)
+                       {
+                               if (i->second->use_count)
+                               {
+                                       /* RPL_STATSCOMMANDS */
+                                       results.push_back("212 "+user->nick+" "+i->second->name+" "+ConvToStr(i->second->use_count));
+                               }
+                       }
+               break;
+
+               /* stats z (debug and memory info) */
+               case 'z':
+               {
+                       results.push_back("249 "+user->nick+" :Users: "+ConvToStr(ServerInstance->Users->clientlist->size()));
+                       results.push_back("249 "+user->nick+" :Channels: "+ConvToStr(ServerInstance->chanlist->size()));
+                       results.push_back("249 "+user->nick+" :Commands: "+ConvToStr(ServerInstance->Parser->cmdlist.size()));
+
+                       float kbitpersec_in, kbitpersec_out, kbitpersec_total;
+                       char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30];
+
+                       SocketEngine::GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total);
+
+                       snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total);
+                       snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out);
+                       snprintf(kbitpersec_in_s, 30, "%03.5f", kbitpersec_in);
+
+                       results.push_back("249 "+user->nick+" :Bandwidth total:  "+ConvToStr(kbitpersec_total_s)+" kilobits/sec");
+                       results.push_back("249 "+user->nick+" :Bandwidth out:    "+ConvToStr(kbitpersec_out_s)+" kilobits/sec");
+                       results.push_back("249 "+user->nick+" :Bandwidth in:     "+ConvToStr(kbitpersec_in_s)+" kilobits/sec");
+
+#ifndef _WIN32
+                       /* Moved this down here so all the not-windows stuff (look w00tie, I didn't say win32!) is in one ifndef.
+                        * Also cuts out some identical code in both branches of the ifndef. -- Om
+                        */
+                       rusage R;
+
+                       /* Not sure why we were doing '0' with a RUSAGE_SELF comment rather than just using RUSAGE_SELF -- Om */
+                       if (!getrusage(RUSAGE_SELF,&R)) /* RUSAGE_SELF */
+                       {
+                               results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr(R.ru_maxrss)+"K");
+                               results.push_back("249 "+user->nick+" :Signals:          "+ConvToStr(R.ru_nsignals));
+                               results.push_back("249 "+user->nick+" :Page faults:      "+ConvToStr(R.ru_majflt));
+                               results.push_back("249 "+user->nick+" :Swaps:            "+ConvToStr(R.ru_nswap));
+                               results.push_back("249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw));
+
+                               char percent[30];
+
+                               float n_elapsed = (ServerInstance->Time() - ServerInstance->stats->LastSampled.tv_sec) * 1000000
+                                       + (ServerInstance->Time_ns() - ServerInstance->stats->LastSampled.tv_nsec) / 1000;
+                               float n_eaten = ((R.ru_utime.tv_sec - ServerInstance->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - ServerInstance->stats->LastCPU.tv_usec);
+                               float per = (n_eaten / n_elapsed) * 100;
+
+                               snprintf(percent, 30, "%03.5f%%", per);
+                               results.push_back("249 "+user->nick+" :CPU Use (now):    "+percent);
+
+                               n_elapsed = ServerInstance->Time() - ServerInstance->startup_time;
+                               n_eaten = (float)R.ru_utime.tv_sec + R.ru_utime.tv_usec / 100000.0;
+                               per = (n_eaten / n_elapsed) * 100;
+                               snprintf(percent, 30, "%03.5f%%", per);
+                               results.push_back("249 "+user->nick+" :CPU Use (total):  "+percent);
+                       }
+#else
+                       PROCESS_MEMORY_COUNTERS MemCounters;
+                       if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters)))
+                       {
+                               results.push_back("249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K");
+                               results.push_back("249 "+user->nick+" :Pagefile usage:   "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K");
+                               results.push_back("249 "+user->nick+" :Page faults:      "+ConvToStr(MemCounters.PageFaultCount));
+                       }
+
+                       FILETIME CreationTime;
+                       FILETIME ExitTime;
+                       FILETIME KernelTime;
+                       FILETIME UserTime;
+                       LARGE_INTEGER ThisSample;
+                       if(GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime) &&
+                               QueryPerformanceCounter(&ThisSample))
+                       {
+                               KernelTime.dwHighDateTime += UserTime.dwHighDateTime;
+                               KernelTime.dwLowDateTime += UserTime.dwLowDateTime;
+                               double n_eaten = (double)( ( (uint64_t)(KernelTime.dwHighDateTime - ServerInstance->stats->LastCPU.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime - ServerInstance->stats->LastCPU.dwLowDateTime) )/100000;
+                               double n_elapsed = (double)(ThisSample.QuadPart - ServerInstance->stats->LastSampled.QuadPart) / ServerInstance->stats->QPFrequency.QuadPart;
+                               double per = (n_eaten/n_elapsed);
+
+                               char percent[30];
+
+                               snprintf(percent, 30, "%03.5f%%", per);
+                               results.push_back("249 "+user->nick+" :CPU Use (now):    "+percent);
+
+                               n_elapsed = ServerInstance->Time() - ServerInstance->startup_time;
+                               n_eaten = (double)(( (uint64_t)(KernelTime.dwHighDateTime) << 32 ) + (uint64_t)(KernelTime.dwLowDateTime))/100000;
+                               per = (n_eaten / n_elapsed);
+                               snprintf(percent, 30, "%03.5f%%", per);
+                               results.push_back("249 "+user->nick+" :CPU Use (total):  "+percent);
+                       }
+#endif
+               }
+               break;
+
+               case 'T':
+               {
+                       results.push_back("249 "+user->nick+" :accepts "+ConvToStr(ServerInstance->stats->statsAccept)+" refused "+ConvToStr(ServerInstance->stats->statsRefused));
+                       results.push_back("249 "+user->nick+" :unknown commands "+ConvToStr(ServerInstance->stats->statsUnknown));
+                       results.push_back("249 "+user->nick+" :nick collisions "+ConvToStr(ServerInstance->stats->statsCollisions));
+                       results.push_back("249 "+user->nick+" :dns requests "+ConvToStr(ServerInstance->stats->statsDnsGood+ServerInstance->stats->statsDnsBad)+" succeeded "+ConvToStr(ServerInstance->stats->statsDnsGood)+" failed "+ConvToStr(ServerInstance->stats->statsDnsBad));
+                       results.push_back("249 "+user->nick+" :connection count "+ConvToStr(ServerInstance->stats->statsConnects));
+                       results.push_back(InspIRCd::Format("249 %s :bytes sent %5.2fK recv %5.2fK", user->nick.c_str(),
+                               ServerInstance->stats->statsSent / 1024.0, ServerInstance->stats->statsRecv / 1024.0));
+               }
+               break;
+
+               /* stats o */
+               case 'o':
+               {
+                       ConfigTagList tags = ServerInstance->Config->ConfTags("oper");
+                       for(ConfigIter i = tags.first; i != tags.second; ++i)
+                       {
+                               ConfigTag* tag = i->second;
+                               results.push_back("243 "+user->nick+" O "+tag->getString("host")+" * "+
+                                       tag->getString("name") + " " + tag->getString("type")+" 0");
+                       }
+               }
+               break;
+               case 'O':
+               {
+                       for (OperIndex::const_iterator i = ServerInstance->Config->OperTypes.begin(); i != ServerInstance->Config->OperTypes.end(); ++i)
+                       {
+                               OperInfo* tag = i->second;
+                               tag->init();
+                               std::string umodes;
+                               std::string cmodes;
+                               for(char c='A'; c < 'z'; c++)
+                               {
+                                       ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_USER);
+                                       if (mh && mh->NeedsOper() && tag->AllowedUserModes[c - 'A'])
+                                               umodes.push_back(c);
+                                       mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL);
+                                       if (mh && mh->NeedsOper() && tag->AllowedChanModes[c - 'A'])
+                                               cmodes.push_back(c);
+                               }
+                               results.push_back("243 "+user->nick+" O "+tag->name.c_str() + " " + umodes + " " + cmodes);
+                       }
+               }
+               break;
+
+               /* stats l (show user I/O stats) */
+               case 'l':
+                       results.push_back("211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open");
+                       for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
+                       {
+                               LocalUser* i = *n;
+                               results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
+                       }
+               break;
+
+               /* stats L (show user I/O stats with IP addresses) */
+               case 'L':
+                       results.push_back("211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open");
+                       for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
+                       {
+                               LocalUser* i = *n;
+                               results.push_back("211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
+                       }
+               break;
+
+               /* stats u (show server uptime) */
+               case 'u':
+               {
+                       time_t current_time = 0;
+                       current_time = ServerInstance->Time();
+                       time_t server_uptime = current_time - ServerInstance->startup_time;
+                       struct tm* stime;
+                       stime = gmtime(&server_uptime);
+                       /* i dont know who the hell would have an ircd running for over a year nonstop, but
+                        * Craig suggested this, and it seemed a good idea so in it went */
+                       if (stime->tm_year > 70)
+                       {
+                               results.push_back(InspIRCd::Format("242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d",
+                                       user->nick.c_str(), stime->tm_year - 70, stime->tm_yday, stime->tm_hour,
+                                       stime->tm_min, stime->tm_sec));
+                       }
+                       else
+                       {
+                               results.push_back(InspIRCd::Format("242 %s :Server up %d days, %.2d:%.2d:%.2d",
+                                       user->nick.c_str(), stime->tm_yday, stime->tm_hour, stime->tm_min,
+                                       stime->tm_sec));
+                       }
+               }
+               break;
+
+               default:
+               break;
+       }
+
+       results.push_back("219 "+user->nick+" "+statschar+" :End of /STATS report");
+       ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)",
+               (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str());
+       return;
+}
+
+CmdResult CommandStats::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() > 1 && parameters[1] != ServerInstance->Config->ServerName)
+               return CMD_SUCCESS;
+       string_list values;
+       char search = parameters[0][0];
+       DoStats(search, user, values);
+
+       const std::string p = ":" + ServerInstance->Config->ServerName + " ";
+       for (size_t i = 0; i < values.size(); i++)
+               user->SendText(p + values[i]);
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandStats)
diff --git a/src/coremods/core_unloadmodule.cpp b/src/coremods/core_unloadmodule.cpp
new file mode 100644 (file)
index 0000000..5d11e02
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /UNLOADMODULE.
+ */
+class CommandUnloadmodule : public Command
+{
+ public:
+       /** Constructor for unloadmodule.
+        */
+       CommandUnloadmodule ( Module* parent) : Command(parent,"UNLOADMODULE",1) { flags_needed = 'o'; syntax = "<modulename>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandUnloadmodule::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (!ServerInstance->Config->ConfValue("security")->getBool("allowcoreunload") &&
+               InspIRCd::Match(parameters[0], "cmd_*.so", ascii_case_insensitive_map))
+       {
+               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :You cannot unload core commands!", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       if (parameters[0] == "cmd_unloadmodule.so" || parameters[0] == "cmd_loadmodule.so")
+       {
+               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :You cannot unload module loading commands!", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       Module* m = ServerInstance->Modules->Find(parameters[0]);
+       if (m && ServerInstance->Modules->Unload(m))
+       {
+               ServerInstance->SNO->WriteGlobalSno('a', "MODULE UNLOADED: %s unloaded %s", user->nick.c_str(), parameters[0].c_str());
+               user->WriteNumeric(RPL_UNLOADEDMODULE, "%s :Module successfully unloaded.", parameters[0].c_str());
+       }
+       else
+       {
+               user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s :%s", parameters[0].c_str(),
+                       m ? ServerInstance->Modules->LastError().c_str() : "No such module");
+               return CMD_FAILURE;
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandUnloadmodule)
diff --git a/src/coremods/core_user/cmd_away.cpp b/src/coremods/core_user/cmd_away.cpp
new file mode 100644 (file)
index 0000000..4f61cec
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /AWAY.
+ */
+class CommandAway : public Command
+{
+ public:
+       /** Constructor for away.
+        */
+       CommandAway ( Module* parent) : Command(parent,"AWAY",0,0) { syntax = "[<message>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+/** Handle /AWAY
+ */
+CmdResult CommandAway::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       ModResult MOD_RESULT;
+
+       if ((parameters.size()) && (!parameters[0].empty()))
+       {
+               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, parameters[0]));
+
+               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
+                       return CMD_FAILURE;
+
+               user->awaytime = ServerInstance->Time();
+               user->awaymsg.assign(parameters[0], 0, ServerInstance->Config->Limits.MaxAway);
+
+               user->WriteNumeric(RPL_NOWAWAY, ":You have been marked as being away");
+       }
+       else
+       {
+               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, ""));
+
+               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
+                       return CMD_FAILURE;
+
+               user->awaymsg.clear();
+               user->WriteNumeric(RPL_UNAWAY, ":You are no longer marked as being away");
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandAway)
diff --git a/src/coremods/core_user/cmd_mode.cpp b/src/coremods/core_user/cmd_mode.cpp
new file mode 100644 (file)
index 0000000..d2e9b4f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /MODE.
+ */
+class CommandMode : public Command
+{
+ public:
+       /** Constructor for mode.
+        */
+       CommandMode ( Module* parent) : Command(parent,"MODE",1) { syntax = "<target> <modes> {<mode-parameters>}"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+
+/** Handle /MODE
+ */
+CmdResult CommandMode::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       ServerInstance->Modes->Process(parameters, user, (IS_LOCAL(user) ? ModeParser::MODE_NONE : ModeParser::MODE_LOCALONLY));
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandMode)
diff --git a/src/coremods/core_user/cmd_nick.cpp b/src/coremods/core_user/cmd_nick.cpp
new file mode 100644 (file)
index 0000000..486fce7
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /NICK.
+ */
+class CommandNick : public Command
+{
+ public:
+       /** Constructor for nick.
+        */
+       CommandNick ( Module* parent) : Command(parent,"NICK", 1, 1) { works_before_reg = true; syntax = "<newnick>"; Penalty = 0; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle nick changes from users.
+ * NOTE: If you are used to ircds based on ircd2.8, and are looking
+ * for the client introduction code in here, youre in the wrong place.
+ * You need to look in the spanningtree module for this!
+ */
+CmdResult CommandNick::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string oldnick = user->nick;
+       std::string newnick = parameters[0];
+
+       // anything except the initial NICK gets a flood penalty
+       if (user->registered == REG_ALL && IS_LOCAL(user))
+               IS_LOCAL(user)->CommandFloodPenalty += 4000;
+
+       if (newnick.empty())
+       {
+               user->WriteNumeric(ERR_ERRONEUSNICKNAME, "* :Erroneous Nickname");
+               return CMD_FAILURE;
+       }
+
+       if (newnick == "0")
+       {
+               newnick = user->uuid;
+       }
+       else if (!ServerInstance->IsNick(newnick))
+       {
+               user->WriteNumeric(ERR_ERRONEUSNICKNAME, "%s :Erroneous Nickname", newnick.c_str());
+               return CMD_FAILURE;
+       }
+
+       if (!user->ChangeNick(newnick, false))
+               return CMD_FAILURE;
+
+       if (user->registered < REG_NICKUSER)
+       {
+               user->registered = (user->registered | REG_NICK);
+               if (user->registered == REG_NICKUSER)
+               {
+                       /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */
+                       ModResult MOD_RESULT;
+                       FIRST_MOD_RESULT(OnUserRegister, MOD_RESULT, (IS_LOCAL(user)));
+                       if (MOD_RESULT == MOD_RES_DENY)
+                               return CMD_FAILURE;
+
+                       // return early to not penalize new users
+                       return CMD_SUCCESS;
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandNick)
diff --git a/src/coremods/core_user/cmd_part.cpp b/src/coremods/core_user/cmd_part.cpp
new file mode 100644 (file)
index 0000000..f427063
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /PART.
+ */
+class CommandPart : public Command
+{
+ public:
+       /** Constructor for part.
+        */
+       CommandPart (Module* parent) : Command(parent,"PART", 1, 2) { Penalty = 5; syntax = "<channel>{,<channel>} [<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+CmdResult CommandPart::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string reason;
+
+       if (IS_LOCAL(user))
+       {
+               if (!ServerInstance->Config->FixedPart.empty())
+                       reason = ServerInstance->Config->FixedPart;
+               else if (parameters.size() > 1)
+                       reason = ServerInstance->Config->PrefixPart + parameters[1] + ServerInstance->Config->SuffixPart;
+       }
+       else
+       {
+               if (parameters.size() > 1)
+                       reason = parameters[1];
+       }
+
+       if (CommandParser::LoopCall(user, this, parameters, 0))
+               return CMD_SUCCESS;
+
+       Channel* c = ServerInstance->FindChan(parameters[0]);
+
+       if (c)
+       {
+               c->PartUser(user, reason);
+       }
+       else
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str());
+               return CMD_FAILURE;
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandPart)
diff --git a/src/coremods/core_user/cmd_pass.cpp b/src/coremods/core_user/cmd_pass.cpp
new file mode 100644 (file)
index 0000000..66b2b57
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /PASS.
+ */
+class CommandPass : public SplitCommand
+{
+ public:
+       /** Constructor for pass.
+        */
+       CommandPass (Module* parent) : SplitCommand(parent,"PASS",1,1) { works_before_reg = true; Penalty = 0; syntax = "<password>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
+};
+
+
+CmdResult CommandPass::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
+{
+       // Check to make sure they haven't registered -- Fix by FCS
+       if (user->registered == REG_ALL)
+       {
+               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You may not reregister");
+               return CMD_FAILURE;
+       }
+       user->password = parameters[0];
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandPass)
diff --git a/src/coremods/core_user/cmd_ping.cpp b/src/coremods/core_user/cmd_ping.cpp
new file mode 100644 (file)
index 0000000..06135f8
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /PING.
+ */
+class CommandPing : public Command
+{
+ public:
+       /** Constructor for ping.
+        */
+       CommandPing ( Module* parent) : Command(parent,"PING", 1, 2) { Penalty = 0; syntax = "<servername> [:<servername>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandPing::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       user->WriteServ("PONG %s :%s", ServerInstance->Config->ServerName.c_str(), parameters[0].c_str());
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandPing)
diff --git a/src/coremods/core_user/cmd_pong.cpp b/src/coremods/core_user/cmd_pong.cpp
new file mode 100644 (file)
index 0000000..06db926
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /PONG.
+ */
+class CommandPong : public Command
+{
+ public:
+       /** Constructor for pong.
+        */
+       CommandPong ( Module* parent) : Command(parent,"PONG", 0, 1) { Penalty = 0; syntax = "<ping-text>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandPong::Handle (const std::vector<std::string>&, User *user)
+{
+       // set the user as alive so they survive to next ping
+       if (IS_LOCAL(user))
+               IS_LOCAL(user)->lastping = 1;
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandPong)
diff --git a/src/coremods/core_user/cmd_quit.cpp b/src/coremods/core_user/cmd_quit.cpp
new file mode 100644 (file)
index 0000000..15dc07d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /QUIT.
+ */
+class CommandQuit : public Command
+{
+ public:
+       /** Constructor for quit.
+        */
+       CommandQuit ( Module* parent) : Command(parent,"QUIT",0,1) { works_before_reg = true; syntax = "[<message>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
+       }
+};
+
+
+CmdResult CommandQuit::Handle (const std::vector<std::string>& parameters, User *user)
+{
+
+       std::string quitmsg;
+
+       if (IS_LOCAL(user))
+       {
+               if (!ServerInstance->Config->FixedQuit.empty())
+                       quitmsg = ServerInstance->Config->FixedQuit;
+               else
+                       quitmsg = parameters.size() ?
+                               ServerInstance->Config->PrefixQuit + parameters[0] + ServerInstance->Config->SuffixQuit
+                               : "Client exited";
+       }
+       else
+               quitmsg = parameters.size() ? parameters[0] : "Client exited";
+
+       std::string* operquit = ServerInstance->OperQuit.get(user);
+       ServerInstance->Users->QuitUser(user, quitmsg, operquit);
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandQuit)
diff --git a/src/coremods/core_user/cmd_user.cpp b/src/coremods/core_user/cmd_user.cpp
new file mode 100644 (file)
index 0000000..cec11c1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /USER.
+ */
+class CommandUser : public SplitCommand
+{
+ public:
+       /** Constructor for user.
+        */
+       CommandUser ( Module* parent) : SplitCommand(parent,"USER",4,4) { works_before_reg = true; Penalty = 0; syntax = "<username> <localhost> <remotehost> <GECOS>"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser *user);
+};
+
+CmdResult CommandUser::HandleLocal(const std::vector<std::string>& parameters, LocalUser *user)
+{
+       /* A user may only send the USER command once */
+       if (!(user->registered & REG_USER))
+       {
+               if (!ServerInstance->IsIdent(parameters[0]))
+               {
+                       /*
+                        * RFC says we must use this numeric, so we do. Let's make it a little more nub friendly though. :)
+                        *  -- Craig, and then w00t.
+                        */
+                       user->WriteNumeric(ERR_NEEDMOREPARAMS, "USER :Your username is not valid");
+                       return CMD_FAILURE;
+               }
+               else
+               {
+                       /*
+                        * The ident field is IDENTMAX+2 in size to account for +1 for the optional
+                        * ~ character, and +1 for null termination, therefore we can safely use up to
+                        * IDENTMAX here.
+                        */
+                       user->ChangeIdent(parameters[0]);
+                       user->fullname.assign(parameters[3].empty() ? "No info" : parameters[3], 0, ServerInstance->Config->Limits.MaxGecos);
+                       user->registered = (user->registered | REG_USER);
+               }
+       }
+       else
+       {
+               user->WriteNumeric(ERR_ALREADYREGISTERED, ":You may not reregister");
+               return CMD_FAILURE;
+       }
+
+       /* parameters 2 and 3 are local and remote hosts, and are ignored */
+       if (user->registered == REG_NICKUSER)
+       {
+               ModResult MOD_RESULT;
+
+               /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */
+               FIRST_MOD_RESULT(OnUserRegister, MOD_RESULT, (user));
+               if (MOD_RESULT == MOD_RES_DENY)
+                       return CMD_FAILURE;
+
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandUser)
diff --git a/src/coremods/core_userhost.cpp b/src/coremods/core_userhost.cpp
new file mode 100644 (file)
index 0000000..541402c
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /USERHOST.
+ */
+class CommandUserhost : public Command
+{
+ public:
+       /** Constructor for userhost.
+        */
+       CommandUserhost ( Module* parent) : Command(parent,"USERHOST", 1, 5) {
+               syntax = "<nick> {<nick>}";
+       }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string retbuf = "302 " + user->nick + " :";
+
+       for (unsigned int i = 0; i < parameters.size(); i++)
+       {
+               User *u = ServerInstance->FindNickOnly(parameters[i]);
+
+               if ((u) && (u->registered == REG_ALL))
+               {
+                       retbuf = retbuf + u->nick;
+
+                       if (u->IsOper())
+                               retbuf = retbuf + "*";
+
+                       retbuf = retbuf + "=";
+
+                       if (u->IsAway())
+                               retbuf += "-";
+                       else
+                               retbuf += "+";
+
+                       retbuf = retbuf + u->ident + "@";
+
+                       if (user->HasPrivPermission("users/auspex"))
+                       {
+                               retbuf = retbuf + u->host;
+                       }
+                       else
+                       {
+                               retbuf = retbuf + u->dhost;
+                       }
+
+                       retbuf = retbuf + " ";
+               }
+       }
+
+       user->WriteServ(retbuf);
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandUserhost)
diff --git a/src/coremods/core_wallops.cpp b/src/coremods/core_wallops.cpp
new file mode 100644 (file)
index 0000000..731eaf3
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /WALLOPS.
+ */
+class CommandWallops : public Command
+{
+       UserModeReference wallopsmode;
+
+ public:
+       /** Constructor for wallops.
+        */
+       CommandWallops(Module* parent)
+               : Command(parent, "WALLOPS", 1, 1)
+               , wallopsmode(parent, "wallops")
+       {
+               flags_needed = 'o';
+               syntax = "<any-text>";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return ROUTE_BROADCAST;
+       }
+};
+
+CmdResult CommandWallops::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string wallop("WALLOPS :");
+       wallop.append(parameters[0]);
+
+       for (LocalUserList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)
+       {
+               User* t = *i;
+               if (t->IsModeSet(wallopsmode))
+                       user->WriteTo(t,wallop);
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandWallops)
diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp
new file mode 100644 (file)
index 0000000..dc39e29
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /WHO.
+ */
+class CommandWho : public Command
+{
+       bool CanView(Channel* chan, User* user);
+       bool opt_viewopersonly;
+       bool opt_showrealhost;
+       bool opt_realname;
+       bool opt_mode;
+       bool opt_ident;
+       bool opt_metadata;
+       bool opt_port;
+       bool opt_away;
+       bool opt_local;
+       bool opt_far;
+       bool opt_time;
+       ChanModeReference secretmode;
+       ChanModeReference privatemode;
+       UserModeReference invisiblemode;
+
+       Membership* get_first_visible_channel(User* u)
+       {
+               for (UCListIter i = u->chans.begin(); i != u->chans.end(); ++i)
+               {
+                       Membership* memb = *i;
+                       if (!memb->chan->IsModeSet(secretmode))
+                               return memb;
+               }
+               return NULL;
+       }
+
+ public:
+       /** Constructor for who.
+        */
+       CommandWho(Module* parent)
+               : Command(parent, "WHO", 1)
+               , secretmode(parent, "secret")
+               , privatemode(parent, "private")
+               , invisiblemode(parent, "invisible")
+       {
+               syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]";
+       }
+
+       void SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string& initial, Membership* memb, User* u, std::vector<std::string>& whoresults);
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       bool whomatch(User* cuser, User* user, const char* matchtext);
+};
+
+bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
+{
+       bool match = false;
+       bool positive = false;
+
+       if (user->registered != REG_ALL)
+               return false;
+
+       if (opt_local && !IS_LOCAL(user))
+               return false;
+       else if (opt_far && IS_LOCAL(user))
+               return false;
+
+       if (opt_mode)
+       {
+               for (const char* n = matchtext; *n; n++)
+               {
+                       if (*n == '+')
+                       {
+                               positive = true;
+                               continue;
+                       }
+                       else if (*n == '-')
+                       {
+                               positive = false;
+                               continue;
+                       }
+                       if (user->IsModeSet(*n) != positive)
+                               return false;
+               }
+               return true;
+       }
+       else
+       {
+               /*
+                * This was previously one awesome pile of ugly nested if, when really, it didn't need
+                * to be, since only one condition was ever checked, a chained if works just fine.
+                * -- w00t
+                */
+               if (opt_metadata)
+               {
+                       match = false;
+                       const Extensible::ExtensibleStore& list = user->GetExtList();
+                       for(Extensible::ExtensibleStore::const_iterator i = list.begin(); i != list.end(); ++i)
+                               if (InspIRCd::Match(i->first->name, matchtext))
+                                       match = true;
+               }
+               else if (opt_realname)
+                       match = InspIRCd::Match(user->fullname, matchtext);
+               else if (opt_showrealhost)
+                       match = InspIRCd::Match(user->host, matchtext, ascii_case_insensitive_map);
+               else if (opt_ident)
+                       match = InspIRCd::Match(user->ident, matchtext, ascii_case_insensitive_map);
+               else if (opt_port)
+               {
+                       irc::portparser portrange(matchtext, false);
+                       long portno = -1;
+                       while ((portno = portrange.GetToken()))
+                               if (IS_LOCAL(user) && portno == IS_LOCAL(user)->GetServerPort())
+                               {
+                                       match = true;
+                                       break;
+                               }
+               }
+               else if (opt_away)
+                       match = InspIRCd::Match(user->awaymsg, matchtext);
+               else if (opt_time)
+               {
+                       long seconds = InspIRCd::Duration(matchtext);
+
+                       // Okay, so time matching, we want all users connected `seconds' ago
+                       if (user->age >= ServerInstance->Time() - seconds)
+                               match = true;
+               }
+
+               /*
+                * Once the conditionals have been checked, only check dhost/nick/server
+                * if they didn't match this user -- and only match if we don't find a match.
+                *
+                * This should make things minutely faster, and again, less ugly.
+                * -- w00t
+                */
+               if (!match)
+                       match = InspIRCd::Match(user->dhost, matchtext, ascii_case_insensitive_map);
+
+               if (!match)
+                       match = InspIRCd::Match(user->nick, matchtext);
+
+               /* Don't allow server name matches if HideWhoisServer is enabled, unless the command user has the priv */
+               if (!match && (ServerInstance->Config->HideWhoisServer.empty() || cuser->HasPrivPermission("users/auspex")))
+                       match = InspIRCd::Match(user->server->GetName(), matchtext);
+
+               return match;
+       }
+}
+
+bool CommandWho::CanView(Channel* chan, User* user)
+{
+       if (!user || !chan)
+               return false;
+
+       /* Bug #383 - moved higher up the list, because if we are in the channel
+        * we can see all its users
+        */
+       if (chan->HasUser(user))
+               return true;
+       /* Opers see all */
+       if (user->HasPrivPermission("users/auspex"))
+               return true;
+       /* Cant see inside a +s or a +p channel unless we are a member (see above) */
+       else if (!chan->IsModeSet(secretmode) && !chan->IsModeSet(privatemode))
+               return true;
+
+       return false;
+}
+
+void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string& initial, Membership* memb, User* u, std::vector<std::string>& whoresults)
+{
+       if (!memb)
+               memb = get_first_visible_channel(u);
+
+       std::string wholine = initial + (memb ? memb->chan->name : "*") + " " + u->ident + " " +
+               (opt_showrealhost ? u->host : u->dhost) + " ";
+       if (!ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"))
+               wholine.append(ServerInstance->Config->HideWhoisServer);
+       else
+               wholine.append(u->server->GetName());
+
+       wholine.append(" " + u->nick + " ");
+
+       /* away? */
+       if (u->IsAway())
+       {
+               wholine.append("G");
+       }
+       else
+       {
+               wholine.append("H");
+       }
+
+       /* oper? */
+       if (u->IsOper())
+       {
+               wholine.push_back('*');
+       }
+
+       if (memb)
+               wholine.push_back(memb->GetPrefixChar());
+
+       wholine.append(" :0 " + u->fullname);
+
+       FOREACH_MOD(OnSendWhoLine, (user, parms, u, memb, wholine));
+
+       if (!wholine.empty())
+               whoresults.push_back(wholine);
+}
+
+CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       /*
+        * XXX - RFC says:
+        *   The <name> passed to WHO is matched against users' host, server, real
+        *   name and nickname
+        * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
+        */
+
+       /* WHO options */
+       opt_viewopersonly = false;
+       opt_showrealhost = false;
+       opt_realname = false;
+       opt_mode = false;
+       opt_ident = false;
+       opt_metadata = false;
+       opt_port = false;
+       opt_away = false;
+       opt_local = false;
+       opt_far = false;
+       opt_time = false;
+
+       std::vector<std::string> whoresults;
+       std::string initial = "352 " + user->nick + " ";
+
+       /* Change '0' into '*' so the wildcard matcher can grok it */
+       std::string matchtext = ((parameters[0] == "0") ? "*" : parameters[0]);
+
+       // WHO flags count as a wildcard
+       bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?.") != std::string::npos));
+
+       if (parameters.size() > 1)
+       {
+               for (std::string::const_iterator iter = parameters[1].begin(); iter != parameters[1].end(); ++iter)
+               {
+                       switch (*iter)
+                       {
+                               case 'o':
+                                       opt_viewopersonly = true;
+                                       break;
+                               case 'h':
+                                       if (user->HasPrivPermission("users/auspex"))
+                                               opt_showrealhost = true;
+                                       break;
+                               case 'r':
+                                       opt_realname = true;
+                                       break;
+                               case 'm':
+                                       if (user->HasPrivPermission("users/auspex"))
+                                               opt_mode = true;
+                                       break;
+                               case 'M':
+                                       if (user->HasPrivPermission("users/auspex"))
+                                               opt_metadata = true;
+                                       break;
+                               case 'i':
+                                       opt_ident = true;
+                                       break;
+                               case 'p':
+                                       if (user->HasPrivPermission("users/auspex"))
+                                               opt_port = true;
+                                       break;
+                               case 'a':
+                                       opt_away = true;
+                                       break;
+                               case 'l':
+                                       if (user->HasPrivPermission("users/auspex") || ServerInstance->Config->HideWhoisServer.empty())
+                                               opt_local = true;
+                                       break;
+                               case 'f':
+                                       if (user->HasPrivPermission("users/auspex") || ServerInstance->Config->HideWhoisServer.empty())
+                                               opt_far = true;
+                                       break;
+                               case 't':
+                                       opt_time = true;
+                                       break;
+                       }
+               }
+       }
+
+
+       /* who on a channel? */
+       Channel* ch = ServerInstance->FindChan(matchtext);
+
+       if (ch)
+       {
+               if (CanView(ch,user))
+               {
+                       bool inside = ch->HasUser(user);
+
+                       /* who on a channel. */
+                       const UserMembList *cu = ch->GetUsers();
+
+                       for (UserMembCIter i = cu->begin(); i != cu->end(); i++)
+                       {
+                               /* None of this applies if we WHO ourselves */
+                               if (user != i->first)
+                               {
+                                       /* opers only, please */
+                                       if (opt_viewopersonly && !i->first->IsOper())
+                                               continue;
+
+                                       /* If we're not inside the channel, hide +i users */
+                                       if (i->first->IsModeSet(invisiblemode) && !inside && !user->HasPrivPermission("users/auspex"))
+                                               continue;
+                               }
+
+                               SendWhoLine(user, parameters, initial, i->second, i->first, whoresults);
+                       }
+               }
+       }
+       else
+       {
+               /* Match against wildcard of nick, server or host */
+               if (opt_viewopersonly)
+               {
+                       /* Showing only opers */
+                       for (std::list<User*>::iterator i = ServerInstance->Users->all_opers.begin(); i != ServerInstance->Users->all_opers.end(); i++)
+                       {
+                               User* oper = *i;
+
+                               if (whomatch(user, oper, matchtext.c_str()))
+                               {
+                                       if (!user->SharesChannelWith(oper))
+                                       {
+                                               if (usingwildcards && (!oper->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex")))
+                                                       continue;
+                                       }
+
+                                       SendWhoLine(user, parameters, initial, NULL, oper, whoresults);
+                               }
+                       }
+               }
+               else
+               {
+                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
+                       {
+                               if (whomatch(user, i->second, matchtext.c_str()))
+                               {
+                                       if (!user->SharesChannelWith(i->second))
+                                       {
+                                               if (usingwildcards && (i->second->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex")))
+                                                       continue;
+                                       }
+
+                                       SendWhoLine(user, parameters, initial, NULL, i->second, whoresults);
+                               }
+                       }
+               }
+       }
+       /* Send the results out */
+       for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
+               user->WriteServ(*n);
+       user->WriteNumeric(RPL_ENDOFWHO, "%s :End of /WHO list.", *parameters[0].c_str() ? parameters[0].c_str() : "*");
+
+       // Penalize the user a bit for large queries
+       // (add one unit of penalty per 200 results)
+       if (IS_LOCAL(user))
+               IS_LOCAL(user)->CommandFloodPenalty += whoresults.size() * 5;
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandWho)
diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp
new file mode 100644 (file)
index 0000000..bd0b624
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/** Handle /WHOIS.
+ */
+class CommandWhois : public SplitCommand
+{
+       ChanModeReference secretmode;
+       ChanModeReference privatemode;
+       UserModeReference snomaskmode;
+
+       void SplitChanList(User* source, User* dest, const std::string& cl);
+       void DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle);
+       std::string ChannelList(User* source, User* dest, bool spy);
+
+ public:
+       /** Constructor for whois.
+        */
+       CommandWhois(Module* parent)
+               : SplitCommand(parent, "WHOIS", 1)
+               , secretmode(parent, "secret")
+               , privatemode(parent, "private")
+               , snomaskmode(parent, "snomask")
+       {
+               Penalty = 2;
+               syntax = "<nick>{,<nick>}";
+       }
+
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user);
+       CmdResult HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target);
+};
+
+std::string CommandWhois::ChannelList(User* source, User* dest, bool spy)
+{
+       std::string list;
+
+       for (UCListIter i = dest->chans.begin(); i != dest->chans.end(); i++)
+       {
+               Membership* memb = *i;
+               Channel* c = memb->chan;
+               /* If the target is the sender, neither +p nor +s is set, or
+                * the channel contains the user, it is not a spy channel
+                */
+               if (spy != (source == dest || !(c->IsModeSet(privatemode) || c->IsModeSet(secretmode)) || c->HasUser(source)))
+               {
+                       list.push_back(memb->GetPrefixChar());
+                       list.append(c->name).push_back(' ');
+               }
+       }
+
+       return list;
+}
+
+void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl)
+{
+       std::string line;
+       std::ostringstream prefix;
+       std::string::size_type start, pos;
+
+       prefix << dest->nick << " :";
+       line = prefix.str();
+       int namelen = ServerInstance->Config->ServerName.length() + 6;
+
+       for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
+       {
+               if (line.length() + namelen + pos - start > 510)
+               {
+                       ServerInstance->SendWhoisLine(source, dest, 319, line);
+                       line = prefix.str();
+               }
+
+               line.append(cl.substr(start, pos - start + 1));
+       }
+
+       if (line.length() != prefix.str().length())
+       {
+               ServerInstance->SendWhoisLine(source, dest, 319, line);
+       }
+}
+
+void CommandWhois::DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle)
+{
+       ServerInstance->SendWhoisLine(user, dest, 311, "%s %s %s * :%s", dest->nick.c_str(), dest->ident.c_str(), dest->dhost.c_str(), dest->fullname.c_str());
+       if (user == dest || user->HasPrivPermission("users/auspex"))
+       {
+               ServerInstance->SendWhoisLine(user, dest, 378, "%s :is connecting from %s@%s %s", dest->nick.c_str(), dest->ident.c_str(), dest->host.c_str(), dest->GetIPString().c_str());
+       }
+
+       std::string cl = ChannelList(user, dest, false);
+       const ServerConfig::OperSpyWhoisState state = user->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE;
+
+       if (state == ServerConfig::SPYWHOIS_SINGLEMSG)
+               cl.append(ChannelList(user, dest, true));
+
+       SplitChanList(user, dest, cl);
+
+       if (state == ServerConfig::SPYWHOIS_SPLITMSG)
+       {
+               std::string scl = ChannelList(user, dest, true);
+               if (scl.length())
+               {
+                       ServerInstance->SendWhoisLine(user, dest, 336, "%s :is on private/secret channels:", dest->nick.c_str());
+                       SplitChanList(user, dest, scl);
+               }
+       }
+       if (user != dest && !ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"))
+       {
+               ServerInstance->SendWhoisLine(user, dest, 312, "%s %s :%s", dest->nick.c_str(), ServerInstance->Config->HideWhoisServer.c_str(), ServerInstance->Config->Network.c_str());
+       }
+       else
+       {
+               ServerInstance->SendWhoisLine(user, dest, 312, "%s %s :%s", dest->nick.c_str(), dest->server->GetName().c_str(), dest->server->GetDesc().c_str());
+       }
+
+       if (dest->IsAway())
+       {
+               ServerInstance->SendWhoisLine(user, dest, 301, "%s :%s", dest->nick.c_str(), dest->awaymsg.c_str());
+       }
+
+       if (dest->IsOper())
+       {
+               if (ServerInstance->Config->GenericOper)
+                       ServerInstance->SendWhoisLine(user, dest, 313, "%s :is an IRC operator", dest->nick.c_str());
+               else
+                       ServerInstance->SendWhoisLine(user, dest, 313, "%s :is %s %s on %s", dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper->name[0]) ? "an" : "a"),dest->oper->name.c_str(), ServerInstance->Config->Network.c_str());
+       }
+
+       if (user == dest || user->HasPrivPermission("users/auspex"))
+       {
+               if (dest->IsModeSet(snomaskmode))
+               {
+                       ServerInstance->SendWhoisLine(user, dest, 379, "%s :is using modes +%s %s", dest->nick.c_str(), dest->FormatModes(), snomaskmode->GetUserParameter(dest).c_str());
+               }
+               else
+               {
+                       ServerInstance->SendWhoisLine(user, dest, 379, "%s :is using modes +%s", dest->nick.c_str(), dest->FormatModes());
+               }
+       }
+
+       FOREACH_MOD(OnWhois, (user,dest));
+
+       /*
+        * We only send these if we've been provided them. That is, if hidewhois is turned off, and user is local, or
+        * if remote whois is queried, too. This is to keep the user hidden, and also since you can't reliably tell remote time. -- w00t
+        */
+       if ((idle) || (signon))
+       {
+               ServerInstance->SendWhoisLine(user, dest, 317, "%s %lu %lu :seconds idle, signon time", dest->nick.c_str(), idle, signon);
+       }
+
+       ServerInstance->SendWhoisLine(user, dest, 318, "%s :End of /WHOIS list.", dest->nick.c_str());
+}
+
+CmdResult CommandWhois::HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target)
+{
+       if (parameters.size() < 2)
+               return CMD_FAILURE;
+
+       User* user = ServerInstance->FindUUID(parameters[0]);
+       if (!user)
+               return CMD_FAILURE;
+
+       unsigned long idle = ConvToInt(parameters.back());
+       DoWhois(user, target, target->signon, idle);
+
+       return CMD_SUCCESS;
+}
+
+CmdResult CommandWhois::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user)
+{
+       User *dest;
+       int userindex = 0;
+       unsigned long idle = 0, signon = 0;
+
+       if (CommandParser::LoopCall(user, this, parameters, 0))
+               return CMD_SUCCESS;
+
+       /*
+        * If 2 paramters are specified (/whois nick nick), ignore the first one like spanningtree
+        * does, and use the second one, otherwise, use the only paramter. -- djGrrr
+        */
+       if (parameters.size() > 1)
+               userindex = 1;
+
+       dest = ServerInstance->FindNickOnly(parameters[userindex]);
+
+       if ((dest) && (dest->registered == REG_ALL))
+       {
+               /*
+                * Okay. Umpteenth attempt at doing this, so let's re-comment...
+                * For local users (/w localuser), we show idletime if hidewhois is disabled
+                * For local users (/w localuser localuser), we always show idletime, hence parameters.size() > 1 check.
+                * For remote users (/w remoteuser), we do NOT show idletime
+                * For remote users (/w remoteuser remoteuser), spanningtree will handle calling do_whois, so we can ignore this case.
+                * Thanks to djGrrr for not being impatient while I have a crap day coding. :p -- w00t
+                */
+               LocalUser* localuser = IS_LOCAL(dest);
+               if (localuser && (ServerInstance->Config->HideWhoisServer.empty() || parameters.size() > 1))
+               {
+                       idle = abs((long)((localuser->idle_lastmsg)-ServerInstance->Time()));
+                       signon = dest->signon;
+               }
+
+               DoWhois(user,dest,signon,idle);
+       }
+       else
+       {
+               /* no such nick/channel */
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", !parameters[userindex].empty() ? parameters[userindex].c_str() : "*");
+               user->WriteNumeric(RPL_ENDOFWHOIS, "%s :End of /WHOIS list.", !parameters[userindex].empty() ? parameters[userindex].c_str() : "*");
+               return CMD_FAILURE;
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandWhois)
diff --git a/src/coremods/core_whowas.cpp b/src/coremods/core_whowas.cpp
new file mode 100644 (file)
index 0000000..0a3a994
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "commands/cmd_whowas.h"
+
+CommandWhowas::CommandWhowas( Module* parent)
+       : Command(parent, "WHOWAS", 1)
+       , GroupSize(0), MaxGroups(0), MaxKeep(0)
+{
+       syntax = "<nick>{,<nick>}";
+       Penalty = 2;
+}
+
+CmdResult CommandWhowas::Handle (const std::vector<std::string>& parameters, User* user)
+{
+       /* if whowas disabled in config */
+       if (this->GroupSize == 0 || this->MaxGroups == 0)
+       {
+               user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :This command has been disabled.", name.c_str());
+               return CMD_FAILURE;
+       }
+
+       whowas_users::iterator i = whowas.find(assign(parameters[0]));
+
+       if (i == whowas.end())
+       {
+               user->WriteNumeric(ERR_WASNOSUCHNICK, "%s :There was no such nickname", parameters[0].c_str());
+       }
+       else
+       {
+               whowas_set* grp = i->second;
+               if (!grp->empty())
+               {
+                       for (whowas_set::iterator ux = grp->begin(); ux != grp->end(); ux++)
+                       {
+                               WhoWasGroup* u = *ux;
+
+                               user->WriteNumeric(RPL_WHOWASUSER, "%s %s %s * :%s", parameters[0].c_str(),
+                                       u->ident.c_str(),u->dhost.c_str(),u->gecos.c_str());
+
+                               if (user->HasPrivPermission("users/auspex"))
+                                       user->WriteNumeric(RPL_WHOWASIP, "%s :was connecting from *@%s",
+                                               parameters[0].c_str(), u->host.c_str());
+
+                               std::string signon = InspIRCd::TimeString(u->signon);
+                               bool hide_server = (!ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex"));
+                               user->WriteNumeric(RPL_WHOISSERVER, "%s %s :%s", parameters[0].c_str(), (hide_server ? ServerInstance->Config->HideWhoisServer.c_str() : u->server.c_str()), signon.c_str());
+                       }
+               }
+               else
+               {
+                       user->WriteNumeric(ERR_WASNOSUCHNICK, "%s :There was no such nickname", parameters[0].c_str());
+               }
+       }
+
+       user->WriteNumeric(RPL_ENDOFWHOWAS, "%s :End of WHOWAS", parameters[0].c_str());
+       return CMD_SUCCESS;
+}
+
+std::string CommandWhowas::GetStats()
+{
+       int whowas_size = 0;
+       int whowas_bytes = 0;
+       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
+       {
+               whowas_set* n = i->second;
+               whowas_size += n->size();
+               whowas_bytes += (sizeof(whowas_set) + ( sizeof(WhoWasGroup) * n->size() ) );
+       }
+       return "Whowas entries: " +ConvToStr(whowas_size)+" ("+ConvToStr(whowas_bytes)+" bytes)";
+}
+
+void CommandWhowas::AddToWhoWas(User* user)
+{
+       /* if whowas disabled */
+       if (this->GroupSize == 0 || this->MaxGroups == 0)
+       {
+               return;
+       }
+
+       // Insert nick if it doesn't exist
+       // 'first' will point to the newly inserted element or to the existing element with an equivalent key
+       std::pair<whowas_users::iterator, bool> ret = whowas.insert(std::make_pair(irc::string(user->nick.c_str()), static_cast<whowas_set*>(NULL)));
+
+       if (ret.second) // If inserted
+       {
+               // This nick is new, create a list for it and add the first record to it
+               whowas_set* n = new whowas_set;
+               n->push_back(new WhoWasGroup(user));
+               ret.first->second = n;
+
+               // Add this nick to the fifo too
+               whowas_fifo.push_back(std::make_pair(ServerInstance->Time(), ret.first->first));
+
+               if (whowas.size() > this->MaxGroups)
+               {
+                       // Too many nicks, remove the nick which was inserted the longest time ago from both the map and the fifo
+                       whowas_users::iterator it = whowas.find(whowas_fifo.front().second);
+                       if (it != whowas.end())
+                       {
+                               whowas_set* set = it->second;
+                               for (whowas_set::iterator i = set->begin(); i != set->end(); ++i)
+                                       delete *i;
+
+                               delete set;
+                               whowas.erase(it);
+                       }
+                       whowas_fifo.pop_front();
+               }
+       }
+       else
+       {
+               // We've met this nick before, add a new record to the list
+               whowas_set* set = ret.first->second;
+               set->push_back(new WhoWasGroup(user));
+
+               // If there are too many records for this nick, remove the oldest (front)
+               if (set->size() > this->GroupSize)
+               {
+                       delete set->front();
+                       set->pop_front();
+               }
+       }
+}
+
+/* on rehash, refactor maps according to new conf values */
+void CommandWhowas::Prune()
+{
+       time_t min = ServerInstance->Time() - this->MaxKeep;
+
+       /* first cut the list to new size (maxgroups) and also prune entries that are timed out. */
+       while (!whowas_fifo.empty())
+       {
+               if ((whowas_fifo.size() > this->MaxGroups) || (whowas_fifo.front().first < min))
+               {
+                       whowas_users::iterator iter = whowas.find(whowas_fifo.front().second);
+
+                       /* hopefully redundant integrity check, but added while debugging r6216 */
+                       if (iter == whowas.end())
+                       {
+                               /* this should never happen, if it does maps are corrupt */
+                               ServerInstance->Logs->Log("WHOWAS", LOG_DEFAULT, "BUG: Whowas maps got corrupted! (1)");
+                               return;
+                       }
+
+                       whowas_set* set = iter->second;
+                       for (whowas_set::iterator i = set->begin(); i != set->end(); ++i)
+                               delete *i;
+
+                       delete set;
+                       whowas.erase(iter);
+                       whowas_fifo.pop_front();
+               }
+               else
+                       break;
+       }
+
+       /* Then cut the whowas sets to new size (groupsize) */
+       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
+       {
+               whowas_set* n = i->second;
+               while (n->size() > this->GroupSize)
+               {
+                       delete n->front();
+                       n->pop_front();
+               }
+       }
+}
+
+/* call maintain once an hour to remove expired nicks */
+void CommandWhowas::Maintain()
+{
+       time_t min = ServerInstance->Time() - this->MaxKeep;
+       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
+       {
+               whowas_set* set = i->second;
+               while (!set->empty() && set->front()->signon < min)
+               {
+                       delete set->front();
+                       set->pop_front();
+               }
+       }
+}
+
+CommandWhowas::~CommandWhowas()
+{
+       for (whowas_users::iterator i = whowas.begin(); i != whowas.end(); ++i)
+       {
+               whowas_set* set = i->second;
+               for (whowas_set::iterator j = set->begin(); j != set->end(); ++j)
+                       delete *j;
+
+               delete set;
+       }
+}
+
+WhoWasGroup::WhoWasGroup(User* user) : host(user->host), dhost(user->dhost), ident(user->ident),
+       server(user->server->GetName()), gecos(user->fullname), signon(user->signon)
+{
+}
+
+class ModuleWhoWas : public Module
+{
+       CommandWhowas cmd;
+
+ public:
+       ModuleWhoWas() : cmd(this)
+       {
+       }
+
+       void OnGarbageCollect()
+       {
+               // Remove all entries older than MaxKeep
+               cmd.Maintain();
+       }
+
+       void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
+       {
+               cmd.AddToWhoWas(user);
+       }
+
+       ModResult OnStats(char symbol, User* user, string_list &results)
+       {
+               if (symbol == 'z')
+                       results.push_back("249 "+user->nick+" :"+cmd.GetStats());
+
+               return MOD_RES_PASSTHRU;
+       }
+
+       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+       {
+               ConfigTag* tag = ServerInstance->Config->ConfValue("whowas");
+               unsigned int NewGroupSize = tag->getInt("groupsize", 10, 0, 10000);
+               unsigned int NewMaxGroups = tag->getInt("maxgroups", 10240, 0, 1000000);
+               unsigned int NewMaxKeep = tag->getDuration("maxkeep", 3600, 3600);
+
+               if ((NewGroupSize == cmd.GroupSize) && (NewMaxGroups == cmd.MaxGroups) && (NewMaxKeep == cmd.MaxKeep))
+                       return;
+
+               cmd.GroupSize = NewGroupSize;
+               cmd.MaxGroups = NewMaxGroups;
+               cmd.MaxKeep = NewMaxKeep;
+               cmd.Prune();
+       }
+
+       Version GetVersion()
+       {
+               return Version("WHOWAS", VF_VENDOR);
+       }
+};
+
+MODULE_INIT(ModuleWhoWas)
diff --git a/src/coremods/core_xline/cmd_eline.cpp b/src/coremods/core_xline/cmd_eline.cpp
new file mode 100644 (file)
index 0000000..509089d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+
+/** Handle /ELINE.
+ */
+class CommandEline : public Command
+{
+ public:
+       /** Constructor for eline.
+        */
+       CommandEline ( Module* parent) : Command(parent,"ELINE",1,3) { flags_needed = 'o'; syntax = "<ident@host> [<duration> :<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+/** Handle /ELINE
+ */
+CmdResult CommandEline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string target = parameters[0];
+
+       if (parameters.size() >= 3)
+       {
+               IdentHostPair ih;
+               User* find = ServerInstance->FindNick(target);
+               if ((find) && (find->registered == REG_ALL))
+               {
+                       ih.first = "*";
+                       ih.second = find->GetIPString();
+                       target = std::string("*@") + find->GetIPString();
+               }
+               else
+                       ih = ServerInstance->XLines->IdentSplit(target);
+
+               if (ih.first.empty())
+               {
+                       user->WriteNotice("*** Target not found");
+                       return CMD_FAILURE;
+               }
+
+               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
+                       return CMD_FAILURE;
+
+               unsigned long duration = InspIRCd::Duration(parameters[1]);
+               ELine* el = new ELine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
+               if (ServerInstance->XLines->AddLine(el, user))
+               {
+                       if (!duration)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent E-line for %s: %s", user->nick.c_str(), target.c_str(), parameters[2].c_str());
+                       }
+                       else
+                       {
+                               time_t c_requires_crap = duration + ServerInstance->Time();
+                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed E-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
+                                               timestr.c_str(), parameters[2].c_str());
+                       }
+               }
+               else
+               {
+                       delete el;
+                       user->WriteNotice("*** E-Line for " + target + " already exists");
+               }
+       }
+       else
+       {
+               if (ServerInstance->XLines->DelLine(target.c_str(), "E", user))
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed E-line on %s",user->nick.c_str(),target.c_str());
+               }
+               else
+               {
+                       user->WriteNotice("*** E-Line " + target + " not found in list, try /stats e");
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandEline)
diff --git a/src/coremods/core_xline/cmd_gline.cpp b/src/coremods/core_xline/cmd_gline.cpp
new file mode 100644 (file)
index 0000000..18a661b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+
+/** Handle /GLINE.
+ */
+class CommandGline : public Command
+{
+ public:
+       /** Constructor for gline.
+        */
+       CommandGline (Module* parent) : Command(parent,"GLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+
+/** Handle /GLINE
+ */
+CmdResult CommandGline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string target = parameters[0];
+
+       if (parameters.size() >= 3)
+       {
+               IdentHostPair ih;
+               User* find = ServerInstance->FindNick(target);
+               if ((find) && (find->registered == REG_ALL))
+               {
+                       ih.first = "*";
+                       ih.second = find->GetIPString();
+                       target = std::string("*@") + find->GetIPString();
+               }
+               else
+                       ih = ServerInstance->XLines->IdentSplit(target);
+
+               if (ih.first.empty())
+               {
+                       user->WriteNotice("*** Target not found");
+                       return CMD_FAILURE;
+               }
+
+               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
+                       return CMD_FAILURE;
+
+               else if (target.find('!') != std::string::npos)
+               {
+                       user->WriteNotice("*** G-Line cannot operate on nick!user@host masks");
+                       return CMD_FAILURE;
+               }
+
+               unsigned long duration = InspIRCd::Duration(parameters[1]);
+               GLine* gl = new GLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
+               if (ServerInstance->XLines->AddLine(gl, user))
+               {
+                       if (!duration)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent G-line for %s: %s",user->nick.c_str(),target.c_str(), parameters[2].c_str());
+                       }
+                       else
+                       {
+                               time_t c_requires_crap = duration + ServerInstance->Time();
+                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed G-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
+                                               timestr.c_str(), parameters[2].c_str());
+                       }
+
+                       ServerInstance->XLines->ApplyLines();
+               }
+               else
+               {
+                       delete gl;
+                       user->WriteNotice("** G-Line for " + target + " already exists");
+               }
+
+       }
+       else
+       {
+               if (ServerInstance->XLines->DelLine(target.c_str(),"G",user))
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed G-line on %s",user->nick.c_str(),target.c_str());
+               }
+               else
+               {
+                       user->WriteNotice("*** G-Line " + target + " not found in list, try /stats g.");
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandGline)
diff --git a/src/coremods/core_xline/cmd_kline.cpp b/src/coremods/core_xline/cmd_kline.cpp
new file mode 100644 (file)
index 0000000..c6a8c7c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+
+/** Handle /KLINE.
+ */
+class CommandKline : public Command
+{
+ public:
+       /** Constructor for kline.
+        */
+       CommandKline ( Module* parent) : Command(parent,"KLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+
+/** Handle /KLINE
+ */
+CmdResult CommandKline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+    std::string target = parameters[0];
+
+       if (parameters.size() >= 3)
+       {
+               IdentHostPair ih;
+               User* find = ServerInstance->FindNick(target);
+               if ((find) && (find->registered == REG_ALL))
+               {
+                       ih.first = "*";
+                       ih.second = find->GetIPString();
+                       target = std::string("*@") + find->GetIPString();
+               }
+               else
+                       ih = ServerInstance->XLines->IdentSplit(target);
+
+        if (ih.first.empty())
+        {
+            user->WriteNotice("*** Target not found");
+            return CMD_FAILURE;
+        }
+
+               if (ServerInstance->HostMatchesEveryone(ih.first+"@"+ih.second,user))
+                       return CMD_FAILURE;
+
+               if (target.find('!') != std::string::npos)
+               {
+                       user->WriteNotice("*** K-Line cannot operate on nick!user@host masks");
+                       return CMD_FAILURE;
+               }
+
+               unsigned long duration = InspIRCd::Duration(parameters[1]);
+               KLine* kl = new KLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str());
+               if (ServerInstance->XLines->AddLine(kl,user))
+               {
+                       if (!duration)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent K-line for %s: %s",user->nick.c_str(),target.c_str(), parameters[2].c_str());
+                       }
+                       else
+                       {
+                               time_t c_requires_crap = duration + ServerInstance->Time();
+                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed K-line for %s, expires on %s: %s",user->nick.c_str(),target.c_str(),
+                                               timestr.c_str(), parameters[2].c_str());
+                       }
+
+                       ServerInstance->XLines->ApplyLines();
+               }
+               else
+               {
+                       delete kl;
+                       user->WriteNotice("*** K-Line for " + target + " already exists");
+               }
+       }
+       else
+       {
+               if (ServerInstance->XLines->DelLine(target.c_str(),"K",user))
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed K-line on %s",user->nick.c_str(),target.c_str());
+               }
+               else
+               {
+                       user->WriteNotice("*** K-Line " + target + " not found in list, try /stats k.");
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandKline)
diff --git a/src/coremods/core_xline/cmd_qline.cpp b/src/coremods/core_xline/cmd_qline.cpp
new file mode 100644 (file)
index 0000000..003aacb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+
+/** Handle /QLINE.  */
+class CommandQline : public Command
+{
+ public:
+       /** Constructor for qline.
+        */
+       CommandQline ( Module* parent) : Command(parent,"QLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<nick> [<duration> :<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param pcnt The number of parameters passed to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+
+CmdResult CommandQline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       if (parameters.size() >= 3)
+       {
+               if (ServerInstance->NickMatchesEveryone(parameters[0],user))
+                       return CMD_FAILURE;
+
+               if (parameters[0].find('@') != std::string::npos || parameters[0].find('!') != std::string::npos || parameters[0].find('.') != std::string::npos)
+               {
+                       user->WriteNotice("*** A Q-Line only bans a nick pattern, not a nick!user@host pattern.");
+                       return CMD_FAILURE;
+               }
+
+               unsigned long duration = InspIRCd::Duration(parameters[1]);
+               QLine* ql = new QLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
+               if (ServerInstance->XLines->AddLine(ql,user))
+               {
+                       if (!duration)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent Q-line for %s: %s",user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
+                       }
+                       else
+                       {
+                               time_t c_requires_crap = duration + ServerInstance->Time();
+                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed Q-line for %s, expires on %s: %s",user->nick.c_str(),parameters[0].c_str(),
+                                               timestr.c_str(), parameters[2].c_str());
+                       }
+                       ServerInstance->XLines->ApplyLines();
+               }
+               else
+               {
+                       delete ql;
+                       user->WriteNotice("*** Q-Line for " + parameters[0] + " already exists");
+               }
+       }
+       else
+       {
+               if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "Q", user))
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed Q-line on %s",user->nick.c_str(),parameters[0].c_str());
+               }
+               else
+               {
+                       user->WriteNotice("*** Q-Line " + parameters[0] + " not found in list, try /stats q.");
+                       return CMD_FAILURE;
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+
+COMMAND_INIT(CommandQline)
diff --git a/src/coremods/core_xline/cmd_zline.cpp b/src/coremods/core_xline/cmd_zline.cpp
new file mode 100644 (file)
index 0000000..eda5b2a
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2009 Matt Smith <dz@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd.  InspIRCd 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+/** Handle /ZLINE.
+ */
+class CommandZline : public Command
+{
+ public:
+       /** Constructor for zline.
+        */
+       CommandZline ( Module* parent) : Command(parent,"ZLINE",1,3) { flags_needed = 'o'; Penalty = 0; syntax = "<ipmask> [<duration> :<reason>]"; }
+       /** Handle command.
+        * @param parameters The parameters to the command
+        * @param user The user issuing the command
+        * @return A value from CmdResult to indicate command success or failure.
+        */
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+};
+
+CmdResult CommandZline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+       std::string target = parameters[0];
+
+       if (parameters.size() >= 3)
+       {
+               if (target.find('!') != std::string::npos)
+               {
+                       user->WriteNotice("*** You cannot include a nickname in a zline, a zline must ban only an IP mask");
+                       return CMD_FAILURE;
+               }
+
+               User *u = ServerInstance->FindNick(target);
+
+               if ((u) && (u->registered == REG_ALL))
+               {
+                       target = u->GetIPString();
+               }
+
+               const char* ipaddr = target.c_str();
+
+               if (strchr(ipaddr,'@'))
+               {
+                       while (*ipaddr != '@')
+                               ipaddr++;
+                       ipaddr++;
+               }
+
+               if (ServerInstance->IPMatchesEveryone(ipaddr,user))
+                       return CMD_FAILURE;
+
+               unsigned long duration = InspIRCd::Duration(parameters[1]);
+               ZLine* zl = new ZLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ipaddr);
+               if (ServerInstance->XLines->AddLine(zl,user))
+               {
+                       if (!duration)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent Z-line for %s: %s", user->nick.c_str(), ipaddr, parameters[2].c_str());
+                       }
+                       else
+                       {
+                               time_t c_requires_crap = duration + ServerInstance->Time();
+                               std::string timestr = InspIRCd::TimeString(c_requires_crap);
+                               ServerInstance->SNO->WriteToSnoMask('x',"%s added timed Z-line for %s, expires on %s: %s",user->nick.c_str(),ipaddr,
+                                               timestr.c_str(), parameters[2].c_str());
+                       }
+                       ServerInstance->XLines->ApplyLines();
+               }
+               else
+               {
+                       delete zl;
+                       user->WriteNotice("*** Z-Line for " + std::string(ipaddr) + " already exists");
+               }
+       }
+       else
+       {
+               if (ServerInstance->XLines->DelLine(target.c_str(),"Z",user))
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed Z-line on %s",user->nick.c_str(),target.c_str());
+               }
+               else
+               {
+                       user->WriteNotice("*** Z-Line " + target + " not found in list, try /stats Z.");
+                       return CMD_FAILURE;
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+COMMAND_INIT(CommandZline)