summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/channels.cpp5
-rw-r--r--src/commands/cmd_admin.cpp7
-rw-r--r--src/commands/cmd_commands.cpp6
-rw-r--r--src/commands/cmd_info.cpp7
-rw-r--r--src/commands/cmd_modules.cpp9
-rw-r--r--src/commands/cmd_whois.cpp16
-rw-r--r--src/configparser.cpp4
-rw-r--r--src/inspircd.cpp17
-rw-r--r--src/mode.cpp18
-rw-r--r--src/modules.cpp19
-rw-r--r--src/modules/m_alias.cpp4
-rw-r--r--src/modules/m_callerid.cpp13
-rw-r--r--src/modules/m_channames.cpp6
-rw-r--r--src/modules/m_dccallow.cpp4
-rw-r--r--src/modules/m_dnsbl.cpp9
-rw-r--r--src/modules/m_helpop.cpp10
-rw-r--r--src/modules/m_httpd.cpp48
-rw-r--r--src/modules/m_httpd_stats.cpp2
-rw-r--r--src/modules/m_ident.cpp2
-rw-r--r--src/modules/m_joinflood.cpp10
-rw-r--r--src/modules/m_mlock.cpp11
-rw-r--r--src/modules/m_override.cpp19
-rw-r--r--src/modules/m_permchannels.cpp6
-rw-r--r--src/modules/m_remove.cpp5
-rw-r--r--src/modules/m_ripemd160.cpp4
-rw-r--r--src/modules/m_sajoin.cpp3
-rw-r--r--src/modules/m_sasl.cpp11
-rw-r--r--src/modules/m_services_account.cpp41
-rw-r--r--src/modules/m_showwhois.cpp2
-rw-r--r--src/modules/m_silence.cpp4
-rw-r--r--src/modules/m_spanningtree/main.cpp12
-rw-r--r--src/modules/m_spanningtree/main.h5
-rw-r--r--src/modules/m_spanningtree/svsnick.cpp16
-rw-r--r--src/modules/m_spanningtree/utils.cpp2
-rw-r--r--src/modules/m_svshold.cpp26
-rw-r--r--src/modules/m_uninvite.cpp7
-rw-r--r--src/modules/m_userip.cpp2
-rw-r--r--src/socket.cpp14
-rw-r--r--src/users.cpp2
39 files changed, 301 insertions, 107 deletions
diff --git a/src/channels.cpp b/src/channels.cpp
index 563bc2704..5865f6724 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -654,7 +654,8 @@ const char* Channel::ChanModes(bool showkey)
*/
void Channel::UserList(User *user)
{
- if (this->IsModeSet(secretmode) && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex"))
+ bool has_privs = user->HasPrivPermission("channels/auspex");
+ if (this->IsModeSet(secretmode) && !this->HasUser(user) && !has_privs)
{
user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", this->name.c_str());
return;
@@ -679,7 +680,7 @@ void Channel::UserList(User *user)
{
if (i->first->quitting)
continue;
- if ((!has_user) && (i->first->IsModeSet(invisiblemode)))
+ if ((!has_user) && (i->first->IsModeSet(invisiblemode)) && (!has_privs))
{
/*
* user is +i, and source not on the channel, does not show
diff --git a/src/commands/cmd_admin.cpp b/src/commands/cmd_admin.cpp
index 3a3eed346..0d6c235f0 100644
--- a/src/commands/cmd_admin.cpp
+++ b/src/commands/cmd_admin.cpp
@@ -30,7 +30,12 @@ class CommandAdmin : public Command
public:
/** Constructor for admin.
*/
- CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0) { syntax = "[<servername>]"; }
+ CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0)
+ {
+ Penalty = 2;
+ syntax = "[<servername>]";
+ }
+
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
diff --git a/src/commands/cmd_commands.cpp b/src/commands/cmd_commands.cpp
index 190c883bd..c45616061 100644
--- a/src/commands/cmd_commands.cpp
+++ b/src/commands/cmd_commands.cpp
@@ -30,7 +30,11 @@ class CommandCommands : public Command
public:
/** Constructor for commands.
*/
- CommandCommands ( Module* parent) : Command(parent,"COMMANDS",0,0) { }
+ CommandCommands(Module* parent) : Command(parent,"COMMANDS",0,0)
+ {
+ Penalty = 3;
+ }
+
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
diff --git a/src/commands/cmd_info.cpp b/src/commands/cmd_info.cpp
index b3f146c30..7ee1c4d3b 100644
--- a/src/commands/cmd_info.cpp
+++ b/src/commands/cmd_info.cpp
@@ -32,7 +32,12 @@ class CommandInfo : public Command
public:
/** Constructor for info.
*/
- CommandInfo ( Module* parent) : Command(parent,"INFO") { syntax = "[<servermask>]"; }
+ CommandInfo(Module* parent) : Command(parent,"INFO")
+ {
+ Penalty = 4;
+ syntax = "[<servername>]";
+ }
+
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
diff --git a/src/commands/cmd_modules.cpp b/src/commands/cmd_modules.cpp
index fe199e7a4..d9fa7d5d5 100644
--- a/src/commands/cmd_modules.cpp
+++ b/src/commands/cmd_modules.cpp
@@ -31,7 +31,12 @@ class CommandModules : public Command
public:
/** Constructor for modules.
*/
- CommandModules ( Module* parent) : Command(parent,"MODULES",0,0) { syntax = "[server]"; }
+ CommandModules(Module* parent) : Command(parent,"MODULES",0,0)
+ {
+ Penalty = 4;
+ syntax = "[<servername>]";
+ }
+
/** Handle command.
* @param parameters The parameters to the comamnd
* @param pcnt The number of parameters passed to teh command
@@ -74,7 +79,7 @@ CmdResult CommandModules::Handle (const std::vector<std::string>& parameters, Us
Module* m = i->second;
Version V = m->GetVersion();
- if (user->HasPrivPermission("servers/auspex"))
+ if (IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"))
{
std::string flags("SvcC");
int pos = 0;
diff --git a/src/commands/cmd_whois.cpp b/src/commands/cmd_whois.cpp
index 7e67676ed..e8a751fa0 100644
--- a/src/commands/cmd_whois.cpp
+++ b/src/commands/cmd_whois.cpp
@@ -80,7 +80,7 @@ void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl
{
std::string line;
std::ostringstream prefix;
- std::string::size_type start, pos, length;
+ std::string::size_type start, pos;
prefix << dest->nick << " :";
line = prefix.str();
@@ -88,23 +88,13 @@ void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl
for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
{
- length = (pos == std::string::npos) ? cl.length() : pos;
-
- if (line.length() + namelen + length - start > 510)
+ if (line.length() + namelen + pos - start > 510)
{
ServerInstance->SendWhoisLine(source, dest, 319, line);
line = prefix.str();
}
- if(pos == std::string::npos)
- {
- line.append(cl.substr(start, length - start));
- break;
- }
- else
- {
- line.append(cl.substr(start, length - start + 1));
- }
+ line.append(cl.substr(start, pos - start + 1));
}
if (line.length() != prefix.str().length())
diff --git a/src/configparser.cpp b/src/configparser.cpp
index e23d6ec43..92f05edd4 100644
--- a/src/configparser.cpp
+++ b/src/configparser.cpp
@@ -499,10 +499,10 @@ std::string ConfigTag::getTagLocation()
return src_name + ":" + ConvToStr(src_line);
}
-ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*&items)
+ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*& Items)
{
ConfigTag* rv = new ConfigTag(Tag, file, line);
- items = &rv->items;
+ Items = &rv->items;
return rv;
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 75e9f3699..fb33f1937 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -161,13 +161,20 @@ void InspIRCd::QuickExit(int status)
exit(status);
}
+// Required for returning the proper value of EXIT_SUCCESS for the parent process
+static void VoidSignalHandler(int signalreceived)
+{
+ exit(0);
+}
+
bool InspIRCd::DaemonSeed()
{
#ifdef _WIN32
std::cout << "InspIRCd Process ID: " << con_green << GetCurrentProcessId() << con_reset << std::endl;
return true;
#else
- signal(SIGTERM, InspIRCd::QuickExit);
+ // Do not use QuickExit here: It will exit with status SIGTERM which would break e.g. daemon scripts
+ signal(SIGTERM, VoidSignalHandler);
int childpid = fork();
if (childpid < 0)
@@ -570,7 +577,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
if (!g)
{
- this->Logs->Log("STARTUP", LOG_DEFAULT, "getgrnam() failed (bad user?): %s", strerror(errno));
+ this->Logs->Log("STARTUP", LOG_DEFAULT, "getgrnam(%s) failed (wrong group?): %s", SetGroup.c_str(), strerror(errno));
this->QuickExit(0);
}
@@ -578,7 +585,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
if (ret == -1)
{
- this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid() failed (bad user?): %s", strerror(errno));
+ this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid() failed (wrong group?): %s", strerror(errno));
this->QuickExit(0);
}
}
@@ -593,7 +600,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
if (!u)
{
- this->Logs->Log("STARTUP", LOG_DEFAULT, "getpwnam() failed (bad user?): %s", strerror(errno));
+ this->Logs->Log("STARTUP", LOG_DEFAULT, "getpwnam(%s) failed (wrong user?): %s", SetUser.c_str(), strerror(errno));
this->QuickExit(0);
}
@@ -601,7 +608,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
if (ret == -1)
{
- this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid() failed (bad user?): %s", strerror(errno));
+ this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid() failed (wrong user?): %s", strerror(errno));
this->QuickExit(0);
}
}
diff --git a/src/mode.cpp b/src/mode.cpp
index e0381b683..ad46e602d 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -207,7 +207,12 @@ PrefixMode::PrefixMode(Module* Creator, const std::string& Name, char ModeLetter
ModeAction PrefixMode::OnModeChange(User* source, User*, Channel* chan, std::string& parameter, bool adding)
{
- User* target = ServerInstance->FindNick(parameter);
+ User* target;
+ if (IS_LOCAL(source))
+ target = ServerInstance->FindNickOnly(parameter);
+ else
+ target = ServerInstance->FindNick(parameter);
+
if (!target)
{
source->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameter.c_str());
@@ -347,9 +352,16 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
void ModeParser::Process(const std::vector<std::string>& parameters, User* user, ModeProcessFlag flags)
{
- std::string target = parameters[0];
+ const std::string& target = parameters[0];
Channel* targetchannel = ServerInstance->FindChan(target);
- User* targetuser = ServerInstance->FindNick(target);
+ User* targetuser = NULL;
+ if (!targetchannel)
+ {
+ if (IS_LOCAL(user))
+ targetuser = ServerInstance->FindNickOnly(target);
+ else
+ targetuser = ServerInstance->FindNick(target);
+ }
ModeType type = targetchannel ? MODETYPE_CHANNEL : MODETYPE_USER;
LastParse.clear();
diff --git a/src/modules.cpp b/src/modules.cpp
index 5c5e4febc..23aceb3e1 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -388,18 +388,23 @@ void ModuleManager::DoSafeUnload(Module* mod)
std::vector<reference<ExtensionItem> > items;
ServerInstance->Extensions.BeginUnregister(modfind->second, items);
/* Give the module a chance to tidy out all its metadata */
- for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+ for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); )
{
- mod->OnCleanup(TYPE_CHANNEL,c->second);
- c->second->doUnhookExtensions(items);
- const UserMembList* users = c->second->GetUsers();
+ Channel* chan = c->second;
+ ++c;
+ mod->OnCleanup(TYPE_CHANNEL, chan);
+ chan->doUnhookExtensions(items);
+ const UserMembList* users = chan->GetUsers();
for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
mi->second->doUnhookExtensions(items);
}
- for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
+ for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); )
{
- mod->OnCleanup(TYPE_USER,u->second);
- u->second->doUnhookExtensions(items);
+ User* user = u->second;
+ // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container
+ ++u;
+ mod->OnCleanup(TYPE_USER, user);
+ user->doUnhookExtensions(items);
}
for(char m='A'; m <= 'z'; m++)
{
diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp
index 065b9184e..b3b5f2c76 100644
--- a/src/modules/m_alias.cpp
+++ b/src/modules/m_alias.cpp
@@ -310,11 +310,11 @@ class ModuleAlias : public Module
for (unsigned int i = 0; i < newline.length(); i++)
{
char c = newline[i];
- if (c == '$')
+ if ((c == '$') && (i + 1 < newline.length()))
{
if (isdigit(newline[i+1]))
{
- int len = (newline[i+2] == '-') ? 3 : 2;
+ int len = ((i + 2 < newline.length()) && (newline[i+2] == '-')) ? 3 : 2;
std::string var = newline.substr(i, len);
result.append(GetVar(var, original_line));
i += len - 1;
diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp
index 3dc932958..6f2c67300 100644
--- a/src/modules/m_callerid.cpp
+++ b/src/modules/m_callerid.cpp
@@ -158,13 +158,18 @@ class CommandAccept : public Command
*/
typedef std::pair<User*, bool> ACCEPTAction;
- static ACCEPTAction GetTargetAndAction(std::string& tok)
+ static ACCEPTAction GetTargetAndAction(std::string& tok, User* cmdfrom = NULL)
{
bool remove = (tok[0] == '-');
if ((remove) || (tok[0] == '+'))
tok.erase(tok.begin());
- User* target = ServerInstance->FindNick(tok);
+ User* target;
+ if (!cmdfrom || !IS_LOCAL(cmdfrom))
+ target = ServerInstance->FindNick(tok);
+ else
+ target = ServerInstance->FindNickOnly(tok);
+
if ((!target) || (target->registered != REG_ALL) || (target->quitting) || (IS_SERVER(target)))
target = NULL;
@@ -216,7 +221,7 @@ public:
}
std::string tok = parameters[0];
- ACCEPTAction action = GetTargetAndAction(tok);
+ ACCEPTAction action = GetTargetAndAction(tok, user);
if (!action.first)
{
user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", tok.c_str());
@@ -248,7 +253,7 @@ public:
// Find the target
std::string targetstring = parameters[0];
- ACCEPTAction action = GetTargetAndAction(targetstring);
+ ACCEPTAction action = GetTargetAndAction(targetstring, user);
if (!action.first)
// Target is a "*" or source is local and the target is a list of nicks
return ROUTE_LOCALONLY;
diff --git a/src/modules/m_channames.cpp b/src/modules/m_channames.cpp
index 8b050df2b..f6d78037d 100644
--- a/src/modules/m_channames.cpp
+++ b/src/modules/m_channames.cpp
@@ -106,6 +106,12 @@ class ModuleChannelNames : public Module
ConfigTag* tag = ServerInstance->Config->ConfValue("channames");
std::string denyToken = tag->getString("denyrange");
std::string allowToken = tag->getString("allowrange");
+
+ if (!denyToken.compare(0, 2, "0-"))
+ denyToken[0] = '1';
+ if (!allowToken.compare(0, 2, "0-"))
+ allowToken[0] = '1';
+
allowedmap.set();
irc::portparser denyrange(denyToken, false);
diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp
index 487e4a7ed..7332402ba 100644
--- a/src/modules/m_dccallow.cpp
+++ b/src/modules/m_dccallow.cpp
@@ -225,6 +225,10 @@ class CommandDccallow : public Command
user->WriteNumeric(998, ": they will be removed from your DCCALLOW list.");
user->WriteNumeric(998, ": your DCCALLOW list will be deleted when you leave IRC.");
user->WriteNumeric(999, ":End of DCCALLOW HELP");
+
+ LocalUser* localuser = IS_LOCAL(user);
+ if (localuser)
+ localuser->CommandFloodPenalty += 4000;
}
void DisplayDCCAllowList(User* user)
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 10419de51..6ee1c317b 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -142,7 +142,10 @@ class DNSBLResolver : public DNS::Request
ServerInstance->XLines->ApplyLines();
}
else
+ {
delete kl;
+ return;
+ }
break;
}
case DNSBLConfEntry::I_GLINE:
@@ -157,7 +160,10 @@ class DNSBLResolver : public DNS::Request
ServerInstance->XLines->ApplyLines();
}
else
+ {
delete gl;
+ return;
+ }
break;
}
case DNSBLConfEntry::I_ZLINE:
@@ -172,7 +178,10 @@ class DNSBLResolver : public DNS::Request
ServerInstance->XLines->ApplyLines();
}
else
+ {
delete zl;
+ return;
+ }
break;
}
case DNSBLConfEntry::I_UNKNOWN:
diff --git a/src/modules/m_helpop.cpp b/src/modules/m_helpop.cpp
index 64bdc2400..2fe958a71 100644
--- a/src/modules/m_helpop.cpp
+++ b/src/modules/m_helpop.cpp
@@ -96,7 +96,6 @@ class CommandHelpop : public Command
class ModuleHelpop : public Module
{
- std::string h_file;
CommandHelpop cmd;
Helpop ho;
@@ -108,7 +107,7 @@ class ModuleHelpop : public Module
void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
{
- helpop_map.clear();
+ HelpopMap help;
ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
for(ConfigIter i = tags.first; i != tags.second; ++i)
@@ -123,20 +122,21 @@ class ModuleHelpop : public Module
throw ModuleException("m_helpop: The key 'index' is reserved for internal purposes. Please remove it.");
}
- helpop_map[key] = value;
+ help[key] = value;
}
- if (helpop_map.find("start") == helpop_map.end())
+ if (help.find("start") == help.end())
{
// error!
throw ModuleException("m_helpop: Helpop file is missing important entry 'start'. Please check the example conf.");
}
- else if (helpop_map.find("nohelp") == helpop_map.end())
+ else if (help.find("nohelp") == help.end())
{
// error!
throw ModuleException("m_helpop: Helpop file is missing important entry 'nohelp'. Please check the example conf.");
}
+ helpop_map.swap(help);
}
void OnWhois(User* src, User* dst) CXX11_OVERRIDE
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index 5a71f8018..735551dff 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -30,6 +30,7 @@ class ModuleHttpServer;
static ModuleHttpServer* HttpModule;
static bool claimed;
+static std::set<HttpServerSocket*> sockets;
/** HTTP socket states
*/
@@ -56,8 +57,11 @@ class HttpServerSocket : public BufferedSocket
std::string http_version;
public:
+ const time_t createtime;
+
HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
: BufferedSocket(newfd), ip(IP), postsize(0)
+ , createtime(ServerInstance->Time())
{
InternalState = HTTP_SERVE_WAIT_REQUEST;
@@ -66,6 +70,11 @@ class HttpServerSocket : public BufferedSocket
GetIOHook()->OnStreamSocketAccept(this, client, server);
}
+ ~HttpServerSocket()
+ {
+ sockets.erase(this);
+ }
+
void OnError(BufferedSocketError) CXX11_OVERRIDE
{
ServerInstance->GlobalCulls.AddItem(this);
@@ -347,6 +356,7 @@ class ModuleHttpServer : public Module
{
std::vector<HttpServerSocket *> httpsocks;
HTTPdAPIImpl APIImpl;
+ unsigned int timeoutsec;
public:
ModuleHttpServer()
@@ -359,6 +369,12 @@ class ModuleHttpServer : public Module
HttpModule = this;
}
+ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+ {
+ ConfigTag* tag = ServerInstance->Config->ConfValue("httpd");
+ timeoutsec = tag->getInt("timeout");
+ }
+
ModResult OnAcceptConnection(int nfd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE
{
if (from->bind_tag->getString("type") != "httpd")
@@ -366,17 +382,39 @@ class ModuleHttpServer : public Module
int port;
std::string incomingip;
irc::sockets::satoap(*client, incomingip, port);
- new HttpServerSocket(nfd, incomingip, from, client, server);
+ sockets.insert(new HttpServerSocket(nfd, incomingip, from, client, server));
return MOD_RES_ALLOW;
}
- ~ModuleHttpServer()
+ void OnBackgroundTimer(time_t curtime) CXX11_OVERRIDE
+ {
+ if (!timeoutsec)
+ return;
+
+ time_t oldest_allowed = curtime - timeoutsec;
+ for (std::set<HttpServerSocket*>::const_iterator i = sockets.begin(); i != sockets.end(); )
+ {
+ HttpServerSocket* sock = *i;
+ ++i;
+ if (sock->createtime < oldest_allowed)
+ {
+ sock->cull();
+ delete sock;
+ }
+ }
+ }
+
+ CullResult cull() CXX11_OVERRIDE
{
- for (size_t i = 0; i < httpsocks.size(); i++)
+ std::set<HttpServerSocket*> local;
+ local.swap(sockets);
+ for (std::set<HttpServerSocket*>::const_iterator i = local.begin(); i != local.end(); ++i)
{
- httpsocks[i]->cull();
- delete httpsocks[i];
+ HttpServerSocket* sock = *i;
+ sock->cull();
+ delete sock;
}
+ return Module::cull();
}
Version GetVersion() CXX11_OVERRIDE
diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp
index 346fe41f5..11809e893 100644
--- a/src/modules/m_httpd_stats.cpp
+++ b/src/modules/m_httpd_stats.cpp
@@ -52,7 +52,7 @@ class ModuleHttpStats : public Module
ret += it->second;
ret += ';';
}
- else if (*x == 0x9 || *x == 0xA || *x == 0xD || *x >= 0x20)
+ else if (*x == 0x09 || *x == 0x0A || *x == 0x0D || ((*x >= 0x20) && (*x <= 0x7e)))
{
// The XML specification defines the following characters as valid inside an XML document:
// Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp
index c73e26b16..1f57fc3e1 100644
--- a/src/modules/m_ident.cpp
+++ b/src/modules/m_ident.cpp
@@ -336,7 +336,7 @@ class ModuleIdent : public Module
/* wooo, got a result (it will be good, or bad) */
if (isock->result.empty())
{
- user->ident.insert(0, 1, '~');
+ user->ident.insert(user->ident.begin(), 1, '~');
user->WriteNotice("*** Could not find your ident, using " + user->ident + " instead.");
}
else
diff --git a/src/modules/m_joinflood.cpp b/src/modules/m_joinflood.cpp
index 81ad7e169..edce2b22c 100644
--- a/src/modules/m_joinflood.cpp
+++ b/src/modules/m_joinflood.cpp
@@ -124,12 +124,8 @@ class JoinFlood : public ModeHandler
if (!channel->IsModeSet(this))
return MODEACTION_DENY;
- joinfloodsettings* f = ext.get(channel);
- if (f)
- {
- ext.unset(channel);
- return MODEACTION_ALLOW;
- }
+ ext.unset(channel);
+ return MODEACTION_ALLOW;
}
return MODEACTION_DENY;
}
@@ -168,7 +164,7 @@ class ModuleJoinFlood : public Module
joinfloodsettings *f = jf.ext.get(memb->chan);
/* But all others are OK */
- if (f)
+ if ((f) && (!f->islocked()))
{
f->addjoin();
if (f->shouldlock())
diff --git a/src/modules/m_mlock.cpp b/src/modules/m_mlock.cpp
index 43eadf63e..22faa2119 100644
--- a/src/modules/m_mlock.cpp
+++ b/src/modules/m_mlock.cpp
@@ -31,12 +31,7 @@ public:
return Version("Implements the ability to have server-side MLOCK enforcement.", VF_VENDOR);
}
- void Prioritize()
- {
- ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
- }
-
- ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters) CXX11_OVERRIDE
+ ModResult OnRawMode(User* source, Channel* channel, const char mode, const std::string& parameter, bool adding, int pcnt)
{
if (!channel)
return MOD_RES_PASSTHRU;
@@ -48,11 +43,11 @@ public:
if (!mlock_str)
return MOD_RES_PASSTHRU;
- std::string::size_type p = parameters[1].find_first_of(*mlock_str);
+ std::string::size_type p = mlock_str->find(mode);
if (p != std::string::npos)
{
source->WriteNumeric(742, "%s %c %s :MODE cannot be set due to channel having an active MLOCK restriction policy",
- channel->name.c_str(), parameters[1][p], mlock_str->c_str());
+ channel->name.c_str(), mode, mlock_str->c_str());
return MOD_RES_DENY;
}
diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp
index ce9ea17e2..346d38b9f 100644
--- a/src/modules/m_override.cpp
+++ b/src/modules/m_override.cpp
@@ -35,6 +35,20 @@ class ModuleOverride : public Module
ChanModeReference key;
ChanModeReference limit;
+ static bool IsOverride(unsigned int userlevel, const std::string& modeline)
+ {
+ for (std::string::const_iterator i = modeline.begin(); i != modeline.end(); ++i)
+ {
+ ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
+ if (!mh)
+ continue;
+
+ if (mh->GetLevelRequired() > userlevel)
+ return true;
+ }
+ return false;
+ }
+
public:
ModuleOverride()
: topiclock(this, "topiclock")
@@ -110,7 +124,10 @@ class ModuleOverride : public Module
unsigned int mode = channel->GetPrefixValue(source);
- if (mode < HALFOP_VALUE && CanOverride(source, "MODE"))
+ if (!IsOverride(mode, parameters[1]))
+ return MOD_RES_PASSTHRU;
+
+ if (CanOverride(source, "MODE"))
{
std::string msg = source->nick+" overriding modes:";
for(unsigned int i=0; i < parameters.size(); i++)
diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp
index a0b3284e3..61080b2dd 100644
--- a/src/modules/m_permchannels.cpp
+++ b/src/modules/m_permchannels.cpp
@@ -165,10 +165,12 @@ class ModulePermanentChannels : public Module
{
PermChannel p;
bool dirty;
+ bool loaded;
bool save_listmodes;
public:
- ModulePermanentChannels() : p(this), dirty(false)
+ ModulePermanentChannels()
+ : p(this), dirty(false), loaded(false)
{
}
@@ -301,8 +303,6 @@ public:
// to be able to set the modes they provide (e.g.: m_stripcolor is inited after us)
// Prioritize() is called after all module initialization is complete, consequently
// all modes are available now
-
- static bool loaded = false;
if (loaded)
return;
diff --git a/src/modules/m_remove.cpp b/src/modules/m_remove.cpp
index 4dcd5aaa1..ed9b6ce25 100644
--- a/src/modules/m_remove.cpp
+++ b/src/modules/m_remove.cpp
@@ -60,7 +60,10 @@ class RemoveBase : public Command
const std::string& username = parameters[neworder ? 1 : 0];
/* Look up the user we're meant to be removing from the channel */
- target = ServerInstance->FindNick(username);
+ if (IS_LOCAL(user))
+ target = ServerInstance->FindNickOnly(username);
+ else
+ target = ServerInstance->FindNick(username);
/* And the channel we're meant to be removing them from */
channel = ServerInstance->FindChan(channame);
diff --git a/src/modules/m_ripemd160.cpp b/src/modules/m_ripemd160.cpp
index 41331543a..261cd1e27 100644
--- a/src/modules/m_ripemd160.cpp
+++ b/src/modules/m_ripemd160.cpp
@@ -149,6 +149,9 @@ typedef uint32_t dword;
class RIProv : public HashProvider
{
+ /** Final hash value
+ */
+ byte hashcode[RMDsize/8];
void MDinit(dword *MDbuf, unsigned int* key)
{
@@ -403,7 +406,6 @@ class RIProv : public HashProvider
byte *RMD(byte *message, dword length, unsigned int* key)
{
dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(E)) */
- static byte hashcode[RMDsize/8]; /* for final hash-value */
dword X[16]; /* current 16-word chunk */
unsigned int i; /* counter */
dword nbytes; /* # of bytes not yet processed */
diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp
index eda58ef96..0748c013b 100644
--- a/src/modules/m_sajoin.cpp
+++ b/src/modules/m_sajoin.cpp
@@ -60,7 +60,7 @@ class CommandSajoin : public Command
Channel* n = Channel::JoinUser(localuser, parameters[1], true);
if (n && n->HasUser(dest))
{
- ServerInstance->SNO->WriteToSnoMask('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+parameters[1]);
+ ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+parameters[1]);
return CMD_SUCCESS;
}
else
@@ -71,7 +71,6 @@ class CommandSajoin : public Command
}
else
{
- ServerInstance->SNO->WriteToSnoMask('a', user->nick+" sent remote SAJOIN to make "+dest->nick+" join "+parameters[1]);
return CMD_SUCCESS;
}
}
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp
index 1d67f0c02..796d343ea 100644
--- a/src/modules/m_sasl.cpp
+++ b/src/modules/m_sasl.cpp
@@ -91,20 +91,23 @@ class SaslAuthenticator
{
case SASL_INIT:
this->agent = msg[0];
- this->user->Write("AUTHENTICATE %s", msg[3].c_str());
this->state = SASL_COMM;
- break;
+ /* fall through */
case SASL_COMM:
if (msg[0] != this->agent)
return this->state;
- if (msg[2] != "D")
+ if (msg[2] == "C")
this->user->Write("AUTHENTICATE %s", msg[3].c_str());
- else
+ else if (msg[2] == "D")
{
this->state = SASL_DONE;
this->result = this->GetSaslResult(msg[3]);
}
+ else if (msg[2] == "M")
+ this->user->WriteNumeric(908, "%s %s :are available SASL mechanisms", this->user->nick.c_str(), msg[3].c_str());
+ else
+ ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Services sent an unknown SASL message \"%s\" \"%s\"", msg[2].c_str(), msg[3].c_str());
break;
case SASL_DONE:
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index 5f288424c..8ab9c9a3b 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -102,6 +102,24 @@ class AChannel_M : public SimpleChannelModeHandler
AChannel_M(Module* Creator) : SimpleChannelModeHandler(Creator, "regmoderated", 'M') { }
};
+static bool ReadCGIIRCExt(const char* extname, User* user, const std::string*& out)
+{
+ ExtensionItem* wiext = ServerInstance->Extensions.GetItem(extname);
+ if (!wiext)
+ return false;
+
+ if (wiext->creator->ModuleSourceFile != "m_cgiirc.so")
+ return false;
+
+ StringExtItem* stringext = static_cast<StringExtItem*>(wiext);
+ std::string* addr = stringext->get(user);
+ if (!addr)
+ return false;
+
+ out = addr;
+ return true;
+}
+
class AccountExtItemImpl : public AccountExtItem
{
public:
@@ -121,8 +139,19 @@ class AccountExtItemImpl : public AccountExtItem
{
// Logged in
if (IS_LOCAL(user))
- user->WriteNumeric(900, "%s %s :You are now logged in as %s",
- user->GetFullHost().c_str(), value.c_str(), value.c_str());
+ {
+ const std::string* host = &user->dhost;
+ if (user->registered != REG_ALL)
+ {
+ if (!ReadCGIIRCExt("cgiirc_webirc_hostname", user, host))
+ {
+ ReadCGIIRCExt("cgiirc_webirc_ip", user, host);
+ }
+ }
+
+ user->WriteNumeric(900, "%s!%s@%s %s :You are now logged in as %s",
+ user->nick.c_str(), user->ident.c_str(), host->c_str(), value.c_str(), value.c_str());
+ }
AccountEvent(creator, user, value).Send();
}
@@ -142,6 +171,7 @@ class ModuleServicesAccount : public Module
Channel_r m4;
User_r m5;
AccountExtItemImpl accountname;
+ bool checking_ban;
public:
ModuleServicesAccount() : m1(this), m2(this), m3(this), m4(this), m5(this),
accountname(this)
@@ -219,8 +249,7 @@ class ModuleServicesAccount : public Module
ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask) CXX11_OVERRIDE
{
- static bool checking = false;
- if (checking)
+ if (checking_ban)
return MOD_RES_PASSTHRU;
if ((mask.length() > 2) && (mask[1] == ':'))
@@ -240,9 +269,9 @@ class ModuleServicesAccount : public Module
/* If we made it this far we know the user isn't registered
so just deny if it matches */
- checking = true;
+ checking_ban = true;
bool result = chan->CheckBan(user, mask.substr(2));
- checking = false;
+ checking_ban = false;
if (result)
return MOD_RES_DENY;
diff --git a/src/modules/m_showwhois.cpp b/src/modules/m_showwhois.cpp
index 7a3b2d352..783f7d3fe 100644
--- a/src/modules/m_showwhois.cpp
+++ b/src/modules/m_showwhois.cpp
@@ -42,7 +42,7 @@ class SeeWhois : public SimpleUserModeHandler
class WhoisNoticeCmd : public Command
{
public:
- WhoisNoticeCmd(Module* Creator) : Command(Creator,"WHOISNOTICE", 1)
+ WhoisNoticeCmd(Module* Creator) : Command(Creator,"WHOISNOTICE", 2)
{
flags_needed = FLAG_SERVERONLY;
}
diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp
index fe7418621..3a213c6e7 100644
--- a/src/modules/m_silence.cpp
+++ b/src/modules/m_silence.cpp
@@ -85,7 +85,7 @@ class CommandSVSSilence : public Command
if (IS_LOCAL(u))
{
- ServerInstance->Parser->CallHandler("SILENCE", std::vector<std::string>(++parameters.begin(), parameters.end()), u);
+ ServerInstance->Parser->CallHandler("SILENCE", std::vector<std::string>(parameters.begin() + 1, parameters.end()), u);
}
return CMD_SUCCESS;
@@ -301,7 +301,7 @@ class ModuleSilence : public Module
void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
{
- maxsilence = ServerInstance->Config->ConfValue("showwhois")->getInt("maxentries", 32);
+ maxsilence = ServerInstance->Config->ConfValue("silence")->getInt("maxentries", 32);
if (!maxsilence)
maxsilence = 32;
}
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 9a7cddec3..671e10269 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -38,6 +38,7 @@
ModuleSpanningTree::ModuleSpanningTree()
: rconnect(this), rsquit(this), map(this)
, commands(NULL), DNS(this, "DNS")
+ , KeepNickTS(false)
{
}
@@ -246,7 +247,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
{
bool ipvalid = true;
- if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+ if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
{
ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Not connecting to myself.");
return;
@@ -377,9 +378,9 @@ ModResult ModuleSpanningTree::HandleConnect(const std::vector<std::string>& para
for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++)
{
Link* x = *i;
- if (InspIRCd::Match(x->Name.c_str(),parameters[0]))
+ if (InspIRCd::Match(x->Name.c_str(),parameters[0], rfc_case_insensitive_map))
{
- if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+ if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
{
RemoteMessage(user, "*** CONNECT: Server \002%s\002 is ME, not connecting.",x->Name.c_str());
return MOD_RES_DENY;
@@ -529,7 +530,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
if (user->registered != REG_ALL || !IS_LOCAL(user))
return;
- CmdBuilder(user, "FNAME").push(gecos).Broadcast();
+ CmdBuilder(user, "FNAME").push_last(gecos).Broadcast();
}
void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident)
@@ -587,11 +588,12 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick)
/** IMPORTANT: We don't update the TS if the oldnick is just a case change of the newnick!
*/
- if (irc::string(user->nick.c_str()) != assign(oldnick))
+ if ((irc::string(user->nick.c_str()) != assign(oldnick)) && (!this->KeepNickTS))
user->age = ServerInstance->Time();
params.push_back(ConvToStr(user->age));
params.Broadcast();
+ this->KeepNickTS = false;
}
else if (!loopCall && user->nick == user->uuid)
{
diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h
index 513e86a2f..12667aebf 100644
--- a/src/modules/m_spanningtree/main.h
+++ b/src/modules/m_spanningtree/main.h
@@ -77,6 +77,11 @@ class ModuleSpanningTree : public Module
*/
bool SplitInProgress;
+ /** If true OnUserPostNick() won't update the nick TS before sending the NICK,
+ * used when handling SVSNICK.
+ */
+ bool KeepNickTS;
+
/** Constructor
*/
ModuleSpanningTree();
diff --git a/src/modules/m_spanningtree/svsnick.cpp b/src/modules/m_spanningtree/svsnick.cpp
index a504afbd7..b3480eb55 100644
--- a/src/modules/m_spanningtree/svsnick.cpp
+++ b/src/modules/m_spanningtree/svsnick.cpp
@@ -20,6 +20,7 @@
#include "inspircd.h"
+#include "main.h"
#include "commands.h"
CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameters)
@@ -32,17 +33,28 @@ CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameter
if (isdigit(nick[0]))
nick = u->uuid;
+ // Don't update the TS if the nick is exactly the same
+ if (u->nick == nick)
+ return CMD_FAILURE;
+
+ time_t NickTS = ConvToInt(parameters[2]);
+ if (NickTS <= 0)
+ return CMD_FAILURE;
+
+ ModuleSpanningTree* st = (ModuleSpanningTree*)(Module*)creator;
+ st->KeepNickTS = true;
+ u->age = NickTS;
+
if (!u->ForceNickChange(nick))
{
/* buh. UID them */
if (!u->ForceNickChange(u->uuid))
{
ServerInstance->Users->QuitUser(u, "Nickname collision");
- return CMD_SUCCESS;
}
}
- u->age = ConvToInt(parameters[2]);
+ st->KeepNickTS = false;
}
return CMD_SUCCESS;
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index fd51fb6b4..de96b073d 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -363,7 +363,7 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name)
for (std::vector<reference<Link> >::iterator i = LinkBlocks.begin(); i != LinkBlocks.end(); ++i)
{
Link* x = *i;
- if (InspIRCd::Match(x->Name.c_str(), name.c_str()))
+ if (InspIRCd::Match(x->Name.c_str(), name.c_str(), rfc_case_insensitive_map))
{
return x;
}
diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp
index b1b454e63..c821f63bb 100644
--- a/src/modules/m_svshold.cpp
+++ b/src/modules/m_svshold.cpp
@@ -23,6 +23,11 @@
#include "inspircd.h"
#include "xline.h"
+namespace
+{
+ bool silent;
+}
+
/** Holds a SVSHold item
*/
class SVSHold : public XLine
@@ -48,6 +53,15 @@ public:
return InspIRCd::Match(s, nickname);
}
+ void DisplayExpiry()
+ {
+ if (!silent)
+ {
+ ServerInstance->SNO->WriteToSnoMask('x', "Removing expired SVSHOLD %s (set by %s %ld seconds ago)",
+ nickname.c_str(), source.c_str(), (long)(ServerInstance->Time() - set_time));
+ }
+ }
+
const std::string& Displayable()
{
return nickname;
@@ -99,7 +113,8 @@ class CommandSvshold : public Command
{
if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "SVSHOLD", user))
{
- ServerInstance->SNO->WriteToSnoMask('x',"%s removed SVSHOLD on %s",user->nick.c_str(),parameters[0].c_str());
+ if (!silent)
+ ServerInstance->SNO->WriteToSnoMask('x',"%s removed SVSHOLD on %s",user->nick.c_str(),parameters[0].c_str());
}
else
{
@@ -116,6 +131,9 @@ class CommandSvshold : public Command
if (ServerInstance->XLines->AddLine(r, user))
{
+ if (silent)
+ return CMD_SUCCESS;
+
if (!duration)
{
ServerInstance->SNO->WriteGlobalSno('x', "%s added permanent SVSHOLD for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
@@ -159,6 +177,12 @@ class ModuleSVSHold : public Module
ServerInstance->XLines->RegisterFactory(&s);
}
+ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+ {
+ ConfigTag* tag = ServerInstance->Config->ConfValue("svshold");
+ silent = tag->getBool("silent");
+ }
+
ModResult OnStats(char symbol, User* user, string_list &out) CXX11_OVERRIDE
{
if(symbol != 'S')
diff --git a/src/modules/m_uninvite.cpp b/src/modules/m_uninvite.cpp
index 6eaeb285f..97ad841f1 100644
--- a/src/modules/m_uninvite.cpp
+++ b/src/modules/m_uninvite.cpp
@@ -35,7 +35,12 @@ class CommandUninvite : public Command
CmdResult Handle (const std::vector<std::string> &parameters, User *user)
{
- User* u = ServerInstance->FindNick(parameters[0]);
+ User* u;
+ if (IS_LOCAL(user))
+ u = ServerInstance->FindNickOnly(parameters[0]);
+ else
+ u = ServerInstance->FindNick(parameters[0]);
+
Channel* c = ServerInstance->FindChan(parameters[1]);
if ((!c) || (!u) || (u->registered != REG_ALL))
diff --git a/src/modules/m_userip.cpp b/src/modules/m_userip.cpp
index f4e67d6bf..96505a047 100644
--- a/src/modules/m_userip.cpp
+++ b/src/modules/m_userip.cpp
@@ -40,7 +40,7 @@ class CommandUserip : public Command
for (int i = 0; i < (int)parameters.size(); i++)
{
- User *u = ServerInstance->FindNick(parameters[i]);
+ User *u = ServerInstance->FindNickOnly(parameters[i]);
if ((u) && (u->registered == REG_ALL))
{
// Anyone may query their own IP
diff --git a/src/socket.cpp b/src/socket.cpp
index 9ec7544f2..4ebed1ccd 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -262,35 +262,41 @@ bool irc::sockets::sockaddrs::operator==(const irc::sockets::sockaddrs& other) c
static void sa2cidr(irc::sockets::cidr_mask& cidr, const irc::sockets::sockaddrs& sa, int range)
{
const unsigned char* base;
+ unsigned char target_byte;
cidr.type = sa.sa.sa_family;
+
+ memset(cidr.bits, 0, sizeof(cidr.bits));
+
if (cidr.type == AF_INET)
{
+ target_byte = sizeof(sa.in4.sin_addr);
base = (unsigned char*)&sa.in4.sin_addr;
if (range > 32)
range = 32;
}
else if (cidr.type == AF_INET6)
{
+ target_byte = sizeof(sa.in6.sin6_addr);
base = (unsigned char*)&sa.in6.sin6_addr;
if (range > 128)
range = 128;
}
else
{
- base = (unsigned char*)"";
- range = 0;
+ cidr.length = 0;
+ return;
}
cidr.length = range;
unsigned int border = range / 8;
unsigned int bitmask = (0xFF00 >> (range & 7)) & 0xFF;
- for(unsigned int i=0; i < 16; i++)
+ for(unsigned int i=0; i < target_byte; i++)
{
if (i < border)
cidr.bits[i] = base[i];
else if (i == border)
cidr.bits[i] = base[i] & bitmask;
else
- cidr.bits[i] = 0;
+ return;
}
}
diff --git a/src/users.cpp b/src/users.cpp
index eff72033d..dab3aad6c 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -761,7 +761,7 @@ const std::string& User::GetIPString()
irc::sockets::satoap(client_sa, cachedip, port);
/* IP addresses starting with a : on irc are a Bad Thing (tm) */
if (cachedip[0] == ':')
- cachedip.insert(0,1,'0');
+ cachedip.insert(cachedip.begin(),1,'0');
}
return cachedip;