From d45cb5451eedd213862abeab5da9a30d96a494b2 Mon Sep 17 00:00:00 2001 From: MichaƂ Zegan Date: Thu, 11 Dec 2014 20:29:17 +0100 Subject: Fix issue 1627. It required that the FHost message was rewritten for the insp20 protocol module instead of relying on inspircd12's version. The insp20 version internally removes +x mode on host change. --- modules/protocol/inspircd20.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 98cfb40dc..eb711e099 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -782,6 +782,19 @@ struct IRCDMessageEncap : IRCDMessage } }; +struct IRCDMessageFHost : IRCDMessage +{ + IRCDMessageFHost(Module *creator) : IRCDMessage(creator, "FHOST", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + void Run(MessageSource &source, const std::vector ¶ms) anope_override + { + User *u = source.GetUser(); + u->SetDisplayedHost(params[0]); + if (u->HasMode("CLOAK")) + u->RemoveModeInternal(source, ModeManager::FindUserModeByName("CLOAK")); + } +}; + struct IRCDMessageFIdent : IRCDMessage { IRCDMessageFIdent(Module *creator) : IRCDMessage(creator, "FIDENT", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } @@ -857,7 +870,7 @@ class ProtoInspIRCd20 : public Module Message::Topic message_topic; /* InspIRCd 1.2 message handlers */ - ServiceAlias message_endburst, message_fhost, message_fjoin, message_fmode, + ServiceAlias message_endburst, message_fjoin, message_fmode, message_ftopic, message_idle, message_metadata, message_mode, message_nick, message_opertype, message_rsquit, message_server, message_squit, message_time, message_uid; @@ -865,6 +878,7 @@ class ProtoInspIRCd20 : public Module /* Our message handlers */ IRCDMessageCapab message_capab; IRCDMessageEncap message_encap; + IRCDMessageFHost message_fhost; IRCDMessageFIdent message_fident; IRCDMessageSave message_save; @@ -883,7 +897,6 @@ class ProtoInspIRCd20 : public Module message_privmsg(this), message_quit(this), message_stats(this), message_topic(this), message_endburst("IRCDMessage", "inspircd20/endburst", "inspircd12/endburst"), - message_fhost("IRCDMessage", "inspircd20/fhost", "inspircd12/fhost"), message_fjoin("IRCDMessage", "inspircd20/fjoin", "inspircd12/fjoin"), message_fmode("IRCDMessage", "inspircd20/fmode", "inspircd12/fmode"), message_ftopic("IRCDMessage", "inspircd20/ftopic", "inspircd12/ftopic"), @@ -898,7 +911,7 @@ class ProtoInspIRCd20 : public Module message_time("IRCDMessage", "inspircd20/time", "inspircd12/time"), message_uid("IRCDMessage", "inspircd20/uid", "inspircd12/uid"), - message_capab(this), message_encap(this), message_fident(this), message_save(this) + message_capab(this), message_encap(this), message_fhost(this), message_fident(this), message_save(this) { if (ModuleManager::LoadModule("inspircd12", User::Find(creator)) != MOD_ERR_OK) -- cgit From 609f87d39fd0d0eeea28aefceca1702e692f2554 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Jan 2015 14:23:02 -0500 Subject: Include botserv/* in default Services Administrator opertype to behave like 1.8 --- data/example.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/example.conf b/data/example.conf index 223f770fb..534b99fa3 100644 --- a/data/example.conf +++ b/data/example.conf @@ -851,7 +851,7 @@ opertype inherits = "Services Operator" - commands = "chanserv/access/list chanserv/drop chanserv/getkey chanserv/saset/noexpire memoserv/sendall nickserv/saset/* nickserv/getemail operserv/news operserv/jupe operserv/svs operserv/stats operserv/oline operserv/noop operserv/forbid global/*" + commands = "botserv/* chanserv/access/list chanserv/drop chanserv/getkey chanserv/saset/noexpire memoserv/sendall nickserv/saset/* nickserv/getemail operserv/news operserv/jupe operserv/svs operserv/stats operserv/oline operserv/noop operserv/forbid global/*" privs = "*" } -- cgit From 32007f81cf0bb475f3621d7637666b06ffa482b9 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Jan 2015 15:17:16 -0500 Subject: Add networkinfo:nick_chars option to allow configuring additional characters allowed in nicknames --- data/example.conf | 10 ++++++++++ include/config.h | 2 ++ src/config.cpp | 1 + src/protocol.cpp | 6 ++++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/data/example.conf b/data/example.conf index 534b99fa3..c1fc5c20d 100644 --- a/data/example.conf +++ b/data/example.conf @@ -319,6 +319,16 @@ networkinfo */ modelistsize = 100 + /* + * Characters allowed in nicknames. This always includes the characters described + * in RFC1459, and so does not need to be set for normal behavior. Changing this to + * include characters your IRCd doesn't support will cause your IRCd and/or Services + * to break. Multibyte characters are not supported, nor are escape sequences. + * + * It is recommended you DON'T change this. + */ + #nick_chars = "" + /* * The characters allowed in hostnames. This is used for validating hostnames given * to services, such as BotServ bot hostnames and user vhosts. Changing this is not diff --git a/include/config.h b/include/config.h index b132c5d2d..2ae6e3ced 100644 --- a/include/config.h +++ b/include/config.h @@ -103,6 +103,8 @@ namespace Configuration time_t TimeoutCheck; /* options:usestrictprivmsg */ bool UseStrictPrivmsg; + /* networkinfo:nickchars */ + Anope::string NickChars; /* either "/msg " or "/" */ Anope::string StrictPrivmsg; diff --git a/src/config.cpp b/src/config.cpp index 3ce4251e7..18a6c5d39 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -191,6 +191,7 @@ Conf::Conf() : Block("") } this->DefLanguage = options->Get("defaultlanguage"); this->TimeoutCheck = options->Get("timeoutcheck"); + this->NickChars = networkinfo->Get("nick_chars"); for (int i = 0; i < this->CountBlock("uplink"); ++i) { diff --git a/src/protocol.cpp b/src/protocol.cpp index 05bcb54fe..0d09fee24 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -365,8 +365,10 @@ bool IRCDProto::IsNickValid(const Anope::string &nick) Anope::string special = "[]\\`_^{|}"; for (unsigned 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 - && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[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; -- cgit From 1f02278a1c307975548499fe2a6d6d79f8397d0c Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Jan 2015 15:23:24 -0500 Subject: Log user away messages --- data/example.conf | 2 +- src/messages.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/data/example.conf b/data/example.conf index c1fc5c20d..0db803f62 100644 --- a/data/example.conf +++ b/data/example.conf @@ -713,7 +713,7 @@ log * create, destroy, join, part, kick, leave, mode * * Valid user options are: - * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper + * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper, away * * Rawio and debug are simple yes/no answers, there are no types for them. * diff --git a/src/messages.cpp b/src/messages.cpp index 7036acfc7..a771b2f1f 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -25,7 +25,13 @@ using namespace Message; void Away::Run(MessageSource &source, const std::vector ¶ms) { - FOREACH_MOD(OnUserAway, (source.GetUser(), params.empty() ? "" : params[0])); + const Anope::string &msg = !params.empty() ? params[0] : ""; + + FOREACH_MOD(OnUserAway, (source.GetUser(), msg)); + if (!msg.empty()) + Log(source.GetUser(), "away") << "is now away: " << msg; + else + Log(source.GetUser(), "away") << "is no longer away"; } void Capab::Run(MessageSource &source, const std::vector ¶ms) -- cgit From 969cd5dd6cac1bc702d5d1379f7bf54c1aadc6c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Jan 2015 15:29:19 -0500 Subject: Always use source name when logging server kicks --- src/channels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/channels.cpp b/src/channels.cpp index 0ef8cf532..b1038f69e 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -746,7 +746,7 @@ void Channel::KickInternal(const MessageSource &source, const Anope::string &nic if (sender) Log(sender, this, "kick") << "kicked " << target->nick << " (" << reason << ")"; else - Log(target, this, "kick") << "was kicked by " << source.GetSource() << " (" << reason << ")"; + Log(target, this, "kick") << "was kicked by " << source.GetName() << " (" << reason << ")"; Anope::string chname = this->name; -- cgit From 3055b7272b1cc4d4099e639932d8b84ccef36a37 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 10 Jan 2015 15:37:49 -0500 Subject: Fix m_xmlrpc server configuration option --- modules/m_xmlrpc.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/m_xmlrpc.cpp b/modules/m_xmlrpc.cpp index 36401b800..1d08bed43 100644 --- a/modules/m_xmlrpc.cpp +++ b/modules/m_xmlrpc.cpp @@ -162,11 +162,8 @@ class ModuleXMLRPC : public Module MyXMLRPCServiceInterface xmlrpcinterface; ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - httpref("HTTPProvider", "httpd/main"), xmlrpcinterface(this, "xmlrpc") + xmlrpcinterface(this, "xmlrpc") { - if (!httpref) - throw ModuleException("Unable to find http reference, is m_httpd loaded?"); - httpref->RegisterPage(&xmlrpcinterface); } @@ -178,7 +175,12 @@ class ModuleXMLRPC : public Module void OnReload(Configuration::Conf *conf) anope_override { + if (httpref) + httpref->UnregisterPage(&xmlrpcinterface); this->httpref = ServiceReference("HTTPProvider", conf->GetModule(this)->Get("server", "httpd/main")); + if (!httpref) + throw ConfigException("Unable to find http reference, is m_httpd loaded?"); + httpref->RegisterPage(&xmlrpcinterface); } }; -- cgit From 7e0cb6d8ef283d83fcabee131f88ebe85e2ba44f Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Fri, 2 Jan 2015 21:09:05 -0500 Subject: cs_entrymsg to use SET permission, not isFounder Correcting syntax error (i don't actually know c++) --- modules/commands/cs_entrymsg.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index 6df6918da..89b66a977 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -143,7 +143,7 @@ class CommandEntryMessage : public Command else { (*messages)->push_back(new EntryMsgImpl(ci, source.GetNick(), message)); - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message"; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message"; source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str()); } } @@ -166,7 +166,7 @@ class CommandEntryMessage : public Command delete (*messages)->at(i - 1); if ((*messages)->empty()) ci->Shrink("entrymsg"); - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message"; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message"; source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str()); } else @@ -183,7 +183,7 @@ class CommandEntryMessage : public Command { ci->Shrink("entrymsg"); - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages"; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages"; source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str()); } @@ -212,7 +212,7 @@ class CommandEntryMessage : public Command return; } - if (!source.IsFounder(ci) && !source.HasPriv("chanserv/administration")) + if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -253,6 +253,9 @@ class CommandEntryMessage : public Command source.Reply(_("The \002ENTRYMSG CLEAR\002 command clears all entries from\n" "the list of messages shown to users when they join\n" "the channel, effectively disabling entry messages.")); + source.Reply(" "); + source.Reply(_("Adding, deleting, or clearing entry messages requires the\n" + "SET permission.")); return true; } }; -- cgit From d324e9152012500c7a811d7adda6ad2c6fbcd26f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 26 Jan 2015 13:16:25 -0500 Subject: Fix negatively locking param modes in default mlock --- modules/commands/cs_mode.cpp | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index d5c356fa4..8a30f102c 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -958,16 +958,40 @@ class CSMode : public Module for (unsigned i = 0; i < mlock.length(); ++i) { if (mlock[i] == '+') + { add = true; - else if (mlock[i] == '-') + continue; + } + + if (mlock[i] == '-') + { add = false; - else + continue; + } + + ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]); + if (!cm) + continue; + + Anope::string param; + if (cm->type == MODE_PARAM) + { + ChannelModeParam *cmp = anope_dynamic_static_cast(cm); + if (add || !cmp->minus_no_arg) + { + sep.GetToken(param); + if (param.empty() || !cmp->IsValid(param)) + continue; + } + } + else if (cm->type != MODE_REGULAR) { - ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]); - Anope::string param; - if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param))) - ml->SetMLock(cm, add, param); + sep.GetToken(param); + if (param.empty()) + continue; } + + ml->SetMLock(cm, add, param); } } ml->Check(); -- cgit From 2264a206d262f07f6c6d91df867383d6413e0c3f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 26 Jan 2015 15:10:18 -0500 Subject: Check virtual mode bases better --- include/modes.h | 4 ++++ src/modes.cpp | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/modes.h b/include/modes.h index 9c5916c0f..729e979d4 100644 --- a/include/modes.h +++ b/include/modes.h @@ -107,6 +107,8 @@ class CoreExport ChannelMode : public Mode bool CanSet(User *u) const anope_override; + virtual void Check() { } + /** 'wrap' this channel mode and param to the underlying mode and param */ virtual ChannelMode *Wrap(Anope::string ¶m); @@ -215,6 +217,8 @@ class CoreExport ChannelModeVirtual : public T ~ChannelModeVirtual(); + void Check() anope_override; + ChannelMode *Wrap(Anope::string ¶m) anope_override; ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) = 0; diff --git a/src/modes.cpp b/src/modes.cpp index dafe2ddca..38266f95f 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -213,7 +213,7 @@ ChannelModeVirtual::~ChannelModeVirtual() } template -ChannelMode *ChannelModeVirtual::Wrap(Anope::string ¶m) +void ChannelModeVirtual::Check() { if (basech == NULL) { @@ -221,7 +221,11 @@ ChannelMode *ChannelModeVirtual::Wrap(Anope::string ¶m) if (basech) basech->listeners.push_back(this); } +} +template +ChannelMode *ChannelModeVirtual::Wrap(Anope::string ¶m) +{ return basech; } @@ -453,6 +457,9 @@ bool ModeManager::AddChannelMode(ChannelMode *cm) FOREACH_MOD(OnChannelModeAdd, (cm)); + for (unsigned int i = 0; i < ChannelModes.size(); ++i) + ChannelModes[i]->Check(); + return true; } -- cgit From 845ca576b4c5a94f0a3ec12a4dd524a7d017155e Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 28 Jan 2015 22:57:15 -0500 Subject: More properly track topic change sources and allow users with access to change topics through topiclock --- include/channels.h | 2 +- include/modules.h | 5 +++-- modules/commands/cs_topic.cpp | 4 ++-- modules/extra/stats/irc2sql/irc2sql.cpp | 2 +- modules/extra/stats/irc2sql/irc2sql.h | 2 +- modules/extra/stats/m_chanstats.cpp | 7 +++---- modules/protocol/bahamut.cpp | 4 ++-- modules/protocol/hybrid.cpp | 2 +- modules/protocol/inspircd12.cpp | 2 +- modules/protocol/ngircd.cpp | 8 ++++---- modules/protocol/ratbox.cpp | 2 +- modules/protocol/unreal.cpp | 2 +- src/channels.cpp | 14 +++++--------- src/messages.cpp | 2 +- 14 files changed, 27 insertions(+), 31 deletions(-) diff --git a/include/channels.h b/include/channels.h index 9bc6c27c6..80459d357 100644 --- a/include/channels.h +++ b/include/channels.h @@ -258,7 +258,7 @@ class CoreExport Channel : public Base, public Extensible * @param newtopic The new topic * @param ts The time the new topic is being set */ - void ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts = Anope::CurTime); + void ChangeTopicInternal(User *u, const Anope::string &user, const Anope::string &newtopic, time_t ts = Anope::CurTime); /** Update the topic of the channel, and reset it if topiclock etc says to * @param user The user setting the topic diff --git a/include/modules.h b/include/modules.h index 0569fd33f..5ea35c888 100644 --- a/include/modules.h +++ b/include/modules.h @@ -474,11 +474,12 @@ class CoreExport Module : public Extensible virtual void OnJoinChannel(User *u, Channel *c) { throw NotImplementedException(); } /** Called when a new topic is set + * @param source The user changing the topic, if any * @param c The channel - * @param setter The user who set the new topic + * @param setter The user who set the new topic, if there is no source * @param topic The new topic */ - virtual void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) { throw NotImplementedException(); } + virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) { throw NotImplementedException(); } /** Called before a channel expires * @param ci The channel diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp index 1506bcc9c..353cf83a3 100644 --- a/modules/commands/cs_topic.cpp +++ b/modules/commands/cs_topic.cpp @@ -227,7 +227,7 @@ class CSTopic : public Module } } - void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override { if (!c->ci) return; @@ -237,7 +237,7 @@ class CSTopic : public Module * This desyncs what is really set with what we have stored, and we end up resetting the topic often when * it is not required */ - if (topiclock.HasExt(c->ci) && c->ci->last_topic != c->topic) + if (topiclock.HasExt(c->ci) && c->ci->last_topic != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC"))) { c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time); } diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp index fd0ca5890..87ede04fd 100644 --- a/modules/extra/stats/irc2sql/irc2sql.cpp +++ b/modules/extra/stats/irc2sql/irc2sql.cpp @@ -243,7 +243,7 @@ void IRC2SQL::OnLeaveChannel(User *u, Channel *c) this->RunQuery(query); } -void IRC2SQL::OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) +void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) { query = "UPDATE `" + prefix + "chan` " "SET topic=@topic@, topicauthor=@author@, topictime=FROM_UNIXTIME(@time@) " diff --git a/modules/extra/stats/irc2sql/irc2sql.h b/modules/extra/stats/irc2sql/irc2sql.h index 0c516f5e3..1ed5790aa 100644 --- a/modules/extra/stats/irc2sql/irc2sql.h +++ b/modules/extra/stats/irc2sql/irc2sql.h @@ -69,7 +69,7 @@ class IRC2SQL : public Module EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override; EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override; - void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override; + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override; void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) anope_override; }; diff --git a/modules/extra/stats/m_chanstats.cpp b/modules/extra/stats/m_chanstats.cpp index 7a2fe0486..27b1b3eae 100644 --- a/modules/extra/stats/m_chanstats.cpp +++ b/modules/extra/stats/m_chanstats.cpp @@ -517,14 +517,13 @@ class MChanstats : public Module info.AddOption(_("Chanstats")); } - void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override { - User *u = User::Find(user); - if (!u || !u->Account() || !c->ci || !cs_stats.HasExt(c->ci)) + if (!source || !source->Account() || !c->ci || !cs_stats.HasExt(c->ci)) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);"; query.SetValue("channel", c->name); - query.SetValue("nick", GetDisplay(u)); + query.SetValue("nick", GetDisplay(source)); this->RunQuery(query); } diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index a399ecece..4e193da01 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -461,11 +461,11 @@ struct IRCDMessageTopic : IRCDMessage { IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { } - void Run(MessageSource &, const std::vector ¶ms) anope_override + void Run(MessageSource &source, const std::vector ¶ms) anope_override { Channel *c = Channel::Find(params[0]); if (c) - c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); + c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); } }; diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 52c442dc3..b6ee17d45 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -512,7 +512,7 @@ struct IRCDMessageTBurst : IRCDMessage Channel *c = Channel::Find(params[1]); if (c) - c->ChangeTopicInternal(setter, params[4], topic_time); + c->ChangeTopicInternal(NULL, setter, params[4], topic_time); } }; diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index 5fb226d99..192a783fe 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -998,7 +998,7 @@ struct IRCDMessageFTopic : IRCDMessage Channel *c = Channel::Find(params[0]); if (c) - c->ChangeTopicInternal(params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : Anope::CurTime); + c->ChangeTopicInternal(NULL, params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : Anope::CurTime); } }; diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index 61613423e..28f68007b 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -257,7 +257,7 @@ struct IRCDMessageChaninfo : IRCDMessage if (params.size() == 3) { - c->ChangeTopicInternal(source.GetName(), params[2], Anope::CurTime); + c->ChangeTopicInternal(NULL, source.GetName(), params[2], Anope::CurTime); } else if (params.size() == 5) { @@ -271,9 +271,9 @@ struct IRCDMessageChaninfo : IRCDMessage case 'l': modes += " " + params[3]; continue; + } } - } - c->ChangeTopicInternal(source.GetName(), params[4], Anope::CurTime); + c->ChangeTopicInternal(NULL, source.GetName(), params[4], Anope::CurTime); } c->SetModesInternal(source, modes); @@ -590,7 +590,7 @@ struct IRCDMessageTopic : IRCDMessage Log(LOG_DEBUG) << "TOPIC for nonexistant channel " << params[0]; return; } - c->ChangeTopicInternal(source.GetName(), params[1], Anope::CurTime); + c->ChangeTopicInternal(source.GetUser(), source.GetName(), params[1], Anope::CurTime); } }; diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 8fd9a30cf..8ccabd604 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -185,7 +185,7 @@ struct IRCDMessageTBurst : IRCDMessage const Anope::string &setter = params.size() == 4 ? params[2] : "", topic = params.size() == 4 ? params[3] : params[2]; - c->ChangeTopicInternal(setter, topic, topic_time); + c->ChangeTopicInternal(NULL, setter, topic, topic_time); } }; diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 40cb1fe70..1bb0db657 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -1146,7 +1146,7 @@ struct IRCDMessageTopic : IRCDMessage { Channel *c = Channel::Find(params[0]); if (c) - c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); + c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); } }; diff --git a/src/channels.cpp b/src/channels.cpp index b1038f69e..7e7702d7e 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -789,26 +789,22 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) return true; } -void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts) +void Channel::ChangeTopicInternal(User *u, const Anope::string &user, const Anope::string &newtopic, time_t ts) { - User *u = User::Find(user); - this->topic = newtopic; this->topic_setter = u ? u->nick : user; this->topic_ts = ts; this->topic_time = Anope::CurTime; - Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << (u ? u->nick : user) << " to " << newtopic; + Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << this->topic_setter << " to " << newtopic; - FOREACH_MOD(OnTopicUpdated, (this, user, this->topic)); + FOREACH_MOD(OnTopicUpdated, (u, this, user, this->topic)); } void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts) { - User *u = User::Find(user); - this->topic = newtopic; - this->topic_setter = u ? u->nick : user; + this->topic_setter = user; this->topic_ts = ts; IRCD->SendTopic(this->ci->WhoSends(), this); @@ -816,7 +812,7 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop /* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */ this->topic_time = Anope::CurTime; - FOREACH_MOD(OnTopicUpdated, (this, user, this->topic)); + FOREACH_MOD(OnTopicUpdated, (NULL, this, user, this->topic)); } void Channel::SetCorrectModes(User *user, bool give_modes) diff --git a/src/messages.cpp b/src/messages.cpp index a771b2f1f..4e1bcd0db 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -472,7 +472,7 @@ void Topic::Run(MessageSource &source, const std::vector ¶ms) { Channel *c = Channel::Find(params[0]); if (c) - c->ChangeTopicInternal(source.GetSource(), params[1], Anope::CurTime); + c->ChangeTopicInternal(source.GetUser(), source.GetSource(), params[1], Anope::CurTime); return; } -- cgit From dc5039e994a9bcbc0a59591296a753659095fd5b Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 3 Feb 2015 18:42:35 -0500 Subject: Properly unescape xmlrpc --- docs/XMLRPC/XMLRPC | 4 ++-- modules/m_xmlrpc.cpp | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/XMLRPC/XMLRPC b/docs/XMLRPC/XMLRPC index a183af097..95a18abc4 100644 --- a/docs/XMLRPC/XMLRPC +++ b/docs/XMLRPC/XMLRPC @@ -3,8 +3,8 @@ This allows external applications, such as websites, to execute remote procedure Currently there are 5 supported XMLRPC calls, provided by m_xmlrpc_main: -checkAuthetication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password - is correct for the account name, useful for making login pages on websites. +checkAuthentication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password + is correct for the account name, useful for making login pages on websites. command - Takes three parameters, a service name (BotServ, ChanServ, NickServ), a user name (whether online or not), and the command to execute. This will execute a the given command to Anope using the given service name. If the user given is online, the diff --git a/modules/m_xmlrpc.cpp b/modules/m_xmlrpc.cpp index 1d08bed43..2fd900e61 100644 --- a/modules/m_xmlrpc.cpp +++ b/modules/m_xmlrpc.cpp @@ -53,6 +53,39 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage return ret; } + static Anope::string Unescape(const Anope::string &string) + { + Anope::string ret = string; + for (int i = 0; special[i].character.empty() == false; ++i) + if (!special[i].replace.empty()) + ret = ret.replace_all_cs(special[i].replace, special[i].character); + + for (size_t i, last = 0; (i = string.find("&#", last)) != Anope::string::npos;) + { + last = i + 1; + + size_t end = string.find(';', i); + if (end == Anope::string::npos) + break; + + Anope::string ch = string.substr(i + 2, end - (i + 2)); + + if (ch.empty()) + continue; + + long l; + if (!ch.empty() && ch[0] == 'x') + l = strtol(ch.substr(1).c_str(), NULL, 16); + else + l = strtol(ch.c_str(), NULL, 10); + + if (l > 0 && l < 256) + ret = ret.replace_all_cs("&#" + ch + ";", Anope::string(l)); + } + + return ret; + } + private: static bool GetData(Anope::string &content, Anope::string &tag, Anope::string &data) { @@ -98,8 +131,8 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage } while (istag && !content.empty()); - tag = prev; - data = cur; + tag = Unescape(prev); + data = Unescape(cur); return !istag && !data.empty(); } -- cgit From 64ca357b136bc190e5fec32269b34b85bf9cf610 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 3 Feb 2015 19:38:23 -0500 Subject: Make module version system work --- include/CMakeLists.txt | 3 +- include/modules.h | 20 +++++--- include/version.cpp | 123 +++++++++++++++++++++++++++++++++++-------------- src/misc.cpp | 7 +-- src/modulemanager.cpp | 86 +++++++++++++++++++++++----------- src/version.sh | 6 +-- 6 files changed, 166 insertions(+), 79 deletions(-) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 6170cde27..1a96d7111 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -7,7 +7,7 @@ get_target_property(version_BINARY version LOCATION) # Modify version.h from the above executable, with dependencies to version.cpp # and all of the source files in the main build add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_build - COMMAND ${version_BINARY} ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h + COMMAND ${version_BINARY} ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h DEPENDS version ${SRC_SRCS} ) # Add version to list of files for CPack to ignore @@ -15,6 +15,7 @@ get_filename_component(version_BINARY ${version_BINARY} NAME) add_to_cpack_ignored_files("${version_BINARY}$" TRUE) if(NOT WIN32) add_to_cpack_ignored_files("version.h$" TRUE) + add_to_cpack_ignored_files("build.h$" TRUE) endif(NOT WIN32) set(PCH_SOURCES_GCH "") diff --git a/include/modules.h b/include/modules.h index 5ea35c888..0c10caa7b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -20,6 +20,7 @@ #include "timers.h" #include "logger.h" #include "extensible.h" +#include "version.h" /** This definition is used as shorthand for the various classes * and functions needed to make a module loadable by the OS. @@ -40,6 +41,10 @@ extern "C" void AnopeFini(x *m) \ { \ delete m; \ + } \ + extern "C" DllExport ModuleVersion AnopeVersion() \ + { \ + return ModuleVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); \ } #else # define MODULE_INIT(x) \ @@ -50,6 +55,10 @@ extern "C" DllExport void AnopeFini(x *m) \ { \ delete m; \ + } \ + extern "C" DllExport ModuleVersion AnopeVersion() \ + { \ + return ModuleVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); \ } #endif @@ -279,12 +288,6 @@ class CoreExport Module : public Extensible */ void SetAuthor(const Anope::string &author); - /** Get the version of Anope this module was - * compiled against - * @return The version - */ - ModuleVersion GetVersion() const; - virtual void Prioritize(); /* Everything below here are events. Modules must ModuleManager::Attach to these events @@ -1206,6 +1209,11 @@ class CoreExport ModuleManager * @return MOD_ERR_OK on success, anything else on fail */ static ModuleReturn DeleteModule(Module *m); + + /** Get the version of Anope the module was compiled against + * @return The version + */ + static ModuleVersion GetVersion(void *handle); }; #endif // MODULES_H diff --git a/include/version.cpp b/include/version.cpp index b0ea0423d..119403e13 100644 --- a/include/version.cpp +++ b/include/version.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include static std::string get_git_hash(const std::string &git_dir) { @@ -45,29 +45,16 @@ static std::string get_git_hash(const std::string &git_dir) return "g" + filebuf.substr(0, 7); } -int main(int argc, char *argv[]) +static bool read_version_sh(const std::string &version_sh, std::map &versions) { - if (argc < 3) - { - std::cerr << "Syntax: " << argv[0] << " " << std::endl; - return 1; - } - - std::string version_sh = std::string(argv[1]) + "/src/version.sh"; - std::string git_dir = std::string(argv[1]) + "/.git"; - - std::fstream fd; - - fd.clear(); - fd.open(version_sh.c_str(), std::ios::in); + std::fstream fd(version_sh.c_str(), std::ios::in); if (!fd.is_open()) { std::cerr << "Error: Unable to open src/version.sh for reading: " << version_sh << std::endl; - return 1; + return false; } std::string filebuf; - std::list > versions; while (getline(fd, filebuf)) { if (!filebuf.find("VERSION_")) @@ -75,24 +62,25 @@ int main(int argc, char *argv[]) size_t eq = filebuf.find('='); std::string type = filebuf.substr(0, eq); - std::string value = filebuf.substr(eq + 2, filebuf.length() - eq - 3); - versions.push_back(std::make_pair(type, value)); + std::string value = filebuf.substr(eq + 1); + + versions[type] = value; } } fd.close(); - std::string git_version = get_git_hash(git_dir); - if (!git_version.empty()) - versions.push_back(std::make_pair("VERSION_GIT", git_version)); + return true; +} - fd.clear(); - fd.open(argv[2], std::ios::in); +static bool write_build_h(const std::string &buildh) +{ + std::fstream fd(buildh.c_str(), std::ios::in); std::string build = "#define BUILD 1"; if (fd.is_open()) { - while (getline(fd, filebuf)) + for (std::string filebuf; getline(fd, filebuf);) { if (!filebuf.find("#define BUILD")) { @@ -110,27 +98,92 @@ int main(int argc, char *argv[]) } fd.clear(); - fd.open(argv[2], std::ios::out); - + fd.open(buildh.c_str(), std::ios::out); if (!fd.is_open()) { - std::cerr << "Error: Unable to include/version.h for writing: " << argv[2] << std::endl; - return 1; + std::cerr << "Error: Unable to open build.h for writing: " << buildh << std::endl; + return false; } fd << "/* This file is automatically generated by version.cpp - do not edit it! */" << std::endl; + fd << build << std::endl; + fd.close(); + + return true; +} - for (std::list >::iterator it = versions.begin(), it_end = versions.end(); it != it_end; ++it) +static void read_version_h(const std::string &versionh, std::map &versions) +{ + std::fstream fd(versionh.c_str(), std::ios::in); + + if (!fd.is_open()) + return; + + for (std::string filebuf; getline(fd, filebuf);) { - if (it->first == "VERSION_EXTRA" || it->first == "VERSION_GIT") - fd << "#define " << it->first << " \"" << it->second << "\"" << std::endl; - else - fd << "#define " << it->first << " " << it->second << std::endl; + if (!filebuf.find("#define VERSION_")) + { + size_t space = filebuf.substr(8).find(' '); + + std::string name = filebuf.substr(8).substr(0, space), + version = filebuf.substr(8).substr(space + 1); + + versions[name] = version; + } } - fd << build << std::endl; + fd.close(); +} + +static bool write_version_h(const std::string &versionh, const std::map &versions) +{ + std::fstream fd(versionh.c_str(), std::ios::out); + + if (!fd.is_open()) + return false; + + for (std::map::const_iterator it = versions.begin(); it != versions.end(); ++it) + { + fd << "#define " << it->first << " " << it->second << std::endl; + } fd.close(); + return true; +} + +int main(int argc, char *argv[]) +{ + if (argc < 4) + { + std::cerr << "Syntax: " << argv[0] << " " << std::endl; + return 1; + } + + std::string version_sh = std::string(argv[1]) + "/src/version.sh"; + std::string git_dir = std::string(argv[1]) + "/.git"; + std::string versionh = argv[2]; + std::string buildh = argv[3]; + + std::map versions, old_versions; + + if (!read_version_sh(version_sh, versions)) + return -1; + + std::string git_version = get_git_hash(git_dir); + if (!git_version.empty()) + versions["VERSION_GIT"] = '"' + git_version + '"'; + + if (!write_build_h(buildh)) + return -1; + + read_version_h(versionh, old_versions); + + if (versions == old_versions) + return 0; + + if (!write_version_h(versionh, versions)) + return -1; + return 0; } diff --git a/src/misc.cpp b/src/misc.cpp index 57314c53b..a6addbc3f 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -11,7 +11,7 @@ */ #include "services.h" -#include "version.h" +#include "build.h" #include "modules.h" #include "lists.h" #include "config.h" @@ -617,11 +617,6 @@ const Anope::string Anope::LastError() #endif } -ModuleVersion Module::GetVersion() const -{ - return ModuleVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); -} - Anope::string Anope::Version() { #ifdef VERSION_GIT diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 2e7c624cd..98342b08e 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -166,6 +166,46 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) return MOD_ERR_NOLOAD; } + try + { + ModuleVersion v = GetVersion(handle); + + if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor())) + { + Log() << "Module " << modname << " is compiled against an older version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort(); + dlclose(handle); + return MOD_ERR_VERSION; + } + else if (v.GetMajor() > Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() > Anope::VersionMinor())) + { + Log() << "Module " << modname << " is compiled against a newer version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort(); + dlclose(handle); + return MOD_ERR_VERSION; + } + else if (v.GetPatch() < Anope::VersionPatch()) + { + Log() << "Module " << modname << " is compiled against an older version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort(); + dlclose(handle); + return MOD_ERR_VERSION; + } + else if (v.GetPatch() > Anope::VersionPatch()) + { + Log() << "Module " << modname << " is compiled against a newer version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort(); + dlclose(handle); + return MOD_ERR_VERSION; + } + else + { + Log(LOG_DEBUG_2) << "Module " << modname << " is compiled against current version of Anope " << Anope::VersionShort(); + } + } + catch (const ModuleException &ex) + { + /* this error has already been logged */ + dlclose(handle); + return MOD_ERR_NOLOAD; + } + dlerror(); Module *(*func)(const Anope::string &, const Anope::string &) = function_cast(dlsym(handle, "AnopeInit")); err = dlerror(); @@ -206,34 +246,6 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) m->filename = pbuf; m->handle = handle; - ModuleVersion v = m->GetVersion(); - if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor())) - { - Log() << "Module " << modname << " is compiled against an older version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort(); - DeleteModule(m); - return MOD_ERR_VERSION; - } - else if (v.GetMajor() > Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() > Anope::VersionMinor())) - { - Log() << "Module " << modname << " is compiled against a newer version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort(); - DeleteModule(m); - return MOD_ERR_VERSION; - } - else if (v.GetPatch() < Anope::VersionPatch()) - { - Log() << "Module " << modname << " is compiled against an older version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort(); - DeleteModule(m); - return MOD_ERR_VERSION; - } - else if (v.GetPatch() > Anope::VersionPatch()) - { - Log() << "Module " << modname << " is compiled against a newer version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort(); - DeleteModule(m); - return MOD_ERR_VERSION; - } - else - Log(LOG_DEBUG_2) << "Module " << modname << " is compiled against current version of Anope " << Anope::VersionShort(); - /* Initialize config */ try { @@ -272,6 +284,24 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) return MOD_ERR_OK; } +ModuleVersion ModuleManager::GetVersion(void *handle) +{ + dlerror(); + ModuleVersion (*func)() = function_cast(dlsym(handle, "AnopeVersion"));; + if (!func) + { + Log() << "No version function found, not an Anope module"; + + const char *err = dlerror(); + if (err && *err) + Log(LOG_DEBUG) << err; + + throw ModuleException("No version"); + } + + return func(); +} + ModuleReturn ModuleManager::UnloadModule(Module *m, User *u) { if (!m) diff --git a/src/version.sh b/src/version.sh index a7046fa72..198556b24 100644 --- a/src/version.sh +++ b/src/version.sh @@ -1,7 +1,7 @@ #!/bin/sh -VERSION_MAJOR="2" -VERSION_MINOR="0" -VERSION_PATCH="2" +VERSION_MAJOR=2 +VERSION_MINOR=0 +VERSION_PATCH=2 VERSION_EXTRA="-git" -- cgit From 9834518b28e3bb6ec62000c26be4e5927ca92979 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 5 Feb 2015 20:16:36 -0500 Subject: Fix os_mode to handle channels going away due to mode changes, and maybe cs_mode --- modules/commands/cs_mode.cpp | 2 +- modules/commands/os_mode.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 8a30f102c..b11bc8862 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -487,7 +487,7 @@ class CommandCSMode : public Command case '*': if (adding == -1 || !has_access) break; - for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j) + for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j) { ChannelMode *cm = ModeManager::GetChannelModes()[j]; diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp index 379879844..b6f26c7b3 100644 --- a/modules/commands/os_mode.cpp +++ b/modules/commands/os_mode.cpp @@ -26,7 +26,7 @@ class CommandOSMode : public Command const Anope::string &target = params[0]; const Anope::string &modes = params[1]; - Channel *c = Channel::Find(target); + Reference c = Channel::Find(target); if (!c) source.Reply(CHAN_X_NOT_IN_USE, target.c_str()); else if (c->bouncy_modes) @@ -36,9 +36,15 @@ class CommandOSMode : public Command bool all = params.size() > 2 && params[2].equals_ci("ALL"); const Channel::ModeList chmodes = c->GetModes(); - for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end; ++it) + for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end && c; ++it) c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false); + if (!c) + { + source.Reply(_("Modes cleared on %s and the channel destroyed."), target.c_str()); + return; + } + if (all) { for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) @@ -65,7 +71,7 @@ class CommandOSMode : public Command Anope::string log_modes, log_params; sep.GetToken(mode); - for (unsigned i = 0; i < mode.length(); ++i) + for (unsigned i = 0; i < mode.length() && c; ++i) { char ch = mode[i]; @@ -116,7 +122,7 @@ class CommandOSMode : public Command } if (!log_modes.replace_all_cs("+", "").replace_all_cs("-", "").empty()) - Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << c->name; + Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << (c ? c->name : target); } } -- cgit From 8550e2216791ad6df1d789ae332d61fac8619433 Mon Sep 17 00:00:00 2001 From: miwob Date: Fri, 6 Feb 2015 19:39:31 +0100 Subject: - Update ircd-hybrid protocol module to support channel mode 'C' (no CTCPs) --- modules/protocol/hybrid.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index b6ee17d45..dc6d7a6c1 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -645,7 +645,7 @@ class ProtoHybrid : public Module ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); - /* v/h/o/a/q */ + /* v/h/o */ ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); @@ -663,6 +663,7 @@ class ProtoHybrid : public Module ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); + ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); -- cgit From f484a68dee0c8e20256d755b0f2b24d62fceb4ed Mon Sep 17 00:00:00 2001 From: miwob Date: Fri, 6 Feb 2015 20:28:30 +0100 Subject: - Removed SendGlobopsInternal() override as it's basically a duplicate of SendGlobopsInternal() in protocol.c --- modules/protocol/hybrid.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index b6ee17d45..f0c359be4 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -66,11 +66,6 @@ class HybridProto : public IRCDProto UplinkSocket::Message(bi) << "PRIVMSG $$" << dest->GetName() << " :" << msg; } - void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override - { - UplinkSocket::Message(source) << "GLOBOPS :" << buf; - } - void SendSQLine(User *, const XLine *x) anope_override { UplinkSocket::Message(FindIntroduced()) << "ENCAP * RESV " << (x->expires ? x->expires - Anope::CurTime : 0) << " " << x->mask << " 0 :" << x->reason; -- cgit From 41ae2dbefbe632860c9cda16e73e6ca55c8032f6 Mon Sep 17 00:00:00 2001 From: miwob Date: Sat, 7 Feb 2015 19:08:55 +0100 Subject: - Added some missing user modes to the ircd-hybrid protocol module --- modules/protocol/hybrid.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index b6ee17d45..af29b6227 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -626,10 +626,13 @@ class ProtoHybrid : public Module { /* Add user modes */ ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G')); ModeManager::AddUserMode(new UserModeOperOnly("CALLERID", 'g')); ModeManager::AddUserMode(new UserMode("INVIS", 'i')); ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("HIDECHANS", 'p')); + ModeManager::AddUserMode(new UserMode("HIDEIDLE", 'q')); ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); @@ -638,6 +641,7 @@ class ProtoHybrid : public Module ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H')); ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); ModeManager::AddUserMode(new UserModeNoone("SSL", 'S')); + ModeManager::AddUserMode(new UserModeNoone("WEBIRC", 'W')); ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); /* b/e/I */ -- cgit From 2f49065500e5e913eb6275a13f6d580131d9abf8 Mon Sep 17 00:00:00 2001 From: miwob Date: Sun, 8 Feb 2015 12:29:16 +0100 Subject: Misc changes to the ircd-hybrid protocol module: - Increase MaxModes to 6 - SendLogout(): send "+d *" instead of "+d 0" - Update copyright year - Removed user mode +z from supported modes --- modules/protocol/hybrid.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 438229780..9eff5a6a0 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -1,7 +1,7 @@ /* ircd-hybrid-8 protocol module * * (C) 2003-2014 Anope Team - * (C) 2012-2014 ircd-hybrid development team + * (C) 2012-2015 ircd-hybrid development team * * Please read COPYING and README for further details. * @@ -48,7 +48,7 @@ class HybridProto : public IRCDProto CanCertFP = true; CanSetVHost = true; RequiresID = true; - MaxModes = 4; + MaxModes = 6; } void SendInvite(const MessageSource &source, const Channel *c, User *u) anope_override @@ -232,7 +232,7 @@ class HybridProto : public IRCDProto void SendLogout(User *u) anope_override { - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0"); + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d *"); } void SendChannel(Channel *c) anope_override @@ -628,7 +628,6 @@ class ProtoHybrid : public Module ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z')); ModeManager::AddUserMode(new UserMode("DEAF", 'D')); ModeManager::AddUserMode(new UserModeOperOnly("HIDEOPER", 'H')); ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); -- cgit From 1e86c460008c0ecfea5d1a13f928e830815c4a80 Mon Sep 17 00:00:00 2001 From: miwob Date: Tue, 10 Feb 2015 22:48:22 +0100 Subject: - Minor update to anope.de_DE.po; removed double space + proper translation --- language/anope.de_DE.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/anope.de_DE.po b/language/anope.de_DE.po index c57d4b698..af6a0102c 100644 --- a/language/anope.de_DE.po +++ b/language/anope.de_DE.po @@ -6389,7 +6389,7 @@ msgstr "%s ist ein services operator vom Typ %s." #: modules/commands/ns_info.cpp:34 #, c-format msgid "Nick %s is part of this Network's Services." -msgstr "Der Nickname %s ist ein teil der Network Services." +msgstr "Der Nickname %s ist ein Teil der Netzwerkdienste." #: include/language.h:80 #, fuzzy, c-format -- cgit From 61a8dd57f7984194dc453ef56b5b05c957aedd8b Mon Sep 17 00:00:00 2001 From: H7-25 Date: Thu, 5 Feb 2015 19:45:27 +0100 Subject: Added kickcheck override for users with protected privs --- modules/commands/cs_set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp index afd2c3547..3c7a0f32c 100644 --- a/modules/commands/cs_set.cpp +++ b/modules/commands/cs_set.cpp @@ -1252,7 +1252,7 @@ class CSSet : public Module EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override { - if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT")) + if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT") || u->IsProtected()) return EVENT_CONTINUE; if (c->ci->AccessFor(u).empty() && (!c->ci->GetFounder() || u->Account() != c->ci->GetFounder())) -- cgit From 6ada3ec87180df159a2d55634a1972611f7fe62a Mon Sep 17 00:00:00 2001 From: miwob Date: Sun, 15 Feb 2015 21:27:01 +0100 Subject: - Change SendForceNickChange() to use UIDs --- modules/protocol/hybrid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 438229780..5e4ce490e 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -252,7 +252,7 @@ class HybridProto : public IRCDProto void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override { - UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when; + UplinkSocket::Message(Me) << "SVSNICK " << u->GetUID() << " " << newnick << " " << when; } void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) anope_override -- cgit From abe232601b05fc78ae1c419165e4075b5690052c Mon Sep 17 00:00:00 2001 From: miwob Date: Sun, 15 Feb 2015 21:33:22 +0100 Subject: - Update SendClientIntroduction() to use * for account names instead of 0 --- modules/protocol/hybrid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 438229780..6debde0b9 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -212,7 +212,7 @@ class HybridProto : public IRCDProto Anope::string modes = "+" + u->GetModes(); UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " " - << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " 0 :" << u->realname; + << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " * :" << u->realname; } void SendEOB() anope_override @@ -541,7 +541,7 @@ struct IRCDMessageUID : IRCDMessage IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } /* 0 1 2 3 4 5 6 7 8 9 */ - /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB 1350157108 :Mining all the time */ + /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB Steve :Mining all the time */ void Run(MessageSource &source, const std::vector ¶ms) anope_override { Anope::string ip = params[6]; -- cgit From 76337bc04ac0072019cd3025da55eecd6692490f Mon Sep 17 00:00:00 2001 From: miwob Date: Sun, 15 Feb 2015 21:47:55 +0100 Subject: - Misc updates to the hybrid protocol modules: - best supported version is 8.2.x - fixed UID message handler to cope with account names being '*' - minium required TS version is TS6 now --- modules/protocol/hybrid.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 438229780..4cc170574 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -36,7 +36,7 @@ class HybridProto : public IRCDProto } public: - HybridProto(Module *creator) : IRCDProto(creator, "Hybrid 8.1.x") + HybridProto(Module *creator) : IRCDProto(creator, "Hybrid 8.2.x") { DefaultPseudoclientModes = "+oi"; CanSVSNick = true; @@ -204,7 +204,7 @@ class HybridProto : public IRCDProto SendServer(Me); - UplinkSocket::Message() << "SVINFO 6 5 0 :" << Anope::CurTime; + UplinkSocket::Message() << "SVINFO 6 6 0 :" << Anope::CurTime; } void SendClientIntroduction(User *u) anope_override @@ -550,7 +550,7 @@ struct IRCDMessageUID : IRCDMessage ip.clear(); NickAlias *na = NULL; - if (params[8] != "0") + if (params[8] != "0" && params[8] != "*") na = NickAlias::Find(params[8]); /* Source is always the server */ -- cgit From 7de4b86b7fb44f800db2e5b4e4c69e1ccc6fbda3 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 23 Feb 2015 15:47:08 -0500 Subject: Move GIT_VERSION define to build.h, otherwise version.h is bumped per commit which forces a rebuild --- include/version.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/version.cpp b/include/version.cpp index 119403e13..22921202b 100644 --- a/include/version.cpp +++ b/include/version.cpp @@ -73,7 +73,7 @@ static bool read_version_sh(const std::string &version_sh, std::map Date: Sat, 7 Mar 2015 19:05:41 +0100 Subject: Correct wrong XML response tag --- modules/m_xmlrpc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/m_xmlrpc.cpp b/modules/m_xmlrpc.cpp index 2fd900e61..01300fbbb 100644 --- a/modules/m_xmlrpc.cpp +++ b/modules/m_xmlrpc.cpp @@ -179,10 +179,10 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage if (!request.id.empty()) request.reply("id", request.id); - Anope::string r = "\n\n" + request.name + "\n\n\n\n\n"; + Anope::string r = "\n\n" + request.name + "\n\n\n\n\n"; for (std::map::const_iterator it = request.get_replies().begin(); it != request.get_replies().end(); ++it) r += "\n" + it->first + "\n\n" + this->Sanitize(it->second) + "\n\n\n"; - r += "\n\n\n\n"; + r += "\n\n\n\n"; request.r.Write(r); } -- cgit From fb17bc85ead8c1be6ebe1561f77865f083fdc000 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 11 Mar 2015 08:48:08 -0400 Subject: Redesign m_ldap to no longer rely on undefined behavior Accessing the same LDAP* from multiple threads at once is always undefined, even if one thread is just polling ldap_result. Instead keep one thread per connection and issue blocking queries on the thread. --- include/modules/ldap.h | 42 +-- modules/extra/m_ldap.cpp | 621 +++++++++++++++++--------------- modules/extra/m_ldap_authentication.cpp | 136 +++---- 3 files changed, 385 insertions(+), 414 deletions(-) diff --git a/include/modules/ldap.h b/include/modules/ldap.h index 65be27687..20ca71cf8 100644 --- a/include/modules/ldap.h +++ b/include/modules/ldap.h @@ -1,8 +1,6 @@ #ifndef ANOPE_LDAP_H #define ANOPE_LDAP_H -typedef int LDAPQuery; - class LDAPException : public ModuleException { public: @@ -59,28 +57,26 @@ struct LDAPAttributes : public std::map messages; Anope::string error; - enum QueryType - { - QUERY_UNKNOWN, - QUERY_BIND, - QUERY_SEARCH, - QUERY_ADD, - QUERY_DELETE, - QUERY_MODIFY - }; - QueryType type; - LDAPQuery id; LDAPResult() { this->type = QUERY_UNKNOWN; - this->id = -1; } size_t size() const @@ -126,48 +122,42 @@ class LDAPProvider : public Service /** Attempt to bind to the LDAP server as an admin * @param i The LDAPInterface the result is sent to - * @return The query ID */ - virtual LDAPQuery BindAsAdmin(LDAPInterface *i) = 0; + virtual void BindAsAdmin(LDAPInterface *i) = 0; /** Bind to LDAP * @param i The LDAPInterface the result is sent to * @param who The binddn * @param pass The password - * @return The query ID */ - virtual LDAPQuery Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) = 0; + virtual void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) = 0; /** Search ldap for the specified filter * @param i The LDAPInterface the result is sent to * @param base The base DN to search * @param filter The filter to apply - * @return The query ID */ - virtual LDAPQuery Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) = 0; + virtual void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) = 0; /** Add an entry to LDAP * @param i The LDAPInterface the result is sent to * @param dn The dn of the entry to add * @param attributes