mirror of
https://github.com/znc/znc.git
synced 2026-06-27 05:21:38 +02:00
Committing patches from crox/psychon
git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@790 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
@@ -38,6 +38,7 @@ void CChan::Reset() {
|
||||
m_sTopic = "";
|
||||
m_sTopicOwner = "";
|
||||
m_ulTopicDate = 0;
|
||||
m_ulCreationDate = 0;
|
||||
ClearNicks();
|
||||
}
|
||||
|
||||
@@ -81,16 +82,27 @@ void CChan::JoinUser(bool bForce, const CString& sKey, CClient* pClient) {
|
||||
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 333 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " " + GetTopicOwner() + " " + CString(GetTopicDate()), pClient);
|
||||
}
|
||||
|
||||
CString sPre = ":" + m_pUser->GetIRCServer() + " 353 " + m_pUser->GetIRCNick().GetNick() + " = " + GetName() + " :";
|
||||
CString sPre = ":" + m_pUser->GetIRCServer() + " 353 " + m_pUser->GetIRCNick().GetNick() + " " + GetModeForNames() + " " + GetName() + " :";
|
||||
CString sLine = sPre;
|
||||
CString sPerm, sNick;
|
||||
|
||||
for (map<CString,CNick*>::iterator a = m_msNicks.begin(); a != m_msNicks.end(); a++) {
|
||||
char c = a->second->GetPermChar();
|
||||
if (c != '\0') {
|
||||
sLine += c;
|
||||
if(pClient->HasNamesx()) {
|
||||
sPerm = a->second->GetPermStr();
|
||||
} else {
|
||||
char c = a->second->GetPermChar();
|
||||
sPerm = "";
|
||||
if (c != '\0') {
|
||||
sPerm += c;
|
||||
}
|
||||
}
|
||||
if(pClient->HasUHNames() && !a->second->GetIdent().empty() && a->second->GetHost().empty()) {
|
||||
sNick = a->first + "!" + a->second->GetIdent() + "@" + a->second->GetHost();
|
||||
} else {
|
||||
sNick = a->first;
|
||||
}
|
||||
|
||||
sLine += a->first;
|
||||
sLine += sPerm + sNick;
|
||||
|
||||
if (sLine.size() >= 490 || a == (--m_msNicks.end())) {
|
||||
m_pUser->PutUser(sLine, pClient);
|
||||
@@ -134,6 +146,20 @@ CString CChan::GetModeString() const {
|
||||
return (sModes.empty()) ? sModes : ("+" + sModes + sArgs);
|
||||
}
|
||||
|
||||
CString CChan::GetModeForNames() const {
|
||||
CString sMode;
|
||||
|
||||
for (map<unsigned char, CString>::const_iterator it = m_musModes.begin(); it != m_musModes.end(); it++) {
|
||||
if (it->first == 's') {
|
||||
sMode = "@";
|
||||
} else if ((it->first == 'p') && sMode.empty()){
|
||||
sMode = "*";
|
||||
}
|
||||
}
|
||||
|
||||
return (sMode.empty() ? "=" : sMode);
|
||||
}
|
||||
|
||||
void CChan::SetModes(const CString& sModes) {
|
||||
m_musModes.clear();
|
||||
m_uLimit = 0;
|
||||
@@ -373,28 +399,42 @@ int CChan::AddNicks(const CString& sNicks) {
|
||||
|
||||
bool CChan::AddNick(const CString& sNick) {
|
||||
const char* p = sNick.c_str();
|
||||
char cPrefix = '\0';
|
||||
CString sPrefix, sTmp, sIdent, sHost;
|
||||
|
||||
if (m_pUser->GetIRCSock()->IsPermChar(*p)) {
|
||||
cPrefix = *p;
|
||||
while (m_pUser->GetIRCSock()->IsPermChar(*p)) {
|
||||
sPrefix += *p;
|
||||
|
||||
if (!*++p) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CNick* pNick = FindNick(p);
|
||||
sTmp = p;
|
||||
sIdent = sTmp.Token(1, true, "!").Token(0, true, "@");
|
||||
sHost = sTmp.Token(1, true, "@");
|
||||
sTmp = sTmp.Token(0, false, "!");
|
||||
|
||||
CNick* pNick = FindNick(sTmp);
|
||||
if (!pNick) {
|
||||
pNick = new CNick(p);
|
||||
pNick = new CNick(sTmp);
|
||||
pNick->SetUser(m_pUser);
|
||||
}
|
||||
|
||||
if (pNick->AddPerm(cPrefix)) {
|
||||
IncPermCount(cPrefix);
|
||||
if(!sIdent.empty())
|
||||
pNick->SetIdent(sIdent);
|
||||
if(!sHost.empty())
|
||||
pNick->SetHost(sHost);
|
||||
|
||||
for(CString::size_type i = 0; i < sPrefix.length(); i++) {
|
||||
if (pNick->AddPerm(sPrefix[i])) {
|
||||
IncPermCount(sPrefix[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pNick->GetNick().CaseCmp(m_pUser->GetCurNick()) == 0) {
|
||||
AddPerm(cPrefix);
|
||||
for(CString::size_type i = 0; i < sPrefix.length(); i++) {
|
||||
AddPerm(sPrefix[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_msNicks[pNick->GetNick()] = pNick;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
M_Op = 'o',
|
||||
M_Voice = 'v',
|
||||
M_Ban = 'b',
|
||||
M_Except = 'e',
|
||||
M_Except = 'e'
|
||||
} EModes;
|
||||
|
||||
CChan(const CString& sName, CUser* pUser, bool bInConfig);
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
void OnVoice(const CString& sOpNick, const CString& sNick, bool bVoiced);
|
||||
CString GetModeString() const;
|
||||
CString GetModeArg(CString& sArgs) const;
|
||||
CString GetModeForNames() const;
|
||||
// !Modes
|
||||
|
||||
// Nicks
|
||||
@@ -109,6 +110,7 @@ public:
|
||||
void SetWhoDone(bool b = true) { m_bWhoDone = b; }
|
||||
void SetDetached(bool b = true) { m_bDetached = b; }
|
||||
void SetInConfig(bool b) { m_bInConfig = b; }
|
||||
void SetCreationDate(unsigned long u) { m_ulCreationDate = u; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
@@ -134,6 +136,7 @@ public:
|
||||
bool AutoCycle() const { return m_bAutoCycle; }
|
||||
bool IsDetached() const { return m_bDetached; }
|
||||
bool InConfig() const { return m_bInConfig; }
|
||||
unsigned long GetCreationDate() const { return m_ulCreationDate; }
|
||||
// !Getters
|
||||
private:
|
||||
protected:
|
||||
@@ -149,6 +152,7 @@ protected:
|
||||
CString m_sTopic;
|
||||
CString m_sTopicOwner;
|
||||
unsigned long m_ulTopicDate;
|
||||
unsigned long m_ulCreationDate;
|
||||
CUser* m_pUser;
|
||||
CNick m_Nick;
|
||||
unsigned int m_uLimit;
|
||||
|
||||
+49
-4
@@ -115,6 +115,13 @@ void CClient::ReadLine(const CString& sData) {
|
||||
PutStatusNotice("Detached from [" + sChan + "]");
|
||||
return;
|
||||
}
|
||||
} else if (sCommand.CaseCmp("PING") == 0) {
|
||||
CString sTarget = sLine.Token(1);
|
||||
|
||||
if (sTarget.CaseCmp("irc.znc.com") == 0) {
|
||||
PutClient("PONG " + sLine.substr(5));
|
||||
return;
|
||||
}
|
||||
} else if (sCommand.CaseCmp("PONG") == 0) {
|
||||
return; // Block pong replies, we already responded to the pings
|
||||
} else if (sCommand.CaseCmp("JOIN") == 0) {
|
||||
@@ -185,6 +192,21 @@ void CClient::ReadLine(const CString& sData) {
|
||||
if (!sMessage.empty()) {
|
||||
sLine += " :" + sMessage;
|
||||
}
|
||||
} else if (sCommand.CaseCmp("MODE") == 0) {
|
||||
CString sTarget = sLine.Token(1);
|
||||
CString sModes = sLine.Token(2, true);
|
||||
|
||||
if (m_pUser && m_pUser->IsChan(sTarget)) {
|
||||
CChan *pChan = m_pUser->FindChan(sTarget);
|
||||
|
||||
if (pChan && sModes.empty()) {
|
||||
PutClient(":" + m_pUser->GetIRCServer() + " 324 " + GetNick() + " " + sTarget + " " + pChan->GetModeString());
|
||||
if (pChan->GetCreationDate() > 0) {
|
||||
PutClient(":" + m_pUser->GetIRCServer() + " 329 " + GetNick() + " " + sTarget + " " + CString(pChan->GetCreationDate()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (sCommand.CaseCmp("QUIT") == 0) {
|
||||
if (m_pUser) {
|
||||
m_pUser->UserDisconnected(this);
|
||||
@@ -192,6 +214,17 @@ void CClient::ReadLine(const CString& sData) {
|
||||
|
||||
Close(); // Treat a client quit as a detach
|
||||
return; // Don't forward this msg. We don't want the client getting us disconnected.
|
||||
} else if (sCommand.CaseCmp("PROTOCTL") == 0) {
|
||||
unsigned int i = 1;
|
||||
while(!sLine.Token(i).empty()) {
|
||||
if(sLine.Token(i).CaseCmp("NAMESX") == 0) {
|
||||
m_bNamesx = true;
|
||||
} else if(sLine.Token(i).CaseCmp("UHNAMES") == 0) {
|
||||
m_bUHNames = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return; // If the server understands it, we already enabled namesx / uhnames
|
||||
} else if (sCommand.CaseCmp("NOTICE") == 0) {
|
||||
CString sTarget = sLine.Token(1);
|
||||
CString sMsg = sLine.Token(2, true);
|
||||
@@ -805,8 +838,8 @@ void CClient::UserCommand(const CString& sLine) {
|
||||
|
||||
const vector<CServer*>& vServers = m_pUser->GetServers();
|
||||
|
||||
if (vServers.size() <= 1) {
|
||||
PutStatus("You must have at least one server at all times.");
|
||||
if (vServers.size() <= 0) {
|
||||
PutStatus("You don't have any servers added.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -817,6 +850,7 @@ void CClient::UserCommand(const CString& sLine) {
|
||||
}
|
||||
} else if (sCommand.CaseCmp("LISTSERVERS") == 0) {
|
||||
if (m_pUser) {
|
||||
if (m_pUser->HasServers()) {
|
||||
const vector<CServer*>& vServers = m_pUser->GetServers();
|
||||
CTable Table;
|
||||
Table.AddColumn("Host");
|
||||
@@ -841,6 +875,9 @@ void CClient::UserCommand(const CString& sLine) {
|
||||
PutStatus(sLine);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PutStatus("You don't have any servers added.");
|
||||
}
|
||||
}
|
||||
} else if (sCommand.CaseCmp("TOPICS") == 0) {
|
||||
if (m_pUser) {
|
||||
@@ -870,13 +907,17 @@ void CClient::UserCommand(const CString& sLine) {
|
||||
} else if (sCommand.CaseCmp("SEND") == 0) {
|
||||
CString sToNick = sLine.Token(1);
|
||||
CString sFile = sLine.Token(2);
|
||||
CString sAllowedPath = m_pUser->GetDLPath();
|
||||
CString sAbsolutePath;
|
||||
|
||||
if ((sToNick.empty()) || (sFile.empty())) {
|
||||
PutStatus("Usage: Send <nick> <file>");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!m_pUser->IsAdmin() && sFile.Left(1) == "~") || sFile.Left(1) == "/" || sFile.find("..") != CString::npos) {
|
||||
sAbsolutePath = CUtils::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath());
|
||||
|
||||
if (sAbsolutePath.Left(sAllowedPath.length()) != sAllowedPath) {
|
||||
PutStatus("Illegal path.");
|
||||
return;
|
||||
}
|
||||
@@ -886,13 +927,17 @@ void CClient::UserCommand(const CString& sLine) {
|
||||
}
|
||||
} else if (sCommand.CaseCmp("GET") == 0) {
|
||||
CString sFile = sLine.Token(1);
|
||||
CString sAllowedPath = m_pUser->GetDLPath();
|
||||
CString sAbsolutePath;
|
||||
|
||||
if (sFile.empty()) {
|
||||
PutStatus("Usage: Get <file>");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!m_pUser->IsAdmin() && sFile.Left(1) == "~") || sFile.Left(1) == "/" || sFile.find("..") != CString::npos) {
|
||||
sAbsolutePath = CUtils::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath());
|
||||
|
||||
if (sAbsolutePath.Left(sAllowedPath.length()) != sAllowedPath) {
|
||||
PutStatus("Illegal path.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ public:
|
||||
m_bGotPass = false;
|
||||
m_bGotNick = false;
|
||||
m_bGotUser = false;
|
||||
m_bNamesx = false;
|
||||
m_bUHNames = false;
|
||||
m_uKeepNickCounter = 0;
|
||||
EnableReadLine();
|
||||
}
|
||||
@@ -90,6 +92,8 @@ public:
|
||||
|
||||
CString GetNick() const;
|
||||
CString GetNickMask() const;
|
||||
bool HasNamesx() const { return m_bNamesx; }
|
||||
bool HasUHNames() const { return m_bUHNames; }
|
||||
|
||||
bool DecKeepNickCounter();
|
||||
void UserCommand(const CString& sCommand);
|
||||
@@ -122,6 +126,8 @@ protected:
|
||||
bool m_bGotPass;
|
||||
bool m_bGotNick;
|
||||
bool m_bGotUser;
|
||||
bool m_bNamesx;
|
||||
bool m_bUHNames;
|
||||
CUser* m_pUser;
|
||||
CString m_sNick;
|
||||
CString m_sPass;
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ void CDCCBounce::PutPeer(const CString& sLine) {
|
||||
|
||||
unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sLocalIP, const CString& sRemoteIP) {
|
||||
CDCCBounce* pDCCBounce = new CDCCBounce(pUser, uLongIP, uPort, sFileName, sNick, sRemoteIP, sLocalIP, bIsChat);
|
||||
unsigned short uListenPort = CZNC::Get().GetManager().ListenAllRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, false, SOMAXCONN, pDCCBounce, 120);
|
||||
unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, sLocalIP, false, SOMAXCONN, pDCCBounce, 120);
|
||||
|
||||
return uListenPort;
|
||||
}
|
||||
|
||||
+28
-5
@@ -10,23 +10,31 @@ using std::endl;
|
||||
|
||||
CFile::CFile() {
|
||||
m_iFD = -1;
|
||||
m_bClose = false;
|
||||
}
|
||||
|
||||
CFile::CFile(const CString& sLongName) {
|
||||
m_iFD = -1;
|
||||
m_bClose = false;
|
||||
|
||||
SetFileName(sLongName);
|
||||
}
|
||||
|
||||
CFile::CFile(int iFD, const CString& sLongName) {
|
||||
m_iFD = iFD;
|
||||
m_bClose = false;
|
||||
|
||||
SetFileName(sLongName);
|
||||
}
|
||||
|
||||
CFile::~CFile() {
|
||||
if (m_iFD != -1) {
|
||||
if (m_bClose && m_iFD != -1) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void CFile::SetFileName(const CString& sLongName) {
|
||||
m_sLongName = sLongName;
|
||||
m_iFD = -1;
|
||||
|
||||
m_sShortName = sLongName;
|
||||
m_sShortName.TrimRight("/");
|
||||
@@ -217,6 +225,15 @@ bool CFile::Seek(unsigned long uPos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CFile::Truncate() {
|
||||
if (m_iFD != -1 && ftruncate(m_iFD, 0) == 0) {
|
||||
ClearBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CFile::Open(const CString& sFileName, int iFlags, mode_t iMode) {
|
||||
SetFileName(sFileName);
|
||||
return Open(iFlags, iMode);
|
||||
@@ -228,7 +245,11 @@ bool CFile::Open(int iFlags, mode_t iMode) {
|
||||
}
|
||||
|
||||
m_iFD = open(m_sLongName.c_str(), iFlags, iMode);
|
||||
return (m_iFD > -1);
|
||||
if (m_iFD < 0)
|
||||
return false;
|
||||
|
||||
m_bClose = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int CFile::Read(char *pszBuffer, int iBytes) {
|
||||
@@ -306,8 +327,10 @@ int CFile::Write(const CString & sData) {
|
||||
return Write(sData.data(), sData.size());
|
||||
}
|
||||
void CFile::Close() {
|
||||
if (m_iFD >= 0) {
|
||||
close(m_iFD); m_iFD = -1;
|
||||
if (m_iFD >= 0 && m_bClose) {
|
||||
close(m_iFD);
|
||||
m_iFD = -1;
|
||||
m_bClose = false;
|
||||
}
|
||||
}
|
||||
void CFile::ClearBuffer() { m_sBuffer.clear(); }
|
||||
|
||||
@@ -23,6 +23,7 @@ class CFile {
|
||||
public:
|
||||
CFile();
|
||||
CFile(const CString& sLongName);
|
||||
CFile(int iFD, const CString& sLongName);
|
||||
virtual ~CFile();
|
||||
|
||||
enum EOptions {
|
||||
@@ -106,6 +107,7 @@ public:
|
||||
bool Chmod(mode_t mode);
|
||||
static bool Chmod(const CString& sFile, mode_t mode);
|
||||
bool Seek(unsigned long uPos);
|
||||
bool Truncate();
|
||||
bool Open(const CString& sFileName, int iFlags, mode_t iMode = 0644);
|
||||
bool Open(int iFlags, mode_t iMode = 0644);
|
||||
int Read(char *pszBuffer, int iBytes);
|
||||
@@ -128,6 +130,7 @@ private:
|
||||
protected:
|
||||
CString m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName)
|
||||
CString m_sShortName; //!< Filename alone, without path
|
||||
bool m_bClose;
|
||||
};
|
||||
|
||||
class CDir : public vector<CFile*> {
|
||||
|
||||
+73
-15
@@ -12,6 +12,8 @@ CIRCSock::CIRCSock(CUser* pUser) : Csock() {
|
||||
m_bKeepNick = true;
|
||||
m_bAuthed = false;
|
||||
m_bOrigNickPending = false;
|
||||
m_bNamesx = false;
|
||||
m_bUHNames = false;
|
||||
EnableReadLine();
|
||||
m_Nick.SetIdent(pUser->GetIdent());
|
||||
m_Nick.SetHost(pUser->GetVHost());
|
||||
@@ -299,20 +301,65 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 329: {
|
||||
sRest.Trim();
|
||||
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
|
||||
|
||||
if (pChan) {
|
||||
unsigned long ulDate = strtoul(sLine.Token(4).c_str(), NULL, 10);
|
||||
pChan->SetCreationDate(ulDate);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 353: { // NAMES
|
||||
sRest.Trim();
|
||||
// Todo: allow for non @+= server msgs
|
||||
CChan* pChan = m_pUser->FindChan(sRest.Token(1));
|
||||
if (pChan) {
|
||||
CString sNicks = sRest.Token(2, true);
|
||||
if (sNicks.Left(1) == ":") {
|
||||
sNicks.LeftChomp();
|
||||
}
|
||||
if (!pChan) // Todo: should this still be forwarded to clients?
|
||||
return;
|
||||
|
||||
pChan->AddNicks(sNicks);
|
||||
CString sNicks = sRest.Token(2, true);
|
||||
if (sNicks.Left(1) == ":") {
|
||||
sNicks.LeftChomp();
|
||||
}
|
||||
|
||||
pChan->AddNicks(sNicks);
|
||||
|
||||
CString sTmp;
|
||||
vector<CClient*>& vClients = m_pUser->GetClients();
|
||||
for (unsigned int a = 0; a < vClients.size(); a++) {
|
||||
if((!m_bNamesx || vClients[a]->HasNamesx()) &&
|
||||
(!m_bUHNames || vClients[a]->HasUHNames())) {
|
||||
m_pUser->PutUser(sLine, vClients[a]);
|
||||
} else {
|
||||
sTmp = sLine.Token(0) + " ";
|
||||
sTmp += sLine.Token(1) + " ";
|
||||
sTmp += sLine.Token(2) + " ";
|
||||
sTmp += sLine.Token(3) + " ";
|
||||
sTmp += sLine.Token(4) + " :";
|
||||
while(!sNicks.empty()) {
|
||||
CString sNick = sNicks.Token(0);
|
||||
sNicks = sNicks.Token(1, true);
|
||||
if(m_bNamesx && !vClients[a]->HasNamesx()
|
||||
&& IsPermChar(sNick[0])) {
|
||||
while(sNick.length() > 2
|
||||
&& IsPermChar(sNick[1])) {
|
||||
sNick = sNick[0] + sNick.substr(2);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_bUHNames && !vClients[a]->HasUHNames()) {
|
||||
sNick = sNick.Token(0, false, "!");
|
||||
}
|
||||
|
||||
sTmp += sNick + " ";
|
||||
}
|
||||
sTmp.RightChomp();
|
||||
m_pUser->PutUser(sTmp, vClients[a]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 366: { // end of names list
|
||||
m_pUser->PutUser(sLine); // First send them the raw
|
||||
|
||||
@@ -612,7 +659,7 @@ bool CIRCSock::OnCTCPReply(CNick& Nick, CString& sMessage) {
|
||||
bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
MODULECALL(OnPrivCTCP(Nick, sMessage), m_pUser, NULL, return true);
|
||||
|
||||
if (strncasecmp(sMessage.c_str(), "DCC ", 4) == 0 && m_pUser && m_pUser->BounceDCCs()) {
|
||||
if (strncasecmp(sMessage.c_str(), "DCC ", 4) == 0 && m_pUser && m_pUser->BounceDCCs() && m_pUser->IsUserAttached()) {
|
||||
// DCC CHAT chat 2453612361 44592
|
||||
CString sType = sMessage.Token(1);
|
||||
CString sFile = sMessage.Token(2);
|
||||
@@ -621,13 +668,10 @@ 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_pUser->IsUserAttached()) {
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP));
|
||||
|
||||
if (uBNCPort) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
} else if (sType.CaseCmp("SEND") == 0) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
@@ -780,6 +824,8 @@ void CIRCSock::Disconnected() {
|
||||
if (!m_pUser->IsBeingDeleted()) {
|
||||
m_pUser->PutStatus("Disconnected from IRC. Reconnecting...");
|
||||
}
|
||||
m_pUser->ClearRawBuffer();
|
||||
m_pUser->ClearMotdBuffer();
|
||||
|
||||
ResetChans();
|
||||
}
|
||||
@@ -789,6 +835,8 @@ void CIRCSock::SockError(int iErrno) {
|
||||
if (!m_pUser->IsBeingDeleted()) {
|
||||
m_pUser->PutStatus("Disconnected from IRC. Reconnecting...");
|
||||
}
|
||||
m_pUser->ClearRawBuffer();
|
||||
m_pUser->ClearMotdBuffer();
|
||||
|
||||
ResetChans();
|
||||
}
|
||||
@@ -798,6 +846,8 @@ void CIRCSock::Timeout() {
|
||||
if (!m_pUser->IsBeingDeleted()) {
|
||||
m_pUser->PutStatus("IRC connection timed out. Reconnecting...");
|
||||
}
|
||||
m_pUser->ClearRawBuffer();
|
||||
m_pUser->ClearMotdBuffer();
|
||||
|
||||
ResetChans();
|
||||
}
|
||||
@@ -807,6 +857,8 @@ void CIRCSock::ConnectionRefused() {
|
||||
if (!m_pUser->IsBeingDeleted()) {
|
||||
m_pUser->PutStatus("Connection Refused. Reconnecting...");
|
||||
}
|
||||
m_pUser->ClearRawBuffer();
|
||||
m_pUser->ClearMotdBuffer();
|
||||
}
|
||||
|
||||
void CIRCSock::ParseISupport(const CString& sLine) {
|
||||
@@ -846,6 +898,12 @@ void CIRCSock::ParseISupport(const CString& sLine) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sName.CaseCmp("NAMESX") == 0) {
|
||||
m_bNamesx = true;
|
||||
PutIRC("PROTOCTL NAMESX");
|
||||
} else if (sName.CaseCmp("UHNAMES") == 0) {
|
||||
m_bUHNames = true;
|
||||
PutIRC("PROTOCTL UHNAMES");
|
||||
}
|
||||
|
||||
sArg = sLine.Token(i++);
|
||||
|
||||
@@ -66,6 +66,8 @@ public:
|
||||
const CString& GetNick() const { return m_Nick.GetNick(); }
|
||||
const CString& GetPass() const { return m_sPass; }
|
||||
bool IsOrigNickPending() const { return m_bOrigNickPending; }
|
||||
bool HasNamesx() const { return m_bNamesx; }
|
||||
bool HasUHNames() const { return m_bUHNames; }
|
||||
// !Getters
|
||||
private:
|
||||
void SetNick(const CString& sNick);
|
||||
@@ -74,6 +76,8 @@ protected:
|
||||
bool m_bAuthed;
|
||||
bool m_bKeepNick;
|
||||
bool m_bOrigNickPending;
|
||||
bool m_bNamesx;
|
||||
bool m_bUHNames;
|
||||
CString m_sPerms;
|
||||
CString m_sPermModes;
|
||||
map<unsigned char, EChanModeArgs> m_mueChanModes;
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
CXX=@CXX@
|
||||
CXXFLAGS=@CXXFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
INCLUDES=@INCLUDES@
|
||||
LIBS=@LIBS@
|
||||
prefix=@prefix@
|
||||
@@ -14,10 +15,10 @@ depend::
|
||||
@if test -n "@MODTARGET@"; then (cd modules; $(MAKE) depend); fi
|
||||
|
||||
znc: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ $(LIBS) $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(INCLUDES) $(OBJS) $(LIBS)
|
||||
|
||||
znc-static: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) -static -o $@ $(INCLUDES) $(OBJS) $(LIBS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -static -o $@ $(INCLUDES) $(OBJS) $(LIBS)
|
||||
strip $@
|
||||
|
||||
modules::
|
||||
|
||||
@@ -117,11 +117,17 @@ void CNick::UpdatePermChar() {
|
||||
const set<unsigned char>& CNick::GetChanPerms() const { return m_suChanPerms; }
|
||||
const unsigned char CNick::GetPermChar() const { return m_cPerm; }
|
||||
CString CNick::GetPermStr() const {
|
||||
CIRCSock* pIRCSock = (!m_pUser) ? NULL : m_pUser->GetIRCSock();
|
||||
const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms();
|
||||
CString sRet;
|
||||
|
||||
if (m_cPerm) {
|
||||
sRet += m_cPerm;
|
||||
}
|
||||
for (unsigned int a = 0; a < sChanPerms.size(); a++) {
|
||||
const unsigned char& c = sChanPerms[a];
|
||||
|
||||
if (HasPerm(c)) {
|
||||
sRet += c;
|
||||
}
|
||||
}
|
||||
|
||||
return sRet;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
EASCII,
|
||||
EURL,
|
||||
EHTML,
|
||||
ESQL,
|
||||
ESQL
|
||||
} EEscape;
|
||||
|
||||
explicit CString(char c);
|
||||
|
||||
@@ -88,8 +88,9 @@ void CUser::DelClients() {
|
||||
bool CUser::OnBoot() {
|
||||
#ifdef _MODULES
|
||||
return GetModules().OnBoot();
|
||||
#endif
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CUser::IRCConnected(CIRCSock* pIRCSock) {
|
||||
@@ -114,7 +115,8 @@ CString CUser::ExpandString(const CString& sStr) const {
|
||||
CString& CUser::ExpandString(const CString& sStr, CString& sRet) const {
|
||||
sRet = sStr;
|
||||
sRet.Replace("%user%", GetUserName());
|
||||
sRet.Replace("%nick%", GetUserName());
|
||||
sRet.Replace("%defnick%", GetNick());
|
||||
sRet.Replace("%nick%", GetCurNick());
|
||||
sRet.Replace("%altnick%", GetAltNick());
|
||||
sRet.Replace("%ident%", GetIdent());
|
||||
sRet.Replace("%realname%", GetRealName());
|
||||
@@ -414,11 +416,6 @@ bool CUser::IsValid(CString& sErrMsg, bool bSkipPass) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_vServers.empty()) {
|
||||
sErrMsg = "No servers defined";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -723,6 +720,11 @@ CIRCSock* CUser::GetIRCSock() {
|
||||
return (CIRCSock*) CZNC::Get().GetManager().FindSockByName("IRC::" + m_sUserName);
|
||||
}
|
||||
|
||||
const CIRCSock* CUser::GetIRCSock() const {
|
||||
// Todo: same as above
|
||||
return (CIRCSock*) CZNC::Get().GetManager().FindSockByName("IRC::" + m_sUserName);
|
||||
}
|
||||
|
||||
CString CUser::GetLocalIP() {
|
||||
CIRCSock* pIRCSock = GetIRCSock();
|
||||
|
||||
@@ -872,8 +874,8 @@ bool CUser::GetFile(const CString& sRemoteNick, const CString& sRemoteIP, unsign
|
||||
return true;
|
||||
}
|
||||
|
||||
CString CUser::GetCurNick() {
|
||||
CIRCSock* pIRCSock = GetIRCSock();
|
||||
CString CUser::GetCurNick() const {
|
||||
const CIRCSock* pIRCSock = GetIRCSock();
|
||||
|
||||
if (pIRCSock) {
|
||||
return pIRCSock->GetNick();
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
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 = "");
|
||||
bool ResumeFile(const CString& sRemoteNick, unsigned short uPort, unsigned long uFileSize);
|
||||
CString GetCurNick();
|
||||
CString GetCurNick() const;
|
||||
bool Clone(const CUser& User, CString& sErrorRet);
|
||||
void BounceAllClients();
|
||||
|
||||
@@ -130,6 +130,7 @@ public:
|
||||
// Getters
|
||||
vector<CClient*>& GetClients() { return m_vClients; }
|
||||
CIRCSock* GetIRCSock();
|
||||
const CIRCSock* GetIRCSock() const;
|
||||
const CString& GetUserName() const;
|
||||
const CString& GetCleanUserName() const;
|
||||
const CString& GetNick(bool bAllowDefault = true) const;
|
||||
@@ -165,6 +166,7 @@ public:
|
||||
bool KeepBuffer() const;
|
||||
bool AutoCycle() const;
|
||||
bool IsBeingDeleted() const { return m_bBeingDeleted; }
|
||||
bool HasServers() const { return m_vServers.size() > 0; }
|
||||
// !Getters
|
||||
private:
|
||||
protected:
|
||||
|
||||
@@ -117,7 +117,7 @@ void CUtils::GenerateCert(FILE *pOut, bool bEncPrivKey, const CString& sHost) {
|
||||
X509_free( pCert );
|
||||
EVP_PKEY_free( pKey );
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif /* HAVE_LIBSSL */
|
||||
|
||||
CString CUtils::GetIP(unsigned long addr) {
|
||||
|
||||
@@ -86,8 +86,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void Open(const CString& sFile) {
|
||||
m_fd = open(sFile.c_str(), O_RDONLY);
|
||||
void Open(const CString& sFile, bool bRw = false) {
|
||||
m_fd = open(sFile.c_str(), bRw ? O_RDWR : O_RDONLY);
|
||||
m_bCreated = false;
|
||||
|
||||
if (m_fd == -1) {
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
}
|
||||
|
||||
//! timeout in milliseconds
|
||||
bool TryExLock(const CString& sLockFile, unsigned long long iTimeout = 0) {
|
||||
Open(sLockFile);
|
||||
bool TryExLock(const CString& sLockFile, unsigned long long iTimeout = 0, bool bRw = false) {
|
||||
Open(sLockFile, bRw);
|
||||
return TryExLock(iTimeout);
|
||||
}
|
||||
|
||||
@@ -154,6 +154,9 @@ public:
|
||||
bool LockSh() { return Lock(LOCK_SH); }
|
||||
bool UnLock() { return Lock(LOCK_UN); }
|
||||
|
||||
CString GetFileName() { return m_sFileName; }
|
||||
int GetFD() { return m_fd; }
|
||||
|
||||
private:
|
||||
bool Lock(int iOperation) {
|
||||
if (m_fd == -1) {
|
||||
@@ -177,7 +180,7 @@ class CException {
|
||||
public:
|
||||
typedef enum {
|
||||
EX_Shutdown,
|
||||
EX_BadModVersion,
|
||||
EX_BadModVersion
|
||||
} EType;
|
||||
|
||||
CException(EType e) {
|
||||
|
||||
@@ -681,13 +681,13 @@ echo X"$0" |
|
||||
/^X\(\/\).*/{ s//\1/; q; }
|
||||
s/.*/./; q'`
|
||||
srcdir=$ac_confdir
|
||||
if test ! -r "$srcdir/$ac_unique_file"; then
|
||||
if test ! -r $srcdir/$ac_unique_file; then
|
||||
srcdir=..
|
||||
fi
|
||||
else
|
||||
ac_srcdir_defaulted=no
|
||||
fi
|
||||
if test ! -r "$srcdir/$ac_unique_file"; then
|
||||
if test ! -r $srcdir/$ac_unique_file; then
|
||||
if test "$ac_srcdir_defaulted" = yes; then
|
||||
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
|
||||
{ (exit 1); exit 1; }; }
|
||||
@@ -696,7 +696,7 @@ if test ! -r "$srcdir/$ac_unique_file"; then
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
|
||||
(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
|
||||
{ echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
|
||||
{ (exit 1); exit 1; }; }
|
||||
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
|
||||
@@ -1931,6 +1931,15 @@ function appendCXX {
|
||||
CXXFLAGS=$*
|
||||
fi
|
||||
}
|
||||
|
||||
function appendLD {
|
||||
if test "$LDFLAGS" != ""; then
|
||||
LDFLAGS="$LDFLAGS $*"
|
||||
else
|
||||
LDFLAGS=$*
|
||||
fi
|
||||
}
|
||||
|
||||
if `echo $host_os | grep -i 'freebsd' >/dev/null 2>/dev/null`; then
|
||||
appendInc -I/usr/local/include
|
||||
appendLib -L/usr/local/lib -lcompat
|
||||
@@ -3325,7 +3334,7 @@ fi
|
||||
MODFLAGS="$CXXFLAGS"
|
||||
else
|
||||
MODFLAGS="$CXXFLAGS"
|
||||
appendCXX -rdynamic
|
||||
appendLD -Wl,--export-dynamic
|
||||
fi
|
||||
MODFLAGS="$MODFLAGS -I`pwd`"
|
||||
MODTARGET="modules"
|
||||
@@ -3435,6 +3444,7 @@ VERSION=`grep '#define VERSION' main.h | awk '{print $3}'`
|
||||
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile"
|
||||
|
||||
ac_config_files="$ac_config_files znc-config"
|
||||
|
||||
+11
-1
@@ -27,6 +27,15 @@ function appendCXX {
|
||||
CXXFLAGS=$*
|
||||
fi
|
||||
}
|
||||
|
||||
function appendLD {
|
||||
if test "$LDFLAGS" != ""; then
|
||||
LDFLAGS="$LDFLAGS $*"
|
||||
else
|
||||
LDFLAGS=$*
|
||||
fi
|
||||
}
|
||||
|
||||
if `echo $host_os | grep -i 'freebsd' >/dev/null 2>/dev/null`; then
|
||||
appendInc -I/usr/local/include
|
||||
appendLib -L/usr/local/lib -lcompat
|
||||
@@ -83,7 +92,7 @@ if test "$MODULES" = "yes"; then
|
||||
MODFLAGS="$CXXFLAGS"
|
||||
else
|
||||
MODFLAGS="$CXXFLAGS"
|
||||
appendCXX -rdynamic
|
||||
appendLD -Wl,--export-dynamic
|
||||
fi
|
||||
MODFLAGS="$MODFLAGS -I`pwd`"
|
||||
MODTARGET="modules"
|
||||
@@ -116,6 +125,7 @@ VERSION=`grep '#define VERSION' main.h | awk '{print $3}'`
|
||||
|
||||
AC_SUBST([CXXFLAGS])
|
||||
AC_SUBST([MODFLAGS])
|
||||
AC_SUBST([LDFLAGS])
|
||||
AC_SUBST([INCLUDES])
|
||||
AC_SUBST([LIBS])
|
||||
AC_SUBST([MODULES])
|
||||
|
||||
@@ -18,17 +18,18 @@
|
||||
File Locations
|
||||
</h2>
|
||||
<ul>
|
||||
<li> <strong>Config</strong> - ZNC gets its configuration by reading the file ~/.znc/znc.conf
|
||||
<li> <strong>Config</strong> - ZNC gets its configuration by reading the file ~/.znc/znc.conf. See znc --help and znc --makeconf.
|
||||
<li> <strong>Misc</strong> - Other files are also stored in the ~/.znc directory such as the SSL cert (znc.pem) and PidFile (znc.pid).
|
||||
<li> <strong>Local Modules</strong> - Stored in ~/.znc/modules. ZNC will look in the local module dir first when trying to load a module.
|
||||
<li> <strong>Global Modules</strong> - Stored in /usr/share/znc/modules by default.
|
||||
<li> <strong>Binaries</strong> - znc and znc-config are stored in /usr/bin by default. You can change this when you configure by using <em>./configure --prefix=/whatever/path/you/want</em>
|
||||
<li> <strong>Binaries</strong> - znc, znc-config and znc-buildmod are stored in /usr/bin by default. You can change this when you configure by using <em>./configure --prefix=/whatever/path/you/want</em>
|
||||
</ul>
|
||||
<h2>
|
||||
Config File - (~/.znc/znc.conf)
|
||||
</h2>
|
||||
<ul>
|
||||
<li> <strong>ListenPort</strong> - The port that ZNC will listen on. If the port is prepended with a '+' then ZNC listens using ssl.
|
||||
<li> <strong>Listen</strong> - The port that ZNC will listen on. If the port is prepended with a '+' then ZNC listens using ssl. If you want to listen on a specific ip, use the address as first argument and the port as second.
|
||||
<li> <strong>Listen6</strong> - The same as Listen, but uses IPv6 instead of IPv4.
|
||||
<li> <strong>ISpoofFile</strong> - ZNC will write the ident of the user trying to connect to this file. Very useful if your shell supports oidentd.
|
||||
<li> <strong>PidFile</strong> - The pid file that is created when znc starts.
|
||||
<li> <strong>StatusPrefix</strong> - The prefix for the status and module queries.
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<li> <em>g++ `znc-config --cflags` `znc-config --include` `znc-config --libs` -shared -o example.so example.cpp</em>
|
||||
</ul>
|
||||
</ul>
|
||||
<li> Place the .so file into your ~/.znc/modules directory !!!WARNING!!! if you overwrite a .so file while znc has it loaded it can and probably will crash znc, <em>/msg *status unloadmod foo</em> first!
|
||||
<li> Place the .so file into your ~/.znc/modules directory. You can load it with <em>/msg *status loadmod foo</em>. If you overwrite a .so file while znc has it loaded it can crash znc, <em>/msg *status unloadmod foo</em> first!
|
||||
</ul>
|
||||
<h2>
|
||||
Code
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
#include "MD5.h"
|
||||
|
||||
static struct option g_LongOpts[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'v' },
|
||||
{ "makeconf", 0, NULL, 'c' },
|
||||
{ "makepass", 0, NULL, 's' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "makeconf", no_argument, 0, 'c' },
|
||||
{ "makepass", no_argument, 0, 's' },
|
||||
#ifdef HAVE_LIBSSL
|
||||
{ "makepem", 0, NULL, 'p' },
|
||||
{ "encrypt-pem", 0, NULL, 'e' },
|
||||
{ "makepem", no_argument, 0, 'p' },
|
||||
{ "encrypt-pem", no_argument, 0, 'e' },
|
||||
#endif /* HAVE_LIBSSL */
|
||||
{ NULL }
|
||||
{ "datadir", required_argument, 0, 'd' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
void GenerateHelp(const char *appname) {
|
||||
@@ -31,6 +32,7 @@ void GenerateHelp(const char *appname) {
|
||||
CUtils::PrintMessage("\t-p, --makepem Generates a pemfile for use with SSL");
|
||||
CUtils::PrintMessage("\t-e, --encrypt-pem when used along with --makepem, encrypts the private key in the pemfile");
|
||||
#endif /* HAVE_LIBSSL */
|
||||
CUtils::PrintMessage("\t-d, --datadir Set a different znc repository");
|
||||
}
|
||||
|
||||
void die(int sig) {
|
||||
@@ -51,6 +53,7 @@ void die(int sig) {
|
||||
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
CString sConfig;
|
||||
CString sDataDir = "";
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
InitSSL();
|
||||
@@ -63,10 +66,10 @@ int main(int argc, char** argv, char** envp) {
|
||||
bool bMakePem = false;
|
||||
bool bEncPem = false;
|
||||
|
||||
while ((iArg = getopt_long(argc, argv, "hvcspe", g_LongOpts, &iOptIndex)) != -1) {
|
||||
while ((iArg = getopt_long(argc, argv, "hvcsped:", g_LongOpts, &iOptIndex)) != -1) {
|
||||
#else
|
||||
|
||||
while ((iArg = getopt_long(argc, argv, "hvcs", g_LongOpts, &iOptIndex)) != -1) {
|
||||
while ((iArg = getopt_long(argc, argv, "hvcsd:", g_LongOpts, &iOptIndex)) != -1) {
|
||||
#endif /* HAVE_LIBSSL */
|
||||
switch (iArg) {
|
||||
case 'h':
|
||||
@@ -89,6 +92,9 @@ int main(int argc, char** argv, char** envp) {
|
||||
bEncPem = true;
|
||||
break;
|
||||
#endif /* HAVE_LIBSSL */
|
||||
case 'd':
|
||||
sDataDir = CString(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
GenerateHelp(argv[0]);
|
||||
@@ -104,7 +110,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
if (bMakeConf) {
|
||||
CZNC& ZNC = CZNC::Get();
|
||||
ZNC.InitDirs("");
|
||||
ZNC.InitDirs("", sDataDir);
|
||||
if (ZNC.WriteNewConfig(sConfig)) {
|
||||
char* args[3];
|
||||
|
||||
@@ -134,7 +140,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (bMakePem) {
|
||||
CZNC* pZNC = &CZNC::Get();
|
||||
pZNC->InitDirs("");
|
||||
pZNC->InitDirs("", sDataDir);
|
||||
pZNC->WritePemFile( bEncPem );
|
||||
|
||||
delete pZNC;
|
||||
@@ -155,7 +161,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
}
|
||||
|
||||
CZNC* pZNC = &CZNC::Get();
|
||||
pZNC->InitDirs(((argc) ? argv[0] : ""));
|
||||
pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir);
|
||||
|
||||
if (!pZNC->ParseConfig(sConfig)) {
|
||||
CUtils::PrintError("Unrecoverable config error.");
|
||||
|
||||
+14
-1
@@ -117,6 +117,19 @@ public:
|
||||
|
||||
PutModule(sMsg);
|
||||
}
|
||||
} else if (sCommand.Token(0).CaseCmp("SHOW") == 0) {
|
||||
if (m_pUser) {
|
||||
CString sExpanded = GetAwayNick();
|
||||
CString sMsg = "AwayNick is set to [" + m_sFormat + "]";
|
||||
|
||||
if (m_sFormat != sExpanded) {
|
||||
sMsg += " (" + sExpanded + ")";
|
||||
}
|
||||
|
||||
PutModule(sMsg);
|
||||
}
|
||||
} else if(sCommand.Token(0).CaseCmp("HELP") == 0) {
|
||||
PutModule("Commands are: show, timers, set [awaynick]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +138,7 @@ public:
|
||||
CIRCSock* pIRCSock = m_pUser->GetIRCSock();
|
||||
|
||||
if (pIRCSock) {
|
||||
pIRCSock->GetMaxNickLen();
|
||||
uLen = pIRCSock->GetMaxNickLen();
|
||||
}
|
||||
|
||||
return m_pUser->ExpandString(m_sFormat).Left(uLen);
|
||||
|
||||
+11
-5
@@ -35,12 +35,13 @@ public:
|
||||
if(sPerf.Left(1) == "/")
|
||||
sPerf.LeftChomp();
|
||||
|
||||
if(sPerf.Token(0).AsUpper() == "MSG") {
|
||||
if(sPerf.Token(0).CaseCmp("MSG") == 0) {
|
||||
sPerf = "PRIVMSG " + sPerf.Token(1, true);
|
||||
}
|
||||
|
||||
if(sPerf.Token(0).AsUpper() == "PRIVMSG" ||
|
||||
sPerf.Token(0).AsUpper() == "NOTICE") {
|
||||
if((sPerf.Token(0).CaseCmp("PRIVMSG") == 0 ||
|
||||
sPerf.Token(0).CaseCmp("NOTICE") == 0) &&
|
||||
sPerf.Token(2).Left(1) != ":") {
|
||||
sPerf = sPerf.Token(0) + " " + sPerf.Token(1)
|
||||
+ " :" + sPerf.Token(2, true);
|
||||
}
|
||||
@@ -64,9 +65,14 @@ public:
|
||||
} else if(sCmdName == "list")
|
||||
{
|
||||
int i = 1;
|
||||
CString sExpanded;
|
||||
for(VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); it++, i++)
|
||||
{
|
||||
PutModule(CString( i ) + ": " + *it);
|
||||
sExpanded = GetUser()->ExpandString( *it );
|
||||
if(sExpanded != *it)
|
||||
PutModule(CString( i ) + ": " + *it + " (" + sExpanded + ")");
|
||||
else
|
||||
PutModule(CString( i ) + ": " + *it);
|
||||
}
|
||||
PutModule(" -- End of List");
|
||||
} else if(sCmdName == "save")
|
||||
@@ -86,7 +92,7 @@ public:
|
||||
for( VCString::iterator it = m_vPerform.begin();
|
||||
it != m_vPerform.end(); it++)
|
||||
{
|
||||
PutIRC(*it);
|
||||
PutIRC( GetUser()->ExpandString( *it ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-2
@@ -115,10 +115,27 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool OnLoad(const CString& sArgs) {
|
||||
virtual bool OnLoad(const CString& sArgStr) {
|
||||
bool bSSL = false;
|
||||
bool bIPv6 = false;
|
||||
CString sArgs(sArgStr);
|
||||
CString sOpt;
|
||||
CString sPort;
|
||||
|
||||
if (sArgs.Left(1) == "-") {
|
||||
sOpt = sArgs.Token(0);
|
||||
sArgs = sArgs.Token(1, true);
|
||||
|
||||
if (sOpt.CaseCmp("-IPV6") == 0) {
|
||||
bIPv6 = true;
|
||||
} else if (sOpt.CaseCmp("-IPV4") == 0) {
|
||||
bIPv6 = false;
|
||||
} else {
|
||||
CUtils::PrintMessage("Unknown option [" + sOpt + "] valid options are -ipv4 or -ipv6", true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sArgs.find(" ") != CString::npos) {
|
||||
m_sListenHost = sArgs.Token(0);
|
||||
sPort = sArgs.Token(1);
|
||||
@@ -146,7 +163,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_pManager->ListenHost(m_uPort, "WebAdmin::Listener", m_sListenHost, bSSL, SOMAXCONN, pListenSock);
|
||||
return m_pManager->ListenHost(m_uPort, "WebAdmin::Listener", m_sListenHost, bSSL, SOMAXCONN, pListenSock, 0, bIPv6);
|
||||
}
|
||||
|
||||
void AddSock(CWebAdminSock* pSock) {
|
||||
|
||||
+18
-23
@@ -1,4 +1,4 @@
|
||||
# Copyright 1999-2005 Gentoo Foundation
|
||||
# Copyright 1999-2007 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header$
|
||||
|
||||
@@ -10,34 +10,29 @@ SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
KEYWORDS="x86 amd64 ~sparc"
|
||||
IUSE="ssl ipv6 nomodules debug"
|
||||
RESTRICT="nostrip"
|
||||
KEYWORDS="~amd64 ~sparc ~x86 ~x86-fbsd"
|
||||
IUSE="ssl ipv6 modules debug perl sasl"
|
||||
|
||||
RDEPEND="virtual/libc"
|
||||
DEPEND="virtual/libc
|
||||
>=sys-devel/gcc-3.2.3-r4
|
||||
ssl? ( >=dev-libs/openssl-0.9.7d )"
|
||||
|
||||
src_unpack() {
|
||||
unpack ${A} || die "unpack failed"
|
||||
}
|
||||
DEPEND="ssl? ( >=dev-libs/openssl-0.9.7d )
|
||||
perl? ( dev-lang/perl )
|
||||
sasl? ( dev-libs/cyrus-sasl )"
|
||||
RDEPEND="${DEPEND}"
|
||||
|
||||
src_compile() {
|
||||
local MY_CONFARGS=""
|
||||
|
||||
use ssl || MY_CONFARGS="${MY_CONFARGS} --disable-openssl"
|
||||
use ipv6 && MY_CONFARGS="${MY_CONFARGS} --enable-ipv6"
|
||||
use nomodules && MY_CONFARGS="${MY_CONFARGS} --disable-modules"
|
||||
use debug && MY_CONFARGS="${MY_CONFARGS} --enable-debug"
|
||||
|
||||
econf ${MY_CONFARGS} || die "econf failed"
|
||||
emake CFLAGS="${CFLAGS}" || die "emake failed"
|
||||
econf \
|
||||
$(use_enable ssl openssl) \
|
||||
$(use_enable ipv6) \
|
||||
$(use_enable modules) \
|
||||
$(use_enable debug) \
|
||||
$(use_enable perl) \
|
||||
$(use_enable sasl) \
|
||||
|| die "econf failed"
|
||||
emake || die "emake failed"
|
||||
}
|
||||
|
||||
src_install() {
|
||||
make install DESTDIR=${D}
|
||||
dodoc docs/*.html || die "dodoc failed"
|
||||
make install DESTDIR="${D}" || die "make install failed."
|
||||
dohtml docs/*.html || die "dohtml failed"
|
||||
dodoc AUTHORS znc.conf || die "dodoc failed"
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,14 @@ CZNC::CZNC() {
|
||||
#ifdef _MODULES
|
||||
m_pModules = new CGlobalModules();
|
||||
#endif
|
||||
m_bISpoofLocked = false;
|
||||
m_pISpoofLockFile = NULL;
|
||||
SetISpoofFormat(""); // Set ISpoofFormat to default
|
||||
}
|
||||
|
||||
CZNC::~CZNC() {
|
||||
if(m_pISpoofLockFile)
|
||||
ReleaseISpoof();
|
||||
|
||||
#ifdef _MODULES
|
||||
m_pModules->UnloadAll();
|
||||
|
||||
@@ -115,7 +118,7 @@ int CZNC::Loop() {
|
||||
|
||||
m_Manager.Loop();
|
||||
|
||||
if (m_bISpoofLocked) {
|
||||
if (m_pISpoofLockFile != NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -135,7 +138,7 @@ int CZNC::Loop() {
|
||||
|
||||
CIRCSock* pIRCSock = (CIRCSock*) m_Manager.FindSockByName(sSockName);
|
||||
|
||||
if (!pIRCSock) {
|
||||
if (!pIRCSock && pUser->HasServers()) {
|
||||
if (pUser->ConnectPaused() && pUser->IsLastServer()) {
|
||||
continue;
|
||||
}
|
||||
@@ -146,24 +149,10 @@ int CZNC::Loop() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_sISpoofFile.empty()) {
|
||||
CFile File(m_sISpoofFile);
|
||||
|
||||
if (File.Open(O_RDONLY)) {
|
||||
char buf[1024];
|
||||
memset((char*) buf, 0, 1024);
|
||||
File.Read(buf, 1023);
|
||||
File.Close();
|
||||
m_sOrigISpoof = buf;
|
||||
}
|
||||
|
||||
if (File.Open(O_WRONLY | O_TRUNC | O_CREAT)) {
|
||||
CString sData = m_sISpoofFormat.Token(0, false, "%") + pUser->GetIdent() + m_sISpoofFormat.Token(1, true, "%");
|
||||
File.Write(sData + "\n");
|
||||
File.Close();
|
||||
}
|
||||
|
||||
m_bISpoofLocked = true;
|
||||
if(!WriteISpoof(pUser)) {
|
||||
DEBUG_ONLY(cout << "ISpoof could not be written" << endl);
|
||||
pUser->PutStatus("ISpoof could not be written, retrying...");
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_ONLY(cout << "User [" << pUser->GetUserName() << "] is connecting to [" << pServer->GetName() << ":" << pServer->GetPort() << "] ..." << endl);
|
||||
@@ -190,19 +179,53 @@ int CZNC::Loop() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CZNC::ReleaseISpoof() {
|
||||
if (!m_sISpoofFile.empty()) {
|
||||
CFile File(m_sISpoofFile);
|
||||
bool CZNC::WriteISpoof(CUser* pUser) {
|
||||
if(m_pISpoofLockFile != NULL)
|
||||
return false;
|
||||
|
||||
if (File.Open(O_WRONLY | O_TRUNC | O_CREAT)) {
|
||||
if (!m_sISpoofFile.empty()) {
|
||||
m_pISpoofLockFile = new CLockFile;
|
||||
if(!m_pISpoofLockFile->TryExLock(m_sISpoofFile, 50, true)) {
|
||||
delete m_pISpoofLockFile;
|
||||
m_pISpoofLockFile = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
CFile File(m_pISpoofLockFile->GetFD(), m_pISpoofLockFile->GetFileName());
|
||||
|
||||
char buf[1024];
|
||||
memset((char*) buf, 0, 1024);
|
||||
File.Read(buf, 1023);
|
||||
m_sOrigISpoof = buf;
|
||||
|
||||
if (!File.Seek(0) || !File.Truncate()) {
|
||||
delete m_pISpoofLockFile;
|
||||
m_pISpoofLockFile = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
CString sData = m_sISpoofFormat.Token(0, false, "%") + pUser->GetIdent() + m_sISpoofFormat.Token(1, true, "%");
|
||||
File.Write(sData + "\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CZNC::ReleaseISpoof() {
|
||||
if(m_pISpoofLockFile == NULL)
|
||||
return;
|
||||
|
||||
if (!m_sISpoofFile.empty()) {
|
||||
CFile File(m_pISpoofLockFile->GetFD(), m_pISpoofLockFile->GetFileName());
|
||||
|
||||
if (File.Seek(0) && File.Truncate()) {
|
||||
File.Write(m_sOrigISpoof);
|
||||
File.Close();
|
||||
}
|
||||
|
||||
m_sOrigISpoof = "";
|
||||
}
|
||||
|
||||
m_bISpoofLocked = false;
|
||||
delete m_pISpoofLockFile;
|
||||
m_pISpoofLockFile = NULL;
|
||||
}
|
||||
|
||||
bool CZNC::WritePidFile(int iPid) {
|
||||
@@ -289,7 +312,7 @@ bool CZNC::IsHostAllowed(const CString& sHostMask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CZNC::InitDirs(const CString& sArgvPath) {
|
||||
void CZNC::InitDirs(const CString& sArgvPath, const CString& sDataDir) {
|
||||
char buf[PATH_MAX];
|
||||
getcwd(buf, PATH_MAX);
|
||||
|
||||
@@ -308,7 +331,11 @@ void CZNC::InitDirs(const CString& sArgvPath) {
|
||||
m_sHomePath = m_sCurPath;
|
||||
}
|
||||
|
||||
m_sZNCPath = m_sHomePath + "/.znc";
|
||||
if (sDataDir.empty()) {
|
||||
m_sZNCPath = m_sHomePath + "/.znc";
|
||||
} else {
|
||||
m_sZNCPath = sDataDir;
|
||||
}
|
||||
|
||||
// Other dirs that we use
|
||||
m_sConfPath = m_sZNCPath + "/configs";
|
||||
@@ -1090,6 +1117,10 @@ bool CZNC::ParseConfig(const CString& sConfig) {
|
||||
m_sISpoofFormat = sValue;
|
||||
continue;
|
||||
} else if (sName.CaseCmp("ISpoofFile") == 0) {
|
||||
if(sValue.Left(2) == "~/") {
|
||||
sValue.LeftChomp(2);
|
||||
sValue = GetHomePath() + "/" + sValue;
|
||||
}
|
||||
m_sISpoofFile = sValue;
|
||||
continue;
|
||||
} else if (sName.CaseCmp("MOTD") == 0) {
|
||||
|
||||
@@ -88,13 +88,14 @@ public:
|
||||
|
||||
void DeleteUsers();
|
||||
int Loop();
|
||||
bool WriteISpoof(CUser* pUser);
|
||||
void ReleaseISpoof();
|
||||
bool WritePidFile(int iPid);
|
||||
CUser* GetUser(const CString& sUser);
|
||||
Csock* FindSockByName(const CString& sSockName);
|
||||
bool ParseConfig(const CString& sConfig);
|
||||
bool IsHostAllowed(const CString& sHostMask);
|
||||
void InitDirs(const CString& sArgvPath);
|
||||
void InitDirs(const CString& sArgvPath, const CString& sDataDir);
|
||||
bool OnBoot();
|
||||
CString ExpandConfigPath(const CString& sConfigFile);
|
||||
bool WriteNewConfig(const CString& sConfig);
|
||||
@@ -172,7 +173,7 @@ protected:
|
||||
VCString m_vsVHosts;
|
||||
VCString m_vsMotd;
|
||||
CLockFile m_LockFile;
|
||||
bool m_bISpoofLocked;
|
||||
CLockFile* m_pISpoofLockFile;
|
||||
map<CString,CUser*>::iterator m_itUserIter; // This needs to be reset to m_msUsers.begin() if anything is added or removed to the map
|
||||
#ifdef _MODULES
|
||||
CGlobalModules* m_pModules;
|
||||
@@ -219,7 +220,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN, pClient, m_bIPV6);
|
||||
return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN, pClient, 0, m_bIPV6);
|
||||
}
|
||||
private:
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user