diff options
-rw-r--r-- | include/extern.h | 1 | ||||
-rw-r--r-- | include/modes.h | 2 | ||||
-rw-r--r-- | src/protocol/bahamut.c | 1 | ||||
-rw-r--r-- | src/protocol/inspircd11.c | 213 | ||||
-rw-r--r-- | src/protocol/inspircd12.cpp | 368 | ||||
-rw-r--r-- | src/protocol/ratbox.c | 28 | ||||
-rw-r--r-- | src/protocol/unreal32.c | 187 | ||||
-rw-r--r-- | src/servers.c | 43 |
8 files changed, 546 insertions, 297 deletions
diff --git a/include/extern.h b/include/extern.h index a4ed84ac1..a3d7a1734 100644 --- a/include/extern.h +++ b/include/extern.h @@ -488,7 +488,6 @@ E Server *findserver(Server *s, const char *name); E void do_server(const char *source, const char *servername, const char *hops, const char *descript, const char *numeric); E void do_squit(const char *source, int ac, const char **av); -E void capab_parse(int ac, const char **av); E int anope_check_sync(const char *name); E void finish_sync(Server *serv, int sync_links); diff --git a/include/modes.h b/include/modes.h index 66f5f85b8..b7874438e 100644 --- a/include/modes.h +++ b/include/modes.h @@ -36,7 +36,7 @@ enum ChannelModeName CMODE_PRIVATE, CMODE_REGISTERED, CMODE_SECRET, CMODE_TOPIC, CMODE_AUDITORIUM, CMODE_SSL, CMODE_ADMINONLY, CMODE_NOCTCP, CMODE_FILTER, CMODE_NOKNOCK, CMODE_REDIRECT, CMODE_REGMODERATED, CMODE_NONICK, CMODE_OPERONLY, CMODE_NOKICK, CMODE_REGISTEREDONLY, CMODE_STRIPCOLOR, CMODE_NONOTICE, CMODE_NOINVITE, CMODE_ALLINVITE, - CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, + CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, CMODE_DELAYEDJOIN, /* b/e/I */ CMODE_BAN, CMODE_EXCEPT, diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c index ddb9747ee..d045649a1 100644 --- a/src/protocol/bahamut.c +++ b/src/protocol/bahamut.c @@ -549,7 +549,6 @@ int anope_event_nick(const char *source, int ac, const char **av) /* EVENT : CAPAB */ int anope_event_capab(const char *source, int ac, const char **av) { - capab_parse(ac, av); return MOD_CONT; } diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c index db5f93c23..d86286562 100644 --- a/src/protocol/inspircd11.c +++ b/src/protocol/inspircd11.c @@ -513,15 +513,16 @@ int anope_event_fjoin(const char *source, int ac, const char **av) /* Loop through prefixes */ while ((ch = ModeManager::GetStatusChar(buf[0]))) { - buf.erase(buf.begin()); ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); if (cm) { Alog() << "Recieved unknown mode prefix " << buf[0] << " in FJOIN string"; + buf.erase(buf.begin()); continue; } + buf.erase(buf.begin()); Status.push_back(cm); } @@ -888,8 +889,6 @@ int anope_event_whois(const char *source, int ac, const char **av) int anope_event_capab(const char *source, int ac, const char **av) { - int argc; - if (strcasecmp(av[0], "START") == 0) { /* reset CAPAB */ has_servicesmod = 0; @@ -930,6 +929,157 @@ int anope_event_capab(const char *source, int ac, const char **av) if (strstr(av[1], "m_hidechans.so")) { has_hidechansmod = 1; } + } else if (strcasecmp(av[0], "CAPABILITIES") == 0) { + spacesepstream ssep(av[1]); + std::string capab; + while (ssep.GetToken(capab)) + { + if (capab.find("CHANMODES") != std::string::npos) + { + std::string modes(capab.begin() + 10, capab.end()); + commasepstream sep(modes); + std::string modebuf; + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'b': + ModeManager::AddChannelMode('b', new ChannelModeBan()); + continue; + case 'e': + ModeManager::AddChannelMode('e', new ChannelModeExcept()); + continue; + case 'I': + ModeManager::AddChannelMode('I', new ChannelModeInvite()); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'k': + ModeManager::AddChannelMode('k', new ChannelModeKey()); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'f': + ModeManager::AddChannelMode('f', new ChannelModeFlood()); + case 'l': + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT, true)); + continue; + case 'L': + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT, true)); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'i': + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + continue; + case 'm': + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + continue; + case 'n': + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + continue; + case 'p': + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + continue; + case 's': + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + continue; + case 't': + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + continue; + case 'r': + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + continue; + case 'c': + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + continue; + case 'u': + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + continue; + case 'z': + ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); + continue; + case 'A': + ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); + continue; + case 'C': + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + continue; + case 'G': + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + continue; + case 'K': + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + continue; + case 'N': + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + continue; + case 'O': + ModeManager::AddChannelMode('O', new ChannelModeOper()); + continue; + case 'Q': + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + continue; + case 'R': + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); + continue; + case 'S': + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); + continue; + case 'V': + ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); + continue; + } + } + } + else if (capab.find("PREIX=(") != std::string::npos) + { + std::string modes(capab.begin() + 8, capab.begin() + capab.find(")")); + std::string chars(capab.begin() + capab.find(")") + 1, capab.end()); + + for (size_t t = 0; t < modes.size(); ++t) + { + switch (modes[t]) + { + case 'q': + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '~')); + continue; + case 'a': + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true)); + continue; + case 'o': + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true)); + continue; + case 'h': + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%')); + continue; + case 'v': + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+')); + continue; + } + } + } + } } else if (strcasecmp(av[0], "END") == 0) { if (!has_globopsmod) { send_cmd(NULL, "ERROR :m_globops is not loaded. This is required by Anope"); @@ -958,24 +1108,7 @@ int anope_event_capab(const char *source, int ac, const char **av) if (!has_chgidentmod) { ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded."); } - if (has_messagefloodmod) { - ModeManager::AddChannelMode('f', new ChannelModeFlood()); - } - if (has_banexceptionmod) { - ModeManager::AddChannelMode('e', new ChannelModeExcept()); - } - if (has_inviteexceptionmod) { - ModeManager::AddChannelMode('e', new ChannelModeInvite()); - } ircd->svshold = has_svsholdmod; - - /* Generate a fake capabs parsing call so things like NOQUIT work - * fine. It's ugly, but it works.... - */ - argc = 6; - const char *argv[] = {"NOQUIT", "SSJ3", "NICK2", "VL", "TLKEXT", "UNCONNECT"}; - - capab_parse(argc, argv); } return MOD_CONT; } @@ -1033,9 +1166,8 @@ bool ChannelModeFlood::IsValid(const std::string &value) return false; } -void moduleAddModes() +static void AddModes() { - /* Add user modes */ ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); @@ -1043,41 +1175,6 @@ void moduleAddModes() ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); - - /* b/e/I */ - ModeManager::AddChannelMode('b', new ChannelModeBan()); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+')); - ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%')); - ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true)); - ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true)); - ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '~')); - - /* Add channel modes */ - ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); - ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); - ModeManager::AddChannelMode('k', new ChannelModeKey()); - ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); - ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); - ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); - ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); - ModeManager::AddChannelMode('r', new ChannelModeRegistered()); - ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); - ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); - ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); - ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); - ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); - ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); - ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); - ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); - ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); - ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); - ModeManager::AddChannelMode('O', new ChannelModeOper()); - ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); - ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); - ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); - ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); } class ProtoInspIRCd : public Module @@ -1094,7 +1191,7 @@ class ProtoInspIRCd : public Module pmodule_ircd_var(myIrcd); pmodule_ircd_useTSMode(0); - moduleAddModes(); + AddModes(); pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp index 245b37cb6..a767d5a06 100644 --- a/src/protocol/inspircd12.cpp +++ b/src/protocol/inspircd12.cpp @@ -578,13 +578,14 @@ int anope_event_fjoin(const char *source, int ac, const char **av) while (buf[0] != ',') { ChannelMode *cm = ModeManager::FindChannelModeByChar(buf[0]); - buf.erase(buf.begin()); if (!cm) { Alog() << "Recieved unknown mode prefix " << buf[0] << " in FJOIN string"; + buf.erase(buf.begin()); continue; } + buf.erase(buf.begin()); Status.push_back(cm); } buf.erase(buf.begin()); @@ -977,8 +978,6 @@ int anope_event_metadata(const char *source, int ac, const char **av) int anope_event_capab(const char *source, int ac, const char **av) { - int argc; - if (strcasecmp(av[0], "START") == 0) { /* reset CAPAB */ has_servicesmod = 0; @@ -997,11 +996,6 @@ int anope_event_capab(const char *source, int ac, const char **av) } if (strstr(av[1], "m_services_account.so")) { has_servicesmod = 1; - ModeManager::AddChannelMode('r', new ChannelModeRegistered()); - ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); - ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); - ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); - ModeManager::AddUserMode('R', new UserMode(UMODE_REGPRIV)); } if (strstr(av[1], "m_svshold.so")) { has_svsholdmod = 1; @@ -1023,75 +1017,256 @@ int anope_event_capab(const char *source, int ac, const char **av) } if (strstr(av[1], "m_hidechans.so")) { has_hidechansmod = 1; - ModeManager::AddUserMode('I', new UserMode(UMODE_PRIV)); } if (strstr(av[1], "m_servprotect.so")) { ircd->pseudoclient_mode = "+Ik"; - ModeManager::AddUserMode('k', new UserMode(UMODE_PROTECTED)); } - - /* Add channel modes to Anope, but only if theyre supported by the IRCd */ - if (strstr(av[1], "m_blockcolor.so")) - ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); - if (strstr(av[1], "m_auditorium.so")) - ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); - if (strstr(av[1], "m_sslmodes.so")) - ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); - if (strstr(av[1], "m_allowinvite.so")) - ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); - if (strstr(av[1], "m_noctcp.so")) - ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); - if (strstr(av[1], "m_censor.so")) - ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); - if (strstr(av[1], "m_knock.so")) - ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); - if (strstr(av[1], "m_redirect.so")) - ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT, true)); - if (strstr(av[1], "m_nonicks.so")) - ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); - if (strstr(av[1], "m_operchans.so")) - ModeManager::AddChannelMode('O', new ChannelModeOper()); - if (strstr(av[1], "m_nokicks.so")) - ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); - if (strstr(av[1], "m_stripcolor.so")) - ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); - if (strstr(av[1], "m_callerid.so")) - ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); - if (strstr(av[1], "m_helpop.so")) - ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); - if (strstr(av[1], "m_cloaking.so")) - ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); - if (strstr(av[1], "m_blockcaps.so")) - ModeManager::AddChannelMode('B', new ChannelMode(CMODE_BLOCKCAPS)); - if (strstr(av[1], "m_nickflood.so")) - ModeManager::AddChannelMode('F', new ChannelModeParam(CMODE_NICKFLOOD, true)); - if (strstr(av[1], "m_messageflood.so")) - ModeManager::AddChannelMode('f', new ChannelModeParam(CMODE_FLOOD, true)); - if (strstr(av[1], "m_joinflood.so")) - ModeManager::AddChannelMode('j', new ChannelModeParam(CMODE_JOINFLOOD, true)); - if (strstr(av[1], "m_permchannels.so")) - ModeManager::AddChannelMode('P', new ChannelMode(CMODE_PERM)); - if (strstr(av[1], "m_nonotice.so")) - ModeManager::AddChannelMode('T', new ChannelMode(CMODE_NONOTICE)); - - /* User modes */ - if (strstr(av[1], "m_botmode.so")) - ModeManager::AddUserMode('B', new UserMode(UMODE_BOT)); - if (strstr(av[1], "m_commonchans.so")) - ModeManager::AddUserMode('c', new UserMode(UMODE_COMMONCHANS)); - if (strstr(av[1], "m_deaf.so")) - ModeManager::AddUserMode('d', new UserMode(UMODE_DEAF)); - if (strstr(av[1], "m_censor.so")) - ModeManager::AddUserMode('G', new UserMode(UMODE_FILTER)); - if (strstr(av[1], "m_hideoper.so")) - ModeManager::AddUserMode('H', new UserMode(UMODE_HIDEOPER)); - if (strstr(av[1], "m_invisible.so")) - ModeManager::AddUserMode('Q', new UserMode(UMODE_HIDDEN)); - if (strstr(av[1], "m_stripcolor.so")) - ModeManager::AddUserMode('S', new UserMode(UMODE_STRIPCOLOR)); - if (strstr(av[1], "m_showwhois.so")) - ModeManager::AddUserMode('W', new UserMode(UMODE_WHOIS)); - + } else if (strcasecmp(av[0], "CAPABILITIES") == 0) { + spacesepstream ssep(av[1]); + std::string capab; + while (ssep.GetToken(capab)) + { + if (capab.find("CHANMODES") != std::string::npos) + { + std::string modes(capab.begin() + 10, capab.end()); + commasepstream sep(modes); + std::string modebuf; + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'b': + ModeManager::AddChannelMode('b', new ChannelModeBan()); + continue; + case 'e': + ModeManager::AddChannelMode('e', new ChannelModeExcept()); + continue; + case 'I': + ModeManager::AddChannelMode('I', new ChannelModeInvite()); + continue; + case 'g': + ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'k': + ModeManager::AddChannelMode('k', new ChannelModeKey()); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'F': + ModeManager::AddChannelMode('F', new ChannelModeParam(CMODE_NICKFLOOD, true)); + continue; + case 'J': + ModeManager::AddChannelMode('J', new ChannelModeParam(CMODE_JOINFLOOD, true)); + continue; + case 'L': + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT, true)); + continue; + case 'f': + ModeManager::AddChannelMode('f', new ChannelModeFlood()); + continue; + case 'j': + ModeManager::AddChannelMode('j', new ChannelModeParam(CMODE_JOINFLOOD, true)); + continue; + case 'l': + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT, true)); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'A': + ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); + continue; + case 'B': + ModeManager::AddChannelMode('B', new ChannelMode(CMODE_BLOCKCAPS)); + continue; + case 'C': + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + continue; + case 'D': + ModeManager::AddChannelMode('D', new ChannelMode(CMODE_DELAYEDJOIN)); + continue; + case 'G': + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + continue; + case 'K': + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + continue; + case 'M': + ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); + continue; + case 'N': + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + continue; + case 'O': + ModeManager::AddChannelMode('O', new ChannelModeOper()); + continue; + case 'P': + ModeManager::AddChannelMode('P', new ChannelMode(CMODE_PERM)); + continue; + case 'Q': + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + continue; + case 'R': + ModeManager::AddUserMode('R', new UserMode(UMODE_REGPRIV)); + continue; + case 'S': + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); + continue; + case 'T': + ModeManager::AddChannelMode('T', new ChannelMode(CMODE_NONOTICE)); + continue; + case 'i': + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + continue; + case 'm': + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + continue; + case 'n': + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + continue; + case 'p': + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + continue; + case 'r': + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + continue; + case 's': + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + continue; + case 't': + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + continue; + case 'u': + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + continue; + case 'z': + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + continue; + case 'h': + ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); + continue; + } + } + } + else if (capab.find("USERMODES") != std::string::npos) + { + std::string modes(capab.begin() + 10, capab.end()); + commasepstream sep(modes); + std::string modebuf; + + while (sep.GetToken(modebuf)) + { + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 's': + ModeManager::AddUserMode('S', new UserMode(UMODE_STRIPCOLOR)); + continue; + case 'B': + ModeManager::AddUserMode('B', new UserMode(UMODE_BOT)); + continue; + case 'G': + ModeManager::AddUserMode('G', new UserMode(UMODE_FILTER)); + continue; + case 'H': + ModeManager::AddUserMode('H', new UserMode(UMODE_HIDEOPER)); + continue; + case 'I': + ModeManager::AddUserMode('I', new UserMode(UMODE_PRIV)); + continue; + case 'Q': + ModeManager::AddUserMode('Q', new UserMode(UMODE_HIDDEN)); + continue; + case 'R': + ModeManager::AddUserMode('R', new UserMode(UMODE_REGPRIV)); + continue; + case 'S': + ModeManager::AddUserMode('S', new UserMode(UMODE_STRIPCOLOR)); + continue; + case 'W': + ModeManager::AddUserMode('W', new UserMode(UMODE_WHOIS)); + continue; + case 'c': + ModeManager::AddUserMode('c', new UserMode(UMODE_COMMONCHANS)); + continue; + case 'g': + ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); + continue; + case 'i': + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + continue; + case 'k': + ModeManager::AddUserMode('k', new UserMode(UMODE_PROTECTED)); + continue; + case 'o': + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + continue; + case 'r': + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + continue; + case 'w': + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + continue; + case 'x': + ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); + continue; + case 'd': + ModeManager::AddUserMode('d', new UserMode(UMODE_DEAF)); + continue; + } + } + } + } + else if (capab.find("PREFIX=(") != std::string::npos) + { + std::string modes(capab.begin() + 8, capab.begin() + capab.find(")")); + std::string chars(capab.begin() + capab.find(")") + 1, capab.end()); + + for (size_t t = 0; t < modes.size(); ++t) + { + switch (modes[t]) + { + case 'q': + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, chars[t])); + continue; + case 'a': + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, chars[t], true)); + continue; + case 'o': + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, chars[t], true)); + continue; + case 'h': + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, chars[t])); + continue; + case 'v': + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, chars[t])); + continue; + } + } + } + } } else if (strcasecmp(av[0], "END") == 0) { if (!has_globopsmod) { send_cmd(NULL, "ERROR :m_globops is not loaded. This is required by Anope"); @@ -1120,24 +1295,7 @@ int anope_event_capab(const char *source, int ac, const char **av) if (!has_chgidentmod) { ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded."); } - if (has_messagefloodmod) { - ModeManager::AddChannelMode('f', new ChannelModeFlood()); - } - if (has_banexceptionmod) { - ModeManager::AddChannelMode('e', new ChannelModeExcept()); - } - if (has_inviteexceptionmod) { - ModeManager::AddChannelMode('I', new ChannelModeInvite()); - } ircd->svshold = has_svsholdmod; - - /* Generate a fake capabs parsing call so things like NOQUIT work - * fine. It's ugly, but it works.... - */ - argc = 6; - const char *argv[] = {"NOQUIT", "SSJ3", "NICK2", "VL", "TLKEXT", "UNCONNECT"}; - - capab_parse(argc, argv); } return MOD_CONT; } @@ -1215,34 +1373,6 @@ bool ChannelModeFlood::IsValid(const std::string &value) else return 0; } -void moduleAddModes() -{ - /* Add user modes */ - ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); - ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); - ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); - - /* b/e/I */ - ModeManager::AddChannelMode('b', new ChannelModeBan()); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+')); - ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%')); - ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true)); - ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true)); - ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '~')); - - /* Add channel modes */ - ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); - ModeManager::AddChannelMode('k', new ChannelModeKey()); - ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT, true)); - ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); - ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); - ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); - ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); - ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); -} - class ProtoInspIRCd : public Module { public: @@ -1260,8 +1390,6 @@ class ProtoInspIRCd : public Module pmodule_ircd_var(myIrcd); pmodule_ircd_useTSMode(0); - moduleAddModes(); - pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); } diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c index dbd32ac10..b5c7f66a7 100644 --- a/src/protocol/ratbox.c +++ b/src/protocol/ratbox.c @@ -794,34 +794,6 @@ int anope_event_tmode(const char *source, int ac, const char **av) /* Event: PROTOCTL */ int anope_event_capab(const char *source, int ac, const char **av) { - int argvsize = 8; - int argc; - const char **argv; - char *str; - - if (ac < 1) - return MOD_CONT; - - /* We get the params as one arg, we should split it for capab_parse */ - argv = static_cast<const char **>(scalloc(argvsize, sizeof(const char *))); - argc = 0; - while ((str = myStrGetToken(av[0], ' ', argc))) { - if (argc == argvsize) { - argvsize += 8; - argv = static_cast<const char **>(srealloc(argv, argvsize * sizeof(const char *))); - } - argv[argc] = str; - argc++; - } - - capab_parse(argc, argv); - - /* Free our built ac/av */ - for (argvsize = 0; argvsize < argc; argvsize++) { - delete [] argv[argvsize]; - } - free(const_cast<char **>(argv)); - return MOD_CONT; } diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c index 7963ae6c8..427500b98 100644 --- a/src/protocol/unreal32.c +++ b/src/protocol/unreal32.c @@ -477,7 +477,139 @@ class UnrealIRCdProto : public IRCDProto /* Event: PROTOCTL */ int anope_event_capab(const char *source, int ac, const char **av) { - capab_parse(ac, av); + for (int i = 0; i < ac; ++i) + { + std::string capab = av[i]; + + if (capab.find("CHANMODES") != std::string::npos) + { + std::string modes(capab.begin() + 10, capab.end()); + commasepstream sep(modes); + std::string modebuf; + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'b': + ModeManager::AddChannelMode('b', new ChannelModeBan()); + continue; + case 'e': + ModeManager::AddChannelMode('e', new ChannelModeExcept()); + continue; + case 'I': + ModeManager::AddChannelMode('I', new ChannelModeInvite()); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'k': + ModeManager::AddChannelMode('k', new ChannelModeKey()); + continue; + case 'f': + ModeManager::AddChannelMode('f', new ChannelModeFlood()); + continue; + case 'L': + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'l': + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT, true)); + continue; + case 'j': + ModeManager::AddChannelMode('j', new ChannelModeParam(CMODE_JOINFLOOD, true)); + continue; + } + } + + sep.GetToken(modebuf); + for (size_t t = 0; t < modebuf.size(); ++t) + { + switch (modebuf[t]) + { + case 'p': + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + continue; + case 's': + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + continue; + case 'm': + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + continue; + case 'n': + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + continue; + case 't': + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + continue; + case 'i': + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + continue; + case 'r': + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + continue; + case 'R': + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); + continue; + case 'c': + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + continue; + case 'O': + ModeManager::AddChannelMode('O', new ChannelModeOper()); + continue; + case 'A': + ModeManager::AddChannelMode('A', new ChannelModeAdmin()); + continue; + case 'Q': + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + continue; + case 'K': + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + continue; + case 'V': + ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); + continue; + case 'C': + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + continue; + case 'u': + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + continue; + case 'z': + ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); + continue; + case 'N': + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + continue; + case 'S': + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); + continue; + case 'M': + ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); + continue; + case 'T': + ModeManager::AddChannelMode('T', new ChannelMode(CMODE_NONOTICE)); + continue; + case 'G': + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + continue; + } + } + } + } return MOD_CONT; } @@ -1218,8 +1350,15 @@ bool ChannelModeFlood::IsValid(const std::string &value2) } } -void moduleAddModes() +static void AddModes() { + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+')); + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true)); + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true)); + /* Unreal sends +q as * */ + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '*')); + /* Add user modes */ ModeManager::AddUserMode('A', new UserMode(UMODE_SERV_ADMIN)); ModeManager::AddUserMode('B', new UserMode(UMODE_BOT)); @@ -1246,48 +1385,6 @@ void moduleAddModes() ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); ModeManager::AddUserMode('z', new UserMode(UMODE_SSL)); - - /* b/e/I */ - ModeManager::AddChannelMode('b', new ChannelModeBan()); - ModeManager::AddChannelMode('e', new ChannelModeExcept()); - ModeManager::AddChannelMode('I', new ChannelModeInvite()); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+')); - ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%')); - ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true)); - ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true)); - /* Unreal sends +q as * */ - ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '*')); - - /* Add channel modes */ - ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); - ModeManager::AddChannelMode('f', new ChannelModeFlood()); - ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); - ModeManager::AddChannelMode('j', new ChannelModeParam(CMODE_JOINFLOOD, true)); - ModeManager::AddChannelMode('k', new ChannelModeKey()); - ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT, true)); - ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); - ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); - ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); - ModeManager::AddChannelMode('r', new ChannelModeRegistered()); - ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); - ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); - ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); - ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); - ModeManager::AddChannelMode('A', new ChannelModeAdmin()); - ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); - ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); - ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); - ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); - ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); - ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); - ModeManager::AddChannelMode('O', new ChannelModeOper()); - ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); - ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); - ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); - ModeManager::AddChannelMode('T', new ChannelMode(CMODE_NONOTICE)); - ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); } class ProtoUnreal : public Module @@ -1304,7 +1401,7 @@ class ProtoUnreal : public Module pmodule_ircd_var(myIrcd); pmodule_ircd_useTSMode(0); - moduleAddModes(); + AddModes(); pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/servers.c b/src/servers.c index fca229d22..474f4f3e1 100644 --- a/src/servers.c +++ b/src/servers.c @@ -460,49 +460,6 @@ void do_squit(const char *source, int ac, const char **av) /*************************************************************************/ /** - * Handle parsing the CAPAB/PROTOCTL messages - * @param ac Number of arguments in av - * @param av Agruments - * @return void - */ -void capab_parse(int ac, const char **av) -{ - int i; - int j; - char *s, *tmp; - - const char *temp; - - for (i = 0; i < ac; i++) { - temp = av[i]; - - s = myStrGetToken(temp, '=', 0); - tmp = myStrGetTokenRemainder(temp, '=', 1); - - if (!s) - continue; - - for (j = 0; capab_info[j].token; j++) { - if (stricmp(s, capab_info[j].token) == 0) - uplink_capab |= capab_info[j].flag; - /* Special cases */ - if ((stricmp(s, "NICKIP") == 0) && !ircd->nickip) - ircd->nickip = 1; - if ((stricmp(s, "CHANMODES") == 0) && tmp) - ircd->chanmodes = sstrdup(tmp); - if ((stricmp(s, "NICKCHARS") == 0) && tmp) - ircd->nickchars = sstrdup(tmp); - } - - delete [] s; - if (tmp) - delete [] tmp; - } -} - -/*************************************************************************/ - -/** * Search the uline servers array to find out if the server that just set the * mode is in our uline list * @param server Server Setting the mode |