00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "services.h"
00014 #include "modules.h"
00015 #include "protocol.h"
00016 #include "users.h"
00017 #include "servers.h"
00018 #include "config.h"
00019 #include "uplink.h"
00020 #include "bots.h"
00021 #include "channels.h"
00022
00023 IRCDProto *IRCD = NULL;
00024
00025 IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator, "IRCDProto", creator->name), proto_name(p)
00026 {
00027 DefaultPseudoclientModes = "+io";
00028 CanSVSNick = CanSVSJoin = CanSetVHost = CanSetVIdent = CanSNLine = CanSQLine = CanSQLineChannel
00029 = CanSZLine = CanSVSHold = CanSVSO = CanCertFP = RequiresID = false;
00030 MaxModes = 3;
00031
00032 if (IRCD == NULL)
00033 IRCD = this;
00034 }
00035
00036 IRCDProto::~IRCDProto()
00037 {
00038 if (IRCD == this)
00039 IRCD = NULL;
00040 }
00041
00042 const Anope::string &IRCDProto::GetProtocolName()
00043 {
00044 return this->proto_name;
00045 }
00046
00047 void IRCDProto::SendSVSKillInternal(const BotInfo *source, User *user, const Anope::string &buf)
00048 {
00049 UplinkSocket::Message(source) << "KILL " << user->GetUID() << " :" << buf;
00050 }
00051
00052 void IRCDProto::SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
00053 {
00054 UplinkSocket::Message(bi) << "MODE " << dest->name << " " << buf;
00055 }
00056
00057 void IRCDProto::SendKickInternal(const BotInfo *bi, const Channel *c, const User *u, const Anope::string &r)
00058 {
00059 if (!r.empty())
00060 UplinkSocket::Message(bi) << "KICK " << c->name << " " << u->GetUID() << " :" << r;
00061 else
00062 UplinkSocket::Message(bi) << "KICK " << c->name << " " << u->GetUID();
00063 }
00064
00065 void IRCDProto::SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf)
00066 {
00067 if (Config->NSDefFlags.count("msg"))
00068 SendPrivmsgInternal(bi, dest, buf);
00069 else
00070 SendNoticeInternal(bi, dest, buf);
00071 }
00072
00073 void IRCDProto::SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg)
00074 {
00075 UplinkSocket::Message(bi) << "NOTICE " << dest << " :" << msg;
00076 }
00077
00078 void IRCDProto::SendPrivmsgInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf)
00079 {
00080 UplinkSocket::Message(bi) << "PRIVMSG " << dest << " :" << buf;
00081 }
00082
00083 void IRCDProto::SendQuitInternal(const User *u, const Anope::string &buf)
00084 {
00085 if (!buf.empty())
00086 UplinkSocket::Message(u) << "QUIT :" << buf;
00087 else
00088 UplinkSocket::Message(u) << "QUIT";
00089 }
00090
00091 void IRCDProto::SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
00092 {
00093 if (!buf.empty())
00094 UplinkSocket::Message(bi) << "PART " << chan->name << " :" << buf;
00095 else
00096 UplinkSocket::Message(bi) << "PART " << chan->name;
00097 }
00098
00099 void IRCDProto::SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
00100 {
00101 if (source)
00102 UplinkSocket::Message(source) << "GLOBOPS :" << buf;
00103 else
00104 UplinkSocket::Message(Me) << "GLOBOPS :" << buf;
00105 }
00106
00107 void IRCDProto::SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf)
00108 {
00109 Anope::string s = Anope::NormalizeBuffer(buf);
00110 this->SendNoticeInternal(bi, dest, "\1" + s + "\1");
00111 }
00112
00113 void IRCDProto::SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf)
00114 {
00115 Anope::string n = stringify(numeric);
00116 if (numeric < 10)
00117 n = "0" + n;
00118 if (numeric < 100)
00119 n = "0" + n;
00120 UplinkSocket::Message(Me) << n << " " << dest << " " << buf;
00121 }
00122
00123 void IRCDProto::SendTopic(BotInfo *bi, Channel *c)
00124 {
00125 UplinkSocket::Message(bi) << "TOPIC " << c->name << " :" << c->topic;
00126 }
00127
00128 void IRCDProto::SendSVSKill(const BotInfo *source, User *user, const char *fmt, ...)
00129 {
00130 if (!user || !fmt)
00131 return;
00132
00133 va_list args;
00134 char buf[BUFSIZE] = "";
00135 va_start(args, fmt);
00136 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00137 va_end(args);
00138 SendSVSKillInternal(source, user, buf);
00139 }
00140
00141 void IRCDProto::SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...)
00142 {
00143 va_list args;
00144 char buf[BUFSIZE] = "";
00145 va_start(args, fmt);
00146 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00147 va_end(args);
00148 SendModeInternal(bi, dest, buf);
00149 }
00150
00151 void IRCDProto::SendMode(const BotInfo *bi, const User *u, const char *fmt, ...)
00152 {
00153 va_list args;
00154 char buf[BUFSIZE] = "";
00155 va_start(args, fmt);
00156 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00157 va_end(args);
00158 SendModeInternal(bi, u, buf);
00159 }
00160
00161 void IRCDProto::SendKick(const BotInfo *bi, const Channel *chan, const User *user, const char *fmt, ...)
00162 {
00163 if (!bi || !chan || !user)
00164 return;
00165
00166 va_list args;
00167 char buf[BUFSIZE] = "";
00168 va_start(args, fmt);
00169 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00170 va_end(args);
00171 SendKickInternal(bi, chan, user, buf);
00172 }
00173
00174 void IRCDProto::SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
00175 {
00176 va_list args;
00177 char buf[BUFSIZE] = "";
00178 va_start(args, fmt);
00179 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00180 va_end(args);
00181 SendMessageInternal(bi, dest, buf);
00182 }
00183
00184 void IRCDProto::SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
00185 {
00186 va_list args;
00187 char buf[BUFSIZE] = "";
00188 va_start(args, fmt);
00189 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00190 va_end(args);
00191 SendNoticeInternal(bi, dest, buf);
00192 }
00193
00194 void IRCDProto::SendAction(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
00195 {
00196 va_list args;
00197 char buf[BUFSIZE] = "";
00198 va_start(args, fmt);
00199 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00200 va_end(args);
00201 Anope::string actionbuf = Anope::string("\1ACTION ") + buf + '\1';
00202 SendPrivmsgInternal(bi, dest, actionbuf);
00203 }
00204
00205 void IRCDProto::SendPrivmsg(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
00206 {
00207 va_list args;
00208 char buf[BUFSIZE] = "";
00209 va_start(args, fmt);
00210 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00211 va_end(args);
00212 SendPrivmsgInternal(bi, dest, buf);
00213 }
00214
00215 void IRCDProto::SendQuit(const User *u, const char *fmt, ...)
00216 {
00217 va_list args;
00218 char buf[BUFSIZE] = "";
00219 va_start(args, fmt);
00220 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00221 va_end(args);
00222 SendQuitInternal(u, buf);
00223 }
00224
00225 void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who)
00226 {
00227 if (servname.empty())
00228 UplinkSocket::Message(Me) << "PING " << who;
00229 else
00230 UplinkSocket::Message(Me) << "PING " << servname << " " << who;
00231 }
00232
00239 void IRCDProto::SendPong(const Anope::string &servname, const Anope::string &who)
00240 {
00241 if (servname.empty())
00242 UplinkSocket::Message(Me) << "PONG " << who;
00243 else
00244 UplinkSocket::Message(Me) << "PONG " << servname << " " << who;
00245 }
00246
00247 void IRCDProto::SendInvite(const BotInfo *bi, const Channel *c, const User *u)
00248 {
00249 UplinkSocket::Message(bi) << "INVITE " << u->GetUID() << " " << c->name;
00250 }
00251
00252 void IRCDProto::SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...)
00253 {
00254 if (fmt)
00255 {
00256 va_list args;
00257 char buf[BUFSIZE] = "";
00258 va_start(args, fmt);
00259 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00260 va_end(args);
00261 SendPartInternal(bi, chan, buf);
00262 }
00263 else
00264 SendPartInternal(bi, chan, "");
00265 }
00266
00267 void IRCDProto::SendGlobops(const BotInfo *source, const char *fmt, ...)
00268 {
00269 va_list args;
00270 char buf[BUFSIZE] = "";
00271 va_start(args, fmt);
00272 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00273 va_end(args);
00274 SendGlobopsInternal(source, buf);
00275 }
00276
00277 void IRCDProto::SendSquit(Server *s, const Anope::string &message)
00278 {
00279 UplinkSocket::Message() << "SQUIT " << s->GetName() << " :" << message;
00280 }
00281
00282 void IRCDProto::SendNickChange(const User *u, const Anope::string &newnick)
00283 {
00284 UplinkSocket::Message(u) << "NICK " << newnick << " " << Anope::CurTime;
00285 }
00286
00287 void IRCDProto::SendForceNickChange(const User *u, const Anope::string &newnick, time_t when)
00288 {
00289 UplinkSocket::Message() << "SVSNICK " << u->nick << " " << newnick << " " << when;
00290 }
00291
00292 void IRCDProto::SendCTCP(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
00293 {
00294 va_list args;
00295 char buf[BUFSIZE] = "";
00296 va_start(args, fmt);
00297 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00298 va_end(args);
00299 SendCTCPInternal(bi, dest, buf);
00300 }
00301
00302 void IRCDProto::SendNumeric(int numeric, const Anope::string &dest, const char *fmt, ...)
00303 {
00304 va_list args;
00305 char buf[BUFSIZE] = "";
00306 va_start(args, fmt);
00307 vsnprintf(buf, BUFSIZE - 1, fmt, args);
00308 va_end(args);
00309 SendNumericInternal(numeric, dest, buf);
00310 }
00311
00312 bool IRCDProto::IsNickValid(const Anope::string &nick)
00313 {
00322 if (nick.empty())
00323 return false;
00324
00325 Anope::string special = "[]\\`_^{|}";
00326
00327 for (unsigned i = 0; i < nick.length(); ++i)
00328 if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z') && special.find(nick[i]) == Anope::string::npos
00329 && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-')))
00330 return false;
00331
00332 return true;
00333 }
00334
00335 bool IRCDProto::IsChannelValid(const Anope::string &chan)
00336 {
00337 if (chan.empty() || chan[0] != '#' || chan.length() > Config->ChanLen)
00338 return false;
00339
00340 return true;
00341 }
00342
00343 bool IRCDProto::IsIdentValid(const Anope::string &ident)
00344 {
00345 if (ident.empty() || ident.length() > Config->UserLen)
00346 return false;
00347
00348 for (unsigned i = 0; i < ident.length(); ++i)
00349 {
00350 const char &c = ident[i];
00351 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
00352 ;
00353 else
00354 return false;
00355 }
00356
00357 return true;
00358 }
00359
00360 bool IRCDProto::IsHostValid(const Anope::string &host)
00361 {
00362 if (host.empty() || host.length() > Config->HostLen)
00363 return false;
00364
00365 if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos)
00366 return false;
00367 else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos)
00368 return false;
00369
00370 int dots = 0;
00371 for (unsigned i = 0; i < host.length(); ++i)
00372 {
00373 if (host[i] == '.')
00374 ++dots;
00375 if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos)
00376 return false;
00377 }
00378
00379 return Config->VhostUndotted || dots > 0;
00380 }
00381
00382 void IRCDProto::SendOper(User *u)
00383 {
00384 SendNumericInternal(381, u->GetUID(), ":You are now an IRC operator (set by services)");
00385 u->SetMode(OperServ, "OPER");
00386 }
00387
00388 MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
00389 {
00390 if (src.empty())
00391 this->s = !Me->GetLinks().empty() ? Me->GetLinks().front() : NULL;
00392 else if (IRCD->RequiresID || src.find('.') != Anope::string::npos)
00393 this->s = Server::Find(src);
00394 if (this->s == NULL)
00395 this->u = User::Find(src);
00396 }
00397
00398 MessageSource::MessageSource(User *_u) : source(_u ? _u->nick : ""), u(_u), s(NULL)
00399 {
00400 }
00401
00402 MessageSource::MessageSource(Server *_s) : source(_s ? _s->GetName() : ""), u(NULL), s(_s)
00403 {
00404 }
00405
00406 const Anope::string MessageSource::GetName()
00407 {
00408 if (this->s)
00409 return this->s->GetName();
00410 else if (this->u)
00411 return this->u->nick;
00412 else
00413 return this->source;
00414 }
00415
00416 const Anope::string &MessageSource::GetSource()
00417 {
00418 return this->source;
00419 }
00420
00421 User *MessageSource::GetUser()
00422 {
00423 return this->u;
00424 }
00425
00426 Server *MessageSource::GetServer()
00427 {
00428 return this->s;
00429 }
00430
00431 IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned p) : Service(o, "IRCDMessage", o->name + "/" + n.lower()), name(n), param_count(p)
00432 {
00433 }
00434
00435 unsigned IRCDMessage::GetParamCount() const
00436 {
00437 return this->param_count;
00438 }
00439