123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001
- From: Alexander Barton <alex@barton.de>
- Date: Mon, 16 May 2011 18:23:01 +0200
- Subject: [PATCH 1/2] Revert "Removed ngircd as we've decided not to support it at this time"
- This reverts commit 605b5d57171d2f0fac56ee2ee3e1b1bbdadeb24f and re-enables
- the ngIRCd protocol module for Anope.
- ---
- modules/protocol/ngircd.cpp | 475 +++++++++++++++++++++++++++++++++++++++++++
- 1 files changed, 475 insertions(+), 0 deletions(-)
- create mode 100644 modules/protocol/ngircd.cpp
- diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
- new file mode 100644
- index 0000000..6e1f21f
- --- /dev/null
- +++ b/modules/protocol/ngircd.cpp
- @@ -0,0 +1,475 @@
- +/* ngIRCd IRCD functions
- + *
- + * (C) 2003-2011 Anope Team
- + * Contact us at team@anope.org
- + *
- + * Please read COPYING and README for further details.
- + *
- + * Based on the original code of Epona by Lara.
- + * Based on the original code of Services by Andy Church.
- + */
- +
- +#include "services.h"
- +#include "modules.h"
- +
- +IRCDVar myIrcd[] = {
- + {"ngIRCd", /* ircd name */
- + "+oi", /* Modes used by pseudoclients */
- + 0, /* SVSNICK */
- + 0, /* Vhost */
- + 0, /* Supports SNlines */
- + 0, /* Supports SQlines */
- + 0, /* Supports SZlines */
- + 0, /* Join 2 Message */
- + 0, /* Chan SQlines */
- + 1, /* Quit on Kill */
- + 0, /* vidents */
- + 0, /* svshold */
- + 0, /* time stamp on mode */
- + 0, /* UMODE */
- + 0, /* O:LINE */
- + 0, /* No Knock requires +i */
- + 0, /* Can remove User Channel Modes with SVSMODE */
- + 0, /* Sglines are not enforced until user reconnects */
- + 0, /* ts6 */
- + "$", /* TLD Prefix for Global */
- + 20, /* Max number of modes we can send per line */
- + 0, /* IRCd sends a SSL users certificate fingerprint */
- + }
- + ,
- + {NULL}
- +};
- +
- +/* PASS */
- +class ngIRCdProto : public IRCDProto
- +{
- + void SendAkill(User *u, const XLine *x)
- + {
- + if (SGLine && u == NULL)
- + for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- + {
- + u = it->second;
- + ++it;
- + if (SGLine->Check(u) != NULL)
- + break;
- + }
- + }
- +
- + void SendAkillDel(const XLine*) { }
- +
- + void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
- + {
- + send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
- + }
- +
- + void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
- + {
- + send_cmd(user->nick, "JOIN %s", c->name.c_str());
- + if (status)
- + for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- + if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
- + c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
- + }
- +
- + void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
- + {
- + send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
- + }
- +
- + /* SERVER name hop descript */
- + void SendServer(const Server *server)
- + {
- + send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
- + }
- +
- + void SendConnect()
- + {
- + send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
- + /* Make myself known to myself in the serverlist */
- + SendServer(Me);
- + /* finish the enhanced server handshake and register the connection */
- + this->SendNumeric(Config->ServerName, 376, "*", ":End of MOTD command");
- + }
- +
- + // Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
- + void SendClientIntroduction(const User *u, const Anope::string &modes)
- + {
- + EnforceQlinedNick(u->nick, "");
- + send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
- + }
- +
- + void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
- + {
- + if (!buf.empty())
- + send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
- + else
- + send_cmd(bi->nick, "PART %s", chan->name.c_str());
- + }
- +
- + void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
- + {
- + send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
- + }
- +
- + void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
- + {
- + send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
- + }
- +
- + void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
- + {
- + if (!buf.empty())
- + send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
- + else
- + send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
- + }
- +
- + void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
- + {
- + send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
- + }
- +
- + /* INVITE */
- + void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
- + {
- + send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
- + }
- +
- + void SendChannel(Channel *c)
- + {
- + Anope::string mlock_modes = get_mlock_modes(c->ci, true);
- + if (mlock_modes.empty())
- + mlock_modes = "+";
- + send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
- + }
- + void SendTopic(BotInfo *bi, Channel *c)
- + {
- + send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
- + }
- +};
- +
- +class ngIRCdIRCdMessage : public IRCdMessage
- +{
- + public:
- + bool OnSJoin(const Anope::string&, const std::vector<Anope::string>&) { return false; }
- +
- + /*
- + * Received: :dev.anope.de MODE #anope +b *!*@*aol*
- + */
- + bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- + {
- + if (params.size() < 2)
- + return true;
- +
- + Anope::string modes = params[1];
- + for (unsigned i = 2; i < params.size(); ++i)
- + modes += " " + params[i];
- +
- + if (params[0][0] == '#' || params[0][0] == '&')
- + do_cmode(source, params[0], modes, "");
- + else
- + do_umode(params[0], params[1]);
- +
- + return true;
- + }
- +
- + /*
- + Received: :DukeP_ NICK :test2
- + Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator
- + source = nickname on nickchange, servername on newuser
- + params[0] = nick
- + params[1] = <unknown>
- + params[2] = username
- + params[3] = host
- + params[4] = <unknown>
- + params[5] = modes
- + params[6] = info
- + */
- + bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- + {
- + if (params.size() == 1)
- + {
- + // we have a nickchange
- + do_nick(source, params[0], "", "", "", "", Anope::CurTime, "", "", "", "");
- + }
- + else if (params.size() == 7)
- + {
- + // a new user is connecting to the network
- + User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
- + if (user)
- + validate_user(user);
- + }
- + else
- + {
- + Log() << "Received NICK with invalid number of parameters. source = " << source << "param[0] = " << params[0] << "params.size() = " << params.size();
- + }
- + return true;
- + }
- +
- + bool OnServer(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- + {
- + if (params.size() == 3)
- + do_server("", params[0], 0, params[2], params[1]);
- + else
- + do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
- + return true;
- + }
- +
- + bool OnTopic(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- + {
- + Channel *c = findchan(params[0]);
- + if (!c)
- + {
- + Log() << "TOPIC for nonexistant channel " << params[0];
- + return true;
- + }
- +
- + c->ChangeTopicInternal(source, params[1]);
- + return true;
- + }
- +
- + /*
- + * <@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>
- + */
- + bool OnJoin (const Anope::string &source, const std::vector<Anope::string> ¶ms)
- + {
- + if (!params.empty())
- + {
- + size_t pos = params[0].find('\7');
- + if (pos != Anope::string::npos)
- + {
- + Anope::string channel = params[0].substr(0, pos);
- + Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
- + do_join(source, channel, "");
- + do_cmode(source, channel, mode, "");
- + }
- + else
- + do_join(source, params[0], "");
- + }
- + return true;
- + }
- +};
- +
- +/*
- + * CHANINFO <chan> +<modes>
- + * CHANINFO <chan> +<modes> :<topic>
- + * CHANINFO <chan> +<modes> <key> <limit> :<topic>
- + */
- +bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- +
- + Channel *c = findchan(params[0]);
- + if (!c)
- + c = new Channel(params[0]);
- +
- + Anope::string modes = params[1];
- +
- + if (params.size() == 3)
- + {
- + c->ChangeTopicInternal(source, params[2], Anope::CurTime);
- + }
- + else if (params.size() == 5)
- + {
- + for (size_t i = 0, end = params[1].length(); i < end; ++i)
- + {
- + switch(params[1][i])
- + {
- + case 'k':
- + modes += " " + params[2];
- + continue;
- + case 'l':
- + modes += " " + params[3];
- + continue;
- + }
- + }
- + c->ChangeTopicInternal(source, params[4], Anope::CurTime);
- + }
- +
- + c->SetModesInternal(NULL, modes);
- +
- + return true;
- +}
- +
- +/*
- + * Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP
- + */
- +bool event_njoin(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + Channel *c = findchan(params[0]);
- + commasepstream sep(params[1]);
- + Anope::string buf;
- +
- + if (!c)
- + {
- + c = new Channel(params[0], Anope::CurTime);
- + c->SetFlag(CH_SYNCING);
- + }
- +
- + while (sep.GetToken(buf))
- + {
- + std::list<ChannelMode *> Status;
- + char ch;
- +
- + /* Get prefixes from the nick */
- + while ((ch = ModeManager::GetStatusChar(buf[0])))
- + {
- + buf.erase(buf.begin());
- + ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
- + if (!cm)
- + {
- + Log() << "Received unknown mode prefix " << ch << " in NJOIN string.";
- + continue;
- + }
- + Status.push_back(cm);
- + }
- + User *u = finduser(buf);
- + if (!u)
- + {
- + Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << c->name;
- + continue;
- + }
- +
- + EventReturn MOD_RESULT;
- + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
- +
- + /* Add the user to the Channel */
- + c->JoinUser(u);
- +
- + /* Update their status internally on the channel
- + * This will enforce secureops etc on the user
- + */
- + for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
- + c->SetModeInternal(*it, buf);
- + /* Now set whatever modes this user is allowed to have on the channel */
- + chan_set_correct_modes(u, c, 1);
- +
- + /* Check to see if modules want the user to join, if they do
- + * check to see if they are allowed to join (CheckKick will kick/ban them)
- + * Don't trigger OnJoinChannel event then as the user will be destroyed
- + */
- + if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
- + continue;
- +
- + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
- + } /* while */
- +
- + if (c->HasFlag(CH_SYNCING))
- + {
- + c->UnsetFlag(CH_SYNCING);
- + c->Sync();
- + }
- +
- + return true;
- +}
- +
- +bool event_kick(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + if (params.size() > 2)
- + do_kick(source, params[0], params[1], params[2]);
- + return true;
- +}
- +
- +bool event_pass(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + return true;
- +}
- +
- +bool event_005(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + size_t pos;
- + Anope::string name, data;
- + for (unsigned i = 0, end = params.size(); i < end; ++i)
- + {
- + pos = params[i].find('=');
- + if (pos != Anope::string::npos)
- + {
- + name = params[i].substr(0, pos);
- + data = params[i].substr(pos+1, params[i].length());
- + if (name == "NICKLEN")
- + {
- + unsigned newlen = convertTo<unsigned>(data);
- + if (Config->NickLen != newlen)
- + {
- + Log() << "Config->NickLen changed from " << Config->NickLen << " to " << newlen;
- + Config->NickLen = newlen;
- + }
- + }
- + }
- + }
- + return true;
- +}
- +
- +bool event_442(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + return true;
- +}
- +
- +bool event_376(const Anope::string &source, const std::vector<Anope::string> ¶ms)
- +{
- + return true;
- +}
- +
- +
- +class ProtongIRCd : public Module
- +{
- + Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
- + message_442, message_376;
- +
- + ngIRCdProto ircd_proto;
- + ngIRCdIRCdMessage ircd_message;
- +
- + void AddModes()
- + {
- + /* Add user modes */
- + ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
- + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- + ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- + ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
- + ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
- + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
- +
- + /* b/e/I */
- + ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
- + ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
- +
- + /* v/h/o/a/q */
- + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
- + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
- +
- + /* Add channel modes */
- + // channel modes: biIklmnoPstvz
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
- + ModeManager::AddChannelMode(new ChannelModeKey('k'));
- + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
- + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
- + }
- +
- + public:
- + ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
- + message_kick("KICK", event_kick), message_pass("PASS", event_pass),
- + message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
- + message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
- + {
- + this->SetAuthor("Anope");
- + this->SetType(PROTOCOL);
- +
- + Capab.SetFlag(CAPAB_QS);
- +
- + pmodule_ircd_var(myIrcd);
- + pmodule_ircd_proto(&this->ircd_proto);
- + pmodule_ircd_message(&this->ircd_message);
- +
- + this->AddModes();
- + }
- +};
- +
- +MODULE_INIT(ProtongIRCd)
- --
- 1.7.2.5
|