mirror of
https://github.com/znc/znc.git
synced 2026-08-06 08:52:57 +02:00
Added preliminary support for multiple clients per user
git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@547 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
@@ -64,7 +64,7 @@ void CChan::Cycle() const {
|
||||
m_pUser->PutIRC("PART " + GetName() + "\r\nJOIN " + GetName() + " " + GetKey());
|
||||
}
|
||||
|
||||
void CChan::JoinUser(bool bForce, const CString& sKey) {
|
||||
void CChan::JoinUser(bool bForce, const CString& sKey, CUserSock* pUserSock) {
|
||||
if (!bForce && (!IsOn() || !IsDetached())) {
|
||||
IncClientRequests();
|
||||
|
||||
@@ -72,11 +72,11 @@ void CChan::JoinUser(bool bForce, const CString& sKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " JOIN :" + GetName());
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " JOIN :" + GetName(), pUserSock);
|
||||
|
||||
if (!GetTopic().empty()) {
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 332 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :" + GetTopic());
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 333 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " " + GetTopicOwner() + " " + CString::ToString(GetTopicDate()));
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 332 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :" + GetTopic(), pUserSock);
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 333 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " " + GetTopicOwner() + " " + CString::ToString(GetTopicDate()), pUserSock);
|
||||
}
|
||||
|
||||
CString sPre = ":" + m_pUser->GetIRCServer() + " 353 " + m_pUser->GetIRCNick().GetNick() + " = " + GetName() + " :";
|
||||
@@ -91,35 +91,32 @@ void CChan::JoinUser(bool bForce, const CString& sKey) {
|
||||
sLine += a->first;
|
||||
|
||||
if (sLine.size() >= 490 || a == (--m_msNicks.end())) {
|
||||
m_pUser->PutUser(sLine);
|
||||
m_pUser->PutUser(sLine, pUserSock);
|
||||
sLine = sPre;
|
||||
} else {
|
||||
sLine += " ";
|
||||
}
|
||||
}
|
||||
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 366 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :End of /NAMES list.");
|
||||
SendBuffer();
|
||||
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 366 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :End of /NAMES list.", pUserSock);
|
||||
m_bDetached = false;
|
||||
}
|
||||
|
||||
void CChan::SendBuffer() {
|
||||
// Send Buffer
|
||||
if (m_pUser->IsUserAttached()) {
|
||||
const vector<CString>& vsBuffer = GetBuffer();
|
||||
|
||||
if (vsBuffer.size()) {
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + GetName() + " :Buffer Playback...");
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + GetName() + " :Buffer Playback...", pUserSock);
|
||||
|
||||
for (unsigned int a = 0; a < vsBuffer.size(); a++) {
|
||||
m_pUser->PutUser(vsBuffer[a]);
|
||||
m_pUser->PutUser(vsBuffer[a], pUserSock);
|
||||
}
|
||||
|
||||
if (!KeepBuffer()) {
|
||||
ClearBuffer();
|
||||
}
|
||||
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + GetName() + " :Playback Complete.");
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + GetName() + " :Playback Complete.", pUserSock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Nick.h"
|
||||
#include "String.h"
|
||||
#include "FileUtils.h"
|
||||
#include "UserSock.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -48,10 +49,9 @@ public:
|
||||
bool WriteConfig(CFile& File);
|
||||
void Joined();
|
||||
void Cycle() const;
|
||||
void JoinUser(bool bForce = false, const CString& sKey = "");
|
||||
void JoinUser(bool bForce = false, const CString& sKey = "", CUserSock* pUserSock = NULL);
|
||||
void DetachUser();
|
||||
void AttachUser();
|
||||
void SendBuffer();
|
||||
|
||||
void IncClientRequests();
|
||||
bool DecClientRequests();
|
||||
|
||||
+50
-124
@@ -7,16 +7,12 @@
|
||||
|
||||
CIRCSock::CIRCSock(CUser* pUser) : Csock() {
|
||||
m_pUser = pUser;
|
||||
m_pUserSock = NULL;
|
||||
m_pAwayNickTimer = NULL;
|
||||
m_uQueryBufferCount = 50;
|
||||
m_bISpoofReleased = false;
|
||||
m_bKeepNick = true;
|
||||
m_bAuthed = false;
|
||||
m_bOrigNickPending = false;
|
||||
EnableReadLine();
|
||||
m_RawBuffer.SetLineCount(100); // This should be more than enough raws, especially since we are buffering the MOTD separately
|
||||
m_MotdBuffer.SetLineCount(200); // This should be more than enough motd lines
|
||||
m_Nick.SetIdent(pUser->GetIdent());
|
||||
m_Nick.SetHost(pUser->GetVHost());
|
||||
|
||||
@@ -41,10 +37,7 @@ CIRCSock::~CIRCSock() {
|
||||
vChans[a]->Reset();
|
||||
}
|
||||
|
||||
if (m_pUserSock) {
|
||||
m_pUserSock->IRCDisconnected();
|
||||
m_pUserSock = NULL;
|
||||
}
|
||||
m_pUser->IRCDisconnected();
|
||||
|
||||
for (map<CString, CChan*>::iterator a = m_msChans.begin(); a != m_msChans.end(); a++) {
|
||||
delete a->second;
|
||||
@@ -103,18 +96,22 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
m_bAuthed = true;
|
||||
m_pUser->PutStatus("Connected!");
|
||||
|
||||
if (m_pUserSock) {
|
||||
CString sClientNick = m_pUserSock->GetNick();
|
||||
vector<CUserSock*>& vUserSocks = m_pUser->GetUserSocks();
|
||||
|
||||
for (unsigned int a = 0; a < vUserSocks.size(); a++) {
|
||||
CUserSock* pUserSock = vUserSocks[a];
|
||||
CString sClientNick = pUserSock->GetNick();
|
||||
|
||||
if (sClientNick.CaseCmp(sNick) != 0) {
|
||||
// If they connected with a nick that doesn't match the one we got on irc, then we need to update them
|
||||
PutUser(":" + sClientNick + "!" + m_Nick.GetIdent() + "@" + m_Nick.GetHost() + " NICK :" + sNick);
|
||||
pUserSock->PutServ(":" + sClientNick + "!" + m_Nick.GetIdent() + "@" + m_Nick.GetHost() + " NICK :" + sNick);
|
||||
}
|
||||
}
|
||||
|
||||
SetNick(sNick);
|
||||
|
||||
m_RawBuffer.Clear();
|
||||
m_RawBuffer.AddLine(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
m_pUser->ClearRawBuffer();
|
||||
m_pUser->AddRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
|
||||
// Now that we are connected, we need to join our chans
|
||||
const vector<CChan*>& vChans = m_pUser->GetChans();
|
||||
@@ -140,18 +137,18 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
case 255: // client count
|
||||
case 265: // local users
|
||||
case 266: // global users
|
||||
m_RawBuffer.AddLine(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
m_pUser->AddRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
break;
|
||||
case 375: // begin motd
|
||||
m_MotdBuffer.Clear();
|
||||
m_pUser->ClearMotdBuffer();
|
||||
case 372: // motd
|
||||
case 376: // end motd
|
||||
m_MotdBuffer.AddLine(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
m_pUser->AddMotdBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
|
||||
break;
|
||||
case 471: // :irc.server.net 471 nick #chan :Cannot join channel (+l)
|
||||
case 473: // :irc.server.net 473 nick #chan :Cannot join channel (+i)
|
||||
case 475: // :irc.server.net 475 nick #chan :Cannot join channel (+k)
|
||||
if (m_pUserSock) {
|
||||
if (m_pUser->IsUserAttached()) {
|
||||
CChan* pChan = m_pUser->FindChan(sRest.substr(0, sRest.find(' ')));
|
||||
|
||||
if ((pChan) && (!pChan->IsOn())) {
|
||||
@@ -207,9 +204,15 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
// :irc.server.net 433 mynick badnick :Nickname is already in use.
|
||||
if ((m_bKeepNick) && (m_pUser->GetKeepNick())) {
|
||||
if (sBadNick.CaseCmp(sConfNick) == 0) {
|
||||
if ((!m_pUserSock) || (!m_pUserSock->DecKeepNickCounter())) {
|
||||
SetOrigNickPending(false);
|
||||
return;
|
||||
vector<CUserSock*>& vUserSocks = m_pUser->GetUserSocks();
|
||||
|
||||
for (unsigned int a = 0; a < vUserSocks.size(); a++) {
|
||||
CUserSock* pUserSock = vUserSocks[a];
|
||||
|
||||
if (!pUserSock || !pUserSock->DecKeepNickCounter()) {
|
||||
SetOrigNickPending(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,27 +314,27 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
break;
|
||||
case 366: { // end of names list
|
||||
PutUser(sLine); // First send them the raw
|
||||
m_pUser->PutUser(sLine); // First send them the raw
|
||||
|
||||
// :irc.server.com 366 nick #chan :End of /NAMES list.
|
||||
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
|
||||
|
||||
if (pChan) {
|
||||
if (IsUserAttached()) {
|
||||
if (m_pUser->IsUserAttached()) {
|
||||
const vector<CString>& vsBuffer = pChan->GetBuffer();
|
||||
|
||||
if (vsBuffer.size()) {
|
||||
PutUser(":***!znc@znc.com PRIVMSG " + pChan->GetName() + " :Buffer Playback...");
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + pChan->GetName() + " :Buffer Playback...");
|
||||
|
||||
for (unsigned int a = 0; a < vsBuffer.size(); a++) {
|
||||
PutUser(vsBuffer[a]);
|
||||
m_pUser->PutUser(vsBuffer[a]);
|
||||
}
|
||||
|
||||
if (!pChan->KeepBuffer()) {
|
||||
pChan->ClearBuffer();
|
||||
}
|
||||
|
||||
PutUser(":***!znc@znc.com PRIVMSG " + pChan->GetName() + " :Playback Complete.");
|
||||
m_pUser->PutUser(":***!znc@znc.com PRIVMSG " + pChan->GetName() + " :Playback Complete.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,7 +530,7 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
}
|
||||
|
||||
PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :\001" + sMsg + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :\001" + sMsg + "\001");
|
||||
return;
|
||||
} else {
|
||||
if (sTarget.CaseCmp(GetNick()) == 0) {
|
||||
@@ -541,7 +544,7 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
}
|
||||
|
||||
PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :" + sMsg);
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :" + sMsg);
|
||||
return;
|
||||
} else if (sCmd.CaseCmp("TOPIC") == 0) {
|
||||
// :nick!ident@host.com TOPIC #chan :This is a topic
|
||||
@@ -551,7 +554,7 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
CString sTopic = sLine.Token(3, true);
|
||||
sTopic.LeftChomp();
|
||||
pChan->SetTopicOwner(Nick.GetNick());
|
||||
pChan->SetTopicDate((unsigned long) time(NULL)); // @todo use local time
|
||||
pChan->SetTopicDate((unsigned long) time(NULL));
|
||||
pChan->SetTopic(sTopic);
|
||||
}
|
||||
} else if (sCmd.CaseCmp("PRIVMSG") == 0) {
|
||||
@@ -577,7 +580,7 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
}
|
||||
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sMsg + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sMsg + "\001");
|
||||
return;
|
||||
} else {
|
||||
if (sTarget.CaseCmp(GetNick()) == 0) {
|
||||
@@ -590,14 +593,14 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
}
|
||||
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg);
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PutUser(sLine);
|
||||
m_pUser->PutUser(sLine);
|
||||
}
|
||||
|
||||
void CIRCSock::KeepNick(bool bForce) {
|
||||
@@ -628,26 +631,26 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
unsigned long uFileSize = strtoul(sMessage.Token(5).c_str(), NULL, 10);
|
||||
|
||||
if (sType.CaseCmp("CHAT") == 0) {
|
||||
if (m_pUserSock) {
|
||||
if (m_pUser->IsUserAttached()) {
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP));
|
||||
|
||||
if (uBNCPort) {
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString::ToString(CUtils::GetLongIP(GetLocalIP())) + " " + CString::ToString(uBNCPort) + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString::ToString(CUtils::GetLongIP(GetLocalIP())) + " " + CString::ToString(uBNCPort) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.CaseCmp("SEND") == 0) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC SEND " + sFile + " " + CString::ToString(CUtils::GetLongIP(GetLocalIP())) + " " + CString::ToString(uBNCPort) + " " + CString::ToString(uFileSize) + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC SEND " + sFile + " " + CString::ToString(CUtils::GetLongIP(GetLocalIP())) + " " + CString::ToString(uBNCPort) + " " + CString::ToString(uFileSize) + "\001");
|
||||
}
|
||||
} else if (sType.CaseCmp("RESUME") == 0) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
CDCCBounce* pSock = (CDCCBounce*) CZNC::Get().GetManager().FindSockByLocalPort(atoi(sMessage.Token(3).c_str()));
|
||||
|
||||
if ((pSock) && (strncasecmp(pSock->GetSockName().c_str(), "DCC::", 5) == 0)) {
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString::ToString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString::ToString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
} else if (sType.CaseCmp("ACCEPT") == 0) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
@@ -658,7 +661,7 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
|
||||
if ((pSock) && (strncasecmp(pSock->GetSockName().c_str(), "DCC::", 5) == 0)) {
|
||||
if (pSock->GetUserPort() == atoi(sMessage.Token(3).c_str())) {
|
||||
PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString::ToString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString::ToString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -675,7 +678,7 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
sReply = it->second;
|
||||
}
|
||||
|
||||
if (sReply.empty() && sQuery == "VERSION" && !IsUserAttached()) {
|
||||
if (sReply.empty() && sQuery == "VERSION" && !m_pUser->IsUserAttached()) {
|
||||
sReply = "ZNC by prozac - http://znc.sourceforge.net";
|
||||
}
|
||||
|
||||
@@ -691,9 +694,9 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
bool CIRCSock::OnPrivNotice(CNick& Nick, CString& sMessage) {
|
||||
MODULECALL(OnPrivNotice(Nick, sMessage));
|
||||
|
||||
if (!m_pUserSock) {
|
||||
if (!m_pUser->IsUserAttached()) {
|
||||
// If the user is detached, add to the buffer
|
||||
m_QueryBuffer.AddLine(":" + Nick.GetNickMask() + " NOTICE ", " :" + sMessage);
|
||||
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " NOTICE ", " :" + sMessage);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -702,9 +705,9 @@ bool CIRCSock::OnPrivNotice(CNick& Nick, CString& sMessage) {
|
||||
bool CIRCSock::OnPrivMsg(CNick& Nick, CString& sMessage) {
|
||||
MODULECALL(OnPrivMsg(Nick, sMessage));
|
||||
|
||||
if (!m_pUserSock) {
|
||||
if (!m_pUser->IsUserAttached()) {
|
||||
// If the user is detached, add to the buffer
|
||||
m_QueryBuffer.AddLine(":" + Nick.GetNickMask() + " PRIVMSG ", " :" + sMessage);
|
||||
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " PRIVMSG ", " :" + sMessage);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -728,7 +731,7 @@ bool CIRCSock::OnChanNotice(CNick& Nick, const CString& sChan, CString& sMessage
|
||||
if (pChan) {
|
||||
MODULECALL(OnChanNotice(Nick, *pChan, sMessage));
|
||||
|
||||
if ((pChan->KeepBuffer()) || (!m_pUserSock)) {
|
||||
if ((pChan->KeepBuffer()) || (!m_pUser->IsUserAttached())) {
|
||||
pChan->AddBuffer(":" + Nick.GetNickMask() + " NOTICE " + sChan + " :" + sMessage);
|
||||
}
|
||||
}
|
||||
@@ -741,7 +744,7 @@ bool CIRCSock::OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage) {
|
||||
if (pChan) {
|
||||
MODULECALL(OnChanMsg(Nick, *pChan, sMessage));
|
||||
|
||||
if ((pChan->KeepBuffer()) || (!m_pUserSock)) {
|
||||
if (pChan->KeepBuffer() || !m_pUser->IsUserAttached()) {
|
||||
pChan->AddBuffer(":" + Nick.GetNickMask() + " PRIVMSG " + sChan + " :" + sMessage);
|
||||
}
|
||||
}
|
||||
@@ -749,98 +752,19 @@ bool CIRCSock::OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage) {
|
||||
return ((pChan) && (pChan->IsDetached()));
|
||||
}
|
||||
|
||||
void CIRCSock::UserConnected(CUserSock* pUserSock) {
|
||||
if (m_pUserSock) {
|
||||
m_pUserSock->BouncedOff();
|
||||
}
|
||||
|
||||
m_pUserSock = pUserSock;
|
||||
CString sConfNick = m_pUser->GetNick();
|
||||
|
||||
if (GetNick().CaseCmp(CNick::Concat(sConfNick, m_pUser->GetAwaySuffix(), GetMaxNickLen())) == 0) {
|
||||
PutServ("NICK " + sConfNick);
|
||||
}
|
||||
|
||||
if (m_RawBuffer.IsEmpty()) {
|
||||
PutUser(":irc.znc.com 001 " + m_pUserSock->GetNick() + " :- Welcome to ZNC -");
|
||||
} else {
|
||||
unsigned int uIdx = 0;
|
||||
CString sLine;
|
||||
|
||||
while (m_RawBuffer.GetLine(GetNick(), sLine, uIdx++)) {
|
||||
PutUser(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the cached MOTD
|
||||
if (m_MotdBuffer.IsEmpty()) {
|
||||
PutServ("MOTD");
|
||||
} else {
|
||||
unsigned int uIdx = 0;
|
||||
CString sLine;
|
||||
|
||||
while (m_MotdBuffer.GetLine(GetNick(), sLine, uIdx++)) {
|
||||
PutUser(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
const vector<CChan*>& vChans = m_pUser->GetChans();
|
||||
for (unsigned int a = 0; a < vChans.size(); a++) {
|
||||
if ((vChans[a]->IsOn()) && (!vChans[a]->IsDetached())) {
|
||||
vChans[a]->JoinUser(true);
|
||||
}
|
||||
}
|
||||
|
||||
CString sBufLine;
|
||||
while (m_QueryBuffer.GetNextLine(GetNick(), sBufLine)) {
|
||||
PutUser(sBufLine);
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::UserDisconnected() {
|
||||
if (m_pUserSock && !m_pAwayNickTimer) {
|
||||
m_pAwayNickTimer = new CAwayNickTimer(m_pUser);
|
||||
CZNC::Get().GetManager().AddCron(m_pAwayNickTimer);
|
||||
}
|
||||
|
||||
m_pUserSock = NULL;
|
||||
}
|
||||
|
||||
void CIRCSock::PutServ(const CString& sLine) {
|
||||
DEBUG_ONLY(cout << GetSockName() << " -> [" << sLine << "]" << endl);
|
||||
Write(sLine + "\r\n");
|
||||
}
|
||||
|
||||
void CIRCSock::PutUser(const CString& sLine) {
|
||||
if (m_pUserSock) {
|
||||
m_pUserSock->PutServ(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::PutStatus(const CString& sLine) {
|
||||
if (m_pUserSock) {
|
||||
m_pUserSock->PutStatus(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::SetNick(const CString& sNick) {
|
||||
m_Nick.SetNick(sNick);
|
||||
m_pUser->SetIRCNick(m_Nick);
|
||||
|
||||
if (m_pUserSock) {
|
||||
m_pUserSock->SetNick(sNick);
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::Connected() {
|
||||
DEBUG_ONLY(cout << GetSockName() << " == Connected()" << endl);
|
||||
|
||||
CUserSock* pUserSock = (CUserSock*) CZNC::Get().FindSockByName("USR::" + m_pUser->GetUserName());
|
||||
|
||||
if (pUserSock) {
|
||||
m_pUserSock = pUserSock;
|
||||
pUserSock->IRCConnected(this);
|
||||
}
|
||||
m_pUser->IRCConnected(this);
|
||||
|
||||
if (!m_sPass.empty()) {
|
||||
PutServ("PASS " + m_sPass);
|
||||
@@ -889,7 +813,9 @@ void CIRCSock::ParseISupport(const CString& sLine) {
|
||||
m_sPerms = sPrefixes;
|
||||
m_sPermModes = sPermModes;
|
||||
}
|
||||
} else if (sName.CaseCmp("CHANMODES") == 0) {
|
||||
} else if (sName.CaseCmp("CHANTYPES") == 0) {
|
||||
m_pUser->SetChanPrefixes(sValue);
|
||||
} else if (sName.CaseCmp("NICKLEN") == 0) {
|
||||
unsigned int uMax = sValue.ToUInt();
|
||||
|
||||
if (uMax) {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
// Forward Declarations
|
||||
class CZNC;
|
||||
class CUserSock;
|
||||
class CAwayNickTimer;
|
||||
// !Forward Declarations
|
||||
|
||||
@@ -42,12 +41,7 @@ public:
|
||||
virtual void Timeout();
|
||||
|
||||
void KeepNick(bool bForce = false);
|
||||
bool IsUserAttached() { return (m_pUserSock != NULL); }
|
||||
void UserConnected(CUserSock* pUserSock);
|
||||
void UserDisconnected();
|
||||
void PutServ(const CString& sLine);
|
||||
void PutUser(const CString& sLine);
|
||||
void PutStatus(const CString& sLine);
|
||||
void CIRCSock::ParseISupport(const CString& sLine);
|
||||
|
||||
// Setters
|
||||
@@ -84,14 +78,9 @@ protected:
|
||||
CUser* m_pUser;
|
||||
CNick m_Nick;
|
||||
CString m_sPass;
|
||||
CBuffer m_RawBuffer;
|
||||
CBuffer m_MotdBuffer;
|
||||
CUserSock* m_pUserSock;
|
||||
map<CString, CChan*> m_msChans;
|
||||
unsigned int m_uMaxNickLen;
|
||||
unsigned int m_uQueryBufferCount;
|
||||
CAwayNickTimer* m_pAwayNickTimer;
|
||||
CBuffer m_QueryBuffer;
|
||||
};
|
||||
|
||||
#endif // !_IRCSOCK_H
|
||||
|
||||
+7
-4
@@ -164,6 +164,7 @@ CModule::CModule(void* pDLL, CUser* pUser, const CString& sModName) {
|
||||
m_pDLL = pDLL;
|
||||
m_pManager = &(CZNC::Get().GetManager());;
|
||||
m_pUser = pUser;
|
||||
m_pUserSock = NULL;
|
||||
m_sModName = sModName;
|
||||
|
||||
if (m_pUser) {
|
||||
@@ -177,6 +178,7 @@ CModule::CModule(void* pDLL, const CString& sModName) {
|
||||
m_pDLL = pDLL;
|
||||
m_pManager = &(CZNC::Get().GetManager());
|
||||
m_pUser = NULL;
|
||||
m_pUserSock = NULL;
|
||||
m_sModName = sModName;
|
||||
|
||||
m_sSavePath = CZNC::Get().GetZNCPath() + "/moddata/" + m_sModName;
|
||||
@@ -196,6 +198,7 @@ CModule::~CModule() {
|
||||
}
|
||||
|
||||
void CModule::SetUser(CUser* pUser) { m_pUser = pUser; }
|
||||
void CModule::SetUserSock(CUserSock* pUserSock) { m_pUserSock = pUserSock; }
|
||||
void CModule::Unload() { throw UNLOAD; }
|
||||
|
||||
bool CModule::LoadRegistry() {
|
||||
@@ -478,16 +481,16 @@ bool CModule::PutIRC(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutIRC(sLine) : false;
|
||||
}
|
||||
bool CModule::PutUser(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutUser(sLine) : false;
|
||||
return (m_pUser) ? m_pUser->PutUser(sLine, m_pUserSock) : false;
|
||||
}
|
||||
bool CModule::PutStatus(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutStatus(sLine) : false;
|
||||
return (m_pUser) ? m_pUser->PutStatus(sLine, m_pUserSock) : false;
|
||||
}
|
||||
bool CModule::PutModule(const CString& sLine, const CString& sIdent, const CString& sHost) {
|
||||
return (m_pUser) ? m_pUser->PutUser(":" + GetModNick() + "!" + sIdent + "@" + sHost + " PRIVMSG " + m_pUser->GetCurNick() + " :" + sLine) : false;
|
||||
return (m_pUser) ? m_pUser->PutUser(":" + GetModNick() + "!" + sIdent + "@" + sHost + " PRIVMSG " + m_pUser->GetCurNick() + " :" + sLine, m_pUserSock) : false;
|
||||
}
|
||||
bool CModule::PutModNotice(const CString& sLine, const CString& sIdent, const CString& sHost) {
|
||||
return (m_pUser) ? m_pUser->PutUser(":" + GetModNick() + "!" + sIdent + "@" + sHost + " NOTICE " + m_pUser->GetCurNick() + " :" + sLine) : false;
|
||||
return (m_pUser) ? m_pUser->PutUser(":" + GetModNick() + "!" + sIdent + "@" + sHost + " NOTICE " + m_pUser->GetCurNick() + " :" + sLine, m_pUserSock) : false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "main.h"
|
||||
#include "FileUtils.h"
|
||||
#include "UserSock.h"
|
||||
#include <dlfcn.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
@@ -192,6 +193,7 @@ public:
|
||||
} EModException;
|
||||
|
||||
void SetUser(CUser* pUser);
|
||||
void SetUserSock(CUserSock* pUserSock);
|
||||
void Unload();
|
||||
|
||||
virtual bool OnLoad(const CString& sArgs);
|
||||
@@ -290,6 +292,7 @@ public:
|
||||
const CString& GetDescription() const { return m_sDescription; }
|
||||
const CString& GetArgs() const { return m_sArgs; }
|
||||
CUser* GetUser() { return m_pUser; }
|
||||
CUserSock* GetUserSock() { return m_pUserSock; }
|
||||
TSocketManager<Csock>* GetManager() { return m_pManager; }
|
||||
// !Getters
|
||||
|
||||
@@ -301,6 +304,7 @@ protected:
|
||||
void* m_pDLL;
|
||||
TSocketManager<Csock>* m_pManager;
|
||||
CUser* m_pUser;
|
||||
CUserSock* m_pUserSock;
|
||||
CString m_sModName;
|
||||
CString m_sSavePath;
|
||||
CString m_sArgs;
|
||||
|
||||
@@ -19,6 +19,8 @@ CUser::CUser(const CString& sUserName) {
|
||||
#ifdef _MODULES
|
||||
m_pModules = new CModules;
|
||||
#endif
|
||||
m_RawBuffer.SetLineCount(100); // This should be more than enough raws, especially since we are buffering the MOTD separately
|
||||
m_MotdBuffer.SetLineCount(200); // This should be more than enough motd lines
|
||||
m_bBounceDCCs = true;
|
||||
m_bPassHashed = false;
|
||||
m_bUseClientIP = false;
|
||||
@@ -26,6 +28,7 @@ CUser::CUser(const CString& sUserName) {
|
||||
m_bDenyLoadMod = false;
|
||||
m_bAdmin= false;
|
||||
m_sStatusPrefix = "*";
|
||||
m_sChanPrefixes = "#&";
|
||||
m_uBufferCount = 50;
|
||||
m_bKeepBuffer = false;
|
||||
m_bAutoCycle = true;
|
||||
@@ -49,6 +52,10 @@ CUser::~CUser() {
|
||||
delete m_vChans[b];
|
||||
}
|
||||
|
||||
for (unsigned int c = 0; c < m_vUserSocks.size(); c++) {
|
||||
CZNC::Get().GetManager().DelSockByAddr(m_vUserSocks[c]);
|
||||
}
|
||||
|
||||
CZNC::Get().GetManager().DelCronByAddr(m_pKeepNickTimer);
|
||||
CZNC::Get().GetManager().DelCronByAddr(m_pJoinTimer);
|
||||
}
|
||||
@@ -60,6 +67,84 @@ bool CUser::OnBoot() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CUser::IRCConnected(CIRCSock* pIRCSock) {
|
||||
TSocketManager<Csock>& Manager = CZNC::Get().GetManager();
|
||||
|
||||
for (unsigned int a = 0; a < Manager.size(); a++) {
|
||||
CUserSock* pUserSock = (CUserSock*) Manager[a];
|
||||
const CString& sSockName = pUserSock->GetSockName();
|
||||
|
||||
if (sSockName == ("USR::" + GetUserName())) {
|
||||
m_vUserSocks.push_back(pUserSock);
|
||||
pUserSock->IRCConnected(pIRCSock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::IRCDisconnected() {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
m_vUserSocks[a]->IRCDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::UserConnected(CUserSock* pUserSock) {
|
||||
m_vUserSocks.push_back(pUserSock);
|
||||
CString sConfNick = GetNick();
|
||||
|
||||
/*if (ircsock.Nick().CaseCmp(CNick::Concat(sConfNick, GetAwaySuffix(), GetMaxNickLen())) == 0) {
|
||||
PutIRC("NICK " + sConfNick);
|
||||
} nigs */
|
||||
|
||||
if (m_RawBuffer.IsEmpty()) {
|
||||
pUserSock->PutServ(":irc.znc.com 001 " + pUserSock->GetNick() + " :- Welcome to ZNC -");
|
||||
} else {
|
||||
unsigned int uIdx = 0;
|
||||
CString sLine;
|
||||
|
||||
while (m_RawBuffer.GetLine(GetNick(), sLine, uIdx++)) {
|
||||
pUserSock->PutServ(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the cached MOTD
|
||||
if (m_MotdBuffer.IsEmpty()) {
|
||||
PutIRC("MOTD");
|
||||
} else {
|
||||
unsigned int uIdx = 0;
|
||||
CString sLine;
|
||||
|
||||
while (m_MotdBuffer.GetLine(GetNick(), sLine, uIdx++)) {
|
||||
pUserSock->PutServ(sLine);
|
||||
}
|
||||
}
|
||||
|
||||
const vector<CChan*>& vChans = GetChans();
|
||||
for (unsigned int a = 0; a < vChans.size(); a++) {
|
||||
if ((vChans[a]->IsOn()) && (!vChans[a]->IsDetached())) {
|
||||
vChans[a]->JoinUser(true, "", pUserSock);
|
||||
}
|
||||
}
|
||||
|
||||
CString sBufLine;
|
||||
while (m_QueryBuffer.GetNextLine(GetNick(), sBufLine)) {
|
||||
pUserSock->PutServ(sBufLine);
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::UserDisconnected(CUserSock* pUserSock) {
|
||||
/*if (!m_pAwayNickTimer) {
|
||||
m_pAwayNickTimer = new CAwayNickTimer(this);
|
||||
CZNC::Get().GetManager().AddCron(m_pAwayNickTimer);
|
||||
}*/
|
||||
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
if (m_vUserSocks[a] == pUserSock) {
|
||||
m_vUserSocks.erase(m_vUserSocks.begin() + a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CUser::Clone(const CUser& User, CString& sErrorRet) {
|
||||
unsigned int a = 0;
|
||||
sErrorRet.clear();
|
||||
@@ -99,8 +184,9 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet) {
|
||||
AddAllowedHost(*it);
|
||||
}
|
||||
|
||||
CUserSock* pSock = GetUserSock();
|
||||
if (pSock) {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
CUserSock* pSock = m_vUserSocks[a];
|
||||
|
||||
if (!IsHostAllowed(pSock->GetRemoteIP())) {
|
||||
pSock->PutStatusNotice("You are being disconnected because your IP is no longer allowed to connect to this user");
|
||||
pSock->Close();
|
||||
@@ -540,7 +626,7 @@ bool CUser::CheckPass(const CString& sPass) {
|
||||
return (m_sPass.CaseCmp((char*) CMD5(sPass)) == 0);
|
||||
}
|
||||
|
||||
CUserSock* CUser::GetUserSock() {
|
||||
/*CUserSock* CUser::GetUserSock() {
|
||||
// Todo: optimize this by saving a pointer to the sock
|
||||
TSocketManager<Csock>& Manager = CZNC::Get().GetManager();
|
||||
CString sSockName = "USR::" + m_sUserName;
|
||||
@@ -555,17 +641,7 @@ CUserSock* CUser::GetUserSock() {
|
||||
}
|
||||
|
||||
return (CUserSock*) CZNC::Get().GetManager().FindSockByName(sSockName);
|
||||
}
|
||||
|
||||
bool CUser::IsUserAttached() {
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
|
||||
if (!pUserSock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pUserSock->IsAttached();
|
||||
}
|
||||
}*/
|
||||
|
||||
CIRCSock* CUser::GetIRCSock() {
|
||||
// Todo: optimize this by saving a pointer to the sock
|
||||
@@ -579,10 +655,8 @@ CString CUser::GetLocalIP() {
|
||||
return pIRCSock->GetLocalIP();
|
||||
}
|
||||
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
|
||||
if (pUserSock) {
|
||||
return pUserSock->GetLocalIP();
|
||||
if (m_vUserSocks.size()) {
|
||||
return m_vUserSocks[0]->GetLocalIP();
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -599,48 +673,60 @@ bool CUser::PutIRC(const CString& sLine) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUser::PutUser(const CString& sLine) {
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
bool CUser::PutUser(const CString& sLine, CUserSock* pUserSock) {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
if (!pUserSock || pUserSock == m_vUserSocks[a]) {
|
||||
m_vUserSocks[a]->PutServ(sLine);
|
||||
|
||||
if (!pUserSock) {
|
||||
return false;
|
||||
if (pUserSock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pUserSock->PutServ(sLine);
|
||||
return true;
|
||||
return (pUserSock == NULL);
|
||||
}
|
||||
|
||||
bool CUser::PutStatus(const CString& sLine) {
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
bool CUser::PutStatus(const CString& sLine, CUserSock* pUserSock) {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
if (!pUserSock || pUserSock == m_vUserSocks[a]) {
|
||||
m_vUserSocks[a]->PutStatus(sLine);
|
||||
|
||||
if (!pUserSock) {
|
||||
return false;
|
||||
if (pUserSock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pUserSock->PutStatus(sLine);
|
||||
return true;
|
||||
return (pUserSock == NULL);
|
||||
}
|
||||
|
||||
bool CUser::PutStatusNotice(const CString& sLine) {
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
bool CUser::PutStatusNotice(const CString& sLine, CUserSock* pUserSock) {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
if (!pUserSock || pUserSock == m_vUserSocks[a]) {
|
||||
m_vUserSocks[a]->PutStatusNotice(sLine);
|
||||
|
||||
if (!pUserSock) {
|
||||
return false;
|
||||
if (pUserSock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pUserSock->PutStatusNotice(sLine);
|
||||
return true;
|
||||
return (pUserSock == NULL);
|
||||
}
|
||||
|
||||
bool CUser::PutModule(const CString& sModule, const CString& sLine) {
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
bool CUser::PutModule(const CString& sModule, const CString& sLine, CUserSock* pUserSock) {
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
if (!pUserSock || pUserSock == m_vUserSocks[a]) {
|
||||
m_vUserSocks[a]->PutModule(sModule, sLine);
|
||||
|
||||
if (!pUserSock) {
|
||||
return false;
|
||||
if (pUserSock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pUserSock->PutModule(sModule, sLine);
|
||||
return true;
|
||||
return (pUserSock == NULL);
|
||||
}
|
||||
|
||||
bool CUser::ResumeFile(const CString& sRemoteNick, unsigned short uPort, unsigned long uFileSize) {
|
||||
@@ -718,10 +804,8 @@ CString CUser::GetCurNick() {
|
||||
return pIRCSock->GetNick();
|
||||
}
|
||||
|
||||
CUserSock* pUserSock = GetUserSock();
|
||||
|
||||
if (pUserSock) {
|
||||
return pUserSock->GetNick();
|
||||
if (m_vUserSocks.size()) {
|
||||
return m_vUserSocks[0]->GetNick();
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -742,9 +826,20 @@ void CUser::SetKeepNick(bool b) { m_bKeepNick = b; }
|
||||
void CUser::SetDenyLoadMod(bool b) { m_bDenyLoadMod = b; }
|
||||
void CUser::SetAdmin(bool b) { m_bAdmin = b; }
|
||||
void CUser::SetDefaultChanModes(const CString& s) { m_sDefaultChanModes = s; }
|
||||
void CUser::SetIRCNick(const CNick& n) { m_IRCNick = n; }
|
||||
void CUser::SetIRCServer(const CString& s) { m_sIRCServer = s; }
|
||||
void CUser::SetQuitMsg(const CString& s) { m_sQuitMsg = s; }
|
||||
void CUser::SetBufferCount(unsigned int u) { m_uBufferCount = u; }
|
||||
void CUser::SetKeepBuffer(bool b) { m_bKeepBuffer = b; }
|
||||
void CUser::SetAutoCycle(bool b) { m_bAutoCycle = b; }
|
||||
|
||||
void CUser::SetIRCNick(const CNick& n) {
|
||||
m_IRCNick = n;
|
||||
|
||||
for (unsigned int a = 0; a < m_vUserSocks.size(); a++) {
|
||||
m_vUserSocks[a]->SetNick(n.GetNick());
|
||||
}
|
||||
}
|
||||
|
||||
bool CUser::AddCTCPReply(const CString& sCTCP, const CString& sReply) {
|
||||
if (sCTCP.empty() || sReply.empty()) {
|
||||
return false;
|
||||
@@ -753,9 +848,6 @@ bool CUser::AddCTCPReply(const CString& sCTCP, const CString& sReply) {
|
||||
m_mssCTCPReplies[sCTCP.AsUpper()] = sReply;
|
||||
return true;
|
||||
}
|
||||
void CUser::SetBufferCount(unsigned int u) { m_uBufferCount = u; }
|
||||
void CUser::SetKeepBuffer(bool b) { m_bKeepBuffer = b; }
|
||||
void CUser::SetAutoCycle(bool b) { m_bAutoCycle = b; }
|
||||
|
||||
bool CUser::SetStatusPrefix(const CString& s) {
|
||||
if ((!s.empty()) && (s.length() < 6) && (s.find(' ') == CString::npos)) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <set>
|
||||
#include "Nick.h"
|
||||
#include "FileUtils.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
using std::vector;
|
||||
using std::set;
|
||||
@@ -55,16 +56,29 @@ public:
|
||||
// !Modules
|
||||
#endif
|
||||
|
||||
// Buffers
|
||||
void AddRawBuffer(const CString& sPre, const CString& sPost) { m_RawBuffer.AddLine(sPre, sPost); }
|
||||
void AddMotdBuffer(const CString& sPre, const CString& sPost) { m_MotdBuffer.AddLine(sPre, sPost); }
|
||||
void AddQueryBuffer(const CString& sPre, const CString& sPost) { m_QueryBuffer.AddLine(sPre, sPost); }
|
||||
void ClearRawBuffer() { m_RawBuffer.Clear(); }
|
||||
void ClearMotdBuffer() { m_MotdBuffer.Clear(); }
|
||||
void ClearQueryBuffer() { m_QueryBuffer.Clear(); }
|
||||
// !Buffers
|
||||
bool OnBoot();
|
||||
bool IsUserAttached();
|
||||
|
||||
bool PutIRC(const CString& sLine);
|
||||
bool PutUser(const CString& sLine);
|
||||
bool PutStatus(const CString& sLine);
|
||||
bool PutStatusNotice(const CString& sLine);
|
||||
bool PutModule(const CString& sModule, const CString& sLine);
|
||||
bool PutUser(const CString& sLine, CUserSock* pUserSock = NULL);
|
||||
bool PutStatus(const CString& sLine, CUserSock* pUserSock = NULL);
|
||||
bool PutStatusNotice(const CString& sLine, CUserSock* pUserSock = NULL);
|
||||
bool PutModule(const CString& sModule, const CString& sLine, CUserSock* pUserSock = NULL);
|
||||
|
||||
bool IsUserAttached() { return (m_vUserSocks.size() > 0); }
|
||||
void UserConnected(CUserSock* pUserSock);
|
||||
void UserDisconnected(CUserSock* pUserSock);
|
||||
|
||||
CString GetLocalIP();
|
||||
void IRCConnected(CIRCSock* pIRCSock);
|
||||
void IRCDisconnected();
|
||||
|
||||
bool SendFile(const CString& sRemoteNick, const CString& sFileName, const CString& sModuleName = "");
|
||||
bool GetFile(const CString& sRemoteNick, const CString& sRemoteIP, unsigned short uRemotePort, const CString& sFileName, unsigned long uFileSize, const CString& sModuleName = "");
|
||||
@@ -95,10 +109,11 @@ public:
|
||||
void SetBufferCount(unsigned int u);
|
||||
void SetKeepBuffer(bool b);
|
||||
void SetAutoCycle(bool b);
|
||||
void SetChanPrefixes(const CString& s) { m_sChanPrefixes = (s.empty()) ? "#&" : s; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
CUserSock* GetUserSock();
|
||||
vector<CUserSock*>& GetUserSocks() { return m_vUserSocks; }
|
||||
CIRCSock* GetIRCSock();
|
||||
const CString& GetUserName() const;
|
||||
const CString& GetNick() const;
|
||||
@@ -111,6 +126,9 @@ public:
|
||||
bool IsPassHashed() const;
|
||||
const set<CString>& GetAllowedHosts() const;
|
||||
|
||||
const CString& GetChanPrefixes() const { return m_sChanPrefixes; }
|
||||
bool IsChan(const CString& sChan) const { return (sChan.size() && GetChanPrefixes().find(sChan[0]) != CString::npos); }
|
||||
|
||||
const CString& GetUserPath() const { if (!CFile::Exists(m_sUserPath)) { CUtils::MakeDir(m_sUserPath); } return m_sUserPath; }
|
||||
const CString& GetDLPath() const { if (!CFile::Exists(m_sDLPath)) { CUtils::MakeDir(m_sDLPath); } return m_sDLPath; }
|
||||
|
||||
@@ -144,6 +162,7 @@ protected:
|
||||
CString m_sPass;
|
||||
CString m_sStatusPrefix;
|
||||
CString m_sDefaultChanModes;
|
||||
CString m_sChanPrefixes;
|
||||
CNick m_IRCNick;
|
||||
CString m_sIRCServer;
|
||||
CString m_sQuitMsg;
|
||||
@@ -154,6 +173,10 @@ protected:
|
||||
CString m_sDLPath;
|
||||
// !Paths
|
||||
|
||||
CBuffer m_RawBuffer;
|
||||
CBuffer m_MotdBuffer;
|
||||
CBuffer m_QueryBuffer;
|
||||
|
||||
bool m_bBounceDCCs;
|
||||
bool m_bPassHashed;
|
||||
bool m_bUseClientIP;
|
||||
@@ -168,6 +191,7 @@ protected:
|
||||
|
||||
vector<CServer*> m_vServers;
|
||||
vector<CChan*> m_vChans;
|
||||
vector<CUserSock*> m_vUserSocks;
|
||||
set<CString> m_ssAllowedHosts;
|
||||
unsigned int m_uServerIdx;
|
||||
unsigned int m_uBufferCount;
|
||||
|
||||
+26
-3
@@ -142,7 +142,7 @@ void CUserSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
} else if (sCommand.CaseCmp("QUIT") == 0) {
|
||||
if (m_pIRCSock) {
|
||||
m_pIRCSock->UserDisconnected();
|
||||
m_pUser->UserDisconnected(this);
|
||||
}
|
||||
|
||||
Close(); // Treat a client quit as a detach
|
||||
@@ -168,9 +168,13 @@ void CUserSock::ReadLine(const CString& sData) {
|
||||
CModule* pModule = CZNC::Get().GetModules().FindModule(sModule);
|
||||
|
||||
if (pModule) {
|
||||
pModule->SetUserSock(this);
|
||||
pModule->OnModNotice(sMsg);
|
||||
pModule->SetUserSock(NULL);
|
||||
} else if ((pModule = m_pUser->GetModules().FindModule(sModule))) {
|
||||
pModule->SetUserSock(this);
|
||||
pModule->OnModNotice(sMsg);
|
||||
pModule->SetUserSock(NULL);
|
||||
} else {
|
||||
PutStatus("No such module [" + sModule + "]");
|
||||
}
|
||||
@@ -318,7 +322,9 @@ void CUserSock::ReadLine(const CString& sData) {
|
||||
|
||||
CModule* pModule = m_pUser->GetModules().FindModule(sModule);
|
||||
if (pModule) {
|
||||
pModule->SetUserSock(this);
|
||||
pModule->OnModCTCP(sCTCP);
|
||||
pModule->SetUserSock(NULL);
|
||||
} else {
|
||||
PutStatus("No such module [" + sModule + "]");
|
||||
}
|
||||
@@ -349,7 +355,9 @@ void CUserSock::ReadLine(const CString& sData) {
|
||||
|
||||
CModule* pModule = m_pUser->GetModules().FindModule(sModule);
|
||||
if (pModule) {
|
||||
pModule->SetUserSock(this);
|
||||
pModule->OnModCommand(sMsg);
|
||||
pModule->SetUserSock(NULL);
|
||||
} else {
|
||||
PutStatus("No such module [" + sModule + "]");
|
||||
}
|
||||
@@ -369,6 +377,21 @@ void CUserSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
|
||||
PutIRC("PRIVMSG " + sTarget + " :" + sMsg);
|
||||
|
||||
// Relay to the rest of the clients that may be connected to this user
|
||||
|
||||
if (m_pUser && m_pUser->IsChan(sTarget)) {
|
||||
vector<CUserSock*>& vUserSocks = m_pUser->GetUserSocks();
|
||||
|
||||
for (unsigned int a = 0; a < vUserSocks.size(); a++) {
|
||||
CUserSock* pUserSock = vUserSocks[a];
|
||||
|
||||
if (pUserSock != this) {
|
||||
pUserSock->PutServ(":" + GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -974,7 +997,7 @@ void CUserSock::AuthUser() {
|
||||
|
||||
if (pIRCSock) {
|
||||
m_pIRCSock = pIRCSock;
|
||||
pIRCSock->UserConnected(this);
|
||||
m_pUser->UserConnected(this);
|
||||
}
|
||||
|
||||
VOIDMODULECALL(OnUserAttached());
|
||||
@@ -992,7 +1015,7 @@ void CUserSock::ConnectionRefused() {
|
||||
|
||||
void CUserSock::Disconnected() {
|
||||
if (m_pIRCSock) {
|
||||
m_pIRCSock->UserDisconnected();
|
||||
m_pUser->UserDisconnected(this);
|
||||
m_pIRCSock = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _MAIN_H
|
||||
#define _MAIN_H
|
||||
|
||||
#define VERSION 0.041
|
||||
#define VERSION 0.042
|
||||
|
||||
#ifndef _MODDIR_
|
||||
#define _MODDIR_ "/usr/share/znc"
|
||||
|
||||
+9
-2
@@ -14,9 +14,10 @@ class CShellMod;
|
||||
|
||||
class CExecSock : public Csock {
|
||||
public:
|
||||
CExecSock(CShellMod* pShellMod, const CString& sExec) : Csock() {
|
||||
CExecSock(CShellMod* pShellMod, CUserSock* pUserSock, const CString& sExec) : Csock() {
|
||||
EnableReadLine();
|
||||
m_pParent = pShellMod;
|
||||
m_pUserSock = pUserSock;
|
||||
int iReadFD, iWriteFD;
|
||||
m_iPid = popen2(iReadFD, iWriteFD, sExec);
|
||||
ConnectFD(iReadFD, iWriteFD, "0.0.0.0:0");
|
||||
@@ -83,6 +84,8 @@ public:
|
||||
}
|
||||
return;
|
||||
}
|
||||
private:
|
||||
CUserSock* m_pUserSock;
|
||||
};
|
||||
|
||||
class CShellMod : public CModule {
|
||||
@@ -185,7 +188,7 @@ public:
|
||||
}
|
||||
|
||||
void RunCommand(const CString& sCommand) {
|
||||
m_pManager->AddSock((Csock*) new CExecSock(this, "cd " + m_sPath + " && " + sCommand), "SHELL");
|
||||
m_pManager->AddSock((Csock*) new CExecSock(this, m_pUserSock, "cd " + m_sPath + " && " + sCommand), "SHELL");
|
||||
}
|
||||
private:
|
||||
CString m_sPath;
|
||||
@@ -204,11 +207,15 @@ void CExecSock::ReadLine(const CString& sData) {
|
||||
a = sLine.find('\t');
|
||||
}
|
||||
|
||||
m_pParent->SetUserSock(m_pUserSock);
|
||||
m_pParent->PutShell(sLine);
|
||||
m_pParent->SetUserSock(NULL);
|
||||
}
|
||||
|
||||
void CExecSock::Disconnected() {
|
||||
m_pParent->SetUserSock(m_pUserSock);
|
||||
m_pParent->PutShell("znc$");
|
||||
m_pParent->SetUserSock(NULL);
|
||||
}
|
||||
|
||||
MODULEDEFS(CShellMod, "Gives shell access")
|
||||
|
||||
@@ -74,11 +74,6 @@ int CZNC::Loop() {
|
||||
for (set<CUser*>::iterator it = m_ssDelUsers.begin(); it != m_ssDelUsers.end(); it++) {
|
||||
CUser* pUser = *it;
|
||||
m_msUsers.erase(pUser->GetUserName());
|
||||
CUserSock* pUserSock = pUser->GetUserSock();
|
||||
|
||||
if (pUserSock) {
|
||||
m_Manager.DelSockByAddr(pUserSock);
|
||||
}
|
||||
|
||||
CIRCSock* pIRCSock = pUser->GetIRCSock();
|
||||
|
||||
@@ -148,11 +143,7 @@ int CZNC::Loop() {
|
||||
}
|
||||
|
||||
DEBUG_ONLY( cout << "User [" << pUser->GetUserName() << "] is connecting to [" << pServer->GetName() << ":" << pServer->GetPort() << "] ..." << endl);
|
||||
CUserSock* pUserSock = pUser->GetUserSock();
|
||||
|
||||
if (pUserSock) {
|
||||
pUserSock->PutStatus("Attempting to connect to [" + pServer->GetName() + ":" + CString::ToString(pServer->GetPort()) + "] ...");
|
||||
}
|
||||
pUser->PutStatus("Attempting to connect to [" + pServer->GetName() + ":" + CString::ToString(pServer->GetPort()) + "] ...");
|
||||
|
||||
pIRCSock = new CIRCSock(pUser);
|
||||
pIRCSock->SetPass(pServer->GetPass());
|
||||
@@ -166,10 +157,7 @@ int CZNC::Loop() {
|
||||
#endif
|
||||
if (!m_Manager.Connect(pServer->GetName(), pServer->GetPort(), sSockName, 20, bSSL, pUser->GetVHost(), pIRCSock)) {
|
||||
ReleaseISpoof();
|
||||
|
||||
if (pUserSock) {
|
||||
pUserSock->PutStatus("Unable to connect. (Bad host?)");
|
||||
}
|
||||
pUser->PutStatus("Unable to connect. (Bad host?)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user