diff options
Diffstat (limited to 'src/protocol.cpp')
-rw-r--r-- | src/protocol.cpp | 387 |
1 files changed, 54 insertions, 333 deletions
diff --git a/src/protocol.cpp b/src/protocol.cpp index 1195673e4..c0ca483c6 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,12 +1,20 @@ /* + * Anope IRC Services * - * (C) 2003-2017 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2003-2017 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ #include "services.h" @@ -18,334 +26,42 @@ #include "uplink.h" #include "bots.h" #include "channels.h" +#include "numeric.h" -IRCDProto *IRCD = NULL; +IRCDProto *IRCD = nullptr; -IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator, "IRCDProto", creator->name), proto_name(p) +IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator, NAME, p) + , proto_name(p) { - DefaultPseudoclientModes = "+io"; - CanSVSNick = CanSVSJoin = CanSetVHost = CanSetVIdent = CanSNLine = CanSQLine = CanSQLineChannel - = CanSZLine = CanSVSHold = CanSVSO = CanCertFP = RequiresID = AmbiguousID = false; - MaxModes = 3; - MaxLine = 512; - - if (IRCD == NULL) - IRCD = this; } IRCDProto::~IRCDProto() { - if (IRCD == this) - IRCD = NULL; } -const Anope::string &IRCDProto::GetProtocolName() +const Anope::string &IRCDProto::GetProtocolName() const { return this->proto_name; } -static inline char nextID(int pos, Anope::string &buf) -{ - char &c = buf[pos]; - if (c == 'Z') - c = '0'; - else if (c != '9') - ++c; - else if (pos) - c = 'A'; - else - c = '0'; - return c; -} - -Anope::string IRCDProto::UID_Retrieve() -{ - if (!IRCD || !IRCD->RequiresID) - return ""; - - static Anope::string current_uid = "AAAAAA"; - - do - { - int current_len = current_uid.length() - 1; - while (current_len >= 0 && nextID(current_len--, current_uid) == 'A'); - } - while (User::Find(Me->GetSID() + current_uid) != NULL); - - return Me->GetSID() + current_uid; -} - -Anope::string IRCDProto::SID_Retrieve() -{ - if (!IRCD || !IRCD->RequiresID) - return ""; - - static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<const Anope::string>("id"); - if (current_sid.empty()) - current_sid = "00A"; - - do - { - int current_len = current_sid.length() - 1; - while (current_len >= 0 && nextID(current_len--, current_sid) == 'A'); - } - while (Server::Find(current_sid) != NULL); - - return current_sid; -} - -void IRCDProto::SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason) -{ - UplinkSocket::Message(source) << "KILL " << target << " :" << reason; -} - -void IRCDProto::SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) -{ - UplinkSocket::Message(source) << "KILL " << user->GetUID() << " :" << buf; -} - -void IRCDProto::SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) -{ - UplinkSocket::Message(source) << "MODE " << dest->name << " " << buf; -} - -void IRCDProto::SendModeInternal(const MessageSource &source, User *dest, const Anope::string &buf) -{ - UplinkSocket::Message(source) << "MODE " << dest->GetUID() << " " << buf; -} - -void IRCDProto::SendKickInternal(const MessageSource &source, const Channel *c, User *u, const Anope::string &r) -{ - if (!r.empty()) - UplinkSocket::Message(source) << "KICK " << c->name << " " << u->GetUID() << " :" << r; - else - UplinkSocket::Message(source) << "KICK " << c->name << " " << u->GetUID(); -} - -void IRCDProto::SendNoticeInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) -{ - UplinkSocket::Message(source) << "NOTICE " << dest << " :" << msg; -} - -void IRCDProto::SendPrivmsgInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &buf) -{ - UplinkSocket::Message(source) << "PRIVMSG " << dest << " :" << buf; -} - -void IRCDProto::SendQuitInternal(User *u, const Anope::string &buf) -{ - if (!buf.empty()) - UplinkSocket::Message(u) << "QUIT :" << buf; - else - UplinkSocket::Message(u) << "QUIT"; -} - -void IRCDProto::SendPartInternal(User *u, const Channel *chan, const Anope::string &buf) -{ - if (!buf.empty()) - UplinkSocket::Message(u) << "PART " << chan->name << " :" << buf; - else - UplinkSocket::Message(u) << "PART " << chan->name; -} - -void IRCDProto::SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) -{ - UplinkSocket::Message(source) << "GLOBOPS :" << buf; -} - -void IRCDProto::SendCTCPInternal(const MessageSource &source, const Anope::string &dest, const Anope::string &buf) +void IRCDProto::SendCTCPReply(const MessageSource &source, const Anope::string &dest, const Anope::string &buf) { Anope::string s = Anope::NormalizeBuffer(buf); - this->SendNoticeInternal(source, dest, "\1" + s + "\1"); + this->SendNotice(source, dest, "\1" + s + "\1"); } -void IRCDProto::SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) +void IRCDProto::SendNumeric(int numeric, User *dest, IRCMessage &message) { - Anope::string n = stringify(numeric); - if (numeric < 10) - n = "0" + n; - if (numeric < 100) - n = "0" + n; - UplinkSocket::Message(Me) << n << " " << dest << " " << buf; + Uplink::SendMessage(message); } -void IRCDProto::SendTopic(const MessageSource &source, Channel *c) +void IRCDProto::SendAction(const MessageSource &source, const Anope::string &dest, const Anope::string &message) { - UplinkSocket::Message(source) << "TOPIC " << c->name << " :" << c->topic; -} + Anope::string actionbuf = "\1ACTION "; + actionbuf.append(message); + actionbuf.append('\1'); -void IRCDProto::SendSVSKill(const MessageSource &source, User *user, const char *fmt, ...) -{ - if (!user || !fmt) - return; - - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendSVSKillInternal(source, user, buf); -} - -void IRCDProto::SendMode(const MessageSource &source, const Channel *dest, const char *fmt, ...) -{ - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendModeInternal(source, dest, buf); -} - -void IRCDProto::SendMode(const MessageSource &source, User *u, const char *fmt, ...) -{ - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendModeInternal(source, u, buf); -} - -void IRCDProto::SendKick(const MessageSource &source, const Channel *chan, User *user, const char *fmt, ...) -{ - if (!chan || !user) - return; - - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendKickInternal(source, chan, user, buf); -} - -void IRCDProto::SendNotice(const MessageSource &source, 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); - SendNoticeInternal(source, dest, buf); -} - -void IRCDProto::SendAction(const MessageSource &source, 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); - Anope::string actionbuf = Anope::string("\1ACTION ") + buf + '\1'; - SendPrivmsgInternal(source, dest, actionbuf); -} - -void IRCDProto::SendPrivmsg(const MessageSource &source, 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); - SendPrivmsgInternal(source, dest, buf); -} - -void IRCDProto::SendQuit(User *u, const char *fmt, ...) -{ - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendQuitInternal(u, buf); -} - -void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who) -{ - if (servname.empty()) - UplinkSocket::Message(Me) << "PING " << who; - else - UplinkSocket::Message(Me) << "PING " << servname << " " << who; -} - -/** - * Send a PONG reply to a received PING. - * servname should be left NULL to send a one param reply. - * @param servname Daemon or client that is responding to the PING. - * @param who Origin of the PING and destination of the PONG message. - **/ -void IRCDProto::SendPong(const Anope::string &servname, const Anope::string &who) -{ - if (servname.empty()) - UplinkSocket::Message(Me) << "PONG " << who; - else - UplinkSocket::Message(Me) << "PONG " << servname << " " << who; -} - -void IRCDProto::SendInvite(const MessageSource &source, const Channel *c, User *u) -{ - UplinkSocket::Message(source) << "INVITE " << u->GetUID() << " " << c->name; -} - -void IRCDProto::SendPart(User *user, const Channel *chan, const char *fmt, ...) -{ - if (fmt) - { - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendPartInternal(user, chan, buf); - } - else - SendPartInternal(user, chan, ""); -} - -void IRCDProto::SendGlobops(const MessageSource &source, const char *fmt, ...) -{ - va_list args; - char buf[BUFSIZE] = ""; - va_start(args, fmt); - vsnprintf(buf, BUFSIZE - 1, fmt, args); - va_end(args); - SendGlobopsInternal(source, buf); -} - -void IRCDProto::SendSquit(Server *s, const Anope::string &message) -{ - UplinkSocket::Message() << "SQUIT " << s->GetSID() << " :" << message; -} - -void IRCDProto::SendNickChange(User *u, const Anope::string &newnick) -{ - UplinkSocket::Message(u) << "NICK " << newnick << " " << Anope::CurTime; -} - -void IRCDProto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) -{ - UplinkSocket::Message() << "SVSNICK " << u->GetUID() << " " << newnick << " " << when; -} - -void IRCDProto::SendCTCP(const MessageSource &source, 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); - SendCTCPInternal(source, dest, buf); -} - -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(numeric, dest, buf); + SendPrivmsg(source, dest, actionbuf); } bool IRCDProto::IsNickValid(const Anope::string &nick) @@ -360,16 +76,16 @@ bool IRCDProto::IsNickValid(const Anope::string &nick) if (nick.empty()) return false; - + Anope::string special = "[]\\`_^{|}"; - - for (unsigned i = 0; i < nick.length(); ++i) + + for (unsigned int i = 0; i < nick.length(); ++i) if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z') && special.find(nick[i]) == Anope::string::npos && (Config && Config->NickChars.find(nick[i]) == Anope::string::npos) && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-'))) return false; - + return true; } @@ -389,7 +105,7 @@ bool IRCDProto::IsIdentValid(const Anope::string &ident) if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) return false; - for (unsigned i = 0; i < ident.length(); ++i) + for (unsigned int i = 0; i < ident.length(); ++i) { const char &c = ident[i]; @@ -407,8 +123,8 @@ bool IRCDProto::IsHostValid(const Anope::string &host) if (host.empty() || host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) return false; - const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<const Anope::string>("disallow_start_or_end"), - vhostchars = Config->GetBlock("networkinfo")->Get<const Anope::string>("vhost_chars"); + const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<Anope::string>("disallow_start_or_end"), + vhostchars = Config->GetBlock("networkinfo")->Get<Anope::string>("vhost_chars"); if (vhostdisablebe.find_first_of(host[0]) != Anope::string::npos) return false; @@ -416,7 +132,7 @@ bool IRCDProto::IsHostValid(const Anope::string &host) return false; int dots = 0; - for (unsigned i = 0; i < host.length(); ++i) + for (unsigned int i = 0; i < host.length(); ++i) { if (host[i] == '.') ++dots; @@ -427,13 +143,7 @@ bool IRCDProto::IsHostValid(const Anope::string &host) return dots > 0 || Config->GetBlock("networkinfo")->Get<bool>("allow_undotted_vhosts"); } -void IRCDProto::SendOper(User *u) -{ - SendNumericInternal(381, u->GetUID(), ":You are now an IRC operator (set by services)"); - u->SetMode(NULL, "OPER"); -} - -unsigned IRCDProto::GetMaxListFor(Channel *c) +unsigned int IRCDProto::GetMaxListFor(Channel *c) { return c->HasMode("LBAN") ? 0 : Config->GetBlock("networkinfo")->Get<int>("modelistsize"); } @@ -445,7 +155,7 @@ Anope::string IRCDProto::NormalizeMask(const Anope::string &mask) return Entry("", mask).GetNUHMask(); } -MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL) +MessageSource::MessageSource(const Anope::string &src) : source(src) { /* no source for incoming message is our uplink */ if (src.empty()) @@ -456,11 +166,11 @@ MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s this->u = User::Find(src); } -MessageSource::MessageSource(User *_u) : source(_u ? _u->nick : ""), u(_u), s(NULL) +MessageSource::MessageSource(User *_u) : source(_u ? _u->nick : ""), u(_u) { } -MessageSource::MessageSource(Server *_s) : source(_s ? _s->GetName() : ""), u(NULL), s(_s) +MessageSource::MessageSource(Server *_s) : source(_s ? _s->GetName() : ""), s(_s) { } @@ -474,6 +184,15 @@ const Anope::string &MessageSource::GetName() const return this->source; } +const Anope::string &MessageSource::GetUID() const +{ + if (this->s) + return this->s->GetSID(); + if (this->u) + return this->u->GetUID(); + return this->source; +} + const Anope::string &MessageSource::GetSource() const { return this->source; @@ -484,9 +203,9 @@ User *MessageSource::GetUser() const return this->u; } -BotInfo *MessageSource::GetBot() const +ServiceBot *MessageSource::GetBot() const { - return BotInfo::Find(this->GetName(), true); + return ServiceBot::Find(this->GetName(), true); } Server *MessageSource::GetServer() const @@ -494,11 +213,13 @@ Server *MessageSource::GetServer() const return this->s; } -IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned p) : Service(o, "IRCDMessage", o->name + "/" + n.lower()), name(n), param_count(p) +IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned int p) : Service(o, NAME, o->name + "/" + n.lower()) + , name(n) + , param_count(p) { } -unsigned IRCDMessage::GetParamCount() const +unsigned int IRCDMessage::GetParamCount() const { return this->param_count; } |