void IRCDProto::Parse(const Anope::string &buffer, Anope::string &source, Anope::string &command, std::vector<Anope::string> ¶ms) { spacesepstream sep(buffer); if (buffer[0] == ':') { sep.GetToken(source); source.erase(0, 1); } sep.GetToken(command); for (Anope::string token; sep.GetToken(token);) { if (token[0] == ':') { if (!sep.StreamEnd()) params.push_back(token.substr(1) + " " + sep.GetRemaining()); else params.push_back(token.substr(1)); break; } else params.push_back(token); } }
void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message) { Anope::string versionstr; if (bi != StatServ) return; if (message[0] == '\1' && message[message.length() - 1] == '\1') { if (message.substr(0, 9).equals_ci("\1VERSION ")) { if (u->HasExt("CTCPVERSION")) return; u->Extend<bool>("CTCPVERSION"); versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10)); if (versionstr.empty()) return; query = "UPDATE `" + prefix + "user` " "SET version=@version@ " "WHERE nick=@nick@"; query.SetValue("version", versionstr); query.SetValue("nick", u->nick); this->RunQuery(query); } } }
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; }
/** The following comes from InspIRCd to get the full path of the Anope executable */ static Anope::string GetFullProgDir(const Anope::string &argv0) { char buffer[PATH_MAX]; #ifdef _WIN32 /* Windows has specific API calls to get the EXE path that never fail. * For once, Windows has something of use, compared to the POSIX code * for this, this is positively neato. */ if (GetModuleFileName(NULL, buffer, PATH_MAX)) { Anope::string fullpath = buffer; Anope::string::size_type n = fullpath.rfind("\\"); Anope::ServicesBin = fullpath.substr(n + 1, fullpath.length()); return fullpath.substr(0, n); } #else // Get the current working directory if (getcwd(buffer, PATH_MAX)) { Anope::string remainder = argv0; Anope::ServicesBin = remainder; Anope::string::size_type n = Anope::ServicesBin.rfind("/"); Anope::string fullpath; if (Anope::ServicesBin[0] == '/') fullpath = Anope::ServicesBin.substr(0, n); else fullpath = Anope::string(buffer) + "/" + Anope::ServicesBin.substr(0, n); Anope::ServicesBin = Anope::ServicesBin.substr(n + 1, remainder.length()); return fullpath; } #endif return "/"; }
cidr::cidr(const Anope::string &ip) { bool ipv6 = ip.find(':') != Anope::string::npos; size_t sl = ip.find_last_of('/'); if (sl == Anope::string::npos) { this->cidr_ip = ip; this->cidr_len = ipv6 ? 128 : 32; this->addr.pton(ipv6 ? AF_INET6 : AF_INET, ip); } else { Anope::string real_ip = ip.substr(0, sl); Anope::string cidr_range = ip.substr(sl + 1); this->cidr_ip = real_ip; this->cidr_len = ipv6 ? 128 : 32; try { if (cidr_range.is_pos_number_only()) this->cidr_len = convertTo<unsigned int>(cidr_range); } catch (const ConvertException &) { } this->addr.pton(ipv6 ? AF_INET6 : AF_INET, real_ip); } }
NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(true), desc(descending) { Anope::string error; commasepstream sep(list); Anope::string token; sep.GetToken(token); if (token.empty()) token = list; do { size_t t = token.find('-'); if (t == Anope::string::npos) { unsigned num = convertTo<unsigned>(token, error, false); if (error.empty()) numbers.insert(num); else { if (!this->InvalidRange(list)) { is_valid = false; return; } } } else { Anope::string error2; unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false); unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false); if (error.empty() && error2.empty()) { for (unsigned i = num1; i <= num2; ++i) numbers.insert(i); } else { if (!this->InvalidRange(list)) { is_valid = false; return; } } } } while (sep.GetToken(token)); }
/** * Checks whether we have a valid, common e-mail address. * This is NOT entirely RFC compliant, and won't be so, because I said * *common* cases. ;) It is very unlikely that e-mail addresses that * are really being used will fail the check. * * @param email Email to Validate * @return bool */ bool MailValidate(const Anope::string &email) { bool has_period = false; static char specials[] = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '}; if (email.empty()) return false; Anope::string copy = email; size_t at = copy.find('@'); if (at == Anope::string::npos) return false; Anope::string domain = copy.substr(at + 1); copy = copy.substr(0, at); /* Don't accept empty copy or domain. */ if (copy.empty() || domain.empty()) return false; /* Check for forbidden characters in the name */ for (unsigned i = 0, end = copy.length(); i < end; ++i) { if (copy[i] <= 31 || copy[i] >= 127) return false; for (unsigned int j = 0; j < 13; ++j) if (copy[i] == specials[j]) return false; } /* Check for forbidden characters in the domain */ for (unsigned i = 0, end = domain.length(); i < end; ++i) { if (domain[i] <= 31 || domain[i] >= 127) return false; for (unsigned int j = 0; j < 13; ++j) if (domain[i] == specials[j]) return false; if (domain[i] == '.') { if (!i || i == end - 1) return false; has_period = true; } } return has_period; }
static bool GetData(Anope::string &content, Anope::string &tag, Anope::string &data) { if (content.empty()) return false; Anope::string prev, cur; bool istag; do { prev = cur; cur.clear(); int len = 0; istag = false; if (content[0] == '<') { len = content.find_first_of('>'); istag = true; } else if (content[0] != '>') { len = content.find_first_of('<'); } if (len) { if (istag) { cur = content.substr(1, len - 1); content.erase(0, len + 1); while (!content.empty() && content[0] == ' ') content.erase(content.begin()); } else { cur = content.substr(0,len); content.erase(0, len); } } } while (istag && !content.empty()); tag = Unescape(prev); data = Unescape(cur); return !istag && !data.empty(); }
void plexus::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost) { Anope::string sid = uid.substr(0, 3); Server *s = Server::Find(sid); Uplink::Send(Me, "ENCAP", s ? s->GetName() : sid, "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc); }
Anope::string GetAttribute(const Anope::string &command) { size_t sp = command.rfind(' '); if (sp != Anope::string::npos) return command.substr(sp + 1); return command; }
/* strip dots from username, and remove anything after the first + */ Anope::string CleanMail(const Anope::string &email) { size_t host = email.find('@'); if (host == Anope::string::npos) return email; Anope::string username = email.substr(0, host); username = username.replace_all_cs(".", ""); size_t sz = username.find('+'); if (sz != Anope::string::npos) username = username.substr(0, sz); Anope::string cleaned = username + email.substr(host); logger.Debug("cleaned {0} to {1}", email, cleaned); return cleaned; }
void DoAdd(CommandSource &source, ChanServ::Channel *ci, const Anope::string &word) { size_t pos = word.rfind(' '); BadWordType bwtype = BW_ANY; Anope::string realword = word; if (pos != Anope::string::npos) { Anope::string opt = word.substr(pos + 1); if (!opt.empty()) { if (opt.equals_ci("SINGLE")) bwtype = BW_SINGLE; else if (opt.equals_ci("START")) bwtype = BW_START; else if (opt.equals_ci("END")) bwtype = BW_END; } realword = word.substr(0, pos); } unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax"); if (badwords->GetBadWordCount(ci) >= badwordsmax) { source.Reply(_("Sorry, you can only have \002{0}\002 bad words entries on a channel."), badwordsmax); return; } bool casesensitive = Config->GetModule(this->module)->Get<bool>("casesensitive"); for (BadWord *bw : badwords->GetBadWords(ci)) if ((casesensitive && realword.equals_cs(bw->GetWord())) || (!casesensitive && realword.equals_ci(bw->GetWord()))) { source.Reply(_("\002{0}\002 already exists in \002{1}\002 bad words list."), bw->GetWord(), ci->GetName()); return; } bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword; badwords->AddBadWord(ci, realword, bwtype); source.Reply(_("\002{0}\002 added to \002{1}\002 bad words list."), realword, ci->GetName()); }
/** * Is the given nick a network service * @param nick to check * @param int Check if botserv bots * @return int */ bool nickIsServices(const Anope::string &tempnick, bool bot) { if (tempnick.empty()) return false; Anope::string nick = tempnick; size_t at = nick.find('@'); if (at != Anope::string::npos) { Anope::string servername = nick.substr(at + 1); if (!servername.equals_ci(Config->ServerName)) return false; nick = nick.substr(0, at); } BotInfo *bi = findbot(nick); if (bi) return bot ? true : bi->HasFlag(BI_CORE); return false; }
bool IsValid(const Anope::string &value) const { try { Anope::string rest; if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty()) return true; } catch (const ConvertException &) { } return false; }
void Message::Mode::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Anope::string buf; for (unsigned i = 1; i < params.size(); ++i) buf += " " + params[i]; if (IRCD->IsChannelValid(params[0])) { Channel *c = Channel::Find(params[0]); if (c) c->SetModesInternal(source, buf.substr(1), 0); } else { User *u = User::Find(params[0]); if (u) u->SetModesInternal(source, "%s", buf.substr(1).c_str()); } }
void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &chans) { std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>(); Anope::string delchans; Anope::string notfoundchans; commasepstream sep(chans); for (Anope::string chan; sep.GetToken(chan);) { unsigned i = 0; for (; i < channels.size(); ++i) if (channels[i]->GetChannel().equals_ci(chan)) break; if (i == channels.size()) notfoundchans += chan + ", "; else { delete channels[i]; delchans += chan + ", "; } } if (!notfoundchans.empty()) { notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2); source.Reply(_("\002{0}\002 was not found on the auto join list of \002{1}\002."), notfoundchans, nc->GetDisplay()); } if (delchans.empty()) return; delchans = delchans.substr(0, delchans.length() - 2); Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->GetDisplay(); source.Reply(_("\002{0}\002 was removed from the auto join list of \002{1}\002."), delchans, nc->GetDisplay()); }
/** Called on startup to organize our starting arguments in a better way * and check for errors * @param ac number of args * @param av args */ static void ParseCommandLineArguments(int ac, char **av) { for (int i = 1; i < ac; ++i) { Anope::string option = av[i]; Anope::string param; while (!option.empty() && option[0] == '-') option.erase(option.begin()); size_t t = option.find('='); if (t != Anope::string::npos) { param = option.substr(t + 1); option.erase(t); } if (option.empty()) continue; CommandLineArguments.push_back(std::make_pair(option, param)); } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } User *u = source.GetUser(); NickServ::Nick *na = NickServ::FindNick(source.GetNick()); if (!na || na->GetAccount() != source.GetAccount()) { source.Reply(_("Access denied.")); //XXX with nonickownership this should be allowed. return; } if (source.GetAccount()->HasFieldS("UNCONFIRMED")) { source.Reply(_("You must confirm your account before you may request a vhost.")); return; } Anope::string rawhostmask = params[0]; Anope::string user, host; size_t a = rawhostmask.find('@'); if (a == Anope::string::npos) host = rawhostmask; else { user = rawhostmask.substr(0, a); host = rawhostmask.substr(a + 1); } if (host.empty()) { this->OnSyntaxError(source, ""); return; } if (!user.empty()) { if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) { source.Reply(_("The username \002{0}\002 is too long, please use a username shorter than %d characters."), Config->GetBlock("networkinfo")->Get<unsigned>("userlen")); return; } if (!IRCD->CanSetVIdent) { source.Reply(_("Vhosts may not contain a username.")); return; } if (!IRCD->IsIdentValid(user)) { source.Reply(_("The requested username is not valid.")); return; } } if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } if (!IRCD->IsHostValid(host)) { source.Reply(_("The requested hostname is not valid.")); return; } time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); if (Config->GetModule(this->GetOwner())->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime) { source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay); u->lastmemosend = Anope::CurTime; return; } HostRequest *req = Serialize::New<HostRequest *>(); req->SetNick(na); req->SetIdent(user); req->SetHost(host); req->SetTime(Anope::CurTime); source.Reply(_("Your vhost has been requested.")); this->SendMemos(source, user, host); Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host; }
void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &receiver = params[0]; Anope::string message = params[1]; User *u = source.GetUser(); if (IRCD->IsChannelValid(receiver)) { Channel *c = Channel::Find(receiver); if (c) { EventManager::Get()->Dispatch(&Event::Privmsg::OnPrivmsg, u, c, message); } } else { /* If a server is specified (nick@server format), make sure it matches * us, and strip it off. */ Anope::string botname = receiver; size_t s = receiver.find('@'); bool nick_only = false; if (s != Anope::string::npos) { Anope::string servername(receiver.begin() + s + 1, receiver.end()); botname = botname.substr(0, s); nick_only = true; if (!servername.equals_ci(Me->GetName())) return; } else if (!IRCD->RequiresID && Config->UseStrictPrivmsg) { ServiceBot *bi = ServiceBot::Find(receiver); if (!bi) return; Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick; u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str()); return; } ServiceBot *bi = ServiceBot::Find(botname, nick_only); if (bi) { if (message[0] == '\1' && message[message.length() - 1] == '\1') { if (message.substr(0, 6).equals_ci("\1PING ")) { Anope::string buf = message; buf.erase(buf.begin()); buf.erase(buf.end() - 1); IRCD->SendCTCP(bi, u->nick, "%s", buf.c_str()); } else if (message.substr(0, 9).equals_ci("\1VERSION\1")) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str()); } return; } EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotPrivmsg::OnBotPrivmsg, u, bi, message); if (MOD_RESULT == EVENT_STOP) return; bi->OnMessage(u, message); } } return; }
bool IRCdMessage::OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> ¶ms) { const Anope::string &receiver = params.size() > 0 ? params[0] : ""; Anope::string message = params.size() > 1 ? params[1] : ""; /* Messages from servers can happen on some IRCds, check for . */ if (source.empty() || receiver.empty() || message.empty() || source.find('.') != Anope::string::npos) return true; User *u = finduser(source); if (!u) { Log() << message << ": user record for " << source << " not found"; BotInfo *bi = findbot(receiver); if (bi) ircdproto->SendMessage(bi, source, "%s", "Internal error - unable to process request."); return true; } if (receiver[0] == '#') { Channel *c = findchan(receiver); if (c) { FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message)); } } else { /* If a server is specified (nick@server format), make sure it matches * us, and strip it off. */ Anope::string botname = receiver; size_t s = receiver.find('@'); if (s != Anope::string::npos) { Anope::string servername(receiver.begin() + s + 1, receiver.end()); botname = botname.substr(0, s); if (!servername.equals_ci(Config->ServerName)) return true; } else if (Config->UseStrictPrivMsg) { BotInfo *bi = findbot(receiver); if (!bi) return true; Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source; u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), receiver.c_str(), receiver.c_str(), Config->ServerName.c_str(), receiver.c_str()); return true; } BotInfo *bi = findbot(botname); if (bi) { EventReturn MOD_RESULT; FOREACH_RESULT(I_OnBotPrivmsg, OnBotPrivmsg(u, bi, message)); if (MOD_RESULT == EVENT_STOP) return true; if (message[0] == '\1' && message[message.length() - 1] == '\1') { if (message.substr(0, 6).equals_ci("\1PING ")) { Anope::string buf = message; buf.erase(buf.begin()); buf.erase(buf.end() - 1); ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str()); } else if (message.substr(0, 9).equals_ci("\1VERSION\1")) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); } return true; } bi->OnMessage(u, message); } } return true; }
EventReturn OnLoadDatabase() override { const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<Anope::string>("database", "anope.db"); std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary); if (!fd.is_open()) { Log(this) << "Unable to open " << db_name << " for reading!"; return EVENT_STOP; } Serialize::TypeBase *type = nullptr; Serialize::Object *obj = nullptr; for (Anope::string buf; std::getline(fd, buf.str());) { if (buf.find("OBJECT ") == 0) { Anope::string t = buf.substr(7); if (obj) Log(LOG_DEBUG) << "obj != null but got OBJECT"; if (type) Log(LOG_DEBUG) << "type != null but got OBJECT"; type = Serialize::TypeBase::Find(t); obj = nullptr; } else if (buf.find("ID ") == 0) { if (!type || obj) continue; try { Serialize::ID id = convertTo<Serialize::ID>(buf.substr(3)); obj = type->Require(id); } catch (const ConvertException &) { Log(LOG_DEBUG) << "Unable to parse object id " << buf.substr(3); } } else if (buf.find("DATA ") == 0) { if (!type) continue; if (!obj) obj = type->Create(); size_t sp = buf.find(' ', 5); // Skip DATA if (sp == Anope::string::npos) continue; Anope::string key = buf.substr(5, sp - 5), value = buf.substr(sp + 1); Serialize::FieldBase *field = type->GetField(key); if (field) field->UnserializeFromString(obj, value); } else if (buf.find("END") == 0) { type = nullptr; obj = nullptr; } } fd.close(); loaded = true; return EVENT_STOP; }
int main(int ac, char **av, char **envp) { BinaryDir = GetFullProgDir(av[0]); if (BinaryDir[BinaryDir.length() - 1] == '.') BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2); #ifdef _WIN32 Anope::string::size_type n = BinaryDir.rfind('\\'); #else Anope::string::size_type n = BinaryDir.rfind('/'); #endif Anope::ServicesDir = BinaryDir.substr(0, n); #ifdef _WIN32 /* Clean out the module runtime directory prior to running, just in case files were left behind during a previous run */ ModuleManager::CleanupRuntimeDirectory(); OnStartup(); #endif try { /* General initialization first */ Anope::Init(ac, av); } catch (const CoreException &ex) { Anope::Logger.Log(ex.GetReason()); return -1; } try { Uplink::Connect(); } catch (const SocketException &ex) { Anope::Logger.Terminal(_("Unable to connect to uplink #{0} ({1}:{2}): {3}"), Anope::CurrentUplink + 1, Config->Uplinks[Anope::CurrentUplink].host, Config->Uplinks[Anope::CurrentUplink].port, ex.GetReason()); } /* Set up timers */ time_t last_check = Anope::CurTime; ExpireTimer expireTimer(Config->GetBlock("options")->Get<time_t>("expiretimeout", "30m")); Uplink::PingTimer pingTimer(30); /*** Main loop. ***/ while (!Anope::Quitting) { Anope::Logger.Debug2("Top of main loop"); /* Process timers */ if (Anope::CurTime - last_check >= Config->TimeoutCheck) { TimerManager::TickTimers(Anope::CurTime); last_check = Anope::CurTime; } /* Process the socket engine */ SocketEngine::Process(); if (Anope::Signal) Anope::HandleSignal(); } if (Anope::Restarting) { EventManager::Get()->Dispatch(&Event::Restart::OnRestart); } else { EventManager::Get()->Dispatch(&Event::Shutdown::OnShutdown); } if (Anope::QuitReason.empty()) Anope::QuitReason = "Terminating, reason unknown"; Anope::Logger.Log(Anope::QuitReason); delete UplinkSock; ModuleManager::UnloadAll(); SocketEngine::Shutdown(); for (Module *m; (m = ModuleManager::FindFirstOf(PROTOCOL)) != NULL;) ModuleManager::UnloadModule(m, NULL); #ifdef _WIN32 ModuleManager::CleanupRuntimeDirectory(); OnShutdown(); #endif if (Anope::Restarting) { chdir(BinaryDir.c_str()); Anope::string sbin = "./" + Anope::ServicesBin; av[0] = const_cast<char *>(sbin.c_str()); execve(Anope::ServicesBin.c_str(), av, envp); Anope::Logger.Log("Restart failed"); Anope::ReturnValue = -1; } return Anope::ReturnValue; }
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0) { Anope::string n, u, h; size_t at = fh.find('@'); if (at != Anope::string::npos) { this->host = fh.substr(at + 1); const Anope::string &nu = fh.substr(0, at); size_t ex = nu.find('!'); if (ex != Anope::string::npos) { this->user = nu.substr(ex + 1); this->nick = nu.substr(0, ex); } else this->user = nu; } else { if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos) this->host = fh; else this->nick = fh; } at = this->host.find('#'); if (at != Anope::string::npos) { this->real = this->host.substr(at + 1); this->host = this->host.substr(0, at); } /* If the mask is all *'s it will match anything, so just clear it */ if (this->nick.find_first_not_of("*") == Anope::string::npos) this->nick.clear(); if (this->user.find_first_not_of("*") == Anope::string::npos) this->user.clear(); if (this->host.find_first_not_of("*") == Anope::string::npos) this->host.clear(); else { /* Host might be a CIDR range */ size_t sl = this->host.find_last_of('/'); if (sl != Anope::string::npos) { const Anope::string &cidr_ip = this->host.substr(0, sl), &cidr_range = this->host.substr(sl + 1); sockaddrs addr(cidr_ip); try { if (addr.valid() && cidr_range.is_pos_number_only()) { this->cidr_len = convertTo<unsigned short>(cidr_range); /* If we got here, cidr_len is a valid number. * If cidr_len is >32 (or 128) it is handled later in * cidr::match */ this->host = cidr_ip; Log(LOG_DEBUG) << "Ban " << m << " has cidr " << this->cidr_len; } } catch (const ConvertException &) { } } } if (this->real.find_first_not_of("*") == Anope::string::npos) this->real.clear(); }
/** Main process routine * @param buffer A raw line from the uplink to do things with */ void process(const Anope::string &buffer) { /* If debugging, log the buffer */ Log(LOG_RAWIO) << "Received: " << buffer; /* Strip all extra spaces */ Anope::string buf = buffer; buf = buf.replace_all_cs(" ", " "); if (buf.empty()) return; Anope::string source; if (buf[0] == ':') { size_t space = buf.find_first_of(" "); if (space == Anope::string::npos) return; source = buf.substr(1, space - 1); buf = buf.substr(space + 1); if (source.empty() || buf.empty()) return; } spacesepstream buf_sep(buf); Anope::string buf_token; Anope::string command = buf; if (buf_sep.GetToken(buf_token)) command = buf_token; std::vector<Anope::string> params; while (buf_sep.GetToken(buf_token)) { if (buf_token[0] == ':') { if (!buf_sep.StreamEnd()) params.push_back(buf_token.substr(1) + " " + buf_sep.GetRemaining()); else params.push_back(buf_token.substr(1)); break; } else params.push_back(buf_token); } if (protocoldebug) { Log() << "Source : " << (source.empty() ? "No source" : source); Log() << "Command: " << command; if (params.empty()) Log() << "No params"; else for (unsigned i = 0; i < params.size(); ++i) Log() << "params " << i << ": " << params[i]; } std::vector<Message *> messages = Anope::FindMessage(command); if (!messages.empty()) { bool retVal = true; for (std::vector<Message *>::iterator it = messages.begin(), it_end = messages.end(); retVal == true && it != it_end; ++it) { Message *m = *it; if (m->func) retVal = m->func(source, params); } } else Log(LOG_DEBUG) << "unknown message from server (" << buffer << ")"; }
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) override { Server *s = Server::Find(uid.substr(0, 3)); Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", "*", "*", acc); }
void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Replacements &r) { int fd = open((template_base + "/" + this->file_name).c_str(), O_RDONLY); if (fd < 0) { Log(LOG_NORMAL, "httpd") << "Error serving file " << page_name << " (" << (template_base + "/" + this->file_name) << "): " << strerror(errno); client->SendError(HTTP_PAGE_NOT_FOUND, "Page not found"); return; } Anope::string buf; int i; char buffer[BUFSIZE]; while ((i = read(fd, buffer, sizeof(buffer) - 1)) > 0) { buffer[i] = 0; buf += buffer; } close(fd); Anope::string finished; bool escaped = false; for (unsigned j = 0; j < buf.length(); ++j) { if (buf[j] == '\\' && j + 1 < buf.length() && (buf[j + 1] == '{' || buf[j + 1] == '}')) escaped = true; else if (buf[j] == '{' && !escaped) { size_t f = buf.substr(j).find('}'); if (f == Anope::string::npos) break; const Anope::string &content = buf.substr(j + 1, f - 1); if (content.find("IF ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() == 4 && tokens[1] == "EQ") { Anope::string first = FindReplacement(r, tokens[2]), second = FindReplacement(r, tokens[3]); if (first.empty()) first = tokens[2]; if (second.empty()) second = tokens[3]; bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && first == second); } else if (tokens.size() == 3 && tokens[1] == "EXISTS") { bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && r.count(tokens[2]) > 0); } else Log() << "Invalid IF in web template " << this->file_name; } else if (content == "ELSE") { if (IfStack.empty()) Log() << "Invalid ELSE with no stack in web template" << this->file_name; else { bool old = IfStack.top(); IfStack.pop(); // Pop off previous if() bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && !old); // Push back the opposite of what was popped } } else if (content == "END IF") { if (IfStack.empty()) Log() << "END IF with empty stack?"; else IfStack.pop(); } else if (content.find("FOR ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() != 4 || tokens[2] != "IN") Log() << "Invalid FOR in web template " << this->file_name; else { std::vector<Anope::string> temp_variables, real_variables; commasepstream(tokens[1]).GetTokens(temp_variables); commasepstream(tokens[3]).GetTokens(real_variables); if (temp_variables.size() != real_variables.size()) Log() << "Invalid FOR in web template " << this->file_name << " variable mismatch"; else ForLoop::Stack.push_back(ForLoop(j + f, r, temp_variables, real_variables)); } } else if (content == "END FOR") { if (ForLoop::Stack.empty()) Log() << "END FOR with empty stack?"; else { ForLoop &fl = ForLoop::Stack.back(); if (fl.finished(r)) ForLoop::Stack.pop_back(); else { fl.increment(r); if (fl.finished(r)) ForLoop::Stack.pop_back(); else { j = fl.start; // Move pointer back to start of the loop continue; // To prevent skipping over this block which doesn't exist anymore } } } } else if (content.find("INCLUDE ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() != 2) Log() << "Invalid INCLUDE in web template " << this->file_name; else { if (!finished.empty()) { reply.Write(finished); // Write out what we have currently so we insert this files contents here finished.clear(); } TemplateFileServer tfs(tokens[1]); tfs.Serve(server, page_name, client, message, reply, r); } } else { // If the if stack is empty or we are in a true statement bool ifok = IfStack.empty() || IfStack.top(); bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r); if (ifok && forok) { const Anope::string &replacement = FindReplacement(r, content.substr(0, f - 1)); finished += replacement; } } j += f; // Skip over this whole block } else { escaped = false; // If the if stack is empty or we are in a true statement bool ifok = IfStack.empty() || IfStack.top(); bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r); if (ifok && forok) finished += buf[j]; } } if (!finished.empty()) reply.Write(finished); }
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) override { Server *s = Server::Find(uid.substr(0, 3)); UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * * * " << acc; }
void DoAdd(CommandSource &source, NickServ::Account *nc, const Anope::string &chans, const Anope::string &keys) { std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>(); Anope::string addedchans; Anope::string alreadyadded; Anope::string invalidkey; commasepstream ksep(keys, true); commasepstream csep(chans); for (Anope::string chan, key; csep.GetToken(chan);) { ksep.GetToken(key); unsigned i = 0; for (; i < channels.size(); ++i) if (channels[i]->GetChannel().equals_ci(chan)) break; if (channels.size() >= Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax")) { source.Reply(_("Sorry, the maximum of \002{0}\002 auto join entries has been reached."), Config->GetModule(this->GetOwner())->Get<unsigned>("ajoinmax")); return; } if (i != channels.size()) alreadyadded += chan + ", "; else if (IRCD->IsChannelValid(chan) == false) source.Reply(_("\002{0}\002 isn't a valid channel."), chan); else { Channel *c = Channel::Find(chan); Anope::string k; if (c && c->GetParam("KEY", k) && key != k) { invalidkey += chan + ", "; continue; } AutoJoin *entry = Serialize::New<AutoJoin *>(); entry->SetOwner(nc); entry->SetChannel(chan); entry->SetKey(key); addedchans += chan + ", "; } } if (!alreadyadded.empty()) { alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2); source.Reply(_("\002{0}\002 is already on the auto join list of \002{1}\002."), alreadyadded, nc->GetDisplay()); } if (!invalidkey.empty()) { invalidkey = invalidkey.substr(0, invalidkey.length() - 2); source.Reply(_("\002{0}\002 had an invalid key specified, and was ignored."), invalidkey); } if (addedchans.empty()) return; addedchans = addedchans.substr(0, addedchans.length() - 2); Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->GetDisplay(); source.Reply(_("\002{0}\002 added to the auto join list of \002{1}\002."), addedchans, nc->GetDisplay()); }