From 01b15bfb5b8928b1f6e98383d3817e9d90b443f5 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Sun, 13 Nov 2011 00:18:43 +0000 Subject: [PATCH] Fix webadmin when editing a user Since this creates a new user, and then clones it. It would clear all the networks. To fix this, I have made an option bCloneNetworks to CUser::Clone. This replaces the bCloneChans because this is unnessecery now. Fixes #88 --- include/znc/IRCNetwork.h | 4 +-- include/znc/User.h | 2 +- src/IRCNetwork.cpp | 9 +++--- src/User.cpp | 65 ++++++++++++++++++++-------------------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index 9e5c2e55..82e36310 100644 --- a/include/znc/IRCNetwork.h +++ b/include/znc/IRCNetwork.h @@ -30,10 +30,10 @@ public: static bool IsValidNetwork(const CString& sNetwork); CIRCNetwork(CUser *pUser, const CString& sName); - CIRCNetwork(CUser *pUser, const CIRCNetwork& Network, bool bCloneChans = true); + CIRCNetwork(CUser *pUser, const CIRCNetwork& Network); ~CIRCNetwork(); - void Clone(const CIRCNetwork& Network, bool bCloneChans = true); + void Clone(const CIRCNetwork& Network); CString GetNetworkPath(); diff --git a/include/znc/User.h b/include/znc/User.h index 3646c5a6..68ac28b2 100644 --- a/include/znc/User.h +++ b/include/znc/User.h @@ -91,7 +91,7 @@ public: CString AddTimestamp(const CString& sStr) const; CString AddTimestamp(time_t tm, const CString& sStr) const; - bool Clone(const CUser& User, CString& sErrorRet, bool bCloneChans = true); + bool Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks = true); void BounceAllClients(); void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index f2a0b4e9..549ce3c2 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -54,7 +54,7 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CString& sName) { m_QueryBuffer.SetLineCount(250, true); } -CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork &Network, bool bCloneChans) { +CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork &Network) { m_pUser = NULL; SetUser(pUser); @@ -70,10 +70,10 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CIRCNetwork &Network, bool bCloneCh m_MotdBuffer.SetLineCount(200, true); // This should be more than enough motd lines m_QueryBuffer.SetLineCount(250, true); - Clone(Network, bCloneChans); + Clone(Network); } -void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneChans) { +void CIRCNetwork::Clone(const CIRCNetwork& Network) { m_sName = Network.GetName(); SetNick(Network.GetNick()); @@ -136,8 +136,7 @@ void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneChans) { if (!pNewChan) { pChan->SetInConfig(false); } else { - if (bCloneChans) - pChan->Clone(*pNewChan); + pChan->Clone(*pNewChan); } } // !Chans diff --git a/src/User.cpp b/src/User.cpp index 9cb5067d..f64d4bd1 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -563,7 +563,7 @@ void CUser::UserDisconnected(CClient* pClient) { } } -bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { +bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks) { unsigned int a = 0; sErrorRet.clear(); @@ -615,40 +615,41 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { // !Allowed Hosts // Networks - const vector& vNetworks = User.GetNetworks(); - for (vector::const_iterator it = vNetworks.begin(); it != vNetworks.end(); ++it) { - CIRCNetwork *pNetwork = FindNetwork((*it)->GetName()); + if (bCloneNetworks) { + const vector& vNetworks = User.GetNetworks(); + for (vector::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 ssDeleteNetworks; - for (vector::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) { - if (!(User.FindNetwork((*it)->GetName()))) { - ssDeleteNetworks.insert((*it)->GetName()); - } - } - - for (set::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& vClients = FindNetwork(*it)->GetClients(); - - while (vClients.begin() != vClients.end()) { - CClient *pClient = vClients.front(); - // This line will remove pClient from vClients, - // because it's a reference to the internal Network's vector. - pClient->SetNetwork(NULL); + if (pNetwork) { + pNetwork->Clone(*(*it)); + } else { + new CIRCNetwork(this, *(*it)); + } } - DeleteNetwork(*it); + set ssDeleteNetworks; + for (vector::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) { + if (!(User.FindNetwork((*it)->GetName()))) { + ssDeleteNetworks.insert((*it)->GetName()); + } + } + + for (set::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& vClients = FindNetwork(*it)->GetClients(); + + while (vClients.begin() != vClients.end()) { + CClient *pClient = vClients.front(); + // This line will remove pClient from vClients, + // because it's a reference to the internal Network's vector. + pClient->SetNetwork(NULL); + DeleteNetwork(*it); + } + } } // !Networks