/* * <@po||ux> DukeP: RFC 2813, 4.2.1: the JOIN command on server-server links * separates the modes ("o") with ASCII 7, not space. And you can't see ASCII 7. * * if a user joins a new channel, the ircd sends <channelname>\7<umode> */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { User *user = source.GetUser(); size_t pos = params[0].find('\7'); Anope::string channel, modes; if (pos != Anope::string::npos) { channel = params[0].substr(0, pos); modes = '+' + params[0].substr(pos+1, params[0].length()) + " " + user->nick; } else { channel = params[0]; } std::vector<Anope::string> new_params; new_params.push_back(channel); Message::Join::Run(source, new_params); if (!modes.empty()) { Channel *c = Channel::Find(channel); if (c) c->SetModesInternal(source, modes); } }
/* :0MCAAAAAB CERTFP 4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { User *u = source.GetUser(); u->fingerprint = params[0]; Event::OnFingerprint(&Event::Fingerprint::OnFingerprint, u); }
/* * :42X EUID DukePyrolator 1 1353240577 +Zi ~jens erft-5d80b00b.pool.mediaWays.net 93.128.176.11 42XAAAAAD * * :jens * :<SID> EUID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <VHOST> <IP> <UID> <REALHOST> <ACCOUNT> :<GECOS> * 0 1 2 3 4 5 6 7 8 9 10 * * Introduces a user. The hostname field is now always the visible host. * The realhost field is * if the real host is equal to the visible host. * The account field is * if the login is not set. * Note that even if both new fields are *, an EUID command still carries more * information than a UID command (namely that real host is visible host and the * user is not logged in with services). Hence a NICK or UID command received * from a remote server should not be sent in EUID form to other servers. */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { NickServ::Nick *na = NULL; if (params[9] != "*") na = NickServ::FindNick(params[9]); User::OnIntroduce(params[0], params[4], params[8], params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? na->GetAccount() : NULL); }
void Quit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &reason = params[0]; User *user = source.GetUser(); Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")"; user->Quit(reason); }
void Invite::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *targ = User::Find(params[0]); Channel *c = Channel::Find(params[1]); if (!targ || targ->server != Me || !c || c->FindUser(targ)) return; EventManager::Get()->Dispatch(&Event::Invite::OnInvite, source.GetUser(), c, targ); }
void Time::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { time_t t; time(&t); struct tm *tm = localtime(&t); char buf[64]; strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm); IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Me->GetName().c_str(), buf); return; }
void MessageEditorListCtrl::_Commit() { MessageSource *source = const_cast<MessageSource*>(_GetSource()); if (source) { assert((_sourceType == MessageSourceType::Verbs || _sourceType == MessageSourceType::Talkers) && "Other types should go through components."); source->Commit(); if (_pDoc) { // Send out notification. Be lazy and just say "all message files". auto hint = WrapHint(MessageChangeHint::AllMessageFiles); _pDoc->UpdateAllViewsAndNonViews(nullptr, 0, &hint); } // Notify the class browser. I'd rather have this functionality here than in the MessageSource. // An even better way would be to have a thread that is monitoring certain files. SCIClassBrowser &browser = *appState->GetResourceMap().GetClassBrowser(); browser.TriggerReloadScript(source->GetBackingFile().c_str()); } }
void Message::Stats::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.GetUser(); switch (params[0][0]) { case 'l': if (u->HasMode("OPER")) { IRCD->SendNumeric(211, source.GetSource(), "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); IRCD->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[Anope::CurrentUplink].host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - Anope::StartTime)); } IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; case 'o': case 'O': /* Check whether the user is an operator */ if (!u->HasMode("OPER") && Config->GetBlock("options")->Get<bool>("hidestatso")) IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); else { for (Oper *o : Serialize::GetObjects<Oper *>()) IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->GetName().c_str(), o->GetType()->GetName().replace_all_cs(" ", "_").c_str()); IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } break; case 'u': { ::Stats *s = Serialize::GetObject<::Stats *>(); long uptime = static_cast<long>(Anope::CurTime - Anope::StartTime); IRCD->SendNumeric(242, source.GetSource(), ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); IRCD->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", UserListByNick.size(), OperCount, s ? s->GetMaxUserCount() : 0); IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; } /* case 'u' */ default: IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } return; }
void bahamut::ServerMessage::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { unsigned int hops = 0; try { hops = convertTo<unsigned>(params[1]); } catch (const ConvertException &) { } new Server(source.GetServer(), params[0], hops, params[2]); }
void User::KillInternal(const MessageSource &source, const Anope::string &reason) { if (this->quit) { Log(LOG_DEBUG) << "Duplicate quit for " << this->nick; return; } Log(this, "killed") << "was killed by " << source.GetName() << " (Reason: " << reason << ")"; this->Quit(reason); }
/* XXX We should cache the file somewhere not open/read/close it on every request */ void MOTD::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Server *s = Server::Find(params[0]); if (s != Me) return; FILE *f = fopen(Config->GetBlock("serverinfo")->Get<Anope::string>("motd").c_str(), "r"); if (f) { IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", s->GetName().c_str()); char buf[BUFSIZE]; while (fgets(buf, sizeof(buf), f)) { buf[strlen(buf) - 1] = 0; IRCD->SendNumeric(372, source.GetSource(), ":- %s", buf); } fclose(f); IRCD->SendNumeric(376, source.GetSource(), ":End of /MOTD command."); } else IRCD->SendNumeric(422, source.GetSource(), ":- MOTD file not found! Please contact your IRC administrator."); }
void bahamut::Topic::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Channel *c = Channel::Find(params[0]); time_t ts = Anope::CurTime; try { ts = convertTo<time_t>(params[2]); } catch (const ConvertException &) { } if (c) c->ChangeTopicInternal(source.GetUser(), params[1], params[3], ts); }
void Notice::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Anope::string message = params[1]; User *u = source.GetUser(); /* ignore channel notices */ if (!IRCD->IsChannelValid(params[0])) { ServiceBot *bi = ServiceBot::Find(params[0]); if (!bi) return; EventManager::Get()->Dispatch(&Event::BotNotice::OnBotNotice, u, bi, message); } }
/* * NICK - NEW * Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator * Parameters: <nickname> <hopcount> <username> <host> <servertoken> <umode> :<realname> * source = server * params[0] = nick * params[1] = hopcount * params[2] = username/ident * params[3] = host * params[4] = servertoken * params[5] = modes * params[6] = info * * NICK - change * Received: :DukeP_ NICK :test2 * source = oldnick * params[0] = newnick * */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { if (params.size() == 1) { // we have a nickchange source.GetUser()->ChangeNick(params[0]); } else if (params.size() == 7) { // a new user is connecting to the network Server *s = Server::Find(params[4]); if (s == NULL) { Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[4] << "?"; return; } User::OnIntroduce(params[0], params[2], params[3], "", "", s, params[6], Anope::CurTime, params[5], "", NULL); Log(LOG_DEBUG) << "Registered nick \"" << params[0] << "\" on server " << s->GetName() << "."; } else { Log(LOG_DEBUG) << "Received NICK with invalid number of parameters. source = " << source.GetName() << "params[0] = " << params[0] << "params.size() = " << params.size(); } }
/* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB Steve :Mining all the time */ void hybrid::UID::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Anope::string ip = params[6]; if (ip == "0") /* Can be 0 for spoofed clients */ ip.clear(); NickServ::Nick *na = NULL; if (params[8] != "0" && params[8] != "*") na = NickServ::FindNick(params[8]); /* Source is always the server */ User::OnIntroduce(params[0], params[4], params[5], "", ip, source.GetServer(), params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], na ? na->GetAccount() : NULL); }
void SendTopic(const MessageSource &source, Channel *c) override { ServiceBot *bi = source.GetBot(); bool needjoin = c->FindUser(bi) == NULL; if (needjoin) { ChannelStatus status; status.AddMode('o'); bi->Join(c, &status); } IRCDProto::SendTopic(source, c); if (needjoin) bi->Part(c); }
// Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam void ratbox::Encap::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { if (params[1] == "LOGIN" || params[1] == "SU") { User *u = source.GetUser(); NickServ::Account *nc = NickServ::FindAccount(params[2]); if (!nc) return; u->Login(nc); /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if * their server isn't syncing) and then we receive this.. so tell them about it. */ if (u->server->IsSynced()) u->SendMessage(Config->GetClient("NickServ"), _("You have been logged in as \002%s\002."), nc->GetDisplay().c_str()); } }
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { if (params.size() == 3) { // our uplink is introducing itself new Server(Me, params[0], 1, params[2], "1"); } else { // our uplink is introducing a new server unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0; new Server(source.GetServer(), params[0], hops, params[3], params[2]); } /* * ngIRCd does not send an EOB, so we send a PING immediately * when receiving a new server and then finish sync once we * get a pong back from that server. */ IRCD->SendPing(Me->GetName(), params[0]); }
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { User *u = source.GetUser(); // In a burst, states that the source user is logged in as the account. if (params[1] == "LOGIN" || params[1] == "SU") { NickServ::Account *nc = NickServ::FindAccount(params[2]); if (!nc) return; u->Login(nc); } // Received: :42XAAAAAE ENCAP * CERTFP :3f122a9cc7811dbad3566bf2cec3009007c0868f if (params[1] == "CERTFP") { u->fingerprint = params[2]; EventManager::Get()->Dispatch(&Event::Fingerprint::OnFingerprint, u); } /* * Received: :42X ENCAP * SASL 42XAAAAAH * S PLAIN * Received: :42X ENCAP * SASL 42XAAAAAC * D A * * Part of a SASL authentication exchange. The mode is 'C' to send some data * (base64 encoded), or 'S' to end the exchange (data indicates type of * termination: 'A' for abort, 'F' for authentication failure, 'S' for * authentication success). * * Charybdis only accepts messages from SASL agents; these must have umode +S */ if (params[1] == "SASL" && SASL::sasl && params.size() >= 6) { SASL::Message m; m.source = params[2]; m.target = params[3]; m.type = params[4]; m.data = params[5]; m.ext = params.size() > 6 ? params[6] : ""; SASL::sasl->ProcessMessage(m); } }
void Part::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.GetUser(); const Anope::string &reason = params.size() > 1 ? params[1] : ""; Anope::string channel; commasepstream sep(params[0]); while (sep.GetToken(channel)) { Channel *c = Channel::Find(channel); if (!c || !u->FindChannel(c)) continue; Log(u, c, "part") << "Reason: " << (!reason.empty() ? reason : "No reason"); EventManager::Get()->Dispatch(&Event::PrePartChannel::OnPrePartChannel, u, c); c->DeleteUser(u); EventManager::Get()->Dispatch(&Event::PartChannel::OnPartChannel, u, c, c->name, reason); } }
void Whois::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *u = User::Find(params[0]); if (u && u->server == Me) { const ServiceBot *bi = ServiceBot::Find(u->GetUID()); IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); if (bi) IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str()); IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Me->GetName().c_str(), Config->GetBlock("serverinfo")->Get<Anope::string>("description").c_str()); if (bi) IRCD->SendNumeric(317, source.GetSource(), "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(bi->signon)); IRCD->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", u->nick.c_str()); } else IRCD->SendNumeric(401, source.GetSource(), "%s :No such user.", params[0].c_str()); }
/* ** NICK - new ** source = NULL ** parv[0] = nickname ** parv[1] = hopcount ** parv[2] = timestamp ** parv[3] = modes ** parv[4] = username ** parv[5] = hostname ** parv[6] = server ** parv[7] = servicestamp ** parv[8] = IP ** parv[9] = info ** NICK - change ** source = oldnick ** parv[0] = new nickname ** parv[1] = hopcount */ void bahamut::Nick::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { if (params.size() == 10) { Server *s = Server::Find(params[6]); if (s == nullptr) { Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[6] << "?"; return; } NickServ::Nick *na = nullptr; time_t signon = 0, stamp = 0; try { signon = convertTo<time_t>(params[2]); stamp = convertTo<time_t>(params[7]); } catch (const ConvertException &) { } if (signon && signon == stamp && NickServ::service) na = NickServ::service->FindNick(params[0]); User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? na->GetAccount() : nullptr); } else { User *u = source.GetUser(); if (u) u->ChangeNick(params[0]); } }
void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &receiver = params[0]; Anope::string message = params[1]; User *u = source.GetUser(); if (IRCD->IsChannelValid(receiver)) { Channel *c = Channel::Find(receiver); if (c) { EventManager::Get()->Dispatch(&Event::Privmsg::OnPrivmsg, u, c, message); } } else { /* If a server is specified (nick@server format), make sure it matches * us, and strip it off. */ Anope::string botname = receiver; size_t s = receiver.find('@'); bool nick_only = false; if (s != Anope::string::npos) { Anope::string servername(receiver.begin() + s + 1, receiver.end()); botname = botname.substr(0, s); nick_only = true; if (!servername.equals_ci(Me->GetName())) return; } else if (!IRCD->RequiresID && Config->UseStrictPrivmsg) { ServiceBot *bi = ServiceBot::Find(receiver); if (!bi) return; Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick; u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str()); return; } ServiceBot *bi = ServiceBot::Find(botname, nick_only); if (bi) { if (message[0] == '\1' && message[message.length() - 1] == '\1') { if (message.substr(0, 6).equals_ci("\1PING ")) { Anope::string buf = message; buf.erase(buf.begin()); buf.erase(buf.end() - 1); IRCD->SendCTCP(bi, u->nick, "%s", buf.c_str()); } else if (message.substr(0, 9).equals_ci("\1VERSION\1")) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str()); } return; } EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotPrivmsg::OnBotPrivmsg, u, bi, message); if (MOD_RESULT == EVENT_STOP) return; bi->OnMessage(u, message); } } return; }
void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users) { bool created; Channel *c = Channel::FindOrCreate(chan, created, ts ? ts : Anope::CurTime); bool keep_their_modes = true; if (created) c->syncing = true; /* Some IRCds do not include a TS */ else if (!ts) ; /* Our creation time is newer than what the server gave us, so reset the channel to the older time */ else if (c->creation_time > ts) { c->creation_time = ts; c->Reset(); } /* Their TS is newer, don't accept any modes from them */ else if (ts > c->creation_time) keep_their_modes = false; /* Update the modes for the channel */ if (keep_their_modes && !modes.empty()) /* If we are syncing, mlock is checked later in Channel::Sync. It is important to not check it here * so that Channel::SetCorrectModes can correctly detect the presence of channel mode +r. */ c->SetModesInternal(source, modes, ts, !c->syncing); for (std::list<SJoinUser>::const_iterator it = users.begin(), it_end = users.end(); it != it_end; ++it) { const ChannelStatus &status = it->first; User *u = it->second; keep_their_modes = ts <= c->creation_time; // OnJoinChannel can call modules which can modify this channel's ts if (c->FindUser(u)) continue; /* Add the user to the channel */ c->JoinUser(u, keep_their_modes ? &status : NULL); /* Check if the user is allowed to join */ if (c->CheckKick(u)) continue; /* Set whatever modes the user should have, and remove any that * they aren't allowed to have (secureops etc). */ c->SetCorrectModes(u, true); EventManager::Get()->Dispatch(&Event::JoinChannel::OnJoinChannel, u, c); } /* Channel is done syncing */ if (c->syncing) { /* Sync the channel (mode lock, topic, etc) */ /* the channel is synced when the netmerge is complete */ Server *src = source.GetServer() ? source.GetServer() : Me; if (src && src->IsSynced()) { c->Sync(); if (c->CheckDelete()) delete c; } } }
void hybrid::Pong::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { source.GetServer()->Sync(false); }
/* * ngIRCd does not send an EOB, so we send a PING immediately * when receiving a new server and then finish sync once we * get a pong back from that server. */ void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override { if (!source.GetServer()->IsSynced()) source.GetServer()->Sync(false); }
void Version::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); IRCD->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str()); }
// :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB :Adam void ratbox::UID::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { /* Source is always the server */ User::OnIntroduce(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL); }
void User::Kill(const MessageSource &source, const Anope::string &reason) { Anope::string real_reason = source.GetName() + " (" + reason + ")"; IRCD->SendSVSKill(source, this, "%s", real_reason.c_str()); }
/* :0MCAAAAAB NICK newnick 1350157102 */ void hybrid::Nick::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { source.GetUser()->ChangeNick(params[0], convertTo<time_t>(params[1])); }