summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base64.cpp2
-rw-r--r--src/channels.cpp15
-rw-r--r--src/command.cpp2
-rw-r--r--src/config.cpp2
-rw-r--r--src/logger.cpp4
-rw-r--r--src/protocol.cpp3
-rw-r--r--src/servers.cpp2
-rw-r--r--src/socket_transport.cpp15
-rw-r--r--src/sockets.cpp42
-rw-r--r--src/users.cpp40
-rw-r--r--src/version.sh2
-rw-r--r--src/win32/anope_windows.h2
12 files changed, 83 insertions, 48 deletions
diff --git a/src/base64.cpp b/src/base64.cpp
index 420290a34..d4d9ff43e 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -159,7 +159,7 @@ void Anope::B64Decode(const Anope::string &src, Anope::string &target)
state = 0;
}
}
- if (!target[target.length() - 1])
+ if (!target.empty() && !target[target.length() - 1])
target.erase(target.length() - 1);
}
diff --git a/src/channels.cpp b/src/channels.cpp
index fe0e0600b..27e186b83 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -85,13 +85,17 @@ void Channel::Reset()
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
this->SetCorrectModes(it->second->user, true);
- this->Sync();
+ // If the channel is syncing now, do not force a sync due to Reset(), as we are probably iterating over users in Message::SJoin
+ // A sync will come soon
+ if (!syncing)
+ this->Sync();
}
void Channel::Sync()
{
syncing = false;
FOREACH_MOD(OnChannelSync, (this));
+ CheckModes();
}
void Channel::CheckModes()
@@ -727,11 +731,7 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
vsnprintf(buf, BUFSIZE - 1, reason, args);
va_end(args);
- /* May not kick ulines */
- if (u->server->IsULined())
- return false;
-
- /* Do not kick protected clients */
+ /* Do not kick protected clients or Ulines */
if (u->IsProtected())
return false;
@@ -863,9 +863,6 @@ bool Channel::CheckKick(User *user)
/* We don't enforce services restrictions on clients on ulined services
* as this will likely lead to kick/rejoin floods. ~ Viper */
- if (user->server->IsULined())
- return false;
-
if (user->IsProtected())
return false;
diff --git a/src/command.cpp b/src/command.cpp
index fe1f9e30d..6aa2f744b 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -218,7 +218,7 @@ void Command::Run(CommandSource &source, const Anope::string &message)
if (it == source.service->commands.end())
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s %s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
source.Reply(_("Unknown command \002%s\002."), message.c_str());
return;
diff --git a/src/config.cpp b/src/config.cpp
index 3dd7b6c69..734be17d3 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -97,7 +97,7 @@ template<> time_t Block::Get(const Anope::string &tag, const Anope::string &def)
template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) const
{
const Anope::string &str = Get<const Anope::string>(tag, def);
- return str.equals_ci("yes") || str.equals_ci("on") || str.equals_ci("true");
+ return !str.empty() && !str.equals_ci("no") && !str.equals_ci("off") && !str.equals_ci("false") && !str.equals_ci("0");
}
static void ValidateNotEmpty(const Anope::string &block, const Anope::string &name, const Anope::string &value)
diff --git a/src/logger.cpp b/src/logger.cpp
index 76cb328d4..445e71949 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -75,7 +75,7 @@ const Anope::string &LogFile::GetName() const
return this->filename;
}
-Log::Log(LogType t, const Anope::string &cat, BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), type(t), category(cat)
+Log::Log(LogType t, const Anope::string &cat, BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(t), category(cat)
{
}
@@ -116,7 +116,7 @@ Log::Log(BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NUL
{
}
-Log::Log(Module *mod, const Anope::string &cat) : bi(NULL), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
+Log::Log(Module *mod, const Anope::string &cat, BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), source(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
{
}
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 2287447b6..01c8d31c8 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -322,6 +322,9 @@ bool IRCDProto::IsChannelValid(const Anope::string &chan)
if (chan.empty() || chan[0] != '#' || chan.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
return false;
+ if (chan.find_first_of(" ,") != Anope::string::npos)
+ return false;
+
return true;
}
diff --git a/src/servers.cpp b/src/servers.cpp
index 7699e64ca..0adeb6727 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -38,7 +38,7 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
if (!ssid.empty())
Servers::ByID[ssid] = this;
- Log(this, "connect") << "uplinked to " << (this->uplink ? this->uplink->GetName() : "no uplink") << " connected to the network";
+ Log(this, "connect") << "has connected to the network (uplinked to " << (this->uplink ? this->uplink->GetName() : "no uplink") << ")";
/* Add this server to our uplinks leaf list */
if (this->uplink)
diff --git a/src/socket_transport.cpp b/src/socket_transport.cpp
index 72b712232..1476d0662 100644
--- a/src/socket_transport.cpp
+++ b/src/socket_transport.cpp
@@ -29,8 +29,10 @@ bool BufferedSocket::ProcessRead()
this->recv_len = 0;
int len = this->io->Recv(this, tbuffer, sizeof(tbuffer) - 1);
- if (len <= 0)
+ if (len == 0)
return false;
+ if (len < 0)
+ return SocketEngine::IgnoreErrno();
tbuffer[len] = 0;
this->read_buffer.append(tbuffer);
@@ -42,8 +44,11 @@ bool BufferedSocket::ProcessRead()
bool BufferedSocket::ProcessWrite()
{
int count = this->io->Send(this, this->write_buffer);
- if (count <= -1)
+ if (count == 0)
return false;
+ if (count < 0)
+ return SocketEngine::IgnoreErrno();
+
this->write_buffer = this->write_buffer.substr(count);
if (this->write_buffer.empty())
SocketEngine::Change(this, false, SF_WRITABLE);
@@ -58,8 +63,8 @@ const Anope::string BufferedSocket::GetLine()
return "";
Anope::string str = this->read_buffer.substr(0, s + 1);
this->read_buffer.erase(0, s + 1);
- this->read_buffer.ltrim();
- return str.trim();
+ this->read_buffer.ltrim("\r\n");
+ return str.trim("\r\n");
}
void BufferedSocket::Write(const char *buffer, size_t l)
@@ -162,6 +167,8 @@ bool BinarySocket::ProcessWrite()
void BinarySocket::Write(const char *buffer, size_t l)
{
+ if (l == 0)
+ return;
this->write_buffer.push_back(new DataBlock(buffer, l));
SocketEngine::Change(this, true, SF_WRITABLE);
}
diff --git a/src/sockets.cpp b/src/sockets.cpp
index e71505d44..f047c5f44 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -348,15 +348,17 @@ size_t cidr::hash::operator()(const cidr &s) const
int SocketIO::Recv(Socket *s, char *buf, size_t sz)
{
- size_t i = recv(s->GetFD(), buf, sz, 0);
- TotalRead += i;
+ int i = recv(s->GetFD(), buf, sz, 0);
+ if (i > 0)
+ TotalRead += i;
return i;
}
int SocketIO::Send(Socket *s, const char *buf, size_t sz)
{
- size_t i = send(s->GetFD(), buf, sz, 0);
- TotalWritten += i;
+ int i = send(s->GetFD(), buf, sz, 0);
+ if (i > 0)
+ TotalWritten += i;
return i;
}
@@ -402,7 +404,7 @@ void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int por
int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size());
if (c == -1)
{
- if (Anope::LastErrorCode() != EINPROGRESS)
+ if (!SocketEngine::IgnoreErrno())
s->OnError(Anope::LastError());
else
{
@@ -515,8 +517,8 @@ ListenSocket::ListenSocket(const Anope::string &bindip, int port, bool i)
{
this->SetBlocking(false);
- const char op = 1;
- setsockopt(this->GetFD(), SOL_SOCKET, SO_REUSEADDR, &op, sizeof(op));
+ const int op = 1;
+ setsockopt(this->GetFD(), SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&op), sizeof(op));
this->bindaddr.pton(i ? AF_INET6 : AF_INET, bindip, port);
this->io->Bind(this, bindip, port);
@@ -542,3 +544,29 @@ bool ListenSocket::ProcessRead()
return true;
}
+int SocketEngine::GetLastError()
+{
+#ifndef _WIN32
+ return errno;
+#else
+ return WSAGetLastError();
+#endif
+}
+
+void SocketEngine::SetLastError(int err)
+{
+#ifndef _WIN32
+ errno = err;
+#else
+ WSASetLastError(err);
+#endif
+}
+
+bool SocketEngine::IgnoreErrno()
+{
+ return GetLastError() == EAGAIN
+ || GetLastError() == EWOULDBLOCK
+ || GetLastError() == EINTR
+ || GetLastError() == EINPROGRESS;
+}
+
diff --git a/src/users.cpp b/src/users.cpp
index 55a3a84ab..b9564a2d5 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -303,9 +303,9 @@ void User::Identify(NickAlias *na)
na->last_seen = Anope::CurTime;
}
- this->Login(na->nc);
+ IRCD->SendLogin(this, na);
- IRCD->SendLogin(this);
+ this->Login(na->nc);
FOREACH_MOD(OnNickIdentify, (this));
@@ -463,6 +463,12 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
this->modes[um->name] = param;
+ if (um->name == "OPER")
+ ++OperCount;
+
+ if (um->name == "CLOAK" || um->name == "VHOST")
+ this->UpdateHost();
+
FOREACH_MOD(OnUserModeSet, (source, this, um->name));
}
@@ -473,6 +479,15 @@ void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
this->modes.erase(um->name);
+ if (um->name == "OPER")
+ --OperCount;
+
+ if (um->name == "CLOAK" || um->name == "VHOST")
+ {
+ this->vhost.clear();
+ this->UpdateHost();
+ }
+
FOREACH_MOD(OnUserModeUnset, (source, this, um->name));
}
@@ -592,20 +607,6 @@ void User::SetModesInternal(const MessageSource &source, const char *umodes, ...
}
else
this->RemoveModeInternal(source, um);
-
- if (um->name == "OPER")
- {
- if (add)
- ++OperCount;
- else
- --OperCount;
- }
- else if (um->name == "CLOAK" || um->name == "VHOST")
- {
- if (!add && !this->vhost.empty())
- this->vhost.clear();
- this->UpdateHost();
- }
}
}
@@ -641,12 +642,9 @@ ChanUserContainer *User::FindChannel(Channel *c) const
return NULL;
}
-bool User::IsProtected() const
+bool User::IsProtected()
{
- if (this->HasMode("PROTECTED") || this->HasMode("GOD"))
- return true;
-
- return false;
+ return this->HasMode("PROTECTED") || this->HasMode("GOD") || this->HasPriv("protected") || (this->server && this->server->IsULined());
}
void User::Kill(const MessageSource &source, const Anope::string &reason)
diff --git a/src/version.sh b/src/version.sh
index f043eafb9..9cb652e24 100644
--- a/src/version.sh
+++ b/src/version.sh
@@ -3,5 +3,5 @@
VERSION_MAJOR="2"
VERSION_MINOR="0"
VERSION_PATCH="0"
-VERSION_EXTRA="-rc1"
+VERSION_EXTRA="-rc3"
diff --git a/src/win32/anope_windows.h b/src/win32/anope_windows.h
index d2077b1c9..ad561f9b3 100644
--- a/src/win32/anope_windows.h
+++ b/src/win32/anope_windows.h
@@ -59,6 +59,8 @@
#include "pthread/pthread.h"
#include "sigaction/sigaction.h"
+typedef int ssize_t;
+
namespace Anope
{
class string;