void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &nick = !params.empty() ? params[0] : source.GetNick(); const NickServ::Nick *na = NickServ::FindNick(nick); spacesepstream sep(nick); Anope::string nickbuf; while (sep.GetToken(nickbuf)) { #if 0 User *u2 = User::Find(nickbuf, true); if (!u2) /* Nick is not online */ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, ""); else if (u2->IsIdentified() && na && na->GetAccount() == u2->Account()) /* Nick is identified */ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 3, u2->Account()->GetDisplay().c_str()); else if (u2->IsRecognized()) /* Nick is recognised, but NOT identified */ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 2, u2->Account() ? u2->Account()->GetDisplay().c_str() : ""); else if (!na) /* Nick is online, but NOT a registered */ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, ""); else /* Nick is not identified for the nick, but they could be logged into an account, * so we tell the user about it */ source.Reply("STATUS %s %d %s", nickbuf.c_str(), 1, u2->Account() ? u2->Account()->GetDisplay().c_str() : ""); #endif } }
/* Makes a simple ban and kicks the target * @param requester The user requesting the kickban * @param ci The channel * @param u The user being kicked * @param reason The reason */ void bot_raw_ban(User *requester, ChannelInfo *ci, User *u, const Anope::string &reason) { if (!u || !ci) return; if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, ACCESS_DENIED)); return; } AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester); if (ci->HasFlag(CI_PEACE) && u != requester && u_access >= req_access) return; if (matches_list(ci->c, u, CMODE_EXCEPT)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, _("User matches channel except."))); return; } Anope::string mask; get_idealban(ci, u, mask); ci->c->SetMode(NULL, CMODE_BAN, mask); /* Check if we need to do a signkick or not -GD */ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK"))) ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str()); else ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str()); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.u; const Anope::string &nick = !params.empty() ? params[0] : u->nick; NickAlias *na = findnick(nick); spacesepstream sep(nick); Anope::string nickbuf; while (sep.GetToken(nickbuf)) { User *u2 = finduser(nickbuf); if (!u2) /* Nick is not online */ source.Reply(_("STATUS %s %d %s"), nickbuf.c_str(), 0, ""); else if (u2->IsIdentified() && na && na->nc == u2->Account()) /* Nick is identified */ source.Reply(_("STATUS %s %d %s"), nickbuf.c_str(), 3, u2->Account()->display.c_str()); else if (u2->IsRecognized()) /* Nick is recognised, but NOT identified */ source.Reply(_("STATUS %s %d %s"), nickbuf.c_str(), 2, u2->Account() ? u2->Account()->display.c_str() : ""); else if (!na) /* Nick is online, but NOT a registered */ source.Reply(_("STATUS %s %d %s"), nickbuf.c_str(), 0, ""); else /* Nick is not identified for the nick, but they could be logged into an account, * so we tell the user about it */ source.Reply(_("STATUS %s %d %s"), nickbuf.c_str(), 1, u2->Account() ? u2->Account()->display.c_str() : ""); } return; }
void User::Identify(NickServ::Nick *na) { if (this->nick.equals_ci(na->GetNick())) { na->SetLastUsermask(this->GetIdent() + "@" + this->GetDisplayedHost()); na->SetLastRealhost(this->GetIdent() + "@" + this->host); na->SetLastRealname(this->realname); na->SetLastSeen(Anope::CurTime); } IRCD->SendLogin(this, na); this->Login(na->GetAccount()); EventManager::Get()->Dispatch(&Event::NickIdentify::OnNickIdentify, this); if (this->IsServicesOper()) { Anope::string m = this->nc->o->GetType()->modes; if (!m.empty()) { this->SetModes(NULL, "%s", m.c_str()); this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m.c_str()); UserMode *um = ModeManager::FindUserModeByName("OPER"); if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos) IRCD->SendOper(this); } if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty()) { this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost()); this->SetDisplayedHost(this->nc->o->GetVhost()); IRCD->SendVhost(this, "", this->nc->o->GetVhost()); } } }
void ModuleManager::CleanupRuntimeDirectory() { Anope::string dirbuf = services_dir + "/modules/runtime"; Log(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait"; DIR *dirp = opendir(dirbuf.c_str()); if (!dirp) { Log(LOG_DEBUG) << "Cannot open directory (" << dirbuf << ")"; return; } for (dirent *dp; (dp = readdir(dirp));) { if (!dp->d_ino) continue; if (Anope::string(dp->d_name).equals_cs(".") || Anope::string(dp->d_name).equals_cs("..")) continue; Anope::string filebuf = dirbuf + "/" + dp->d_name; unlink(filebuf.c_str()); } closedir(dirp); }
void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message) { EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg"); if (!message.is_pos_number_only()) source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str()); else if (messages != NULL) { try { unsigned i = convertTo<unsigned>(message); if (i > 0 && i <= messages->size()) { messages->erase(messages->begin() + i - 1); if (messages->empty()) ci->Shrink("cs_entrymsg"); source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str()); } else throw ConvertException(); } catch (const ConvertException &) { source.Reply(_("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str()); } } else source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str()); }
void sockaddrs::pton(int type, const Anope::string &address, int pport) { this->clear(); switch (type) { case AF_INET: { int i = inet_pton(type, address.c_str(), &sa4.sin_addr); if (i <= 0) this->clear(); else { sa4.sin_family = type; sa4.sin_port = htons(pport); } break; } case AF_INET6: { int i = inet_pton(type, address.c_str(), &sa6.sin6_addr); if (i <= 0) this->clear(); else { sa6.sin6_family = type; sa6.sin6_port = htons(pport); } break; } default: break; } }
int LDAPBind::run() { berval cred; cred.bv_val = strdup(pass.c_str()); cred.bv_len = pass.length(); int i = ldap_sasl_bind_s(service->GetConnection(), who.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); free(cred.bv_val); return i; }
void Command::SendSyntax(CommandSource &source) { Anope::string s = Language::Translate(source.GetAccount(), _("Syntax")); if (!this->syntax.empty()) { source.Reply("%s: \002%s %s\002", s.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[0].c_str())); Anope::string spaces(s.length(), ' '); for (unsigned i = 1, j = this->syntax.size(); i < j; ++i) source.Reply("%s \002%s %s\002", spaces.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[i].c_str())); } else source.Reply("%s: \002%s\002", s.c_str(), source.command.c_str()); }
/** * Copy the module from the modules folder to the runtime folder. * This will prevent module updates while the modules is loaded from * triggering a segfault, as the actaul file in use will be in the * runtime folder. * @param name the name of the module to copy * @param output the destination to copy the module to * @return MOD_ERR_OK on success */ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &output) { Anope::string input = services_dir + "/modules/" + name + ".so"; struct stat s; if (stat(input.c_str(), &s) == -1) return MOD_ERR_NOEXIST; else if (!S_ISREG(s.st_mode)) return MOD_ERR_NOEXIST; std::ifstream source(input.c_str(), std::ios_base::in | std::ios_base::binary); if (!source.is_open()) return MOD_ERR_NOEXIST; char *tmp_output = strdup(output.c_str()); int target_fd = mkstemp(tmp_output); if (target_fd == -1 || close(target_fd) == -1) { free(tmp_output); source.close(); return MOD_ERR_FILE_IO; } output = tmp_output; free(tmp_output); Log(LOG_DEBUG) << "Runtime module location: " << output; std::ofstream target(output.c_str(), std::ios_base::in | std::ios_base::binary); if (!target.is_open()) { source.close(); return MOD_ERR_FILE_IO; } int want = s.st_size; char *buffer = new char[s.st_size]; while (want > 0 && !source.fail() && !target.fail()) { source.read(buffer, want); int read_len = source.gcount(); target.write(buffer, read_len); want -= read_len; } delete [] buffer; source.close(); target.close(); return !source.fail() && !target.fail() ? MOD_ERR_OK : MOD_ERR_FILE_IO; }
void Command::Run(CommandSource &source, const Anope::string &message) { std::vector<Anope::string> params; spacesepstream(message).GetTokens(params); bool has_help = source.service->commands.find("HELP") != source.service->commands.end(); CommandInfo::map::const_iterator it = source.service->commands.end(); unsigned count = 0; for (unsigned max = params.size(); it == source.service->commands.end() && max > 0; --max) { Anope::string full_command; for (unsigned i = 0; i < max; ++i) full_command += " " + params[i]; full_command.erase(full_command.begin()); ++count; it = source.service->commands.find(full_command); } if (it == source.service->commands.end()) { if (has_help) source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); else source.Reply(_("Unknown command \002%s\002."), message.c_str()); return; } const CommandInfo &info = it->second; ServiceReference<Command> c("Command", info.name); if (!c) { if (has_help) source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); else source.Reply(_("Unknown command \002%s\002."), message.c_str()); Log(source.service) << "Command " << it->first << " exists on me, but its service " << info.name << " was not found!"; return; } for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i) params.erase(params.begin()); while (c->max_params > 0 && params.size() > c->max_params) { params[c->max_params - 1] += " " + params[c->max_params]; params.erase(params.begin() + c->max_params); } c->Run(source, it->first, info, params); }
void DoList(CommandSource &source) { Log(LOG_ADMIN, source, this) << "LIST"; Anope::string index; index = Anope::ReadOnly ? _("%s is enabled") : _("%s is disabled"); source.Reply(index.c_str(), "READONLY"); index = Anope::Debug ? _("%s is enabled") : _("%s is disabled"); source.Reply(index.c_str(), "DEBUG"); index = Anope::NoExpire ? _("%s is enabled") : _("%s is disabled"); source.Reply(index.c_str(), "NOEXPIRE"); return; }
void DoTop(CommandSource &source, const std::vector<Anope::string> ¶ms, bool is_global, int limit = 1) { Anope::string channel; if (!params.empty()) channel = params[0]; else if (source.c && source.c->ci) channel = source.c->ci->GetName(); if (!is_global && channel.empty()) is_global = true; try { SQL::Query query; query = "SELECT nick, letters, words, line, actions," "smileys_happy+smileys_sad+smileys_other as smileys " "FROM `" + prefix + "chanstats` " "WHERE `nick` != '' AND `chan` = @channel@ AND `type` = 'total' " "ORDER BY `letters` DESC LIMIT @limit@;"; query.SetValue("limit", limit, false); if (is_global) query.SetValue("channel", ""); else query.SetValue("channel", channel.c_str()); SQL::Result res = this->RunQuery(query); if (res.Rows() > 0) { source.Reply(_("Top %i of %s"), limit, (is_global ? "Network" : channel.c_str())); for (int i = 0; i < res.Rows(); ++i) { source.Reply(_("%2lu \002%-16s\002 letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"), i+1, res.Get(i, "nick").c_str(), res.Get(i, "letters").c_str(), res.Get(i, "words").c_str(), res.Get(i, "line").c_str(), res.Get(i, "smileys").c_str(), res.Get(i, "actions").c_str()); } } else source.Reply(_("No stats for %s."), is_global ? "Network" : channel.c_str()); } catch (const SQL::Exception &ex) { Log(LOG_DEBUG) << ex.GetReason(); } }
ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : LocalUser(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), botmodes(bmodes) { this->type = UserType::BOT; this->lastmsg = Anope::CurTime; this->introduced = false; bi = botinfo.Create(); bi->bot = this; bi->SetNick(nnick); bi->SetUser(nuser); bi->SetHost(nhost); bi->SetRealName(nreal); bi->SetCreated(Anope::CurTime); Event::OnCreateBot(&Event::CreateBot::OnCreateBot, this); // If we're synchronised with the uplink already, send the bot. if (Me && Me->IsSynced()) { Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : IRCD->DefaultPseudoclientModes; if (!tmodes.empty()) this->SetModesInternal(this, tmodes.c_str()); //XXX //XLine x(this->nick, "Reserved for services"); //IRCD->SendSQLine(NULL, &x); IRCD->SendClientIntroduction(this); this->introduced = true; } }
int LDAPModify::run() { LDAPMod **mods = LDAPService::BuildMods(attributes); int i = ldap_modify_ext_s(service->GetConnection(), base.c_str(), mods, NULL, NULL); LDAPService::FreeMods(mods); return i; }
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; }
void Language::InitLanguages() { #if GETTEXT_FOUND Log(LOG_DEBUG) << "Initializing Languages..."; Languages.clear(); if (!bindtextdomain("anope", Anope::LocaleDir.c_str())) Log() << "Error calling bindtextdomain, " << Anope::LastError(); else Log(LOG_DEBUG) << "Successfully bound anope to " << Anope::LocaleDir; setlocale(LC_ALL, ""); spacesepstream sep(Config->GetBlock("options")->Get<Anope::string>("languages")); Anope::string language; while (sep.GetToken(language)) { const Anope::string &lang_name = Translate(language.c_str(), _("English")); if (lang_name == "English") { Log() << "Unable to use language " << language; continue; } Log(LOG_DEBUG) << "Found language " << language; Languages.push_back(language); } #else Log() << "Unable to initialize languages, gettext is not installed"; #endif }
Anope::string SQLiteService::Escape(const Anope::string &query) { char *e = sqlite3_mprintf("%q", query.c_str()); Anope::string buffer = e; sqlite3_free(e); return buffer; }
ModuleReturn ModuleManager::DeleteModule(Module *m) { if (!m || !m->handle) return MOD_ERR_PARAMS; void *handle = m->handle; Anope::string filename = m->filename; Log(LOG_DEBUG) << "Unloading module " << m->name; dlerror(); void (*destroy_func)(Module *m) = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini")); const char *err = dlerror(); if (!destroy_func || (err && *err)) { Log() << "No destroy function found for " << m->name << ", chancing delete..."; delete m; /* we just have to chance they haven't overwrote the delete operator then... */ } else destroy_func(m); /* Let the module delete it self, just in case */ if (dlclose(handle)) Log() << dlerror(); if (!filename.empty()) unlink(filename.c_str()); return MOD_ERR_OK; }
EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override { if (!md5) return EVENT_CONTINUE; Encryption::Context *context = md5->CreateContext(); context->Update(reinterpret_cast<const unsigned char *>(src.c_str()), src.length()); context->Finalize(); Encryption::Hash hash = context->GetFinalizedHash(); char digest[32], digest2[16]; memset(digest, 0, sizeof(digest)); if (hash.second > sizeof(digest)) throw CoreException("Hash too large"); memcpy(digest, hash.first, hash.second); for (int i = 0; i < 32; i += 2) digest2[i / 2] = XTOI(digest[i]) << 4 | XTOI(digest[i + 1]); Anope::string buf = "oldmd5:" + Anope::Hex(digest2, sizeof(digest2)); Log(LOG_DEBUG_2) << "(enc_old) hashed password from [" << src << "] to [" << buf << "]"; dest = buf; delete context; return EVENT_ALLOW; }
char *dlerror(void) { static Anope::string err; err = Anope::LastError(); SetLastError(0); return err.empty() ? NULL : const_cast<char *>(err.c_str()); }
/** Check if a file exists * @param filename The file * @return true if the file exists, false if it doens't */ bool IsFile(const Anope::string &filename) { struct stat fileinfo; if (!stat(filename.c_str(), &fileinfo)) return true; return false; }
PCRERegex(const Anope::string &expr) : Regex(expr) { const char *error; int erroffset; this->regex = pcre_compile(expr.c_str(), PCRE_CASELESS, &error, &erroffset, NULL); if (!this->regex) throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + error); }
void CommandSource::Reply(const Anope::string &message) { const char *translated_message = Language::Translate(this->nc, message.c_str()); sepstream sep(translated_message, '\n', true); Anope::string tok; while (sep.GetToken(tok)) this->reply->SendMessage(this->service, tok); }
void BackupDatabase() { tm *tm = localtime(&Anope::CurTime); if (tm->tm_mday != last_day) { last_day = tm->tm_mday; const std::map<Anope::string, Serialize::TypeBase *> &types = Serialize::TypeBase::GetTypes(); std::set<Anope::string> dbs; dbs.insert(Config->GetModule(this)->Get<Anope::string>("database", "anope.db")); for (const std::pair<Anope::string, Serialize::TypeBase *> &p : types) { Serialize::TypeBase *stype = p.second; if (stype->GetOwner()) dbs.insert("module_" + stype->GetOwner()->name + ".db"); } for (std::set<Anope::string>::const_iterator it = dbs.begin(), it_end = dbs.end(); it != it_end; ++it) { const Anope::string &oldname = Anope::DataDir + "/" + *it; Anope::string newname = Anope::DataDir + "/backups/" + *it + "-" + stringify(tm->tm_year + 1900) + Anope::printf("-%02i-", tm->tm_mon + 1) + Anope::printf("%02i", tm->tm_mday); /* Backup already exists or no database to backup */ if (Anope::IsFile(newname) || !Anope::IsFile(oldname)) continue; Log(LOG_DEBUG) << "db_flatfile: Attempting to rename " << *it << " to " << newname; if (rename(oldname.c_str(), newname.c_str())) { Anope::string err = Anope::LastError(); Log(this) << "Unable to back up database " << *it << " (" << err << ")!"; if (!Config->GetModule(this)->Get<bool>("nobackupokay")) { Anope::Quitting = true; Anope::QuitReason = "Unable to back up database " + *it + " (" + err + ")"; } continue; } backups[*it].push_back(newname); unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups"); if (keepbackups > 0 && backups[*it].size() > keepbackups) { unlink(backups[*it].front().c_str()); backups[*it].pop_front(); } } } }
POSIXRegex(const Anope::string &expr) : Regex(expr) { int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB); if (err) { char buf[BUFSIZE]; regerror(err, &this->regbuf, buf, sizeof(buf)); regfree(&this->regbuf); throw RegexException("Error in regex " + expr + ": " + buf); } }
/* Makes a kick with a "dynamic" reason ;) * @param requester The user requesting the kick * @param ci The channel * @param u The user being kicked * @param reason The reason for the kick */ void bot_raw_kick(User *requester, ChannelInfo *ci, User *u, const Anope::string &reason) { if (!u || !ci || !ci->c || !ci->c->FindUser(u)) return; if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, ACCESS_DENIED)); return; } AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester); if (ci->HasFlag(CI_PEACE) && requester != u && u_access >= req_access) return; if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK"))) ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str()); else ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str()); }
void User::SendMessage(const MessageSource &source, const Anope::string &msg) { const char *translated_message = Language::Translate(this, msg.c_str()); /* Send privmsg instead of notice if: * - UsePrivmsg is enabled * - The user is not registered and NSDefMsg is enabled * - The user is registered and has set /ns set msg on */ bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasFieldS("MSG"))); sepstream sep(translated_message, '\n', true); for (Anope::string tok; sep.GetToken(tok);) { if (tok.empty()) tok = " "; spacesepstream ssep(tok, true); Anope::string buf; for (Anope::string word; ssep.GetToken(word);) { Anope::string add = buf.empty() ? word : " " + word; if (buf.length() + add.length() > Config->LineWrap) { if (send_privmsg) IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str()); else IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str()); buf.clear(); add = word; } buf.append(add); } if (!buf.empty()) { if (send_privmsg) IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str()); else IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str()); } } }
void ServiceBot::Part(Channel *c, const Anope::string &reason) { if (c->FindUser(this) == NULL) return; Event::OnPrePartChannel(&Event::PrePartChannel::OnPrePartChannel, this, c); IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : ""); c->DeleteUser(this); Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, c, c->name, reason); }
void DoView(CommandSource &source, const std::vector<Anope::string> ¶ms) { Anope::string param = params[1]; Session *session = session_service->FindSession(param); if (!session) source.Reply(_("\002%s\002 not found on session list."), param.c_str()); else { Exception *exception = session_service->FindException(param); source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), param.c_str(), session->count, exception && exception->limit > Config->DefSessionLimit ? exception->limit : Config->DefSessionLimit); } return; }