mirror of
https://github.com/znc/znc.git
synced 2026-07-05 09:21:31 +02:00
Properly handle CIRCNetwork's when we rehash
This commit does the following: - Do not segfault on rehash - Delete CIRCNetwork's when they are removed from config - Update to the configs nick/altnick/realname/ident
This commit is contained in:
@@ -30,9 +30,11 @@ public:
|
||||
static bool IsValidNetwork(const CString& sNetwork);
|
||||
|
||||
CIRCNetwork(CUser *pUser, const CString& sName);
|
||||
CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneChans = true);
|
||||
CIRCNetwork(CUser *pUser, const CIRCNetwork& Network, bool bCloneChans = true);
|
||||
~CIRCNetwork();
|
||||
|
||||
void Clone(const CIRCNetwork& Network, bool bCloneChans = true);
|
||||
|
||||
CString GetNetworkPath();
|
||||
|
||||
void DelServers();
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public:
|
||||
bool DeleteNetwork(const CString& sNetwork);
|
||||
bool AddNetwork(CIRCNetwork *pNetwork);
|
||||
void RemoveNetwork(CIRCNetwork *pNetwork);
|
||||
CIRCNetwork* FindNetwork(const CString& sNetwork);
|
||||
CIRCNetwork* FindNetwork(const CString& sNetwork) const;
|
||||
const vector<CIRCNetwork*>& GetNetworks() const;
|
||||
// !Networks
|
||||
|
||||
|
||||
+47
-5
@@ -54,10 +54,9 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CString& sName) {
|
||||
m_QueryBuffer.SetLineCount(250, true);
|
||||
}
|
||||
|
||||
CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneChans) {
|
||||
CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork &Network, bool bCloneChans) {
|
||||
m_pUser = NULL;
|
||||
SetUser(pUser);
|
||||
m_sName = pNetwork->GetName();
|
||||
|
||||
m_pModules = new CModules;
|
||||
|
||||
@@ -71,8 +70,19 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneC
|
||||
m_MotdBuffer.SetLineCount(200, true); // This should be more than enough motd lines
|
||||
m_QueryBuffer.SetLineCount(250, true);
|
||||
|
||||
Clone(Network, bCloneChans);
|
||||
}
|
||||
|
||||
void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneChans) {
|
||||
m_sName = Network.GetName();
|
||||
|
||||
SetNick(Network.GetNick());
|
||||
SetAltNick(Network.GetAltNick());
|
||||
SetIdent(Network.GetIdent());
|
||||
SetRealName(Network.GetRealName());
|
||||
|
||||
// Servers
|
||||
const vector<CServer*>& vServers = pNetwork->GetServers();
|
||||
const vector<CServer*>& vServers = Network.GetServers();
|
||||
CString sServer;
|
||||
CServer* pCurServ = GetCurrentServer();
|
||||
|
||||
@@ -107,7 +117,7 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneC
|
||||
// !Servers
|
||||
|
||||
// Chans
|
||||
const vector<CChan*>& vChans = pNetwork->GetChans();
|
||||
const vector<CChan*>& vChans = Network.GetChans();
|
||||
for (a = 0; a < vChans.size(); a++) {
|
||||
CChan* pNewChan = vChans[a];
|
||||
CChan* pChan = FindChan(pNewChan->GetName());
|
||||
@@ -121,7 +131,7 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneC
|
||||
|
||||
for (a = 0; a < m_vChans.size(); a++) {
|
||||
CChan* pChan = m_vChans[a];
|
||||
CChan* pNewChan = pNetwork->FindChan(pChan->GetName());
|
||||
CChan* pNewChan = Network.FindChan(pChan->GetName());
|
||||
|
||||
if (!pNewChan) {
|
||||
pChan->SetInConfig(false);
|
||||
@@ -131,6 +141,38 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork *pNetwork, bool bCloneC
|
||||
}
|
||||
}
|
||||
// !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
|
||||
|
||||
}
|
||||
|
||||
CIRCNetwork::~CIRCNetwork() {
|
||||
|
||||
+34
-5
@@ -449,8 +449,8 @@ bool CUser::DeleteNetwork(const CString& sNetwork) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CIRCNetwork* CUser::FindNetwork(const CString& sNetwork) {
|
||||
for (vector<CIRCNetwork*>::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
|
||||
CIRCNetwork* CUser::FindNetwork(const CString& sNetwork) const {
|
||||
for (vector<CIRCNetwork*>::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
|
||||
CIRCNetwork *pNetwork = *it;
|
||||
if (pNetwork->GetName().Equals(sNetwork)) {
|
||||
return pNetwork;
|
||||
@@ -528,7 +528,7 @@ CString CUser::AddTimestamp(time_t tm, const CString& sStr) const {
|
||||
// The Control+O key combination in mIRC inserts ascii character 15,
|
||||
// which turns off all previous attributes, including color, bold, underline, and italics.
|
||||
sRet += "\x0F ";
|
||||
|
||||
|
||||
sRet += szTimestamp;
|
||||
}
|
||||
}
|
||||
@@ -616,8 +616,37 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) {
|
||||
|
||||
// Networks
|
||||
const vector<CIRCNetwork*>& vNetworks = User.GetNetworks();
|
||||
for (a = 0; a < vNetworks.size(); a++) {
|
||||
new CIRCNetwork(this, vNetworks[a], bCloneChans);
|
||||
for (vector<CIRCNetwork*>::const_iterator it = vNetworks.begin(); it != vNetworks.end(); ++it) {
|
||||
CIRCNetwork *pNetwork = FindNetwork((*it)->GetName());
|
||||
|
||||
if (pNetwork) {
|
||||
pNetwork->Clone(*(*it), bCloneChans);
|
||||
} else {
|
||||
new CIRCNetwork(this, *(*it), bCloneChans);
|
||||
}
|
||||
}
|
||||
|
||||
set<CString> ssDeleteNetworks;
|
||||
for (vector<CIRCNetwork*>::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
|
||||
if (!(User.FindNetwork((*it)->GetName()))) {
|
||||
ssDeleteNetworks.insert((*it)->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
for (set<CString>::const_iterator it = ssDeleteNetworks.begin(); it != ssDeleteNetworks.end(); ++it) {
|
||||
// The following will move all the clients to the user.
|
||||
// So the clients are not disconnected. The client could
|
||||
// have requested the rehash. Then when we do
|
||||
// client->PutStatus("Rehashing succeeded!") we would
|
||||
// crash if there was no client anymore.
|
||||
vector<CClient*>& vClients = FindNetwork(*it)->GetClients();
|
||||
|
||||
while (vClients.begin() != vClients.end()) {
|
||||
CClient *pClient = vClients.front();
|
||||
pClient->SetNetwork(NULL);
|
||||
}
|
||||
|
||||
DeleteNetwork(*it);
|
||||
}
|
||||
// !Networks
|
||||
|
||||
|
||||
Reference in New Issue
Block a user