void ClearAllBuffers() { CIRCNetwork* pNetwork = GetNetwork(); if (pNetwork) { const vector<CChan*>& vChans = pNetwork->GetChans(); for (CChan* pChan : vChans) { // Skip detached channels, they weren't read yet if (pChan->IsDetached()) continue; pChan->ClearBuffer(); // We deny AutoClearChanBuffer on all channels since this module // doesn't make any sense with it pChan->SetAutoClearChanBuffer(false); } vector<CQuery*> VQueries = pNetwork->GetQueries(); for (CQuery* pQuery : VQueries) { pNetwork->DelQuery(pQuery->GetName()); } // We deny AutoClearQueryBuffer since this module // doesn't make any sense with it GetUser()->SetAutoClearQueryBuffer(false); } }
void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneName) { if (bCloneName) { m_sName = Network.GetName(); } m_fFloodRate = Network.GetFloodRate(); m_uFloodBurst = Network.GetFloodBurst(); m_uJoinDelay = Network.GetJoinDelay(); SetNick(Network.GetNick()); SetAltNick(Network.GetAltNick()); SetIdent(Network.GetIdent()); SetRealName(Network.GetRealName()); SetBindHost(Network.GetBindHost()); SetEncoding(Network.GetEncoding()); SetQuitMsg(Network.GetQuitMsg()); m_ssTrustedFingerprints = Network.m_ssTrustedFingerprints; // Servers const vector<CServer*>& vServers = Network.GetServers(); CString sServer; CServer* pCurServ = GetCurrentServer(); if (pCurServ) { sServer = pCurServ->GetName(); } DelServers(); for (CServer* pServer : vServers) { AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), pServer->IsSSL()); } m_uServerIdx = 0; for (size_t a = 0; a < m_vServers.size(); a++) { if (sServer.Equals(m_vServers[a]->GetName())) { m_uServerIdx = a + 1; break; } } if (m_uServerIdx == 0) { m_uServerIdx = m_vServers.size(); CIRCSock* pSock = GetIRCSock(); if (pSock) { PutStatus("Jumping servers because this server is no longer in the list"); pSock->Quit(); } } // !Servers // Chans const vector<CChan*>& vChans = Network.GetChans(); for (CChan* pNewChan : vChans) { CChan* pChan = FindChan(pNewChan->GetName()); if (pChan) { pChan->SetInConfig(pNewChan->InConfig()); } else { AddChan(pNewChan->GetName(), pNewChan->InConfig()); } } for (CChan* pChan : m_vChans) { CChan* pNewChan = Network.FindChan(pChan->GetName()); if (!pNewChan) { pChan->SetInConfig(false); } else { pChan->Clone(*pNewChan); } } // !Chans // Modules set<CString> ssUnloadMods; CModules& vCurMods = GetModules(); const CModules& vNewMods = Network.GetModules(); for (CModule* pNewMod : vNewMods) { CString sModRet; CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); if (!pCurMod) { vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), CModInfo::NetworkModule, m_pUser, this, sModRet); } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), m_pUser, this, sModRet); } } for (CModule* pCurMod : vCurMods) { CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); if (!pNewMod) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (const CString& sMod : ssUnloadMods) { vCurMods.UnloadModule(sMod); } // !Modules SetIRCConnectEnabled(Network.GetIRCConnectEnabled()); }
void CIRCNetwork::Clone(const CIRCNetwork& Network) { m_sName = Network.GetName(); SetNick(Network.GetNick()); SetAltNick(Network.GetAltNick()); SetIdent(Network.GetIdent()); SetRealName(Network.GetRealName()); // Servers const vector<CServer*>& vServers = Network.GetServers(); CString sServer; CServer* pCurServ = GetCurrentServer(); if (pCurServ) { sServer = pCurServ->GetName(); } DelServers(); unsigned int a; for (a = 0; a < vServers.size(); a++) { CServer* pServer = vServers[a]; AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), pServer->IsSSL()); } m_uServerIdx = 0; for (a = 0; a < m_vServers.size(); a++) { if (sServer.Equals(m_vServers[a]->GetName())) { m_uServerIdx = a + 1; break; } } if (m_uServerIdx == 0) { m_uServerIdx = m_vServers.size(); CIRCSock* pSock = GetIRCSock(); if (pSock) { PutStatus("Jumping servers because this server is no longer in the list"); pSock->Quit(); } } // !Servers // Chans const vector<CChan*>& vChans = Network.GetChans(); for (a = 0; a < vChans.size(); a++) { CChan* pNewChan = vChans[a]; CChan* pChan = FindChan(pNewChan->GetName()); if (pChan) { pChan->SetInConfig(pNewChan->InConfig()); } else { AddChan(pNewChan->GetName(), pNewChan->InConfig()); } } for (a = 0; a < m_vChans.size(); a++) { CChan* pChan = m_vChans[a]; CChan* pNewChan = Network.FindChan(pChan->GetName()); if (!pNewChan) { pChan->SetInConfig(false); } else { pChan->Clone(*pNewChan); } } // !Chans // Modules set<CString> ssUnloadMods; CModules& vCurMods = GetModules(); const CModules& vNewMods = Network.GetModules(); for (a = 0; a < vNewMods.size(); a++) { CString sModRet; CModule* pNewMod = vNewMods[a]; CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); if (!pCurMod) { vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), CModInfo::NetworkModule, m_pUser, this, sModRet); } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), m_pUser, this, sModRet); } } for (a = 0; a < vCurMods.size(); a++) { CModule* pCurMod = vCurMods[a]; CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); if (!pNewMod) { ssUnloadMods.insert(pCurMod->GetModName()); } } for (set<CString>::iterator it = ssUnloadMods.begin(); it != ssUnloadMods.end(); ++it) { vCurMods.UnloadModule(*it); } // !Modules SetIRCConnectEnabled(Network.GetIRCConnectEnabled()); }
void CClient::UserCommand(CString& sLine) { if (!m_pUser) { return; } if (sLine.empty()) { return; } NETWORKMODULECALL(OnStatusCommand(sLine), m_pUser, m_pNetwork, this, return); const CString sCommand = sLine.Token(0); if (sCommand.Equals("HELP")) { HelpUser(); } else if (sCommand.Equals("LISTNICKS")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1); if (sChan.empty()) { PutStatus("Usage: ListNicks <#chan>"); return; } CChan* pChan = m_pNetwork->FindChan(sChan); if (!pChan) { PutStatus("You are not on [" + sChan + "]"); return; } if (!pChan->IsOn()) { PutStatus("You are not on [" + sChan + "] [trying]"); return; } const map<CString,CNick>& msNicks = pChan->GetNicks(); CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); const CString& sPerms = (pIRCSock) ? pIRCSock->GetPerms() : ""; if (!msNicks.size()) { PutStatus("No nicks on [" + sChan + "]"); return; } CTable Table; for (unsigned int p = 0; p < sPerms.size(); p++) { CString sPerm; sPerm += sPerms[p]; Table.AddColumn(sPerm); } Table.AddColumn("Nick"); Table.AddColumn("Ident"); Table.AddColumn("Host"); for (map<CString,CNick>::const_iterator a = msNicks.begin(); a != msNicks.end(); ++a) { Table.AddRow(); for (unsigned int b = 0; b < sPerms.size(); b++) { if (a->second.HasPerm(sPerms[b])) { CString sPerm; sPerm += sPerms[b]; Table.SetCell(sPerm, sPerm); } } Table.SetCell("Nick", a->second.GetNick()); Table.SetCell("Ident", a->second.GetIdent()); Table.SetCell("Host", a->second.GetHost()); } PutStatus(Table); } else if (sCommand.Equals("DETACH")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1); if (sChan.empty()) { PutStatus("Usage: Detach <#chan>"); return; } const vector<CChan*>& vChans = m_pNetwork->GetChans(); vector<CChan*>::const_iterator it; unsigned int uMatches = 0, uDetached = 0; for (it = vChans.begin(); it != vChans.end(); ++it) { if (!(*it)->GetName().WildCmp(sChan)) continue; uMatches++; if ((*it)->IsDetached()) continue; uDetached++; (*it)->DetachUser(); } PutStatus("There were [" + CString(uMatches) + "] channels matching [" + sChan + "]"); PutStatus("Detached [" + CString(uDetached) + "] channels"); } else if (sCommand.Equals("VERSION")) { PutStatus(CZNC::GetTag()); PutStatus(CZNC::GetCompileOptionsString()); } else if (sCommand.Equals("MOTD") || sCommand.Equals("ShowMOTD")) { if (!SendMotd()) { PutStatus("There is no MOTD set."); } } else if (m_pUser->IsAdmin() && sCommand.Equals("Rehash")) { CString sRet; if (CZNC::Get().RehashConfig(sRet)) { PutStatus("Rehashing succeeded!"); } else { PutStatus("Rehashing failed: " + sRet); } } else if (m_pUser->IsAdmin() && sCommand.Equals("SaveConfig")) { if (CZNC::Get().WriteConfig()) { PutStatus("Wrote config to [" + CZNC::Get().GetConfigFile() + "]"); } else { PutStatus("Error while trying to write config."); } } else if (sCommand.Equals("LISTCLIENTS")) { CUser* pUser = m_pUser; CString sNick = sLine.Token(1); if (!sNick.empty()) { if (!m_pUser->IsAdmin()) { PutStatus("Usage: ListClients"); return; } pUser = CZNC::Get().FindUser(sNick); if (!pUser) { PutStatus("No such user [" + sNick + "]"); return; } } vector<CClient*> vClients = pUser->GetAllClients(); if (vClients.empty()) { PutStatus("No clients are connected"); return; } CTable Table; Table.AddColumn("Host"); Table.AddColumn("Network"); for (unsigned int a = 0; a < vClients.size(); a++) { Table.AddRow(); Table.SetCell("Host", vClients[a]->GetRemoteIP()); if (vClients[a]->GetNetwork()) { Table.SetCell("Network", vClients[a]->GetNetwork()->GetName()); } } PutStatus(Table); } else if (m_pUser->IsAdmin() && sCommand.Equals("LISTUSERS")) { const map<CString, CUser*>& msUsers = CZNC::Get().GetUserMap(); CTable Table; Table.AddColumn("Username"); Table.AddColumn("Networks"); Table.AddColumn("Clients"); for (map<CString, CUser*>::const_iterator it = msUsers.begin(); it != msUsers.end(); ++it) { Table.AddRow(); Table.SetCell("Username", it->first); Table.SetCell("Networks", CString(it->second->GetNetworks().size())); Table.SetCell("Clients", CString(it->second->GetAllClients().size())); } PutStatus(Table); } else if (m_pUser->IsAdmin() && sCommand.Equals("SetMOTD")) { CString sMessage = sLine.Token(1, true); if (sMessage.empty()) { PutStatus("Usage: SetMOTD <Message>"); } else { CZNC::Get().SetMotd(sMessage); PutStatus("MOTD set to [" + sMessage + "]"); } } else if (m_pUser->IsAdmin() && sCommand.Equals("AddMOTD")) { CString sMessage = sLine.Token(1, true); if (sMessage.empty()) { PutStatus("Usage: AddMOTD <Message>"); } else { CZNC::Get().AddMotd(sMessage); PutStatus("Added [" + sMessage + "] to MOTD"); } } else if (m_pUser->IsAdmin() && sCommand.Equals("ClearMOTD")) { CZNC::Get().ClearMotd(); PutStatus("Cleared MOTD"); } else if (m_pUser->IsAdmin() && sCommand.Equals("BROADCAST")) { CZNC::Get().Broadcast(sLine.Token(1, true)); } else if (m_pUser->IsAdmin() && (sCommand.Equals("SHUTDOWN") || sCommand.Equals("RESTART"))) { bool bRestart = sCommand.Equals("RESTART"); CString sMessage = sLine.Token(1, true); bool bForce = false; if (sMessage.Token(0).Equals("FORCE")) { bForce = true; sMessage = sMessage.Token(1, true); } if (sMessage.empty()) { sMessage = (bRestart ? "ZNC is being restarted NOW!" : "ZNC is being shut down NOW!"); } if(!CZNC::Get().WriteConfig() && !bForce) { PutStatus("ERROR: Writing config file to disk failed! Aborting. Use " + sCommand.AsUpper() + " FORCE to ignore."); } else { CZNC::Get().Broadcast(sMessage); throw CException(bRestart ? CException::EX_Restart : CException::EX_Shutdown); } } else if (sCommand.Equals("JUMP") || sCommand.Equals("CONNECT")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } if (!m_pNetwork->HasServers()) { PutStatus("You don't have any servers added."); return; } CString sArgs = sLine.Token(1, true); CServer *pServer = NULL; if (!sArgs.empty()) { pServer = m_pNetwork->FindServer(sArgs); if (!pServer) { PutStatus("Server [" + sArgs + "] not found"); return; } m_pNetwork->SetNextServer(pServer); // If we are already connecting to some server, // we have to abort that attempt Csock *pIRCSock = GetIRCSock(); if (pIRCSock && !pIRCSock->IsConnected()) { pIRCSock->Close(); } } if (GetIRCSock()) { GetIRCSock()->Quit(); if (pServer) PutStatus("Connecting to [" + pServer->GetName() + "]..."); else PutStatus("Jumping to the next server in the list..."); } else { if (pServer) PutStatus("Connecting to [" + pServer->GetName() + "]..."); else PutStatus("Connecting..."); } m_pNetwork->SetIRCConnectEnabled(true); return; } else if (sCommand.Equals("DISCONNECT")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } if (GetIRCSock()) { CString sQuitMsg = sLine.Token(1, true); GetIRCSock()->Quit(sQuitMsg); } m_pNetwork->SetIRCConnectEnabled(false); PutStatus("Disconnected from IRC. Use 'connect' to reconnect."); return; } else if (sCommand.Equals("ENABLECHAN")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1, true); if (sChan.empty()) { PutStatus("Usage: EnableChan <channel>"); } else { const vector<CChan*>& vChans = m_pNetwork->GetChans(); vector<CChan*>::const_iterator it; unsigned int uMatches = 0, uEnabled = 0; for (it = vChans.begin(); it != vChans.end(); ++it) { if (!(*it)->GetName().WildCmp(sChan)) continue; uMatches++; if (!(*it)->IsDisabled()) continue; uEnabled++; (*it)->Enable(); } PutStatus("There were [" + CString(uMatches) + "] channels matching [" + sChan + "]"); PutStatus("Enabled [" + CString(uEnabled) + "] channels"); } } else if (sCommand.Equals("LISTCHANS")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CUser* pUser = m_pUser; CIRCNetwork* pNetwork = m_pNetwork; const CString sNick = sLine.Token(1); const CString sNetwork = sLine.Token(2); if (!sNick.empty()) { if (!m_pUser->IsAdmin()) { PutStatus("Usage: ListChans"); return; } pUser = CZNC::Get().FindUser(sNick); if (!pUser) { PutStatus("No such user [" + sNick + "]"); return; } pNetwork = pUser->FindNetwork(sNetwork); if (!pNetwork) { PutStatus("No such network for user [" + sNetwork + "]"); return; } } const vector<CChan*>& vChans = pNetwork->GetChans(); CIRCSock* pIRCSock = pNetwork->GetIRCSock(); const CString& sPerms = (pIRCSock) ? pIRCSock->GetPerms() : ""; if (!vChans.size()) { PutStatus("There are no channels defined."); return; } CTable Table; Table.AddColumn("Name"); Table.AddColumn("Status"); Table.AddColumn("Conf"); Table.AddColumn("Buf"); Table.AddColumn("Modes"); Table.AddColumn("Users"); for (unsigned int p = 0; p < sPerms.size(); p++) { CString sPerm; sPerm += sPerms[p]; Table.AddColumn(sPerm); } unsigned int uNumDetached = 0, uNumDisabled = 0, uNumJoined = 0; for (unsigned int a = 0; a < vChans.size(); a++) { const CChan* pChan = vChans[a]; Table.AddRow(); Table.SetCell("Name", pChan->GetPermStr() + pChan->GetName()); Table.SetCell("Status", ((vChans[a]->IsOn()) ? ((vChans[a]->IsDetached()) ? "Detached" : "Joined") : ((vChans[a]->IsDisabled()) ? "Disabled" : "Trying"))); Table.SetCell("Conf", CString((pChan->InConfig()) ? "yes" : "")); Table.SetCell("Buf", CString((pChan->KeepBuffer()) ? "*" : "") + CString(pChan->GetBufferCount())); Table.SetCell("Modes", pChan->GetModeString()); Table.SetCell("Users", CString(pChan->GetNickCount())); map<char, unsigned int> mPerms = pChan->GetPermCounts(); for (unsigned int b = 0; b < sPerms.size(); b++) { char cPerm = sPerms[b]; Table.SetCell(CString(cPerm), CString(mPerms[cPerm])); } if(pChan->IsDetached()) uNumDetached++; if(pChan->IsOn()) uNumJoined++; if(pChan->IsDisabled()) uNumDisabled++; } PutStatus(Table); PutStatus("Total: " + CString(vChans.size()) + " - Joined: " + CString(uNumJoined) + " - Detached: " + CString(uNumDetached) + " - Disabled: " + CString(uNumDisabled)); } else if (sCommand.Equals("ADDNETWORK")) { #ifndef ENABLE_ADD_NETWORK if (!m_pUser->IsAdmin()) { PutStatus("Permission denied"); return; } #endif CString sNetwork = sLine.Token(1); if (sNetwork.empty()) { PutStatus("Usage: AddNetwork <name>"); return; } if (m_pUser->AddNetwork(sNetwork)) { PutStatus("Network added. Use /znc JumpNetwork " + sNetwork + ", or connect to ZNC with username " + m_pUser->GetUserName() + "/" + sNetwork + " (instead of just " + m_pUser->GetUserName() + ") to connect to it."); } else { PutStatus("Unable to add that network"); PutStatus("Perhaps that network is already added"); } } else if (m_pUser->IsAdmin() && sCommand.Equals("DELNETWORK")) { CString sNetwork = sLine.Token(1); if (sNetwork.empty()) { PutStatus("Usage: DelNetwork <name>"); return; } if (m_pNetwork && m_pNetwork->GetName().Equals(sNetwork)) { SetNetwork(NULL); } if (m_pUser->DeleteNetwork(sNetwork)) { PutStatus("Network deleted"); } else { PutStatus("Failed to delete network"); PutStatus("Perhaps this network doesn't exist"); } } else if (sCommand.Equals("LISTNETWORKS")) { CUser *pUser = m_pUser; if (m_pUser->IsAdmin() && !sLine.Token(1).empty()) { pUser = CZNC::Get().FindUser(sLine.Token(1)); if (!pUser) { PutStatus("User not found " + sLine.Token(1)); return; } } const vector<CIRCNetwork*>& vNetworks = pUser->GetNetworks(); CTable Table; Table.AddColumn("Network"); Table.AddColumn("OnIRC"); Table.AddColumn("IRC Server"); Table.AddColumn("IRC User"); Table.AddColumn("Channels"); for (unsigned int a = 0; a < vNetworks.size(); a++) { CIRCNetwork* pNetwork = vNetworks[a]; Table.AddRow(); Table.SetCell("Network", pNetwork->GetName()); if (pNetwork->IsIRCConnected()) { Table.SetCell("OnIRC", "Yes"); Table.SetCell("IRC Server", pNetwork->GetIRCServer()); Table.SetCell("IRC User", pNetwork->GetIRCNick().GetNickMask()); Table.SetCell("Channels", CString(pNetwork->GetChans().size())); } else { Table.SetCell("OnIRC", "No"); } } if (PutStatus(Table) == 0) { PutStatus("No networks"); } } else if (sCommand.Equals("JUMPNETWORK")) { CString sNetwork = sLine.Token(1); if (sNetwork.empty()) { PutStatus("No network supplied."); return; } if (m_pNetwork && (m_pNetwork->GetName() == sNetwork)) { PutStatus("You are already connected with this network."); return; } CIRCNetwork *pNetwork = m_pUser->FindNetwork(sNetwork); if (pNetwork) { PutStatus("Switched to " + sNetwork); SetNetwork(pNetwork); } else { PutStatus("You don't have a network named " + sNetwork); } } else if (sCommand.Equals("MODE")) { CString sNetwork = sLine.Token(1); if (sNetwork.empty()) { PutStatus("Syntax: MODE <support/default>"); return; } if (m_pNetwork && (m_pNetwork->GetName() == sNetwork)) { PutStatus("You are already in this mode."); return; } CIRCNetwork *pNetwork = m_pUser->FindNetwork(sNetwork); if (pNetwork) { PutStatus("You are now in " + sNetwork + " mode."); SetNetwork(pNetwork); } else { PutStatus("ERROR! Contact GeekBouncer admins immediately"); } } else if (m_pUser->IsAdmin() && sCommand.Equals("ADDSERVER")) { CString sServer = sLine.Token(1); if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } if (sServer.empty()) { PutStatus("Usage: AddServer <host> [[+]port] [pass]"); return; } if (m_pNetwork->AddServer(sLine.Token(1, true))) { PutStatus("Server added"); } else { PutStatus("Unable to add that server"); PutStatus("Perhaps the server is already added or openssl is disabled?"); } } else if (m_pUser->IsAdmin() && sCommand.Equals("REMSERVER") || sCommand.Equals("DELSERVER")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sServer = sLine.Token(1); unsigned short uPort = sLine.Token(2).ToUShort(); CString sPass = sLine.Token(3); if (sServer.empty()) { PutStatus("Usage: RemServer <host> [port] [pass]"); return; } if (!m_pNetwork->HasServers()) { PutStatus("You don't have any servers added."); return; } if (m_pNetwork->DelServer(sServer, uPort, sPass)) { PutStatus("Server removed"); } else { PutStatus("No such server"); } } else if (sCommand.Equals("LISTSERVERS")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } if (m_pNetwork->HasServers()) { const vector<CServer*>& vServers = m_pNetwork->GetServers(); CServer* pCurServ = m_pNetwork->GetCurrentServer(); CTable Table; Table.AddColumn("Host"); Table.AddColumn("Port"); Table.AddColumn("SSL"); Table.AddColumn("Pass"); for (unsigned int a = 0; a < vServers.size(); a++) { CServer* pServer = vServers[a]; Table.AddRow(); Table.SetCell("Host", pServer->GetName() + (pServer == pCurServ ? "*" : "")); Table.SetCell("Port", CString(pServer->GetPort())); Table.SetCell("SSL", (pServer->IsSSL()) ? "SSL" : ""); Table.SetCell("Pass", pServer->GetPass()); } PutStatus(Table); } else { PutStatus("You don't have any servers added."); } } else if (sCommand.Equals("TOPICS")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } const vector<CChan*>& vChans = m_pNetwork->GetChans(); CTable Table; Table.AddColumn("Name"); Table.AddColumn("Set By"); Table.AddColumn("Topic"); for (unsigned int a = 0; a < vChans.size(); a++) { CChan* pChan = vChans[a]; Table.AddRow(); Table.SetCell("Name", pChan->GetName()); Table.SetCell("Set By", pChan->GetTopicOwner()); Table.SetCell("Topic", pChan->GetTopic()); } PutStatus(Table); } else if (sCommand.Equals("LISTMODS") || sCommand.Equals("LISTMODULES")) { if (m_pUser->IsAdmin()) { CModules& GModules = CZNC::Get().GetModules(); if (!GModules.size()) { PutStatus("No global modules loaded."); } else { PutStatus("Global modules:"); CTable GTable; GTable.AddColumn("Name"); GTable.AddColumn("Arguments"); for (unsigned int b = 0; b < GModules.size(); b++) { GTable.AddRow(); GTable.SetCell("Name", GModules[b]->GetModName()); GTable.SetCell("Arguments", GModules[b]->GetArgs()); } PutStatus(GTable); } } CModules& Modules = m_pUser->GetModules(); if (!Modules.size()) { PutStatus("Your user has no modules loaded."); } else { PutStatus("User modules:"); CTable Table; Table.AddColumn("Name"); Table.AddColumn("Arguments"); for (unsigned int b = 0; b < Modules.size(); b++) { Table.AddRow(); Table.SetCell("Name", Modules[b]->GetModName()); Table.SetCell("Arguments", Modules[b]->GetArgs()); } PutStatus(Table); } if (m_pNetwork) { CModules& NetworkModules = m_pNetwork->GetModules(); if (NetworkModules.empty()) { PutStatus("This network has no modules loaded."); } else { PutStatus("Network modules:"); CTable Table; Table.AddColumn("Name"); Table.AddColumn("Arguments"); for (unsigned int b = 0; b < NetworkModules.size(); b++) { Table.AddRow(); Table.SetCell("Name", NetworkModules[b]->GetModName()); Table.SetCell("Arguments", NetworkModules[b]->GetArgs()); } PutStatus(Table); } } return; } else if (sCommand.Equals("LISTAVAILMODS") || sCommand.Equals("LISTAVAILABLEMODULES")) { if (m_pUser->DenyLoadMod()) { PutStatus("Access Denied."); return; } if (m_pUser->IsAdmin()) { set<CModInfo> ssGlobalMods; CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, CModInfo::GlobalModule); if (ssGlobalMods.empty()) { PutStatus("No global modules available."); } else { PutStatus("Global modules:"); CTable GTable; GTable.AddColumn("Name"); GTable.AddColumn("Description"); set<CModInfo>::iterator it; for (it = ssGlobalMods.begin(); it != ssGlobalMods.end(); ++it) { const CModInfo& Info = *it; GTable.AddRow(); GTable.SetCell("Name", (CZNC::Get().GetModules().FindModule(Info.GetName()) ? "*" : " ") + Info.GetName()); GTable.SetCell("Description", Info.GetDescription().Ellipsize(128)); } PutStatus(GTable); } } set<CModInfo> ssUserMods; CZNC::Get().GetModules().GetAvailableMods(ssUserMods); if (!ssUserMods.size()) { PutStatus("No user modules available."); } else { PutStatus("User modules:"); CTable Table; Table.AddColumn("Name"); Table.AddColumn("Description"); set<CModInfo>::iterator it; for (it = ssUserMods.begin(); it != ssUserMods.end(); ++it) { const CModInfo& Info = *it; Table.AddRow(); Table.SetCell("Name", (m_pUser->GetModules().FindModule(Info.GetName()) ? "*" : " ") + Info.GetName()); Table.SetCell("Description", Info.GetDescription().Ellipsize(128)); } PutStatus(Table); } set<CModInfo> ssNetworkMods; CZNC::Get().GetModules().GetAvailableMods(ssNetworkMods, CModInfo::NetworkModule); if (!ssNetworkMods.size()) { PutStatus("No network modules available."); } else { PutStatus("Network modules:"); CTable Table; Table.AddColumn("Name"); Table.AddColumn("Description"); set<CModInfo>::const_iterator it; for (it = ssNetworkMods.begin(); it != ssNetworkMods.end(); ++it) { const CModInfo& Info = *it; Table.AddRow(); Table.SetCell("Name", ((m_pNetwork && m_pNetwork->GetModules().FindModule(Info.GetName())) ? "*" : " ") + Info.GetName()); Table.SetCell("Description", Info.GetDescription().Ellipsize(128)); } PutStatus(Table); } return; } else if (sCommand.Equals("LOADMOD") || sCommand.Equals("LOADMODULE")) { CModInfo::EModuleType eType; CString sType = sLine.Token(1); CString sMod = sLine.Token(2); CString sArgs = sLine.Token(3, true); if (sType.Equals("global")) { eType = CModInfo::GlobalModule; } else if (sType.Equals("user")) { eType = CModInfo::UserModule; } else if (sType.Equals("network")) { eType = CModInfo::NetworkModule; } else { sMod = sType; sArgs = sLine.Token(2, true); sType = "default"; // Will be set correctly later eType = CModInfo::UserModule; } if (m_pUser->DenyLoadMod()) { PutStatus("Unable to load [" + sMod + "]: Access Denied."); return; } if (sMod.empty()) { PutStatus("Usage: LoadMod [type] <module> [args]"); return; } CModInfo ModInfo; CString sRetMsg; if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + "]"); return; } if (sType.Equals("default")) { eType = ModInfo.GetDefaultType(); } if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { PutStatus("Unable to load global module [" + sMod + "]: Access Denied."); return; } if (eType == CModInfo::NetworkModule && !m_pNetwork) { PutStatus("Unable to load network module [" + sMod + "] Not connected with a network."); return; } CString sModRet; bool b = false; switch (eType) { case CModInfo::GlobalModule: b = CZNC::Get().GetModules().LoadModule(sMod, sArgs, eType, NULL, NULL, sModRet); break; case CModInfo::UserModule: b = m_pUser->GetModules().LoadModule(sMod, sArgs, eType, m_pUser, NULL, sModRet); break; case CModInfo::NetworkModule: b = m_pNetwork->GetModules().LoadModule(sMod, sArgs, eType, m_pUser, m_pNetwork, sModRet); break; default: sModRet = "Unable to load module [" + sMod + "]: Unknown module type"; } if (b) sModRet = "Loaded module [" + sMod + "] " + sModRet; PutStatus(sModRet); return; } else if (sCommand.Equals("UNLOADMOD") || sCommand.Equals("UNLOADMODULE")) { CModInfo::EModuleType eType = CModInfo::UserModule; CString sType = sLine.Token(1); CString sMod = sLine.Token(2); if (sType.Equals("global")) { eType = CModInfo::GlobalModule; } else if (sType.Equals("user")) { eType = CModInfo::UserModule; } else if (sType.Equals("network")) { eType = CModInfo::NetworkModule; } else { sMod = sType; sType = "default"; } if (m_pUser->DenyLoadMod()) { PutStatus("Unable to unload [" + sMod + "] Access Denied."); return; } if (sMod.empty()) { PutStatus("Usage: UnloadMod [type] <module>"); return; } if (sType.Equals("default")) { CModInfo ModInfo; CString sRetMsg; if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + "]"); return; } eType = ModInfo.GetDefaultType(); } if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { PutStatus("Unable to unload global module [" + sMod + "]: Access Denied."); return; } if (eType == CModInfo::NetworkModule && !m_pNetwork) { PutStatus("Unable to unload network module [" + sMod + "] Not connected with a network."); return; } CString sModRet; switch (eType) { case CModInfo::GlobalModule: CZNC::Get().GetModules().UnloadModule(sMod, sModRet); break; case CModInfo::UserModule: m_pUser->GetModules().UnloadModule(sMod, sModRet); break; case CModInfo::NetworkModule: m_pNetwork->GetModules().UnloadModule(sMod, sModRet); break; default: sModRet = "Unable to unload module [" + sMod + "]: Unknown module type"; } PutStatus(sModRet); return; } else if (sCommand.Equals("RELOADMOD") || sCommand.Equals("RELOADMODULE")) { CModInfo::EModuleType eType; CString sType = sLine.Token(1); CString sMod = sLine.Token(2); CString sArgs = sLine.Token(3, true); if (m_pUser->DenyLoadMod()) { PutStatus("Unable to reload modules. Access Denied."); return; } if (sType.Equals("global")) { eType = CModInfo::GlobalModule; } else if (sType.Equals("user")) { eType = CModInfo::UserModule; } else if (sType.Equals("network")) { eType = CModInfo::NetworkModule; } else { sMod = sType; sArgs = sLine.Token(2, true); sType = "default"; // Will be set correctly later eType = CModInfo::UserModule; } if (sMod.empty()) { PutStatus("Usage: ReloadMod [type] <module> [args]"); return; } if (sType.Equals("default")) { CModInfo ModInfo; CString sRetMsg; if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { PutStatus("Unable to find modinfo for [" + sMod + "] [" + sRetMsg + "]"); return; } eType = ModInfo.GetDefaultType(); } if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { PutStatus("Unable to reload global module [" + sMod + "]: Access Denied."); return; } if (eType == CModInfo::NetworkModule && !m_pNetwork) { PutStatus("Unable to load network module [" + sMod + "] Not connected with a network."); return; } CString sModRet; switch (eType) { case CModInfo::GlobalModule: CZNC::Get().GetModules().ReloadModule(sMod, sArgs, NULL, NULL, sModRet); break; case CModInfo::UserModule: m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, NULL, sModRet); break; case CModInfo::NetworkModule: m_pNetwork->GetModules().ReloadModule(sMod, sArgs, m_pUser, m_pNetwork, sModRet); break; default: sModRet = "Unable to reload module [" + sMod + "]: Unknown module type"; } PutStatus(sModRet); return; } else if ((sCommand.Equals("UPDATEMOD") || sCommand.Equals("UPDATEMODULE")) && m_pUser->IsAdmin() ) { CString sMod = sLine.Token(1); if (sMod.empty()) { PutStatus("Usage: UpdateMod <module>"); return; } PutStatus("Reloading [" + sMod + "] everywhere"); if (CZNC::Get().UpdateModule(sMod)) { PutStatus("Done"); } else { PutStatus("Done, but there were errors, [" + sMod + "] could not be loaded everywhere."); } } else if ((sCommand.Equals("ADDBINDHOST") || sCommand.Equals("ADDVHOST")) && m_pUser->IsAdmin()) { CString sHost = sLine.Token(1); if (sHost.empty()) { PutStatus("Usage: AddBindHost <host>"); return; } if (CZNC::Get().AddBindHost(sHost)) { PutStatus("Done"); } else { PutStatus("The host [" + sHost + "] is already in the list"); } } else if ((sCommand.Equals("REMBINDHOST") || sCommand.Equals("REMVHOST") || sCommand.Equals("DELVHOST")) && m_pUser->IsAdmin()) { CString sHost = sLine.Token(1); if (sHost.empty()) { PutStatus("Usage: RemBindHost <host>"); return; } if (CZNC::Get().RemBindHost(sHost)) { PutStatus("Done"); } else { PutStatus("The host [" + sHost + "] is not in the list"); } } else if ((sCommand.Equals("LISTBINDHOSTS") || sCommand.Equals("LISTVHOSTS")) && (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { const VCString& vsHosts = CZNC::Get().GetBindHosts(); if (vsHosts.empty()) { PutStatus("No bind hosts configured"); return; } CTable Table; Table.AddColumn("Host"); VCString::const_iterator it; for (it = vsHosts.begin(); it != vsHosts.end(); ++it) { Table.AddRow(); Table.SetCell("Host", *it); } PutStatus(Table); } else if ((sCommand.Equals("SETBINDHOST") || sCommand.Equals("SETVHOST")) && (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { CString sHost = sLine.Token(1); if (sHost.empty()) { PutStatus("Usage: SetBindHost <host>"); return; } if (sHost.Equals(m_pUser->GetBindHost())) { PutStatus("You already have this bind host!"); return; } const VCString& vsHosts = CZNC::Get().GetBindHosts(); if (!m_pUser->IsAdmin() && !vsHosts.empty()) { VCString::const_iterator it; bool bFound = false; for (it = vsHosts.begin(); it != vsHosts.end(); ++it) { if (sHost.Equals(*it)) { bFound = true; break; } } if (!bFound) { PutStatus("You may not use this bind host. See [ListBindHosts] for a list"); return; } } m_pUser->SetBindHost(sHost); PutStatus("Set bind host to [" + m_pUser->GetBindHost() + "]"); } else if ((sCommand.Equals("CLEARBINDHOST") || sCommand.Equals("CLEARVHOST")) && (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { m_pUser->SetBindHost(""); PutStatus("Bind Host Cleared"); } else if (sCommand.Equals("PLAYBUFFER")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1); if (sChan.empty()) { PutStatus("Usage: PlayBuffer <#chan>"); return; } CChan* pChan = m_pNetwork->FindChan(sChan); if (!pChan) { PutStatus("You are not on [" + sChan + "]"); return; } if (!pChan->IsOn()) { PutStatus("You are not on [" + sChan + "] [trying]"); return; } if (pChan->GetBuffer().IsEmpty()) { PutStatus("The buffer for [" + sChan + "] is empty"); return; } pChan->SendBuffer(this); } else if (sCommand.Equals("CLEARBUFFER")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1); if (sChan.empty()) { PutStatus("Usage: ClearBuffer <#chan>"); return; } CChan* pChan = m_pNetwork->FindChan(sChan); if (!pChan) { PutStatus("You are not on [" + sChan + "]"); return; } const vector<CChan*>& vChans = m_pNetwork->GetChans(); vector<CChan*>::const_iterator it; unsigned int uMatches = 0; for (it = vChans.begin(); it != vChans.end(); ++it) { if (!(*it)->GetName().WildCmp(sChan)) continue; uMatches++; (*it)->ClearBuffer(); } PutStatus("The buffer for [" + CString(uMatches) + "] channels matching [" + sChan + "] has been cleared"); } else if (sCommand.Equals("CLEARALLCHANNELBUFFERS")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } vector<CChan*>::const_iterator it; const vector<CChan*>& vChans = m_pNetwork->GetChans(); for (it = vChans.begin(); it != vChans.end(); ++it) { (*it)->ClearBuffer(); } PutStatus("All channel buffers have been cleared"); } else if (sCommand.Equals("SETBUFFER")) { if (!m_pNetwork) { PutStatus("You must be connected with a network to use this command"); return; } CString sChan = sLine.Token(1); if (sChan.empty()) { PutStatus("Usage: SetBuffer <#chan> [linecount]"); return; } unsigned int uLineCount = sLine.Token(2).ToUInt(); const vector<CChan*>& vChans = m_pNetwork->GetChans(); vector<CChan*>::const_iterator it; unsigned int uMatches = 0, uFail = 0; for (it = vChans.begin(); it != vChans.end(); ++it) { if (!(*it)->GetName().WildCmp(sChan)) continue; uMatches++; if (!(*it)->SetBufferCount(uLineCount)) uFail++; } PutStatus("BufferCount for [" + CString(uMatches - uFail) + "] channels was set to [" + CString(uLineCount) + "]"); if (uFail > 0) { PutStatus("Setting BufferCount failed for [" + CString(uFail) + "] channels, " "max buffer count is " + CString(CZNC::Get().GetMaxBufferSize())); } } else if (m_pUser->IsAdmin() && sCommand.Equals("TRAFFIC")) { CZNC::TrafficStatsPair Users, ZNC, Total; CZNC::TrafficStatsMap traffic = CZNC::Get().GetTrafficStats(Users, ZNC, Total); CZNC::TrafficStatsMap::const_iterator it; CTable Table; Table.AddColumn("Username"); Table.AddColumn("In"); Table.AddColumn("Out"); Table.AddColumn("Total"); for (it = traffic.begin(); it != traffic.end(); ++it) { Table.AddRow(); Table.SetCell("Username", it->first); Table.SetCell("In", CString::ToByteStr(it->second.first)); Table.SetCell("Out", CString::ToByteStr(it->second.second)); Table.SetCell("Total", CString::ToByteStr(it->second.first + it->second.second)); } Table.AddRow(); Table.SetCell("Username", "<Users>"); Table.SetCell("In", CString::ToByteStr(Users.first)); Table.SetCell("Out", CString::ToByteStr(Users.second)); Table.SetCell("Total", CString::ToByteStr(Users.first + Users.second)); Table.AddRow(); Table.SetCell("Username", "<ZNC>"); Table.SetCell("In", CString::ToByteStr(ZNC.first)); Table.SetCell("Out", CString::ToByteStr(ZNC.second)); Table.SetCell("Total", CString::ToByteStr(ZNC.first + ZNC.second)); Table.AddRow(); Table.SetCell("Username", "<Total>"); Table.SetCell("In", CString::ToByteStr(Total.first)); Table.SetCell("Out", CString::ToByteStr(Total.second)); Table.SetCell("Total", CString::ToByteStr(Total.first + Total.second)); PutStatus(Table); } else if (sCommand.Equals("UPTIME")) { PutStatus("Running for " + CZNC::Get().GetUptime()); } else if (m_pUser->IsAdmin() && (sCommand.Equals("LISTPORTS") || sCommand.Equals("ADDPORT") || sCommand.Equals("DELPORT"))) { UserPortCommand(sLine); } else { PutStatus("Unknown command [" + sCommand + "] try 'Help'"); } }