diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 71 | ||||
| -rw-r--r-- | src/messages.cpp | 32 | ||||
| -rw-r--r-- | src/misc.cpp | 39 | ||||
| -rw-r--r-- | src/modulemanager.cpp | 2 | ||||
| -rw-r--r-- | src/operserv.cpp | 220 | ||||
| -rw-r--r-- | src/protocol.cpp | 78 | ||||
| -rw-r--r-- | src/regchannel.cpp | 4 |
8 files changed, 297 insertions, 151 deletions
diff --git a/src/config.cpp b/src/config.cpp index 784142556..758bf1544 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -11,7 +11,6 @@ #include "services.h" #include "config.h" -#include "module.h" #include "extern.h" #include "bots.h" #include "access.h" @@ -1157,6 +1156,7 @@ ConfigItems::ConfigItems(ServerConfig *conf) {"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero}, {"options", "hideprivilegedcommands", "no", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation}, {"options", "nonicknameownership", "no", new ValueContainerBool(&conf->NoNicknameOwnership), DT_BOOLEAN | DT_NORELOAD, NoValidation}, + {"options", "regexengine", "", new ValueContainerString(&conf->RegexEngine), DT_STRING, NoValidation}, {"nickserv", "name", "", new ValueContainerString(&conf->NickServ), DT_STRING, NoValidation}, {"nickserv", "emailregistration", "no", new ValueContainerBool(&conf->NSEmailReg), DT_BOOLEAN, NoValidation}, {"nickserv", "forceemail", "no", new ValueContainerBool(&conf->NSForceEmail), DT_BOOLEAN, ValidateEmailReg}, diff --git a/src/main.cpp b/src/main.cpp index 55f185057..1d0a3e963 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -178,50 +178,71 @@ void UplinkSocket::OnError(const Anope::string &error) Log(LOG_TERMINAL) << "Unable to connect to server " << Config->Uplinks[CurrentUplink]->host << ":" << Config->Uplinks[CurrentUplink]->port << (!error.empty() ? (": " + error) : ""); } -UplinkSocket::Message::Message() +UplinkSocket::Message::Message() : server(NULL), user(NULL) { } -UplinkSocket::Message::Message(const Anope::string &s) : source(s) +UplinkSocket::Message::Message(const Server *s) : server(s), user(NULL) { } +UplinkSocket::Message::Message(const User *u) : server(NULL), user(u) +{ + if (!u) + server = Me; +} + UplinkSocket::Message::~Message() { - if (!UplinkSock) - { - if (!this->source.empty()) - Log(LOG_DEBUG) << "Attempted to send \"" << this->source << " " << this->buffer.str() << "\" with UplinkSock NULL"; - else - Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL"; - return; - } + Anope::string message_source = ""; - if (this->source == Me->GetName()) + if (this->server != NULL) { + if (this->server != Me && !this->server->HasFlag(SERVER_JUPED)) + { + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->server->GetName() << " who is not from me?"; + return; + } + if (ircd->ts6) - this->source = Me->GetSID(); + message_source = this->server->GetSID(); + else + message_source = this->server->GetName(); } - else if (!this->source.empty() && this->source != Me->GetSID()) + else if (this->user != NULL) { - BotInfo *bi = findbot(this->source); - if (bi != NULL) + if (this->user->server != Me && !this->user->server->HasFlag(SERVER_JUPED)) { - if (bi->introduced == false) - { - Log(LOG_DEBUG) << "Attempted to send \"" << this->source << " " << this->buffer.str() << "\" with source not introduced"; - return; - } + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->user->nick << " who is not from me?"; + return; + } - if (ircd->ts6) - this->source = bi->GetUID(); + BotInfo *bi = findbot(this->user->nick); + if (bi != NULL && bi->introduced == false) + { + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced"; + return; } + + if (ircd->ts6) + message_source = this->user->GetUID(); + else + message_source = this->user->nick; + } + + if (!UplinkSock) + { + if (!message_source.empty()) + Log(LOG_DEBUG) << "Attempted to send \"" << message_source << " " << this->buffer.str() << "\" with UplinkSock NULL"; + else + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL"; + return; } - if (!this->source.empty()) + if (!message_source.empty()) { - UplinkSock->Write(":" + this->source + " " + this->buffer.str()); - Log(LOG_RAWIO) << "Sent: :" << this->source << " " << this->buffer.str(); + UplinkSock->Write(":" + message_source + " " + this->buffer.str()); + Log(LOG_RAWIO) << "Sent: :" << message_source << " " << this->buffer.str(); } else { diff --git a/src/messages.cpp b/src/messages.cpp index fa93e528c..52e7c57c1 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -30,17 +30,17 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ case 'l': if (u && u->HasMode(UMODE_OPER)) { - ircdproto->SendNumeric(Config->ServerName, 211, source, "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); - ircdproto->SendNumeric(Config->ServerName, 211, source, "%s %d %d %d %d %d %d %ld", Config->Uplinks[CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - start_time)); + ircdproto->SendNumeric(211, source, "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); + ircdproto->SendNumeric(211, source, "%s %d %d %d %d %d %d %ld", Config->Uplinks[CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - start_time)); } - ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); break; case 'o': case 'O': /* Check whether the user is an operator */ if (u && !u->HasMode(UMODE_OPER) && Config->HideStatsO) - ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); else { for (unsigned i = 0; i < Config->Opers.size(); ++i) @@ -49,10 +49,10 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ NickAlias *na = findnick(o->name); if (na) - ircdproto->SendNumeric(Config->ServerName, 243, source, "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); + ircdproto->SendNumeric(243, source, "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); } - ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); } break; @@ -60,14 +60,14 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ case 'u': { time_t uptime = Anope::CurTime - start_time; - ircdproto->SendNumeric(Config->ServerName, 242, source, ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); - ircdproto->SendNumeric(Config->ServerName, 250, source, ":Current users: %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt); - ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(242, source, ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); + ircdproto->SendNumeric(250, source, ":Current users: %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt); + ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); break; } /* case 'u' */ default: - ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); } return true; @@ -83,14 +83,14 @@ bool OnTime(const Anope::string &source, const std::vector<Anope::string> &) struct tm *tm = localtime(&t); char buf[64]; strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm); - ircdproto->SendNumeric(Config->ServerName, 391, source, "%s :%s", Config->ServerName.c_str(), buf); + ircdproto->SendNumeric(391, source, "%s :%s", Config->ServerName.c_str(), buf); return true; } bool OnVersion(const Anope::string &source, const std::vector<Anope::string> &) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - ircdproto->SendNumeric(Config->ServerName, 351, source, "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); + ircdproto->SendNumeric(351, source, "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); return true; } @@ -103,18 +103,18 @@ bool OnMotd(const Anope::string &source, const std::vector<Anope::string> &) FILE *f = fopen(Config->MOTDFilename.c_str(), "r"); if (f) { - ircdproto->SendNumeric(Config->ServerName, 375, source, ":- %s Message of the Day", Config->ServerName.c_str()); + ircdproto->SendNumeric(375, source, ":- %s Message of the Day", Config->ServerName.c_str()); char buf[BUFSIZE]; while (fgets(buf, sizeof(buf), f)) { buf[strlen(buf) - 1] = 0; - ircdproto->SendNumeric(Config->ServerName, 372, source, ":- %s", buf); + ircdproto->SendNumeric(372, source, ":- %s", buf); } fclose(f); - ircdproto->SendNumeric(Config->ServerName, 376, source, ":End of /MOTD command."); + ircdproto->SendNumeric(376, source, ":End of /MOTD command."); } else - ircdproto->SendNumeric(Config->ServerName, 422, source, ":- MOTD file not found! Please contact your IRC administrator."); + ircdproto->SendNumeric(422, source, ":- MOTD file not found! Please contact your IRC administrator."); return true; } diff --git a/src/misc.cpp b/src/misc.cpp index 5f36358d3..855155409 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -18,6 +18,7 @@ #include "config.h" #include "bots.h" #include "language.h" +#include "regexpr.h" #include <errno.h> #include <sys/types.h> @@ -570,10 +571,46 @@ std::vector<Anope::string> BuildStringVector(const Anope::string &src, char deli /*************************************************************************/ -bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case_sensitive) +bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case_sensitive, bool use_regex) { size_t s = 0, m = 0, str_len = str.length(), mask_len = mask.length(); + if (use_regex && mask_len >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/') + { + Anope::string stripped_mask = mask.substr(1, mask_len - 2); + // This is often called with the same mask multiple times in a row, so cache it + static Regex *r = NULL; + + if (r == NULL || r->GetExpression() != stripped_mask) + { + service_reference<RegexProvider> provider("Regex", Config->RegexEngine); + if (provider) + { + try + { + delete r; + r = NULL; + // This may throw + r = provider->Compile(stripped_mask); + } + catch (const RegexException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + } + else + { + delete r; + r = NULL; + } + } + + if (r != NULL && r->Matches(str)) + return true; + + // Fall through to non regex match + } + while (s < str_len && m < mask_len && mask[m] != '*') { char string = str[s], wild = mask[m]; diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index d16b71cad..6837f7d1f 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -462,7 +462,7 @@ void ModuleManager::UnloadAll() { std::vector<Anope::string> modules[MT_END]; for (std::list<Module *>::iterator it = Modules.begin(), it_end = Modules.end(); it != it_end; ++it) - if ((*it)->type != PROTOCOL) + if ((*it)->type != PROTOCOL && !(*it)->GetPermanent()) modules[(*it)->type].push_back((*it)->name); for (size_t i = MT_BEGIN + 1; i != MT_END; ++i) diff --git a/src/operserv.cpp b/src/operserv.cpp index 6cdbf2ff3..018c9b4e0 100644 --- a/src/operserv.cpp +++ b/src/operserv.cpp @@ -16,19 +16,54 @@ #include "users.h" #include "extern.h" #include "sockets.h" +#include "regexpr.h" +#include "config.h" +#include "commands.h" /* List of XLine managers we check users against in XLineManager::CheckAll */ std::list<XLineManager *> XLineManager::XLineManagers; -std::map<Anope::string, XLine *, ci::less> XLineManager::XLinesByUID; +std::multimap<Anope::string, XLine *, ci::less> XLineManager::XLinesByUID; + +void XLine::InitRegex() +{ + if (!Config->RegexEngine.empty() && this->Mask.length() >= 2 && this->Mask[0] == '/' && this->Mask[this->Mask.length() - 1] == '/') + { + Anope::string stripped_mask = this->Mask.substr(1, this->Mask.length() - 2); + + service_reference<RegexProvider> provider("Regex", Config->RegexEngine); + if (provider) + { + try + { + this->regex = provider->Compile(stripped_mask); + } + catch (const RegexException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + } + } +} XLine::XLine(const Anope::string &mask, const Anope::string &reason, const Anope::string &uid) : Mask(mask), Created(0), Expires(0), Reason(reason), UID(uid) { + regex = NULL; manager = NULL; + + this->InitRegex(); } XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid) : Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason), UID(uid) { + regex = NULL; manager = NULL; + + this->InitRegex(); +} + +XLine::~XLine() +{ + delete regex; } Anope::string XLine::GetNick() const @@ -47,7 +82,7 @@ Anope::string XLine::GetUser() const if (host_t != Anope::string::npos) { - if (user_t != Anope::string::npos) + if (user_t != Anope::string::npos && host_t > user_t) return this->Mask.substr(user_t + 1, host_t - user_t - 1); else return this->Mask.substr(0, host_t); @@ -58,12 +93,49 @@ Anope::string XLine::GetUser() const Anope::string XLine::GetHost() const { - size_t host_t = this->Mask.find('@'); + size_t host_t = this->Mask.find('@'), real_t = this->Mask.find('#'); + + if (host_t != Anope::string::npos) + { + if (real_t != Anope::string::npos && real_t > host_t) + return this->Mask.substr(host_t + 1, real_t - host_t - 1); + else + return this->Mask.substr(host_t + 1); + } + else + return ""; +} + +Anope::string XLine::GetReal() const +{ + size_t real_t = this->Mask.find('#'); - if (host_t == Anope::string::npos) - return this->Mask; + if (real_t != Anope::string::npos) + return this->Mask.substr(real_t + 1); else - return this->Mask.substr(host_t + 1); + return ""; +} + +Anope::string XLine::GetReason() const +{ + Anope::string r = this->Reason; + if (Config->AddAkiller && !this->By.empty()) + r = "[" + this->By + "] " + r; + if (!this->UID.empty()) + r += " (ID: " + this->UID + ")"; + return r; +} + +bool XLine::HasNickOrReal() const +{ + bool r = this->GetNick().find_first_not_of("?*") != Anope::string::npos; + r = r || this->GetReal().find_first_not_of("?*") != Anope::string::npos; + return r; +} + +bool XLine::IsRegex() const +{ + return !this->Mask.empty() && this->Mask[0] == '/' && this->Mask[this->Mask.length() - 1] == '/'; } Anope::string XLine::serialize_name() const @@ -128,40 +200,43 @@ void XLineManager::UnregisterXLineManager(XLineManager *xlm) * @param u The user * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match */ -std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u) +void XLineManager::CheckAll(User *u) { - std::pair<XLineManager *, XLine *> ret; - - ret.first = NULL; - ret.second = NULL; - for (std::list<XLineManager *>::iterator it = XLineManagers.begin(), it_end = XLineManagers.end(); it != it_end; ++it) { XLineManager *xlm = *it; - XLine *x = xlm->Check(u); + XLine *x = xlm->CheckAllXLines(u); if (x) { - ret.first = xlm; - ret.second = x; + xlm->OnMatch(u, x); break; } } - - return ret; } Anope::string XLineManager::GenerateUID() { Anope::string id; - for (int i = 0; i < 10; ++i) + int count = 0; + while (id.empty() || XLinesByUID.count(id) > 0) { - char c; - do - c = (random() % 75) + 48; - while (!isupper(c) && !isdigit(c)); - id += c; + if (++count > 10) + { + id.clear(); + Log(LOG_DEBUG) << "Unable to generate XLine UID"; + break; + } + + for (int i = 0; i < 10; ++i) + { + char c; + do + c = (random() % 75) + 48; + while (!isupper(c) && !isdigit(c)); + id += c; + } } return id; @@ -212,7 +287,7 @@ void XLineManager::AddXLine(XLine *x) { x->manager = this; if (!x->UID.empty()) - XLinesByUID[x->UID] = x; + XLinesByUID.insert(std::make_pair(x->UID, x)); this->XLines.push_back(x); } @@ -225,7 +300,15 @@ bool XLineManager::DelXLine(XLine *x) std::vector<XLine *>::iterator it = std::find(this->XLines.begin(), this->XLines.end(), x); if (!x->UID.empty()) - XLinesByUID.erase(x->UID); + { + std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID.find(x->UID), it3 = XLinesByUID.upper_bound(x->UID); + for (; it2 != XLinesByUID.end() && it2 != it3; ++it2) + if (it2->second == x) + { + XLinesByUID.erase(it2); + break; + } + } if (it != this->XLines.end()) { @@ -266,53 +349,57 @@ void XLineManager::Clear() } /** Checks if a mask can/should be added to the XLineManager + * @param source The source adding the mask. * @param mask The mask * @param expires When the mask would expire - * @return A pair of int and XLine*. - * 1 - Mask already exists - * 2 - Mask already exists, but the expiry time was changed - * 3 - Mask is already covered by another mask - * In each case the XLine it matches/is covered by is returned in XLine* + * @param reason the reason + * @return true if the mask can be added */ -std::pair<int, XLine *> XLineManager::CanAdd(const Anope::string &mask, time_t expires) +bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason) { - std::pair<int, XLine *> ret; - - ret.first = 0; - ret.second = NULL; - for (unsigned i = this->GetCount(); i > 0; --i) { XLine *x = this->GetEntry(i - 1); - ret.second = x; if (x->Mask.equals_ci(mask)) { if (!x->Expires || x->Expires >= expires) { - ret.first = 1; - break; + if (x->Reason != reason) + { + x->Reason = reason; + source.Reply(_("Reason for %s updated."), x->Mask.c_str()); + } + else + source.Reply(_("%s already exists."), mask.c_str()); } else { x->Expires = expires; - - ret.first = 2; - break; + if (x->Reason != reason) + { + x->Reason = reason; + source.Reply(_("Expiry and reason updated for %s."), x->Mask.c_str()); + } + else + source.Reply(_("Expiry for %s updated."), x->Mask.c_str()); } + + return false; } else if (Anope::Match(mask, x->Mask) && (!x->Expires || x->Expires >= expires)) { - ret.first = 3; - break; + source.Reply(_("%s is already covered by %s."), mask.c_str(), x->Mask.c_str()); + return false; } else if (Anope::Match(x->Mask, mask) && (!expires || x->Expires <= expires)) { + source.Reply(_("Removing %s because %s covers it."), x->Mask.c_str(), mask.c_str()); this->DelXLine(x); } } - return ret; + return true; } /** Checks if this list has an entry @@ -322,8 +409,10 @@ std::pair<int, XLine *> XLineManager::CanAdd(const Anope::string &mask, time_t e XLine *XLineManager::HasEntry(const Anope::string &mask) { std::map<Anope::string, XLine *, ci::less>::iterator it = XLinesByUID.find(mask); - if (it != XLinesByUID.end() && (it->second->manager == NULL || it->second->manager == this)) - return it->second; + if (it != XLinesByUID.end()) + for (std::map<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID.upper_bound(mask); it != it2; ++it) + if (it->second->manager == NULL || it->second->manager == this) + return it->second; for (unsigned i = 0, end = this->XLines.size(); i < end; ++i) { XLine *x = this->XLines[i]; @@ -337,9 +426,9 @@ XLine *XLineManager::HasEntry(const Anope::string &mask) /** Check a user against all of the xlines in this XLineManager * @param u The user - * @return The xline the user marches, if any. Also calls OnMatch() + * @return The xline the user marches, if any. */ -XLine *XLineManager::Check(User *u) +XLine *XLineManager::CheckAllXLines(User *u) { for (unsigned i = this->XLines.size(); i > 0; --i) { @@ -352,30 +441,9 @@ XLine *XLineManager::Check(User *u) continue; } - if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick())) - continue; - - if (!x->GetUser().empty() && !Anope::Match(u->GetIdent(), x->GetUser())) - continue; - - if (!x->GetHost().empty()) - { - try - { - cidr cidr_ip(x->GetHost()); - sockaddrs ip(u->ip); - if (cidr_ip.match(ip)) - { - OnMatch(u, x); - return x; - } - } - catch (const SocketException &) { } - } - - if (x->GetHost().empty() || (Anope::Match(u->host, x->GetHost()) || (!u->chost.empty() && Anope::Match(u->chost, x->GetHost())) || (!u->vhost.empty() && Anope::Match(u->vhost, x->GetHost())))) + if (this->Check(u, x)) { - OnMatch(u, x); + this->OnMatch(u, x); return x; } } @@ -383,14 +451,6 @@ XLine *XLineManager::Check(User *u) return NULL; } -/** Called when a user matches a xline in this XLineManager - * @param u The user - * @param x The XLine they match - */ -void XLineManager::OnMatch(User *u, XLine *x) -{ -} - /** Called when an XLine expires * @param x The xline */ diff --git a/src/protocol.cpp b/src/protocol.cpp index 051f6f2d1..f51880bbe 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -39,6 +39,24 @@ void pmodule_ircd_message(IRCdMessage *message) ircdmessage = message; } +void IRCDProto::SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf) +{ + UplinkSocket::Message(source) << "KILL " << (ircd->ts6 ? user->GetUID() : user->nick) << " :" << buf; +} + +void IRCDProto::SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf) +{ + UplinkSocket::Message(bi) << "MODE " << dest->name << " " << buf; +} + +void IRCDProto::SendKickInternal(const BotInfo *bi, const Channel *c, const User *u, const Anope::string &r) +{ + if (!r.empty()) + UplinkSocket::Message(bi) << "KICK " << c->name << " " << (ircd->ts6 ? u->GetUID() : u->nick) << " :" << r; + else + UplinkSocket::Message(bi) << "KICK " << c->name << " " << (ircd->ts6 ? u->GetUID() : u->nick); +} + void IRCDProto::SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf) { if (Config->NSDefFlags.HasFlag(NI_MSG)) @@ -49,33 +67,36 @@ void IRCDProto::SendMessageInternal(const BotInfo *bi, const Anope::string &dest void IRCDProto::SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg) { - UplinkSocket::Message(bi->nick) << "NOTICE " << dest << " :" << msg; + UplinkSocket::Message(bi) << "NOTICE " << dest << " :" << msg; } void IRCDProto::SendPrivmsgInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf) { - UplinkSocket::Message(bi->nick) << "PRIVMSG " << dest << " :" << buf; + UplinkSocket::Message(bi) << "PRIVMSG " << dest << " :" << buf; } void IRCDProto::SendQuitInternal(const User *u, const Anope::string &buf) { if (!buf.empty()) - UplinkSocket::Message(u->nick) << "QUIT :" << buf; + UplinkSocket::Message(u) << "QUIT :" << buf; else - UplinkSocket::Message(u->nick) << "QUIT"; + UplinkSocket::Message(u) << "QUIT"; } void IRCDProto::SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf) { if (!buf.empty()) - UplinkSocket::Message(bi->nick) << "PART " << chan->name << " :" << buf; + UplinkSocket::Message(bi) << "PART " << chan->name << " :" << buf; else - UplinkSocket::Message(bi->nick) << "PART " << chan->name; + UplinkSocket::Message(bi) << "PART " << chan->name; } void IRCDProto::SendGlobopsInternal(const BotInfo *source, const Anope::string &buf) { - UplinkSocket::Message(source ? source->nick : Config->ServerName) << "GLOBOPS :" << buf; + if (source) + UplinkSocket::Message(source) << "GLOBOPS :" << buf; + else + UplinkSocket::Message(Me) << "GLOBOPS :" << buf; } void IRCDProto::SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf) @@ -84,14 +105,19 @@ void IRCDProto::SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, c this->SendNoticeInternal(bi, dest, "\1" + s + "\1"); } -void IRCDProto::SendNumericInternal(const Anope::string &source, int numeric, const Anope::string &dest, const Anope::string &buf) +void IRCDProto::SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) { Anope::string n = stringify(numeric); if (numeric < 10) n = "0" + n; if (numeric < 100) n = "0" + n; - UplinkSocket::Message(source) << n << " " << dest << " " << buf; + UplinkSocket::Message(Me) << n << " " << dest << " " << buf; +} + +void IRCDProto::SendTopic(BotInfo *bi, Channel *c) +{ + UplinkSocket::Message(bi) << "TOPIC " << c->name << " :" << c->topic; } void IRCDProto::SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...) @@ -183,12 +209,12 @@ void IRCDProto::SendPrivmsg(const BotInfo *bi, const Anope::string &dest, const void IRCDProto::SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) { - UplinkSocket::Message(bi->nick) << "NOTICE " << ircd->globaltldprefix << dest->GetName() << " :" << msg; + UplinkSocket::Message(bi) << "NOTICE " << ircd->globaltldprefix << dest->GetName() << " :" << msg; } void IRCDProto::SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) { - UplinkSocket::Message(bi->nick) << "PRIVMSG " << ircd->globaltldprefix << dest->GetName() << " :" << msg; + UplinkSocket::Message(bi) << "PRIVMSG " << ircd->globaltldprefix << dest->GetName() << " :" << msg; } void IRCDProto::SendQuit(const User *u, const char *fmt, ...) @@ -204,9 +230,9 @@ void IRCDProto::SendQuit(const User *u, const char *fmt, ...) void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who) { if (servname.empty()) - UplinkSocket::Message(Config->ServerName) << "PING " << who; + UplinkSocket::Message(Me) << "PING " << who; else - UplinkSocket::Message(Config->ServerName) << "PING " << servname << " " << who; + UplinkSocket::Message(Me) << "PING " << servname << " " << who; } /** @@ -218,14 +244,14 @@ void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who void IRCDProto::SendPong(const Anope::string &servname, const Anope::string &who) { if (servname.empty()) - UplinkSocket::Message(Config->ServerName) << "PONG " << who; + UplinkSocket::Message(Me) << "PONG " << who; else - UplinkSocket::Message(Config->ServerName) << "PONG " << servname << " " << who; + UplinkSocket::Message(Me) << "PONG " << servname << " " << who; } -void IRCDProto::SendInvite(const BotInfo *bi, const Anope::string &chan, const Anope::string &nick) +void IRCDProto::SendInvite(const BotInfo *bi, const Channel *c, const User *u) { - UplinkSocket::Message(bi->nick) << "INVITE " << nick << " " << chan; + UplinkSocket::Message(bi) << "INVITE " << (ircd->ts6 ? u->GetUID() : u->nick) << " " << c->name; } void IRCDProto::SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...) @@ -260,7 +286,7 @@ void IRCDProto::SendSquit(Server *s, const Anope::string &message) void IRCDProto::SendChangeBotNick(const BotInfo *bi, const Anope::string &newnick) { - UplinkSocket::Message(bi->nick) << "NICK " << newnick << " " << Anope::CurTime; + UplinkSocket::Message(bi) << "NICK " << newnick << " " << Anope::CurTime; } void IRCDProto::SendForceNickChange(const User *u, const Anope::string &newnick, time_t when) @@ -278,14 +304,14 @@ void IRCDProto::SendCTCP(const BotInfo *bi, const Anope::string &dest, const cha SendCTCPInternal(bi, dest, buf); } -void IRCDProto::SendNumeric(const Anope::string &source, int numeric, const Anope::string &dest, const char *fmt, ...) +void IRCDProto::SendNumeric(int numeric, const Anope::string &dest, const char *fmt, ...) { va_list args; char buf[BUFSIZE] = ""; va_start(args, fmt); vsnprintf(buf, BUFSIZE - 1, fmt, args); va_end(args); - SendNumericInternal(source, numeric, dest, buf); + SendNumericInternal(numeric, dest, buf); } bool IRCDProto::IsChannelValid(const Anope::string &chan) @@ -518,16 +544,16 @@ bool IRCdMessage::OnWhois(const Anope::string &source, const std::vector<Anope:: if (u && u->server == Me) { BotInfo *bi = findbot(u->nick); - ircdproto->SendNumeric(Config->ServerName, 311, source, "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); + ircdproto->SendNumeric(311, source, "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); if (bi) - ircdproto->SendNumeric(Config->ServerName, 307, source, "%s :is a registered nick", bi->nick.c_str()); - ircdproto->SendNumeric(Config->ServerName, 312, source, "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str()); + ircdproto->SendNumeric(307, source, "%s :is a registered nick", bi->nick.c_str()); + ircdproto->SendNumeric(312, source, "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str()); if (bi) - ircdproto->SendNumeric(Config->ServerName, 317, source, "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time)); - ircdproto->SendNumeric(Config->ServerName, 318, source, "%s :End of /WHOIS list.", params[0].c_str()); + ircdproto->SendNumeric(317, source, "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time)); + ircdproto->SendNumeric(318, source, "%s :End of /WHOIS list.", params[0].c_str()); } else - ircdproto->SendNumeric(Config->ServerName, 401, source, "%s :No such user.", params[0].c_str()); + ircdproto->SendNumeric(401, source, "%s :No such user.", params[0].c_str()); } return true; diff --git a/src/regchannel.cpp b/src/regchannel.cpp index 34a578917..25526ee8b 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -660,7 +660,7 @@ void ChannelInfo::EraseAkick(unsigned index) { if (this->akick.empty() || index >= this->akick.size()) return; - + delete this->akick[index]; this->akick.erase(this->akick.begin() + index); } @@ -719,6 +719,8 @@ void ChannelInfo::EraseBadWord(unsigned index) { if (this->badwords.empty() || index >= this->badwords.size()) return; + + FOREACH_MOD(I_OnBadWordDel, OnBadWordDel(this, this->badwords[index])); delete this->badwords[index]; this->badwords.erase(this->badwords.begin() + index); |
