summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-04-07 23:46:44 -0500
committerAdam <Adam@anope.org>2013-04-07 23:46:44 -0500
commitfb7fef7a849342ab8463743497e781c5c3e6ae88 (patch)
tree5d230a68b6eed70c7b4f718410dd62fea779654c /src
parent36602224b8b1a11326a224779d16bcb12f0ed532 (diff)
Optimizations of much of the more commonly used code
Diffstat (limited to 'src')
-rw-r--r--src/access.cpp10
-rw-r--r--src/bots.cpp4
-rw-r--r--src/channels.cpp115
-rw-r--r--src/config.cpp11
-rw-r--r--src/hashcomp.cpp80
-rw-r--r--src/logger.cpp209
-rw-r--r--src/main.cpp3
-rw-r--r--src/messages.cpp15
-rw-r--r--src/misc.cpp6
-rw-r--r--src/modes.cpp219
-rw-r--r--src/process.cpp29
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/regchannel.cpp31
-rw-r--r--src/servers.cpp56
-rw-r--r--src/users.cpp24
15 files changed, 418 insertions, 396 deletions
diff --git a/src/access.cpp b/src/access.cpp
index dd5881108..7a178b446 100644
--- a/src/access.cpp
+++ b/src/access.cpp
@@ -152,18 +152,18 @@ Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data)
return access;
}
-bool ChanAccess::Matches(const User *u, const NickCore *nc) const
+bool ChanAccess::Matches(const User *u, const NickCore *acc) const
{
bool is_mask = this->mask.find_first_of("!@?*") != Anope::string::npos;
if (u && is_mask && Anope::Match(u->nick, this->mask))
return true;
else if (u && Anope::Match(u->GetDisplayedMask(), this->mask))
return true;
- else if (nc)
- for (unsigned i = nc->aliases->size(); i > 0; --i)
+ else if (acc)
+ for (unsigned i = 0; i < acc->aliases->size(); ++i)
{
- const NickAlias *na = nc->aliases->at(i - 1);
- if (na && Anope::Match(na->nick, this->mask))
+ const NickAlias *na = acc->aliases->at(i);
+ if (Anope::Match(na->nick, this->mask))
return true;
}
return false;
diff --git a/src/bots.cpp b/src/bots.cpp
index 698a37f4e..f1a96eacf 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -224,8 +224,8 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
{
- Channel *c = Channel::Find(chname);
- return this->Join(c ? c : new Channel(chname), status);
+ bool c;
+ return this->Join(Channel::FindOrCreate(chname, c), status);
}
void BotInfo::Part(Channel *c, const Anope::string &reason)
diff --git a/src/channels.cpp b/src/channels.cpp
index 8e4074352..f3a061e94 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -33,11 +33,6 @@ Channel::Channel(const Anope::string &nname, time_t ts)
this->name = nname;
- size_t old = ChannelList.size();
- ChannelList[this->name] = this;
- if (old == ChannelList.size())
- Log(LOG_DEBUG) << "Duplicate channel " << this->name << " in table?";
-
this->creation_time = ts;
this->server_modetime = this->chanserv_modetime = 0;
this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0;
@@ -46,7 +41,8 @@ Channel::Channel(const Anope::string &nname, time_t ts)
if (this->ci)
this->ci->c = this;
- Log(NULL, this, "create");
+ if (Me->IsSynced())
+ Log(NULL, this, "create");
FOREACH_MOD(I_OnChannelCreate, OnChannelCreate(this));
}
@@ -57,7 +53,8 @@ Channel::~Channel()
ModeManager::StackerDel(this);
- Log(NULL, this, "destroy");
+ if (Me->IsSynced())
+ Log(NULL, this, "destroy");
if (this->ci)
this->ci->c = NULL;
@@ -71,27 +68,20 @@ void Channel::Reset()
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
ChannelStatus f = uc->status;
- uc->status.modes.clear();
+ uc->status.Clear();
if (BotInfo::Find(uc->user->nick))
- {
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (f.modes.count(cm->name))
- this->SetMode(NULL, cm, uc->user->GetUID(), false);
- }
- }
+ for (size_t i = 0; i < f.Modes().length(); ++i)
+ this->SetMode(NULL, ModeManager::FindChannelModeByName(f.Modes()[i]), uc->user->GetUID(), false);
}
this->CheckModes();
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
- this->SetCorrectModes((*it)->user, true, false);
+ this->SetCorrectModes(it->second->user, true, false);
if (this->ci && Me && Me->IsSynced())
this->ci->RestoreTopic();
@@ -99,7 +89,7 @@ void Channel::Reset()
void Channel::Sync()
{
- if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.front()->user)))
+ if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.begin()->second->user)))
{
this->Hold();
}
@@ -175,11 +165,12 @@ void Channel::CheckModes()
ChanUserContainer* Channel::JoinUser(User *user)
{
- Log(user, this, "join");
+ if (user->server->IsSynced())
+ Log(user, this, "join");
ChanUserContainer *cuc = new ChanUserContainer(user, this);
- user->chans.push_back(cuc);
- this->users.push_back(cuc);
+ user->chans[this] = cuc;
+ this->users[user] = cuc;
if (this->ci && this->ci->HasExt("PERSIST") && this->creation_time > this->ci->time_registered)
{
@@ -194,31 +185,18 @@ ChanUserContainer* Channel::JoinUser(User *user)
void Channel::DeleteUser(User *user)
{
- Log(user, this, "leave");
+ if (user->server->IsSynced() && !user->Quitting())
+ Log(user, this, "leave");
+
FOREACH_MOD(I_OnLeaveChannel, OnLeaveChannel(user, this));
- ChanUserContainer *cul;
- ChanUserList::iterator cit, cit_end;
- for (cit = this->users.begin(), cit_end = this->users.end(); cit != cit_end && (*cit)->user != user; ++cit);
- if (cit == cit_end)
- {
+ ChanUserContainer *cu = user->FindChannel(this);
+ if (!this->users.erase(user))
Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant user " << user->nick << " from channel " << this->name;
- return;
- }
- cul = *cit;
- this->users.erase(cit);
- ChanUserList::iterator uit, uit_end;
- for (uit = user->chans.begin(), uit_end = user->chans.end(); uit != uit_end && (*uit)->chan != this; ++uit);
- if (uit == uit_end)
+ if (!user->chans.erase(this))
Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant channel " << this->name << " from " << user->nick << "'s channel list";
- else
- {
- if (cul != *uit)
- Log(LOG_DEBUG) << "Channel::DeleteUser() mismatch between user and channel usre container objects";
- user->chans.erase(uit);
- }
- delete cul;
+ delete cu;
/* Channel is persistent, it shouldn't be deleted and the service bot should stay */
if (this->HasExt("PERSIST") || (this->ci && this->ci->HasExt("PERSIST")))
@@ -238,30 +216,30 @@ void Channel::DeleteUser(User *user)
delete this;
}
-ChanUserContainer *Channel::FindUser(const User *u) const
+ChanUserContainer *Channel::FindUser(User *u) const
{
- for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
- if ((*it)->user == u)
- return *it;
+ ChanUserList::const_iterator it = this->users.find(u);
+ if (it != this->users.end())
+ return it->second;
return NULL;
}
-bool Channel::HasUserStatus(const User *u, ChannelModeStatus *cms) const
+bool Channel::HasUserStatus(User *u, ChannelModeStatus *cms)
{
/* Usually its more efficient to search the users channels than the channels users */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
{
if (cms)
- return cc->status.modes.count(cms->name);
+ return cc->status.HasMode(cms->mchar);
else
- return cc->status.modes.empty();
+ return cc->status.Empty();
}
return false;
}
-bool Channel::HasUserStatus(const User *u, const Anope::string &mname) const
+bool Channel::HasUserStatus(User *u, const Anope::string &mname)
{
return HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(ModeManager::FindChannelModeByName(mname)));
}
@@ -345,7 +323,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anop
/* Set the status on the user */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
- cc->status.modes.insert(cm->name);
+ cc->status.AddMode(cm->mchar);
FOREACH_RESULT(I_OnChannelModeSet, OnChannelModeSet(this, setter, cm->name, param));
@@ -418,7 +396,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
/* Remove the status on the user */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
- cc->status.modes.erase(cm->name);
+ cc->status.DelMode(cm->mchar);
FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->name, param));
@@ -427,7 +405,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
/* Reset modes on bots if we're supposed to */
if (this->ci && this->ci->bi && this->ci->bi == bi)
{
- if (ModeManager::DefaultBotModes.modes.count(cm->name))
+ if (ModeManager::DefaultBotModes.HasMode(cm->mchar))
this->SetMode(bi, cm, bi->GetUID());
}
@@ -964,16 +942,16 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
if (give_modes && (!user->Account() || user->Account()->HasExt("AUTOOP")) && (!check_noop || !ci->HasExt("NOAUTOOP")))
{
if (owner && u_access.HasPriv("AUTOOWNER"))
- this->SetMode(NULL, "OWNER", user->GetUID());
+ this->SetMode(NULL, owner, user->GetUID());
else if (admin && u_access.HasPriv("AUTOPROTECT"))
- this->SetMode(NULL, "PROTECT", user->GetUID());
+ this->SetMode(NULL, admin, user->GetUID());
if (op && u_access.HasPriv("AUTOOP"))
- this->SetMode(NULL, "OP", user->GetUID());
+ this->SetMode(NULL, op, user->GetUID());
else if (halfop && u_access.HasPriv("AUTOHALFOP"))
- this->SetMode(NULL, "HALFOP", user->GetUID());
+ this->SetMode(NULL, halfop, user->GetUID());
else if (voice && u_access.HasPriv("AUTOVOICE"))
- this->SetMode(NULL, "VOICE", user->GetUID());
+ this->SetMode(NULL, voice, user->GetUID());
}
/* If this channel has secureops, or the registered channel mode exists and the channel does not have +r set (aka the channel
* was created just now or while we were off), or the registered channel mode does not exist and channel is syncing (aka just
@@ -983,16 +961,16 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
if ((ci->HasExt("SECUREOPS") || (registered && !this->HasMode("REGISTERED")) || (!registered && this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined())
{
if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME"))
- this->RemoveMode(NULL, "OWNER", user->GetUID());
+ this->RemoveMode(NULL, owner, user->GetUID());
if (admin && !u_access.HasPriv("AUTOPROTECT") && !u_access.HasPriv("PROTECTME"))
- this->RemoveMode(NULL, "PROTECT", user->GetUID());
+ this->RemoveMode(NULL, admin, user->GetUID());
if (op && this->HasUserStatus(user, "OP") && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME"))
- this->RemoveMode(NULL, "OP", user->GetUID());
+ this->RemoveMode(NULL, op, user->GetUID());
if (halfop && !u_access.HasPriv("AUTOHALFOP") && !u_access.HasPriv("HALFOPME"))
- this->RemoveMode(NULL, "HALFOP", user->GetUID());
+ this->RemoveMode(NULL, halfop, user->GetUID());
}
// Check mlock
@@ -1016,7 +994,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
}
}
-bool Channel::Unban(const User *u, bool full)
+bool Channel::Unban(User *u, bool full)
{
if (!this->HasMode("BAN"))
return false;
@@ -1047,3 +1025,12 @@ Channel* Channel::Find(const Anope::string &name)
return NULL;
}
+Channel *Channel::FindOrCreate(const Anope::string &name, bool &created, time_t ts)
+{
+ Channel* &chan = ChannelList[name];
+ created = chan == NULL;
+ if (!chan)
+ chan = new Channel(name, ts);
+ return chan;
+}
+
diff --git a/src/config.cpp b/src/config.cpp
index 1c2aae988..4d1267f23 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -137,6 +137,7 @@ ServerConfig::ServerConfig()
Log() << "Unknown casemap " << this->CaseMap << " - casemap not changed";
}
}
+ Anope::CaseMapRebuild();
if (this->SessionIPv4CIDR > 32 || this->SessionIPv6CIDR > 128)
throw ConfigException("Session CIDR value out of range");
@@ -894,12 +895,10 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope:
continue; // Can't happen
/* Remove all existing modes */
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm && cm->type == MODE_STATUS)
- c->RemoveMode(bi, cm, bi->GetUID());
- }
+ ChanUserContainer *cu = c->FindUser(bi);
+ if (cu != NULL)
+ for (size_t i = 0; i < cu->status.Modes().length(); ++i)
+ c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), bi->GetUID());
/* Set the new modes */
for (unsigned j = 0; j < want_modes.length(); ++j)
{
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 2f7816746..aac381c9b 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -13,6 +13,30 @@
/* Case map in use by Anope */
std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
+/* Cache of the above case map, forced upper */
+static unsigned char case_map_upper[256], case_map_lower[256];
+
+/* called whenever Anope::casemap is modified to rebuild the casemap cache */
+void Anope::CaseMapRebuild()
+{
+ const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
+
+ for (unsigned i = 0; i < sizeof(case_map_upper); ++i)
+ {
+ case_map_upper[i] = ct.toupper(i);
+ case_map_lower[i] = ct.tolower(i);
+ }
+}
+
+unsigned char Anope::tolower(unsigned char c)
+{
+ return case_map_lower[c];
+}
+
+unsigned char Anope::toupper(unsigned char c)
+{
+ return case_map_upper[c];
+}
/*
*
@@ -23,29 +47,25 @@ std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<c
bool ci::ci_char_traits::eq(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) == ct.toupper(c2nd);
+ return case_map_upper[static_cast<unsigned char>(c1st)] == case_map_upper[static_cast<unsigned char>(c2nd)];
}
bool ci::ci_char_traits::ne(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) != ct.toupper(c2nd);
+ return !eq(c1st, c2nd);
}
bool ci::ci_char_traits::lt(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) < ct.toupper(c2nd);
+ return case_map_upper[static_cast<unsigned char>(c1st)] < case_map_upper[static_cast<unsigned char>(c2nd)];
}
int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
-
for (unsigned i = 0; i < n; ++i)
{
- register char c1 = ct.toupper(*str1), c2 = ct.toupper(*str2);
+ register unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)],
+ c2 = case_map_upper[static_cast<unsigned char>(*str2)];
if (c1 > c2)
return 1;
@@ -62,9 +82,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
const char *ci::ci_char_traits::find(const char *s1, int n, char c)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- register char c_u = ct.toupper(c);
- while (n-- > 0 && ct.toupper(*s1) != c_u)
+ while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != static_cast<unsigned char>(c))
++s1;
return n >= 0 ? s1 : NULL;
}
@@ -74,35 +92,29 @@ bool ci::less::operator()(const Anope::string &s1, const Anope::string &s2) cons
return s1.ci_str().compare(s2.ci_str()) < 0;
}
-sepstream::sepstream(const Anope::string &source, char seperator) : tokens(source), sep(seperator)
+sepstream::sepstream(const Anope::string &source, char seperator) : tokens(source), sep(seperator), pos(0)
{
- last_starting_position = n = tokens.begin();
}
bool sepstream::GetToken(Anope::string &token)
{
- Anope::string::iterator lsp = last_starting_position;
+ size_t p = this->pos;
- while (n != tokens.end())
+ while (p < this->tokens.length() && this->tokens[p] == this->sep)
+ ++p;
+
+ if (this->StreamEnd())
{
- if (*n == sep || n + 1 == tokens.end())
- {
- last_starting_position = n + 1;
- token = Anope::string(lsp, n + 1 == tokens.end() ? n + 1 : n);
-
- while (token.length() && token.rfind(sep) == token.length() - 1)
- token.erase(token.end() - 1);
-
- ++n;
-
- return true;
- }
-
- ++n;
+ token.clear();
+ return false;
}
- token.clear();
- return false;
+ while (p < this->tokens.length() && this->tokens[p] != this->sep)
+ ++p;
+
+ token = this->tokens.substr(this->pos, p - this->pos);
+ this->pos = p + 1;
+ return true;
}
bool sepstream::GetToken(Anope::string &token, int num)
@@ -135,11 +147,11 @@ bool sepstream::GetTokenRemainder(Anope::string &token, int num)
const Anope::string sepstream::GetRemaining()
{
- return Anope::string(n, tokens.end());
+ return !this->StreamEnd() ? this->tokens.substr(this->pos) : "";
}
bool sepstream::StreamEnd()
{
- return n == tokens.end();
+ return this->pos >= this->tokens.length();
}
diff --git a/src/logger.cpp b/src/logger.cpp
index d46030486..f738cb2e1 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -56,9 +56,7 @@ static Anope::string GetTimeStamp()
static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime)
{
char timestamp[32];
-
tm *tm = localtime(&t);
-
strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
return Anope::LogDir + "/" + file + "." + timestamp;
@@ -68,7 +66,12 @@ LogFile::LogFile(const Anope::string &name) : filename(name), stream(name.c_str(
{
}
-Anope::string LogFile::GetName() const
+LogFile::~LogFile()
+{
+ this->stream.close();
+}
+
+const Anope::string &LogFile::GetName() const
{
return this->filename;
}
@@ -77,8 +80,6 @@ Log::Log(LogType t, const Anope::string &cat, const BotInfo *b) : bi(b), u(NULL)
{
if (!bi && Config)
bi = Global;
- if (bi)
- this->sources.push_back(bi->nick);
}
Log::Log(LogType t, CommandSource &source, Command *_c, const ChannelInfo *_ci) : nick(source.GetNick()), u(source.GetUser()), nc(source.nc), c(_c), chan(NULL), ci(_ci), s(NULL), m(NULL), type(t)
@@ -96,13 +97,6 @@ Log::Log(LogType t, CommandSource &source, Command *_c, const ChannelInfo *_ci)
if (this->bi == NULL && Config)
this->bi = Global;
this->category = c->name;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- if (u)
- this->sources.push_back(u->nick);
- this->sources.push_back(c->name);
- if (ci)
- this->sources.push_back(ci->name);
}
Log::Log(const User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(NULL), c(NULL), chan(ch), ci(chan ? *chan->ci : NULL), s(NULL), m(NULL), type(LOG_CHANNEL), category(cat)
@@ -112,11 +106,6 @@ Log::Log(const User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u
if (Config)
this->bi = ChanServ;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- if (u)
- this->sources.push_back(u->nick);
- this->sources.push_back(chan->name);
}
Log::Log(const User *_u, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
@@ -126,9 +115,6 @@ Log::Log(const User *_u, const Anope::string &cat, const BotInfo *_bi) : bi(_bi)
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- this->sources.push_back(u->nick);
}
Log::Log(Server *serv, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
@@ -140,23 +126,16 @@ Log::Log(Server *serv, const Anope::string &cat, const BotInfo *_bi) : bi(_bi),
this->bi = OperServ;
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- this->sources.push_back(s->GetName());
}
Log::Log(const BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
{
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(bi->nick);
}
Log::Log(Module *mod, const Anope::string &cat) : bi(NULL), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
{
- if (m)
- this->sources.push_back(m->name);
}
Log::~Log()
@@ -167,11 +146,12 @@ Log::~Log()
std::cout << GetTimeStamp() << " " << this->BuildPrefix() << this->buf.str() << std::endl;
else if (this->type == LOG_TERMINAL)
std::cout << this->BuildPrefix() << this->buf.str() << std::endl;
- for (unsigned i = 0; Config && i < Config->LogInfos.size(); ++i)
- {
- LogInfo *l = Config->LogInfos[i];
- l->ProcessMessage(this);
- }
+
+ if (Config)
+ for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
+ if (Config->LogInfos[i]->HasType(this->type, this->category))
+ Config->LogInfos[i]->ProcessMessage(this);
+
FOREACH_MOD(I_OnLog, OnLog(this));
}
@@ -264,40 +244,20 @@ Anope::string Log::BuildPrefix() const
return buffer;
}
-LogInfo::LogInfo(int la, bool rio, bool ldebug) : log_age(la), raw_io(rio), debug(ldebug)
+LogInfo::LogInfo(int la, bool rio, bool ldebug) : last_day(0), log_age(la), raw_io(rio), debug(ldebug)
{
}
LogInfo::~LogInfo()
{
- for (std::map<Anope::string, LogFile *>::iterator it = this->logfiles.begin(), it_end = this->logfiles.end(); it != it_end; ++it)
- {
- LogFile *f = it->second;
-
- if (f && f->stream.is_open())
- f->stream.close();
- delete f;
- }
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ delete this->logfiles[i];
this->logfiles.clear();
}
-void LogInfo::AddType(std::list<Anope::string> &list, const Anope::string &type)
-{
- for (std::list<Anope::string>::iterator it = list.begin(), it_end = list.end(); it != it_end; ++it)
- {
- if (Anope::Match(type, *it))
- {
- Log() << "Log: Type " << type << " is already covered by " << *it;
- return;
- }
- }
-
- list.push_back(type);
-}
-
bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
{
- const std::list<Anope::string> *list = NULL;
+ const std::vector<Anope::string> *list = NULL;
switch (ltype)
{
case LOG_ADMIN:
@@ -338,9 +298,9 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
if (list == NULL)
return false;
- for (std::list<Anope::string>::const_iterator it = list->begin(), it_end = list->end(); it != it_end; ++it)
+ for (unsigned i = 0; i < list->size(); ++i)
{
- Anope::string cat = *it;
+ Anope::string cat = list->at(i);
bool inverse = false;
if (cat[0] == '~')
{
@@ -356,36 +316,63 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
return false;
}
-void LogInfo::ProcessMessage(const Log *l)
+void LogInfo::OpenLogFiles()
{
- static time_t lastwarn = Anope::CurTime;
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ delete this->logfiles[i];
+ this->logfiles.clear();
- if (!l)
- throw CoreException("Bad values passed to LogInfo::ProcessMessages");
- else if (!this->HasType(l->type, l->category))
- return;
-
+ for (unsigned i = 0; i < this->targets.size(); ++i)
+ {
+ const Anope::string &target = this->targets[i];
+
+ if (target.empty() || target[0] == '#' || target == "globops")
+ continue;
+
+ LogFile *lf = new LogFile(CreateLogName(target));
+ if (!lf->stream.is_open())
+ {
+ Log() << "Unable to open logfile " << lf->GetName();
+ delete lf;
+ }
+ else
+ this->logfiles.push_back(lf);
+ }
+}
+
+void LogInfo::ProcessMessage(const Log *l)
+{
if (!this->sources.empty())
{
bool log = false;
- for (std::list<Anope::string>::const_iterator it = this->sources.begin(), it_end = this->sources.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < this->sources.size() && !log; ++i)
{
- if (std::find(l->sources.begin(), l->sources.end(), *it) != l->sources.end())
- {
+ const Anope::string &src = this->sources[i];
+
+ if (l->bi && src == l->bi->nick)
+ log = true;
+ else if (l->u && src == l->u->nick)
+ log = true;
+ else if (l->nc && src == l->nc->display)
+ log = true;
+ else if (l->ci && src == l->ci->name)
+ log = true;
+ else if (l->m && src == l->m->name)
+ log = true;
+ else if (l->s && src == l->s->GetName())
log = true;
- break;
- }
}
if (!log)
return;
}
- for (std::list<Anope::string>::iterator it = this->targets.begin(), it_end = this->targets.end(); it != it_end; ++it)
+ const Anope::string &buffer = l->BuildPrefix() + l->buf.str();
+
+ for (unsigned i = 0; i < this->targets.size(); ++i)
{
- const Anope::string &target = *it;
- Anope::string buffer = l->BuildPrefix() + l->buf.str();
+ const Anope::string &target = this->targets[i];
- if (target[0] == '#')
+ if (!target.empty() && target[0] == '#')
{
if (UplinkSock && l->type <= LOG_NORMAL && Me && Me->IsSynced())
{
@@ -402,63 +389,35 @@ void LogInfo::ProcessMessage(const Log *l)
IRCD->SendGlobops(l->bi, "%s", buffer.c_str());
}
}
- else
- {
- LogFile *log = NULL;
- std::map<Anope::string, LogFile *>::iterator lit = this->logfiles.find(target);
- if (lit != this->logfiles.end())
- {
- log = lit->second;
- if (log && log->GetName() != CreateLogName(target))
- {
- delete log;
- this->logfiles.erase(lit);
- log = new LogFile(CreateLogName(target));
- this->logfiles[target] = log;
-
- if (this->log_age)
- {
- Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age);
- if (IsFile(oldlog))
- {
- unlink(oldlog.c_str());
- Log(LOG_DEBUG) << "Deleted old logfile " << oldlog;
- }
- }
- }
- if (!log || !log->stream.is_open())
- {
- if (log && lastwarn + 300 < Anope::CurTime)
- {
- lastwarn = Anope::CurTime;
- Log() << "Unable to open logfile " << log->GetName();
- }
- delete log;
- this->logfiles.erase(lit);
- log = NULL;
- }
- }
- else if (lit == this->logfiles.end())
+ }
+
+ tm *tm = localtime(&Anope::CurTime);
+ if (tm->tm_mday != this->last_day)
+ {
+ this->last_day = tm->tm_mday;
+ this->OpenLogFiles();
+
+ if (this->log_age)
+ for (unsigned i = 0; i < this->targets.size(); ++i)
{
- log = new LogFile(CreateLogName(target));
+ const Anope::string &target = this->targets[i];
+
+ if (target.empty() || target[0] == '#' || target == "globops")
+ continue;
- if (!log->stream.is_open())
+ Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age);
+ if (IsFile(oldlog))
{
- if (lastwarn + 300 < Anope::CurTime)
- {
- lastwarn = Anope::CurTime;
- Log() << "Unable to open logfile " << log->GetName();
- }
- delete log;
- log = NULL;
+ unlink(oldlog.c_str());
+ Log(LOG_DEBUG) << "Deleted old logfile " << oldlog;
}
- else
- this->logfiles[target] = log;
}
+ }
- if (log)
- log->stream << GetTimeStamp() << " " << buffer << std::endl;
- }
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ {
+ LogFile *lf = this->logfiles[i];
+ lf->stream << GetTimeStamp() << " " << buffer << std::endl;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 2e15f5874..059650df0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -106,6 +106,9 @@ static Anope::string GetFullProgDir(const Anope::string &argv0)
int main(int ac, char **av, char **envp)
{
+ /* String comparisons won't work until we build the case map cache, so do it first */
+ Anope::CaseMapRebuild();
+
BinaryDir = GetFullProgDir(av[0]);
if (BinaryDir[BinaryDir.length() - 1] == '.')
BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2);
diff --git a/src/messages.cpp b/src/messages.cpp
index 567a24b6a..178d376c3 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -64,7 +64,7 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
for (User::ChanUserList::iterator it = user->chans.begin(), it_end = user->chans.end(); it != it_end; )
{
- ChanUserContainer *cc = *it++;
+ ChanUserContainer *cc = it->second++;
Anope::string channame = cc->chan->name;
FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan));
@@ -84,14 +84,12 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users)
{
- Channel *c = Channel::Find(chan);
+ bool created;
+ Channel *c = Channel::FindOrCreate(chan, created, ts ? ts : Anope::CurTime);
bool keep_their_modes = true;
- if (!c)
- {
- c = new Channel(chan, ts ? ts : Anope::CurTime);
+ if (created)
c->Extend("SYNCING");
- }
/* Some IRCds do not include a TS */
else if (!ts)
;
@@ -124,7 +122,8 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
ChanUserContainer *cc = c->JoinUser(u);
/* Update their status internally on the channel */
- cc->status = status;
+ if (keep_their_modes)
+ cc->status = status;
/* Set whatever modes the user should have, and remove any that
* they aren't allowed to have (secureops etc).
@@ -193,7 +192,7 @@ void Kill::Run(MessageSource &source, const std::vector<Anope::string> &params)
bi->introduced = true;
for (User::ChanUserList::const_iterator cit = bi->chans.begin(), cit_end = bi->chans.end(); cit != cit_end; ++cit)
- IRCD->SendJoin(bi, (*cit)->chan, &(*cit)->status);
+ IRCD->SendJoin(bi, cit->second->chan, &cit->second->status);
}
else
u->KillInternal(source.GetSource(), params[1]);
diff --git a/src/misc.cpp b/src/misc.cpp
index ad8512c56..20a53e7cc 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -406,7 +406,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
}
else
{
- if (tolower(wild) != tolower(string) && wild != '?')
+ if (Anope::tolower(wild) != Anope::tolower(string) && wild != '?')
return false;
}
@@ -441,7 +441,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
}
else
{