diff --git a/.clang-format b/.clang-format index ed804f1b..d479d561 100644 --- a/.clang-format +++ b/.clang-format @@ -2,7 +2,6 @@ BasedOnStyle: Google Standard: Cpp11 -UseTab: ForIndentation IndentWidth: 4 TabWidth: 4 AccessModifierOffset: -2 diff --git a/include/znc/Buffer.h b/include/znc/Buffer.h index 7afe58ee..5938c9c6 100644 --- a/include/znc/Buffer.h +++ b/include/znc/Buffer.h @@ -29,86 +29,86 @@ class CClient; class CBufLine { public: - CBufLine() : CBufLine("") { - throw 0; - } // shouldn't be called, but is needed for compilation - CBufLine(const CMessage& Format, const CString& sText = ""); - /// @deprecated - CBufLine(const CString& sFormat, const CString& sText = "", - const timeval* ts = nullptr, - const MCString& mssTags = MCString::EmptyMap); - ~CBufLine(); - CMessage ToMessage(const CClient& Client, const MCString& mssParams) const; - /// @deprecated Use ToMessage() instead - CString GetLine(const CClient& Client, const MCString& mssParams) const; - /// @deprecated - void UpdateTime(); + CBufLine() : CBufLine("") { + throw 0; + } // shouldn't be called, but is needed for compilation + CBufLine(const CMessage& Format, const CString& sText = ""); + /// @deprecated + CBufLine(const CString& sFormat, const CString& sText = "", + const timeval* ts = nullptr, + const MCString& mssTags = MCString::EmptyMap); + ~CBufLine(); + CMessage ToMessage(const CClient& Client, const MCString& mssParams) const; + /// @deprecated Use ToMessage() instead + CString GetLine(const CClient& Client, const MCString& mssParams) const; + /// @deprecated + void UpdateTime(); - bool Equals(const CMessage& Format) const { - return m_Message.Equals(Format); - } + bool Equals(const CMessage& Format) const { + return m_Message.Equals(Format); + } - // Setters - void SetFormat(const CString& sFormat) { m_Message.Parse(sFormat); } - void SetText(const CString& sText) { m_sText = sText; } - void SetTime(const timeval& ts) { m_Message.SetTime(ts); } - void SetTags(const MCString& mssTags) { m_Message.SetTags(mssTags); } - // !Setters + // Setters + void SetFormat(const CString& sFormat) { m_Message.Parse(sFormat); } + void SetText(const CString& sText) { m_sText = sText; } + void SetTime(const timeval& ts) { m_Message.SetTime(ts); } + void SetTags(const MCString& mssTags) { m_Message.SetTags(mssTags); } + // !Setters - // Getters - const CString& GetCommand() const { return m_Message.GetCommand(); } - CString GetFormat() const { - return m_Message.ToString(CMessage::ExcludeTags); - } - const CString& GetText() const { return m_sText; } - timeval GetTime() const { return m_Message.GetTime(); } - const MCString& GetTags() const { return m_Message.GetTags(); } - // !Getters + // Getters + const CString& GetCommand() const { return m_Message.GetCommand(); } + CString GetFormat() const { + return m_Message.ToString(CMessage::ExcludeTags); + } + const CString& GetText() const { return m_sText; } + timeval GetTime() const { return m_Message.GetTime(); } + const MCString& GetTags() const { return m_Message.GetTags(); } + // !Getters private: protected: - CMessage m_Message; - CString m_sText; + CMessage m_Message; + CString m_sText; }; class CBuffer : private std::deque { public: - CBuffer(unsigned int uLineCount = 100); - ~CBuffer(); + CBuffer(unsigned int uLineCount = 100); + ~CBuffer(); - size_type AddLine(const CMessage& Format, const CString& sText = ""); - size_type UpdateLine(const CString& sCommand, const CMessage& Format, - const CString& sText = ""); - size_type UpdateExactLine(const CMessage& Format, - const CString& sText = ""); + size_type AddLine(const CMessage& Format, const CString& sText = ""); + size_type UpdateLine(const CString& sCommand, const CMessage& Format, + const CString& sText = ""); + size_type UpdateExactLine(const CMessage& Format, + const CString& sText = ""); - size_type AddLine(const CString& sFormat, const CString& sText = "", - const timeval* ts = nullptr, - const MCString& mssTags = MCString::EmptyMap); - /// Same as AddLine, but replaces a line whose format string starts with sMatch if there is one. - size_type UpdateLine(const CString& sMatch, const CString& sFormat, - const CString& sText = ""); - /// Same as UpdateLine, but does nothing if this exact line already exists. - /// We need this because "/version" sends us the 005 raws again - size_type UpdateExactLine(const CString& sFormat, - const CString& sText = ""); - const CBufLine& GetBufLine(unsigned int uIdx) const; - CString GetLine(size_type uIdx, const CClient& Client, - const MCString& msParams = MCString::EmptyMap) const; - size_type Size() const { return size(); } - bool IsEmpty() const { return empty(); } - void Clear() { clear(); } + size_type AddLine(const CString& sFormat, const CString& sText = "", + const timeval* ts = nullptr, + const MCString& mssTags = MCString::EmptyMap); + /// Same as AddLine, but replaces a line whose format string starts with sMatch if there is one. + size_type UpdateLine(const CString& sMatch, const CString& sFormat, + const CString& sText = ""); + /// Same as UpdateLine, but does nothing if this exact line already exists. + /// We need this because "/version" sends us the 005 raws again + size_type UpdateExactLine(const CString& sFormat, + const CString& sText = ""); + const CBufLine& GetBufLine(unsigned int uIdx) const; + CString GetLine(size_type uIdx, const CClient& Client, + const MCString& msParams = MCString::EmptyMap) const; + size_type Size() const { return size(); } + bool IsEmpty() const { return empty(); } + void Clear() { clear(); } - // Setters - bool SetLineCount(unsigned int u, bool bForce = false); - // !Setters + // Setters + bool SetLineCount(unsigned int u, bool bForce = false); + // !Setters - // Getters - unsigned int GetLineCount() const { return m_uLineCount; } - // !Getters + // Getters + unsigned int GetLineCount() const { return m_uLineCount; } + // !Getters private: protected: - unsigned int m_uLineCount; + unsigned int m_uLineCount; }; #endif // !ZNC_BUFFER_H diff --git a/include/znc/Chan.h b/include/znc/Chan.h index f16552ce..fedfb2e7 100644 --- a/include/znc/Chan.h +++ b/include/znc/Chan.h @@ -33,178 +33,178 @@ class CFile; class CChan { public: - typedef enum { - Voice = '+', - HalfOp = '%', - Op = '@', - Admin = '!', - Owner = '*' - } EUserPerms; + typedef enum { + Voice = '+', + HalfOp = '%', + Op = '@', + Admin = '!', + Owner = '*' + } EUserPerms; - typedef enum { - M_Private = 'p', - M_Secret = 's', - M_Moderated = 'm', - M_InviteOnly = 'i', - M_NoMessages = 'n', - M_OpTopic = 't', - M_Limit = 'l', - M_Key = 'k', - M_Op = 'o', - M_Voice = 'v', - M_Ban = 'b', - M_Except = 'e' - } EModes; + typedef enum { + M_Private = 'p', + M_Secret = 's', + M_Moderated = 'm', + M_InviteOnly = 'i', + M_NoMessages = 'n', + M_OpTopic = 't', + M_Limit = 'l', + M_Key = 'k', + M_Op = 'o', + M_Voice = 'v', + M_Ban = 'b', + M_Except = 'e' + } EModes; - CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig, - CConfig* pConfig = nullptr); - ~CChan(); + CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig, + CConfig* pConfig = nullptr); + ~CChan(); - CChan(const CChan&) = delete; - CChan& operator=(const CChan&) = delete; + CChan(const CChan&) = delete; + CChan& operator=(const CChan&) = delete; - void Reset(); - CConfig ToConfig() const; - void Clone(CChan& chan); - void Cycle() const; - void JoinUser(const CString& sKey = ""); - void AttachUser(CClient* pClient = nullptr); - void DetachUser(); + void Reset(); + CConfig ToConfig() const; + void Clone(CChan& chan); + void Cycle() const; + void JoinUser(const CString& sKey = ""); + void AttachUser(CClient* pClient = nullptr); + void DetachUser(); - void OnWho(const CString& sNick, const CString& sIdent, - const CString& sHost); + void OnWho(const CString& sNick, const CString& sIdent, + const CString& sHost); - // Modes - void SetModes(const CString& s); - void ModeChange(const CString& sModes, const CNick* OpNick = nullptr); - bool AddMode(unsigned char uMode, const CString& sArg); - bool RemMode(unsigned char uMode); - CString GetModeString() const; - CString GetModeArg(CString& sArgs) const; - CString GetModeForNames() const; - // !Modes + // Modes + void SetModes(const CString& s); + void ModeChange(const CString& sModes, const CNick* OpNick = nullptr); + bool AddMode(unsigned char uMode, const CString& sArg); + bool RemMode(unsigned char uMode); + CString GetModeString() const; + CString GetModeArg(CString& sArgs) const; + CString GetModeForNames() const; + // !Modes - // Nicks - void ClearNicks(); - const CNick* FindNick(const CString& sNick) const; - CNick* FindNick(const CString& sNick); - int AddNicks(const CString& sNicks); - bool AddNick(const CString& sNick); - bool RemNick(const CString& sNick); - bool ChangeNick(const CString& sOldNick, const CString& sNewNick); - // !Nicks + // Nicks + void ClearNicks(); + const CNick* FindNick(const CString& sNick) const; + CNick* FindNick(const CString& sNick); + int AddNicks(const CString& sNicks); + bool AddNick(const CString& sNick); + bool RemNick(const CString& sNick); + bool ChangeNick(const CString& sOldNick, const CString& sNewNick); + // !Nicks - // Buffer - const CBuffer& GetBuffer() const { return m_Buffer; } - unsigned int GetBufferCount() const { return m_Buffer.GetLineCount(); } - bool SetBufferCount(unsigned int u, bool bForce = false) { - m_bHasBufferCountSet = true; - return m_Buffer.SetLineCount(u, bForce); - } - void InheritBufferCount(unsigned int u, bool bForce = false) { - if (!m_bHasBufferCountSet) m_Buffer.SetLineCount(u, bForce); - } - void ResetBufferCount(); - size_t AddBuffer(const CMessage& Format, const CString& sText = "") { - return m_Buffer.AddLine(Format, sText); - } - /// @deprecated - size_t AddBuffer(const CString& sFormat, const CString& sText = "", - const timeval* ts = nullptr, - const MCString& mssTags = MCString::EmptyMap) { - return m_Buffer.AddLine(sFormat, sText, ts, mssTags); - } - void ClearBuffer() { m_Buffer.Clear(); } - void SendBuffer(CClient* pClient); - void SendBuffer(CClient* pClient, const CBuffer& Buffer); - // !Buffer + // Buffer + const CBuffer& GetBuffer() const { return m_Buffer; } + unsigned int GetBufferCount() const { return m_Buffer.GetLineCount(); } + bool SetBufferCount(unsigned int u, bool bForce = false) { + m_bHasBufferCountSet = true; + return m_Buffer.SetLineCount(u, bForce); + } + void InheritBufferCount(unsigned int u, bool bForce = false) { + if (!m_bHasBufferCountSet) m_Buffer.SetLineCount(u, bForce); + } + void ResetBufferCount(); + size_t AddBuffer(const CMessage& Format, const CString& sText = "") { + return m_Buffer.AddLine(Format, sText); + } + /// @deprecated + size_t AddBuffer(const CString& sFormat, const CString& sText = "", + const timeval* ts = nullptr, + const MCString& mssTags = MCString::EmptyMap) { + return m_Buffer.AddLine(sFormat, sText, ts, mssTags); + } + void ClearBuffer() { m_Buffer.Clear(); } + void SendBuffer(CClient* pClient); + void SendBuffer(CClient* pClient, const CBuffer& Buffer); + // !Buffer - // m_Nick wrappers - CString GetPermStr() const { return m_Nick.GetPermStr(); } - bool HasPerm(unsigned char uPerm) const { return m_Nick.HasPerm(uPerm); } - bool AddPerm(unsigned char uPerm) { return m_Nick.AddPerm(uPerm); } - bool RemPerm(unsigned char uPerm) { return m_Nick.RemPerm(uPerm); } - // !wrappers + // m_Nick wrappers + CString GetPermStr() const { return m_Nick.GetPermStr(); } + bool HasPerm(unsigned char uPerm) const { return m_Nick.HasPerm(uPerm); } + bool AddPerm(unsigned char uPerm) { return m_Nick.AddPerm(uPerm); } + bool RemPerm(unsigned char uPerm) { return m_Nick.RemPerm(uPerm); } + // !wrappers - // Setters - void SetModeKnown(bool b) { m_bModeKnown = b; } - void SetIsOn(bool b) { - m_bIsOn = b; - if (!b) { - Reset(); - } - } - void SetKey(const CString& s); - void SetTopic(const CString& s) { m_sTopic = s; } - void SetTopicOwner(const CString& s) { m_sTopicOwner = s; } - void SetTopicDate(unsigned long u) { m_ulTopicDate = u; } - void SetDefaultModes(const CString& s) { m_sDefaultModes = s; } - void SetAutoClearChanBuffer(bool b); - void InheritAutoClearChanBuffer(bool b); - void ResetAutoClearChanBuffer(); - void SetDetached(bool b = true) { m_bDetached = b; } - void SetInConfig(bool b); - void SetCreationDate(unsigned long u) { m_ulCreationDate = u; } - void Disable() { m_bDisabled = true; } - void Enable(); - void IncJoinTries() { m_uJoinTries++; } - void ResetJoinTries() { m_uJoinTries = 0; } - // !Setters + // Setters + void SetModeKnown(bool b) { m_bModeKnown = b; } + void SetIsOn(bool b) { + m_bIsOn = b; + if (!b) { + Reset(); + } + } + void SetKey(const CString& s); + void SetTopic(const CString& s) { m_sTopic = s; } + void SetTopicOwner(const CString& s) { m_sTopicOwner = s; } + void SetTopicDate(unsigned long u) { m_ulTopicDate = u; } + void SetDefaultModes(const CString& s) { m_sDefaultModes = s; } + void SetAutoClearChanBuffer(bool b); + void InheritAutoClearChanBuffer(bool b); + void ResetAutoClearChanBuffer(); + void SetDetached(bool b = true) { m_bDetached = b; } + void SetInConfig(bool b); + void SetCreationDate(unsigned long u) { m_ulCreationDate = u; } + void Disable() { m_bDisabled = true; } + void Enable(); + void IncJoinTries() { m_uJoinTries++; } + void ResetJoinTries() { m_uJoinTries = 0; } + // !Setters - // Getters - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - bool IsModeKnown() const { return m_bModeKnown; } - bool HasMode(unsigned char uMode) const; - CString GetOptions() const; - CString GetModeArg(unsigned char uMode) const; - std::map GetPermCounts() const; - bool IsOn() const { return m_bIsOn; } - const CString& GetName() const { return m_sName; } - const std::map& GetModes() const { - return m_musModes; - } - const CString& GetKey() const { return m_sKey; } - const CString& GetTopic() const { return m_sTopic; } - const CString& GetTopicOwner() const { return m_sTopicOwner; } - unsigned long GetTopicDate() const { return m_ulTopicDate; } - const CString& GetDefaultModes() const { return m_sDefaultModes; } - const std::map& GetNicks() const { return m_msNicks; } - size_t GetNickCount() const { return m_msNicks.size(); } - bool AutoClearChanBuffer() const { return m_bAutoClearChanBuffer; } - bool IsDetached() const { return m_bDetached; } - bool InConfig() const { return m_bInConfig; } - unsigned long GetCreationDate() const { return m_ulCreationDate; } - bool IsDisabled() const { return m_bDisabled; } - unsigned int GetJoinTries() const { return m_uJoinTries; } - bool HasBufferCountSet() const { return m_bHasBufferCountSet; } - bool HasAutoClearChanBufferSet() const { - return m_bHasAutoClearChanBufferSet; - } - // !Getters + // Getters + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + bool IsModeKnown() const { return m_bModeKnown; } + bool HasMode(unsigned char uMode) const; + CString GetOptions() const; + CString GetModeArg(unsigned char uMode) const; + std::map GetPermCounts() const; + bool IsOn() const { return m_bIsOn; } + const CString& GetName() const { return m_sName; } + const std::map& GetModes() const { + return m_musModes; + } + const CString& GetKey() const { return m_sKey; } + const CString& GetTopic() const { return m_sTopic; } + const CString& GetTopicOwner() const { return m_sTopicOwner; } + unsigned long GetTopicDate() const { return m_ulTopicDate; } + const CString& GetDefaultModes() const { return m_sDefaultModes; } + const std::map& GetNicks() const { return m_msNicks; } + size_t GetNickCount() const { return m_msNicks.size(); } + bool AutoClearChanBuffer() const { return m_bAutoClearChanBuffer; } + bool IsDetached() const { return m_bDetached; } + bool InConfig() const { return m_bInConfig; } + unsigned long GetCreationDate() const { return m_ulCreationDate; } + bool IsDisabled() const { return m_bDisabled; } + unsigned int GetJoinTries() const { return m_uJoinTries; } + bool HasBufferCountSet() const { return m_bHasBufferCountSet; } + bool HasAutoClearChanBufferSet() const { + return m_bHasAutoClearChanBufferSet; + } + // !Getters private: protected: - bool m_bDetached; - bool m_bIsOn; - bool m_bAutoClearChanBuffer; - bool m_bInConfig; - bool m_bDisabled; - bool m_bHasBufferCountSet; - bool m_bHasAutoClearChanBufferSet; - CString m_sName; - CString m_sKey; - CString m_sTopic; - CString m_sTopicOwner; - unsigned long m_ulTopicDate; - unsigned long m_ulCreationDate; - CIRCNetwork* m_pNetwork; - CNick m_Nick; - unsigned int m_uJoinTries; - CString m_sDefaultModes; - std::map m_msNicks; // Todo: make this caseless (irc style) - CBuffer m_Buffer; + bool m_bDetached; + bool m_bIsOn; + bool m_bAutoClearChanBuffer; + bool m_bInConfig; + bool m_bDisabled; + bool m_bHasBufferCountSet; + bool m_bHasAutoClearChanBufferSet; + CString m_sName; + CString m_sKey; + CString m_sTopic; + CString m_sTopicOwner; + unsigned long m_ulTopicDate; + unsigned long m_ulCreationDate; + CIRCNetwork* m_pNetwork; + CNick m_Nick; + unsigned int m_uJoinTries; + CString m_sDefaultModes; + std::map m_msNicks; // Todo: make this caseless (irc style) + CBuffer m_Buffer; - bool m_bModeKnown; - std::map m_musModes; + bool m_bModeKnown; + std::map m_musModes; }; #endif // !ZNC_CHAN_H diff --git a/include/znc/Client.h b/include/znc/Client.h index 9a4eac1e..73c1dd11 100644 --- a/include/znc/Client.h +++ b/include/znc/Client.h @@ -36,162 +36,162 @@ class CChan; class CAuthBase { public: - CAuthBase(const CString& sUsername, const CString& sPassword, - CZNCSock* pSock) - : m_sUsername(sUsername), m_sPassword(sPassword), m_pSock(pSock) {} + CAuthBase(const CString& sUsername, const CString& sPassword, + CZNCSock* pSock) + : m_sUsername(sUsername), m_sPassword(sPassword), m_pSock(pSock) {} - virtual ~CAuthBase() {} + virtual ~CAuthBase() {} - CAuthBase(const CAuthBase&) = delete; - CAuthBase& operator=(const CAuthBase&) = delete; + CAuthBase(const CAuthBase&) = delete; + CAuthBase& operator=(const CAuthBase&) = delete; - virtual void SetLoginInfo(const CString& sUsername, - const CString& sPassword, CZNCSock* pSock) { - m_sUsername = sUsername; - m_sPassword = sPassword; - m_pSock = pSock; - } + virtual void SetLoginInfo(const CString& sUsername, + const CString& sPassword, CZNCSock* pSock) { + m_sUsername = sUsername; + m_sPassword = sPassword; + m_pSock = pSock; + } - void AcceptLogin(CUser& User); - void RefuseLogin(const CString& sReason); + void AcceptLogin(CUser& User); + void RefuseLogin(const CString& sReason); - const CString& GetUsername() const { return m_sUsername; } - const CString& GetPassword() const { return m_sPassword; } - Csock* GetSocket() const { return m_pSock; } - CString GetRemoteIP() const; + const CString& GetUsername() const { return m_sUsername; } + const CString& GetPassword() const { return m_sPassword; } + Csock* GetSocket() const { return m_pSock; } + CString GetRemoteIP() const; - // Invalidate this CAuthBase instance which means it will no longer use - // m_pSock and AcceptLogin() or RefusedLogin() will have no effect. - virtual void Invalidate(); + // Invalidate this CAuthBase instance which means it will no longer use + // m_pSock and AcceptLogin() or RefusedLogin() will have no effect. + virtual void Invalidate(); protected: - virtual void AcceptedLogin(CUser& User) = 0; - virtual void RefusedLogin(const CString& sReason) = 0; + virtual void AcceptedLogin(CUser& User) = 0; + virtual void RefusedLogin(const CString& sReason) = 0; private: - CString m_sUsername; - CString m_sPassword; - CZNCSock* m_pSock; + CString m_sUsername; + CString m_sPassword; + CZNCSock* m_pSock; }; class CClientAuth : public CAuthBase { public: - CClientAuth(CClient* pClient, const CString& sUsername, - const CString& sPassword); - virtual ~CClientAuth() {} + CClientAuth(CClient* pClient, const CString& sUsername, + const CString& sPassword); + virtual ~CClientAuth() {} - CClientAuth(const CClientAuth&) = delete; - CClientAuth& operator=(const CClientAuth&) = delete; + CClientAuth(const CClientAuth&) = delete; + CClientAuth& operator=(const CClientAuth&) = delete; - void Invalidate() override { - m_pClient = nullptr; - CAuthBase::Invalidate(); - } - void AcceptedLogin(CUser& User) override; - void RefusedLogin(const CString& sReason) override; + void Invalidate() override { + m_pClient = nullptr; + CAuthBase::Invalidate(); + } + void AcceptedLogin(CUser& User) override; + void RefusedLogin(const CString& sReason) override; private: protected: - CClient* m_pClient; + CClient* m_pClient; }; class CClient : public CIRCSocket { public: - CClient() - : CIRCSocket(), - m_bGotPass(false), - m_bGotNick(false), - m_bGotUser(false), - m_bInCap(false), - m_bCapNotify(false), - m_bAwayNotify(false), - m_bAccountNotify(false), - m_bExtendedJoin(false), - m_bNamesx(false), - m_bUHNames(false), - m_bAway(false), - m_bServerTime(false), - m_bBatch(false), - m_bEchoMessage(false), - m_bSelfMessage(false), - m_bPlaybackActive(false), - m_pUser(nullptr), - m_pNetwork(nullptr), - m_sNick("unknown-nick"), - m_sPass(""), - m_sUser(""), - m_sNetwork(""), - m_sIdentifier(""), - m_spAuth(), - m_ssAcceptedCaps(), - m_mCoreCaps({ - {"multi-prefix", - {false, [this](bool bVal) { m_bNamesx = bVal; }}}, - {"userhost-in-names", - {false, [this](bool bVal) { m_bUHNames = bVal; }}}, - {"echo-message", - {false, [this](bool bVal) { m_bEchoMessage = bVal; }}}, - {"server-time", - {false, [this](bool bVal) { m_bServerTime = bVal; }}}, - {"batch", {false, [this](bool bVal) { m_bBatch = bVal; }}}, - {"cap-notify", - {false, [this](bool bVal) { m_bCapNotify = bVal; }}}, - {"away-notify", - {true, [this](bool bVal) { m_bAwayNotify = bVal; }}}, - {"account-notify", - {true, [this](bool bVal) { m_bAccountNotify = bVal; }}}, - {"extended-join", - {true, [this](bool bVal) { m_bExtendedJoin = bVal; }}}, - }) { - EnableReadLine(); - // RFC says a line can have 512 chars max, but we are - // a little more gentle ;) - SetMaxBufferThreshold(1024); + CClient() + : CIRCSocket(), + m_bGotPass(false), + m_bGotNick(false), + m_bGotUser(false), + m_bInCap(false), + m_bCapNotify(false), + m_bAwayNotify(false), + m_bAccountNotify(false), + m_bExtendedJoin(false), + m_bNamesx(false), + m_bUHNames(false), + m_bAway(false), + m_bServerTime(false), + m_bBatch(false), + m_bEchoMessage(false), + m_bSelfMessage(false), + m_bPlaybackActive(false), + m_pUser(nullptr), + m_pNetwork(nullptr), + m_sNick("unknown-nick"), + m_sPass(""), + m_sUser(""), + m_sNetwork(""), + m_sIdentifier(""), + m_spAuth(), + m_ssAcceptedCaps(), + m_mCoreCaps({ + {"multi-prefix", + {false, [this](bool bVal) { m_bNamesx = bVal; }}}, + {"userhost-in-names", + {false, [this](bool bVal) { m_bUHNames = bVal; }}}, + {"echo-message", + {false, [this](bool bVal) { m_bEchoMessage = bVal; }}}, + {"server-time", + {false, [this](bool bVal) { m_bServerTime = bVal; }}}, + {"batch", {false, [this](bool bVal) { m_bBatch = bVal; }}}, + {"cap-notify", + {false, [this](bool bVal) { m_bCapNotify = bVal; }}}, + {"away-notify", + {true, [this](bool bVal) { m_bAwayNotify = bVal; }}}, + {"account-notify", + {true, [this](bool bVal) { m_bAccountNotify = bVal; }}}, + {"extended-join", + {true, [this](bool bVal) { m_bExtendedJoin = bVal; }}}, + }) { + EnableReadLine(); + // RFC says a line can have 512 chars max, but we are + // a little more gentle ;) + SetMaxBufferThreshold(1024); - // For compatibility with older clients - m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"]; - m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"]; - m_mCoreCaps["znc.in/self-message"] = { - false, [this](bool bVal) { m_bSelfMessage = bVal; }}; - } + // For compatibility with older clients + m_mCoreCaps["znc.in/server-time-iso"] = m_mCoreCaps["server-time"]; + m_mCoreCaps["znc.in/batch"] = m_mCoreCaps["batch"]; + m_mCoreCaps["znc.in/self-message"] = { + false, [this](bool bVal) { m_bSelfMessage = bVal; }}; + } - virtual ~CClient(); + virtual ~CClient(); - CClient(const CClient&) = delete; - CClient& operator=(const CClient&) = delete; + CClient(const CClient&) = delete; + CClient& operator=(const CClient&) = delete; - void SendRequiredPasswordNotice(); - void AcceptLogin(CUser& User); - void RefuseLogin(const CString& sReason); + void SendRequiredPasswordNotice(); + void AcceptLogin(CUser& User); + void RefuseLogin(const CString& sReason); - CString GetNick(bool bAllowIRCNick = true) const; - CString GetNickMask() const; - CString GetIdentifier() const { return m_sIdentifier; } - bool HasCapNotify() const { return m_bCapNotify; } - bool HasAwayNotify() const { return m_bAwayNotify; } - bool HasAccountNotify() const { return m_bAccountNotify; } - bool HasExtendedJoin() const { return m_bExtendedJoin; } - bool HasNamesx() const { return m_bNamesx; } - bool HasUHNames() const { return m_bUHNames; } - bool IsAway() const { return m_bAway; } - bool HasServerTime() const { return m_bServerTime; } - bool HasBatch() const { return m_bBatch; } - bool HasEchoMessage() const { return m_bEchoMessage; } - bool HasSelfMessage() const { return m_bSelfMessage; } + CString GetNick(bool bAllowIRCNick = true) const; + CString GetNickMask() const; + CString GetIdentifier() const { return m_sIdentifier; } + bool HasCapNotify() const { return m_bCapNotify; } + bool HasAwayNotify() const { return m_bAwayNotify; } + bool HasAccountNotify() const { return m_bAccountNotify; } + bool HasExtendedJoin() const { return m_bExtendedJoin; } + bool HasNamesx() const { return m_bNamesx; } + bool HasUHNames() const { return m_bUHNames; } + bool IsAway() const { return m_bAway; } + bool HasServerTime() const { return m_bServerTime; } + bool HasBatch() const { return m_bBatch; } + bool HasEchoMessage() const { return m_bEchoMessage; } + bool HasSelfMessage() const { return m_bSelfMessage; } - static bool IsValidIdentifier(const CString& sIdentifier); + static bool IsValidIdentifier(const CString& sIdentifier); - void UserCommand(CString& sLine); - void UserPortCommand(CString& sLine); - void StatusCTCP(const CString& sCommand); - void BouncedOff(); - bool IsAttached() const { return m_pUser != nullptr; } + void UserCommand(CString& sLine); + void UserPortCommand(CString& sLine); + void StatusCTCP(const CString& sCommand); + void BouncedOff(); + bool IsAttached() const { return m_pUser != nullptr; } - bool IsPlaybackActive() const { return m_bPlaybackActive; } - void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; } + bool IsPlaybackActive() const { return m_bPlaybackActive; } + void SetPlaybackActive(bool bActive) { m_bPlaybackActive = bActive; } - void PutIRC(const CString& sLine); - /** Sends a raw data line to the client. + void PutIRC(const CString& sLine); + /** Sends a raw data line to the client. * @param sLine The line to be sent. * * The line is first passed \e unmodified to the \ref CModule::OnSendToClient() @@ -200,8 +200,8 @@ class CClient : public CIRCSocket { * These lines appear in the debug output in the following syntax: * \code [time] (user/network) ZNC -> CLI [line] \endcode */ - void PutClient(const CString& sLine); - /** Sends a message to the client. + void PutClient(const CString& sLine); + /** Sends a message to the client. * @param Message The message to be sent. * @note Only known and compatible messages and tags are sent. * @return \c true if the message was sent, or \c false if it was ignored. @@ -247,105 +247,105 @@ class CClient : public CIRCSocket { * pClient->PutClient(Message.ToString()); * \endcode */ - bool PutClient(const CMessage& Message); - unsigned int PutStatus(const CTable& table); - void PutStatus(const CString& sLine); - void PutStatusNotice(const CString& sLine); - void PutModule(const CString& sModule, const CString& sLine); - void PutModNotice(const CString& sModule, const CString& sLine); + bool PutClient(const CMessage& Message); + unsigned int PutStatus(const CTable& table); + void PutStatus(const CString& sLine); + void PutStatusNotice(const CString& sLine); + void PutModule(const CString& sModule, const CString& sLine); + void PutModNotice(const CString& sModule, const CString& sLine); - bool IsCapEnabled(const CString& sCap) const { - return 1 == m_ssAcceptedCaps.count(sCap); - } + bool IsCapEnabled(const CString& sCap) const { + return 1 == m_ssAcceptedCaps.count(sCap); + } - void NotifyServerDependentCaps(const SCString& ssCaps); - void ClearServerDependentCaps(); + void NotifyServerDependentCaps(const SCString& ssCaps); + void ClearServerDependentCaps(); - void ReadLine(const CString& sData) override; - bool SendMotd(); - void HelpUser(const CString& sFilter = ""); - void AuthUser(); - void Connected() override; - void Timeout() override; - void Disconnected() override; - void ConnectionRefused() override; - void ReachedMaxBuffer() override; + void ReadLine(const CString& sData) override; + bool SendMotd(); + void HelpUser(const CString& sFilter = ""); + void AuthUser(); + void Connected() override; + void Timeout() override; + void Disconnected() override; + void ConnectionRefused() override; + void ReachedMaxBuffer() override; - void SetNick(const CString& s); - void SetAway(bool bAway) { m_bAway = bAway; } - CUser* GetUser() const { return m_pUser; } - void SetNetwork(CIRCNetwork* pNetwork, bool bDisconnect = true, - bool bReconnect = true); - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - const std::vector& GetClients() const; - const CIRCSock* GetIRCSock() const; - CIRCSock* GetIRCSock(); - CString GetFullName() const; + void SetNick(const CString& s); + void SetAway(bool bAway) { m_bAway = bAway; } + CUser* GetUser() const { return m_pUser; } + void SetNetwork(CIRCNetwork* pNetwork, bool bDisconnect = true, + bool bReconnect = true); + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + const std::vector& GetClients() const; + const CIRCSock* GetIRCSock() const; + CIRCSock* GetIRCSock(); + CString GetFullName() const; private: - void HandleCap(const CMessage& Message); - void RespondCap(const CString& sResponse); - void ParsePass(const CString& sAuthLine); - void ParseUser(const CString& sAuthLine); - void ParseIdentifier(const CString& sAuthLine); + void HandleCap(const CMessage& Message); + void RespondCap(const CString& sResponse); + void ParsePass(const CString& sAuthLine); + void ParseUser(const CString& sAuthLine); + void ParseIdentifier(const CString& sAuthLine); - template - void AddBuffer(const T& Message); - void EchoMessage(const CMessage& Message); + template + void AddBuffer(const T& Message); + void EchoMessage(const CMessage& Message); - std::set MatchChans(const CString& sPatterns) const; - unsigned int AttachChans(const std::set& sChans); - unsigned int DetachChans(const std::set& sChans); + std::set MatchChans(const CString& sPatterns) const; + unsigned int AttachChans(const std::set& sChans); + unsigned int DetachChans(const std::set& sChans); - bool OnActionMessage(CActionMessage& Message); - bool OnCTCPMessage(CCTCPMessage& Message); - bool OnJoinMessage(CJoinMessage& Message); - bool OnModeMessage(CModeMessage& Message); - bool OnNoticeMessage(CNoticeMessage& Message); - bool OnPartMessage(CPartMessage& Message); - bool OnPingMessage(CMessage& Message); - bool OnPongMessage(CMessage& Message); - bool OnQuitMessage(CQuitMessage& Message); - bool OnTextMessage(CTextMessage& Message); - bool OnTopicMessage(CTopicMessage& Message); - bool OnOtherMessage(CMessage& Message); + bool OnActionMessage(CActionMessage& Message); + bool OnCTCPMessage(CCTCPMessage& Message); + bool OnJoinMessage(CJoinMessage& Message); + bool OnModeMessage(CModeMessage& Message); + bool OnNoticeMessage(CNoticeMessage& Message); + bool OnPartMessage(CPartMessage& Message); + bool OnPingMessage(CMessage& Message); + bool OnPongMessage(CMessage& Message); + bool OnQuitMessage(CQuitMessage& Message); + bool OnTextMessage(CTextMessage& Message); + bool OnTopicMessage(CTopicMessage& Message); + bool OnOtherMessage(CMessage& Message); protected: - bool m_bGotPass; - bool m_bGotNick; - bool m_bGotUser; - bool m_bInCap; - bool m_bCapNotify; - bool m_bAwayNotify; - bool m_bAccountNotify; - bool m_bExtendedJoin; - bool m_bNamesx; - bool m_bUHNames; - bool m_bAway; - bool m_bServerTime; - bool m_bBatch; - bool m_bEchoMessage; - bool m_bSelfMessage; - bool m_bPlaybackActive; - CUser* m_pUser; - CIRCNetwork* m_pNetwork; - CString m_sNick; - CString m_sPass; - CString m_sUser; - CString m_sNetwork; - CString m_sIdentifier; - std::shared_ptr m_spAuth; - SCString m_ssAcceptedCaps; - // The capabilities supported by the ZNC core - capability names mapped - // to a pair which contains a bool describing whether the capability is - // server-dependent, and a capability value change handler. - std::map>> - m_mCoreCaps; - // A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed - // in CAP LS and may be notified to the client with CAP NEW (cap-notify). - SCString m_ssServerDependentCaps; + bool m_bGotPass; + bool m_bGotNick; + bool m_bGotUser; + bool m_bInCap; + bool m_bCapNotify; + bool m_bAwayNotify; + bool m_bAccountNotify; + bool m_bExtendedJoin; + bool m_bNamesx; + bool m_bUHNames; + bool m_bAway; + bool m_bServerTime; + bool m_bBatch; + bool m_bEchoMessage; + bool m_bSelfMessage; + bool m_bPlaybackActive; + CUser* m_pUser; + CIRCNetwork* m_pNetwork; + CString m_sNick; + CString m_sPass; + CString m_sUser; + CString m_sNetwork; + CString m_sIdentifier; + std::shared_ptr m_spAuth; + SCString m_ssAcceptedCaps; + // The capabilities supported by the ZNC core - capability names mapped + // to a pair which contains a bool describing whether the capability is + // server-dependent, and a capability value change handler. + std::map>> + m_mCoreCaps; + // A subset of CIRCSock::GetAcceptedCaps(), the caps that can be listed + // in CAP LS and may be notified to the client with CAP NEW (cap-notify). + SCString m_ssServerDependentCaps; - friend class ClientTest; + friend class ClientTest; }; #endif // !ZNC_CLIENT_H diff --git a/include/znc/Config.h b/include/znc/Config.h index a0be08e6..f5de5cbb 100644 --- a/include/znc/Config.h +++ b/include/znc/Config.h @@ -24,150 +24,150 @@ class CFile; class CConfig; struct CConfigEntry { - CConfigEntry(); - CConfigEntry(const CConfig& Config); - CConfigEntry(const CConfigEntry& other); - ~CConfigEntry(); - CConfigEntry& operator=(const CConfigEntry& other); + CConfigEntry(); + CConfigEntry(const CConfig& Config); + CConfigEntry(const CConfigEntry& other); + ~CConfigEntry(); + CConfigEntry& operator=(const CConfigEntry& other); - CConfig* m_pSubConfig; + CConfig* m_pSubConfig; }; class CConfig { public: - CConfig() : m_ConfigEntries(), m_SubConfigs() {} + CConfig() : m_ConfigEntries(), m_SubConfigs() {} - typedef std::map EntryMap; - typedef std::map SubConfig; - typedef std::map SubConfigMap; + typedef std::map EntryMap; + typedef std::map SubConfig; + typedef std::map SubConfigMap; - typedef EntryMap::const_iterator EntryMapIterator; - typedef SubConfigMap::const_iterator SubConfigMapIterator; + typedef EntryMap::const_iterator EntryMapIterator; + typedef SubConfigMap::const_iterator SubConfigMapIterator; - EntryMapIterator BeginEntries() const { return m_ConfigEntries.begin(); } - EntryMapIterator EndEntries() const { return m_ConfigEntries.end(); } + EntryMapIterator BeginEntries() const { return m_ConfigEntries.begin(); } + EntryMapIterator EndEntries() const { return m_ConfigEntries.end(); } - SubConfigMapIterator BeginSubConfigs() const { - return m_SubConfigs.begin(); - } - SubConfigMapIterator EndSubConfigs() const { return m_SubConfigs.end(); } + SubConfigMapIterator BeginSubConfigs() const { + return m_SubConfigs.begin(); + } + SubConfigMapIterator EndSubConfigs() const { return m_SubConfigs.end(); } - void AddKeyValuePair(const CString& sName, const CString& sValue) { - if (sName.empty() || sValue.empty()) { - return; - } + void AddKeyValuePair(const CString& sName, const CString& sValue) { + if (sName.empty() || sValue.empty()) { + return; + } - m_ConfigEntries[sName].push_back(sValue); - } + m_ConfigEntries[sName].push_back(sValue); + } - bool AddSubConfig(const CString& sTag, const CString& sName, - CConfig Config) { - SubConfig& conf = m_SubConfigs[sTag]; - SubConfig::const_iterator it = conf.find(sName); + bool AddSubConfig(const CString& sTag, const CString& sName, + CConfig Config) { + SubConfig& conf = m_SubConfigs[sTag]; + SubConfig::const_iterator it = conf.find(sName); - if (it != conf.end()) { - return false; - } + if (it != conf.end()) { + return false; + } - conf[sName] = Config; - return true; - } + conf[sName] = Config; + return true; + } - bool FindStringVector(const CString& sName, VCString& vsList, - bool bErase = true) { - EntryMap::iterator it = m_ConfigEntries.find(sName); - vsList.clear(); - if (it == m_ConfigEntries.end()) return false; - vsList = it->second; + bool FindStringVector(const CString& sName, VCString& vsList, + bool bErase = true) { + EntryMap::iterator it = m_ConfigEntries.find(sName); + vsList.clear(); + if (it == m_ConfigEntries.end()) return false; + vsList = it->second; - if (bErase) { - m_ConfigEntries.erase(it); - } + if (bErase) { + m_ConfigEntries.erase(it); + } - return true; - } + return true; + } - bool FindStringEntry(const CString& sName, CString& sRes, - const CString& sDefault = "") { - EntryMap::iterator it = m_ConfigEntries.find(sName); - sRes = sDefault; - if (it == m_ConfigEntries.end() || it->second.empty()) return false; - sRes = it->second.front(); - it->second.erase(it->second.begin()); - if (it->second.empty()) m_ConfigEntries.erase(it); - return true; - } + bool FindStringEntry(const CString& sName, CString& sRes, + const CString& sDefault = "") { + EntryMap::iterator it = m_ConfigEntries.find(sName); + sRes = sDefault; + if (it == m_ConfigEntries.end() || it->second.empty()) return false; + sRes = it->second.front(); + it->second.erase(it->second.begin()); + if (it->second.empty()) m_ConfigEntries.erase(it); + return true; + } - bool FindBoolEntry(const CString& sName, bool& bRes, - bool bDefault = false) { - CString s; - if (FindStringEntry(sName, s)) { - bRes = s.ToBool(); - return true; - } - bRes = bDefault; - return false; - } + bool FindBoolEntry(const CString& sName, bool& bRes, + bool bDefault = false) { + CString s; + if (FindStringEntry(sName, s)) { + bRes = s.ToBool(); + return true; + } + bRes = bDefault; + return false; + } - bool FindUIntEntry(const CString& sName, unsigned int& uRes, - unsigned int uDefault = 0) { - CString s; - if (FindStringEntry(sName, s)) { - uRes = s.ToUInt(); - return true; - } - uRes = uDefault; - return false; - } + bool FindUIntEntry(const CString& sName, unsigned int& uRes, + unsigned int uDefault = 0) { + CString s; + if (FindStringEntry(sName, s)) { + uRes = s.ToUInt(); + return true; + } + uRes = uDefault; + return false; + } - bool FindUShortEntry(const CString& sName, unsigned short& uRes, - unsigned short uDefault = 0) { - CString s; - if (FindStringEntry(sName, s)) { - uRes = s.ToUShort(); - return true; - } - uRes = uDefault; - return false; - } + bool FindUShortEntry(const CString& sName, unsigned short& uRes, + unsigned short uDefault = 0) { + CString s; + if (FindStringEntry(sName, s)) { + uRes = s.ToUShort(); + return true; + } + uRes = uDefault; + return false; + } - bool FindDoubleEntry(const CString& sName, double& fRes, - double fDefault = 0) { - CString s; - if (FindStringEntry(sName, s)) { - fRes = s.ToDouble(); - return true; - } - fRes = fDefault; - return false; - } + bool FindDoubleEntry(const CString& sName, double& fRes, + double fDefault = 0) { + CString s; + if (FindStringEntry(sName, s)) { + fRes = s.ToDouble(); + return true; + } + fRes = fDefault; + return false; + } - bool FindSubConfig(const CString& sName, SubConfig& Config, - bool bErase = true) { - SubConfigMap::iterator it = m_SubConfigs.find(sName); - if (it == m_SubConfigs.end()) { - Config.clear(); - return false; - } - Config = it->second; + bool FindSubConfig(const CString& sName, SubConfig& Config, + bool bErase = true) { + SubConfigMap::iterator it = m_SubConfigs.find(sName); + if (it == m_SubConfigs.end()) { + Config.clear(); + return false; + } + Config = it->second; - if (bErase) { - m_SubConfigs.erase(it); - } + if (bErase) { + m_SubConfigs.erase(it); + } - return true; - } + return true; + } - bool empty() const { - return m_ConfigEntries.empty() && m_SubConfigs.empty(); - } + bool empty() const { + return m_ConfigEntries.empty() && m_SubConfigs.empty(); + } - bool Parse(CFile& file, CString& sErrorMsg); - void Write(CFile& file, unsigned int iIndentation = 0); + bool Parse(CFile& file, CString& sErrorMsg); + void Write(CFile& file, unsigned int iIndentation = 0); private: - EntryMap m_ConfigEntries; - SubConfigMap m_SubConfigs; + EntryMap m_ConfigEntries; + SubConfigMap m_SubConfigs; }; #endif // !ZNC_CONFIG_H diff --git a/include/znc/ExecSock.h b/include/znc/ExecSock.h index 55a38a15..f7b77bba 100644 --- a/include/znc/ExecSock.h +++ b/include/znc/ExecSock.h @@ -24,31 +24,31 @@ //! @author imaginos@imaginos.net class CExecSock : public CZNCSock { public: - CExecSock() : CZNCSock(0), m_iPid(-1) {} + CExecSock() : CZNCSock(0), m_iPid(-1) {} - int Execute(const CString& sExec) { - int iReadFD, iWriteFD; - m_iPid = popen2(iReadFD, iWriteFD, sExec); - if (m_iPid != -1) { - ConnectFD(iReadFD, iWriteFD, "0.0.0.0:0"); - } - return (m_iPid); - } - void Kill(int iSignal) { - kill(m_iPid, iSignal); - Close(); - } - virtual ~CExecSock() { - close2(m_iPid, GetRSock(), GetWSock()); - SetRSock(-1); - SetWSock(-1); - } + int Execute(const CString& sExec) { + int iReadFD, iWriteFD; + m_iPid = popen2(iReadFD, iWriteFD, sExec); + if (m_iPid != -1) { + ConnectFD(iReadFD, iWriteFD, "0.0.0.0:0"); + } + return (m_iPid); + } + void Kill(int iSignal) { + kill(m_iPid, iSignal); + Close(); + } + virtual ~CExecSock() { + close2(m_iPid, GetRSock(), GetWSock()); + SetRSock(-1); + SetWSock(-1); + } - int popen2(int& iReadFD, int& iWriteFD, const CString& sCommand); - void close2(int iPid, int iReadFD, int iWriteFD); + int popen2(int& iReadFD, int& iWriteFD, const CString& sCommand); + void close2(int iPid, int iReadFD, int iWriteFD); private: - int m_iPid; + int m_iPid; }; #endif // !ZNC_EXECSOCK_H diff --git a/include/znc/FileUtils.h b/include/znc/FileUtils.h index bd0d763f..cc7ed6c2 100644 --- a/include/znc/FileUtils.h +++ b/include/znc/FileUtils.h @@ -29,235 +29,235 @@ class CFile { public: - CFile(); - CFile(const CString& sLongName); - ~CFile(); + CFile(); + CFile(const CString& sLongName); + ~CFile(); - enum EFileTypes { - FT_REGULAR, - FT_DIRECTORY, - FT_CHARACTER, - FT_BLOCK, - FT_FIFO, - FT_LINK, - FT_SOCK - }; + enum EFileTypes { + FT_REGULAR, + FT_DIRECTORY, + FT_CHARACTER, + FT_BLOCK, + FT_FIFO, + FT_LINK, + FT_SOCK + }; - void SetFileName(const CString& sLongName); - static bool IsReg(const CString& sLongName, bool bUseLstat = false); - static bool IsDir(const CString& sLongName, bool bUseLstat = false); - static bool IsChr(const CString& sLongName, bool bUseLstat = false); - static bool IsBlk(const CString& sLongName, bool bUseLstat = false); - static bool IsFifo(const CString& sLongName, bool bUseLstat = false); - static bool IsLnk(const CString& sLongName, bool bUseLstat = true); - static bool IsSock(const CString& sLongName, bool bUseLstat = false); + void SetFileName(const CString& sLongName); + static bool IsReg(const CString& sLongName, bool bUseLstat = false); + static bool IsDir(const CString& sLongName, bool bUseLstat = false); + static bool IsChr(const CString& sLongName, bool bUseLstat = false); + static bool IsBlk(const CString& sLongName, bool bUseLstat = false); + static bool IsFifo(const CString& sLongName, bool bUseLstat = false); + static bool IsLnk(const CString& sLongName, bool bUseLstat = true); + static bool IsSock(const CString& sLongName, bool bUseLstat = false); - bool IsReg(bool bUseLstat = false) const; - bool IsDir(bool bUseLstat = false) const; - bool IsChr(bool bUseLstat = false) const; - bool IsBlk(bool bUseLstat = false) const; - bool IsFifo(bool bUseLstat = false) const; - bool IsLnk(bool bUseLstat = true) const; - bool IsSock(bool bUseLstat = false) const; + bool IsReg(bool bUseLstat = false) const; + bool IsDir(bool bUseLstat = false) const; + bool IsChr(bool bUseLstat = false) const; + bool IsBlk(bool bUseLstat = false) const; + bool IsFifo(bool bUseLstat = false) const; + bool IsLnk(bool bUseLstat = true) const; + bool IsSock(bool bUseLstat = false) const; - // for gettin file types, using fstat instead - static bool FType(const CString& sFileName, EFileTypes eType, - bool bUseLstat = false); + // for gettin file types, using fstat instead + static bool FType(const CString& sFileName, EFileTypes eType, + bool bUseLstat = false); - enum EFileAttr { FA_Name, FA_Size, FA_ATime, FA_MTime, FA_CTime, FA_UID }; + enum EFileAttr { FA_Name, FA_Size, FA_ATime, FA_MTime, FA_CTime, FA_UID }; - // - // Functions to retrieve file information - // - bool Exists() const; - off_t GetSize() const; - time_t GetATime() const; - time_t GetMTime() const; - time_t GetCTime() const; - uid_t GetUID() const; - gid_t GetGID() const; - static bool Exists(const CString& sFile); + // + // Functions to retrieve file information + // + bool Exists() const; + off_t GetSize() const; + time_t GetATime() const; + time_t GetMTime() const; + time_t GetCTime() const; + uid_t GetUID() const; + gid_t GetGID() const; + static bool Exists(const CString& sFile); - static off_t GetSize(const CString& sFile); - static time_t GetATime(const CString& sFile); - static time_t GetMTime(const CString& sFile); - static time_t GetCTime(const CString& sFile); - static uid_t GetUID(const CString& sFile); - static gid_t GetGID(const CString& sFile); - static int GetInfo(const CString& sFile, struct stat& st); + static off_t GetSize(const CString& sFile); + static time_t GetATime(const CString& sFile); + static time_t GetMTime(const CString& sFile); + static time_t GetCTime(const CString& sFile); + static uid_t GetUID(const CString& sFile); + static gid_t GetGID(const CString& sFile); + static int GetInfo(const CString& sFile, struct stat& st); - // - // Functions to manipulate the file on the filesystem - // - bool Delete(); - bool Move(const CString& sNewFileName, bool bOverwrite = false); - bool Copy(const CString& sNewFileName, bool bOverwrite = false); + // + // Functions to manipulate the file on the filesystem + // + bool Delete(); + bool Move(const CString& sNewFileName, bool bOverwrite = false); + bool Copy(const CString& sNewFileName, bool bOverwrite = false); - static bool Delete(const CString& sFileName); - static bool Move(const CString& sOldFileName, const CString& sNewFileName, - bool bOverwrite = false); - static bool Copy(const CString& sOldFileName, const CString& sNewFileName, - bool bOverwrite = false); - bool Chmod(mode_t mode); - static bool Chmod(const CString& sFile, mode_t mode); - bool Seek(off_t uPos); - bool Truncate(); - bool Sync(); - bool Open(const CString& sFileName, int iFlags = O_RDONLY, - mode_t iMode = 0644); - bool Open(int iFlags = O_RDONLY, mode_t iMode = 0644); - ssize_t Read(char* pszBuffer, int iBytes); - bool ReadLine(CString& sData, const CString& sDelimiter = "\n"); - bool ReadFile(CString& sData, size_t iMaxSize = 512 * 1024); - ssize_t Write(const char* pszBuffer, size_t iBytes); - ssize_t Write(const CString& sData); - void Close(); - void ClearBuffer(); + static bool Delete(const CString& sFileName); + static bool Move(const CString& sOldFileName, const CString& sNewFileName, + bool bOverwrite = false); + static bool Copy(const CString& sOldFileName, const CString& sNewFileName, + bool bOverwrite = false); + bool Chmod(mode_t mode); + static bool Chmod(const CString& sFile, mode_t mode); + bool Seek(off_t uPos); + bool Truncate(); + bool Sync(); + bool Open(const CString& sFileName, int iFlags = O_RDONLY, + mode_t iMode = 0644); + bool Open(int iFlags = O_RDONLY, mode_t iMode = 0644); + ssize_t Read(char* pszBuffer, int iBytes); + bool ReadLine(CString& sData, const CString& sDelimiter = "\n"); + bool ReadFile(CString& sData, size_t iMaxSize = 512 * 1024); + ssize_t Write(const char* pszBuffer, size_t iBytes); + ssize_t Write(const CString& sData); + void Close(); + void ClearBuffer(); - bool TryExLock(const CString& sLockFile, int iFlags = O_RDWR | O_CREAT); - bool TryExLock(); - bool ExLock(); - bool UnLock(); + bool TryExLock(const CString& sLockFile, int iFlags = O_RDWR | O_CREAT); + bool TryExLock(); + bool ExLock(); + bool UnLock(); - bool IsOpen() const; - CString GetLongName() const; - CString GetShortName() const; - CString GetDir() const; + bool IsOpen() const; + CString GetLongName() const; + CString GetShortName() const; + CString GetDir() const; - bool HadError() const { return m_bHadError; } - void ResetError() { m_bHadError = false; } + bool HadError() const { return m_bHadError; } + void ResetError() { m_bHadError = false; } - static void InitHomePath(const CString& sFallback); - static const CString& GetHomePath() { return m_sHomePath; } + static void InitHomePath(const CString& sFallback); + static const CString& GetHomePath() { return m_sHomePath; } private: - // fcntl() locking wrapper - bool Lock(short iType, bool bBlocking); + // fcntl() locking wrapper + bool Lock(short iType, bool bBlocking); - CString m_sBuffer; - int m_iFD; - bool m_bHadError; + CString m_sBuffer; + int m_iFD; + bool m_bHadError; - static CString m_sHomePath; + static CString m_sHomePath; protected: - CString m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName) - CString m_sShortName; //!< Filename alone, without path + CString m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName) + CString m_sShortName; //!< Filename alone, without path }; class CDir : public std::vector { public: - CDir(const CString& sDir) : m_eSortAttr(CFile::FA_Name), m_bDesc(false) { - Fill(sDir); - } + CDir(const CString& sDir) : m_eSortAttr(CFile::FA_Name), m_bDesc(false) { + Fill(sDir); + } - CDir() : m_eSortAttr(CFile::FA_Name), m_bDesc(false) {} + CDir() : m_eSortAttr(CFile::FA_Name), m_bDesc(false) {} - ~CDir() { CleanUp(); } + ~CDir() { CleanUp(); } - void CleanUp() { - for (unsigned int a = 0; a < size(); a++) { - delete (*this)[a]; - } + void CleanUp() { + for (unsigned int a = 0; a < size(); a++) { + delete (*this)[a]; + } - clear(); - } + clear(); + } - size_t Fill(const CString& sDir) { return FillByWildcard(sDir, "*"); } + size_t Fill(const CString& sDir) { return FillByWildcard(sDir, "*"); } - size_t FillByWildcard(const CString& sDir, const CString& sWildcard) { - CleanUp(); - DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str()); + size_t FillByWildcard(const CString& sDir, const CString& sWildcard) { + CleanUp(); + DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str()); - if (!dir) { - return 0; - } + if (!dir) { + return 0; + } - struct dirent* de; + struct dirent* de; - while ((de = readdir(dir)) != nullptr) { - if ((strcmp(de->d_name, ".") == 0) || - (strcmp(de->d_name, "..") == 0)) { - continue; - } - if ((!sWildcard.empty()) && - (!CString(de->d_name).WildCmp(sWildcard))) { - continue; - } + while ((de = readdir(dir)) != nullptr) { + if ((strcmp(de->d_name, ".") == 0) || + (strcmp(de->d_name, "..") == 0)) { + continue; + } + if ((!sWildcard.empty()) && + (!CString(de->d_name).WildCmp(sWildcard))) { + continue; + } - CFile* file = - new CFile(sDir.TrimSuffix_n("/") + "/" + - de->d_name /*, this*/); // @todo need to pass pointer - // to 'this' if we want to do - // Sort() - push_back(file); - } + CFile* file = + new CFile(sDir.TrimSuffix_n("/") + "/" + + de->d_name /*, this*/); // @todo need to pass pointer + // to 'this' if we want to do + // Sort() + push_back(file); + } - closedir(dir); - return size(); - } + closedir(dir); + return size(); + } - static unsigned int Chmod(mode_t mode, const CString& sWildcard, - const CString& sDir = ".") { - CDir cDir; - cDir.FillByWildcard(sDir, sWildcard); - return cDir.Chmod(mode); - } + static unsigned int Chmod(mode_t mode, const CString& sWildcard, + const CString& sDir = ".") { + CDir cDir; + cDir.FillByWildcard(sDir, sWildcard); + return cDir.Chmod(mode); + } - unsigned int Chmod(mode_t mode) { - unsigned int uRet = 0; - for (unsigned int a = 0; a < size(); a++) { - if ((*this)[a]->Chmod(mode)) { - uRet++; - } - } + unsigned int Chmod(mode_t mode) { + unsigned int uRet = 0; + for (unsigned int a = 0; a < size(); a++) { + if ((*this)[a]->Chmod(mode)) { + uRet++; + } + } - return uRet; - } + return uRet; + } - static unsigned int Delete(const CString& sWildcard, - const CString& sDir = ".") { - CDir cDir; - cDir.FillByWildcard(sDir, sWildcard); - return cDir.Delete(); - } + static unsigned int Delete(const CString& sWildcard, + const CString& sDir = ".") { + CDir cDir; + cDir.FillByWildcard(sDir, sWildcard); + return cDir.Delete(); + } - unsigned int Delete() { - unsigned int uRet = 0; - for (unsigned int a = 0; a < size(); a++) { - if ((*this)[a]->Delete()) { - uRet++; - } - } + unsigned int Delete() { + unsigned int uRet = 0; + for (unsigned int a = 0; a < size(); a++) { + if ((*this)[a]->Delete()) { + uRet++; + } + } - return uRet; - } + return uRet; + } - CFile::EFileAttr GetSortAttr() const { return m_eSortAttr; } - bool IsDescending() const { return m_bDesc; } + CFile::EFileAttr GetSortAttr() const { return m_eSortAttr; } + bool IsDescending() const { return m_bDesc; } - // Check if sPath + "/" + sAdd (~/ is handled) is an absolute path which - // resides under sPath. Returns absolute path on success, else "". - static CString CheckPathPrefix(const CString& sPath, const CString& sAdd, - const CString& sHomeDir = ""); - static CString ChangeDir(const CString& sPath, const CString& sAdd, - const CString& sHomeDir = ""); - static bool MakeDir(const CString& sPath, mode_t iMode = 0700); + // Check if sPath + "/" + sAdd (~/ is handled) is an absolute path which + // resides under sPath. Returns absolute path on success, else "". + static CString CheckPathPrefix(const CString& sPath, const CString& sAdd, + const CString& sHomeDir = ""); + static CString ChangeDir(const CString& sPath, const CString& sAdd, + const CString& sHomeDir = ""); + static bool MakeDir(const CString& sPath, mode_t iMode = 0700); - static CString GetCWD() { - CString sRet; - char* pszCurDir = getcwd(nullptr, 0); - if (pszCurDir) { - sRet = pszCurDir; - free(pszCurDir); - } + static CString GetCWD() { + CString sRet; + char* pszCurDir = getcwd(nullptr, 0); + if (pszCurDir) { + sRet = pszCurDir; + free(pszCurDir); + } - return sRet; - } + return sRet; + } private: protected: - CFile::EFileAttr m_eSortAttr; - bool m_bDesc; + CFile::EFileAttr m_eSortAttr; + bool m_bDesc; }; #endif // !ZNC_FILEUTILS_H diff --git a/include/znc/HTTPSock.h b/include/znc/HTTPSock.h index ef66b9a8..25eb6726 100644 --- a/include/znc/HTTPSock.h +++ b/include/znc/HTTPSock.h @@ -25,124 +25,124 @@ class CModule; class CHTTPSock : public CSocket { public: - CHTTPSock(CModule* pMod, const CString& sURIPrefix); - CHTTPSock(CModule* pMod, const CString& sURIPrefix, - const CString& sHostname, unsigned short uPort, - int iTimeout = 60); - virtual ~CHTTPSock(); + CHTTPSock(CModule* pMod, const CString& sURIPrefix); + CHTTPSock(CModule* pMod, const CString& sURIPrefix, + const CString& sHostname, unsigned short uPort, + int iTimeout = 60); + virtual ~CHTTPSock(); - // Csocket derived members - void ReadData(const char* data, size_t len) override; - void ReadLine(const CString& sData) override; - void Connected() override; - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override = 0; - // !Csocket derived members + // Csocket derived members + void ReadData(const char* data, size_t len) override; + void ReadLine(const CString& sData) override; + void Connected() override; + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override = 0; + // !Csocket derived members - // Hooks - virtual bool ForceLogin(); - virtual bool OnLogin(const CString& sUser, const CString& sPass, - bool bBasic); - virtual void OnPageRequest(const CString& sURI) = 0; - virtual bool PrintFile(const CString& sFileName, CString sContentType = ""); - // !Hooks + // Hooks + virtual bool ForceLogin(); + virtual bool OnLogin(const CString& sUser, const CString& sPass, + bool bBasic); + virtual void OnPageRequest(const CString& sURI) = 0; + virtual bool PrintFile(const CString& sFileName, CString sContentType = ""); + // !Hooks - void CheckPost(); - bool SentHeader() const; - bool PrintHeader(off_t uContentLength, const CString& sContentType = "", - unsigned int uStatusId = 200, - const CString& sStatusMsg = "OK"); - void AddHeader(const CString& sName, const CString& sValue); - void SetContentType(const CString& sContentType); + void CheckPost(); + bool SentHeader() const; + bool PrintHeader(off_t uContentLength, const CString& sContentType = "", + unsigned int uStatusId = 200, + const CString& sStatusMsg = "OK"); + void AddHeader(const CString& sName, const CString& sValue); + void SetContentType(const CString& sContentType); - bool PrintNotFound(); - bool Redirect(const CString& sURL); - bool PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, - const CString& sMessage); - static void ParseParams(const CString& sParams, - std::map& msvsParams); - void ParseURI(); - void GetPage(); - static CString GetDate(time_t tm = 0); - CString GetRemoteIP() const override; + bool PrintNotFound(); + bool Redirect(const CString& sURL); + bool PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, + const CString& sMessage); + static void ParseParams(const CString& sParams, + std::map& msvsParams); + void ParseURI(); + void GetPage(); + static CString GetDate(time_t tm = 0); + CString GetRemoteIP() const override; - // Cookies - CString GetRequestCookie(const CString& sKey) const; - bool SendCookie(const CString& sKey, const CString& sValue); - // Cookies + // Cookies + CString GetRequestCookie(const CString& sKey) const; + bool SendCookie(const CString& sKey, const CString& sValue); + // Cookies - // Setters - void SetDocRoot(const CString& s); - void SetLoggedIn(bool b) { m_bLoggedIn = b; } - // !Setters + // Setters + void SetDocRoot(const CString& s); + void SetLoggedIn(bool b) { m_bLoggedIn = b; } + // !Setters - // Getters - CString GetPath() const; - bool IsLoggedIn() const { return m_bLoggedIn; } - const CString& GetDocRoot() const; - const CString& GetUser() const; - const CString& GetPass() const; - const CString& GetParamString() const; - const CString& GetContentType() const; - const CString& GetURIPrefix() const; - bool IsPost() const; - // !Getters + // Getters + CString GetPath() const; + bool IsLoggedIn() const { return m_bLoggedIn; } + const CString& GetDocRoot() const; + const CString& GetUser() const; + const CString& GetPass() const; + const CString& GetParamString() const; + const CString& GetContentType() const; + const CString& GetURIPrefix() const; + bool IsPost() const; + // !Getters - // Parameter access - CString GetParam(const CString& sName, bool bPost = true, - const CString& sFilter = "\r\n") const; - CString GetRawParam(const CString& sName, bool bPost = true) const; - bool HasParam(const CString& sName, bool bPost = true) const; - const std::map& GetParams(bool bPost = true) const; - size_t GetParamValues(const CString& sName, VCString& vsRet, - bool bPost = true, - const CString& sFilter = "\r\n") const; - size_t GetParamValues(const CString& sName, std::set& ssRet, - bool bPost = true, - const CString& sFilter = "\r\n") const; - // !Parameter access + // Parameter access + CString GetParam(const CString& sName, bool bPost = true, + const CString& sFilter = "\r\n") const; + CString GetRawParam(const CString& sName, bool bPost = true) const; + bool HasParam(const CString& sName, bool bPost = true) const; + const std::map& GetParams(bool bPost = true) const; + size_t GetParamValues(const CString& sName, VCString& vsRet, + bool bPost = true, + const CString& sFilter = "\r\n") const; + size_t GetParamValues(const CString& sName, std::set& ssRet, + bool bPost = true, + const CString& sFilter = "\r\n") const; + // !Parameter access private: - static CString GetRawParam(const CString& sName, - const std::map& msvsParams); - static CString GetParam(const CString& sName, - const std::map& msvsParams, - const CString& sFilter); - static size_t GetParamValues(const CString& sName, VCString& vsRet, - const std::map& msvsParams, - const CString& sFilter); - static size_t GetParamValues(const CString& sName, std::set& ssRet, - const std::map& msvsParams, - const CString& sFilter); + static CString GetRawParam(const CString& sName, + const std::map& msvsParams); + static CString GetParam(const CString& sName, + const std::map& msvsParams, + const CString& sFilter); + static size_t GetParamValues(const CString& sName, VCString& vsRet, + const std::map& msvsParams, + const CString& sFilter); + static size_t GetParamValues(const CString& sName, std::set& ssRet, + const std::map& msvsParams, + const CString& sFilter); - void WriteFileUncompressed(CFile& File); - void WriteFileGzipped(CFile& File); + void WriteFileUncompressed(CFile& File); + void WriteFileGzipped(CFile& File); protected: - void PrintPage(const CString& sPage); - void Init(); + void PrintPage(const CString& sPage); + void Init(); - bool m_bSentHeader; - bool m_bGotHeader; - bool m_bLoggedIn; - bool m_bPost; - bool m_bDone; - bool m_bBasicAuth; - unsigned long m_uPostLen; - CString m_sPostData; - CString m_sURI; - CString m_sUser; - CString m_sPass; - CString m_sContentType; - CString m_sDocRoot; - CString m_sForwardedIP; - std::map m_msvsPOSTParams; - std::map m_msvsGETParams; - MCString m_msHeaders; - bool m_bHTTP10Client; - CString m_sIfNoneMatch; - bool m_bAcceptGzip; - MCString m_msRequestCookies; - MCString m_msResponseCookies; - CString m_sURIPrefix; + bool m_bSentHeader; + bool m_bGotHeader; + bool m_bLoggedIn; + bool m_bPost; + bool m_bDone; + bool m_bBasicAuth; + unsigned long m_uPostLen; + CString m_sPostData; + CString m_sURI; + CString m_sUser; + CString m_sPass; + CString m_sContentType; + CString m_sDocRoot; + CString m_sForwardedIP; + std::map m_msvsPOSTParams; + std::map m_msvsGETParams; + MCString m_msHeaders; + bool m_bHTTP10Client; + CString m_sIfNoneMatch; + bool m_bAcceptGzip; + MCString m_msRequestCookies; + MCString m_msResponseCookies; + CString m_sURIPrefix; }; #endif // !ZNC_HTTPSOCK_H diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index f4c43c5a..26e866f7 100644 --- a/include/znc/IRCNetwork.h +++ b/include/znc/IRCNetwork.h @@ -39,292 +39,292 @@ class CMessage; class CIRCNetwork { public: - static bool IsValidNetwork(const CString& sNetwork); + static bool IsValidNetwork(const CString& sNetwork); - CIRCNetwork(CUser* pUser, const CString& sName); - CIRCNetwork(CUser* pUser, const CIRCNetwork& Network); - ~CIRCNetwork(); + CIRCNetwork(CUser* pUser, const CString& sName); + CIRCNetwork(CUser* pUser, const CIRCNetwork& Network); + ~CIRCNetwork(); - CIRCNetwork(const CIRCNetwork&) = delete; - CIRCNetwork& operator=(const CIRCNetwork&) = delete; + CIRCNetwork(const CIRCNetwork&) = delete; + CIRCNetwork& operator=(const CIRCNetwork&) = delete; - enum { - JOIN_FREQUENCY = 30, - /** How long must an IRC connection be idle before ZNC sends a ping */ - PING_FREQUENCY = 120, - /** Time between checks if PINGs need to be sent */ - PING_SLACK = 30, - /** Timeout after which IRC connections are closed. Must + enum { + JOIN_FREQUENCY = 30, + /** How long must an IRC connection be idle before ZNC sends a ping */ + PING_FREQUENCY = 120, + /** Time between checks if PINGs need to be sent */ + PING_SLACK = 30, + /** Timeout after which IRC connections are closed. Must * obviously be greater than PING_FREQUENCY + PING_SLACK. */ - NO_TRAFFIC_TIMEOUT = 180 - }; + NO_TRAFFIC_TIMEOUT = 180 + }; - void Clone(const CIRCNetwork& Network, bool bCloneName = true); + void Clone(const CIRCNetwork& Network, bool bCloneName = true); - CString GetNetworkPath() const; + CString GetNetworkPath() const; - void DelServers(); + void DelServers(); - bool ParseConfig(CConfig* pConfig, CString& sError, bool bUpgrade = false); - CConfig ToConfig() const; + bool ParseConfig(CConfig* pConfig, CString& sError, bool bUpgrade = false); + CConfig ToConfig() const; - void BounceAllClients(); + void BounceAllClients(); - bool IsUserAttached() const { return !m_vClients.empty(); } - bool IsUserOnline() const; - void ClientConnected(CClient* pClient); - void ClientDisconnected(CClient* pClient); + bool IsUserAttached() const { return !m_vClients.empty(); } + bool IsUserOnline() const; + void ClientConnected(CClient* pClient); + void ClientDisconnected(CClient* pClient); - CUser* GetUser() const; - const CString& GetName() const; - bool IsNetworkAttached() const { return !m_vClients.empty(); } - const std::vector& GetClients() const { return m_vClients; } - std::vector FindClients(const CString& sIdentifier) const; + CUser* GetUser() const; + const CString& GetName() const; + bool IsNetworkAttached() const { return !m_vClients.empty(); } + const std::vector& GetClients() const { return m_vClients; } + std::vector FindClients(const CString& sIdentifier) const; - void SetUser(CUser* pUser); - bool SetName(const CString& sName); + void SetUser(CUser* pUser); + bool SetName(const CString& sName); - // Modules - CModules& GetModules() { return *m_pModules; } - const CModules& GetModules() const { return *m_pModules; } - // !Modules + // Modules + CModules& GetModules() { return *m_pModules; } + const CModules& GetModules() const { return *m_pModules; } + // !Modules - bool PutUser(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutUser(const CMessage& Message, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutStatus(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutModule(const CString& sModule, const CString& sLine, - CClient* pClient = nullptr, CClient* pSkipClient = nullptr); + bool PutUser(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutUser(const CMessage& Message, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutStatus(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutModule(const CString& sModule, const CString& sLine, + CClient* pClient = nullptr, CClient* pSkipClient = nullptr); - const std::vector& GetChans() const; - CChan* FindChan(CString sName) const; - std::vector FindChans(const CString& sWild) const; - bool AddChan(CChan* pChan); - bool AddChan(const CString& sName, bool bInConfig); - bool DelChan(const CString& sName); - void JoinChans(); - void JoinChans(std::set& sChans); + const std::vector& GetChans() const; + CChan* FindChan(CString sName) const; + std::vector FindChans(const CString& sWild) const; + bool AddChan(CChan* pChan); + bool AddChan(const CString& sName, bool bInConfig); + bool DelChan(const CString& sName); + void JoinChans(); + void JoinChans(std::set& sChans); - const std::vector& GetQueries() const; - CQuery* FindQuery(const CString& sName) const; - std::vector FindQueries(const CString& sWild) const; - CQuery* AddQuery(const CString& sName); - bool DelQuery(const CString& sName); + const std::vector& GetQueries() const; + CQuery* FindQuery(const CString& sName) const; + std::vector FindQueries(const CString& sWild) const; + CQuery* AddQuery(const CString& sName); + bool DelQuery(const CString& sName); - const CString& GetChanPrefixes() const { return m_sChanPrefixes; } - void SetChanPrefixes(const CString& s) { m_sChanPrefixes = s; } - bool IsChan(const CString& sChan) const; + const CString& GetChanPrefixes() const { return m_sChanPrefixes; } + void SetChanPrefixes(const CString& s) { m_sChanPrefixes = s; } + bool IsChan(const CString& sChan) const; - const std::vector& GetServers() const; - bool HasServers() const { return !m_vServers.empty(); } - CServer* FindServer(const CString& sName) const; - bool DelServer(const CString& sName, unsigned short uPort, - const CString& sPass); - bool AddServer(const CString& sName); - bool AddServer(const CString& sName, unsigned short uPort, - const CString& sPass = "", bool bSSL = false); - CServer* GetNextServer(bool bAdvance = true); - CServer* GetCurrentServer() const; - void SetIRCServer(const CString& s); - bool SetNextServer(const CServer* pServer); - bool IsLastServer() const; + const std::vector& GetServers() const; + bool HasServers() const { return !m_vServers.empty(); } + CServer* FindServer(const CString& sName) const; + bool DelServer(const CString& sName, unsigned short uPort, + const CString& sPass); + bool AddServer(const CString& sName); + bool AddServer(const CString& sName, unsigned short uPort, + const CString& sPass = "", bool bSSL = false); + CServer* GetNextServer(bool bAdvance = true); + CServer* GetCurrentServer() const; + void SetIRCServer(const CString& s); + bool SetNextServer(const CServer* pServer); + bool IsLastServer() const; - const SCString& GetTrustedFingerprints() const { - return m_ssTrustedFingerprints; - } - void AddTrustedFingerprint(const CString& sFP) { - m_ssTrustedFingerprints.insert( - sFP.Escape_n(CString::EHEXCOLON, CString::EHEXCOLON)); - } - void DelTrustedFingerprint(const CString& sFP) { - m_ssTrustedFingerprints.erase(sFP); - } - void ClearTrustedFingerprints() { m_ssTrustedFingerprints.clear(); } + const SCString& GetTrustedFingerprints() const { + return m_ssTrustedFingerprints; + } + void AddTrustedFingerprint(const CString& sFP) { + m_ssTrustedFingerprints.insert( + sFP.Escape_n(CString::EHEXCOLON, CString::EHEXCOLON)); + } + void DelTrustedFingerprint(const CString& sFP) { + m_ssTrustedFingerprints.erase(sFP); + } + void ClearTrustedFingerprints() { m_ssTrustedFingerprints.clear(); } - void SetIRCConnectEnabled(bool b); - bool GetIRCConnectEnabled() const { return m_bIRCConnectEnabled; } + void SetIRCConnectEnabled(bool b); + bool GetIRCConnectEnabled() const { return m_bIRCConnectEnabled; } - CIRCSock* GetIRCSock() { return m_pIRCSock; } - const CIRCSock* GetIRCSock() const { return m_pIRCSock; } - const CString& GetIRCServer() const; - const CNick& GetIRCNick() const; - void SetIRCNick(const CNick& n); - CString GetCurNick() const; - bool IsIRCAway() const { return m_bIRCAway; } - void SetIRCAway(bool b) { m_bIRCAway = b; } + CIRCSock* GetIRCSock() { return m_pIRCSock; } + const CIRCSock* GetIRCSock() const { return m_pIRCSock; } + const CString& GetIRCServer() const; + const CNick& GetIRCNick() const; + void SetIRCNick(const CNick& n); + CString GetCurNick() const; + bool IsIRCAway() const { return m_bIRCAway; } + void SetIRCAway(bool b) { m_bIRCAway = b; } - bool Connect(); - /** This method will return whether the user is connected and authenticated to an IRC server. + bool Connect(); + /** This method will return whether the user is connected and authenticated to an IRC server. */ - bool IsIRCConnected() const; - void SetIRCSocket(CIRCSock* pIRCSock); - void IRCConnected(); - void IRCDisconnected(); - void CheckIRCConnect(); + bool IsIRCConnected() const; + void SetIRCSocket(CIRCSock* pIRCSock); + void IRCConnected(); + void IRCDisconnected(); + void CheckIRCConnect(); - bool PutIRC(const CString& sLine); + bool PutIRC(const CString& sLine); - // Buffers - void AddRawBuffer(const CMessage& Format, const CString& sText = "") { - m_RawBuffer.AddLine(Format, sText); - } - void UpdateRawBuffer(const CString& sCommand, const CMessage& Format, - const CString& sText = "") { - m_RawBuffer.UpdateLine(sCommand, Format, sText); - } - void UpdateExactRawBuffer(const CMessage& Format, - const CString& sText = "") { - m_RawBuffer.UpdateExactLine(Format, sText); - } - void ClearRawBuffer() { m_RawBuffer.Clear(); } + // Buffers + void AddRawBuffer(const CMessage& Format, const CString& sText = "") { + m_RawBuffer.AddLine(Format, sText); + } + void UpdateRawBuffer(const CString& sCommand, const CMessage& Format, + const CString& sText = "") { + m_RawBuffer.UpdateLine(sCommand, Format, sText); + } + void UpdateExactRawBuffer(const CMessage& Format, + const CString& sText = "") { + m_RawBuffer.UpdateExactLine(Format, sText); + } + void ClearRawBuffer() { m_RawBuffer.Clear(); } - /// @deprecated - void AddRawBuffer(const CString& sFormat, const CString& sText = "") { - m_RawBuffer.AddLine(sFormat, sText); - } - /// @deprecated - void UpdateRawBuffer(const CString& sMatch, const CString& sFormat, - const CString& sText = "") { - m_RawBuffer.UpdateLine(sMatch, sFormat, sText); - } - /// @deprecated - void UpdateExactRawBuffer(const CString& sFormat, - const CString& sText = "") { - m_RawBuffer.UpdateExactLine(sFormat, sText); - } + /// @deprecated + void AddRawBuffer(const CString& sFormat, const CString& sText = "") { + m_RawBuffer.AddLine(sFormat, sText); + } + /// @deprecated + void UpdateRawBuffer(const CString& sMatch, const CString& sFormat, + const CString& sText = "") { + m_RawBuffer.UpdateLine(sMatch, sFormat, sText); + } + /// @deprecated + void UpdateExactRawBuffer(const CString& sFormat, + const CString& sText = "") { + m_RawBuffer.UpdateExactLine(sFormat, sText); + } - void AddMotdBuffer(const CMessage& Format, const CString& sText = "") { - m_MotdBuffer.AddLine(Format, sText); - } - void UpdateMotdBuffer(const CString& sCommand, const CMessage& Format, - const CString& sText = "") { - m_MotdBuffer.UpdateLine(sCommand, Format, sText); - } - void ClearMotdBuffer() { m_MotdBuffer.Clear(); } + void AddMotdBuffer(const CMessage& Format, const CString& sText = "") { + m_MotdBuffer.AddLine(Format, sText); + } + void UpdateMotdBuffer(const CString& sCommand, const CMessage& Format, + const CString& sText = "") { + m_MotdBuffer.UpdateLine(sCommand, Format, sText); + } + void ClearMotdBuffer() { m_MotdBuffer.Clear(); } - /// @deprecated - void AddMotdBuffer(const CString& sFormat, const CString& sText = "") { - m_MotdBuffer.AddLine(sFormat, sText); - } - /// @deprecated - void UpdateMotdBuffer(const CString& sMatch, const CString& sFormat, - const CString& sText = "") { - m_MotdBuffer.UpdateLine(sMatch, sFormat, sText); - } + /// @deprecated + void AddMotdBuffer(const CString& sFormat, const CString& sText = "") { + m_MotdBuffer.AddLine(sFormat, sText); + } + /// @deprecated + void UpdateMotdBuffer(const CString& sMatch, const CString& sFormat, + const CString& sText = "") { + m_MotdBuffer.UpdateLine(sMatch, sFormat, sText); + } - void AddNoticeBuffer(const CMessage& Format, const CString& sText = "") { - m_NoticeBuffer.AddLine(Format, sText); - } - void UpdateNoticeBuffer(const CString& sCommand, const CMessage& Format, - const CString& sText = "") { - m_NoticeBuffer.UpdateLine(sCommand, Format, sText); - } - void ClearNoticeBuffer() { m_NoticeBuffer.Clear(); } + void AddNoticeBuffer(const CMessage& Format, const CString& sText = "") { + m_NoticeBuffer.AddLine(Format, sText); + } + void UpdateNoticeBuffer(const CString& sCommand, const CMessage& Format, + const CString& sText = "") { + m_NoticeBuffer.UpdateLine(sCommand, Format, sText); + } + void ClearNoticeBuffer() { m_NoticeBuffer.Clear(); } - /// @deprecated - void AddNoticeBuffer(const CString& sFormat, const CString& sText = "") { - m_NoticeBuffer.AddLine(sFormat, sText); - } - /// @deprecated - void UpdateNoticeBuffer(const CString& sMatch, const CString& sFormat, - const CString& sText = "") { - m_NoticeBuffer.UpdateLine(sMatch, sFormat, sText); - } + /// @deprecated + void AddNoticeBuffer(const CString& sFormat, const CString& sText = "") { + m_NoticeBuffer.AddLine(sFormat, sText); + } + /// @deprecated + void UpdateNoticeBuffer(const CString& sMatch, const CString& sFormat, + const CString& sText = "") { + m_NoticeBuffer.UpdateLine(sMatch, sFormat, sText); + } - void ClearQueryBuffer(); - // !Buffers + void ClearQueryBuffer(); + // !Buffers - // la - const CString& GetNick(const bool bAllowDefault = true) const; - const CString& GetAltNick(const bool bAllowDefault = true) const; - const CString& GetIdent(const bool bAllowDefault = true) const; - CString GetRealName() const; - const CString& GetBindHost() const; - const CString& GetEncoding() const; - CString GetQuitMsg() const; + // la + const CString& GetNick(const bool bAllowDefault = true) const; + const CString& GetAltNick(const bool bAllowDefault = true) const; + const CString& GetIdent(const bool bAllowDefault = true) const; + CString GetRealName() const; + const CString& GetBindHost() const; + const CString& GetEncoding() const; + CString GetQuitMsg() const; - void SetNick(const CString& s); - void SetAltNick(const CString& s); - void SetIdent(const CString& s); - void SetRealName(const CString& s); - void SetBindHost(const CString& s); - void SetEncoding(const CString& s); - void SetQuitMsg(const CString& s); + void SetNick(const CString& s); + void SetAltNick(const CString& s); + void SetIdent(const CString& s); + void SetRealName(const CString& s); + void SetBindHost(const CString& s); + void SetEncoding(const CString& s); + void SetQuitMsg(const CString& s); - double GetFloodRate() const { return m_fFloodRate; } - unsigned short int GetFloodBurst() const { return m_uFloodBurst; } - void SetFloodRate(double fFloodRate) { m_fFloodRate = fFloodRate; } - void SetFloodBurst(unsigned short int uFloodBurst) { - m_uFloodBurst = uFloodBurst; - } + double GetFloodRate() const { return m_fFloodRate; } + unsigned short int GetFloodBurst() const { return m_uFloodBurst; } + void SetFloodRate(double fFloodRate) { m_fFloodRate = fFloodRate; } + void SetFloodBurst(unsigned short int uFloodBurst) { + m_uFloodBurst = uFloodBurst; + } - unsigned short int GetJoinDelay() const { return m_uJoinDelay; } - void SetJoinDelay(unsigned short int uJoinDelay) { - m_uJoinDelay = uJoinDelay; - } + unsigned short int GetJoinDelay() const { return m_uJoinDelay; } + void SetJoinDelay(unsigned short int uJoinDelay) { + m_uJoinDelay = uJoinDelay; + } - unsigned long long BytesRead() const { return m_uBytesRead; } - unsigned long long BytesWritten() const { return m_uBytesWritten; } + unsigned long long BytesRead() const { return m_uBytesRead; } + unsigned long long BytesWritten() const { return m_uBytesWritten; } - void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } - void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } + void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } + void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } - CString ExpandString(const CString& sStr) const; - CString& ExpandString(const CString& sStr, CString& sRet) const; + CString ExpandString(const CString& sStr) const; + CString& ExpandString(const CString& sStr, CString& sRet) const; private: - bool JoinChan(CChan* pChan); - bool LoadModule(const CString& sModName, const CString& sArgs, - const CString& sNotice, CString& sError); + bool JoinChan(CChan* pChan); + bool LoadModule(const CString& sModName, const CString& sArgs, + const CString& sNotice, CString& sError); protected: - CString m_sName; - CUser* m_pUser; + CString m_sName; + CUser* m_pUser; - CString m_sNick; - CString m_sAltNick; - CString m_sIdent; - CString m_sRealName; - CString m_sBindHost; - CString m_sEncoding; - CString m_sQuitMsg; - SCString m_ssTrustedFingerprints; + CString m_sNick; + CString m_sAltNick; + CString m_sIdent; + CString m_sRealName; + CString m_sBindHost; + CString m_sEncoding; + CString m_sQuitMsg; + SCString m_ssTrustedFingerprints; - CModules* m_pModules; + CModules* m_pModules; - std::vector m_vClients; + std::vector m_vClients; - CIRCSock* m_pIRCSock; + CIRCSock* m_pIRCSock; - std::vector m_vChans; - std::vector m_vQueries; + std::vector m_vChans; + std::vector m_vQueries; - CString m_sChanPrefixes; + CString m_sChanPrefixes; - bool m_bIRCConnectEnabled; - CString m_sIRCServer; - std::vector m_vServers; - size_t m_uServerIdx; ///< Index in m_vServers of our current server + 1 + bool m_bIRCConnectEnabled; + CString m_sIRCServer; + std::vector m_vServers; + size_t m_uServerIdx; ///< Index in m_vServers of our current server + 1 - CNick m_IRCNick; - bool m_bIRCAway; + CNick m_IRCNick; + bool m_bIRCAway; - double m_fFloodRate; ///< Set to -1 to disable protection. - unsigned short int m_uFloodBurst; + double m_fFloodRate; ///< Set to -1 to disable protection. + unsigned short int m_uFloodBurst; - CBuffer m_RawBuffer; - CBuffer m_MotdBuffer; - CBuffer m_NoticeBuffer; + CBuffer m_RawBuffer; + CBuffer m_MotdBuffer; + CBuffer m_NoticeBuffer; - CIRCNetworkPingTimer* m_pPingTimer; - CIRCNetworkJoinTimer* m_pJoinTimer; + CIRCNetworkPingTimer* m_pPingTimer; + CIRCNetworkJoinTimer* m_pJoinTimer; - unsigned short int m_uJoinDelay; - unsigned long long m_uBytesRead; - unsigned long long m_uBytesWritten; + unsigned short int m_uJoinDelay; + unsigned long long m_uBytesRead; + unsigned long long m_uBytesWritten; }; #endif // !ZNC_IRCNETWORK_H diff --git a/include/znc/IRCSock.h b/include/znc/IRCSock.h index b47f098c..6bebe021 100644 --- a/include/znc/IRCSock.h +++ b/include/znc/IRCSock.h @@ -34,154 +34,154 @@ class CClient; // TODO: This class needs new name class CIRCSock : public CIRCSocket { public: - CIRCSock(CIRCNetwork* pNetwork); - virtual ~CIRCSock(); + CIRCSock(CIRCNetwork* pNetwork); + virtual ~CIRCSock(); - CIRCSock(const CIRCSock&) = delete; - CIRCSock& operator=(const CIRCSock&) = delete; + CIRCSock(const CIRCSock&) = delete; + CIRCSock& operator=(const CIRCSock&) = delete; - typedef enum { - // These values must line up with their position in the CHANMODE - // argument to raw 005 - ListArg = 0, - HasArg = 1, - ArgWhenSet = 2, - NoArg = 3 - } EChanModeArgs; + typedef enum { + // These values must line up with their position in the CHANMODE + // argument to raw 005 + ListArg = 0, + HasArg = 1, + ArgWhenSet = 2, + NoArg = 3 + } EChanModeArgs; - void ReadLine(const CString& sData) override; - void Connected() override; - void Disconnected() override; - void ConnectionRefused() override; - void SockError(int iErrno, const CString& sDescription) override; - void Timeout() override; - void ReachedMaxBuffer() override; + void ReadLine(const CString& sData) override; + void Connected() override; + void Disconnected() override; + void ConnectionRefused() override; + void SockError(int iErrno, const CString& sDescription) override; + void Timeout() override; + void ReachedMaxBuffer() override; - void PutIRC(const CString& sLine); - void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only - void ResetChans(); - void Quit(const CString& sQuitMsg = ""); + void PutIRC(const CString& sLine); + void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only + void ResetChans(); + void Quit(const CString& sQuitMsg = ""); - /** You can call this from CModule::OnServerCapResult to suspend + /** You can call this from CModule::OnServerCapResult to suspend * sending other CAP requests and CAP END for a while. Each * call to PauseCap should be balanced with a call to ResumeCap. */ - void PauseCap(); - /** If you used PauseCap, call this when CAP negotiation and logging in + void PauseCap(); + /** If you used PauseCap, call this when CAP negotiation and logging in * should be resumed again. */ - void ResumeCap(); + void ResumeCap(); - // Setters - void SetPass(const CString& s) { m_sPass = s; } - // !Setters + // Setters + void SetPass(const CString& s) { m_sPass = s; } + // !Setters - // Getters - unsigned int GetMaxNickLen() const { return m_uMaxNickLen; } - EChanModeArgs GetModeType(unsigned char uMode) const; - unsigned char GetPermFromMode(unsigned char uMode) const; - const std::map& GetChanModes() const { - return m_mueChanModes; - } - bool IsPermChar(const char c) const { - return (c != '\0' && GetPerms().find(c) != CString::npos); - } - bool IsPermMode(const char c) const { - return (c != '\0' && GetPermModes().find(c) != CString::npos); - } - const CString& GetPerms() const { return m_sPerms; } - const CString& GetPermModes() const { return m_sPermModes; } - CString GetNickMask() const { return m_Nick.GetNickMask(); } - const CString& GetNick() const { return m_Nick.GetNick(); } - const CString& GetPass() const { return m_sPass; } - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - bool HasNamesx() const { return m_bNamesx; } - bool HasUHNames() const { return m_bUHNames; } - bool HasAwayNotify() const { return m_bAwayNotify; } - bool HasAccountNotify() const { return m_bAccountNotify; } - bool HasExtendedJoin() const { return m_bExtendedJoin; } - bool HasServerTime() const { return m_bServerTime; } - const std::set& GetUserModes() const { - return m_scUserModes; - } - // This is true if we are past raw 001 - bool IsAuthed() const { return m_bAuthed; } - const SCString& GetAcceptedCaps() const { return m_ssAcceptedCaps; } - bool IsCapAccepted(const CString& sCap) { - return 1 == m_ssAcceptedCaps.count(sCap); - } - const MCString& GetISupport() const { return m_mISupport; } - CString GetISupport(const CString& sKey, - const CString& sDefault = "") const; - // !Getters + // Getters + unsigned int GetMaxNickLen() const { return m_uMaxNickLen; } + EChanModeArgs GetModeType(unsigned char uMode) const; + unsigned char GetPermFromMode(unsigned char uMode) const; + const std::map& GetChanModes() const { + return m_mueChanModes; + } + bool IsPermChar(const char c) const { + return (c != '\0' && GetPerms().find(c) != CString::npos); + } + bool IsPermMode(const char c) const { + return (c != '\0' && GetPermModes().find(c) != CString::npos); + } + const CString& GetPerms() const { return m_sPerms; } + const CString& GetPermModes() const { return m_sPermModes; } + CString GetNickMask() const { return m_Nick.GetNickMask(); } + const CString& GetNick() const { return m_Nick.GetNick(); } + const CString& GetPass() const { return m_sPass; } + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + bool HasNamesx() const { return m_bNamesx; } + bool HasUHNames() const { return m_bUHNames; } + bool HasAwayNotify() const { return m_bAwayNotify; } + bool HasAccountNotify() const { return m_bAccountNotify; } + bool HasExtendedJoin() const { return m_bExtendedJoin; } + bool HasServerTime() const { return m_bServerTime; } + const std::set& GetUserModes() const { + return m_scUserModes; + } + // This is true if we are past raw 001 + bool IsAuthed() const { return m_bAuthed; } + const SCString& GetAcceptedCaps() const { return m_ssAcceptedCaps; } + bool IsCapAccepted(const CString& sCap) { + return 1 == m_ssAcceptedCaps.count(sCap); + } + const MCString& GetISupport() const { return m_mISupport; } + CString GetISupport(const CString& sKey, + const CString& sDefault = "") const; + // !Getters - // TODO move this function to CIRCNetwork and make it non-static? - static bool IsFloodProtected(double fRate); + // TODO move this function to CIRCNetwork and make it non-static? + static bool IsFloodProtected(double fRate); private: - // Message Handlers - bool OnAccountMessage(CMessage& Message); - bool OnActionMessage(CActionMessage& Message); - bool OnAwayMessage(CMessage& Message); - bool OnCapabilityMessage(CMessage& Message); - bool OnCTCPMessage(CCTCPMessage& Message); - bool OnErrorMessage(CMessage& Message); - bool OnInviteMessage(CMessage& Message); - bool OnJoinMessage(CJoinMessage& Message); - bool OnKickMessage(CKickMessage& Message); - bool OnModeMessage(CModeMessage& Message); - bool OnNickMessage(CNickMessage& Message); - bool OnNoticeMessage(CNoticeMessage& Message); - bool OnNumericMessage(CNumericMessage& Message); - bool OnPartMessage(CPartMessage& Message); - bool OnPingMessage(CMessage& Message); - bool OnPongMessage(CMessage& Message); - bool OnQuitMessage(CQuitMessage& Message); - bool OnTextMessage(CTextMessage& Message); - bool OnTopicMessage(CTopicMessage& Message); - bool OnWallopsMessage(CMessage& Message); - bool OnServerCapAvailable(const CString& sCap); - // !Message Handlers + // Message Handlers + bool OnAccountMessage(CMessage& Message); + bool OnActionMessage(CActionMessage& Message); + bool OnAwayMessage(CMessage& Message); + bool OnCapabilityMessage(CMessage& Message); + bool OnCTCPMessage(CCTCPMessage& Message); + bool OnErrorMessage(CMessage& Message); + bool OnInviteMessage(CMessage& Message); + bool OnJoinMessage(CJoinMessage& Message); + bool OnKickMessage(CKickMessage& Message); + bool OnModeMessage(CModeMessage& Message); + bool OnNickMessage(CNickMessage& Message); + bool OnNoticeMessage(CNoticeMessage& Message); + bool OnNumericMessage(CNumericMessage& Message); + bool OnPartMessage(CPartMessage& Message); + bool OnPingMessage(CMessage& Message); + bool OnPongMessage(CMessage& Message); + bool OnQuitMessage(CQuitMessage& Message); + bool OnTextMessage(CTextMessage& Message); + bool OnTopicMessage(CTopicMessage& Message); + bool OnWallopsMessage(CMessage& Message); + bool OnServerCapAvailable(const CString& sCap); + // !Message Handlers - void SetNick(const CString& sNick); - void ParseISupport(const CMessage& Message); - // This is called when we connect and the nick we want is already taken - void SendAltNick(const CString& sBadNick); - void SendNextCap(); - void TrySend(); + void SetNick(const CString& sNick); + void ParseISupport(const CMessage& Message); + // This is called when we connect and the nick we want is already taken + void SendAltNick(const CString& sBadNick); + void SendNextCap(); + void TrySend(); protected: - bool m_bAuthed; - bool m_bNamesx; - bool m_bUHNames; - bool m_bAwayNotify; - bool m_bAccountNotify; - bool m_bExtendedJoin; - bool m_bServerTime; - CString m_sPerms; - CString m_sPermModes; - std::set m_scUserModes; - std::map m_mueChanModes; - CIRCNetwork* m_pNetwork; - CNick m_Nick; - CString m_sPass; - std::map m_msChans; - unsigned int m_uMaxNickLen; - unsigned int m_uCapPaused; - SCString m_ssAcceptedCaps; - SCString m_ssPendingCaps; - time_t m_lastCTCP; - unsigned int m_uNumCTCP; - static const time_t m_uCTCPFloodTime; - static const unsigned int m_uCTCPFloodCount; - MCString m_mISupport; - std::deque m_vsSendQueue; - short int m_iSendsAllowed; - unsigned short int m_uFloodBurst; - double m_fFloodRate; - bool m_bFloodProtection; + bool m_bAuthed; + bool m_bNamesx; + bool m_bUHNames; + bool m_bAwayNotify; + bool m_bAccountNotify; + bool m_bExtendedJoin; + bool m_bServerTime; + CString m_sPerms; + CString m_sPermModes; + std::set m_scUserModes; + std::map m_mueChanModes; + CIRCNetwork* m_pNetwork; + CNick m_Nick; + CString m_sPass; + std::map m_msChans; + unsigned int m_uMaxNickLen; + unsigned int m_uCapPaused; + SCString m_ssAcceptedCaps; + SCString m_ssPendingCaps; + time_t m_lastCTCP; + unsigned int m_uNumCTCP; + static const time_t m_uCTCPFloodTime; + static const unsigned int m_uCTCPFloodCount; + MCString m_mISupport; + std::deque m_vsSendQueue; + short int m_iSendsAllowed; + unsigned short int m_uFloodBurst; + double m_fFloodRate; + bool m_bFloodProtection; - friend class CIRCFloodTimer; + friend class CIRCFloodTimer; }; #endif // !ZNC_IRCSOCK_H diff --git a/include/znc/Listener.h b/include/znc/Listener.h index 43492657..1fdf482e 100644 --- a/include/znc/Listener.h +++ b/include/znc/Listener.h @@ -26,77 +26,77 @@ class CRealListener; class CListener { public: - typedef enum { ACCEPT_IRC, ACCEPT_HTTP, ACCEPT_ALL } EAcceptType; + typedef enum { ACCEPT_IRC, ACCEPT_HTTP, ACCEPT_ALL } EAcceptType; - CListener(unsigned short uPort, const CString& sBindHost, - const CString& sURIPrefix, bool bSSL, EAddrType eAddr, - EAcceptType eAccept) - : m_bSSL(bSSL), - m_eAddr(eAddr), - m_uPort(uPort), - m_sBindHost(sBindHost), - m_sURIPrefix(sURIPrefix), - m_pListener(nullptr), - m_eAcceptType(eAccept) {} + CListener(unsigned short uPort, const CString& sBindHost, + const CString& sURIPrefix, bool bSSL, EAddrType eAddr, + EAcceptType eAccept) + : m_bSSL(bSSL), + m_eAddr(eAddr), + m_uPort(uPort), + m_sBindHost(sBindHost), + m_sURIPrefix(sURIPrefix), + m_pListener(nullptr), + m_eAcceptType(eAccept) {} - ~CListener(); + ~CListener(); - CListener(const CListener&) = delete; - CListener& operator=(const CListener&) = delete; + CListener(const CListener&) = delete; + CListener& operator=(const CListener&) = delete; - // Getters - bool IsSSL() const { return m_bSSL; } - EAddrType GetAddrType() const { return m_eAddr; } - unsigned short GetPort() const { return m_uPort; } - const CString& GetBindHost() const { return m_sBindHost; } - CRealListener* GetRealListener() const { return m_pListener; } - const CString& GetURIPrefix() const { return m_sURIPrefix; } - EAcceptType GetAcceptType() const { return m_eAcceptType; } - // !Getters + // Getters + bool IsSSL() const { return m_bSSL; } + EAddrType GetAddrType() const { return m_eAddr; } + unsigned short GetPort() const { return m_uPort; } + const CString& GetBindHost() const { return m_sBindHost; } + CRealListener* GetRealListener() const { return m_pListener; } + const CString& GetURIPrefix() const { return m_sURIPrefix; } + EAcceptType GetAcceptType() const { return m_eAcceptType; } + // !Getters - // It doesn't make sense to change any of the settings after Listen() - // except this one, so don't add other setters! - void SetAcceptType(EAcceptType eType) { m_eAcceptType = eType; } + // It doesn't make sense to change any of the settings after Listen() + // except this one, so don't add other setters! + void SetAcceptType(EAcceptType eType) { m_eAcceptType = eType; } - bool Listen(); - void ResetRealListener(); + bool Listen(); + void ResetRealListener(); private: protected: - bool m_bSSL; - EAddrType m_eAddr; - unsigned short m_uPort; - CString m_sBindHost; - CString m_sURIPrefix; - CRealListener* m_pListener; - EAcceptType m_eAcceptType; + bool m_bSSL; + EAddrType m_eAddr; + unsigned short m_uPort; + CString m_sBindHost; + CString m_sURIPrefix; + CRealListener* m_pListener; + EAcceptType m_eAcceptType; }; class CRealListener : public CZNCSock { public: - CRealListener(CListener& listener) : CZNCSock(), m_Listener(listener) {} - virtual ~CRealListener(); + CRealListener(CListener& listener) : CZNCSock(), m_Listener(listener) {} + virtual ~CRealListener(); - bool ConnectionFrom(const CString& sHost, unsigned short uPort) override; - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; - void SockError(int iErrno, const CString& sDescription) override; + bool ConnectionFrom(const CString& sHost, unsigned short uPort) override; + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + void SockError(int iErrno, const CString& sDescription) override; private: - CListener& m_Listener; + CListener& m_Listener; }; class CIncomingConnection : public CZNCSock { public: - CIncomingConnection(const CString& sHostname, unsigned short uPort, - CListener::EAcceptType eAcceptType, - const CString& sURIPrefix); - virtual ~CIncomingConnection() {} - void ReadLine(const CString& sData) override; - void ReachedMaxBuffer() override; + CIncomingConnection(const CString& sHostname, unsigned short uPort, + CListener::EAcceptType eAcceptType, + const CString& sURIPrefix); + virtual ~CIncomingConnection() {} + void ReadLine(const CString& sData) override; + void ReachedMaxBuffer() override; private: - CListener::EAcceptType m_eAcceptType; - const CString m_sURIPrefix; + CListener::EAcceptType m_eAcceptType; + const CString m_sURIPrefix; }; #endif // !ZNC_LISTENER_H diff --git a/include/znc/MD5.h b/include/znc/MD5.h index 624d1a83..6bc239a1 100644 --- a/include/znc/MD5.h +++ b/include/znc/MD5.h @@ -16,34 +16,34 @@ using std::string; #endif typedef struct { - uint32 total[2]; - uint32 state[4]; - uint8 buffer[64]; + uint32 total[2]; + uint32 state[4]; + uint8 buffer[64]; } md5_context; class CMD5 { protected: - char m_szMD5[33]; + char m_szMD5[33]; public: - CMD5(); - CMD5(const string& sText); - CMD5(const char* szText, uint32 nTextLen); - ~CMD5(); + CMD5(); + CMD5(const string& sText); + CMD5(const char* szText, uint32 nTextLen); + ~CMD5(); - operator string() const { return (string)m_szMD5; } + operator string() const { return (string)m_szMD5; } - operator char*() const { return (char*)m_szMD5; } + operator char*() const { return (char*)m_szMD5; } - char* MakeHash(const char* szText, uint32 nTextLen); + char* MakeHash(const char* szText, uint32 nTextLen); protected: - void md5_starts(md5_context* ctx) const; - void md5_update(md5_context* ctx, const uint8* input, uint32 length) const; - void md5_finish(md5_context* ctx, uint8 digest[16]) const; + void md5_starts(md5_context* ctx) const; + void md5_update(md5_context* ctx, const uint8* input, uint32 length) const; + void md5_finish(md5_context* ctx, uint8 digest[16]) const; private: - void md5_process(md5_context* ctx, const uint8 data[64]) const; + void md5_process(md5_context* ctx, const uint8 data[64]) const; }; #endif /* ZNC_MD5_H */ diff --git a/include/znc/Message.h b/include/znc/Message.h index 386155ab..b4a3037f 100644 --- a/include/znc/Message.h +++ b/include/znc/Message.h @@ -41,135 +41,135 @@ class CIRCNetwork; class CMessage { public: - explicit CMessage(const CString& sMessage = ""); - CMessage(const CNick& Nick, const CString& sCommand, - const VCString& vsParams = VCString(), - const MCString& mssTags = MCString::EmptyMap); + explicit CMessage(const CString& sMessage = ""); + CMessage(const CNick& Nick, const CString& sCommand, + const VCString& vsParams = VCString(), + const MCString& mssTags = MCString::EmptyMap); - enum class Type { - Unknown, - Account, - Action, - Away, - Capability, - CTCP, - Error, - Invite, - Join, - Kick, - Mode, - Nick, - Notice, - Numeric, - Part, - Ping, - Pong, - Quit, - Text, - Topic, - Wallops, - }; - Type GetType() const { return m_eType; } + enum class Type { + Unknown, + Account, + Action, + Away, + Capability, + CTCP, + Error, + Invite, + Join, + Kick, + Mode, + Nick, + Notice, + Numeric, + Part, + Ping, + Pong, + Quit, + Text, + Topic, + Wallops, + }; + Type GetType() const { return m_eType; } - bool Equals(const CMessage& Other) const; - void Clone(const CMessage& Other); + bool Equals(const CMessage& Other) const; + void Clone(const CMessage& Other); - // ZNC <-> IRC - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } + // ZNC <-> IRC + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } - // ZNC <-> CLI - CClient* GetClient() const { return m_pClient; } - void SetClient(CClient* pClient) { m_pClient = pClient; } + // ZNC <-> CLI + CClient* GetClient() const { return m_pClient; } + void SetClient(CClient* pClient) { m_pClient = pClient; } - CChan* GetChan() const { return m_pChan; } - void SetChan(CChan* pChan) { m_pChan = pChan; } + CChan* GetChan() const { return m_pChan; } + void SetChan(CChan* pChan) { m_pChan = pChan; } - CNick& GetNick() { return m_Nick; } - const CNick& GetNick() const { return m_Nick; } - void SetNick(const CNick& Nick) { m_Nick = Nick; } + CNick& GetNick() { return m_Nick; } + const CNick& GetNick() const { return m_Nick; } + void SetNick(const CNick& Nick) { m_Nick = Nick; } - const CString& GetCommand() const { return m_sCommand; } - void SetCommand(const CString& sCommand); + const CString& GetCommand() const { return m_sCommand; } + void SetCommand(const CString& sCommand); - const VCString& GetParams() const { return m_vsParams; } - CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const; - void SetParams(const VCString& vsParams); + const VCString& GetParams() const { return m_vsParams; } + CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const; + void SetParams(const VCString& vsParams); - CString GetParam(unsigned int uIdx) const; - void SetParam(unsigned int uIdx, const CString& sParam); + CString GetParam(unsigned int uIdx) const; + void SetParam(unsigned int uIdx, const CString& sParam); - const timeval& GetTime() const { return m_time; } - void SetTime(const timeval& ts) { m_time = ts; } + const timeval& GetTime() const { return m_time; } + void SetTime(const timeval& ts) { m_time = ts; } - const MCString& GetTags() const { return m_mssTags; } - void SetTags(const MCString& mssTags) { m_mssTags = mssTags; } + const MCString& GetTags() const { return m_mssTags; } + void SetTags(const MCString& mssTags) { m_mssTags = mssTags; } - CString GetTag(const CString& sKey) const; - void SetTag(const CString& sKey, const CString& sValue); + CString GetTag(const CString& sKey) const; + void SetTag(const CString& sKey, const CString& sValue); - enum FormatFlags { - IncludeAll = 0x0, - ExcludePrefix = 0x1, - ExcludeTags = 0x2 - }; + enum FormatFlags { + IncludeAll = 0x0, + ExcludePrefix = 0x1, + ExcludeTags = 0x2 + }; - CString ToString(unsigned int uFlags = IncludeAll) const; - void Parse(CString sMessage); + CString ToString(unsigned int uFlags = IncludeAll) const; + void Parse(CString sMessage); // Implicit and explicit conversion to a subclass reference. #ifndef SWIG - template - M& As() ZNC_LVREFQUAL { - static_assert(std::is_base_of{}, - "Must be subclass of CMessage"); - static_assert(sizeof(M) == sizeof(CMessage), - "No data members allowed in CMessage subclasses."); - return static_cast(*this); - } + template + M& As() ZNC_LVREFQUAL { + static_assert(std::is_base_of{}, + "Must be subclass of CMessage"); + static_assert(sizeof(M) == sizeof(CMessage), + "No data members allowed in CMessage subclasses."); + return static_cast(*this); + } - template - const M& As() const ZNC_LVREFQUAL { - static_assert(std::is_base_of{}, - "Must be subclass of CMessage"); - static_assert(sizeof(M) == sizeof(CMessage), - "No data members allowed in CMessage subclasses."); - return static_cast(*this); - } + template + const M& As() const ZNC_LVREFQUAL { + static_assert(std::is_base_of{}, + "Must be subclass of CMessage"); + static_assert(sizeof(M) == sizeof(CMessage), + "No data members allowed in CMessage subclasses."); + return static_cast(*this); + } - template {}>::type> - operator M&() ZNC_LVREFQUAL { - return As(); - } - template {}>::type> - operator const M&() const ZNC_LVREFQUAL { - return As(); - } + template {}>::type> + operator M&() ZNC_LVREFQUAL { + return As(); + } + template {}>::type> + operator const M&() const ZNC_LVREFQUAL { + return As(); + } // REGISTER_ZNC_MESSAGE allows SWIG to instantiate correct .As<> calls. #define REGISTER_ZNC_MESSAGE(M) #else - // SWIG (as of 3.0.7) doesn't parse ref-qualifiers, and doesn't - // differentiate constness. - template - M& As(); + // SWIG (as of 3.0.7) doesn't parse ref-qualifiers, and doesn't + // differentiate constness. + template + M& As(); #endif private: - void InitTime(); - void InitType(); + void InitTime(); + void InitType(); - CNick m_Nick; - CString m_sCommand; - VCString m_vsParams; - MCString m_mssTags; - timeval m_time; - CIRCNetwork* m_pNetwork = nullptr; - CClient* m_pClient = nullptr; - CChan* m_pChan = nullptr; - Type m_eType = Type::Unknown; - bool m_bColon = false; + CNick m_Nick; + CString m_sCommand; + VCString m_vsParams; + MCString m_mssTags; + timeval m_time; + CIRCNetwork* m_pNetwork = nullptr; + CClient* m_pClient = nullptr; + CChan* m_pChan = nullptr; + Type m_eType = Type::Unknown; + bool m_bColon = false; }; // For gtest @@ -177,7 +177,7 @@ class CMessage { template {}>::type> inline ::std::ostream& operator<<(::std::ostream& os, const M& msg) { - return os << msg.ToString().Escape_n(CString::EDEBUG); + return os << msg.ToString().Escape_n(CString::EDEBUG); } #endif @@ -188,100 +188,100 @@ inline ::std::ostream& operator<<(::std::ostream& os, const M& msg) { // allowed to hold extra data of their own. class CTargetMessage : public CMessage { public: - CString GetTarget() const { return GetParam(0); } - void SetTarget(const CString& sTarget) { SetParam(0, sTarget); } + CString GetTarget() const { return GetParam(0); } + void SetTarget(const CString& sTarget) { SetParam(0, sTarget); } }; REGISTER_ZNC_MESSAGE(CTargetMessage); class CActionMessage : public CTargetMessage { public: - CString GetText() const { - return GetParam(1).TrimPrefix_n("\001ACTION ").TrimSuffix_n("\001"); - } - void SetText(const CString& sText) { - SetParam(1, "\001ACTION " + sText + "\001"); - } + CString GetText() const { + return GetParam(1).TrimPrefix_n("\001ACTION ").TrimSuffix_n("\001"); + } + void SetText(const CString& sText) { + SetParam(1, "\001ACTION " + sText + "\001"); + } }; REGISTER_ZNC_MESSAGE(CActionMessage); class CCTCPMessage : public CTargetMessage { public: - bool IsReply() const { return GetCommand().Equals("NOTICE"); } - CString GetText() const { - return GetParam(1).TrimPrefix_n("\001").TrimSuffix_n("\001"); - } - void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); } + bool IsReply() const { return GetCommand().Equals("NOTICE"); } + CString GetText() const { + return GetParam(1).TrimPrefix_n("\001").TrimSuffix_n("\001"); + } + void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); } }; REGISTER_ZNC_MESSAGE(CCTCPMessage); class CJoinMessage : public CTargetMessage { public: - CString GetKey() const { return GetParam(1); } - void SetKey(const CString& sKey) { SetParam(1, sKey); } + CString GetKey() const { return GetParam(1); } + void SetKey(const CString& sKey) { SetParam(1, sKey); } }; REGISTER_ZNC_MESSAGE(CJoinMessage); class CModeMessage : public CTargetMessage { public: - CString GetModes() const { return GetParams(1).TrimPrefix_n(":"); } + CString GetModes() const { return GetParams(1).TrimPrefix_n(":"); } }; REGISTER_ZNC_MESSAGE(CModeMessage); class CNickMessage : public CMessage { public: - CString GetOldNick() const { return GetNick().GetNick(); } - CString GetNewNick() const { return GetParam(0); } - void SetNewNick(const CString& sNick) { SetParam(0, sNick); } + CString GetOldNick() const { return GetNick().GetNick(); } + CString GetNewNick() const { return GetParam(0); } + void SetNewNick(const CString& sNick) { SetParam(0, sNick); } }; REGISTER_ZNC_MESSAGE(CNickMessage); class CNoticeMessage : public CTargetMessage { public: - CString GetText() const { return GetParam(1); } - void SetText(const CString& sText) { SetParam(1, sText); } + CString GetText() const { return GetParam(1); } + void SetText(const CString& sText) { SetParam(1, sText); } }; REGISTER_ZNC_MESSAGE(CNoticeMessage); class CNumericMessage : public CMessage { public: - unsigned int GetCode() const { return GetCommand().ToUInt(); } + unsigned int GetCode() const { return GetCommand().ToUInt(); } }; REGISTER_ZNC_MESSAGE(CNumericMessage); class CKickMessage : public CTargetMessage { public: - CString GetKickedNick() const { return GetParam(1); } - void SetKickedNick(const CString& sNick) { SetParam(1, sNick); } - CString GetReason() const { return GetParam(2); } - void SetReason(const CString& sReason) { SetParam(2, sReason); } + CString GetKickedNick() const { return GetParam(1); } + void SetKickedNick(const CString& sNick) { SetParam(1, sNick); } + CString GetReason() const { return GetParam(2); } + void SetReason(const CString& sReason) { SetParam(2, sReason); } }; REGISTER_ZNC_MESSAGE(CKickMessage); class CPartMessage : public CTargetMessage { public: - CString GetReason() const { return GetParam(1); } - void SetReason(const CString& sReason) { SetParam(1, sReason); } + CString GetReason() const { return GetParam(1); } + void SetReason(const CString& sReason) { SetParam(1, sReason); } }; REGISTER_ZNC_MESSAGE(CPartMessage); class CQuitMessage : public CMessage { public: - CString GetReason() const { return GetParam(0); } - void SetReason(const CString& sReason) { SetParam(0, sReason); } + CString GetReason() const { return GetParam(0); } + void SetReason(const CString& sReason) { SetParam(0, sReason); } }; REGISTER_ZNC_MESSAGE(CQuitMessage); class CTextMessage : public CTargetMessage { public: - CString GetText() const { return GetParam(1); } - void SetText(const CString& sText) { SetParam(1, sText); } + CString GetText() const { return GetParam(1); } + void SetText(const CString& sText) { SetParam(1, sText); } }; REGISTER_ZNC_MESSAGE(CTextMessage); class CTopicMessage : public CTargetMessage { public: - CString GetTopic() const { return GetParam(1); } - void SetTopic(const CString& sTopic) { SetParam(1, sTopic); } + CString GetTopic() const { return GetParam(1); } + void SetTopic(const CString& sTopic) { SetParam(1, sTopic); } }; REGISTER_ZNC_MESSAGE(CTopicMessage); diff --git a/include/znc/Modules.h b/include/znc/Modules.h index fac567da..06e955dc 100644 --- a/include/znc/Modules.h +++ b/include/znc/Modules.h @@ -57,18 +57,18 @@ class CModInfo; #endif #define MODCOMMONDEFS(CLASS, DESCRIPTION, TYPE) \ - extern "C" { \ - MODULE_EXPORT bool ZNCModInfo(double dCoreVersion, CModInfo& Info); \ - bool ZNCModInfo(double dCoreVersion, CModInfo& Info) { \ - if (dCoreVersion != VERSION) return false; \ - Info.SetDescription(DESCRIPTION); \ - Info.SetDefaultType(TYPE); \ - Info.AddType(TYPE); \ - Info.SetLoader(TModLoad); \ - TModInfo(Info); \ - return true; \ - } \ - } + extern "C" { \ + MODULE_EXPORT bool ZNCModInfo(double dCoreVersion, CModInfo& Info); \ + bool ZNCModInfo(double dCoreVersion, CModInfo& Info) { \ + if (dCoreVersion != VERSION) return false; \ + Info.SetDescription(DESCRIPTION); \ + Info.SetDefaultType(TYPE); \ + Info.AddType(TYPE); \ + Info.SetLoader(TModLoad); \ + TModInfo(Info); \ + return true; \ + } \ + } /** Instead of writing a constructor, you should call this macro. It accepts all * the necessary arguments and passes them on to CModule's constructor. You @@ -86,27 +86,27 @@ class CModInfo; * @param CLASS The name of your module's class. */ #define MODCONSTRUCTOR(CLASS) \ - CLASS(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, \ - const CString& sModName, const CString& sModPath, \ - CModInfo::EModuleType eType) \ - : CModule(pDLL, pUser, pNetwork, sModName, sModPath, eType) + CLASS(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, \ + const CString& sModName, const CString& sModPath, \ + CModInfo::EModuleType eType) \ + : CModule(pDLL, pUser, pNetwork, sModName, sModPath, eType) // User Module Macros /** This works exactly like MODULEDEFS, but for user modules. */ #define USERMODULEDEFS(CLASS, DESCRIPTION) \ - MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::UserModule) + MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::UserModule) // !User Module Macros // Global Module Macros /** This works exactly like MODULEDEFS, but for global modules. */ #define GLOBALMODULEDEFS(CLASS, DESCRIPTION) \ - MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::GlobalModule) + MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::GlobalModule) // !Global Module Macros // Network Module Macros /** This works exactly like MODULEDEFS, but for network modules. */ #define NETWORKMODULEDEFS(CLASS, DESCRIPTION) \ - MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::NetworkModule) + MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::NetworkModule) // !Network Module Macros /** At the end of your source file, you must call this macro in global context. @@ -129,51 +129,51 @@ class CSockManager; class CTimer : public CCron { public: - CTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription); + CTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription); - virtual ~CTimer(); + virtual ~CTimer(); - CTimer(const CTimer&) = delete; - CTimer& operator=(const CTimer&) = delete; + CTimer(const CTimer&) = delete; + CTimer& operator=(const CTimer&) = delete; - // Setters - void SetModule(CModule* p); - void SetDescription(const CString& s); - // !Setters + // Setters + void SetModule(CModule* p); + void SetDescription(const CString& s); + // !Setters - // Getters - CModule* GetModule() const; - const CString& GetDescription() const; - // !Getters + // Getters + CModule* GetModule() const; + const CString& GetDescription() const; + // !Getters private: protected: - CModule* m_pModule; - CString m_sDescription; + CModule* m_pModule; + CString m_sDescription; }; typedef void (*FPTimer_t)(CModule*, CFPTimer*); class CFPTimer : public CTimer { public: - CFPTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), - m_pFBCallback(nullptr) {} + CFPTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), + m_pFBCallback(nullptr) {} - virtual ~CFPTimer() {} + virtual ~CFPTimer() {} - void SetFPCallback(FPTimer_t p) { m_pFBCallback = p; } + void SetFPCallback(FPTimer_t p) { m_pFBCallback = p; } protected: - void RunJob() override { - if (m_pFBCallback) { - m_pFBCallback(m_pModule, this); - } - } + void RunJob() override { + if (m_pFBCallback) { + m_pFBCallback(m_pModule, this); + } + } private: - FPTimer_t m_pFBCallback; + FPTimer_t m_pFBCallback; }; #ifdef HAVE_PTHREAD @@ -181,23 +181,23 @@ class CFPTimer : public CTimer { /// cancelled when the module is unloaded. class CModuleJob : public CJob { public: - CModuleJob(CModule* pModule, const CString& sName, const CString& sDesc) - : CJob(), m_pModule(pModule), m_sName(sName), m_sDescription(sDesc) {} - virtual ~CModuleJob(); + CModuleJob(CModule* pModule, const CString& sName, const CString& sDesc) + : CJob(), m_pModule(pModule), m_sName(sName), m_sDescription(sDesc) {} + virtual ~CModuleJob(); - CModuleJob(const CModuleJob&) = delete; - CModuleJob& operator=(const CModuleJob&) = delete; + CModuleJob(const CModuleJob&) = delete; + CModuleJob& operator=(const CModuleJob&) = delete; - // Getters - CModule* GetModule() const { return m_pModule; } - const CString& GetName() const { return m_sName; } - const CString& GetDescription() const { return m_sDescription; } - // !Getters + // Getters + CModule* GetModule() const { return m_pModule; } + const CString& GetName() const { return m_sName; } + const CString& GetDescription() const { return m_sDescription; } + // !Getters protected: - CModule* m_pModule; - const CString m_sName; - const CString m_sDescription; + CModule* m_pModule; + const CString m_sName; + const CString m_sDescription; }; #endif @@ -205,81 +205,81 @@ typedef void* ModHandle; class CModInfo { public: - typedef enum { GlobalModule, UserModule, NetworkModule } EModuleType; + typedef enum { GlobalModule, UserModule, NetworkModule } EModuleType; - typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, - CIRCNetwork* pNetwork, - const CString& sModName, - const CString& sModPath, EModuleType eType); + typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, + CIRCNetwork* pNetwork, + const CString& sModName, + const CString& sModPath, EModuleType eType); - CModInfo() : CModInfo("", "", NetworkModule) {} - CModInfo(const CString& sName, const CString& sPath, EModuleType eType) - : m_seType(), - m_eDefaultType(eType), - m_sName(sName), - m_sPath(sPath), - m_sDescription(""), - m_sWikiPage(""), - m_sArgsHelpText(""), - m_bHasArgs(false), - m_fLoader(nullptr) {} - ~CModInfo() {} + CModInfo() : CModInfo("", "", NetworkModule) {} + CModInfo(const CString& sName, const CString& sPath, EModuleType eType) + : m_seType(), + m_eDefaultType(eType), + m_sName(sName), + m_sPath(sPath), + m_sDescription(""), + m_sWikiPage(""), + m_sArgsHelpText(""), + m_bHasArgs(false), + m_fLoader(nullptr) {} + ~CModInfo() {} - bool operator<(const CModInfo& Info) const { - return (GetName() < Info.GetName()); - } + bool operator<(const CModInfo& Info) const { + return (GetName() < Info.GetName()); + } - bool SupportsType(EModuleType eType) const { - return m_seType.find(eType) != m_seType.end(); - } + bool SupportsType(EModuleType eType) const { + return m_seType.find(eType) != m_seType.end(); + } - void AddType(EModuleType eType) { m_seType.insert(eType); } + void AddType(EModuleType eType) { m_seType.insert(eType); } - static CString ModuleTypeToString(EModuleType eType) { - switch (eType) { - case GlobalModule: - return "Global"; - case UserModule: - return "User"; - case NetworkModule: - return "Network"; - default: - return "UNKNOWN"; - } - } + static CString ModuleTypeToString(EModuleType eType) { + switch (eType) { + case GlobalModule: + return "Global"; + case UserModule: + return "User"; + case NetworkModule: + return "Network"; + default: + return "UNKNOWN"; + } + } - // Getters - const CString& GetName() const { return m_sName; } - const CString& GetPath() const { return m_sPath; } - const CString& GetDescription() const { return m_sDescription; } - const CString& GetWikiPage() const { return m_sWikiPage; } - const CString& GetArgsHelpText() const { return m_sArgsHelpText; } - bool GetHasArgs() const { return m_bHasArgs; } - ModLoader GetLoader() const { return m_fLoader; } - EModuleType GetDefaultType() const { return m_eDefaultType; } - // !Getters + // Getters + const CString& GetName() const { return m_sName; } + const CString& GetPath() const { return m_sPath; } + const CString& GetDescription() const { return m_sDescription; } + const CString& GetWikiPage() const { return m_sWikiPage; } + const CString& GetArgsHelpText() const { return m_sArgsHelpText; } + bool GetHasArgs() const { return m_bHasArgs; } + ModLoader GetLoader() const { return m_fLoader; } + EModuleType GetDefaultType() const { return m_eDefaultType; } + // !Getters - // Setters - void SetName(const CString& s) { m_sName = s; } - void SetPath(const CString& s) { m_sPath = s; } - void SetDescription(const CString& s) { m_sDescription = s; } - void SetWikiPage(const CString& s) { m_sWikiPage = s; } - void SetArgsHelpText(const CString& s) { m_sArgsHelpText = s; } - void SetHasArgs(bool b = false) { m_bHasArgs = b; } - void SetLoader(ModLoader fLoader) { m_fLoader = fLoader; } - void SetDefaultType(EModuleType eType) { m_eDefaultType = eType; } - // !Setters + // Setters + void SetName(const CString& s) { m_sName = s; } + void SetPath(const CString& s) { m_sPath = s; } + void SetDescription(const CString& s) { m_sDescription = s; } + void SetWikiPage(const CString& s) { m_sWikiPage = s; } + void SetArgsHelpText(const CString& s) { m_sArgsHelpText = s; } + void SetHasArgs(bool b = false) { m_bHasArgs = b; } + void SetLoader(ModLoader fLoader) { m_fLoader = fLoader; } + void SetDefaultType(EModuleType eType) { m_eDefaultType = eType; } + // !Setters private: protected: - std::set m_seType; - EModuleType m_eDefaultType; - CString m_sName; - CString m_sPath; - CString m_sDescription; - CString m_sWikiPage; - CString m_sArgsHelpText; - bool m_bHasArgs; - ModLoader m_fLoader; + std::set m_seType; + EModuleType m_eDefaultType; + CString m_sName; + CString m_sPath; + CString m_sDescription; + CString m_sWikiPage; + CString m_sArgsHelpText; + bool m_bHasArgs; + ModLoader m_fLoader; }; template @@ -289,63 +289,63 @@ template CModule* TModLoad(ModHandle p, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, const CString& sModPath, CModInfo::EModuleType eType) { - return new M(p, pUser, pNetwork, sModName, sModPath, eType); + return new M(p, pUser, pNetwork, sModName, sModPath, eType); } /** A helper class for handling commands in modules. */ class CModCommand { public: - /// Type for the callback function that handles the actual command. - typedef void (CModule::*ModCmdFunc)(const CString& sLine); - typedef std::function CmdFunc; + /// Type for the callback function that handles the actual command. + typedef void (CModule::*ModCmdFunc)(const CString& sLine); + typedef std::function CmdFunc; - /// Default constructor, needed so that this can be saved in a std::map. - CModCommand(); + /// Default constructor, needed so that this can be saved in a std::map. + CModCommand(); - /** Construct a new CModCommand. + /** Construct a new CModCommand. * @param sCmd The name of the command. * @param func The command's callback function. * @param sArgs Help text describing the arguments to this command. * @param sDesc Help text describing what this command does. */ - CModCommand(const CString& sCmd, CModule* pMod, ModCmdFunc func, - const CString& sArgs, const CString& sDesc); - CModCommand(const CString& sCmd, CmdFunc func, const CString& sArgs, - const CString& sDesc); + CModCommand(const CString& sCmd, CModule* pMod, ModCmdFunc func, + const CString& sArgs, const CString& sDesc); + CModCommand(const CString& sCmd, CmdFunc func, const CString& sArgs, + const CString& sDesc); - /** Copy constructor, needed so that this can be saved in a std::map. + /** Copy constructor, needed so that this can be saved in a std::map. * @param other Object to copy from. */ - CModCommand(const CModCommand& other); + CModCommand(const CModCommand& other); - /** Assignment operator, needed so that this can be saved in a std::map. + /** Assignment operator, needed so that this can be saved in a std::map. * @param other Object to copy from. */ - CModCommand& operator=(const CModCommand& other); + CModCommand& operator=(const CModCommand& other); - /** Initialize a CTable so that it can be used with AddHelp(). + /** Initialize a CTable so that it can be used with AddHelp(). * @param Table The instance of CTable to initialize. */ - static void InitHelp(CTable& Table); + static void InitHelp(CTable& Table); - /** Add this command to the CTable instance. + /** Add this command to the CTable instance. * @param Table Instance of CTable to which this should be added. * @warning The Table should be initialized via InitHelp(). */ - void AddHelp(CTable& Table) const; + void AddHelp(CTable& Table) const; - const CString& GetCommand() const { return m_sCmd; } - CmdFunc GetFunction() const { return m_pFunc; } - const CString& GetArgs() const { return m_sArgs; } - const CString& GetDescription() const { return m_sDesc; } + const CString& GetCommand() const { return m_sCmd; } + CmdFunc GetFunction() const { return m_pFunc; } + const CString& GetArgs() const { return m_sArgs; } + const CString& GetDescription() const { return m_sDesc; } - void Call(const CString& sLine) const { m_pFunc(sLine); } + void Call(const CString& sLine) const { m_pFunc(sLine); } private: - CString m_sCmd; - CmdFunc m_pFunc; - CString m_sArgs; - CString m_sDesc; + CString m_sCmd; + CmdFunc m_pFunc; + CString m_sArgs; + CString m_sDesc; }; /** The base class for your own ZNC modules. @@ -363,83 +363,83 @@ class CModCommand { */ class CModule { public: - CModule( - ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, - const CString& sModName, const CString& sDataDir, - CModInfo::EModuleType eType = - CModInfo::NetworkModule); // TODO: remove default value in ZNC 2.x - virtual ~CModule(); + CModule( + ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, + const CString& sModName, const CString& sDataDir, + CModInfo::EModuleType eType = + CModInfo::NetworkModule); // TODO: remove default value in ZNC 2.x + virtual ~CModule(); - CModule(const CModule&) = delete; - CModule& operator=(const CModule&) = delete; + CModule(const CModule&) = delete; + CModule& operator=(const CModule&) = delete; - /** This enum is just used for return from module hooks. Based on this + /** This enum is just used for return from module hooks. Based on this * return, ZNC then decides what to do with the event which caused the * module hook. */ - typedef enum { - /** ZNC will continue event processing normally. This is what + typedef enum { + /** ZNC will continue event processing normally. This is what * you should return normally. */ - CONTINUE = 1, - /** This is the same as both CModule::HALTMODS and + CONTINUE = 1, + /** This is the same as both CModule::HALTMODS and * CModule::HALTCORE together. */ - HALT = 2, - /** Stop sending this even to other modules which were not + HALT = 2, + /** Stop sending this even to other modules which were not * called yet. Internally, the event is handled normally. */ - HALTMODS = 3, - /** Continue calling other modules. When done, ignore the event + HALTMODS = 3, + /** Continue calling other modules. When done, ignore the event * in the ZNC core. (For most module hooks this means that a * given event won't be forwarded to the connected users) */ - HALTCORE = 4 - } EModRet; + HALTCORE = 4 + } EModRet; - typedef enum { - /** Your module can throw this enum at any given time. When this + typedef enum { + /** Your module can throw this enum at any given time. When this * is thrown, the module will be unloaded. */ - UNLOAD - } EModException; + UNLOAD + } EModException; - void SetUser(CUser* pUser); - void SetNetwork(CIRCNetwork* pNetwork); - void SetClient(CClient* pClient); + void SetUser(CUser* pUser); + void SetNetwork(CIRCNetwork* pNetwork); + void SetClient(CClient* pClient); - /** This function throws CModule::UNLOAD which causes this module to be unloaded. + /** This function throws CModule::UNLOAD which causes this module to be unloaded. */ - void Unload() { throw UNLOAD; } + void Unload() { throw UNLOAD; } - /** This module hook is called when a module is loaded + /** This module hook is called when a module is loaded * @param sArgsi The arguments for the modules. * @param sMessage A message that may be displayed to the user after * loading the module. Useful for returning error messages. * @return true if the module loaded successfully, else false. */ - virtual bool OnLoad(const CString& sArgsi, CString& sMessage); - /** This module hook is called during ZNC startup. Only modules loaded + virtual bool OnLoad(const CString& sArgsi, CString& sMessage); + /** This module hook is called during ZNC startup. Only modules loaded * from znc.conf get this call. * @return false to abort ZNC startup. */ - virtual bool OnBoot(); + virtual bool OnBoot(); - /** Modules which can only be used with an active user session have to return true here. + /** Modules which can only be used with an active user session have to return true here. * @return false for modules that can do stuff for non-logged in web users as well. */ - virtual bool WebRequiresLogin() { return true; } - /** Return true if this module should only be usable for admins on the web. + virtual bool WebRequiresLogin() { return true; } + /** Return true if this module should only be usable for admins on the web. * @return false if normal users can use this module's web pages as well. */ - virtual bool WebRequiresAdmin() { return false; } - /** Return the title of the module's section in the web interface's side bar. + virtual bool WebRequiresAdmin() { return false; } + /** Return the title of the module's section in the web interface's side bar. * @return The Title. */ - virtual CString GetWebMenuTitle() { return ""; } - virtual CString GetWebPath(); - virtual CString GetWebFilesPath(); - /** For WebMods: Called before the list of registered SubPages will be checked. + virtual CString GetWebMenuTitle() { return ""; } + virtual CString GetWebPath(); + virtual CString GetWebFilesPath(); + /** For WebMods: Called before the list of registered SubPages will be checked. * Important: If you return true, you need to take care of calling WebSock.Close! * This allows for stuff like returning non-templated data, long-polling and other fun. * @param WebSock The active request. @@ -447,8 +447,8 @@ class CModule { * @return true if you handled the page request or false if the name is to be checked * against the list of registered SubPages and their permission settings. */ - virtual bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName); - /** If OnWebPreRequest returned false, and the RequiresAdmin/IsAdmin check has been passed, + virtual bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName); + /** If OnWebPreRequest returned false, and the RequiresAdmin/IsAdmin check has been passed, * this method will be called with the page name. It will also be called for pages that * have NOT been specifically registered with AddSubPage. * @param WebSock The active request. @@ -457,22 +457,22 @@ class CModule { * @return You MUST return true if you want the template to be evaluated and sent to the browser. * Return false if you called Redirect() or PrintErrorPage(). If you didn't, a 404 page will be sent. */ - virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl); - /** Registers a sub page for the sidebar. + virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl); + /** Registers a sub page for the sidebar. * @param spSubPage The SubPage instance. */ - virtual void AddSubPage(TWebSubPage spSubPage) { - m_vSubPages.push_back(spSubPage); - } - /** Removes all registered (AddSubPage'd) SubPages. + virtual void AddSubPage(TWebSubPage spSubPage) { + m_vSubPages.push_back(spSubPage); + } + /** Removes all registered (AddSubPage'd) SubPages. */ - virtual void ClearSubPages() { m_vSubPages.clear(); } - /** Returns a list of all registered SubPages. Don't mess with it too much. + virtual void ClearSubPages() { m_vSubPages.clear(); } + /** Returns a list of all registered SubPages. Don't mess with it too much. * @return The List. */ - virtual VWebSubPages& GetSubPages() { return m_vSubPages; } - /** Using this hook, module can embed web stuff directly to different places. + virtual VWebSubPages& GetSubPages() { return m_vSubPages; } + /** Using this hook, module can embed web stuff directly to different places. * This method is called whenever embededded modules I/O happens. * Name of used .tmpl file (if any) is up to caller. * @param WebSock Socket for web connection, don't do bad things with it. @@ -481,30 +481,30 @@ class CModule { * @return If you don't need to embed web stuff to the specified place, just return false. * Exact meaning of return value is up to caller, and depends on context. */ - virtual bool OnEmbeddedWebRequest(CWebSock& WebSock, - const CString& sPageName, - CTemplate& Tmpl); + virtual bool OnEmbeddedWebRequest(CWebSock& WebSock, + const CString& sPageName, + CTemplate& Tmpl); - /** Called just before znc.conf is rehashed */ - virtual void OnPreRehash(); - /** This module hook is called after a successful rehash. */ - virtual void OnPostRehash(); - /** This module hook is called when a user gets disconnected from IRC. */ - virtual void OnIRCDisconnected(); - /** This module hook is called after a successful login to IRC. */ - virtual void OnIRCConnected(); - /** This module hook is called just before ZNC tries to establish a + /** Called just before znc.conf is rehashed */ + virtual void OnPreRehash(); + /** This module hook is called after a successful rehash. */ + virtual void OnPostRehash(); + /** This module hook is called when a user gets disconnected from IRC. */ + virtual void OnIRCDisconnected(); + /** This module hook is called after a successful login to IRC. */ + virtual void OnIRCConnected(); + /** This module hook is called just before ZNC tries to establish a * connection to an IRC server. * @param pIRCSock The socket that will be used for the connection. * @return See CModule::EModRet. */ - virtual EModRet OnIRCConnecting(CIRCSock* pIRCSock); - /** This module hook is called when a CIRCSock fails to connect or + virtual EModRet OnIRCConnecting(CIRCSock* pIRCSock); + /** This module hook is called when a CIRCSock fails to connect or * a module returned HALTCORE from OnIRCConnecting. * @param pIRCSock The socket that failed to connect. */ - virtual void OnIRCConnectionError(CIRCSock* pIRCSock); - /** This module hook is called before loging in to the IRC server. The + virtual void OnIRCConnectionError(CIRCSock* pIRCSock); + /** This module hook is called before loging in to the IRC server. The * low-level connection is established at this point, but SSL * handshakes didn't necessarily finish yet. * @param sPass The server password that will be used. @@ -514,15 +514,15 @@ class CModule { * @param sRealName The real name that will be used. * @return See CModule::EModRet. */ - virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick, - CString& sIdent, CString& sRealName); - /** This module hook is called when a message is broadcasted to all users. + virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick, + CString& sIdent, CString& sRealName); + /** This module hook is called when a message is broadcasted to all users. * @param sMessage The message that is broadcasted. * @return see CModule::EModRet */ - virtual EModRet OnBroadcast(CString& sMessage); + virtual EModRet OnBroadcast(CString& sMessage); - /** This module hook is called when a user mode on a channel changes. + /** This module hook is called when a user mode on a channel changes. * @param pOpNick The nick who sent the mode change, or nullptr if set by server. * @param Nick The nick whose channel mode changes. * @param Channel The channel on which the user mode is changed. @@ -533,33 +533,33 @@ class CModule { * @see CIRCSock::GetModeType() for converting uMode into a mode (e.g. * 'o' for op). */ - virtual void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, - bool bAdded, bool bNoChange); - virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, - bool bAdded, bool bNoChange); - /** Called when a nick is opped on a channel */ - virtual void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - virtual void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - /** Called when a nick is deopped on a channel */ - virtual void OnDeop2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, bool bNoChange); - virtual void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - /** Called when a nick is voiced on a channel */ - virtual void OnVoice2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, bool bNoChange); - virtual void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - /** Called when a nick is devoiced on a channel */ - virtual void OnDevoice2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, bool bNoChange); - virtual void OnDevoice(const CNick& OpNick, const CNick& Nick, - CChan& Channel, bool bNoChange); - /** Called on an individual channel mode change. + virtual void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, + bool bAdded, bool bNoChange); + virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, + bool bAdded, bool bNoChange); + /** Called when a nick is opped on a channel */ + virtual void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + virtual void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + /** Called when a nick is deopped on a channel */ + virtual void OnDeop2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, bool bNoChange); + virtual void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + /** Called when a nick is voiced on a channel */ + virtual void OnVoice2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, bool bNoChange); + virtual void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + /** Called when a nick is devoiced on a channel */ + virtual void OnDevoice2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, bool bNoChange); + virtual void OnDevoice(const CNick& OpNick, const CNick& Nick, + CChan& Channel, bool bNoChange); + /** Called on an individual channel mode change. * @param pOpNick The nick who changes the channel mode, or nullptr if set by server. * @param Channel The channel whose mode is changed. * @param uMode The mode character that is changed. @@ -567,664 +567,664 @@ class CModule { * @param bAdded True if this mode is added ("+"), else false. * @param bNoChange True if this mode was already effective before. */ - virtual void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange); - virtual void OnMode(const CNick& OpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange); - /** Called on any channel mode change. This is called before the more + virtual void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange); + virtual void OnMode(const CNick& OpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange); + /** Called on any channel mode change. This is called before the more * detailed mode hooks like e.g. OnOp() and OnMode(). * @param pOpNick The nick who changes the channel mode, or nullptr if set by server. * @param Channel The channel whose mode is changed. * @param sModes The raw mode change, e.g. "+s-io". * @param sArgs All arguments to the mode change from sModes. */ - virtual void OnRawMode2(const CNick* pOpNick, CChan& Channel, - const CString& sModes, const CString& sArgs); - virtual void OnRawMode(const CNick& OpNick, CChan& Channel, - const CString& sModes, const CString& sArgs); + virtual void OnRawMode2(const CNick* pOpNick, CChan& Channel, + const CString& sModes, const CString& sArgs); + virtual void OnRawMode(const CNick& OpNick, CChan& Channel, + const CString& sModes, const CString& sArgs); - /** Called on any raw IRC line received from the IRC server. + /** Called on any raw IRC line received from the IRC server. * @param sLine The line read from the server. * @note The line does not include message tags. Use OnRawMessage() to access them. * @return See CModule::EModRet. */ - virtual EModRet OnRaw(CString& sLine); - /** Called on any raw message received from the IRC server. + virtual EModRet OnRaw(CString& sLine); + /** Called on any raw message received from the IRC server. * @since 1.7.0 * @param Message The received message. * @return See CModule::EModRet. */ - virtual EModRet OnRawMessage(CMessage& Message); + virtual EModRet OnRawMessage(CMessage& Message); - /** Called when a numeric message is received from the IRC server. + /** Called when a numeric message is received from the IRC server. * @since 1.7.0 * @param Message The received message. * @return See CModule::EModRet. */ - virtual EModRet OnNumericMessage(CNumericMessage& Message); + virtual EModRet OnNumericMessage(CNumericMessage& Message); - /** Called when a command to *status is sent. + /** Called when a command to *status is sent. * @param sCommand The command sent. * @return See CModule::EModRet. */ - virtual EModRet OnStatusCommand(CString& sCommand); - /** Called when a command to your module is sent, e.g. query to *modname. + virtual EModRet OnStatusCommand(CString& sCommand); + /** Called when a command to your module is sent, e.g. query to *modname. * @param sCommand The command that was sent. */ - virtual void OnModCommand(const CString& sCommand); - /** This is similar to OnModCommand(), but it is only called if + virtual void OnModCommand(const CString& sCommand); + /** This is similar to OnModCommand(), but it is only called if * HandleCommand didn't find any that wants to handle this. This is only * called if HandleCommand() is called, which practically means that * this is only called if you don't overload OnModCommand(). * @param sCommand The command that was sent. */ - virtual void OnUnknownModCommand(const CString& sCommand); - /** Called when a your module nick was sent a notice. + virtual void OnUnknownModCommand(const CString& sCommand); + /** Called when a your module nick was sent a notice. * @param sMessage The message which was sent. */ - virtual void OnModNotice(const CString& sMessage); - /** Called when your module nick was sent a CTCP message. OnModCommand() + virtual void OnModNotice(const CString& sMessage); + /** Called when your module nick was sent a CTCP message. OnModCommand() * won't be called for this message. * @param sMessage The message which was sent. */ - virtual void OnModCTCP(const CString& sMessage); + virtual void OnModCTCP(const CString& sMessage); - /** Called when a nick quit from IRC. + /** Called when a nick quit from IRC. * @since 1.7.0 * @param Message The quit message. * @param vChans List of channels which you and nick share. */ - virtual void OnQuitMessage(CQuitMessage& Message, - const std::vector& vChans); - /// @deprecated Use OnQuitMessage() instead. - virtual void OnQuit(const CNick& Nick, const CString& sMessage, - const std::vector& vChans); + virtual void OnQuitMessage(CQuitMessage& Message, + const std::vector& vChans); + /// @deprecated Use OnQuitMessage() instead. + virtual void OnQuit(const CNick& Nick, const CString& sMessage, + const std::vector& vChans); - /** Called when a nickname change occurs. + /** Called when a nickname change occurs. * @since 1.7.0 * @param Message The nick message. * @param vChans Channels which we and nick share. */ - virtual void OnNickMessage(CNickMessage& Message, - const std::vector& vChans); - /// @deprecated Use OnNickMessage() instead. - virtual void OnNick(const CNick& Nick, const CString& sNewNick, - const std::vector& vChans); + virtual void OnNickMessage(CNickMessage& Message, + const std::vector& vChans); + /// @deprecated Use OnNickMessage() instead. + virtual void OnNick(const CNick& Nick, const CString& sNewNick, + const std::vector& vChans); - /** Called when a nick is kicked from a channel. + /** Called when a nick is kicked from a channel. * @since 1.7.0 * @param Message The kick message. */ - virtual void OnKickMessage(CKickMessage& Message); - /// @deprecated Use OnKickMessage() instead. - virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, - CChan& Channel, const CString& sMessage); + virtual void OnKickMessage(CKickMessage& Message); + /// @deprecated Use OnKickMessage() instead. + virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, + CChan& Channel, const CString& sMessage); - /** This module hook is called just before ZNC tries to join an IRC channel. + /** This module hook is called just before ZNC tries to join an IRC channel. * @param Chan The channel which is about to get joined. * @return See CModule::EModRet. */ - virtual EModRet OnJoining(CChan& Channel); + virtual EModRet OnJoining(CChan& Channel); - /** Called when a nick joins a channel. + /** Called when a nick joins a channel. * @since 1.7.0 * @param Message The join message. */ - virtual void OnJoinMessage(CJoinMessage& Message); - /// @deprecated Use OnJoinMessage() instead. - virtual void OnJoin(const CNick& Nick, CChan& Channel); + virtual void OnJoinMessage(CJoinMessage& Message); + /// @deprecated Use OnJoinMessage() instead. + virtual void OnJoin(const CNick& Nick, CChan& Channel); - /** Called when a nick parts a channel. + /** Called when a nick parts a channel. * @since 1.7.0 * @param Message The part message. */ - virtual void OnPartMessage(CPartMessage& Message); - /// @deprecated Use OnPartMessage() instead. - virtual void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage); + virtual void OnPartMessage(CPartMessage& Message); + /// @deprecated Use OnPartMessage() instead. + virtual void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage); - /** Called when user is invited into a channel + /** Called when user is invited into a channel * @param Nick The nick who invited you. * @param sChan The channel the user got invited into * @return See CModule::EModRet. * @todo Add OnInviteMessage() hook */ - virtual EModRet OnInvite(const CNick& Nick, const CString& sChan); + virtual EModRet OnInvite(const CNick& Nick, const CString& sChan); - /** Called before a channel buffer is played back to a client. + /** Called before a channel buffer is played back to a client. * @param Chan The channel which will be played back. * @param Client The client the buffer will be played back to. * @return See CModule::EModRet. */ - virtual EModRet OnChanBufferStarting(CChan& Chan, CClient& Client); - /** Called after a channel buffer was played back to a client. + virtual EModRet OnChanBufferStarting(CChan& Chan, CClient& Client); + /** Called after a channel buffer was played back to a client. * @param Chan The channel which was played back. * @param Client The client the buffer was played back to. * @return See CModule::EModRet. */ - virtual EModRet OnChanBufferEnding(CChan& Chan, CClient& Client); + virtual EModRet OnChanBufferEnding(CChan& Chan, CClient& Client); - /** Called for each message during a channel's buffer play back. + /** Called for each message during a channel's buffer play back. * @since 1.7.0 * @param Message The playback message. * @return See CModule::EModRet. */ - virtual EModRet OnChanBufferPlayMessage(CMessage& Message); - /// @deprecated Use OnChanBufferPlayMessage() instead. - virtual EModRet OnChanBufferPlayLine2(CChan& Chan, CClient& Client, - CString& sLine, const timeval& tv); - /// @deprecated Use OnChanBufferPlayMessage() instead. - virtual EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, - CString& sLine); + virtual EModRet OnChanBufferPlayMessage(CMessage& Message); + /// @deprecated Use OnChanBufferPlayMessage() instead. + virtual EModRet OnChanBufferPlayLine2(CChan& Chan, CClient& Client, + CString& sLine, const timeval& tv); + /// @deprecated Use OnChanBufferPlayMessage() instead. + virtual EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, + CString& sLine); - /** Called for each message during a query's buffer play back. + /** Called for each message during a query's buffer play back. * @since 1.7.0 * @param Message The playback message. * @return See CModule::EModRet. */ - virtual EModRet OnPrivBufferPlayMessage(CMessage& Message); - /// @deprecated Use OnPrivBufferPlayMessage() instead. - virtual EModRet OnPrivBufferPlayLine2(CClient& Client, CString& sLine, - const timeval& tv); - /// @deprecated Use OnPrivBufferPlayMessage() instead. - virtual EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine); + virtual EModRet OnPrivBufferPlayMessage(CMessage& Message); + /// @deprecated Use OnPrivBufferPlayMessage() instead. + virtual EModRet OnPrivBufferPlayLine2(CClient& Client, CString& sLine, + const timeval& tv); + /// @deprecated Use OnPrivBufferPlayMessage() instead. + virtual EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine); - /** Called when a client successfully logged in to ZNC. */ - virtual void OnClientLogin(); - /** Called when a client disconnected from ZNC. */ - virtual void OnClientDisconnect(); + /** Called when a client successfully logged in to ZNC. */ + virtual void OnClientLogin(); + /** Called when a client disconnected from ZNC. */ + virtual void OnClientDisconnect(); - /** This module hook is called when a client sends a raw traffic line to ZNC. + /** This module hook is called when a client sends a raw traffic line to ZNC. * @param sLine The raw traffic line sent. * @note The line does not include message tags. Use OnUserRawMessage() to access them. * @return See CModule::EModRet. */ - virtual EModRet OnUserRaw(CString& sLine); - /** This module hook is called when a client sends any message to ZNC. + virtual EModRet OnUserRaw(CString& sLine); + /** This module hook is called when a client sends any message to ZNC. * @since 1.7.0 * @param Message The message sent. * @return See CModule::EModRet. */ - virtual EModRet OnUserRawMessage(CMessage& Message); + virtual EModRet OnUserRawMessage(CMessage& Message); - /** This module hook is called when a client sends a CTCP reply. + /** This module hook is called when a client sends a CTCP reply. * @since 1.7.0 * @param Message The CTCP reply message. * @return See CModule::EModRet. */ - virtual EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message); - /// @deprecated Use OnUserCTCPReplyMessage() instead. - virtual EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage); + virtual EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message); + /// @deprecated Use OnUserCTCPReplyMessage() instead. + virtual EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage); - /** This module hook is called when a client sends a CTCP request. + /** This module hook is called when a client sends a CTCP request. * @since 1.7.0 * @param Message The CTCP request message. * @return See CModule::EModRet. * @note This is not called for CTCP ACTION messages, use * CModule::OnUserActionMessage() instead. */ - virtual EModRet OnUserCTCPMessage(CCTCPMessage& Message); - /// @deprecated Use OnUserCTCPMessage() instead. - virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage); + virtual EModRet OnUserCTCPMessage(CCTCPMessage& Message); + /// @deprecated Use OnUserCTCPMessage() instead. + virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage); - /** Called when a client sends a CTCP ACTION request ("/me"). + /** Called when a client sends a CTCP ACTION request ("/me"). * @since 1.7.0 * @param Message The action message. * @return See CModule::EModRet. * @note CModule::OnUserCTCPMessage() will not be called for this message. */ - virtual EModRet OnUserActionMessage(CActionMessage& Message); - /// @deprecated Use OnUserActionMessage() instead. - virtual EModRet OnUserAction(CString& sTarget, CString& sMessage); + virtual EModRet OnUserActionMessage(CActionMessage& Message); + /// @deprecated Use OnUserActionMessage() instead. + virtual EModRet OnUserAction(CString& sTarget, CString& sMessage); - /** This module hook is called when a user sends a normal IRC message. + /** This module hook is called when a user sends a normal IRC message. * @since 1.7.0 * @param Message The message which was sent. * @return See CModule::EModRet. */ - virtual EModRet OnUserTextMessage(CTextMessage& Message); - /// @deprecated Use OnUserTextMessage() instead. - virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage); + virtual EModRet OnUserTextMessage(CTextMessage& Message); + /// @deprecated Use OnUserTextMessage() instead. + virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage); - /** This module hook is called when a user sends a notice message. + /** This module hook is called when a user sends a notice message. * @since 1.7.0 * @param Message The message which was sent. * @return See CModule::EModRet. */ - virtual EModRet OnUserNoticeMessage(CNoticeMessage& Message); - /// @deprecated Use OnUserNoticeMessage() instead. - virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage); + virtual EModRet OnUserNoticeMessage(CNoticeMessage& Message); + /// @deprecated Use OnUserNoticeMessage() instead. + virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage); - /** This hooks is called when a user sends a JOIN message. + /** This hooks is called when a user sends a JOIN message. * @since 1.7.0 * @param Message The join message. * @return See CModule::EModRet. */ - virtual EModRet OnUserJoinMessage(CJoinMessage& Message); - /// @deprecated Use OnUserJoinMessage() instead. - virtual EModRet OnUserJoin(CString& sChannel, CString& sKey); + virtual EModRet OnUserJoinMessage(CJoinMessage& Message); + /// @deprecated Use OnUserJoinMessage() instead. + virtual EModRet OnUserJoin(CString& sChannel, CString& sKey); - /** This hooks is called when a user sends a PART message. + /** This hooks is called when a user sends a PART message. * @since 1.7.0 * @param Message The part message. * @return See CModule::EModRet. */ - virtual EModRet OnUserPartMessage(CPartMessage& Message); - /// @deprecated Use OnUserPartMessage() instead. - virtual EModRet OnUserPart(CString& sChannel, CString& sMessage); + virtual EModRet OnUserPartMessage(CPartMessage& Message); + /// @deprecated Use OnUserPartMessage() instead. + virtual EModRet OnUserPart(CString& sChannel, CString& sMessage); - /** This module hook is called when a user wants to change a channel topic. + /** This module hook is called when a user wants to change a channel topic. * @since 1.7.0 * @param Message The topic message. * @return See CModule::EModRet. */ - virtual EModRet OnUserTopicMessage(CTopicMessage& Message); - /// @deprecated Use OnUserTopicMessage() instead. - virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic); + virtual EModRet OnUserTopicMessage(CTopicMessage& Message); + /// @deprecated Use OnUserTopicMessage() instead. + virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic); - /** This hook is called when a user requests a channel's topic. + /** This hook is called when a user requests a channel's topic. * @param sChannel The channel for which the request is. * @return See CModule::EModRet. */ - virtual EModRet OnUserTopicRequest(CString& sChannel); + virtual EModRet OnUserTopicRequest(CString& sChannel); - /** This module hook is called when a user requests to quit from network. + /** This module hook is called when a user requests to quit from network. * @since 1.7.0 * @param Message The quit message the client sent. * @return See CModule::EModRet. */ - virtual EModRet OnUserQuitMessage(CQuitMessage& Message); - /// @deprecated Use OnUserQuitMessage() instead. - virtual EModRet OnUserQuit(CString& sMessage); + virtual EModRet OnUserQuitMessage(CQuitMessage& Message); + /// @deprecated Use OnUserQuitMessage() instead. + virtual EModRet OnUserQuit(CString& sMessage); - /** Called when we receive a CTCP reply from IRC. + /** Called when we receive a CTCP reply from IRC. * @since 1.7.0 * @param Message The CTCP reply message. * @return See CModule::EModRet. */ - virtual EModRet OnCTCPReplyMessage(CCTCPMessage& Message); - /// @deprecated Use OnCTCPReplyMessage() instead. - virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage); + virtual EModRet OnCTCPReplyMessage(CCTCPMessage& Message); + /// @deprecated Use OnCTCPReplyMessage() instead. + virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage); - /** Called when we receive a private CTCP request from IRC. + /** Called when we receive a private CTCP request from IRC. * @since 1.7.0 * @param Message The CTCP request message. * @return See CModule::EModRet. */ - virtual EModRet OnPrivCTCPMessage(CCTCPMessage& Message); - /// @deprecated Use OnPrivCTCPMessage() instead. - virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage); + virtual EModRet OnPrivCTCPMessage(CCTCPMessage& Message); + /// @deprecated Use OnPrivCTCPMessage() instead. + virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage); - /** Called when we receive a channel CTCP request from IRC. + /** Called when we receive a channel CTCP request from IRC. * @since 1.7.0 * @param Message The CTCP request message. * @return See CModule::EModRet. */ - virtual EModRet OnChanCTCPMessage(CCTCPMessage& Message); - /// @deprecated Use OnChanCTCPMessage() instead. - virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage); + virtual EModRet OnChanCTCPMessage(CCTCPMessage& Message); + /// @deprecated Use OnChanCTCPMessage() instead. + virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage); - /** Called when we receive a private CTCP ACTION ("/me" in query) from IRC. + /** Called when we receive a private CTCP ACTION ("/me" in query) from IRC. * @since 1.7.0 * @param Message The action message * @return See CModule::EModRet. */ - virtual EModRet OnPrivActionMessage(CActionMessage& Message); - /// @deprecated Use OnPrivActionMessage() instead. - virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage); + virtual EModRet OnPrivActionMessage(CActionMessage& Message); + /// @deprecated Use OnPrivActionMessage() instead. + virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage); - /** Called when we receive a channel CTCP ACTION ("/me" in a channel) from IRC. + /** Called when we receive a channel CTCP ACTION ("/me" in a channel) from IRC. * @since 1.7.0 * @param Message The action message * @return See CModule::EModRet. */ - virtual EModRet OnChanActionMessage(CActionMessage& Message); - /// @deprecated Use OnChanActionMessage() instead. - virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage); + virtual EModRet OnChanActionMessage(CActionMessage& Message); + /// @deprecated Use OnChanActionMessage() instead. + virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage); - /** Called when we receive a private message from IRC. + /** Called when we receive a private message from IRC. * @since 1.7.0 * @param Message The private message. * @return See CModule::EModRet. */ - virtual EModRet OnPrivMessage(CTextMessage& Message); - /// @deprecated Use OnPrivMessage() instead. - virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage); + virtual EModRet OnPrivMessage(CTextMessage& Message); + /// @deprecated Use OnPrivMessage() instead. + virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage); - /** Called when we receive a channel message from IRC. + /** Called when we receive a channel message from IRC. * @since 1.7.0 * @param Message The channel message. * @return See CModule::EModRet. */ - virtual EModRet OnChanMessage(CTextMessage& Message); - /// @deprecated Use OnChanMessage() instead. - virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage); + virtual EModRet OnChanMessage(CTextMessage& Message); + /// @deprecated Use OnChanMessage() instead. + virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage); - /** Called when we receive a private notice. + /** Called when we receive a private notice. * @since 1.7.0 * @param Message The notice message. * @return See CModule::EModRet. */ - virtual EModRet OnPrivNoticeMessage(CNoticeMessage& Message); - /// @deprecated Use OnPrivNoticeMessage() instead. - virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage); + virtual EModRet OnPrivNoticeMessage(CNoticeMessage& Message); + /// @deprecated Use OnPrivNoticeMessage() instead. + virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage); - /** Called when we receive a channel notice. + /** Called when we receive a channel notice. * @since 1.7.0 * @param Message The notice message. * @return See CModule::EModRet. */ - virtual EModRet OnChanNoticeMessage(CNoticeMessage& Message); - /// @deprecated Use OnChanNoticeMessage() instead. - virtual EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage); + virtual EModRet OnChanNoticeMessage(CNoticeMessage& Message); + /// @deprecated Use OnChanNoticeMessage() instead. + virtual EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage); - /** Called when we receive a channel topic change from IRC. + /** Called when we receive a channel topic change from IRC. * @since 1.7.0 * @param Message The topic message. * @return See CModule::EModRet. */ - virtual EModRet OnTopicMessage(CTopicMessage& Message); - /// @deprecated Use OnTopicMessage() instead. - virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic); + virtual EModRet OnTopicMessage(CTopicMessage& Message); + /// @deprecated Use OnTopicMessage() instead. + virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic); - /** Called for every CAP received via CAP LS from server. + /** Called for every CAP received via CAP LS from server. * @param sCap capability supported by server. * @return true if your module supports this CAP and * needs to turn it on with CAP REQ. */ - virtual bool OnServerCapAvailable(const CString& sCap); - /** Called for every CAP accepted or rejected by server + virtual bool OnServerCapAvailable(const CString& sCap); + /** Called for every CAP accepted or rejected by server * (with CAP ACK or CAP NAK after our CAP REQ). * @param sCap capability accepted/rejected by server. * @param bSuccess true if capability was accepted, false if rejected. */ - virtual void OnServerCapResult(const CString& sCap, bool bSuccess); + virtual void OnServerCapResult(const CString& sCap, bool bSuccess); - /** This module hook is called just before ZNC tries to join a channel + /** This module hook is called just before ZNC tries to join a channel * by itself because it's in the config but wasn't joined yet. * @param Channel The channel which will be joined. * @return See CModule::EModRet. */ - virtual EModRet OnTimerAutoJoin(CChan& Channel); + virtual EModRet OnTimerAutoJoin(CChan& Channel); - /** This module hook is called when a network is being added. + /** This module hook is called when a network is being added. * @param Network The new IRC network. * @param sErrorRet A message that may be displayed to the user if * the module stops adding the network. * @return See CModule::EModRet. */ - virtual EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet); - /** This module hook is called when a network is deleted. + virtual EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet); + /** This module hook is called when a network is deleted. * @param Network The IRC network which is going to be deleted. * @return See CModule::EModRet. */ - virtual EModRet OnDeleteNetwork(CIRCNetwork& Network); + virtual EModRet OnDeleteNetwork(CIRCNetwork& Network); - /** Called when ZNC sends a raw traffic line to a client. + /** Called when ZNC sends a raw traffic line to a client. * @param sLine The raw traffic line sent. * @param Client The client this line is sent to. * @warning Calling PutUser() from within this hook leads to infinite recursion. * @return See CModule::EModRet. */ - virtual EModRet OnSendToClient(CString& sLine, CClient& Client); - /** Called when ZNC sends a raw traffic line to the IRC server. + virtual EModRet OnSendToClient(CString& sLine, CClient& Client); + /** Called when ZNC sends a raw traffic line to the IRC server. * @param sLine The raw traffic line sent. * @warning Calling PutIRC() from within this hook leads to infinite recursion. * @return See CModule::EModRet. */ - virtual EModRet OnSendToIRC(CString& sLine); + virtual EModRet OnSendToIRC(CString& sLine); - ModHandle GetDLL() { return m_pDLL; } - static double GetCoreVersion() { return VERSION; } + ModHandle GetDLL() { return m_pDLL; } + static double GetCoreVersion() { return VERSION; } - /** This function sends a given raw IRC line to the IRC server, if we + /** This function sends a given raw IRC line to the IRC server, if we * are connected to one. Else this line is discarded. * @param sLine The line which should be sent. * @return true if the line was queued for sending. */ - virtual bool PutIRC(const CString& sLine); - /** This function sends a given raw IRC line to a client. + virtual bool PutIRC(const CString& sLine); + /** This function sends a given raw IRC line to a client. * If we are in a module hook which is called for a specific client, * only that client will get the line, else all connected clients will * receive this line. * @param sLine The line which should be sent. * @return true if the line was sent to at least one client. */ - virtual bool PutUser(const CString& sLine); - /** This function generates a query from *status. If we are in a module + virtual bool PutUser(const CString& sLine); + /** This function generates a query from *status. If we are in a module * hook for a specific client, only that client gets this message, else * all connected clients will receive it. * @param sLine The message which should be sent from *status. * @return true if the line was sent to at least one client. */ - virtual bool PutStatus(const CString& sLine); - /** This function sends a query from your module nick. If we are in a + virtual bool PutStatus(const CString& sLine); + /** This function sends a query from your module nick. If we are in a * module hook for a specific client, only that client gets this * message, else all connected clients will receive it. * @param sLine The message which should be sent. * @return true if the line was sent to at least one client. */ - virtual bool PutModule(const CString& sLine); - /** This function calls CModule::PutModule(const CString&, const + virtual bool PutModule(const CString& sLine); + /** This function calls CModule::PutModule(const CString&, const * CString&, const CString&) for each line in the table. * @param table The table which should be send. * @return The number of lines sent. */ - virtual unsigned int PutModule(const CTable& table); - /** Send a notice from your module nick. If we are in a module hook for + virtual unsigned int PutModule(const CTable& table); + /** Send a notice from your module nick. If we are in a module hook for * a specific client, only that client gets this notice, else all * clients will receive it. * @param sLine The line which should be sent. * @return true if the line was sent to at least one client. */ - virtual bool PutModNotice(const CString& sLine); + virtual bool PutModNotice(const CString& sLine); - /** @returns The name of the module. */ - const CString& GetModName() const { return m_sModName; } + /** @returns The name of the module. */ + const CString& GetModName() const { return m_sModName; } - /** @returns The nick of the module. This is just the module name + /** @returns The nick of the module. This is just the module name * prefixed by the status prefix. */ - CString GetModNick() const; + CString GetModNick() const; - /** Get the module's data dir. + /** Get the module's data dir. * Modules can be accompanied by static data, e.g. skins for webadmin. * These function will return the path to that data. */ - const CString& GetModDataDir() const { return m_sDataDir; } + const CString& GetModDataDir() const { return m_sDataDir; } - // Timer stuff - bool AddTimer(CTimer* pTimer); - bool AddTimer(FPTimer_t pFBCallback, const CString& sLabel, u_int uInterval, - u_int uCycles = 0, const CString& sDescription = ""); - bool RemTimer(CTimer* pTimer); - bool RemTimer(const CString& sLabel); - bool UnlinkTimer(CTimer* pTimer); - CTimer* FindTimer(const CString& sLabel); - std::set::const_iterator BeginTimers() const { - return m_sTimers.begin(); - } - std::set::const_iterator EndTimers() const { - return m_sTimers.end(); - } - virtual void ListTimers(); - // !Timer stuff + // Timer stuff + bool AddTimer(CTimer* pTimer); + bool AddTimer(FPTimer_t pFBCallback, const CString& sLabel, u_int uInterval, + u_int uCycles = 0, const CString& sDescription = ""); + bool RemTimer(CTimer* pTimer); + bool RemTimer(const CString& sLabel); + bool UnlinkTimer(CTimer* pTimer); + CTimer* FindTimer(const CString& sLabel); + std::set::const_iterator BeginTimers() const { + return m_sTimers.begin(); + } + std::set::const_iterator EndTimers() const { + return m_sTimers.end(); + } + virtual void ListTimers(); + // !Timer stuff - // Socket stuff - bool AddSocket(CSocket* pSocket); - bool RemSocket(CSocket* pSocket); - bool RemSocket(const CString& sSockName); - bool UnlinkSocket(CSocket* pSocket); - CSocket* FindSocket(const CString& sSockName); - std::set::const_iterator BeginSockets() const { - return m_sSockets.begin(); - } - std::set::const_iterator EndSockets() const { - return m_sSockets.end(); - } - virtual void ListSockets(); + // Socket stuff + bool AddSocket(CSocket* pSocket); + bool RemSocket(CSocket* pSocket); + bool RemSocket(const CString& sSockName); + bool UnlinkSocket(CSocket* pSocket); + CSocket* FindSocket(const CString& sSockName); + std::set::const_iterator BeginSockets() const { + return m_sSockets.begin(); + } + std::set::const_iterator EndSockets() const { + return m_sSockets.end(); + } + virtual void ListSockets(); // !Socket stuff #ifdef HAVE_PTHREAD - // Job stuff - void AddJob(CModuleJob* pJob); - void CancelJob(CModuleJob* pJob); - bool CancelJob(const CString& sJobName); - void CancelJobs(const std::set& sJobs); - bool UnlinkJob(CModuleJob* pJob); + // Job stuff + void AddJob(CModuleJob* pJob); + void CancelJob(CModuleJob* pJob); + bool CancelJob(const CString& sJobName); + void CancelJobs(const std::set& sJobs); + bool UnlinkJob(CModuleJob* pJob); // !Job stuff #endif - // Command stuff - /// Register the "Help" command. - void AddHelpCommand(); - /// @return True if the command was successfully added. - bool AddCommand(const CModCommand& Command); - /// @return True if the command was successfully added. - bool AddCommand(const CString& sCmd, CModCommand::ModCmdFunc func, - const CString& sArgs = "", const CString& sDesc = ""); - /// @return True if the command was successfully added. - bool AddCommand(const CString& sCmd, const CString& sArgs, - const CString& sDesc, - std::function func); - /// @return True if the command was successfully removed. - bool RemCommand(const CString& sCmd); - /// @return The CModCommand instance or nullptr if none was found. - const CModCommand* FindCommand(const CString& sCmd) const; - /** This function tries to dispatch the given command via the correct + // Command stuff + /// Register the "Help" command. + void AddHelpCommand(); + /// @return True if the command was successfully added. + bool AddCommand(const CModCommand& Command); + /// @return True if the command was successfully added. + bool AddCommand(const CString& sCmd, CModCommand::ModCmdFunc func, + const CString& sArgs = "", const CString& sDesc = ""); + /// @return True if the command was successfully added. + bool AddCommand(const CString& sCmd, const CString& sArgs, + const CString& sDesc, + std::function func); + /// @return True if the command was successfully removed. + bool RemCommand(const CString& sCmd); + /// @return The CModCommand instance or nullptr if none was found. + const CModCommand* FindCommand(const CString& sCmd) const; + /** This function tries to dispatch the given command via the correct * instance of CModCommand. Before this can be called, commands have to * be added via AddCommand(). If no matching commands are found then * OnUnknownModCommand will be called. * @param sLine The command line to handle. * @return True if something was done, else false. */ - bool HandleCommand(const CString& sLine); - /** Send a description of all registered commands via PutModule(). + bool HandleCommand(const CString& sLine); + /** Send a description of all registered commands via PutModule(). * @param sLine The help command that is being asked for. */ - void HandleHelpCommand(const CString& sLine = ""); - // !Command stuff + void HandleHelpCommand(const CString& sLine = ""); + // !Command stuff - bool LoadRegistry(); - bool SaveRegistry() const; - bool MoveRegistry(const CString& sPath); - bool SetNV(const CString& sName, const CString& sValue, - bool bWriteToDisk = true); - CString GetNV(const CString& sName) const; - bool HasNV(const CString& sName) const { - return m_mssRegistry.find(sName) != m_mssRegistry.end(); - } - bool DelNV(const CString& sName, bool bWriteToDisk = true); - MCString::iterator FindNV(const CString& sName) { - return m_mssRegistry.find(sName); - } - MCString::iterator EndNV() { return m_mssRegistry.end(); } - MCString::iterator BeginNV() { return m_mssRegistry.begin(); } - void DelNV(MCString::iterator it) { m_mssRegistry.erase(it); } - bool ClearNV(bool bWriteToDisk = true); + bool LoadRegistry(); + bool SaveRegistry() const; + bool MoveRegistry(const CString& sPath); + bool SetNV(const CString& sName, const CString& sValue, + bool bWriteToDisk = true); + CString GetNV(const CString& sName) const; + bool HasNV(const CString& sName) const { + return m_mssRegistry.find(sName) != m_mssRegistry.end(); + } + bool DelNV(const CString& sName, bool bWriteToDisk = true); + MCString::iterator FindNV(const CString& sName) { + return m_mssRegistry.find(sName); + } + MCString::iterator EndNV() { return m_mssRegistry.end(); } + MCString::iterator BeginNV() { return m_mssRegistry.begin(); } + void DelNV(MCString::iterator it) { m_mssRegistry.erase(it); } + bool ClearNV(bool bWriteToDisk = true); - const CString& GetSavePath() const; - CString ExpandString(const CString& sStr) const; - CString& ExpandString(const CString& sStr, CString& sRet) const; + const CString& GetSavePath() const; + CString ExpandString(const CString& sStr) const; + CString& ExpandString(const CString& sStr, CString& sRet) const; - // Setters - void SetType(CModInfo::EModuleType eType) { m_eType = eType; } - void SetDescription(const CString& s) { m_sDescription = s; } - void SetModPath(const CString& s) { m_sModPath = s; } - void SetArgs(const CString& s) { m_sArgs = s; } - // !Setters + // Setters + void SetType(CModInfo::EModuleType eType) { m_eType = eType; } + void SetDescription(const CString& s) { m_sDescription = s; } + void SetModPath(const CString& s) { m_sModPath = s; } + void SetArgs(const CString& s) { m_sArgs = s; } + // !Setters - // Getters - CModInfo::EModuleType GetType() const { return m_eType; } - const CString& GetDescription() const { return m_sDescription; } - const CString& GetArgs() const { return m_sArgs; } - const CString& GetModPath() const { return m_sModPath; } + // Getters + CModInfo::EModuleType GetType() const { return m_eType; } + const CString& GetDescription() const { return m_sDescription; } + const CString& GetArgs() const { return m_sArgs; } + const CString& GetModPath() const { return m_sModPath; } - /** @returns For user modules this returns the user for which this + /** @returns For user modules this returns the user for which this * module was loaded. For global modules this returns nullptr, * except when we are in a user-specific module hook in which * case this is the user pointer. */ - CUser* GetUser() const { return m_pUser; } - /** @returns nullptr except when we are in a network-specific module hook in + CUser* GetUser() const { return m_pUser; } + /** @returns nullptr except when we are in a network-specific module hook in * which case this is the network for which the hook is called. */ - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - /** @returns nullptr except when we are in a client-specific module hook in + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + /** @returns nullptr except when we are in a client-specific module hook in * which case this is the client for which the hook is called. */ - CClient* GetClient() const { return m_pClient; } - CSockManager* GetManager() const { return m_pManager; } - // !Getters + CClient* GetClient() const { return m_pClient; } + CSockManager* GetManager() const { return m_pManager; } + // !Getters - // Global Modules - /** This module hook is called when a user is being added. + // Global Modules + /** This module hook is called when a user is being added. * @param User The user which will be added. * @param sErrorRet A message that may be displayed to the user if * the module stops adding the user. * @return See CModule::EModRet. */ - virtual EModRet OnAddUser(CUser& User, CString& sErrorRet); - /** This module hook is called when a user is deleted. + virtual EModRet OnAddUser(CUser& User, CString& sErrorRet); + /** This module hook is called when a user is deleted. * @param User The user which will be deleted. * @return See CModule::EModRet. */ - virtual EModRet OnDeleteUser(CUser& User); - /** This module hook is called when there is an incoming connection on + virtual EModRet OnDeleteUser(CUser& User); + /** This module hook is called when there is an incoming connection on * any of ZNC's listening sockets. * @param pSock The incoming client socket. * @param sHost The IP the client is connecting from. * @param uPort The port the client is connecting from. */ - virtual void OnClientConnect(CZNCSock* pSock, const CString& sHost, - unsigned short uPort); - /** This module hook is called when a client tries to login. If your + virtual void OnClientConnect(CZNCSock* pSock, const CString& sHost, + unsigned short uPort); + /** This module hook is called when a client tries to login. If your * module wants to handle the login attempt, it must return * CModule::EModRet::HALT; * @param Auth The necessary authentication info for this login attempt. * @return See CModule::EModRet. */ - virtual EModRet OnLoginAttempt(std::shared_ptr Auth); - /** Called after a client login was rejected. + virtual EModRet OnLoginAttempt(std::shared_ptr Auth); + /** Called after a client login was rejected. * @param sUsername The username that tried to log in. * @param sRemoteIP The IP address from which the client tried to login. */ - virtual void OnFailedLogin(const CString& sUsername, - const CString& sRemoteIP); - /** This function behaves like CModule::OnUserRaw(), but is also called + virtual void OnFailedLogin(const CString& sUsername, + const CString& sRemoteIP); + /** This function behaves like CModule::OnUserRaw(), but is also called * before the client successfully logged in to ZNC. You should always * prefer to use CModule::OnUserRaw() if possible. * @param pClient The client which send this line. * @param sLine The raw traffic line which the client sent. */ - virtual EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine); - virtual EModRet OnUnknownUserRawMessage(CMessage& Message); + virtual EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine); + virtual EModRet OnUnknownUserRawMessage(CMessage& Message); - /** Called when a client told us CAP LS. Use ssCaps.insert("cap-name") + /** Called when a client told us CAP LS. Use ssCaps.insert("cap-name") * for announcing capabilities which your module supports. * @param pClient The client which requested the list. * @param ssCaps set of caps which will be sent to client. */ - virtual void OnClientCapLs(CClient* pClient, SCString& ssCaps); - /** Called only to check if your module supports turning on/off named capability. + virtual void OnClientCapLs(CClient* pClient, SCString& ssCaps); + /** Called only to check if your module supports turning on/off named capability. * @param pClient The client which wants to enable/disable a capability. * @param sCap name of capability. * @param bState On or off, depending on which case is interesting for client. * @return true if your module supports this capability in the specified state. */ - virtual bool IsClientCapSupported(CClient* pClient, const CString& sCap, - bool bState); - /** Called when we actually need to turn a capability on or off for a client. + virtual bool IsClientCapSupported(CClient* pClient, const CString& sCap, + bool bState); + /** Called when we actually need to turn a capability on or off for a client. * @param pClient The client which requested the capability. * @param sCap name of wanted capability. * @param bState On or off, depending on which case client needs. */ - virtual void OnClientCapRequest(CClient* pClient, const CString& sCap, - bool bState); + virtual void OnClientCapRequest(CClient* pClient, const CString& sCap, + bool bState); - /** Called when a module is going to be loaded. + /** Called when a module is going to be loaded. * @param sModName name of the module. * @param eType wanted type of the module (user/global). * @param sArgs arguments of the module. @@ -1233,275 +1233,275 @@ class CModule { * @param[out] sRetMsg text about loading of the module. * @return See CModule::EModRet. */ - virtual EModRet OnModuleLoading(const CString& sModName, - const CString& sArgs, - CModInfo::EModuleType eType, bool& bSuccess, - CString& sRetMsg); - /** Called when a module is going to be unloaded. + virtual EModRet OnModuleLoading(const CString& sModName, + const CString& sArgs, + CModInfo::EModuleType eType, bool& bSuccess, + CString& sRetMsg); + /** Called when a module is going to be unloaded. * @param pModule the module. * @param[out] bSuccess the module was unloaded successfully * as result of this module hook? * @param[out] sRetMsg text about unloading of the module. * @return See CModule::EModRet. */ - virtual EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, - CString& sRetMsg); - /** Called when info about a module is needed. + virtual EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, + CString& sRetMsg); + /** Called when info about a module is needed. * @param[out] ModInfo put result here, if your module knows it. * @param sModule name of the module. * @param bSuccess this module provided info about the module. * @param sRetMsg text describing possible issues. * @return See CModule::EModRet. */ - virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, - bool& bSuccess, CString& sRetMsg); - /** Called when list of available mods is requested. + virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, + bool& bSuccess, CString& sRetMsg); + /** Called when list of available mods is requested. * @param ssMods put new modules here. * @param bGlobal true if global modules are needed. */ - virtual void OnGetAvailableMods(std::set& ssMods, - CModInfo::EModuleType eType); - // !Global Modules + virtual void OnGetAvailableMods(std::set& ssMods, + CModInfo::EModuleType eType); + // !Global Modules protected: - CModInfo::EModuleType m_eType; - CString m_sDescription; - std::set m_sTimers; - std::set m_sSockets; + CModInfo::EModuleType m_eType; + CString m_sDescription; + std::set m_sTimers; + std::set m_sSockets; #ifdef HAVE_PTHREAD - std::set m_sJobs; + std::set m_sJobs; #endif - ModHandle m_pDLL; - CSockManager* m_pManager; - CUser* m_pUser; - CIRCNetwork* m_pNetwork; - CClient* m_pClient; - CString m_sModName; - CString m_sDataDir; - CString m_sSavePath; - CString m_sArgs; - CString m_sModPath; + ModHandle m_pDLL; + CSockManager* m_pManager; + CUser* m_pUser; + CIRCNetwork* m_pNetwork; + CClient* m_pClient; + CString m_sModName; + CString m_sDataDir; + CString m_sSavePath; + CString m_sArgs; + CString m_sModPath; private: - MCString - m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this - VWebSubPages m_vSubPages; - std::map m_mCommands; + MCString + m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this + VWebSubPages m_vSubPages; + std::map m_mCommands; }; class CModules : public std::vector { public: - CModules(); - ~CModules(); + CModules(); + ~CModules(); - CModules(const CModules&) = default; - CModules& operator=(const CModules&) = default; + CModules(const CModules&) = default; + CModules& operator=(const CModules&) = default; - void SetUser(CUser* pUser) { m_pUser = pUser; } - void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } - void SetClient(CClient* pClient) { m_pClient = pClient; } - CUser* GetUser() const { return m_pUser; } - CIRCNetwork* GetNetwork() const { return m_pNetwork; } - CClient* GetClient() const { return m_pClient; } + void SetUser(CUser* pUser) { m_pUser = pUser; } + void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } + void SetClient(CClient* pClient) { m_pClient = pClient; } + CUser* GetUser() const { return m_pUser; } + CIRCNetwork* GetNetwork() const { return m_pNetwork; } + CClient* GetClient() const { return m_pClient; } - void UnloadAll(); + void UnloadAll(); - bool OnBoot(); - bool OnPreRehash(); - bool OnPostRehash(); - bool OnIRCDisconnected(); - bool OnIRCConnected(); - bool OnIRCConnecting(CIRCSock* pIRCSock); - bool OnIRCConnectionError(CIRCSock* pIRCSock); - bool OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, - CString& sRealName); - bool OnBroadcast(CString& sMessage); + bool OnBoot(); + bool OnPreRehash(); + bool OnPostRehash(); + bool OnIRCDisconnected(); + bool OnIRCConnected(); + bool OnIRCConnecting(CIRCSock* pIRCSock); + bool OnIRCConnectionError(CIRCSock* pIRCSock); + bool OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, + CString& sRealName); + bool OnBroadcast(CString& sMessage); - bool OnChanPermission2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, bool bAdded, - bool bNoChange); - bool OnChanPermission(const CNick& OpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, bool bAdded, - bool bNoChange); - bool OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange); - bool OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, - const CString& sArgs); - bool OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, - const CString& sArgs); - bool OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange); - bool OnMode(const CNick& OpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange); + bool OnChanPermission2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, bool bAdded, + bool bNoChange); + bool OnChanPermission(const CNick& OpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, bool bAdded, + bool bNoChange); + bool OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange); + bool OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, + const CString& sArgs); + bool OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, + const CString& sArgs); + bool OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange); + bool OnMode(const CNick& OpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange); - bool OnRaw(CString& sLine); - bool OnRawMessage(CMessage& Message); - bool OnNumericMessage(CNumericMessage& Message); + bool OnRaw(CString& sLine); + bool OnRawMessage(CMessage& Message); + bool OnNumericMessage(CNumericMessage& Message); - bool OnStatusCommand(CString& sCommand); - bool OnModCommand(const CString& sCommand); - bool OnModNotice(const CString& sMessage); - bool OnModCTCP(const CString& sMessage); + bool OnStatusCommand(CString& sCommand); + bool OnModCommand(const CString& sCommand); + bool OnModNotice(const CString& sMessage); + bool OnModCTCP(const CString& sMessage); - bool OnQuit(const CNick& Nick, const CString& sMessage, - const std::vector& vChans); - bool OnQuitMessage(CQuitMessage& Message, - const std::vector& vChans); - bool OnNick(const CNick& Nick, const CString& sNewNick, - const std::vector& vChans); - bool OnNickMessage(CNickMessage& Message, - const std::vector& vChans); - bool OnKick(const CNick& Nick, const CString& sOpNick, CChan& Channel, - const CString& sMessage); - bool OnKickMessage(CKickMessage& Message); - bool OnJoining(CChan& Channel); - bool OnJoin(const CNick& Nick, CChan& Channel); - bool OnJoinMessage(CJoinMessage& Message); - bool OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage); - bool OnPartMessage(CPartMessage& Message); - bool OnInvite(const CNick& Nick, const CString& sChan); + bool OnQuit(const CNick& Nick, const CString& sMessage, + const std::vector& vChans); + bool OnQuitMessage(CQuitMessage& Message, + const std::vector& vChans); + bool OnNick(const CNick& Nick, const CString& sNewNick, + const std::vector& vChans); + bool OnNickMessage(CNickMessage& Message, + const std::vector& vChans); + bool OnKick(const CNick& Nick, const CString& sOpNick, CChan& Channel, + const CString& sMessage); + bool OnKickMessage(CKickMessage& Message); + bool OnJoining(CChan& Channel); + bool OnJoin(const CNick& Nick, CChan& Channel); + bool OnJoinMessage(CJoinMessage& Message); + bool OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage); + bool OnPartMessage(CPartMessage& Message); + bool OnInvite(const CNick& Nick, const CString& sChan); - bool OnChanBufferStarting(CChan& Chan, CClient& Client); - bool OnChanBufferEnding(CChan& Chan, CClient& Client); - bool OnChanBufferPlayLine2(CChan& Chan, CClient& Client, CString& sLine, - const timeval& tv); - bool OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine); - bool OnPrivBufferPlayLine2(CClient& Client, CString& sLine, - const timeval& tv); - bool OnPrivBufferPlayLine(CClient& Client, CString& sLine); - bool OnChanBufferPlayMessage(CMessage& Message); - bool OnPrivBufferPlayMessage(CMessage& Message); + bool OnChanBufferStarting(CChan& Chan, CClient& Client); + bool OnChanBufferEnding(CChan& Chan, CClient& Client); + bool OnChanBufferPlayLine2(CChan& Chan, CClient& Client, CString& sLine, + const timeval& tv); + bool OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine); + bool OnPrivBufferPlayLine2(CClient& Client, CString& sLine, + const timeval& tv); + bool OnPrivBufferPlayLine(CClient& Client, CString& sLine); + bool OnChanBufferPlayMessage(CMessage& Message); + bool OnPrivBufferPlayMessage(CMessage& Message); - bool OnClientLogin(); - bool OnClientDisconnect(); - bool OnUserRaw(CString& sLine); - bool OnUserRawMessage(CMessage& Message); - bool OnUserCTCPReply(CString& sTarget, CString& sMessage); - bool OnUserCTCPReplyMessage(CCTCPMessage& Message); - bool OnUserCTCP(CString& sTarget, CString& sMessage); - bool OnUserCTCPMessage(CCTCPMessage& Message); - bool OnUserAction(CString& sTarget, CString& sMessage); - bool OnUserActionMessage(CActionMessage& Message); - bool OnUserMsg(CString& sTarget, CString& sMessage); - bool OnUserTextMessage(CTextMessage& Message); - bool OnUserNotice(CString& sTarget, CString& sMessage); - bool OnUserNoticeMessage(CNoticeMessage& Message); - bool OnUserJoin(CString& sChannel, CString& sKey); - bool OnUserJoinMessage(CJoinMessage& Message); - bool OnUserPart(CString& sChannel, CString& sMessage); - bool OnUserPartMessage(CPartMessage& Message); - bool OnUserTopic(CString& sChannel, CString& sTopic); - bool OnUserTopicMessage(CTopicMessage& Message); - bool OnUserTopicRequest(CString& sChannel); - bool OnUserQuit(CString& sMessage); - bool OnUserQuitMessage(CQuitMessage& Message); + bool OnClientLogin(); + bool OnClientDisconnect(); + bool OnUserRaw(CString& sLine); + bool OnUserRawMessage(CMessage& Message); + bool OnUserCTCPReply(CString& sTarget, CString& sMessage); + bool OnUserCTCPReplyMessage(CCTCPMessage& Message); + bool OnUserCTCP(CString& sTarget, CString& sMessage); + bool OnUserCTCPMessage(CCTCPMessage& Message); + bool OnUserAction(CString& sTarget, CString& sMessage); + bool OnUserActionMessage(CActionMessage& Message); + bool OnUserMsg(CString& sTarget, CString& sMessage); + bool OnUserTextMessage(CTextMessage& Message); + bool OnUserNotice(CString& sTarget, CString& sMessage); + bool OnUserNoticeMessage(CNoticeMessage& Message); + bool OnUserJoin(CString& sChannel, CString& sKey); + bool OnUserJoinMessage(CJoinMessage& Message); + bool OnUserPart(CString& sChannel, CString& sMessage); + bool OnUserPartMessage(CPartMessage& Message); + bool OnUserTopic(CString& sChannel, CString& sTopic); + bool OnUserTopicMessage(CTopicMessage& Message); + bool OnUserTopicRequest(CString& sChannel); + bool OnUserQuit(CString& sMessage); + bool OnUserQuitMessage(CQuitMessage& Message); - bool OnCTCPReply(CNick& Nick, CString& sMessage); - bool OnCTCPReplyMessage(CCTCPMessage& Message); - bool OnPrivCTCP(CNick& Nick, CString& sMessage); - bool OnPrivCTCPMessage(CCTCPMessage& Message); - bool OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage); - bool OnChanCTCPMessage(CCTCPMessage& Message); - bool OnPrivAction(CNick& Nick, CString& sMessage); - bool OnPrivActionMessage(CActionMessage& Message); - bool OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage); - bool OnChanActionMessage(CActionMessage& Message); - bool OnPrivMsg(CNick& Nick, CString& sMessage); - bool OnPrivMessage(CTextMessage& Message); - bool OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage); - bool OnChanMessage(CTextMessage& Message); - bool OnPrivNotice(CNick& Nick, CString& sMessage); - bool OnPrivNoticeMessage(CNoticeMessage& Message); - bool OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage); - bool OnChanNoticeMessage(CNoticeMessage& Message); - bool OnTopic(CNick& Nick, CChan& Channel, CString& sTopic); - bool OnTopicMessage(CTopicMessage& Message); - bool OnTimerAutoJoin(CChan& Channel); + bool OnCTCPReply(CNick& Nick, CString& sMessage); + bool OnCTCPReplyMessage(CCTCPMessage& Message); + bool OnPrivCTCP(CNick& Nick, CString& sMessage); + bool OnPrivCTCPMessage(CCTCPMessage& Message); + bool OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage); + bool OnChanCTCPMessage(CCTCPMessage& Message); + bool OnPrivAction(CNick& Nick, CString& sMessage); + bool OnPrivActionMessage(CActionMessage& Message); + bool OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage); + bool OnChanActionMessage(CActionMessage& Message); + bool OnPrivMsg(CNick& Nick, CString& sMessage); + bool OnPrivMessage(CTextMessage& Message); + bool OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage); + bool OnChanMessage(CTextMessage& Message); + bool OnPrivNotice(CNick& Nick, CString& sMessage); + bool OnPrivNoticeMessage(CNoticeMessage& Message); + bool OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage); + bool OnChanNoticeMessage(CNoticeMessage& Message); + bool OnTopic(CNick& Nick, CChan& Channel, CString& sTopic); + bool OnTopicMessage(CTopicMessage& Message); + bool OnTimerAutoJoin(CChan& Channel); - bool OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet); - bool OnDeleteNetwork(CIRCNetwork& Network); + bool OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet); + bool OnDeleteNetwork(CIRCNetwork& Network); - bool OnSendToClient(CString& sLine, CClient& Client); - bool OnSendToIRC(CString& sLine); + bool OnSendToClient(CString& sLine, CClient& Client); + bool OnSendToIRC(CString& sLine); - bool OnServerCapAvailable(const CString& sCap); - bool OnServerCapResult(const CString& sCap, bool bSuccess); + bool OnServerCapAvailable(const CString& sCap); + bool OnServerCapResult(const CString& sCap, bool bSuccess); - CModule* FindModule(const CString& sModule) const; - bool LoadModule(const CString& sModule, const CString& sArgs, - CModInfo::EModuleType eType, CUser* pUser, - CIRCNetwork* pNetwork, CString& sRetMsg); - bool UnloadModule(const CString& sModule); - bool UnloadModule(const CString& sModule, CString& sRetMsg); - bool ReloadModule(const CString& sModule, const CString& sArgs, - CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg); + CModule* FindModule(const CString& sModule) const; + bool LoadModule(const CString& sModule, const CString& sArgs, + CModInfo::EModuleType eType, CUser* pUser, + CIRCNetwork* pNetwork, CString& sRetMsg); + bool UnloadModule(const CString& sModule); + bool UnloadModule(const CString& sModule, CString& sRetMsg); + bool ReloadModule(const CString& sModule, const CString& sArgs, + CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg); - static bool GetModInfo(CModInfo& ModInfo, const CString& sModule, - CString& sRetMsg); - static bool GetModPathInfo(CModInfo& ModInfo, const CString& sModule, - const CString& sModPath, CString& sRetMsg); - static void GetAvailableMods( - std::set& ssMods, - CModInfo::EModuleType eType = CModInfo::UserModule); - static void GetDefaultMods( - std::set& ssMods, - CModInfo::EModuleType eType = CModInfo::UserModule); + static bool GetModInfo(CModInfo& ModInfo, const CString& sModule, + CString& sRetMsg); + static bool GetModPathInfo(CModInfo& ModInfo, const CString& sModule, + const CString& sModPath, CString& sRetMsg); + static void GetAvailableMods( + std::set& ssMods, + CModInfo::EModuleType eType = CModInfo::UserModule); + static void GetDefaultMods( + std::set& ssMods, + CModInfo::EModuleType eType = CModInfo::UserModule); - // This returns the path to the .so and to the data dir - // which is where static data (webadmin skins) are saved - static bool FindModPath(const CString& sModule, CString& sModPath, - CString& sDataPath); - // Return a list of pairs for directories in - // which modules can be found. - typedef std::queue> ModDirList; - static ModDirList GetModDirs(); + // This returns the path to the .so and to the data dir + // which is where static data (webadmin skins) are saved + static bool FindModPath(const CString& sModule, CString& sModPath, + CString& sDataPath); + // Return a list of pairs for directories in + // which modules can be found. + typedef std::queue> ModDirList; + static ModDirList GetModDirs(); - // Global Modules - bool OnAddUser(CUser& User, CString& sErrorRet); - bool OnDeleteUser(CUser& User); - bool OnClientConnect(CZNCSock* pSock, const CString& sHost, - unsigned short uPort); - bool OnLoginAttempt(std::shared_ptr Auth); - bool OnFailedLogin(const CString& sUsername, const CString& sRemoteIP); - bool OnUnknownUserRaw(CClient* pClient, CString& sLine); - bool OnUnknownUserRawMessage(CMessage& Message); - bool OnClientCapLs(CClient* pClient, SCString& ssCaps); - bool IsClientCapSupported(CClient* pClient, const CString& sCap, - bool bState); - bool OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState); - bool OnModuleLoading(const CString& sModName, const CString& sArgs, - CModInfo::EModuleType eType, bool& bSuccess, - CString& sRetMsg); - bool OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg); - bool OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, - CString& sRetMsg); - bool OnGetAvailableMods(std::set& ssMods, - CModInfo::EModuleType eType); - // !Global Modules + // Global Modules + bool OnAddUser(CUser& User, CString& sErrorRet); + bool OnDeleteUser(CUser& User); + bool OnClientConnect(CZNCSock* pSock, const CString& sHost, + unsigned short uPort); + bool OnLoginAttempt(std::shared_ptr Auth); + bool OnFailedLogin(const CString& sUsername, const CString& sRemoteIP); + bool OnUnknownUserRaw(CClient* pClient, CString& sLine); + bool OnUnknownUserRawMessage(CMessage& Message); + bool OnClientCapLs(CClient* pClient, SCString& ssCaps); + bool IsClientCapSupported(CClient* pClient, const CString& sCap, + bool bState); + bool OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState); + bool OnModuleLoading(const CString& sModName, const CString& sArgs, + CModInfo::EModuleType eType, bool& bSuccess, + CString& sRetMsg); + bool OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg); + bool OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, + CString& sRetMsg); + bool OnGetAvailableMods(std::set& ssMods, + CModInfo::EModuleType eType); + // !Global Modules private: - static ModHandle OpenModule(const CString& sModule, const CString& sModPath, - bool& bVersionMismatch, CModInfo& Info, - CString& sRetMsg); + static ModHandle OpenModule(const CString& sModule, const CString& sModPath, + bool& bVersionMismatch, CModInfo& Info, + CString& sRetMsg); protected: - CUser* m_pUser; - CIRCNetwork* m_pNetwork; - CClient* m_pClient; + CUser* m_pUser; + CIRCNetwork* m_pNetwork; + CClient* m_pClient; }; #endif // !ZNC_MODULES_H diff --git a/include/znc/Nick.h b/include/znc/Nick.h index d5b31e1d..86fcbfb4 100644 --- a/include/znc/Nick.h +++ b/include/znc/Nick.h @@ -28,48 +28,48 @@ class CChan; class CNick { public: - CNick(); - CNick(const CString& sNick); - ~CNick(); + CNick(); + CNick(const CString& sNick); + ~CNick(); - CNick(const CNick&) = default; - CNick& operator=(const CNick&) = default; + CNick(const CNick&) = default; + CNick& operator=(const CNick&) = default; - void Reset(); - void Parse(const CString& sNickMask); - CString GetHostMask() const; - size_t GetCommonChans(std::vector& vChans, - CIRCNetwork* pNetwork) const; - bool NickEquals(const CString& nickname) const; + void Reset(); + void Parse(const CString& sNickMask); + CString GetHostMask() const; + size_t GetCommonChans(std::vector& vChans, + CIRCNetwork* pNetwork) const; + bool NickEquals(const CString& nickname) const; - // Setters - void SetNetwork(CIRCNetwork* pNetwork); - void SetNick(const CString& s); - void SetIdent(const CString& s); - void SetHost(const CString& s); - bool AddPerm(unsigned char uPerm); - bool RemPerm(unsigned char uPerm); - // !Setters + // Setters + void SetNetwork(CIRCNetwork* pNetwork); + void SetNick(const CString& s); + void SetIdent(const CString& s); + void SetHost(const CString& s); + bool AddPerm(unsigned char uPerm); + bool RemPerm(unsigned char uPerm); + // !Setters - // Getters - CString GetPermStr() const; - unsigned char GetPermChar() const; - bool HasPerm(unsigned char uPerm) const; - const CString& GetNick() const; - const CString& GetIdent() const; - const CString& GetHost() const; - CString GetNickMask() const; - // !Getters + // Getters + CString GetPermStr() const; + unsigned char GetPermChar() const; + bool HasPerm(unsigned char uPerm) const; + const CString& GetNick() const; + const CString& GetIdent() const; + const CString& GetHost() const; + CString GetNickMask() const; + // !Getters - void Clone(const CNick& SourceNick); + void Clone(const CNick& SourceNick); private: protected: - CString m_sChanPerms; - CIRCNetwork* m_pNetwork; - CString m_sNick; - CString m_sIdent; - CString m_sHost; + CString m_sChanPerms; + CIRCNetwork* m_pNetwork; + CString m_sNick; + CString m_sIdent; + CString m_sHost; }; #endif // !ZNC_NICK_H diff --git a/include/znc/Query.h b/include/znc/Query.h index 19e8e5ae..77488075 100644 --- a/include/znc/Query.h +++ b/include/znc/Query.h @@ -28,40 +28,40 @@ class CIRCNetwork; class CQuery { public: - CQuery(const CString& sName, CIRCNetwork* pNetwork); - ~CQuery(); + CQuery(const CString& sName, CIRCNetwork* pNetwork); + ~CQuery(); - CQuery(const CQuery&) = delete; - CQuery& operator=(const CQuery&) = delete; + CQuery(const CQuery&) = delete; + CQuery& operator=(const CQuery&) = delete; - // Buffer - const CBuffer& GetBuffer() const { return m_Buffer; } - unsigned int GetBufferCount() const { return m_Buffer.GetLineCount(); } - bool SetBufferCount(unsigned int u, bool bForce = false) { - return m_Buffer.SetLineCount(u, bForce); - } - size_t AddBuffer(const CMessage& Format, const CString& sText = "") { - return m_Buffer.AddLine(Format, sText); - } - /// @deprecated - size_t AddBuffer(const CString& sFormat, const CString& sText = "", - const timeval* ts = nullptr, - const MCString& mssTags = MCString::EmptyMap) { - return m_Buffer.AddLine(sFormat, sText, ts, mssTags); - } - void ClearBuffer() { m_Buffer.Clear(); } - void SendBuffer(CClient* pClient); - void SendBuffer(CClient* pClient, const CBuffer& Buffer); - // !Buffer + // Buffer + const CBuffer& GetBuffer() const { return m_Buffer; } + unsigned int GetBufferCount() const { return m_Buffer.GetLineCount(); } + bool SetBufferCount(unsigned int u, bool bForce = false) { + return m_Buffer.SetLineCount(u, bForce); + } + size_t AddBuffer(const CMessage& Format, const CString& sText = "") { + return m_Buffer.AddLine(Format, sText); + } + /// @deprecated + size_t AddBuffer(const CString& sFormat, const CString& sText = "", + const timeval* ts = nullptr, + const MCString& mssTags = MCString::EmptyMap) { + return m_Buffer.AddLine(sFormat, sText, ts, mssTags); + } + void ClearBuffer() { m_Buffer.Clear(); } + void SendBuffer(CClient* pClient); + void SendBuffer(CClient* pClient, const CBuffer& Buffer); + // !Buffer - // Getters - const CString& GetName() const { return m_sName; } - // !Getters + // Getters + const CString& GetName() const { return m_sName; } + // !Getters private: - CString m_sName; - CIRCNetwork* m_pNetwork; - CBuffer m_Buffer; + CString m_sName; + CIRCNetwork* m_pNetwork; + CBuffer m_Buffer; }; #endif // !ZNC_QUERY_H diff --git a/include/znc/SHA256.h b/include/znc/SHA256.h index 7d68e8d4..a541c06a 100644 --- a/include/znc/SHA256.h +++ b/include/znc/SHA256.h @@ -47,10 +47,10 @@ #include typedef struct { - size_t tot_len; - size_t len; - unsigned char block[2 * SHA256_BLOCK_SIZE]; - uint32_t h[8]; + size_t tot_len; + size_t len; + unsigned char block[2 * SHA256_BLOCK_SIZE]; + uint32_t h[8]; } sha256_ctx; void sha256_init(sha256_ctx* ctx); diff --git a/include/znc/Server.h b/include/znc/Server.h index 7b7130e3..16ac7abc 100644 --- a/include/znc/Server.h +++ b/include/znc/Server.h @@ -22,23 +22,23 @@ class CServer { public: - CServer(const CString& sName, unsigned short uPort = 6667, - const CString& sPass = "", bool bSSL = false); - ~CServer(); + CServer(const CString& sName, unsigned short uPort = 6667, + const CString& sPass = "", bool bSSL = false); + ~CServer(); - const CString& GetName() const; - unsigned short GetPort() const; - const CString& GetPass() const; - bool IsSSL() const; - CString GetString(bool bIncludePassword = true) const; - static bool IsValidHostName(const CString& sHostName); + const CString& GetName() const; + unsigned short GetPort() const; + const CString& GetPass() const; + bool IsSSL() const; + CString GetString(bool bIncludePassword = true) const; + static bool IsValidHostName(const CString& sHostName); private: protected: - CString m_sName; - unsigned short m_uPort; - CString m_sPass; - bool m_bSSL; + CString m_sName; + unsigned short m_uPort; + CString m_sPass; + bool m_bSSL; }; #endif // !ZNC_SERVER_H diff --git a/include/znc/Socket.h b/include/znc/Socket.h index 871c1570..d8a3449d 100644 --- a/include/znc/Socket.h +++ b/include/znc/Socket.h @@ -25,197 +25,197 @@ class CModule; class CZNCSock : public Csock { public: - CZNCSock(int timeout = 60); - CZNCSock(const CString& sHost, u_short port, int timeout = 60); - ~CZNCSock() {} + CZNCSock(int timeout = 60); + CZNCSock(const CString& sHost, u_short port, int timeout = 60); + ~CZNCSock() {} - int ConvertAddress(const struct sockaddr_storage* pAddr, socklen_t iAddrLen, - CString& sIP, u_short* piPort) const override; + int ConvertAddress(const struct sockaddr_storage* pAddr, socklen_t iAddrLen, + CString& sIP, u_short* piPort) const override; #ifdef HAVE_LIBSSL - int VerifyPeerCertificate(int iPreVerify, - X509_STORE_CTX* pStoreCTX) override; - void SSLHandShakeFinished() override; - bool SNIConfigureClient(CString& sHostname) override; + int VerifyPeerCertificate(int iPreVerify, + X509_STORE_CTX* pStoreCTX) override; + void SSLHandShakeFinished() override; + bool SNIConfigureClient(CString& sHostname) override; #endif - void SetHostToVerifySSL(const CString& sHost) { - m_sHostToVerifySSL = sHost; - } - CString GetSSLPeerFingerprint() const; - void SetSSLTrustedPeerFingerprints(const SCString& ssFPs) { - m_ssTrustedFingerprints = ssFPs; - } + void SetHostToVerifySSL(const CString& sHost) { + m_sHostToVerifySSL = sHost; + } + CString GetSSLPeerFingerprint() const; + void SetSSLTrustedPeerFingerprints(const SCString& ssFPs) { + m_ssTrustedFingerprints = ssFPs; + } #ifndef HAVE_ICU - // Don't fail to compile when ICU is not enabled - void SetEncoding(const CString&) {} + // Don't fail to compile when ICU is not enabled + void SetEncoding(const CString&) {} #endif - virtual CString GetRemoteIP() const { return Csock::GetRemoteIP(); } + virtual CString GetRemoteIP() const { return Csock::GetRemoteIP(); } protected: - // All existing errno codes seem to be in range 1-300 - enum { - errnoBadSSLCert = 12569, - }; + // All existing errno codes seem to be in range 1-300 + enum { + errnoBadSSLCert = 12569, + }; private: - CString m_sHostToVerifySSL; - SCString m_ssTrustedFingerprints; - SCString m_ssCertVerificationErrors; + CString m_sHostToVerifySSL; + SCString m_ssTrustedFingerprints; + SCString m_ssCertVerificationErrors; }; enum EAddrType { ADDR_IPV4ONLY, ADDR_IPV6ONLY, ADDR_ALL }; class CSockManager : public TSocketManager { public: - CSockManager(); - virtual ~CSockManager(); + CSockManager(); + virtual ~CSockManager(); - bool ListenHost(u_short iPort, const CString& sSockName, - const CString& sBindHost, bool bSSL = false, - int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, - u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { - CSListener L(iPort, sBindHost); + bool ListenHost(u_short iPort, const CString& sSockName, + const CString& sBindHost, bool bSSL = false, + int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, + u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { + CSListener L(iPort, sBindHost); - L.SetSockName(sSockName); - L.SetIsSSL(bSSL); - L.SetTimeout(iTimeout); - L.SetMaxConns(iMaxConns); + L.SetSockName(sSockName); + L.SetIsSSL(bSSL); + L.SetTimeout(iTimeout); + L.SetMaxConns(iMaxConns); #ifdef HAVE_IPV6 - switch (eAddr) { - case ADDR_IPV4ONLY: - L.SetAFRequire(CSSockAddr::RAF_INET); - break; - case ADDR_IPV6ONLY: - L.SetAFRequire(CSSockAddr::RAF_INET6); - break; - case ADDR_ALL: - L.SetAFRequire(CSSockAddr::RAF_ANY); - break; - } + switch (eAddr) { + case ADDR_IPV4ONLY: + L.SetAFRequire(CSSockAddr::RAF_INET); + break; + case ADDR_IPV6ONLY: + L.SetAFRequire(CSSockAddr::RAF_INET6); + break; + case ADDR_ALL: + L.SetAFRequire(CSSockAddr::RAF_ANY); + break; + } #endif - return Listen(L, pcSock); - } + return Listen(L, pcSock); + } - bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false, - int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, - u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { - return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock, - iTimeout, eAddr); - } + bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false, + int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, + u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { + return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock, + iTimeout, eAddr); + } - u_short ListenRand(const CString& sSockName, const CString& sBindHost, - bool bSSL = false, int iMaxConns = SOMAXCONN, - CZNCSock* pcSock = nullptr, u_int iTimeout = 0, - EAddrType eAddr = ADDR_ALL) { - unsigned short uPort = 0; - CSListener L(0, sBindHost); + u_short ListenRand(const CString& sSockName, const CString& sBindHost, + bool bSSL = false, int iMaxConns = SOMAXCONN, + CZNCSock* pcSock = nullptr, u_int iTimeout = 0, + EAddrType eAddr = ADDR_ALL) { + unsigned short uPort = 0; + CSListener L(0, sBindHost); - L.SetSockName(sSockName); - L.SetIsSSL(bSSL); - L.SetTimeout(iTimeout); - L.SetMaxConns(iMaxConns); + L.SetSockName(sSockName); + L.SetIsSSL(bSSL); + L.SetTimeout(iTimeout); + L.SetMaxConns(iMaxConns); #ifdef HAVE_IPV6 - switch (eAddr) { - case ADDR_IPV4ONLY: - L.SetAFRequire(CSSockAddr::RAF_INET); - break; - case ADDR_IPV6ONLY: - L.SetAFRequire(CSSockAddr::RAF_INET6); - break; - case ADDR_ALL: - L.SetAFRequire(CSSockAddr::RAF_ANY); - break; - } + switch (eAddr) { + case ADDR_IPV4ONLY: + L.SetAFRequire(CSSockAddr::RAF_INET); + break; + case ADDR_IPV6ONLY: + L.SetAFRequire(CSSockAddr::RAF_INET6); + break; + case ADDR_ALL: + L.SetAFRequire(CSSockAddr::RAF_ANY); + break; + } #endif - Listen(L, pcSock, &uPort); + Listen(L, pcSock, &uPort); - return uPort; - } + return uPort; + } - u_short ListenAllRand(const CString& sSockName, bool bSSL = false, - int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, - u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { - return (ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, - eAddr)); - } + u_short ListenAllRand(const CString& sSockName, bool bSSL = false, + int iMaxConns = SOMAXCONN, CZNCSock* pcSock = nullptr, + u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) { + return (ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, + eAddr)); + } - void Connect(const CString& sHostname, u_short iPort, - const CString& sSockName, int iTimeout = 60, bool bSSL = false, - const CString& sBindHost = "", CZNCSock* pcSock = nullptr); + void Connect(const CString& sHostname, u_short iPort, + const CString& sSockName, int iTimeout = 60, bool bSSL = false, + const CString& sBindHost = "", CZNCSock* pcSock = nullptr); - unsigned int GetAnonConnectionCount(const CString& sIP) const; + unsigned int GetAnonConnectionCount(const CString& sIP) const; private: - void FinishConnect(const CString& sHostname, u_short iPort, - const CString& sSockName, int iTimeout, bool bSSL, - const CString& sBindHost, CZNCSock* pcSock); + void FinishConnect(const CString& sHostname, u_short iPort, + const CString& sSockName, int iTimeout, bool bSSL, + const CString& sBindHost, CZNCSock* pcSock); #ifdef HAVE_PTHREAD - class CThreadMonitorFD; - friend class CThreadMonitorFD; + class CThreadMonitorFD; + friend class CThreadMonitorFD; #endif #ifdef HAVE_THREADED_DNS - struct TDNSTask { - TDNSTask() - : sHostname(""), - iPort(0), - sSockName(""), - iTimeout(0), - bSSL(false), - sBindhost(""), - pcSock(nullptr), - bDoneTarget(false), - bDoneBind(false), - aiTarget(nullptr), - aiBind(nullptr) {} + struct TDNSTask { + TDNSTask() + : sHostname(""), + iPort(0), + sSockName(""), + iTimeout(0), + bSSL(false), + sBindhost(""), + pcSock(nullptr), + bDoneTarget(false), + bDoneBind(false), + aiTarget(nullptr), + aiBind(nullptr) {} - TDNSTask(const TDNSTask&) = delete; - TDNSTask& operator=(const TDNSTask&) = delete; + TDNSTask(const TDNSTask&) = delete; + TDNSTask& operator=(const TDNSTask&) = delete; - CString sHostname; - u_short iPort; - CString sSockName; - int iTimeout; - bool bSSL; - CString sBindhost; - CZNCSock* pcSock; + CString sHostname; + u_short iPort; + CString sSockName; + int iTimeout; + bool bSSL; + CString sBindhost; + CZNCSock* pcSock; - bool bDoneTarget; - bool bDoneBind; - addrinfo* aiTarget; - addrinfo* aiBind; - }; - class CDNSJob : public CJob { - public: - CDNSJob() - : sHostname(""), - task(nullptr), - pManager(nullptr), - bBind(false), - iRes(0), - aiResult(nullptr) {} + bool bDoneTarget; + bool bDoneBind; + addrinfo* aiTarget; + addrinfo* aiBind; + }; + class CDNSJob : public CJob { + public: + CDNSJob() + : sHostname(""), + task(nullptr), + pManager(nullptr), + bBind(false), + iRes(0), + aiResult(nullptr) {} - CDNSJob(const CDNSJob&) = delete; - CDNSJob& operator=(const CDNSJob&) = delete; + CDNSJob(const CDNSJob&) = delete; + CDNSJob& operator=(const CDNSJob&) = delete; - CString sHostname; - TDNSTask* task; - CSockManager* pManager; - bool bBind; + CString sHostname; + TDNSTask* task; + CSockManager* pManager; + bool bBind; - int iRes; - addrinfo* aiResult; + int iRes; + addrinfo* aiResult; - void runThread() override; - void runMain() override; - }; - void StartTDNSThread(TDNSTask* task, bool bBind); - void SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult); - static void* TDNSThread(void* argument); + void runThread() override; + void runMain() override; + }; + void StartTDNSThread(TDNSTask* task, bool bBind); + void SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult); + static void* TDNSThread(void* argument); #endif protected: }; @@ -231,48 +231,48 @@ class CSockManager : public TSocketManager { */ class CSocket : public CZNCSock { public: - /** + /** * @brief ctor * @param pModule the module this sock instance is associated to */ - CSocket(CModule* pModule); - /** + CSocket(CModule* pModule); + /** * @brief ctor * @param pModule the module this sock instance is associated to * @param sHostname the hostname being connected to * @param uPort the port being connected to * @param iTimeout the timeout period for this specific sock */ - CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, - int iTimeout = 60); - virtual ~CSocket(); + CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, + int iTimeout = 60); + virtual ~CSocket(); - CSocket(const CSocket&) = delete; - CSocket& operator=(const CSocket&) = delete; + CSocket(const CSocket&) = delete; + CSocket& operator=(const CSocket&) = delete; - using Csock::Connect; - using Csock::Listen; + using Csock::Connect; + using Csock::Listen; - //! This defaults to closing the socket, feel free to override - void ReachedMaxBuffer() override; - void SockError(int iErrno, const CString& sDescription) override; + //! This defaults to closing the socket, feel free to override + void ReachedMaxBuffer() override; + void SockError(int iErrno, const CString& sDescription) override; - //! This limits the global connections from this IP to defeat DoS attacks, feel free to override. The ACL used is provided by the main interface @see CZNC::AllowConnectionFrom - bool ConnectionFrom(const CString& sHost, unsigned short uPort) override; + //! This limits the global connections from this IP to defeat DoS attacks, feel free to override. The ACL used is provided by the main interface @see CZNC::AllowConnectionFrom + bool ConnectionFrom(const CString& sHost, unsigned short uPort) override; - //! Ease of use Connect, assigns to the manager and is subsequently tracked - bool Connect(const CString& sHostname, unsigned short uPort, - bool bSSL = false, unsigned int uTimeout = 60); - //! Ease of use Listen, assigned to the manager and is subsequently tracked - bool Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout = 0); + //! Ease of use Connect, assigns to the manager and is subsequently tracked + bool Connect(const CString& sHostname, unsigned short uPort, + bool bSSL = false, unsigned int uTimeout = 60); + //! Ease of use Listen, assigned to the manager and is subsequently tracked + bool Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout = 0); - // Getters - CModule* GetModule() const; - // !Getters + // Getters + CModule* GetModule() const; + // !Getters private: protected: - CModule* - m_pModule; //!< pointer to the module that this sock instance belongs to + CModule* + m_pModule; //!< pointer to the module that this sock instance belongs to }; /** @@ -282,7 +282,7 @@ class CSocket : public CZNCSock { class CIRCSocket : public CZNCSock { public: #ifdef HAVE_ICU - /** + /** * @brief Allow IRC control characters to appear even if protocol encoding explicitly disallows them. * * E.g. ISO-2022-JP disallows 0x0F, which in IRC means "reset format", @@ -292,14 +292,14 @@ class CIRCSocket : public CZNCSock { * In case if protocol encoding uses these code points for something else, the encoding takes preference, * and they are not IRC control characters anymore. */ - void IcuExtToUCallback(UConverterToUnicodeArgs* toArgs, - const char* codeUnits, int32_t length, - UConverterCallbackReason reason, - UErrorCode* err) override; - void IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs, - const UChar* codeUnits, int32_t length, - UChar32 codePoint, UConverterCallbackReason reason, - UErrorCode* err) override; + void IcuExtToUCallback(UConverterToUnicodeArgs* toArgs, + const char* codeUnits, int32_t length, + UConverterCallbackReason reason, + UErrorCode* err) override; + void IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs, + const UChar* codeUnits, int32_t length, + UChar32 codePoint, UConverterCallbackReason reason, + UErrorCode* err) override; #endif }; diff --git a/include/znc/Template.h b/include/znc/Template.h index 8325e011..f00cbac8 100644 --- a/include/znc/Template.h +++ b/include/znc/Template.h @@ -27,28 +27,28 @@ class CTemplate; class CTemplateTagHandler { public: - CTemplateTagHandler() {} - virtual ~CTemplateTagHandler() {} + CTemplateTagHandler() {} + virtual ~CTemplateTagHandler() {} - virtual bool HandleVar(CTemplate& Tmpl, const CString& sName, - const CString& sArgs, CString& sOutput) { - return false; - } + virtual bool HandleVar(CTemplate& Tmpl, const CString& sName, + const CString& sArgs, CString& sOutput) { + return false; + } - virtual bool HandleTag(CTemplate& Tmpl, const CString& sName, - const CString& sArgs, CString& sOutput) { - return false; - } + virtual bool HandleTag(CTemplate& Tmpl, const CString& sName, + const CString& sArgs, CString& sOutput) { + return false; + } - virtual bool HandleIf(CTemplate& Tmpl, const CString& sName, - const CString& sArgs, CString& sOutput) { - return HandleVar(Tmpl, sName, sArgs, sOutput); - } + virtual bool HandleIf(CTemplate& Tmpl, const CString& sName, + const CString& sArgs, CString& sOutput) { + return HandleVar(Tmpl, sName, sArgs, sOutput); + } - virtual bool HandleValue(CTemplate& Tmpl, CString& sValue, - const MCString& msOptions) { - return false; - } + virtual bool HandleValue(CTemplate& Tmpl, CString& sValue, + const MCString& msOptions) { + return false; + } private: }; @@ -56,161 +56,161 @@ class CTemplate; class CTemplateOptions { public: - CTemplateOptions() - : m_eEscapeFrom(CString::EASCII), m_eEscapeTo(CString::EASCII) {} + CTemplateOptions() + : m_eEscapeFrom(CString::EASCII), m_eEscapeTo(CString::EASCII) {} - virtual ~CTemplateOptions() {} + virtual ~CTemplateOptions() {} - void Parse(const CString& sLine); + void Parse(const CString& sLine); - // Getters - CString::EEscape GetEscapeFrom() const { return m_eEscapeFrom; } - CString::EEscape GetEscapeTo() const { return m_eEscapeTo; } - // !Getters + // Getters + CString::EEscape GetEscapeFrom() const { return m_eEscapeFrom; } + CString::EEscape GetEscapeTo() const { return m_eEscapeTo; } + // !Getters private: - CString::EEscape m_eEscapeFrom; - CString::EEscape m_eEscapeTo; + CString::EEscape m_eEscapeFrom; + CString::EEscape m_eEscapeTo; }; class CTemplateLoopContext { public: - CTemplateLoopContext(unsigned long uFilePos, const CString& sLoopName, - bool bReverse, std::vector* pRows) - : m_bReverse(bReverse), - m_bHasData(false), - m_sName(sLoopName), - m_uRowIndex(0), - m_uFilePosition(uFilePos), - m_pvRows(pRows) {} + CTemplateLoopContext(unsigned long uFilePos, const CString& sLoopName, + bool bReverse, std::vector* pRows) + : m_bReverse(bReverse), + m_bHasData(false), + m_sName(sLoopName), + m_uRowIndex(0), + m_uFilePosition(uFilePos), + m_pvRows(pRows) {} - virtual ~CTemplateLoopContext() {} + virtual ~CTemplateLoopContext() {} - CTemplateLoopContext(const CTemplateLoopContext&) = default; - CTemplateLoopContext& operator=(const CTemplateLoopContext&) = default; + CTemplateLoopContext(const CTemplateLoopContext&) = default; + CTemplateLoopContext& operator=(const CTemplateLoopContext&) = default; - // Setters - void SetHasData(bool b = true) { m_bHasData = b; } - void SetName(const CString& s) { m_sName = s; } - void SetRowIndex(unsigned int u) { m_uRowIndex = u; } - unsigned int IncRowIndex() { return ++m_uRowIndex; } - unsigned int DecRowIndex() { - if (m_uRowIndex == 0) { - return 0; - } - return --m_uRowIndex; - } - void SetFilePosition(unsigned int u) { m_uFilePosition = u; } - // !Setters + // Setters + void SetHasData(bool b = true) { m_bHasData = b; } + void SetName(const CString& s) { m_sName = s; } + void SetRowIndex(unsigned int u) { m_uRowIndex = u; } + unsigned int IncRowIndex() { return ++m_uRowIndex; } + unsigned int DecRowIndex() { + if (m_uRowIndex == 0) { + return 0; + } + return --m_uRowIndex; + } + void SetFilePosition(unsigned int u) { m_uFilePosition = u; } + // !Setters - // Getters - bool HasData() const { return m_bHasData; } - const CString& GetName() const { return m_sName; } - unsigned long GetFilePosition() const { return m_uFilePosition; } - unsigned int GetRowIndex() const { return m_uRowIndex; } - size_t GetRowCount() { return m_pvRows->size(); } - std::vector* GetRows() { return m_pvRows; } - CTemplate* GetNextRow() { return GetRow(IncRowIndex()); } - CTemplate* GetCurRow() { return GetRow(m_uRowIndex); } + // Getters + bool HasData() const { return m_bHasData; } + const CString& GetName() const { return m_sName; } + unsigned long GetFilePosition() const { return m_uFilePosition; } + unsigned int GetRowIndex() const { return m_uRowIndex; } + size_t GetRowCount() { return m_pvRows->size(); } + std::vector* GetRows() { return m_pvRows; } + CTemplate* GetNextRow() { return GetRow(IncRowIndex()); } + CTemplate* GetCurRow() { return GetRow(m_uRowIndex); } - CTemplate* GetRow(unsigned int uIndex); - CString GetValue(const CString& sName, bool bFromIf = false); - // !Getters + CTemplate* GetRow(unsigned int uIndex); + CString GetValue(const CString& sName, bool bFromIf = false); + // !Getters private: - bool m_bReverse; //!< Iterate through this loop in reverse order - bool m_bHasData; //!< Tells whether this loop has real data or not - CString m_sName; //!< The name portion of the tag - unsigned int m_uRowIndex; //!< The index of the current row we're on - unsigned long - m_uFilePosition; //!< The file position of the opening tag - std::vector* - m_pvRows; //!< This holds pointers to the templates associated with this loop + bool m_bReverse; //!< Iterate through this loop in reverse order + bool m_bHasData; //!< Tells whether this loop has real data or not + CString m_sName; //!< The name portion of the tag + unsigned int m_uRowIndex; //!< The index of the current row we're on + unsigned long + m_uFilePosition; //!< The file position of the opening tag + std::vector* + m_pvRows; //!< This holds pointers to the templates associated with this loop }; class CTemplate : public MCString { public: - CTemplate() : CTemplate("") {} + CTemplate() : CTemplate("") {} - CTemplate(const CString& sFileName) - : MCString(), - m_pParent(nullptr), - m_sFileName(sFileName), - m_lsbPaths(), - m_mvLoops(), - m_vLoopContexts(), - m_spOptions(new CTemplateOptions), - m_vspTagHandlers() {} + CTemplate(const CString& sFileName) + : MCString(), + m_pParent(nullptr), + m_sFileName(sFileName), + m_lsbPaths(), + m_mvLoops(), + m_vLoopContexts(), + m_spOptions(new CTemplateOptions), + m_vspTagHandlers() {} - CTemplate(const std::shared_ptr& Options, - CTemplate* pParent = nullptr) - : MCString(), - m_pParent(pParent), - m_sFileName(""), - m_lsbPaths(), - m_mvLoops(), - m_vLoopContexts(), - m_spOptions(Options), - m_vspTagHandlers() {} + CTemplate(const std::shared_ptr& Options, + CTemplate* pParent = nullptr) + : MCString(), + m_pParent(pParent), + m_sFileName(""), + m_lsbPaths(), + m_mvLoops(), + m_vLoopContexts(), + m_spOptions(Options), + m_vspTagHandlers() {} - virtual ~CTemplate(); + virtual ~CTemplate(); - CTemplate(const CTemplate& other) = default; - CTemplate& operator=(const CTemplate& other) = default; + CTemplate(const CTemplate& other) = default; + CTemplate& operator=(const CTemplate& other) = default; - //! Class for implementing custom tags in subclasses - void AddTagHandler(std::shared_ptr spTagHandler) { - m_vspTagHandlers.push_back(spTagHandler); - } + //! Class for implementing custom tags in subclasses + void AddTagHandler(std::shared_ptr spTagHandler) { + m_vspTagHandlers.push_back(spTagHandler); + } - std::vector>& GetTagHandlers() { - if (m_pParent) { - return m_pParent->GetTagHandlers(); - } + std::vector>& GetTagHandlers() { + if (m_pParent) { + return m_pParent->GetTagHandlers(); + } - return m_vspTagHandlers; - } + return m_vspTagHandlers; + } - CString ResolveLiteral(const CString& sString); + CString ResolveLiteral(const CString& sString); - void Init(); + void Init(); - CTemplate* GetParent(bool bRoot); - CString ExpandFile(const CString& sFilename, bool bFromInc = false); - bool SetFile(const CString& sFileName); + CTemplate* GetParent(bool bRoot); + CString ExpandFile(const CString& sFilename, bool bFromInc = false); + bool SetFile(const CString& sFileName); - void SetPath(const CString& sPath); // Sets the dir:dir:dir type path to - // look at for templates, as of right - // now no ../../.. protection - CString MakePath(const CString& sPath) const; - void PrependPath(const CString& sPath, bool bIncludesOnly = false); - void AppendPath(const CString& sPath, bool bIncludesOnly = false); - void RemovePath(const CString& sPath); - void ClearPaths(); - bool PrintString(CString& sRet); - bool Print(std::ostream& oOut); - bool Print(const CString& sFileName, std::ostream& oOut); - bool ValidIf(const CString& sArgs); - bool ValidExpr(const CString& sExpr); - bool IsTrue(const CString& sName); - bool HasLoop(const CString& sName); - CString GetValue(const CString& sName, bool bFromIf = false); - CTemplate& AddRow(const CString& sName); - CTemplate* GetRow(const CString& sName, unsigned int uIndex); - std::vector* GetLoop(const CString& sName); - void DelCurLoopContext(); - CTemplateLoopContext* GetCurLoopContext(); - CTemplate* GetCurTemplate(); + void SetPath(const CString& sPath); // Sets the dir:dir:dir type path to + // look at for templates, as of right + // now no ../../.. protection + CString MakePath(const CString& sPath) const; + void PrependPath(const CString& sPath, bool bIncludesOnly = false); + void AppendPath(const CString& sPath, bool bIncludesOnly = false); + void RemovePath(const CString& sPath); + void ClearPaths(); + bool PrintString(CString& sRet); + bool Print(std::ostream& oOut); + bool Print(const CString& sFileName, std::ostream& oOut); + bool ValidIf(const CString& sArgs); + bool ValidExpr(const CString& sExpr); + bool IsTrue(const CString& sName); + bool HasLoop(const CString& sName); + CString GetValue(const CString& sName, bool bFromIf = false); + CTemplate& AddRow(const CString& sName); + CTemplate* GetRow(const CString& sName, unsigned int uIndex); + std::vector* GetLoop(const CString& sName); + void DelCurLoopContext(); + CTemplateLoopContext* GetCurLoopContext(); + CTemplate* GetCurTemplate(); - // Getters - const CString& GetFileName() const { return m_sFileName; } - // !Getters + // Getters + const CString& GetFileName() const { return m_sFileName; } + // !Getters private: - CTemplate* m_pParent; - CString m_sFileName; - std::list> m_lsbPaths; - std::map> m_mvLoops; - std::vector m_vLoopContexts; - std::shared_ptr m_spOptions; - std::vector> m_vspTagHandlers; + CTemplate* m_pParent; + CString m_sFileName; + std::list> m_lsbPaths; + std::map> m_mvLoops; + std::vector m_vLoopContexts; + std::shared_ptr m_spOptions; + std::vector> m_vspTagHandlers; }; #endif // !ZNC_TEMPLATE_H diff --git a/include/znc/Threads.h b/include/znc/Threads.h index 6fcdae1b..7280bd67 100644 --- a/include/znc/Threads.h +++ b/include/znc/Threads.h @@ -66,102 +66,102 @@ using CConditionVariable = std::condition_variable_any; */ class CJob { public: - friend class CThreadPool; + friend class CThreadPool; - enum EJobState { READY, RUNNING, DONE, CANCELLED }; + enum EJobState { READY, RUNNING, DONE, CANCELLED }; - CJob() : m_eState(READY) {} + CJob() : m_eState(READY) {} - /// Destructor, always called from the main thread. - virtual ~CJob() {} + /// Destructor, always called from the main thread. + virtual ~CJob() {} - /// This function is called in a separate thread and can do heavy, blocking work. - virtual void runThread() = 0; + /// This function is called in a separate thread and can do heavy, blocking work. + virtual void runThread() = 0; - /// This function is called from the main thread after runThread() - /// finishes. It can be used to handle the results from runThread() - /// without needing synchronization primitives. - virtual void runMain() = 0; + /// This function is called from the main thread after runThread() + /// finishes. It can be used to handle the results from runThread() + /// without needing synchronization primitives. + virtual void runMain() = 0; - /// This can be used to check if the job was cancelled. For example, - /// runThread() can return early if this returns true. - bool wasCancelled() const; + /// This can be used to check if the job was cancelled. For example, + /// runThread() can return early if this returns true. + bool wasCancelled() const; private: - // Undefined copy constructor and assignment operator - CJob(const CJob&); - CJob& operator=(const CJob&); + // Undefined copy constructor and assignment operator + CJob(const CJob&); + CJob& operator=(const CJob&); - // Synchronized via the thread pool's mutex! Do not access without that - // mutex! - EJobState m_eState; + // Synchronized via the thread pool's mutex! Do not access without that + // mutex! + EJobState m_eState; }; class CThreadPool { private: - friend class CJob; + friend class CJob; - CThreadPool(); - ~CThreadPool(); + CThreadPool(); + ~CThreadPool(); public: - static CThreadPool& Get(); + static CThreadPool& Get(); - /// Add a job to the thread pool and run it. The job will be deleted when done. - void addJob(CJob* job); + /// Add a job to the thread pool and run it. The job will be deleted when done. + void addJob(CJob* job); - /// Cancel a job that was previously passed to addJob(). This *might* - /// mean that runThread() and/or runMain() will not be called on the job. - /// This function BLOCKS until the job finishes! - void cancelJob(CJob* job); + /// Cancel a job that was previously passed to addJob(). This *might* + /// mean that runThread() and/or runMain() will not be called on the job. + /// This function BLOCKS until the job finishes! + void cancelJob(CJob* job); - /// Cancel some jobs that were previously passed to addJob(). This *might* - /// mean that runThread() and/or runMain() will not be called on some of - /// the jobs. This function BLOCKS until all jobs finish! - void cancelJobs(const std::set& jobs); + /// Cancel some jobs that were previously passed to addJob(). This *might* + /// mean that runThread() and/or runMain() will not be called on some of + /// the jobs. This function BLOCKS until all jobs finish! + void cancelJobs(const std::set& jobs); - int getReadFD() const { return m_iJobPipe[0]; } + int getReadFD() const { return m_iJobPipe[0]; } - void handlePipeReadable() const; + void handlePipeReadable() const; private: - void jobDone(CJob* pJob); + void jobDone(CJob* pJob); - // Check if the calling thread is still needed, must be called with m_mutex - // held - bool threadNeeded() const; + // Check if the calling thread is still needed, must be called with m_mutex + // held + bool threadNeeded() const; - CJob* getJobFromPipe() const; - void finishJob(CJob*) const; + CJob* getJobFromPipe() const; + void finishJob(CJob*) const; - void threadFunc(); + void threadFunc(); - // mutex protecting all of these members - CMutex m_mutex; + // mutex protecting all of these members + CMutex m_mutex; - // condition variable for waiting idle threads - CConditionVariable m_cond; + // condition variable for waiting idle threads + CConditionVariable m_cond; - // condition variable for reporting finished cancellation - CConditionVariable m_cancellationCond; + // condition variable for reporting finished cancellation + CConditionVariable m_cancellationCond; - // condition variable for waiting running threads == 0 - CConditionVariable m_exit_cond; + // condition variable for waiting running threads == 0 + CConditionVariable m_exit_cond; - // when this is true, all threads should exit - bool m_done; + // when this is true, all threads should exit + bool m_done; - // total number of running threads - size_t m_num_threads; + // total number of running threads + size_t m_num_threads; - // number of idle threads waiting on the condition variable - size_t m_num_idle; + // number of idle threads waiting on the condition variable + size_t m_num_idle; - // pipe for waking up the main thread - int m_iJobPipe[2]; + // pipe for waking up the main thread + int m_iJobPipe[2]; - // list of pending jobs - std::list m_jobs; + // list of pending jobs + std::list m_jobs; }; #endif // HAVE_PTHREAD diff --git a/include/znc/User.h b/include/znc/User.h index 389e2398..30d57e63 100644 --- a/include/znc/User.h +++ b/include/znc/User.h @@ -36,232 +36,232 @@ class CServer; class CUser { public: - CUser(const CString& sUserName); - ~CUser(); + CUser(const CString& sUserName); + ~CUser(); - CUser(const CUser&) = delete; - CUser& operator=(const CUser&) = delete; + CUser(const CUser&) = delete; + CUser& operator=(const CUser&) = delete; - bool ParseConfig(CConfig* Config, CString& sError); + bool ParseConfig(CConfig* Config, CString& sError); - // TODO refactor this - enum eHashType { - HASH_NONE, - HASH_MD5, - HASH_SHA256, + // TODO refactor this + enum eHashType { + HASH_NONE, + HASH_MD5, + HASH_SHA256, - HASH_DEFAULT = HASH_SHA256 - }; + HASH_DEFAULT = HASH_SHA256 + }; - // If you change the default hash here and in HASH_DEFAULT, - // don't forget CUtils::sDefaultHash! - // TODO refactor this - static CString SaltedHash(const CString& sPass, const CString& sSalt) { - return CUtils::SaltedSHA256Hash(sPass, sSalt); - } + // If you change the default hash here and in HASH_DEFAULT, + // don't forget CUtils::sDefaultHash! + // TODO refactor this + static CString SaltedHash(const CString& sPass, const CString& sSalt) { + return CUtils::SaltedSHA256Hash(sPass, sSalt); + } - CConfig ToConfig() const; - bool CheckPass(const CString& sPass) const; - bool AddAllowedHost(const CString& sHostMask); - bool RemAllowedHost(const CString& sHostMask); - void ClearAllowedHosts(); - bool IsHostAllowed(const CString& sHostMask) const; - bool IsValid(CString& sErrMsg, bool bSkipPass = false) const; - static bool IsValidUserName(const CString& sUserName); - static CString MakeCleanUserName(const CString& sUserName); + CConfig ToConfig() const; + bool CheckPass(const CString& sPass) const; + bool AddAllowedHost(const CString& sHostMask); + bool RemAllowedHost(const CString& sHostMask); + void ClearAllowedHosts(); + bool IsHostAllowed(const CString& sHostMask) const; + bool IsValid(CString& sErrMsg, bool bSkipPass = false) const; + static bool IsValidUserName(const CString& sUserName); + static CString MakeCleanUserName(const CString& sUserName); - // Modules - CModules& GetModules() { return *m_pModules; } - const CModules& GetModules() const { return *m_pModules; } - // !Modules + // Modules + CModules& GetModules() { return *m_pModules; } + const CModules& GetModules() const { return *m_pModules; } + // !Modules - // Networks - CIRCNetwork* AddNetwork(const CString& sNetwork, CString& sErrorRet); - bool DeleteNetwork(const CString& sNetwork); - bool AddNetwork(CIRCNetwork* pNetwork); - void RemoveNetwork(CIRCNetwork* pNetwork); - CIRCNetwork* FindNetwork(const CString& sNetwork) const; - const std::vector& GetNetworks() const; - bool HasSpaceForNewNetwork() const; - // !Networks + // Networks + CIRCNetwork* AddNetwork(const CString& sNetwork, CString& sErrorRet); + bool DeleteNetwork(const CString& sNetwork); + bool AddNetwork(CIRCNetwork* pNetwork); + void RemoveNetwork(CIRCNetwork* pNetwork); + CIRCNetwork* FindNetwork(const CString& sNetwork) const; + const std::vector& GetNetworks() const; + bool HasSpaceForNewNetwork() const; + // !Networks - bool PutUser(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutAllUser(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutStatus(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutStatusNotice(const CString& sLine, CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); - bool PutModule(const CString& sModule, const CString& sLine, - CClient* pClient = nullptr, CClient* pSkipClient = nullptr); - bool PutModNotice(const CString& sModule, const CString& sLine, - CClient* pClient = nullptr, - CClient* pSkipClient = nullptr); + bool PutUser(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutAllUser(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutStatus(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutStatusNotice(const CString& sLine, CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); + bool PutModule(const CString& sModule, const CString& sLine, + CClient* pClient = nullptr, CClient* pSkipClient = nullptr); + bool PutModNotice(const CString& sModule, const CString& sLine, + CClient* pClient = nullptr, + CClient* pSkipClient = nullptr); - bool IsUserAttached() const; - void UserConnected(CClient* pClient); - void UserDisconnected(CClient* pClient); + bool IsUserAttached() const; + void UserConnected(CClient* pClient); + void UserDisconnected(CClient* pClient); - CString GetLocalDCCIP() const; + CString GetLocalDCCIP() const; - CString ExpandString(const CString& sStr) const; - CString& ExpandString(const CString& sStr, CString& sRet) const; + CString ExpandString(const CString& sStr) const; + CString& ExpandString(const CString& sStr, CString& sRet) const; - CString AddTimestamp(const CString& sStr) const; - CString AddTimestamp(time_t tm, const CString& sStr) const; + CString AddTimestamp(const CString& sStr) const; + CString AddTimestamp(time_t tm, const CString& sStr) const; - void CloneNetworks(const CUser& User); - bool Clone(const CUser& User, CString& sErrorRet, - bool bCloneNetworks = true); - void BounceAllClients(); + void CloneNetworks(const CUser& User); + bool Clone(const CUser& User, CString& sErrorRet, + bool bCloneNetworks = true); + void BounceAllClients(); - void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } - void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } + void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } + void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } - // Setters - void SetNick(const CString& s); - void SetAltNick(const CString& s); - void SetIdent(const CString& s); - void SetRealName(const CString& s); - void SetBindHost(const CString& s); - void SetDCCBindHost(const CString& s); - void SetPass(const CString& s, eHashType eHash, const CString& sSalt = ""); - void SetMultiClients(bool b); - void SetDenyLoadMod(bool b); - void SetAdmin(bool b); - void SetDenySetBindHost(bool b); - bool SetStatusPrefix(const CString& s); - void SetDefaultChanModes(const CString& s); - void SetClientEncoding(const CString& s); - void SetQuitMsg(const CString& s); - bool AddCTCPReply(const CString& sCTCP, const CString& sReply); - bool DelCTCPReply(const CString& sCTCP); - /** @deprecated Use SetChanBufferSize() or SetQueryBufferSize() instead. */ - bool SetBufferCount(unsigned int u, bool bForce = false); - bool SetChanBufferSize(unsigned int u, bool bForce = false); - bool SetQueryBufferSize(unsigned int u, bool bForce = false); - void SetAutoClearChanBuffer(bool b); - void SetAutoClearQueryBuffer(bool b); + // Setters + void SetNick(const CString& s); + void SetAltNick(const CString& s); + void SetIdent(const CString& s); + void SetRealName(const CString& s); + void SetBindHost(const CString& s); + void SetDCCBindHost(const CString& s); + void SetPass(const CString& s, eHashType eHash, const CString& sSalt = ""); + void SetMultiClients(bool b); + void SetDenyLoadMod(bool b); + void SetAdmin(bool b); + void SetDenySetBindHost(bool b); + bool SetStatusPrefix(const CString& s); + void SetDefaultChanModes(const CString& s); + void SetClientEncoding(const CString& s); + void SetQuitMsg(const CString& s); + bool AddCTCPReply(const CString& sCTCP, const CString& sReply); + bool DelCTCPReply(const CString& sCTCP); + /** @deprecated Use SetChanBufferSize() or SetQueryBufferSize() instead. */ + bool SetBufferCount(unsigned int u, bool bForce = false); + bool SetChanBufferSize(unsigned int u, bool bForce = false); + bool SetQueryBufferSize(unsigned int u, bool bForce = false); + void SetAutoClearChanBuffer(bool b); + void SetAutoClearQueryBuffer(bool b); - void SetBeingDeleted(bool b) { m_bBeingDeleted = b; } - void SetTimestampFormat(const CString& s) { m_sTimestampFormat = s; } - void SetTimestampAppend(bool b) { m_bAppendTimestamp = b; } - void SetTimestampPrepend(bool b) { m_bPrependTimestamp = b; } - void SetTimezone(const CString& s) { m_sTimezone = s; } - void SetJoinTries(unsigned int i) { m_uMaxJoinTries = i; } - void SetMaxJoins(unsigned int i) { m_uMaxJoins = i; } - void SetSkinName(const CString& s) { m_sSkinName = s; } - void SetMaxNetworks(unsigned int i) { m_uMaxNetworks = i; } - void SetMaxQueryBuffers(unsigned int i) { m_uMaxQueryBuffers = i; } - // !Setters + void SetBeingDeleted(bool b) { m_bBeingDeleted = b; } + void SetTimestampFormat(const CString& s) { m_sTimestampFormat = s; } + void SetTimestampAppend(bool b) { m_bAppendTimestamp = b; } + void SetTimestampPrepend(bool b) { m_bPrependTimestamp = b; } + void SetTimezone(const CString& s) { m_sTimezone = s; } + void SetJoinTries(unsigned int i) { m_uMaxJoinTries = i; } + void SetMaxJoins(unsigned int i) { m_uMaxJoins = i; } + void SetSkinName(const CString& s) { m_sSkinName = s; } + void SetMaxNetworks(unsigned int i) { m_uMaxNetworks = i; } + void SetMaxQueryBuffers(unsigned int i) { m_uMaxQueryBuffers = i; } + // !Setters - // Getters - const std::vector& GetUserClients() const { return m_vClients; } - std::vector GetAllClients() const; - const CString& GetUserName() const; - const CString& GetCleanUserName() const; - const CString& GetNick(bool bAllowDefault = true) const; - const CString& GetAltNick(bool bAllowDefault = true) const; - const CString& GetIdent(bool bAllowDefault = true) const; - CString GetRealName() const; - const CString& GetBindHost() const; - const CString& GetDCCBindHost() const; - const CString& GetPass() const; - eHashType GetPassHashType() const; - const CString& GetPassSalt() const; - const std::set& GetAllowedHosts() const; - const CString& GetTimestampFormat() const; - const CString& GetClientEncoding() const; - bool GetTimestampAppend() const; - bool GetTimestampPrepend() const; + // Getters + const std::vector& GetUserClients() const { return m_vClients; } + std::vector GetAllClients() const; + const CString& GetUserName() const; + const CString& GetCleanUserName() const; + const CString& GetNick(bool bAllowDefault = true) const; + const CString& GetAltNick(bool bAllowDefault = true) const; + const CString& GetIdent(bool bAllowDefault = true) const; + CString GetRealName() const; + const CString& GetBindHost() const; + const CString& GetDCCBindHost() const; + const CString& GetPass() const; + eHashType GetPassHashType() const; + const CString& GetPassSalt() const; + const std::set& GetAllowedHosts() const; + const CString& GetTimestampFormat() const; + const CString& GetClientEncoding() const; + bool GetTimestampAppend() const; + bool GetTimestampPrepend() const; - const CString& GetUserPath() const; + const CString& GetUserPath() const; - bool DenyLoadMod() const; - bool IsAdmin() const; - bool DenySetBindHost() const; - bool MultiClients() const; - const CString& GetStatusPrefix() const; - const CString& GetDefaultChanModes() const; + bool DenyLoadMod() const; + bool IsAdmin() const; + bool DenySetBindHost() const; + bool MultiClients() const; + const CString& GetStatusPrefix() const; + const CString& GetDefaultChanModes() const; - CString GetQuitMsg() const; - const MCString& GetCTCPReplies() const; - /** @deprecated Use GetChanBufferSize() or GetQueryBufferSize() instead. */ - unsigned int GetBufferCount() const; - unsigned int GetChanBufferSize() const; - unsigned int GetQueryBufferSize() const; - bool AutoClearChanBuffer() const; - bool AutoClearQueryBuffer() const; - bool IsBeingDeleted() const { return m_bBeingDeleted; } - CString GetTimezone() const { return m_sTimezone; } - unsigned long long BytesRead() const; - unsigned long long BytesWritten() const; - unsigned int JoinTries() const { return m_uMaxJoinTries; } - unsigned int MaxJoins() const { return m_uMaxJoins; } - CString GetSkinName() const; - unsigned int MaxNetworks() const { return m_uMaxNetworks; } - unsigned int MaxQueryBuffers() const { return m_uMaxQueryBuffers; } - // !Getters + CString GetQuitMsg() const; + const MCString& GetCTCPReplies() const; + /** @deprecated Use GetChanBufferSize() or GetQueryBufferSize() instead. */ + unsigned int GetBufferCount() const; + unsigned int GetChanBufferSize() const; + unsigned int GetQueryBufferSize() const; + bool AutoClearChanBuffer() const; + bool AutoClearQueryBuffer() const; + bool IsBeingDeleted() const { return m_bBeingDeleted; } + CString GetTimezone() const { return m_sTimezone; } + unsigned long long BytesRead() const; + unsigned long long BytesWritten() const; + unsigned int JoinTries() const { return m_uMaxJoinTries; } + unsigned int MaxJoins() const { return m_uMaxJoins; } + CString GetSkinName() const; + unsigned int MaxNetworks() const { return m_uMaxNetworks; } + unsigned int MaxQueryBuffers() const { return m_uMaxQueryBuffers; } + // !Getters protected: - const CString m_sUserName; - const CString m_sCleanUserName; - CString m_sNick; - CString m_sAltNick; - CString m_sIdent; - CString m_sRealName; - CString m_sBindHost; - CString m_sDCCBindHost; - CString m_sPass; - CString m_sPassSalt; - CString m_sStatusPrefix; - CString m_sDefaultChanModes; - CString m_sClientEncoding; + const CString m_sUserName; + const CString m_sCleanUserName; + CString m_sNick; + CString m_sAltNick; + CString m_sIdent; + CString m_sRealName; + CString m_sBindHost; + CString m_sDCCBindHost; + CString m_sPass; + CString m_sPassSalt; + CString m_sStatusPrefix; + CString m_sDefaultChanModes; + CString m_sClientEncoding; - CString m_sQuitMsg; - MCString m_mssCTCPReplies; - CString m_sTimestampFormat; - CString m_sTimezone; - eHashType m_eHashType; + CString m_sQuitMsg; + MCString m_mssCTCPReplies; + CString m_sTimestampFormat; + CString m_sTimezone; + eHashType m_eHashType; - // Paths - CString m_sUserPath; - // !Paths + // Paths + CString m_sUserPath; + // !Paths - bool m_bMultiClients; - bool m_bDenyLoadMod; - bool m_bAdmin; - bool m_bDenySetBindHost; - bool m_bAutoClearChanBuffer; - bool m_bAutoClearQueryBuffer; - bool m_bBeingDeleted; - bool m_bAppendTimestamp; - bool m_bPrependTimestamp; + bool m_bMultiClients; + bool m_bDenyLoadMod; + bool m_bAdmin; + bool m_bDenySetBindHost; + bool m_bAutoClearChanBuffer; + bool m_bAutoClearQueryBuffer; + bool m_bBeingDeleted; + bool m_bAppendTimestamp; + bool m_bPrependTimestamp; - CUserTimer* m_pUserTimer; + CUserTimer* m_pUserTimer; - std::vector m_vIRCNetworks; - std::vector m_vClients; - std::set m_ssAllowedHosts; - unsigned int m_uChanBufferSize; - unsigned int m_uQueryBufferSize; - unsigned long long m_uBytesRead; - unsigned long long m_uBytesWritten; - unsigned int m_uMaxJoinTries; - unsigned int m_uMaxNetworks; - unsigned int m_uMaxQueryBuffers; - unsigned int m_uMaxJoins; - CString m_sSkinName; + std::vector m_vIRCNetworks; + std::vector m_vClients; + std::set m_ssAllowedHosts; + unsigned int m_uChanBufferSize; + unsigned int m_uQueryBufferSize; + unsigned long long m_uBytesRead; + unsigned long long m_uBytesWritten; + unsigned int m_uMaxJoinTries; + unsigned int m_uMaxNetworks; + unsigned int m_uMaxQueryBuffers; + unsigned int m_uMaxJoins; + CString m_sSkinName; - CModules* m_pModules; + CModules* m_pModules; private: - void SetKeepBuffer(bool b) { - SetAutoClearChanBuffer(!b); - } // XXX compatibility crap, added in 0.207 - bool LoadModule(const CString& sModName, const CString& sArgs, - const CString& sNotice, CString& sError); + void SetKeepBuffer(bool b) { + SetAutoClearChanBuffer(!b); + } // XXX compatibility crap, added in 0.207 + bool LoadModule(const CString& sModName, const CString& sArgs, + const CString& sNotice, CString& sError); }; #endif // !ZNC_USER_H diff --git a/include/znc/Utils.h b/include/znc/Utils.h index 8374d334..06c6ce3a 100644 --- a/include/znc/Utils.h +++ b/include/znc/Utils.h @@ -29,71 +29,71 @@ #include static inline void SetFdCloseOnExec(int fd) { - int flags = fcntl(fd, F_GETFD, 0); - if (flags < 0) return; // Ignore errors - // When we execve() a new process this fd is now automatically closed. - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + int flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) return; // Ignore errors + // When we execve() a new process this fd is now automatically closed. + fcntl(fd, F_SETFD, flags | FD_CLOEXEC); } static const char g_HexDigits[] = "0123456789abcdef"; class CUtils { public: - CUtils(); - ~CUtils(); + CUtils(); + ~CUtils(); - static CString GetIP(unsigned long addr); - static unsigned long GetLongIP(const CString& sIP); + static CString GetIP(unsigned long addr); + static unsigned long GetLongIP(const CString& sIP); - static void PrintError(const CString& sMessage); - static void PrintMessage(const CString& sMessage, bool bStrong = false); - static void PrintPrompt(const CString& sMessage); - static void PrintAction(const CString& sMessage); - static void PrintStatus(bool bSuccess, const CString& sMessage = ""); + static void PrintError(const CString& sMessage); + static void PrintMessage(const CString& sMessage, bool bStrong = false); + static void PrintPrompt(const CString& sMessage); + static void PrintAction(const CString& sMessage); + static void PrintStatus(bool bSuccess, const CString& sMessage = ""); #ifndef SWIGPERL - // TODO refactor this - static const CString sDefaultHash; + // TODO refactor this + static const CString sDefaultHash; #endif - static CString GetSaltedHashPass(CString& sSalt); - static CString GetSalt(); - static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt); - static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt); - static CString GetPass(const CString& sPrompt); - static bool GetInput(const CString& sPrompt, CString& sRet, - const CString& sDefault = "", - const CString& sHint = ""); - static bool GetBoolInput(const CString& sPrompt, bool bDefault); - static bool GetBoolInput(const CString& sPrompt, bool* pbDefault = nullptr); - static bool GetNumInput(const CString& sPrompt, unsigned int& uRet, - unsigned int uMin = 0, unsigned int uMax = ~0, - unsigned int uDefault = ~0); + static CString GetSaltedHashPass(CString& sSalt); + static CString GetSalt(); + static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt); + static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt); + static CString GetPass(const CString& sPrompt); + static bool GetInput(const CString& sPrompt, CString& sRet, + const CString& sDefault = "", + const CString& sHint = ""); + static bool GetBoolInput(const CString& sPrompt, bool bDefault); + static bool GetBoolInput(const CString& sPrompt, bool* pbDefault = nullptr); + static bool GetNumInput(const CString& sPrompt, unsigned int& uRet, + unsigned int uMin = 0, unsigned int uMax = ~0, + unsigned int uDefault = ~0); - static unsigned long long GetMillTime() { - struct timeval tv; - unsigned long long iTime = 0; - gettimeofday(&tv, nullptr); - iTime = (unsigned long long)tv.tv_sec * 1000; - iTime += ((unsigned long long)tv.tv_usec / 1000); - return iTime; - } + static unsigned long long GetMillTime() { + struct timeval tv; + unsigned long long iTime = 0; + gettimeofday(&tv, nullptr); + iTime = (unsigned long long)tv.tv_sec * 1000; + iTime += ((unsigned long long)tv.tv_usec / 1000); + return iTime; + } #ifdef HAVE_LIBSSL - static void GenerateCert(FILE* pOut, const CString& sHost = ""); + static void GenerateCert(FILE* pOut, const CString& sHost = ""); #endif /* HAVE_LIBSSL */ - static CString CTime(time_t t, const CString& sTZ); - static CString FormatTime(time_t t, const CString& sFormat, - const CString& sTZ); - static CString FormatServerTime(const timeval& tv); - static timeval ParseServerTime(const CString& sTime); - static SCString GetTimezones(); - static SCString GetEncodings(); + static CString CTime(time_t t, const CString& sTZ); + static CString FormatTime(time_t t, const CString& sFormat, + const CString& sTZ); + static CString FormatServerTime(const timeval& tv); + static timeval ParseServerTime(const CString& sTime); + static SCString GetTimezones(); + static SCString GetEncodings(); - /// @deprecated Use CMessage instead - static MCString GetMessageTags(const CString& sLine); - /// @deprecated Use CMessage instead - static void SetMessageTags(CString& sLine, const MCString& mssTags); + /// @deprecated Use CMessage instead + static MCString GetMessageTags(const CString& sLine); + /// @deprecated Use CMessage instead + static void SetMessageTags(CString& sLine, const MCString& mssTags); private: protected: @@ -101,16 +101,16 @@ class CUtils { class CException { public: - typedef enum { EX_Shutdown, EX_Restart } EType; + typedef enum { EX_Shutdown, EX_Restart } EType; - CException(EType e) : m_eType(e) {} - virtual ~CException() {} + CException(EType e) : m_eType(e) {} + virtual ~CException() {} - EType GetType() const { return m_eType; } + EType GetType() const { return m_eType; } private: protected: - EType m_eType; + EType m_eType; }; /** Previously this generated a grid-like output from a given input. @@ -134,61 +134,61 @@ class CException { */ class CTable : protected std::vector> { public: - /** Constructor + /** Constructor * * @param uPreferredWidth If width of table is bigger than this, text in cells will be wrapped to several lines, if possible */ - CTable() : m_vsHeaders(), m_vsOutput() {} - virtual ~CTable() {} + CTable() : m_vsHeaders(), m_vsOutput() {} + virtual ~CTable() {} - /** Adds a new column to the table. + /** Adds a new column to the table. * Please note that you should add all columns before starting to fill * the table! * @param sName The name of the column. * @return false if a column by that name already existed. */ - bool AddColumn(const CString& sName); + bool AddColumn(const CString& sName); - /** Adds a new row to the table. + /** Adds a new row to the table. * After calling this you can fill the row with content. * @return The index of this row */ - size_type AddRow(); + size_type AddRow(); - /** Sets a given cell in the table to a value. + /** Sets a given cell in the table to a value. * @param sColumn The name of the column you want to fill. * @param sValue The value to write into that column. * @param uRowIdx The index of the row to use as returned by AddRow(). * If this is not given, the last row will be used. * @return True if setting the cell was successful. */ - bool SetCell(const CString& sColumn, const CString& sValue, - size_type uRowIdx = ~0); + bool SetCell(const CString& sColumn, const CString& sValue, + size_type uRowIdx = ~0); - /** Get a line of the table's output + /** Get a line of the table's output * @param uIdx The index of the line you want. * @param sLine This string will receive the output. * @return True unless uIdx is past the end of the table. */ - bool GetLine(unsigned int uIdx, CString& sLine) const; + bool GetLine(unsigned int uIdx, CString& sLine) const; - /// Completely clear the table. - void Clear(); + /// Completely clear the table. + void Clear(); - /// @return The number of rows in this table, not counting the header. - using std::vector>::size; + /// @return The number of rows in this table, not counting the header. + using std::vector>::size; - /// @return True if this table doesn't contain any rows. - using std::vector>::empty; + /// @return True if this table doesn't contain any rows. + using std::vector>::empty; private: - unsigned int GetColumnIndex(const CString& sName) const; - VCString Render() const; + unsigned int GetColumnIndex(const CString& sName) const; + VCString Render() const; protected: - // TODO: cleanup these fields before 1.7.0 (I don't want to break ABI) - VCString m_vsHeaders; - mutable VCString m_vsOutput; // Rendered table + // TODO: cleanup these fields before 1.7.0 (I don't want to break ABI) + VCString m_vsHeaders; + mutable VCString m_vsOutput; // Rendered table }; #ifdef HAVE_LIBSSL @@ -198,35 +198,35 @@ class CTable : protected std::vector> { //! does Blowfish w/64 bit feedback, no padding class CBlowfish { public: - /** + /** * @param sPassword key to encrypt with * @param iEncrypt encrypt method (BF_DECRYPT or BF_ENCRYPT) * @param sIvec what to set the ivector to start with, default sets it all 0's */ - CBlowfish(const CString& sPassword, int iEncrypt, - const CString& sIvec = ""); - ~CBlowfish(); + CBlowfish(const CString& sPassword, int iEncrypt, + const CString& sIvec = ""); + ~CBlowfish(); - CBlowfish(const CBlowfish&) = default; - CBlowfish& operator=(const CBlowfish&) = default; + CBlowfish(const CBlowfish&) = default; + CBlowfish& operator=(const CBlowfish&) = default; - //! output must be freed - static unsigned char* MD5(const unsigned char* input, u_int ilen); + //! output must be freed + static unsigned char* MD5(const unsigned char* input, u_int ilen); - //! returns an md5 of the CString (not hex encoded) - static CString MD5(const CString& sInput, bool bHexEncode = false); + //! returns an md5 of the CString (not hex encoded) + static CString MD5(const CString& sInput, bool bHexEncode = false); - //! output must be the same size as input - void Crypt(unsigned char* input, unsigned char* output, u_int ibytes); + //! output must be the same size as input + void Crypt(unsigned char* input, unsigned char* output, u_int ibytes); - //! must free result - unsigned char* Crypt(unsigned char* input, u_int ibytes); - CString Crypt(const CString& sData); + //! must free result + unsigned char* Crypt(unsigned char* input, u_int ibytes); + CString Crypt(const CString& sData); private: - unsigned char* m_ivec; - BF_KEY m_bkey; - int m_iEncrypt, m_num; + unsigned char* m_ivec; + BF_KEY m_bkey; + int m_iEncrypt, m_num; }; #endif /* HAVE_LIBSSL */ @@ -239,120 +239,120 @@ class CBlowfish { template class TCacheMap { public: - TCacheMap(unsigned int uTTL = 5000) : m_mItems(), m_uTTL(uTTL) {} + TCacheMap(unsigned int uTTL = 5000) : m_mItems(), m_uTTL(uTTL) {} - virtual ~TCacheMap() {} + virtual ~TCacheMap() {} - /** + /** * @brief This function adds an item to the cache using the default time-to-live value * @param Item the item to add to the cache */ - void AddItem(const K& Item) { AddItem(Item, m_uTTL); } + void AddItem(const K& Item) { AddItem(Item, m_uTTL); } - /** + /** * @brief This function adds an item to the cache using a custom time-to-live value * @param Item the item to add to the cache * @param uTTL the time-to-live for this specific item */ - void AddItem(const K& Item, unsigned int uTTL) { AddItem(Item, V(), uTTL); } + void AddItem(const K& Item, unsigned int uTTL) { AddItem(Item, V(), uTTL); } - /** + /** * @brief This function adds an item to the cache using the default time-to-live value * @param Item the item to add to the cache * @param Val The value associated with the key Item */ - void AddItem(const K& Item, const V& Val) { AddItem(Item, Val, m_uTTL); } + void AddItem(const K& Item, const V& Val) { AddItem(Item, Val, m_uTTL); } - /** + /** * @brief This function adds an item to the cache using a custom time-to-live value * @param Item the item to add to the cache * @param Val The value associated with the key Item * @param uTTL the time-to-live for this specific item */ - void AddItem(const K& Item, const V& Val, unsigned int uTTL) { - if (!uTTL) { - // If time-to-live is zero we don't want to waste our time adding - // it - RemItem(Item); // Remove the item incase it already exists - return; - } + void AddItem(const K& Item, const V& Val, unsigned int uTTL) { + if (!uTTL) { + // If time-to-live is zero we don't want to waste our time adding + // it + RemItem(Item); // Remove the item incase it already exists + return; + } - m_mItems[Item] = value(CUtils::GetMillTime() + uTTL, Val); - } + m_mItems[Item] = value(CUtils::GetMillTime() + uTTL, Val); + } - /** + /** * @brief Performs a Cleanup() and then checks to see if your item exists * @param Item The item to check for * @return true if item exists */ - bool HasItem(const K& Item) { - Cleanup(); - return (m_mItems.find(Item) != m_mItems.end()); - } + bool HasItem(const K& Item) { + Cleanup(); + return (m_mItems.find(Item) != m_mItems.end()); + } - /** + /** * @brief Performs a Cleanup() and returns a pointer to the object, or nullptr * @param Item The item to check for * @return Pointer to the item or nullptr if there is no suitable one */ - V* GetItem(const K& Item) { - Cleanup(); - iterator it = m_mItems.find(Item); - if (it == m_mItems.end()) return nullptr; - return &it->second.second; - } + V* GetItem(const K& Item) { + Cleanup(); + iterator it = m_mItems.find(Item); + if (it == m_mItems.end()) return nullptr; + return &it->second.second; + } - /** + /** * @brief Removes a specific item from the cache * @param Item The item to be removed * @return true if item existed and was removed, false if it never existed */ - bool RemItem(const K& Item) { return (m_mItems.erase(Item) != 0); } + bool RemItem(const K& Item) { return (m_mItems.erase(Item) != 0); } - /** + /** * @brief Cycles through the queue removing all of the stale entries */ - void Cleanup() { - iterator it = m_mItems.begin(); + void Cleanup() { + iterator it = m_mItems.begin(); - while (it != m_mItems.end()) { - if (CUtils::GetMillTime() > (it->second.first)) { - m_mItems.erase(it++); - } else { - ++it; - } - } - } + while (it != m_mItems.end()) { + if (CUtils::GetMillTime() > (it->second.first)) { + m_mItems.erase(it++); + } else { + ++it; + } + } + } - /** + /** * @brief Clear all entries */ - void Clear() { m_mItems.clear(); } + void Clear() { m_mItems.clear(); } - /** + /** * @brief Returns all entries */ - std::map GetItems() { - Cleanup(); - std::map mItems; - for (const auto& it : m_mItems) { - mItems[it.first] = it.second.second; - } - return mItems; - } + std::map GetItems() { + Cleanup(); + std::map mItems; + for (const auto& it : m_mItems) { + mItems[it.first] = it.second.second; + } + return mItems; + } - // Setters - void SetTTL(unsigned int u) { m_uTTL = u; } - // !Setters - // Getters - unsigned int GetTTL() const { return m_uTTL; } - // !Getters + // Setters + void SetTTL(unsigned int u) { m_uTTL = u; } + // !Setters + // Getters + unsigned int GetTTL() const { return m_uTTL; } + // !Getters protected: - typedef std::pair value; - typedef typename std::map::iterator iterator; - std::map - m_mItems; //!< Map of cached items. The value portion of the map is for the expire time - unsigned int m_uTTL; //!< Default time-to-live duration + typedef std::pair value; + typedef typename std::map::iterator iterator; + std::map + m_mItems; //!< Map of cached items. The value portion of the map is for the expire time + unsigned int m_uTTL; //!< Default time-to-live duration }; #endif // !ZNC_UTILS_H diff --git a/include/znc/WebModules.h b/include/znc/WebModules.h index e0b3fb11..5bd18042 100644 --- a/include/znc/WebModules.h +++ b/include/znc/WebModules.h @@ -33,156 +33,156 @@ typedef std::vector VWebSubPages; class CZNCTagHandler : public CTemplateTagHandler { public: - CZNCTagHandler(CWebSock& pWebSock); - virtual ~CZNCTagHandler() {} + CZNCTagHandler(CWebSock& pWebSock); + virtual ~CZNCTagHandler() {} - bool HandleTag(CTemplate& Tmpl, const CString& sName, const CString& sArgs, - CString& sOutput) override; + bool HandleTag(CTemplate& Tmpl, const CString& sName, const CString& sArgs, + CString& sOutput) override; private: - CWebSock& m_WebSock; + CWebSock& m_WebSock; }; class CWebSession { public: - CWebSession(const CString& sId, const CString& sIP); - ~CWebSession(); + CWebSession(const CString& sId, const CString& sIP); + ~CWebSession(); - CWebSession(const CWebSession&) = delete; - CWebSession& operator=(const CWebSession&) = delete; + CWebSession(const CWebSession&) = delete; + CWebSession& operator=(const CWebSession&) = delete; - const CString& GetId() const { return m_sId; } - const CString& GetIP() const { return m_sIP; } - CUser* GetUser() const { return m_pUser; } - time_t GetLastActive() const { return m_tmLastActive; } - bool IsLoggedIn() const { return m_pUser != nullptr; } - bool IsAdmin() const; - void UpdateLastActive(); + const CString& GetId() const { return m_sId; } + const CString& GetIP() const { return m_sIP; } + CUser* GetUser() const { return m_pUser; } + time_t GetLastActive() const { return m_tmLastActive; } + bool IsLoggedIn() const { return m_pUser != nullptr; } + bool IsAdmin() const; + void UpdateLastActive(); - CUser* SetUser(CUser* p) { - m_pUser = p; - return m_pUser; - } + CUser* SetUser(CUser* p) { + m_pUser = p; + return m_pUser; + } - void ClearMessageLoops(); - void FillMessageLoops(CTemplate& Tmpl); - size_t AddError(const CString& sMessage); - size_t AddSuccess(const CString& sMessage); + void ClearMessageLoops(); + void FillMessageLoops(CTemplate& Tmpl); + size_t AddError(const CString& sMessage); + size_t AddSuccess(const CString& sMessage); private: - CString m_sId; - CString m_sIP; - CUser* m_pUser; - VCString m_vsErrorMsgs; - VCString m_vsSuccessMsgs; - time_t m_tmLastActive; + CString m_sId; + CString m_sIP; + CUser* m_pUser; + VCString m_vsErrorMsgs; + VCString m_vsSuccessMsgs; + time_t m_tmLastActive; }; class CWebSubPage { public: - CWebSubPage(const CString& sName, const CString& sTitle = "", - unsigned int uFlags = 0) - : m_uFlags(uFlags), m_sName(sName), m_sTitle(sTitle), m_vParams() {} + CWebSubPage(const CString& sName, const CString& sTitle = "", + unsigned int uFlags = 0) + : m_uFlags(uFlags), m_sName(sName), m_sTitle(sTitle), m_vParams() {} - CWebSubPage(const CString& sName, const CString& sTitle, - const VPair& vParams, unsigned int uFlags = 0) - : m_uFlags(uFlags), - m_sName(sName), - m_sTitle(sTitle), - m_vParams(vParams) {} + CWebSubPage(const CString& sName, const CString& sTitle, + const VPair& vParams, unsigned int uFlags = 0) + : m_uFlags(uFlags), + m_sName(sName), + m_sTitle(sTitle), + m_vParams(vParams) {} - virtual ~CWebSubPage() {} + virtual ~CWebSubPage() {} - enum { F_ADMIN = 1 }; + enum { F_ADMIN = 1 }; - void SetName(const CString& s) { m_sName = s; } - void SetTitle(const CString& s) { m_sTitle = s; } - void AddParam(const CString& sName, const CString& sValue) { - m_vParams.push_back(make_pair(sName, sValue)); - } + void SetName(const CString& s) { m_sName = s; } + void SetTitle(const CString& s) { m_sTitle = s; } + void AddParam(const CString& sName, const CString& sValue) { + m_vParams.push_back(make_pair(sName, sValue)); + } - bool RequiresAdmin() const { return m_uFlags & F_ADMIN; } + bool RequiresAdmin() const { return m_uFlags & F_ADMIN; } - const CString& GetName() const { return m_sName; } - const CString& GetTitle() const { return m_sTitle; } - const VPair& GetParams() const { return m_vParams; } + const CString& GetName() const { return m_sName; } + const CString& GetTitle() const { return m_sTitle; } + const VPair& GetParams() const { return m_vParams; } private: - unsigned int m_uFlags; - CString m_sName; - CString m_sTitle; - VPair m_vParams; + unsigned int m_uFlags; + CString m_sName; + CString m_sTitle; + VPair m_vParams; }; class CWebSessionMap : public TCacheMap> { public: - CWebSessionMap(unsigned int uTTL = 5000) - : TCacheMap>(uTTL) {} - void FinishUserSessions(const CUser& User); + CWebSessionMap(unsigned int uTTL = 5000) + : TCacheMap>(uTTL) {} + void FinishUserSessions(const CUser& User); }; class CWebSock : public CHTTPSock { public: - enum EPageReqResult { - PAGE_NOTFOUND, // print 404 and Close() - PAGE_PRINT, // print page contents and Close() - PAGE_DEFERRED, // async processing, Close() will be called from a - // different place - PAGE_DONE // all stuff has been done - }; + enum EPageReqResult { + PAGE_NOTFOUND, // print 404 and Close() + PAGE_PRINT, // print page contents and Close() + PAGE_DEFERRED, // async processing, Close() will be called from a + // different place + PAGE_DONE // all stuff has been done + }; - CWebSock(const CString& sURIPrefix); - virtual ~CWebSock(); + CWebSock(const CString& sURIPrefix); + virtual ~CWebSock(); - bool ForceLogin() override; - bool OnLogin(const CString& sUser, const CString& sPass, - bool bBasic) override; - void OnPageRequest(const CString& sURI) override; + bool ForceLogin() override; + bool OnLogin(const CString& sUser, const CString& sPass, + bool bBasic) override; + void OnPageRequest(const CString& sURI) override; - EPageReqResult PrintTemplate(const CString& sPageName, CString& sPageRet, - CModule* pModule = nullptr); - EPageReqResult PrintStaticFile(const CString& sPath, CString& sPageRet, - CModule* pModule = nullptr); + EPageReqResult PrintTemplate(const CString& sPageName, CString& sPageRet, + CModule* pModule = nullptr); + EPageReqResult PrintStaticFile(const CString& sPath, CString& sPageRet, + CModule* pModule = nullptr); - CString FindTmpl(CModule* pModule, const CString& sName); + CString FindTmpl(CModule* pModule, const CString& sName); - void PrintErrorPage(const CString& sMessage); + void PrintErrorPage(const CString& sMessage); - std::shared_ptr GetSession(); + std::shared_ptr GetSession(); - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; - static CString GetSkinPath(const CString& sSkinName); - void GetAvailSkins(VCString& vRet) const; - CString GetSkinName(); + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + static CString GetSkinPath(const CString& sSkinName); + void GetAvailSkins(VCString& vRet) const; + CString GetSkinName(); - CString GetRequestCookie(const CString& sKey); - bool SendCookie(const CString& sKey, const CString& sValue); + CString GetRequestCookie(const CString& sKey); + bool SendCookie(const CString& sKey, const CString& sValue); - static void FinishUserSessions(const CUser& User); + static void FinishUserSessions(const CUser& User); protected: - using CHTTPSock::PrintErrorPage; + using CHTTPSock::PrintErrorPage; - bool AddModLoop(const CString& sLoopName, CModule& Module, - CTemplate* pTemplate = nullptr); - VCString GetDirs(CModule* pModule, bool bIsTemplate); - void SetPaths(CModule* pModule, bool bIsTemplate = false); - void SetVars(); - CString GetCSRFCheck(); + bool AddModLoop(const CString& sLoopName, CModule& Module, + CTemplate* pTemplate = nullptr); + VCString GetDirs(CModule* pModule, bool bIsTemplate); + void SetPaths(CModule* pModule, bool bIsTemplate = false); + void SetVars(); + CString GetCSRFCheck(); private: - EPageReqResult OnPageRequestInternal(const CString& sURI, - CString& sPageRet); + EPageReqResult OnPageRequestInternal(const CString& sURI, + CString& sPageRet); - bool m_bPathsSet; - CTemplate m_Template; - std::shared_ptr m_spAuth; - CString m_sModName; - CString m_sPath; - CString m_sPage; - std::shared_ptr m_spSession; + bool m_bPathsSet; + CTemplate m_Template; + std::shared_ptr m_spAuth; + CString m_sModName; + CString m_sPath; + CString m_sPage; + std::shared_ptr m_spSession; - static const unsigned int m_uiMaxSessions; + static const unsigned int m_uiMaxSessions; }; #endif // !ZNC_WEBMODULES_H diff --git a/include/znc/ZNCDebug.h b/include/znc/ZNCDebug.h index 8c858356..62315d59 100644 --- a/include/znc/ZNCDebug.h +++ b/include/znc/ZNCDebug.h @@ -33,28 +33,28 @@ * @param f The expression you want to display. */ #define DEBUG(f) \ - do { \ - if (CDebug::Debug()) { \ - CDebugStream sDebug; \ - sDebug << f; \ - } \ - } while (0) + do { \ + if (CDebug::Debug()) { \ + CDebugStream sDebug; \ + sDebug << f; \ + } \ + } while (0) class CDebug { public: - static void SetStdoutIsTTY(bool b) { stdoutIsTTY = b; } - static bool StdoutIsTTY() { return stdoutIsTTY; } - static void SetDebug(bool b) { debug = b; } - static bool Debug() { return debug; } + static void SetStdoutIsTTY(bool b) { stdoutIsTTY = b; } + static bool StdoutIsTTY() { return stdoutIsTTY; } + static void SetDebug(bool b) { debug = b; } + static bool Debug() { return debug; } protected: - static bool stdoutIsTTY; - static bool debug; + static bool stdoutIsTTY; + static bool debug; }; class CDebugStream : public std::ostringstream { public: - ~CDebugStream(); + ~CDebugStream(); }; #endif // !ZNCDEBUG_H diff --git a/include/znc/ZNCString.h b/include/znc/ZNCString.h index 96e2ec31..79c2a48b 100644 --- a/include/znc/ZNCString.h +++ b/include/znc/ZNCString.h @@ -67,107 +67,107 @@ enum class CaseSensitivity { CaseInsensitive, CaseSensitive }; */ class CString : public std::string { public: - typedef enum { - EASCII, - EURL, - EHTML, - ESQL, - ENAMEDFMT, - EDEBUG, - EMSGTAG, - EHEXCOLON, - } EEscape; + typedef enum { + EASCII, + EURL, + EHTML, + ESQL, + ENAMEDFMT, + EDEBUG, + EMSGTAG, + EHEXCOLON, + } EEscape; - static const CaseSensitivity CaseSensitive = CaseSensitivity::CaseSensitive; - static const CaseSensitivity CaseInsensitive = - CaseSensitivity::CaseInsensitive; + static const CaseSensitivity CaseSensitive = CaseSensitivity::CaseSensitive; + static const CaseSensitivity CaseInsensitive = + CaseSensitivity::CaseInsensitive; - explicit CString(bool b) : std::string(b ? "true" : "false") {} - explicit CString(char c); - explicit CString(unsigned char c); - explicit CString(short i); - explicit CString(unsigned short i); - explicit CString(int i); - explicit CString(unsigned int i); - explicit CString(long i); - explicit CString(unsigned long i); - explicit CString(long long i); - explicit CString(unsigned long long i); - explicit CString(double i, int precision = 2); - explicit CString(float i, int precision = 2); + explicit CString(bool b) : std::string(b ? "true" : "false") {} + explicit CString(char c); + explicit CString(unsigned char c); + explicit CString(short i); + explicit CString(unsigned short i); + explicit CString(int i); + explicit CString(unsigned int i); + explicit CString(long i); + explicit CString(unsigned long i); + explicit CString(long long i); + explicit CString(unsigned long long i); + explicit CString(double i, int precision = 2); + explicit CString(float i, int precision = 2); - CString() : std::string() {} - CString(const char* c) : std::string(c) {} - CString(const char* c, size_t l) : std::string(c, l) {} - CString(const std::string& s) : std::string(s) {} - CString(size_t n, char c) : std::string(n, c) {} - CString(std::initializer_list list) : std::string(list) {} - ~CString() {} + CString() : std::string() {} + CString(const char* c) : std::string(c) {} + CString(const char* c, size_t l) : std::string(c, l) {} + CString(const std::string& s) : std::string(s) {} + CString(size_t n, char c) : std::string(n, c) {} + CString(std::initializer_list list) : std::string(list) {} + ~CString() {} - /** + /** * Casts a CString to another type. Implemented via std::stringstream, you use this * for any class that has an operator<<(std::ostream, YourClass). * @param target The object to cast into. If the cast fails, its state is unspecified. * @return True if the cast succeeds, and false if it fails. */ - template - bool Convert(T* target) const { - std::stringstream ss(*this); - ss >> *target; - return (bool)ss; // we don't care why it failed, only whether it failed - } + template + bool Convert(T* target) const { + std::stringstream ss(*this); + ss >> *target; + return (bool)ss; // we don't care why it failed, only whether it failed + } - /** + /** * Joins a collection of objects together, using 'this' as a delimiter. * You can pass either pointers to arrays, or iterators to collections. * @param i_begin An iterator pointing to the beginning of a group of objects. * @param i_end An iterator pointing past the end of a group of objects. * @return The joined string */ - template - CString Join(Iterator i_start, const Iterator& i_end) const { - if (i_start == i_end) return CString(""); - std::ostringstream output; - output << *i_start; - while (true) { - ++i_start; - if (i_start == i_end) return CString(output.str()); - output << *this; - output << *i_start; - } - } + template + CString Join(Iterator i_start, const Iterator& i_end) const { + if (i_start == i_end) return CString(""); + std::ostringstream output; + output << *i_start; + while (true) { + ++i_start; + if (i_start == i_end) return CString(output.str()); + output << *this; + output << *i_start; + } + } - /** + /** * Compare this string caselessly to some other string. * @param s The string to compare to. * @param uLen The number of characters to compare. * @return An integer less than, equal to, or greater than zero if this * string smaller, equal.... to the given string. */ - int CaseCmp(const CString& s, - CString::size_type uLen = CString::npos) const; - /** + int CaseCmp(const CString& s, + CString::size_type uLen = CString::npos) const; + /** * Compare this string case sensitively to some other string. * @param s The string to compare to. * @param uLen The number of characters to compare. * @return An integer less than, equal to, or greater than zero if this * string smaller, equal.... to the given string. */ - int StrCmp(const CString& s, CString::size_type uLen = CString::npos) const; - /** + int StrCmp(const CString& s, CString::size_type uLen = CString::npos) const; + /** * Check if this string is equal to some other string. * @param s The string to compare to. * @param cs CaseSensitive if you want the comparison to be case * sensitive, CaseInsensitive (default) otherwise. * @return True if the strings are equal. */ - bool Equals(const CString& s, CaseSensitivity cs = CaseInsensitive) const; - /** + bool Equals(const CString& s, CaseSensitivity cs = CaseInsensitive) const; + /** * @deprecated */ - bool Equals(const CString& s, bool bCaseSensitive, - CString::size_type uLen = CString::npos) const; - /** + bool Equals(const CString& s, bool bCaseSensitive, + CString::size_type uLen = CString::npos) const; + /** * Do a wildcard comparison between two strings. * For example, the following returns true: * WildCmp("*!?bar@foo", "I_am!~bar@foo"); @@ -178,9 +178,9 @@ class CString : public std::string { * @todo Make cs CaseInsensitive by default. * @return true if the wildcard matches. */ - static bool WildCmp(const CString& sWild, const CString& sString, - CaseSensitivity cs = CaseSensitive); - /** + static bool WildCmp(const CString& sWild, const CString& sString, + CaseSensitivity cs = CaseSensitive); + /** * Do a wild compare on this string. * @param sWild The wildcards used to for the comparison. * @param cs CaseSensitive (default) if you want the comparison @@ -188,39 +188,39 @@ class CString : public std::string { * @todo Make cs CaseInsensitive by default. * @return The result of this->WildCmp(sWild, *this);. */ - bool WildCmp(const CString& sWild, - CaseSensitivity cs = CaseSensitive) const; + bool WildCmp(const CString& sWild, + CaseSensitivity cs = CaseSensitive) const; - /** + /** * Turn all characters in this string into their upper-case equivalent. * @returns A reference to *this. */ - CString& MakeUpper(); - /** + CString& MakeUpper(); + /** * Turn all characters in this string into their lower-case equivalent. * @returns A reference to *this. */ - CString& MakeLower(); - /** + CString& MakeLower(); + /** * Return a copy of this string with all characters turned into * upper-case. * @return The new string. */ - CString AsUpper() const; - /** + CString AsUpper() const; + /** * Return a copy of this string with all characters turned into * lower-case. * @return The new string. */ - CString AsLower() const; + CString AsLower() const; - static EEscape ToEscape(const CString& sEsc); - CString Escape_n(EEscape eFrom, EEscape eTo) const; - CString Escape_n(EEscape eTo) const; - CString& Escape(EEscape eFrom, EEscape eTo); - CString& Escape(EEscape eTo); + static EEscape ToEscape(const CString& sEsc); + CString Escape_n(EEscape eFrom, EEscape eTo) const; + CString Escape_n(EEscape eTo) const; + CString& Escape(EEscape eFrom, EEscape eTo); + CString& Escape(EEscape eTo); - /** Replace all occurrences in a string. + /** Replace all occurrences in a string. * * You can specify a "safe zone" via sLeft and sRight. Anything inside * of such a zone will not be replaced. This does not do recursion, so @@ -240,12 +240,12 @@ class CString : public std::string { * sRight are removed. * @returns The number of replacements done. */ - static unsigned int Replace(CString& sStr, const CString& sReplace, - const CString& sWith, const CString& sLeft = "", - const CString& sRight = "", - bool bRemoveDelims = false); + static unsigned int Replace(CString& sStr, const CString& sReplace, + const CString& sWith, const CString& sLeft = "", + const CString& sRight = "", + bool bRemoveDelims = false); - /** Replace all occurrences in the current string. + /** Replace all occurrences in the current string. * @see CString::Replace * @param sReplace The string to look for. * @param sWith The replacement to use. @@ -255,10 +255,10 @@ class CString : public std::string { * @return The result of the replacing. The current string is left * unchanged. */ - CString Replace_n(const CString& sReplace, const CString& sWith, - const CString& sLeft = "", const CString& sRight = "", - bool bRemoveDelims = false) const; - /** Replace all occurrences in the current string. + CString Replace_n(const CString& sReplace, const CString& sWith, + const CString& sLeft = "", const CString& sRight = "", + bool bRemoveDelims = false) const; + /** Replace all occurrences in the current string. * @see CString::Replace * @param sReplace The string to look for. * @param sWith The replacement to use. @@ -267,33 +267,33 @@ class CString : public std::string { * @param bRemoveDelims If true, all matching delimiters are removed. * @returns The number of replacements done. */ - unsigned int Replace(const CString& sReplace, const CString& sWith, - const CString& sLeft = "", const CString& sRight = "", - bool bRemoveDelims = false); - /** Ellipsize the current string. + unsigned int Replace(const CString& sReplace, const CString& sWith, + const CString& sLeft = "", const CString& sRight = "", + bool bRemoveDelims = false); + /** Ellipsize the current string. * For example, ellipsizing "Hello, I'm Bob" to the length 9 would * result in "Hello,...". * @param uLen The length to ellipsize to. * @return The ellipsized string. */ - CString Ellipsize(unsigned int uLen) const; - /** Return the left part of the string. + CString Ellipsize(unsigned int uLen) const; + /** Return the left part of the string. * @param uCount The number of characters to keep. * @return The resulting string. */ - CString Left(size_type uCount) const; - /** Return the right part of the string. + CString Left(size_type uCount) const; + /** Return the right part of the string. * @param uCount The number of characters to keep. * @return The resulting string. */ - CString Right(size_type uCount) const; + CString Right(size_type uCount) const; - /** Get the first line of this string. + /** Get the first line of this string. * @return The first line of text. */ - CString FirstLine() const { return Token(0, false, "\n"); } + CString FirstLine() const { return Token(0, false, "\n"); } - /** Get a token out of this string. For example in the string "a bc d e", + /** Get a token out of this string. For example in the string "a bc d e", * each of "a", "bc", "d" and "e" are tokens. * @param uPos The number of the token you are interested. The first * token has a position of 0. @@ -308,22 +308,22 @@ class CString : public std::string { * after it. * @see Split() if you need a string split into all of its tokens. */ - CString Token(size_t uPos, bool bRest = false, const CString& sSep = " ", - bool bAllowEmpty = false) const; + CString Token(size_t uPos, bool bRest = false, const CString& sSep = " ", + bool bAllowEmpty = false) const; - /** Get a token out of this string. This function behaves much like the + /** Get a token out of this string. This function behaves much like the * other Token() function in this class. The extra arguments are * handled similarly to Split(). */ - CString Token(size_t uPos, bool bRest, const CString& sSep, - bool bAllowEmpty, const CString& sLeft, const CString& sRight, - bool bTrimQuotes = true) const; + CString Token(size_t uPos, bool bRest, const CString& sSep, + bool bAllowEmpty, const CString& sLeft, const CString& sRight, + bool bTrimQuotes = true) const; - size_type URLSplit(MCString& msRet) const; - size_type OptionSplit(MCString& msRet, bool bUpperKeys = false) const; - size_type QuoteSplit(VCString& vsRet) const; + size_type URLSplit(MCString& msRet) const; + size_type OptionSplit(MCString& msRet, bool bUpperKeys = false) const; + size_type QuoteSplit(VCString& vsRet) const; - /** Split up this string into tokens. + /** Split up this string into tokens. * Via sLeft and sRight you can define "markers" like with Replace(). * Anything in such a marked section is treated as a single token. All * occurences of sDelim in such a block are ignored. @@ -338,21 +338,21 @@ class CString : public std::string { * each token. * @return The number of tokens found. */ - size_type Split(const CString& sDelim, VCString& vsRet, - bool bAllowEmpty = true, const CString& sLeft = "", - const CString& sRight = "", bool bTrimQuotes = true, - bool bTrimWhiteSpace = false) const; + size_type Split(const CString& sDelim, VCString& vsRet, + bool bAllowEmpty = true, const CString& sLeft = "", + const CString& sRight = "", bool bTrimQuotes = true, + bool bTrimWhiteSpace = false) const; - /** Split up this string into tokens. + /** Split up this string into tokens. * This function is identical to the other CString::Split(), except that * the result is returned as a SCString instead of a VCString. */ - size_type Split(const CString& sDelim, SCString& ssRet, - bool bAllowEmpty = true, const CString& sLeft = "", - const CString& sRight = "", bool bTrimQuotes = true, - bool bTrimWhiteSpace = false) const; + size_type Split(const CString& sDelim, SCString& ssRet, + bool bAllowEmpty = true, const CString& sLeft = "", + const CString& sRight = "", bool bTrimQuotes = true, + bool bTrimWhiteSpace = false) const; - /** Build a string from a format string, replacing values from a map. + /** Build a string from a format string, replacing values from a map. * The format specification can contain simple named parameters that match * keys in the given map. For example in the string "a {b} c", the key "b" * is looked up in the map, and inserted for "{b}". @@ -360,35 +360,35 @@ class CString : public std::string { * @param msValues A map of named parameters to their values. * @return The string with named parameters replaced. */ - static CString NamedFormat(const CString& sFormat, - const MCString& msValues); + static CString NamedFormat(const CString& sFormat, + const MCString& msValues); - /** Produces a random string. + /** Produces a random string. * @param uLength The length of the resulting string. * @return A random string. */ - static CString RandomString(unsigned int uLength); + static CString RandomString(unsigned int uLength); - /** @return The MD5 hash of this string. */ - CString MD5() const; - /** @return The SHA256 hash of this string. */ - CString SHA256() const; + /** @return The MD5 hash of this string. */ + CString MD5() const; + /** @return The SHA256 hash of this string. */ + CString SHA256() const; - /** Treat this string as base64-encoded data and decode it. + /** Treat this string as base64-encoded data and decode it. * @param sRet String to which the result of the decode is safed. * @return The length of the resulting string. */ - unsigned long Base64Decode(CString& sRet) const; - /** Treat this string as base64-encoded data and decode it. + unsigned long Base64Decode(CString& sRet) const; + /** Treat this string as base64-encoded data and decode it. * The result is saved in this CString instance. * @return The length of the resulting string. */ - unsigned long Base64Decode(); - /** Treat this string as base64-encoded data and decode it. + unsigned long Base64Decode(); + /** Treat this string as base64-encoded data and decode it. * @return The decoded string. */ - CString Base64Decode_n() const; - /** Base64-encode the current string. + CString Base64Decode_n() const; + /** Base64-encode the current string. * @param sRet String where the result is saved. * @param uWrap A boolean(!?!) that decides if the result should be * wrapped after everywhere 57 characters. @@ -396,194 +396,194 @@ class CString : public std::string { * @todo WTF @ uWrap. * @todo This only returns false if some formula we use was wrong?! */ - bool Base64Encode(CString& sRet, unsigned int uWrap = 0) const; - /** Base64-encode the current string. + bool Base64Encode(CString& sRet, unsigned int uWrap = 0) const; + /** Base64-encode the current string. * This string is overwritten with the result of the encode. * @todo return value and param are as with Base64Encode() from above. */ - bool Base64Encode(unsigned int uWrap = 0); - /** Base64-encode the current string + bool Base64Encode(unsigned int uWrap = 0); + /** Base64-encode the current string * @todo uWrap is as broken as Base64Encode()'s uWrap. * @return The encoded string. */ - CString Base64Encode_n(unsigned int uWrap = 0) const; + CString Base64Encode_n(unsigned int uWrap = 0) const; #ifdef HAVE_LIBSSL - CString Encrypt_n(const CString& sPass, const CString& sIvec = "") const; - CString Decrypt_n(const CString& sPass, const CString& sIvec = "") const; - void Encrypt(const CString& sPass, const CString& sIvec = ""); - void Decrypt(const CString& sPass, const CString& sIvec = ""); - void Crypt(const CString& sPass, bool bEncrypt, const CString& sIvec = ""); + CString Encrypt_n(const CString& sPass, const CString& sIvec = "") const; + CString Decrypt_n(const CString& sPass, const CString& sIvec = "") const; + void Encrypt(const CString& sPass, const CString& sIvec = ""); + void Decrypt(const CString& sPass, const CString& sIvec = ""); + void Crypt(const CString& sPass, bool bEncrypt, const CString& sIvec = ""); #endif - /** Pretty-print a percent value. + /** Pretty-print a percent value. * @param d The percent value. This should be in range 0-100. * @return The "pretty" string. */ - static CString ToPercent(double d); - /** Pretty-print a number of bytes. + static CString ToPercent(double d); + /** Pretty-print a number of bytes. * @param d The number of bytes. * @return A string describing the number of bytes. */ - static CString ToByteStr(unsigned long long d); - /** Pretty-print a time span. + static CString ToByteStr(unsigned long long d); + /** Pretty-print a time span. * @param s Number of seconds to print. * @return A string like "4w 6d 4h 3m 58s". */ - static CString ToTimeStr(unsigned long s); + static CString ToTimeStr(unsigned long s); - /** @return True if this string is not "false". */ - bool ToBool() const; - /** @return The numerical value of this string similar to atoi(). */ - short ToShort() const; - /** @return The numerical value of this string similar to atoi(). */ - unsigned short ToUShort() const; - /** @return The numerical value of this string similar to atoi(). */ - int ToInt() const; - /** @return The numerical value of this string similar to atoi(). */ - long ToLong() const; - /** @return The numerical value of this string similar to atoi(). */ - unsigned int ToUInt() const; - /** @return The numerical value of this string similar to atoi(). */ - unsigned long ToULong() const; - /** @return The numerical value of this string similar to atoi(). */ - unsigned long long ToULongLong() const; - /** @return The numerical value of this string similar to atoi(). */ - long long ToLongLong() const; - /** @return The numerical value of this string similar to atoi(). */ - double ToDouble() const; + /** @return True if this string is not "false". */ + bool ToBool() const; + /** @return The numerical value of this string similar to atoi(). */ + short ToShort() const; + /** @return The numerical value of this string similar to atoi(). */ + unsigned short ToUShort() const; + /** @return The numerical value of this string similar to atoi(). */ + int ToInt() const; + /** @return The numerical value of this string similar to atoi(). */ + long ToLong() const; + /** @return The numerical value of this string similar to atoi(). */ + unsigned int ToUInt() const; + /** @return The numerical value of this string similar to atoi(). */ + unsigned long ToULong() const; + /** @return The numerical value of this string similar to atoi(). */ + unsigned long long ToULongLong() const; + /** @return The numerical value of this string similar to atoi(). */ + long long ToLongLong() const; + /** @return The numerical value of this string similar to atoi(). */ + double ToDouble() const; - /** Trim this string. All leading/trailing occurences of characters from + /** Trim this string. All leading/trailing occurences of characters from * s are removed. * @param s A list of characters that should be trimmed. * @return true if this string was modified. */ - bool Trim(const CString& s = " \t\r\n"); - /** Trim this string. All leading occurences of characters from s are + bool Trim(const CString& s = " \t\r\n"); + /** Trim this string. All leading occurences of characters from s are * removed. * @param s A list of characters that should be trimmed. * @return true if this string was modified. */ - bool TrimLeft(const CString& s = " \t\r\n"); - /** Trim this string. All trailing occurences of characters from s are + bool TrimLeft(const CString& s = " \t\r\n"); + /** Trim this string. All trailing occurences of characters from s are * removed. * @param s A list of characters that should be trimmed. * @return true if this string was modified. */ - bool TrimRight(const CString& s = " \t\r\n"); - /** Trim this string. All leading/trailing occurences of characters from + bool TrimRight(const CString& s = " \t\r\n"); + /** Trim this string. All leading/trailing occurences of characters from * s are removed. This CString instance is not modified. * @param s A list of characters that should be trimmed. * @return The trimmed string. */ - CString Trim_n(const CString& s = " \t\r\n") const; - /** Trim this string. All leading occurences of characters from s are + CString Trim_n(const CString& s = " \t\r\n") const; + /** Trim this string. All leading occurences of characters from s are * removed. This CString instance is not modified. * @param s A list of characters that should be trimmed. * @return The trimmed string. */ - CString TrimLeft_n(const CString& s = " \t\r\n") const; - /** Trim this string. All trailing occurences of characters from s are + CString TrimLeft_n(const CString& s = " \t\r\n") const; + /** Trim this string. All trailing occurences of characters from s are * removed. This CString instance is not modified. * @param s A list of characters that should be trimmed. * @return The trimmed string. */ - CString TrimRight_n(const CString& s = " \t\r\n") const; + CString TrimRight_n(const CString& s = " \t\r\n") const; - /** Trim a given prefix. + /** Trim a given prefix. * @param sPrefix The prefix that should be removed. * @return True if this string was modified. */ - bool TrimPrefix(const CString& sPrefix = ":"); - /** Trim a given suffix. + bool TrimPrefix(const CString& sPrefix = ":"); + /** Trim a given suffix. * @param sSuffix The suffix that should be removed. * @return True if this string was modified. */ - bool TrimSuffix(const CString& sSuffix); - /** Trim a given prefix. + bool TrimSuffix(const CString& sSuffix); + /** Trim a given prefix. * @param sPrefix The prefix that should be removed. * @return A copy of this string without the prefix. */ - CString TrimPrefix_n(const CString& sPrefix = ":") const; - /** Trim a given suffix. + CString TrimPrefix_n(const CString& sPrefix = ":") const; + /** Trim a given suffix. * @param sSuffix The suffix that should be removed. * @return A copy of this string without the prefix. */ - CString TrimSuffix_n(const CString& sSuffix) const; + CString TrimSuffix_n(const CString& sSuffix) const; - /** Find the position of the given substring. + /** Find the position of the given substring. * @param s The substring to search for. * @param cs CaseSensitive if you want the comparison to be case * sensitive, CaseInsensitive (default) otherwise. * @return The position of the substring if found, CString::npos otherwise. */ - size_t Find(const CString& s, CaseSensitivity cs = CaseInsensitive) const; - /** Check whether the string starts with a given prefix. + size_t Find(const CString& s, CaseSensitivity cs = CaseInsensitive) const; + /** Check whether the string starts with a given prefix. * @param sPrefix The prefix. * @param cs CaseSensitive if you want the comparison to be case * sensitive, CaseInsensitive (default) otherwise. * @return True if the string starts with prefix, false otherwise. */ - bool StartsWith(const CString& sPrefix, - CaseSensitivity cs = CaseInsensitive) const; - /** Check whether the string ends with a given suffix. + bool StartsWith(const CString& sPrefix, + CaseSensitivity cs = CaseInsensitive) const; + /** Check whether the string ends with a given suffix. * @param sSuffix The suffix. * @param cs CaseSensitive if you want the comparison to be case * sensitive, CaseInsensitive (default) otherwise. * @return True if the string ends with suffix, false otherwise. */ - bool EndsWith(const CString& sSuffix, - CaseSensitivity cs = CaseInsensitive) const; - /** + bool EndsWith(const CString& sSuffix, + CaseSensitivity cs = CaseInsensitive) const; + /** * Check whether the string contains a given string. * @param s The string to search. * @param bCaseSensitive Whether the search is case sensitive. * @return True if this string contains the other string, falser otherwise. */ - bool Contains(const CString& s, CaseSensitivity cs = CaseInsensitive) const; + bool Contains(const CString& s, CaseSensitivity cs = CaseInsensitive) const; - /** Remove characters from the beginning of this string. + /** Remove characters from the beginning of this string. * @param uLen The number of characters to remove. * @return true if this string was modified. */ - bool LeftChomp(size_type uLen = 1); - /** Remove characters from the end of this string. + bool LeftChomp(size_type uLen = 1); + /** Remove characters from the end of this string. * @param uLen The number of characters to remove. * @return true if this string was modified. */ - bool RightChomp(size_type uLen = 1); - /** Remove characters from the beginning of this string. + bool RightChomp(size_type uLen = 1); + /** Remove characters from the beginning of this string. * This string object isn't modified. * @param uLen The number of characters to remove. * @return The result of the conversion. */ - CString LeftChomp_n(size_type uLen = 1) const; - /** Remove characters from the end of this string. + CString LeftChomp_n(size_type uLen = 1) const; + /** Remove characters from the end of this string. * This string object isn't modified. * @param uLen The number of characters to remove. * @return The result of the conversion. */ - CString RightChomp_n(size_type uLen = 1) const; - /** Remove controls characters from this string. + CString RightChomp_n(size_type uLen = 1) const; + /** Remove controls characters from this string. * Controls characters are color codes, and those in C0 set * See https://en.wikipedia.org/wiki/C0_and_C1_control_codes * @return The result of the conversion. */ - CString& StripControls(); - /** Remove controls characters from this string. + CString& StripControls(); + /** Remove controls characters from this string. * Controls characters are color codes, and those in C0 set * See https://en.wikipedia.org/wiki/C0_and_C1_control_codes * This string object isn't modified. * @return The result of the conversion. */ - CString StripControls_n() const; + CString StripControls_n() const; private: protected: - unsigned char* strnchr(const unsigned char* src, unsigned char c, - unsigned int iMaxBytes, - unsigned char* pFill = nullptr, - unsigned int* piCount = nullptr) const; + unsigned char* strnchr(const unsigned char* src, unsigned char c, + unsigned int iMaxBytes, + unsigned char* pFill = nullptr, + unsigned int* piCount = nullptr) const; }; /** @@ -594,73 +594,73 @@ class CString : public std::string { */ class MCString : public std::map { public: - /** Construct an empty MCString. */ - MCString() : std::map() {} - /** Construct a MCString using an initializer list eg. MCString m = { {"key1", "val1"}, {"key2", "val2"} }; */ - MCString(std::initializer_list> list) - : std::map(list) {} - /** Destruct this MCString. */ - virtual ~MCString() { clear(); } + /** Construct an empty MCString. */ + MCString() : std::map() {} + /** Construct a MCString using an initializer list eg. MCString m = { {"key1", "val1"}, {"key2", "val2"} }; */ + MCString(std::initializer_list> list) + : std::map(list) {} + /** Destruct this MCString. */ + virtual ~MCString() { clear(); } - /** A static instance of an empty map. */ - static const MCString EmptyMap; + /** A static instance of an empty map. */ + static const MCString EmptyMap; - /** Status codes that can be returned by WriteToDisk() and + /** Status codes that can be returned by WriteToDisk() and * ReadFromDisk(). */ - enum status_t { - /// No errors. - MCS_SUCCESS = 0, - /// Opening the file failed. - MCS_EOPEN = 1, - /// Writing to the file failed. - MCS_EWRITE = 2, - /// WriteFilter() failed. - MCS_EWRITEFIL = 3, - /// ReadFilter() failed. - MCS_EREADFIL = 4 - }; + enum status_t { + /// No errors. + MCS_SUCCESS = 0, + /// Opening the file failed. + MCS_EOPEN = 1, + /// Writing to the file failed. + MCS_EWRITE = 2, + /// WriteFilter() failed. + MCS_EWRITEFIL = 3, + /// ReadFilter() failed. + MCS_EREADFIL = 4 + }; - /** Write this map to a file. + /** Write this map to a file. * @param sPath The file name to write to. * @param iMode The mode for the file. * @return The result of the operation. * @see WriteFilter. */ - enum status_t WriteToDisk(const CString& sPath, mode_t iMode = 0644) const; - /** Read a map from a file. + enum status_t WriteToDisk(const CString& sPath, mode_t iMode = 0644) const; + /** Read a map from a file. * @param sPath The file name to read from. * @return The result of the operation. * @see ReadFilter. */ - enum status_t ReadFromDisk(const CString& sPath); + enum status_t ReadFromDisk(const CString& sPath); - /** Filter used while writing this map. This function is called by + /** Filter used while writing this map. This function is called by * WriteToDisk() for each pair that is going to be written. This * function has the chance to modify the data that will be written. * @param sKey The key that will be written. Can be modified. * @param sValue The value that will be written. Can be modified. * @return true unless WriteToDisk() should fail with MCS_EWRITEFIL. */ - virtual bool WriteFilter(CString& sKey, CString& sValue) const { - return true; - } - /** Filter used while reading this map. This function is called by + virtual bool WriteFilter(CString& sKey, CString& sValue) const { + return true; + } + /** Filter used while reading this map. This function is called by * ReadFromDisk() for each pair that is beging read. This function has * the chance to modify the data that is being read. * @param sKey The key that was read. Can be modified. * @param sValue The value that was read. Can be modified. * @return true unless ReadFromDisk() should fail with MCS_EWRITEFIL. */ - virtual bool ReadFilter(CString& sKey, CString& sValue) const { - return true; - } + virtual bool ReadFilter(CString& sKey, CString& sValue) const { + return true; + } - /** Encode a value so that it can safely be parsed by ReadFromDisk(). + /** Encode a value so that it can safely be parsed by ReadFromDisk(). * This is an internal function. */ - virtual CString& Encode(CString& sValue) const; - /** Undo the effects of Encode(). This is an internal function. */ - virtual CString& Decode(CString& sValue) const; + virtual CString& Encode(CString& sValue) const; + /** Undo the effects of Encode(). This is an internal function. */ + virtual CString& Decode(CString& sValue) const; }; #endif // !ZNCSTRING_H diff --git a/include/znc/defines.h b/include/znc/defines.h index b63d6cca..bfe223cc 100644 --- a/include/znc/defines.h +++ b/include/znc/defines.h @@ -34,7 +34,7 @@ // Redefine some Csocket debugging mechanisms to use ZNC's #define CS_DEBUG(f) DEBUG(__FILE__ << ":" << __LINE__ << " " << f) #define PERROR(f) \ - DEBUG(__FILE__ << ":" << __LINE__ << " " << f << ": " \ - << strerror(GetSockError())) + DEBUG(__FILE__ << ":" << __LINE__ << " " << f << ": " \ + << strerror(GetSockError())) #endif // !ZNC_DEFINES_H diff --git a/include/znc/main.h b/include/znc/main.h index 04a001c4..29fd7fad 100644 --- a/include/znc/main.h +++ b/include/znc/main.h @@ -24,106 +24,106 @@ extern bool ZNC_NO_NEED_TO_DO_ANYTHING_ON_MODULE_CALL_EXITER; #define NOTHING &ZNC_NO_NEED_TO_DO_ANYTHING_ON_MODULE_CALL_EXITER #define ALLMODULECALL(macFUNC, macEXITER) \ - do { \ - CModules& GMods = CZNC::Get().GetModules(); \ - bool bAllExit = false; \ - if (GMods.macFUNC) { \ - bAllExit = true; \ - } else { \ - const map& mUsers = CZNC::Get().GetUserMap(); \ - map::const_iterator it; \ - for (it = mUsers.begin(); it != mUsers.end(); ++it) { \ - CModules& UMods = it->second->GetModules(); \ - if (UMods.macFUNC) { \ - bAllExit = true; \ - break; \ - } \ - const vector& mNets = it->second->GetNetworks(); \ - vector::const_iterator it2; \ - for (it2 = mNets.begin(); it2 != mNets.end(); ++it2) { \ - CModules& NMods = (*it2)->GetModules(); \ - if (NMods.macFUNC) { \ - bAllExit = true; \ - break; \ - } \ - } \ - if (bAllExit) break; \ - } \ - } \ - if (bAllExit) *macEXITER = true; \ - } while (false) + do { \ + CModules& GMods = CZNC::Get().GetModules(); \ + bool bAllExit = false; \ + if (GMods.macFUNC) { \ + bAllExit = true; \ + } else { \ + const map& mUsers = CZNC::Get().GetUserMap(); \ + map::const_iterator it; \ + for (it = mUsers.begin(); it != mUsers.end(); ++it) { \ + CModules& UMods = it->second->GetModules(); \ + if (UMods.macFUNC) { \ + bAllExit = true; \ + break; \ + } \ + const vector& mNets = it->second->GetNetworks(); \ + vector::const_iterator it2; \ + for (it2 = mNets.begin(); it2 != mNets.end(); ++it2) { \ + CModules& NMods = (*it2)->GetModules(); \ + if (NMods.macFUNC) { \ + bAllExit = true; \ + break; \ + } \ + } \ + if (bAllExit) break; \ + } \ + } \ + if (bAllExit) *macEXITER = true; \ + } while (false) #define _GLOBALMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \ - do { \ - CModules& GMods = CZNC::Get().GetModules(); \ - CUser* pOldGUser = GMods.GetUser(); \ - CIRCNetwork* pOldGNetwork = GMods.GetNetwork(); \ - CClient* pOldGClient = GMods.GetClient(); \ - GMods.SetUser(macUSER); \ - GMods.SetNetwork(macNETWORK); \ - GMods.SetClient(macCLIENT); \ - if (GMods.macFUNC) { \ - GMods.SetUser(pOldGUser); \ - GMods.SetNetwork(pOldGNetwork); \ - GMods.SetClient(pOldGClient); \ - *macEXITER = true; \ - } \ - GMods.SetUser(pOldGUser); \ - GMods.SetNetwork(pOldGNetwork); \ - GMods.SetClient(pOldGClient); \ - } while (false) + do { \ + CModules& GMods = CZNC::Get().GetModules(); \ + CUser* pOldGUser = GMods.GetUser(); \ + CIRCNetwork* pOldGNetwork = GMods.GetNetwork(); \ + CClient* pOldGClient = GMods.GetClient(); \ + GMods.SetUser(macUSER); \ + GMods.SetNetwork(macNETWORK); \ + GMods.SetClient(macCLIENT); \ + if (GMods.macFUNC) { \ + GMods.SetUser(pOldGUser); \ + GMods.SetNetwork(pOldGNetwork); \ + GMods.SetClient(pOldGClient); \ + *macEXITER = true; \ + } \ + GMods.SetUser(pOldGUser); \ + GMods.SetNetwork(pOldGNetwork); \ + GMods.SetClient(pOldGClient); \ + } while (false) #define _USERMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \ - do { \ - bool bGlobalExited = false; \ - _GLOBALMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, \ - &bGlobalExited); \ - if (bGlobalExited) { \ - *macEXITER = true; \ - break; \ - } \ - if (macUSER != nullptr) { \ - CModules& UMods = macUSER->GetModules(); \ - CIRCNetwork* pOldUNetwork = UMods.GetNetwork(); \ - CClient* pOldUClient = UMods.GetClient(); \ - UMods.SetNetwork(macNETWORK); \ - UMods.SetClient(macCLIENT); \ - if (UMods.macFUNC) { \ - UMods.SetNetwork(pOldUNetwork); \ - UMods.SetClient(pOldUClient); \ - *macEXITER = true; \ - } \ - UMods.SetNetwork(pOldUNetwork); \ - UMods.SetClient(pOldUClient); \ - } \ - } while (false) + do { \ + bool bGlobalExited = false; \ + _GLOBALMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, \ + &bGlobalExited); \ + if (bGlobalExited) { \ + *macEXITER = true; \ + break; \ + } \ + if (macUSER != nullptr) { \ + CModules& UMods = macUSER->GetModules(); \ + CIRCNetwork* pOldUNetwork = UMods.GetNetwork(); \ + CClient* pOldUClient = UMods.GetClient(); \ + UMods.SetNetwork(macNETWORK); \ + UMods.SetClient(macCLIENT); \ + if (UMods.macFUNC) { \ + UMods.SetNetwork(pOldUNetwork); \ + UMods.SetClient(pOldUClient); \ + *macEXITER = true; \ + } \ + UMods.SetNetwork(pOldUNetwork); \ + UMods.SetClient(pOldUClient); \ + } \ + } while (false) #define NETWORKMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \ - do { \ - bool bUserExited = false; \ - _USERMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, \ - &bUserExited); \ - if (bUserExited) { \ - *macEXITER = true; \ - break; \ - } \ - if (macNETWORK != nullptr) { \ - CModules& NMods = macNETWORK->GetModules(); \ - CClient* pOldNClient = NMods.GetClient(); \ - NMods.SetClient(macCLIENT); \ - if (NMods.macFUNC) { \ - NMods.SetClient(pOldNClient); \ - *macEXITER = true; \ - } \ - NMods.SetClient(pOldNClient); \ - } \ - } while (false) + do { \ + bool bUserExited = false; \ + _USERMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, \ + &bUserExited); \ + if (bUserExited) { \ + *macEXITER = true; \ + break; \ + } \ + if (macNETWORK != nullptr) { \ + CModules& NMods = macNETWORK->GetModules(); \ + CClient* pOldNClient = NMods.GetClient(); \ + NMods.SetClient(macCLIENT); \ + if (NMods.macFUNC) { \ + NMods.SetClient(pOldNClient); \ + *macEXITER = true; \ + } \ + NMods.SetClient(pOldNClient); \ + } \ + } while (false) #define GLOBALMODULECALL(macFUNC, macEXITER) \ - _GLOBALMODULECALL(macFUNC, nullptr, nullptr, nullptr, macEXITER) + _GLOBALMODULECALL(macFUNC, nullptr, nullptr, nullptr, macEXITER) #define USERMODULECALL(macFUNC, macUSER, macCLIENT, macEXITER) \ - _USERMODULECALL(macFUNC, macUSER, nullptr, macCLIENT, macEXITER) + _USERMODULECALL(macFUNC, macUSER, nullptr, macCLIENT, macEXITER) /** @mainpage * Welcome to the API documentation for ZNC. diff --git a/include/znc/znc.h b/include/znc/znc.h index 25c114c5..30a8b200 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -35,263 +35,263 @@ class CFile; class CZNC { public: - CZNC(); - ~CZNC(); + CZNC(); + ~CZNC(); - CZNC(const CZNC&) = delete; - CZNC& operator=(const CZNC&) = delete; + CZNC(const CZNC&) = delete; + CZNC& operator=(const CZNC&) = delete; - enum ConfigState { - ECONFIG_NOTHING, - ECONFIG_NEED_REHASH, - ECONFIG_NEED_WRITE, - ECONFIG_NEED_VERBOSE_WRITE, - ECONFIG_NEED_QUIT, // Not really config... - }; + enum ConfigState { + ECONFIG_NOTHING, + ECONFIG_NEED_REHASH, + ECONFIG_NEED_WRITE, + ECONFIG_NEED_VERBOSE_WRITE, + ECONFIG_NEED_QUIT, // Not really config... + }; - void DeleteUsers(); - void Loop(); - bool WritePidFile(int iPid); - bool DeletePidFile(); - bool WaitForChildLock(); - bool IsHostAllowed(const CString& sHostMask) const; - // This returns false if there are too many anonymous connections from this - // ip - bool AllowConnectionFrom(const CString& sIP) const; - void InitDirs(const CString& sArgvPath, const CString& sDataDir); - bool OnBoot(); - CString ExpandConfigPath(const CString& sConfigFile, - bool bAllowMkDir = true); - bool WriteNewConfig(const CString& sConfigFile); - bool WriteConfig(); - bool ParseConfig(const CString& sConfig, CString& sError); - bool RehashConfig(CString& sError); - void BackupConfigOnce(const CString& sSuffix); - static CString GetVersion(); - static CString GetTag(bool bIncludeVersion = true, bool bHTML = false); - static CString GetCompileOptionsString(); - CString GetUptime() const; - /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ - void ClearBindHosts() {} - /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ - bool AddBindHost(const CString& sHost) { return false; } - /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ - bool RemBindHost(const CString& sHost) { return false; } - void ClearTrustedProxies(); - bool AddTrustedProxy(const CString& sHost); - bool RemTrustedProxy(const CString& sHost); - void Broadcast(const CString& sMessage, bool bAdminOnly = false, - CUser* pSkipUser = nullptr, CClient* pSkipClient = nullptr); - void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } - void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } - unsigned long long BytesRead() const { return m_uBytesRead; } - unsigned long long BytesWritten() const { return m_uBytesWritten; } + void DeleteUsers(); + void Loop(); + bool WritePidFile(int iPid); + bool DeletePidFile(); + bool WaitForChildLock(); + bool IsHostAllowed(const CString& sHostMask) const; + // This returns false if there are too many anonymous connections from this + // ip + bool AllowConnectionFrom(const CString& sIP) const; + void InitDirs(const CString& sArgvPath, const CString& sDataDir); + bool OnBoot(); + CString ExpandConfigPath(const CString& sConfigFile, + bool bAllowMkDir = true); + bool WriteNewConfig(const CString& sConfigFile); + bool WriteConfig(); + bool ParseConfig(const CString& sConfig, CString& sError); + bool RehashConfig(CString& sError); + void BackupConfigOnce(const CString& sSuffix); + static CString GetVersion(); + static CString GetTag(bool bIncludeVersion = true, bool bHTML = false); + static CString GetCompileOptionsString(); + CString GetUptime() const; + /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ + void ClearBindHosts() {} + /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ + bool AddBindHost(const CString& sHost) { return false; } + /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ + bool RemBindHost(const CString& sHost) { return false; } + void ClearTrustedProxies(); + bool AddTrustedProxy(const CString& sHost); + bool RemTrustedProxy(const CString& sHost); + void Broadcast(const CString& sMessage, bool bAdminOnly = false, + CUser* pSkipUser = nullptr, CClient* pSkipClient = nullptr); + void AddBytesRead(unsigned long long u) { m_uBytesRead += u; } + void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } + unsigned long long BytesRead() const { return m_uBytesRead; } + unsigned long long BytesWritten() const { return m_uBytesWritten; } - // Traffic fun - typedef std::pair TrafficStatsPair; - typedef std::map TrafficStatsMap; - // Returns a map which maps user names to - // while also providing the traffic of all users together, traffic which - // couldn't be accounted to any particular user and the total traffic - // generated through ZNC. - TrafficStatsMap GetTrafficStats(TrafficStatsPair& Users, - TrafficStatsPair& ZNC, - TrafficStatsPair& Total); - TrafficStatsMap GetNetworkTrafficStats(const CString& sUsername, - TrafficStatsPair& Total); + // Traffic fun + typedef std::pair TrafficStatsPair; + typedef std::map TrafficStatsMap; + // Returns a map which maps user names to + // while also providing the traffic of all users together, traffic which + // couldn't be accounted to any particular user and the total traffic + // generated through ZNC. + TrafficStatsMap GetTrafficStats(TrafficStatsPair& Users, + TrafficStatsPair& ZNC, + TrafficStatsPair& Total); + TrafficStatsMap GetNetworkTrafficStats(const CString& sUsername, + TrafficStatsPair& Total); - // Authenticate a user. - // The result is passed back via callbacks to CAuthBase. - void AuthUser(std::shared_ptr AuthClass); + // Authenticate a user. + // The result is passed back via callbacks to CAuthBase. + void AuthUser(std::shared_ptr AuthClass); - // Setters - void SetConfigState(enum ConfigState e) { - std::lock_guard guard(m_mutexConfigState); - m_eConfigState = e; - } - void SetSkinName(const CString& s) { m_sSkinName = s; } - void SetStatusPrefix(const CString& s) { - m_sStatusPrefix = (s.empty()) ? "*" : s; - } - void SetMaxBufferSize(unsigned int i) { m_uiMaxBufferSize = i; } - void SetAnonIPLimit(unsigned int i) { m_uiAnonIPLimit = i; } - void SetServerThrottle(unsigned int i) { - m_sConnectThrottle.SetTTL(i * 1000); - } - void SetProtectWebSessions(bool b) { m_bProtectWebSessions = b; } - void SetHideVersion(bool b) { m_bHideVersion = b; } - void SetConnectDelay(unsigned int i); - void SetSSLCiphers(const CString& sCiphers) { m_sSSLCiphers = sCiphers; } - bool SetSSLProtocols(const CString& sProtocols); - void SetSSLCertFile(const CString& sFile) { m_sSSLCertFile = sFile; } - // !Setters + // Setters + void SetConfigState(enum ConfigState e) { + std::lock_guard guard(m_mutexConfigState); + m_eConfigState = e; + } + void SetSkinName(const CString& s) { m_sSkinName = s; } + void SetStatusPrefix(const CString& s) { + m_sStatusPrefix = (s.empty()) ? "*" : s; + } + void SetMaxBufferSize(unsigned int i) { m_uiMaxBufferSize = i; } + void SetAnonIPLimit(unsigned int i) { m_uiAnonIPLimit = i; } + void SetServerThrottle(unsigned int i) { + m_sConnectThrottle.SetTTL(i * 1000); + } + void SetProtectWebSessions(bool b) { m_bProtectWebSessions = b; } + void SetHideVersion(bool b) { m_bHideVersion = b; } + void SetConnectDelay(unsigned int i); + void SetSSLCiphers(const CString& sCiphers) { m_sSSLCiphers = sCiphers; } + bool SetSSLProtocols(const CString& sProtocols); + void SetSSLCertFile(const CString& sFile) { m_sSSLCertFile = sFile; } + // !Setters - // Getters - enum ConfigState GetConfigState() { - std::lock_guard guard(m_mutexConfigState); - return m_eConfigState; - } - CSockManager& GetManager() { return m_Manager; } - const CSockManager& GetManager() const { return m_Manager; } - CModules& GetModules() { return *m_pModules; } - CString GetSkinName() const { return m_sSkinName; } - const CString& GetStatusPrefix() const { return m_sStatusPrefix; } - const CString& GetCurPath() const; - const CString& GetHomePath() const; - const CString& GetZNCPath() const; - CString GetConfPath(bool bAllowMkDir = true) const; - CString GetUserPath() const; - CString GetModPath() const; - CString GetPemLocation() const; - CString GetKeyLocation() const; - CString GetDHParamLocation() const; - const CString& GetConfigFile() const { return m_sConfigFile; } - bool WritePemFile(); - /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ - const VCString& GetBindHosts() const { return m_vsBindHosts; } - const VCString& GetTrustedProxies() const { return m_vsTrustedProxies; } - const std::vector& GetListeners() const { - return m_vpListeners; - } - time_t TimeStarted() const { return m_TimeStarted; } - unsigned int GetMaxBufferSize() const { return m_uiMaxBufferSize; } - unsigned int GetAnonIPLimit() const { return m_uiAnonIPLimit; } - unsigned int GetServerThrottle() const { - return m_sConnectThrottle.GetTTL() / 1000; - } - unsigned int GetConnectDelay() const { return m_uiConnectDelay; } - bool GetProtectWebSessions() const { return m_bProtectWebSessions; } - bool GetHideVersion() const { return m_bHideVersion; } - CString GetSSLCiphers() const { return m_sSSLCiphers; } - CString GetSSLProtocols() const { return m_sSSLProtocols; } - Csock::EDisableProtocol GetDisabledSSLProtocols() const { - return static_cast(m_uDisabledSSLProtocols); - } - CString GetSSLCertFile() const { return m_sSSLCertFile; } - static VCString GetAvailableSSLProtocols(); - // !Getters + // Getters + enum ConfigState GetConfigState() { + std::lock_guard guard(m_mutexConfigState); + return m_eConfigState; + } + CSockManager& GetManager() { return m_Manager; } + const CSockManager& GetManager() const { return m_Manager; } + CModules& GetModules() { return *m_pModules; } + CString GetSkinName() const { return m_sSkinName; } + const CString& GetStatusPrefix() const { return m_sStatusPrefix; } + const CString& GetCurPath() const; + const CString& GetHomePath() const; + const CString& GetZNCPath() const; + CString GetConfPath(bool bAllowMkDir = true) const; + CString GetUserPath() const; + CString GetModPath() const; + CString GetPemLocation() const; + CString GetKeyLocation() const; + CString GetDHParamLocation() const; + const CString& GetConfigFile() const { return m_sConfigFile; } + bool WritePemFile(); + /** @deprecated Since 1.7.0. List of allowed bind hosts was a flawed design. */ + const VCString& GetBindHosts() const { return m_vsBindHosts; } + const VCString& GetTrustedProxies() const { return m_vsTrustedProxies; } + const std::vector& GetListeners() const { + return m_vpListeners; + } + time_t TimeStarted() const { return m_TimeStarted; } + unsigned int GetMaxBufferSize() const { return m_uiMaxBufferSize; } + unsigned int GetAnonIPLimit() const { return m_uiAnonIPLimit; } + unsigned int GetServerThrottle() const { + return m_sConnectThrottle.GetTTL() / 1000; + } + unsigned int GetConnectDelay() const { return m_uiConnectDelay; } + bool GetProtectWebSessions() const { return m_bProtectWebSessions; } + bool GetHideVersion() const { return m_bHideVersion; } + CString GetSSLCiphers() const { return m_sSSLCiphers; } + CString GetSSLProtocols() const { return m_sSSLProtocols; } + Csock::EDisableProtocol GetDisabledSSLProtocols() const { + return static_cast(m_uDisabledSSLProtocols); + } + CString GetSSLCertFile() const { return m_sSSLCertFile; } + static VCString GetAvailableSSLProtocols(); + // !Getters - // Static allocator - static void CreateInstance(); - static CZNC& Get(); - static void DestroyInstance(); - CUser* FindUser(const CString& sUsername); - CModule* FindModule(const CString& sModName, const CString& sUsername); - CModule* FindModule(const CString& sModName, CUser* pUser); + // Static allocator + static void CreateInstance(); + static CZNC& Get(); + static void DestroyInstance(); + CUser* FindUser(const CString& sUsername); + CModule* FindModule(const CString& sModName, const CString& sUsername); + CModule* FindModule(const CString& sModName, CUser* pUser); - /** Reload a module everywhere + /** Reload a module everywhere * * This method will unload a module globally, for a user and for each * network. It will then reload them all again. * * @param sModule The name of the module to reload */ - bool UpdateModule(const CString& sModule); + bool UpdateModule(const CString& sModule); - bool DeleteUser(const CString& sUsername); - bool AddUser(CUser* pUser, CString& sErrorRet, bool bStartup = false); - const std::map& GetUserMap() const { return (m_msUsers); } + bool DeleteUser(const CString& sUsername); + bool AddUser(CUser* pUser, CString& sErrorRet, bool bStartup = false); + const std::map& GetUserMap() const { return (m_msUsers); } - // Listener yummy - CListener* FindListener(u_short uPort, const CString& BindHost, - EAddrType eAddr); - bool AddListener(CListener*); - bool AddListener(unsigned short uPort, const CString& sBindHost, - const CString& sURIPrefix, bool bSSL, EAddrType eAddr, - CListener::EAcceptType eAccept, CString& sError); - bool DelListener(CListener*); + // Listener yummy + CListener* FindListener(u_short uPort, const CString& BindHost, + EAddrType eAddr); + bool AddListener(CListener*); + bool AddListener(unsigned short uPort, const CString& sBindHost, + const CString& sURIPrefix, bool bSSL, EAddrType eAddr, + CListener::EAcceptType eAccept, CString& sError); + bool DelListener(CListener*); - // Message of the Day - void SetMotd(const CString& sMessage) { - ClearMotd(); - AddMotd(sMessage); - } - void AddMotd(const CString& sMessage) { - if (!sMessage.empty()) { - m_vsMotd.push_back(sMessage); - } - } - void ClearMotd() { m_vsMotd.clear(); } - const VCString& GetMotd() const { return m_vsMotd; } - // !MOTD + // Message of the Day + void SetMotd(const CString& sMessage) { + ClearMotd(); + AddMotd(sMessage); + } + void AddMotd(const CString& sMessage) { + if (!sMessage.empty()) { + m_vsMotd.push_back(sMessage); + } + } + void ClearMotd() { m_vsMotd.clear(); } + const VCString& GetMotd() const { return m_vsMotd; } + // !MOTD - void AddServerThrottle(CString sName) { - m_sConnectThrottle.AddItem(sName, true); - } - bool GetServerThrottle(CString sName) { - bool* b = m_sConnectThrottle.GetItem(sName); - return (b && *b); - } + void AddServerThrottle(CString sName) { + m_sConnectThrottle.AddItem(sName, true); + } + bool GetServerThrottle(CString sName) { + bool* b = m_sConnectThrottle.GetItem(sName); + return (b && *b); + } - void AddNetworkToQueue(CIRCNetwork* pNetwork); - std::list& GetConnectionQueue() { return m_lpConnectQueue; } + void AddNetworkToQueue(CIRCNetwork* pNetwork); + std::list& GetConnectionQueue() { return m_lpConnectQueue; } - // This creates a CConnectQueueTimer if we haven't got one yet - void EnableConnectQueue(); - void DisableConnectQueue(); + // This creates a CConnectQueueTimer if we haven't got one yet + void EnableConnectQueue(); + void DisableConnectQueue(); - void PauseConnectQueue(); - void ResumeConnectQueue(); + void PauseConnectQueue(); + void ResumeConnectQueue(); - // Never call this unless you are CConnectQueueTimer::~CConnectQueueTimer() - void LeakConnectQueueTimer(CConnectQueueTimer* pTimer); + // Never call this unless you are CConnectQueueTimer::~CConnectQueueTimer() + void LeakConnectQueueTimer(CConnectQueueTimer* pTimer); - static void DumpConfig(const CConfig* Config); + static void DumpConfig(const CConfig* Config); private: - CFile* InitPidFile(); + CFile* InitPidFile(); - bool ReadConfig(CConfig& config, CString& sError); - bool LoadGlobal(CConfig& config, CString& sError); - bool LoadUsers(CConfig& config, CString& sError); - bool LoadListeners(CConfig& config, CString& sError); - void UnloadRemovedModules(const MCString& msModules); + bool ReadConfig(CConfig& config, CString& sError); + bool LoadGlobal(CConfig& config, CString& sError); + bool LoadUsers(CConfig& config, CString& sError); + bool LoadListeners(CConfig& config, CString& sError); + void UnloadRemovedModules(const MCString& msModules); - bool HandleUserDeletion(); - CString MakeConfigHeader(); - bool AddListener(const CString& sLine, CString& sError); - bool AddListener(CConfig* pConfig, CString& sError); + bool HandleUserDeletion(); + CString MakeConfigHeader(); + bool AddListener(const CString& sLine, CString& sError); + bool AddListener(CConfig* pConfig, CString& sError); protected: - time_t m_TimeStarted; + time_t m_TimeStarted; - enum ConfigState m_eConfigState; - std::mutex m_mutexConfigState; + enum ConfigState m_eConfigState; + std::mutex m_mutexConfigState; - std::vector m_vpListeners; - std::map m_msUsers; - std::map m_msDelUsers; - CSockManager m_Manager; + std::vector m_vpListeners; + std::map m_msUsers; + std::map m_msDelUsers; + CSockManager m_Manager; - CString m_sCurPath; - CString m_sZNCPath; + CString m_sCurPath; + CString m_sZNCPath; - CString m_sConfigFile; - CString m_sSkinName; - CString m_sStatusPrefix; - CString m_sPidFile; - CString m_sSSLCertFile; - CString m_sSSLKeyFile; - CString m_sSSLDHParamFile; - CString m_sSSLCiphers; - CString m_sSSLProtocols; - VCString m_vsBindHosts; // TODO: remove (deprecated in 1.7.0) - VCString m_vsTrustedProxies; - VCString m_vsMotd; - CFile* m_pLockFile; - unsigned int m_uiConnectDelay; - unsigned int m_uiAnonIPLimit; - unsigned int m_uiMaxBufferSize; - unsigned int m_uDisabledSSLProtocols; - CModules* m_pModules; - unsigned long long m_uBytesRead; - unsigned long long m_uBytesWritten; - std::list m_lpConnectQueue; - CConnectQueueTimer* m_pConnectQueueTimer; - unsigned int m_uiConnectPaused; - TCacheMap m_sConnectThrottle; - bool m_bProtectWebSessions; - bool m_bHideVersion; + CString m_sConfigFile; + CString m_sSkinName; + CString m_sStatusPrefix; + CString m_sPidFile; + CString m_sSSLCertFile; + CString m_sSSLKeyFile; + CString m_sSSLDHParamFile; + CString m_sSSLCiphers; + CString m_sSSLProtocols; + VCString m_vsBindHosts; // TODO: remove (deprecated in 1.7.0) + VCString m_vsTrustedProxies; + VCString m_vsMotd; + CFile* m_pLockFile; + unsigned int m_uiConnectDelay; + unsigned int m_uiAnonIPLimit; + unsigned int m_uiMaxBufferSize; + unsigned int m_uDisabledSSLProtocols; + CModules* m_pModules; + unsigned long long m_uBytesRead; + unsigned long long m_uBytesWritten; + std::list m_lpConnectQueue; + CConnectQueueTimer* m_pConnectQueueTimer; + unsigned int m_uiConnectPaused; + TCacheMap m_sConnectThrottle; + bool m_bProtectWebSessions; + bool m_bHideVersion; }; #endif // !ZNC_H diff --git a/modules/adminlog.cpp b/modules/adminlog.cpp index 06bcb5cf..d96670ca 100644 --- a/modules/adminlog.cpp +++ b/modules/adminlog.cpp @@ -24,202 +24,202 @@ class CAdminLogMod : public CModule { public: - MODCONSTRUCTOR(CAdminLogMod) { - AddHelpCommand(); - AddCommand("Show", static_cast( - &CAdminLogMod::OnShowCommand), - "", "Show the logging target"); - AddCommand("Target", static_cast( - &CAdminLogMod::OnTargetCommand), - " [path]", "Set the logging target"); - openlog("znc", LOG_PID, LOG_DAEMON); - } + MODCONSTRUCTOR(CAdminLogMod) { + AddHelpCommand(); + AddCommand("Show", static_cast( + &CAdminLogMod::OnShowCommand), + "", "Show the logging target"); + AddCommand("Target", static_cast( + &CAdminLogMod::OnTargetCommand), + " [path]", "Set the logging target"); + openlog("znc", LOG_PID, LOG_DAEMON); + } - virtual ~CAdminLogMod() { - Log("Logging ended."); - closelog(); - } + virtual ~CAdminLogMod() { + Log("Logging ended."); + closelog(); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - CString sTarget = GetNV("target"); - if (sTarget.Equals("syslog")) - m_eLogMode = LOG_TO_SYSLOG; - else if (sTarget.Equals("both")) - m_eLogMode = LOG_TO_BOTH; - else if (sTarget.Equals("file")) - m_eLogMode = LOG_TO_FILE; - else - m_eLogMode = LOG_TO_FILE; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + CString sTarget = GetNV("target"); + if (sTarget.Equals("syslog")) + m_eLogMode = LOG_TO_SYSLOG; + else if (sTarget.Equals("both")) + m_eLogMode = LOG_TO_BOTH; + else if (sTarget.Equals("file")) + m_eLogMode = LOG_TO_FILE; + else + m_eLogMode = LOG_TO_FILE; - SetLogFilePath(GetNV("path")); + SetLogFilePath(GetNV("path")); - Log("Logging started. ZNC PID[" + CString(getpid()) + "] UID/GID[" + - CString(getuid()) + ":" + CString(getgid()) + "]"); - return true; - } + Log("Logging started. ZNC PID[" + CString(getpid()) + "] UID/GID[" + + CString(getuid()) + ":" + CString(getgid()) + "]"); + return true; + } - void OnIRCConnected() override { - Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + - "] connected to IRC: " + - GetNetwork()->GetCurrentServer()->GetName()); - } + void OnIRCConnected() override { + Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + + "] connected to IRC: " + + GetNetwork()->GetCurrentServer()->GetName()); + } - void OnIRCDisconnected() override { - Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + - "] disconnected from IRC"); - } + void OnIRCDisconnected() override { + Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + + "] disconnected from IRC"); + } - EModRet OnRaw(CString& sLine) override { - if (sLine.StartsWith("ERROR ")) { - // ERROR :Closing Link: nick[24.24.24.24] (Excess Flood) - // ERROR :Closing Link: nick[24.24.24.24] Killer (Local kill by - // Killer (reason)) - CString sError(sLine.substr(6)); - if (sError.Left(1) == ":") sError.LeftChomp(); - Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + - "] disconnected from IRC: " + - GetNetwork()->GetCurrentServer()->GetName() + " [" + - sError + "]", - LOG_NOTICE); - } - return CONTINUE; - } + EModRet OnRaw(CString& sLine) override { + if (sLine.StartsWith("ERROR ")) { + // ERROR :Closing Link: nick[24.24.24.24] (Excess Flood) + // ERROR :Closing Link: nick[24.24.24.24] Killer (Local kill by + // Killer (reason)) + CString sError(sLine.substr(6)); + if (sError.Left(1) == ":") sError.LeftChomp(); + Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + + "] disconnected from IRC: " + + GetNetwork()->GetCurrentServer()->GetName() + " [" + + sError + "]", + LOG_NOTICE); + } + return CONTINUE; + } - void OnClientLogin() override { - Log("[" + GetUser()->GetUserName() + "] connected to ZNC from " + - GetClient()->GetRemoteIP()); - } + void OnClientLogin() override { + Log("[" + GetUser()->GetUserName() + "] connected to ZNC from " + + GetClient()->GetRemoteIP()); + } - void OnClientDisconnect() override { - Log("[" + GetUser()->GetUserName() + "] disconnected from ZNC from " + - GetClient()->GetRemoteIP()); - } + void OnClientDisconnect() override { + Log("[" + GetUser()->GetUserName() + "] disconnected from ZNC from " + + GetClient()->GetRemoteIP()); + } - void OnFailedLogin(const CString& sUsername, - const CString& sRemoteIP) override { - Log("[" + sUsername + "] failed to login from " + sRemoteIP, - LOG_WARNING); - } + void OnFailedLogin(const CString& sUsername, + const CString& sRemoteIP) override { + Log("[" + sUsername + "] failed to login from " + sRemoteIP, + LOG_WARNING); + } - void SetLogFilePath(CString sPath) { - if (sPath.empty()) { - sPath = GetSavePath() + "/znc.log"; - } + void SetLogFilePath(CString sPath) { + if (sPath.empty()) { + sPath = GetSavePath() + "/znc.log"; + } - CFile LogFile(sPath); - CString sLogDir = LogFile.GetDir(); - struct stat ModDirInfo; - CFile::GetInfo(GetSavePath(), ModDirInfo); - if (!CFile::Exists(sLogDir)) { - CDir::MakeDir(sLogDir, ModDirInfo.st_mode); - } + CFile LogFile(sPath); + CString sLogDir = LogFile.GetDir(); + struct stat ModDirInfo; + CFile::GetInfo(GetSavePath(), ModDirInfo); + if (!CFile::Exists(sLogDir)) { + CDir::MakeDir(sLogDir, ModDirInfo.st_mode); + } - m_sLogFile = sPath; - SetNV("path", sPath); - } + m_sLogFile = sPath; + SetNV("path", sPath); + } - void Log(CString sLine, int iPrio = LOG_INFO) { - if (m_eLogMode & LOG_TO_SYSLOG) syslog(iPrio, "%s", sLine.c_str()); + void Log(CString sLine, int iPrio = LOG_INFO) { + if (m_eLogMode & LOG_TO_SYSLOG) syslog(iPrio, "%s", sLine.c_str()); - if (m_eLogMode & LOG_TO_FILE) { - time_t curtime; - tm* timeinfo; - char buf[23]; + if (m_eLogMode & LOG_TO_FILE) { + time_t curtime; + tm* timeinfo; + char buf[23]; - time(&curtime); - timeinfo = localtime(&curtime); - strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S] ", timeinfo); + time(&curtime); + timeinfo = localtime(&curtime); + strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S] ", timeinfo); - CFile LogFile(m_sLogFile); + CFile LogFile(m_sLogFile); - if (LogFile.Open(O_WRONLY | O_APPEND | O_CREAT)) - LogFile.Write(buf + sLine + "\n"); - else - DEBUG("Failed to write to [" << m_sLogFile - << "]: " << strerror(errno)); - } - } + if (LogFile.Open(O_WRONLY | O_APPEND | O_CREAT)) + LogFile.Write(buf + sLine + "\n"); + else + DEBUG("Failed to write to [" << m_sLogFile + << "]: " << strerror(errno)); + } + } - void OnModCommand(const CString& sCommand) override { - if (!GetUser()->IsAdmin()) { - PutModule("Access denied"); - } else { - HandleCommand(sCommand); - } - } + void OnModCommand(const CString& sCommand) override { + if (!GetUser()->IsAdmin()) { + PutModule("Access denied"); + } else { + HandleCommand(sCommand); + } + } - void OnTargetCommand(const CString& sCommand) { - CString sArg = sCommand.Token(1, false); - CString sTarget; - CString sMessage; - LogMode mode; + void OnTargetCommand(const CString& sCommand) { + CString sArg = sCommand.Token(1, false); + CString sTarget; + CString sMessage; + LogMode mode; - if (sArg.Equals("file")) { - sTarget = "file"; - sMessage = "Now logging to file"; - mode = LOG_TO_FILE; - } else if (sArg.Equals("syslog")) { - sTarget = "syslog"; - sMessage = "Now only logging to syslog"; - mode = LOG_TO_SYSLOG; - } else if (sArg.Equals("both")) { - sTarget = "both"; - sMessage = "Now logging to syslog and file"; - mode = LOG_TO_BOTH; - } else { - if (sArg.empty()) { - PutModule("Usage: Target [path]"); - } else { - PutModule("Unknown target"); - } - return; - } + if (sArg.Equals("file")) { + sTarget = "file"; + sMessage = "Now logging to file"; + mode = LOG_TO_FILE; + } else if (sArg.Equals("syslog")) { + sTarget = "syslog"; + sMessage = "Now only logging to syslog"; + mode = LOG_TO_SYSLOG; + } else if (sArg.Equals("both")) { + sTarget = "both"; + sMessage = "Now logging to syslog and file"; + mode = LOG_TO_BOTH; + } else { + if (sArg.empty()) { + PutModule("Usage: Target [path]"); + } else { + PutModule("Unknown target"); + } + return; + } - if (mode != LOG_TO_SYSLOG) { - CString sPath = sCommand.Token(2, true); - SetLogFilePath(sPath); - sMessage += " [" + sPath + "]"; - } + if (mode != LOG_TO_SYSLOG) { + CString sPath = sCommand.Token(2, true); + SetLogFilePath(sPath); + sMessage += " [" + sPath + "]"; + } - Log(sMessage); - SetNV("target", sTarget); - m_eLogMode = mode; - PutModule(sMessage); - } + Log(sMessage); + SetNV("target", sTarget); + m_eLogMode = mode; + PutModule(sMessage); + } - void OnShowCommand(const CString& sCommand) { - CString sTarget; + void OnShowCommand(const CString& sCommand) { + CString sTarget; - switch (m_eLogMode) { - case LOG_TO_FILE: - sTarget = "file"; - break; - case LOG_TO_SYSLOG: - sTarget = "syslog"; - break; - case LOG_TO_BOTH: - sTarget = "both, file and syslog"; - break; - } + switch (m_eLogMode) { + case LOG_TO_FILE: + sTarget = "file"; + break; + case LOG_TO_SYSLOG: + sTarget = "syslog"; + break; + case LOG_TO_BOTH: + sTarget = "both, file and syslog"; + break; + } - PutModule("Logging is enabled for " + sTarget); - if (m_eLogMode != LOG_TO_SYSLOG) - PutModule("Log file will be written to [" + m_sLogFile + "]"); - } + PutModule("Logging is enabled for " + sTarget); + if (m_eLogMode != LOG_TO_SYSLOG) + PutModule("Log file will be written to [" + m_sLogFile + "]"); + } private: - enum LogMode { - LOG_TO_FILE = 1 << 0, - LOG_TO_SYSLOG = 1 << 1, - LOG_TO_BOTH = LOG_TO_FILE | LOG_TO_SYSLOG - }; - LogMode m_eLogMode = LOG_TO_FILE; - CString m_sLogFile; + enum LogMode { + LOG_TO_FILE = 1 << 0, + LOG_TO_SYSLOG = 1 << 1, + LOG_TO_BOTH = LOG_TO_FILE | LOG_TO_SYSLOG + }; + LogMode m_eLogMode = LOG_TO_FILE; + CString m_sLogFile; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("adminlog"); + Info.SetWikiPage("adminlog"); } GLOBALMODULEDEFS(CAdminLogMod, "Log ZNC events to file and/or syslog.") diff --git a/modules/alias.cpp b/modules/alias.cpp index d2fd0f62..bc1c70c4 100644 --- a/modules/alias.cpp +++ b/modules/alias.cpp @@ -27,374 +27,374 @@ using std::stringstream; class CAlias { private: - CModule* parent; - CString name; - VCString alias_cmds; + CModule* parent; + CString name; + VCString alias_cmds; public: - // getters/setters - const CString& GetName() const { return name; } + // getters/setters + const CString& GetName() const { return name; } - // name should be a single, all uppercase word - void SetName(const CString& newname) { - name = newname.Token(0, false, " "); - name.MakeUpper(); - } + // name should be a single, all uppercase word + void SetName(const CString& newname) { + name = newname.Token(0, false, " "); + name.MakeUpper(); + } - // combined getter/setter for command list - VCString& AliasCmds() { return alias_cmds; } + // combined getter/setter for command list + VCString& AliasCmds() { return alias_cmds; } - // check registry if alias exists - static bool AliasExists(CModule* module, CString alias_name) { - alias_name = alias_name.Token(0, false, " ").MakeUpper(); - return (module->FindNV(alias_name) != module->EndNV()); - } + // check registry if alias exists + static bool AliasExists(CModule* module, CString alias_name) { + alias_name = alias_name.Token(0, false, " ").MakeUpper(); + return (module->FindNV(alias_name) != module->EndNV()); + } - // populate alias from stored settings in registry, or return false if none - // exists - static bool AliasGet(CAlias& alias, CModule* module, CString line) { - line = line.Token(0, false, " ").MakeUpper(); - MCString::iterator i = module->FindNV(line); - if (i == module->EndNV()) return false; - alias.parent = module; - alias.name = line; - i->second.Split("\n", alias.alias_cmds, false); - return true; - } + // populate alias from stored settings in registry, or return false if none + // exists + static bool AliasGet(CAlias& alias, CModule* module, CString line) { + line = line.Token(0, false, " ").MakeUpper(); + MCString::iterator i = module->FindNV(line); + if (i == module->EndNV()) return false; + alias.parent = module; + alias.name = line; + i->second.Split("\n", alias.alias_cmds, false); + return true; + } - // constructors - CAlias() : parent(nullptr) {} - CAlias(CModule* new_parent, const CString& new_name) : parent(new_parent) { - SetName(new_name); - } + // constructors + CAlias() : parent(nullptr) {} + CAlias(CModule* new_parent, const CString& new_name) : parent(new_parent) { + SetName(new_name); + } - // produce a command string from this alias' command list - CString GetCommands() const { - return CString("\n").Join(alias_cmds.begin(), alias_cmds.end()); - } + // produce a command string from this alias' command list + CString GetCommands() const { + return CString("\n").Join(alias_cmds.begin(), alias_cmds.end()); + } - // write this alias to registry - void Commit() const { - if (!parent) return; - parent->SetNV(name, GetCommands()); - } + // write this alias to registry + void Commit() const { + if (!parent) return; + parent->SetNV(name, GetCommands()); + } - // delete this alias from regisrty - void Delete() const { - if (!parent) return; - parent->DelNV(name); - } + // delete this alias from regisrty + void Delete() const { + if (!parent) return; + parent->DelNV(name); + } private: - // this function helps imprint out. it checks if there is a substitution - // token at 'caret' in 'alias_data' - // and if it finds one, pulls the appropriate token out of 'line' and - // appends it to 'output', and updates 'caret'. - // 'skip' is updated based on the logic that we should skip the % at the - // caret if we fail to parse the token. - static void ParseToken(const CString& alias_data, const CString& line, - CString& output, size_t& caret, size_t& skip) { - bool optional = false; - bool subsequent = false; - size_t index = caret + 1; - int token = -1; + // this function helps imprint out. it checks if there is a substitution + // token at 'caret' in 'alias_data' + // and if it finds one, pulls the appropriate token out of 'line' and + // appends it to 'output', and updates 'caret'. + // 'skip' is updated based on the logic that we should skip the % at the + // caret if we fail to parse the token. + static void ParseToken(const CString& alias_data, const CString& line, + CString& output, size_t& caret, size_t& skip) { + bool optional = false; + bool subsequent = false; + size_t index = caret + 1; + int token = -1; - skip = 1; + skip = 1; - if (alias_data.length() > index && alias_data[index] == '?') { - optional = true; - ++index; - } // try to read optional flag - if (alias_data.length() > index && - CString(alias_data.substr(index)) - .Convert(&token)) // try to read integer - { - while (alias_data.length() > index && alias_data[index] >= '0' && - alias_data[index] <= '9') - ++index; - // skip any numeric digits in string (supposed to fail if - // whitespace precedes integer) - } else { - // token was malformed. leave caret unchanged, and flag first - // character for skipping - return; - } - if (alias_data.length() > index && alias_data[index] == '+') { - subsequent = true; - ++index; - } // try to read subsequent flag - if (alias_data.length() > index && alias_data[index] == '%') { - ++index; - } // try to read end-of-substitution marker - else - return; + if (alias_data.length() > index && alias_data[index] == '?') { + optional = true; + ++index; + } // try to read optional flag + if (alias_data.length() > index && + CString(alias_data.substr(index)) + .Convert(&token)) // try to read integer + { + while (alias_data.length() > index && alias_data[index] >= '0' && + alias_data[index] <= '9') + ++index; + // skip any numeric digits in string (supposed to fail if + // whitespace precedes integer) + } else { + // token was malformed. leave caret unchanged, and flag first + // character for skipping + return; + } + if (alias_data.length() > index && alias_data[index] == '+') { + subsequent = true; + ++index; + } // try to read subsequent flag + if (alias_data.length() > index && alias_data[index] == '%') { + ++index; + } // try to read end-of-substitution marker + else + return; - // if we get here, we're definitely dealing with a token, so get the - // token's value - CString stok = line.Token(token, subsequent, " "); + // if we get here, we're definitely dealing with a token, so get the + // token's value + CString stok = line.Token(token, subsequent, " "); - if (stok.empty() && !optional) - throw std::invalid_argument( - CString("missing required parameter: ") + - CString(token)); // blow up if token is required and also empty - output.append(stok); // write token value to output + if (stok.empty() && !optional) + throw std::invalid_argument( + CString("missing required parameter: ") + + CString(token)); // blow up if token is required and also empty + output.append(stok); // write token value to output - skip = 0; // since we're moving the cursor after the end of the token, - // skip no characters - caret = index; // advance the cursor forward by the size of the token - } + skip = 0; // since we're moving the cursor after the end of the token, + // skip no characters + caret = index; // advance the cursor forward by the size of the token + } public: - // read an IRC line and do token substitution - // throws an exception if a required parameter is missing, and might also - // throw if you manage to make it bork - CString Imprint(CString line) const { - CString output; - CString alias_data = GetCommands(); - alias_data = parent->ExpandString(alias_data); - size_t lastfound = 0, skip = 0; + // read an IRC line and do token substitution + // throws an exception if a required parameter is missing, and might also + // throw if you manage to make it bork + CString Imprint(CString line) const { + CString output; + CString alias_data = GetCommands(); + alias_data = parent->ExpandString(alias_data); + size_t lastfound = 0, skip = 0; - // it would be very inefficient to attempt to blindly replace every - // possible token - // so let's just parse the line and replace when we find them - // token syntax: - // %[?]n[+]% - // adding ? makes the substitution optional (you'll get "" if there are - // insufficient tokens, otherwise the alias will fail) - // adding + makes the substitution contain all tokens from the nth to - // the end of the line - while (true) { - // if (found >= (int) alias_data.length()) break; - // ^ shouldn't be possible. - size_t found = alias_data.find("%", lastfound + skip); - if (found == CString::npos) break; // if we found nothing, break - // capture everything between the last stopping point and here - output.append(alias_data.substr(lastfound, found - lastfound)); - // attempt to read a token, updates indices based on - // success/failure - ParseToken(alias_data, line, output, found, skip); - lastfound = found; - } + // it would be very inefficient to attempt to blindly replace every + // possible token + // so let's just parse the line and replace when we find them + // token syntax: + // %[?]n[+]% + // adding ? makes the substitution optional (you'll get "" if there are + // insufficient tokens, otherwise the alias will fail) + // adding + makes the substitution contain all tokens from the nth to + // the end of the line + while (true) { + // if (found >= (int) alias_data.length()) break; + // ^ shouldn't be possible. + size_t found = alias_data.find("%", lastfound + skip); + if (found == CString::npos) break; // if we found nothing, break + // capture everything between the last stopping point and here + output.append(alias_data.substr(lastfound, found - lastfound)); + // attempt to read a token, updates indices based on + // success/failure + ParseToken(alias_data, line, output, found, skip); + lastfound = found; + } - output += alias_data.substr(lastfound); // append from the final - return output; - } + output += alias_data.substr(lastfound); // append from the final + return output; + } }; class CAliasMod : public CModule { private: - bool sending_lines; + bool sending_lines; public: - void CreateCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - if (!CAlias::AliasExists(this, name)) { - CAlias na(this, name); - na.Commit(); - PutModule("Created alias: " + na.GetName()); - } else - PutModule("Alias already exists."); - } + void CreateCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + if (!CAlias::AliasExists(this, name)) { + CAlias na(this, name); + na.Commit(); + PutModule("Created alias: " + na.GetName()); + } else + PutModule("Alias already exists."); + } - void DeleteCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias delete_alias; - if (CAlias::AliasGet(delete_alias, this, name)) { - PutModule("Deleted alias: " + delete_alias.GetName()); - delete_alias.Delete(); - } else - PutModule("Alias does not exist."); - } + void DeleteCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias delete_alias; + if (CAlias::AliasGet(delete_alias, this, name)) { + PutModule("Deleted alias: " + delete_alias.GetName()); + delete_alias.Delete(); + } else + PutModule("Alias does not exist."); + } - void AddCmd(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias add_alias; - if (CAlias::AliasGet(add_alias, this, name)) { - add_alias.AliasCmds().push_back(sLine.Token(2, true, " ")); - add_alias.Commit(); - PutModule("Modified alias."); - } else - PutModule("Alias does not exist."); - } + void AddCmd(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias add_alias; + if (CAlias::AliasGet(add_alias, this, name)) { + add_alias.AliasCmds().push_back(sLine.Token(2, true, " ")); + add_alias.Commit(); + PutModule("Modified alias."); + } else + PutModule("Alias does not exist."); + } - void InsertCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias insert_alias; - int index; - if (CAlias::AliasGet(insert_alias, this, name)) { - // if Convert succeeds, then i has been successfully read from user - // input - if (!sLine.Token(2, false, " ").Convert(&index) || index < 0 || - index > (int)insert_alias.AliasCmds().size()) { - PutModule("Invalid index."); - return; - } + void InsertCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias insert_alias; + int index; + if (CAlias::AliasGet(insert_alias, this, name)) { + // if Convert succeeds, then i has been successfully read from user + // input + if (!sLine.Token(2, false, " ").Convert(&index) || index < 0 || + index > (int)insert_alias.AliasCmds().size()) { + PutModule("Invalid index."); + return; + } - insert_alias.AliasCmds().insert( - insert_alias.AliasCmds().begin() + index, - sLine.Token(3, true, " ")); - insert_alias.Commit(); - PutModule("Modified alias."); - } else - PutModule("Alias does not exist."); - } + insert_alias.AliasCmds().insert( + insert_alias.AliasCmds().begin() + index, + sLine.Token(3, true, " ")); + insert_alias.Commit(); + PutModule("Modified alias."); + } else + PutModule("Alias does not exist."); + } - void RemoveCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias remove_alias; - int index; - if (CAlias::AliasGet(remove_alias, this, name)) { - if (!sLine.Token(2, false, " ").Convert(&index) || index < 0 || - index > (int)remove_alias.AliasCmds().size() - 1) { - PutModule("Invalid index."); - return; - } + void RemoveCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias remove_alias; + int index; + if (CAlias::AliasGet(remove_alias, this, name)) { + if (!sLine.Token(2, false, " ").Convert(&index) || index < 0 || + index > (int)remove_alias.AliasCmds().size() - 1) { + PutModule("Invalid index."); + return; + } - remove_alias.AliasCmds().erase(remove_alias.AliasCmds().begin() + - index); - remove_alias.Commit(); - PutModule("Modified alias."); - } else - PutModule("Alias does not exist."); - } + remove_alias.AliasCmds().erase(remove_alias.AliasCmds().begin() + + index); + remove_alias.Commit(); + PutModule("Modified alias."); + } else + PutModule("Alias does not exist."); + } - void ClearCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias clear_alias; - if (CAlias::AliasGet(clear_alias, this, name)) { - clear_alias.AliasCmds().clear(); - clear_alias.Commit(); - PutModule("Modified alias."); - } else - PutModule("Alias does not exist."); - } + void ClearCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias clear_alias; + if (CAlias::AliasGet(clear_alias, this, name)) { + clear_alias.AliasCmds().clear(); + clear_alias.Commit(); + PutModule("Modified alias."); + } else + PutModule("Alias does not exist."); + } - void ListCommand(const CString& sLine) { - CString output = "The following aliases exist:"; - MCString::iterator i = BeginNV(); - if (i == EndNV()) output += " [none]"; - for (; i != EndNV(); ++i) { - output.append(" "); - output.append(i->first); - } - PutModule(output); - } + void ListCommand(const CString& sLine) { + CString output = "The following aliases exist:"; + MCString::iterator i = BeginNV(); + if (i == EndNV()) output += " [none]"; + for (; i != EndNV(); ++i) { + output.append(" "); + output.append(i->first); + } + PutModule(output); + } - void DumpCommand(const CString& sLine) { - MCString::iterator i = BeginNV(); + void DumpCommand(const CString& sLine) { + MCString::iterator i = BeginNV(); - if (i == EndNV()) { - PutModule("There are no aliases."); - return; - } + if (i == EndNV()) { + PutModule("There are no aliases."); + return; + } - PutModule("-----------------------"); - PutModule("/ZNC-CLEAR-ALL-ALIASES!"); - for (; i != EndNV(); ++i) { - PutModule("/msg " + GetModNick() + " Create " + i->first); - if (!i->second.empty()) { - VCString it; - uint idx; - i->second.Split("\n", it); + PutModule("-----------------------"); + PutModule("/ZNC-CLEAR-ALL-ALIASES!"); + for (; i != EndNV(); ++i) { + PutModule("/msg " + GetModNick() + " Create " + i->first); + if (!i->second.empty()) { + VCString it; + uint idx; + i->second.Split("\n", it); - for (idx = 0; idx < it.size(); ++idx) { - PutModule("/msg " + GetModNick() + " Add " + i->first + - " " + it[idx]); - } - } - } - PutModule("-----------------------"); - } + for (idx = 0; idx < it.size(); ++idx) { + PutModule("/msg " + GetModNick() + " Add " + i->first + + " " + it[idx]); + } + } + } + PutModule("-----------------------"); + } - void InfoCommand(const CString& sLine) { - CString name = sLine.Token(1, false, " "); - CAlias info_alias; - if (CAlias::AliasGet(info_alias, this, name)) { - PutModule("Actions for alias " + info_alias.GetName() + ":"); - for (size_t i = 0; i < info_alias.AliasCmds().size(); ++i) { - CString num(i); - CString padding(4 - (num.length() > 3 ? 3 : num.length()), ' '); - PutModule(num + padding + info_alias.AliasCmds()[i]); - } - PutModule("End of actions for alias " + info_alias.GetName() + "."); - } else - PutModule("Alias does not exist."); - } + void InfoCommand(const CString& sLine) { + CString name = sLine.Token(1, false, " "); + CAlias info_alias; + if (CAlias::AliasGet(info_alias, this, name)) { + PutModule("Actions for alias " + info_alias.GetName() + ":"); + for (size_t i = 0; i < info_alias.AliasCmds().size(); ++i) { + CString num(i); + CString padding(4 - (num.length() > 3 ? 3 : num.length()), ' '); + PutModule(num + padding + info_alias.AliasCmds()[i]); + } + PutModule("End of actions for alias " + info_alias.GetName() + "."); + } else + PutModule("Alias does not exist."); + } - MODCONSTRUCTOR(CAliasMod), sending_lines(false) { - AddHelpCommand(); - AddCommand("Create", static_cast( - &CAliasMod::CreateCommand), - "", "Creates a new, blank alias called name."); - AddCommand("Delete", static_cast( - &CAliasMod::DeleteCommand), - "", "Deletes an existing alias."); - AddCommand("Add", - static_cast(&CAliasMod::AddCmd), - " ", "Adds a line to an existing alias."); - AddCommand("Insert", static_cast( - &CAliasMod::InsertCommand), - " ", - "Inserts a line into an existing alias."); - AddCommand("Remove", static_cast( - &CAliasMod::RemoveCommand), - " ", "Removes a line from an existing alias."); - AddCommand("Clear", static_cast( - &CAliasMod::ClearCommand), - "", "Removes all line from an existing alias."); - AddCommand("List", static_cast( - &CAliasMod::ListCommand), - "", "Lists all aliases by name."); - AddCommand("Info", static_cast( - &CAliasMod::InfoCommand), - "", "Reports the actions performed by an alias."); - AddCommand( - "Dump", - static_cast(&CAliasMod::DumpCommand), "", - "Generate a list of commands to copy your alias config."); - } + MODCONSTRUCTOR(CAliasMod), sending_lines(false) { + AddHelpCommand(); + AddCommand("Create", static_cast( + &CAliasMod::CreateCommand), + "", "Creates a new, blank alias called name."); + AddCommand("Delete", static_cast( + &CAliasMod::DeleteCommand), + "", "Deletes an existing alias."); + AddCommand("Add", + static_cast(&CAliasMod::AddCmd), + " ", "Adds a line to an existing alias."); + AddCommand("Insert", static_cast( + &CAliasMod::InsertCommand), + " ", + "Inserts a line into an existing alias."); + AddCommand("Remove", static_cast( + &CAliasMod::RemoveCommand), + " ", "Removes a line from an existing alias."); + AddCommand("Clear", static_cast( + &CAliasMod::ClearCommand), + "", "Removes all line from an existing alias."); + AddCommand("List", static_cast( + &CAliasMod::ListCommand), + "", "Lists all aliases by name."); + AddCommand("Info", static_cast( + &CAliasMod::InfoCommand), + "", "Reports the actions performed by an alias."); + AddCommand( + "Dump", + static_cast(&CAliasMod::DumpCommand), "", + "Generate a list of commands to copy your alias config."); + } - EModRet OnUserRaw(CString& sLine) override { - CAlias current_alias; + EModRet OnUserRaw(CString& sLine) override { + CAlias current_alias; - if (sending_lines) return CONTINUE; + if (sending_lines) return CONTINUE; - try { - if (sLine.Equals("ZNC-CLEAR-ALL-ALIASES!")) { - ListCommand(""); - PutModule("Clearing all of them!"); - ClearNV(); - return HALT; - } else if (CAlias::AliasGet(current_alias, this, sLine)) { - VCString rawLines; - current_alias.Imprint(sLine).Split("\n", rawLines, false); - sending_lines = true; + try { + if (sLine.Equals("ZNC-CLEAR-ALL-ALIASES!")) { + ListCommand(""); + PutModule("Clearing all of them!"); + ClearNV(); + return HALT; + } else if (CAlias::AliasGet(current_alias, this, sLine)) { + VCString rawLines; + current_alias.Imprint(sLine).Split("\n", rawLines, false); + sending_lines = true; - for (size_t i = 0; i < rawLines.size(); ++i) { - m_pClient->ReadLine(rawLines[i]); - } + for (size_t i = 0; i < rawLines.size(); ++i) { + m_pClient->ReadLine(rawLines[i]); + } - sending_lines = false; - return HALT; - } - } catch (std::exception& e) { - CString my_nick = - (GetNetwork() == nullptr ? "" : GetNetwork()->GetCurNick()); - if (my_nick.empty()) my_nick = "*"; - PutUser(CString(":znc.in 461 " + my_nick + " " + - current_alias.GetName() + " :ZNC alias error: ") + - e.what()); - return HALTCORE; - } + sending_lines = false; + return HALT; + } + } catch (std::exception& e) { + CString my_nick = + (GetNetwork() == nullptr ? "" : GetNetwork()->GetCurNick()); + if (my_nick.empty()) my_nick = "*"; + PutUser(CString(":znc.in 461 " + my_nick + " " + + current_alias.GetName() + " :ZNC alias error: ") + + e.what()); + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("alias"); - Info.AddType(CModInfo::NetworkModule); + Info.SetWikiPage("alias"); + Info.AddType(CModInfo::NetworkModule); } USERMODULEDEFS(CAliasMod, "Provides bouncer-side command alias support.") diff --git a/modules/autoattach.cpp b/modules/autoattach.cpp index 871f4003..23709227 100644 --- a/modules/autoattach.cpp +++ b/modules/autoattach.cpp @@ -21,268 +21,268 @@ using std::vector; class CAttachMatch { public: - CAttachMatch(CModule* pModule, const CString& sChannels, - const CString& sSearch, const CString& sHostmasks, - bool bNegated) { - m_pModule = pModule; - m_sChannelWildcard = sChannels; - m_sSearchWildcard = sSearch; - m_sHostmaskWildcard = sHostmasks; - m_bNegated = bNegated; + CAttachMatch(CModule* pModule, const CString& sChannels, + const CString& sSearch, const CString& sHostmasks, + bool bNegated) { + m_pModule = pModule; + m_sChannelWildcard = sChannels; + m_sSearchWildcard = sSearch; + m_sHostmaskWildcard = sHostmasks; + m_bNegated = bNegated; - if (m_sChannelWildcard.empty()) m_sChannelWildcard = "*"; - if (m_sSearchWildcard.empty()) m_sSearchWildcard = "*"; - if (m_sHostmaskWildcard.empty()) m_sHostmaskWildcard = "*!*@*"; - } + if (m_sChannelWildcard.empty()) m_sChannelWildcard = "*"; + if (m_sSearchWildcard.empty()) m_sSearchWildcard = "*"; + if (m_sHostmaskWildcard.empty()) m_sHostmaskWildcard = "*!*@*"; + } - bool IsMatch(const CString& sChan, const CString& sHost, - const CString& sMessage) const { - if (!sHost.WildCmp(m_sHostmaskWildcard, CString::CaseInsensitive)) - return false; - if (!sChan.WildCmp(m_sChannelWildcard, CString::CaseInsensitive)) - return false; - if (!sMessage.WildCmp(m_pModule->ExpandString(m_sSearchWildcard), - CString::CaseInsensitive)) - return false; - return true; - } + bool IsMatch(const CString& sChan, const CString& sHost, + const CString& sMessage) const { + if (!sHost.WildCmp(m_sHostmaskWildcard, CString::CaseInsensitive)) + return false; + if (!sChan.WildCmp(m_sChannelWildcard, CString::CaseInsensitive)) + return false; + if (!sMessage.WildCmp(m_pModule->ExpandString(m_sSearchWildcard), + CString::CaseInsensitive)) + return false; + return true; + } - bool IsNegated() const { return m_bNegated; } + bool IsNegated() const { return m_bNegated; } - const CString& GetHostMask() const { return m_sHostmaskWildcard; } + const CString& GetHostMask() const { return m_sHostmaskWildcard; } - const CString& GetSearch() const { return m_sSearchWildcard; } + const CString& GetSearch() const { return m_sSearchWildcard; } - const CString& GetChans() const { return m_sChannelWildcard; } + const CString& GetChans() const { return m_sChannelWildcard; } - CString ToString() { - CString sRes; - if (m_bNegated) sRes += "!"; - sRes += m_sChannelWildcard; - sRes += " "; - sRes += m_sSearchWildcard; - sRes += " "; - sRes += m_sHostmaskWildcard; - return sRes; - } + CString ToString() { + CString sRes; + if (m_bNegated) sRes += "!"; + sRes += m_sChannelWildcard; + sRes += " "; + sRes += m_sSearchWildcard; + sRes += " "; + sRes += m_sHostmaskWildcard; + return sRes; + } private: - bool m_bNegated; - CModule* m_pModule; - CString m_sChannelWildcard; - CString m_sSearchWildcard; - CString m_sHostmaskWildcard; + bool m_bNegated; + CModule* m_pModule; + CString m_sChannelWildcard; + CString m_sSearchWildcard; + CString m_sHostmaskWildcard; }; class CChanAttach : public CModule { public: - typedef vector VAttachMatch; - typedef VAttachMatch::iterator VAttachIter; + typedef vector VAttachMatch; + typedef VAttachMatch::iterator VAttachIter; private: - void HandleAdd(const CString& sLine) { - CString sMsg = sLine.Token(1, true); - bool bHelp = false; - bool bNegated = sMsg.TrimPrefix("!"); - CString sChan = sMsg.Token(0); - CString sSearch = sMsg.Token(1); - CString sHost = sMsg.Token(2); + void HandleAdd(const CString& sLine) { + CString sMsg = sLine.Token(1, true); + bool bHelp = false; + bool bNegated = sMsg.TrimPrefix("!"); + CString sChan = sMsg.Token(0); + CString sSearch = sMsg.Token(1); + CString sHost = sMsg.Token(2); - if (sChan.empty()) { - bHelp = true; - } else if (Add(bNegated, sChan, sSearch, sHost)) { - PutModule("Added to list"); - } else { - PutModule(sLine.Token(1, true) + " is already added"); - bHelp = true; - } - if (bHelp) { - PutModule("Usage: Add [!]<#chan> "); - PutModule("Wildcards are allowed"); - } - } + if (sChan.empty()) { + bHelp = true; + } else if (Add(bNegated, sChan, sSearch, sHost)) { + PutModule("Added to list"); + } else { + PutModule(sLine.Token(1, true) + " is already added"); + bHelp = true; + } + if (bHelp) { + PutModule("Usage: Add [!]<#chan> "); + PutModule("Wildcards are allowed"); + } + } - void HandleDel(const CString& sLine) { - CString sMsg = sLine.Token(1, true); - bool bNegated = sMsg.TrimPrefix("!"); - CString sChan = sMsg.Token(0); - CString sSearch = sMsg.Token(1); - CString sHost = sMsg.Token(2); + void HandleDel(const CString& sLine) { + CString sMsg = sLine.Token(1, true); + bool bNegated = sMsg.TrimPrefix("!"); + CString sChan = sMsg.Token(0); + CString sSearch = sMsg.Token(1); + CString sHost = sMsg.Token(2); - if (Del(bNegated, sChan, sSearch, sHost)) { - PutModule("Removed " + sChan + " from list"); - } else { - PutModule("Usage: Del [!]<#chan> "); - } - } + if (Del(bNegated, sChan, sSearch, sHost)) { + PutModule("Removed " + sChan + " from list"); + } else { + PutModule("Usage: Del [!]<#chan> "); + } + } - void HandleList(const CString& sLine) { - CTable Table; - Table.AddColumn("Neg"); - Table.AddColumn("Chan"); - Table.AddColumn("Search"); - Table.AddColumn("Host"); + void HandleList(const CString& sLine) { + CTable Table; + Table.AddColumn("Neg"); + Table.AddColumn("Chan"); + Table.AddColumn("Search"); + Table.AddColumn("Host"); - VAttachIter it = m_vMatches.begin(); - for (; it != m_vMatches.end(); ++it) { - Table.AddRow(); - Table.SetCell("Neg", it->IsNegated() ? "!" : ""); - Table.SetCell("Chan", it->GetChans()); - Table.SetCell("Search", it->GetSearch()); - Table.SetCell("Host", it->GetHostMask()); - } + VAttachIter it = m_vMatches.begin(); + for (; it != m_vMatches.end(); ++it) { + Table.AddRow(); + Table.SetCell("Neg", it->IsNegated() ? "!" : ""); + Table.SetCell("Chan", it->GetChans()); + Table.SetCell("Search", it->GetSearch()); + Table.SetCell("Host", it->GetHostMask()); + } - if (Table.size()) { - PutModule(Table); - } else { - PutModule("You have no entries."); - } - } + if (Table.size()) { + PutModule(Table); + } else { + PutModule("You have no entries."); + } + } public: - MODCONSTRUCTOR(CChanAttach) { - AddHelpCommand(); - AddCommand("Add", static_cast( - &CChanAttach::HandleAdd), - "[!]<#chan> ", - "Add an entry, use !#chan to negate and * for wildcards"); - AddCommand("Del", static_cast( - &CChanAttach::HandleDel), - "[!]<#chan> ", - "Remove an entry, needs to be an exact match"); - AddCommand("List", static_cast( - &CChanAttach::HandleList), - "", "List all entries"); - } + MODCONSTRUCTOR(CChanAttach) { + AddHelpCommand(); + AddCommand("Add", static_cast( + &CChanAttach::HandleAdd), + "[!]<#chan> ", + "Add an entry, use !#chan to negate and * for wildcards"); + AddCommand("Del", static_cast( + &CChanAttach::HandleDel), + "[!]<#chan> ", + "Remove an entry, needs to be an exact match"); + AddCommand("List", static_cast( + &CChanAttach::HandleList), + "", "List all entries"); + } - virtual ~CChanAttach() {} + virtual ~CChanAttach() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - VCString vsChans; - sArgs.Split(" ", vsChans, false); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + VCString vsChans; + sArgs.Split(" ", vsChans, false); - for (VCString::const_iterator it = vsChans.begin(); it != vsChans.end(); - ++it) { - CString sAdd = *it; - bool bNegated = sAdd.TrimPrefix("!"); - CString sChan = sAdd.Token(0); - CString sSearch = sAdd.Token(1); - CString sHost = sAdd.Token(2, true); + for (VCString::const_iterator it = vsChans.begin(); it != vsChans.end(); + ++it) { + CString sAdd = *it; + bool bNegated = sAdd.TrimPrefix("!"); + CString sChan = sAdd.Token(0); + CString sSearch = sAdd.Token(1); + CString sHost = sAdd.Token(2, true); - if (!Add(bNegated, sChan, sSearch, sHost)) { - PutModule("Unable to add [" + *it + "]"); - } - } + if (!Add(bNegated, sChan, sSearch, sHost)) { + PutModule("Unable to add [" + *it + "]"); + } + } - // Load our saved settings, ignore errors - MCString::iterator it; - for (it = BeginNV(); it != EndNV(); ++it) { - CString sAdd = it->first; - bool bNegated = sAdd.TrimPrefix("!"); - CString sChan = sAdd.Token(0); - CString sSearch = sAdd.Token(1); - CString sHost = sAdd.Token(2, true); + // Load our saved settings, ignore errors + MCString::iterator it; + for (it = BeginNV(); it != EndNV(); ++it) { + CString sAdd = it->first; + bool bNegated = sAdd.TrimPrefix("!"); + CString sChan = sAdd.Token(0); + CString sSearch = sAdd.Token(1); + CString sHost = sAdd.Token(2, true); - Add(bNegated, sChan, sSearch, sHost); - } + Add(bNegated, sChan, sSearch, sHost); + } - return true; - } + return true; + } - void TryAttach(const CNick& Nick, CChan& Channel, CString& Message) { - const CString& sChan = Channel.GetName(); - const CString& sHost = Nick.GetHostMask(); - const CString& sMessage = Message; - VAttachIter it; + void TryAttach(const CNick& Nick, CChan& Channel, CString& Message) { + const CString& sChan = Channel.GetName(); + const CString& sHost = Nick.GetHostMask(); + const CString& sMessage = Message; + VAttachIter it; - if (!Channel.IsDetached()) return; + if (!Channel.IsDetached()) return; - // Any negated match? - for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { - if (it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) return; - } + // Any negated match? + for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { + if (it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) return; + } - // Now check for a positive match - for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { - if (!it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) { - Channel.AttachUser(); - return; - } - } - } + // Now check for a positive match + for (it = m_vMatches.begin(); it != m_vMatches.end(); ++it) { + if (!it->IsNegated() && it->IsMatch(sChan, sHost, sMessage)) { + Channel.AttachUser(); + return; + } + } + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - TryAttach(Nick, Channel, sMessage); - return CONTINUE; - } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + TryAttach(Nick, Channel, sMessage); + return CONTINUE; + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - TryAttach(Nick, Channel, sMessage); - return CONTINUE; - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + TryAttach(Nick, Channel, sMessage); + return CONTINUE; + } - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override { - TryAttach(Nick, Channel, sMessage); - return CONTINUE; - } + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override { + TryAttach(Nick, Channel, sMessage); + return CONTINUE; + } - VAttachIter FindEntry(const CString& sChan, const CString& sSearch, - const CString& sHost) { - VAttachIter it = m_vMatches.begin(); - for (; it != m_vMatches.end(); ++it) { - if (sHost.empty() || it->GetHostMask() != sHost) continue; - if (sSearch.empty() || it->GetSearch() != sSearch) continue; - if (sChan.empty() || it->GetChans() != sChan) continue; - return it; - } - return m_vMatches.end(); - } + VAttachIter FindEntry(const CString& sChan, const CString& sSearch, + const CString& sHost) { + VAttachIter it = m_vMatches.begin(); + for (; it != m_vMatches.end(); ++it) { + if (sHost.empty() || it->GetHostMask() != sHost) continue; + if (sSearch.empty() || it->GetSearch() != sSearch) continue; + if (sChan.empty() || it->GetChans() != sChan) continue; + return it; + } + return m_vMatches.end(); + } - bool Add(bool bNegated, const CString& sChan, const CString& sSearch, - const CString& sHost) { - CAttachMatch attach(this, sChan, sSearch, sHost, bNegated); + bool Add(bool bNegated, const CString& sChan, const CString& sSearch, + const CString& sHost) { + CAttachMatch attach(this, sChan, sSearch, sHost, bNegated); - // Check for duplicates - VAttachIter it = m_vMatches.begin(); - for (; it != m_vMatches.end(); ++it) { - if (it->GetHostMask() == attach.GetHostMask() && - it->GetChans() == attach.GetChans() && - it->GetSearch() == attach.GetSearch()) - return false; - } + // Check for duplicates + VAttachIter it = m_vMatches.begin(); + for (; it != m_vMatches.end(); ++it) { + if (it->GetHostMask() == attach.GetHostMask() && + it->GetChans() == attach.GetChans() && + it->GetSearch() == attach.GetSearch()) + return false; + } - m_vMatches.push_back(attach); + m_vMatches.push_back(attach); - // Also save it for next module load - SetNV(attach.ToString(), ""); + // Also save it for next module load + SetNV(attach.ToString(), ""); - return true; - } + return true; + } - bool Del(bool bNegated, const CString& sChan, const CString& sSearch, - const CString& sHost) { - VAttachIter it = FindEntry(sChan, sSearch, sHost); - if (it == m_vMatches.end() || it->IsNegated() != bNegated) return false; + bool Del(bool bNegated, const CString& sChan, const CString& sSearch, + const CString& sHost) { + VAttachIter it = FindEntry(sChan, sSearch, sHost); + if (it == m_vMatches.end() || it->IsNegated() != bNegated) return false; - DelNV(it->ToString()); - m_vMatches.erase(it); + DelNV(it->ToString()); + m_vMatches.erase(it); - return true; - } + return true; + } private: - VAttachMatch m_vMatches; + VAttachMatch m_vMatches; }; template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::UserModule); - Info.SetWikiPage("autoattach"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "List of channel masks and channel masks with ! before them."); + Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("autoattach"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "List of channel masks and channel masks with ! before them."); } NETWORKMODULEDEFS(CChanAttach, "Reattaches you to channels on activity.") diff --git a/modules/autocycle.cpp b/modules/autocycle.cpp index e2f88fa1..3d29b068 100644 --- a/modules/autocycle.cpp +++ b/modules/autocycle.cpp @@ -21,213 +21,213 @@ using std::vector; class CAutoCycleMod : public CModule { public: - MODCONSTRUCTOR(CAutoCycleMod) { - AddHelpCommand(); - AddCommand("Add", static_cast( - &CAutoCycleMod::OnAddCommand), - "[!]<#chan>", - "Add an entry, use !#chan to negate and * for wildcards"); - AddCommand("Del", static_cast( - &CAutoCycleMod::OnDelCommand), - "[!]<#chan>", "Remove an entry, needs to be an exact match"); - AddCommand("List", static_cast( - &CAutoCycleMod::OnListCommand), - "", "List all entries"); - m_recentlyCycled.SetTTL(15 * 1000); - } + MODCONSTRUCTOR(CAutoCycleMod) { + AddHelpCommand(); + AddCommand("Add", static_cast( + &CAutoCycleMod::OnAddCommand), + "[!]<#chan>", + "Add an entry, use !#chan to negate and * for wildcards"); + AddCommand("Del", static_cast( + &CAutoCycleMod::OnDelCommand), + "[!]<#chan>", "Remove an entry, needs to be an exact match"); + AddCommand("List", static_cast( + &CAutoCycleMod::OnListCommand), + "", "List all entries"); + m_recentlyCycled.SetTTL(15 * 1000); + } - virtual ~CAutoCycleMod() {} + virtual ~CAutoCycleMod() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - VCString vsChans; - sArgs.Split(" ", vsChans, false); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + VCString vsChans; + sArgs.Split(" ", vsChans, false); - for (const CString& sChan : vsChans) { - if (!Add(sChan)) { - PutModule("Unable to add [" + sChan + "]"); - } - } + for (const CString& sChan : vsChans) { + if (!Add(sChan)) { + PutModule("Unable to add [" + sChan + "]"); + } + } - // Load our saved settings, ignore errors - MCString::iterator it; - for (it = BeginNV(); it != EndNV(); ++it) { - Add(it->first); - } + // Load our saved settings, ignore errors + MCString::iterator it; + for (it = BeginNV(); it != EndNV(); ++it) { + Add(it->first); + } - // Default is auto cycle for all channels - if (m_vsChans.empty()) Add("*"); + // Default is auto cycle for all channels + if (m_vsChans.empty()) Add("*"); - return true; - } + return true; + } - void OnAddCommand(const CString& sLine) { - CString sChan = sLine.Token(1); + void OnAddCommand(const CString& sLine) { + CString sChan = sLine.Token(1); - if (AlreadyAdded(sChan)) { - PutModule(sChan + " is already added"); - } else if (Add(sChan)) { - PutModule("Added " + sChan + " to list"); - } else { - PutModule("Usage: Add [!]<#chan>"); - } - } + if (AlreadyAdded(sChan)) { + PutModule(sChan + " is already added"); + } else if (Add(sChan)) { + PutModule("Added " + sChan + " to list"); + } else { + PutModule("Usage: Add [!]<#chan>"); + } + } - void OnDelCommand(const CString& sLine) { - CString sChan = sLine.Token(1); + void OnDelCommand(const CString& sLine) { + CString sChan = sLine.Token(1); - if (Del(sChan)) - PutModule("Removed " + sChan + " from list"); - else - PutModule("Usage: Del [!]<#chan>"); - } + if (Del(sChan)) + PutModule("Removed " + sChan + " from list"); + else + PutModule("Usage: Del [!]<#chan>"); + } - void OnListCommand(const CString& sLine) { - CTable Table; - Table.AddColumn("Chan"); + void OnListCommand(const CString& sLine) { + CTable Table; + Table.AddColumn("Chan"); - for (const CString& sChan : m_vsChans) { - Table.AddRow(); - Table.SetCell("Chan", sChan); - } + for (const CString& sChan : m_vsChans) { + Table.AddRow(); + Table.SetCell("Chan", sChan); + } - for (const CString& sChan : m_vsNegChans) { - Table.AddRow(); - Table.SetCell("Chan", "!" + sChan); - } + for (const CString& sChan : m_vsNegChans) { + Table.AddRow(); + Table.SetCell("Chan", "!" + sChan); + } - if (Table.size()) { - PutModule(Table); - } else { - PutModule("You have no entries."); - } - } + if (Table.size()) { + PutModule(Table); + } else { + PutModule("You have no entries."); + } + } - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override { - AutoCycle(Channel); - } + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override { + AutoCycle(Channel); + } - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override { - for (CChan* pChan : vChans) AutoCycle(*pChan); - } + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override { + for (CChan* pChan : vChans) AutoCycle(*pChan); + } - void OnKick(const CNick& Nick, const CString& sOpNick, CChan& Channel, - const CString& sMessage) override { - AutoCycle(Channel); - } + void OnKick(const CNick& Nick, const CString& sOpNick, CChan& Channel, + const CString& sMessage) override { + AutoCycle(Channel); + } protected: - void AutoCycle(CChan& Channel) { - if (!IsAutoCycle(Channel.GetName())) return; + void AutoCycle(CChan& Channel) { + if (!IsAutoCycle(Channel.GetName())) return; - // Did we recently annoy opers via cycling of an empty channel? - if (m_recentlyCycled.HasItem(Channel.GetName())) return; + // Did we recently annoy opers via cycling of an empty channel? + if (m_recentlyCycled.HasItem(Channel.GetName())) return; - // Is there only one person left in the channel? - if (Channel.GetNickCount() != 1) return; + // Is there only one person left in the channel? + if (Channel.GetNickCount() != 1) return; - // Is that person us and we don't have op? - const CNick& pNick = Channel.GetNicks().begin()->second; - if (!pNick.HasPerm(CChan::Op) && - pNick.NickEquals(GetNetwork()->GetCurNick())) { - Channel.Cycle(); - m_recentlyCycled.AddItem(Channel.GetName()); - } - } + // Is that person us and we don't have op? + const CNick& pNick = Channel.GetNicks().begin()->second; + if (!pNick.HasPerm(CChan::Op) && + pNick.NickEquals(GetNetwork()->GetCurNick())) { + Channel.Cycle(); + m_recentlyCycled.AddItem(Channel.GetName()); + } + } - bool AlreadyAdded(const CString& sInput) { - CString sChan = sInput; - if (sChan.TrimPrefix("!")) { - for (const CString& s : m_vsNegChans) { - if (s.Equals(sChan)) return true; - } - } else { - for (const CString& s : m_vsChans) { - if (s.Equals(sChan)) return true; - } - } - return false; - } + bool AlreadyAdded(const CString& sInput) { + CString sChan = sInput; + if (sChan.TrimPrefix("!")) { + for (const CString& s : m_vsNegChans) { + if (s.Equals(sChan)) return true; + } + } else { + for (const CString& s : m_vsChans) { + if (s.Equals(sChan)) return true; + } + } + return false; + } - bool Add(const CString& sChan) { - if (sChan.empty() || sChan == "!") { - return false; - } + bool Add(const CString& sChan) { + if (sChan.empty() || sChan == "!") { + return false; + } - if (sChan.Left(1) == "!") { - m_vsNegChans.push_back(sChan.substr(1)); - } else { - m_vsChans.push_back(sChan); - } + if (sChan.Left(1) == "!") { + m_vsNegChans.push_back(sChan.substr(1)); + } else { + m_vsChans.push_back(sChan); + } - // Also save it for next module load - SetNV(sChan, ""); + // Also save it for next module load + SetNV(sChan, ""); - return true; - } + return true; + } - bool Del(const CString& sChan) { - vector::iterator it, end; + bool Del(const CString& sChan) { + vector::iterator it, end; - if (sChan.empty() || sChan == "!") return false; + if (sChan.empty() || sChan == "!") return false; - if (sChan.Left(1) == "!") { - CString sTmp = sChan.substr(1); - it = m_vsNegChans.begin(); - end = m_vsNegChans.end(); + if (sChan.Left(1) == "!") { + CString sTmp = sChan.substr(1); + it = m_vsNegChans.begin(); + end = m_vsNegChans.end(); - for (; it != end; ++it) - if (*it == sTmp) break; + for (; it != end; ++it) + if (*it == sTmp) break; - if (it == end) return false; + if (it == end) return false; - m_vsNegChans.erase(it); - } else { - it = m_vsChans.begin(); - end = m_vsChans.end(); + m_vsNegChans.erase(it); + } else { + it = m_vsChans.begin(); + end = m_vsChans.end(); - for (; it != end; ++it) - if (*it == sChan) break; + for (; it != end; ++it) + if (*it == sChan) break; - if (it == end) return false; + if (it == end) return false; - m_vsChans.erase(it); - } + m_vsChans.erase(it); + } - DelNV(sChan); + DelNV(sChan); - return true; - } + return true; + } - bool IsAutoCycle(const CString& sChan) { - for (const CString& s : m_vsNegChans) { - if (sChan.WildCmp(s, CString::CaseInsensitive)) { - return false; - } - } + bool IsAutoCycle(const CString& sChan) { + for (const CString& s : m_vsNegChans) { + if (sChan.WildCmp(s, CString::CaseInsensitive)) { + return false; + } + } - for (const CString& s : m_vsChans) { - if (sChan.WildCmp(s, CString::CaseInsensitive)) { - return true; - } - } + for (const CString& s : m_vsChans) { + if (sChan.WildCmp(s, CString::CaseInsensitive)) { + return true; + } + } - return false; - } + return false; + } private: - vector m_vsChans; - vector m_vsNegChans; - TCacheMap m_recentlyCycled; + vector m_vsChans; + vector m_vsNegChans; + TCacheMap m_recentlyCycled; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("autocycle"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "List of channel masks and channel masks with ! before them."); + Info.SetWikiPage("autocycle"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "List of channel masks and channel masks with ! before them."); } NETWORKMODULEDEFS(CAutoCycleMod, diff --git a/modules/autoop.cpp b/modules/autoop.cpp index 61611465..b4281558 100644 --- a/modules/autoop.cpp +++ b/modules/autoop.cpp @@ -27,620 +27,620 @@ class CAutoOpMod; class CAutoOpTimer : public CTimer { public: - CAutoOpTimer(CAutoOpMod* pModule) - : CTimer((CModule*)pModule, 20, 0, "AutoOpChecker", - "Check channels for auto op candidates") { - m_pParent = pModule; - } + CAutoOpTimer(CAutoOpMod* pModule) + : CTimer((CModule*)pModule, 20, 0, "AutoOpChecker", + "Check channels for auto op candidates") { + m_pParent = pModule; + } - virtual ~CAutoOpTimer() {} + virtual ~CAutoOpTimer() {} private: protected: - void RunJob() override; + void RunJob() override; - CAutoOpMod* m_pParent; + CAutoOpMod* m_pParent; }; class CAutoOpUser { public: - CAutoOpUser() {} + CAutoOpUser() {} - CAutoOpUser(const CString& sLine) { FromString(sLine); } + CAutoOpUser(const CString& sLine) { FromString(sLine); } - CAutoOpUser(const CString& sUsername, const CString& sUserKey, - const CString& sHostmasks, const CString& sChannels) - : m_sUsername(sUsername), m_sUserKey(sUserKey) { - AddHostmasks(sHostmasks); - AddChans(sChannels); - } + CAutoOpUser(const CString& sUsername, const CString& sUserKey, + const CString& sHostmasks, const CString& sChannels) + : m_sUsername(sUsername), m_sUserKey(sUserKey) { + AddHostmasks(sHostmasks); + AddChans(sChannels); + } - virtual ~CAutoOpUser() {} + virtual ~CAutoOpUser() {} - const CString& GetUsername() const { return m_sUsername; } - const CString& GetUserKey() const { return m_sUserKey; } + const CString& GetUsername() const { return m_sUsername; } + const CString& GetUserKey() const { return m_sUserKey; } - bool ChannelMatches(const CString& sChan) const { - for (const CString& s : m_ssChans) { - if (sChan.AsLower().WildCmp(s, CString::CaseInsensitive)) { - return true; - } - } + bool ChannelMatches(const CString& sChan) const { + for (const CString& s : m_ssChans) { + if (sChan.AsLower().WildCmp(s, CString::CaseInsensitive)) { + return true; + } + } - return false; - } + return false; + } - bool HostMatches(const CString& sHostmask) { - for (const CString& s : m_ssHostmasks) { - if (sHostmask.WildCmp(s, CString::CaseInsensitive)) { - return true; - } - } - return false; - } + bool HostMatches(const CString& sHostmask) { + for (const CString& s : m_ssHostmasks) { + if (sHostmask.WildCmp(s, CString::CaseInsensitive)) { + return true; + } + } + return false; + } - CString GetHostmasks() const { - return CString(",").Join(m_ssHostmasks.begin(), m_ssHostmasks.end()); - } + CString GetHostmasks() const { + return CString(",").Join(m_ssHostmasks.begin(), m_ssHostmasks.end()); + } - CString GetChannels() const { - return CString(" ").Join(m_ssChans.begin(), m_ssChans.end()); - } + CString GetChannels() const { + return CString(" ").Join(m_ssChans.begin(), m_ssChans.end()); + } - bool DelHostmasks(const CString& sHostmasks) { - VCString vsHostmasks; - sHostmasks.Split(",", vsHostmasks); + bool DelHostmasks(const CString& sHostmasks) { + VCString vsHostmasks; + sHostmasks.Split(",", vsHostmasks); - for (const CString& s : vsHostmasks) { - m_ssHostmasks.erase(s); - } + for (const CString& s : vsHostmasks) { + m_ssHostmasks.erase(s); + } - return m_ssHostmasks.empty(); - } + return m_ssHostmasks.empty(); + } - void AddHostmasks(const CString& sHostmasks) { - VCString vsHostmasks; - sHostmasks.Split(",", vsHostmasks); + void AddHostmasks(const CString& sHostmasks) { + VCString vsHostmasks; + sHostmasks.Split(",", vsHostmasks); - for (const CString& s : vsHostmasks) { - m_ssHostmasks.insert(s); - } - } + for (const CString& s : vsHostmasks) { + m_ssHostmasks.insert(s); + } + } - void DelChans(const CString& sChans) { - VCString vsChans; - sChans.Split(" ", vsChans); + void DelChans(const CString& sChans) { + VCString vsChans; + sChans.Split(" ", vsChans); - for (const CString& sChan : vsChans) { - m_ssChans.erase(sChan.AsLower()); - } - } + for (const CString& sChan : vsChans) { + m_ssChans.erase(sChan.AsLower()); + } + } - void AddChans(const CString& sChans) { - VCString vsChans; - sChans.Split(" ", vsChans); + void AddChans(const CString& sChans) { + VCString vsChans; + sChans.Split(" ", vsChans); - for (const CString& sChan : vsChans) { - m_ssChans.insert(sChan.AsLower()); - } - } + for (const CString& sChan : vsChans) { + m_ssChans.insert(sChan.AsLower()); + } + } - CString ToString() const { - return m_sUsername + "\t" + GetHostmasks() + "\t" + m_sUserKey + "\t" + - GetChannels(); - } + CString ToString() const { + return m_sUsername + "\t" + GetHostmasks() + "\t" + m_sUserKey + "\t" + + GetChannels(); + } - bool FromString(const CString& sLine) { - m_sUsername = sLine.Token(0, false, "\t"); - sLine.Token(1, false, "\t").Split(",", m_ssHostmasks); - m_sUserKey = sLine.Token(2, false, "\t"); - sLine.Token(3, false, "\t").Split(" ", m_ssChans); + bool FromString(const CString& sLine) { + m_sUsername = sLine.Token(0, false, "\t"); + sLine.Token(1, false, "\t").Split(",", m_ssHostmasks); + m_sUserKey = sLine.Token(2, false, "\t"); + sLine.Token(3, false, "\t").Split(" ", m_ssChans); - return !m_sUserKey.empty(); - } + return !m_sUserKey.empty(); + } private: protected: - CString m_sUsername; - CString m_sUserKey; - set m_ssHostmasks; - set m_ssChans; + CString m_sUsername; + CString m_sUserKey; + set m_ssHostmasks; + set m_ssChans; }; class CAutoOpMod : public CModule { public: - MODCONSTRUCTOR(CAutoOpMod) { - AddHelpCommand(); - AddCommand("ListUsers", static_cast( - &CAutoOpMod::OnListUsersCommand), - "", "List all users"); - AddCommand("AddChans", static_cast( - &CAutoOpMod::OnAddChansCommand), - " [channel] ...", "Adds channels to a user"); - AddCommand("DelChans", static_cast( - &CAutoOpMod::OnDelChansCommand), - " [channel] ...", - "Removes channels from a user"); - AddCommand("AddMasks", static_cast( - &CAutoOpMod::OnAddMasksCommand), - " ,[mask] ...", "Adds masks to a user"); - AddCommand("DelMasks", static_cast( - &CAutoOpMod::OnDelMasksCommand), - " ,[mask] ...", "Removes masks from a user"); - AddCommand("AddUser", static_cast( - &CAutoOpMod::OnAddUserCommand), - " [,...] [channels]", - "Adds a user"); - AddCommand("DelUser", static_cast( - &CAutoOpMod::OnDelUserCommand), - "", "Removes a user"); - } - - bool OnLoad(const CString& sArgs, CString& sMessage) override { - AddTimer(new CAutoOpTimer(this)); - - // Load the users - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - const CString& sLine = it->second; - CAutoOpUser* pUser = new CAutoOpUser; - - if (!pUser->FromString(sLine) || - FindUser(pUser->GetUsername().AsLower())) { - delete pUser; - } else { - m_msUsers[pUser->GetUsername().AsLower()] = pUser; - } - } - - return true; - } - - virtual ~CAutoOpMod() { - for (const auto& it : m_msUsers) { - delete it.second; - } - m_msUsers.clear(); - } - - void OnJoin(const CNick& Nick, CChan& Channel) override { - // If we have ops in this chan - if (Channel.HasPerm(CChan::Op)) { - CheckAutoOp(Nick, Channel); - } - } - - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override { - MCString::iterator it = m_msQueue.find(Nick.GetNick().AsLower()); - - if (it != m_msQueue.end()) { - m_msQueue.erase(it); - } - } - - void OnNick(const CNick& OldNick, const CString& sNewNick, - const vector& vChans) override { - // Update the queue with nick changes - MCString::iterator it = m_msQueue.find(OldNick.GetNick().AsLower()); - - if (it != m_msQueue.end()) { - m_msQueue[sNewNick.AsLower()] = it->second; - m_msQueue.erase(it); - } - } - - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - if (!sMessage.Token(0).Equals("!ZNCAO")) { - return CONTINUE; - } - - CString sCommand = sMessage.Token(1); - - if (sCommand.Equals("CHALLENGE")) { - ChallengeRespond(Nick, sMessage.Token(2)); - } else if (sCommand.Equals("RESPONSE")) { - VerifyResponse(Nick, sMessage.Token(2)); - } - - return HALTCORE; - } - - void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - if (Nick.GetNick() == GetNetwork()->GetIRCNick().GetNick()) { - const map& msNicks = Channel.GetNicks(); - - for (const auto& it : msNicks) { - if (!it.second.HasPerm(CChan::Op)) { - CheckAutoOp(it.second, Channel); - } - } - } - } - - void OnModCommand(const CString& sLine) override { - CString sCommand = sLine.Token(0).AsUpper(); - if (sCommand.Equals("TIMERS")) { - // for testing purposes - hidden from help - ListTimers(); - } else { - HandleCommand(sLine); - } - } - - void OnAddUserCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sHost = sLine.Token(2); - CString sKey = sLine.Token(3); - - if (sHost.empty()) { - PutModule( - "Usage: AddUser [,...] " - "[channels]"); - } else { - CAutoOpUser* pUser = - AddUser(sUser, sKey, sHost, sLine.Token(4, true)); - - if (pUser) { - SetNV(sUser, pUser->ToString()); - } - } - } - - void OnDelUserCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - - if (sUser.empty()) { - PutModule("Usage: DelUser "); - } else { - DelUser(sUser); - DelNV(sUser); - } - } - - void OnListUsersCommand(const CString& sLine) { - if (m_msUsers.empty()) { - PutModule("There are no users defined"); - return; - } - - CTable Table; - - Table.AddColumn("User"); - Table.AddColumn("Hostmasks"); - Table.AddColumn("Key"); - Table.AddColumn("Channels"); - - for (const auto& it : m_msUsers) { - VCString vsHostmasks; - it.second->GetHostmasks().Split(",", vsHostmasks); - for (unsigned int a = 0; a < vsHostmasks.size(); a++) { - Table.AddRow(); - if (a == 0) { - Table.SetCell("User", it.second->GetUsername()); - Table.SetCell("Key", it.second->GetUserKey()); - Table.SetCell("Channels", it.second->GetChannels()); - } else if (a == vsHostmasks.size() - 1) { - Table.SetCell("User", "`-"); - } else { - Table.SetCell("User", "|-"); - } - Table.SetCell("Hostmasks", vsHostmasks[a]); - } - } - - PutModule(Table); - } - - void OnAddChansCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sChans = sLine.Token(2, true); - - if (sChans.empty()) { - PutModule("Usage: AddChans [channel] ..."); - return; - } - - CAutoOpUser* pUser = FindUser(sUser); - - if (!pUser) { - PutModule("No such user"); - return; - } - - pUser->AddChans(sChans); - PutModule("Channel(s) added to user [" + pUser->GetUsername() + "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } - - void OnDelChansCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sChans = sLine.Token(2, true); - - if (sChans.empty()) { - PutModule("Usage: DelChans [channel] ..."); - return; - } - - CAutoOpUser* pUser = FindUser(sUser); - - if (!pUser) { - PutModule("No such user"); - return; - } - - pUser->DelChans(sChans); - PutModule("Channel(s) Removed from user [" + pUser->GetUsername() + - "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } - - void OnAddMasksCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sHostmasks = sLine.Token(2, true); - - if (sHostmasks.empty()) { - PutModule("Usage: AddMasks ,[mask] ..."); - return; - } - - CAutoOpUser* pUser = FindUser(sUser); - - if (!pUser) { - PutModule("No such user"); - return; - } - - pUser->AddHostmasks(sHostmasks); - PutModule("Hostmasks(s) added to user [" + pUser->GetUsername() + "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } - - void OnDelMasksCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sHostmasks = sLine.Token(2, true); - - if (sHostmasks.empty()) { - PutModule("Usage: DelMasks ,[mask] ..."); - return; - } - - CAutoOpUser* pUser = FindUser(sUser); - - if (!pUser) { - PutModule("No such user"); - return; - } - - if (pUser->DelHostmasks(sHostmasks)) { - PutModule("Removed user [" + pUser->GetUsername() + "] with key [" + - pUser->GetUserKey() + "] and channels [" + - pUser->GetChannels() + "]"); - DelUser(sUser); - DelNV(sUser); - } else { - PutModule("Hostmasks(s) Removed from user [" + - pUser->GetUsername() + "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } - } - - CAutoOpUser* FindUser(const CString& sUser) { - map::iterator it = - m_msUsers.find(sUser.AsLower()); - - return (it != m_msUsers.end()) ? it->second : nullptr; - } - - CAutoOpUser* FindUserByHost(const CString& sHostmask, - const CString& sChannel = "") { - for (const auto& it : m_msUsers) { - CAutoOpUser* pUser = it.second; - - if (pUser->HostMatches(sHostmask) && - (sChannel.empty() || pUser->ChannelMatches(sChannel))) { - return pUser; - } - } - - return nullptr; - } - - bool CheckAutoOp(const CNick& Nick, CChan& Channel) { - CAutoOpUser* pUser = - FindUserByHost(Nick.GetHostMask(), Channel.GetName()); - - if (!pUser) { - return false; - } - - if (pUser->GetUserKey().Equals("__NOKEY__")) { - PutIRC("MODE " + Channel.GetName() + " +o " + Nick.GetNick()); - } else { - // then insert this nick into the queue, the timer does the rest - CString sNick = Nick.GetNick().AsLower(); - if (m_msQueue.find(sNick) == m_msQueue.end()) { - m_msQueue[sNick] = ""; - } - } - - return true; - } - - void DelUser(const CString& sUser) { - map::iterator it = - m_msUsers.find(sUser.AsLower()); - - if (it == m_msUsers.end()) { - PutModule("That user does not exist"); - return; - } - - delete it->second; - m_msUsers.erase(it); - PutModule("User [" + sUser + "] removed"); - } - - CAutoOpUser* AddUser(const CString& sUser, const CString& sKey, - const CString& sHosts, const CString& sChans) { - if (m_msUsers.find(sUser) != m_msUsers.end()) { - PutModule("That user already exists"); - return nullptr; - } - - CAutoOpUser* pUser = new CAutoOpUser(sUser, sKey, sHosts, sChans); - m_msUsers[sUser.AsLower()] = pUser; - PutModule("User [" + sUser + "] added with hostmask(s) [" + sHosts + - "]"); - return pUser; - } - - bool ChallengeRespond(const CNick& Nick, const CString& sChallenge) { - // Validate before responding - don't blindly trust everyone - bool bValid = false; - bool bMatchedHost = false; - CAutoOpUser* pUser = nullptr; - - for (const auto& it : m_msUsers) { - pUser = it.second; - - // First verify that the person who challenged us matches a user's - // host - if (pUser->HostMatches(Nick.GetHostMask())) { - const vector& Chans = GetNetwork()->GetChans(); - bMatchedHost = true; - - // Also verify that they are opped in at least one of the user's - // chans - for (CChan* pChan : Chans) { - const CNick* pNick = pChan->FindNick(Nick.GetNick()); - - if (pNick) { - if (pNick->HasPerm(CChan::Op) && - pUser->ChannelMatches(pChan->GetName())) { - bValid = true; - break; - } - } - } - - if (bValid) { - break; - } - } - } - - if (!bValid) { - if (bMatchedHost) { - PutModule("[" + Nick.GetHostMask() + - "] sent us a challenge but they are not opped in any " - "defined channels."); - } else { - PutModule("[" + Nick.GetHostMask() + - "] sent us a challenge but they do not match a " - "defined user."); - } - - return false; - } - - if (sChallenge.length() != AUTOOP_CHALLENGE_LENGTH) { - PutModule("WARNING! [" + Nick.GetHostMask() + - "] sent an invalid challenge."); - return false; - } - - CString sResponse = pUser->GetUserKey() + "::" + sChallenge; - PutIRC("NOTICE " + Nick.GetNick() + " :!ZNCAO RESPONSE " + - sResponse.MD5()); - return false; - } - - bool VerifyResponse(const CNick& Nick, const CString& sResponse) { - MCString::iterator itQueue = m_msQueue.find(Nick.GetNick().AsLower()); - - if (itQueue == m_msQueue.end()) { - PutModule( - "[" + Nick.GetHostMask() + - "] sent an unchallenged response. This could be due to lag."); - return false; - } - - CString sChallenge = itQueue->second; - m_msQueue.erase(itQueue); - - for (const auto& it : m_msUsers) { - if (it.second->HostMatches(Nick.GetHostMask())) { - if (sResponse == - CString(it.second->GetUserKey() + "::" + sChallenge) - .MD5()) { - OpUser(Nick, *it.second); - return true; - } else { - PutModule("WARNING! [" + Nick.GetHostMask() + - "] sent a bad response. Please verify that you " - "have their correct password."); - return false; - } - } - } - - PutModule("WARNING! [" + Nick.GetHostMask() + - "] sent a response but did not match any defined users."); - return false; - } - - void ProcessQueue() { - bool bRemoved = true; - - // First remove any stale challenges - - while (bRemoved) { - bRemoved = false; - - for (MCString::iterator it = m_msQueue.begin(); - it != m_msQueue.end(); ++it) { - if (!it->second.empty()) { - m_msQueue.erase(it); - bRemoved = true; - break; - } - } - } - - // Now issue challenges for the new users in the queue - for (auto& it : m_msQueue) { - it.second = CString::RandomString(AUTOOP_CHALLENGE_LENGTH); - PutIRC("NOTICE " + it.first + " :!ZNCAO CHALLENGE " + it.second); - } - } - - void OpUser(const CNick& Nick, const CAutoOpUser& User) { - const vector& Chans = GetNetwork()->GetChans(); - - for (CChan* pChan : Chans) { - if (pChan->HasPerm(CChan::Op) && - User.ChannelMatches(pChan->GetName())) { - const CNick* pNick = pChan->FindNick(Nick.GetNick()); - - if (pNick && !pNick->HasPerm(CChan::Op)) { - PutIRC("MODE " + pChan->GetName() + " +o " + - Nick.GetNick()); - } - } - } - } + MODCONSTRUCTOR(CAutoOpMod) { + AddHelpCommand(); + AddCommand("ListUsers", static_cast( + &CAutoOpMod::OnListUsersCommand), + "", "List all users"); + AddCommand("AddChans", static_cast( + &CAutoOpMod::OnAddChansCommand), + " [channel] ...", "Adds channels to a user"); + AddCommand("DelChans", static_cast( + &CAutoOpMod::OnDelChansCommand), + " [channel] ...", + "Removes channels from a user"); + AddCommand("AddMasks", static_cast( + &CAutoOpMod::OnAddMasksCommand), + " ,[mask] ...", "Adds masks to a user"); + AddCommand("DelMasks", static_cast( + &CAutoOpMod::OnDelMasksCommand), + " ,[mask] ...", "Removes masks from a user"); + AddCommand("AddUser", static_cast( + &CAutoOpMod::OnAddUserCommand), + " [,...] [channels]", + "Adds a user"); + AddCommand("DelUser", static_cast( + &CAutoOpMod::OnDelUserCommand), + "", "Removes a user"); + } + + bool OnLoad(const CString& sArgs, CString& sMessage) override { + AddTimer(new CAutoOpTimer(this)); + + // Load the users + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + const CString& sLine = it->second; + CAutoOpUser* pUser = new CAutoOpUser; + + if (!pUser->FromString(sLine) || + FindUser(pUser->GetUsername().AsLower())) { + delete pUser; + } else { + m_msUsers[pUser->GetUsername().AsLower()] = pUser; + } + } + + return true; + } + + virtual ~CAutoOpMod() { + for (const auto& it : m_msUsers) { + delete it.second; + } + m_msUsers.clear(); + } + + void OnJoin(const CNick& Nick, CChan& Channel) override { + // If we have ops in this chan + if (Channel.HasPerm(CChan::Op)) { + CheckAutoOp(Nick, Channel); + } + } + + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override { + MCString::iterator it = m_msQueue.find(Nick.GetNick().AsLower()); + + if (it != m_msQueue.end()) { + m_msQueue.erase(it); + } + } + + void OnNick(const CNick& OldNick, const CString& sNewNick, + const vector& vChans) override { + // Update the queue with nick changes + MCString::iterator it = m_msQueue.find(OldNick.GetNick().AsLower()); + + if (it != m_msQueue.end()) { + m_msQueue[sNewNick.AsLower()] = it->second; + m_msQueue.erase(it); + } + } + + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + if (!sMessage.Token(0).Equals("!ZNCAO")) { + return CONTINUE; + } + + CString sCommand = sMessage.Token(1); + + if (sCommand.Equals("CHALLENGE")) { + ChallengeRespond(Nick, sMessage.Token(2)); + } else if (sCommand.Equals("RESPONSE")) { + VerifyResponse(Nick, sMessage.Token(2)); + } + + return HALTCORE; + } + + void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + if (Nick.GetNick() == GetNetwork()->GetIRCNick().GetNick()) { + const map& msNicks = Channel.GetNicks(); + + for (const auto& it : msNicks) { + if (!it.second.HasPerm(CChan::Op)) { + CheckAutoOp(it.second, Channel); + } + } + } + } + + void OnModCommand(const CString& sLine) override { + CString sCommand = sLine.Token(0).AsUpper(); + if (sCommand.Equals("TIMERS")) { + // for testing purposes - hidden from help + ListTimers(); + } else { + HandleCommand(sLine); + } + } + + void OnAddUserCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sHost = sLine.Token(2); + CString sKey = sLine.Token(3); + + if (sHost.empty()) { + PutModule( + "Usage: AddUser [,...] " + "[channels]"); + } else { + CAutoOpUser* pUser = + AddUser(sUser, sKey, sHost, sLine.Token(4, true)); + + if (pUser) { + SetNV(sUser, pUser->ToString()); + } + } + } + + void OnDelUserCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + + if (sUser.empty()) { + PutModule("Usage: DelUser "); + } else { + DelUser(sUser); + DelNV(sUser); + } + } + + void OnListUsersCommand(const CString& sLine) { + if (m_msUsers.empty()) { + PutModule("There are no users defined"); + return; + } + + CTable Table; + + Table.AddColumn("User"); + Table.AddColumn("Hostmasks"); + Table.AddColumn("Key"); + Table.AddColumn("Channels"); + + for (const auto& it : m_msUsers) { + VCString vsHostmasks; + it.second->GetHostmasks().Split(",", vsHostmasks); + for (unsigned int a = 0; a < vsHostmasks.size(); a++) { + Table.AddRow(); + if (a == 0) { + Table.SetCell("User", it.second->GetUsername()); + Table.SetCell("Key", it.second->GetUserKey()); + Table.SetCell("Channels", it.second->GetChannels()); + } else if (a == vsHostmasks.size() - 1) { + Table.SetCell("User", "`-"); + } else { + Table.SetCell("User", "|-"); + } + Table.SetCell("Hostmasks", vsHostmasks[a]); + } + } + + PutModule(Table); + } + + void OnAddChansCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sChans = sLine.Token(2, true); + + if (sChans.empty()) { + PutModule("Usage: AddChans [channel] ..."); + return; + } + + CAutoOpUser* pUser = FindUser(sUser); + + if (!pUser) { + PutModule("No such user"); + return; + } + + pUser->AddChans(sChans); + PutModule("Channel(s) added to user [" + pUser->GetUsername() + "]"); + SetNV(pUser->GetUsername(), pUser->ToString()); + } + + void OnDelChansCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sChans = sLine.Token(2, true); + + if (sChans.empty()) { + PutModule("Usage: DelChans [channel] ..."); + return; + } + + CAutoOpUser* pUser = FindUser(sUser); + + if (!pUser) { + PutModule("No such user"); + return; + } + + pUser->DelChans(sChans); + PutModule("Channel(s) Removed from user [" + pUser->GetUsername() + + "]"); + SetNV(pUser->GetUsername(), pUser->ToString()); + } + + void OnAddMasksCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sHostmasks = sLine.Token(2, true); + + if (sHostmasks.empty()) { + PutModule("Usage: AddMasks ,[mask] ..."); + return; + } + + CAutoOpUser* pUser = FindUser(sUser); + + if (!pUser) { + PutModule("No such user"); + return; + } + + pUser->AddHostmasks(sHostmasks); + PutModule("Hostmasks(s) added to user [" + pUser->GetUsername() + "]"); + SetNV(pUser->GetUsername(), pUser->ToString()); + } + + void OnDelMasksCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sHostmasks = sLine.Token(2, true); + + if (sHostmasks.empty()) { + PutModule("Usage: DelMasks ,[mask] ..."); + return; + } + + CAutoOpUser* pUser = FindUser(sUser); + + if (!pUser) { + PutModule("No such user"); + return; + } + + if (pUser->DelHostmasks(sHostmasks)) { + PutModule("Removed user [" + pUser->GetUsername() + "] with key [" + + pUser->GetUserKey() + "] and channels [" + + pUser->GetChannels() + "]"); + DelUser(sUser); + DelNV(sUser); + } else { + PutModule("Hostmasks(s) Removed from user [" + + pUser->GetUsername() + "]"); + SetNV(pUser->GetUsername(), pUser->ToString()); + } + } + + CAutoOpUser* FindUser(const CString& sUser) { + map::iterator it = + m_msUsers.find(sUser.AsLower()); + + return (it != m_msUsers.end()) ? it->second : nullptr; + } + + CAutoOpUser* FindUserByHost(const CString& sHostmask, + const CString& sChannel = "") { + for (const auto& it : m_msUsers) { + CAutoOpUser* pUser = it.second; + + if (pUser->HostMatches(sHostmask) && + (sChannel.empty() || pUser->ChannelMatches(sChannel))) { + return pUser; + } + } + + return nullptr; + } + + bool CheckAutoOp(const CNick& Nick, CChan& Channel) { + CAutoOpUser* pUser = + FindUserByHost(Nick.GetHostMask(), Channel.GetName()); + + if (!pUser) { + return false; + } + + if (pUser->GetUserKey().Equals("__NOKEY__")) { + PutIRC("MODE " + Channel.GetName() + " +o " + Nick.GetNick()); + } else { + // then insert this nick into the queue, the timer does the rest + CString sNick = Nick.GetNick().AsLower(); + if (m_msQueue.find(sNick) == m_msQueue.end()) { + m_msQueue[sNick] = ""; + } + } + + return true; + } + + void DelUser(const CString& sUser) { + map::iterator it = + m_msUsers.find(sUser.AsLower()); + + if (it == m_msUsers.end()) { + PutModule("That user does not exist"); + return; + } + + delete it->second; + m_msUsers.erase(it); + PutModule("User [" + sUser + "] removed"); + } + + CAutoOpUser* AddUser(const CString& sUser, const CString& sKey, + const CString& sHosts, const CString& sChans) { + if (m_msUsers.find(sUser) != m_msUsers.end()) { + PutModule("That user already exists"); + return nullptr; + } + + CAutoOpUser* pUser = new CAutoOpUser(sUser, sKey, sHosts, sChans); + m_msUsers[sUser.AsLower()] = pUser; + PutModule("User [" + sUser + "] added with hostmask(s) [" + sHosts + + "]"); + return pUser; + } + + bool ChallengeRespond(const CNick& Nick, const CString& sChallenge) { + // Validate before responding - don't blindly trust everyone + bool bValid = false; + bool bMatchedHost = false; + CAutoOpUser* pUser = nullptr; + + for (const auto& it : m_msUsers) { + pUser = it.second; + + // First verify that the person who challenged us matches a user's + // host + if (pUser->HostMatches(Nick.GetHostMask())) { + const vector& Chans = GetNetwork()->GetChans(); + bMatchedHost = true; + + // Also verify that they are opped in at least one of the user's + // chans + for (CChan* pChan : Chans) { + const CNick* pNick = pChan->FindNick(Nick.GetNick()); + + if (pNick) { + if (pNick->HasPerm(CChan::Op) && + pUser->ChannelMatches(pChan->GetName())) { + bValid = true; + break; + } + } + } + + if (bValid) { + break; + } + } + } + + if (!bValid) { + if (bMatchedHost) { + PutModule("[" + Nick.GetHostMask() + + "] sent us a challenge but they are not opped in any " + "defined channels."); + } else { + PutModule("[" + Nick.GetHostMask() + + "] sent us a challenge but they do not match a " + "defined user."); + } + + return false; + } + + if (sChallenge.length() != AUTOOP_CHALLENGE_LENGTH) { + PutModule("WARNING! [" + Nick.GetHostMask() + + "] sent an invalid challenge."); + return false; + } + + CString sResponse = pUser->GetUserKey() + "::" + sChallenge; + PutIRC("NOTICE " + Nick.GetNick() + " :!ZNCAO RESPONSE " + + sResponse.MD5()); + return false; + } + + bool VerifyResponse(const CNick& Nick, const CString& sResponse) { + MCString::iterator itQueue = m_msQueue.find(Nick.GetNick().AsLower()); + + if (itQueue == m_msQueue.end()) { + PutModule( + "[" + Nick.GetHostMask() + + "] sent an unchallenged response. This could be due to lag."); + return false; + } + + CString sChallenge = itQueue->second; + m_msQueue.erase(itQueue); + + for (const auto& it : m_msUsers) { + if (it.second->HostMatches(Nick.GetHostMask())) { + if (sResponse == + CString(it.second->GetUserKey() + "::" + sChallenge) + .MD5()) { + OpUser(Nick, *it.second); + return true; + } else { + PutModule("WARNING! [" + Nick.GetHostMask() + + "] sent a bad response. Please verify that you " + "have their correct password."); + return false; + } + } + } + + PutModule("WARNING! [" + Nick.GetHostMask() + + "] sent a response but did not match any defined users."); + return false; + } + + void ProcessQueue() { + bool bRemoved = true; + + // First remove any stale challenges + + while (bRemoved) { + bRemoved = false; + + for (MCString::iterator it = m_msQueue.begin(); + it != m_msQueue.end(); ++it) { + if (!it->second.empty()) { + m_msQueue.erase(it); + bRemoved = true; + break; + } + } + } + + // Now issue challenges for the new users in the queue + for (auto& it : m_msQueue) { + it.second = CString::RandomString(AUTOOP_CHALLENGE_LENGTH); + PutIRC("NOTICE " + it.first + " :!ZNCAO CHALLENGE " + it.second); + } + } + + void OpUser(const CNick& Nick, const CAutoOpUser& User) { + const vector& Chans = GetNetwork()->GetChans(); + + for (CChan* pChan : Chans) { + if (pChan->HasPerm(CChan::Op) && + User.ChannelMatches(pChan->GetName())) { + const CNick* pNick = pChan->FindNick(Nick.GetNick()); + + if (pNick && !pNick->HasPerm(CChan::Op)) { + PutIRC("MODE " + pChan->GetName() + " +o " + + Nick.GetNick()); + } + } + } + } private: - map m_msUsers; - MCString m_msQueue; + map m_msUsers; + MCString m_msQueue; }; void CAutoOpTimer::RunJob() { m_pParent->ProcessQueue(); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("autoop"); + Info.SetWikiPage("autoop"); } NETWORKMODULEDEFS(CAutoOpMod, "Auto op the good people") diff --git a/modules/autoreply.cpp b/modules/autoreply.cpp index 33fcaa8e..f868ec43 100644 --- a/modules/autoreply.cpp +++ b/modules/autoreply.cpp @@ -20,80 +20,80 @@ class CAutoReplyMod : public CModule { public: - MODCONSTRUCTOR(CAutoReplyMod) { - AddHelpCommand(); - AddCommand("Set", static_cast( - &CAutoReplyMod::OnSetCommand), - "", "Sets a new reply"); - AddCommand("Show", static_cast( - &CAutoReplyMod::OnShowCommand), - "", "Displays the current query reply"); - m_Messaged.SetTTL(1000 * 120); - } + MODCONSTRUCTOR(CAutoReplyMod) { + AddHelpCommand(); + AddCommand("Set", static_cast( + &CAutoReplyMod::OnSetCommand), + "", "Sets a new reply"); + AddCommand("Show", static_cast( + &CAutoReplyMod::OnShowCommand), + "", "Displays the current query reply"); + m_Messaged.SetTTL(1000 * 120); + } - virtual ~CAutoReplyMod() {} + virtual ~CAutoReplyMod() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (!sArgs.empty()) { - SetReply(sArgs); - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (!sArgs.empty()) { + SetReply(sArgs); + } - return true; - } + return true; + } - void SetReply(const CString& sReply) { SetNV("Reply", sReply); } + void SetReply(const CString& sReply) { SetNV("Reply", sReply); } - CString GetReply() { - CString sReply = GetNV("Reply"); - if (sReply.empty()) { - sReply = "%nick% is currently away, try again later"; - SetReply(sReply); - } + CString GetReply() { + CString sReply = GetNV("Reply"); + if (sReply.empty()) { + sReply = "%nick% is currently away, try again later"; + SetReply(sReply); + } - return ExpandString(sReply); - } + return ExpandString(sReply); + } - void Handle(const CString& sNick) { - CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); - if (!pIRCSock) - // WTF? - return; - if (sNick == pIRCSock->GetNick()) return; - if (m_Messaged.HasItem(sNick)) return; + void Handle(const CString& sNick) { + CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); + if (!pIRCSock) + // WTF? + return; + if (sNick == pIRCSock->GetNick()) return; + if (m_Messaged.HasItem(sNick)) return; - if (GetNetwork()->IsUserAttached()) return; + if (GetNetwork()->IsUserAttached()) return; - m_Messaged.AddItem(sNick); - PutIRC("NOTICE " + sNick + " :" + GetReply()); - } + m_Messaged.AddItem(sNick); + PutIRC("NOTICE " + sNick + " :" + GetReply()); + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - Handle(Nick.GetNick()); - return CONTINUE; - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + Handle(Nick.GetNick()); + return CONTINUE; + } - void OnShowCommand(const CString& sCommand) { - PutModule("Current reply is: " + GetNV("Reply") + " (" + GetReply() + - ")"); - } + void OnShowCommand(const CString& sCommand) { + PutModule("Current reply is: " + GetNV("Reply") + " (" + GetReply() + + ")"); + } - void OnSetCommand(const CString& sCommand) { - SetReply(sCommand.Token(1, true)); - PutModule("New reply set"); - } + void OnSetCommand(const CString& sCommand) { + SetReply(sCommand.Token(1, true)); + PutModule("New reply set"); + } private: - TCacheMap m_Messaged; + TCacheMap m_Messaged; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("autoreply"); - Info.AddType(CModInfo::NetworkModule); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "You might specify a reply text. It is used when automatically " - "answering queries, if you are not connected to ZNC."); + Info.SetWikiPage("autoreply"); + Info.AddType(CModInfo::NetworkModule); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "You might specify a reply text. It is used when automatically " + "answering queries, if you are not connected to ZNC."); } USERMODULEDEFS(CAutoReplyMod, "Reply to queries when you are away") diff --git a/modules/autovoice.cpp b/modules/autovoice.cpp index 32025ae2..fd7f355e 100644 --- a/modules/autovoice.cpp +++ b/modules/autovoice.cpp @@ -23,346 +23,346 @@ using std::set; class CAutoVoiceUser { public: - CAutoVoiceUser() {} + CAutoVoiceUser() {} - CAutoVoiceUser(const CString& sLine) { FromString(sLine); } + CAutoVoiceUser(const CString& sLine) { FromString(sLine); } - CAutoVoiceUser(const CString& sUsername, const CString& sHostmask, - const CString& sChannels) - : m_sUsername(sUsername), m_sHostmask(sHostmask) { - AddChans(sChannels); - } + CAutoVoiceUser(const CString& sUsername, const CString& sHostmask, + const CString& sChannels) + : m_sUsername(sUsername), m_sHostmask(sHostmask) { + AddChans(sChannels); + } - virtual ~CAutoVoiceUser() {} + virtual ~CAutoVoiceUser() {} - const CString& GetUsername() const { return m_sUsername; } - const CString& GetHostmask() const { return m_sHostmask; } + const CString& GetUsername() const { return m_sUsername; } + const CString& GetHostmask() const { return m_sHostmask; } - bool ChannelMatches(const CString& sChan) const { - for (const CString& s : m_ssChans) { - if (sChan.AsLower().WildCmp(s, CString::CaseInsensitive)) { - return true; - } - } + bool ChannelMatches(const CString& sChan) const { + for (const CString& s : m_ssChans) { + if (sChan.AsLower().WildCmp(s, CString::CaseInsensitive)) { + return true; + } + } - return false; - } + return false; + } - bool HostMatches(const CString& sHostmask) { - return sHostmask.WildCmp(m_sHostmask, CString::CaseInsensitive); - } + bool HostMatches(const CString& sHostmask) { + return sHostmask.WildCmp(m_sHostmask, CString::CaseInsensitive); + } - CString GetChannels() const { - CString sRet; + CString GetChannels() const { + CString sRet; - for (const CString& sChan : m_ssChans) { - if (!sRet.empty()) { - sRet += " "; - } + for (const CString& sChan : m_ssChans) { + if (!sRet.empty()) { + sRet += " "; + } - sRet += sChan; - } + sRet += sChan; + } - return sRet; - } + return sRet; + } - void DelChans(const CString& sChans) { - VCString vsChans; - sChans.Split(" ", vsChans); + void DelChans(const CString& sChans) { + VCString vsChans; + sChans.Split(" ", vsChans); - for (const CString& sChan : vsChans) { - m_ssChans.erase(sChan.AsLower()); - } - } + for (const CString& sChan : vsChans) { + m_ssChans.erase(sChan.AsLower()); + } + } - void AddChans(const CString& sChans) { - VCString vsChans; - sChans.Split(" ", vsChans); + void AddChans(const CString& sChans) { + VCString vsChans; + sChans.Split(" ", vsChans); - for (const CString& sChan : vsChans) { - m_ssChans.insert(sChan.AsLower()); - } - } + for (const CString& sChan : vsChans) { + m_ssChans.insert(sChan.AsLower()); + } + } - CString ToString() const { - CString sChans; + CString ToString() const { + CString sChans; - for (const CString& sChan : m_ssChans) { - if (!sChans.empty()) { - sChans += " "; - } + for (const CString& sChan : m_ssChans) { + if (!sChans.empty()) { + sChans += " "; + } - sChans += sChan; - } + sChans += sChan; + } - return m_sUsername + "\t" + m_sHostmask + "\t" + sChans; - } + return m_sUsername + "\t" + m_sHostmask + "\t" + sChans; + } - bool FromString(const CString& sLine) { - m_sUsername = sLine.Token(0, false, "\t"); - m_sHostmask = sLine.Token(1, false, "\t"); - sLine.Token(2, false, "\t").Split(" ", m_ssChans); + bool FromString(const CString& sLine) { + m_sUsername = sLine.Token(0, false, "\t"); + m_sHostmask = sLine.Token(1, false, "\t"); + sLine.Token(2, false, "\t").Split(" ", m_ssChans); - return !m_sHostmask.empty(); - } + return !m_sHostmask.empty(); + } private: protected: - CString m_sUsername; - CString m_sHostmask; - set m_ssChans; + CString m_sUsername; + CString m_sHostmask; + set m_ssChans; }; class CAutoVoiceMod : public CModule { public: - MODCONSTRUCTOR(CAutoVoiceMod) { - AddHelpCommand(); - AddCommand("ListUsers", static_cast( - &CAutoVoiceMod::OnListUsersCommand), - "", "List all users"); - AddCommand("AddChans", static_cast( - &CAutoVoiceMod::OnAddChansCommand), - " [channel] ...", "Adds channels to a user"); - AddCommand("DelChans", static_cast( - &CAutoVoiceMod::OnDelChansCommand), - " [channel] ...", - "Removes channels from a user"); - AddCommand("AddUser", static_cast( - &CAutoVoiceMod::OnAddUserCommand), - " [channels]", "Adds a user"); - AddCommand("DelUser", static_cast( - &CAutoVoiceMod::OnDelUserCommand), - "", "Removes a user"); - } + MODCONSTRUCTOR(CAutoVoiceMod) { + AddHelpCommand(); + AddCommand("ListUsers", static_cast( + &CAutoVoiceMod::OnListUsersCommand), + "", "List all users"); + AddCommand("AddChans", static_cast( + &CAutoVoiceMod::OnAddChansCommand), + " [channel] ...", "Adds channels to a user"); + AddCommand("DelChans", static_cast( + &CAutoVoiceMod::OnDelChansCommand), + " [channel] ...", + "Removes channels from a user"); + AddCommand("AddUser", static_cast( + &CAutoVoiceMod::OnAddUserCommand), + " [channels]", "Adds a user"); + AddCommand("DelUser", static_cast( + &CAutoVoiceMod::OnDelUserCommand), + "", "Removes a user"); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - // Load the chans from the command line - unsigned int a = 0; - VCString vsChans; - sArgs.Split(" ", vsChans, false); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + // Load the chans from the command line + unsigned int a = 0; + VCString vsChans; + sArgs.Split(" ", vsChans, false); - for (const CString& sChan : vsChans) { - CString sName = "Args"; - sName += CString(a); - AddUser(sName, "*", sChan); - } + for (const CString& sChan : vsChans) { + CString sName = "Args"; + sName += CString(a); + AddUser(sName, "*", sChan); + } - // Load the saved users - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - const CString& sLine = it->second; - CAutoVoiceUser* pUser = new CAutoVoiceUser; + // Load the saved users + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + const CString& sLine = it->second; + CAutoVoiceUser* pUser = new CAutoVoiceUser; - if (!pUser->FromString(sLine) || - FindUser(pUser->GetUsername().AsLower())) { - delete pUser; - } else { - m_msUsers[pUser->GetUsername().AsLower()] = pUser; - } - } + if (!pUser->FromString(sLine) || + FindUser(pUser->GetUsername().AsLower())) { + delete pUser; + } else { + m_msUsers[pUser->GetUsername().AsLower()] = pUser; + } + } - return true; - } + return true; + } - virtual ~CAutoVoiceMod() { - for (const auto& it : m_msUsers) { - delete it.second; - } + virtual ~CAutoVoiceMod() { + for (const auto& it : m_msUsers) { + delete it.second; + } - m_msUsers.clear(); - } + m_msUsers.clear(); + } - void OnJoin(const CNick& Nick, CChan& Channel) override { - // If we have ops in this chan - if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) { - for (const auto& it : m_msUsers) { - // and the nick who joined is a valid user - if (it.second->HostMatches(Nick.GetHostMask()) && - it.second->ChannelMatches(Channel.GetName())) { - PutIRC("MODE " + Channel.GetName() + " +v " + - Nick.GetNick()); - break; - } - } - } - } + void OnJoin(const CNick& Nick, CChan& Channel) override { + // If we have ops in this chan + if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) { + for (const auto& it : m_msUsers) { + // and the nick who joined is a valid user + if (it.second->HostMatches(Nick.GetHostMask()) && + it.second->ChannelMatches(Channel.GetName())) { + PutIRC("MODE " + Channel.GetName() + " +v " + + Nick.GetNick()); + break; + } + } + } + } - void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - if (Nick.NickEquals(GetNetwork()->GetNick())) { - const map& msNicks = Channel.GetNicks(); + void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + if (Nick.NickEquals(GetNetwork()->GetNick())) { + const map& msNicks = Channel.GetNicks(); - for (const auto& it : msNicks) { - if (!it.second.HasPerm(CChan::Voice)) { - CheckAutoVoice(it.second, Channel); - } - } - } - } + for (const auto& it : msNicks) { + if (!it.second.HasPerm(CChan::Voice)) { + CheckAutoVoice(it.second, Channel); + } + } + } + } - bool CheckAutoVoice(const CNick& Nick, CChan& Channel) { - CAutoVoiceUser* pUser = - FindUserByHost(Nick.GetHostMask(), Channel.GetName()); - if (!pUser) { - return false; - } + bool CheckAutoVoice(const CNick& Nick, CChan& Channel) { + CAutoVoiceUser* pUser = + FindUserByHost(Nick.GetHostMask(), Channel.GetName()); + if (!pUser) { + return false; + } - PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); - return true; - } + PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); + return true; + } - void OnAddUserCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sHost = sLine.Token(2); + void OnAddUserCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sHost = sLine.Token(2); - if (sHost.empty()) { - PutModule("Usage: AddUser [channels]"); - } else { - CAutoVoiceUser* pUser = AddUser(sUser, sHost, sLine.Token(3, true)); + if (sHost.empty()) { + PutModule("Usage: AddUser [channels]"); + } else { + CAutoVoiceUser* pUser = AddUser(sUser, sHost, sLine.Token(3, true)); - if (pUser) { - SetNV(sUser, pUser->ToString()); - } - } - } + if (pUser) { + SetNV(sUser, pUser->ToString()); + } + } + } - void OnDelUserCommand(const CString& sLine) { - CString sUser = sLine.Token(1); + void OnDelUserCommand(const CString& sLine) { + CString sUser = sLine.Token(1); - if (sUser.empty()) { - PutModule("Usage: DelUser "); - } else { - DelUser(sUser); - DelNV(sUser); - } - } + if (sUser.empty()) { + PutModule("Usage: DelUser "); + } else { + DelUser(sUser); + DelNV(sUser); + } + } - void OnListUsersCommand(const CString& sLine) { - if (m_msUsers.empty()) { - PutModule("There are no users defined"); - return; - } + void OnListUsersCommand(const CString& sLine) { + if (m_msUsers.empty()) { + PutModule("There are no users defined"); + return; + } - CTable Table; + CTable Table; - Table.AddColumn("User"); - Table.AddColumn("Hostmask"); - Table.AddColumn("Channels"); + Table.AddColumn("User"); + Table.AddColumn("Hostmask"); + Table.AddColumn("Channels"); - for (const auto& it : m_msUsers) { - Table.AddRow(); - Table.SetCell("User", it.second->GetUsername()); - Table.SetCell("Hostmask", it.second->GetHostmask()); - Table.SetCell("Channels", it.second->GetChannels()); - } + for (const auto& it : m_msUsers) { + Table.AddRow(); + Table.SetCell("User", it.second->GetUsername()); + Table.SetCell("Hostmask", it.second->GetHostmask()); + Table.SetCell("Channels", it.second->GetChannels()); + } - PutModule(Table); - } + PutModule(Table); + } - void OnAddChansCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sChans = sLine.Token(2, true); + void OnAddChansCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sChans = sLine.Token(2, true); - if (sChans.empty()) { - PutModule("Usage: AddChans [channel] ..."); - return; - } + if (sChans.empty()) { + PutModule("Usage: AddChans [channel] ..."); + return; + } - CAutoVoiceUser* pUser = FindUser(sUser); + CAutoVoiceUser* pUser = FindUser(sUser); - if (!pUser) { - PutModule("No such user"); - return; - } + if (!pUser) { + PutModule("No such user"); + return; + } - pUser->AddChans(sChans); - PutModule("Channel(s) added to user [" + pUser->GetUsername() + "]"); + pUser->AddChans(sChans); + PutModule("Channel(s) added to user [" + pUser->GetUsername() + "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } + SetNV(pUser->GetUsername(), pUser->ToString()); + } - void OnDelChansCommand(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sChans = sLine.Token(2, true); + void OnDelChansCommand(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sChans = sLine.Token(2, true); - if (sChans.empty()) { - PutModule("Usage: DelChans [channel] ..."); - return; - } + if (sChans.empty()) { + PutModule("Usage: DelChans [channel] ..."); + return; + } - CAutoVoiceUser* pUser = FindUser(sUser); + CAutoVoiceUser* pUser = FindUser(sUser); - if (!pUser) { - PutModule("No such user"); - return; - } + if (!pUser) { + PutModule("No such user"); + return; + } - pUser->DelChans(sChans); - PutModule("Channel(s) Removed from user [" + pUser->GetUsername() + - "]"); + pUser->DelChans(sChans); + PutModule("Channel(s) Removed from user [" + pUser->GetUsername() + + "]"); - SetNV(pUser->GetUsername(), pUser->ToString()); - } + SetNV(pUser->GetUsername(), pUser->ToString()); + } - CAutoVoiceUser* FindUser(const CString& sUser) { - map::iterator it = - m_msUsers.find(sUser.AsLower()); + CAutoVoiceUser* FindUser(const CString& sUser) { + map::iterator it = + m_msUsers.find(sUser.AsLower()); - return (it != m_msUsers.end()) ? it->second : nullptr; - } + return (it != m_msUsers.end()) ? it->second : nullptr; + } - CAutoVoiceUser* FindUserByHost(const CString& sHostmask, - const CString& sChannel = "") { - for (const auto& it : m_msUsers) { - CAutoVoiceUser* pUser = it.second; + CAutoVoiceUser* FindUserByHost(const CString& sHostmask, + const CString& sChannel = "") { + for (const auto& it : m_msUsers) { + CAutoVoiceUser* pUser = it.second; - if (pUser->HostMatches(sHostmask) && - (sChannel.empty() || pUser->ChannelMatches(sChannel))) { - return pUser; - } - } + if (pUser->HostMatches(sHostmask) && + (sChannel.empty() || pUser->ChannelMatches(sChannel))) { + return pUser; + } + } - return nullptr; - } + return nullptr; + } - void DelUser(const CString& sUser) { - map::iterator it = - m_msUsers.find(sUser.AsLower()); + void DelUser(const CString& sUser) { + map::iterator it = + m_msUsers.find(sUser.AsLower()); - if (it == m_msUsers.end()) { - PutModule("That user does not exist"); - return; - } + if (it == m_msUsers.end()) { + PutModule("That user does not exist"); + return; + } - delete it->second; - m_msUsers.erase(it); - PutModule("User [" + sUser + "] removed"); - } + delete it->second; + m_msUsers.erase(it); + PutModule("User [" + sUser + "] removed"); + } - CAutoVoiceUser* AddUser(const CString& sUser, const CString& sHost, - const CString& sChans) { - if (m_msUsers.find(sUser) != m_msUsers.end()) { - PutModule("That user already exists"); - return nullptr; - } + CAutoVoiceUser* AddUser(const CString& sUser, const CString& sHost, + const CString& sChans) { + if (m_msUsers.find(sUser) != m_msUsers.end()) { + PutModule("That user already exists"); + return nullptr; + } - CAutoVoiceUser* pUser = new CAutoVoiceUser(sUser, sHost, sChans); - m_msUsers[sUser.AsLower()] = pUser; - PutModule("User [" + sUser + "] added with hostmask [" + sHost + "]"); - return pUser; - } + CAutoVoiceUser* pUser = new CAutoVoiceUser(sUser, sHost, sChans); + m_msUsers[sUser.AsLower()] = pUser; + PutModule("User [" + sUser + "] added with hostmask [" + sHost + "]"); + return pUser; + } private: - map m_msUsers; + map m_msUsers; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("autovoice"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "Each argument is either a channel you want autovoice for (which can " - "include wildcards) or, if it starts with !, it is an exception for " - "autovoice."); + Info.SetWikiPage("autovoice"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "Each argument is either a channel you want autovoice for (which can " + "include wildcards) or, if it starts with !, it is an exception for " + "autovoice."); } NETWORKMODULEDEFS(CAutoVoiceMod, "Auto voice the good people") diff --git a/modules/awaynick.cpp b/modules/awaynick.cpp index e74331ae..a4792961 100644 --- a/modules/awaynick.cpp +++ b/modules/awaynick.cpp @@ -18,17 +18,17 @@ class CAwayNickMod : public CModule { public: - MODCONSTRUCTOR(CAwayNickMod) {} + MODCONSTRUCTOR(CAwayNickMod) {} - bool OnLoad(const CString&, CString& sMessage) override { - sMessage = "retired module - see http://wiki.znc.in/awaynick"; - return false; - } + bool OnLoad(const CString&, CString& sMessage) override { + sMessage = "retired module - see http://wiki.znc.in/awaynick"; + return false; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("awaynick"); + Info.SetWikiPage("awaynick"); } NETWORKMODULEDEFS(CAwayNickMod, diff --git a/modules/awaystore.cpp b/modules/awaystore.cpp index 2d441c14..c928b599 100644 --- a/modules/awaystore.cpp +++ b/modules/awaystore.cpp @@ -45,480 +45,480 @@ class CAway; class CAwayJob : public CTimer { public: - CAwayJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + CAwayJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CAwayJob() {} + virtual ~CAwayJob() {} protected: - void RunJob() override; + void RunJob() override; }; class CAway : public CModule { - void AwayCommand(const CString& sCommand) { - CString sReason; - time_t curtime; - time(&curtime); + void AwayCommand(const CString& sCommand) { + CString sReason; + time_t curtime; + time(&curtime); - if (sCommand.Token(1) != "-quiet") { - sReason = CUtils::FormatTime(curtime, sCommand.Token(1, true), - GetUser()->GetTimezone()); - PutModNotice("You have been marked as away"); - } else { - sReason = CUtils::FormatTime(curtime, sCommand.Token(2, true), - GetUser()->GetTimezone()); - } + if (sCommand.Token(1) != "-quiet") { + sReason = CUtils::FormatTime(curtime, sCommand.Token(1, true), + GetUser()->GetTimezone()); + PutModNotice("You have been marked as away"); + } else { + sReason = CUtils::FormatTime(curtime, sCommand.Token(2, true), + GetUser()->GetTimezone()); + } - Away(false, sReason); - } + Away(false, sReason); + } - void BackCommand(const CString& sCommand) { - if ((m_vMessages.empty()) && (sCommand.Token(1) != "-quiet")) - PutModNotice("Welcome Back!"); - Ping(); - Back(); - } + void BackCommand(const CString& sCommand) { + if ((m_vMessages.empty()) && (sCommand.Token(1) != "-quiet")) + PutModNotice("Welcome Back!"); + Ping(); + Back(); + } - void MessagesCommand(const CString& sCommand) { - for (u_int a = 0; a < m_vMessages.size(); a++) - PutModule(m_vMessages[a]); - } + void MessagesCommand(const CString& sCommand) { + for (u_int a = 0; a < m_vMessages.size(); a++) + PutModule(m_vMessages[a]); + } - void ReplayCommand(const CString& sCommand) { - CString nick = GetClient()->GetNick(); - for (u_int a = 0; a < m_vMessages.size(); a++) { - CString sWhom = m_vMessages[a].Token(1, false, ":"); - CString sMessage = m_vMessages[a].Token(2, true, ":"); - PutUser(":" + sWhom + " PRIVMSG " + nick + " :" + sMessage); - } - } + void ReplayCommand(const CString& sCommand) { + CString nick = GetClient()->GetNick(); + for (u_int a = 0; a < m_vMessages.size(); a++) { + CString sWhom = m_vMessages[a].Token(1, false, ":"); + CString sMessage = m_vMessages[a].Token(2, true, ":"); + PutUser(":" + sWhom + " PRIVMSG " + nick + " :" + sMessage); + } + } - void DeleteCommand(const CString& sCommand) { - CString sWhich = sCommand.Token(1); - if (sWhich == "all") { - PutModNotice("Deleted " + CString(m_vMessages.size()) + - " Messages."); - for (u_int a = 0; a < m_vMessages.size(); a++) - m_vMessages.erase(m_vMessages.begin() + a--); - } else if (sWhich.empty()) { - PutModNotice("USAGE: delete "); - return; - } else { - u_int iNum = sWhich.ToUInt(); - if (iNum >= m_vMessages.size()) { - PutModNotice("Illegal Message # Requested"); - return; - } else { - m_vMessages.erase(m_vMessages.begin() + iNum); - PutModNotice("Message Erased."); - } - SaveBufferToDisk(); - } - } + void DeleteCommand(const CString& sCommand) { + CString sWhich = sCommand.Token(1); + if (sWhich == "all") { + PutModNotice("Deleted " + CString(m_vMessages.size()) + + " Messages."); + for (u_int a = 0; a < m_vMessages.size(); a++) + m_vMessages.erase(m_vMessages.begin() + a--); + } else if (sWhich.empty()) { + PutModNotice("USAGE: delete "); + return; + } else { + u_int iNum = sWhich.ToUInt(); + if (iNum >= m_vMessages.size()) { + PutModNotice("Illegal Message # Requested"); + return; + } else { + m_vMessages.erase(m_vMessages.begin() + iNum); + PutModNotice("Message Erased."); + } + SaveBufferToDisk(); + } + } - void SaveCommand(const CString& sCommand) { - if (m_saveMessages) { - SaveBufferToDisk(); - PutModNotice("Messages saved to disk."); - } else { - PutModNotice("There are no messages to save."); - } - } + void SaveCommand(const CString& sCommand) { + if (m_saveMessages) { + SaveBufferToDisk(); + PutModNotice("Messages saved to disk."); + } else { + PutModNotice("There are no messages to save."); + } + } - void PingCommand(const CString& sCommand) { - Ping(); - if (m_bIsAway) Back(); - } + void PingCommand(const CString& sCommand) { + Ping(); + if (m_bIsAway) Back(); + } - void PassCommand(const CString& sCommand) { - m_sPassword = sCommand.Token(1); - PutModNotice("Password Updated to [" + m_sPassword + "]"); - } + void PassCommand(const CString& sCommand) { + m_sPassword = sCommand.Token(1); + PutModNotice("Password Updated to [" + m_sPassword + "]"); + } - void ShowCommand(const CString& sCommand) { - map> msvOutput; - for (u_int a = 0; a < m_vMessages.size(); a++) { - CString sTime = m_vMessages[a].Token(0, false); - CString sWhom = m_vMessages[a].Token(1, false); - CString sMessage = m_vMessages[a].Token(2, true); + void ShowCommand(const CString& sCommand) { + map> msvOutput; + for (u_int a = 0; a < m_vMessages.size(); a++) { + CString sTime = m_vMessages[a].Token(0, false); + CString sWhom = m_vMessages[a].Token(1, false); + CString sMessage = m_vMessages[a].Token(2, true); - if ((sTime.empty()) || (sWhom.empty()) || (sMessage.empty())) { - // illegal format - PutModule("Corrupt message! [" + m_vMessages[a] + "]"); - m_vMessages.erase(m_vMessages.begin() + a--); - continue; - } + if ((sTime.empty()) || (sWhom.empty()) || (sMessage.empty())) { + // illegal format + PutModule("Corrupt message! [" + m_vMessages[a] + "]"); + m_vMessages.erase(m_vMessages.begin() + a--); + continue; + } - time_t iTime = sTime.ToULong(); - char szFormat[64]; - struct tm t; - localtime_r(&iTime, &t); - size_t iCount = strftime(szFormat, 64, "%F %T", &t); + time_t iTime = sTime.ToULong(); + char szFormat[64]; + struct tm t; + localtime_r(&iTime, &t); + size_t iCount = strftime(szFormat, 64, "%F %T", &t); - if (iCount <= 0) { - PutModule("Corrupt time stamp! [" + m_vMessages[a] + "]"); - m_vMessages.erase(m_vMessages.begin() + a--); - continue; - } + if (iCount <= 0) { + PutModule("Corrupt time stamp! [" + m_vMessages[a] + "]"); + m_vMessages.erase(m_vMessages.begin() + a--); + continue; + } - CString sTmp = " " + CString(a) + ") ["; - sTmp.append(szFormat, iCount); - sTmp += "] "; - sTmp += sMessage; - msvOutput[sWhom].push_back(sTmp); - } + CString sTmp = " " + CString(a) + ") ["; + sTmp.append(szFormat, iCount); + sTmp += "] "; + sTmp += sMessage; + msvOutput[sWhom].push_back(sTmp); + } - for (map>::iterator it = msvOutput.begin(); - it != msvOutput.end(); ++it) { - PutModule(it->first); - for (u_int a = 0; a < it->second.size(); a++) - PutModule(it->second[a]); - } + for (map>::iterator it = msvOutput.begin(); + it != msvOutput.end(); ++it) { + PutModule(it->first); + for (u_int a = 0; a < it->second.size(); a++) + PutModule(it->second[a]); + } - PutModule("#--- End Messages"); - } + PutModule("#--- End Messages"); + } - void EnableTimerCommand(const CString& sCommand) { - SetAwayTime(300); - PutModule("Timer set to 300 seconds"); - } + void EnableTimerCommand(const CString& sCommand) { + SetAwayTime(300); + PutModule("Timer set to 300 seconds"); + } - void DisableTimerCommand(const CString& sCommand) { - SetAwayTime(0); - PutModule("Timer disabled"); - } + void DisableTimerCommand(const CString& sCommand) { + SetAwayTime(0); + PutModule("Timer disabled"); + } - void SetTimerCommand(const CString& sCommand) { - int iSetting = sCommand.Token(1).ToInt(); + void SetTimerCommand(const CString& sCommand) { + int iSetting = sCommand.Token(1).ToInt(); - SetAwayTime(iSetting); + SetAwayTime(iSetting); - if (iSetting == 0) - PutModule("Timer disabled"); - else - PutModule("Timer set to " + CString(iSetting) + " seconds"); - } + if (iSetting == 0) + PutModule("Timer disabled"); + else + PutModule("Timer set to " + CString(iSetting) + " seconds"); + } - void TimerCommand(const CString& sCommand) { - PutModule("Current timer setting: " + CString(GetAwayTime()) + - " seconds"); - } + void TimerCommand(const CString& sCommand) { + PutModule("Current timer setting: " + CString(GetAwayTime()) + + " seconds"); + } public: - MODCONSTRUCTOR(CAway) { - Ping(); - m_bIsAway = false; - m_bBootError = false; - m_saveMessages = true; - m_chanMessages = false; - SetAwayTime(300); - AddTimer( - new CAwayJob(this, 60, 0, "AwayJob", - "Checks for idle and saves messages every 1 minute")); + MODCONSTRUCTOR(CAway) { + Ping(); + m_bIsAway = false; + m_bBootError = false; + m_saveMessages = true; + m_chanMessages = false; + SetAwayTime(300); + AddTimer( + new CAwayJob(this, 60, 0, "AwayJob", + "Checks for idle and saves messages every 1 minute")); - AddHelpCommand(); - AddCommand("Away", - static_cast(&CAway::AwayCommand), - "[-quiet]"); - AddCommand("Back", - static_cast(&CAway::BackCommand), - "[-quiet]"); - AddCommand("Messages", - static_cast(&CAway::BackCommand)); - AddCommand("Delete", - static_cast(&CAway::DeleteCommand), - "delete "); - AddCommand("Save", - static_cast(&CAway::SaveCommand)); - AddCommand("Ping", - static_cast(&CAway::PingCommand)); - AddCommand("Pass", - static_cast(&CAway::PassCommand)); - AddCommand("Show", - static_cast(&CAway::ShowCommand)); - AddCommand("Replay", - static_cast(&CAway::ReplayCommand)); - AddCommand("EnableTimer", static_cast( - &CAway::EnableTimerCommand)); - AddCommand("DisableTimer", static_cast( - &CAway::DisableTimerCommand)); - AddCommand("SetTimer", static_cast( - &CAway::SetTimerCommand), - ""); - AddCommand("Timer", - static_cast(&CAway::TimerCommand)); - } + AddHelpCommand(); + AddCommand("Away", + static_cast(&CAway::AwayCommand), + "[-quiet]"); + AddCommand("Back", + static_cast(&CAway::BackCommand), + "[-quiet]"); + AddCommand("Messages", + static_cast(&CAway::BackCommand)); + AddCommand("Delete", + static_cast(&CAway::DeleteCommand), + "delete "); + AddCommand("Save", + static_cast(&CAway::SaveCommand)); + AddCommand("Ping", + static_cast(&CAway::PingCommand)); + AddCommand("Pass", + static_cast(&CAway::PassCommand)); + AddCommand("Show", + static_cast(&CAway::ShowCommand)); + AddCommand("Replay", + static_cast(&CAway::ReplayCommand)); + AddCommand("EnableTimer", static_cast( + &CAway::EnableTimerCommand)); + AddCommand("DisableTimer", static_cast( + &CAway::DisableTimerCommand)); + AddCommand("SetTimer", static_cast( + &CAway::SetTimerCommand), + ""); + AddCommand("Timer", + static_cast(&CAway::TimerCommand)); + } - virtual ~CAway() { - if (!m_bBootError) SaveBufferToDisk(); - } + virtual ~CAway() { + if (!m_bBootError) SaveBufferToDisk(); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - CString sMyArgs = sArgs; - size_t uIndex = 0; - if (sMyArgs.Token(0) == "-nostore") { - uIndex++; - m_saveMessages = false; - } - if (sMyArgs.Token(uIndex) == "-chans") { - uIndex++; - m_chanMessages = true; - } - if (sMyArgs.Token(uIndex) == "-notimer") { - SetAwayTime(0); - sMyArgs = sMyArgs.Token(uIndex + 1, true); - } else if (sMyArgs.Token(uIndex) == "-timer") { - SetAwayTime(sMyArgs.Token(uIndex + 1).ToInt()); - sMyArgs = sMyArgs.Token(uIndex + 2, true); - } - if (m_saveMessages) { - if (!sMyArgs.empty()) { - m_sPassword = CBlowfish::MD5(sMyArgs); - } else { - sMessage = - "This module needs as an argument a keyphrase used for " - "encryption"; - return false; - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + CString sMyArgs = sArgs; + size_t uIndex = 0; + if (sMyArgs.Token(0) == "-nostore") { + uIndex++; + m_saveMessages = false; + } + if (sMyArgs.Token(uIndex) == "-chans") { + uIndex++; + m_chanMessages = true; + } + if (sMyArgs.Token(uIndex) == "-notimer") { + SetAwayTime(0); + sMyArgs = sMyArgs.Token(uIndex + 1, true); + } else if (sMyArgs.Token(uIndex) == "-timer") { + SetAwayTime(sMyArgs.Token(uIndex + 1).ToInt()); + sMyArgs = sMyArgs.Token(uIndex + 2, true); + } + if (m_saveMessages) { + if (!sMyArgs.empty()) { + m_sPassword = CBlowfish::MD5(sMyArgs); + } else { + sMessage = + "This module needs as an argument a keyphrase used for " + "encryption"; + return false; + } - if (!BootStrap()) { - sMessage = - "Failed to decrypt your saved messages - " - "Did you give the right encryption key as an argument to " - "this module?"; - m_bBootError = true; - return false; - } - } + if (!BootStrap()) { + sMessage = + "Failed to decrypt your saved messages - " + "Did you give the right encryption key as an argument to " + "this module?"; + m_bBootError = true; + return false; + } + } - return true; - } + return true; + } - void OnIRCConnected() override { - if (m_bIsAway) { - Away(true); // reset away if we are reconnected - } else { - // ircd seems to remember your away if you killed the client and - // came back - Back(); - } - } + void OnIRCConnected() override { + if (m_bIsAway) { + Away(true); // reset away if we are reconnected + } else { + // ircd seems to remember your away if you killed the client and + // came back + Back(); + } + } - bool BootStrap() { - CString sFile; - if (DecryptMessages(sFile)) { - VCString vsLines; - VCString::iterator it; + bool BootStrap() { + CString sFile; + if (DecryptMessages(sFile)) { + VCString vsLines; + VCString::iterator it; - sFile.Split("\n", vsLines); + sFile.Split("\n", vsLines); - for (it = vsLines.begin(); it != vsLines.end(); ++it) { - CString sLine(*it); - sLine.Trim(); - AddMessage(sLine); - } - } else { - m_sPassword = ""; - CUtils::PrintError("[" + GetModName() + - ".so] Failed to Decrypt Messages"); - return (false); - } + for (it = vsLines.begin(); it != vsLines.end(); ++it) { + CString sLine(*it); + sLine.Trim(); + AddMessage(sLine); + } + } else { + m_sPassword = ""; + CUtils::PrintError("[" + GetModName() + + ".so] Failed to Decrypt Messages"); + return (false); + } - return (true); - } + return (true); + } - void SaveBufferToDisk() { - if (!m_sPassword.empty()) { - CString sFile = CRYPT_VERIFICATION_TOKEN; + void SaveBufferToDisk() { + if (!m_sPassword.empty()) { + CString sFile = CRYPT_VERIFICATION_TOKEN; - for (u_int b = 0; b < m_vMessages.size(); b++) - sFile += m_vMessages[b] + "\n"; + for (u_int b = 0; b < m_vMessages.size(); b++) + sFile += m_vMessages[b] + "\n"; - CBlowfish c(m_sPassword, BF_ENCRYPT); - sFile = c.Crypt(sFile); - CString sPath = GetPath(); - if (!sPath.empty()) { - CFile File(sPath); - if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { - File.Chmod(0600); - File.Write(sFile); - } - File.Close(); - } - } - } + CBlowfish c(m_sPassword, BF_ENCRYPT); + sFile = c.Crypt(sFile); + CString sPath = GetPath(); + if (!sPath.empty()) { + CFile File(sPath); + if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { + File.Chmod(0600); + File.Write(sFile); + } + File.Close(); + } + } + } - void OnClientLogin() override { Back(true); } - void OnClientDisconnect() override { Away(); } + void OnClientLogin() override { Back(true); } + void OnClientDisconnect() override { Away(); } - CString GetPath() { - CString sBuffer = GetUser()->GetUserName(); - CString sRet = GetSavePath(); - sRet += "/.znc-away-" + CBlowfish::MD5(sBuffer, true); - return (sRet); - } + CString GetPath() { + CString sBuffer = GetUser()->GetUserName(); + CString sRet = GetSavePath(); + sRet += "/.znc-away-" + CBlowfish::MD5(sBuffer, true); + return (sRet); + } - void Away(bool bForce = false, const CString& sReason = "") { - if ((!m_bIsAway) || (bForce)) { - if (!bForce) - m_sReason = sReason; - else if (!sReason.empty()) - m_sReason = sReason; + void Away(bool bForce = false, const CString& sReason = "") { + if ((!m_bIsAway) || (bForce)) { + if (!bForce) + m_sReason = sReason; + else if (!sReason.empty()) + m_sReason = sReason; - time_t iTime = time(nullptr); - char* pTime = ctime(&iTime); - CString sTime; - if (pTime) { - sTime = pTime; - sTime.Trim(); - } - if (m_sReason.empty()) m_sReason = "Auto Away at " + sTime; - PutIRC("AWAY :" + m_sReason); - m_bIsAway = true; - } - } + time_t iTime = time(nullptr); + char* pTime = ctime(&iTime); + CString sTime; + if (pTime) { + sTime = pTime; + sTime.Trim(); + } + if (m_sReason.empty()) m_sReason = "Auto Away at " + sTime; + PutIRC("AWAY :" + m_sReason); + m_bIsAway = true; + } + } - void Back(bool bUsePrivMessage = false) { - PutIRC("away"); - m_bIsAway = false; - if (!m_vMessages.empty()) { - if (bUsePrivMessage) { - PutModule("Welcome Back!"); - PutModule("You have " + CString(m_vMessages.size()) + - " messages!"); - } else { - PutModNotice("Welcome Back!"); - PutModNotice("You have " + CString(m_vMessages.size()) + - " messages!"); - } - } - m_sReason = ""; - } + void Back(bool bUsePrivMessage = false) { + PutIRC("away"); + m_bIsAway = false; + if (!m_vMessages.empty()) { + if (bUsePrivMessage) { + PutModule("Welcome Back!"); + PutModule("You have " + CString(m_vMessages.size()) + + " messages!"); + } else { + PutModNotice("Welcome Back!"); + PutModNotice("You have " + CString(m_vMessages.size()) + + " messages!"); + } + } + m_sReason = ""; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - if (m_bIsAway) AddMessage(time(nullptr), Nick, sMessage); - return (CONTINUE); - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + if (m_bIsAway) AddMessage(time(nullptr), Nick, sMessage); + return (CONTINUE); + } - EModRet OnChanMsg(CNick& nick, CChan& channel, CString& sMessage) override { - if (m_bIsAway && m_chanMessages && - sMessage.AsLower().find(m_pNetwork->GetCurNick().AsLower()) != - CString::npos) { - AddMessage(time(nullptr), nick, channel.GetName() + " " + sMessage); - } + EModRet OnChanMsg(CNick& nick, CChan& channel, CString& sMessage) override { + if (m_bIsAway && m_chanMessages && + sMessage.AsLower().find(m_pNetwork->GetCurNick().AsLower()) != + CString::npos) { + AddMessage(time(nullptr), nick, channel.GetName() + " " + sMessage); + } - return (CONTINUE); - } + return (CONTINUE); + } - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { - if (m_bIsAway) { - AddMessage(time(nullptr), Nick, "* " + sMessage); - } - return (CONTINUE); - } + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { + if (m_bIsAway) { + AddMessage(time(nullptr), Nick, "* " + sMessage); + } + return (CONTINUE); + } - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - Ping(); - if (m_bIsAway) Back(); + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + Ping(); + if (m_bIsAway) Back(); - return (CONTINUE); - } + return (CONTINUE); + } - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - Ping(); - if (m_bIsAway) Back(); + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + Ping(); + if (m_bIsAway) Back(); - return (CONTINUE); - } + return (CONTINUE); + } - EModRet OnUserAction(CString& sTarget, CString& sMessage) override { - Ping(); - if (m_bIsAway) Back(); + EModRet OnUserAction(CString& sTarget, CString& sMessage) override { + Ping(); + if (m_bIsAway) Back(); - return (CONTINUE); - } + return (CONTINUE); + } - time_t GetTimeStamp() const { return (m_iLastSentData); } - void Ping() { m_iLastSentData = time(nullptr); } - time_t GetAwayTime() { return m_iAutoAway; } - void SetAwayTime(time_t u) { m_iAutoAway = u; } + time_t GetTimeStamp() const { return (m_iLastSentData); } + void Ping() { m_iLastSentData = time(nullptr); } + time_t GetAwayTime() { return m_iAutoAway; } + void SetAwayTime(time_t u) { m_iAutoAway = u; } - bool IsAway() { return (m_bIsAway); } + bool IsAway() { return (m_bIsAway); } private: - CString m_sPassword; - bool m_bBootError; - bool DecryptMessages(CString& sBuffer) { - CString sMessages = GetPath(); - CString sFile; - sBuffer = ""; + CString m_sPassword; + bool m_bBootError; + bool DecryptMessages(CString& sBuffer) { + CString sMessages = GetPath(); + CString sFile; + sBuffer = ""; - CFile File(sMessages); + CFile File(sMessages); - if (sMessages.empty() || !File.Open() || !File.ReadFile(sFile)) { - PutModule("Unable to find buffer"); - return (true); // gonna be successful here - } + if (sMessages.empty() || !File.Open() || !File.ReadFile(sFile)) { + PutModule("Unable to find buffer"); + return (true); // gonna be successful here + } - File.Close(); + File.Close(); - if (!sFile.empty()) { - CBlowfish c(m_sPassword, BF_DECRYPT); - sBuffer = c.Crypt(sFile); + if (!sFile.empty()) { + CBlowfish c(m_sPassword, BF_DECRYPT); + sBuffer = c.Crypt(sFile); - if (sBuffer.Left(strlen(CRYPT_VERIFICATION_TOKEN)) != - CRYPT_VERIFICATION_TOKEN) { - // failed to decode :( - PutModule("Unable to decode Encrypted messages"); - return (false); - } - sBuffer.erase(0, strlen(CRYPT_VERIFICATION_TOKEN)); - } - return (true); - } + if (sBuffer.Left(strlen(CRYPT_VERIFICATION_TOKEN)) != + CRYPT_VERIFICATION_TOKEN) { + // failed to decode :( + PutModule("Unable to decode Encrypted messages"); + return (false); + } + sBuffer.erase(0, strlen(CRYPT_VERIFICATION_TOKEN)); + } + return (true); + } - void AddMessage(time_t iTime, const CNick& Nick, const CString& sMessage) { - if (Nick.GetNick() == GetNetwork()->GetIRCNick().GetNick()) - return; // ignore messages from self - AddMessage(CString(iTime) + " " + Nick.GetNickMask() + " " + sMessage); - } + void AddMessage(time_t iTime, const CNick& Nick, const CString& sMessage) { + if (Nick.GetNick() == GetNetwork()->GetIRCNick().GetNick()) + return; // ignore messages from self + AddMessage(CString(iTime) + " " + Nick.GetNickMask() + " " + sMessage); + } - void AddMessage(const CString& sText) { - if (m_saveMessages) { - m_vMessages.push_back(sText); - } - } + void AddMessage(const CString& sText) { + if (m_saveMessages) { + m_vMessages.push_back(sText); + } + } - time_t m_iLastSentData; - bool m_bIsAway; - time_t m_iAutoAway; - vector m_vMessages; - CString m_sReason; - bool m_saveMessages; - bool m_chanMessages; + time_t m_iLastSentData; + bool m_bIsAway; + time_t m_iAutoAway; + vector m_vMessages; + CString m_sReason; + bool m_saveMessages; + bool m_chanMessages; }; void CAwayJob::RunJob() { - CAway* p = (CAway*)GetModule(); - p->SaveBufferToDisk(); + CAway* p = (CAway*)GetModule(); + p->SaveBufferToDisk(); - if (!p->IsAway()) { - time_t iNow = time(nullptr); + if (!p->IsAway()) { + time_t iNow = time(nullptr); - if ((iNow - p->GetTimeStamp()) > p->GetAwayTime() && - p->GetAwayTime() != 0) - p->Away(); - } + if ((iNow - p->GetTimeStamp()) > p->GetAwayTime() && + p->GetAwayTime() != 0) + p->Away(); + } } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("awaystore"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "[ -notimer | -timer N ] [-chans] passw0rd . N is number of seconds, " - "600 by default."); + Info.SetWikiPage("awaystore"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "[ -notimer | -timer N ] [-chans] passw0rd . N is number of seconds, " + "600 by default."); } NETWORKMODULEDEFS(CAway, diff --git a/modules/block_motd.cpp b/modules/block_motd.cpp index fdb1c981..c77b63eb 100644 --- a/modules/block_motd.cpp +++ b/modules/block_motd.cpp @@ -18,54 +18,54 @@ class CBlockMotd : public CModule { public: - MODCONSTRUCTOR(CBlockMotd) { - AddHelpCommand(); - AddCommand("GetMotd", static_cast( - &CBlockMotd::OverrideCommand), - "[]", - "Override the block with this command. Can optionally " - "specify which server to query."); - } + MODCONSTRUCTOR(CBlockMotd) { + AddHelpCommand(); + AddCommand("GetMotd", static_cast( + &CBlockMotd::OverrideCommand), + "[]", + "Override the block with this command. Can optionally " + "specify which server to query."); + } - virtual ~CBlockMotd() {} + virtual ~CBlockMotd() {} - void OverrideCommand(const CString& sLine) { - m_bTemporaryAcceptMotd = true; - const CString sServer = sLine.Token(1); + void OverrideCommand(const CString& sLine) { + m_bTemporaryAcceptMotd = true; + const CString sServer = sLine.Token(1); - if (sServer.empty()) { - PutIRC("motd"); - } else { - PutIRC("motd " + sServer); - } - } + if (sServer.empty()) { + PutIRC("motd"); + } else { + PutIRC("motd " + sServer); + } + } - EModRet OnRaw(CString& sLine) override { - const CString sCmd = sLine.Token(1); + EModRet OnRaw(CString& sLine) override { + const CString sCmd = sLine.Token(1); - if ((sCmd == "375" /* begin of MOTD */ || sCmd == "372" /* MOTD */) && - !m_bTemporaryAcceptMotd) - return HALT; + if ((sCmd == "375" /* begin of MOTD */ || sCmd == "372" /* MOTD */) && + !m_bTemporaryAcceptMotd) + return HALT; - if (sCmd == "376" /* End of MOTD */) { - if (!m_bTemporaryAcceptMotd) { - sLine = sLine.Token(0) + " 422 " + sLine.Token(2) + - " :MOTD blocked by ZNC"; - } - m_bTemporaryAcceptMotd = false; - } - return CONTINUE; - } + if (sCmd == "376" /* End of MOTD */) { + if (!m_bTemporaryAcceptMotd) { + sLine = sLine.Token(0) + " 422 " + sLine.Token(2) + + " :MOTD blocked by ZNC"; + } + m_bTemporaryAcceptMotd = false; + } + return CONTINUE; + } private: - bool m_bTemporaryAcceptMotd = false; + bool m_bTemporaryAcceptMotd = false; }; template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::NetworkModule); - Info.AddType(CModInfo::GlobalModule); - Info.SetWikiPage("block_motd"); + Info.AddType(CModInfo::NetworkModule); + Info.AddType(CModInfo::GlobalModule); + Info.SetWikiPage("block_motd"); } USERMODULEDEFS(CBlockMotd, diff --git a/modules/blockuser.cpp b/modules/blockuser.cpp index 8534cf09..39fb05a5 100644 --- a/modules/blockuser.cpp +++ b/modules/blockuser.cpp @@ -23,192 +23,192 @@ using std::vector; class CBlockUser : public CModule { public: - MODCONSTRUCTOR(CBlockUser) { - AddHelpCommand(); - AddCommand("List", static_cast( - &CBlockUser::OnListCommand), - "", "List blocked users"); - AddCommand("Block", static_cast( - &CBlockUser::OnBlockCommand), - "", "Block a user"); - AddCommand("Unblock", static_cast( - &CBlockUser::OnUnblockCommand), - "", "Unblock a user"); - } + MODCONSTRUCTOR(CBlockUser) { + AddHelpCommand(); + AddCommand("List", static_cast( + &CBlockUser::OnListCommand), + "", "List blocked users"); + AddCommand("Block", static_cast( + &CBlockUser::OnBlockCommand), + "", "Block a user"); + AddCommand("Unblock", static_cast( + &CBlockUser::OnUnblockCommand), + "", "Unblock a user"); + } - virtual ~CBlockUser() {} + virtual ~CBlockUser() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - VCString vArgs; - VCString::iterator it; - MCString::iterator it2; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + VCString vArgs; + VCString::iterator it; + MCString::iterator it2; - // Load saved settings - for (it2 = BeginNV(); it2 != EndNV(); ++it2) { - // Ignore errors - Block(it2->first); - } + // Load saved settings + for (it2 = BeginNV(); it2 != EndNV(); ++it2) { + // Ignore errors + Block(it2->first); + } - // Parse arguments, each argument is a user name to block - sArgs.Split(" ", vArgs, false); + // Parse arguments, each argument is a user name to block + sArgs.Split(" ", vArgs, false); - for (it = vArgs.begin(); it != vArgs.end(); ++it) { - if (!Block(*it)) { - sMessage = "Could not block [" + *it + "]"; - return false; - } - } + for (it = vArgs.begin(); it != vArgs.end(); ++it) { + if (!Block(*it)) { + sMessage = "Could not block [" + *it + "]"; + return false; + } + } - return true; - } + return true; + } - EModRet OnLoginAttempt(std::shared_ptr Auth) override { - if (IsBlocked(Auth->GetUsername())) { - Auth->RefuseLogin(MESSAGE); - return HALT; - } + EModRet OnLoginAttempt(std::shared_ptr Auth) override { + if (IsBlocked(Auth->GetUsername())) { + Auth->RefuseLogin(MESSAGE); + return HALT; + } - return CONTINUE; - } + return CONTINUE; + } - void OnModCommand(const CString& sCommand) override { - if (!GetUser()->IsAdmin()) { - PutModule("Access denied"); - } else { - HandleCommand(sCommand); - } - } + void OnModCommand(const CString& sCommand) override { + if (!GetUser()->IsAdmin()) { + PutModule("Access denied"); + } else { + HandleCommand(sCommand); + } + } - void OnListCommand(const CString& sCommand) { - CTable Table; - MCString::iterator it; + void OnListCommand(const CString& sCommand) { + CTable Table; + MCString::iterator it; - Table.AddColumn("Blocked user"); + Table.AddColumn("Blocked user"); - for (it = BeginNV(); it != EndNV(); ++it) { - Table.AddRow(); - Table.SetCell("Blocked user", it->first); - } + for (it = BeginNV(); it != EndNV(); ++it) { + Table.AddRow(); + Table.SetCell("Blocked user", it->first); + } - if (PutModule(Table) == 0) PutModule("No users blocked"); - } + if (PutModule(Table) == 0) PutModule("No users blocked"); + } - void OnBlockCommand(const CString& sCommand) { - CString sUser = sCommand.Token(1, true); + void OnBlockCommand(const CString& sCommand) { + CString sUser = sCommand.Token(1, true); - if (sUser.empty()) { - PutModule("Usage: Block "); - return; - } + if (sUser.empty()) { + PutModule("Usage: Block "); + return; + } - if (GetUser()->GetUserName().Equals(sUser)) { - PutModule("You can't block yourself"); - return; - } + if (GetUser()->GetUserName().Equals(sUser)) { + PutModule("You can't block yourself"); + return; + } - if (Block(sUser)) - PutModule("Blocked [" + sUser + "]"); - else - PutModule("Could not block [" + sUser + "] (misspelled?)"); - } + if (Block(sUser)) + PutModule("Blocked [" + sUser + "]"); + else + PutModule("Could not block [" + sUser + "] (misspelled?)"); + } - void OnUnblockCommand(const CString& sCommand) { - CString sUser = sCommand.Token(1, true); + void OnUnblockCommand(const CString& sCommand) { + CString sUser = sCommand.Token(1, true); - if (sUser.empty()) { - PutModule("Usage: Unblock "); - return; - } + if (sUser.empty()) { + PutModule("Usage: Unblock "); + return; + } - if (DelNV(sUser)) - PutModule("Unblocked [" + sUser + "]"); - else - PutModule("This user is not blocked"); - } + if (DelNV(sUser)) + PutModule("Unblocked [" + sUser + "]"); + else + PutModule("This user is not blocked"); + } - bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "webadmin/user" && WebSock.GetSession()->IsAdmin()) { - CString sAction = Tmpl["WebadminAction"]; - if (sAction == "display") { - Tmpl["Blocked"] = CString(IsBlocked(Tmpl["Username"])); - Tmpl["Self"] = CString(Tmpl["Username"].Equals( - WebSock.GetSession()->GetUser()->GetUserName())); - return true; - } - if (sAction == "change" && - WebSock.GetParam("embed_blockuser_presented").ToBool()) { - if (Tmpl["Username"].Equals( - WebSock.GetSession()->GetUser()->GetUserName()) && - WebSock.GetParam("embed_blockuser_block").ToBool()) { - WebSock.GetSession()->AddError("You can't block yourself"); - } else if (WebSock.GetParam("embed_blockuser_block").ToBool()) { - if (!WebSock.GetParam("embed_blockuser_old").ToBool()) { - if (Block(Tmpl["Username"])) { - WebSock.GetSession()->AddSuccess( - "Blocked [" + Tmpl["Username"] + "]"); - } else { - WebSock.GetSession()->AddError( - "Couldn't block [" + Tmpl["Username"] + "]"); - } - } - } else if (WebSock.GetParam("embed_blockuser_old").ToBool()) { - if (DelNV(Tmpl["Username"])) { - WebSock.GetSession()->AddSuccess( - "Unblocked [" + Tmpl["Username"] + "]"); - } else { - WebSock.GetSession()->AddError( - "User [" + Tmpl["Username"] + "is not blocked"); - } - } - return true; - } - } - return false; - } + bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "webadmin/user" && WebSock.GetSession()->IsAdmin()) { + CString sAction = Tmpl["WebadminAction"]; + if (sAction == "display") { + Tmpl["Blocked"] = CString(IsBlocked(Tmpl["Username"])); + Tmpl["Self"] = CString(Tmpl["Username"].Equals( + WebSock.GetSession()->GetUser()->GetUserName())); + return true; + } + if (sAction == "change" && + WebSock.GetParam("embed_blockuser_presented").ToBool()) { + if (Tmpl["Username"].Equals( + WebSock.GetSession()->GetUser()->GetUserName()) && + WebSock.GetParam("embed_blockuser_block").ToBool()) { + WebSock.GetSession()->AddError("You can't block yourself"); + } else if (WebSock.GetParam("embed_blockuser_block").ToBool()) { + if (!WebSock.GetParam("embed_blockuser_old").ToBool()) { + if (Block(Tmpl["Username"])) { + WebSock.GetSession()->AddSuccess( + "Blocked [" + Tmpl["Username"] + "]"); + } else { + WebSock.GetSession()->AddError( + "Couldn't block [" + Tmpl["Username"] + "]"); + } + } + } else if (WebSock.GetParam("embed_blockuser_old").ToBool()) { + if (DelNV(Tmpl["Username"])) { + WebSock.GetSession()->AddSuccess( + "Unblocked [" + Tmpl["Username"] + "]"); + } else { + WebSock.GetSession()->AddError( + "User [" + Tmpl["Username"] + "is not blocked"); + } + } + return true; + } + } + return false; + } private: - bool IsBlocked(const CString& sUser) { - MCString::iterator it; - for (it = BeginNV(); it != EndNV(); ++it) { - if (sUser == it->first) { - return true; - } - } - return false; - } + bool IsBlocked(const CString& sUser) { + MCString::iterator it; + for (it = BeginNV(); it != EndNV(); ++it) { + if (sUser == it->first) { + return true; + } + } + return false; + } - bool Block(const CString& sUser) { - CUser* pUser = CZNC::Get().FindUser(sUser); + bool Block(const CString& sUser) { + CUser* pUser = CZNC::Get().FindUser(sUser); - if (!pUser) return false; + if (!pUser) return false; - // Disconnect all clients - vector vpClients = pUser->GetAllClients(); - vector::iterator it; - for (it = vpClients.begin(); it != vpClients.end(); ++it) { - (*it)->PutStatusNotice(MESSAGE); - (*it)->Close(Csock::CLT_AFTERWRITE); - } + // Disconnect all clients + vector vpClients = pUser->GetAllClients(); + vector::iterator it; + for (it = vpClients.begin(); it != vpClients.end(); ++it) { + (*it)->PutStatusNotice(MESSAGE); + (*it)->Close(Csock::CLT_AFTERWRITE); + } - // Disconnect all networks from irc - vector vNetworks = pUser->GetNetworks(); - for (vector::iterator it2 = vNetworks.begin(); - it2 != vNetworks.end(); ++it2) { - (*it2)->SetIRCConnectEnabled(false); - } + // Disconnect all networks from irc + vector vNetworks = pUser->GetNetworks(); + for (vector::iterator it2 = vNetworks.begin(); + it2 != vNetworks.end(); ++it2) { + (*it2)->SetIRCConnectEnabled(false); + } - SetNV(pUser->GetUserName(), ""); - return true; - } + SetNV(pUser->GetUserName(), ""); + return true; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("blockuser"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "Enter one or more user names. Separate them by spaces."); + Info.SetWikiPage("blockuser"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "Enter one or more user names. Separate them by spaces."); } GLOBALMODULEDEFS(CBlockUser, "Block certain users from logging in.") diff --git a/modules/bouncedcc.cpp b/modules/bouncedcc.cpp index 749616b6..8d30ba63 100644 --- a/modules/bouncedcc.cpp +++ b/modules/bouncedcc.cpp @@ -23,70 +23,70 @@ class CBounceDCCMod; class CDCCBounce : public CSocket { public: - CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort, - const CString& sFileName, const CString& sRemoteNick, - const CString& sRemoteIP, bool bIsChat = false); - CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, - unsigned short uPort, const CString& sRemoteNick, - const CString& sRemoteIP, const CString& sFileName, - int iTimeout = 60, bool bIsChat = false); - virtual ~CDCCBounce(); + CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort, + const CString& sFileName, const CString& sRemoteNick, + const CString& sRemoteIP, bool bIsChat = false); + CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, + unsigned short uPort, const CString& sRemoteNick, + const CString& sRemoteIP, const CString& sFileName, + int iTimeout = 60, bool bIsChat = false); + virtual ~CDCCBounce(); - static unsigned short DCCRequest(const CString& sNick, - unsigned long uLongIP, - unsigned short uPort, - const CString& sFileName, bool bIsChat, - CBounceDCCMod* pMod, - const CString& sRemoteIP); + static unsigned short DCCRequest(const CString& sNick, + unsigned long uLongIP, + unsigned short uPort, + const CString& sFileName, bool bIsChat, + CBounceDCCMod* pMod, + const CString& sRemoteIP); - void ReadLine(const CString& sData) override; - void ReadData(const char* data, size_t len) override; - void ReadPaused() override; - void Timeout() override; - void ConnectionRefused() override; - void ReachedMaxBuffer() override; - void SockError(int iErrno, const CString& sDescription) override; - void Connected() override; - void Disconnected() override; - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; - void Shutdown(); - void PutServ(const CString& sLine); - void PutPeer(const CString& sLine); - bool IsPeerConnected() { - return (m_pPeer) ? m_pPeer->IsConnected() : false; - } + void ReadLine(const CString& sData) override; + void ReadData(const char* data, size_t len) override; + void ReadPaused() override; + void Timeout() override; + void ConnectionRefused() override; + void ReachedMaxBuffer() override; + void SockError(int iErrno, const CString& sDescription) override; + void Connected() override; + void Disconnected() override; + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + void Shutdown(); + void PutServ(const CString& sLine); + void PutPeer(const CString& sLine); + bool IsPeerConnected() { + return (m_pPeer) ? m_pPeer->IsConnected() : false; + } - // Setters - void SetPeer(CDCCBounce* p) { m_pPeer = p; } - void SetRemoteIP(const CString& s) { m_sRemoteIP = s; } - void SetRemoteNick(const CString& s) { m_sRemoteNick = s; } - void SetRemote(bool b) { m_bIsRemote = b; } - // !Setters + // Setters + void SetPeer(CDCCBounce* p) { m_pPeer = p; } + void SetRemoteIP(const CString& s) { m_sRemoteIP = s; } + void SetRemoteNick(const CString& s) { m_sRemoteNick = s; } + void SetRemote(bool b) { m_bIsRemote = b; } + // !Setters - // Getters - unsigned short GetUserPort() const { return m_uRemotePort; } - const CString& GetRemoteAddr() const { return m_sRemoteIP; } - const CString& GetRemoteNick() const { return m_sRemoteNick; } - const CString& GetFileName() const { return m_sFileName; } - CDCCBounce* GetPeer() const { return m_pPeer; } - bool IsRemote() { return m_bIsRemote; } - bool IsChat() { return m_bIsChat; } - // !Getters + // Getters + unsigned short GetUserPort() const { return m_uRemotePort; } + const CString& GetRemoteAddr() const { return m_sRemoteIP; } + const CString& GetRemoteNick() const { return m_sRemoteNick; } + const CString& GetFileName() const { return m_sFileName; } + CDCCBounce* GetPeer() const { return m_pPeer; } + bool IsRemote() { return m_bIsRemote; } + bool IsChat() { return m_bIsChat; } + // !Getters private: protected: - CString m_sRemoteNick; - CString m_sRemoteIP; - CString m_sConnectIP; - CString m_sLocalIP; - CString m_sFileName; - CBounceDCCMod* m_pModule; - CDCCBounce* m_pPeer; - unsigned short m_uRemotePort; - bool m_bIsChat; - bool m_bIsRemote; + CString m_sRemoteNick; + CString m_sRemoteIP; + CString m_sConnectIP; + CString m_sLocalIP; + CString m_sFileName; + CBounceDCCMod* m_pModule; + CDCCBounce* m_pPeer; + unsigned short m_uRemotePort; + bool m_bIsChat; + bool m_bIsRemote; - static const unsigned int m_uiMaxDCCBuffer; - static const unsigned int m_uiMinDCCBuffer; + static const unsigned int m_uiMaxDCCBuffer; + static const unsigned int m_uiMinDCCBuffer; }; // If we buffer more than this in memory, we will throttle the receiving side @@ -96,226 +96,226 @@ const unsigned int CDCCBounce::m_uiMinDCCBuffer = 2 * 1024; class CBounceDCCMod : public CModule { public: - void ListDCCsCommand(const CString& sLine) { - CTable Table; - Table.AddColumn("Type"); - Table.AddColumn("State"); - Table.AddColumn("Speed"); - Table.AddColumn("Nick"); - Table.AddColumn("IP"); - Table.AddColumn("File"); + void ListDCCsCommand(const CString& sLine) { + CTable Table; + Table.AddColumn("Type"); + Table.AddColumn("State"); + Table.AddColumn("Speed"); + Table.AddColumn("Nick"); + Table.AddColumn("IP"); + Table.AddColumn("File"); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCBounce* pSock = (CDCCBounce*)*it; - CString sSockName = pSock->GetSockName(); + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCBounce* pSock = (CDCCBounce*)*it; + CString sSockName = pSock->GetSockName(); - if (!(pSock->IsRemote())) { - Table.AddRow(); - Table.SetCell("Nick", pSock->GetRemoteNick()); - Table.SetCell("IP", pSock->GetRemoteAddr()); + if (!(pSock->IsRemote())) { + Table.AddRow(); + Table.SetCell("Nick", pSock->GetRemoteNick()); + Table.SetCell("IP", pSock->GetRemoteAddr()); - if (pSock->IsChat()) { - Table.SetCell("Type", "Chat"); - } else { - Table.SetCell("Type", "Xfer"); - Table.SetCell("File", pSock->GetFileName()); - } + if (pSock->IsChat()) { + Table.SetCell("Type", "Chat"); + } else { + Table.SetCell("Type", "Xfer"); + Table.SetCell("File", pSock->GetFileName()); + } - CString sState = "Waiting"; - if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) { - sState = "Halfway"; - if ((pSock->IsConnected()) && (pSock->IsPeerConnected())) { - sState = "Connected"; - } - } - Table.SetCell("State", sState); - } - } + CString sState = "Waiting"; + if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) { + sState = "Halfway"; + if ((pSock->IsConnected()) && (pSock->IsPeerConnected())) { + sState = "Connected"; + } + } + Table.SetCell("State", sState); + } + } - if (PutModule(Table) == 0) { - PutModule("You have no active DCCs."); - } - } + if (PutModule(Table) == 0) { + PutModule("You have no active DCCs."); + } + } - void UseClientIPCommand(const CString& sLine) { - CString sValue = sLine.Token(1, true); + void UseClientIPCommand(const CString& sLine) { + CString sValue = sLine.Token(1, true); - if (!sValue.empty()) { - SetNV("UseClientIP", sValue); - } + if (!sValue.empty()) { + SetNV("UseClientIP", sValue); + } - PutModule("UseClientIP: " + CString(GetNV("UseClientIP").ToBool())); - } + PutModule("UseClientIP: " + CString(GetNV("UseClientIP").ToBool())); + } - MODCONSTRUCTOR(CBounceDCCMod) { - AddHelpCommand(); - AddCommand("ListDCCs", static_cast( - &CBounceDCCMod::ListDCCsCommand), - "", "List all active DCCs"); - AddCommand("UseClientIP", static_cast( - &CBounceDCCMod::UseClientIPCommand), - ""); - } + MODCONSTRUCTOR(CBounceDCCMod) { + AddHelpCommand(); + AddCommand("ListDCCs", static_cast( + &CBounceDCCMod::ListDCCsCommand), + "", "List all active DCCs"); + AddCommand("UseClientIP", static_cast( + &CBounceDCCMod::UseClientIPCommand), + ""); + } - virtual ~CBounceDCCMod() {} + virtual ~CBounceDCCMod() {} - CString GetLocalDCCIP() { return GetUser()->GetLocalDCCIP(); } + CString GetLocalDCCIP() { return GetUser()->GetLocalDCCIP(); } - bool UseClientIP() { return GetNV("UseClientIP").ToBool(); } + bool UseClientIP() { return GetNV("UseClientIP").ToBool(); } - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { - if (sMessage.StartsWith("DCC ")) { - CString sType = - sMessage.Token(1, false, " ", false, "\"", "\"", true); - CString sFile = - sMessage.Token(2, false, " ", false, "\"", "\"", false); - unsigned long uLongIP = sMessage.Token(3, false, " ", false, "\"", - "\"", true).ToULong(); - unsigned short uPort = sMessage.Token(4, false, " ", false, "\"", - "\"", true).ToUShort(); - unsigned long uFileSize = sMessage.Token(5, false, " ", false, "\"", - "\"", true).ToULong(); - CString sIP = GetLocalDCCIP(); + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { + if (sMessage.StartsWith("DCC ")) { + CString sType = + sMessage.Token(1, false, " ", false, "\"", "\"", true); + CString sFile = + sMessage.Token(2, false, " ", false, "\"", "\"", false); + unsigned long uLongIP = sMessage.Token(3, false, " ", false, "\"", + "\"", true).ToULong(); + unsigned short uPort = sMessage.Token(4, false, " ", false, "\"", + "\"", true).ToUShort(); + unsigned long uFileSize = sMessage.Token(5, false, " ", false, "\"", + "\"", true).ToULong(); + CString sIP = GetLocalDCCIP(); - if (!UseClientIP()) { - uLongIP = CUtils::GetLongIP(GetClient()->GetRemoteIP()); - } + if (!UseClientIP()) { + uLongIP = CUtils::GetLongIP(GetClient()->GetRemoteIP()); + } - if (sType.Equals("CHAT")) { - unsigned short uBNCPort = CDCCBounce::DCCRequest( - sTarget, uLongIP, uPort, "", true, this, ""); - if (uBNCPort) { - PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + - CString(CUtils::GetLongIP(sIP)) + " " + - CString(uBNCPort) + "\001"); - } - } else if (sType.Equals("SEND")) { - // DCC SEND readme.txt 403120438 5550 1104 - unsigned short uBNCPort = CDCCBounce::DCCRequest( - sTarget, uLongIP, uPort, sFile, false, this, ""); - if (uBNCPort) { - PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + - " " + CString(CUtils::GetLongIP(sIP)) + " " + - CString(uBNCPort) + " " + CString(uFileSize) + - "\001"); - } - } else if (sType.Equals("RESUME")) { - // PRIVMSG user :DCC RESUME "znc.o" 58810 151552 - unsigned short uResumePort = sMessage.Token(3).ToUShort(); + if (sType.Equals("CHAT")) { + unsigned short uBNCPort = CDCCBounce::DCCRequest( + sTarget, uLongIP, uPort, "", true, this, ""); + if (uBNCPort) { + PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + + CString(CUtils::GetLongIP(sIP)) + " " + + CString(uBNCPort) + "\001"); + } + } else if (sType.Equals("SEND")) { + // DCC SEND readme.txt 403120438 5550 1104 + unsigned short uBNCPort = CDCCBounce::DCCRequest( + sTarget, uLongIP, uPort, sFile, false, this, ""); + if (uBNCPort) { + PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + + " " + CString(CUtils::GetLongIP(sIP)) + " " + + CString(uBNCPort) + " " + CString(uFileSize) + + "\001"); + } + } else if (sType.Equals("RESUME")) { + // PRIVMSG user :DCC RESUME "znc.o" 58810 151552 + unsigned short uResumePort = sMessage.Token(3).ToUShort(); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCBounce* pSock = (CDCCBounce*)*it; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCBounce* pSock = (CDCCBounce*)*it; - if (pSock->GetLocalPort() == uResumePort) { - PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + - " " + sFile + " " + - CString(pSock->GetUserPort()) + " " + - sMessage.Token(4) + "\001"); - } - } - } else if (sType.Equals("ACCEPT")) { - // Need to lookup the connection by port, filter the port, and - // forward to the user + if (pSock->GetLocalPort() == uResumePort) { + PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + + " " + sFile + " " + + CString(pSock->GetUserPort()) + " " + + sMessage.Token(4) + "\001"); + } + } + } else if (sType.Equals("ACCEPT")) { + // Need to lookup the connection by port, filter the port, and + // forward to the user - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCBounce* pSock = (CDCCBounce*)*it; - if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) { - PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + - " " + sFile + " " + - CString(pSock->GetLocalPort()) + " " + - sMessage.Token(4) + "\001"); - } - } - } + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCBounce* pSock = (CDCCBounce*)*it; + if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) { + PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + + " " + sFile + " " + + CString(pSock->GetLocalPort()) + " " + + sMessage.Token(4) + "\001"); + } + } + } - return HALTCORE; - } + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - CIRCNetwork* pNetwork = GetNetwork(); - if (sMessage.StartsWith("DCC ") && pNetwork->IsUserAttached()) { - // DCC CHAT chat 2453612361 44592 - CString sType = - sMessage.Token(1, false, " ", false, "\"", "\"", true); - CString sFile = - sMessage.Token(2, false, " ", false, "\"", "\"", false); - unsigned long uLongIP = sMessage.Token(3, false, " ", false, "\"", - "\"", true).ToULong(); - unsigned short uPort = sMessage.Token(4, false, " ", false, "\"", - "\"", true).ToUShort(); - unsigned long uFileSize = sMessage.Token(5, false, " ", false, "\"", - "\"", true).ToULong(); + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + CIRCNetwork* pNetwork = GetNetwork(); + if (sMessage.StartsWith("DCC ") && pNetwork->IsUserAttached()) { + // DCC CHAT chat 2453612361 44592 + CString sType = + sMessage.Token(1, false, " ", false, "\"", "\"", true); + CString sFile = + sMessage.Token(2, false, " ", false, "\"", "\"", false); + unsigned long uLongIP = sMessage.Token(3, false, " ", false, "\"", + "\"", true).ToULong(); + unsigned short uPort = sMessage.Token(4, false, " ", false, "\"", + "\"", true).ToUShort(); + unsigned long uFileSize = sMessage.Token(5, false, " ", false, "\"", + "\"", true).ToULong(); - if (sType.Equals("CHAT")) { - CNick FromNick(Nick.GetNickMask()); - unsigned short uBNCPort = CDCCBounce::DCCRequest( - FromNick.GetNick(), uLongIP, uPort, "", true, this, - CUtils::GetIP(uLongIP)); - if (uBNCPort) { - CString sIP = GetLocalDCCIP(); - PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + - pNetwork->GetCurNick() + " :\001DCC CHAT chat " + - CString(CUtils::GetLongIP(sIP)) + " " + - CString(uBNCPort) + "\001"); - } - } else if (sType.Equals("SEND")) { - // DCC SEND readme.txt 403120438 5550 1104 - unsigned short uBNCPort = CDCCBounce::DCCRequest( - Nick.GetNick(), uLongIP, uPort, sFile, false, this, - CUtils::GetIP(uLongIP)); - if (uBNCPort) { - CString sIP = GetLocalDCCIP(); - PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + - pNetwork->GetCurNick() + " :\001DCC SEND " + sFile + - " " + CString(CUtils::GetLongIP(sIP)) + " " + - CString(uBNCPort) + " " + CString(uFileSize) + - "\001"); - } - } else if (sType.Equals("RESUME")) { - // Need to lookup the connection by port, filter the port, and - // forward to the user - unsigned short uResumePort = sMessage.Token(3).ToUShort(); + if (sType.Equals("CHAT")) { + CNick FromNick(Nick.GetNickMask()); + unsigned short uBNCPort = CDCCBounce::DCCRequest( + FromNick.GetNick(), uLongIP, uPort, "", true, this, + CUtils::GetIP(uLongIP)); + if (uBNCPort) { + CString sIP = GetLocalDCCIP(); + PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + + pNetwork->GetCurNick() + " :\001DCC CHAT chat " + + CString(CUtils::GetLongIP(sIP)) + " " + + CString(uBNCPort) + "\001"); + } + } else if (sType.Equals("SEND")) { + // DCC SEND readme.txt 403120438 5550 1104 + unsigned short uBNCPort = CDCCBounce::DCCRequest( + Nick.GetNick(), uLongIP, uPort, sFile, false, this, + CUtils::GetIP(uLongIP)); + if (uBNCPort) { + CString sIP = GetLocalDCCIP(); + PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + + pNetwork->GetCurNick() + " :\001DCC SEND " + sFile + + " " + CString(CUtils::GetLongIP(sIP)) + " " + + CString(uBNCPort) + " " + CString(uFileSize) + + "\001"); + } + } else if (sType.Equals("RESUME")) { + // Need to lookup the connection by port, filter the port, and + // forward to the user + unsigned short uResumePort = sMessage.Token(3).ToUShort(); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCBounce* pSock = (CDCCBounce*)*it; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCBounce* pSock = (CDCCBounce*)*it; - if (pSock->GetLocalPort() == uResumePort) { - PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + - pNetwork->GetCurNick() + " :\001DCC " + sType + - " " + sFile + " " + - CString(pSock->GetUserPort()) + " " + - sMessage.Token(4) + "\001"); - } - } - } else if (sType.Equals("ACCEPT")) { - // Need to lookup the connection by port, filter the port, and - // forward to the user - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCBounce* pSock = (CDCCBounce*)*it; + if (pSock->GetLocalPort() == uResumePort) { + PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + + pNetwork->GetCurNick() + " :\001DCC " + sType + + " " + sFile + " " + + CString(pSock->GetUserPort()) + " " + + sMessage.Token(4) + "\001"); + } + } + } else if (sType.Equals("ACCEPT")) { + // Need to lookup the connection by port, filter the port, and + // forward to the user + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCBounce* pSock = (CDCCBounce*)*it; - if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) { - PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + - pNetwork->GetCurNick() + " :\001DCC " + sType + - " " + sFile + " " + - CString(pSock->GetLocalPort()) + " " + - sMessage.Token(4) + "\001"); - } - } - } + if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) { + PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + + pNetwork->GetCurNick() + " :\001DCC " + sType + + " " + sFile + " " + + CString(pSock->GetLocalPort()) + " " + + sMessage.Token(4) + "\001"); + } + } + } - return HALTCORE; - } + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } }; CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, @@ -323,22 +323,22 @@ CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, const CString& sRemoteNick, const CString& sRemoteIP, bool bIsChat) : CSocket(pMod) { - m_uRemotePort = uPort; - m_sConnectIP = CUtils::GetIP(uLongIP); - m_sRemoteIP = sRemoteIP; - m_sFileName = sFileName; - m_sRemoteNick = sRemoteNick; - m_pModule = pMod; - m_bIsChat = bIsChat; - m_sLocalIP = pMod->GetLocalDCCIP(); - m_pPeer = nullptr; - m_bIsRemote = false; + m_uRemotePort = uPort; + m_sConnectIP = CUtils::GetIP(uLongIP); + m_sRemoteIP = sRemoteIP; + m_sFileName = sFileName; + m_sRemoteNick = sRemoteNick; + m_pModule = pMod; + m_bIsChat = bIsChat; + m_sLocalIP = pMod->GetLocalDCCIP(); + m_pPeer = nullptr; + m_bIsRemote = false; - if (bIsChat) { - EnableReadLine(); - } else { - DisableReadLine(); - } + if (bIsChat) { + EnableReadLine(); + } else { + DisableReadLine(); + } } CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, @@ -346,178 +346,178 @@ CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, const CString& sRemoteIP, const CString& sFileName, int iTimeout, bool bIsChat) : CSocket(pMod, sHostname, uPort, iTimeout) { - m_uRemotePort = 0; - m_bIsChat = bIsChat; - m_pModule = pMod; - m_pPeer = nullptr; - m_sRemoteNick = sRemoteNick; - m_sFileName = sFileName; - m_sRemoteIP = sRemoteIP; - m_bIsRemote = false; + m_uRemotePort = 0; + m_bIsChat = bIsChat; + m_pModule = pMod; + m_pPeer = nullptr; + m_sRemoteNick = sRemoteNick; + m_sFileName = sFileName; + m_sRemoteIP = sRemoteIP; + m_bIsRemote = false; - SetMaxBufferThreshold(10240); - if (bIsChat) { - EnableReadLine(); - } else { - DisableReadLine(); - } + SetMaxBufferThreshold(10240); + if (bIsChat) { + EnableReadLine(); + } else { + DisableReadLine(); + } } CDCCBounce::~CDCCBounce() { - if (m_pPeer) { - m_pPeer->Shutdown(); - m_pPeer = nullptr; - } + if (m_pPeer) { + m_pPeer->Shutdown(); + m_pPeer = nullptr; + } } void CDCCBounce::ReadLine(const CString& sData) { - CString sLine = sData.TrimRight_n("\r\n"); + CString sLine = sData.TrimRight_n("\r\n"); - DEBUG(GetSockName() << " <- [" << sLine << "]"); + DEBUG(GetSockName() << " <- [" << sLine << "]"); - PutPeer(sLine); + PutPeer(sLine); } void CDCCBounce::ReachedMaxBuffer() { - DEBUG(GetSockName() << " == ReachedMaxBuffer()"); + DEBUG(GetSockName() << " == ReachedMaxBuffer()"); - CString sType = (m_bIsChat) ? "Chat" : "Xfer"; + CString sType = (m_bIsChat) ? "Chat" : "Xfer"; - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Too long line received"); - Close(); + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Too long line received"); + Close(); } void CDCCBounce::ReadData(const char* data, size_t len) { - if (m_pPeer) { - m_pPeer->Write(data, len); + if (m_pPeer) { + m_pPeer->Write(data, len); - size_t BufLen = m_pPeer->GetInternalWriteBuffer().length(); + size_t BufLen = m_pPeer->GetInternalWriteBuffer().length(); - if (BufLen >= m_uiMaxDCCBuffer) { - DEBUG(GetSockName() << " The send buffer is over the " - "limit (" << BufLen << "), throttling"); - PauseRead(); - } - } + if (BufLen >= m_uiMaxDCCBuffer) { + DEBUG(GetSockName() << " The send buffer is over the " + "limit (" << BufLen << "), throttling"); + PauseRead(); + } + } } void CDCCBounce::ReadPaused() { - if (!m_pPeer || - m_pPeer->GetInternalWriteBuffer().length() <= m_uiMinDCCBuffer) - UnPauseRead(); + if (!m_pPeer || + m_pPeer->GetInternalWriteBuffer().length() <= m_uiMinDCCBuffer) + UnPauseRead(); } void CDCCBounce::Timeout() { - DEBUG(GetSockName() << " == Timeout()"); - CString sType = (m_bIsChat) ? "Chat" : "Xfer"; + DEBUG(GetSockName() << " == Timeout()"); + CString sType = (m_bIsChat) ? "Chat" : "Xfer"; - if (IsRemote()) { - CString sHost = Csock::GetHostName(); - if (!sHost.empty()) { - sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]"; - } else { - sHost = "."; - } + if (IsRemote()) { + CString sHost = Csock::GetHostName(); + if (!sHost.empty()) { + sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]"; + } else { + sHost = "."; + } - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Timeout while connecting" + sHost); - } else { - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Timeout waiting for incoming connection [" + - Csock::GetLocalIP() + ":" + - CString(Csock::GetLocalPort()) + "]"); - } + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Timeout while connecting" + sHost); + } else { + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Timeout waiting for incoming connection [" + + Csock::GetLocalIP() + ":" + + CString(Csock::GetLocalPort()) + "]"); + } } void CDCCBounce::ConnectionRefused() { - DEBUG(GetSockName() << " == ConnectionRefused()"); + DEBUG(GetSockName() << " == ConnectionRefused()"); - CString sType = (m_bIsChat) ? "Chat" : "Xfer"; - CString sHost = Csock::GetHostName(); - if (!sHost.empty()) { - sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]"; - } else { - sHost = "."; - } + CString sType = (m_bIsChat) ? "Chat" : "Xfer"; + CString sHost = Csock::GetHostName(); + if (!sHost.empty()) { + sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]"; + } else { + sHost = "."; + } - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Connection Refused while connecting" + sHost); + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Connection Refused while connecting" + sHost); } void CDCCBounce::SockError(int iErrno, const CString& sDescription) { - DEBUG(GetSockName() << " == SockError(" << iErrno << ")"); - CString sType = (m_bIsChat) ? "Chat" : "Xfer"; + DEBUG(GetSockName() << " == SockError(" << iErrno << ")"); + CString sType = (m_bIsChat) ? "Chat" : "Xfer"; - if (IsRemote()) { - CString sHost = Csock::GetHostName(); - if (!sHost.empty()) { - sHost = "[" + sHost + " " + CString(Csock::GetPort()) + "]"; - } + if (IsRemote()) { + CString sHost = Csock::GetHostName(); + if (!sHost.empty()) { + sHost = "[" + sHost + " " + CString(Csock::GetPort()) + "]"; + } - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Socket error [" + sDescription + "]" + sHost); - } else { - m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + - "): Socket error [" + sDescription + "] [" + - Csock::GetLocalIP() + ":" + - CString(Csock::GetLocalPort()) + "]"); - } + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Socket error [" + sDescription + "]" + sHost); + } else { + m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + + "): Socket error [" + sDescription + "] [" + + Csock::GetLocalIP() + ":" + + CString(Csock::GetLocalPort()) + "]"); + } } void CDCCBounce::Connected() { - SetTimeout(0); - DEBUG(GetSockName() << " == Connected()"); + SetTimeout(0); + DEBUG(GetSockName() << " == Connected()"); } void CDCCBounce::Disconnected() { - DEBUG(GetSockName() << " == Disconnected()"); + DEBUG(GetSockName() << " == Disconnected()"); } void CDCCBounce::Shutdown() { - m_pPeer = nullptr; - DEBUG(GetSockName() << " == Close(); because my peer told me to"); - Close(); + m_pPeer = nullptr; + DEBUG(GetSockName() << " == Close(); because my peer told me to"); + Close(); } Csock* CDCCBounce::GetSockObj(const CString& sHost, unsigned short uPort) { - Close(); + Close(); - if (m_sRemoteIP.empty()) { - m_sRemoteIP = sHost; - } + if (m_sRemoteIP.empty()) { + m_sRemoteIP = sHost; + } - CDCCBounce* pSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, - m_sRemoteIP, m_sFileName, m_bIsChat); - CDCCBounce* pRemoteSock = - new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, - m_sFileName, m_bIsChat); - pSock->SetPeer(pRemoteSock); - pRemoteSock->SetPeer(pSock); - pRemoteSock->SetRemote(true); - pSock->SetRemote(false); + CDCCBounce* pSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, + m_sRemoteIP, m_sFileName, m_bIsChat); + CDCCBounce* pRemoteSock = + new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, + m_sFileName, m_bIsChat); + pSock->SetPeer(pRemoteSock); + pRemoteSock->SetPeer(pSock); + pRemoteSock->SetRemote(true); + pSock->SetRemote(false); - CZNC::Get().GetManager().Connect( - m_sConnectIP, m_uRemotePort, - "DCC::" + CString((m_bIsChat) ? "Chat" : "XFER") + "::Remote::" + - m_sRemoteNick, - 60, false, m_sLocalIP, pRemoteSock); + CZNC::Get().GetManager().Connect( + m_sConnectIP, m_uRemotePort, + "DCC::" + CString((m_bIsChat) ? "Chat" : "XFER") + "::Remote::" + + m_sRemoteNick, + 60, false, m_sLocalIP, pRemoteSock); - pSock->SetSockName(GetSockName()); - return pSock; + pSock->SetSockName(GetSockName()); + return pSock; } void CDCCBounce::PutServ(const CString& sLine) { - DEBUG(GetSockName() << " -> [" << sLine << "]"); - Write(sLine + "\r\n"); + DEBUG(GetSockName() << " -> [" << sLine << "]"); + Write(sLine + "\r\n"); } void CDCCBounce::PutPeer(const CString& sLine) { - if (m_pPeer) { - m_pPeer->PutServ(sLine); - } else { - PutServ("*** Not connected yet ***"); - } + if (m_pPeer) { + m_pPeer->PutServ(sLine); + } else { + PutServ("*** Not connected yet ***"); + } } unsigned short CDCCBounce::DCCRequest(const CString& sNick, @@ -526,18 +526,18 @@ unsigned short CDCCBounce::DCCRequest(const CString& sNick, const CString& sFileName, bool bIsChat, CBounceDCCMod* pMod, const CString& sRemoteIP) { - CDCCBounce* pDCCBounce = new CDCCBounce(pMod, uLongIP, uPort, sFileName, - sNick, sRemoteIP, bIsChat); - unsigned short uListenPort = CZNC::Get().GetManager().ListenRand( - "DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, - pMod->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120); + CDCCBounce* pDCCBounce = new CDCCBounce(pMod, uLongIP, uPort, sFileName, + sNick, sRemoteIP, bIsChat); + unsigned short uListenPort = CZNC::Get().GetManager().ListenRand( + "DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, + pMod->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120); - return uListenPort; + return uListenPort; } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("bouncedcc"); + Info.SetWikiPage("bouncedcc"); } USERMODULEDEFS(CBounceDCCMod, diff --git a/modules/buffextras.cpp b/modules/buffextras.cpp index cb500ffe..68df26c5 100644 --- a/modules/buffextras.cpp +++ b/modules/buffextras.cpp @@ -21,93 +21,93 @@ using std::vector; class CBuffExtras : public CModule { public: - MODCONSTRUCTOR(CBuffExtras) {} + MODCONSTRUCTOR(CBuffExtras) {} - virtual ~CBuffExtras() {} + virtual ~CBuffExtras() {} - void AddBuffer(CChan& Channel, const CString& sMessage, - const timeval* tv = nullptr, - const MCString& mssTags = MCString::EmptyMap) { - // If they have AutoClearChanBuffer enabled, only add messages if no - // client is connected - if (Channel.AutoClearChanBuffer() && GetNetwork()->IsUserOnline()) - return; + void AddBuffer(CChan& Channel, const CString& sMessage, + const timeval* tv = nullptr, + const MCString& mssTags = MCString::EmptyMap) { + // If they have AutoClearChanBuffer enabled, only add messages if no + // client is connected + if (Channel.AutoClearChanBuffer() && GetNetwork()->IsUserOnline()) + return; - Channel.AddBuffer(":" + GetModNick() + "!" + GetModName() + - "@znc.in PRIVMSG " + - _NAMEDFMT(Channel.GetName()) + " :{text}", - sMessage, tv, mssTags); - } + Channel.AddBuffer(":" + GetModNick() + "!" + GetModName() + + "@znc.in PRIVMSG " + + _NAMEDFMT(Channel.GetName()) + " :{text}", + sMessage, tv, mssTags); + } - void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override { - const CString sNickMask = pOpNick ? pOpNick->GetNickMask() : "Server"; - AddBuffer(Channel, sNickMask + " set mode: " + sModes + " " + sArgs); - } + void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override { + const CString sNickMask = pOpNick ? pOpNick->GetNickMask() : "Server"; + AddBuffer(Channel, sNickMask + " set mode: " + sModes + " " + sArgs); + } - void OnKickMessage(CKickMessage& Message) override { - const CNick& OpNick = Message.GetNick(); - const CString sKickedNick = Message.GetKickedNick(); - CChan& Channel = *Message.GetChan(); - const CString sMessage = Message.GetReason(); - AddBuffer(Channel, OpNick.GetNickMask() + " kicked " + sKickedNick + - " Reason: [" + sMessage + "]", - &Message.GetTime(), Message.GetTags()); - } + void OnKickMessage(CKickMessage& Message) override { + const CNick& OpNick = Message.GetNick(); + const CString sKickedNick = Message.GetKickedNick(); + CChan& Channel = *Message.GetChan(); + const CString sMessage = Message.GetReason(); + AddBuffer(Channel, OpNick.GetNickMask() + " kicked " + sKickedNick + + " Reason: [" + sMessage + "]", + &Message.GetTime(), Message.GetTags()); + } - void OnQuitMessage(CQuitMessage& Message, - const vector& vChans) override { - const CNick& Nick = Message.GetNick(); - const CString sMessage = Message.GetReason(); - CString sMsg = - Nick.GetNickMask() + " quit with message: [" + sMessage + "]"; - for (CChan* pChan : vChans) { - AddBuffer(*pChan, sMsg, &Message.GetTime(), Message.GetTags()); - } - } + void OnQuitMessage(CQuitMessage& Message, + const vector& vChans) override { + const CNick& Nick = Message.GetNick(); + const CString sMessage = Message.GetReason(); + CString sMsg = + Nick.GetNickMask() + " quit with message: [" + sMessage + "]"; + for (CChan* pChan : vChans) { + AddBuffer(*pChan, sMsg, &Message.GetTime(), Message.GetTags()); + } + } - void OnJoinMessage(CJoinMessage& Message) override { - const CNick& Nick = Message.GetNick(); - CChan& Channel = *Message.GetChan(); - AddBuffer(Channel, Nick.GetNickMask() + " joined", &Message.GetTime(), - Message.GetTags()); - } + void OnJoinMessage(CJoinMessage& Message) override { + const CNick& Nick = Message.GetNick(); + CChan& Channel = *Message.GetChan(); + AddBuffer(Channel, Nick.GetNickMask() + " joined", &Message.GetTime(), + Message.GetTags()); + } - void OnPartMessage(CPartMessage& Message) override { - const CNick& Nick = Message.GetNick(); - CChan& Channel = *Message.GetChan(); - const CString sMessage = Message.GetReason(); - AddBuffer(Channel, Nick.GetNickMask() + " parted with message: [" + - sMessage + "]", - &Message.GetTime(), Message.GetTags()); - } + void OnPartMessage(CPartMessage& Message) override { + const CNick& Nick = Message.GetNick(); + CChan& Channel = *Message.GetChan(); + const CString sMessage = Message.GetReason(); + AddBuffer(Channel, Nick.GetNickMask() + " parted with message: [" + + sMessage + "]", + &Message.GetTime(), Message.GetTags()); + } - void OnNickMessage(CNickMessage& Message, - const vector& vChans) override { - const CNick& OldNick = Message.GetNick(); - const CString sNewNick = Message.GetNewNick(); - CString sMsg = OldNick.GetNickMask() + " is now known as " + sNewNick; - for (CChan* pChan : vChans) { - AddBuffer(*pChan, sMsg, &Message.GetTime(), Message.GetTags()); - } - } + void OnNickMessage(CNickMessage& Message, + const vector& vChans) override { + const CNick& OldNick = Message.GetNick(); + const CString sNewNick = Message.GetNewNick(); + CString sMsg = OldNick.GetNickMask() + " is now known as " + sNewNick; + for (CChan* pChan : vChans) { + AddBuffer(*pChan, sMsg, &Message.GetTime(), Message.GetTags()); + } + } - EModRet OnTopicMessage(CTopicMessage& Message) override { - const CNick& Nick = Message.GetNick(); - CChan& Channel = *Message.GetChan(); - const CString sTopic = Message.GetTopic(); - AddBuffer(Channel, - Nick.GetNickMask() + " changed the topic to: " + sTopic, - &Message.GetTime(), Message.GetTags()); + EModRet OnTopicMessage(CTopicMessage& Message) override { + const CNick& Nick = Message.GetNick(); + CChan& Channel = *Message.GetChan(); + const CString sTopic = Message.GetTopic(); + AddBuffer(Channel, + Nick.GetNickMask() + " changed the topic to: " + sTopic, + &Message.GetTime(), Message.GetTags()); - return CONTINUE; - } + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("buffextras"); - Info.AddType(CModInfo::NetworkModule); + Info.SetWikiPage("buffextras"); + Info.AddType(CModInfo::NetworkModule); } USERMODULEDEFS(CBuffExtras, "Add joins, parts etc. to the playback buffer") diff --git a/modules/cert.cpp b/modules/cert.cpp index 90755668..7c28d8d4 100644 --- a/modules/cert.cpp +++ b/modules/cert.cpp @@ -23,85 +23,85 @@ class CCertMod : public CModule { public: - void Delete(const CString& line) { - if (CFile::Delete(PemFile())) { - PutModule("Pem file deleted"); - } else { - PutModule( - "The pem file doesn't exist or there was a error deleting the " - "pem file."); - } - } + void Delete(const CString& line) { + if (CFile::Delete(PemFile())) { + PutModule("Pem file deleted"); + } else { + PutModule( + "The pem file doesn't exist or there was a error deleting the " + "pem file."); + } + } - void Info(const CString& line) { - if (HasPemFile()) { - PutModule("You have a certificate in: " + PemFile()); - } else { - PutModule( - "You do not have a certificate. Please use the web interface " - "to add a certificate"); - if (GetUser()->IsAdmin()) { - PutModule("Alternatively you can either place one at " + - PemFile()); - } - } - } + void Info(const CString& line) { + if (HasPemFile()) { + PutModule("You have a certificate in: " + PemFile()); + } else { + PutModule( + "You do not have a certificate. Please use the web interface " + "to add a certificate"); + if (GetUser()->IsAdmin()) { + PutModule("Alternatively you can either place one at " + + PemFile()); + } + } + } - MODCONSTRUCTOR(CCertMod) { - AddHelpCommand(); - AddCommand("delete", - static_cast(&CCertMod::Delete), "", - "Delete the current certificate"); - AddCommand("info", - static_cast(&CCertMod::Info), "", - "Show the current certificate"); - } + MODCONSTRUCTOR(CCertMod) { + AddHelpCommand(); + AddCommand("delete", + static_cast(&CCertMod::Delete), "", + "Delete the current certificate"); + AddCommand("info", + static_cast(&CCertMod::Info), "", + "Show the current certificate"); + } - virtual ~CCertMod() {} + virtual ~CCertMod() {} - CString PemFile() const { return GetSavePath() + "/user.pem"; } + CString PemFile() const { return GetSavePath() + "/user.pem"; } - bool HasPemFile() const { return (CFile::Exists(PemFile())); } + bool HasPemFile() const { return (CFile::Exists(PemFile())); } - EModRet OnIRCConnecting(CIRCSock* pIRCSock) override { - if (HasPemFile()) { - pIRCSock->SetPemLocation(PemFile()); - } + EModRet OnIRCConnecting(CIRCSock* pIRCSock) override { + if (HasPemFile()) { + pIRCSock->SetPemLocation(PemFile()); + } - return CONTINUE; - } + return CONTINUE; + } - CString GetWebMenuTitle() override { return "Certificate"; } + CString GetWebMenuTitle() override { return "Certificate"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - Tmpl["Cert"] = CString(HasPemFile()); - return true; - } else if (sPageName == "update") { - CFile fPemFile(PemFile()); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + Tmpl["Cert"] = CString(HasPemFile()); + return true; + } else if (sPageName == "update") { + CFile fPemFile(PemFile()); - if (fPemFile.Open(O_WRONLY | O_TRUNC | O_CREAT)) { - fPemFile.Write(WebSock.GetParam("cert", true, "")); - fPemFile.Close(); - } + if (fPemFile.Open(O_WRONLY | O_TRUNC | O_CREAT)) { + fPemFile.Write(WebSock.GetParam("cert", true, "")); + fPemFile.Close(); + } - WebSock.Redirect(GetWebPath()); - return true; - } else if (sPageName == "delete") { - CFile::Delete(PemFile()); - WebSock.Redirect(GetWebPath()); - return true; - } + WebSock.Redirect(GetWebPath()); + return true; + } else if (sPageName == "delete") { + CFile::Delete(PemFile()); + WebSock.Redirect(GetWebPath()); + return true; + } - return false; - } + return false; + } }; template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::UserModule); - Info.SetWikiPage("cert"); + Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("cert"); } NETWORKMODULEDEFS(CCertMod, "Use a ssl certificate to connect to a server") diff --git a/modules/certauth.cpp b/modules/certauth.cpp index 2e726bdf..84dc9319 100644 --- a/modules/certauth.cpp +++ b/modules/certauth.cpp @@ -26,265 +26,265 @@ using std::pair; class CSSLClientCertMod : public CModule { public: - MODCONSTRUCTOR(CSSLClientCertMod) { - AddHelpCommand(); - AddCommand("Add", static_cast( - &CSSLClientCertMod::HandleAddCommand), - "[pubkey]", - "If pubkey is not provided will use the current key"); - AddCommand("Del", static_cast( - &CSSLClientCertMod::HandleDelCommand), - "id"); - AddCommand("List", static_cast( - &CSSLClientCertMod::HandleListCommand), - "", "List your public keys"); - AddCommand("Show", static_cast( - &CSSLClientCertMod::HandleShowCommand), - "", "Print your current key"); - } + MODCONSTRUCTOR(CSSLClientCertMod) { + AddHelpCommand(); + AddCommand("Add", static_cast( + &CSSLClientCertMod::HandleAddCommand), + "[pubkey]", + "If pubkey is not provided will use the current key"); + AddCommand("Del", static_cast( + &CSSLClientCertMod::HandleDelCommand), + "id"); + AddCommand("List", static_cast( + &CSSLClientCertMod::HandleListCommand), + "", "List your public keys"); + AddCommand("Show", static_cast( + &CSSLClientCertMod::HandleShowCommand), + "", "Print your current key"); + } - virtual ~CSSLClientCertMod() {} + virtual ~CSSLClientCertMod() {} - bool OnBoot() override { - const vector& vListeners = CZNC::Get().GetListeners(); + bool OnBoot() override { + const vector& vListeners = CZNC::Get().GetListeners(); - // We need the SSL_VERIFY_PEER flag on all listeners, or else - // the client doesn't send a ssl cert - for (CListener* pListener : vListeners) - pListener->GetRealListener()->SetRequireClientCertFlags( - SSL_VERIFY_PEER); + // We need the SSL_VERIFY_PEER flag on all listeners, or else + // the client doesn't send a ssl cert + for (CListener* pListener : vListeners) + pListener->GetRealListener()->SetRequireClientCertFlags( + SSL_VERIFY_PEER); - for (MCString::const_iterator it = BeginNV(); it != EndNV(); ++it) { - VCString vsKeys; + for (MCString::const_iterator it = BeginNV(); it != EndNV(); ++it) { + VCString vsKeys; - if (CZNC::Get().FindUser(it->first) == nullptr) { - DEBUG("Unknown user in saved data [" + it->first + "]"); - continue; - } + if (CZNC::Get().FindUser(it->first) == nullptr) { + DEBUG("Unknown user in saved data [" + it->first + "]"); + continue; + } - it->second.Split(" ", vsKeys, false); - for (const CString& sKey : vsKeys) { - m_PubKeys[it->first].insert(sKey.AsLower()); - } - } + it->second.Split(" ", vsKeys, false); + for (const CString& sKey : vsKeys) { + m_PubKeys[it->first].insert(sKey.AsLower()); + } + } - return true; - } + return true; + } - void OnPostRehash() override { OnBoot(); } + void OnPostRehash() override { OnBoot(); } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - OnBoot(); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + OnBoot(); - return true; - } + return true; + } - bool Save() { - ClearNV(false); - for (const auto& it : m_PubKeys) { - CString sVal; - for (const CString& sKey : it.second) { - sVal += sKey + " "; - } + bool Save() { + ClearNV(false); + for (const auto& it : m_PubKeys) { + CString sVal; + for (const CString& sKey : it.second) { + sVal += sKey + " "; + } - if (!sVal.empty()) SetNV(it.first, sVal, false); - } + if (!sVal.empty()) SetNV(it.first, sVal, false); + } - return SaveRegistry(); - } + return SaveRegistry(); + } - bool AddKey(CUser* pUser, const CString& sKey) { - const pair pair = - m_PubKeys[pUser->GetUserName()].insert(sKey.AsLower()); + bool AddKey(CUser* pUser, const CString& sKey) { + const pair pair = + m_PubKeys[pUser->GetUserName()].insert(sKey.AsLower()); - if (pair.second) { - Save(); - } + if (pair.second) { + Save(); + } - return pair.second; - } + return pair.second; + } - EModRet OnLoginAttempt(std::shared_ptr Auth) override { - const CString sUser = Auth->GetUsername(); - Csock* pSock = Auth->GetSocket(); - CUser* pUser = CZNC::Get().FindUser(sUser); + EModRet OnLoginAttempt(std::shared_ptr Auth) override { + const CString sUser = Auth->GetUsername(); + Csock* pSock = Auth->GetSocket(); + CUser* pUser = CZNC::Get().FindUser(sUser); - if (pSock == nullptr || pUser == nullptr) return CONTINUE; + if (pSock == nullptr || pUser == nullptr) return CONTINUE; - const CString sPubKey = GetKey(pSock); - DEBUG("User: " << sUser << " Key: " << sPubKey); + const CString sPubKey = GetKey(pSock); + DEBUG("User: " << sUser << " Key: " << sPubKey); - if (sPubKey.empty()) { - DEBUG("Peer got no public key, ignoring"); - return CONTINUE; - } + if (sPubKey.empty()) { + DEBUG("Peer got no public key, ignoring"); + return CONTINUE; + } - MSCString::const_iterator it = m_PubKeys.find(sUser); - if (it == m_PubKeys.end()) { - DEBUG("No saved pubkeys for this client"); - return CONTINUE; - } + MSCString::const_iterator it = m_PubKeys.find(sUser); + if (it == m_PubKeys.end()) { + DEBUG("No saved pubkeys for this client"); + return CONTINUE; + } - SCString::const_iterator it2 = it->second.find(sPubKey); - if (it2 == it->second.end()) { - DEBUG("Invalid pubkey"); - return CONTINUE; - } + SCString::const_iterator it2 = it->second.find(sPubKey); + if (it2 == it->second.end()) { + DEBUG("Invalid pubkey"); + return CONTINUE; + } - // This client uses a valid pubkey for this user, let them in - DEBUG("Accepted pubkey auth"); - Auth->AcceptLogin(*pUser); + // This client uses a valid pubkey for this user, let them in + DEBUG("Accepted pubkey auth"); + Auth->AcceptLogin(*pUser); - return HALT; - } + return HALT; + } - void HandleShowCommand(const CString& sLine) { - const CString sPubKey = GetKey(GetClient()); + void HandleShowCommand(const CString& sLine) { + const CString sPubKey = GetKey(GetClient()); - if (sPubKey.empty()) { - PutModule("You are not connected with any valid public key"); - } else { - PutModule("Your current public key is: " + sPubKey); - } - } + if (sPubKey.empty()) { + PutModule("You are not connected with any valid public key"); + } else { + PutModule("Your current public key is: " + sPubKey); + } + } - void HandleAddCommand(const CString& sLine) { - CString sPubKey = sLine.Token(1); + void HandleAddCommand(const CString& sLine) { + CString sPubKey = sLine.Token(1); - if (sPubKey.empty()) { - sPubKey = GetKey(GetClient()); - } + if (sPubKey.empty()) { + sPubKey = GetKey(GetClient()); + } - if (sPubKey.empty()) { - PutModule("You did not supply a public key or connect with one."); - } else { - if (AddKey(GetUser(), sPubKey)) { - PutModule("'" + sPubKey + "' added."); - } else { - PutModule("The key '" + sPubKey + "' is already added."); - } - } - } + if (sPubKey.empty()) { + PutModule("You did not supply a public key or connect with one."); + } else { + if (AddKey(GetUser(), sPubKey)) { + PutModule("'" + sPubKey + "' added."); + } else { + PutModule("The key '" + sPubKey + "' is already added."); + } + } + } - void HandleListCommand(const CString& sLine) { - CTable Table; + void HandleListCommand(const CString& sLine) { + CTable Table; - Table.AddColumn("Id"); - Table.AddColumn("Key"); + Table.AddColumn("Id"); + Table.AddColumn("Key"); - MSCString::const_iterator it = m_PubKeys.find(GetUser()->GetUserName()); - if (it == m_PubKeys.end()) { - PutModule("No keys set for your user"); - return; - } + MSCString::const_iterator it = m_PubKeys.find(GetUser()->GetUserName()); + if (it == m_PubKeys.end()) { + PutModule("No keys set for your user"); + return; + } - unsigned int id = 1; - for (const CString& sKey : it->second) { - Table.AddRow(); - Table.SetCell("Id", CString(id++)); - Table.SetCell("Key", sKey); - } + unsigned int id = 1; + for (const CString& sKey : it->second) { + Table.AddRow(); + Table.SetCell("Id", CString(id++)); + Table.SetCell("Key", sKey); + } - if (PutModule(Table) == 0) { - // This double check is necessary, because the - // set could be empty. - PutModule("No keys set for your user"); - } - } + if (PutModule(Table) == 0) { + // This double check is necessary, because the + // set could be empty. + PutModule("No keys set for your user"); + } + } - void HandleDelCommand(const CString& sLine) { - unsigned int id = sLine.Token(1, true).ToUInt(); - MSCString::iterator it = m_PubKeys.find(GetUser()->GetUserName()); + void HandleDelCommand(const CString& sLine) { + unsigned int id = sLine.Token(1, true).ToUInt(); + MSCString::iterator it = m_PubKeys.find(GetUser()->GetUserName()); - if (it == m_PubKeys.end()) { - PutModule("No keys set for your user"); - return; - } + if (it == m_PubKeys.end()) { + PutModule("No keys set for your user"); + return; + } - if (id == 0 || id > it->second.size()) { - PutModule("Invalid #, check \"list\""); - return; - } + if (id == 0 || id > it->second.size()) { + PutModule("Invalid #, check \"list\""); + return; + } - SCString::const_iterator it2 = it->second.begin(); - while (id > 1) { - ++it2; - id--; - } + SCString::const_iterator it2 = it->second.begin(); + while (id > 1) { + ++it2; + id--; + } - it->second.erase(it2); - if (it->second.size() == 0) m_PubKeys.erase(it); - PutModule("Removed"); + it->second.erase(it2); + if (it->second.size() == 0) m_PubKeys.erase(it); + PutModule("Removed"); - Save(); - } + Save(); + } - CString GetKey(Csock* pSock) { - CString sRes; - long int res = pSock->GetPeerFingerprint(sRes); + CString GetKey(Csock* pSock) { + CString sRes; + long int res = pSock->GetPeerFingerprint(sRes); - DEBUG("GetKey() returned status " << res << " with key " << sRes); + DEBUG("GetKey() returned status " << res << " with key " << sRes); - // This is 'inspired' by charybdis' libratbox - switch (res) { - case X509_V_OK: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - return sRes.AsLower(); - default: - return ""; - } - } + // This is 'inspired' by charybdis' libratbox + switch (res) { + case X509_V_OK: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return sRes.AsLower(); + default: + return ""; + } + } - CString GetWebMenuTitle() override { return "certauth"; } + CString GetWebMenuTitle() override { return "certauth"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - CUser* pUser = WebSock.GetSession()->GetUser(); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + CUser* pUser = WebSock.GetSession()->GetUser(); - if (sPageName == "index") { - MSCString::const_iterator it = m_PubKeys.find(pUser->GetUserName()); - if (it != m_PubKeys.end()) { - for (const CString& sKey : it->second) { - CTemplate& row = Tmpl.AddRow("KeyLoop"); - row["Key"] = sKey; - } - } + if (sPageName == "index") { + MSCString::const_iterator it = m_PubKeys.find(pUser->GetUserName()); + if (it != m_PubKeys.end()) { + for (const CString& sKey : it->second) { + CTemplate& row = Tmpl.AddRow("KeyLoop"); + row["Key"] = sKey; + } + } - return true; - } else if (sPageName == "add") { - AddKey(pUser, WebSock.GetParam("key")); - WebSock.Redirect(GetWebPath()); - return true; - } else if (sPageName == "delete") { - MSCString::iterator it = m_PubKeys.find(pUser->GetUserName()); - if (it != m_PubKeys.end()) { - if (it->second.erase(WebSock.GetParam("key", false))) { - if (it->second.size() == 0) { - m_PubKeys.erase(it); - } + return true; + } else if (sPageName == "add") { + AddKey(pUser, WebSock.GetParam("key")); + WebSock.Redirect(GetWebPath()); + return true; + } else if (sPageName == "delete") { + MSCString::iterator it = m_PubKeys.find(pUser->GetUserName()); + if (it != m_PubKeys.end()) { + if (it->second.erase(WebSock.GetParam("key", false))) { + if (it->second.size() == 0) { + m_PubKeys.erase(it); + } - Save(); - } - } + Save(); + } + } - WebSock.Redirect(GetWebPath()); - return true; - } + WebSock.Redirect(GetWebPath()); + return true; + } - return false; - } + return false; + } private: - // Maps user names to a list of allowed pubkeys - typedef map> MSCString; - MSCString m_PubKeys; + // Maps user names to a list of allowed pubkeys + typedef map> MSCString; + MSCString m_PubKeys; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("certauth"); + Info.SetWikiPage("certauth"); } GLOBALMODULEDEFS(CSSLClientCertMod, diff --git a/modules/chansaver.cpp b/modules/chansaver.cpp index f603bb5c..edca67e7 100644 --- a/modules/chansaver.cpp +++ b/modules/chansaver.cpp @@ -20,71 +20,71 @@ class CChanSaverMod : public CModule { public: - MODCONSTRUCTOR(CChanSaverMod) {} + MODCONSTRUCTOR(CChanSaverMod) {} - virtual ~CChanSaverMod() {} + virtual ~CChanSaverMod() {} - bool OnLoad(const CString& sArgsi, CString& sMessage) override { - switch (GetType()) { - case CModInfo::GlobalModule: - LoadUsers(); - break; - case CModInfo::UserModule: - LoadUser(GetUser()); - break; - case CModInfo::NetworkModule: - LoadNetwork(GetNetwork()); - break; - } - return true; - } + bool OnLoad(const CString& sArgsi, CString& sMessage) override { + switch (GetType()) { + case CModInfo::GlobalModule: + LoadUsers(); + break; + case CModInfo::UserModule: + LoadUser(GetUser()); + break; + case CModInfo::NetworkModule: + LoadNetwork(GetNetwork()); + break; + } + return true; + } - void LoadUsers() { - const std::map& vUsers = CZNC::Get().GetUserMap(); - for (const auto& user : vUsers) { - LoadUser(user.second); - } - } + void LoadUsers() { + const std::map& vUsers = CZNC::Get().GetUserMap(); + for (const auto& user : vUsers) { + LoadUser(user.second); + } + } - void LoadUser(CUser* pUser) { - const std::vector& vNetworks = pUser->GetNetworks(); - for (const CIRCNetwork* pNetwork : vNetworks) { - LoadNetwork(pNetwork); - } - } + void LoadUser(CUser* pUser) { + const std::vector& vNetworks = pUser->GetNetworks(); + for (const CIRCNetwork* pNetwork : vNetworks) { + LoadNetwork(pNetwork); + } + } - void LoadNetwork(const CIRCNetwork* pNetwork) { - const std::vector& vChans = pNetwork->GetChans(); - for (CChan* pChan : vChans) { - // If that channel isn't yet in the config, - // we'll have to add it... - if (!pChan->InConfig()) { - pChan->SetInConfig(true); - } - } - } + void LoadNetwork(const CIRCNetwork* pNetwork) { + const std::vector& vChans = pNetwork->GetChans(); + for (CChan* pChan : vChans) { + // If that channel isn't yet in the config, + // we'll have to add it... + if (!pChan->InConfig()) { + pChan->SetInConfig(true); + } + } + } - void OnJoin(const CNick& Nick, CChan& Channel) override { - if (!Channel.InConfig() && - GetNetwork()->GetIRCNick().NickEquals(Nick.GetNick())) { - Channel.SetInConfig(true); - } - } + void OnJoin(const CNick& Nick, CChan& Channel) override { + if (!Channel.InConfig() && + GetNetwork()->GetIRCNick().NickEquals(Nick.GetNick())) { + Channel.SetInConfig(true); + } + } - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override { - if (Channel.InConfig() && - GetNetwork()->GetIRCNick().NickEquals(Nick.GetNick())) { - Channel.SetInConfig(false); - } - } + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override { + if (Channel.InConfig() && + GetNetwork()->GetIRCNick().NickEquals(Nick.GetNick())) { + Channel.SetInConfig(false); + } + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("chansaver"); - Info.AddType(CModInfo::NetworkModule); - Info.AddType(CModInfo::GlobalModule); + Info.SetWikiPage("chansaver"); + Info.AddType(CModInfo::NetworkModule); + Info.AddType(CModInfo::GlobalModule); } USERMODULEDEFS(CChanSaverMod, "Keep config up-to-date when user joins/parts.") diff --git a/modules/clearbufferonmsg.cpp b/modules/clearbufferonmsg.cpp index f55885a9..40684315 100644 --- a/modules/clearbufferonmsg.cpp +++ b/modules/clearbufferonmsg.cpp @@ -22,139 +22,139 @@ using std::vector; enum { - RULE_MSG, - RULE_CTCP, - RULE_ACTION, - RULE_NOTICE, - RULE_PART, - RULE_TOPIC, - RULE_QUIT, - RULE_MAX, + RULE_MSG, + RULE_CTCP, + RULE_ACTION, + RULE_NOTICE, + RULE_PART, + RULE_TOPIC, + RULE_QUIT, + RULE_MAX, }; class CClearBufferOnMsgMod : public CModule { public: - MODCONSTRUCTOR(CClearBufferOnMsgMod) { - SetAllRules(true); - // false for backward compatibility - m_bRules[RULE_QUIT] = false; - } + MODCONSTRUCTOR(CClearBufferOnMsgMod) { + SetAllRules(true); + // false for backward compatibility + m_bRules[RULE_QUIT] = false; + } - void ClearAllBuffers() { - CIRCNetwork* pNetwork = GetNetwork(); + void ClearAllBuffers() { + CIRCNetwork* pNetwork = GetNetwork(); - if (pNetwork) { - const vector& vChans = pNetwork->GetChans(); + if (pNetwork) { + const vector& vChans = pNetwork->GetChans(); - for (CChan* pChan : vChans) { - // Skip detached channels, they weren't read yet - if (pChan->IsDetached()) continue; + for (CChan* pChan : vChans) { + // Skip detached channels, they weren't read yet + if (pChan->IsDetached()) continue; - pChan->ClearBuffer(); - // We deny AutoClearChanBuffer on all channels since this module - // doesn't make any sense with it - pChan->SetAutoClearChanBuffer(false); - } + pChan->ClearBuffer(); + // We deny AutoClearChanBuffer on all channels since this module + // doesn't make any sense with it + pChan->SetAutoClearChanBuffer(false); + } - vector VQueries = pNetwork->GetQueries(); + vector VQueries = pNetwork->GetQueries(); - for (CQuery* pQuery : VQueries) { - pNetwork->DelQuery(pQuery->GetName()); - } + for (CQuery* pQuery : VQueries) { + pNetwork->DelQuery(pQuery->GetName()); + } - // We deny AutoClearQueryBuffer since this module - // doesn't make any sense with it - GetUser()->SetAutoClearQueryBuffer(false); - } - } + // We deny AutoClearQueryBuffer since this module + // doesn't make any sense with it + GetUser()->SetAutoClearQueryBuffer(false); + } + } - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - if (m_bRules[RULE_MSG]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + if (m_bRules[RULE_MSG]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { - if (m_bRules[RULE_CTCP]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { + if (m_bRules[RULE_CTCP]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserAction(CString& sTarget, CString& sMessage) override { - if (m_bRules[RULE_ACTION]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserAction(CString& sTarget, CString& sMessage) override { + if (m_bRules[RULE_ACTION]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - if (m_bRules[RULE_NOTICE]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + if (m_bRules[RULE_NOTICE]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserPart(CString& sChannel, CString& sMessage) override { - if (m_bRules[RULE_PART]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserPart(CString& sChannel, CString& sMessage) override { + if (m_bRules[RULE_PART]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserTopic(CString& sChannel, CString& sTopic) override { - if (m_bRules[RULE_TOPIC]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserTopic(CString& sChannel, CString& sTopic) override { + if (m_bRules[RULE_TOPIC]) ClearAllBuffers(); + return CONTINUE; + } - EModRet OnUserQuit(CString& sMessage) override { - if (m_bRules[RULE_QUIT]) ClearAllBuffers(); - return CONTINUE; - } + EModRet OnUserQuit(CString& sMessage) override { + if (m_bRules[RULE_QUIT]) ClearAllBuffers(); + return CONTINUE; + } - void SetAllRules(bool bVal) { - for (int i = 0; i < RULE_MAX; i++) m_bRules[i] = bVal; - } + void SetAllRules(bool bVal) { + for (int i = 0; i < RULE_MAX; i++) m_bRules[i] = bVal; + } - void SetRule(const CString& sOpt, bool bVal) { - static const struct { - CString sName; - int Index; - } Names[RULE_MAX] = { - {"msg", RULE_MSG}, - {"ctcp", RULE_CTCP}, - {"action", RULE_ACTION}, - {"notice", RULE_NOTICE}, - {"part", RULE_PART}, - {"topic", RULE_TOPIC}, - {"quit", RULE_QUIT}, - }; + void SetRule(const CString& sOpt, bool bVal) { + static const struct { + CString sName; + int Index; + } Names[RULE_MAX] = { + {"msg", RULE_MSG}, + {"ctcp", RULE_CTCP}, + {"action", RULE_ACTION}, + {"notice", RULE_NOTICE}, + {"part", RULE_PART}, + {"topic", RULE_TOPIC}, + {"quit", RULE_QUIT}, + }; - if (sOpt.Equals("all")) { - SetAllRules(bVal); - } else { - for (int i = 0; i < RULE_MAX; i++) { - if (sOpt.Equals(Names[i].sName)) - m_bRules[Names[i].Index] = bVal; - } - } - } + if (sOpt.Equals("all")) { + SetAllRules(bVal); + } else { + for (int i = 0; i < RULE_MAX; i++) { + if (sOpt.Equals(Names[i].sName)) + m_bRules[Names[i].Index] = bVal; + } + } + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - VCString vsOpts; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + VCString vsOpts; - sArgs.Split(" ", vsOpts, false); + sArgs.Split(" ", vsOpts, false); - for (CString& sOpt : vsOpts) { - if (sOpt.StartsWith("!")) - SetRule(sOpt.substr(1), false); - else if (!sOpt.empty()) - SetRule(sOpt, true); - } + for (CString& sOpt : vsOpts) { + if (sOpt.StartsWith("!")) + SetRule(sOpt.substr(1), false); + else if (!sOpt.empty()) + SetRule(sOpt, true); + } - return true; - } + return true; + } private: - bool m_bRules[RULE_MAX]; + bool m_bRules[RULE_MAX]; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("clearbufferonmsg"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("[ [!] ]"); + Info.SetWikiPage("clearbufferonmsg"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("[ [!] ]"); } USERMODULEDEFS( diff --git a/modules/clientnotify.cpp b/modules/clientnotify.cpp index d07eaa25..d9a347c9 100644 --- a/modules/clientnotify.cpp +++ b/modules/clientnotify.cpp @@ -21,135 +21,135 @@ using std::set; class CClientNotifyMod : public CModule { protected: - CString m_sMethod; - bool m_bNewOnly{}; - bool m_bOnDisconnect{}; + CString m_sMethod; + bool m_bNewOnly{}; + bool m_bOnDisconnect{}; - set m_sClientsSeen; + set m_sClientsSeen; - void SaveSettings() { - SetNV("method", m_sMethod); - SetNV("newonly", m_bNewOnly ? "1" : "0"); - SetNV("ondisconnect", m_bOnDisconnect ? "1" : "0"); - } + void SaveSettings() { + SetNV("method", m_sMethod); + SetNV("newonly", m_bNewOnly ? "1" : "0"); + SetNV("ondisconnect", m_bOnDisconnect ? "1" : "0"); + } - void SendNotification(const CString& sMessage) { - if (m_sMethod == "message") { - GetUser()->PutStatus(sMessage, nullptr, GetClient()); - } else if (m_sMethod == "notice") { - GetUser()->PutStatusNotice(sMessage, nullptr, GetClient()); - } - } + void SendNotification(const CString& sMessage) { + if (m_sMethod == "message") { + GetUser()->PutStatus(sMessage, nullptr, GetClient()); + } else if (m_sMethod == "notice") { + GetUser()->PutStatusNotice(sMessage, nullptr, GetClient()); + } + } public: - MODCONSTRUCTOR(CClientNotifyMod) { - AddHelpCommand(); - AddCommand("Method", static_cast( - &CClientNotifyMod::OnMethodCommand), - "", "Sets the notify method"); - AddCommand("NewOnly", static_cast( - &CClientNotifyMod::OnNewOnlyCommand), - "", - "Turns notifications for unseen IP addresses on or off"); - AddCommand("OnDisconnect", static_cast( - &CClientNotifyMod::OnDisconnectCommand), - "", - "Turns notifications for clients disconnecting on or off"); - AddCommand("Show", static_cast( - &CClientNotifyMod::OnShowCommand), - "", "Show the current settings"); - } + MODCONSTRUCTOR(CClientNotifyMod) { + AddHelpCommand(); + AddCommand("Method", static_cast( + &CClientNotifyMod::OnMethodCommand), + "", "Sets the notify method"); + AddCommand("NewOnly", static_cast( + &CClientNotifyMod::OnNewOnlyCommand), + "", + "Turns notifications for unseen IP addresses on or off"); + AddCommand("OnDisconnect", static_cast( + &CClientNotifyMod::OnDisconnectCommand), + "", + "Turns notifications for clients disconnecting on or off"); + AddCommand("Show", static_cast( + &CClientNotifyMod::OnShowCommand), + "", "Show the current settings"); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_sMethod = GetNV("method"); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_sMethod = GetNV("method"); - if (m_sMethod != "notice" && m_sMethod != "message" && - m_sMethod != "off") { - m_sMethod = "message"; - } + if (m_sMethod != "notice" && m_sMethod != "message" && + m_sMethod != "off") { + m_sMethod = "message"; + } - // default = off for these: + // default = off for these: - m_bNewOnly = (GetNV("newonly") == "1"); - m_bOnDisconnect = (GetNV("ondisconnect") == "1"); + m_bNewOnly = (GetNV("newonly") == "1"); + m_bOnDisconnect = (GetNV("ondisconnect") == "1"); - return true; - } + return true; + } - void OnClientLogin() override { - CString sRemoteIP = GetClient()->GetRemoteIP(); - if (!m_bNewOnly || - m_sClientsSeen.find(sRemoteIP) == m_sClientsSeen.end()) { - SendNotification( - "Another client authenticated as your user. " - "Use the 'ListClients' command to see all " + - CString(GetUser()->GetAllClients().size()) + " clients."); + void OnClientLogin() override { + CString sRemoteIP = GetClient()->GetRemoteIP(); + if (!m_bNewOnly || + m_sClientsSeen.find(sRemoteIP) == m_sClientsSeen.end()) { + SendNotification( + "Another client authenticated as your user. " + "Use the 'ListClients' command to see all " + + CString(GetUser()->GetAllClients().size()) + " clients."); - // the set<> will automatically disregard duplicates: - m_sClientsSeen.insert(sRemoteIP); - } - } + // the set<> will automatically disregard duplicates: + m_sClientsSeen.insert(sRemoteIP); + } + } - void OnClientDisconnect() override { - if (m_bOnDisconnect) { - SendNotification( - "A client disconnected from your user. " - "Use the 'ListClients' command to see the " + - CString(GetUser()->GetAllClients().size()) + - " remaining client(s)."); - } - } + void OnClientDisconnect() override { + if (m_bOnDisconnect) { + SendNotification( + "A client disconnected from your user. " + "Use the 'ListClients' command to see the " + + CString(GetUser()->GetAllClients().size()) + + " remaining client(s)."); + } + } - void OnMethodCommand(const CString& sCommand) { - const CString& sArg = sCommand.Token(1, true).AsLower(); + void OnMethodCommand(const CString& sCommand) { + const CString& sArg = sCommand.Token(1, true).AsLower(); - if (sArg != "notice" && sArg != "message" && sArg != "off") { - PutModule("Usage: Method "); - return; - } + if (sArg != "notice" && sArg != "message" && sArg != "off") { + PutModule("Usage: Method "); + return; + } - m_sMethod = sArg; - SaveSettings(); - PutModule("Saved."); - } + m_sMethod = sArg; + SaveSettings(); + PutModule("Saved."); + } - void OnNewOnlyCommand(const CString& sCommand) { - const CString& sArg = sCommand.Token(1, true).AsLower(); + void OnNewOnlyCommand(const CString& sCommand) { + const CString& sArg = sCommand.Token(1, true).AsLower(); - if (sArg.empty()) { - PutModule("Usage: NewOnly "); - return; - } + if (sArg.empty()) { + PutModule("Usage: NewOnly "); + return; + } - m_bNewOnly = sArg.ToBool(); - SaveSettings(); - PutModule("Saved."); - } + m_bNewOnly = sArg.ToBool(); + SaveSettings(); + PutModule("Saved."); + } - void OnDisconnectCommand(const CString& sCommand) { - const CString& sArg = sCommand.Token(1, true).AsLower(); + void OnDisconnectCommand(const CString& sCommand) { + const CString& sArg = sCommand.Token(1, true).AsLower(); - if (sArg.empty()) { - PutModule("Usage: OnDisconnect "); - return; - } + if (sArg.empty()) { + PutModule("Usage: OnDisconnect "); + return; + } - m_bOnDisconnect = sArg.ToBool(); - SaveSettings(); - PutModule("Saved."); - } + m_bOnDisconnect = sArg.ToBool(); + SaveSettings(); + PutModule("Saved."); + } - void OnShowCommand(const CString& sLine) { - PutModule("Current settings: Method: " + m_sMethod + - ", for unseen IP addresses only: " + CString(m_bNewOnly) + - ", notify on disconnecting clients: " + - CString(m_bOnDisconnect)); - } + void OnShowCommand(const CString& sLine) { + PutModule("Current settings: Method: " + m_sMethod + + ", for unseen IP addresses only: " + CString(m_bNewOnly) + + ", notify on disconnecting clients: " + + CString(m_bOnDisconnect)); + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("clientnotify"); + Info.SetWikiPage("clientnotify"); } USERMODULEDEFS(CClientNotifyMod, diff --git a/modules/controlpanel.cpp b/modules/controlpanel.cpp index dab21852..e78203ae 100644 --- a/modules/controlpanel.cpp +++ b/modules/controlpanel.cpp @@ -27,1542 +27,1542 @@ using std::vector; template struct array_size_helper { - char __place_holder[N]; + char __place_holder[N]; }; template static array_size_helper array_size(T (&)[N]) { - return array_size_helper(); + return array_size_helper(); } #define ARRAY_SIZE(array) sizeof(array_size((array))) class CAdminMod : public CModule { - using CModule::PutModule; + using CModule::PutModule; - void PrintVarsHelp(const CString& sFilter, const char* vars[][2], - unsigned int uSize, const CString& sDescription) { - CTable VarTable; - VarTable.AddColumn("Type"); - VarTable.AddColumn("Variables"); - std::map mvsTypedVariables; - for (unsigned int i = 0; i != uSize; ++i) { - CString sVar = CString(vars[i][0]).AsLower(); - if (sFilter.empty() || sVar.StartsWith(sFilter) || - sVar.WildCmp(sFilter)) { - mvsTypedVariables[vars[i][1]].emplace_back(vars[i][0]); - } - } - for (const auto& i : mvsTypedVariables) { - VarTable.AddRow(); - VarTable.SetCell("Type", i.first); - VarTable.SetCell("Variables", CString(", ").Join(i.second.cbegin(), - i.second.cend())); - } - if (!VarTable.empty()) { - PutModule(sDescription); - PutModule(VarTable); - } - } + void PrintVarsHelp(const CString& sFilter, const char* vars[][2], + unsigned int uSize, const CString& sDescription) { + CTable VarTable; + VarTable.AddColumn("Type"); + VarTable.AddColumn("Variables"); + std::map mvsTypedVariables; + for (unsigned int i = 0; i != uSize; ++i) { + CString sVar = CString(vars[i][0]).AsLower(); + if (sFilter.empty() || sVar.StartsWith(sFilter) || + sVar.WildCmp(sFilter)) { + mvsTypedVariables[vars[i][1]].emplace_back(vars[i][0]); + } + } + for (const auto& i : mvsTypedVariables) { + VarTable.AddRow(); + VarTable.SetCell("Type", i.first); + VarTable.SetCell("Variables", CString(", ").Join(i.second.cbegin(), + i.second.cend())); + } + if (!VarTable.empty()) { + PutModule(sDescription); + PutModule(VarTable); + } + } - void PrintHelp(const CString& sLine) { - HandleHelpCommand(sLine); + void PrintHelp(const CString& sLine) { + HandleHelpCommand(sLine); - static const char* str = "String"; - static const char* boolean = "Boolean (true/false)"; - static const char* integer = "Integer"; - static const char* doublenum = "Double"; + static const char* str = "String"; + static const char* boolean = "Boolean (true/false)"; + static const char* integer = "Integer"; + static const char* doublenum = "Double"; - const CString sCmdFilter = sLine.Token(1, false); - const CString sVarFilter = sLine.Token(2, true).AsLower(); + const CString sCmdFilter = sLine.Token(1, false); + const CString sVarFilter = sLine.Token(2, true).AsLower(); - if (sCmdFilter.empty() || sCmdFilter.StartsWith("Set") || - sCmdFilter.StartsWith("Get")) { - static const char* vars[][2] = { - {"Nick", str}, - {"Altnick", str}, - {"Ident", str}, - {"RealName", str}, - {"BindHost", str}, - {"MultiClients", boolean}, - {"DenyLoadMod", boolean}, - {"DenySetBindHost", boolean}, - {"DefaultChanModes", str}, - {"QuitMsg", str}, - {"ChanBufferSize", integer}, - {"QueryBufferSize", integer}, - {"AutoClearChanBuffer", boolean}, - {"AutoClearQueryBuffer", boolean}, - {"Password", str}, - {"JoinTries", integer}, - {"MaxJoins", integer}, - {"MaxNetworks", integer}, - {"MaxQueryBuffers", integer}, - {"Timezone", str}, - {"Admin", boolean}, - {"AppendTimestamp", boolean}, - {"PrependTimestamp", boolean}, - {"TimestampFormat", str}, - {"DCCBindHost", str}, - {"StatusPrefix", str}, + if (sCmdFilter.empty() || sCmdFilter.StartsWith("Set") || + sCmdFilter.StartsWith("Get")) { + static const char* vars[][2] = { + {"Nick", str}, + {"Altnick", str}, + {"Ident", str}, + {"RealName", str}, + {"BindHost", str}, + {"MultiClients", boolean}, + {"DenyLoadMod", boolean}, + {"DenySetBindHost", boolean}, + {"DefaultChanModes", str}, + {"QuitMsg", str}, + {"ChanBufferSize", integer}, + {"QueryBufferSize", integer}, + {"AutoClearChanBuffer", boolean}, + {"AutoClearQueryBuffer", boolean}, + {"Password", str}, + {"JoinTries", integer}, + {"MaxJoins", integer}, + {"MaxNetworks", integer}, + {"MaxQueryBuffers", integer}, + {"Timezone", str}, + {"Admin", boolean}, + {"AppendTimestamp", boolean}, + {"PrependTimestamp", boolean}, + {"TimestampFormat", str}, + {"DCCBindHost", str}, + {"StatusPrefix", str}, #ifdef HAVE_ICU - {"ClientEncoding", str}, + {"ClientEncoding", str}, #endif - }; - PrintVarsHelp(sVarFilter, vars, ARRAY_SIZE(vars), - "The following variables are available when using " - "the Set/Get commands:"); - } + }; + PrintVarsHelp(sVarFilter, vars, ARRAY_SIZE(vars), + "The following variables are available when using " + "the Set/Get commands:"); + } - if (sCmdFilter.empty() || sCmdFilter.StartsWith("SetNetwork") || - sCmdFilter.StartsWith("GetNetwork")) { - static const char* nvars[][2] = { - {"Nick", str}, - {"Altnick", str}, - {"Ident", str}, - {"RealName", str}, - {"BindHost", str}, - {"FloodRate", doublenum}, - {"FloodBurst", integer}, - {"JoinDelay", integer}, + if (sCmdFilter.empty() || sCmdFilter.StartsWith("SetNetwork") || + sCmdFilter.StartsWith("GetNetwork")) { + static const char* nvars[][2] = { + {"Nick", str}, + {"Altnick", str}, + {"Ident", str}, + {"RealName", str}, + {"BindHost", str}, + {"FloodRate", doublenum}, + {"FloodBurst", integer}, + {"JoinDelay", integer}, #ifdef HAVE_ICU - {"Encoding", str}, + {"Encoding", str}, #endif - {"QuitMsg", str}, - }; - PrintVarsHelp(sVarFilter, nvars, ARRAY_SIZE(nvars), - "The following variables are available when using " - "the SetNetwork/GetNetwork commands:"); - } + {"QuitMsg", str}, + }; + PrintVarsHelp(sVarFilter, nvars, ARRAY_SIZE(nvars), + "The following variables are available when using " + "the SetNetwork/GetNetwork commands:"); + } - if (sCmdFilter.empty() || sCmdFilter.StartsWith("SetChan") || - sCmdFilter.StartsWith("GetChan")) { - static const char* cvars[][2] = {{"DefModes", str}, - {"Key", str}, - {"BufferSize", integer}, - {"InConfig", boolean}, - {"AutoClearChanBuffer", boolean}, - {"Detached", boolean}}; - PrintVarsHelp(sVarFilter, cvars, ARRAY_SIZE(cvars), - "The following variables are available when using " - "the SetChan/GetChan commands:"); - } + if (sCmdFilter.empty() || sCmdFilter.StartsWith("SetChan") || + sCmdFilter.StartsWith("GetChan")) { + static const char* cvars[][2] = {{"DefModes", str}, + {"Key", str}, + {"BufferSize", integer}, + {"InConfig", boolean}, + {"AutoClearChanBuffer", boolean}, + {"Detached", boolean}}; + PrintVarsHelp(sVarFilter, cvars, ARRAY_SIZE(cvars), + "The following variables are available when using " + "the SetChan/GetChan commands:"); + } - if (sCmdFilter.empty()) - PutModule( - "You can use $user as the user name and $network as the " - "network name for modifying your own user and network."); - } + if (sCmdFilter.empty()) + PutModule( + "You can use $user as the user name and $network as the " + "network name for modifying your own user and network."); + } - CUser* FindUser(const CString& sUsername) { - if (sUsername.Equals("$me") || sUsername.Equals("$user")) - return GetUser(); - CUser* pUser = CZNC::Get().FindUser(sUsername); - if (!pUser) { - PutModule("Error: User [" + sUsername + "] not found."); - return nullptr; - } - if (pUser != GetUser() && !GetUser()->IsAdmin()) { - PutModule( - "Error: You need to have admin rights to modify other users!"); - return nullptr; - } - return pUser; - } + CUser* FindUser(const CString& sUsername) { + if (sUsername.Equals("$me") || sUsername.Equals("$user")) + return GetUser(); + CUser* pUser = CZNC::Get().FindUser(sUsername); + if (!pUser) { + PutModule("Error: User [" + sUsername + "] not found."); + return nullptr; + } + if (pUser != GetUser() && !GetUser()->IsAdmin()) { + PutModule( + "Error: You need to have admin rights to modify other users!"); + return nullptr; + } + return pUser; + } - CIRCNetwork* FindNetwork(CUser* pUser, const CString& sNetwork) { - if (sNetwork.Equals("$net") || sNetwork.Equals("$network")) { - if (pUser != GetUser()) { - PutModule("Error: You cannot use " + sNetwork + - " to modify other users!"); - return nullptr; - } - return CModule::GetNetwork(); - } - CIRCNetwork* pNetwork = pUser->FindNetwork(sNetwork); - if (!pNetwork) { - PutModule("Error: [" + pUser->GetUserName() + - "] does not have a network named [" + sNetwork + "]."); - } - return pNetwork; - } + CIRCNetwork* FindNetwork(CUser* pUser, const CString& sNetwork) { + if (sNetwork.Equals("$net") || sNetwork.Equals("$network")) { + if (pUser != GetUser()) { + PutModule("Error: You cannot use " + sNetwork + + " to modify other users!"); + return nullptr; + } + return CModule::GetNetwork(); + } + CIRCNetwork* pNetwork = pUser->FindNetwork(sNetwork); + if (!pNetwork) { + PutModule("Error: [" + pUser->GetUserName() + + "] does not have a network named [" + sNetwork + "]."); + } + return pNetwork; + } - void Get(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - CString sUsername = sLine.Token(2, true); - CUser* pUser; + void Get(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + CString sUsername = sLine.Token(2, true); + CUser* pUser; - if (sVar.empty()) { - PutModule("Usage: Get [username]"); - return; - } + if (sVar.empty()) { + PutModule("Usage: Get [username]"); + return; + } - if (sUsername.empty()) { - pUser = GetUser(); - } else { - pUser = FindUser(sUsername); - } + if (sUsername.empty()) { + pUser = GetUser(); + } else { + pUser = FindUser(sUsername); + } - if (!pUser) return; + if (!pUser) return; - if (sVar == "nick") - PutModule("Nick = " + pUser->GetNick()); - else if (sVar == "altnick") - PutModule("AltNick = " + pUser->GetAltNick()); - else if (sVar == "ident") - PutModule("Ident = " + pUser->GetIdent()); - else if (sVar == "realname") - PutModule("RealName = " + pUser->GetRealName()); - else if (sVar == "bindhost") - PutModule("BindHost = " + pUser->GetBindHost()); - else if (sVar == "multiclients") - PutModule("MultiClients = " + CString(pUser->MultiClients())); - else if (sVar == "denyloadmod") - PutModule("DenyLoadMod = " + CString(pUser->DenyLoadMod())); - else if (sVar == "denysetbindhost") - PutModule("DenySetBindHost = " + CString(pUser->DenySetBindHost())); - else if (sVar == "defaultchanmodes") - PutModule("DefaultChanModes = " + pUser->GetDefaultChanModes()); - else if (sVar == "quitmsg") - PutModule("QuitMsg = " + pUser->GetQuitMsg()); - else if (sVar == "buffercount") - PutModule("BufferCount = " + CString(pUser->GetBufferCount())); - else if (sVar == "chanbuffersize") - PutModule("ChanBufferSize = " + - CString(pUser->GetChanBufferSize())); - else if (sVar == "querybuffersize") - PutModule("QueryBufferSize = " + - CString(pUser->GetQueryBufferSize())); - else if (sVar == "keepbuffer") - // XXX compatibility crap, added in 0.207 - PutModule("KeepBuffer = " + CString(!pUser->AutoClearChanBuffer())); - else if (sVar == "autoclearchanbuffer") - PutModule("AutoClearChanBuffer = " + - CString(pUser->AutoClearChanBuffer())); - else if (sVar == "autoclearquerybuffer") - PutModule("AutoClearQueryBuffer = " + - CString(pUser->AutoClearQueryBuffer())); - else if (sVar == "maxjoins") - PutModule("MaxJoins = " + CString(pUser->MaxJoins())); - else if (sVar == "maxnetworks") - PutModule("MaxNetworks = " + CString(pUser->MaxNetworks())); - else if (sVar == "maxquerybuffers") - PutModule("MaxQueryBuffers = " + CString(pUser->MaxQueryBuffers())); - else if (sVar == "jointries") - PutModule("JoinTries = " + CString(pUser->JoinTries())); - else if (sVar == "timezone") - PutModule("Timezone = " + pUser->GetTimezone()); - else if (sVar == "appendtimestamp") - PutModule("AppendTimestamp = " + - CString(pUser->GetTimestampAppend())); - else if (sVar == "prependtimestamp") - PutModule("PrependTimestamp = " + - CString(pUser->GetTimestampPrepend())); - else if (sVar == "timestampformat") - PutModule("TimestampFormat = " + pUser->GetTimestampFormat()); - else if (sVar == "dccbindhost") - PutModule("DCCBindHost = " + CString(pUser->GetDCCBindHost())); - else if (sVar == "admin") - PutModule("Admin = " + CString(pUser->IsAdmin())); - else if (sVar == "statusprefix") - PutModule("StatusPrefix = " + pUser->GetStatusPrefix()); + if (sVar == "nick") + PutModule("Nick = " + pUser->GetNick()); + else if (sVar == "altnick") + PutModule("AltNick = " + pUser->GetAltNick()); + else if (sVar == "ident") + PutModule("Ident = " + pUser->GetIdent()); + else if (sVar == "realname") + PutModule("RealName = " + pUser->GetRealName()); + else if (sVar == "bindhost") + PutModule("BindHost = " + pUser->GetBindHost()); + else if (sVar == "multiclients") + PutModule("MultiClients = " + CString(pUser->MultiClients())); + else if (sVar == "denyloadmod") + PutModule("DenyLoadMod = " + CString(pUser->DenyLoadMod())); + else if (sVar == "denysetbindhost") + PutModule("DenySetBindHost = " + CString(pUser->DenySetBindHost())); + else if (sVar == "defaultchanmodes") + PutModule("DefaultChanModes = " + pUser->GetDefaultChanModes()); + else if (sVar == "quitmsg") + PutModule("QuitMsg = " + pUser->GetQuitMsg()); + else if (sVar == "buffercount") + PutModule("BufferCount = " + CString(pUser->GetBufferCount())); + else if (sVar == "chanbuffersize") + PutModule("ChanBufferSize = " + + CString(pUser->GetChanBufferSize())); + else if (sVar == "querybuffersize") + PutModule("QueryBufferSize = " + + CString(pUser->GetQueryBufferSize())); + else if (sVar == "keepbuffer") + // XXX compatibility crap, added in 0.207 + PutModule("KeepBuffer = " + CString(!pUser->AutoClearChanBuffer())); + else if (sVar == "autoclearchanbuffer") + PutModule("AutoClearChanBuffer = " + + CString(pUser->AutoClearChanBuffer())); + else if (sVar == "autoclearquerybuffer") + PutModule("AutoClearQueryBuffer = " + + CString(pUser->AutoClearQueryBuffer())); + else if (sVar == "maxjoins") + PutModule("MaxJoins = " + CString(pUser->MaxJoins())); + else if (sVar == "maxnetworks") + PutModule("MaxNetworks = " + CString(pUser->MaxNetworks())); + else if (sVar == "maxquerybuffers") + PutModule("MaxQueryBuffers = " + CString(pUser->MaxQueryBuffers())); + else if (sVar == "jointries") + PutModule("JoinTries = " + CString(pUser->JoinTries())); + else if (sVar == "timezone") + PutModule("Timezone = " + pUser->GetTimezone()); + else if (sVar == "appendtimestamp") + PutModule("AppendTimestamp = " + + CString(pUser->GetTimestampAppend())); + else if (sVar == "prependtimestamp") + PutModule("PrependTimestamp = " + + CString(pUser->GetTimestampPrepend())); + else if (sVar == "timestampformat") + PutModule("TimestampFormat = " + pUser->GetTimestampFormat()); + else if (sVar == "dccbindhost") + PutModule("DCCBindHost = " + CString(pUser->GetDCCBindHost())); + else if (sVar == "admin") + PutModule("Admin = " + CString(pUser->IsAdmin())); + else if (sVar == "statusprefix") + PutModule("StatusPrefix = " + pUser->GetStatusPrefix()); #ifdef HAVE_ICU - else if (sVar == "clientencoding") - PutModule("ClientEncoding = " + pUser->GetClientEncoding()); + else if (sVar == "clientencoding") + PutModule("ClientEncoding = " + pUser->GetClientEncoding()); #endif - else - PutModule("Error: Unknown variable"); - } + else + PutModule("Error: Unknown variable"); + } - void Set(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - CString sUserName = sLine.Token(2); - CString sValue = sLine.Token(3, true); + void Set(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + CString sUserName = sLine.Token(2); + CString sValue = sLine.Token(3, true); - if (sValue.empty()) { - PutModule("Usage: Set "); - return; - } + if (sValue.empty()) { + PutModule("Usage: Set "); + return; + } - CUser* pUser = FindUser(sUserName); - if (!pUser) return; + CUser* pUser = FindUser(sUserName); + if (!pUser) return; - if (sVar == "nick") { - pUser->SetNick(sValue); - PutModule("Nick = " + sValue); - } else if (sVar == "altnick") { - pUser->SetAltNick(sValue); - PutModule("AltNick = " + sValue); - } else if (sVar == "ident") { - pUser->SetIdent(sValue); - PutModule("Ident = " + sValue); - } else if (sVar == "realname") { - pUser->SetRealName(sValue); - PutModule("RealName = " + sValue); - } else if (sVar == "bindhost") { - if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { - if (sValue.Equals(GetUser()->GetBindHost())) { - PutModule("This bind host is already set!"); - return; - } + if (sVar == "nick") { + pUser->SetNick(sValue); + PutModule("Nick = " + sValue); + } else if (sVar == "altnick") { + pUser->SetAltNick(sValue); + PutModule("AltNick = " + sValue); + } else if (sVar == "ident") { + pUser->SetIdent(sValue); + PutModule("Ident = " + sValue); + } else if (sVar == "realname") { + pUser->SetRealName(sValue); + PutModule("RealName = " + sValue); + } else if (sVar == "bindhost") { + if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { + if (sValue.Equals(GetUser()->GetBindHost())) { + PutModule("This bind host is already set!"); + return; + } - pUser->SetBindHost(sValue); - PutModule("BindHost = " + sValue); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "multiclients") { - bool b = sValue.ToBool(); - pUser->SetMultiClients(b); - PutModule("MultiClients = " + CString(b)); - } else if (sVar == "denyloadmod") { - if (GetUser()->IsAdmin()) { - bool b = sValue.ToBool(); - pUser->SetDenyLoadMod(b); - PutModule("DenyLoadMod = " + CString(b)); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "denysetbindhost") { - if (GetUser()->IsAdmin()) { - bool b = sValue.ToBool(); - pUser->SetDenySetBindHost(b); - PutModule("DenySetBindHost = " + CString(b)); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "defaultchanmodes") { - pUser->SetDefaultChanModes(sValue); - PutModule("DefaultChanModes = " + sValue); - } else if (sVar == "quitmsg") { - pUser->SetQuitMsg(sValue); - PutModule("QuitMsg = " + sValue); - } else if (sVar == "chanbuffersize" || sVar == "buffercount") { - unsigned int i = sValue.ToUInt(); - // Admins don't have to honour the buffer limit - if (pUser->SetChanBufferSize(i, GetUser()->IsAdmin())) { - PutModule("ChanBufferSize = " + sValue); - } else { - PutModule("Setting failed, limit is " + - CString(CZNC::Get().GetMaxBufferSize())); - } - } else if (sVar == "querybuffersize") { - unsigned int i = sValue.ToUInt(); - // Admins don't have to honour the buffer limit - if (pUser->SetQueryBufferSize(i, GetUser()->IsAdmin())) { - PutModule("QueryBufferSize = " + sValue); - } else { - PutModule("Setting failed, limit is " + - CString(CZNC::Get().GetMaxBufferSize())); - } - } else if (sVar == "keepbuffer") { - // XXX compatibility crap, added in 0.207 - bool b = !sValue.ToBool(); - pUser->SetAutoClearChanBuffer(b); - PutModule("AutoClearChanBuffer = " + CString(b)); - } else if (sVar == "autoclearchanbuffer") { - bool b = sValue.ToBool(); - pUser->SetAutoClearChanBuffer(b); - PutModule("AutoClearChanBuffer = " + CString(b)); - } else if (sVar == "autoclearquerybuffer") { - bool b = sValue.ToBool(); - pUser->SetAutoClearQueryBuffer(b); - PutModule("AutoClearQueryBuffer = " + CString(b)); - } else if (sVar == "password") { - const CString sSalt = CUtils::GetSalt(); - const CString sHash = CUser::SaltedHash(sValue, sSalt); - pUser->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); - PutModule("Password has been changed!"); - } else if (sVar == "maxjoins") { - unsigned int i = sValue.ToUInt(); - pUser->SetMaxJoins(i); - PutModule("MaxJoins = " + CString(pUser->MaxJoins())); - } else if (sVar == "maxnetworks") { - if (GetUser()->IsAdmin()) { - unsigned int i = sValue.ToUInt(); - pUser->SetMaxNetworks(i); - PutModule("MaxNetworks = " + sValue); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "maxquerybuffers") { - unsigned int i = sValue.ToUInt(); - pUser->SetMaxQueryBuffers(i); - PutModule("MaxQueryBuffers = " + sValue); - } else if (sVar == "jointries") { - unsigned int i = sValue.ToUInt(); - pUser->SetJoinTries(i); - PutModule("JoinTries = " + CString(pUser->JoinTries())); - } else if (sVar == "timezone") { - pUser->SetTimezone(sValue); - PutModule("Timezone = " + pUser->GetTimezone()); - } else if (sVar == "admin") { - if (GetUser()->IsAdmin() && pUser != GetUser()) { - bool b = sValue.ToBool(); - pUser->SetAdmin(b); - PutModule("Admin = " + CString(pUser->IsAdmin())); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "prependtimestamp") { - bool b = sValue.ToBool(); - pUser->SetTimestampPrepend(b); - PutModule("PrependTimestamp = " + CString(b)); - } else if (sVar == "appendtimestamp") { - bool b = sValue.ToBool(); - pUser->SetTimestampAppend(b); - PutModule("AppendTimestamp = " + CString(b)); - } else if (sVar == "timestampformat") { - pUser->SetTimestampFormat(sValue); - PutModule("TimestampFormat = " + sValue); - } else if (sVar == "dccbindhost") { - if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { - pUser->SetDCCBindHost(sValue); - PutModule("DCCBindHost = " + sValue); - } else { - PutModule("Access denied!"); - } - } else if (sVar == "statusprefix") { - if (sVar.find_first_of(" \t\n") == CString::npos) { - pUser->SetStatusPrefix(sValue); - PutModule("StatusPrefix = " + sValue); - } else { - PutModule("That would be a bad idea!"); - } - } + pUser->SetBindHost(sValue); + PutModule("BindHost = " + sValue); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "multiclients") { + bool b = sValue.ToBool(); + pUser->SetMultiClients(b); + PutModule("MultiClients = " + CString(b)); + } else if (sVar == "denyloadmod") { + if (GetUser()->IsAdmin()) { + bool b = sValue.ToBool(); + pUser->SetDenyLoadMod(b); + PutModule("DenyLoadMod = " + CString(b)); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "denysetbindhost") { + if (GetUser()->IsAdmin()) { + bool b = sValue.ToBool(); + pUser->SetDenySetBindHost(b); + PutModule("DenySetBindHost = " + CString(b)); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "defaultchanmodes") { + pUser->SetDefaultChanModes(sValue); + PutModule("DefaultChanModes = " + sValue); + } else if (sVar == "quitmsg") { + pUser->SetQuitMsg(sValue); + PutModule("QuitMsg = " + sValue); + } else if (sVar == "chanbuffersize" || sVar == "buffercount") { + unsigned int i = sValue.ToUInt(); + // Admins don't have to honour the buffer limit + if (pUser->SetChanBufferSize(i, GetUser()->IsAdmin())) { + PutModule("ChanBufferSize = " + sValue); + } else { + PutModule("Setting failed, limit is " + + CString(CZNC::Get().GetMaxBufferSize())); + } + } else if (sVar == "querybuffersize") { + unsigned int i = sValue.ToUInt(); + // Admins don't have to honour the buffer limit + if (pUser->SetQueryBufferSize(i, GetUser()->IsAdmin())) { + PutModule("QueryBufferSize = " + sValue); + } else { + PutModule("Setting failed, limit is " + + CString(CZNC::Get().GetMaxBufferSize())); + } + } else if (sVar == "keepbuffer") { + // XXX compatibility crap, added in 0.207 + bool b = !sValue.ToBool(); + pUser->SetAutoClearChanBuffer(b); + PutModule("AutoClearChanBuffer = " + CString(b)); + } else if (sVar == "autoclearchanbuffer") { + bool b = sValue.ToBool(); + pUser->SetAutoClearChanBuffer(b); + PutModule("AutoClearChanBuffer = " + CString(b)); + } else if (sVar == "autoclearquerybuffer") { + bool b = sValue.ToBool(); + pUser->SetAutoClearQueryBuffer(b); + PutModule("AutoClearQueryBuffer = " + CString(b)); + } else if (sVar == "password") { + const CString sSalt = CUtils::GetSalt(); + const CString sHash = CUser::SaltedHash(sValue, sSalt); + pUser->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); + PutModule("Password has been changed!"); + } else if (sVar == "maxjoins") { + unsigned int i = sValue.ToUInt(); + pUser->SetMaxJoins(i); + PutModule("MaxJoins = " + CString(pUser->MaxJoins())); + } else if (sVar == "maxnetworks") { + if (GetUser()->IsAdmin()) { + unsigned int i = sValue.ToUInt(); + pUser->SetMaxNetworks(i); + PutModule("MaxNetworks = " + sValue); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "maxquerybuffers") { + unsigned int i = sValue.ToUInt(); + pUser->SetMaxQueryBuffers(i); + PutModule("MaxQueryBuffers = " + sValue); + } else if (sVar == "jointries") { + unsigned int i = sValue.ToUInt(); + pUser->SetJoinTries(i); + PutModule("JoinTries = " + CString(pUser->JoinTries())); + } else if (sVar == "timezone") { + pUser->SetTimezone(sValue); + PutModule("Timezone = " + pUser->GetTimezone()); + } else if (sVar == "admin") { + if (GetUser()->IsAdmin() && pUser != GetUser()) { + bool b = sValue.ToBool(); + pUser->SetAdmin(b); + PutModule("Admin = " + CString(pUser->IsAdmin())); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "prependtimestamp") { + bool b = sValue.ToBool(); + pUser->SetTimestampPrepend(b); + PutModule("PrependTimestamp = " + CString(b)); + } else if (sVar == "appendtimestamp") { + bool b = sValue.ToBool(); + pUser->SetTimestampAppend(b); + PutModule("AppendTimestamp = " + CString(b)); + } else if (sVar == "timestampformat") { + pUser->SetTimestampFormat(sValue); + PutModule("TimestampFormat = " + sValue); + } else if (sVar == "dccbindhost") { + if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { + pUser->SetDCCBindHost(sValue); + PutModule("DCCBindHost = " + sValue); + } else { + PutModule("Access denied!"); + } + } else if (sVar == "statusprefix") { + if (sVar.find_first_of(" \t\n") == CString::npos) { + pUser->SetStatusPrefix(sValue); + PutModule("StatusPrefix = " + sValue); + } else { + PutModule("That would be a bad idea!"); + } + } #ifdef HAVE_ICU - else if (sVar == "clientencoding") { - pUser->SetClientEncoding(sValue); - PutModule("ClientEncoding = " + sValue); - } + else if (sVar == "clientencoding") { + pUser->SetClientEncoding(sValue); + PutModule("ClientEncoding = " + sValue); + } #endif - else - PutModule("Error: Unknown variable"); - } + else + PutModule("Error: Unknown variable"); + } - void GetNetwork(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - const CString sUsername = sLine.Token(2); - const CString sNetwork = sLine.Token(3); + void GetNetwork(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + const CString sUsername = sLine.Token(2); + const CString sNetwork = sLine.Token(3); - CIRCNetwork* pNetwork = nullptr; - CUser* pUser; + CIRCNetwork* pNetwork = nullptr; + CUser* pUser; - if (sVar.empty()) { - PutModule("Usage: GetNetwork [username] [network]"); - return; - } + if (sVar.empty()) { + PutModule("Usage: GetNetwork [username] [network]"); + return; + } - if (sUsername.empty()) { - pUser = GetUser(); - } else { - pUser = FindUser(sUsername); - } + if (sUsername.empty()) { + pUser = GetUser(); + } else { + pUser = FindUser(sUsername); + } - if (!pUser) { - return; - } + if (!pUser) { + return; + } - if (sNetwork.empty()) { - if (pUser == GetUser()) { - pNetwork = CModule::GetNetwork(); - } else { - PutModule( - "Error: A network must be specified to get another users " - "settings."); - return; - } + if (sNetwork.empty()) { + if (pUser == GetUser()) { + pNetwork = CModule::GetNetwork(); + } else { + PutModule( + "Error: A network must be specified to get another users " + "settings."); + return; + } - if (!pNetwork) { - PutModule("You are not currently attached to a network."); - return; - } - } else { - pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - PutModule("Error: Invalid network."); - return; - } - } + if (!pNetwork) { + PutModule("You are not currently attached to a network."); + return; + } + } else { + pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + PutModule("Error: Invalid network."); + return; + } + } - if (sVar.Equals("nick")) { - PutModule("Nick = " + pNetwork->GetNick()); - } else if (sVar.Equals("altnick")) { - PutModule("AltNick = " + pNetwork->GetAltNick()); - } else if (sVar.Equals("ident")) { - PutModule("Ident = " + pNetwork->GetIdent()); - } else if (sVar.Equals("realname")) { - PutModule("RealName = " + pNetwork->GetRealName()); - } else if (sVar.Equals("bindhost")) { - PutModule("BindHost = " + pNetwork->GetBindHost()); - } else if (sVar.Equals("floodrate")) { - PutModule("FloodRate = " + CString(pNetwork->GetFloodRate())); - } else if (sVar.Equals("floodburst")) { - PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); - } else if (sVar.Equals("joindelay")) { - PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); + if (sVar.Equals("nick")) { + PutModule("Nick = " + pNetwork->GetNick()); + } else if (sVar.Equals("altnick")) { + PutModule("AltNick = " + pNetwork->GetAltNick()); + } else if (sVar.Equals("ident")) { + PutModule("Ident = " + pNetwork->GetIdent()); + } else if (sVar.Equals("realname")) { + PutModule("RealName = " + pNetwork->GetRealName()); + } else if (sVar.Equals("bindhost")) { + PutModule("BindHost = " + pNetwork->GetBindHost()); + } else if (sVar.Equals("floodrate")) { + PutModule("FloodRate = " + CString(pNetwork->GetFloodRate())); + } else if (sVar.Equals("floodburst")) { + PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); + } else if (sVar.Equals("joindelay")) { + PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); #ifdef HAVE_ICU - } else if (sVar.Equals("encoding")) { - PutModule("Encoding = " + pNetwork->GetEncoding()); + } else if (sVar.Equals("encoding")) { + PutModule("Encoding = " + pNetwork->GetEncoding()); #endif - } else if (sVar.Equals("quitmsg")) { - PutModule("QuitMsg = " + pNetwork->GetQuitMsg()); - } else { - PutModule("Error: Unknown variable"); - } - } + } else if (sVar.Equals("quitmsg")) { + PutModule("QuitMsg = " + pNetwork->GetQuitMsg()); + } else { + PutModule("Error: Unknown variable"); + } + } - void SetNetwork(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - const CString sUsername = sLine.Token(2); - const CString sNetwork = sLine.Token(3); - const CString sValue = sLine.Token(4, true); + void SetNetwork(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + const CString sUsername = sLine.Token(2); + const CString sNetwork = sLine.Token(3); + const CString sValue = sLine.Token(4, true); - CUser* pUser = nullptr; - CIRCNetwork* pNetwork = nullptr; + CUser* pUser = nullptr; + CIRCNetwork* pNetwork = nullptr; - if (sValue.empty()) { - PutModule( - "Usage: SetNetwork "); - return; - } + if (sValue.empty()) { + PutModule( + "Usage: SetNetwork "); + return; + } - if (sUsername.empty()) { - pUser = GetUser(); - pNetwork = CModule::GetNetwork(); - } else { - pUser = FindUser(sUsername); - if (!pUser) { - return; - } + if (sUsername.empty()) { + pUser = GetUser(); + pNetwork = CModule::GetNetwork(); + } else { + pUser = FindUser(sUsername); + if (!pUser) { + return; + } - pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork && !sNetwork.empty()) { - return; - } - } + pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork && !sNetwork.empty()) { + return; + } + } - if (sVar.Equals("nick")) { - pNetwork->SetNick(sValue); - PutModule("Nick = " + pNetwork->GetNick()); - } else if (sVar.Equals("altnick")) { - pNetwork->SetAltNick(sValue); - PutModule("AltNick = " + pNetwork->GetAltNick()); - } else if (sVar.Equals("ident")) { - pNetwork->SetIdent(sValue); - PutModule("Ident = " + pNetwork->GetIdent()); - } else if (sVar.Equals("realname")) { - pNetwork->SetRealName(sValue); - PutModule("RealName = " + pNetwork->GetRealName()); - } else if (sVar.Equals("bindhost")) { - if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { - if (sValue.Equals(pNetwork->GetBindHost())) { - PutModule("This bind host is already set!"); - return; - } + if (sVar.Equals("nick")) { + pNetwork->SetNick(sValue); + PutModule("Nick = " + pNetwork->GetNick()); + } else if (sVar.Equals("altnick")) { + pNetwork->SetAltNick(sValue); + PutModule("AltNick = " + pNetwork->GetAltNick()); + } else if (sVar.Equals("ident")) { + pNetwork->SetIdent(sValue); + PutModule("Ident = " + pNetwork->GetIdent()); + } else if (sVar.Equals("realname")) { + pNetwork->SetRealName(sValue); + PutModule("RealName = " + pNetwork->GetRealName()); + } else if (sVar.Equals("bindhost")) { + if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) { + if (sValue.Equals(pNetwork->GetBindHost())) { + PutModule("This bind host is already set!"); + return; + } - pNetwork->SetBindHost(sValue); - PutModule("BindHost = " + sValue); - } else { - PutModule("Access denied!"); - } - } else if (sVar.Equals("floodrate")) { - pNetwork->SetFloodRate(sValue.ToDouble()); - PutModule("FloodRate = " + CString(pNetwork->GetFloodRate())); - } else if (sVar.Equals("floodburst")) { - pNetwork->SetFloodBurst(sValue.ToUShort()); - PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); - } else if (sVar.Equals("joindelay")) { - pNetwork->SetJoinDelay(sValue.ToUShort()); - PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); + pNetwork->SetBindHost(sValue); + PutModule("BindHost = " + sValue); + } else { + PutModule("Access denied!"); + } + } else if (sVar.Equals("floodrate")) { + pNetwork->SetFloodRate(sValue.ToDouble()); + PutModule("FloodRate = " + CString(pNetwork->GetFloodRate())); + } else if (sVar.Equals("floodburst")) { + pNetwork->SetFloodBurst(sValue.ToUShort()); + PutModule("FloodBurst = " + CString(pNetwork->GetFloodBurst())); + } else if (sVar.Equals("joindelay")) { + pNetwork->SetJoinDelay(sValue.ToUShort()); + PutModule("JoinDelay = " + CString(pNetwork->GetJoinDelay())); #ifdef HAVE_ICU - } else if (sVar.Equals("encoding")) { - pNetwork->SetEncoding(sValue); - PutModule("Encoding = " + pNetwork->GetEncoding()); + } else if (sVar.Equals("encoding")) { + pNetwork->SetEncoding(sValue); + PutModule("Encoding = " + pNetwork->GetEncoding()); #endif - } else if (sVar.Equals("quitmsg")) { - pNetwork->SetQuitMsg(sValue); - PutModule("QuitMsg = " + pNetwork->GetQuitMsg()); - } else { - PutModule("Error: Unknown variable"); - } - } - - void AddChan(const CString& sLine) { - const CString sUsername = sLine.Token(1); - const CString sNetwork = sLine.Token(2); - const CString sChan = sLine.Token(3); - - if (sChan.empty()) { - PutModule("Usage: AddChan "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - if (pNetwork->FindChan(sChan)) { - PutModule("Error: [" + sUsername + - "] already has a channel named [" + sChan + "]."); - return; - } - - CChan* pChan = new CChan(sChan, pNetwork, true); - if (pNetwork->AddChan(pChan)) - PutModule("Channel [" + pChan->GetName() + "] for user [" + - sUsername + "] added."); - else - PutModule("Could not add channel [" + sChan + "] for user [" + - sUsername + "], does it already exist?"); - } - - void DelChan(const CString& sLine) { - const CString sUsername = sLine.Token(1); - const CString sNetwork = sLine.Token(2); - const CString sChan = sLine.Token(3); - - if (sChan.empty()) { - PutModule("Usage: DelChan "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - std::vector vChans = pNetwork->FindChans(sChan); - if (vChans.empty()) { - PutModule("Error: User [" + sUsername + - "] does not have any channel matching [" + sChan + "]."); - return; - } - - VCString vsNames; - for (const CChan* pChan : vChans) { - const CString& sName = pChan->GetName(); - vsNames.push_back(sName); - pNetwork->PutIRC("PART " + sName); - pNetwork->DelChan(sName); - } - - PutModule("Channel(s) [" + - CString(",").Join(vsNames.begin(), vsNames.end()) + - "] for user [" + sUsername + "] deleted."); - } - - void GetChan(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - CString sUsername = sLine.Token(2); - CString sNetwork = sLine.Token(3); - CString sChan = sLine.Token(4, true); - - if (sChan.empty()) { - PutModule("Usage: GetChan "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - std::vector vChans = pNetwork->FindChans(sChan); - if (vChans.empty()) { - PutModule("Error: No channel(s) matching [" + sChan + "] found."); - return; - } - - for (CChan* pChan : vChans) { - if (sVar == "defmodes") { - PutModule(pChan->GetName() + ": DefModes = " + - pChan->GetDefaultModes()); - } else if (sVar == "buffersize" || sVar == "buffer") { - CString sValue(pChan->GetBufferCount()); - if (!pChan->HasBufferCountSet()) { - sValue += " (default)"; - } - PutModule(pChan->GetName() + ": BufferSize = " + sValue); - } else if (sVar == "inconfig") { - PutModule(pChan->GetName() + ": InConfig = " + - CString(pChan->InConfig())); - } else if (sVar == "keepbuffer") { - // XXX compatibility crap, added in 0.207 - PutModule(pChan->GetName() + ": KeepBuffer = " + - CString(!pChan->AutoClearChanBuffer())); - } else if (sVar == "autoclearchanbuffer") { - CString sValue(pChan->AutoClearChanBuffer()); - if (!pChan->HasAutoClearChanBufferSet()) { - sValue += " (default)"; - } - PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + - sValue); - } else if (sVar == "detached") { - PutModule(pChan->GetName() + ": Detached = " + - CString(pChan->IsDetached())); - } else if (sVar == "key") { - PutModule(pChan->GetName() + ": Key = " + pChan->GetKey()); - } else { - PutModule("Error: Unknown variable"); - return; - } - } - } - - void SetChan(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - CString sUsername = sLine.Token(2); - CString sNetwork = sLine.Token(3); - CString sChan = sLine.Token(4); - CString sValue = sLine.Token(5, true); - - if (sValue.empty()) { - PutModule( - "Usage: SetChan " - ""); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - std::vector vChans = pNetwork->FindChans(sChan); - if (vChans.empty()) { - PutModule("Error: No channel(s) matching [" + sChan + "] found."); - return; - } - - for (CChan* pChan : vChans) { - if (sVar == "defmodes") { - pChan->SetDefaultModes(sValue); - PutModule(pChan->GetName() + ": DefModes = " + sValue); - } else if (sVar == "buffersize" || sVar == "buffer") { - unsigned int i = sValue.ToUInt(); - if (sValue.Equals("-")) { - pChan->ResetBufferCount(); - PutModule(pChan->GetName() + ": BufferSize = " + - CString(pChan->GetBufferCount())); - } else if (pChan->SetBufferCount(i, GetUser()->IsAdmin())) { - // Admins don't have to honour the buffer limit - PutModule(pChan->GetName() + ": BufferSize = " + sValue); - } else { - PutModule("Setting failed, limit is " + - CString(CZNC::Get().GetMaxBufferSize())); - return; - } - } else if (sVar == "inconfig") { - bool b = sValue.ToBool(); - pChan->SetInConfig(b); - PutModule(pChan->GetName() + ": InConfig = " + CString(b)); - } else if (sVar == "keepbuffer") { - // XXX compatibility crap, added in 0.207 - bool b = !sValue.ToBool(); - pChan->SetAutoClearChanBuffer(b); - PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + - CString(b)); - } else if (sVar == "autoclearchanbuffer") { - if (sValue.Equals("-")) { - pChan->ResetAutoClearChanBuffer(); - } else { - bool b = sValue.ToBool(); - pChan->SetAutoClearChanBuffer(b); - } - PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + - CString(pChan->AutoClearChanBuffer())); - } else if (sVar == "detached") { - bool b = sValue.ToBool(); - if (pChan->IsDetached() != b) { - if (b) - pChan->DetachUser(); - else - pChan->AttachUser(); - } - PutModule(pChan->GetName() + ": Detached = " + CString(b)); - } else if (sVar == "key") { - pChan->SetKey(sValue); - PutModule(pChan->GetName() + ": Key = " + sValue); - } else { - PutModule("Error: Unknown variable"); - return; - } - } - } - - void ListUsers(const CString&) { - if (!GetUser()->IsAdmin()) return; - - const map& msUsers = CZNC::Get().GetUserMap(); - CTable Table; - Table.AddColumn("Username"); - Table.AddColumn("Realname"); - Table.AddColumn("IsAdmin"); - Table.AddColumn("Nick"); - Table.AddColumn("AltNick"); - Table.AddColumn("Ident"); - Table.AddColumn("BindHost"); - - for (const auto& it : msUsers) { - Table.AddRow(); - Table.SetCell("Username", it.first); - Table.SetCell("Realname", it.second->GetRealName()); - if (!it.second->IsAdmin()) - Table.SetCell("IsAdmin", "No"); - else - Table.SetCell("IsAdmin", "Yes"); - Table.SetCell("Nick", it.second->GetNick()); - Table.SetCell("AltNick", it.second->GetAltNick()); - Table.SetCell("Ident", it.second->GetIdent()); - Table.SetCell("BindHost", it.second->GetBindHost()); - } - - PutModule(Table); - } - - void AddUser(const CString& sLine) { - if (!GetUser()->IsAdmin()) { - PutModule("Error: You need to have admin rights to add new users!"); - return; - } - - const CString sUsername = sLine.Token(1), sPassword = sLine.Token(2); - if (sPassword.empty()) { - PutModule("Usage: AddUser "); - return; - } - - if (CZNC::Get().FindUser(sUsername)) { - PutModule("Error: User [" + sUsername + "] already exists!"); - return; - } - - CUser* pNewUser = new CUser(sUsername); - CString sSalt = CUtils::GetSalt(); - pNewUser->SetPass(CUser::SaltedHash(sPassword, sSalt), - CUser::HASH_DEFAULT, sSalt); - - CString sErr; - if (!CZNC::Get().AddUser(pNewUser, sErr)) { - delete pNewUser; - PutModule("Error: User not added! [" + sErr + "]"); - return; - } - - PutModule("User [" + sUsername + "] added!"); - return; - } - - void DelUser(const CString& sLine) { - if (!GetUser()->IsAdmin()) { - PutModule("Error: You need to have admin rights to delete users!"); - return; - } - - const CString sUsername = sLine.Token(1, true); - if (sUsername.empty()) { - PutModule("Usage: DelUser "); - return; - } - - CUser* pUser = CZNC::Get().FindUser(sUsername); - - if (!pUser) { - PutModule("Error: User [" + sUsername + "] does not exist!"); - return; - } - - if (pUser == GetUser()) { - PutModule("Error: You can't delete yourself!"); - return; - } - - if (!CZNC::Get().DeleteUser(pUser->GetUserName())) { - // This can't happen, because we got the user from FindUser() - PutModule("Error: Internal error!"); - return; - } - - PutModule("User [" + sUsername + "] deleted!"); - return; - } - - void CloneUser(const CString& sLine) { - if (!GetUser()->IsAdmin()) { - PutModule("Error: You need to have admin rights to add new users!"); - return; - } - - const CString sOldUsername = sLine.Token(1), - sNewUsername = sLine.Token(2, true); - - if (sOldUsername.empty() || sNewUsername.empty()) { - PutModule("Usage: CloneUser "); - return; - } - - CUser* pOldUser = CZNC::Get().FindUser(sOldUsername); - - if (!pOldUser) { - PutModule("Error: User [" + sOldUsername + "] not found!"); - return; - } - - CUser* pNewUser = new CUser(sNewUsername); - CString sError; - if (!pNewUser->Clone(*pOldUser, sError)) { - delete pNewUser; - PutModule("Error: Cloning failed! [" + sError + "]"); - return; - } - - if (!CZNC::Get().AddUser(pNewUser, sError)) { - delete pNewUser; - PutModule("Error: User not added! [" + sError + "]"); - return; - } - - PutModule("User [" + sNewUsername + "] added!"); - return; - } - - void AddNetwork(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CUser* pUser = GetUser(); - - if (sNetwork.empty()) { - sNetwork = sUser; - } else { - pUser = FindUser(sUser); - if (!pUser) { - PutModule("User [" + sUser + "] not found"); - return; - } - } - - if (sNetwork.empty()) { - PutModule("Usage: AddNetwork [user] network"); - return; - } - - if (!GetUser()->IsAdmin() && !pUser->HasSpaceForNewNetwork()) { - PutStatus( - "Network number limit reached. Ask an admin to increase the " - "limit for you, or delete unneeded networks using /znc " - "DelNetwork "); - return; - } - - if (pUser->FindNetwork(sNetwork)) { - PutModule("[" + pUser->GetUserName() + - "] already has a network with the name [" + sNetwork + - "]"); - return; - } - - CString sNetworkAddError; - if (pUser->AddNetwork(sNetwork, sNetworkAddError)) { - PutModule("Network [" + sNetwork + "] added for user [" + - pUser->GetUserName() + "]."); - } else { - PutModule("Network [" + sNetwork + - "] could not be added for user [" + pUser->GetUserName() + - "]: " + sNetworkAddError); - } - } - - void DelNetwork(const CString& sLine) { - CString sUser = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CUser* pUser = GetUser(); - - if (sNetwork.empty()) { - sNetwork = sUser; - } else { - pUser = FindUser(sUser); - if (!pUser) { - return; - } - } - - if (sNetwork.empty()) { - PutModule("Usage: DelNetwork [user] network"); - return; - } - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - if (pNetwork == CModule::GetNetwork()) { - PutModule("The currently active network can be deleted via " + - GetUser()->GetStatusPrefix() + "status"); - return; - } - - if (pUser->DeleteNetwork(sNetwork)) { - PutModule("Network [" + sNetwork + "] deleted on user [" + - pUser->GetUserName() + "]."); - } else { - PutModule("Network [" + sNetwork + - "] could not be deleted for user [" + - pUser->GetUserName() + "]."); - } - } - - void ListNetworks(const CString& sLine) { - CString sUser = sLine.Token(1); - CUser* pUser = GetUser(); - - if (!sUser.empty()) { - pUser = FindUser(sUser); - if (!pUser) { - return; - } - } - - const vector& vNetworks = pUser->GetNetworks(); - - CTable Table; - Table.AddColumn("Network"); - Table.AddColumn("OnIRC"); - Table.AddColumn("IRC Server"); - Table.AddColumn("IRC User"); - Table.AddColumn("Channels"); - - for (const CIRCNetwork* pNetwork : vNetworks) { - Table.AddRow(); - Table.SetCell("Network", pNetwork->GetName()); - if (pNetwork->IsIRCConnected()) { - Table.SetCell("OnIRC", "Yes"); - Table.SetCell("IRC Server", pNetwork->GetIRCServer()); - Table.SetCell("IRC User", pNetwork->GetIRCNick().GetNickMask()); - Table.SetCell("Channels", CString(pNetwork->GetChans().size())); - } else { - Table.SetCell("OnIRC", "No"); - } - } - - if (PutModule(Table) == 0) { - PutModule("No networks"); - } - } - - void AddServer(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CString sServer = sLine.Token(3, true); - - if (sServer.empty()) { - PutModule("Usage: AddServer "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - if (pNetwork->AddServer(sServer)) - PutModule("Added IRC Server [" + sServer + "] for network [" + - sNetwork + "] for user [" + pUser->GetUserName() + "]."); - else - PutModule("Could not add IRC server [" + sServer + - "] for network [" + sNetwork + "] for user [" + - pUser->GetUserName() + "]."); - } - - void DelServer(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CString sServer = sLine.Token(3, true); - unsigned short uPort = sLine.Token(4).ToUShort(); - CString sPass = sLine.Token(5); - - if (sServer.empty()) { - PutModule("Usage: DelServer "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - if (pNetwork->DelServer(sServer, uPort, sPass)) - PutModule("Deleted IRC Server [" + sServer + "] for network [" + - sNetwork + "] for user [" + pUser->GetUserName() + "]."); - else - PutModule("Could not delete IRC server [" + sServer + - "] for network [" + sNetwork + "] for user [" + - pUser->GetUserName() + "]."); - } - - void ReconnectUser(const CString& sLine) { - CString sUserName = sLine.Token(1); - CString sNetwork = sLine.Token(2); - - if (sNetwork.empty()) { - PutModule("Usage: Reconnect "); - return; - } - - CUser* pUser = FindUser(sUserName); - if (!pUser) { - PutModule("User [" + sUserName + "] not found."); - return; - } - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - CIRCSock* pIRCSock = pNetwork->GetIRCSock(); - // cancel connection attempt: - if (pIRCSock && !pIRCSock->IsConnected()) { - pIRCSock->Close(); - } - // or close existing connection: - else if (pIRCSock) { - pIRCSock->Quit(); - } - - // then reconnect - pNetwork->SetIRCConnectEnabled(true); - - PutModule("Queued network [" + sNetwork + "] for user [" + - pUser->GetUserName() + "] for a reconnect."); - } - - void DisconnectUser(const CString& sLine) { - CString sUserName = sLine.Token(1); - CString sNetwork = sLine.Token(2); - - if (sNetwork.empty()) { - PutModule("Usage: Disconnect "); - return; - } - - CUser* pUser = FindUser(sUserName); - if (!pUser) { - PutModule("User [" + sUserName + "] not found."); - return; - } - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - pNetwork->SetIRCConnectEnabled(false); - PutModule("Closed IRC connection for network [" + sNetwork + - "] on user [" + sUserName + "]."); - } - - void ListCTCP(const CString& sLine) { - CString sUserName = sLine.Token(1, true); - - if (sUserName.empty()) { - sUserName = GetUser()->GetUserName(); - } - CUser* pUser = FindUser(sUserName); - if (!pUser) return; - - const MCString& msCTCPReplies = pUser->GetCTCPReplies(); - CTable Table; - Table.AddColumn("Request"); - Table.AddColumn("Reply"); - for (const auto& it : msCTCPReplies) { - Table.AddRow(); - Table.SetCell("Request", it.first); - Table.SetCell("Reply", it.second); - } - - if (Table.empty()) { - PutModule("No CTCP replies for user [" + pUser->GetUserName() + - "] configured!"); - } else { - PutModule("CTCP replies for user [" + pUser->GetUserName() + "]:"); - PutModule(Table); - } - } - - void AddCTCP(const CString& sLine) { - CString sUserName = sLine.Token(1); - CString sCTCPRequest = sLine.Token(2); - CString sCTCPReply = sLine.Token(3, true); - - if (sCTCPRequest.empty()) { - sCTCPRequest = sUserName; - sCTCPReply = sLine.Token(2, true); - sUserName = GetUser()->GetUserName(); - } - if (sCTCPRequest.empty()) { - PutModule("Usage: AddCTCP [user] [request] [reply]"); - PutModule( - "This will cause ZNC to reply to the CTCP instead of " - "forwarding it to clients."); - PutModule( - "An empty reply will cause the CTCP request to be blocked."); - return; - } - - CUser* pUser = FindUser(sUserName); - if (!pUser) return; - - if (pUser->AddCTCPReply(sCTCPRequest, sCTCPReply)) - PutModule("Added!"); - else - PutModule("Error!"); - } - - void DelCTCP(const CString& sLine) { - CString sUserName = sLine.Token(1); - CString sCTCPRequest = sLine.Token(2, true); - - if (sCTCPRequest.empty()) { - sCTCPRequest = sUserName; - sUserName = GetUser()->GetUserName(); - } - CUser* pUser = FindUser(sUserName); - if (!pUser) return; - - if (sCTCPRequest.empty()) { - PutModule("Usage: DelCTCP [user] [request]"); - return; - } - - if (pUser->DelCTCPReply(sCTCPRequest)) - PutModule("Successfully removed [" + sCTCPRequest + "] for user [" + - pUser->GetUserName() + "]."); - else - PutModule("Error: [" + sCTCPRequest + "] not found for user [" + - pUser->GetUserName() + "]!"); - } - - void LoadModuleFor(CModules& Modules, const CString& sModName, - const CString& sArgs, CModInfo::EModuleType eType, - CUser* pUser, CIRCNetwork* pNetwork) { - if (pUser->DenyLoadMod() && !GetUser()->IsAdmin()) { - PutModule("Loading modules has been disabled."); - return; - } - - CString sModRet; - CModule* pMod = Modules.FindModule(sModName); - if (!pMod) { - if (!Modules.LoadModule(sModName, sArgs, eType, pUser, pNetwork, - sModRet)) { - PutModule("Unable to load module [" + sModName + "] [" + - sModRet + "]"); - } else { - PutModule("Loaded module [" + sModName + "]"); - } - } else if (pMod->GetArgs() != sArgs) { - if (!Modules.ReloadModule(sModName, sArgs, pUser, pNetwork, - sModRet)) { - PutModule("Unable to reload module [" + sModName + "] [" + - sModRet + "]"); - } else { - PutModule("Reloaded module [" + sModName + "]"); - } - } else { - PutModule("Unable to load module [" + sModName + - "] because it is already loaded"); - } - } - - void LoadModuleForUser(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sModName = sLine.Token(2); - CString sArgs = sLine.Token(3, true); - - if (sModName.empty()) { - PutModule("Usage: LoadModule [args]"); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - LoadModuleFor(pUser->GetModules(), sModName, sArgs, - CModInfo::UserModule, pUser, nullptr); - } - - void LoadModuleForNetwork(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CString sModName = sLine.Token(3); - CString sArgs = sLine.Token(4, true); - - if (sModName.empty()) { - PutModule( - "Usage: LoadNetModule " - "[args]"); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - LoadModuleFor(pNetwork->GetModules(), sModName, sArgs, - CModInfo::NetworkModule, pUser, pNetwork); - } - - void UnLoadModuleFor(CModules& Modules, const CString& sModName, - CUser* pUser) { - if (pUser->DenyLoadMod() && !GetUser()->IsAdmin()) { - PutModule("Loading modules has been disabled."); - return; - } - - if (Modules.FindModule(sModName) == this) { - PutModule("Please use /znc unloadmod " + sModName); - return; - } - - CString sModRet; - if (!Modules.UnloadModule(sModName, sModRet)) { - PutModule("Unable to unload module [" + sModName + "] [" + sModRet + - "]"); - } else { - PutModule("Unloaded module [" + sModName + "]"); - } - } - - void UnLoadModuleForUser(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sModName = sLine.Token(2); - - if (sModName.empty()) { - PutModule("Usage: UnloadModule "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - UnLoadModuleFor(pUser->GetModules(), sModName, pUser); - } - - void UnLoadModuleForNetwork(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sNetwork = sLine.Token(2); - CString sModName = sLine.Token(3); - - if (sModName.empty()) { - PutModule( - "Usage: UnloadNetModule "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - UnLoadModuleFor(pNetwork->GetModules(), sModName, pUser); - } - - void ListModulesFor(CModules& Modules, const CString& sWhere) { - if (!Modules.size()) { - PutModule(sWhere + " has no modules loaded."); - } else { - PutModule("Modules loaded for " + sWhere + ":"); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Arguments"); - - for (const CModule* pMod : Modules) { - Table.AddRow(); - Table.SetCell("Name", pMod->GetModName()); - Table.SetCell("Arguments", pMod->GetArgs()); - } - - PutModule(Table); - } - } - - void ListModulesForUser(const CString& sLine) { - CString sUsername = sLine.Token(1); - - if (sUsername.empty()) { - PutModule("Usage: ListMods "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - ListModulesFor(pUser->GetModules(), - "User [" + pUser->GetUserName() + "]"); - } - - void ListModulesForNetwork(const CString& sLine) { - CString sUsername = sLine.Token(1); - CString sNetwork = sLine.Token(2); - - if (sNetwork.empty()) { - PutModule("Usage: ListNetMods "); - return; - } - - CUser* pUser = FindUser(sUsername); - if (!pUser) return; - - CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); - if (!pNetwork) { - return; - } - - ListModulesFor(pNetwork->GetModules(), - "Network [" + pNetwork->GetName() + "] of user [" + - pUser->GetUserName() + "]"); - } + } else if (sVar.Equals("quitmsg")) { + pNetwork->SetQuitMsg(sValue); + PutModule("QuitMsg = " + pNetwork->GetQuitMsg()); + } else { + PutModule("Error: Unknown variable"); + } + } + + void AddChan(const CString& sLine) { + const CString sUsername = sLine.Token(1); + const CString sNetwork = sLine.Token(2); + const CString sChan = sLine.Token(3); + + if (sChan.empty()) { + PutModule("Usage: AddChan "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + if (pNetwork->FindChan(sChan)) { + PutModule("Error: [" + sUsername + + "] already has a channel named [" + sChan + "]."); + return; + } + + CChan* pChan = new CChan(sChan, pNetwork, true); + if (pNetwork->AddChan(pChan)) + PutModule("Channel [" + pChan->GetName() + "] for user [" + + sUsername + "] added."); + else + PutModule("Could not add channel [" + sChan + "] for user [" + + sUsername + "], does it already exist?"); + } + + void DelChan(const CString& sLine) { + const CString sUsername = sLine.Token(1); + const CString sNetwork = sLine.Token(2); + const CString sChan = sLine.Token(3); + + if (sChan.empty()) { + PutModule("Usage: DelChan "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + std::vector vChans = pNetwork->FindChans(sChan); + if (vChans.empty()) { + PutModule("Error: User [" + sUsername + + "] does not have any channel matching [" + sChan + "]."); + return; + } + + VCString vsNames; + for (const CChan* pChan : vChans) { + const CString& sName = pChan->GetName(); + vsNames.push_back(sName); + pNetwork->PutIRC("PART " + sName); + pNetwork->DelChan(sName); + } + + PutModule("Channel(s) [" + + CString(",").Join(vsNames.begin(), vsNames.end()) + + "] for user [" + sUsername + "] deleted."); + } + + void GetChan(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + CString sUsername = sLine.Token(2); + CString sNetwork = sLine.Token(3); + CString sChan = sLine.Token(4, true); + + if (sChan.empty()) { + PutModule("Usage: GetChan "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + std::vector vChans = pNetwork->FindChans(sChan); + if (vChans.empty()) { + PutModule("Error: No channel(s) matching [" + sChan + "] found."); + return; + } + + for (CChan* pChan : vChans) { + if (sVar == "defmodes") { + PutModule(pChan->GetName() + ": DefModes = " + + pChan->GetDefaultModes()); + } else if (sVar == "buffersize" || sVar == "buffer") { + CString sValue(pChan->GetBufferCount()); + if (!pChan->HasBufferCountSet()) { + sValue += " (default)"; + } + PutModule(pChan->GetName() + ": BufferSize = " + sValue); + } else if (sVar == "inconfig") { + PutModule(pChan->GetName() + ": InConfig = " + + CString(pChan->InConfig())); + } else if (sVar == "keepbuffer") { + // XXX compatibility crap, added in 0.207 + PutModule(pChan->GetName() + ": KeepBuffer = " + + CString(!pChan->AutoClearChanBuffer())); + } else if (sVar == "autoclearchanbuffer") { + CString sValue(pChan->AutoClearChanBuffer()); + if (!pChan->HasAutoClearChanBufferSet()) { + sValue += " (default)"; + } + PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + + sValue); + } else if (sVar == "detached") { + PutModule(pChan->GetName() + ": Detached = " + + CString(pChan->IsDetached())); + } else if (sVar == "key") { + PutModule(pChan->GetName() + ": Key = " + pChan->GetKey()); + } else { + PutModule("Error: Unknown variable"); + return; + } + } + } + + void SetChan(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + CString sUsername = sLine.Token(2); + CString sNetwork = sLine.Token(3); + CString sChan = sLine.Token(4); + CString sValue = sLine.Token(5, true); + + if (sValue.empty()) { + PutModule( + "Usage: SetChan " + ""); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + std::vector vChans = pNetwork->FindChans(sChan); + if (vChans.empty()) { + PutModule("Error: No channel(s) matching [" + sChan + "] found."); + return; + } + + for (CChan* pChan : vChans) { + if (sVar == "defmodes") { + pChan->SetDefaultModes(sValue); + PutModule(pChan->GetName() + ": DefModes = " + sValue); + } else if (sVar == "buffersize" || sVar == "buffer") { + unsigned int i = sValue.ToUInt(); + if (sValue.Equals("-")) { + pChan->ResetBufferCount(); + PutModule(pChan->GetName() + ": BufferSize = " + + CString(pChan->GetBufferCount())); + } else if (pChan->SetBufferCount(i, GetUser()->IsAdmin())) { + // Admins don't have to honour the buffer limit + PutModule(pChan->GetName() + ": BufferSize = " + sValue); + } else { + PutModule("Setting failed, limit is " + + CString(CZNC::Get().GetMaxBufferSize())); + return; + } + } else if (sVar == "inconfig") { + bool b = sValue.ToBool(); + pChan->SetInConfig(b); + PutModule(pChan->GetName() + ": InConfig = " + CString(b)); + } else if (sVar == "keepbuffer") { + // XXX compatibility crap, added in 0.207 + bool b = !sValue.ToBool(); + pChan->SetAutoClearChanBuffer(b); + PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + + CString(b)); + } else if (sVar == "autoclearchanbuffer") { + if (sValue.Equals("-")) { + pChan->ResetAutoClearChanBuffer(); + } else { + bool b = sValue.ToBool(); + pChan->SetAutoClearChanBuffer(b); + } + PutModule(pChan->GetName() + ": AutoClearChanBuffer = " + + CString(pChan->AutoClearChanBuffer())); + } else if (sVar == "detached") { + bool b = sValue.ToBool(); + if (pChan->IsDetached() != b) { + if (b) + pChan->DetachUser(); + else + pChan->AttachUser(); + } + PutModule(pChan->GetName() + ": Detached = " + CString(b)); + } else if (sVar == "key") { + pChan->SetKey(sValue); + PutModule(pChan->GetName() + ": Key = " + sValue); + } else { + PutModule("Error: Unknown variable"); + return; + } + } + } + + void ListUsers(const CString&) { + if (!GetUser()->IsAdmin()) return; + + const map& msUsers = CZNC::Get().GetUserMap(); + CTable Table; + Table.AddColumn("Username"); + Table.AddColumn("Realname"); + Table.AddColumn("IsAdmin"); + Table.AddColumn("Nick"); + Table.AddColumn("AltNick"); + Table.AddColumn("Ident"); + Table.AddColumn("BindHost"); + + for (const auto& it : msUsers) { + Table.AddRow(); + Table.SetCell("Username", it.first); + Table.SetCell("Realname", it.second->GetRealName()); + if (!it.second->IsAdmin()) + Table.SetCell("IsAdmin", "No"); + else + Table.SetCell("IsAdmin", "Yes"); + Table.SetCell("Nick", it.second->GetNick()); + Table.SetCell("AltNick", it.second->GetAltNick()); + Table.SetCell("Ident", it.second->GetIdent()); + Table.SetCell("BindHost", it.second->GetBindHost()); + } + + PutModule(Table); + } + + void AddUser(const CString& sLine) { + if (!GetUser()->IsAdmin()) { + PutModule("Error: You need to have admin rights to add new users!"); + return; + } + + const CString sUsername = sLine.Token(1), sPassword = sLine.Token(2); + if (sPassword.empty()) { + PutModule("Usage: AddUser "); + return; + } + + if (CZNC::Get().FindUser(sUsername)) { + PutModule("Error: User [" + sUsername + "] already exists!"); + return; + } + + CUser* pNewUser = new CUser(sUsername); + CString sSalt = CUtils::GetSalt(); + pNewUser->SetPass(CUser::SaltedHash(sPassword, sSalt), + CUser::HASH_DEFAULT, sSalt); + + CString sErr; + if (!CZNC::Get().AddUser(pNewUser, sErr)) { + delete pNewUser; + PutModule("Error: User not added! [" + sErr + "]"); + return; + } + + PutModule("User [" + sUsername + "] added!"); + return; + } + + void DelUser(const CString& sLine) { + if (!GetUser()->IsAdmin()) { + PutModule("Error: You need to have admin rights to delete users!"); + return; + } + + const CString sUsername = sLine.Token(1, true); + if (sUsername.empty()) { + PutModule("Usage: DelUser "); + return; + } + + CUser* pUser = CZNC::Get().FindUser(sUsername); + + if (!pUser) { + PutModule("Error: User [" + sUsername + "] does not exist!"); + return; + } + + if (pUser == GetUser()) { + PutModule("Error: You can't delete yourself!"); + return; + } + + if (!CZNC::Get().DeleteUser(pUser->GetUserName())) { + // This can't happen, because we got the user from FindUser() + PutModule("Error: Internal error!"); + return; + } + + PutModule("User [" + sUsername + "] deleted!"); + return; + } + + void CloneUser(const CString& sLine) { + if (!GetUser()->IsAdmin()) { + PutModule("Error: You need to have admin rights to add new users!"); + return; + } + + const CString sOldUsername = sLine.Token(1), + sNewUsername = sLine.Token(2, true); + + if (sOldUsername.empty() || sNewUsername.empty()) { + PutModule("Usage: CloneUser "); + return; + } + + CUser* pOldUser = CZNC::Get().FindUser(sOldUsername); + + if (!pOldUser) { + PutModule("Error: User [" + sOldUsername + "] not found!"); + return; + } + + CUser* pNewUser = new CUser(sNewUsername); + CString sError; + if (!pNewUser->Clone(*pOldUser, sError)) { + delete pNewUser; + PutModule("Error: Cloning failed! [" + sError + "]"); + return; + } + + if (!CZNC::Get().AddUser(pNewUser, sError)) { + delete pNewUser; + PutModule("Error: User not added! [" + sError + "]"); + return; + } + + PutModule("User [" + sNewUsername + "] added!"); + return; + } + + void AddNetwork(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CUser* pUser = GetUser(); + + if (sNetwork.empty()) { + sNetwork = sUser; + } else { + pUser = FindUser(sUser); + if (!pUser) { + PutModule("User [" + sUser + "] not found"); + return; + } + } + + if (sNetwork.empty()) { + PutModule("Usage: AddNetwork [user] network"); + return; + } + + if (!GetUser()->IsAdmin() && !pUser->HasSpaceForNewNetwork()) { + PutStatus( + "Network number limit reached. Ask an admin to increase the " + "limit for you, or delete unneeded networks using /znc " + "DelNetwork "); + return; + } + + if (pUser->FindNetwork(sNetwork)) { + PutModule("[" + pUser->GetUserName() + + "] already has a network with the name [" + sNetwork + + "]"); + return; + } + + CString sNetworkAddError; + if (pUser->AddNetwork(sNetwork, sNetworkAddError)) { + PutModule("Network [" + sNetwork + "] added for user [" + + pUser->GetUserName() + "]."); + } else { + PutModule("Network [" + sNetwork + + "] could not be added for user [" + pUser->GetUserName() + + "]: " + sNetworkAddError); + } + } + + void DelNetwork(const CString& sLine) { + CString sUser = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CUser* pUser = GetUser(); + + if (sNetwork.empty()) { + sNetwork = sUser; + } else { + pUser = FindUser(sUser); + if (!pUser) { + return; + } + } + + if (sNetwork.empty()) { + PutModule("Usage: DelNetwork [user] network"); + return; + } + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + if (pNetwork == CModule::GetNetwork()) { + PutModule("The currently active network can be deleted via " + + GetUser()->GetStatusPrefix() + "status"); + return; + } + + if (pUser->DeleteNetwork(sNetwork)) { + PutModule("Network [" + sNetwork + "] deleted on user [" + + pUser->GetUserName() + "]."); + } else { + PutModule("Network [" + sNetwork + + "] could not be deleted for user [" + + pUser->GetUserName() + "]."); + } + } + + void ListNetworks(const CString& sLine) { + CString sUser = sLine.Token(1); + CUser* pUser = GetUser(); + + if (!sUser.empty()) { + pUser = FindUser(sUser); + if (!pUser) { + return; + } + } + + const vector& vNetworks = pUser->GetNetworks(); + + CTable Table; + Table.AddColumn("Network"); + Table.AddColumn("OnIRC"); + Table.AddColumn("IRC Server"); + Table.AddColumn("IRC User"); + Table.AddColumn("Channels"); + + for (const CIRCNetwork* pNetwork : vNetworks) { + Table.AddRow(); + Table.SetCell("Network", pNetwork->GetName()); + if (pNetwork->IsIRCConnected()) { + Table.SetCell("OnIRC", "Yes"); + Table.SetCell("IRC Server", pNetwork->GetIRCServer()); + Table.SetCell("IRC User", pNetwork->GetIRCNick().GetNickMask()); + Table.SetCell("Channels", CString(pNetwork->GetChans().size())); + } else { + Table.SetCell("OnIRC", "No"); + } + } + + if (PutModule(Table) == 0) { + PutModule("No networks"); + } + } + + void AddServer(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CString sServer = sLine.Token(3, true); + + if (sServer.empty()) { + PutModule("Usage: AddServer "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + if (pNetwork->AddServer(sServer)) + PutModule("Added IRC Server [" + sServer + "] for network [" + + sNetwork + "] for user [" + pUser->GetUserName() + "]."); + else + PutModule("Could not add IRC server [" + sServer + + "] for network [" + sNetwork + "] for user [" + + pUser->GetUserName() + "]."); + } + + void DelServer(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CString sServer = sLine.Token(3, true); + unsigned short uPort = sLine.Token(4).ToUShort(); + CString sPass = sLine.Token(5); + + if (sServer.empty()) { + PutModule("Usage: DelServer "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + if (pNetwork->DelServer(sServer, uPort, sPass)) + PutModule("Deleted IRC Server [" + sServer + "] for network [" + + sNetwork + "] for user [" + pUser->GetUserName() + "]."); + else + PutModule("Could not delete IRC server [" + sServer + + "] for network [" + sNetwork + "] for user [" + + pUser->GetUserName() + "]."); + } + + void ReconnectUser(const CString& sLine) { + CString sUserName = sLine.Token(1); + CString sNetwork = sLine.Token(2); + + if (sNetwork.empty()) { + PutModule("Usage: Reconnect "); + return; + } + + CUser* pUser = FindUser(sUserName); + if (!pUser) { + PutModule("User [" + sUserName + "] not found."); + return; + } + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + CIRCSock* pIRCSock = pNetwork->GetIRCSock(); + // cancel connection attempt: + if (pIRCSock && !pIRCSock->IsConnected()) { + pIRCSock->Close(); + } + // or close existing connection: + else if (pIRCSock) { + pIRCSock->Quit(); + } + + // then reconnect + pNetwork->SetIRCConnectEnabled(true); + + PutModule("Queued network [" + sNetwork + "] for user [" + + pUser->GetUserName() + "] for a reconnect."); + } + + void DisconnectUser(const CString& sLine) { + CString sUserName = sLine.Token(1); + CString sNetwork = sLine.Token(2); + + if (sNetwork.empty()) { + PutModule("Usage: Disconnect "); + return; + } + + CUser* pUser = FindUser(sUserName); + if (!pUser) { + PutModule("User [" + sUserName + "] not found."); + return; + } + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + pNetwork->SetIRCConnectEnabled(false); + PutModule("Closed IRC connection for network [" + sNetwork + + "] on user [" + sUserName + "]."); + } + + void ListCTCP(const CString& sLine) { + CString sUserName = sLine.Token(1, true); + + if (sUserName.empty()) { + sUserName = GetUser()->GetUserName(); + } + CUser* pUser = FindUser(sUserName); + if (!pUser) return; + + const MCString& msCTCPReplies = pUser->GetCTCPReplies(); + CTable Table; + Table.AddColumn("Request"); + Table.AddColumn("Reply"); + for (const auto& it : msCTCPReplies) { + Table.AddRow(); + Table.SetCell("Request", it.first); + Table.SetCell("Reply", it.second); + } + + if (Table.empty()) { + PutModule("No CTCP replies for user [" + pUser->GetUserName() + + "] configured!"); + } else { + PutModule("CTCP replies for user [" + pUser->GetUserName() + "]:"); + PutModule(Table); + } + } + + void AddCTCP(const CString& sLine) { + CString sUserName = sLine.Token(1); + CString sCTCPRequest = sLine.Token(2); + CString sCTCPReply = sLine.Token(3, true); + + if (sCTCPRequest.empty()) { + sCTCPRequest = sUserName; + sCTCPReply = sLine.Token(2, true); + sUserName = GetUser()->GetUserName(); + } + if (sCTCPRequest.empty()) { + PutModule("Usage: AddCTCP [user] [request] [reply]"); + PutModule( + "This will cause ZNC to reply to the CTCP instead of " + "forwarding it to clients."); + PutModule( + "An empty reply will cause the CTCP request to be blocked."); + return; + } + + CUser* pUser = FindUser(sUserName); + if (!pUser) return; + + if (pUser->AddCTCPReply(sCTCPRequest, sCTCPReply)) + PutModule("Added!"); + else + PutModule("Error!"); + } + + void DelCTCP(const CString& sLine) { + CString sUserName = sLine.Token(1); + CString sCTCPRequest = sLine.Token(2, true); + + if (sCTCPRequest.empty()) { + sCTCPRequest = sUserName; + sUserName = GetUser()->GetUserName(); + } + CUser* pUser = FindUser(sUserName); + if (!pUser) return; + + if (sCTCPRequest.empty()) { + PutModule("Usage: DelCTCP [user] [request]"); + return; + } + + if (pUser->DelCTCPReply(sCTCPRequest)) + PutModule("Successfully removed [" + sCTCPRequest + "] for user [" + + pUser->GetUserName() + "]."); + else + PutModule("Error: [" + sCTCPRequest + "] not found for user [" + + pUser->GetUserName() + "]!"); + } + + void LoadModuleFor(CModules& Modules, const CString& sModName, + const CString& sArgs, CModInfo::EModuleType eType, + CUser* pUser, CIRCNetwork* pNetwork) { + if (pUser->DenyLoadMod() && !GetUser()->IsAdmin()) { + PutModule("Loading modules has been disabled."); + return; + } + + CString sModRet; + CModule* pMod = Modules.FindModule(sModName); + if (!pMod) { + if (!Modules.LoadModule(sModName, sArgs, eType, pUser, pNetwork, + sModRet)) { + PutModule("Unable to load module [" + sModName + "] [" + + sModRet + "]"); + } else { + PutModule("Loaded module [" + sModName + "]"); + } + } else if (pMod->GetArgs() != sArgs) { + if (!Modules.ReloadModule(sModName, sArgs, pUser, pNetwork, + sModRet)) { + PutModule("Unable to reload module [" + sModName + "] [" + + sModRet + "]"); + } else { + PutModule("Reloaded module [" + sModName + "]"); + } + } else { + PutModule("Unable to load module [" + sModName + + "] because it is already loaded"); + } + } + + void LoadModuleForUser(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sModName = sLine.Token(2); + CString sArgs = sLine.Token(3, true); + + if (sModName.empty()) { + PutModule("Usage: LoadModule [args]"); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + LoadModuleFor(pUser->GetModules(), sModName, sArgs, + CModInfo::UserModule, pUser, nullptr); + } + + void LoadModuleForNetwork(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CString sModName = sLine.Token(3); + CString sArgs = sLine.Token(4, true); + + if (sModName.empty()) { + PutModule( + "Usage: LoadNetModule " + "[args]"); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + LoadModuleFor(pNetwork->GetModules(), sModName, sArgs, + CModInfo::NetworkModule, pUser, pNetwork); + } + + void UnLoadModuleFor(CModules& Modules, const CString& sModName, + CUser* pUser) { + if (pUser->DenyLoadMod() && !GetUser()->IsAdmin()) { + PutModule("Loading modules has been disabled."); + return; + } + + if (Modules.FindModule(sModName) == this) { + PutModule("Please use /znc unloadmod " + sModName); + return; + } + + CString sModRet; + if (!Modules.UnloadModule(sModName, sModRet)) { + PutModule("Unable to unload module [" + sModName + "] [" + sModRet + + "]"); + } else { + PutModule("Unloaded module [" + sModName + "]"); + } + } + + void UnLoadModuleForUser(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sModName = sLine.Token(2); + + if (sModName.empty()) { + PutModule("Usage: UnloadModule "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + UnLoadModuleFor(pUser->GetModules(), sModName, pUser); + } + + void UnLoadModuleForNetwork(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sNetwork = sLine.Token(2); + CString sModName = sLine.Token(3); + + if (sModName.empty()) { + PutModule( + "Usage: UnloadNetModule "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + UnLoadModuleFor(pNetwork->GetModules(), sModName, pUser); + } + + void ListModulesFor(CModules& Modules, const CString& sWhere) { + if (!Modules.size()) { + PutModule(sWhere + " has no modules loaded."); + } else { + PutModule("Modules loaded for " + sWhere + ":"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Arguments"); + + for (const CModule* pMod : Modules) { + Table.AddRow(); + Table.SetCell("Name", pMod->GetModName()); + Table.SetCell("Arguments", pMod->GetArgs()); + } + + PutModule(Table); + } + } + + void ListModulesForUser(const CString& sLine) { + CString sUsername = sLine.Token(1); + + if (sUsername.empty()) { + PutModule("Usage: ListMods "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + ListModulesFor(pUser->GetModules(), + "User [" + pUser->GetUserName() + "]"); + } + + void ListModulesForNetwork(const CString& sLine) { + CString sUsername = sLine.Token(1); + CString sNetwork = sLine.Token(2); + + if (sNetwork.empty()) { + PutModule("Usage: ListNetMods "); + return; + } + + CUser* pUser = FindUser(sUsername); + if (!pUser) return; + + CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork); + if (!pNetwork) { + return; + } + + ListModulesFor(pNetwork->GetModules(), + "Network [" + pNetwork->GetName() + "] of user [" + + pUser->GetUserName() + "]"); + } public: - MODCONSTRUCTOR(CAdminMod) { - AddCommand("Help", - static_cast(&CAdminMod::PrintHelp), - "[command] [variable]", - "Prints help for matching commands and variables"); - AddCommand("Get", static_cast(&CAdminMod::Get), - " [username]", - "Prints the variable's value for the given or current user"); - AddCommand("Set", static_cast(&CAdminMod::Set), - " ", - "Sets the variable's value for the given user"); - AddCommand("GetNetwork", - static_cast(&CAdminMod::GetNetwork), - " [username] [network]", - "Prints the variable's value for the given network"); - AddCommand("SetNetwork", - static_cast(&CAdminMod::SetNetwork), - " ", - "Sets the variable's value for the given network"); - AddCommand("GetChan", - static_cast(&CAdminMod::GetChan), - " [username] ", - "Prints the variable's value for the given channel"); - AddCommand("SetChan", - static_cast(&CAdminMod::SetChan), - " ", - "Sets the variable's value for the given channel"); - AddCommand("AddChan", - static_cast(&CAdminMod::AddChan), - " ", "Adds a new channel"); - AddCommand("DelChan", - static_cast(&CAdminMod::DelChan), - " ", "Deletes a channel"); - AddCommand("ListUsers", - static_cast(&CAdminMod::ListUsers), - "", "Lists users"); - AddCommand("AddUser", - static_cast(&CAdminMod::AddUser), - " ", "Adds a new user"); - AddCommand("DelUser", - static_cast(&CAdminMod::DelUser), - "", "Deletes a user"); - AddCommand("CloneUser", - static_cast(&CAdminMod::CloneUser), - " ", "Clones a user"); - AddCommand("AddServer", - static_cast(&CAdminMod::AddServer), - " ", - "Adds a new IRC server for the given or current user"); - AddCommand("DelServer", - static_cast(&CAdminMod::DelServer), - " ", - "Deletes an IRC server from the given or current user"); - AddCommand( - "Reconnect", - static_cast(&CAdminMod::ReconnectUser), - " ", "Cycles the user's IRC server connection"); - AddCommand("Disconnect", static_cast( - &CAdminMod::DisconnectUser), - " ", - "Disconnects the user from their IRC server"); - AddCommand( - "LoadModule", - static_cast(&CAdminMod::LoadModuleForUser), - " [args]", "Loads a Module for a user"); - AddCommand("UnLoadModule", static_cast( - &CAdminMod::UnLoadModuleForUser), - " ", "Removes a Module of a user"); - AddCommand("ListMods", static_cast( - &CAdminMod::ListModulesForUser), - "", "Get the list of modules for a user"); - AddCommand("LoadNetModule", static_cast( - &CAdminMod::LoadModuleForNetwork), - " [args]", - "Loads a Module for a network"); - AddCommand("UnLoadNetModule", static_cast( - &CAdminMod::UnLoadModuleForNetwork), - " ", - "Removes a Module of a network"); - AddCommand("ListNetMods", static_cast( - &CAdminMod::ListModulesForNetwork), - " ", - "Get the list of modules for a network"); - AddCommand("ListCTCPs", - static_cast(&CAdminMod::ListCTCP), - "", "List the configured CTCP replies"); - AddCommand("AddCTCP", - static_cast(&CAdminMod::AddCTCP), - " [reply]", "Configure a new CTCP reply"); - AddCommand("DelCTCP", - static_cast(&CAdminMod::DelCTCP), - " ", "Remove a CTCP reply"); + MODCONSTRUCTOR(CAdminMod) { + AddCommand("Help", + static_cast(&CAdminMod::PrintHelp), + "[command] [variable]", + "Prints help for matching commands and variables"); + AddCommand("Get", static_cast(&CAdminMod::Get), + " [username]", + "Prints the variable's value for the given or current user"); + AddCommand("Set", static_cast(&CAdminMod::Set), + " ", + "Sets the variable's value for the given user"); + AddCommand("GetNetwork", + static_cast(&CAdminMod::GetNetwork), + " [username] [network]", + "Prints the variable's value for the given network"); + AddCommand("SetNetwork", + static_cast(&CAdminMod::SetNetwork), + " ", + "Sets the variable's value for the given network"); + AddCommand("GetChan", + static_cast(&CAdminMod::GetChan), + " [username] ", + "Prints the variable's value for the given channel"); + AddCommand("SetChan", + static_cast(&CAdminMod::SetChan), + " ", + "Sets the variable's value for the given channel"); + AddCommand("AddChan", + static_cast(&CAdminMod::AddChan), + " ", "Adds a new channel"); + AddCommand("DelChan", + static_cast(&CAdminMod::DelChan), + " ", "Deletes a channel"); + AddCommand("ListUsers", + static_cast(&CAdminMod::ListUsers), + "", "Lists users"); + AddCommand("AddUser", + static_cast(&CAdminMod::AddUser), + " ", "Adds a new user"); + AddCommand("DelUser", + static_cast(&CAdminMod::DelUser), + "", "Deletes a user"); + AddCommand("CloneUser", + static_cast(&CAdminMod::CloneUser), + " ", "Clones a user"); + AddCommand("AddServer", + static_cast(&CAdminMod::AddServer), + " ", + "Adds a new IRC server for the given or current user"); + AddCommand("DelServer", + static_cast(&CAdminMod::DelServer), + " ", + "Deletes an IRC server from the given or current user"); + AddCommand( + "Reconnect", + static_cast(&CAdminMod::ReconnectUser), + " ", "Cycles the user's IRC server connection"); + AddCommand("Disconnect", static_cast( + &CAdminMod::DisconnectUser), + " ", + "Disconnects the user from their IRC server"); + AddCommand( + "LoadModule", + static_cast(&CAdminMod::LoadModuleForUser), + " [args]", "Loads a Module for a user"); + AddCommand("UnLoadModule", static_cast( + &CAdminMod::UnLoadModuleForUser), + " ", "Removes a Module of a user"); + AddCommand("ListMods", static_cast( + &CAdminMod::ListModulesForUser), + "", "Get the list of modules for a user"); + AddCommand("LoadNetModule", static_cast( + &CAdminMod::LoadModuleForNetwork), + " [args]", + "Loads a Module for a network"); + AddCommand("UnLoadNetModule", static_cast( + &CAdminMod::UnLoadModuleForNetwork), + " ", + "Removes a Module of a network"); + AddCommand("ListNetMods", static_cast( + &CAdminMod::ListModulesForNetwork), + " ", + "Get the list of modules for a network"); + AddCommand("ListCTCPs", + static_cast(&CAdminMod::ListCTCP), + "", "List the configured CTCP replies"); + AddCommand("AddCTCP", + static_cast(&CAdminMod::AddCTCP), + " [reply]", "Configure a new CTCP reply"); + AddCommand("DelCTCP", + static_cast(&CAdminMod::DelCTCP), + " ", "Remove a CTCP reply"); - // Network commands - AddCommand("AddNetwork", - static_cast(&CAdminMod::AddNetwork), - "[username] ", "Add a network for a user"); - AddCommand("DelNetwork", - static_cast(&CAdminMod::DelNetwork), - "[username] ", "Delete a network for a user"); - AddCommand("ListNetworks", static_cast( - &CAdminMod::ListNetworks), - "[username]", "List all networks for a user"); - } + // Network commands + AddCommand("AddNetwork", + static_cast(&CAdminMod::AddNetwork), + "[username] ", "Add a network for a user"); + AddCommand("DelNetwork", + static_cast(&CAdminMod::DelNetwork), + "[username] ", "Delete a network for a user"); + AddCommand("ListNetworks", static_cast( + &CAdminMod::ListNetworks), + "[username]", "List all networks for a user"); + } - virtual ~CAdminMod() {} + virtual ~CAdminMod() {} }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("controlpanel"); + Info.SetWikiPage("controlpanel"); } USERMODULEDEFS(CAdminMod, diff --git a/modules/crypt.cpp b/modules/crypt.cpp index 0fa3e703..1281b970 100644 --- a/modules/crypt.cpp +++ b/modules/crypt.cpp @@ -48,294 +48,294 @@ #define NICK_PREFIX_KEY "[nick-prefix]" class CCryptMod : public CModule { - CString NickPrefix() { - MCString::iterator it = FindNV(NICK_PREFIX_KEY); - return it != EndNV() ? it->second : "*"; - } + CString NickPrefix() { + MCString::iterator it = FindNV(NICK_PREFIX_KEY); + return it != EndNV() ? it->second : "*"; + } public: - MODCONSTRUCTOR(CCryptMod) { - AddHelpCommand(); - AddCommand("DelKey", static_cast( - &CCryptMod::OnDelKeyCommand), - "<#chan|Nick>", "Remove a key for nick or channel"); - AddCommand("SetKey", static_cast( - &CCryptMod::OnSetKeyCommand), - "<#chan|Nick> ", "Set a key for nick or channel"); - AddCommand("ListKeys", static_cast( - &CCryptMod::OnListKeysCommand), - "", "List all keys"); - } + MODCONSTRUCTOR(CCryptMod) { + AddHelpCommand(); + AddCommand("DelKey", static_cast( + &CCryptMod::OnDelKeyCommand), + "<#chan|Nick>", "Remove a key for nick or channel"); + AddCommand("SetKey", static_cast( + &CCryptMod::OnSetKeyCommand), + "<#chan|Nick> ", "Set a key for nick or channel"); + AddCommand("ListKeys", static_cast( + &CCryptMod::OnListKeysCommand), + "", "List all keys"); + } - virtual ~CCryptMod() {} + virtual ~CCryptMod() {} - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - sTarget.TrimPrefix(NickPrefix()); + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + sTarget.TrimPrefix(NickPrefix()); - if (sMessage.TrimPrefix("``")) { - return CONTINUE; - } + if (sMessage.TrimPrefix("``")) { + return CONTINUE; + } - MCString::iterator it = FindNV(sTarget.AsLower()); + MCString::iterator it = FindNV(sTarget.AsLower()); - if (it != EndNV()) { - CChan* pChan = GetNetwork()->FindChan(sTarget); - CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); - if (pChan) { - if (!pChan->AutoClearChanBuffer()) - pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + - " PRIVMSG " + _NAMEDFMT(sTarget) + - " :{text}", - sMessage); - GetUser()->PutUser(":" + NickPrefix() + sNickMask + - " PRIVMSG " + sTarget + " :" + sMessage, - nullptr, GetClient()); - } + if (it != EndNV()) { + CChan* pChan = GetNetwork()->FindChan(sTarget); + CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); + if (pChan) { + if (!pChan->AutoClearChanBuffer()) + pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + + " PRIVMSG " + _NAMEDFMT(sTarget) + + " :{text}", + sMessage); + GetUser()->PutUser(":" + NickPrefix() + sNickMask + + " PRIVMSG " + sTarget + " :" + sMessage, + nullptr, GetClient()); + } - CString sMsg = MakeIvec() + sMessage; - sMsg.Encrypt(it->second); - sMsg.Base64Encode(); - sMsg = "+OK *" + sMsg; + CString sMsg = MakeIvec() + sMessage; + sMsg.Encrypt(it->second); + sMsg.Base64Encode(); + sMsg = "+OK *" + sMsg; - PutIRC("PRIVMSG " + sTarget + " :" + sMsg); - return HALTCORE; - } + PutIRC("PRIVMSG " + sTarget + " :" + sMsg); + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - sTarget.TrimPrefix(NickPrefix()); + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + sTarget.TrimPrefix(NickPrefix()); - if (sMessage.TrimPrefix("``")) { - return CONTINUE; - } + if (sMessage.TrimPrefix("``")) { + return CONTINUE; + } - MCString::iterator it = FindNV(sTarget.AsLower()); + MCString::iterator it = FindNV(sTarget.AsLower()); - if (it != EndNV()) { - CChan* pChan = GetNetwork()->FindChan(sTarget); - CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); - if (pChan) { - if (!pChan->AutoClearChanBuffer()) - pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + - " NOTICE " + _NAMEDFMT(sTarget) + - " :{text}", - sMessage); - GetUser()->PutUser(":" + NickPrefix() + sNickMask + " NOTICE " + - sTarget + " :" + sMessage, - NULL, GetClient()); - } + if (it != EndNV()) { + CChan* pChan = GetNetwork()->FindChan(sTarget); + CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); + if (pChan) { + if (!pChan->AutoClearChanBuffer()) + pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + + " NOTICE " + _NAMEDFMT(sTarget) + + " :{text}", + sMessage); + GetUser()->PutUser(":" + NickPrefix() + sNickMask + " NOTICE " + + sTarget + " :" + sMessage, + NULL, GetClient()); + } - CString sMsg = MakeIvec() + sMessage; - sMsg.Encrypt(it->second); - sMsg.Base64Encode(); - sMsg = "+OK *" + sMsg; + CString sMsg = MakeIvec() + sMessage; + sMsg.Encrypt(it->second); + sMsg.Base64Encode(); + sMsg = "+OK *" + sMsg; - PutIRC("NOTICE " + sTarget + " :" + sMsg); - return HALTCORE; - } + PutIRC("NOTICE " + sTarget + " :" + sMsg); + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserAction(CString& sTarget, CString& sMessage) override { - sTarget.TrimPrefix(NickPrefix()); + EModRet OnUserAction(CString& sTarget, CString& sMessage) override { + sTarget.TrimPrefix(NickPrefix()); - if (sMessage.TrimPrefix("``")) { - return CONTINUE; - } + if (sMessage.TrimPrefix("``")) { + return CONTINUE; + } - MCString::iterator it = FindNV(sTarget.AsLower()); + MCString::iterator it = FindNV(sTarget.AsLower()); - if (it != EndNV()) { - CChan* pChan = GetNetwork()->FindChan(sTarget); - CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); - if (pChan) { - if (!pChan->AutoClearChanBuffer()) - pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + - " PRIVMSG " + _NAMEDFMT(sTarget) + - " :\001ACTION {text}\001", - sMessage); - GetUser()->PutUser(":" + NickPrefix() + sNickMask + - " PRIVMSG " + sTarget + " :\001ACTION " + - sMessage + "\001", - NULL, GetClient()); - } + if (it != EndNV()) { + CChan* pChan = GetNetwork()->FindChan(sTarget); + CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); + if (pChan) { + if (!pChan->AutoClearChanBuffer()) + pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + + " PRIVMSG " + _NAMEDFMT(sTarget) + + " :\001ACTION {text}\001", + sMessage); + GetUser()->PutUser(":" + NickPrefix() + sNickMask + + " PRIVMSG " + sTarget + " :\001ACTION " + + sMessage + "\001", + NULL, GetClient()); + } - CString sMsg = MakeIvec() + sMessage; - sMsg.Encrypt(it->second); - sMsg.Base64Encode(); - sMsg = "+OK *" + sMsg; + CString sMsg = MakeIvec() + sMessage; + sMsg.Encrypt(it->second); + sMsg.Base64Encode(); + sMsg = "+OK *" + sMsg; - PutIRC("PRIVMSG " + sTarget + " :\001ACTION " + sMsg + "\001"); - return HALTCORE; - } + PutIRC("PRIVMSG " + sTarget + " :\001ACTION " + sMsg + "\001"); + return HALTCORE; + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserTopic(CString& sTarget, CString& sMessage) override { - sTarget.TrimPrefix(NickPrefix()); + EModRet OnUserTopic(CString& sTarget, CString& sMessage) override { + sTarget.TrimPrefix(NickPrefix()); - if (sMessage.TrimPrefix("``")) { - return CONTINUE; - } + if (sMessage.TrimPrefix("``")) { + return CONTINUE; + } - MCString::iterator it = FindNV(sTarget.AsLower()); + MCString::iterator it = FindNV(sTarget.AsLower()); - if (it != EndNV()) { - sMessage = MakeIvec() + sMessage; - sMessage.Encrypt(it->second); - sMessage.Base64Encode(); - sMessage = "+OK *" + sMessage; - } + if (it != EndNV()) { + sMessage = MakeIvec() + sMessage; + sMessage.Encrypt(it->second); + sMessage.Base64Encode(); + sMessage = "+OK *" + sMessage; + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - FilterIncoming(Nick.GetNick(), Nick, sMessage); - return CONTINUE; - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + FilterIncoming(Nick.GetNick(), Nick, sMessage); + return CONTINUE; + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - FilterIncoming(Nick.GetNick(), Nick, sMessage); - return CONTINUE; - } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + FilterIncoming(Nick.GetNick(), Nick, sMessage); + return CONTINUE; + } - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { - FilterIncoming(Nick.GetNick(), Nick, sMessage); - return CONTINUE; - } + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { + FilterIncoming(Nick.GetNick(), Nick, sMessage); + return CONTINUE; + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - FilterIncoming(Channel.GetName(), Nick, sMessage); - return CONTINUE; - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + FilterIncoming(Channel.GetName(), Nick, sMessage); + return CONTINUE; + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - FilterIncoming(Channel.GetName(), Nick, sMessage); - return CONTINUE; - } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + FilterIncoming(Channel.GetName(), Nick, sMessage); + return CONTINUE; + } - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override { - FilterIncoming(Channel.GetName(), Nick, sMessage); - return CONTINUE; - } + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override { + FilterIncoming(Channel.GetName(), Nick, sMessage); + return CONTINUE; + } - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sMessage) override { - FilterIncoming(Channel.GetName(), Nick, sMessage); - return CONTINUE; - } + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sMessage) override { + FilterIncoming(Channel.GetName(), Nick, sMessage); + return CONTINUE; + } - EModRet OnRaw(CString& sLine) override { - if (!sLine.Token(1).Equals("332")) { - return CONTINUE; - } + EModRet OnRaw(CString& sLine) override { + if (!sLine.Token(1).Equals("332")) { + return CONTINUE; + } - CChan* pChan = GetNetwork()->FindChan(sLine.Token(3)); - if (pChan) { - CNick* Nick = pChan->FindNick(sLine.Token(2)); - CString sTopic = sLine.Token(4, true); - sTopic.TrimPrefix(":"); + CChan* pChan = GetNetwork()->FindChan(sLine.Token(3)); + if (pChan) { + CNick* Nick = pChan->FindNick(sLine.Token(2)); + CString sTopic = sLine.Token(4, true); + sTopic.TrimPrefix(":"); - FilterIncoming(pChan->GetName(), *Nick, sTopic); - sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + - sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic; - } + FilterIncoming(pChan->GetName(), *Nick, sTopic); + sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + + sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic; + } - return CONTINUE; - } + return CONTINUE; + } - void FilterIncoming(const CString& sTarget, CNick& Nick, - CString& sMessage) { - if (sMessage.TrimPrefix("+OK *")) { - MCString::iterator it = FindNV(sTarget.AsLower()); + void FilterIncoming(const CString& sTarget, CNick& Nick, + CString& sMessage) { + if (sMessage.TrimPrefix("+OK *")) { + MCString::iterator it = FindNV(sTarget.AsLower()); - if (it != EndNV()) { - sMessage.Base64Decode(); - sMessage.Decrypt(it->second); - sMessage.LeftChomp(8); - sMessage = sMessage.c_str(); - Nick.SetNick(NickPrefix() + Nick.GetNick()); - } - } - } + if (it != EndNV()) { + sMessage.Base64Decode(); + sMessage.Decrypt(it->second); + sMessage.LeftChomp(8); + sMessage = sMessage.c_str(); + Nick.SetNick(NickPrefix() + Nick.GetNick()); + } + } + } - void OnDelKeyCommand(const CString& sCommand) { - CString sTarget = sCommand.Token(1); + void OnDelKeyCommand(const CString& sCommand) { + CString sTarget = sCommand.Token(1); - if (!sTarget.empty()) { - if (DelNV(sTarget.AsLower())) { - PutModule("Target [" + sTarget + "] deleted"); - } else { - PutModule("Target [" + sTarget + "] not found"); - } - } else { - PutModule("Usage DelKey <#chan|Nick>"); - } - } + if (!sTarget.empty()) { + if (DelNV(sTarget.AsLower())) { + PutModule("Target [" + sTarget + "] deleted"); + } else { + PutModule("Target [" + sTarget + "] not found"); + } + } else { + PutModule("Usage DelKey <#chan|Nick>"); + } + } - void OnSetKeyCommand(const CString& sCommand) { - CString sTarget = sCommand.Token(1); - CString sKey = sCommand.Token(2, true); + void OnSetKeyCommand(const CString& sCommand) { + CString sTarget = sCommand.Token(1); + CString sKey = sCommand.Token(2, true); - // Strip "cbc:" from beginning of string incase someone pastes directly - // from mircryption - sKey.TrimPrefix("cbc:"); + // Strip "cbc:" from beginning of string incase someone pastes directly + // from mircryption + sKey.TrimPrefix("cbc:"); - if (!sKey.empty()) { - SetNV(sTarget.AsLower(), sKey); - PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + - "]"); - } else { - PutModule("Usage: SetKey <#chan|Nick> "); - } - } + if (!sKey.empty()) { + SetNV(sTarget.AsLower(), sKey); + PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + + "]"); + } else { + PutModule("Usage: SetKey <#chan|Nick> "); + } + } - void OnListKeysCommand(const CString& sCommand) { - if (BeginNV() == EndNV()) { - PutModule("You have no encryption keys set."); - } else { - CTable Table; - Table.AddColumn("Target"); - Table.AddColumn("Key"); + void OnListKeysCommand(const CString& sCommand) { + if (BeginNV() == EndNV()) { + PutModule("You have no encryption keys set."); + } else { + CTable Table; + Table.AddColumn("Target"); + Table.AddColumn("Key"); - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - Table.AddRow(); - Table.SetCell("Target", it->first); - Table.SetCell("Key", it->second); - } + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + Table.AddRow(); + Table.SetCell("Target", it->first); + Table.SetCell("Key", it->second); + } - MCString::iterator it = FindNV(NICK_PREFIX_KEY); - if (it == EndNV()) { - Table.AddRow(); - Table.SetCell("Target", NICK_PREFIX_KEY); - Table.SetCell("Key", NickPrefix()); - } + MCString::iterator it = FindNV(NICK_PREFIX_KEY); + if (it == EndNV()) { + Table.AddRow(); + Table.SetCell("Target", NICK_PREFIX_KEY); + Table.SetCell("Key", NickPrefix()); + } - PutModule(Table); - } - } + PutModule(Table); + } + } - CString MakeIvec() { - CString sRet; - time_t t; - time(&t); - int r = rand(); - sRet.append((char*)&t, 4); - sRet.append((char*)&r, 4); + CString MakeIvec() { + CString sRet; + time_t t; + time(&t); + int r = rand(); + sRet.append((char*)&t, 4); + sRet.append((char*)&r, 4); - return sRet; - } + return sRet; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("crypt"); + Info.SetWikiPage("crypt"); } NETWORKMODULEDEFS(CCryptMod, "Encryption for channel/private messages") diff --git a/modules/ctcpflood.cpp b/modules/ctcpflood.cpp index 05e2a4a8..379336a6 100644 --- a/modules/ctcpflood.cpp +++ b/modules/ctcpflood.cpp @@ -20,134 +20,134 @@ class CCtcpFloodMod : public CModule { public: - MODCONSTRUCTOR(CCtcpFloodMod) { - AddHelpCommand(); - AddCommand("Secs", static_cast( - &CCtcpFloodMod::OnSecsCommand), - "", "Set seconds limit"); - AddCommand("Lines", static_cast( - &CCtcpFloodMod::OnLinesCommand), - "", "Set lines limit"); - AddCommand("Show", static_cast( - &CCtcpFloodMod::OnShowCommand), - "", "Show the current limits"); - } + MODCONSTRUCTOR(CCtcpFloodMod) { + AddHelpCommand(); + AddCommand("Secs", static_cast( + &CCtcpFloodMod::OnSecsCommand), + "", "Set seconds limit"); + AddCommand("Lines", static_cast( + &CCtcpFloodMod::OnLinesCommand), + "", "Set lines limit"); + AddCommand("Show", static_cast( + &CCtcpFloodMod::OnShowCommand), + "", "Show the current limits"); + } - ~CCtcpFloodMod() {} + ~CCtcpFloodMod() {} - void Save() { - // We save the settings twice because the module arguments can - // be more easily edited via webadmin, while the SetNV() stuff - // survives e.g. /msg *status reloadmod ctcpflood. - SetNV("secs", CString(m_iThresholdSecs)); - SetNV("msgs", CString(m_iThresholdMsgs)); + void Save() { + // We save the settings twice because the module arguments can + // be more easily edited via webadmin, while the SetNV() stuff + // survives e.g. /msg *status reloadmod ctcpflood. + SetNV("secs", CString(m_iThresholdSecs)); + SetNV("msgs", CString(m_iThresholdMsgs)); - SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs)); - } + SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs)); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_iThresholdMsgs = sArgs.Token(0).ToUInt(); - m_iThresholdSecs = sArgs.Token(1).ToUInt(); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_iThresholdMsgs = sArgs.Token(0).ToUInt(); + m_iThresholdSecs = sArgs.Token(1).ToUInt(); - if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) { - m_iThresholdMsgs = GetNV("msgs").ToUInt(); - m_iThresholdSecs = GetNV("secs").ToUInt(); - } + if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) { + m_iThresholdMsgs = GetNV("msgs").ToUInt(); + m_iThresholdSecs = GetNV("secs").ToUInt(); + } - if (m_iThresholdSecs == 0) m_iThresholdSecs = 2; - if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 4; + if (m_iThresholdSecs == 0) m_iThresholdSecs = 2; + if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 4; - Save(); + Save(); - return true; - } + return true; + } - EModRet Message(const CNick& Nick, const CString& sMessage) { - // We never block /me, because it doesn't cause a reply - if (sMessage.Token(0).Equals("ACTION")) return CONTINUE; + EModRet Message(const CNick& Nick, const CString& sMessage) { + // We never block /me, because it doesn't cause a reply + if (sMessage.Token(0).Equals("ACTION")) return CONTINUE; - if (m_tLastCTCP + m_iThresholdSecs < time(nullptr)) { - m_tLastCTCP = time(nullptr); - m_iNumCTCP = 0; - } + if (m_tLastCTCP + m_iThresholdSecs < time(nullptr)) { + m_tLastCTCP = time(nullptr); + m_iNumCTCP = 0; + } - m_iNumCTCP++; + m_iNumCTCP++; - if (m_iNumCTCP < m_iThresholdMsgs) - return CONTINUE; - else if (m_iNumCTCP == m_iThresholdMsgs) - PutModule("Limit reached by [" + Nick.GetHostMask() + - "], blocking all CTCP"); + if (m_iNumCTCP < m_iThresholdMsgs) + return CONTINUE; + else if (m_iNumCTCP == m_iThresholdMsgs) + PutModule("Limit reached by [" + Nick.GetHostMask() + + "], blocking all CTCP"); - // Reset the timeout so that we continue blocking messages - m_tLastCTCP = time(nullptr); + // Reset the timeout so that we continue blocking messages + m_tLastCTCP = time(nullptr); - return HALT; - } + return HALT; + } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - return Message(Nick, sMessage); - } + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + return Message(Nick, sMessage); + } - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - return Message(Nick, sMessage); - } + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + return Message(Nick, sMessage); + } - void OnSecsCommand(const CString& sCommand) { - const CString& sArg = sCommand.Token(1, true); + void OnSecsCommand(const CString& sCommand) { + const CString& sArg = sCommand.Token(1, true); - if (sArg.empty()) { - PutModule("Usage: Secs "); - return; - } + if (sArg.empty()) { + PutModule("Usage: Secs "); + return; + } - m_iThresholdSecs = sArg.ToUInt(); - if (m_iThresholdSecs == 0) m_iThresholdSecs = 1; + m_iThresholdSecs = sArg.ToUInt(); + if (m_iThresholdSecs == 0) m_iThresholdSecs = 1; - PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + "]"); - Save(); - } + PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + "]"); + Save(); + } - void OnLinesCommand(const CString& sCommand) { - const CString& sArg = sCommand.Token(1, true); + void OnLinesCommand(const CString& sCommand) { + const CString& sArg = sCommand.Token(1, true); - if (sArg.empty()) { - PutModule("Usage: Lines "); - return; - } + if (sArg.empty()) { + PutModule("Usage: Lines "); + return; + } - m_iThresholdMsgs = sArg.ToUInt(); - if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 2; + m_iThresholdMsgs = sArg.ToUInt(); + if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 2; - PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]"); - Save(); - } + PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]"); + Save(); + } - void OnShowCommand(const CString& sCommand) { - PutModule("Current limit is " + CString(m_iThresholdMsgs) + - " CTCPs " - "in " + - CString(m_iThresholdSecs) + " secs"); - } + void OnShowCommand(const CString& sCommand) { + PutModule("Current limit is " + CString(m_iThresholdMsgs) + + " CTCPs " + "in " + + CString(m_iThresholdSecs) + " secs"); + } private: - time_t m_tLastCTCP = 0; - unsigned int m_iNumCTCP = 0; + time_t m_tLastCTCP = 0; + unsigned int m_iNumCTCP = 0; - time_t m_iThresholdSecs{}; - unsigned int m_iThresholdMsgs{}; + time_t m_iThresholdSecs{}; + unsigned int m_iThresholdMsgs{}; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("ctcpflood"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "This user module takes none to two arguments. The first argument is " - "the number of lines after which the flood-protection is triggered. " - "The second argument is the time (s) to in which the number of lines " - "is reached. The default setting is 4 CTCPs in 2 seconds"); + Info.SetWikiPage("ctcpflood"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "This user module takes none to two arguments. The first argument is " + "the number of lines after which the flood-protection is triggered. " + "The second argument is the time (s) to in which the number of lines " + "is reached. The default setting is 4 CTCPs in 2 seconds"); } USERMODULEDEFS(CCtcpFloodMod, "Don't forward CTCP floods to clients") diff --git a/modules/cyrusauth.cpp b/modules/cyrusauth.cpp index 079c7ea3..29be5d12 100644 --- a/modules/cyrusauth.cpp +++ b/modules/cyrusauth.cpp @@ -28,209 +28,209 @@ class CSASLAuthMod : public CModule { public: - MODCONSTRUCTOR(CSASLAuthMod) { - m_Cache.SetTTL(60000 /*ms*/); + MODCONSTRUCTOR(CSASLAuthMod) { + m_Cache.SetTTL(60000 /*ms*/); - m_cbs[0].id = SASL_CB_GETOPT; - m_cbs[0].proc = reinterpret_cast(CSASLAuthMod::getopt); - m_cbs[0].context = this; - m_cbs[1].id = SASL_CB_LIST_END; - m_cbs[1].proc = nullptr; - m_cbs[1].context = nullptr; + m_cbs[0].id = SASL_CB_GETOPT; + m_cbs[0].proc = reinterpret_cast(CSASLAuthMod::getopt); + m_cbs[0].context = this; + m_cbs[1].id = SASL_CB_LIST_END; + m_cbs[1].proc = nullptr; + m_cbs[1].context = nullptr; - AddHelpCommand(); - AddCommand("CreateUser", static_cast( - &CSASLAuthMod::CreateUserCommand), - "[yes|no]"); - AddCommand("CloneUser", static_cast( - &CSASLAuthMod::CloneUserCommand), - "[username]"); - AddCommand("DisableCloneUser", - static_cast( - &CSASLAuthMod::DisableCloneUserCommand)); - } + AddHelpCommand(); + AddCommand("CreateUser", static_cast( + &CSASLAuthMod::CreateUserCommand), + "[yes|no]"); + AddCommand("CloneUser", static_cast( + &CSASLAuthMod::CloneUserCommand), + "[username]"); + AddCommand("DisableCloneUser", + static_cast( + &CSASLAuthMod::DisableCloneUserCommand)); + } - virtual ~CSASLAuthMod() { sasl_done(); } + virtual ~CSASLAuthMod() { sasl_done(); } - void OnModCommand(const CString& sCommand) override { - if (GetUser()->IsAdmin()) { - HandleCommand(sCommand); - } else { - PutModule("Access denied"); - } - } + void OnModCommand(const CString& sCommand) override { + if (GetUser()->IsAdmin()) { + HandleCommand(sCommand); + } else { + PutModule("Access denied"); + } + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - VCString vsArgs; - VCString::const_iterator it; - sArgs.Split(" ", vsArgs, false); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + VCString vsArgs; + VCString::const_iterator it; + sArgs.Split(" ", vsArgs, false); - for (it = vsArgs.begin(); it != vsArgs.end(); ++it) { - if (it->Equals("saslauthd") || it->Equals("auxprop")) { - m_sMethod += *it + " "; - } else { - CUtils::PrintError("Ignoring invalid SASL pwcheck method: " + - *it); - sMessage = "Ignored invalid SASL pwcheck method"; - } - } + for (it = vsArgs.begin(); it != vsArgs.end(); ++it) { + if (it->Equals("saslauthd") || it->Equals("auxprop")) { + m_sMethod += *it + " "; + } else { + CUtils::PrintError("Ignoring invalid SASL pwcheck method: " + + *it); + sMessage = "Ignored invalid SASL pwcheck method"; + } + } - m_sMethod.TrimRight(); + m_sMethod.TrimRight(); - if (m_sMethod.empty()) { - sMessage = "Need a pwcheck method as argument (saslauthd, auxprop)"; - return false; - } + if (m_sMethod.empty()) { + sMessage = "Need a pwcheck method as argument (saslauthd, auxprop)"; + return false; + } - if (sasl_server_init(nullptr, nullptr) != SASL_OK) { - sMessage = "SASL Could Not Be Initialized - Halting Startup"; - return false; - } + if (sasl_server_init(nullptr, nullptr) != SASL_OK) { + sMessage = "SASL Could Not Be Initialized - Halting Startup"; + return false; + } - return true; - } + return true; + } - EModRet OnLoginAttempt(std::shared_ptr Auth) override { - const CString& sUsername = Auth->GetUsername(); - const CString& sPassword = Auth->GetPassword(); - CUser* pUser(CZNC::Get().FindUser(sUsername)); - sasl_conn_t* sasl_conn(nullptr); - bool bSuccess = false; + EModRet OnLoginAttempt(std::shared_ptr Auth) override { + const CString& sUsername = Auth->GetUsername(); + const CString& sPassword = Auth->GetPassword(); + CUser* pUser(CZNC::Get().FindUser(sUsername)); + sasl_conn_t* sasl_conn(nullptr); + bool bSuccess = false; - if (!pUser && !CreateUser()) { - return CONTINUE; - } + if (!pUser && !CreateUser()) { + return CONTINUE; + } - const CString sCacheKey(CString(sUsername + ":" + sPassword).MD5()); - if (m_Cache.HasItem(sCacheKey)) { - bSuccess = true; - DEBUG("saslauth: Found [" + sUsername + "] in cache"); - } else if (sasl_server_new("znc", nullptr, nullptr, nullptr, nullptr, - m_cbs, 0, &sasl_conn) == SASL_OK && - sasl_checkpass(sasl_conn, sUsername.c_str(), - sUsername.size(), sPassword.c_str(), - sPassword.size()) == SASL_OK) { - m_Cache.AddItem(sCacheKey); + const CString sCacheKey(CString(sUsername + ":" + sPassword).MD5()); + if (m_Cache.HasItem(sCacheKey)) { + bSuccess = true; + DEBUG("saslauth: Found [" + sUsername + "] in cache"); + } else if (sasl_server_new("znc", nullptr, nullptr, nullptr, nullptr, + m_cbs, 0, &sasl_conn) == SASL_OK && + sasl_checkpass(sasl_conn, sUsername.c_str(), + sUsername.size(), sPassword.c_str(), + sPassword.size()) == SASL_OK) { + m_Cache.AddItem(sCacheKey); - DEBUG("saslauth: Successful SASL authentication [" + sUsername + - "]"); + DEBUG("saslauth: Successful SASL authentication [" + sUsername + + "]"); - bSuccess = true; - } + bSuccess = true; + } - sasl_dispose(&sasl_conn); + sasl_dispose(&sasl_conn); - if (bSuccess) { - if (!pUser) { - CString sErr; - pUser = new CUser(sUsername); + if (bSuccess) { + if (!pUser) { + CString sErr; + pUser = new CUser(sUsername); - if (ShouldCloneUser()) { - CUser* pBaseUser = CZNC::Get().FindUser(CloneUser()); + if (ShouldCloneUser()) { + CUser* pBaseUser = CZNC::Get().FindUser(CloneUser()); - if (!pBaseUser) { - DEBUG("saslauth: Clone User [" << CloneUser() - << "] User not found"); - delete pUser; - pUser = nullptr; - } + if (!pBaseUser) { + DEBUG("saslauth: Clone User [" << CloneUser() + << "] User not found"); + delete pUser; + pUser = nullptr; + } - if (pUser && !pUser->Clone(*pBaseUser, sErr)) { - DEBUG("saslauth: Clone User [" << CloneUser() - << "] failed: " << sErr); - delete pUser; - pUser = nullptr; - } - } + if (pUser && !pUser->Clone(*pBaseUser, sErr)) { + DEBUG("saslauth: Clone User [" << CloneUser() + << "] failed: " << sErr); + delete pUser; + pUser = nullptr; + } + } - if (pUser) { - // "::" is an invalid MD5 hash, so user won't be able to - // login by usual method - pUser->SetPass("::", CUser::HASH_MD5, "::"); - } + if (pUser) { + // "::" is an invalid MD5 hash, so user won't be able to + // login by usual method + pUser->SetPass("::", CUser::HASH_MD5, "::"); + } - if (pUser && !CZNC::Get().AddUser(pUser, sErr)) { - DEBUG("saslauth: Add user [" << sUsername - << "] failed: " << sErr); - delete pUser; - pUser = nullptr; - } - } + if (pUser && !CZNC::Get().AddUser(pUser, sErr)) { + DEBUG("saslauth: Add user [" << sUsername + << "] failed: " << sErr); + delete pUser; + pUser = nullptr; + } + } - if (pUser) { - Auth->AcceptLogin(*pUser); - return HALT; - } - } + if (pUser) { + Auth->AcceptLogin(*pUser); + return HALT; + } + } - return CONTINUE; - } + return CONTINUE; + } - const CString& GetMethod() const { return m_sMethod; } + const CString& GetMethod() const { return m_sMethod; } - void CreateUserCommand(const CString& sLine) { - CString sCreate = sLine.Token(1); + void CreateUserCommand(const CString& sLine) { + CString sCreate = sLine.Token(1); - if (!sCreate.empty()) { - SetNV("CreateUser", sCreate); - } + if (!sCreate.empty()) { + SetNV("CreateUser", sCreate); + } - if (CreateUser()) { - PutModule("We will create users on their first login"); - } else { - PutModule("We will not create users on their first login"); - } - } + if (CreateUser()) { + PutModule("We will create users on their first login"); + } else { + PutModule("We will not create users on their first login"); + } + } - void CloneUserCommand(const CString& sLine) { - CString sUsername = sLine.Token(1); + void CloneUserCommand(const CString& sLine) { + CString sUsername = sLine.Token(1); - if (!sUsername.empty()) { - SetNV("CloneUser", sUsername); - } + if (!sUsername.empty()) { + SetNV("CloneUser", sUsername); + } - if (ShouldCloneUser()) { - PutModule("We will clone [" + CloneUser() + "]"); - } else { - PutModule("We will not clone a user"); - } - } + if (ShouldCloneUser()) { + PutModule("We will clone [" + CloneUser() + "]"); + } else { + PutModule("We will not clone a user"); + } + } - void DisableCloneUserCommand(const CString& sLine) { - DelNV("CloneUser"); - PutModule("Clone user disabled"); - } + void DisableCloneUserCommand(const CString& sLine) { + DelNV("CloneUser"); + PutModule("Clone user disabled"); + } - bool CreateUser() const { return GetNV("CreateUser").ToBool(); } + bool CreateUser() const { return GetNV("CreateUser").ToBool(); } - CString CloneUser() const { return GetNV("CloneUser"); } + CString CloneUser() const { return GetNV("CloneUser"); } - bool ShouldCloneUser() { return !GetNV("CloneUser").empty(); } + bool ShouldCloneUser() { return !GetNV("CloneUser").empty(); } protected: - TCacheMap m_Cache; + TCacheMap m_Cache; - sasl_callback_t m_cbs[2]; - CString m_sMethod; + sasl_callback_t m_cbs[2]; + CString m_sMethod; - static int getopt(void* context, const char* plugin_name, - const char* option, const char** result, unsigned* len) { - if (CString(option).Equals("pwcheck_method")) { - *result = ((CSASLAuthMod*)context)->GetMethod().c_str(); - return SASL_OK; - } + static int getopt(void* context, const char* plugin_name, + const char* option, const char** result, unsigned* len) { + if (CString(option).Equals("pwcheck_method")) { + *result = ((CSASLAuthMod*)context)->GetMethod().c_str(); + return SASL_OK; + } - return SASL_CONTINUE; - } + return SASL_CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("cyrusauth"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "This global module takes up to two arguments - the methods of " - "authentication - auxprop and saslauthd"); + Info.SetWikiPage("cyrusauth"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "This global module takes up to two arguments - the methods of " + "authentication - auxprop and saslauthd"); } GLOBALMODULEDEFS( diff --git a/modules/dcc.cpp b/modules/dcc.cpp index 6a2a45a0..2774435d 100644 --- a/modules/dcc.cpp +++ b/modules/dcc.cpp @@ -24,538 +24,538 @@ class CDCCMod; class CDCCSock : public CSocket { public: - CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, - const CString& sLocalFile, unsigned long uFileSize = 0, - CFile* pFile = nullptr); - CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, - const CString& sRemoteIP, unsigned short uRemotePort, - const CString& sLocalFile, unsigned long uFileSize); - virtual ~CDCCSock(); + CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, + const CString& sLocalFile, unsigned long uFileSize = 0, + CFile* pFile = nullptr); + CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, + const CString& sRemoteIP, unsigned short uRemotePort, + const CString& sLocalFile, unsigned long uFileSize); + virtual ~CDCCSock(); - void ReadData(const char* data, size_t len) override; - void ConnectionRefused() override; - void SockError(int iErrno, const CString& sDescription) override; - void Timeout() override; - void Connected() override; - void Disconnected() override; - void SendPacket(); - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; - CFile* OpenFile(bool bWrite = true); - bool Seek(unsigned long int uPos); + void ReadData(const char* data, size_t len) override; + void ConnectionRefused() override; + void SockError(int iErrno, const CString& sDescription) override; + void Timeout() override; + void Connected() override; + void Disconnected() override; + void SendPacket(); + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + CFile* OpenFile(bool bWrite = true); + bool Seek(unsigned long int uPos); - // Setters - void SetRemoteIP(const CString& s) { m_sRemoteIP = s; } - void SetRemoteNick(const CString& s) { m_sRemoteNick = s; } - void SetFileName(const CString& s) { m_sFileName = s; } - void SetFileOffset(unsigned long u) { m_uBytesSoFar = u; } - // !Setters + // Setters + void SetRemoteIP(const CString& s) { m_sRemoteIP = s; } + void SetRemoteNick(const CString& s) { m_sRemoteNick = s; } + void SetFileName(const CString& s) { m_sFileName = s; } + void SetFileOffset(unsigned long u) { m_uBytesSoFar = u; } + // !Setters - // Getters - unsigned short GetUserPort() const { return m_uRemotePort; } - const CString& GetRemoteNick() const { return m_sRemoteNick; } - const CString& GetFileName() const { return m_sFileName; } - const CString& GetLocalFile() const { return m_sLocalFile; } - CFile* GetFile() { return m_pFile; } - double GetProgress() const { - return ((m_uFileSize) && (m_uBytesSoFar)) - ? (double)(((double)m_uBytesSoFar / (double)m_uFileSize) * - 100.0) - : 0; - } - bool IsSend() const { return m_bSend; } - // const CString& GetRemoteIP() const { return m_sRemoteIP; } - // !Getters + // Getters + unsigned short GetUserPort() const { return m_uRemotePort; } + const CString& GetRemoteNick() const { return m_sRemoteNick; } + const CString& GetFileName() const { return m_sFileName; } + const CString& GetLocalFile() const { return m_sLocalFile; } + CFile* GetFile() { return m_pFile; } + double GetProgress() const { + return ((m_uFileSize) && (m_uBytesSoFar)) + ? (double)(((double)m_uBytesSoFar / (double)m_uFileSize) * + 100.0) + : 0; + } + bool IsSend() const { return m_bSend; } + // const CString& GetRemoteIP() const { return m_sRemoteIP; } + // !Getters private: protected: - CString m_sRemoteNick; - CString m_sRemoteIP; - CString m_sFileName; - CString m_sLocalFile; - CString m_sSendBuf; - unsigned short m_uRemotePort; - unsigned long long m_uFileSize; - unsigned long long m_uBytesSoFar; - bool m_bSend; - bool m_bNoDelFile; - CFile* m_pFile; - CDCCMod* m_pModule; + CString m_sRemoteNick; + CString m_sRemoteIP; + CString m_sFileName; + CString m_sLocalFile; + CString m_sSendBuf; + unsigned short m_uRemotePort; + unsigned long long m_uFileSize; + unsigned long long m_uBytesSoFar; + bool m_bSend; + bool m_bNoDelFile; + CFile* m_pFile; + CDCCMod* m_pModule; }; class CDCCMod : public CModule { public: - MODCONSTRUCTOR(CDCCMod) { - AddHelpCommand(); - AddCommand("Send", - static_cast(&CDCCMod::SendCommand), - " "); - AddCommand("Get", - static_cast(&CDCCMod::GetCommand), - ""); - AddCommand("ListTransfers", static_cast( - &CDCCMod::ListTransfersCommand)); - } + MODCONSTRUCTOR(CDCCMod) { + AddHelpCommand(); + AddCommand("Send", + static_cast(&CDCCMod::SendCommand), + " "); + AddCommand("Get", + static_cast(&CDCCMod::GetCommand), + ""); + AddCommand("ListTransfers", static_cast( + &CDCCMod::ListTransfersCommand)); + } - virtual ~CDCCMod() {} + virtual ~CDCCMod() {} #ifndef MOD_DCC_ALLOW_EVERYONE - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (!GetUser()->IsAdmin()) { - sMessage = "You must be admin to use the DCC module"; - return false; - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (!GetUser()->IsAdmin()) { + sMessage = "You must be admin to use the DCC module"; + return false; + } - return true; - } + return true; + } #endif - bool SendFile(const CString& sRemoteNick, const CString& sFileName) { - CString sFullPath = CDir::ChangeDir(GetSavePath(), sFileName, - CZNC::Get().GetHomePath()); - CDCCSock* pSock = new CDCCSock(this, sRemoteNick, sFullPath); + bool SendFile(const CString& sRemoteNick, const CString& sFileName) { + CString sFullPath = CDir::ChangeDir(GetSavePath(), sFileName, + CZNC::Get().GetHomePath()); + CDCCSock* pSock = new CDCCSock(this, sRemoteNick, sFullPath); - CFile* pFile = pSock->OpenFile(false); + CFile* pFile = pSock->OpenFile(false); - if (!pFile) { - delete pSock; - return false; - } + if (!pFile) { + delete pSock; + return false; + } - CString sLocalDCCIP = GetUser()->GetLocalDCCIP(); - unsigned short uPort = CZNC::Get().GetManager().ListenRand( - "DCC::LISTEN::" + sRemoteNick, sLocalDCCIP, false, SOMAXCONN, pSock, - 120); + CString sLocalDCCIP = GetUser()->GetLocalDCCIP(); + unsigned short uPort = CZNC::Get().GetManager().ListenRand( + "DCC::LISTEN::" + sRemoteNick, sLocalDCCIP, false, SOMAXCONN, pSock, + 120); - if (GetUser()->GetNick().Equals(sRemoteNick)) { - PutUser(":*dcc!znc@znc.in PRIVMSG " + sRemoteNick + - " :\001DCC SEND " + pFile->GetShortName() + " " + - CString(CUtils::GetLongIP(sLocalDCCIP)) + " " + - CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); - } else { - PutIRC("PRIVMSG " + sRemoteNick + " :\001DCC SEND " + - pFile->GetShortName() + " " + - CString(CUtils::GetLongIP(sLocalDCCIP)) + " " + - CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); - } + if (GetUser()->GetNick().Equals(sRemoteNick)) { + PutUser(":*dcc!znc@znc.in PRIVMSG " + sRemoteNick + + " :\001DCC SEND " + pFile->GetShortName() + " " + + CString(CUtils::GetLongIP(sLocalDCCIP)) + " " + + CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); + } else { + PutIRC("PRIVMSG " + sRemoteNick + " :\001DCC SEND " + + pFile->GetShortName() + " " + + CString(CUtils::GetLongIP(sLocalDCCIP)) + " " + + CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); + } - PutModule("DCC -> [" + sRemoteNick + "][" + pFile->GetShortName() + - "] - Attempting Send."); - return true; - } + PutModule("DCC -> [" + sRemoteNick + "][" + pFile->GetShortName() + + "] - Attempting Send."); + return true; + } - bool GetFile(const CString& sRemoteNick, const CString& sRemoteIP, - unsigned short uRemotePort, const CString& sFileName, - unsigned long uFileSize) { - if (CFile::Exists(sFileName)) { - PutModule("DCC <- [" + sRemoteNick + "][" + sFileName + - "] - File already exists."); - return false; - } + bool GetFile(const CString& sRemoteNick, const CString& sRemoteIP, + unsigned short uRemotePort, const CString& sFileName, + unsigned long uFileSize) { + if (CFile::Exists(sFileName)) { + PutModule("DCC <- [" + sRemoteNick + "][" + sFileName + + "] - File already exists."); + return false; + } - CDCCSock* pSock = new CDCCSock(this, sRemoteNick, sRemoteIP, - uRemotePort, sFileName, uFileSize); + CDCCSock* pSock = new CDCCSock(this, sRemoteNick, sRemoteIP, + uRemotePort, sFileName, uFileSize); - if (!pSock->OpenFile()) { - delete pSock; - return false; - } + if (!pSock->OpenFile()) { + delete pSock; + return false; + } - CZNC::Get().GetManager().Connect(sRemoteIP, uRemotePort, - "DCC::GET::" + sRemoteNick, 60, false, - GetUser()->GetLocalDCCIP(), pSock); + CZNC::Get().GetManager().Connect(sRemoteIP, uRemotePort, + "DCC::GET::" + sRemoteNick, 60, false, + GetUser()->GetLocalDCCIP(), pSock); - PutModule("DCC <- [" + sRemoteNick + "][" + sFileName + - "] - Attempting to connect to [" + sRemoteIP + "]"); - return true; - } + PutModule("DCC <- [" + sRemoteNick + "][" + sFileName + + "] - Attempting to connect to [" + sRemoteIP + "]"); + return true; + } - void SendCommand(const CString& sLine) { - CString sToNick = sLine.Token(1); - CString sFile = sLine.Token(2); - CString sAllowedPath = GetSavePath(); - CString sAbsolutePath; + void SendCommand(const CString& sLine) { + CString sToNick = sLine.Token(1); + CString sFile = sLine.Token(2); + CString sAllowedPath = GetSavePath(); + CString sAbsolutePath; - if ((sToNick.empty()) || (sFile.empty())) { - PutModule("Usage: Send "); - return; - } + if ((sToNick.empty()) || (sFile.empty())) { + PutModule("Usage: Send "); + return; + } - sAbsolutePath = CDir::CheckPathPrefix(sAllowedPath, sFile); + sAbsolutePath = CDir::CheckPathPrefix(sAllowedPath, sFile); - if (sAbsolutePath.empty()) { - PutStatus("Illegal path."); - return; - } + if (sAbsolutePath.empty()) { + PutStatus("Illegal path."); + return; + } - SendFile(sToNick, sFile); - } + SendFile(sToNick, sFile); + } - void GetCommand(const CString& sLine) { - CString sFile = sLine.Token(1); - CString sAllowedPath = GetSavePath(); - CString sAbsolutePath; + void GetCommand(const CString& sLine) { + CString sFile = sLine.Token(1); + CString sAllowedPath = GetSavePath(); + CString sAbsolutePath; - if (sFile.empty()) { - PutModule("Usage: Get "); - return; - } + if (sFile.empty()) { + PutModule("Usage: Get "); + return; + } - sAbsolutePath = CDir::CheckPathPrefix(sAllowedPath, sFile); + sAbsolutePath = CDir::CheckPathPrefix(sAllowedPath, sFile); - if (sAbsolutePath.empty()) { - PutModule("Illegal path."); - return; - } + if (sAbsolutePath.empty()) { + PutModule("Illegal path."); + return; + } - SendFile(GetUser()->GetNick(), sFile); - } + SendFile(GetUser()->GetNick(), sFile); + } - void ListTransfersCommand(const CString& sLine) { - CTable Table; - Table.AddColumn("Type"); - Table.AddColumn("State"); - Table.AddColumn("Speed"); - Table.AddColumn("Nick"); - Table.AddColumn("IP"); - Table.AddColumn("File"); + void ListTransfersCommand(const CString& sLine) { + CTable Table; + Table.AddColumn("Type"); + Table.AddColumn("State"); + Table.AddColumn("Speed"); + Table.AddColumn("Nick"); + Table.AddColumn("IP"); + Table.AddColumn("File"); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCSock* pSock = (CDCCSock*)*it; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCSock* pSock = (CDCCSock*)*it; - Table.AddRow(); - Table.SetCell("Nick", pSock->GetRemoteNick()); - Table.SetCell("IP", pSock->GetRemoteIP()); - Table.SetCell("File", pSock->GetFileName()); + Table.AddRow(); + Table.SetCell("Nick", pSock->GetRemoteNick()); + Table.SetCell("IP", pSock->GetRemoteIP()); + Table.SetCell("File", pSock->GetFileName()); - if (pSock->IsSend()) { - Table.SetCell("Type", "Sending"); - } else { - Table.SetCell("Type", "Getting"); - } + if (pSock->IsSend()) { + Table.SetCell("Type", "Sending"); + } else { + Table.SetCell("Type", "Getting"); + } - if (pSock->GetType() == Csock::LISTENER) { - Table.SetCell("State", "Waiting"); - } else { - Table.SetCell("State", - CString::ToPercent(pSock->GetProgress())); - Table.SetCell( - "Speed", - CString((int)(pSock->GetAvgRead() / 1024.0)) + " KiB/s"); - } - } + if (pSock->GetType() == Csock::LISTENER) { + Table.SetCell("State", "Waiting"); + } else { + Table.SetCell("State", + CString::ToPercent(pSock->GetProgress())); + Table.SetCell( + "Speed", + CString((int)(pSock->GetAvgRead() / 1024.0)) + " KiB/s"); + } + } - if (PutModule(Table) == 0) { - PutModule("You have no active DCC transfers."); - } - } + if (PutModule(Table) == 0) { + PutModule("You have no active DCC transfers."); + } + } - void OnModCTCP(const CString& sMessage) override { - if (sMessage.StartsWith("DCC RESUME ")) { - CString sFile = sMessage.Token(2); - unsigned short uResumePort = sMessage.Token(3).ToUShort(); - unsigned long uResumeSize = sMessage.Token(4).ToULong(); + void OnModCTCP(const CString& sMessage) override { + if (sMessage.StartsWith("DCC RESUME ")) { + CString sFile = sMessage.Token(2); + unsigned short uResumePort = sMessage.Token(3).ToUShort(); + unsigned long uResumeSize = sMessage.Token(4).ToULong(); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CDCCSock* pSock = (CDCCSock*)*it; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CDCCSock* pSock = (CDCCSock*)*it; - if (pSock->GetLocalPort() == uResumePort) { - if (pSock->Seek(uResumeSize)) { - PutModule( - "DCC -> [" + pSock->GetRemoteNick() + "][" + - pSock->GetFileName() + - "] - Attempting to resume from file position [" + - CString(uResumeSize) + "]"); - PutUser(":*dcc!znc@znc.in PRIVMSG " + - GetUser()->GetNick() + " :\001DCC ACCEPT " + - sFile + " " + CString(uResumePort) + " " + - CString(uResumeSize) + "\001"); - } else { - PutModule("DCC -> [" + GetUser()->GetNick() + "][" + - sFile + - "] Unable to find send to initiate resume."); - } - } - } - } else if (sMessage.StartsWith("DCC SEND ")) { - CString sLocalFile = - CDir::CheckPathPrefix(GetSavePath(), sMessage.Token(2)); - if (sLocalFile.empty()) { - PutModule("Bad DCC file: " + sMessage.Token(2)); - } - unsigned long uLongIP = sMessage.Token(3).ToULong(); - unsigned short uPort = sMessage.Token(4).ToUShort(); - unsigned long uFileSize = sMessage.Token(5).ToULong(); - GetFile(GetClient()->GetNick(), CUtils::GetIP(uLongIP), uPort, - sLocalFile, uFileSize); - } - } + if (pSock->GetLocalPort() == uResumePort) { + if (pSock->Seek(uResumeSize)) { + PutModule( + "DCC -> [" + pSock->GetRemoteNick() + "][" + + pSock->GetFileName() + + "] - Attempting to resume from file position [" + + CString(uResumeSize) + "]"); + PutUser(":*dcc!znc@znc.in PRIVMSG " + + GetUser()->GetNick() + " :\001DCC ACCEPT " + + sFile + " " + CString(uResumePort) + " " + + CString(uResumeSize) + "\001"); + } else { + PutModule("DCC -> [" + GetUser()->GetNick() + "][" + + sFile + + "] Unable to find send to initiate resume."); + } + } + } + } else if (sMessage.StartsWith("DCC SEND ")) { + CString sLocalFile = + CDir::CheckPathPrefix(GetSavePath(), sMessage.Token(2)); + if (sLocalFile.empty()) { + PutModule("Bad DCC file: " + sMessage.Token(2)); + } + unsigned long uLongIP = sMessage.Token(3).ToULong(); + unsigned short uPort = sMessage.Token(4).ToUShort(); + unsigned long uFileSize = sMessage.Token(5).ToULong(); + GetFile(GetClient()->GetNick(), CUtils::GetIP(uLongIP), uPort, + sLocalFile, uFileSize); + } + } }; CDCCSock::CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, const CString& sLocalFile, unsigned long uFileSize, CFile* pFile) : CSocket(pMod) { - m_sRemoteNick = sRemoteNick; - m_uFileSize = uFileSize; - m_uRemotePort = 0; - m_uBytesSoFar = 0; - m_pModule = pMod; - m_pFile = pFile; - m_sLocalFile = sLocalFile; - m_bSend = true; - m_bNoDelFile = false; - SetMaxBufferThreshold(0); + m_sRemoteNick = sRemoteNick; + m_uFileSize = uFileSize; + m_uRemotePort = 0; + m_uBytesSoFar = 0; + m_pModule = pMod; + m_pFile = pFile; + m_sLocalFile = sLocalFile; + m_bSend = true; + m_bNoDelFile = false; + SetMaxBufferThreshold(0); } CDCCSock::CDCCSock(CDCCMod* pMod, const CString& sRemoteNick, const CString& sRemoteIP, unsigned short uRemotePort, const CString& sLocalFile, unsigned long uFileSize) : CSocket(pMod) { - m_sRemoteNick = sRemoteNick; - m_sRemoteIP = sRemoteIP; - m_uRemotePort = uRemotePort; - m_uFileSize = uFileSize; - m_uBytesSoFar = 0; - m_pModule = pMod; - m_pFile = nullptr; - m_sLocalFile = sLocalFile; - m_bSend = false; - m_bNoDelFile = false; - SetMaxBufferThreshold(0); + m_sRemoteNick = sRemoteNick; + m_sRemoteIP = sRemoteIP; + m_uRemotePort = uRemotePort; + m_uFileSize = uFileSize; + m_uBytesSoFar = 0; + m_pModule = pMod; + m_pFile = nullptr; + m_sLocalFile = sLocalFile; + m_bSend = false; + m_bNoDelFile = false; + SetMaxBufferThreshold(0); } CDCCSock::~CDCCSock() { - if ((m_pFile) && (!m_bNoDelFile)) { - m_pFile->Close(); - delete m_pFile; - } + if ((m_pFile) && (!m_bNoDelFile)) { + m_pFile->Close(); + delete m_pFile; + } } void CDCCSock::ReadData(const char* data, size_t len) { - if (!m_pFile) { - DEBUG("File not open! closing get."); - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + - m_sRemoteNick + "][" + m_sFileName + - "] - File not open!"); - Close(); - return; - } + if (!m_pFile) { + DEBUG("File not open! closing get."); + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + + m_sRemoteNick + "][" + m_sFileName + + "] - File not open!"); + Close(); + return; + } - // DCC specs says the receiving end sends the number of bytes it - // received so far as a 4 byte integer in network byte order, so we need - // uint32_t to do the job portably. This also means that the maximum - // file that we can transfer is 4 GiB big (see OpenFile()). - if (m_bSend) { - m_sSendBuf.append(data, len); + // DCC specs says the receiving end sends the number of bytes it + // received so far as a 4 byte integer in network byte order, so we need + // uint32_t to do the job portably. This also means that the maximum + // file that we can transfer is 4 GiB big (see OpenFile()). + if (m_bSend) { + m_sSendBuf.append(data, len); - while (m_sSendBuf.size() >= 4) { - uint32_t iRemoteSoFar; - memcpy(&iRemoteSoFar, m_sSendBuf.data(), sizeof(iRemoteSoFar)); - iRemoteSoFar = ntohl(iRemoteSoFar); + while (m_sSendBuf.size() >= 4) { + uint32_t iRemoteSoFar; + memcpy(&iRemoteSoFar, m_sSendBuf.data(), sizeof(iRemoteSoFar)); + iRemoteSoFar = ntohl(iRemoteSoFar); - if ((iRemoteSoFar + 65536) >= m_uBytesSoFar) { - SendPacket(); - } + if ((iRemoteSoFar + 65536) >= m_uBytesSoFar) { + SendPacket(); + } - m_sSendBuf.erase(0, 4); - } - } else { - m_pFile->Write(data, len); - m_uBytesSoFar += len; - uint32_t uSoFar = htonl((uint32_t)m_uBytesSoFar); - Write((char*)&uSoFar, sizeof(uSoFar)); + m_sSendBuf.erase(0, 4); + } + } else { + m_pFile->Write(data, len); + m_uBytesSoFar += len; + uint32_t uSoFar = htonl((uint32_t)m_uBytesSoFar); + Write((char*)&uSoFar, sizeof(uSoFar)); - if (m_uBytesSoFar >= m_uFileSize) { - Close(); - } - } + if (m_uBytesSoFar >= m_uFileSize) { + Close(); + } + } } void CDCCSock::ConnectionRefused() { - DEBUG(GetSockName() << " == ConnectionRefused()"); - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + - "][" + m_sFileName + "] - Connection Refused."); + DEBUG(GetSockName() << " == ConnectionRefused()"); + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + + "][" + m_sFileName + "] - Connection Refused."); } void CDCCSock::Timeout() { - DEBUG(GetSockName() << " == Timeout()"); - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + - "][" + m_sFileName + "] - Timed Out."); + DEBUG(GetSockName() << " == Timeout()"); + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + + "][" + m_sFileName + "] - Timed Out."); } void CDCCSock::SockError(int iErrno, const CString& sDescription) { - DEBUG(GetSockName() << " == SockError(" << iErrno << ", " << sDescription - << ")"); - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + - "][" + m_sFileName + "] - Socket Error [" + - sDescription + "]"); + DEBUG(GetSockName() << " == SockError(" << iErrno << ", " << sDescription + << ")"); + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + + "][" + m_sFileName + "] - Socket Error [" + + sDescription + "]"); } void CDCCSock::Connected() { - DEBUG(GetSockName() << " == Connected(" << GetRemoteIP() << ")"); - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + - "][" + m_sFileName + "] - Transfer Started."); + DEBUG(GetSockName() << " == Connected(" << GetRemoteIP() << ")"); + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + m_sRemoteNick + + "][" + m_sFileName + "] - Transfer Started."); - if (m_bSend) { - SendPacket(); - } + if (m_bSend) { + SendPacket(); + } - SetTimeout(120); + SetTimeout(120); } void CDCCSock::Disconnected() { - const CString sStart = ((m_bSend) ? "DCC -> [" : "DCC <- [") + - m_sRemoteNick + "][" + m_sFileName + "] - "; + const CString sStart = ((m_bSend) ? "DCC -> [" : "DCC <- [") + + m_sRemoteNick + "][" + m_sFileName + "] - "; - DEBUG(GetSockName() << " == Disconnected()"); + DEBUG(GetSockName() << " == Disconnected()"); - if (m_uBytesSoFar > m_uFileSize) { - m_pModule->PutModule(sStart + "TooMuchData!"); - } else if (m_uBytesSoFar == m_uFileSize) { - if (m_bSend) { - m_pModule->PutModule( - sStart + "Completed! - Sent [" + m_sLocalFile + "] at [" + - CString((int)(GetAvgWrite() / 1024.0)) + " KiB/s ]"); - } else { - m_pModule->PutModule( - sStart + "Completed! - Saved to [" + m_sLocalFile + "] at [" + - CString((int)(GetAvgRead() / 1024.0)) + " KiB/s ]"); - } - } else { - m_pModule->PutModule(sStart + "Incomplete!"); - } + if (m_uBytesSoFar > m_uFileSize) { + m_pModule->PutModule(sStart + "TooMuchData!"); + } else if (m_uBytesSoFar == m_uFileSize) { + if (m_bSend) { + m_pModule->PutModule( + sStart + "Completed! - Sent [" + m_sLocalFile + "] at [" + + CString((int)(GetAvgWrite() / 1024.0)) + " KiB/s ]"); + } else { + m_pModule->PutModule( + sStart + "Completed! - Saved to [" + m_sLocalFile + "] at [" + + CString((int)(GetAvgRead() / 1024.0)) + " KiB/s ]"); + } + } else { + m_pModule->PutModule(sStart + "Incomplete!"); + } } void CDCCSock::SendPacket() { - if (!m_pFile) { - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + - m_sRemoteNick + "][" + m_sFileName + - "] - File closed prematurely."); - Close(); - return; - } + if (!m_pFile) { + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + + m_sRemoteNick + "][" + m_sFileName + + "] - File closed prematurely."); + Close(); + return; + } - if (GetInternalWriteBuffer().size() > 1024 * 1024) { - // There is still enough data to be written, don't add more - // stuff to that buffer. - DEBUG("SendPacket(): Skipping send, buffer still full enough [" - << GetInternalWriteBuffer().size() << "][" << m_sRemoteNick - << "][" << m_sFileName << "]"); - return; - } + if (GetInternalWriteBuffer().size() > 1024 * 1024) { + // There is still enough data to be written, don't add more + // stuff to that buffer. + DEBUG("SendPacket(): Skipping send, buffer still full enough [" + << GetInternalWriteBuffer().size() << "][" << m_sRemoteNick + << "][" << m_sFileName << "]"); + return; + } - char szBuf[4096]; - ssize_t iLen = m_pFile->Read(szBuf, 4096); + char szBuf[4096]; + ssize_t iLen = m_pFile->Read(szBuf, 4096); - if (iLen < 0) { - m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + - m_sRemoteNick + "][" + m_sFileName + - "] - Error reading from file."); - Close(); - return; - } + if (iLen < 0) { + m_pModule->PutModule(((m_bSend) ? "DCC -> [" : "DCC <- [") + + m_sRemoteNick + "][" + m_sFileName + + "] - Error reading from file."); + Close(); + return; + } - if (iLen > 0) { - Write(szBuf, iLen); - m_uBytesSoFar += iLen; - } + if (iLen > 0) { + Write(szBuf, iLen); + m_uBytesSoFar += iLen; + } } Csock* CDCCSock::GetSockObj(const CString& sHost, unsigned short uPort) { - Close(); + Close(); - CDCCSock* pSock = new CDCCSock(m_pModule, m_sRemoteNick, m_sLocalFile, - m_uFileSize, m_pFile); - pSock->SetSockName("DCC::SEND::" + m_sRemoteNick); - pSock->SetTimeout(120); - pSock->SetFileName(m_sFileName); - pSock->SetFileOffset(m_uBytesSoFar); - m_bNoDelFile = true; + CDCCSock* pSock = new CDCCSock(m_pModule, m_sRemoteNick, m_sLocalFile, + m_uFileSize, m_pFile); + pSock->SetSockName("DCC::SEND::" + m_sRemoteNick); + pSock->SetTimeout(120); + pSock->SetFileName(m_sFileName); + pSock->SetFileOffset(m_uBytesSoFar); + m_bNoDelFile = true; - return pSock; + return pSock; } CFile* CDCCSock::OpenFile(bool bWrite) { - if ((m_pFile) || (m_sLocalFile.empty())) { - m_pModule->PutModule(((bWrite) ? "DCC <- [" : "DCC -> [") + - m_sRemoteNick + "][" + m_sLocalFile + - "] - Unable to open file."); - return nullptr; - } + if ((m_pFile) || (m_sLocalFile.empty())) { + m_pModule->PutModule(((bWrite) ? "DCC <- [" : "DCC -> [") + + m_sRemoteNick + "][" + m_sLocalFile + + "] - Unable to open file."); + return nullptr; + } - m_pFile = new CFile(m_sLocalFile); + m_pFile = new CFile(m_sLocalFile); - if (bWrite) { - if (m_pFile->Exists()) { - delete m_pFile; - m_pFile = nullptr; - m_pModule->PutModule("DCC <- [" + m_sRemoteNick + - "] - File already exists [" + m_sLocalFile + - "]"); - return nullptr; - } + if (bWrite) { + if (m_pFile->Exists()) { + delete m_pFile; + m_pFile = nullptr; + m_pModule->PutModule("DCC <- [" + m_sRemoteNick + + "] - File already exists [" + m_sLocalFile + + "]"); + return nullptr; + } - if (!m_pFile->Open(O_WRONLY | O_TRUNC | O_CREAT)) { - delete m_pFile; - m_pFile = nullptr; - m_pModule->PutModule("DCC <- [" + m_sRemoteNick + - "] - Could not open file [" + m_sLocalFile + - "]"); - return nullptr; - } - } else { - if (!m_pFile->IsReg()) { - delete m_pFile; - m_pFile = nullptr; - m_pModule->PutModule("DCC -> [" + m_sRemoteNick + - "] - Not a file [" + m_sLocalFile + "]"); - return nullptr; - } + if (!m_pFile->Open(O_WRONLY | O_TRUNC | O_CREAT)) { + delete m_pFile; + m_pFile = nullptr; + m_pModule->PutModule("DCC <- [" + m_sRemoteNick + + "] - Could not open file [" + m_sLocalFile + + "]"); + return nullptr; + } + } else { + if (!m_pFile->IsReg()) { + delete m_pFile; + m_pFile = nullptr; + m_pModule->PutModule("DCC -> [" + m_sRemoteNick + + "] - Not a file [" + m_sLocalFile + "]"); + return nullptr; + } - if (!m_pFile->Open()) { - delete m_pFile; - m_pFile = nullptr; - m_pModule->PutModule("DCC -> [" + m_sRemoteNick + - "] - Could not open file [" + m_sLocalFile + - "]"); - return nullptr; - } + if (!m_pFile->Open()) { + delete m_pFile; + m_pFile = nullptr; + m_pModule->PutModule("DCC -> [" + m_sRemoteNick + + "] - Could not open file [" + m_sLocalFile + + "]"); + return nullptr; + } - // The DCC specs only allow file transfers with files smaller - // than 4GiB (see ReadData()). - unsigned long long uFileSize = m_pFile->GetSize(); - if (uFileSize > (unsigned long long)0xffffffffULL) { - delete m_pFile; - m_pFile = nullptr; - m_pModule->PutModule("DCC -> [" + m_sRemoteNick + - "] - File too large (>4 GiB) [" + - m_sLocalFile + "]"); - return nullptr; - } + // The DCC specs only allow file transfers with files smaller + // than 4GiB (see ReadData()). + unsigned long long uFileSize = m_pFile->GetSize(); + if (uFileSize > (unsigned long long)0xffffffffULL) { + delete m_pFile; + m_pFile = nullptr; + m_pModule->PutModule("DCC -> [" + m_sRemoteNick + + "] - File too large (>4 GiB) [" + + m_sLocalFile + "]"); + return nullptr; + } - m_uFileSize = uFileSize; - } + m_uFileSize = uFileSize; + } - m_sFileName = m_pFile->GetShortName(); + m_sFileName = m_pFile->GetShortName(); - return m_pFile; + return m_pFile; } bool CDCCSock::Seek(unsigned long int uPos) { - if (m_pFile) { - if (m_pFile->Seek(uPos)) { - m_uBytesSoFar = uPos; - return true; - } - } + if (m_pFile) { + if (m_pFile->Seek(uPos)) { + m_uBytesSoFar = uPos; + return true; + } + } - return false; + return false; } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("dcc"); + Info.SetWikiPage("dcc"); } USERMODULEDEFS(CDCCMod, diff --git a/modules/fail2ban.cpp b/modules/fail2ban.cpp index b16f717b..e946587d 100644 --- a/modules/fail2ban.cpp +++ b/modules/fail2ban.cpp @@ -18,210 +18,210 @@ class CFailToBanMod : public CModule { public: - MODCONSTRUCTOR(CFailToBanMod) { - AddHelpCommand(); - AddCommand( - "Timeout", static_cast( - &CFailToBanMod::OnTimeoutCommand), - "[minutes]", - "The number of minutes IPs are blocked after a failed login."); - AddCommand("Attempts", static_cast( - &CFailToBanMod::OnAttemptsCommand), - "[count]", "The number of allowed failed login attempts."); - AddCommand("Ban", static_cast( - &CFailToBanMod::OnBanCommand), - "", "Ban the specified hosts."); - AddCommand("Unban", static_cast( - &CFailToBanMod::OnUnbanCommand), - "", "Unban the specified hosts."); - AddCommand("List", static_cast( - &CFailToBanMod::OnListCommand), - "", "List banned hosts."); - } - virtual ~CFailToBanMod() {} + MODCONSTRUCTOR(CFailToBanMod) { + AddHelpCommand(); + AddCommand( + "Timeout", static_cast( + &CFailToBanMod::OnTimeoutCommand), + "[minutes]", + "The number of minutes IPs are blocked after a failed login."); + AddCommand("Attempts", static_cast( + &CFailToBanMod::OnAttemptsCommand), + "[count]", "The number of allowed failed login attempts."); + AddCommand("Ban", static_cast( + &CFailToBanMod::OnBanCommand), + "", "Ban the specified hosts."); + AddCommand("Unban", static_cast( + &CFailToBanMod::OnUnbanCommand), + "", "Unban the specified hosts."); + AddCommand("List", static_cast( + &CFailToBanMod::OnListCommand), + "", "List banned hosts."); + } + virtual ~CFailToBanMod() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - CString sTimeout = sArgs.Token(0); - CString sAttempts = sArgs.Token(1); - unsigned int timeout = sTimeout.ToUInt(); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + CString sTimeout = sArgs.Token(0); + CString sAttempts = sArgs.Token(1); + unsigned int timeout = sTimeout.ToUInt(); - if (sAttempts.empty()) - m_uiAllowedFailed = 2; - else - m_uiAllowedFailed = sAttempts.ToUInt(); + if (sAttempts.empty()) + m_uiAllowedFailed = 2; + else + m_uiAllowedFailed = sAttempts.ToUInt(); - if (sArgs.empty()) { - timeout = 1; - } else if (timeout == 0 || m_uiAllowedFailed == 0 || - !sArgs.Token(2, true).empty()) { - sMessage = - "Invalid argument, must be the number of minutes " - "IPs are blocked after a failed login and can be " - "followed by number of allowed failed login attempts"; - return false; - } + if (sArgs.empty()) { + timeout = 1; + } else if (timeout == 0 || m_uiAllowedFailed == 0 || + !sArgs.Token(2, true).empty()) { + sMessage = + "Invalid argument, must be the number of minutes " + "IPs are blocked after a failed login and can be " + "followed by number of allowed failed login attempts"; + return false; + } - // SetTTL() wants milliseconds - m_Cache.SetTTL(timeout * 60 * 1000); + // SetTTL() wants milliseconds + m_Cache.SetTTL(timeout * 60 * 1000); - return true; - } + return true; + } - void OnPostRehash() override { m_Cache.Clear(); } + void OnPostRehash() override { m_Cache.Clear(); } - void Add(const CString& sHost, unsigned int count) { - m_Cache.AddItem(sHost, count, m_Cache.GetTTL()); - } + void Add(const CString& sHost, unsigned int count) { + m_Cache.AddItem(sHost, count, m_Cache.GetTTL()); + } - bool Remove(const CString& sHost) { return m_Cache.RemItem(sHost); } + bool Remove(const CString& sHost) { return m_Cache.RemItem(sHost); } - void OnTimeoutCommand(const CString& sCommand) { - CString sArg = sCommand.Token(1); + void OnTimeoutCommand(const CString& sCommand) { + CString sArg = sCommand.Token(1); - if (!sArg.empty()) { - unsigned int uTimeout = sArg.ToUInt(); - if (uTimeout == 0) { - PutModule("Usage: Timeout [minutes]"); - } else { - m_Cache.SetTTL(uTimeout * 60 * 1000); - SetArgs(CString(m_Cache.GetTTL() / 60 / 1000) + " " + - CString(m_uiAllowedFailed)); - PutModule("Timeout: " + CString(uTimeout) + " min"); - } - } else { - PutModule("Timeout: " + CString(m_Cache.GetTTL() / 60 / 1000) + - " min"); - } - } + if (!sArg.empty()) { + unsigned int uTimeout = sArg.ToUInt(); + if (uTimeout == 0) { + PutModule("Usage: Timeout [minutes]"); + } else { + m_Cache.SetTTL(uTimeout * 60 * 1000); + SetArgs(CString(m_Cache.GetTTL() / 60 / 1000) + " " + + CString(m_uiAllowedFailed)); + PutModule("Timeout: " + CString(uTimeout) + " min"); + } + } else { + PutModule("Timeout: " + CString(m_Cache.GetTTL() / 60 / 1000) + + " min"); + } + } - void OnAttemptsCommand(const CString& sCommand) { - CString sArg = sCommand.Token(1); + void OnAttemptsCommand(const CString& sCommand) { + CString sArg = sCommand.Token(1); - if (!sArg.empty()) { - unsigned int uiAttempts = sArg.ToUInt(); - if (uiAttempts == 0) { - PutModule("Usage: Attempts [count]"); - } else { - m_uiAllowedFailed = uiAttempts; - SetArgs(CString(m_Cache.GetTTL() / 60 / 1000) + " " + - CString(m_uiAllowedFailed)); - PutModule("Attempts: " + CString(uiAttempts)); - } - } else { - PutModule("Attempts: " + CString(m_uiAllowedFailed)); - } - } + if (!sArg.empty()) { + unsigned int uiAttempts = sArg.ToUInt(); + if (uiAttempts == 0) { + PutModule("Usage: Attempts [count]"); + } else { + m_uiAllowedFailed = uiAttempts; + SetArgs(CString(m_Cache.GetTTL() / 60 / 1000) + " " + + CString(m_uiAllowedFailed)); + PutModule("Attempts: " + CString(uiAttempts)); + } + } else { + PutModule("Attempts: " + CString(m_uiAllowedFailed)); + } + } - void OnBanCommand(const CString& sCommand) { - CString sHosts = sCommand.Token(1, true); + void OnBanCommand(const CString& sCommand) { + CString sHosts = sCommand.Token(1, true); - if (sHosts.empty()) { - PutStatus("Usage: Ban "); - return; - } + if (sHosts.empty()) { + PutStatus("Usage: Ban "); + return; + } - VCString vsHosts; - sHosts.Replace(",", " "); - sHosts.Split(" ", vsHosts, false, "", "", true, true); + VCString vsHosts; + sHosts.Replace(",", " "); + sHosts.Split(" ", vsHosts, false, "", "", true, true); - for (const CString& sHost : vsHosts) { - Add(sHost, 0); - PutModule("Banned: " + sHost); - } - } + for (const CString& sHost : vsHosts) { + Add(sHost, 0); + PutModule("Banned: " + sHost); + } + } - void OnUnbanCommand(const CString& sCommand) { - CString sHosts = sCommand.Token(1, true); + void OnUnbanCommand(const CString& sCommand) { + CString sHosts = sCommand.Token(1, true); - if (sHosts.empty()) { - PutStatus("Usage: Unban "); - return; - } + if (sHosts.empty()) { + PutStatus("Usage: Unban "); + return; + } - VCString vsHosts; - sHosts.Replace(",", " "); - sHosts.Split(" ", vsHosts, false, "", "", true, true); + VCString vsHosts; + sHosts.Replace(",", " "); + sHosts.Split(" ", vsHosts, false, "", "", true, true); - for (const CString& sHost : vsHosts) { - if (Remove(sHost)) { - PutModule("Unbanned: " + sHost); - } else { - PutModule("Ignored: " + sHost); - } - } - } + for (const CString& sHost : vsHosts) { + if (Remove(sHost)) { + PutModule("Unbanned: " + sHost); + } else { + PutModule("Ignored: " + sHost); + } + } + } - void OnListCommand(const CString& sCommand) { - CTable Table; - Table.AddColumn("Host"); - Table.AddColumn("Attempts"); + void OnListCommand(const CString& sCommand) { + CTable Table; + Table.AddColumn("Host"); + Table.AddColumn("Attempts"); - for (const auto& it : m_Cache.GetItems()) { - Table.AddRow(); - Table.SetCell("Host", it.first); - Table.SetCell("Attempts", CString(it.second)); - } + for (const auto& it : m_Cache.GetItems()) { + Table.AddRow(); + Table.SetCell("Host", it.first); + Table.SetCell("Attempts", CString(it.second)); + } - if (Table.empty()) { - PutModule("No bans"); - } else { - PutModule(Table); - } - } + if (Table.empty()) { + PutModule("No bans"); + } else { + PutModule(Table); + } + } - void OnClientConnect(CZNCSock* pClient, const CString& sHost, - unsigned short uPort) override { - unsigned int* pCount = m_Cache.GetItem(sHost); - if (sHost.empty() || pCount == nullptr || *pCount < m_uiAllowedFailed) { - return; - } + void OnClientConnect(CZNCSock* pClient, const CString& sHost, + unsigned short uPort) override { + unsigned int* pCount = m_Cache.GetItem(sHost); + if (sHost.empty() || pCount == nullptr || *pCount < m_uiAllowedFailed) { + return; + } - // refresh their ban - Add(sHost, *pCount); + // refresh their ban + Add(sHost, *pCount); - pClient->Write( - "ERROR :Closing link [Please try again later - reconnecting too " - "fast]\r\n"); - pClient->Close(Csock::CLT_AFTERWRITE); - } + pClient->Write( + "ERROR :Closing link [Please try again later - reconnecting too " + "fast]\r\n"); + pClient->Close(Csock::CLT_AFTERWRITE); + } - void OnFailedLogin(const CString& sUsername, - const CString& sRemoteIP) override { - unsigned int* pCount = m_Cache.GetItem(sRemoteIP); - if (pCount) - Add(sRemoteIP, *pCount + 1); - else - Add(sRemoteIP, 1); - } + void OnFailedLogin(const CString& sUsername, + const CString& sRemoteIP) override { + unsigned int* pCount = m_Cache.GetItem(sRemoteIP); + if (pCount) + Add(sRemoteIP, *pCount + 1); + else + Add(sRemoteIP, 1); + } - EModRet OnLoginAttempt(std::shared_ptr Auth) override { - // e.g. webadmin ends up here - const CString& sRemoteIP = Auth->GetRemoteIP(); + EModRet OnLoginAttempt(std::shared_ptr Auth) override { + // e.g. webadmin ends up here + const CString& sRemoteIP = Auth->GetRemoteIP(); - if (sRemoteIP.empty()) return CONTINUE; + if (sRemoteIP.empty()) return CONTINUE; - unsigned int* pCount = m_Cache.GetItem(sRemoteIP); - if (pCount && *pCount >= m_uiAllowedFailed) { - // OnFailedLogin() will refresh their ban - Auth->RefuseLogin("Please try again later - reconnecting too fast"); - return HALT; - } + unsigned int* pCount = m_Cache.GetItem(sRemoteIP); + if (pCount && *pCount >= m_uiAllowedFailed) { + // OnFailedLogin() will refresh their ban + Auth->RefuseLogin("Please try again later - reconnecting too fast"); + return HALT; + } - return CONTINUE; - } + return CONTINUE; + } private: - TCacheMap m_Cache; - unsigned int m_uiAllowedFailed{}; + TCacheMap m_Cache; + unsigned int m_uiAllowedFailed{}; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("fail2ban"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "You might enter the time in minutes for the IP banning and the number " - "of failed logins before any action is taken."); + Info.SetWikiPage("fail2ban"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "You might enter the time in minutes for the IP banning and the number " + "of failed logins before any action is taken."); } GLOBALMODULEDEFS(CFailToBanMod, "Block IPs for some time after a failed login.") diff --git a/modules/flooddetach.cpp b/modules/flooddetach.cpp index 3d402b99..ac4c27cc 100644 --- a/modules/flooddetach.cpp +++ b/modules/flooddetach.cpp @@ -22,232 +22,232 @@ using std::map; class CFloodDetachMod : public CModule { public: - MODCONSTRUCTOR(CFloodDetachMod) { - m_iThresholdSecs = 0; - m_iThresholdMsgs = 0; + MODCONSTRUCTOR(CFloodDetachMod) { + m_iThresholdSecs = 0; + m_iThresholdMsgs = 0; - AddHelpCommand(); - AddCommand("Show", static_cast( - &CFloodDetachMod::ShowCommand), - ""); - AddCommand("Secs", static_cast( - &CFloodDetachMod::SecsCommand), - "[]"); - AddCommand("Lines", static_cast( - &CFloodDetachMod::LinesCommand), - "[]"); - AddCommand("Silent", static_cast( - &CFloodDetachMod::SilentCommand), - "[yes|no]"); - } + AddHelpCommand(); + AddCommand("Show", static_cast( + &CFloodDetachMod::ShowCommand), + ""); + AddCommand("Secs", static_cast( + &CFloodDetachMod::SecsCommand), + "[]"); + AddCommand("Lines", static_cast( + &CFloodDetachMod::LinesCommand), + "[]"); + AddCommand("Silent", static_cast( + &CFloodDetachMod::SilentCommand), + "[yes|no]"); + } - ~CFloodDetachMod() {} + ~CFloodDetachMod() {} - void Save() { - // We save the settings twice because the module arguments can - // be more easily edited via webadmin, while the SetNV() stuff - // survives e.g. /msg *status reloadmod ctcpflood. - SetNV("secs", CString(m_iThresholdSecs)); - SetNV("msgs", CString(m_iThresholdMsgs)); + void Save() { + // We save the settings twice because the module arguments can + // be more easily edited via webadmin, while the SetNV() stuff + // survives e.g. /msg *status reloadmod ctcpflood. + SetNV("secs", CString(m_iThresholdSecs)); + SetNV("msgs", CString(m_iThresholdMsgs)); - SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs)); - } + SetArgs(CString(m_iThresholdMsgs) + " " + CString(m_iThresholdSecs)); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_iThresholdMsgs = sArgs.Token(0).ToUInt(); - m_iThresholdSecs = sArgs.Token(1).ToUInt(); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_iThresholdMsgs = sArgs.Token(0).ToUInt(); + m_iThresholdSecs = sArgs.Token(1).ToUInt(); - if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) { - m_iThresholdMsgs = GetNV("msgs").ToUInt(); - m_iThresholdSecs = GetNV("secs").ToUInt(); - } + if (m_iThresholdMsgs == 0 || m_iThresholdSecs == 0) { + m_iThresholdMsgs = GetNV("msgs").ToUInt(); + m_iThresholdSecs = GetNV("secs").ToUInt(); + } - if (m_iThresholdSecs == 0) m_iThresholdSecs = 2; - if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 5; + if (m_iThresholdSecs == 0) m_iThresholdSecs = 2; + if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 5; - Save(); + Save(); - return true; - } + return true; + } - void OnIRCDisconnected() override { m_chans.clear(); } + void OnIRCDisconnected() override { m_chans.clear(); } - void Cleanup() { - Limits::iterator it; - time_t now = time(nullptr); + void Cleanup() { + Limits::iterator it; + time_t now = time(nullptr); - for (it = m_chans.begin(); it != m_chans.end(); ++it) { - // The timeout for this channel did not expire yet? - if (it->second.first + (time_t)m_iThresholdSecs >= now) continue; + for (it = m_chans.begin(); it != m_chans.end(); ++it) { + // The timeout for this channel did not expire yet? + if (it->second.first + (time_t)m_iThresholdSecs >= now) continue; - CChan* pChan = GetNetwork()->FindChan(it->first); - if (it->second.second >= m_iThresholdMsgs && pChan && - pChan->IsDetached()) { - // The channel is detached and it is over the - // messages limit. Since we only track those - // limits for non-detached channels or for - // channels which we detached, this means that - // we detached because of a flood. + CChan* pChan = GetNetwork()->FindChan(it->first); + if (it->second.second >= m_iThresholdMsgs && pChan && + pChan->IsDetached()) { + // The channel is detached and it is over the + // messages limit. Since we only track those + // limits for non-detached channels or for + // channels which we detached, this means that + // we detached because of a flood. - if (!GetNV("silent").ToBool()) { - PutModule("Flood in [" + pChan->GetName() + - "] is over, " - "re-attaching..."); - } - // No buffer playback, makes sense, doesn't it? - pChan->ClearBuffer(); - pChan->AttachUser(); - } + if (!GetNV("silent").ToBool()) { + PutModule("Flood in [" + pChan->GetName() + + "] is over, " + "re-attaching..."); + } + // No buffer playback, makes sense, doesn't it? + pChan->ClearBuffer(); + pChan->AttachUser(); + } - Limits::iterator it2 = it++; - m_chans.erase(it2); + Limits::iterator it2 = it++; + m_chans.erase(it2); - // Without this Bad Things (tm) could happen - if (it == m_chans.end()) break; - } - } + // Without this Bad Things (tm) could happen + if (it == m_chans.end()) break; + } + } - void Message(CChan& Channel) { - Limits::iterator it; - time_t now = time(nullptr); + void Message(CChan& Channel) { + Limits::iterator it; + time_t now = time(nullptr); - // First: Clean up old entries and reattach where necessary - Cleanup(); + // First: Clean up old entries and reattach where necessary + Cleanup(); - it = m_chans.find(Channel.GetName()); + it = m_chans.find(Channel.GetName()); - if (it == m_chans.end()) { - // We don't track detached channels - if (Channel.IsDetached()) return; + if (it == m_chans.end()) { + // We don't track detached channels + if (Channel.IsDetached()) return; - // This is the first message for this channel, start a - // new timeout. - std::pair tmp(now, 1); - m_chans[Channel.GetName()] = tmp; - return; - } + // This is the first message for this channel, start a + // new timeout. + std::pair tmp(now, 1); + m_chans[Channel.GetName()] = tmp; + return; + } - // No need to check it->second.first (expiry time), since - // Cleanup() would have removed it if it was expired. + // No need to check it->second.first (expiry time), since + // Cleanup() would have removed it if it was expired. - if (it->second.second >= m_iThresholdMsgs) { - // The channel already hit the limit and we detached the - // user, but it is still being flooded, reset the timeout - it->second.first = now; - it->second.second++; - return; - } + if (it->second.second >= m_iThresholdMsgs) { + // The channel already hit the limit and we detached the + // user, but it is still being flooded, reset the timeout + it->second.first = now; + it->second.second++; + return; + } - it->second.second++; + it->second.second++; - if (it->second.second < m_iThresholdMsgs) return; + if (it->second.second < m_iThresholdMsgs) return; - // The channel hit the limit, reset the timeout so that we keep - // it detached for longer. - it->second.first = now; + // The channel hit the limit, reset the timeout so that we keep + // it detached for longer. + it->second.first = now; - Channel.DetachUser(); - if (!GetNV("silent").ToBool()) { - PutModule("Channel [" + Channel.GetName() + - "] was " - "flooded, you've been detached"); - } - } + Channel.DetachUser(); + if (!GetNV("silent").ToBool()) { + PutModule("Channel [" + Channel.GetName() + + "] was " + "flooded, you've been detached"); + } + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - Message(Channel); - return CONTINUE; - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + Message(Channel); + return CONTINUE; + } - // This also catches OnChanAction() - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Message(Channel); - return CONTINUE; - } + // This also catches OnChanAction() + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Message(Channel); + return CONTINUE; + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Message(Channel); - return CONTINUE; - } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Message(Channel); + return CONTINUE; + } - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { - Message(Channel); - return CONTINUE; - } + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { + Message(Channel); + return CONTINUE; + } - void OnNick(const CNick& Nick, const CString& sNewNick, - const std::vector& vChans) override { - for (CChan* pChan : vChans) { - Message(*pChan); - } - } + void OnNick(const CNick& Nick, const CString& sNewNick, + const std::vector& vChans) override { + for (CChan* pChan : vChans) { + Message(*pChan); + } + } - void ShowCommand(const CString& sLine) { - PutModule("Current limit is " + CString(m_iThresholdMsgs) + - " lines " - "in " + - CString(m_iThresholdSecs) + " secs."); - } + void ShowCommand(const CString& sLine) { + PutModule("Current limit is " + CString(m_iThresholdMsgs) + + " lines " + "in " + + CString(m_iThresholdSecs) + " secs."); + } - void SecsCommand(const CString& sLine) { - const CString sArg = sLine.Token(1, true); + void SecsCommand(const CString& sLine) { + const CString sArg = sLine.Token(1, true); - if (sArg.empty()) { - PutModule("Seconds limit is [" + CString(m_iThresholdSecs) + "]"); - } else { - m_iThresholdSecs = sArg.ToUInt(); - if (m_iThresholdSecs == 0) m_iThresholdSecs = 1; + if (sArg.empty()) { + PutModule("Seconds limit is [" + CString(m_iThresholdSecs) + "]"); + } else { + m_iThresholdSecs = sArg.ToUInt(); + if (m_iThresholdSecs == 0) m_iThresholdSecs = 1; - PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + - "]"); - Save(); - } - } + PutModule("Set seconds limit to [" + CString(m_iThresholdSecs) + + "]"); + Save(); + } + } - void LinesCommand(const CString& sLine) { - const CString sArg = sLine.Token(1, true); + void LinesCommand(const CString& sLine) { + const CString sArg = sLine.Token(1, true); - if (sArg.empty()) { - PutModule("Lines limit is [" + CString(m_iThresholdMsgs) + "]"); - } else { - m_iThresholdMsgs = sArg.ToUInt(); - if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 2; + if (sArg.empty()) { + PutModule("Lines limit is [" + CString(m_iThresholdMsgs) + "]"); + } else { + m_iThresholdMsgs = sArg.ToUInt(); + if (m_iThresholdMsgs == 0) m_iThresholdMsgs = 2; - PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]"); - Save(); - } - } + PutModule("Set lines limit to [" + CString(m_iThresholdMsgs) + "]"); + Save(); + } + } - void SilentCommand(const CString& sLine) { - const CString sArg = sLine.Token(1, true); + void SilentCommand(const CString& sLine) { + const CString sArg = sLine.Token(1, true); - if (!sArg.empty()) { - SetNV("silent", CString(sArg.ToBool())); - } + if (!sArg.empty()) { + SetNV("silent", CString(sArg.ToBool())); + } - if (GetNV("silent").ToBool()) { - PutModule("Module messages are disabled"); - } else { - PutModule("Module messages are enabled"); - } - } + if (GetNV("silent").ToBool()) { + PutModule("Module messages are disabled"); + } else { + PutModule("Module messages are enabled"); + } + } private: - typedef map> Limits; - Limits m_chans; - unsigned int m_iThresholdSecs; - unsigned int m_iThresholdMsgs; + typedef map> Limits; + Limits m_chans; + unsigned int m_iThresholdSecs; + unsigned int m_iThresholdMsgs; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("flooddetach"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "This user module takes up to two arguments. Arguments are msgs and " - "secs numbers."); + Info.SetWikiPage("flooddetach"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "This user module takes up to two arguments. Arguments are msgs and " + "secs numbers."); } USERMODULEDEFS(CFloodDetachMod, "Detach channels when flooded") diff --git a/modules/identfile.cpp b/modules/identfile.cpp index f7b15016..14ee4f76 100644 --- a/modules/identfile.cpp +++ b/modules/identfile.cpp @@ -20,204 +20,204 @@ #include class CIdentFileModule : public CModule { - CString m_sOrigISpoof; - CFile* m_pISpoofLockFile; - CIRCSock* m_pIRCSock; + CString m_sOrigISpoof; + CFile* m_pISpoofLockFile; + CIRCSock* m_pIRCSock; public: - MODCONSTRUCTOR(CIdentFileModule) { - AddHelpCommand(); - AddCommand("GetFile", static_cast( - &CIdentFileModule::GetFile)); - AddCommand("SetFile", static_cast( - &CIdentFileModule::SetFile), - ""); - AddCommand("GetFormat", static_cast( - &CIdentFileModule::GetFormat)); - AddCommand("SetFormat", static_cast( - &CIdentFileModule::SetFormat), - ""); - AddCommand("Show", static_cast( - &CIdentFileModule::Show)); + MODCONSTRUCTOR(CIdentFileModule) { + AddHelpCommand(); + AddCommand("GetFile", static_cast( + &CIdentFileModule::GetFile)); + AddCommand("SetFile", static_cast( + &CIdentFileModule::SetFile), + ""); + AddCommand("GetFormat", static_cast( + &CIdentFileModule::GetFormat)); + AddCommand("SetFormat", static_cast( + &CIdentFileModule::SetFormat), + ""); + AddCommand("Show", static_cast( + &CIdentFileModule::Show)); - m_pISpoofLockFile = nullptr; - m_pIRCSock = nullptr; - } + m_pISpoofLockFile = nullptr; + m_pIRCSock = nullptr; + } - virtual ~CIdentFileModule() { ReleaseISpoof(); } + virtual ~CIdentFileModule() { ReleaseISpoof(); } - void GetFile(const CString& sLine) { - PutModule("File is set to: " + GetNV("File")); - } + void GetFile(const CString& sLine) { + PutModule("File is set to: " + GetNV("File")); + } - void SetFile(const CString& sLine) { - SetNV("File", sLine.Token(1, true)); - PutModule("File has been set to: " + GetNV("File")); - } + void SetFile(const CString& sLine) { + SetNV("File", sLine.Token(1, true)); + PutModule("File has been set to: " + GetNV("File")); + } - void SetFormat(const CString& sLine) { - SetNV("Format", sLine.Token(1, true)); - PutModule("Format has been set to: " + GetNV("Format")); - PutModule("Format would be expanded to: " + - ExpandString(GetNV("Format"))); - } + void SetFormat(const CString& sLine) { + SetNV("Format", sLine.Token(1, true)); + PutModule("Format has been set to: " + GetNV("Format")); + PutModule("Format would be expanded to: " + + ExpandString(GetNV("Format"))); + } - void GetFormat(const CString& sLine) { - PutModule("Format is set to: " + GetNV("Format")); - PutModule("Format would be expanded to: " + - ExpandString(GetNV("Format"))); - } + void GetFormat(const CString& sLine) { + PutModule("Format is set to: " + GetNV("Format")); + PutModule("Format would be expanded to: " + + ExpandString(GetNV("Format"))); + } - void Show(const CString& sLine) { - PutModule("m_pISpoofLockFile = " + - CString((long long)m_pISpoofLockFile)); - PutModule("m_pIRCSock = " + CString((long long)m_pIRCSock)); - if (m_pIRCSock) { - PutModule("user/network - " + - m_pIRCSock->GetNetwork()->GetUser()->GetUserName() + "/" + - m_pIRCSock->GetNetwork()->GetName()); - } else { - PutModule("identfile is free"); - } - } + void Show(const CString& sLine) { + PutModule("m_pISpoofLockFile = " + + CString((long long)m_pISpoofLockFile)); + PutModule("m_pIRCSock = " + CString((long long)m_pIRCSock)); + if (m_pIRCSock) { + PutModule("user/network - " + + m_pIRCSock->GetNetwork()->GetUser()->GetUserName() + "/" + + m_pIRCSock->GetNetwork()->GetName()); + } else { + PutModule("identfile is free"); + } + } - void OnModCommand(const CString& sCommand) override { - if (GetUser()->IsAdmin()) { - HandleCommand(sCommand); - } else { - PutModule("Access denied"); - } - } + void OnModCommand(const CString& sCommand) override { + if (GetUser()->IsAdmin()) { + HandleCommand(sCommand); + } else { + PutModule("Access denied"); + } + } - void SetIRCSock(CIRCSock* pIRCSock) { - if (m_pIRCSock) { - CZNC::Get().ResumeConnectQueue(); - } + void SetIRCSock(CIRCSock* pIRCSock) { + if (m_pIRCSock) { + CZNC::Get().ResumeConnectQueue(); + } - m_pIRCSock = pIRCSock; + m_pIRCSock = pIRCSock; - if (m_pIRCSock) { - CZNC::Get().PauseConnectQueue(); - } - } + if (m_pIRCSock) { + CZNC::Get().PauseConnectQueue(); + } + } - bool WriteISpoof() { - if (m_pISpoofLockFile != nullptr) { - return false; - } + bool WriteISpoof() { + if (m_pISpoofLockFile != nullptr) { + return false; + } - m_pISpoofLockFile = new CFile; - if (!m_pISpoofLockFile->TryExLock(GetNV("File"), O_RDWR | O_CREAT)) { - delete m_pISpoofLockFile; - m_pISpoofLockFile = nullptr; - return false; - } + m_pISpoofLockFile = new CFile; + if (!m_pISpoofLockFile->TryExLock(GetNV("File"), O_RDWR | O_CREAT)) { + delete m_pISpoofLockFile; + m_pISpoofLockFile = nullptr; + return false; + } - char buf[1024]; - memset((char*)buf, 0, 1024); - m_pISpoofLockFile->Read(buf, 1024); - m_sOrigISpoof = buf; + char buf[1024]; + memset((char*)buf, 0, 1024); + m_pISpoofLockFile->Read(buf, 1024); + m_sOrigISpoof = buf; - if (!m_pISpoofLockFile->Seek(0) || !m_pISpoofLockFile->Truncate()) { - delete m_pISpoofLockFile; - m_pISpoofLockFile = nullptr; - return false; - } + if (!m_pISpoofLockFile->Seek(0) || !m_pISpoofLockFile->Truncate()) { + delete m_pISpoofLockFile; + m_pISpoofLockFile = nullptr; + return false; + } - CString sData = ExpandString(GetNV("Format")); + CString sData = ExpandString(GetNV("Format")); - // If the format doesn't contain anything expandable, we'll - // assume this is an "old"-style format string. - if (sData == GetNV("Format")) { - sData.Replace("%", GetUser()->GetIdent()); - } + // If the format doesn't contain anything expandable, we'll + // assume this is an "old"-style format string. + if (sData == GetNV("Format")) { + sData.Replace("%", GetUser()->GetIdent()); + } - DEBUG("Writing [" + sData + "] to ident spoof file [" + - m_pISpoofLockFile->GetLongName() + "] for user/network [" + - GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + "]"); + DEBUG("Writing [" + sData + "] to ident spoof file [" + + m_pISpoofLockFile->GetLongName() + "] for user/network [" + + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() + "]"); - m_pISpoofLockFile->Write(sData + "\n"); + m_pISpoofLockFile->Write(sData + "\n"); - return true; - } + return true; + } - void ReleaseISpoof() { - DEBUG("Releasing ident spoof for user/network [" + - (m_pIRCSock - ? m_pIRCSock->GetNetwork()->GetUser()->GetUserName() + "/" + - m_pIRCSock->GetNetwork()->GetName() - : "") + - "]"); + void ReleaseISpoof() { + DEBUG("Releasing ident spoof for user/network [" + + (m_pIRCSock + ? m_pIRCSock->GetNetwork()->GetUser()->GetUserName() + "/" + + m_pIRCSock->GetNetwork()->GetName() + : "") + + "]"); - SetIRCSock(nullptr); + SetIRCSock(nullptr); - if (m_pISpoofLockFile != nullptr) { - if (m_pISpoofLockFile->Seek(0) && m_pISpoofLockFile->Truncate()) { - m_pISpoofLockFile->Write(m_sOrigISpoof); - } + if (m_pISpoofLockFile != nullptr) { + if (m_pISpoofLockFile->Seek(0) && m_pISpoofLockFile->Truncate()) { + m_pISpoofLockFile->Write(m_sOrigISpoof); + } - delete m_pISpoofLockFile; - m_pISpoofLockFile = nullptr; - } - } + delete m_pISpoofLockFile; + m_pISpoofLockFile = nullptr; + } + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_pISpoofLockFile = nullptr; - m_pIRCSock = nullptr; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_pISpoofLockFile = nullptr; + m_pIRCSock = nullptr; - if (GetNV("Format").empty()) { - SetNV("Format", "global { reply \"%ident%\" }"); - } + if (GetNV("Format").empty()) { + SetNV("Format", "global { reply \"%ident%\" }"); + } - if (GetNV("File").empty()) { - SetNV("File", "~/.oidentd.conf"); - } + if (GetNV("File").empty()) { + SetNV("File", "~/.oidentd.conf"); + } - return true; - } + return true; + } - EModRet OnIRCConnecting(CIRCSock* pIRCSock) override { - if (m_pISpoofLockFile != nullptr) { - DEBUG("Aborting connection, ident spoof lock file exists"); - PutModule( - "Aborting connection, another user or network is currently " - "connecting and using the ident spoof file"); - return HALTCORE; - } + EModRet OnIRCConnecting(CIRCSock* pIRCSock) override { + if (m_pISpoofLockFile != nullptr) { + DEBUG("Aborting connection, ident spoof lock file exists"); + PutModule( + "Aborting connection, another user or network is currently " + "connecting and using the ident spoof file"); + return HALTCORE; + } - if (!WriteISpoof()) { - DEBUG("identfile [" + GetNV("File") + "] could not be written"); - PutModule("[" + GetNV("File") + - "] could not be written, retrying..."); - return HALTCORE; - } + if (!WriteISpoof()) { + DEBUG("identfile [" + GetNV("File") + "] could not be written"); + PutModule("[" + GetNV("File") + + "] could not be written, retrying..."); + return HALTCORE; + } - SetIRCSock(pIRCSock); - return CONTINUE; - } + SetIRCSock(pIRCSock); + return CONTINUE; + } - void OnIRCConnected() override { - if (m_pIRCSock == GetNetwork()->GetIRCSock()) { - ReleaseISpoof(); - } - } + void OnIRCConnected() override { + if (m_pIRCSock == GetNetwork()->GetIRCSock()) { + ReleaseISpoof(); + } + } - void OnIRCConnectionError(CIRCSock* pIRCSock) override { - if (m_pIRCSock == pIRCSock) { - ReleaseISpoof(); - } - } + void OnIRCConnectionError(CIRCSock* pIRCSock) override { + if (m_pIRCSock == pIRCSock) { + ReleaseISpoof(); + } + } - void OnIRCDisconnected() override { - if (m_pIRCSock == GetNetwork()->GetIRCSock()) { - ReleaseISpoof(); - } - } + void OnIRCDisconnected() override { + if (m_pIRCSock == GetNetwork()->GetIRCSock()) { + ReleaseISpoof(); + } + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("identfile"); + Info.SetWikiPage("identfile"); } GLOBALMODULEDEFS( diff --git a/modules/imapauth.cpp b/modules/imapauth.cpp index 6e8e2c0d..f37937e4 100644 --- a/modules/imapauth.cpp +++ b/modules/imapauth.cpp @@ -22,150 +22,150 @@ class CIMAPAuthMod; class CIMAPSock : public CSocket { public: - CIMAPSock(CIMAPAuthMod* pModule, std::shared_ptr Auth) - : CSocket((CModule*)pModule), m_spAuth(Auth) { - m_pIMAPMod = pModule; - m_bSentReply = false; - m_bSentLogin = false; - EnableReadLine(); - } + CIMAPSock(CIMAPAuthMod* pModule, std::shared_ptr Auth) + : CSocket((CModule*)pModule), m_spAuth(Auth) { + m_pIMAPMod = pModule; + m_bSentReply = false; + m_bSentLogin = false; + EnableReadLine(); + } - virtual ~CIMAPSock() { - if (!m_bSentReply) { - m_spAuth->RefuseLogin( - "IMAP server is down, please try again later"); - } - } + virtual ~CIMAPSock() { + if (!m_bSentReply) { + m_spAuth->RefuseLogin( + "IMAP server is down, please try again later"); + } + } - void ReadLine(const CString& sLine) override; + void ReadLine(const CString& sLine) override; private: protected: - CIMAPAuthMod* m_pIMAPMod; - bool m_bSentLogin; - bool m_bSentReply; - std::shared_ptr m_spAuth; + CIMAPAuthMod* m_pIMAPMod; + bool m_bSentLogin; + bool m_bSentReply; + std::shared_ptr m_spAuth; }; class CIMAPAuthMod : public CModule { public: - MODCONSTRUCTOR(CIMAPAuthMod) { - m_Cache.SetTTL(60000); - m_sServer = "localhost"; - m_uPort = 143; - m_bSSL = false; - } + MODCONSTRUCTOR(CIMAPAuthMod) { + m_Cache.SetTTL(60000); + m_sServer = "localhost"; + m_uPort = 143; + m_bSSL = false; + } - virtual ~CIMAPAuthMod() {} + virtual ~CIMAPAuthMod() {} - bool OnBoot() override { return true; } + bool OnBoot() override { return true; } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (sArgs.Trim_n().empty()) { - return true; // use defaults - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (sArgs.Trim_n().empty()) { + return true; // use defaults + } - m_sServer = sArgs.Token(0); - CString sPort = sArgs.Token(1); - m_sUserFormat = sArgs.Token(2); + m_sServer = sArgs.Token(0); + CString sPort = sArgs.Token(1); + m_sUserFormat = sArgs.Token(2); - if (sPort.Left(1) == "+") { - m_bSSL = true; - sPort.LeftChomp(); - } + if (sPort.Left(1) == "+") { + m_bSSL = true; + sPort.LeftChomp(); + } - unsigned short uPort = sPort.ToUShort(); + unsigned short uPort = sPort.ToUShort(); - if (uPort) { - m_uPort = uPort; - } + if (uPort) { + m_uPort = uPort; + } - return true; - } + return true; + } - EModRet OnLoginAttempt(std::shared_ptr Auth) override { - CUser* pUser = CZNC::Get().FindUser(Auth->GetUsername()); + EModRet OnLoginAttempt(std::shared_ptr Auth) override { + CUser* pUser = CZNC::Get().FindUser(Auth->GetUsername()); - if (!pUser) { - // @todo Will want to do some sort of && !m_bAllowCreate in the - // future - Auth->RefuseLogin("Invalid User - Halting IMAP Lookup"); - return HALT; - } + if (!pUser) { + // @todo Will want to do some sort of && !m_bAllowCreate in the + // future + Auth->RefuseLogin("Invalid User - Halting IMAP Lookup"); + return HALT; + } - if (pUser && - m_Cache.HasItem(CString(Auth->GetUsername() + ":" + - Auth->GetPassword()).MD5())) { - DEBUG("+++ Found in cache"); - Auth->AcceptLogin(*pUser); - return HALT; - } + if (pUser && + m_Cache.HasItem(CString(Auth->GetUsername() + ":" + + Auth->GetPassword()).MD5())) { + DEBUG("+++ Found in cache"); + Auth->AcceptLogin(*pUser); + return HALT; + } - CIMAPSock* pSock = new CIMAPSock(this, Auth); - pSock->Connect(m_sServer, m_uPort, m_bSSL, 20); + CIMAPSock* pSock = new CIMAPSock(this, Auth); + pSock->Connect(m_sServer, m_uPort, m_bSSL, 20); - return HALT; - } + return HALT; + } - void OnModCommand(const CString& sLine) override {} + void OnModCommand(const CString& sLine) override {} - void CacheLogin(const CString& sLogin) { m_Cache.AddItem(sLogin); } + void CacheLogin(const CString& sLogin) { m_Cache.AddItem(sLogin); } - // Getters - const CString& GetUserFormat() const { return m_sUserFormat; } - // !Getters + // Getters + const CString& GetUserFormat() const { return m_sUserFormat; } + // !Getters private: - // Settings - CString m_sServer; - unsigned short m_uPort; - bool m_bSSL; - CString m_sUserFormat; - // !Settings + // Settings + CString m_sServer; + unsigned short m_uPort; + bool m_bSSL; + CString m_sUserFormat; + // !Settings - TCacheMap m_Cache; + TCacheMap m_Cache; }; void CIMAPSock::ReadLine(const CString& sLine) { - if (!m_bSentLogin) { - CString sUsername = m_spAuth->GetUsername(); - m_bSentLogin = true; + if (!m_bSentLogin) { + CString sUsername = m_spAuth->GetUsername(); + m_bSentLogin = true; - const CString& sFormat = m_pIMAPMod->GetUserFormat(); + const CString& sFormat = m_pIMAPMod->GetUserFormat(); - if (!sFormat.empty()) { - if (sFormat.find('%') != CString::npos) { - sUsername = sFormat.Replace_n("%", sUsername); - } else { - sUsername += sFormat; - } - } + if (!sFormat.empty()) { + if (sFormat.find('%') != CString::npos) { + sUsername = sFormat.Replace_n("%", sUsername); + } else { + sUsername += sFormat; + } + } - Write("AUTH LOGIN " + sUsername + " " + m_spAuth->GetPassword() + - "\r\n"); - } else if (sLine.Left(5) == "AUTH ") { - CUser* pUser = CZNC::Get().FindUser(m_spAuth->GetUsername()); + Write("AUTH LOGIN " + sUsername + " " + m_spAuth->GetPassword() + + "\r\n"); + } else if (sLine.Left(5) == "AUTH ") { + CUser* pUser = CZNC::Get().FindUser(m_spAuth->GetUsername()); - if (pUser && sLine.StartsWith("AUTH OK")) { - m_spAuth->AcceptLogin(*pUser); - // Use MD5 so passes don't sit in memory in plain text - m_pIMAPMod->CacheLogin(CString(m_spAuth->GetUsername() + ":" + - m_spAuth->GetPassword()).MD5()); - DEBUG("+++ Successful IMAP lookup"); - } else { - m_spAuth->RefuseLogin("Invalid Password"); - DEBUG("--- FAILED IMAP lookup"); - } + if (pUser && sLine.StartsWith("AUTH OK")) { + m_spAuth->AcceptLogin(*pUser); + // Use MD5 so passes don't sit in memory in plain text + m_pIMAPMod->CacheLogin(CString(m_spAuth->GetUsername() + ":" + + m_spAuth->GetPassword()).MD5()); + DEBUG("+++ Successful IMAP lookup"); + } else { + m_spAuth->RefuseLogin("Invalid Password"); + DEBUG("--- FAILED IMAP lookup"); + } - m_bSentReply = true; - Close(); - } + m_bSentReply = true; + Close(); + } } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("imapauth"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("[ server [+]port [ UserFormatString ] ]"); + Info.SetWikiPage("imapauth"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("[ server [+]port [ UserFormatString ] ]"); } GLOBALMODULEDEFS(CIMAPAuthMod, "Allow users to authenticate via IMAP.") diff --git a/modules/keepnick.cpp b/modules/keepnick.cpp index e44e8472..296c70fc 100644 --- a/modules/keepnick.cpp +++ b/modules/keepnick.cpp @@ -23,189 +23,189 @@ class CKeepNickMod; class CKeepNickTimer : public CTimer { public: - CKeepNickTimer(CKeepNickMod* pMod); - ~CKeepNickTimer() {} + CKeepNickTimer(CKeepNickMod* pMod); + ~CKeepNickTimer() {} - void RunJob() override; + void RunJob() override; private: - CKeepNickMod* m_pMod; + CKeepNickMod* m_pMod; }; class CKeepNickMod : public CModule { public: - MODCONSTRUCTOR(CKeepNickMod) { - AddHelpCommand(); - AddCommand("Enable", static_cast( - &CKeepNickMod::OnEnableCommand), - "", "Try to get your primary nick"); - AddCommand("Disable", static_cast( - &CKeepNickMod::OnDisableCommand), - "", "No longer trying to get your primary nick"); - AddCommand("State", static_cast( - &CKeepNickMod::OnStateCommand), - "", "Show the current state"); - } + MODCONSTRUCTOR(CKeepNickMod) { + AddHelpCommand(); + AddCommand("Enable", static_cast( + &CKeepNickMod::OnEnableCommand), + "", "Try to get your primary nick"); + AddCommand("Disable", static_cast( + &CKeepNickMod::OnDisableCommand), + "", "No longer trying to get your primary nick"); + AddCommand("State", static_cast( + &CKeepNickMod::OnStateCommand), + "", "Show the current state"); + } - ~CKeepNickMod() {} + ~CKeepNickMod() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_pTimer = nullptr; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_pTimer = nullptr; - // Check if we need to start the timer - if (GetNetwork()->IsIRCConnected()) OnIRCConnected(); + // Check if we need to start the timer + if (GetNetwork()->IsIRCConnected()) OnIRCConnected(); - return true; - } + return true; + } - void KeepNick() { - if (!m_pTimer) - // No timer means we are turned off - return; + void KeepNick() { + if (!m_pTimer) + // No timer means we are turned off + return; - CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); + CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); - if (!pIRCSock) return; + if (!pIRCSock) return; - // Do we already have the nick we want? - if (pIRCSock->GetNick().Equals(GetNick())) return; + // Do we already have the nick we want? + if (pIRCSock->GetNick().Equals(GetNick())) return; - PutIRC("NICK " + GetNick()); - } + PutIRC("NICK " + GetNick()); + } - CString GetNick() { - CString sConfNick = GetNetwork()->GetNick(); - CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); + CString GetNick() { + CString sConfNick = GetNetwork()->GetNick(); + CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); - if (pIRCSock) sConfNick = sConfNick.Left(pIRCSock->GetMaxNickLen()); + if (pIRCSock) sConfNick = sConfNick.Left(pIRCSock->GetMaxNickLen()); - return sConfNick; - } + return sConfNick; + } - void OnNick(const CNick& Nick, const CString& sNewNick, - const vector& vChans) override { - if (sNewNick == GetNetwork()->GetIRCSock()->GetNick()) { - // We are changing our own nick - if (Nick.NickEquals(GetNick())) { - // We are changing our nick away from the conf setting. - // Let's assume the user wants this and disable - // this module (to avoid fighting nickserv). - Disable(); - } else if (sNewNick.Equals(GetNick())) { - // We are changing our nick to the conf setting, - // so we don't need that timer anymore. - Disable(); - } - return; - } + void OnNick(const CNick& Nick, const CString& sNewNick, + const vector& vChans) override { + if (sNewNick == GetNetwork()->GetIRCSock()->GetNick()) { + // We are changing our own nick + if (Nick.NickEquals(GetNick())) { + // We are changing our nick away from the conf setting. + // Let's assume the user wants this and disable + // this module (to avoid fighting nickserv). + Disable(); + } else if (sNewNick.Equals(GetNick())) { + // We are changing our nick to the conf setting, + // so we don't need that timer anymore. + Disable(); + } + return; + } - // If the nick we want is free now, be fast and get the nick - if (Nick.NickEquals(GetNick())) { - KeepNick(); - } - } + // If the nick we want is free now, be fast and get the nick + if (Nick.NickEquals(GetNick())) { + KeepNick(); + } + } - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override { - // If someone with the nick we want quits, be fast and get the nick - if (Nick.NickEquals(GetNick())) { - KeepNick(); - } - } + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override { + // If someone with the nick we want quits, be fast and get the nick + if (Nick.NickEquals(GetNick())) { + KeepNick(); + } + } - void OnIRCDisconnected() override { - // No way we can do something if we aren't connected to IRC. - Disable(); - } + void OnIRCDisconnected() override { + // No way we can do something if we aren't connected to IRC. + Disable(); + } - void OnIRCConnected() override { - if (!GetNetwork()->GetIRCSock()->GetNick().Equals(GetNick())) { - // We don't have the nick we want, try to get it - Enable(); - } - } + void OnIRCConnected() override { + if (!GetNetwork()->GetIRCSock()->GetNick().Equals(GetNick())) { + // We don't have the nick we want, try to get it + Enable(); + } + } - void Enable() { - if (m_pTimer) return; + void Enable() { + if (m_pTimer) return; - m_pTimer = new CKeepNickTimer(this); - AddTimer(m_pTimer); - } + m_pTimer = new CKeepNickTimer(this); + AddTimer(m_pTimer); + } - void Disable() { - if (!m_pTimer) return; + void Disable() { + if (!m_pTimer) return; - m_pTimer->Stop(); - RemTimer(m_pTimer); - m_pTimer = nullptr; - } + m_pTimer->Stop(); + RemTimer(m_pTimer); + m_pTimer = nullptr; + } - EModRet OnUserRaw(CString& sLine) override { - // We dont care if we are not connected to IRC - if (!GetNetwork()->IsIRCConnected()) return CONTINUE; + EModRet OnUserRaw(CString& sLine) override { + // We dont care if we are not connected to IRC + if (!GetNetwork()->IsIRCConnected()) return CONTINUE; - // We are trying to get the config nick and this is a /nick? - if (!m_pTimer || !sLine.Token(0).Equals("NICK")) return CONTINUE; + // We are trying to get the config nick and this is a /nick? + if (!m_pTimer || !sLine.Token(0).Equals("NICK")) return CONTINUE; - // Is the nick change for the nick we are trying to get? - CString sNick = sLine.Token(1); + // Is the nick change for the nick we are trying to get? + CString sNick = sLine.Token(1); - // Don't even think of using spaces in your nick! - if (sNick.Left(1) == ":") sNick.LeftChomp(); + // Don't even think of using spaces in your nick! + if (sNick.Left(1) == ":") sNick.LeftChomp(); - if (!sNick.Equals(GetNick())) return CONTINUE; + if (!sNick.Equals(GetNick())) return CONTINUE; - // Indeed trying to change to this nick, generate a 433 for it. - // This way we can *always* block incoming 433s from the server. - PutUser(":" + GetNetwork()->GetIRCServer() + " 433 " + - GetNetwork()->GetIRCNick().GetNick() + " " + sNick + - " :ZNC is already trying to get this nickname"); - return CONTINUE; - } + // Indeed trying to change to this nick, generate a 433 for it. + // This way we can *always* block incoming 433s from the server. + PutUser(":" + GetNetwork()->GetIRCServer() + " 433 " + + GetNetwork()->GetIRCNick().GetNick() + " " + sNick + + " :ZNC is already trying to get this nickname"); + return CONTINUE; + } - EModRet OnRaw(CString& sLine) override { - // Are we trying to get our primary nick and we caused this error? - // :irc.server.net 433 mynick badnick :Nickname is already in use. - if (m_pTimer && sLine.Token(1) == "433" && - sLine.Token(3).Equals(GetNick())) - return HALT; + EModRet OnRaw(CString& sLine) override { + // Are we trying to get our primary nick and we caused this error? + // :irc.server.net 433 mynick badnick :Nickname is already in use. + if (m_pTimer && sLine.Token(1) == "433" && + sLine.Token(3).Equals(GetNick())) + return HALT; - return CONTINUE; - } + return CONTINUE; + } - void OnEnableCommand(const CString& sCommand) { - Enable(); - PutModule("Trying to get your primary nick"); - } + void OnEnableCommand(const CString& sCommand) { + Enable(); + PutModule("Trying to get your primary nick"); + } - void OnDisableCommand(const CString& sCommand) { - Disable(); - PutModule("No longer trying to get your primary nick"); - } + void OnDisableCommand(const CString& sCommand) { + Disable(); + PutModule("No longer trying to get your primary nick"); + } - void OnStateCommand(const CString& sCommand) { - if (m_pTimer) - PutModule("Currently trying to get your primary nick"); - else - PutModule("Currently disabled, try 'enable'"); - } + void OnStateCommand(const CString& sCommand) { + if (m_pTimer) + PutModule("Currently trying to get your primary nick"); + else + PutModule("Currently disabled, try 'enable'"); + } private: - // If this is nullptr, we are turned off for some reason - CKeepNickTimer* m_pTimer = nullptr; + // If this is nullptr, we are turned off for some reason + CKeepNickTimer* m_pTimer = nullptr; }; CKeepNickTimer::CKeepNickTimer(CKeepNickMod* pMod) : CTimer(pMod, 30, 0, "KeepNickTimer", "Tries to acquire this user's primary nick") { - m_pMod = pMod; + m_pMod = pMod; } void CKeepNickTimer::RunJob() { m_pMod->KeepNick(); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("keepnick"); + Info.SetWikiPage("keepnick"); } NETWORKMODULEDEFS(CKeepNickMod, "Keep trying for your primary nick") diff --git a/modules/kickrejoin.cpp b/modules/kickrejoin.cpp index 2a074236..0b07f524 100644 --- a/modules/kickrejoin.cpp +++ b/modules/kickrejoin.cpp @@ -27,109 +27,109 @@ class CRejoinJob : public CTimer { public: - CRejoinJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + CRejoinJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CRejoinJob() {} + virtual ~CRejoinJob() {} protected: - void RunJob() override { - CIRCNetwork* pNetwork = GetModule()->GetNetwork(); - CChan* pChan = pNetwork->FindChan(GetName().Token(1, true)); + void RunJob() override { + CIRCNetwork* pNetwork = GetModule()->GetNetwork(); + CChan* pChan = pNetwork->FindChan(GetName().Token(1, true)); - if (pChan) { - pChan->Enable(); - GetModule()->PutIRC("JOIN " + pChan->GetName() + " " + - pChan->GetKey()); - } - } + if (pChan) { + pChan->Enable(); + GetModule()->PutIRC("JOIN " + pChan->GetName() + " " + + pChan->GetKey()); + } + } }; class CRejoinMod : public CModule { private: - unsigned int delay = 10; + unsigned int delay = 10; public: - MODCONSTRUCTOR(CRejoinMod) { - AddHelpCommand(); - AddCommand("SetDelay", static_cast( - &CRejoinMod::OnSetDelayCommand), - "", "Set the rejoin delay"); - AddCommand("ShowDelay", static_cast( - &CRejoinMod::OnShowDelayCommand), - "", "Show the rejoin delay"); - } - virtual ~CRejoinMod() {} + MODCONSTRUCTOR(CRejoinMod) { + AddHelpCommand(); + AddCommand("SetDelay", static_cast( + &CRejoinMod::OnSetDelayCommand), + "", "Set the rejoin delay"); + AddCommand("ShowDelay", static_cast( + &CRejoinMod::OnShowDelayCommand), + "", "Show the rejoin delay"); + } + virtual ~CRejoinMod() {} - bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { - if (sArgs.empty()) { - CString sDelay = GetNV("delay"); + bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { + if (sArgs.empty()) { + CString sDelay = GetNV("delay"); - if (sDelay.empty()) - delay = 10; - else - delay = sDelay.ToUInt(); - } else { - int i = sArgs.ToInt(); - if ((i == 0 && sArgs == "0") || i > 0) - delay = i; - else { - sErrorMsg = - "Illegal argument, " - "must be a positive number or 0"; - return false; - } - } + if (sDelay.empty()) + delay = 10; + else + delay = sDelay.ToUInt(); + } else { + int i = sArgs.ToInt(); + if ((i == 0 && sArgs == "0") || i > 0) + delay = i; + else { + sErrorMsg = + "Illegal argument, " + "must be a positive number or 0"; + return false; + } + } - return true; - } + return true; + } - void OnSetDelayCommand(const CString& sCommand) { - int i; - i = sCommand.Token(1).ToInt(); + void OnSetDelayCommand(const CString& sCommand) { + int i; + i = sCommand.Token(1).ToInt(); - if (i < 0) { - PutModule("Negative delays don't make any sense!"); - return; - } + if (i < 0) { + PutModule("Negative delays don't make any sense!"); + return; + } - delay = i; - SetNV("delay", CString(delay)); + delay = i; + SetNV("delay", CString(delay)); - if (delay) - PutModule("Rejoin delay set to " + CString(delay) + " seconds"); - else - PutModule("Rejoin delay disabled"); - } + if (delay) + PutModule("Rejoin delay set to " + CString(delay) + " seconds"); + else + PutModule("Rejoin delay disabled"); + } - void OnShowDelayCommand(const CString& sCommand) { - if (delay) - PutModule("Rejoin delay enabled, " + CString(delay) + " seconds"); - else - PutModule("Rejoin delay disabled"); - } + void OnShowDelayCommand(const CString& sCommand) { + if (delay) + PutModule("Rejoin delay enabled, " + CString(delay) + " seconds"); + else + PutModule("Rejoin delay disabled"); + } - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& pChan, - const CString& sMessage) override { - if (GetNetwork()->GetCurNick().Equals(sKickedNick)) { - if (!delay) { - PutIRC("JOIN " + pChan.GetName() + " " + pChan.GetKey()); - pChan.Enable(); - return; - } - AddTimer(new CRejoinJob(this, delay, 1, "Rejoin " + pChan.GetName(), - "Rejoin channel after a delay")); - } - } + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& pChan, + const CString& sMessage) override { + if (GetNetwork()->GetCurNick().Equals(sKickedNick)) { + if (!delay) { + PutIRC("JOIN " + pChan.GetName() + " " + pChan.GetKey()); + pChan.Enable(); + return; + } + AddTimer(new CRejoinJob(this, delay, 1, "Rejoin " + pChan.GetName(), + "Rejoin channel after a delay")); + } + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("kickrejoin"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "You might enter the number of seconds to wait before rejoining."); + Info.SetWikiPage("kickrejoin"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "You might enter the number of seconds to wait before rejoining."); } NETWORKMODULEDEFS(CRejoinMod, "Autorejoin on kick") diff --git a/modules/lastseen.cpp b/modules/lastseen.cpp index 1e8a429d..e6d155e2 100644 --- a/modules/lastseen.cpp +++ b/modules/lastseen.cpp @@ -24,127 +24,127 @@ using std::multimap; class CLastSeenMod : public CModule { private: - time_t GetTime(const CUser* pUser) { - return GetNV(pUser->GetUserName()).ToULong(); - } + time_t GetTime(const CUser* pUser) { + return GetNV(pUser->GetUserName()).ToULong(); + } - void SetTime(const CUser* pUser) { - SetNV(pUser->GetUserName(), CString(time(nullptr))); - } + void SetTime(const CUser* pUser) { + SetNV(pUser->GetUserName(), CString(time(nullptr))); + } - const CString FormatLastSeen(const CUser* pUser, - const char* sDefault = "") { - time_t last = GetTime(pUser); - if (last < 1) { - return sDefault; - } else { - char buf[1024]; - strftime(buf, sizeof(buf) - 1, "%c", localtime(&last)); - return buf; - } - } + const CString FormatLastSeen(const CUser* pUser, + const char* sDefault = "") { + time_t last = GetTime(pUser); + if (last < 1) { + return sDefault; + } else { + char buf[1024]; + strftime(buf, sizeof(buf) - 1, "%c", localtime(&last)); + return buf; + } + } - typedef multimap MTimeMulti; - typedef map MUsers; + typedef multimap MTimeMulti; + typedef map MUsers; - void ShowCommand(const CString& sLine) { - if (!GetUser()->IsAdmin()) { - PutModule("Access denied"); - return; - } + void ShowCommand(const CString& sLine) { + if (!GetUser()->IsAdmin()) { + PutModule("Access denied"); + return; + } - const MUsers& mUsers = CZNC::Get().GetUserMap(); - MUsers::const_iterator it; - CTable Table; + const MUsers& mUsers = CZNC::Get().GetUserMap(); + MUsers::const_iterator it; + CTable Table; - Table.AddColumn("User"); - Table.AddColumn("Last Seen"); + Table.AddColumn("User"); + Table.AddColumn("Last Seen"); - for (it = mUsers.begin(); it != mUsers.end(); ++it) { - Table.AddRow(); - Table.SetCell("User", it->first); - Table.SetCell("Last Seen", FormatLastSeen(it->second, "never")); - } + for (it = mUsers.begin(); it != mUsers.end(); ++it) { + Table.AddRow(); + Table.SetCell("User", it->first); + Table.SetCell("Last Seen", FormatLastSeen(it->second, "never")); + } - PutModule(Table); - } + PutModule(Table); + } public: - MODCONSTRUCTOR(CLastSeenMod) { - AddHelpCommand(); - AddCommand("Show", static_cast( - &CLastSeenMod::ShowCommand), - "", "Shows list of users and when they last logged in"); - } + MODCONSTRUCTOR(CLastSeenMod) { + AddHelpCommand(); + AddCommand("Show", static_cast( + &CLastSeenMod::ShowCommand), + "", "Shows list of users and when they last logged in"); + } - virtual ~CLastSeenMod() {} + virtual ~CLastSeenMod() {} - // Event stuff: + // Event stuff: - void OnClientLogin() override { SetTime(GetUser()); } + void OnClientLogin() override { SetTime(GetUser()); } - void OnClientDisconnect() override { SetTime(GetUser()); } + void OnClientDisconnect() override { SetTime(GetUser()); } - EModRet OnDeleteUser(CUser& User) override { - DelNV(User.GetUserName()); - return CONTINUE; - } + EModRet OnDeleteUser(CUser& User) override { + DelNV(User.GetUserName()); + return CONTINUE; + } - // Web stuff: + // Web stuff: - bool WebRequiresAdmin() override { return true; } - CString GetWebMenuTitle() override { return "Last Seen"; } + bool WebRequiresAdmin() override { return true; } + CString GetWebMenuTitle() override { return "Last Seen"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - CModules& GModules = CZNC::Get().GetModules(); - Tmpl["WebAdminLoaded"] = - CString(GModules.FindModule("webadmin") != nullptr); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + CModules& GModules = CZNC::Get().GetModules(); + Tmpl["WebAdminLoaded"] = + CString(GModules.FindModule("webadmin") != nullptr); - MTimeMulti mmSorted; - const MUsers& mUsers = CZNC::Get().GetUserMap(); + MTimeMulti mmSorted; + const MUsers& mUsers = CZNC::Get().GetUserMap(); - for (MUsers::const_iterator uit = mUsers.begin(); - uit != mUsers.end(); ++uit) { - mmSorted.insert( - pair(GetTime(uit->second), uit->second)); - } + for (MUsers::const_iterator uit = mUsers.begin(); + uit != mUsers.end(); ++uit) { + mmSorted.insert( + pair(GetTime(uit->second), uit->second)); + } - for (MTimeMulti::const_iterator it = mmSorted.begin(); - it != mmSorted.end(); ++it) { - CUser* pUser = it->second; - CTemplate& Row = Tmpl.AddRow("UserLoop"); + for (MTimeMulti::const_iterator it = mmSorted.begin(); + it != mmSorted.end(); ++it) { + CUser* pUser = it->second; + CTemplate& Row = Tmpl.AddRow("UserLoop"); - Row["Username"] = pUser->GetUserName(); - Row["IsSelf"] = - CString(pUser == WebSock.GetSession()->GetUser()); - Row["LastSeen"] = FormatLastSeen(pUser, "never"); - } + Row["Username"] = pUser->GetUserName(); + Row["IsSelf"] = + CString(pUser == WebSock.GetSession()->GetUser()); + Row["LastSeen"] = FormatLastSeen(pUser, "never"); + } - return true; - } + return true; + } - return false; - } + return false; + } - bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "webadmin/user" && WebSock.GetSession()->IsAdmin()) { - CUser* pUser = CZNC::Get().FindUser(Tmpl["Username"]); - if (pUser) { - Tmpl["LastSeen"] = FormatLastSeen(pUser); - } - return true; - } + bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "webadmin/user" && WebSock.GetSession()->IsAdmin()) { + CUser* pUser = CZNC::Get().FindUser(Tmpl["Username"]); + if (pUser) { + Tmpl["LastSeen"] = FormatLastSeen(pUser); + } + return true; + } - return false; - } + return false; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("lastseen"); + Info.SetWikiPage("lastseen"); } GLOBALMODULEDEFS(CLastSeenMod, diff --git a/modules/listsockets.cpp b/modules/listsockets.cpp index 5253d759..cc538047 100644 --- a/modules/listsockets.cpp +++ b/modules/listsockets.cpp @@ -19,238 +19,238 @@ class CSocketSorter { public: - CSocketSorter(Csock* p) { m_pSock = p; } - bool operator<(const CSocketSorter& other) const { - // The 'biggest' item is displayed first. - // return false: this is first - // return true: other is first + CSocketSorter(Csock* p) { m_pSock = p; } + bool operator<(const CSocketSorter& other) const { + // The 'biggest' item is displayed first. + // return false: this is first + // return true: other is first - // Listeners go to the top - if (m_pSock->GetType() != other.m_pSock->GetType()) { - if (m_pSock->GetType() == Csock::LISTENER) return false; - if (other.m_pSock->GetType() == Csock::LISTENER) return true; - } - const CString& sMyName = m_pSock->GetSockName(); - const CString& sMyName2 = sMyName.Token(1, true, "::"); - bool bMyEmpty = sMyName2.empty(); - const CString& sHisName = other.GetSock()->GetSockName(); - const CString& sHisName2 = sHisName.Token(1, true, "::"); - bool bHisEmpty = sHisName2.empty(); + // Listeners go to the top + if (m_pSock->GetType() != other.m_pSock->GetType()) { + if (m_pSock->GetType() == Csock::LISTENER) return false; + if (other.m_pSock->GetType() == Csock::LISTENER) return true; + } + const CString& sMyName = m_pSock->GetSockName(); + const CString& sMyName2 = sMyName.Token(1, true, "::"); + bool bMyEmpty = sMyName2.empty(); + const CString& sHisName = other.GetSock()->GetSockName(); + const CString& sHisName2 = sHisName.Token(1, true, "::"); + bool bHisEmpty = sHisName2.empty(); - // Then sort by first token after "::" - if (bMyEmpty && !bHisEmpty) return false; - if (bHisEmpty && !bMyEmpty) return true; + // Then sort by first token after "::" + if (bMyEmpty && !bHisEmpty) return false; + if (bHisEmpty && !bMyEmpty) return true; - if (!bMyEmpty && !bHisEmpty) { - int c = sMyName2.StrCmp(sHisName2); - if (c < 0) return false; - if (c > 0) return true; - } - // and finally sort by the whole socket name - return sMyName.StrCmp(sHisName) > 0; - } - Csock* GetSock() const { return m_pSock; } + if (!bMyEmpty && !bHisEmpty) { + int c = sMyName2.StrCmp(sHisName2); + if (c < 0) return false; + if (c > 0) return true; + } + // and finally sort by the whole socket name + return sMyName.StrCmp(sHisName) > 0; + } + Csock* GetSock() const { return m_pSock; } private: - Csock* m_pSock; + Csock* m_pSock; }; class CListSockets : public CModule { public: - MODCONSTRUCTOR(CListSockets) { - AddHelpCommand(); - AddCommand( - "List", - static_cast(&CListSockets::OnListCommand), - "[-n]", - "Show the list of active sockets. Pass -n to show IP addresses"); - } + MODCONSTRUCTOR(CListSockets) { + AddHelpCommand(); + AddCommand( + "List", + static_cast(&CListSockets::OnListCommand), + "[-n]", + "Show the list of active sockets. Pass -n to show IP addresses"); + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { + bool OnLoad(const CString& sArgs, CString& sMessage) override { #ifndef MOD_LISTSOCKETS_ALLOW_EVERYONE - if (!GetUser()->IsAdmin()) { - sMessage = "You must be admin to use this module"; - return false; - } + if (!GetUser()->IsAdmin()) { + sMessage = "You must be admin to use this module"; + return false; + } #endif - return true; - } + return true; + } - std::priority_queue GetSockets() { - CSockManager& m = CZNC::Get().GetManager(); - std::priority_queue ret; + std::priority_queue GetSockets() { + CSockManager& m = CZNC::Get().GetManager(); + std::priority_queue ret; - for (unsigned int a = 0; a < m.size(); a++) { - Csock* pSock = m[a]; - // These sockets went through SwapSockByAddr. That means - // another socket took over the connection from this - // socket. So ignore this to avoid listing the - // connection twice. - if (pSock->GetCloseType() == Csock::CLT_DEREFERENCE) continue; - ret.push(pSock); - } + for (unsigned int a = 0; a < m.size(); a++) { + Csock* pSock = m[a]; + // These sockets went through SwapSockByAddr. That means + // another socket took over the connection from this + // socket. So ignore this to avoid listing the + // connection twice. + if (pSock->GetCloseType() == Csock::CLT_DEREFERENCE) continue; + ret.push(pSock); + } - return ret; - } + return ret; + } - bool WebRequiresAdmin() override { return true; } - CString GetWebMenuTitle() override { return "List sockets"; } + bool WebRequiresAdmin() override { return true; } + CString GetWebMenuTitle() override { return "List sockets"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - if (CZNC::Get().GetManager().empty()) { - return false; - } + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + if (CZNC::Get().GetManager().empty()) { + return false; + } - std::priority_queue socks = GetSockets(); + std::priority_queue socks = GetSockets(); - while (!socks.empty()) { - Csock* pSocket = socks.top().GetSock(); - socks.pop(); + while (!socks.empty()) { + Csock* pSocket = socks.top().GetSock(); + socks.pop(); - CTemplate& Row = Tmpl.AddRow("SocketsLoop"); - Row["Name"] = pSocket->GetSockName(); - Row["Created"] = GetCreatedTime(pSocket); - Row["State"] = GetSocketState(pSocket); - Row["SSL"] = pSocket->GetSSL() ? "Yes" : "No"; - Row["Local"] = GetLocalHost(pSocket, true); - Row["Remote"] = GetRemoteHost(pSocket, true); - Row["In"] = CString::ToByteStr(pSocket->GetBytesRead()); - Row["Out"] = CString::ToByteStr(pSocket->GetBytesWritten()); - } + CTemplate& Row = Tmpl.AddRow("SocketsLoop"); + Row["Name"] = pSocket->GetSockName(); + Row["Created"] = GetCreatedTime(pSocket); + Row["State"] = GetSocketState(pSocket); + Row["SSL"] = pSocket->GetSSL() ? "Yes" : "No"; + Row["Local"] = GetLocalHost(pSocket, true); + Row["Remote"] = GetRemoteHost(pSocket, true); + Row["In"] = CString::ToByteStr(pSocket->GetBytesRead()); + Row["Out"] = CString::ToByteStr(pSocket->GetBytesWritten()); + } - return true; - } + return true; + } - return false; - } + return false; + } - void OnListCommand(const CString& sLine) { - CString sArg = sLine.Token(1, true); + void OnListCommand(const CString& sLine) { + CString sArg = sLine.Token(1, true); - bool bShowHosts = true; - if (sArg.Equals("-n")) { - bShowHosts = false; - } - ShowSocks(bShowHosts); - } + bool bShowHosts = true; + if (sArg.Equals("-n")) { + bShowHosts = false; + } + ShowSocks(bShowHosts); + } - CString GetSocketState(Csock* pSocket) { - switch (pSocket->GetType()) { - case Csock::LISTENER: - return "Listener"; - case Csock::INBOUND: - return "Inbound"; - case Csock::OUTBOUND: - if (pSocket->IsConnected()) - return "Outbound"; - else - return "Connecting"; - } + CString GetSocketState(Csock* pSocket) { + switch (pSocket->GetType()) { + case Csock::LISTENER: + return "Listener"; + case Csock::INBOUND: + return "Inbound"; + case Csock::OUTBOUND: + if (pSocket->IsConnected()) + return "Outbound"; + else + return "Connecting"; + } - return "UNKNOWN"; - } + return "UNKNOWN"; + } - CString GetCreatedTime(Csock* pSocket) { - unsigned long long iStartTime = pSocket->GetStartTime(); - time_t iTime = iStartTime / 1000; - return CUtils::FormatTime(iTime, "%Y-%m-%d %H:%M:%S", - GetUser()->GetTimezone()); - } + CString GetCreatedTime(Csock* pSocket) { + unsigned long long iStartTime = pSocket->GetStartTime(); + time_t iTime = iStartTime / 1000; + return CUtils::FormatTime(iTime, "%Y-%m-%d %H:%M:%S", + GetUser()->GetTimezone()); + } - CString GetLocalHost(Csock* pSocket, bool bShowHosts) { - CString sBindHost; + CString GetLocalHost(Csock* pSocket, bool bShowHosts) { + CString sBindHost; - if (bShowHosts) { - sBindHost = pSocket->GetBindHost(); - } + if (bShowHosts) { + sBindHost = pSocket->GetBindHost(); + } - if (sBindHost.empty()) { - sBindHost = pSocket->GetLocalIP(); - } + if (sBindHost.empty()) { + sBindHost = pSocket->GetLocalIP(); + } - return sBindHost + " " + CString(pSocket->GetLocalPort()); - } + return sBindHost + " " + CString(pSocket->GetLocalPort()); + } - CString GetRemoteHost(Csock* pSocket, bool bShowHosts) { - CString sHost; - u_short uPort; + CString GetRemoteHost(Csock* pSocket, bool bShowHosts) { + CString sHost; + u_short uPort; - if (!bShowHosts) { - sHost = pSocket->GetRemoteIP(); - } + if (!bShowHosts) { + sHost = pSocket->GetRemoteIP(); + } - // While connecting, there might be no ip available - if (sHost.empty()) { - sHost = pSocket->GetHostName(); - } + // While connecting, there might be no ip available + if (sHost.empty()) { + sHost = pSocket->GetHostName(); + } - // While connecting, GetRemotePort() would return 0 - if (pSocket->GetType() == Csock::OUTBOUND) { - uPort = pSocket->GetPort(); - } else { - uPort = pSocket->GetRemotePort(); - } + // While connecting, GetRemotePort() would return 0 + if (pSocket->GetType() == Csock::OUTBOUND) { + uPort = pSocket->GetPort(); + } else { + uPort = pSocket->GetRemotePort(); + } - if (uPort != 0) { - return sHost + " " + CString(uPort); - } + if (uPort != 0) { + return sHost + " " + CString(uPort); + } - return sHost; - } + return sHost; + } - void ShowSocks(bool bShowHosts) { - if (CZNC::Get().GetManager().empty()) { - PutStatus("You have no open sockets."); - return; - } + void ShowSocks(bool bShowHosts) { + if (CZNC::Get().GetManager().empty()) { + PutStatus("You have no open sockets."); + return; + } - std::priority_queue socks = GetSockets(); + std::priority_queue socks = GetSockets(); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Created"); - Table.AddColumn("State"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Created"); + Table.AddColumn("State"); #ifdef HAVE_LIBSSL - Table.AddColumn("SSL"); + Table.AddColumn("SSL"); #endif - Table.AddColumn("Local"); - Table.AddColumn("Remote"); - Table.AddColumn("In"); - Table.AddColumn("Out"); + Table.AddColumn("Local"); + Table.AddColumn("Remote"); + Table.AddColumn("In"); + Table.AddColumn("Out"); - while (!socks.empty()) { - Csock* pSocket = socks.top().GetSock(); - socks.pop(); + while (!socks.empty()) { + Csock* pSocket = socks.top().GetSock(); + socks.pop(); - Table.AddRow(); - Table.SetCell("Name", pSocket->GetSockName()); - Table.SetCell("Created", GetCreatedTime(pSocket)); - Table.SetCell("State", GetSocketState(pSocket)); + Table.AddRow(); + Table.SetCell("Name", pSocket->GetSockName()); + Table.SetCell("Created", GetCreatedTime(pSocket)); + Table.SetCell("State", GetSocketState(pSocket)); #ifdef HAVE_LIBSSL - Table.SetCell("SSL", pSocket->GetSSL() ? "Yes" : "No"); + Table.SetCell("SSL", pSocket->GetSSL() ? "Yes" : "No"); #endif - Table.SetCell("Local", GetLocalHost(pSocket, bShowHosts)); - Table.SetCell("Remote", GetRemoteHost(pSocket, bShowHosts)); - Table.SetCell("In", CString::ToByteStr(pSocket->GetBytesRead())); - Table.SetCell("Out", - CString::ToByteStr(pSocket->GetBytesWritten())); - } + Table.SetCell("Local", GetLocalHost(pSocket, bShowHosts)); + Table.SetCell("Remote", GetRemoteHost(pSocket, bShowHosts)); + Table.SetCell("In", CString::ToByteStr(pSocket->GetBytesRead())); + Table.SetCell("Out", + CString::ToByteStr(pSocket->GetBytesWritten())); + } - PutModule(Table); - return; - } + PutModule(Table); + return; + } - virtual ~CListSockets() {} + virtual ~CListSockets() {} }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("listsockets"); + Info.SetWikiPage("listsockets"); } USERMODULEDEFS(CListSockets, "List active sockets") diff --git a/modules/log.cpp b/modules/log.cpp index 1c67bf4d..3c067773 100644 --- a/modules/log.cpp +++ b/modules/log.cpp @@ -28,477 +28,477 @@ using std::vector; class CLogRule { public: - CLogRule(const CString& sRule, bool bEnabled = true) - : m_sRule(sRule), m_bEnabled(bEnabled) {} + CLogRule(const CString& sRule, bool bEnabled = true) + : m_sRule(sRule), m_bEnabled(bEnabled) {} - const CString& GetRule() const { return m_sRule; } - bool IsEnabled() const { return m_bEnabled; } - void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; } + const CString& GetRule() const { return m_sRule; } + bool IsEnabled() const { return m_bEnabled; } + void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; } - bool Compare(const CString& sTarget) const { - return sTarget.WildCmp(m_sRule, CString::CaseInsensitive); - } + bool Compare(const CString& sTarget) const { + return sTarget.WildCmp(m_sRule, CString::CaseInsensitive); + } - bool operator==(const CLogRule& sOther) const { - return m_sRule == sOther.GetRule(); - } + bool operator==(const CLogRule& sOther) const { + return m_sRule == sOther.GetRule(); + } - CString ToString() const { return (m_bEnabled ? "" : "!") + m_sRule; } + CString ToString() const { return (m_bEnabled ? "" : "!") + m_sRule; } private: - CString m_sRule; - bool m_bEnabled; + CString m_sRule; + bool m_bEnabled; }; class CLogMod : public CModule { - void Set(const CString& sLine) { - const CString sVar = sLine.Token(1).AsLower(); - bool b = sLine.Token(2).ToBool(); + void Set(const CString& sLine) { + const CString sVar = sLine.Token(1).AsLower(); + bool b = sLine.Token(2).ToBool(); - if (sVar == "joins" || sVar == "quits" || sVar == "nickchanges") { - SetNV(sVar, CString(b)); - PutModule("Set " + sVar + " to " + CString(b)); - } else - PutModule(sVar + " is invalid."); - } + if (sVar == "joins" || sVar == "quits" || sVar == "nickchanges") { + SetNV(sVar, CString(b)); + PutModule("Set " + sVar + " to " + CString(b)); + } else + PutModule(sVar + " is invalid."); + } public: - MODCONSTRUCTOR(CLogMod) { - m_bSanitize = false; - AddHelpCommand(); - AddCommand("SetRules", - static_cast(&CLogMod::SetRulesCmd), - "", - "Set logging rules, use !#chan or !query to negate and * " - "for wildcards"); - AddCommand("ClearRules", static_cast( - &CLogMod::ClearRulesCmd), - "", "Clear all logging rules"); - AddCommand("ListRules", - static_cast(&CLogMod::ListRulesCmd), - "", "List all logging rules"); - AddCommand( - "Set", static_cast(&CLogMod::Set), - "boolean", - "Set one of the following booleans, joins, quits, nickchanges"); - } + MODCONSTRUCTOR(CLogMod) { + m_bSanitize = false; + AddHelpCommand(); + AddCommand("SetRules", + static_cast(&CLogMod::SetRulesCmd), + "", + "Set logging rules, use !#chan or !query to negate and * " + "for wildcards"); + AddCommand("ClearRules", static_cast( + &CLogMod::ClearRulesCmd), + "", "Clear all logging rules"); + AddCommand("ListRules", + static_cast(&CLogMod::ListRulesCmd), + "", "List all logging rules"); + AddCommand( + "Set", static_cast(&CLogMod::Set), + "boolean", + "Set one of the following booleans, joins, quits, nickchanges"); + } - void SetRulesCmd(const CString& sLine); - void ClearRulesCmd(const CString& sLine); - void ListRulesCmd(const CString& sLine = ""); - void SetRules(const VCString& vsRules); - VCString SplitRules(const CString& sRules) const; - CString JoinRules(const CString& sSeparator) const; - bool TestRules(const CString& sTarget) const; + void SetRulesCmd(const CString& sLine); + void ClearRulesCmd(const CString& sLine); + void ListRulesCmd(const CString& sLine = ""); + void SetRules(const VCString& vsRules); + VCString SplitRules(const CString& sRules) const; + CString JoinRules(const CString& sSeparator) const; + bool TestRules(const CString& sTarget) const; - void PutLog(const CString& sLine, const CString& sWindow = "status"); - void PutLog(const CString& sLine, const CChan& Channel); - void PutLog(const CString& sLine, const CNick& Nick); - CString GetServer(); + void PutLog(const CString& sLine, const CString& sWindow = "status"); + void PutLog(const CString& sLine, const CChan& Channel); + void PutLog(const CString& sLine, const CNick& Nick); + CString GetServer(); - bool OnLoad(const CString& sArgs, CString& sMessage) override; - void OnIRCConnected() override; - void OnIRCDisconnected() override; - EModRet OnBroadcast(CString& sMessage) override; + bool OnLoad(const CString& sArgs, CString& sMessage) override; + void OnIRCConnected() override; + void OnIRCDisconnected() override; + EModRet OnBroadcast(CString& sMessage) override; - void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override; - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override; - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override; - void OnJoin(const CNick& Nick, CChan& Channel) override; - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override; - void OnNick(const CNick& OldNick, const CString& sNewNick, - const vector& vChans) override; - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; + void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override; + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override; + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override; + void OnJoin(const CNick& Nick, CChan& Channel) override; + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override; + void OnNick(const CNick& OldNick, const CString& sNewNick, + const vector& vChans) override; + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; - /* notices */ - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override; + /* notices */ + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override; - /* actions */ - EModRet OnUserAction(CString& sTarget, CString& sMessage) override; - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override; + /* actions */ + EModRet OnUserAction(CString& sTarget, CString& sMessage) override; + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override; - /* msgs */ - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; + /* msgs */ + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; private: - CString m_sLogPath; - CString m_sTimestamp; - bool m_bSanitize; - vector m_vRules; + CString m_sLogPath; + CString m_sTimestamp; + bool m_bSanitize; + vector m_vRules; }; void CLogMod::SetRulesCmd(const CString& sLine) { - VCString vsRules = SplitRules(sLine.Token(1, true)); + VCString vsRules = SplitRules(sLine.Token(1, true)); - if (vsRules.empty()) { - PutModule("Usage: SetRules "); - PutModule("Wildcards are allowed"); - } else { - SetRules(vsRules); - SetNV("rules", JoinRules(",")); - ListRulesCmd(); - } + if (vsRules.empty()) { + PutModule("Usage: SetRules "); + PutModule("Wildcards are allowed"); + } else { + SetRules(vsRules); + SetNV("rules", JoinRules(",")); + ListRulesCmd(); + } } void CLogMod::ClearRulesCmd(const CString& sLine) { - size_t uCount = m_vRules.size(); + size_t uCount = m_vRules.size(); - if (uCount == 0) { - PutModule("No logging rules. Everything is logged."); - } else { - CString sRules = JoinRules(" "); - SetRules(VCString()); - DelNV("rules"); - PutModule(CString(uCount) + " rule(s) removed: " + sRules); - } + if (uCount == 0) { + PutModule("No logging rules. Everything is logged."); + } else { + CString sRules = JoinRules(" "); + SetRules(VCString()); + DelNV("rules"); + PutModule(CString(uCount) + " rule(s) removed: " + sRules); + } } void CLogMod::ListRulesCmd(const CString& sLine) { - CTable Table; - Table.AddColumn("Rule"); - Table.AddColumn("Logging enabled"); + CTable Table; + Table.AddColumn("Rule"); + Table.AddColumn("Logging enabled"); - for (const CLogRule& Rule : m_vRules) { - Table.AddRow(); - Table.SetCell("Rule", Rule.GetRule()); - Table.SetCell("Logging enabled", CString(Rule.IsEnabled())); - } + for (const CLogRule& Rule : m_vRules) { + Table.AddRow(); + Table.SetCell("Rule", Rule.GetRule()); + Table.SetCell("Logging enabled", CString(Rule.IsEnabled())); + } - if (Table.empty()) { - PutModule("No logging rules. Everything is logged."); - } else { - PutModule(Table); - } + if (Table.empty()) { + PutModule("No logging rules. Everything is logged."); + } else { + PutModule(Table); + } } void CLogMod::SetRules(const VCString& vsRules) { - m_vRules.clear(); + m_vRules.clear(); - for (CString sRule : vsRules) { - bool bEnabled = !sRule.TrimPrefix("!"); - m_vRules.push_back(CLogRule(sRule, bEnabled)); - } + for (CString sRule : vsRules) { + bool bEnabled = !sRule.TrimPrefix("!"); + m_vRules.push_back(CLogRule(sRule, bEnabled)); + } } VCString CLogMod::SplitRules(const CString& sRules) const { - CString sCopy = sRules; - sCopy.Replace(",", " "); + CString sCopy = sRules; + sCopy.Replace(",", " "); - VCString vsRules; - sCopy.Split(" ", vsRules, false, "", "", true, true); + VCString vsRules; + sCopy.Split(" ", vsRules, false, "", "", true, true); - return vsRules; + return vsRules; } CString CLogMod::JoinRules(const CString& sSeparator) const { - VCString vsRules; - for (const CLogRule& Rule : m_vRules) { - vsRules.push_back(Rule.ToString()); - } + VCString vsRules; + for (const CLogRule& Rule : m_vRules) { + vsRules.push_back(Rule.ToString()); + } - return sSeparator.Join(vsRules.begin(), vsRules.end()); + return sSeparator.Join(vsRules.begin(), vsRules.end()); } bool CLogMod::TestRules(const CString& sTarget) const { - for (const CLogRule& Rule : m_vRules) { - if (Rule.Compare(sTarget)) { - return Rule.IsEnabled(); - } - } + for (const CLogRule& Rule : m_vRules) { + if (Rule.Compare(sTarget)) { + return Rule.IsEnabled(); + } + } - return true; + return true; } void CLogMod::PutLog(const CString& sLine, const CString& sWindow /*= "Status"*/) { - if (!TestRules(sWindow)) { - return; - } + if (!TestRules(sWindow)) { + return; + } - CString sPath; - time_t curtime; + CString sPath; + time_t curtime; - time(&curtime); - // Generate file name - sPath = CUtils::FormatTime(curtime, m_sLogPath, GetUser()->GetTimezone()); - if (sPath.empty()) { - DEBUG("Could not format log path [" << sPath << "]"); - return; - } + time(&curtime); + // Generate file name + sPath = CUtils::FormatTime(curtime, m_sLogPath, GetUser()->GetTimezone()); + if (sPath.empty()) { + DEBUG("Could not format log path [" << sPath << "]"); + return; + } - // TODO: Properly handle IRC case mapping - // $WINDOW has to be handled last, since it can contain % - sPath.Replace("$USER", - CString((GetUser() ? GetUser()->GetUserName() : "UNKNOWN"))); - sPath.Replace("$NETWORK", - CString((GetNetwork() ? GetNetwork()->GetName() : "znc"))); - sPath.Replace("$WINDOW", CString(sWindow.Replace_n("/", "-") - .Replace_n("\\", "-")).AsLower()); + // TODO: Properly handle IRC case mapping + // $WINDOW has to be handled last, since it can contain % + sPath.Replace("$USER", + CString((GetUser() ? GetUser()->GetUserName() : "UNKNOWN"))); + sPath.Replace("$NETWORK", + CString((GetNetwork() ? GetNetwork()->GetName() : "znc"))); + sPath.Replace("$WINDOW", CString(sWindow.Replace_n("/", "-") + .Replace_n("\\", "-")).AsLower()); - // Check if it's allowed to write in this specific path - sPath = CDir::CheckPathPrefix(GetSavePath(), sPath); - if (sPath.empty()) { - DEBUG("Invalid log path [" << m_sLogPath << "]."); - return; - } + // Check if it's allowed to write in this specific path + sPath = CDir::CheckPathPrefix(GetSavePath(), sPath); + if (sPath.empty()) { + DEBUG("Invalid log path [" << m_sLogPath << "]."); + return; + } - CFile LogFile(sPath); - CString sLogDir = LogFile.GetDir(); - struct stat ModDirInfo; - CFile::GetInfo(GetSavePath(), ModDirInfo); - if (!CFile::Exists(sLogDir)) CDir::MakeDir(sLogDir, ModDirInfo.st_mode); - if (LogFile.Open(O_WRONLY | O_APPEND | O_CREAT)) { - LogFile.Write(CUtils::FormatTime(curtime, m_sTimestamp, - GetUser()->GetTimezone()) + - " " + (m_bSanitize ? sLine.StripControls_n() : sLine) + - "\n"); - } else - DEBUG("Could not open log file [" << sPath << "]: " << strerror(errno)); + CFile LogFile(sPath); + CString sLogDir = LogFile.GetDir(); + struct stat ModDirInfo; + CFile::GetInfo(GetSavePath(), ModDirInfo); + if (!CFile::Exists(sLogDir)) CDir::MakeDir(sLogDir, ModDirInfo.st_mode); + if (LogFile.Open(O_WRONLY | O_APPEND | O_CREAT)) { + LogFile.Write(CUtils::FormatTime(curtime, m_sTimestamp, + GetUser()->GetTimezone()) + + " " + (m_bSanitize ? sLine.StripControls_n() : sLine) + + "\n"); + } else + DEBUG("Could not open log file [" << sPath << "]: " << strerror(errno)); } void CLogMod::PutLog(const CString& sLine, const CChan& Channel) { - PutLog(sLine, Channel.GetName()); + PutLog(sLine, Channel.GetName()); } void CLogMod::PutLog(const CString& sLine, const CNick& Nick) { - PutLog(sLine, Nick.GetNick()); + PutLog(sLine, Nick.GetNick()); } CString CLogMod::GetServer() { - CServer* pServer = GetNetwork()->GetCurrentServer(); - CString sSSL; + CServer* pServer = GetNetwork()->GetCurrentServer(); + CString sSSL; - if (!pServer) return "(no server)"; + if (!pServer) return "(no server)"; - if (pServer->IsSSL()) sSSL = "+"; - return pServer->GetName() + " " + sSSL + CString(pServer->GetPort()); + if (pServer->IsSSL()) sSSL = "+"; + return pServer->GetName() + " " + sSSL + CString(pServer->GetPort()); } bool CLogMod::OnLoad(const CString& sArgs, CString& sMessage) { - VCString vsArgs; - sArgs.QuoteSplit(vsArgs); + VCString vsArgs; + sArgs.QuoteSplit(vsArgs); - bool bReadingTimestamp = false; - bool bHaveLogPath = false; + bool bReadingTimestamp = false; + bool bHaveLogPath = false; - for (CString& sArg : vsArgs) { - if (bReadingTimestamp) { - m_sTimestamp = sArg; - bReadingTimestamp = false; - } else if (sArg.Equals("-sanitize")) { - m_bSanitize = true; - } else if (sArg.Equals("-timestamp")) { - bReadingTimestamp = true; - } else { - // Only one arg may be LogPath - if (bHaveLogPath) { - sMessage = "Invalid args [" + sArgs + - "]. Only one log path allowed. Check that there " - "are no spaces in the path."; - return false; - } - m_sLogPath = sArg; - bHaveLogPath = true; - } - } + for (CString& sArg : vsArgs) { + if (bReadingTimestamp) { + m_sTimestamp = sArg; + bReadingTimestamp = false; + } else if (sArg.Equals("-sanitize")) { + m_bSanitize = true; + } else if (sArg.Equals("-timestamp")) { + bReadingTimestamp = true; + } else { + // Only one arg may be LogPath + if (bHaveLogPath) { + sMessage = "Invalid args [" + sArgs + + "]. Only one log path allowed. Check that there " + "are no spaces in the path."; + return false; + } + m_sLogPath = sArg; + bHaveLogPath = true; + } + } - if (m_sTimestamp.empty()) { - m_sTimestamp = "[%H:%M:%S]"; - } + if (m_sTimestamp.empty()) { + m_sTimestamp = "[%H:%M:%S]"; + } - // Add default filename to path if it's a folder - if (GetType() == CModInfo::UserModule) { - if (m_sLogPath.Right(1) == "/" || - m_sLogPath.find("$WINDOW") == CString::npos || - m_sLogPath.find("$NETWORK") == CString::npos) { - if (!m_sLogPath.empty()) { - m_sLogPath += "/"; - } - m_sLogPath += "$NETWORK/$WINDOW/%Y-%m-%d.log"; - } - } else if (GetType() == CModInfo::NetworkModule) { - if (m_sLogPath.Right(1) == "/" || - m_sLogPath.find("$WINDOW") == CString::npos) { - if (!m_sLogPath.empty()) { - m_sLogPath += "/"; - } - m_sLogPath += "$WINDOW/%Y-%m-%d.log"; - } - } else { - if (m_sLogPath.Right(1) == "/" || - m_sLogPath.find("$USER") == CString::npos || - m_sLogPath.find("$WINDOW") == CString::npos || - m_sLogPath.find("$NETWORK") == CString::npos) { - if (!m_sLogPath.empty()) { - m_sLogPath += "/"; - } - m_sLogPath += "$USER/$NETWORK/$WINDOW/%Y-%m-%d.log"; - } - } + // Add default filename to path if it's a folder + if (GetType() == CModInfo::UserModule) { + if (m_sLogPath.Right(1) == "/" || + m_sLogPath.find("$WINDOW") == CString::npos || + m_sLogPath.find("$NETWORK") == CString::npos) { + if (!m_sLogPath.empty()) { + m_sLogPath += "/"; + } + m_sLogPath += "$NETWORK/$WINDOW/%Y-%m-%d.log"; + } + } else if (GetType() == CModInfo::NetworkModule) { + if (m_sLogPath.Right(1) == "/" || + m_sLogPath.find("$WINDOW") == CString::npos) { + if (!m_sLogPath.empty()) { + m_sLogPath += "/"; + } + m_sLogPath += "$WINDOW/%Y-%m-%d.log"; + } + } else { + if (m_sLogPath.Right(1) == "/" || + m_sLogPath.find("$USER") == CString::npos || + m_sLogPath.find("$WINDOW") == CString::npos || + m_sLogPath.find("$NETWORK") == CString::npos) { + if (!m_sLogPath.empty()) { + m_sLogPath += "/"; + } + m_sLogPath += "$USER/$NETWORK/$WINDOW/%Y-%m-%d.log"; + } + } - CString sRules = GetNV("rules"); - VCString vsRules = SplitRules(sRules); - SetRules(vsRules); + CString sRules = GetNV("rules"); + VCString vsRules = SplitRules(sRules); + SetRules(vsRules); - // Check if it's allowed to write in this path in general - m_sLogPath = CDir::CheckPathPrefix(GetSavePath(), m_sLogPath); - if (m_sLogPath.empty()) { - sMessage = "Invalid log path [" + m_sLogPath + "]."; - return false; - } else { - sMessage = "Logging to [" + m_sLogPath + "]. Using timestamp format '" + - m_sTimestamp + "'"; - return true; - } + // Check if it's allowed to write in this path in general + m_sLogPath = CDir::CheckPathPrefix(GetSavePath(), m_sLogPath); + if (m_sLogPath.empty()) { + sMessage = "Invalid log path [" + m_sLogPath + "]."; + return false; + } else { + sMessage = "Logging to [" + m_sLogPath + "]. Using timestamp format '" + + m_sTimestamp + "'"; + return true; + } } void CLogMod::OnIRCConnected() { - PutLog("Connected to IRC (" + GetServer() + ")"); + PutLog("Connected to IRC (" + GetServer() + ")"); } void CLogMod::OnIRCDisconnected() { - PutLog("Disconnected from IRC (" + GetServer() + ")"); + PutLog("Disconnected from IRC (" + GetServer() + ")"); } CModule::EModRet CLogMod::OnBroadcast(CString& sMessage) { - PutLog("Broadcast: " + sMessage); - return CONTINUE; + PutLog("Broadcast: " + sMessage); + return CONTINUE; } void CLogMod::OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, const CString& sArgs) { - const CString sNick = pOpNick ? pOpNick->GetNick() : "Server"; - PutLog("*** " + sNick + " sets mode: " + sModes + " " + sArgs, Channel); + const CString sNick = pOpNick ? pOpNick->GetNick() : "Server"; + PutLog("*** " + sNick + " sets mode: " + sModes + " " + sArgs, Channel); } void CLogMod::OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) { - PutLog("*** " + sKickedNick + " was kicked by " + OpNick.GetNick() + " (" + - sMessage + ")", - Channel); + PutLog("*** " + sKickedNick + " was kicked by " + OpNick.GetNick() + " (" + + sMessage + ")", + Channel); } void CLogMod::OnQuit(const CNick& Nick, const CString& sMessage, const vector& vChans) { - if (!HasNV("quits") || GetNV("quits").ToBool()) { - for (CChan* pChan : vChans) - PutLog("*** Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + - "@" + Nick.GetHost() + ") (" + sMessage + ")", - *pChan); - } + if (!HasNV("quits") || GetNV("quits").ToBool()) { + for (CChan* pChan : vChans) + PutLog("*** Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + + "@" + Nick.GetHost() + ") (" + sMessage + ")", + *pChan); + } } void CLogMod::OnJoin(const CNick& Nick, CChan& Channel) { - if (!HasNV("joins") || GetNV("joins").ToBool()) - PutLog("*** Joins: " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + - Nick.GetHost() + ")", - Channel); + if (!HasNV("joins") || GetNV("joins").ToBool()) + PutLog("*** Joins: " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + + Nick.GetHost() + ")", + Channel); } void CLogMod::OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) { - PutLog("*** Parts: " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + - Nick.GetHost() + ") (" + sMessage + ")", - Channel); + PutLog("*** Parts: " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + + Nick.GetHost() + ") (" + sMessage + ")", + Channel); } void CLogMod::OnNick(const CNick& OldNick, const CString& sNewNick, const vector& vChans) { - if (!HasNV("nickchanges") || GetNV("nickchanges").ToBool()) { - for (CChan* pChan : vChans) - PutLog("*** " + OldNick.GetNick() + " is now known as " + sNewNick, - *pChan); - } + if (!HasNV("nickchanges") || GetNV("nickchanges").ToBool()) { + for (CChan* pChan : vChans) + PutLog("*** " + OldNick.GetNick() + " is now known as " + sNewNick, + *pChan); + } } CModule::EModRet CLogMod::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) { - PutLog("*** " + Nick.GetNick() + " changes topic to '" + sTopic + "'", - Channel); - return CONTINUE; + PutLog("*** " + Nick.GetNick() + " changes topic to '" + sTopic + "'", + Channel); + return CONTINUE; } /* notices */ CModule::EModRet CLogMod::OnUserNotice(CString& sTarget, CString& sMessage) { - CIRCNetwork* pNetwork = GetNetwork(); - if (pNetwork) { - PutLog("-" + pNetwork->GetCurNick() + "- " + sMessage, sTarget); - } + CIRCNetwork* pNetwork = GetNetwork(); + if (pNetwork) { + PutLog("-" + pNetwork->GetCurNick() + "- " + sMessage, sTarget); + } - return CONTINUE; + return CONTINUE; } CModule::EModRet CLogMod::OnPrivNotice(CNick& Nick, CString& sMessage) { - PutLog("-" + Nick.GetNick() + "- " + sMessage, Nick); - return CONTINUE; + PutLog("-" + Nick.GetNick() + "- " + sMessage, Nick); + return CONTINUE; } CModule::EModRet CLogMod::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) { - PutLog("-" + Nick.GetNick() + "- " + sMessage, Channel); - return CONTINUE; + PutLog("-" + Nick.GetNick() + "- " + sMessage, Channel); + return CONTINUE; } /* actions */ CModule::EModRet CLogMod::OnUserAction(CString& sTarget, CString& sMessage) { - CIRCNetwork* pNetwork = GetNetwork(); - if (pNetwork) { - PutLog("* " + pNetwork->GetCurNick() + " " + sMessage, sTarget); - } + CIRCNetwork* pNetwork = GetNetwork(); + if (pNetwork) { + PutLog("* " + pNetwork->GetCurNick() + " " + sMessage, sTarget); + } - return CONTINUE; + return CONTINUE; } CModule::EModRet CLogMod::OnPrivAction(CNick& Nick, CString& sMessage) { - PutLog("* " + Nick.GetNick() + " " + sMessage, Nick); - return CONTINUE; + PutLog("* " + Nick.GetNick() + " " + sMessage, Nick); + return CONTINUE; } CModule::EModRet CLogMod::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) { - PutLog("* " + Nick.GetNick() + " " + sMessage, Channel); - return CONTINUE; + PutLog("* " + Nick.GetNick() + " " + sMessage, Channel); + return CONTINUE; } /* msgs */ CModule::EModRet CLogMod::OnUserMsg(CString& sTarget, CString& sMessage) { - CIRCNetwork* pNetwork = GetNetwork(); - if (pNetwork) { - PutLog("<" + pNetwork->GetCurNick() + "> " + sMessage, sTarget); - } + CIRCNetwork* pNetwork = GetNetwork(); + if (pNetwork) { + PutLog("<" + pNetwork->GetCurNick() + "> " + sMessage, sTarget); + } - return CONTINUE; + return CONTINUE; } CModule::EModRet CLogMod::OnPrivMsg(CNick& Nick, CString& sMessage) { - PutLog("<" + Nick.GetNick() + "> " + sMessage, Nick); - return CONTINUE; + PutLog("<" + Nick.GetNick() + "> " + sMessage, Nick); + return CONTINUE; } CModule::EModRet CLogMod::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { - PutLog("<" + Nick.GetNick() + "> " + sMessage, Channel); - return CONTINUE; + PutLog("<" + Nick.GetNick() + "> " + sMessage, Channel); + return CONTINUE; } template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::NetworkModule); - Info.AddType(CModInfo::GlobalModule); - Info.SetHasArgs(true); - Info.SetArgsHelpText("[-sanitize] Optional path where to store logs."); - Info.SetWikiPage("log"); + Info.AddType(CModInfo::NetworkModule); + Info.AddType(CModInfo::GlobalModule); + Info.SetHasArgs(true); + Info.SetArgsHelpText("[-sanitize] Optional path where to store logs."); + Info.SetWikiPage("log"); } USERMODULEDEFS(CLogMod, "Write IRC logs.") diff --git a/modules/missingmotd.cpp b/modules/missingmotd.cpp index 8857e9cb..499ea718 100644 --- a/modules/missingmotd.cpp +++ b/modules/missingmotd.cpp @@ -18,17 +18,17 @@ class CMissingMotd : public CModule { public: - MODCONSTRUCTOR(CMissingMotd) {} + MODCONSTRUCTOR(CMissingMotd) {} - void OnClientLogin() override { - PutUser(":irc.znc.in 422 :MOTD File is missing"); - } + void OnClientLogin() override { + PutUser(":irc.znc.in 422 :MOTD File is missing"); + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("missingmotd"); - Info.SetHasArgs(false); + Info.SetWikiPage("missingmotd"); + Info.SetHasArgs(false); } USERMODULEDEFS(CMissingMotd, "Sends 422 to clients when they login") diff --git a/modules/modperl.cpp b/modules/modperl.cpp index 8f313570..31adfe6f 100644 --- a/modules/modperl.cpp +++ b/modules/modperl.cpp @@ -42,345 +42,345 @@ using std::vector; extern "C" { void boot_DynaLoader(pTHX_ CV* cv); static void xs_init(pTHX) { - newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); } } class CModPerl : public CModule { - PerlInterpreter* m_pPerl; + PerlInterpreter* m_pPerl; public: - MODCONSTRUCTOR(CModPerl) { m_pPerl = nullptr; } + MODCONSTRUCTOR(CModPerl) { m_pPerl = nullptr; } #define PSTART \ - dSP; \ - I32 ax; \ - int ret = 0; \ - ENTER; \ - SAVETMPS; \ - PUSHMARK(SP) + dSP; \ + I32 ax; \ + int ret = 0; \ + ENTER; \ + SAVETMPS; \ + PUSHMARK(SP) #define PCALL(name) \ - PUTBACK; \ - ret = call_pv(name, G_EVAL | G_ARRAY); \ - SPAGAIN; \ - SP -= ret; \ - ax = (SP - PL_stack_base) + 1 + PUTBACK; \ + ret = call_pv(name, G_EVAL | G_ARRAY); \ + SPAGAIN; \ + SP -= ret; \ + ax = (SP - PL_stack_base) + 1 #define PEND \ - ax += 0; \ - PUTBACK; \ - FREETMPS; \ - LEAVE + ax += 0; \ + PUTBACK; \ + FREETMPS; \ + LEAVE #define PUSH_STR(s) XPUSHs(PString(s).GetSV()) #define PUSH_PTR(type, p) \ - XPUSHs(SWIG_NewInstanceObj(const_cast(p), SWIG_TypeQuery(#type), \ - SWIG_SHADOW)) + XPUSHs(SWIG_NewInstanceObj(const_cast(p), SWIG_TypeQuery(#type), \ + SWIG_SHADOW)) - bool OnLoad(const CString& sArgsi, CString& sMessage) override { - CString sModPath, sTmp; - if (!CModules::FindModPath("modperl/startup.pl", sModPath, sTmp)) { - sMessage = "startup.pl not found."; - return false; - } - sTmp = CDir::ChangeDir(sModPath, ".."); - int argc = 6; - char* pArgv[] = {"", - "-T", - "-w", - "-I", - const_cast(sTmp.c_str()), - const_cast(sModPath.c_str()), - nullptr}; - char** argv = pArgv; - char*** const pEnviron = + bool OnLoad(const CString& sArgsi, CString& sMessage) override { + CString sModPath, sTmp; + if (!CModules::FindModPath("modperl/startup.pl", sModPath, sTmp)) { + sMessage = "startup.pl not found."; + return false; + } + sTmp = CDir::ChangeDir(sModPath, ".."); + int argc = 6; + char* pArgv[] = {"", + "-T", + "-w", + "-I", + const_cast(sTmp.c_str()), + const_cast(sModPath.c_str()), + nullptr}; + char** argv = pArgv; + char*** const pEnviron = #if defined(__APPLE__) && defined(__MACH__) - _NSGetEnviron(); + _NSGetEnviron(); #else - &environ; + &environ; #endif - PERL_SYS_INIT3(&argc, &argv, pEnviron); - m_pPerl = perl_alloc(); - perl_construct(m_pPerl); - if (perl_parse(m_pPerl, xs_init, argc, argv, *pEnviron)) { - sMessage = "Can't initialize perl. "; - if (SvTRUE(ERRSV)) { - sMessage += PString(ERRSV); - } - perl_free(m_pPerl); - PERL_SYS_TERM(); - m_pPerl = nullptr; - DEBUG(__PRETTY_FUNCTION__ << " can't init perl"); - return false; - } - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - PSTART; - PCALL("ZNC::Core::Init"); - PEND; - return true; - } + PERL_SYS_INIT3(&argc, &argv, pEnviron); + m_pPerl = perl_alloc(); + perl_construct(m_pPerl); + if (perl_parse(m_pPerl, xs_init, argc, argv, *pEnviron)) { + sMessage = "Can't initialize perl. "; + if (SvTRUE(ERRSV)) { + sMessage += PString(ERRSV); + } + perl_free(m_pPerl); + PERL_SYS_TERM(); + m_pPerl = nullptr; + DEBUG(__PRETTY_FUNCTION__ << " can't init perl"); + return false; + } + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + PSTART; + PCALL("ZNC::Core::Init"); + PEND; + return true; + } - virtual EModRet OnModuleLoading(const CString& sModName, - const CString& sArgs, - CModInfo::EModuleType eType, bool& bSuccess, - CString& sRetMsg) override { - EModRet result = HALT; - PSTART; - PUSH_STR(sModName); - PUSH_STR(sArgs); - mXPUSHi(eType); - PUSH_PTR(CUser*, GetUser()); - PUSH_PTR(CIRCNetwork*, GetNetwork()); - PCALL("ZNC::Core::LoadModule"); + virtual EModRet OnModuleLoading(const CString& sModName, + const CString& sArgs, + CModInfo::EModuleType eType, bool& bSuccess, + CString& sRetMsg) override { + EModRet result = HALT; + PSTART; + PUSH_STR(sModName); + PUSH_STR(sArgs); + mXPUSHi(eType); + PUSH_PTR(CUser*, GetUser()); + PUSH_PTR(CIRCNetwork*, GetNetwork()); + PCALL("ZNC::Core::LoadModule"); - if (SvTRUE(ERRSV)) { - sRetMsg = PString(ERRSV); - bSuccess = false; - result = HALT; - DEBUG("Perl ZNC::Core::LoadModule died: " << sRetMsg); - } else if (ret < 1 || 2 < ret) { - sRetMsg = "Error: Perl ZNC::Core::LoadModule returned " + - CString(ret) + " values."; - bSuccess = false; - result = HALT; - } else { - ELoadPerlMod eLPM = static_cast(SvUV(ST(0))); - if (Perl_NotFound == eLPM) { - result = CONTINUE; // Not a Perl module - } else { - sRetMsg = PString(ST(1)); - result = HALT; - bSuccess = eLPM == Perl_Loaded; - } - } + if (SvTRUE(ERRSV)) { + sRetMsg = PString(ERRSV); + bSuccess = false; + result = HALT; + DEBUG("Perl ZNC::Core::LoadModule died: " << sRetMsg); + } else if (ret < 1 || 2 < ret) { + sRetMsg = "Error: Perl ZNC::Core::LoadModule returned " + + CString(ret) + " values."; + bSuccess = false; + result = HALT; + } else { + ELoadPerlMod eLPM = static_cast(SvUV(ST(0))); + if (Perl_NotFound == eLPM) { + result = CONTINUE; // Not a Perl module + } else { + sRetMsg = PString(ST(1)); + result = HALT; + bSuccess = eLPM == Perl_Loaded; + } + } - PEND; - return result; - } + PEND; + return result; + } - EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, - CString& sRetMsg) override { - CPerlModule* pMod = AsPerlModule(pModule); - if (pMod) { - EModRet result = HALT; - CString sModName = pMod->GetModName(); - PSTART; - XPUSHs(pMod->GetPerlObj()); - PCALL("ZNC::Core::UnloadModule"); - if (SvTRUE(ERRSV)) { - bSuccess = false; - sRetMsg = PString(ERRSV); - } else if (ret < 1 || 2 < ret) { - sRetMsg = "Error: Perl ZNC::Core::UnloadModule returned " + - CString(ret) + " values."; - bSuccess = false; - result = HALT; - } else { - int bUnloaded = SvUV(ST(0)); - if (bUnloaded) { - bSuccess = true; - sRetMsg = "Module [" + sModName + "] unloaded"; - result = HALT; - } else { - result = CONTINUE; // module wasn't loaded by modperl. - // Perhaps a module-provider written in - // perl did that. - } - } - PEND; - DEBUG(__PRETTY_FUNCTION__ << " " << sRetMsg); - return result; - } - return CONTINUE; - } + EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, + CString& sRetMsg) override { + CPerlModule* pMod = AsPerlModule(pModule); + if (pMod) { + EModRet result = HALT; + CString sModName = pMod->GetModName(); + PSTART; + XPUSHs(pMod->GetPerlObj()); + PCALL("ZNC::Core::UnloadModule"); + if (SvTRUE(ERRSV)) { + bSuccess = false; + sRetMsg = PString(ERRSV); + } else if (ret < 1 || 2 < ret) { + sRetMsg = "Error: Perl ZNC::Core::UnloadModule returned " + + CString(ret) + " values."; + bSuccess = false; + result = HALT; + } else { + int bUnloaded = SvUV(ST(0)); + if (bUnloaded) { + bSuccess = true; + sRetMsg = "Module [" + sModName + "] unloaded"; + result = HALT; + } else { + result = CONTINUE; // module wasn't loaded by modperl. + // Perhaps a module-provider written in + // perl did that. + } + } + PEND; + DEBUG(__PRETTY_FUNCTION__ << " " << sRetMsg); + return result; + } + return CONTINUE; + } - virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, - bool& bSuccess, CString& sRetMsg) override { - PSTART; - PUSH_STR(sModule); - PUSH_PTR(CModInfo*, &ModInfo); - PCALL("ZNC::Core::GetModInfo"); - EModRet result = CONTINUE; - if (SvTRUE(ERRSV)) { - bSuccess = false; - sRetMsg = PString(ERRSV); - DEBUG("Perl ZNC::Core::GetModInfo died: " << sRetMsg); - } else if (0 < ret) { - switch (static_cast(SvUV(ST(0)))) { - case Perl_NotFound: - result = CONTINUE; - break; - case Perl_Loaded: - result = HALT; - if (1 == ret) { - bSuccess = true; - } else { - bSuccess = false; - sRetMsg = "Something weird happened"; - } - break; - case Perl_LoadError: - result = HALT; - bSuccess = false; - if (2 == ret) { - sRetMsg = PString(ST(1)); - } else { - sRetMsg = "Something weird happened"; - } - } - } else { - result = HALT; - bSuccess = false; - sRetMsg = "Something weird happened"; - } - PEND; - return result; - } + virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, + bool& bSuccess, CString& sRetMsg) override { + PSTART; + PUSH_STR(sModule); + PUSH_PTR(CModInfo*, &ModInfo); + PCALL("ZNC::Core::GetModInfo"); + EModRet result = CONTINUE; + if (SvTRUE(ERRSV)) { + bSuccess = false; + sRetMsg = PString(ERRSV); + DEBUG("Perl ZNC::Core::GetModInfo died: " << sRetMsg); + } else if (0 < ret) { + switch (static_cast(SvUV(ST(0)))) { + case Perl_NotFound: + result = CONTINUE; + break; + case Perl_Loaded: + result = HALT; + if (1 == ret) { + bSuccess = true; + } else { + bSuccess = false; + sRetMsg = "Something weird happened"; + } + break; + case Perl_LoadError: + result = HALT; + bSuccess = false; + if (2 == ret) { + sRetMsg = PString(ST(1)); + } else { + sRetMsg = "Something weird happened"; + } + } + } else { + result = HALT; + bSuccess = false; + sRetMsg = "Something weird happened"; + } + PEND; + return result; + } - void OnGetAvailableMods(set& ssMods, - CModInfo::EModuleType eType) override { - unsigned int a = 0; - CDir Dir; + void OnGetAvailableMods(set& ssMods, + CModInfo::EModuleType eType) override { + unsigned int a = 0; + CDir Dir; - CModules::ModDirList dirs = CModules::GetModDirs(); + CModules::ModDirList dirs = CModules::GetModDirs(); - while (!dirs.empty()) { - Dir.FillByWildcard(dirs.front().first, "*.pm"); - dirs.pop(); + while (!dirs.empty()) { + Dir.FillByWildcard(dirs.front().first, "*.pm"); + dirs.pop(); - for (a = 0; a < Dir.size(); a++) { - CFile& File = *Dir[a]; - CString sName = File.GetShortName(); - CString sPath = File.GetLongName(); - CModInfo ModInfo; - sName.RightChomp(3); - PSTART; - PUSH_STR(sPath); - PUSH_STR(sName); - PUSH_PTR(CModInfo*, &ModInfo); - PCALL("ZNC::Core::ModInfoByPath"); - if (SvTRUE(ERRSV)) { - DEBUG(__PRETTY_FUNCTION__ << ": " << sPath << ": " - << PString(ERRSV)); - } else if (ModInfo.SupportsType(eType)) { - ssMods.insert(ModInfo); - } - PEND; - } - } - } + for (a = 0; a < Dir.size(); a++) { + CFile& File = *Dir[a]; + CString sName = File.GetShortName(); + CString sPath = File.GetLongName(); + CModInfo ModInfo; + sName.RightChomp(3); + PSTART; + PUSH_STR(sPath); + PUSH_STR(sName); + PUSH_PTR(CModInfo*, &ModInfo); + PCALL("ZNC::Core::ModInfoByPath"); + if (SvTRUE(ERRSV)) { + DEBUG(__PRETTY_FUNCTION__ << ": " << sPath << ": " + << PString(ERRSV)); + } else if (ModInfo.SupportsType(eType)) { + ssMods.insert(ModInfo); + } + PEND; + } + } + } - virtual ~CModPerl() { - if (m_pPerl) { - PSTART; - PCALL("ZNC::Core::UnloadAll"); - PEND; - perl_destruct(m_pPerl); - perl_free(m_pPerl); - PERL_SYS_TERM(); - } - } + virtual ~CModPerl() { + if (m_pPerl) { + PSTART; + PCALL("ZNC::Core::UnloadAll"); + PEND; + perl_destruct(m_pPerl); + perl_free(m_pPerl); + PERL_SYS_TERM(); + } + } }; #include "modperl/functions.cpp" VWebSubPages& CPerlModule::GetSubPages() { - VWebSubPages* result = _GetSubPages(); - if (!result) { - return CModule::GetSubPages(); - } - return *result; + VWebSubPages* result = _GetSubPages(); + if (!result) { + return CModule::GetSubPages(); + } + return *result; } void CPerlTimer::RunJob() { - CPerlModule* pMod = AsPerlModule(GetModule()); - if (pMod) { - PSTART; - XPUSHs(GetPerlObj()); - PCALL("ZNC::Core::CallTimer"); - PEND; - } + CPerlModule* pMod = AsPerlModule(GetModule()); + if (pMod) { + PSTART; + XPUSHs(GetPerlObj()); + PCALL("ZNC::Core::CallTimer"); + PEND; + } } CPerlTimer::~CPerlTimer() { - CPerlModule* pMod = AsPerlModule(GetModule()); - if (pMod) { - PSTART; - XPUSHs(sv_2mortal(m_perlObj)); - PCALL("ZNC::Core::RemoveTimer"); - PEND; - } + CPerlModule* pMod = AsPerlModule(GetModule()); + if (pMod) { + PSTART; + XPUSHs(sv_2mortal(m_perlObj)); + PCALL("ZNC::Core::RemoveTimer"); + PEND; + } } #define SOCKSTART \ - PSTART; \ - XPUSHs(GetPerlObj()) + PSTART; \ + XPUSHs(GetPerlObj()) #define SOCKCBCHECK(OnSuccess) \ - PCALL("ZNC::Core::CallSocket"); \ - if (SvTRUE(ERRSV)) { \ - Close(); \ - DEBUG("Perl socket hook died with: " + PString(ERRSV)); \ - } else { \ - OnSuccess; \ - } \ - PEND + PCALL("ZNC::Core::CallSocket"); \ + if (SvTRUE(ERRSV)) { \ + Close(); \ + DEBUG("Perl socket hook died with: " + PString(ERRSV)); \ + } else { \ + OnSuccess; \ + } \ + PEND #define CBSOCK(Func) \ - void CPerlSocket::Func() { \ - CPerlModule* pMod = AsPerlModule(GetModule()); \ - if (pMod) { \ - SOCKSTART; \ - PUSH_STR("On" #Func); \ - SOCKCBCHECK(); \ - } \ - } + void CPerlSocket::Func() { \ + CPerlModule* pMod = AsPerlModule(GetModule()); \ + if (pMod) { \ + SOCKSTART; \ + PUSH_STR("On" #Func); \ + SOCKCBCHECK(); \ + } \ + } CBSOCK(Connected); CBSOCK(Disconnected); CBSOCK(Timeout); CBSOCK(ConnectionRefused); void CPerlSocket::ReadData(const char* data, size_t len) { - CPerlModule* pMod = AsPerlModule(GetModule()); - if (pMod) { - SOCKSTART; - PUSH_STR("OnReadData"); - XPUSHs(sv_2mortal(newSVpvn(data, len))); - mXPUSHi(len); - SOCKCBCHECK(); - } + CPerlModule* pMod = AsPerlModule(GetModule()); + if (pMod) { + SOCKSTART; + PUSH_STR("OnReadData"); + XPUSHs(sv_2mortal(newSVpvn(data, len))); + mXPUSHi(len); + SOCKCBCHECK(); + } } void CPerlSocket::ReadLine(const CString& sLine) { - CPerlModule* pMod = AsPerlModule(GetModule()); - if (pMod) { - SOCKSTART; - PUSH_STR("OnReadLine"); - PUSH_STR(sLine); - SOCKCBCHECK(); - } + CPerlModule* pMod = AsPerlModule(GetModule()); + if (pMod) { + SOCKSTART; + PUSH_STR("OnReadLine"); + PUSH_STR(sLine); + SOCKCBCHECK(); + } } Csock* CPerlSocket::GetSockObj(const CString& sHost, unsigned short uPort) { - CPerlModule* pMod = AsPerlModule(GetModule()); - Csock* result = nullptr; - if (pMod) { - SOCKSTART; - PUSH_STR("_Accepted"); - PUSH_STR(sHost); - mXPUSHi(uPort); - SOCKCBCHECK(result = SvToPtr("CPerlSocket*")(ST(0));); - } - return result; + CPerlModule* pMod = AsPerlModule(GetModule()); + Csock* result = nullptr; + if (pMod) { + SOCKSTART; + PUSH_STR("_Accepted"); + PUSH_STR(sHost); + mXPUSHi(uPort); + SOCKCBCHECK(result = SvToPtr("CPerlSocket*")(ST(0));); + } + return result; } CPerlSocket::~CPerlSocket() { - CPerlModule* pMod = AsPerlModule(GetModule()); - if (pMod) { - PSTART; - XPUSHs(sv_2mortal(m_perlObj)); - PCALL("ZNC::Core::RemoveSocket"); - PEND; - } + CPerlModule* pMod = AsPerlModule(GetModule()); + if (pMod) { + PSTART; + XPUSHs(sv_2mortal(m_perlObj)); + PCALL("ZNC::Core::RemoveSocket"); + PEND; + } } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("modperl"); + Info.SetWikiPage("modperl"); } GLOBALMODULEDEFS(CModPerl, "Loads perl scripts as ZNC modules") diff --git a/modules/modperl/module.h b/modules/modperl/module.h index 7905322d..e9201a2a 100644 --- a/modules/modperl/module.h +++ b/modules/modperl/module.h @@ -26,210 +26,210 @@ #pragma GCC visibility push(default) #endif class CPerlModule : public CModule { - SV* m_perlObj; - VWebSubPages* _GetSubPages(); + SV* m_perlObj; + VWebSubPages* _GetSubPages(); public: - CPerlModule(CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, - const CString& sDataPath, CModInfo::EModuleType eType, - SV* perlObj) - : CModule(nullptr, pUser, pNetwork, sModName, sDataPath, eType) { - m_perlObj = newSVsv(perlObj); - } - SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } + CPerlModule(CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, + const CString& sDataPath, CModInfo::EModuleType eType, + SV* perlObj) + : CModule(nullptr, pUser, pNetwork, sModName, sDataPath, eType) { + m_perlObj = newSVsv(perlObj); + } + SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } - bool OnBoot() override; - bool WebRequiresLogin() override; - bool WebRequiresAdmin() override; - CString GetWebMenuTitle() override; - bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) override; - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override; - VWebSubPages& GetSubPages() override; - void OnPreRehash() override; - void OnPostRehash() override; - void OnIRCDisconnected() override; - void OnIRCConnected() override; - EModRet OnIRCConnecting(CIRCSock* pIRCSock) override; - void OnIRCConnectionError(CIRCSock* pIRCSock) override; - EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, - CString& sRealName) override; - EModRet OnBroadcast(CString& sMessage) override; - void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, bool bAdded, - bool bNoChange) override; - void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange) override; - void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override; - EModRet OnRaw(CString& sLine) override; - EModRet OnStatusCommand(CString& sCommand) override; - void OnModCommand(const CString& sCommand) override; - void OnModNotice(const CString& sMessage) override; - void OnModCTCP(const CString& sMessage) override; - void OnQuit(const CNick& Nick, const CString& sMessage, - const std::vector& vChans) override; - void OnNick(const CNick& Nick, const CString& sNewNick, - const std::vector& vChans) override; - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override; - EModRet OnJoining(CChan& Channel) override; - void OnJoin(const CNick& Nick, CChan& Channel) override; - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override; - EModRet OnChanBufferStarting(CChan& Chan, CClient& Client) override; - EModRet OnChanBufferEnding(CChan& Chan, CClient& Client) override; - EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, - CString& sLine) override; - EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine) override; - void OnClientLogin() override; - void OnClientDisconnect() override; - EModRet OnUserRaw(CString& sLine) override; - EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override; - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override; - EModRet OnUserAction(CString& sTarget, CString& sMessage) override; - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; - EModRet OnUserJoin(CString& sChannel, CString& sKey) override; - EModRet OnUserPart(CString& sChannel, CString& sMessage) override; - EModRet OnUserTopic(CString& sChannel, CString& sTopic) override; - EModRet OnUserQuit(CString& sMessage) override; - EModRet OnUserTopicRequest(CString& sChannel) override; - EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override; - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override; - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override; - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override; - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override; - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; - bool OnServerCapAvailable(const CString& sCap) override; - void OnServerCapResult(const CString& sCap, bool bSuccess) override; - EModRet OnTimerAutoJoin(CChan& Channel) override; - bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&) override; - EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) override; - EModRet OnDeleteNetwork(CIRCNetwork& Network) override; - EModRet OnSendToClient(CString& sLine, CClient& Client) override; - EModRet OnSendToIRC(CString& sLine) override; + bool OnBoot() override; + bool WebRequiresLogin() override; + bool WebRequiresAdmin() override; + CString GetWebMenuTitle() override; + bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) override; + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override; + VWebSubPages& GetSubPages() override; + void OnPreRehash() override; + void OnPostRehash() override; + void OnIRCDisconnected() override; + void OnIRCConnected() override; + EModRet OnIRCConnecting(CIRCSock* pIRCSock) override; + void OnIRCConnectionError(CIRCSock* pIRCSock) override; + EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, + CString& sRealName) override; + EModRet OnBroadcast(CString& sMessage) override; + void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, bool bAdded, + bool bNoChange) override; + void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange) override; + void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override; + EModRet OnRaw(CString& sLine) override; + EModRet OnStatusCommand(CString& sCommand) override; + void OnModCommand(const CString& sCommand) override; + void OnModNotice(const CString& sMessage) override; + void OnModCTCP(const CString& sMessage) override; + void OnQuit(const CNick& Nick, const CString& sMessage, + const std::vector& vChans) override; + void OnNick(const CNick& Nick, const CString& sNewNick, + const std::vector& vChans) override; + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override; + EModRet OnJoining(CChan& Channel) override; + void OnJoin(const CNick& Nick, CChan& Channel) override; + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override; + EModRet OnChanBufferStarting(CChan& Chan, CClient& Client) override; + EModRet OnChanBufferEnding(CChan& Chan, CClient& Client) override; + EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, + CString& sLine) override; + EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine) override; + void OnClientLogin() override; + void OnClientDisconnect() override; + EModRet OnUserRaw(CString& sLine) override; + EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override; + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override; + EModRet OnUserAction(CString& sTarget, CString& sMessage) override; + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; + EModRet OnUserJoin(CString& sChannel, CString& sKey) override; + EModRet OnUserPart(CString& sChannel, CString& sMessage) override; + EModRet OnUserTopic(CString& sChannel, CString& sTopic) override; + EModRet OnUserQuit(CString& sMessage) override; + EModRet OnUserTopicRequest(CString& sChannel) override; + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override; + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override; + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override; + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override; + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override; + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; + bool OnServerCapAvailable(const CString& sCap) override; + void OnServerCapResult(const CString& sCap, bool bSuccess) override; + EModRet OnTimerAutoJoin(CChan& Channel) override; + bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&) override; + EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) override; + EModRet OnDeleteNetwork(CIRCNetwork& Network) override; + EModRet OnSendToClient(CString& sLine, CClient& Client) override; + EModRet OnSendToIRC(CString& sLine) override; - EModRet OnRawMessage(CMessage& Message) override; - EModRet OnNumericMessage(CNumericMessage& Message) override; - void OnQuitMessage(CQuitMessage& Message, - const std::vector& vChans) override; - void OnNickMessage(CNickMessage& Message, - const std::vector& vChans) override; - void OnKickMessage(CKickMessage& Message) override; - void OnJoinMessage(CJoinMessage& Message) override; - void OnPartMessage(CPartMessage& Message) override; - EModRet OnChanBufferPlayMessage(CMessage& Message) override; - EModRet OnPrivBufferPlayMessage(CMessage& Message) override; - EModRet OnUserRawMessage(CMessage& Message) override; - EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override; - EModRet OnUserCTCPMessage(CCTCPMessage& Message) override; - EModRet OnUserActionMessage(CActionMessage& Message) override; - EModRet OnUserTextMessage(CTextMessage& Message) override; - EModRet OnUserNoticeMessage(CNoticeMessage& Message) override; - EModRet OnUserJoinMessage(CJoinMessage& Message) override; - EModRet OnUserPartMessage(CPartMessage& Message) override; - EModRet OnUserTopicMessage(CTopicMessage& Message) override; - EModRet OnUserQuitMessage(CQuitMessage& Message) override; - EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override; - EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override; - EModRet OnChanCTCPMessage(CCTCPMessage& Message) override; - EModRet OnPrivActionMessage(CActionMessage& Message) override; - EModRet OnChanActionMessage(CActionMessage& Message) override; - EModRet OnPrivMessage(CTextMessage& Message) override; - EModRet OnChanMessage(CTextMessage& Message) override; - EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override; - EModRet OnChanNoticeMessage(CNoticeMessage& Message) override; - EModRet OnTopicMessage(CTopicMessage& Message) override; + EModRet OnRawMessage(CMessage& Message) override; + EModRet OnNumericMessage(CNumericMessage& Message) override; + void OnQuitMessage(CQuitMessage& Message, + const std::vector& vChans) override; + void OnNickMessage(CNickMessage& Message, + const std::vector& vChans) override; + void OnKickMessage(CKickMessage& Message) override; + void OnJoinMessage(CJoinMessage& Message) override; + void OnPartMessage(CPartMessage& Message) override; + EModRet OnChanBufferPlayMessage(CMessage& Message) override; + EModRet OnPrivBufferPlayMessage(CMessage& Message) override; + EModRet OnUserRawMessage(CMessage& Message) override; + EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override; + EModRet OnUserCTCPMessage(CCTCPMessage& Message) override; + EModRet OnUserActionMessage(CActionMessage& Message) override; + EModRet OnUserTextMessage(CTextMessage& Message) override; + EModRet OnUserNoticeMessage(CNoticeMessage& Message) override; + EModRet OnUserJoinMessage(CJoinMessage& Message) override; + EModRet OnUserPartMessage(CPartMessage& Message) override; + EModRet OnUserTopicMessage(CTopicMessage& Message) override; + EModRet OnUserQuitMessage(CQuitMessage& Message) override; + EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override; + EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override; + EModRet OnChanCTCPMessage(CCTCPMessage& Message) override; + EModRet OnPrivActionMessage(CActionMessage& Message) override; + EModRet OnChanActionMessage(CActionMessage& Message) override; + EModRet OnPrivMessage(CTextMessage& Message) override; + EModRet OnChanMessage(CTextMessage& Message) override; + EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override; + EModRet OnChanNoticeMessage(CNoticeMessage& Message) override; + EModRet OnTopicMessage(CTopicMessage& Message) override; }; static inline CPerlModule* AsPerlModule(CModule* p) { - return dynamic_cast(p); + return dynamic_cast(p); } enum ELoadPerlMod { - Perl_NotFound, - Perl_Loaded, - Perl_LoadError, + Perl_NotFound, + Perl_Loaded, + Perl_LoadError, }; class CPerlTimer : public CTimer { - SV* m_perlObj; + SV* m_perlObj; public: - CPerlTimer(CPerlModule* pModule, unsigned int uInterval, - unsigned int uCycles, const CString& sLabel, - const CString& sDescription, SV* perlObj) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), - m_perlObj(newSVsv(perlObj)) { - pModule->AddTimer(this); - } - void RunJob() override; - SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } - ~CPerlTimer(); + CPerlTimer(CPerlModule* pModule, unsigned int uInterval, + unsigned int uCycles, const CString& sLabel, + const CString& sDescription, SV* perlObj) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), + m_perlObj(newSVsv(perlObj)) { + pModule->AddTimer(this); + } + void RunJob() override; + SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } + ~CPerlTimer(); }; inline CPerlTimer* CreatePerlTimer(CPerlModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription, SV* perlObj) { - return new CPerlTimer(pModule, uInterval, uCycles, sLabel, sDescription, - perlObj); + return new CPerlTimer(pModule, uInterval, uCycles, sLabel, sDescription, + perlObj); } class CPerlSocket : public CSocket { - SV* m_perlObj; + SV* m_perlObj; public: - CPerlSocket(CPerlModule* pModule, SV* perlObj) - : CSocket(pModule), m_perlObj(newSVsv(perlObj)) {} - SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } - ~CPerlSocket(); - void Connected() override; - void Disconnected() override; - void Timeout() override; - void ConnectionRefused() override; - void ReadData(const char* data, size_t len) override; - void ReadLine(const CString& sLine) override; - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + CPerlSocket(CPerlModule* pModule, SV* perlObj) + : CSocket(pModule), m_perlObj(newSVsv(perlObj)) {} + SV* GetPerlObj() { return sv_2mortal(newSVsv(m_perlObj)); } + ~CPerlSocket(); + void Connected() override; + void Disconnected() override; + void Timeout() override; + void ConnectionRefused() override; + void ReadData(const char* data, size_t len) override; + void ReadLine(const CString& sLine) override; + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; }; inline CPerlSocket* CreatePerlSocket(CPerlModule* pModule, SV* perlObj) { - return new CPerlSocket(pModule, perlObj); + return new CPerlSocket(pModule, perlObj); } inline bool HaveIPv6() { #ifdef HAVE_IPV6 - return true; + return true; #endif - return false; + return false; } inline bool HaveSSL() { #ifdef HAVE_LIBSSL - return true; + return true; #endif - return false; + return false; } inline bool HaveCharset() { #ifdef HAVE_ICU - return true; + return true; #endif - return false; + return false; } inline int _GetSOMAXCONN() { return SOMAXCONN; } diff --git a/modules/modperl/pstring.h b/modules/modperl/pstring.h index 255bfd0c..3ef11baa 100644 --- a/modules/modperl/pstring.h +++ b/modules/modperl/pstring.h @@ -18,60 +18,60 @@ class PString : public CString { public: - enum EType { STRING, INT, UINT, NUM, BOOL }; + enum EType { STRING, INT, UINT, NUM, BOOL }; - PString() : CString() { m_eType = STRING; } - PString(const char* c) : CString(c) { m_eType = STRING; } - PString(const CString& s) : CString(s) { m_eType = STRING; } - PString(int i) : CString(i) { m_eType = INT; } - PString(u_int i) : CString(i) { m_eType = UINT; } - PString(long i) : CString(i) { m_eType = INT; } - PString(u_long i) : CString(i) { m_eType = UINT; } - PString(long long i) : CString(i) { m_eType = INT; } - PString(unsigned long long i) : CString(i) { m_eType = UINT; } - PString(double i) : CString(i) { m_eType = NUM; } - PString(bool b) : CString((b ? "1" : "0")) { m_eType = BOOL; } - PString(SV* sv) { - STRLEN len = SvCUR(sv); - char* c = SvPV(sv, len); - char* c2 = new char[len + 1]; - memcpy(c2, c, len); - c2[len] = 0; - *this = c2; - delete[] c2; - } + PString() : CString() { m_eType = STRING; } + PString(const char* c) : CString(c) { m_eType = STRING; } + PString(const CString& s) : CString(s) { m_eType = STRING; } + PString(int i) : CString(i) { m_eType = INT; } + PString(u_int i) : CString(i) { m_eType = UINT; } + PString(long i) : CString(i) { m_eType = INT; } + PString(u_long i) : CString(i) { m_eType = UINT; } + PString(long long i) : CString(i) { m_eType = INT; } + PString(unsigned long long i) : CString(i) { m_eType = UINT; } + PString(double i) : CString(i) { m_eType = NUM; } + PString(bool b) : CString((b ? "1" : "0")) { m_eType = BOOL; } + PString(SV* sv) { + STRLEN len = SvCUR(sv); + char* c = SvPV(sv, len); + char* c2 = new char[len + 1]; + memcpy(c2, c, len); + c2[len] = 0; + *this = c2; + delete[] c2; + } - virtual ~PString() {} + virtual ~PString() {} - EType GetType() const { return m_eType; } - void SetType(EType e) { m_eType = e; } + EType GetType() const { return m_eType; } + void SetType(EType e) { m_eType = e; } - SV* GetSV(bool bMakeMortal = true) const { - SV* pSV = nullptr; - switch (GetType()) { - case NUM: - pSV = newSVnv(ToDouble()); - break; - case INT: - pSV = newSViv(ToLongLong()); - break; - case UINT: - case BOOL: - pSV = newSVuv(ToULongLong()); - break; - case STRING: - default: - pSV = newSVpv(data(), length()); - break; - } + SV* GetSV(bool bMakeMortal = true) const { + SV* pSV = nullptr; + switch (GetType()) { + case NUM: + pSV = newSVnv(ToDouble()); + break; + case INT: + pSV = newSViv(ToLongLong()); + break; + case UINT: + case BOOL: + pSV = newSVuv(ToULongLong()); + break; + case STRING: + default: + pSV = newSVpv(data(), length()); + break; + } - if (bMakeMortal) { - pSV = sv_2mortal(pSV); - } + if (bMakeMortal) { + pSV = sv_2mortal(pSV); + } - return pSV; - } + return pSV; + } private: - EType m_eType; + EType m_eType; }; diff --git a/modules/modpython.cpp b/modules/modpython.cpp index 19ef95f0..90272407 100644 --- a/modules/modpython.cpp +++ b/modules/modpython.cpp @@ -32,480 +32,480 @@ using std::vector; using std::set; class CModPython : public CModule { - PyObject* m_PyZNCModule; - PyObject* m_PyFormatException; - vector m_vpObject; + PyObject* m_PyZNCModule; + PyObject* m_PyFormatException; + vector m_vpObject; public: - CString GetPyExceptionStr() { - PyObject* ptype; - PyObject* pvalue; - PyObject* ptraceback; - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - CString result; - if (!pvalue) { - Py_INCREF(Py_None); - pvalue = Py_None; - } - if (!ptraceback) { - Py_INCREF(Py_None); - ptraceback = Py_None; - } - PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); - PyObject* strlist = PyObject_CallFunctionObjArgs( - m_PyFormatException, ptype, pvalue, ptraceback, nullptr); - Py_CLEAR(ptype); - Py_CLEAR(pvalue); - Py_CLEAR(ptraceback); - if (!strlist) { - return "Couldn't get exact error message"; - } + CString GetPyExceptionStr() { + PyObject* ptype; + PyObject* pvalue; + PyObject* ptraceback; + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + CString result; + if (!pvalue) { + Py_INCREF(Py_None); + pvalue = Py_None; + } + if (!ptraceback) { + Py_INCREF(Py_None); + ptraceback = Py_None; + } + PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); + PyObject* strlist = PyObject_CallFunctionObjArgs( + m_PyFormatException, ptype, pvalue, ptraceback, nullptr); + Py_CLEAR(ptype); + Py_CLEAR(pvalue); + Py_CLEAR(ptraceback); + if (!strlist) { + return "Couldn't get exact error message"; + } - if (PySequence_Check(strlist)) { - PyObject* strlist_fast = - PySequence_Fast(strlist, "Shouldn't happen (1)"); - PyObject** items = PySequence_Fast_ITEMS(strlist_fast); - Py_ssize_t L = PySequence_Fast_GET_SIZE(strlist_fast); - for (Py_ssize_t i = 0; i < L; ++i) { - PyObject* utf8 = PyUnicode_AsUTF8String(items[i]); - result += PyBytes_AsString(utf8); - Py_CLEAR(utf8); - } - Py_CLEAR(strlist_fast); - } else { - result = "Can't get exact error message"; - } + if (PySequence_Check(strlist)) { + PyObject* strlist_fast = + PySequence_Fast(strlist, "Shouldn't happen (1)"); + PyObject** items = PySequence_Fast_ITEMS(strlist_fast); + Py_ssize_t L = PySequence_Fast_GET_SIZE(strlist_fast); + for (Py_ssize_t i = 0; i < L; ++i) { + PyObject* utf8 = PyUnicode_AsUTF8String(items[i]); + result += PyBytes_AsString(utf8); + Py_CLEAR(utf8); + } + Py_CLEAR(strlist_fast); + } else { + result = "Can't get exact error message"; + } - Py_CLEAR(strlist); + Py_CLEAR(strlist); - return result; - } + return result; + } - MODCONSTRUCTOR(CModPython) { - Py_Initialize(); - m_PyFormatException = nullptr; - m_PyZNCModule = nullptr; - } + MODCONSTRUCTOR(CModPython) { + Py_Initialize(); + m_PyFormatException = nullptr; + m_PyZNCModule = nullptr; + } - bool OnLoad(const CString& sArgsi, CString& sMessage) override { - CString sModPath, sTmp; + bool OnLoad(const CString& sArgsi, CString& sMessage) override { + CString sModPath, sTmp; #ifdef __CYGWIN__ - CString sDllPath = "modpython/_znc_core.dll"; + CString sDllPath = "modpython/_znc_core.dll"; #else - CString sDllPath = "modpython/_znc_core.so"; + CString sDllPath = "modpython/_znc_core.so"; #endif - if (!CModules::FindModPath(sDllPath, sModPath, sTmp)) { - sMessage = sDllPath + " not found."; - return false; - } - sTmp = CDir::ChangeDir(sModPath, ".."); + if (!CModules::FindModPath(sDllPath, sModPath, sTmp)) { + sMessage = sDllPath + " not found."; + return false; + } + sTmp = CDir::ChangeDir(sModPath, ".."); - PyObject* pyModuleTraceback = PyImport_ImportModule("traceback"); - if (!pyModuleTraceback) { - sMessage = "Couldn't import python module traceback"; - return false; - } - m_PyFormatException = - PyObject_GetAttrString(pyModuleTraceback, "format_exception"); - if (!m_PyFormatException) { - sMessage = "Couldn't get traceback.format_exception"; - Py_CLEAR(pyModuleTraceback); - return false; - } - Py_CLEAR(pyModuleTraceback); + PyObject* pyModuleTraceback = PyImport_ImportModule("traceback"); + if (!pyModuleTraceback) { + sMessage = "Couldn't import python module traceback"; + return false; + } + m_PyFormatException = + PyObject_GetAttrString(pyModuleTraceback, "format_exception"); + if (!m_PyFormatException) { + sMessage = "Couldn't get traceback.format_exception"; + Py_CLEAR(pyModuleTraceback); + return false; + } + Py_CLEAR(pyModuleTraceback); - PyObject* pySysModule = PyImport_ImportModule("sys"); - if (!pySysModule) { - sMessage = GetPyExceptionStr(); - return false; - } - PyObject* pySysPath = PyObject_GetAttrString(pySysModule, "path"); - if (!pySysPath) { - sMessage = GetPyExceptionStr(); - Py_CLEAR(pySysModule); - return false; - } - Py_CLEAR(pySysModule); - PyObject* pyIgnored = - PyObject_CallMethod(pySysPath, const_cast("append"), - const_cast("s"), sTmp.c_str()); - if (!pyIgnored) { - sMessage = GetPyExceptionStr(); - Py_CLEAR(pyIgnored); - return false; - } - Py_CLEAR(pyIgnored); - Py_CLEAR(pySysPath); + PyObject* pySysModule = PyImport_ImportModule("sys"); + if (!pySysModule) { + sMessage = GetPyExceptionStr(); + return false; + } + PyObject* pySysPath = PyObject_GetAttrString(pySysModule, "path"); + if (!pySysPath) { + sMessage = GetPyExceptionStr(); + Py_CLEAR(pySysModule); + return false; + } + Py_CLEAR(pySysModule); + PyObject* pyIgnored = + PyObject_CallMethod(pySysPath, const_cast("append"), + const_cast("s"), sTmp.c_str()); + if (!pyIgnored) { + sMessage = GetPyExceptionStr(); + Py_CLEAR(pyIgnored); + return false; + } + Py_CLEAR(pyIgnored); + Py_CLEAR(pySysPath); - m_PyZNCModule = PyImport_ImportModule("znc"); - if (!m_PyZNCModule) { - sMessage = GetPyExceptionStr(); - return false; - } + m_PyZNCModule = PyImport_ImportModule("znc"); + if (!m_PyZNCModule) { + sMessage = GetPyExceptionStr(); + return false; + } - return true; - } + return true; + } - virtual EModRet OnModuleLoading(const CString& sModName, - const CString& sArgs, - CModInfo::EModuleType eType, bool& bSuccess, - CString& sRetMsg) override { - PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "load_module"); - if (!pyFunc) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - return HALT; - } - PyObject* pyRes = PyObject_CallFunction( - pyFunc, const_cast("ssiNNNN"), sModName.c_str(), - sArgs.c_str(), (int)eType, - (eType == CModInfo::GlobalModule - ? Py_None - : SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0)), - (eType == CModInfo::NetworkModule - ? SWIG_NewInstanceObj(GetNetwork(), - SWIG_TypeQuery("CIRCNetwork*"), 0) - : Py_None), - CPyRetString::wrap(sRetMsg), - SWIG_NewInstanceObj(reinterpret_cast(this), - SWIG_TypeQuery("CModPython*"), 0)); - if (!pyRes) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - Py_CLEAR(pyFunc); - return HALT; - } - Py_CLEAR(pyFunc); - long int ret = PyLong_AsLong(pyRes); - if (PyErr_Occurred()) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - Py_CLEAR(pyRes); - return HALT; - } - Py_CLEAR(pyRes); - switch (ret) { - case 0: - // Not found - return CONTINUE; - case 1: - // Error - bSuccess = false; - return HALT; - case 2: - // Success - bSuccess = true; - return HALT; - } - bSuccess = false; - sRetMsg += " unknown value returned by modpython.load_module"; - return HALT; - } + virtual EModRet OnModuleLoading(const CString& sModName, + const CString& sArgs, + CModInfo::EModuleType eType, bool& bSuccess, + CString& sRetMsg) override { + PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "load_module"); + if (!pyFunc) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + return HALT; + } + PyObject* pyRes = PyObject_CallFunction( + pyFunc, const_cast("ssiNNNN"), sModName.c_str(), + sArgs.c_str(), (int)eType, + (eType == CModInfo::GlobalModule + ? Py_None + : SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0)), + (eType == CModInfo::NetworkModule + ? SWIG_NewInstanceObj(GetNetwork(), + SWIG_TypeQuery("CIRCNetwork*"), 0) + : Py_None), + CPyRetString::wrap(sRetMsg), + SWIG_NewInstanceObj(reinterpret_cast(this), + SWIG_TypeQuery("CModPython*"), 0)); + if (!pyRes) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + Py_CLEAR(pyFunc); + return HALT; + } + Py_CLEAR(pyFunc); + long int ret = PyLong_AsLong(pyRes); + if (PyErr_Occurred()) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + Py_CLEAR(pyRes); + return HALT; + } + Py_CLEAR(pyRes); + switch (ret) { + case 0: + // Not found + return CONTINUE; + case 1: + // Error + bSuccess = false; + return HALT; + case 2: + // Success + bSuccess = true; + return HALT; + } + bSuccess = false; + sRetMsg += " unknown value returned by modpython.load_module"; + return HALT; + } - EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, - CString& sRetMsg) override { - CPyModule* pMod = AsPyModule(pModule); - if (pMod) { - CString sModName = pMod->GetModName(); - PyObject* pyFunc = - PyObject_GetAttrString(m_PyZNCModule, "unload_module"); - if (!pyFunc) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - return HALT; - } - PyObject* pyRes = - PyObject_CallFunctionObjArgs(pyFunc, pMod->GetPyObj(), nullptr); - if (!pyRes) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - Py_CLEAR(pyFunc); - return HALT; - } - if (!PyObject_IsTrue(pyRes)) { - // python module, but not handled by modpython itself. - // some module-provider written on python loaded it? - return CONTINUE; - } - Py_CLEAR(pyFunc); - Py_CLEAR(pyRes); - bSuccess = true; - sRetMsg = "Module [" + sModName + "] unloaded"; - return HALT; - } - return CONTINUE; - } + EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, + CString& sRetMsg) override { + CPyModule* pMod = AsPyModule(pModule); + if (pMod) { + CString sModName = pMod->GetModName(); + PyObject* pyFunc = + PyObject_GetAttrString(m_PyZNCModule, "unload_module"); + if (!pyFunc) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + return HALT; + } + PyObject* pyRes = + PyObject_CallFunctionObjArgs(pyFunc, pMod->GetPyObj(), nullptr); + if (!pyRes) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + Py_CLEAR(pyFunc); + return HALT; + } + if (!PyObject_IsTrue(pyRes)) { + // python module, but not handled by modpython itself. + // some module-provider written on python loaded it? + return CONTINUE; + } + Py_CLEAR(pyFunc); + Py_CLEAR(pyRes); + bSuccess = true; + sRetMsg = "Module [" + sModName + "] unloaded"; + return HALT; + } + return CONTINUE; + } - virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, - bool& bSuccess, CString& sRetMsg) override { - PyObject* pyFunc = - PyObject_GetAttrString(m_PyZNCModule, "get_mod_info"); - if (!pyFunc) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - return HALT; - } - PyObject* pyRes = PyObject_CallFunction( - pyFunc, const_cast("sNN"), sModule.c_str(), - CPyRetString::wrap(sRetMsg), - SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0)); - if (!pyRes) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - Py_CLEAR(pyFunc); - return HALT; - } - Py_CLEAR(pyFunc); - long int x = PyLong_AsLong(pyRes); - if (PyErr_Occurred()) { - sRetMsg = GetPyExceptionStr(); - DEBUG("modpython: " << sRetMsg); - bSuccess = false; - Py_CLEAR(pyRes); - return HALT; - } - Py_CLEAR(pyRes); - switch (x) { - case 0: - return CONTINUE; - case 1: - bSuccess = false; - return HALT; - case 2: - bSuccess = true; - return HALT; - } - bSuccess = false; - sRetMsg = CString("Shouldn't happen. ") + __PRETTY_FUNCTION__ + " on " + - __FILE__ + ":" + CString(__LINE__); - DEBUG(sRetMsg); - return HALT; - } + virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, + bool& bSuccess, CString& sRetMsg) override { + PyObject* pyFunc = + PyObject_GetAttrString(m_PyZNCModule, "get_mod_info"); + if (!pyFunc) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + return HALT; + } + PyObject* pyRes = PyObject_CallFunction( + pyFunc, const_cast("sNN"), sModule.c_str(), + CPyRetString::wrap(sRetMsg), + SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0)); + if (!pyRes) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + Py_CLEAR(pyFunc); + return HALT; + } + Py_CLEAR(pyFunc); + long int x = PyLong_AsLong(pyRes); + if (PyErr_Occurred()) { + sRetMsg = GetPyExceptionStr(); + DEBUG("modpython: " << sRetMsg); + bSuccess = false; + Py_CLEAR(pyRes); + return HALT; + } + Py_CLEAR(pyRes); + switch (x) { + case 0: + return CONTINUE; + case 1: + bSuccess = false; + return HALT; + case 2: + bSuccess = true; + return HALT; + } + bSuccess = false; + sRetMsg = CString("Shouldn't happen. ") + __PRETTY_FUNCTION__ + " on " + + __FILE__ + ":" + CString(__LINE__); + DEBUG(sRetMsg); + return HALT; + } - void TryAddModInfo(const CString& sPath, const CString& sName, - set& ssMods, set& ssAlready, - CModInfo::EModuleType eType) { - if (ssAlready.count(sName)) { - return; - } - PyObject* pyFunc = - PyObject_GetAttrString(m_PyZNCModule, "get_mod_info_path"); - if (!pyFunc) { - CString sRetMsg = GetPyExceptionStr(); - DEBUG("modpython tried to get info about [" - << sPath << "] (1) but: " << sRetMsg); - return; - } - CModInfo ModInfo; - PyObject* pyRes = PyObject_CallFunction( - pyFunc, const_cast("ssN"), sPath.c_str(), sName.c_str(), - SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0)); - if (!pyRes) { - CString sRetMsg = GetPyExceptionStr(); - DEBUG("modpython tried to get info about [" - << sPath << "] (2) but: " << sRetMsg); - Py_CLEAR(pyFunc); - return; - } - Py_CLEAR(pyFunc); - long int x = PyLong_AsLong(pyRes); - if (PyErr_Occurred()) { - CString sRetMsg = GetPyExceptionStr(); - DEBUG("modpython tried to get info about [" - << sPath << "] (3) but: " << sRetMsg); - Py_CLEAR(pyRes); - return; - } - Py_CLEAR(pyRes); - if (x && ModInfo.SupportsType(eType)) { - ssMods.insert(ModInfo); - ssAlready.insert(sName); - } - } + void TryAddModInfo(const CString& sPath, const CString& sName, + set& ssMods, set& ssAlready, + CModInfo::EModuleType eType) { + if (ssAlready.count(sName)) { + return; + } + PyObject* pyFunc = + PyObject_GetAttrString(m_PyZNCModule, "get_mod_info_path"); + if (!pyFunc) { + CString sRetMsg = GetPyExceptionStr(); + DEBUG("modpython tried to get info about [" + << sPath << "] (1) but: " << sRetMsg); + return; + } + CModInfo ModInfo; + PyObject* pyRes = PyObject_CallFunction( + pyFunc, const_cast("ssN"), sPath.c_str(), sName.c_str(), + SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0)); + if (!pyRes) { + CString sRetMsg = GetPyExceptionStr(); + DEBUG("modpython tried to get info about [" + << sPath << "] (2) but: " << sRetMsg); + Py_CLEAR(pyFunc); + return; + } + Py_CLEAR(pyFunc); + long int x = PyLong_AsLong(pyRes); + if (PyErr_Occurred()) { + CString sRetMsg = GetPyExceptionStr(); + DEBUG("modpython tried to get info about [" + << sPath << "] (3) but: " << sRetMsg); + Py_CLEAR(pyRes); + return; + } + Py_CLEAR(pyRes); + if (x && ModInfo.SupportsType(eType)) { + ssMods.insert(ModInfo); + ssAlready.insert(sName); + } + } - void OnGetAvailableMods(set& ssMods, - CModInfo::EModuleType eType) override { - CDir Dir; - CModules::ModDirList dirs = CModules::GetModDirs(); + void OnGetAvailableMods(set& ssMods, + CModInfo::EModuleType eType) override { + CDir Dir; + CModules::ModDirList dirs = CModules::GetModDirs(); - while (!dirs.empty()) { - set already; + while (!dirs.empty()) { + set already; - Dir.Fill(dirs.front().first); - for (unsigned int a = 0; a < Dir.size(); a++) { - CFile& File = *Dir[a]; - CString sName = File.GetShortName(); - CString sPath = File.GetLongName(); - sPath.TrimSuffix(sName); + Dir.Fill(dirs.front().first); + for (unsigned int a = 0; a < Dir.size(); a++) { + CFile& File = *Dir[a]; + CString sName = File.GetShortName(); + CString sPath = File.GetLongName(); + sPath.TrimSuffix(sName); - if (!File.IsDir()) { - if (sName.WildCmp("*.pyc")) { - sName.RightChomp(4); - } else if (sName.WildCmp("*.py") || sName.WildCmp("*.so")) { - sName.RightChomp(3); - } else { - continue; - } - } + if (!File.IsDir()) { + if (sName.WildCmp("*.pyc")) { + sName.RightChomp(4); + } else if (sName.WildCmp("*.py") || sName.WildCmp("*.so")) { + sName.RightChomp(3); + } else { + continue; + } + } - TryAddModInfo(sPath, sName, ssMods, already, eType); - } + TryAddModInfo(sPath, sName, ssMods, already, eType); + } - dirs.pop(); - } - } + dirs.pop(); + } + } - virtual ~CModPython() { - if (!m_PyZNCModule) { - DEBUG( - "~CModPython(): seems like CModPython::OnLoad() didn't " - "initialize python"); - return; - } - PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "unload_all"); - if (!pyFunc) { - CString sRetMsg = GetPyExceptionStr(); - DEBUG("~CModPython(): couldn't find unload_all: " << sRetMsg); - return; - } - PyObject* pyRes = PyObject_CallFunctionObjArgs(pyFunc, nullptr); - if (!pyRes) { - CString sRetMsg = GetPyExceptionStr(); - DEBUG( - "modpython tried to unload all modules in its destructor, but: " - << sRetMsg); - } - Py_CLEAR(pyRes); - Py_CLEAR(pyFunc); + virtual ~CModPython() { + if (!m_PyZNCModule) { + DEBUG( + "~CModPython(): seems like CModPython::OnLoad() didn't " + "initialize python"); + return; + } + PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "unload_all"); + if (!pyFunc) { + CString sRetMsg = GetPyExceptionStr(); + DEBUG("~CModPython(): couldn't find unload_all: " << sRetMsg); + return; + } + PyObject* pyRes = PyObject_CallFunctionObjArgs(pyFunc, nullptr); + if (!pyRes) { + CString sRetMsg = GetPyExceptionStr(); + DEBUG( + "modpython tried to unload all modules in its destructor, but: " + << sRetMsg); + } + Py_CLEAR(pyRes); + Py_CLEAR(pyFunc); - Py_CLEAR(m_PyFormatException); - Py_CLEAR(m_PyZNCModule); - Py_Finalize(); - } + Py_CLEAR(m_PyFormatException); + Py_CLEAR(m_PyZNCModule); + Py_Finalize(); + } }; CString CPyModule::GetPyExceptionStr() { - return m_pModPython->GetPyExceptionStr(); + return m_pModPython->GetPyExceptionStr(); } #include "modpython/functions.cpp" VWebSubPages& CPyModule::GetSubPages() { - VWebSubPages* result = _GetSubPages(); - if (!result) { - return CModule::GetSubPages(); - } - return *result; + VWebSubPages* result = _GetSubPages(); + if (!result) { + return CModule::GetSubPages(); + } + return *result; } void CPyTimer::RunJob() { - CPyModule* pMod = AsPyModule(GetModule()); - if (pMod) { - PyObject* pyRes = PyObject_CallMethod( - m_pyObj, const_cast("RunJob"), const_cast("")); - if (!pyRes) { - CString sRetMsg = m_pModPython->GetPyExceptionStr(); - DEBUG("python timer failed: " << sRetMsg); - Stop(); - } - Py_CLEAR(pyRes); - } + CPyModule* pMod = AsPyModule(GetModule()); + if (pMod) { + PyObject* pyRes = PyObject_CallMethod( + m_pyObj, const_cast("RunJob"), const_cast("")); + if (!pyRes) { + CString sRetMsg = m_pModPython->GetPyExceptionStr(); + DEBUG("python timer failed: " << sRetMsg); + Stop(); + } + Py_CLEAR(pyRes); + } } CPyTimer::~CPyTimer() { - CPyModule* pMod = AsPyModule(GetModule()); - if (pMod) { - PyObject* pyRes = PyObject_CallMethod( - m_pyObj, const_cast("OnShutdown"), const_cast("")); - if (!pyRes) { - CString sRetMsg = m_pModPython->GetPyExceptionStr(); - DEBUG("python timer shutdown failed: " << sRetMsg); - } - Py_CLEAR(pyRes); - Py_CLEAR(m_pyObj); - } + CPyModule* pMod = AsPyModule(GetModule()); + if (pMod) { + PyObject* pyRes = PyObject_CallMethod( + m_pyObj, const_cast("OnShutdown"), const_cast("")); + if (!pyRes) { + CString sRetMsg = m_pModPython->GetPyExceptionStr(); + DEBUG("python timer shutdown failed: " << sRetMsg); + } + Py_CLEAR(pyRes); + Py_CLEAR(m_pyObj); + } } #define CHECKCLEARSOCK(Func) \ - if (!pyRes) { \ - CString sRetMsg = m_pModPython->GetPyExceptionStr(); \ - DEBUG("python socket failed in " Func ": " << sRetMsg); \ - Close(); \ - } \ - Py_CLEAR(pyRes) + if (!pyRes) { \ + CString sRetMsg = m_pModPython->GetPyExceptionStr(); \ + DEBUG("python socket failed in " Func ": " << sRetMsg); \ + Close(); \ + } \ + Py_CLEAR(pyRes) #define CBSOCK(Func) \ - void CPySocket::Func() { \ - PyObject* pyRes = PyObject_CallMethod( \ - m_pyObj, const_cast("On" #Func), const_cast("")); \ - CHECKCLEARSOCK(#Func); \ - } + void CPySocket::Func() { \ + PyObject* pyRes = PyObject_CallMethod( \ + m_pyObj, const_cast("On" #Func), const_cast("")); \ + CHECKCLEARSOCK(#Func); \ + } CBSOCK(Connected); CBSOCK(Disconnected); CBSOCK(Timeout); CBSOCK(ConnectionRefused); void CPySocket::ReadData(const char* data, size_t len) { - PyObject* pyRes = - PyObject_CallMethod(m_pyObj, const_cast("OnReadData"), - const_cast("y#"), data, (int)len); - CHECKCLEARSOCK("OnReadData"); + PyObject* pyRes = + PyObject_CallMethod(m_pyObj, const_cast("OnReadData"), + const_cast("y#"), data, (int)len); + CHECKCLEARSOCK("OnReadData"); } void CPySocket::ReadLine(const CString& sLine) { - PyObject* pyRes = - PyObject_CallMethod(m_pyObj, const_cast("OnReadLine"), - const_cast("s"), sLine.c_str()); - CHECKCLEARSOCK("OnReadLine"); + PyObject* pyRes = + PyObject_CallMethod(m_pyObj, const_cast("OnReadLine"), + const_cast("s"), sLine.c_str()); + CHECKCLEARSOCK("OnReadLine"); } Csock* CPySocket::GetSockObj(const CString& sHost, unsigned short uPort) { - CPySocket* result = nullptr; - PyObject* pyRes = - PyObject_CallMethod(m_pyObj, const_cast("_Accepted"), - const_cast("sH"), sHost.c_str(), uPort); - if (!pyRes) { - CString sRetMsg = m_pModPython->GetPyExceptionStr(); - DEBUG("python socket failed in OnAccepted: " << sRetMsg); - Close(); - } - int res = SWIG_ConvertPtr(pyRes, (void**)&result, - SWIG_TypeQuery("CPySocket*"), 0); - if (!SWIG_IsOK(res)) { - DEBUG( - "python socket was expected to return new socket from OnAccepted, " - "but error=" - << res); - Close(); - result = nullptr; - } - if (!result) { - DEBUG("modpython: OnAccepted didn't return new socket"); - } - Py_CLEAR(pyRes); - return result; + CPySocket* result = nullptr; + PyObject* pyRes = + PyObject_CallMethod(m_pyObj, const_cast("_Accepted"), + const_cast("sH"), sHost.c_str(), uPort); + if (!pyRes) { + CString sRetMsg = m_pModPython->GetPyExceptionStr(); + DEBUG("python socket failed in OnAccepted: " << sRetMsg); + Close(); + } + int res = SWIG_ConvertPtr(pyRes, (void**)&result, + SWIG_TypeQuery("CPySocket*"), 0); + if (!SWIG_IsOK(res)) { + DEBUG( + "python socket was expected to return new socket from OnAccepted, " + "but error=" + << res); + Close(); + result = nullptr; + } + if (!result) { + DEBUG("modpython: OnAccepted didn't return new socket"); + } + Py_CLEAR(pyRes); + return result; } CPySocket::~CPySocket() { - PyObject* pyRes = PyObject_CallMethod( - m_pyObj, const_cast("OnShutdown"), const_cast("")); - if (!pyRes) { - CString sRetMsg = m_pModPython->GetPyExceptionStr(); - DEBUG("python socket failed in OnShutdown: " << sRetMsg); - } - Py_CLEAR(pyRes); - Py_CLEAR(m_pyObj); + PyObject* pyRes = PyObject_CallMethod( + m_pyObj, const_cast("OnShutdown"), const_cast("")); + if (!pyRes) { + CString sRetMsg = m_pModPython->GetPyExceptionStr(); + DEBUG("python socket failed in OnShutdown: " << sRetMsg); + } + Py_CLEAR(pyRes); + Py_CLEAR(m_pyObj); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("modpython"); + Info.SetWikiPage("modpython"); } GLOBALMODULEDEFS(CModPython, "Loads python scripts as ZNC modules") diff --git a/modules/modpython/module.h b/modules/modpython/module.h index 0faec88f..535facf8 100644 --- a/modules/modpython/module.h +++ b/modules/modpython/module.h @@ -20,9 +20,9 @@ // __str__ is added to it in modpython.i class String { public: - CString s; + CString s; - String(const CString& s = "") : s(s) {} + String(const CString& s = "") : s(s) {} }; class CModPython; @@ -31,180 +31,180 @@ class CModPython; #pragma GCC visibility push(default) #endif class CPyModule : public CModule { - PyObject* m_pyObj; - CModPython* m_pModPython; - VWebSubPages* _GetSubPages(); + PyObject* m_pyObj; + CModPython* m_pModPython; + VWebSubPages* _GetSubPages(); public: - CPyModule(CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, - const CString& sDataPath, CModInfo::EModuleType eType, - PyObject* pyObj, CModPython* pModPython) - : CModule(nullptr, pUser, pNetwork, sModName, sDataPath, eType) { - m_pyObj = pyObj; - Py_INCREF(pyObj); - m_pModPython = pModPython; - } - PyObject* GetPyObj() { // borrows - return m_pyObj; - } - PyObject* GetNewPyObj() { - Py_INCREF(m_pyObj); - return m_pyObj; - } - void DeletePyModule() { - Py_CLEAR(m_pyObj); - delete this; - } - CString GetPyExceptionStr(); - CModPython* GetModPython() { return m_pModPython; } + CPyModule(CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, + const CString& sDataPath, CModInfo::EModuleType eType, + PyObject* pyObj, CModPython* pModPython) + : CModule(nullptr, pUser, pNetwork, sModName, sDataPath, eType) { + m_pyObj = pyObj; + Py_INCREF(pyObj); + m_pModPython = pModPython; + } + PyObject* GetPyObj() { // borrows + return m_pyObj; + } + PyObject* GetNewPyObj() { + Py_INCREF(m_pyObj); + return m_pyObj; + } + void DeletePyModule() { + Py_CLEAR(m_pyObj); + delete this; + } + CString GetPyExceptionStr(); + CModPython* GetModPython() { return m_pModPython; } - bool OnBoot() override; - bool WebRequiresLogin() override; - bool WebRequiresAdmin() override; - CString GetWebMenuTitle() override; - bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) override; - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override; - VWebSubPages& GetSubPages() override; - void OnPreRehash() override; - void OnPostRehash() override; - void OnIRCDisconnected() override; - void OnIRCConnected() override; - EModRet OnIRCConnecting(CIRCSock* pIRCSock) override; - void OnIRCConnectionError(CIRCSock* pIRCSock) override; - EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, - CString& sRealName) override; - EModRet OnBroadcast(CString& sMessage) override; - void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, bool bAdded, - bool bNoChange) override; - void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override; - void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, bool bNoChange) override; - void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override; - EModRet OnRaw(CString& sLine) override; - EModRet OnStatusCommand(CString& sCommand) override; - void OnModCommand(const CString& sCommand) override; - void OnModNotice(const CString& sMessage) override; - void OnModCTCP(const CString& sMessage) override; - void OnQuit(const CNick& Nick, const CString& sMessage, - const std::vector& vChans) override; - void OnNick(const CNick& Nick, const CString& sNewNick, - const std::vector& vChans) override; - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override; - EModRet OnJoining(CChan& Channel) override; - void OnJoin(const CNick& Nick, CChan& Channel) override; - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override; - EModRet OnChanBufferStarting(CChan& Chan, CClient& Client) override; - EModRet OnChanBufferEnding(CChan& Chan, CClient& Client) override; - EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, - CString& sLine) override; - EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine) override; - void OnClientLogin() override; - void OnClientDisconnect() override; - EModRet OnUserRaw(CString& sLine) override; - EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override; - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override; - EModRet OnUserAction(CString& sTarget, CString& sMessage) override; - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; - EModRet OnUserJoin(CString& sChannel, CString& sKey) override; - EModRet OnUserPart(CString& sChannel, CString& sMessage) override; - EModRet OnUserTopic(CString& sChannel, CString& sTopic) override; - EModRet OnUserTopicRequest(CString& sChannel) override; - EModRet OnUserQuit(CString& sMessage) override; - EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override; - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override; - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override; - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override; - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override; - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; - bool OnServerCapAvailable(const CString& sCap) override; - void OnServerCapResult(const CString& sCap, bool bSuccess) override; - EModRet OnTimerAutoJoin(CChan& Channel) override; - bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&) override; - EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) override; - EModRet OnDeleteNetwork(CIRCNetwork& Network) override; - EModRet OnSendToClient(CString& sLine, CClient& Client) override; - EModRet OnSendToIRC(CString& sLine) override; + bool OnBoot() override; + bool WebRequiresLogin() override; + bool WebRequiresAdmin() override; + CString GetWebMenuTitle() override; + bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) override; + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override; + VWebSubPages& GetSubPages() override; + void OnPreRehash() override; + void OnPostRehash() override; + void OnIRCDisconnected() override; + void OnIRCConnected() override; + EModRet OnIRCConnecting(CIRCSock* pIRCSock) override; + void OnIRCConnectionError(CIRCSock* pIRCSock) override; + EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, + CString& sRealName) override; + EModRet OnBroadcast(CString& sMessage) override; + void OnChanPermission2(const CNick* pOpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, bool bAdded, + bool bNoChange) override; + void OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override; + void OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, bool bNoChange) override; + void OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override; + EModRet OnRaw(CString& sLine) override; + EModRet OnStatusCommand(CString& sCommand) override; + void OnModCommand(const CString& sCommand) override; + void OnModNotice(const CString& sMessage) override; + void OnModCTCP(const CString& sMessage) override; + void OnQuit(const CNick& Nick, const CString& sMessage, + const std::vector& vChans) override; + void OnNick(const CNick& Nick, const CString& sNewNick, + const std::vector& vChans) override; + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override; + EModRet OnJoining(CChan& Channel) override; + void OnJoin(const CNick& Nick, CChan& Channel) override; + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override; + EModRet OnChanBufferStarting(CChan& Chan, CClient& Client) override; + EModRet OnChanBufferEnding(CChan& Chan, CClient& Client) override; + EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, + CString& sLine) override; + EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine) override; + void OnClientLogin() override; + void OnClientDisconnect() override; + EModRet OnUserRaw(CString& sLine) override; + EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override; + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override; + EModRet OnUserAction(CString& sTarget, CString& sMessage) override; + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override; + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override; + EModRet OnUserJoin(CString& sChannel, CString& sKey) override; + EModRet OnUserPart(CString& sChannel, CString& sMessage) override; + EModRet OnUserTopic(CString& sChannel, CString& sTopic) override; + EModRet OnUserTopicRequest(CString& sChannel) override; + EModRet OnUserQuit(CString& sMessage) override; + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override; + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override; + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override; + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override; + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override; + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override; + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override; + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override; + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override; + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override; + bool OnServerCapAvailable(const CString& sCap) override; + void OnServerCapResult(const CString& sCap, bool bSuccess) override; + EModRet OnTimerAutoJoin(CChan& Channel) override; + bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&) override; + EModRet OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) override; + EModRet OnDeleteNetwork(CIRCNetwork& Network) override; + EModRet OnSendToClient(CString& sLine, CClient& Client) override; + EModRet OnSendToIRC(CString& sLine) override; - EModRet OnRawMessage(CMessage& Message) override; - EModRet OnNumericMessage(CNumericMessage& Message) override; - void OnQuitMessage(CQuitMessage& Message, - const std::vector& vChans) override; - void OnNickMessage(CNickMessage& Message, - const std::vector& vChans) override; - void OnKickMessage(CKickMessage& Message) override; - void OnJoinMessage(CJoinMessage& Message) override; - void OnPartMessage(CPartMessage& Message) override; - EModRet OnChanBufferPlayMessage(CMessage& Message) override; - EModRet OnPrivBufferPlayMessage(CMessage& Message) override; - EModRet OnUserRawMessage(CMessage& Message) override; - EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override; - EModRet OnUserCTCPMessage(CCTCPMessage& Message) override; - EModRet OnUserActionMessage(CActionMessage& Message) override; - EModRet OnUserTextMessage(CTextMessage& Message) override; - EModRet OnUserNoticeMessage(CNoticeMessage& Message) override; - EModRet OnUserJoinMessage(CJoinMessage& Message) override; - EModRet OnUserPartMessage(CPartMessage& Message) override; - EModRet OnUserTopicMessage(CTopicMessage& Message) override; - EModRet OnUserQuitMessage(CQuitMessage& Message) override; - EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override; - EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override; - EModRet OnChanCTCPMessage(CCTCPMessage& Message) override; - EModRet OnPrivActionMessage(CActionMessage& Message) override; - EModRet OnChanActionMessage(CActionMessage& Message) override; - EModRet OnPrivMessage(CTextMessage& Message) override; - EModRet OnChanMessage(CTextMessage& Message) override; - EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override; - EModRet OnChanNoticeMessage(CNoticeMessage& Message) override; - EModRet OnTopicMessage(CTopicMessage& Message) override; + EModRet OnRawMessage(CMessage& Message) override; + EModRet OnNumericMessage(CNumericMessage& Message) override; + void OnQuitMessage(CQuitMessage& Message, + const std::vector& vChans) override; + void OnNickMessage(CNickMessage& Message, + const std::vector& vChans) override; + void OnKickMessage(CKickMessage& Message) override; + void OnJoinMessage(CJoinMessage& Message) override; + void OnPartMessage(CPartMessage& Message) override; + EModRet OnChanBufferPlayMessage(CMessage& Message) override; + EModRet OnPrivBufferPlayMessage(CMessage& Message) override; + EModRet OnUserRawMessage(CMessage& Message) override; + EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override; + EModRet OnUserCTCPMessage(CCTCPMessage& Message) override; + EModRet OnUserActionMessage(CActionMessage& Message) override; + EModRet OnUserTextMessage(CTextMessage& Message) override; + EModRet OnUserNoticeMessage(CNoticeMessage& Message) override; + EModRet OnUserJoinMessage(CJoinMessage& Message) override; + EModRet OnUserPartMessage(CPartMessage& Message) override; + EModRet OnUserTopicMessage(CTopicMessage& Message) override; + EModRet OnUserQuitMessage(CQuitMessage& Message) override; + EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override; + EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override; + EModRet OnChanCTCPMessage(CCTCPMessage& Message) override; + EModRet OnPrivActionMessage(CActionMessage& Message) override; + EModRet OnChanActionMessage(CActionMessage& Message) override; + EModRet OnPrivMessage(CTextMessage& Message) override; + EModRet OnChanMessage(CTextMessage& Message) override; + EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override; + EModRet OnChanNoticeMessage(CNoticeMessage& Message) override; + EModRet OnTopicMessage(CTopicMessage& Message) override; - // Global Modules - EModRet OnAddUser(CUser& User, CString& sErrorRet) override; - EModRet OnDeleteUser(CUser& User) override; - void OnClientConnect(CZNCSock* pSock, const CString& sHost, - unsigned short uPort) override; - void OnFailedLogin(const CString& sUsername, - const CString& sRemoteIP) override; - EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine) override; - EModRet OnUnknownUserRawMessage(CMessage& Message) override; - bool IsClientCapSupported(CClient* pClient, const CString& sCap, - bool bState) override; - void OnClientCapRequest(CClient* pClient, const CString& sCap, - bool bState) override; - virtual EModRet OnModuleLoading(const CString& sModName, - const CString& sArgs, - CModInfo::EModuleType eType, bool& bSuccess, - CString& sRetMsg) override; - EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, - CString& sRetMsg) override; - virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, - bool& bSuccess, CString& sRetMsg) override; - void OnGetAvailableMods(std::set& ssMods, - CModInfo::EModuleType eType) override; - void OnClientCapLs(CClient* pClient, SCString& ssCaps) override; - EModRet OnLoginAttempt(std::shared_ptr Auth) override; + // Global Modules + EModRet OnAddUser(CUser& User, CString& sErrorRet) override; + EModRet OnDeleteUser(CUser& User) override; + void OnClientConnect(CZNCSock* pSock, const CString& sHost, + unsigned short uPort) override; + void OnFailedLogin(const CString& sUsername, + const CString& sRemoteIP) override; + EModRet OnUnknownUserRaw(CClient* pClient, CString& sLine) override; + EModRet OnUnknownUserRawMessage(CMessage& Message) override; + bool IsClientCapSupported(CClient* pClient, const CString& sCap, + bool bState) override; + void OnClientCapRequest(CClient* pClient, const CString& sCap, + bool bState) override; + virtual EModRet OnModuleLoading(const CString& sModName, + const CString& sArgs, + CModInfo::EModuleType eType, bool& bSuccess, + CString& sRetMsg) override; + EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, + CString& sRetMsg) override; + virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, + bool& bSuccess, CString& sRetMsg) override; + void OnGetAvailableMods(std::set& ssMods, + CModInfo::EModuleType eType) override; + void OnClientCapLs(CClient* pClient, SCString& ssCaps) override; + EModRet OnLoginAttempt(std::shared_ptr Auth) override; }; static inline CPyModule* AsPyModule(CModule* p) { - return dynamic_cast(p); + return dynamic_cast(p); } inline CPyModule* CreatePyModule(CUser* pUser, CIRCNetwork* pNetwork, @@ -212,88 +212,88 @@ inline CPyModule* CreatePyModule(CUser* pUser, CIRCNetwork* pNetwork, const CString& sDataPath, CModInfo::EModuleType eType, PyObject* pyObj, CModPython* pModPython) { - return new CPyModule(pUser, pNetwork, sModName, sDataPath, eType, pyObj, - pModPython); + return new CPyModule(pUser, pNetwork, sModName, sDataPath, eType, pyObj, + pModPython); } class CPyTimer : public CTimer { - PyObject* m_pyObj; - CModPython* m_pModPython; + PyObject* m_pyObj; + CModPython* m_pModPython; public: - CPyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription, - PyObject* pyObj) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), - m_pyObj(pyObj) { - Py_INCREF(pyObj); - pModule->AddTimer(this); - m_pModPython = pModule->GetModPython(); - } - void RunJob() override; - PyObject* GetPyObj() { return m_pyObj; } - PyObject* GetNewPyObj() { - Py_INCREF(m_pyObj); - return m_pyObj; - } - ~CPyTimer(); + CPyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription, + PyObject* pyObj) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), + m_pyObj(pyObj) { + Py_INCREF(pyObj); + pModule->AddTimer(this); + m_pModPython = pModule->GetModPython(); + } + void RunJob() override; + PyObject* GetPyObj() { return m_pyObj; } + PyObject* GetNewPyObj() { + Py_INCREF(m_pyObj); + return m_pyObj; + } + ~CPyTimer(); }; inline CPyTimer* CreatePyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription, PyObject* pyObj) { - return new CPyTimer(pModule, uInterval, uCycles, sLabel, sDescription, - pyObj); + return new CPyTimer(pModule, uInterval, uCycles, sLabel, sDescription, + pyObj); } class CPySocket : public CSocket { - PyObject* m_pyObj; - CModPython* m_pModPython; + PyObject* m_pyObj; + CModPython* m_pModPython; public: - CPySocket(CPyModule* pModule, PyObject* pyObj) - : CSocket(pModule), m_pyObj(pyObj) { - Py_INCREF(pyObj); - m_pModPython = pModule->GetModPython(); - } - PyObject* GetPyObj() { return m_pyObj; } - PyObject* GetNewPyObj() { - Py_INCREF(m_pyObj); - return m_pyObj; - } - ~CPySocket(); - void Connected() override; - void Disconnected() override; - void Timeout() override; - void ConnectionRefused() override; - void ReadData(const char* data, size_t len) override; - void ReadLine(const CString& sLine) override; - Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; + CPySocket(CPyModule* pModule, PyObject* pyObj) + : CSocket(pModule), m_pyObj(pyObj) { + Py_INCREF(pyObj); + m_pModPython = pModule->GetModPython(); + } + PyObject* GetPyObj() { return m_pyObj; } + PyObject* GetNewPyObj() { + Py_INCREF(m_pyObj); + return m_pyObj; + } + ~CPySocket(); + void Connected() override; + void Disconnected() override; + void Timeout() override; + void ConnectionRefused() override; + void ReadData(const char* data, size_t len) override; + void ReadLine(const CString& sLine) override; + Csock* GetSockObj(const CString& sHost, unsigned short uPort) override; }; inline CPySocket* CreatePySocket(CPyModule* pModule, PyObject* pyObj) { - return new CPySocket(pModule, pyObj); + return new CPySocket(pModule, pyObj); } inline bool HaveIPv6_() { #ifdef HAVE_IPV6 - return true; + return true; #endif - return false; + return false; } inline bool HaveSSL_() { #ifdef HAVE_LIBSSL - return true; + return true; #endif - return false; + return false; } inline bool HaveCharset_() { #ifdef HAVE_ICU - return true; + return true; #endif - return false; + return false; } inline int GetSOMAXCONN() { return SOMAXCONN; } @@ -308,29 +308,29 @@ inline CString GetVersionExtra() { return ZNC_VERSION_EXTRA; } class MCString_iter { public: - MCString_iter() {} - MCString::iterator x; - MCString_iter(MCString::iterator z) : x(z) {} - void plusplus() { ++x; } - CString get() { return x->first; } - bool is_end(CModule* m) { return m->EndNV() == x; } + MCString_iter() {} + MCString::iterator x; + MCString_iter(MCString::iterator z) : x(z) {} + void plusplus() { ++x; } + CString get() { return x->first; } + bool is_end(CModule* m) { return m->EndNV() == x; } }; class CModulesIter { public: - CModulesIter(CModules* pModules) { - m_pModules = pModules; - m_it = pModules->begin(); - } + CModulesIter(CModules* pModules) { + m_pModules = pModules; + m_it = pModules->begin(); + } - void plusplus() { ++m_it; } + void plusplus() { ++m_it; } - const CModule* get() const { return *m_it; } + const CModule* get() const { return *m_it; } - bool is_end() const { return m_pModules->end() == m_it; } + bool is_end() const { return m_pModules->end() == m_it; } - CModules* m_pModules; - CModules::const_iterator m_it; + CModules* m_pModules; + CModules::const_iterator m_it; }; #if HAVE_VISIBILITY diff --git a/modules/modpython/ret.h b/modules/modpython/ret.h index 7a114758..fe7c8614 100644 --- a/modules/modpython/ret.h +++ b/modules/modpython/ret.h @@ -18,22 +18,22 @@ class CPyRetString { public: - CString& s; - CPyRetString(CString& S) : s(S) {} - static PyObject* wrap(CString& S) { - CPyRetString* x = new CPyRetString(S); - return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetString*"), - SWIG_POINTER_OWN); - } + CString& s; + CPyRetString(CString& S) : s(S) {} + static PyObject* wrap(CString& S) { + CPyRetString* x = new CPyRetString(S); + return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetString*"), + SWIG_POINTER_OWN); + } }; class CPyRetBool { public: - bool& b; - CPyRetBool(bool& B) : b(B) {} - static PyObject* wrap(bool& B) { - CPyRetBool* x = new CPyRetBool(B); - return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetBool*"), - SWIG_POINTER_OWN); - } + bool& b; + CPyRetBool(bool& B) : b(B) {} + static PyObject* wrap(bool& B) { + CPyRetBool* x = new CPyRetBool(B); + return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetBool*"), + SWIG_POINTER_OWN); + } }; diff --git a/modules/modtcl.cpp b/modules/modtcl.cpp index 72df6a32..c6c7a714 100644 --- a/modules/modtcl.cpp +++ b/modules/modtcl.cpp @@ -28,520 +28,520 @@ using std::map; #define STDVAR (ClientData cd, Tcl_Interp * irp, int argc, const char* argv[]) #define BADARGS(nl, nh, example) \ - do { \ - if ((argc < (nl)) || (argc > (nh))) { \ - Tcl_AppendResult(irp, "wrong # args: should be \"", argv[0], \ - (example), "\"", nullptr); \ - return TCL_ERROR; \ - } \ - } while (0) + do { \ + if ((argc < (nl)) || (argc > (nh))) { \ + Tcl_AppendResult(irp, "wrong # args: should be \"", argv[0], \ + (example), "\"", nullptr); \ + return TCL_ERROR; \ + } \ + } while (0) class CModTcl; class CModTclTimer : public CTimer { public: - CModTclTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), - m_pParent(nullptr) {} - virtual ~CModTclTimer() {} + CModTclTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), + m_pParent(nullptr) {} + virtual ~CModTclTimer() {} protected: - void RunJob() override; - CModTcl* m_pParent; + void RunJob() override; + CModTcl* m_pParent; }; class CModTclStartTimer : public CTimer { public: - CModTclStartTimer(CModule* pModule, unsigned int uInterval, - unsigned int uCycles, const CString& sLabel, - const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), - m_pParent(nullptr) {} - virtual ~CModTclStartTimer() {} + CModTclStartTimer(CModule* pModule, unsigned int uInterval, + unsigned int uCycles, const CString& sLabel, + const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription), + m_pParent(nullptr) {} + virtual ~CModTclStartTimer() {} protected: - void RunJob() override; - CModTcl* m_pParent; + void RunJob() override; + CModTcl* m_pParent; }; class CModTcl : public CModule { public: - MODCONSTRUCTOR(CModTcl) { interp = nullptr; } + MODCONSTRUCTOR(CModTcl) { interp = nullptr; } - virtual ~CModTcl() { - if (interp) { - Tcl_DeleteInterp(interp); - } - } + virtual ~CModTcl() { + if (interp) { + Tcl_DeleteInterp(interp); + } + } - bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { + bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { #ifndef MOD_MODTCL_ALLOW_EVERYONE - if (!GetUser()->IsAdmin()) { - sErrorMsg = "You must be admin to use the modtcl module"; - return false; - } + if (!GetUser()->IsAdmin()) { + sErrorMsg = "You must be admin to use the modtcl module"; + return false; + } #endif - AddTimer( - new CModTclStartTimer(this, 1, 1, "ModTclStarter", - "Timer for modtcl to load the interpreter.")); - return true; - } + AddTimer( + new CModTclStartTimer(this, 1, 1, "ModTclStarter", + "Timer for modtcl to load the interpreter.")); + return true; + } - void Start() { - CString sMyArgs = GetArgs(); + void Start() { + CString sMyArgs = GetArgs(); - interp = Tcl_CreateInterp(); - Tcl_Init(interp); - Tcl_CreateCommand(interp, "Binds::ProcessPubm", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "Binds::ProcessMsgm", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "Binds::ProcessTime", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "Binds::ProcessEvnt", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "Binds::ProcessNick", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "Binds::ProcessKick", tcl_Bind, this, - nullptr); - Tcl_CreateCommand(interp, "PutIRC", tcl_PutIRC, this, nullptr); - Tcl_CreateCommand(interp, "PutModule", tcl_PutModule, this, nullptr); - Tcl_CreateCommand(interp, "PutStatus", tcl_PutStatus, this, nullptr); - Tcl_CreateCommand(interp, "PutStatusNotice", tcl_PutStatusNotice, this, - nullptr); - Tcl_CreateCommand(interp, "PutUser", tcl_PutUser, this, nullptr); + interp = Tcl_CreateInterp(); + Tcl_Init(interp); + Tcl_CreateCommand(interp, "Binds::ProcessPubm", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "Binds::ProcessMsgm", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "Binds::ProcessTime", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "Binds::ProcessEvnt", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "Binds::ProcessNick", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "Binds::ProcessKick", tcl_Bind, this, + nullptr); + Tcl_CreateCommand(interp, "PutIRC", tcl_PutIRC, this, nullptr); + Tcl_CreateCommand(interp, "PutModule", tcl_PutModule, this, nullptr); + Tcl_CreateCommand(interp, "PutStatus", tcl_PutStatus, this, nullptr); + Tcl_CreateCommand(interp, "PutStatusNotice", tcl_PutStatusNotice, this, + nullptr); + Tcl_CreateCommand(interp, "PutUser", tcl_PutUser, this, nullptr); - Tcl_CreateCommand(interp, "GetCurNick", tcl_GetCurNick, this, nullptr); - Tcl_CreateCommand(interp, "GetUsername", tcl_GetUsername, this, - nullptr); - Tcl_CreateCommand(interp, "GetRealName", tcl_GetRealName, this, - nullptr); - Tcl_CreateCommand(interp, "GetVHost", tcl_GetBindHost, this, nullptr); - Tcl_CreateCommand(interp, "GetBindHost", tcl_GetBindHost, this, - nullptr); - Tcl_CreateCommand(interp, "GetChans", tcl_GetChans, this, nullptr); - Tcl_CreateCommand(interp, "GetChannelUsers", tcl_GetChannelUsers, this, - nullptr); - Tcl_CreateCommand(interp, "GetChannelModes", tcl_GetChannelModes, this, - nullptr); - Tcl_CreateCommand(interp, "GetServer", tcl_GetServer, this, nullptr); - Tcl_CreateCommand(interp, "GetServerOnline", tcl_GetServerOnline, this, - nullptr); - Tcl_CreateCommand(interp, "GetModules", tcl_GetModules, this, nullptr); - Tcl_CreateCommand(interp, "GetClientCount", tcl_GetClientCount, this, - nullptr); + Tcl_CreateCommand(interp, "GetCurNick", tcl_GetCurNick, this, nullptr); + Tcl_CreateCommand(interp, "GetUsername", tcl_GetUsername, this, + nullptr); + Tcl_CreateCommand(interp, "GetRealName", tcl_GetRealName, this, + nullptr); + Tcl_CreateCommand(interp, "GetVHost", tcl_GetBindHost, this, nullptr); + Tcl_CreateCommand(interp, "GetBindHost", tcl_GetBindHost, this, + nullptr); + Tcl_CreateCommand(interp, "GetChans", tcl_GetChans, this, nullptr); + Tcl_CreateCommand(interp, "GetChannelUsers", tcl_GetChannelUsers, this, + nullptr); + Tcl_CreateCommand(interp, "GetChannelModes", tcl_GetChannelModes, this, + nullptr); + Tcl_CreateCommand(interp, "GetServer", tcl_GetServer, this, nullptr); + Tcl_CreateCommand(interp, "GetServerOnline", tcl_GetServerOnline, this, + nullptr); + Tcl_CreateCommand(interp, "GetModules", tcl_GetModules, this, nullptr); + Tcl_CreateCommand(interp, "GetClientCount", tcl_GetClientCount, this, + nullptr); - Tcl_CreateCommand(interp, "exit", tcl_exit, this, nullptr); + Tcl_CreateCommand(interp, "exit", tcl_exit, this, nullptr); - if (!sMyArgs.empty()) { - i = Tcl_EvalFile(interp, sMyArgs.c_str()); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - } + if (!sMyArgs.empty()) { + i = Tcl_EvalFile(interp, sMyArgs.c_str()); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + } - AddTimer(new CModTclTimer( - this, 1, 0, "ModTclUpdate", - "Timer for modtcl to process pending events and idle callbacks.")); - } + AddTimer(new CModTclTimer( + this, 1, 0, "ModTclUpdate", + "Timer for modtcl to process pending events and idle callbacks.")); + } - void OnModCommand(const CString& sCommand) override { - CString sResult; - VCString vsResult; - CString sCmd = sCommand; + void OnModCommand(const CString& sCommand) override { + CString sResult; + VCString vsResult; + CString sCmd = sCommand; - if (sCmd.Token(0).CaseCmp(".tcl") == 0) sCmd = sCmd.Token(1, true); + if (sCmd.Token(0).CaseCmp(".tcl") == 0) sCmd = sCmd.Token(1, true); - if (sCmd.Left(1).CaseCmp(".") == 0) - sCmd = "Binds::ProcessDcc - - {" + sCmd + "}"; + if (sCmd.Left(1).CaseCmp(".") == 0) + sCmd = "Binds::ProcessDcc - - {" + sCmd + "}"; - Tcl_Eval(interp, sCmd.c_str()); + Tcl_Eval(interp, sCmd.c_str()); - sResult = CString(Tcl_GetStringResult(interp)); - if (!sResult.empty()) { - sResult.Split("\n", vsResult); - unsigned int a = 0; - for (a = 0; a < vsResult.size(); a++) - PutModule(vsResult[a].TrimRight_n()); - } - } + sResult = CString(Tcl_GetStringResult(interp)); + if (!sResult.empty()) { + sResult.Split("\n", vsResult); + unsigned int a = 0; + for (a = 0; a < vsResult.size(); a++) + PutModule(vsResult[a].TrimRight_n()); + } + } - void TclUpdate() { - while (Tcl_DoOneEvent(TCL_DONT_WAIT)) { - } - i = Tcl_Eval(interp, "Binds::ProcessTime"); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - } + void TclUpdate() { + while (Tcl_DoOneEvent(TCL_DONT_WAIT)) { + } + i = Tcl_Eval(interp, "Binds::ProcessTime"); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + } - CString TclEscape(CString sLine) { - sLine.Replace("\\", "\\\\"); - sLine.Replace("{", "\\{"); - sLine.Replace("}", "\\}"); - return sLine; - } + CString TclEscape(CString sLine) { + sLine.Replace("\\", "\\\\"); + sLine.Replace("{", "\\{"); + sLine.Replace("}", "\\}"); + return sLine; + } - void OnPreRehash() override { - if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt prerehash"); - } + void OnPreRehash() override { + if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt prerehash"); + } - void OnPostRehash() override { - if (interp) { - Tcl_Eval(interp, "rehash"); - Tcl_Eval(interp, "Binds::ProcessEvnt rehash"); - } - } + void OnPostRehash() override { + if (interp) { + Tcl_Eval(interp, "rehash"); + Tcl_Eval(interp, "Binds::ProcessEvnt rehash"); + } + } - void OnIRCConnected() override { - if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt init-server"); - } + void OnIRCConnected() override { + if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt init-server"); + } - void OnIRCDisconnected() override { - if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt disconnect-server"); - } + void OnIRCDisconnected() override { + if (interp) Tcl_Eval(interp, "Binds::ProcessEvnt disconnect-server"); + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - CString sMes = TclEscape(sMessage); - CString sNick = TclEscape(CString(Nick.GetNick())); - CString sHost = - TclEscape(CString(Nick.GetIdent() + "@" + Nick.GetHost())); - CString sChannel = TclEscape(CString(Channel.GetName())); + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + CString sMes = TclEscape(sMessage); + CString sNick = TclEscape(CString(Nick.GetNick())); + CString sHost = + TclEscape(CString(Nick.GetIdent() + "@" + Nick.GetHost())); + CString sChannel = TclEscape(CString(Channel.GetName())); - CString sCommand = "Binds::ProcessPubm {" + sNick + "} {" + sHost + - "} - {" + sChannel + "} {" + sMes + "}"; - i = Tcl_Eval(interp, sCommand.c_str()); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - return CONTINUE; - } + CString sCommand = "Binds::ProcessPubm {" + sNick + "} {" + sHost + + "} - {" + sChannel + "} {" + sMes + "}"; + i = Tcl_Eval(interp, sCommand.c_str()); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - CString sMes = TclEscape(sMessage); - CString sNick = TclEscape(CString(Nick.GetNick())); - CString sHost = - TclEscape(CString(Nick.GetIdent() + "@" + Nick.GetHost())); + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + CString sMes = TclEscape(sMessage); + CString sNick = TclEscape(CString(Nick.GetNick())); + CString sHost = + TclEscape(CString(Nick.GetIdent() + "@" + Nick.GetHost())); - CString sCommand = "Binds::ProcessMsgm {" + sNick + "} {" + sHost + - "} - {" + sMes + "}"; - i = Tcl_Eval(interp, sCommand.c_str()); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - return CONTINUE; - } + CString sCommand = "Binds::ProcessMsgm {" + sNick + "} {" + sHost + + "} - {" + sMes + "}"; + i = Tcl_Eval(interp, sCommand.c_str()); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + return CONTINUE; + } - void OnNick(const CNick& OldNick, const CString& sNewNick, - const vector& vChans) override { - CString sOldNick = TclEscape(CString(OldNick.GetNick())); - CString sNewNickTmp = TclEscape(sNewNick); - CString sHost = - TclEscape(CString(OldNick.GetIdent() + "@" + OldNick.GetHost())); + void OnNick(const CNick& OldNick, const CString& sNewNick, + const vector& vChans) override { + CString sOldNick = TclEscape(CString(OldNick.GetNick())); + CString sNewNickTmp = TclEscape(sNewNick); + CString sHost = + TclEscape(CString(OldNick.GetIdent() + "@" + OldNick.GetHost())); - CString sCommand; - // Nick change is triggered for each common chan so that binds can be - // chan specific - unsigned int nLength = vChans.size(); - for (unsigned int n = 0; n < nLength; n++) { - sCommand = "Binds::ProcessNick {" + sOldNick + "} {" + sHost + - "} - {" + vChans[n]->GetName() + "} {" + sNewNickTmp + - "}"; - i = Tcl_Eval(interp, sCommand.c_str()); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - } - } + CString sCommand; + // Nick change is triggered for each common chan so that binds can be + // chan specific + unsigned int nLength = vChans.size(); + for (unsigned int n = 0; n < nLength; n++) { + sCommand = "Binds::ProcessNick {" + sOldNick + "} {" + sHost + + "} - {" + vChans[n]->GetName() + "} {" + sNewNickTmp + + "}"; + i = Tcl_Eval(interp, sCommand.c_str()); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + } + } - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override { - CString sOpNick = TclEscape(CString(OpNick.GetNick())); - CString sNick = TclEscape(sKickedNick); - CString sOpHost = - TclEscape(CString(OpNick.GetIdent() + "@" + OpNick.GetHost())); + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override { + CString sOpNick = TclEscape(CString(OpNick.GetNick())); + CString sNick = TclEscape(sKickedNick); + CString sOpHost = + TclEscape(CString(OpNick.GetIdent() + "@" + OpNick.GetHost())); - CString sCommand = "Binds::ProcessKick {" + sOpNick + "} {" + sOpHost + - "} - {" + Channel.GetName() + "} {" + sNick + "} {" + - sMessage + "}"; - i = Tcl_Eval(interp, sCommand.c_str()); - if (i != TCL_OK) { - PutModule(Tcl_GetStringResult(interp)); - } - } + CString sCommand = "Binds::ProcessKick {" + sOpNick + "} {" + sOpHost + + "} - {" + Channel.GetName() + "} {" + sNick + "} {" + + sMessage + "}"; + i = Tcl_Eval(interp, sCommand.c_str()); + if (i != TCL_OK) { + PutModule(Tcl_GetStringResult(interp)); + } + } private: - Tcl_Interp* interp; - int i; + Tcl_Interp* interp; + int i; - static CString argvit(const char* argv[], unsigned int end, - unsigned int begin, CString delim) { - CString sRet; - unsigned int i; - if (begin < end) sRet = CString(argv[begin]); + static CString argvit(const char* argv[], unsigned int end, + unsigned int begin, CString delim) { + CString sRet; + unsigned int i; + if (begin < end) sRet = CString(argv[begin]); - for (i = begin + 1; i < end; i++) { - sRet = sRet + delim + CString(argv[i]); - } + for (i = begin + 1; i < end; i++) { + sRet = sRet + delim + CString(argv[i]); + } - return sRet; - } + return sRet; + } - // Placeholder for binds incase binds.tcl isn't used - static int tcl_Bind STDVAR { return TCL_OK; } + // Placeholder for binds incase binds.tcl isn't used + static int tcl_Bind STDVAR { return TCL_OK; } - static int tcl_GetCurNick STDVAR { - CModTcl* mod = static_cast(cd); - Tcl_SetResult(irp, (char*)mod->GetNetwork()->GetCurNick().c_str(), - TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetCurNick STDVAR { + CModTcl* mod = static_cast(cd); + Tcl_SetResult(irp, (char*)mod->GetNetwork()->GetCurNick().c_str(), + TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetUsername STDVAR { - CModTcl* mod = static_cast(cd); - Tcl_SetResult(irp, (char*)mod->GetUser()->GetUserName().c_str(), - TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetUsername STDVAR { + CModTcl* mod = static_cast(cd); + Tcl_SetResult(irp, (char*)mod->GetUser()->GetUserName().c_str(), + TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetRealName STDVAR { - CModTcl* mod = static_cast(cd); - Tcl_SetResult(irp, (char*)mod->GetUser()->GetRealName().c_str(), - TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetRealName STDVAR { + CModTcl* mod = static_cast(cd); + Tcl_SetResult(irp, (char*)mod->GetUser()->GetRealName().c_str(), + TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetBindHost STDVAR { - CModTcl* mod = static_cast(cd); - Tcl_SetResult(irp, (char*)mod->GetUser()->GetBindHost().c_str(), - TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetBindHost STDVAR { + CModTcl* mod = static_cast(cd); + Tcl_SetResult(irp, (char*)mod->GetUser()->GetBindHost().c_str(), + TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetChans STDVAR { - char* p; - const char* l[1]; - CModTcl* mod = static_cast(cd); + static int tcl_GetChans STDVAR { + char* p; + const char* l[1]; + CModTcl* mod = static_cast(cd); - BADARGS(1, 1, ""); + BADARGS(1, 1, ""); - const vector& Channels = mod->GetNetwork()->GetChans(); - for (unsigned int c = 0; c < Channels.size(); c++) { - CChan* pChan = Channels[c]; - l[0] = pChan->GetName().c_str(); - p = Tcl_Merge(1, l); - Tcl_AppendElement(irp, p); - Tcl_Free((char*)p); - } + const vector& Channels = mod->GetNetwork()->GetChans(); + for (unsigned int c = 0; c < Channels.size(); c++) { + CChan* pChan = Channels[c]; + l[0] = pChan->GetName().c_str(); + p = Tcl_Merge(1, l); + Tcl_AppendElement(irp, p); + Tcl_Free((char*)p); + } - return TCL_OK; - } + return TCL_OK; + } - static int tcl_GetChannelUsers STDVAR { - char* p; - const char* l[4]; - CModTcl* mod = static_cast(cd); + static int tcl_GetChannelUsers STDVAR { + char* p; + const char* l[4]; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " channel"); + BADARGS(2, 999, " channel"); - CString sChannel = argvit(argv, argc, 1, " "); - CChan* pChannel = mod->GetNetwork()->FindChan(sChannel); + CString sChannel = argvit(argv, argc, 1, " "); + CChan* pChannel = mod->GetNetwork()->FindChan(sChannel); - if (!pChannel) { - CString sMsg = "invalid channel: " + sChannel; - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_ERROR; - } + if (!pChannel) { + CString sMsg = "invalid channel: " + sChannel; + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_ERROR; + } - const map& msNicks = pChannel->GetNicks(); - for (map::const_iterator it = msNicks.begin(); - it != msNicks.end(); ++it) { - const CNick& Nick = it->second; - l[0] = (Nick.GetNick()).c_str(); - l[1] = (Nick.GetIdent()).c_str(); - l[2] = (Nick.GetHost()).c_str(); - l[3] = (Nick.GetPermStr()).c_str(); - p = Tcl_Merge(4, l); - Tcl_AppendElement(irp, p); - Tcl_Free((char*)p); - } + const map& msNicks = pChannel->GetNicks(); + for (map::const_iterator it = msNicks.begin(); + it != msNicks.end(); ++it) { + const CNick& Nick = it->second; + l[0] = (Nick.GetNick()).c_str(); + l[1] = (Nick.GetIdent()).c_str(); + l[2] = (Nick.GetHost()).c_str(); + l[3] = (Nick.GetPermStr()).c_str(); + p = Tcl_Merge(4, l); + Tcl_AppendElement(irp, p); + Tcl_Free((char*)p); + } - return TCL_OK; - } + return TCL_OK; + } - static int tcl_GetChannelModes STDVAR { - CModTcl* mod = static_cast(cd); + static int tcl_GetChannelModes STDVAR { + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " channel"); + BADARGS(2, 999, " channel"); - CString sChannel = argvit(argv, argc, 1, " "); - CChan* pChannel = mod->GetNetwork()->FindChan(sChannel); - CString sMsg; + CString sChannel = argvit(argv, argc, 1, " "); + CChan* pChannel = mod->GetNetwork()->FindChan(sChannel); + CString sMsg; - if (!pChannel) { - sMsg = "invalid channel: " + sChannel; - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_ERROR; - } + if (!pChannel) { + sMsg = "invalid channel: " + sChannel; + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_ERROR; + } - sMsg = pChannel->GetModeString(); - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_OK; - } + sMsg = pChannel->GetModeString(); + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetServer STDVAR { - CModTcl* mod = static_cast(cd); - CServer* pServer = mod->GetNetwork()->GetCurrentServer(); - CString sMsg; - if (pServer) - sMsg = pServer->GetName() + ":" + CString(pServer->GetPort()); - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetServer STDVAR { + CModTcl* mod = static_cast(cd); + CServer* pServer = mod->GetNetwork()->GetCurrentServer(); + CString sMsg; + if (pServer) + sMsg = pServer->GetName() + ":" + CString(pServer->GetPort()); + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetServerOnline STDVAR { - CModTcl* mod = static_cast(cd); - CIRCSock* pIRCSock = mod->GetNetwork()->GetIRCSock(); - CString sMsg = "0"; - if (pIRCSock) sMsg = CString(pIRCSock->GetStartTime()); - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetServerOnline STDVAR { + CModTcl* mod = static_cast(cd); + CIRCSock* pIRCSock = mod->GetNetwork()->GetIRCSock(); + CString sMsg = "0"; + if (pIRCSock) sMsg = CString(pIRCSock->GetStartTime()); + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_OK; + } - static int tcl_GetModules STDVAR { - char* p; - const char* l[3]; - CModTcl* mod = static_cast(cd); + static int tcl_GetModules STDVAR { + char* p; + const char* l[3]; + CModTcl* mod = static_cast(cd); - BADARGS(1, 1, ""); + BADARGS(1, 1, ""); - CModules& GModules = CZNC::Get().GetModules(); - CModules& Modules = mod->GetUser()->GetModules(); + CModules& GModules = CZNC::Get().GetModules(); + CModules& Modules = mod->GetUser()->GetModules(); - for (unsigned int b = 0; b < GModules.size(); b++) { - l[0] = GModules[b]->GetModName().c_str(); - l[1] = GModules[b]->GetArgs().c_str(); - l[2] = "1"; // IsGlobal - p = Tcl_Merge(3, l); - Tcl_AppendElement(irp, p); - Tcl_Free((char*)p); - } - for (unsigned int b = 0; b < Modules.size(); b++) { - l[0] = Modules[b]->GetModName().c_str(); - l[1] = Modules[b]->GetArgs().c_str(); - l[2] = "0"; // IsGlobal - p = Tcl_Merge(3, l); - Tcl_AppendElement(irp, p); - Tcl_Free((char*)p); - } + for (unsigned int b = 0; b < GModules.size(); b++) { + l[0] = GModules[b]->GetModName().c_str(); + l[1] = GModules[b]->GetArgs().c_str(); + l[2] = "1"; // IsGlobal + p = Tcl_Merge(3, l); + Tcl_AppendElement(irp, p); + Tcl_Free((char*)p); + } + for (unsigned int b = 0; b < Modules.size(); b++) { + l[0] = Modules[b]->GetModName().c_str(); + l[1] = Modules[b]->GetArgs().c_str(); + l[2] = "0"; // IsGlobal + p = Tcl_Merge(3, l); + Tcl_AppendElement(irp, p); + Tcl_Free((char*)p); + } - return TCL_OK; - } + return TCL_OK; + } - static int tcl_GetClientCount STDVAR { - CModTcl* mod = static_cast(cd); - Tcl_SetResult( - irp, (char*)CString(mod->GetNetwork()->GetClients().size()).c_str(), - TCL_VOLATILE); - return TCL_OK; - } + static int tcl_GetClientCount STDVAR { + CModTcl* mod = static_cast(cd); + Tcl_SetResult( + irp, (char*)CString(mod->GetNetwork()->GetClients().size()).c_str(), + TCL_VOLATILE); + return TCL_OK; + } - static int tcl_PutIRC STDVAR { - CString sMsg; - CModTcl* mod = static_cast(cd); + static int tcl_PutIRC STDVAR { + CString sMsg; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " string"); - sMsg = argvit(argv, argc, 1, " "); - mod->GetNetwork()->PutIRC(sMsg); - return TCL_OK; - } + BADARGS(2, 999, " string"); + sMsg = argvit(argv, argc, 1, " "); + mod->GetNetwork()->PutIRC(sMsg); + return TCL_OK; + } - static int tcl_PutModule STDVAR { - CString sMsg; - VCString vsMsg; - CModTcl* mod = static_cast(cd); + static int tcl_PutModule STDVAR { + CString sMsg; + VCString vsMsg; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " string"); - sMsg = argvit(argv, argc, 1, " "); - // mod->PutModule(sMsg); - sMsg.Split("\n", vsMsg); - unsigned int a = 0; - for (a = 0; a < vsMsg.size(); a++) - mod->PutModule(vsMsg[a].TrimRight_n()); - return TCL_OK; - } + BADARGS(2, 999, " string"); + sMsg = argvit(argv, argc, 1, " "); + // mod->PutModule(sMsg); + sMsg.Split("\n", vsMsg); + unsigned int a = 0; + for (a = 0; a < vsMsg.size(); a++) + mod->PutModule(vsMsg[a].TrimRight_n()); + return TCL_OK; + } - static int tcl_PutStatus STDVAR { - CString sMsg; - CModTcl* mod = static_cast(cd); + static int tcl_PutStatus STDVAR { + CString sMsg; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " string"); - sMsg = argvit(argv, argc, 1, " "); - mod->PutStatus(sMsg); - return TCL_OK; - } + BADARGS(2, 999, " string"); + sMsg = argvit(argv, argc, 1, " "); + mod->PutStatus(sMsg); + return TCL_OK; + } - static int tcl_PutStatusNotice STDVAR { - CString sMsg; - CModTcl* mod = static_cast(cd); + static int tcl_PutStatusNotice STDVAR { + CString sMsg; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " string"); - sMsg = argvit(argv, argc, 1, " "); - mod->GetUser()->PutStatusNotice(sMsg); - return TCL_OK; - } + BADARGS(2, 999, " string"); + sMsg = argvit(argv, argc, 1, " "); + mod->GetUser()->PutStatusNotice(sMsg); + return TCL_OK; + } - static int tcl_PutUser STDVAR { - CString sMsg; - CModTcl* mod = static_cast(cd); + static int tcl_PutUser STDVAR { + CString sMsg; + CModTcl* mod = static_cast(cd); - BADARGS(2, 999, " string"); - sMsg = argvit(argv, argc, 1, " "); - mod->GetUser()->PutUser(sMsg); - return TCL_OK; - } + BADARGS(2, 999, " string"); + sMsg = argvit(argv, argc, 1, " "); + mod->GetUser()->PutUser(sMsg); + return TCL_OK; + } - static int tcl_exit STDVAR { - CString sMsg; - CModTcl* mod = static_cast(cd); + static int tcl_exit STDVAR { + CString sMsg; + CModTcl* mod = static_cast(cd); - BADARGS(1, 2, " ?reason?"); + BADARGS(1, 2, " ?reason?"); - if (!mod->GetUser()->IsAdmin()) { - sMsg = "You need to be administrator to shutdown the bnc."; - Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); - return TCL_ERROR; - } - if (argc > 1) { - sMsg = argvit(argv, argc, 1, " "); - CZNC::Get().Broadcast(sMsg); - usleep(100000); // Sleep for 10ms to attempt to allow the previous - // Broadcast() to go through to all users - } + if (!mod->GetUser()->IsAdmin()) { + sMsg = "You need to be administrator to shutdown the bnc."; + Tcl_SetResult(irp, (char*)sMsg.c_str(), TCL_VOLATILE); + return TCL_ERROR; + } + if (argc > 1) { + sMsg = argvit(argv, argc, 1, " "); + CZNC::Get().Broadcast(sMsg); + usleep(100000); // Sleep for 10ms to attempt to allow the previous + // Broadcast() to go through to all users + } - throw CException(CException::EX_Shutdown); + throw CException(CException::EX_Shutdown); - return TCL_OK; - } + return TCL_OK; + } }; void CModTclTimer::RunJob() { - CModTcl* p = (CModTcl*)GetModule(); - if (p) p->TclUpdate(); + CModTcl* p = (CModTcl*)GetModule(); + if (p) p->TclUpdate(); } void CModTclStartTimer::RunJob() { - CModTcl* p = (CModTcl*)GetModule(); - if (p) p->Start(); + CModTcl* p = (CModTcl*)GetModule(); + if (p) p->Start(); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("modtcl"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Absolute path to modtcl.tcl file"); + Info.SetWikiPage("modtcl"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("Absolute path to modtcl.tcl file"); } NETWORKMODULEDEFS(CModTcl, "Loads Tcl scripts as ZNC modules") diff --git a/modules/modules_online.cpp b/modules/modules_online.cpp index d9a6d421..f5b5132f 100644 --- a/modules/modules_online.cpp +++ b/modules/modules_online.cpp @@ -20,98 +20,98 @@ class CFOModule : public CModule { public: - MODCONSTRUCTOR(CFOModule) {} - virtual ~CFOModule() {} + MODCONSTRUCTOR(CFOModule) {} + virtual ~CFOModule() {} - bool IsOnlineModNick(const CString& sNick) { - const CString& sPrefix = GetUser()->GetStatusPrefix(); - if (!sNick.StartsWith(sPrefix)) return false; + bool IsOnlineModNick(const CString& sNick) { + const CString& sPrefix = GetUser()->GetStatusPrefix(); + if (!sNick.StartsWith(sPrefix)) return false; - CString sModNick = sNick.substr(sPrefix.length()); - if (sModNick.Equals("status") || - GetNetwork()->GetModules().FindModule(sModNick) || - GetUser()->GetModules().FindModule(sModNick) || - CZNC::Get().GetModules().FindModule(sModNick)) - return true; - return false; - } + CString sModNick = sNick.substr(sPrefix.length()); + if (sModNick.Equals("status") || + GetNetwork()->GetModules().FindModule(sModNick) || + GetUser()->GetModules().FindModule(sModNick) || + CZNC::Get().GetModules().FindModule(sModNick)) + return true; + return false; + } - EModRet OnUserRaw(CString& sLine) override { - // Handle ISON - if (sLine.Token(0).Equals("ison")) { - VCString vsNicks; + EModRet OnUserRaw(CString& sLine) override { + // Handle ISON + if (sLine.Token(0).Equals("ison")) { + VCString vsNicks; - // Get the list of nicks which are being asked for - sLine.Token(1, true).TrimLeft_n(":").Split(" ", vsNicks, false); + // Get the list of nicks which are being asked for + sLine.Token(1, true).TrimLeft_n(":").Split(" ", vsNicks, false); - CString sBNCNicks; - for (const CString& sNick : vsNicks) { - if (IsOnlineModNick(sNick)) { - sBNCNicks += " " + sNick; - } - } - // Remove the leading space - sBNCNicks.LeftChomp(); + CString sBNCNicks; + for (const CString& sNick : vsNicks) { + if (IsOnlineModNick(sNick)) { + sBNCNicks += " " + sNick; + } + } + // Remove the leading space + sBNCNicks.LeftChomp(); - if (!GetNetwork()->GetIRCSock()) { - // if we are not connected to any IRC server, send - // an empty or module-nick filled response. - PutUser(":irc.znc.in 303 " + GetClient()->GetNick() + " :" + - sBNCNicks); - } else { - // We let the server handle this request and then act on - // the 303 response from the IRC server. - m_ISONRequests.push_back(sBNCNicks); - } - } + if (!GetNetwork()->GetIRCSock()) { + // if we are not connected to any IRC server, send + // an empty or module-nick filled response. + PutUser(":irc.znc.in 303 " + GetClient()->GetNick() + " :" + + sBNCNicks); + } else { + // We let the server handle this request and then act on + // the 303 response from the IRC server. + m_ISONRequests.push_back(sBNCNicks); + } + } - // Handle WHOIS - if (sLine.Token(0).Equals("whois")) { - CString sNick = sLine.Token(1); + // Handle WHOIS + if (sLine.Token(0).Equals("whois")) { + CString sNick = sLine.Token(1); - if (IsOnlineModNick(sNick)) { - CIRCNetwork* pNetwork = GetNetwork(); - PutUser(":znc.in 311 " + pNetwork->GetCurNick() + " " + sNick + - " znc znc.in * :" + sNick); - PutUser(":znc.in 312 " + pNetwork->GetCurNick() + " " + sNick + - " *.znc.in :Bouncer"); - PutUser(":znc.in 318 " + pNetwork->GetCurNick() + " " + sNick + - " :End of /WHOIS list."); + if (IsOnlineModNick(sNick)) { + CIRCNetwork* pNetwork = GetNetwork(); + PutUser(":znc.in 311 " + pNetwork->GetCurNick() + " " + sNick + + " znc znc.in * :" + sNick); + PutUser(":znc.in 312 " + pNetwork->GetCurNick() + " " + sNick + + " *.znc.in :Bouncer"); + PutUser(":znc.in 318 " + pNetwork->GetCurNick() + " " + sNick + + " :End of /WHOIS list."); - return HALT; - } - } + return HALT; + } + } - return CONTINUE; - } + return CONTINUE; + } - EModRet OnRaw(CString& sLine) override { - // Handle 303 reply if m_Requests is not empty - if (sLine.Token(1) == "303" && !m_ISONRequests.empty()) { - VCString::iterator it = m_ISONRequests.begin(); + EModRet OnRaw(CString& sLine) override { + // Handle 303 reply if m_Requests is not empty + if (sLine.Token(1) == "303" && !m_ISONRequests.empty()) { + VCString::iterator it = m_ISONRequests.begin(); - sLine.Trim(); + sLine.Trim(); - // Only append a space if this isn't an empty reply - if (sLine.Right(1) != ":") { - sLine += " "; - } + // Only append a space if this isn't an empty reply + if (sLine.Right(1) != ":") { + sLine += " "; + } - // add BNC nicks to the reply - sLine += *it; - m_ISONRequests.erase(it); - } + // add BNC nicks to the reply + sLine += *it; + m_ISONRequests.erase(it); + } - return CONTINUE; - } + return CONTINUE; + } private: - VCString m_ISONRequests; + VCString m_ISONRequests; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("modules_online"); + Info.SetWikiPage("modules_online"); } NETWORKMODULEDEFS(CFOModule, "Make ZNC's *modules to be \"online\".") diff --git a/modules/nickserv.cpp b/modules/nickserv.cpp index 1c87d075..fcc0fea7 100644 --- a/modules/nickserv.cpp +++ b/modules/nickserv.cpp @@ -18,126 +18,126 @@ #include class CNickServ : public CModule { - void DoNickCommand(const CString& sCmd, const CString& sNick) { - MCString msValues; - msValues["nickname"] = sNick; - msValues["password"] = GetNV("Password"); - PutIRC(CString::NamedFormat(GetNV(sCmd), msValues)); - } + void DoNickCommand(const CString& sCmd, const CString& sNick) { + MCString msValues; + msValues["nickname"] = sNick; + msValues["password"] = GetNV("Password"); + PutIRC(CString::NamedFormat(GetNV(sCmd), msValues)); + } public: - void SetCommand(const CString& sLine) { - SetNV("Password", sLine.Token(1, true)); - PutModule("Password set"); - } + void SetCommand(const CString& sLine) { + SetNV("Password", sLine.Token(1, true)); + PutModule("Password set"); + } - void ClearCommand(const CString& sLine) { DelNV("Password"); } + void ClearCommand(const CString& sLine) { DelNV("Password"); } - void SetNSNameCommand(const CString& sLine) { - SetNV("NickServName", sLine.Token(1, true)); - PutModule("NickServ name set"); - } + void SetNSNameCommand(const CString& sLine) { + SetNV("NickServName", sLine.Token(1, true)); + PutModule("NickServ name set"); + } - void ClearNSNameCommand(const CString& sLine) { DelNV("NickServName"); } + void ClearNSNameCommand(const CString& sLine) { DelNV("NickServName"); } - void ViewCommandsCommand(const CString& sLine) { - PutModule("IDENTIFY " + GetNV("IdentifyCmd")); - } + void ViewCommandsCommand(const CString& sLine) { + PutModule("IDENTIFY " + GetNV("IdentifyCmd")); + } - void SetCommandCommand(const CString& sLine) { - CString sCmd = sLine.Token(1); - CString sNewCmd = sLine.Token(2, true); - if (sCmd.Equals("IDENTIFY")) { - SetNV("IdentifyCmd", sNewCmd); - } else { - PutModule("No such editable command. See ViewCommands for list."); - return; - } - PutModule("Ok"); - } + void SetCommandCommand(const CString& sLine) { + CString sCmd = sLine.Token(1); + CString sNewCmd = sLine.Token(2, true); + if (sCmd.Equals("IDENTIFY")) { + SetNV("IdentifyCmd", sNewCmd); + } else { + PutModule("No such editable command. See ViewCommands for list."); + return; + } + PutModule("Ok"); + } - MODCONSTRUCTOR(CNickServ) { - AddHelpCommand(); - AddCommand("Set", - static_cast(&CNickServ::SetCommand), - "password"); - AddCommand("Clear", static_cast( - &CNickServ::ClearCommand), - "", "Clear your nickserv password"); - AddCommand("SetNSName", static_cast( - &CNickServ::SetNSNameCommand), - "nickname", - "Set NickServ name (Useful on networks like EpiKnet, where " - "NickServ is named Themis)"); - AddCommand("ClearNSName", static_cast( - &CNickServ::ClearNSNameCommand), - "", "Reset NickServ name to default (NickServ)"); - AddCommand("ViewCommands", static_cast( - &CNickServ::ViewCommandsCommand), - "", - "Show patterns for lines, which are being sent to NickServ"); - AddCommand("SetCommand", static_cast( - &CNickServ::SetCommandCommand), - "cmd new-pattern", "Set pattern for commands"); - } + MODCONSTRUCTOR(CNickServ) { + AddHelpCommand(); + AddCommand("Set", + static_cast(&CNickServ::SetCommand), + "password"); + AddCommand("Clear", static_cast( + &CNickServ::ClearCommand), + "", "Clear your nickserv password"); + AddCommand("SetNSName", static_cast( + &CNickServ::SetNSNameCommand), + "nickname", + "Set NickServ name (Useful on networks like EpiKnet, where " + "NickServ is named Themis)"); + AddCommand("ClearNSName", static_cast( + &CNickServ::ClearNSNameCommand), + "", "Reset NickServ name to default (NickServ)"); + AddCommand("ViewCommands", static_cast( + &CNickServ::ViewCommandsCommand), + "", + "Show patterns for lines, which are being sent to NickServ"); + AddCommand("SetCommand", static_cast( + &CNickServ::SetCommandCommand), + "cmd new-pattern", "Set pattern for commands"); + } - virtual ~CNickServ() {} + virtual ~CNickServ() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (!sArgs.empty() && sArgs != "") { - SetNV("Password", sArgs); - SetArgs(""); - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (!sArgs.empty() && sArgs != "") { + SetNV("Password", sArgs); + SetArgs(""); + } - if (GetNV("IdentifyCmd").empty()) { - SetNV("IdentifyCmd", "NICKSERV IDENTIFY {password}"); - } + if (GetNV("IdentifyCmd").empty()) { + SetNV("IdentifyCmd", "NICKSERV IDENTIFY {password}"); + } - return true; - } + return true; + } - void HandleMessage(CNick& Nick, const CString& sMessage) { - CString sNickServName = (!GetNV("NickServName").empty()) - ? GetNV("NickServName") - : "NickServ"; - if (!GetNV("Password").empty() && Nick.NickEquals(sNickServName) && - (sMessage.find("msg") != CString::npos || - sMessage.find("authenticate") != CString::npos || - sMessage.find("choose a different nickname") != CString::npos || - sMessage.find("please choose a different nick") != CString::npos || - sMessage.find("If this is your nick, identify yourself with") != - CString::npos || - sMessage.find("If this is your nick, type") != CString::npos || - sMessage.find("This is a registered nickname, please identify") != - CString::npos || - sMessage.StripControls_n().find( - "type /NickServ IDENTIFY password") != CString::npos || - sMessage.StripControls_n().find( - "type /msg NickServ IDENTIFY password") != CString::npos) && - sMessage.AsUpper().find("IDENTIFY") != CString::npos && - sMessage.find("help") == CString::npos) { - MCString msValues; - msValues["password"] = GetNV("Password"); - PutIRC(CString::NamedFormat(GetNV("IdentifyCmd"), msValues)); - } - } + void HandleMessage(CNick& Nick, const CString& sMessage) { + CString sNickServName = (!GetNV("NickServName").empty()) + ? GetNV("NickServName") + : "NickServ"; + if (!GetNV("Password").empty() && Nick.NickEquals(sNickServName) && + (sMessage.find("msg") != CString::npos || + sMessage.find("authenticate") != CString::npos || + sMessage.find("choose a different nickname") != CString::npos || + sMessage.find("please choose a different nick") != CString::npos || + sMessage.find("If this is your nick, identify yourself with") != + CString::npos || + sMessage.find("If this is your nick, type") != CString::npos || + sMessage.find("This is a registered nickname, please identify") != + CString::npos || + sMessage.StripControls_n().find( + "type /NickServ IDENTIFY password") != CString::npos || + sMessage.StripControls_n().find( + "type /msg NickServ IDENTIFY password") != CString::npos) && + sMessage.AsUpper().find("IDENTIFY") != CString::npos && + sMessage.find("help") == CString::npos) { + MCString msValues; + msValues["password"] = GetNV("Password"); + PutIRC(CString::NamedFormat(GetNV("IdentifyCmd"), msValues)); + } + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - HandleMessage(Nick, sMessage); - return CONTINUE; - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + HandleMessage(Nick, sMessage); + return CONTINUE; + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - HandleMessage(Nick, sMessage); - return CONTINUE; - } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + HandleMessage(Nick, sMessage); + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("nickserv"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Please enter your nickserv password."); + Info.SetWikiPage("nickserv"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("Please enter your nickserv password."); } NETWORKMODULEDEFS(CNickServ, "Auths you with NickServ") diff --git a/modules/notes.cpp b/modules/notes.cpp index 8d4621e4..eb607186 100644 --- a/modules/notes.cpp +++ b/modules/notes.cpp @@ -19,212 +19,212 @@ using std::stringstream; class CNotesMod : public CModule { - bool m_bShowNotesOnLogin{}; + bool m_bShowNotesOnLogin{}; - void ListCommand(const CString& sLine) { ListNotes(); } + void ListCommand(const CString& sLine) { ListNotes(); } - void AddNoteCommand(const CString& sLine) { - CString sKey(sLine.Token(1)); - CString sValue(sLine.Token(2, true)); + void AddNoteCommand(const CString& sLine) { + CString sKey(sLine.Token(1)); + CString sValue(sLine.Token(2, true)); - if (!GetNV(sKey).empty()) { - PutModule( - "That note already exists. Use MOD to " - "overwrite."); - } else if (AddNote(sKey, sValue)) { - PutModule("Added note [" + sKey + "]"); - } else { - PutModule("Unable to add note [" + sKey + "]"); - } - } + if (!GetNV(sKey).empty()) { + PutModule( + "That note already exists. Use MOD to " + "overwrite."); + } else if (AddNote(sKey, sValue)) { + PutModule("Added note [" + sKey + "]"); + } else { + PutModule("Unable to add note [" + sKey + "]"); + } + } - void ModCommand(const CString& sLine) { - CString sKey(sLine.Token(1)); - CString sValue(sLine.Token(2, true)); + void ModCommand(const CString& sLine) { + CString sKey(sLine.Token(1)); + CString sValue(sLine.Token(2, true)); - if (AddNote(sKey, sValue)) { - PutModule("Set note for [" + sKey + "]"); - } else { - PutModule("Unable to add note [" + sKey + "]"); - } - } + if (AddNote(sKey, sValue)) { + PutModule("Set note for [" + sKey + "]"); + } else { + PutModule("Unable to add note [" + sKey + "]"); + } + } - void GetCommand(const CString& sLine) { - CString sNote = GetNV(sLine.Token(1, true)); + void GetCommand(const CString& sLine) { + CString sNote = GetNV(sLine.Token(1, true)); - if (sNote.empty()) { - PutModule("This note doesn't exist."); - } else { - PutModule(sNote); - } - } + if (sNote.empty()) { + PutModule("This note doesn't exist."); + } else { + PutModule(sNote); + } + } - void DelCommand(const CString& sLine) { - CString sKey(sLine.Token(1)); + void DelCommand(const CString& sLine) { + CString sKey(sLine.Token(1)); - if (DelNote(sKey)) { - PutModule("Deleted note [" + sKey + "]"); - } else { - PutModule("Unable to delete note [" + sKey + "]"); - } - } + if (DelNote(sKey)) { + PutModule("Deleted note [" + sKey + "]"); + } else { + PutModule("Unable to delete note [" + sKey + "]"); + } + } public: - MODCONSTRUCTOR(CNotesMod) { - using std::placeholders::_1; - AddHelpCommand(); - AddCommand("List", static_cast( - &CNotesMod::ListCommand)); - AddCommand("Add", static_cast( - &CNotesMod::AddNoteCommand), - " "); - AddCommand("Del", - static_cast(&CNotesMod::DelCommand), - "", "Delete a note"); - AddCommand("Mod", " ", "Modify a note", - std::bind(&CNotesMod::ModCommand, this, _1)); - AddCommand("Get", "", "", - [this](const CString& sLine) { GetCommand(sLine); }); - } + MODCONSTRUCTOR(CNotesMod) { + using std::placeholders::_1; + AddHelpCommand(); + AddCommand("List", static_cast( + &CNotesMod::ListCommand)); + AddCommand("Add", static_cast( + &CNotesMod::AddNoteCommand), + " "); + AddCommand("Del", + static_cast(&CNotesMod::DelCommand), + "", "Delete a note"); + AddCommand("Mod", " ", "Modify a note", + std::bind(&CNotesMod::ModCommand, this, _1)); + AddCommand("Get", "", "", + [this](const CString& sLine) { GetCommand(sLine); }); + } - virtual ~CNotesMod() {} + virtual ~CNotesMod() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_bShowNotesOnLogin = !sArgs.Equals("-disableNotesOnLogin"); - return true; - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_bShowNotesOnLogin = !sArgs.Equals("-disableNotesOnLogin"); + return true; + } - CString GetWebMenuTitle() override { return "Notes"; } + CString GetWebMenuTitle() override { return "Notes"; } - void OnClientLogin() override { - if (m_bShowNotesOnLogin) { - ListNotes(true); - } - } + void OnClientLogin() override { + if (m_bShowNotesOnLogin) { + ListNotes(true); + } + } - EModRet OnUserRaw(CString& sLine) override { - if (sLine.Left(1) != "#") { - return CONTINUE; - } + EModRet OnUserRaw(CString& sLine) override { + if (sLine.Left(1) != "#") { + return CONTINUE; + } - CString sKey; - bool bOverwrite = false; + CString sKey; + bool bOverwrite = false; - if (sLine == "#?") { - ListNotes(true); - return HALT; - } else if (sLine.Left(2) == "#-") { - sKey = sLine.Token(0).LeftChomp_n(2); - if (DelNote(sKey)) { - PutModNotice("Deleted note [" + sKey + "]"); - } else { - PutModNotice("Unable to delete note [" + sKey + "]"); - } - return HALT; - } else if (sLine.Left(2) == "#+") { - sKey = sLine.Token(0).LeftChomp_n(2); - bOverwrite = true; - } else if (sLine.Left(1) == "#") { - sKey = sLine.Token(0).LeftChomp_n(1); - } + if (sLine == "#?") { + ListNotes(true); + return HALT; + } else if (sLine.Left(2) == "#-") { + sKey = sLine.Token(0).LeftChomp_n(2); + if (DelNote(sKey)) { + PutModNotice("Deleted note [" + sKey + "]"); + } else { + PutModNotice("Unable to delete note [" + sKey + "]"); + } + return HALT; + } else if (sLine.Left(2) == "#+") { + sKey = sLine.Token(0).LeftChomp_n(2); + bOverwrite = true; + } else if (sLine.Left(1) == "#") { + sKey = sLine.Token(0).LeftChomp_n(1); + } - CString sValue(sLine.Token(1, true)); + CString sValue(sLine.Token(1, true)); - if (!sKey.empty()) { - if (!bOverwrite && FindNV(sKey) != EndNV()) { - PutModNotice( - "That note already exists. Use /#+ to " - "overwrite."); - } else if (AddNote(sKey, sValue)) { - if (!bOverwrite) { - PutModNotice("Added note [" + sKey + "]"); - } else { - PutModNotice("Set note for [" + sKey + "]"); - } - } else { - PutModNotice("Unable to add note [" + sKey + "]"); - } - } + if (!sKey.empty()) { + if (!bOverwrite && FindNV(sKey) != EndNV()) { + PutModNotice( + "That note already exists. Use /#+ to " + "overwrite."); + } else if (AddNote(sKey, sValue)) { + if (!bOverwrite) { + PutModNotice("Added note [" + sKey + "]"); + } else { + PutModNotice("Set note for [" + sKey + "]"); + } + } else { + PutModNotice("Unable to add note [" + sKey + "]"); + } + } - return HALT; - } + return HALT; + } - bool DelNote(const CString& sKey) { return DelNV(sKey); } + bool DelNote(const CString& sKey) { return DelNV(sKey); } - bool AddNote(const CString& sKey, const CString& sNote) { - if (sKey.empty()) { - return false; - } + bool AddNote(const CString& sKey, const CString& sNote) { + if (sKey.empty()) { + return false; + } - return SetNV(sKey, sNote); - } + return SetNV(sKey, sNote); + } - void ListNotes(bool bNotice = false) { - CClient* pClient = GetClient(); + void ListNotes(bool bNotice = false) { + CClient* pClient = GetClient(); - if (pClient) { - CTable Table; - Table.AddColumn("Key"); - Table.AddColumn("Note"); + if (pClient) { + CTable Table; + Table.AddColumn("Key"); + Table.AddColumn("Note"); - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - Table.AddRow(); - Table.SetCell("Key", it->first); - Table.SetCell("Note", it->second); - } + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + Table.AddRow(); + Table.SetCell("Key", it->first); + Table.SetCell("Note", it->second); + } - if (Table.size()) { - unsigned int idx = 0; - CString sLine; - while (Table.GetLine(idx++, sLine)) { - if (bNotice) { - pClient->PutModNotice(GetModName(), sLine); - } else { - pClient->PutModule(GetModName(), sLine); - } - } - } else { - if (bNotice) { - PutModNotice("You have no entries."); - } else { - PutModule("You have no entries."); - } - } - } - } + if (Table.size()) { + unsigned int idx = 0; + CString sLine; + while (Table.GetLine(idx++, sLine)) { + if (bNotice) { + pClient->PutModNotice(GetModName(), sLine); + } else { + pClient->PutModule(GetModName(), sLine); + } + } + } else { + if (bNotice) { + PutModNotice("You have no entries."); + } else { + PutModule("You have no entries."); + } + } + } + } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - CTemplate& Row = Tmpl.AddRow("NotesLoop"); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + CTemplate& Row = Tmpl.AddRow("NotesLoop"); - Row["Key"] = it->first; - Row["Note"] = it->second; - } + Row["Key"] = it->first; + Row["Note"] = it->second; + } - return true; - } else if (sPageName == "delnote") { - DelNote(WebSock.GetParam("key", false)); - WebSock.Redirect(GetWebPath()); - return true; - } else if (sPageName == "addnote") { - AddNote(WebSock.GetParam("key"), WebSock.GetParam("note")); - WebSock.Redirect(GetWebPath()); - return true; - } + return true; + } else if (sPageName == "delnote") { + DelNote(WebSock.GetParam("key", false)); + WebSock.Redirect(GetWebPath()); + return true; + } else if (sPageName == "addnote") { + AddNote(WebSock.GetParam("key"), WebSock.GetParam("note")); + WebSock.Redirect(GetWebPath()); + return true; + } - return false; - } + return false; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("notes"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "This user module takes up to one arguments. It can be " - "-disableNotesOnLogin not to show notes upon client login"); + Info.SetWikiPage("notes"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "This user module takes up to one arguments. It can be " + "-disableNotesOnLogin not to show notes upon client login"); } USERMODULEDEFS(CNotesMod, "Keep and replay notes") diff --git a/modules/notify_connect.cpp b/modules/notify_connect.cpp index 437d22bf..3d221b49 100644 --- a/modules/notify_connect.cpp +++ b/modules/notify_connect.cpp @@ -19,32 +19,32 @@ class CNotifyConnectMod : public CModule { public: - MODCONSTRUCTOR(CNotifyConnectMod) {} + MODCONSTRUCTOR(CNotifyConnectMod) {} - void OnClientLogin() override { NotifyAdmins("attached"); } + void OnClientLogin() override { NotifyAdmins("attached"); } - void OnClientDisconnect() override { NotifyAdmins("detached"); } + void OnClientDisconnect() override { NotifyAdmins("detached"); } private: - void SendAdmins(const CString& msg) { - CZNC::Get().Broadcast(msg, true, nullptr, GetClient()); - } + void SendAdmins(const CString& msg) { + CZNC::Get().Broadcast(msg, true, nullptr, GetClient()); + } - void NotifyAdmins(const CString& event) { - CString client = GetUser()->GetUserName(); - if (GetClient()->GetIdentifier() != "") { - client += "@"; - client += GetClient()->GetIdentifier(); - } - CString ip = GetClient()->GetRemoteIP(); + void NotifyAdmins(const CString& event) { + CString client = GetUser()->GetUserName(); + if (GetClient()->GetIdentifier() != "") { + client += "@"; + client += GetClient()->GetIdentifier(); + } + CString ip = GetClient()->GetRemoteIP(); - SendAdmins(client + " " + event + " (from " + ip + ")"); - } + SendAdmins(client + " " + event + " (from " + ip + ")"); + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("notify_connect"); + Info.SetWikiPage("notify_connect"); } GLOBALMODULEDEFS( diff --git a/modules/partyline.cpp b/modules/partyline.cpp index 1d57add0..9e294398 100644 --- a/modules/partyline.cpp +++ b/modules/partyline.cpp @@ -31,710 +31,710 @@ using std::map; class CPartylineChannel { public: - CPartylineChannel(const CString& sName) { m_sName = sName.AsLower(); } - ~CPartylineChannel() {} + CPartylineChannel(const CString& sName) { m_sName = sName.AsLower(); } + ~CPartylineChannel() {} - const CString& GetTopic() const { return m_sTopic; } - const CString& GetName() const { return m_sName; } - const set& GetNicks() const { return m_ssNicks; } + const CString& GetTopic() const { return m_sTopic; } + const CString& GetName() const { return m_sName; } + const set& GetNicks() const { return m_ssNicks; } - void SetTopic(const CString& s) { m_sTopic = s; } + void SetTopic(const CString& s) { m_sTopic = s; } - void AddNick(const CString& s) { m_ssNicks.insert(s); } - void DelNick(const CString& s) { m_ssNicks.erase(s); } + void AddNick(const CString& s) { m_ssNicks.insert(s); } + void DelNick(const CString& s) { m_ssNicks.erase(s); } - bool IsInChannel(const CString& s) { - return m_ssNicks.find(s) != m_ssNicks.end(); - } + bool IsInChannel(const CString& s) { + return m_ssNicks.find(s) != m_ssNicks.end(); + } protected: - CString m_sTopic; - CString m_sName; - set m_ssNicks; + CString m_sTopic; + CString m_sName; + set m_ssNicks; }; class CPartylineMod : public CModule { public: - void ListChannelsCommand(const CString& sLine) { - if (m_ssChannels.empty()) { - PutModule("There are no open channels."); - return; - } - - CTable Table; - - Table.AddColumn("Channel"); - Table.AddColumn("Users"); - - for (set::const_iterator a = m_ssChannels.begin(); - a != m_ssChannels.end(); ++a) { - Table.AddRow(); - - Table.SetCell("Channel", (*a)->GetName()); - Table.SetCell("Users", CString((*a)->GetNicks().size())); - } - - PutModule(Table); - } - - MODCONSTRUCTOR(CPartylineMod) { - AddHelpCommand(); - AddCommand("List", static_cast( - &CPartylineMod::ListChannelsCommand), - "", "List all open channels"); - } - - virtual ~CPartylineMod() { - // Kick all clients who are in partyline channels - for (set::iterator it = m_ssChannels.begin(); - it != m_ssChannels.end(); ++it) { - set ssNicks = (*it)->GetNicks(); - - for (set::const_iterator it2 = ssNicks.begin(); - it2 != ssNicks.end(); ++it2) { - CUser* pUser = CZNC::Get().FindUser(*it2); - vector vClients = pUser->GetAllClients(); - - for (vector::const_iterator it3 = vClients.begin(); - it3 != vClients.end(); ++it3) { - CClient* pClient = *it3; - pClient->PutClient(":*" + GetModName() + - "!znc@znc.in KICK " + (*it)->GetName() + - " " + pClient->GetNick() + " :" + - GetModName() + " unloaded"); - } - } - } - - while (!m_ssChannels.empty()) { - delete *m_ssChannels.begin(); - m_ssChannels.erase(m_ssChannels.begin()); - } - } - - bool OnBoot() override { - // The config is now read completely, so all Users are set up - Load(); - - return true; - } - - bool OnLoad(const CString& sArgs, CString& sMessage) override { - const map& msUsers = CZNC::Get().GetUserMap(); - - for (map::const_iterator it = msUsers.begin(); - it != msUsers.end(); ++it) { - CUser* pUser = it->second; - for (CClient* pClient : pUser->GetAllClients()) { - CIRCNetwork* pNetwork = pClient->GetNetwork(); - if (!pNetwork || !pNetwork->IsIRCConnected() || - !pNetwork->GetChanPrefixes().Contains(CHAN_PREFIX_1)) { - pClient->PutClient( - ":" + GetIRCServer(pNetwork) + " 005 " + - pClient->GetNick() + " CHANTYPES=" + - (pNetwork ? pNetwork->GetChanPrefixes() : "") + - CHAN_PREFIX_1 " :are supported by this server."); - } - } - } - - VCString vsChans; - VCString::const_iterator it; - sArgs.Split(" ", vsChans, false); - - for (it = vsChans.begin(); it != vsChans.end(); ++it) { - if (it->Left(2) == CHAN_PREFIX) { - m_ssDefaultChans.insert(it->Left(32)); - } - } - - Load(); - - return true; - } - - void Load() { - CString sAction, sKey; - CPartylineChannel* pChannel; - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - if (it->first.find(":") != CString::npos) { - sAction = it->first.Token(0, false, ":"); - sKey = it->first.Token(1, true, ":"); - } else { - // backwards compatibility for older NV data - sAction = "fixedchan"; - sKey = it->first; - } - - if (sAction == "fixedchan") { - // Sorry, this was removed - } - - if (sAction == "topic") { - pChannel = FindChannel(sKey); - if (pChannel && !(it->second).empty()) { - PutChan(pChannel->GetNicks(), ":irc.znc.in TOPIC " + - pChannel->GetName() + - " :" + it->second); - pChannel->SetTopic(it->second); - } - } - } - - return; - } - - void SaveTopic(CPartylineChannel* pChannel) { - if (!pChannel->GetTopic().empty()) - SetNV("topic:" + pChannel->GetName(), pChannel->GetTopic()); - else - DelNV("topic:" + pChannel->GetName()); - } - - EModRet OnDeleteUser(CUser& User) override { - // Loop through each chan - for (set::iterator it = m_ssChannels.begin(); - it != m_ssChannels.end();) { - CPartylineChannel* pChan = *it; - // RemoveUser() might delete channels, so make sure our - // iterator doesn't break. - ++it; - RemoveUser(&User, pChan, "KICK", "User deleted", true); - } - - return CONTINUE; - } - - EModRet OnRaw(CString& sLine) override { - if (sLine.Token(1) == "005") { - CString::size_type uPos = sLine.AsUpper().find("CHANTYPES="); - if (uPos != CString::npos) { - uPos = sLine.find(" ", uPos); - - if (uPos == CString::npos) - sLine.append(CHAN_PREFIX_1); - else - sLine.insert(uPos, CHAN_PREFIX_1); - m_spInjectedPrefixes.insert(GetNetwork()); - } - } - - return CONTINUE; - } - - void OnIRCDisconnected() override { - m_spInjectedPrefixes.erase(GetNetwork()); - } - - void OnClientLogin() override { - CUser* pUser = GetUser(); - CClient* pClient = GetClient(); - CIRCNetwork* pNetwork = GetNetwork(); - if (!pNetwork || !pNetwork->IsIRCConnected()) { - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 005 " + - pClient->GetNick() + " CHANTYPES=" + - CHAN_PREFIX_1 " :are supported by this server."); - } - - // Make sure this user is in the default channels - for (set::iterator a = m_ssDefaultChans.begin(); - a != m_ssDefaultChans.end(); ++a) { - CPartylineChannel* pChannel = GetChannel(*a); - const CString& sNick = pUser->GetUserName(); - - if (pChannel->IsInChannel(sNick)) continue; - - CString sHost = pUser->GetBindHost(); - const set& ssNicks = pChannel->GetNicks(); - - if (sHost.empty()) { - sHost = "znc.in"; - } - PutChan(ssNicks, - ":" + NICK_PREFIX + sNick + "!" + pUser->GetIdent() + "@" + - sHost + " JOIN " + *a, - false); - pChannel->AddNick(sNick); - } - - CString sNickMask = pClient->GetNickMask(); - - for (set::iterator it = m_ssChannels.begin(); - it != m_ssChannels.end(); ++it) { - const set& ssNicks = (*it)->GetNicks(); - - if ((*it)->IsInChannel(pUser->GetUserName())) { - pClient->PutClient(":" + sNickMask + " JOIN " + - (*it)->GetName()); - - if (!(*it)->GetTopic().empty()) { - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 332 " + - pClient->GetNickMask() + " " + - (*it)->GetName() + " :" + - (*it)->GetTopic()); - } - - SendNickList(pUser, pNetwork, ssNicks, (*it)->GetName()); - PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + - (*it)->GetName() + " +" + - CString(pUser->IsAdmin() ? "o" : "v") + - " " + NICK_PREFIX + pUser->GetUserName(), - false); - } - } - } - - void OnClientDisconnect() override { - CUser* pUser = GetUser(); - if (!pUser->IsUserAttached() && !pUser->IsBeingDeleted()) { - for (set::iterator it = m_ssChannels.begin(); - it != m_ssChannels.end(); ++it) { - const set& ssNicks = (*it)->GetNicks(); - - if (ssNicks.find(pUser->GetUserName()) != ssNicks.end()) { - PutChan(ssNicks, - ":*" + GetModName() + "!znc@znc.in MODE " + - (*it)->GetName() + " -ov " + NICK_PREFIX + - pUser->GetUserName() + " " + NICK_PREFIX + - pUser->GetUserName(), - false); - } - } - } - } - - EModRet OnUserRaw(CString& sLine) override { - if (sLine.StartsWith("WHO " CHAN_PREFIX_1)) { - return HALT; - } else if (sLine.StartsWith("MODE " CHAN_PREFIX_1)) { - return HALT; - } else if (sLine.StartsWith("TOPIC " CHAN_PREFIX)) { - CString sChannel = sLine.Token(1); - CString sTopic = sLine.Token(2, true); - - sTopic.TrimPrefix(":"); - - CUser* pUser = GetUser(); - CClient* pClient = GetClient(); - CPartylineChannel* pChannel = FindChannel(sChannel); - - if (pChannel && pChannel->IsInChannel(pUser->GetUserName())) { - const set& ssNicks = pChannel->GetNicks(); - if (!sTopic.empty()) { - if (pUser->IsAdmin()) { - PutChan(ssNicks, ":" + pClient->GetNickMask() + - " TOPIC " + sChannel + " :" + - sTopic); - pChannel->SetTopic(sTopic); - SaveTopic(pChannel); - } else { - pUser->PutUser(":irc.znc.in 482 " + pClient->GetNick() + - " " + sChannel + - " :You're not channel operator"); - } - } else { - sTopic = pChannel->GetTopic(); - - if (sTopic.empty()) { - pUser->PutUser(":irc.znc.in 331 " + pClient->GetNick() + - " " + sChannel + " :No topic is set."); - } else { - pUser->PutUser(":irc.znc.in 332 " + pClient->GetNick() + - " " + sChannel + " :" + sTopic); - } - } - } else { - pUser->PutUser(":irc.znc.in 442 " + pClient->GetNick() + " " + - sChannel + " :You're not on that channel"); - } - return HALT; - } - - return CONTINUE; - } - - EModRet OnUserPart(CString& sChannel, CString& sMessage) override { - if (sChannel.Left(1) != CHAN_PREFIX_1) { - return CONTINUE; - } - - if (sChannel.Left(2) != CHAN_PREFIX) { - GetClient()->PutClient(":" + GetIRCServer(GetNetwork()) + " 401 " + - GetClient()->GetNick() + " " + sChannel + - " :No such channel"); - return HALT; - } - - CPartylineChannel* pChannel = FindChannel(sChannel); - - PartUser(GetUser(), pChannel); - - return HALT; - } - - void PartUser(CUser* pUser, CPartylineChannel* pChannel, - const CString& sMessage = "") { - RemoveUser(pUser, pChannel, "PART", sMessage); - } - - void RemoveUser(CUser* pUser, CPartylineChannel* pChannel, - const CString& sCommand, const CString& sMessage = "", - bool bNickAsTarget = false) { - if (!pChannel || !pChannel->IsInChannel(pUser->GetUserName())) { - return; - } - - vector vClients = pUser->GetAllClients(); - - CString sCmd = " " + sCommand + " "; - CString sMsg = sMessage; - if (!sMsg.empty()) sMsg = " :" + sMsg; - - pChannel->DelNick(pUser->GetUserName()); - - const set& ssNicks = pChannel->GetNicks(); - CString sHost = pUser->GetBindHost(); - - if (sHost.empty()) { - sHost = "znc.in"; - } - - if (bNickAsTarget) { - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pClient = *it; - - pClient->PutClient(":" + pClient->GetNickMask() + sCmd + - pChannel->GetName() + " " + - pClient->GetNick() + sMsg); - } - - PutChan(ssNicks, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + - pUser->GetIdent() + "@" + sHost + sCmd + - pChannel->GetName() + " " + NICK_PREFIX + - pUser->GetUserName() + sMsg, - false, true, pUser); - } else { - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pClient = *it; - - pClient->PutClient(":" + pClient->GetNickMask() + sCmd + - pChannel->GetName() + sMsg); - } - - PutChan(ssNicks, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + - pUser->GetIdent() + "@" + sHost + sCmd + - pChannel->GetName() + sMsg, - false, true, pUser); - } - - if (!pUser->IsBeingDeleted() && - m_ssDefaultChans.find(pChannel->GetName()) != - m_ssDefaultChans.end()) { - JoinUser(pUser, pChannel); - } - - if (ssNicks.empty()) { - delete pChannel; - m_ssChannels.erase(pChannel); - } - } - - EModRet OnUserJoin(CString& sChannel, CString& sKey) override { - if (sChannel.Left(1) != CHAN_PREFIX_1) { - return CONTINUE; - } - - if (sChannel.Left(2) != CHAN_PREFIX) { - GetClient()->PutClient(":" + GetIRCServer(GetNetwork()) + " 403 " + - GetClient()->GetNick() + " " + sChannel + - " :Channels look like " CHAN_PREFIX "znc"); - return HALT; - } - - sChannel = sChannel.Left(32); - CPartylineChannel* pChannel = GetChannel(sChannel); - - JoinUser(GetUser(), pChannel); - - return HALT; - } - - void JoinUser(CUser* pUser, CPartylineChannel* pChannel) { - if (pChannel && !pChannel->IsInChannel(pUser->GetUserName())) { - vector vClients = pUser->GetAllClients(); - - const set& ssNicks = pChannel->GetNicks(); - const CString& sNick = pUser->GetUserName(); - pChannel->AddNick(sNick); - - CString sHost = pUser->GetBindHost(); - - if (sHost.empty()) { - sHost = "znc.in"; - } - - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pClient = *it; - pClient->PutClient(":" + pClient->GetNickMask() + " JOIN " + - pChannel->GetName()); - } - - PutChan(ssNicks, - ":" + NICK_PREFIX + sNick + "!" + pUser->GetIdent() + "@" + - sHost + " JOIN " + pChannel->GetName(), - false, true, pUser); - - if (!pChannel->GetTopic().empty()) { - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pClient = *it; - pClient->PutClient( - ":" + GetIRCServer(pClient->GetNetwork()) + " 332 " + - pClient->GetNickMask() + " " + pChannel->GetName() + - " :" + pChannel->GetTopic()); - } - } - - SendNickList(pUser, nullptr, ssNicks, pChannel->GetName()); - - /* Tell the other clients we have op or voice, the current user's - * clients already know from NAMES list */ - - if (pUser->IsAdmin()) { - PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + - pChannel->GetName() + " +o " + - NICK_PREFIX + pUser->GetUserName(), - false, false, pUser); - } - - PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + - pChannel->GetName() + " +v " + NICK_PREFIX + - pUser->GetUserName(), - false, false, pUser); - } - } - - EModRet HandleMessage(const CString& sCmd, const CString& sTarget, - const CString& sMessage) { - if (sTarget.empty()) { - return CONTINUE; - } - - char cPrefix = sTarget[0]; - - if (cPrefix != CHAN_PREFIX_1C && cPrefix != NICK_PREFIX_C) { - return CONTINUE; - } - - CUser* pUser = GetUser(); - CClient* pClient = GetClient(); - CIRCNetwork* pNetwork = GetNetwork(); - CString sHost = pUser->GetBindHost(); - - if (sHost.empty()) { - sHost = "znc.in"; - } - - if (cPrefix == CHAN_PREFIX_1C) { - if (FindChannel(sTarget) == nullptr) { - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + - pClient->GetNick() + " " + sTarget + - " :No such channel"); - return HALT; - } - - PutChan(sTarget, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + - pUser->GetIdent() + "@" + sHost + " " + sCmd + - " " + sTarget + " :" + sMessage, - true, false); - } else { - CString sNick = sTarget.LeftChomp_n(1); - CUser* pTargetUser = CZNC::Get().FindUser(sNick); - - if (pTargetUser) { - vector vClients = pTargetUser->GetAllClients(); - - if (vClients.empty()) { - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + - pClient->GetNick() + " " + sTarget + - " :User is not attached: " + sNick + ""); - return HALT; - } - - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pTarget = *it; - - pTarget->PutClient( - ":" + NICK_PREFIX + pUser->GetUserName() + "!" + - pUser->GetIdent() + "@" + sHost + " " + sCmd + " " + - pTarget->GetNick() + " :" + sMessage); - } - } else { - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + - pClient->GetNick() + " " + sTarget + - " :No such znc user: " + sNick + ""); - } - } - - return HALT; - } - - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - return HandleMessage("PRIVMSG", sTarget, sMessage); - } - - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - return HandleMessage("NOTICE", sTarget, sMessage); - } - - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { - return HandleMessage("PRIVMSG", sTarget, "\001" + sMessage + "\001"); - } - - EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { - return HandleMessage("NOTICE", sTarget, "\001" + sMessage + "\001"); - } - - const CString GetIRCServer(CIRCNetwork* pNetwork) { - if (!pNetwork) { - return "irc.znc.in"; - } - - const CString& sServer = pNetwork->GetIRCServer(); - if (!sServer.empty()) return sServer; - return "irc.znc.in"; - } - - bool PutChan(const CString& sChan, const CString& sLine, - bool bIncludeCurUser = true, bool bIncludeClient = true, - CUser* pUser = nullptr, CClient* pClient = nullptr) { - CPartylineChannel* pChannel = FindChannel(sChan); - - if (pChannel != nullptr) { - PutChan(pChannel->GetNicks(), sLine, bIncludeCurUser, - bIncludeClient, pUser, pClient); - return true; - } - - return false; - } - - void PutChan(const set& ssNicks, const CString& sLine, - bool bIncludeCurUser = true, bool bIncludeClient = true, - CUser* pUser = nullptr, CClient* pClient = nullptr) { - const map& msUsers = CZNC::Get().GetUserMap(); - - if (!pUser) pUser = GetUser(); - if (!pClient) pClient = GetClient(); - - for (map::const_iterator it = msUsers.begin(); - it != msUsers.end(); ++it) { - if (ssNicks.find(it->first) != ssNicks.end()) { - if (it->second == pUser) { - if (bIncludeCurUser) { - it->second->PutAllUser( - sLine, nullptr, - (bIncludeClient ? nullptr : pClient)); - } - } else { - it->second->PutAllUser(sLine); - } - } - } - } - - void PutUserIRCNick(CUser* pUser, const CString& sPre, - const CString& sPost) { - const vector& vClients = pUser->GetAllClients(); - vector::const_iterator it; - for (it = vClients.begin(); it != vClients.end(); ++it) { - (*it)->PutClient(sPre + (*it)->GetNick() + sPost); - } - } - - void SendNickList(CUser* pUser, CIRCNetwork* pNetwork, - const set& ssNicks, const CString& sChan) { - CString sNickList; - - for (set::const_iterator it = ssNicks.begin(); - it != ssNicks.end(); ++it) { - CUser* pChanUser = CZNC::Get().FindUser(*it); - - if (pChanUser == pUser) { - continue; - } - - if (pChanUser && pChanUser->IsUserAttached()) { - sNickList += (pChanUser->IsAdmin()) ? "@" : "+"; - } - - sNickList += NICK_PREFIX + (*it) + " "; - - if (sNickList.size() >= 500) { - PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 353 ", - " @ " + sChan + " :" + sNickList); - sNickList.clear(); - } - } - - if (sNickList.size()) { - PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 353 ", - " @ " + sChan + " :" + sNickList); - } - - vector vClients = pUser->GetAllClients(); - for (vector::const_iterator it = vClients.begin(); - it != vClients.end(); ++it) { - CClient* pClient = *it; - pClient->PutClient(":" + GetIRCServer(pNetwork) + " 353 " + - pClient->GetNick() + " @ " + sChan + " :" + - ((pUser->IsAdmin()) ? "@" : "+") + - pClient->GetNick()); - } - - PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 366 ", - " " + sChan + " :End of /NAMES list."); - } - - CPartylineChannel* FindChannel(const CString& sChan) { - CString sChannel = sChan.AsLower(); - - for (set::iterator it = m_ssChannels.begin(); - it != m_ssChannels.end(); ++it) { - if ((*it)->GetName().AsLower() == sChannel) return *it; - } - - return nullptr; - } - - CPartylineChannel* GetChannel(const CString& sChannel) { - CPartylineChannel* pChannel = FindChannel(sChannel); - - if (!pChannel) { - pChannel = new CPartylineChannel(sChannel.AsLower()); - m_ssChannels.insert(pChannel); - } - - return pChannel; - } + void ListChannelsCommand(const CString& sLine) { + if (m_ssChannels.empty()) { + PutModule("There are no open channels."); + return; + } + + CTable Table; + + Table.AddColumn("Channel"); + Table.AddColumn("Users"); + + for (set::const_iterator a = m_ssChannels.begin(); + a != m_ssChannels.end(); ++a) { + Table.AddRow(); + + Table.SetCell("Channel", (*a)->GetName()); + Table.SetCell("Users", CString((*a)->GetNicks().size())); + } + + PutModule(Table); + } + + MODCONSTRUCTOR(CPartylineMod) { + AddHelpCommand(); + AddCommand("List", static_cast( + &CPartylineMod::ListChannelsCommand), + "", "List all open channels"); + } + + virtual ~CPartylineMod() { + // Kick all clients who are in partyline channels + for (set::iterator it = m_ssChannels.begin(); + it != m_ssChannels.end(); ++it) { + set ssNicks = (*it)->GetNicks(); + + for (set::const_iterator it2 = ssNicks.begin(); + it2 != ssNicks.end(); ++it2) { + CUser* pUser = CZNC::Get().FindUser(*it2); + vector vClients = pUser->GetAllClients(); + + for (vector::const_iterator it3 = vClients.begin(); + it3 != vClients.end(); ++it3) { + CClient* pClient = *it3; + pClient->PutClient(":*" + GetModName() + + "!znc@znc.in KICK " + (*it)->GetName() + + " " + pClient->GetNick() + " :" + + GetModName() + " unloaded"); + } + } + } + + while (!m_ssChannels.empty()) { + delete *m_ssChannels.begin(); + m_ssChannels.erase(m_ssChannels.begin()); + } + } + + bool OnBoot() override { + // The config is now read completely, so all Users are set up + Load(); + + return true; + } + + bool OnLoad(const CString& sArgs, CString& sMessage) override { + const map& msUsers = CZNC::Get().GetUserMap(); + + for (map::const_iterator it = msUsers.begin(); + it != msUsers.end(); ++it) { + CUser* pUser = it->second; + for (CClient* pClient : pUser->GetAllClients()) { + CIRCNetwork* pNetwork = pClient->GetNetwork(); + if (!pNetwork || !pNetwork->IsIRCConnected() || + !pNetwork->GetChanPrefixes().Contains(CHAN_PREFIX_1)) { + pClient->PutClient( + ":" + GetIRCServer(pNetwork) + " 005 " + + pClient->GetNick() + " CHANTYPES=" + + (pNetwork ? pNetwork->GetChanPrefixes() : "") + + CHAN_PREFIX_1 " :are supported by this server."); + } + } + } + + VCString vsChans; + VCString::const_iterator it; + sArgs.Split(" ", vsChans, false); + + for (it = vsChans.begin(); it != vsChans.end(); ++it) { + if (it->Left(2) == CHAN_PREFIX) { + m_ssDefaultChans.insert(it->Left(32)); + } + } + + Load(); + + return true; + } + + void Load() { + CString sAction, sKey; + CPartylineChannel* pChannel; + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + if (it->first.find(":") != CString::npos) { + sAction = it->first.Token(0, false, ":"); + sKey = it->first.Token(1, true, ":"); + } else { + // backwards compatibility for older NV data + sAction = "fixedchan"; + sKey = it->first; + } + + if (sAction == "fixedchan") { + // Sorry, this was removed + } + + if (sAction == "topic") { + pChannel = FindChannel(sKey); + if (pChannel && !(it->second).empty()) { + PutChan(pChannel->GetNicks(), ":irc.znc.in TOPIC " + + pChannel->GetName() + + " :" + it->second); + pChannel->SetTopic(it->second); + } + } + } + + return; + } + + void SaveTopic(CPartylineChannel* pChannel) { + if (!pChannel->GetTopic().empty()) + SetNV("topic:" + pChannel->GetName(), pChannel->GetTopic()); + else + DelNV("topic:" + pChannel->GetName()); + } + + EModRet OnDeleteUser(CUser& User) override { + // Loop through each chan + for (set::iterator it = m_ssChannels.begin(); + it != m_ssChannels.end();) { + CPartylineChannel* pChan = *it; + // RemoveUser() might delete channels, so make sure our + // iterator doesn't break. + ++it; + RemoveUser(&User, pChan, "KICK", "User deleted", true); + } + + return CONTINUE; + } + + EModRet OnRaw(CString& sLine) override { + if (sLine.Token(1) == "005") { + CString::size_type uPos = sLine.AsUpper().find("CHANTYPES="); + if (uPos != CString::npos) { + uPos = sLine.find(" ", uPos); + + if (uPos == CString::npos) + sLine.append(CHAN_PREFIX_1); + else + sLine.insert(uPos, CHAN_PREFIX_1); + m_spInjectedPrefixes.insert(GetNetwork()); + } + } + + return CONTINUE; + } + + void OnIRCDisconnected() override { + m_spInjectedPrefixes.erase(GetNetwork()); + } + + void OnClientLogin() override { + CUser* pUser = GetUser(); + CClient* pClient = GetClient(); + CIRCNetwork* pNetwork = GetNetwork(); + if (!pNetwork || !pNetwork->IsIRCConnected()) { + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 005 " + + pClient->GetNick() + " CHANTYPES=" + + CHAN_PREFIX_1 " :are supported by this server."); + } + + // Make sure this user is in the default channels + for (set::iterator a = m_ssDefaultChans.begin(); + a != m_ssDefaultChans.end(); ++a) { + CPartylineChannel* pChannel = GetChannel(*a); + const CString& sNick = pUser->GetUserName(); + + if (pChannel->IsInChannel(sNick)) continue; + + CString sHost = pUser->GetBindHost(); + const set& ssNicks = pChannel->GetNicks(); + + if (sHost.empty()) { + sHost = "znc.in"; + } + PutChan(ssNicks, + ":" + NICK_PREFIX + sNick + "!" + pUser->GetIdent() + "@" + + sHost + " JOIN " + *a, + false); + pChannel->AddNick(sNick); + } + + CString sNickMask = pClient->GetNickMask(); + + for (set::iterator it = m_ssChannels.begin(); + it != m_ssChannels.end(); ++it) { + const set& ssNicks = (*it)->GetNicks(); + + if ((*it)->IsInChannel(pUser->GetUserName())) { + pClient->PutClient(":" + sNickMask + " JOIN " + + (*it)->GetName()); + + if (!(*it)->GetTopic().empty()) { + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 332 " + + pClient->GetNickMask() + " " + + (*it)->GetName() + " :" + + (*it)->GetTopic()); + } + + SendNickList(pUser, pNetwork, ssNicks, (*it)->GetName()); + PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + + (*it)->GetName() + " +" + + CString(pUser->IsAdmin() ? "o" : "v") + + " " + NICK_PREFIX + pUser->GetUserName(), + false); + } + } + } + + void OnClientDisconnect() override { + CUser* pUser = GetUser(); + if (!pUser->IsUserAttached() && !pUser->IsBeingDeleted()) { + for (set::iterator it = m_ssChannels.begin(); + it != m_ssChannels.end(); ++it) { + const set& ssNicks = (*it)->GetNicks(); + + if (ssNicks.find(pUser->GetUserName()) != ssNicks.end()) { + PutChan(ssNicks, + ":*" + GetModName() + "!znc@znc.in MODE " + + (*it)->GetName() + " -ov " + NICK_PREFIX + + pUser->GetUserName() + " " + NICK_PREFIX + + pUser->GetUserName(), + false); + } + } + } + } + + EModRet OnUserRaw(CString& sLine) override { + if (sLine.StartsWith("WHO " CHAN_PREFIX_1)) { + return HALT; + } else if (sLine.StartsWith("MODE " CHAN_PREFIX_1)) { + return HALT; + } else if (sLine.StartsWith("TOPIC " CHAN_PREFIX)) { + CString sChannel = sLine.Token(1); + CString sTopic = sLine.Token(2, true); + + sTopic.TrimPrefix(":"); + + CUser* pUser = GetUser(); + CClient* pClient = GetClient(); + CPartylineChannel* pChannel = FindChannel(sChannel); + + if (pChannel && pChannel->IsInChannel(pUser->GetUserName())) { + const set& ssNicks = pChannel->GetNicks(); + if (!sTopic.empty()) { + if (pUser->IsAdmin()) { + PutChan(ssNicks, ":" + pClient->GetNickMask() + + " TOPIC " + sChannel + " :" + + sTopic); + pChannel->SetTopic(sTopic); + SaveTopic(pChannel); + } else { + pUser->PutUser(":irc.znc.in 482 " + pClient->GetNick() + + " " + sChannel + + " :You're not channel operator"); + } + } else { + sTopic = pChannel->GetTopic(); + + if (sTopic.empty()) { + pUser->PutUser(":irc.znc.in 331 " + pClient->GetNick() + + " " + sChannel + " :No topic is set."); + } else { + pUser->PutUser(":irc.znc.in 332 " + pClient->GetNick() + + " " + sChannel + " :" + sTopic); + } + } + } else { + pUser->PutUser(":irc.znc.in 442 " + pClient->GetNick() + " " + + sChannel + " :You're not on that channel"); + } + return HALT; + } + + return CONTINUE; + } + + EModRet OnUserPart(CString& sChannel, CString& sMessage) override { + if (sChannel.Left(1) != CHAN_PREFIX_1) { + return CONTINUE; + } + + if (sChannel.Left(2) != CHAN_PREFIX) { + GetClient()->PutClient(":" + GetIRCServer(GetNetwork()) + " 401 " + + GetClient()->GetNick() + " " + sChannel + + " :No such channel"); + return HALT; + } + + CPartylineChannel* pChannel = FindChannel(sChannel); + + PartUser(GetUser(), pChannel); + + return HALT; + } + + void PartUser(CUser* pUser, CPartylineChannel* pChannel, + const CString& sMessage = "") { + RemoveUser(pUser, pChannel, "PART", sMessage); + } + + void RemoveUser(CUser* pUser, CPartylineChannel* pChannel, + const CString& sCommand, const CString& sMessage = "", + bool bNickAsTarget = false) { + if (!pChannel || !pChannel->IsInChannel(pUser->GetUserName())) { + return; + } + + vector vClients = pUser->GetAllClients(); + + CString sCmd = " " + sCommand + " "; + CString sMsg = sMessage; + if (!sMsg.empty()) sMsg = " :" + sMsg; + + pChannel->DelNick(pUser->GetUserName()); + + const set& ssNicks = pChannel->GetNicks(); + CString sHost = pUser->GetBindHost(); + + if (sHost.empty()) { + sHost = "znc.in"; + } + + if (bNickAsTarget) { + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pClient = *it; + + pClient->PutClient(":" + pClient->GetNickMask() + sCmd + + pChannel->GetName() + " " + + pClient->GetNick() + sMsg); + } + + PutChan(ssNicks, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + + pUser->GetIdent() + "@" + sHost + sCmd + + pChannel->GetName() + " " + NICK_PREFIX + + pUser->GetUserName() + sMsg, + false, true, pUser); + } else { + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pClient = *it; + + pClient->PutClient(":" + pClient->GetNickMask() + sCmd + + pChannel->GetName() + sMsg); + } + + PutChan(ssNicks, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + + pUser->GetIdent() + "@" + sHost + sCmd + + pChannel->GetName() + sMsg, + false, true, pUser); + } + + if (!pUser->IsBeingDeleted() && + m_ssDefaultChans.find(pChannel->GetName()) != + m_ssDefaultChans.end()) { + JoinUser(pUser, pChannel); + } + + if (ssNicks.empty()) { + delete pChannel; + m_ssChannels.erase(pChannel); + } + } + + EModRet OnUserJoin(CString& sChannel, CString& sKey) override { + if (sChannel.Left(1) != CHAN_PREFIX_1) { + return CONTINUE; + } + + if (sChannel.Left(2) != CHAN_PREFIX) { + GetClient()->PutClient(":" + GetIRCServer(GetNetwork()) + " 403 " + + GetClient()->GetNick() + " " + sChannel + + " :Channels look like " CHAN_PREFIX "znc"); + return HALT; + } + + sChannel = sChannel.Left(32); + CPartylineChannel* pChannel = GetChannel(sChannel); + + JoinUser(GetUser(), pChannel); + + return HALT; + } + + void JoinUser(CUser* pUser, CPartylineChannel* pChannel) { + if (pChannel && !pChannel->IsInChannel(pUser->GetUserName())) { + vector vClients = pUser->GetAllClients(); + + const set& ssNicks = pChannel->GetNicks(); + const CString& sNick = pUser->GetUserName(); + pChannel->AddNick(sNick); + + CString sHost = pUser->GetBindHost(); + + if (sHost.empty()) { + sHost = "znc.in"; + } + + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pClient = *it; + pClient->PutClient(":" + pClient->GetNickMask() + " JOIN " + + pChannel->GetName()); + } + + PutChan(ssNicks, + ":" + NICK_PREFIX + sNick + "!" + pUser->GetIdent() + "@" + + sHost + " JOIN " + pChannel->GetName(), + false, true, pUser); + + if (!pChannel->GetTopic().empty()) { + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pClient = *it; + pClient->PutClient( + ":" + GetIRCServer(pClient->GetNetwork()) + " 332 " + + pClient->GetNickMask() + " " + pChannel->GetName() + + " :" + pChannel->GetTopic()); + } + } + + SendNickList(pUser, nullptr, ssNicks, pChannel->GetName()); + + /* Tell the other clients we have op or voice, the current user's + * clients already know from NAMES list */ + + if (pUser->IsAdmin()) { + PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + + pChannel->GetName() + " +o " + + NICK_PREFIX + pUser->GetUserName(), + false, false, pUser); + } + + PutChan(ssNicks, ":*" + GetModName() + "!znc@znc.in MODE " + + pChannel->GetName() + " +v " + NICK_PREFIX + + pUser->GetUserName(), + false, false, pUser); + } + } + + EModRet HandleMessage(const CString& sCmd, const CString& sTarget, + const CString& sMessage) { + if (sTarget.empty()) { + return CONTINUE; + } + + char cPrefix = sTarget[0]; + + if (cPrefix != CHAN_PREFIX_1C && cPrefix != NICK_PREFIX_C) { + return CONTINUE; + } + + CUser* pUser = GetUser(); + CClient* pClient = GetClient(); + CIRCNetwork* pNetwork = GetNetwork(); + CString sHost = pUser->GetBindHost(); + + if (sHost.empty()) { + sHost = "znc.in"; + } + + if (cPrefix == CHAN_PREFIX_1C) { + if (FindChannel(sTarget) == nullptr) { + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + + pClient->GetNick() + " " + sTarget + + " :No such channel"); + return HALT; + } + + PutChan(sTarget, ":" + NICK_PREFIX + pUser->GetUserName() + "!" + + pUser->GetIdent() + "@" + sHost + " " + sCmd + + " " + sTarget + " :" + sMessage, + true, false); + } else { + CString sNick = sTarget.LeftChomp_n(1); + CUser* pTargetUser = CZNC::Get().FindUser(sNick); + + if (pTargetUser) { + vector vClients = pTargetUser->GetAllClients(); + + if (vClients.empty()) { + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + + pClient->GetNick() + " " + sTarget + + " :User is not attached: " + sNick + ""); + return HALT; + } + + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pTarget = *it; + + pTarget->PutClient( + ":" + NICK_PREFIX + pUser->GetUserName() + "!" + + pUser->GetIdent() + "@" + sHost + " " + sCmd + " " + + pTarget->GetNick() + " :" + sMessage); + } + } else { + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 401 " + + pClient->GetNick() + " " + sTarget + + " :No such znc user: " + sNick + ""); + } + } + + return HALT; + } + + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + return HandleMessage("PRIVMSG", sTarget, sMessage); + } + + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + return HandleMessage("NOTICE", sTarget, sMessage); + } + + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { + return HandleMessage("PRIVMSG", sTarget, "\001" + sMessage + "\001"); + } + + EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { + return HandleMessage("NOTICE", sTarget, "\001" + sMessage + "\001"); + } + + const CString GetIRCServer(CIRCNetwork* pNetwork) { + if (!pNetwork) { + return "irc.znc.in"; + } + + const CString& sServer = pNetwork->GetIRCServer(); + if (!sServer.empty()) return sServer; + return "irc.znc.in"; + } + + bool PutChan(const CString& sChan, const CString& sLine, + bool bIncludeCurUser = true, bool bIncludeClient = true, + CUser* pUser = nullptr, CClient* pClient = nullptr) { + CPartylineChannel* pChannel = FindChannel(sChan); + + if (pChannel != nullptr) { + PutChan(pChannel->GetNicks(), sLine, bIncludeCurUser, + bIncludeClient, pUser, pClient); + return true; + } + + return false; + } + + void PutChan(const set& ssNicks, const CString& sLine, + bool bIncludeCurUser = true, bool bIncludeClient = true, + CUser* pUser = nullptr, CClient* pClient = nullptr) { + const map& msUsers = CZNC::Get().GetUserMap(); + + if (!pUser) pUser = GetUser(); + if (!pClient) pClient = GetClient(); + + for (map::const_iterator it = msUsers.begin(); + it != msUsers.end(); ++it) { + if (ssNicks.find(it->first) != ssNicks.end()) { + if (it->second == pUser) { + if (bIncludeCurUser) { + it->second->PutAllUser( + sLine, nullptr, + (bIncludeClient ? nullptr : pClient)); + } + } else { + it->second->PutAllUser(sLine); + } + } + } + } + + void PutUserIRCNick(CUser* pUser, const CString& sPre, + const CString& sPost) { + const vector& vClients = pUser->GetAllClients(); + vector::const_iterator it; + for (it = vClients.begin(); it != vClients.end(); ++it) { + (*it)->PutClient(sPre + (*it)->GetNick() + sPost); + } + } + + void SendNickList(CUser* pUser, CIRCNetwork* pNetwork, + const set& ssNicks, const CString& sChan) { + CString sNickList; + + for (set::const_iterator it = ssNicks.begin(); + it != ssNicks.end(); ++it) { + CUser* pChanUser = CZNC::Get().FindUser(*it); + + if (pChanUser == pUser) { + continue; + } + + if (pChanUser && pChanUser->IsUserAttached()) { + sNickList += (pChanUser->IsAdmin()) ? "@" : "+"; + } + + sNickList += NICK_PREFIX + (*it) + " "; + + if (sNickList.size() >= 500) { + PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 353 ", + " @ " + sChan + " :" + sNickList); + sNickList.clear(); + } + } + + if (sNickList.size()) { + PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 353 ", + " @ " + sChan + " :" + sNickList); + } + + vector vClients = pUser->GetAllClients(); + for (vector::const_iterator it = vClients.begin(); + it != vClients.end(); ++it) { + CClient* pClient = *it; + pClient->PutClient(":" + GetIRCServer(pNetwork) + " 353 " + + pClient->GetNick() + " @ " + sChan + " :" + + ((pUser->IsAdmin()) ? "@" : "+") + + pClient->GetNick()); + } + + PutUserIRCNick(pUser, ":" + GetIRCServer(pNetwork) + " 366 ", + " " + sChan + " :End of /NAMES list."); + } + + CPartylineChannel* FindChannel(const CString& sChan) { + CString sChannel = sChan.AsLower(); + + for (set::iterator it = m_ssChannels.begin(); + it != m_ssChannels.end(); ++it) { + if ((*it)->GetName().AsLower() == sChannel) return *it; + } + + return nullptr; + } + + CPartylineChannel* GetChannel(const CString& sChannel) { + CPartylineChannel* pChannel = FindChannel(sChannel); + + if (!pChannel) { + pChannel = new CPartylineChannel(sChannel.AsLower()); + m_ssChannels.insert(pChannel); + } + + return pChannel; + } private: - set m_ssChannels; - set m_spInjectedPrefixes; - set m_ssDefaultChans; + set m_ssChannels; + set m_spInjectedPrefixes; + set m_ssDefaultChans; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("partyline"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "You may enter a list of channels the user joins, when entering the " - "internal partyline."); + Info.SetWikiPage("partyline"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "You may enter a list of channels the user joins, when entering the " + "internal partyline."); } GLOBALMODULEDEFS(CPartylineMod, diff --git a/modules/perform.cpp b/modules/perform.cpp index b938db47..8de0d786 100644 --- a/modules/perform.cpp +++ b/modules/perform.cpp @@ -17,174 +17,174 @@ #include class CPerform : public CModule { - void Add(const CString& sCommand) { - CString sPerf = sCommand.Token(1, true); + void Add(const CString& sCommand) { + CString sPerf = sCommand.Token(1, true); - if (sPerf.empty()) { - PutModule("Usage: add "); - return; - } + if (sPerf.empty()) { + PutModule("Usage: add "); + return; + } - m_vPerform.push_back(ParsePerform(sPerf)); - PutModule("Added!"); - Save(); - } + m_vPerform.push_back(ParsePerform(sPerf)); + PutModule("Added!"); + Save(); + } - void Del(const CString& sCommand) { - u_int iNum = sCommand.Token(1, true).ToUInt(); + void Del(const CString& sCommand) { + u_int iNum = sCommand.Token(1, true).ToUInt(); - if (iNum > m_vPerform.size() || iNum <= 0) { - PutModule("Illegal # Requested"); - return; - } else { - m_vPerform.erase(m_vPerform.begin() + iNum - 1); - PutModule("Command Erased."); - } - Save(); - } + if (iNum > m_vPerform.size() || iNum <= 0) { + PutModule("Illegal # Requested"); + return; + } else { + m_vPerform.erase(m_vPerform.begin() + iNum - 1); + PutModule("Command Erased."); + } + Save(); + } - void List(const CString& sCommand) { - CTable Table; - unsigned int index = 1; + void List(const CString& sCommand) { + CTable Table; + unsigned int index = 1; - Table.AddColumn("Id"); - Table.AddColumn("Perform"); - Table.AddColumn("Expanded"); + Table.AddColumn("Id"); + Table.AddColumn("Perform"); + Table.AddColumn("Expanded"); - for (const CString& sPerf : m_vPerform) { - Table.AddRow(); - Table.SetCell("Id", CString(index++)); - Table.SetCell("Perform", sPerf); + for (const CString& sPerf : m_vPerform) { + Table.AddRow(); + Table.SetCell("Id", CString(index++)); + Table.SetCell("Perform", sPerf); - CString sExpanded = ExpandString(sPerf); + CString sExpanded = ExpandString(sPerf); - if (sExpanded != sPerf) { - Table.SetCell("Expanded", sExpanded); - } - } + if (sExpanded != sPerf) { + Table.SetCell("Expanded", sExpanded); + } + } - if (PutModule(Table) == 0) { - PutModule("No commands in your perform list."); - } - } + if (PutModule(Table) == 0) { + PutModule("No commands in your perform list."); + } + } - void Execute(const CString& sCommand) { - OnIRCConnected(); - PutModule("perform commands sent"); - } + void Execute(const CString& sCommand) { + OnIRCConnected(); + PutModule("perform commands sent"); + } - void Swap(const CString& sCommand) { - u_int iNumA = sCommand.Token(1).ToUInt(); - u_int iNumB = sCommand.Token(2).ToUInt(); + void Swap(const CString& sCommand) { + u_int iNumA = sCommand.Token(1).ToUInt(); + u_int iNumB = sCommand.Token(2).ToUInt(); - if (iNumA > m_vPerform.size() || iNumA <= 0 || - iNumB > m_vPerform.size() || iNumB <= 0) { - PutModule("Illegal # Requested"); - } else { - std::iter_swap(m_vPerform.begin() + (iNumA - 1), - m_vPerform.begin() + (iNumB - 1)); - PutModule("Commands Swapped."); - Save(); - } - } + if (iNumA > m_vPerform.size() || iNumA <= 0 || + iNumB > m_vPerform.size() || iNumB <= 0) { + PutModule("Illegal # Requested"); + } else { + std::iter_swap(m_vPerform.begin() + (iNumA - 1), + m_vPerform.begin() + (iNumB - 1)); + PutModule("Commands Swapped."); + Save(); + } + } public: - MODCONSTRUCTOR(CPerform) { - AddHelpCommand(); - AddCommand("Add", static_cast(&CPerform::Add), - "", - "Adds perform command to be sent to the server on connect"); - AddCommand("Del", static_cast(&CPerform::Del), - "", "Delete a perform command"); - AddCommand("List", - static_cast(&CPerform::List), "", - "List the perform commands"); - AddCommand("Execute", - static_cast(&CPerform::Execute), "", - "Send the perform commands to the server now"); - AddCommand("Swap", - static_cast(&CPerform::Swap), - " ", "Swap two perform commands"); - } + MODCONSTRUCTOR(CPerform) { + AddHelpCommand(); + AddCommand("Add", static_cast(&CPerform::Add), + "", + "Adds perform command to be sent to the server on connect"); + AddCommand("Del", static_cast(&CPerform::Del), + "", "Delete a perform command"); + AddCommand("List", + static_cast(&CPerform::List), "", + "List the perform commands"); + AddCommand("Execute", + static_cast(&CPerform::Execute), "", + "Send the perform commands to the server now"); + AddCommand("Swap", + static_cast(&CPerform::Swap), + " ", "Swap two perform commands"); + } - virtual ~CPerform() {} + virtual ~CPerform() {} - CString ParsePerform(const CString& sArg) const { - CString sPerf = sArg; + CString ParsePerform(const CString& sArg) const { + CString sPerf = sArg; - if (sPerf.Left(1) == "/") sPerf.LeftChomp(); + if (sPerf.Left(1) == "/") sPerf.LeftChomp(); - if (sPerf.Token(0).Equals("MSG")) { - sPerf = "PRIVMSG " + sPerf.Token(1, true); - } + if (sPerf.Token(0).Equals("MSG")) { + sPerf = "PRIVMSG " + sPerf.Token(1, true); + } - if ((sPerf.Token(0).Equals("PRIVMSG") || - sPerf.Token(0).Equals("NOTICE")) && - sPerf.Token(2).Left(1) != ":") { - sPerf = sPerf.Token(0) + " " + sPerf.Token(1) + " :" + - sPerf.Token(2, true); - } + if ((sPerf.Token(0).Equals("PRIVMSG") || + sPerf.Token(0).Equals("NOTICE")) && + sPerf.Token(2).Left(1) != ":") { + sPerf = sPerf.Token(0) + " " + sPerf.Token(1) + " :" + + sPerf.Token(2, true); + } - return sPerf; - } + return sPerf; + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - GetNV("Perform").Split("\n", m_vPerform, false); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + GetNV("Perform").Split("\n", m_vPerform, false); - return true; - } + return true; + } - void OnIRCConnected() override { - for (const CString& sPerf : m_vPerform) { - PutIRC(ExpandString(sPerf)); - } - } + void OnIRCConnected() override { + for (const CString& sPerf : m_vPerform) { + PutIRC(ExpandString(sPerf)); + } + } - CString GetWebMenuTitle() override { return "Perform"; } + CString GetWebMenuTitle() override { return "Perform"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName != "index") { - // only accept requests to index - return false; - } + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName != "index") { + // only accept requests to index + return false; + } - if (WebSock.IsPost()) { - VCString vsPerf; - WebSock.GetRawParam("perform", true).Split("\n", vsPerf, false); - m_vPerform.clear(); + if (WebSock.IsPost()) { + VCString vsPerf; + WebSock.GetRawParam("perform", true).Split("\n", vsPerf, false); + m_vPerform.clear(); - for (const CString& sPerf : vsPerf) - m_vPerform.push_back(ParsePerform(sPerf)); + for (const CString& sPerf : vsPerf) + m_vPerform.push_back(ParsePerform(sPerf)); - Save(); - } + Save(); + } - for (const CString& sPerf : m_vPerform) { - CTemplate& Row = Tmpl.AddRow("PerformLoop"); - Row["Perform"] = sPerf; - } + for (const CString& sPerf : m_vPerform) { + CTemplate& Row = Tmpl.AddRow("PerformLoop"); + Row["Perform"] = sPerf; + } - return true; - } + return true; + } private: - void Save() { - CString sBuffer = ""; + void Save() { + CString sBuffer = ""; - for (const CString& sPerf : m_vPerform) { - sBuffer += sPerf + "\n"; - } - SetNV("Perform", sBuffer); - } + for (const CString& sPerf : m_vPerform) { + sBuffer += sPerf + "\n"; + } + SetNV("Perform", sBuffer); + } - VCString m_vPerform; + VCString m_vPerform; }; template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::UserModule); - Info.SetWikiPage("perform"); + Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("perform"); } NETWORKMODULEDEFS( diff --git a/modules/q.cpp b/modules/q.cpp index fc690a85..c5e33a7f 100644 --- a/modules/q.cpp +++ b/modules/q.cpp @@ -27,655 +27,655 @@ using std::set; class CQModule : public CModule { public: - MODCONSTRUCTOR(CQModule) {} - virtual ~CQModule() {} + MODCONSTRUCTOR(CQModule) {} + virtual ~CQModule() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (!sArgs.empty()) { - SetUsername(sArgs.Token(0)); - SetPassword(sArgs.Token(1)); - } else { - m_sUsername = GetNV("Username"); - m_sPassword = GetNV("Password"); - } + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (!sArgs.empty()) { + SetUsername(sArgs.Token(0)); + SetPassword(sArgs.Token(1)); + } else { + m_sUsername = GetNV("Username"); + m_sPassword = GetNV("Password"); + } - CString sTmp; - m_bUseCloakedHost = - (sTmp = GetNV("UseCloakedHost")).empty() ? true : sTmp.ToBool(); - m_bUseChallenge = - (sTmp = GetNV("UseChallenge")).empty() ? true : sTmp.ToBool(); - m_bRequestPerms = GetNV("RequestPerms").ToBool(); - m_bJoinOnInvite = - (sTmp = GetNV("JoinOnInvite")).empty() ? true : sTmp.ToBool(); - m_bJoinAfterCloaked = - (sTmp = GetNV("JoinAfterCloaked")).empty() ? true : sTmp.ToBool(); + CString sTmp; + m_bUseCloakedHost = + (sTmp = GetNV("UseCloakedHost")).empty() ? true : sTmp.ToBool(); + m_bUseChallenge = + (sTmp = GetNV("UseChallenge")).empty() ? true : sTmp.ToBool(); + m_bRequestPerms = GetNV("RequestPerms").ToBool(); + m_bJoinOnInvite = + (sTmp = GetNV("JoinOnInvite")).empty() ? true : sTmp.ToBool(); + m_bJoinAfterCloaked = + (sTmp = GetNV("JoinAfterCloaked")).empty() ? true : sTmp.ToBool(); - // Make sure NVs are stored in config. Note: SetUseCloakedHost() is - // called further down. - SetUseChallenge(m_bUseChallenge); - SetRequestPerms(m_bRequestPerms); - SetJoinOnInvite(m_bJoinOnInvite); - SetJoinAfterCloaked(m_bJoinAfterCloaked); + // Make sure NVs are stored in config. Note: SetUseCloakedHost() is + // called further down. + SetUseChallenge(m_bUseChallenge); + SetRequestPerms(m_bRequestPerms); + SetJoinOnInvite(m_bJoinOnInvite); + SetJoinAfterCloaked(m_bJoinAfterCloaked); - OnIRCDisconnected(); // reset module's state + OnIRCDisconnected(); // reset module's state - if (IsIRCConnected()) { - // check for usermode +x if we are already connected - set scUserModes = - GetNetwork()->GetIRCSock()->GetUserModes(); - if (scUserModes.find('x') != scUserModes.end()) m_bCloaked = true; + if (IsIRCConnected()) { + // check for usermode +x if we are already connected + set scUserModes = + GetNetwork()->GetIRCSock()->GetUserModes(); + if (scUserModes.find('x') != scUserModes.end()) m_bCloaked = true; - // This will only happen once, and only if the user loads the module - // after connecting to IRC. - // Also don't notify the user in case he already had mode +x set. - if (GetNV("UseCloakedHost").empty()) { - if (!m_bCloaked) - PutModule( - "Notice: Your host will be cloaked the next time you " - "reconnect to IRC. " - "If you want to cloak your host now, /msg *q Cloak. " - "You can set your preference " - "with /msg *q Set UseCloakedHost true/false."); - m_bUseCloakedHost = true; - SetUseCloakedHost(m_bUseCloakedHost); - m_bJoinAfterCloaked = true; - SetJoinAfterCloaked(m_bJoinAfterCloaked); - } else if (m_bUseChallenge) { - Cloak(); - } - WhoAmI(); - } else { - SetUseCloakedHost(m_bUseCloakedHost); - } + // This will only happen once, and only if the user loads the module + // after connecting to IRC. + // Also don't notify the user in case he already had mode +x set. + if (GetNV("UseCloakedHost").empty()) { + if (!m_bCloaked) + PutModule( + "Notice: Your host will be cloaked the next time you " + "reconnect to IRC. " + "If you want to cloak your host now, /msg *q Cloak. " + "You can set your preference " + "with /msg *q Set UseCloakedHost true/false."); + m_bUseCloakedHost = true; + SetUseCloakedHost(m_bUseCloakedHost); + m_bJoinAfterCloaked = true; + SetJoinAfterCloaked(m_bJoinAfterCloaked); + } else if (m_bUseChallenge) { + Cloak(); + } + WhoAmI(); + } else { + SetUseCloakedHost(m_bUseCloakedHost); + } - return true; - } + return true; + } - void OnIRCDisconnected() override { - m_bCloaked = false; - m_bAuthed = false; - m_bRequestedWhoami = false; - m_bRequestedChallenge = false; - m_bCatchResponse = false; - } + void OnIRCDisconnected() override { + m_bCloaked = false; + m_bAuthed = false; + m_bRequestedWhoami = false; + m_bRequestedChallenge = false; + m_bCatchResponse = false; + } - void OnIRCConnected() override { - if (m_bUseCloakedHost) Cloak(); - WhoAmI(); - } + void OnIRCConnected() override { + if (m_bUseCloakedHost) Cloak(); + WhoAmI(); + } - void OnModCommand(const CString& sLine) override { - CString sCommand = sLine.Token(0).AsLower(); + void OnModCommand(const CString& sLine) override { + CString sCommand = sLine.Token(0).AsLower(); - if (sCommand == "help") { - PutModule("The following commands are available:"); - CTable Table; - Table.AddColumn("Command"); - Table.AddColumn("Description"); - Table.AddRow(); - Table.SetCell("Command", "Auth [ ]"); - Table.SetCell("Description", - "Tries to authenticate you with Q. Both parameters " - "are optional."); - Table.AddRow(); - Table.SetCell("Command", "Cloak"); - Table.SetCell( - "Description", - "Tries to set usermode +x to hide your real hostname."); - Table.AddRow(); - Table.SetCell("Command", "Status"); - Table.SetCell("Description", - "Prints the current status of the module."); - Table.AddRow(); - Table.SetCell("Command", "Update"); - Table.SetCell("Description", - "Re-requests the current user information from Q."); - Table.AddRow(); - Table.SetCell("Command", "Set "); - Table.SetCell("Description", - "Changes the value of the given setting. See the " - "list of settings below."); - Table.AddRow(); - Table.SetCell("Command", "Get"); - Table.SetCell("Description", - "Prints out the current configuration. See the list " - "of settings below."); - PutModule(Table); + if (sCommand == "help") { + PutModule("The following commands are available:"); + CTable Table; + Table.AddColumn("Command"); + Table.AddColumn("Description"); + Table.AddRow(); + Table.SetCell("Command", "Auth [ ]"); + Table.SetCell("Description", + "Tries to authenticate you with Q. Both parameters " + "are optional."); + Table.AddRow(); + Table.SetCell("Command", "Cloak"); + Table.SetCell( + "Description", + "Tries to set usermode +x to hide your real hostname."); + Table.AddRow(); + Table.SetCell("Command", "Status"); + Table.SetCell("Description", + "Prints the current status of the module."); + Table.AddRow(); + Table.SetCell("Command", "Update"); + Table.SetCell("Description", + "Re-requests the current user information from Q."); + Table.AddRow(); + Table.SetCell("Command", "Set "); + Table.SetCell("Description", + "Changes the value of the given setting. See the " + "list of settings below."); + Table.AddRow(); + Table.SetCell("Command", "Get"); + Table.SetCell("Description", + "Prints out the current configuration. See the list " + "of settings below."); + PutModule(Table); - PutModule("The following settings are available:"); - CTable Table2; - Table2.AddColumn("Setting"); - Table2.AddColumn("Type"); - Table2.AddColumn("Description"); - Table2.AddRow(); - Table2.SetCell("Setting", "Username"); - Table2.SetCell("Type", "String"); - Table2.SetCell("Description", "Your Q username."); - Table2.AddRow(); - Table2.SetCell("Setting", "Password"); - Table2.SetCell("Type", "String"); - Table2.SetCell("Description", "Your Q password."); - Table2.AddRow(); - Table2.SetCell("Setting", "UseCloakedHost"); - Table2.SetCell("Type", "Boolean"); - Table2.SetCell("Description", - "Whether to cloak your hostname (+x) automatically " - "on connect."); - Table2.AddRow(); - Table2.SetCell("Setting", "UseChallenge"); - Table2.SetCell("Type", "Boolean"); - Table2.SetCell("Description", - "Whether to use the CHALLENGEAUTH mechanism to " - "avoid sending passwords in cleartext."); - Table2.AddRow(); - Table2.SetCell("Setting", "RequestPerms"); - Table2.SetCell("Type", "Boolean"); - Table2.SetCell( - "Description", - "Whether to request voice/op from Q on join/devoice/deop."); - Table2.AddRow(); - Table2.SetCell("Setting", "JoinOnInvite"); - Table2.SetCell("Type", "Boolean"); - Table2.SetCell("Description", - "Whether to join channels when Q invites you."); - Table2.AddRow(); - Table2.SetCell("Setting", "JoinAfterCloaked"); - Table2.SetCell("Type", "Boolean"); - Table2.SetCell("Description", - "Whether to delay joining channels until after you " - "are cloaked."); - PutModule(Table2); + PutModule("The following settings are available:"); + CTable Table2; + Table2.AddColumn("Setting"); + Table2.AddColumn("Type"); + Table2.AddColumn("Description"); + Table2.AddRow(); + Table2.SetCell("Setting", "Username"); + Table2.SetCell("Type", "String"); + Table2.SetCell("Description", "Your Q username."); + Table2.AddRow(); + Table2.SetCell("Setting", "Password"); + Table2.SetCell("Type", "String"); + Table2.SetCell("Description", "Your Q password."); + Table2.AddRow(); + Table2.SetCell("Setting", "UseCloakedHost"); + Table2.SetCell("Type", "Boolean"); + Table2.SetCell("Description", + "Whether to cloak your hostname (+x) automatically " + "on connect."); + Table2.AddRow(); + Table2.SetCell("Setting", "UseChallenge"); + Table2.SetCell("Type", "Boolean"); + Table2.SetCell("Description", + "Whether to use the CHALLENGEAUTH mechanism to " + "avoid sending passwords in cleartext."); + Table2.AddRow(); + Table2.SetCell("Setting", "RequestPerms"); + Table2.SetCell("Type", "Boolean"); + Table2.SetCell( + "Description", + "Whether to request voice/op from Q on join/devoice/deop."); + Table2.AddRow(); + Table2.SetCell("Setting", "JoinOnInvite"); + Table2.SetCell("Type", "Boolean"); + Table2.SetCell("Description", + "Whether to join channels when Q invites you."); + Table2.AddRow(); + Table2.SetCell("Setting", "JoinAfterCloaked"); + Table2.SetCell("Type", "Boolean"); + Table2.SetCell("Description", + "Whether to delay joining channels until after you " + "are cloaked."); + PutModule(Table2); - PutModule( - "This module takes 2 optional parameters: " - ""); - PutModule("Module settings are stored between restarts."); + PutModule( + "This module takes 2 optional parameters: " + ""); + PutModule("Module settings are stored between restarts."); - } else if (sCommand == "set") { - CString sSetting = sLine.Token(1).AsLower(); - CString sValue = sLine.Token(2); - if (sSetting.empty() || sValue.empty()) { - PutModule("Syntax: Set "); - } else if (sSetting == "username") { - SetUsername(sValue); - PutModule("Username set"); - } else if (sSetting == "password") { - SetPassword(sValue); - PutModule("Password set"); - } else if (sSetting == "usecloakedhost") { - SetUseCloakedHost(sValue.ToBool()); - PutModule("UseCloakedHost set"); - } else if (sSetting == "usechallenge") { - SetUseChallenge(sValue.ToBool()); - PutModule("UseChallenge set"); - } else if (sSetting == "requestperms") { - SetRequestPerms(sValue.ToBool()); - PutModule("RequestPerms set"); - } else if (sSetting == "joinoninvite") { - SetJoinOnInvite(sValue.ToBool()); - PutModule("JoinOnInvite set"); - } else if (sSetting == "joinaftercloaked") { - SetJoinAfterCloaked(sValue.ToBool()); - PutModule("JoinAfterCloaked set"); - } else - PutModule("Unknown setting: " + sSetting); + } else if (sCommand == "set") { + CString sSetting = sLine.Token(1).AsLower(); + CString sValue = sLine.Token(2); + if (sSetting.empty() || sValue.empty()) { + PutModule("Syntax: Set "); + } else if (sSetting == "username") { + SetUsername(sValue); + PutModule("Username set"); + } else if (sSetting == "password") { + SetPassword(sValue); + PutModule("Password set"); + } else if (sSetting == "usecloakedhost") { + SetUseCloakedHost(sValue.ToBool()); + PutModule("UseCloakedHost set"); + } else if (sSetting == "usechallenge") { + SetUseChallenge(sValue.ToBool()); + PutModule("UseChallenge set"); + } else if (sSetting == "requestperms") { + SetRequestPerms(sValue.ToBool()); + PutModule("RequestPerms set"); + } else if (sSetting == "joinoninvite") { + SetJoinOnInvite(sValue.ToBool()); + PutModule("JoinOnInvite set"); + } else if (sSetting == "joinaftercloaked") { + SetJoinAfterCloaked(sValue.ToBool()); + PutModule("JoinAfterCloaked set"); + } else + PutModule("Unknown setting: " + sSetting); - } else if (sCommand == "get" || sCommand == "list") { - CTable Table; - Table.AddColumn("Setting"); - Table.AddColumn("Value"); - Table.AddRow(); - Table.SetCell("Setting", "Username"); - Table.SetCell("Value", m_sUsername); - Table.AddRow(); - Table.SetCell("Setting", "Password"); - Table.SetCell("Value", "*****"); // m_sPassword - Table.AddRow(); - Table.SetCell("Setting", "UseCloakedHost"); - Table.SetCell("Value", CString(m_bUseCloakedHost)); - Table.AddRow(); - Table.SetCell("Setting", "UseChallenge"); - Table.SetCell("Value", CString(m_bUseChallenge)); - Table.AddRow(); - Table.SetCell("Setting", "RequestPerms"); - Table.SetCell("Value", CString(m_bRequestPerms)); - Table.AddRow(); - Table.SetCell("Setting", "JoinOnInvite"); - Table.SetCell("Value", CString(m_bJoinOnInvite)); - Table.AddRow(); - Table.SetCell("Setting", "JoinAfterCloaked"); - Table.SetCell("Value", CString(m_bJoinAfterCloaked)); - PutModule(Table); + } else if (sCommand == "get" || sCommand == "list") { + CTable Table; + Table.AddColumn("Setting"); + Table.AddColumn("Value"); + Table.AddRow(); + Table.SetCell("Setting", "Username"); + Table.SetCell("Value", m_sUsername); + Table.AddRow(); + Table.SetCell("Setting", "Password"); + Table.SetCell("Value", "*****"); // m_sPassword + Table.AddRow(); + Table.SetCell("Setting", "UseCloakedHost"); + Table.SetCell("Value", CString(m_bUseCloakedHost)); + Table.AddRow(); + Table.SetCell("Setting", "UseChallenge"); + Table.SetCell("Value", CString(m_bUseChallenge)); + Table.AddRow(); + Table.SetCell("Setting", "RequestPerms"); + Table.SetCell("Value", CString(m_bRequestPerms)); + Table.AddRow(); + Table.SetCell("Setting", "JoinOnInvite"); + Table.SetCell("Value", CString(m_bJoinOnInvite)); + Table.AddRow(); + Table.SetCell("Setting", "JoinAfterCloaked"); + Table.SetCell("Value", CString(m_bJoinAfterCloaked)); + PutModule(Table); - } else if (sCommand == "status") { - PutModule("Connected: " + CString(IsIRCConnected() ? "yes" : "no")); - PutModule("Cloaked: " + CString(m_bCloaked ? "yes" : "no")); - PutModule("Authed: " + CString(m_bAuthed ? "yes" : "no")); + } else if (sCommand == "status") { + PutModule("Connected: " + CString(IsIRCConnected() ? "yes" : "no")); + PutModule("Cloaked: " + CString(m_bCloaked ? "yes" : "no")); + PutModule("Authed: " + CString(m_bAuthed ? "yes" : "no")); - } else { - // The following commands require an IRC connection. - if (!IsIRCConnected()) { - PutModule("Error: You are not connected to IRC."); - return; - } + } else { + // The following commands require an IRC connection. + if (!IsIRCConnected()) { + PutModule("Error: You are not connected to IRC."); + return; + } - if (sCommand == "cloak") { - if (!m_bCloaked) - Cloak(); - else - PutModule("Error: You are already cloaked!"); + if (sCommand == "cloak") { + if (!m_bCloaked) + Cloak(); + else + PutModule("Error: You are already cloaked!"); - } else if (sCommand == "auth") { - if (!m_bAuthed) - Auth(sLine.Token(1), sLine.Token(2)); - else - PutModule("Error: You are already authed!"); + } else if (sCommand == "auth") { + if (!m_bAuthed) + Auth(sLine.Token(1), sLine.Token(2)); + else + PutModule("Error: You are already authed!"); - } else if (sCommand == "update") { - WhoAmI(); - PutModule("Update requested."); + } else if (sCommand == "update") { + WhoAmI(); + PutModule("Update requested."); - } else { - PutModule("Unknown command. Try 'help'."); - } - } - } + } else { + PutModule("Unknown command. Try 'help'."); + } + } + } - EModRet OnRaw(CString& sLine) override { - // use OnRaw because OnUserMode is not defined (yet?) - if (sLine.Token(1) == "396" && - sLine.Token(3).find("users.quakenet.org") != CString::npos) { - m_bCloaked = true; - PutModule("Cloak successful: Your hostname is now cloaked."); + EModRet OnRaw(CString& sLine) override { + // use OnRaw because OnUserMode is not defined (yet?) + if (sLine.Token(1) == "396" && + sLine.Token(3).find("users.quakenet.org") != CString::npos) { + m_bCloaked = true; + PutModule("Cloak successful: Your hostname is now cloaked."); - // Join channels immediately after our spoof is set, but only if - // both UseCloakedHost and JoinAfterCloaked is enabled. See #602. - if (m_bJoinAfterCloaked) { - GetNetwork()->JoinChans(); - } - } - return CONTINUE; - } + // Join channels immediately after our spoof is set, but only if + // both UseCloakedHost and JoinAfterCloaked is enabled. See #602. + if (m_bJoinAfterCloaked) { + GetNetwork()->JoinChans(); + } + } + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - return HandleMessage(Nick, sMessage); - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + return HandleMessage(Nick, sMessage); + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - return HandleMessage(Nick, sMessage); - } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + return HandleMessage(Nick, sMessage); + } - EModRet OnJoining(CChan& Channel) override { - // Halt if are not already cloaked, but the user requres that we delay - // channel join till after we are cloaked. - if (!m_bCloaked && m_bUseCloakedHost && m_bJoinAfterCloaked) - return HALT; + EModRet OnJoining(CChan& Channel) override { + // Halt if are not already cloaked, but the user requres that we delay + // channel join till after we are cloaked. + if (!m_bCloaked && m_bUseCloakedHost && m_bJoinAfterCloaked) + return HALT; - return CONTINUE; - } + return CONTINUE; + } - void OnJoin(const CNick& Nick, CChan& Channel) override { - if (m_bRequestPerms && IsSelf(Nick)) HandleNeed(Channel, "ov"); - } + void OnJoin(const CNick& Nick, CChan& Channel) override { + if (m_bRequestPerms && IsSelf(Nick)) HandleNeed(Channel, "ov"); + } - void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - if (m_bRequestPerms && IsSelf(Nick) && (!pOpNick || !IsSelf(*pOpNick))) - HandleNeed(Channel, "o"); - } + void OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + if (m_bRequestPerms && IsSelf(Nick) && (!pOpNick || !IsSelf(*pOpNick))) + HandleNeed(Channel, "o"); + } - void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - if (m_bRequestPerms && IsSelf(Nick) && (!pOpNick || !IsSelf(*pOpNick))) - HandleNeed(Channel, "v"); - } + void OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + if (m_bRequestPerms && IsSelf(Nick) && (!pOpNick || !IsSelf(*pOpNick))) + HandleNeed(Channel, "v"); + } - EModRet OnInvite(const CNick& Nick, const CString& sChan) override { - if (!Nick.NickEquals("Q") || - !Nick.GetHost().Equals("CServe.quakenet.org")) - return CONTINUE; - if (m_bJoinOnInvite) GetNetwork()->AddChan(sChan, false); - return CONTINUE; - } + EModRet OnInvite(const CNick& Nick, const CString& sChan) override { + if (!Nick.NickEquals("Q") || + !Nick.GetHost().Equals("CServe.quakenet.org")) + return CONTINUE; + if (m_bJoinOnInvite) GetNetwork()->AddChan(sChan, false); + return CONTINUE; + } - CString GetWebMenuTitle() override { return "Q"; } + CString GetWebMenuTitle() override { return "Q"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - bool bSubmitted = (WebSock.GetParam("submitted").ToInt() != 0); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + bool bSubmitted = (WebSock.GetParam("submitted").ToInt() != 0); - if (bSubmitted) { - CString FormUsername = WebSock.GetParam("user"); - if (!FormUsername.empty()) SetUsername(FormUsername); + if (bSubmitted) { + CString FormUsername = WebSock.GetParam("user"); + if (!FormUsername.empty()) SetUsername(FormUsername); - CString FormPassword = WebSock.GetParam("password"); - if (!FormPassword.empty()) SetPassword(FormPassword); + CString FormPassword = WebSock.GetParam("password"); + if (!FormPassword.empty()) SetPassword(FormPassword); - SetUseCloakedHost(WebSock.GetParam("usecloakedhost").ToBool()); - SetUseChallenge(WebSock.GetParam("usechallenge").ToBool()); - SetRequestPerms(WebSock.GetParam("requestperms").ToBool()); - SetJoinOnInvite(WebSock.GetParam("joinoninvite").ToBool()); - SetJoinAfterCloaked( - WebSock.GetParam("joinaftercloaked").ToBool()); - } + SetUseCloakedHost(WebSock.GetParam("usecloakedhost").ToBool()); + SetUseChallenge(WebSock.GetParam("usechallenge").ToBool()); + SetRequestPerms(WebSock.GetParam("requestperms").ToBool()); + SetJoinOnInvite(WebSock.GetParam("joinoninvite").ToBool()); + SetJoinAfterCloaked( + WebSock.GetParam("joinaftercloaked").ToBool()); + } - Tmpl["Username"] = m_sUsername; + Tmpl["Username"] = m_sUsername; - CTemplate& o1 = Tmpl.AddRow("OptionLoop"); - o1["Name"] = "usecloakedhost"; - o1["DisplayName"] = "UseCloakedHost"; - o1["Tooltip"] = - "Whether to cloak your hostname (+x) automatically on connect."; - o1["Checked"] = CString(m_bUseCloakedHost); + CTemplate& o1 = Tmpl.AddRow("OptionLoop"); + o1["Name"] = "usecloakedhost"; + o1["DisplayName"] = "UseCloakedHost"; + o1["Tooltip"] = + "Whether to cloak your hostname (+x) automatically on connect."; + o1["Checked"] = CString(m_bUseCloakedHost); - CTemplate& o2 = Tmpl.AddRow("OptionLoop"); - o2["Name"] = "usechallenge"; - o2["DisplayName"] = "UseChallenge"; - o2["Tooltip"] = - "Whether to use the CHALLENGEAUTH mechanism to avoid sending " - "passwords in cleartext."; - o2["Checked"] = CString(m_bUseChallenge); + CTemplate& o2 = Tmpl.AddRow("OptionLoop"); + o2["Name"] = "usechallenge"; + o2["DisplayName"] = "UseChallenge"; + o2["Tooltip"] = + "Whether to use the CHALLENGEAUTH mechanism to avoid sending " + "passwords in cleartext."; + o2["Checked"] = CString(m_bUseChallenge); - CTemplate& o3 = Tmpl.AddRow("OptionLoop"); - o3["Name"] = "requestperms"; - o3["DisplayName"] = "RequestPerms"; - o3["Tooltip"] = - "Whether to request voice/op from Q on join/devoice/deop."; - o3["Checked"] = CString(m_bRequestPerms); + CTemplate& o3 = Tmpl.AddRow("OptionLoop"); + o3["Name"] = "requestperms"; + o3["DisplayName"] = "RequestPerms"; + o3["Tooltip"] = + "Whether to request voice/op from Q on join/devoice/deop."; + o3["Checked"] = CString(m_bRequestPerms); - CTemplate& o4 = Tmpl.AddRow("OptionLoop"); - o4["Name"] = "joinoninvite"; - o4["DisplayName"] = "JoinOnInvite"; - o4["Tooltip"] = "Whether to join channels when Q invites you."; - o4["Checked"] = CString(m_bJoinOnInvite); + CTemplate& o4 = Tmpl.AddRow("OptionLoop"); + o4["Name"] = "joinoninvite"; + o4["DisplayName"] = "JoinOnInvite"; + o4["Tooltip"] = "Whether to join channels when Q invites you."; + o4["Checked"] = CString(m_bJoinOnInvite); - CTemplate& o5 = Tmpl.AddRow("OptionLoop"); - o5["Name"] = "joinaftercloaked"; - o5["DisplayName"] = "JoinAfterCloaked"; - o5["Tooltip"] = - "Whether to delay joining channels until after you are " - "cloaked."; - o5["Checked"] = CString(m_bJoinAfterCloaked); + CTemplate& o5 = Tmpl.AddRow("OptionLoop"); + o5["Name"] = "joinaftercloaked"; + o5["DisplayName"] = "JoinAfterCloaked"; + o5["Tooltip"] = + "Whether to delay joining channels until after you are " + "cloaked."; + o5["Checked"] = CString(m_bJoinAfterCloaked); - if (bSubmitted) { - WebSock.GetSession()->AddSuccess("Changes have been saved!"); - } + if (bSubmitted) { + WebSock.GetSession()->AddSuccess("Changes have been saved!"); + } - return true; - } + return true; + } - return false; - } + return false; + } private: - bool m_bCloaked{}; - bool m_bAuthed{}; - bool m_bRequestedWhoami{}; - bool m_bRequestedChallenge{}; - bool m_bCatchResponse{}; - MCString m_msChanModes; + bool m_bCloaked{}; + bool m_bAuthed{}; + bool m_bRequestedWhoami{}; + bool m_bRequestedChallenge{}; + bool m_bCatchResponse{}; + MCString m_msChanModes; - void PutQ(const CString& sMessage) { - PutIRC("PRIVMSG Q@CServe.quakenet.org :" + sMessage); + void PutQ(const CString& sMessage) { + PutIRC("PRIVMSG Q@CServe.quakenet.org :" + sMessage); #if Q_DEBUG_COMMUNICATION - PutModule("[ZNC --> Q] " + sMessage); + PutModule("[ZNC --> Q] " + sMessage); #endif - } + } - void Cloak() { - if (m_bCloaked) return; + void Cloak() { + if (m_bCloaked) return; - PutModule("Cloak: Trying to cloak your hostname, setting +x..."); - PutIRC("MODE " + GetNetwork()->GetIRCSock()->GetNick() + " +x"); - } + PutModule("Cloak: Trying to cloak your hostname, setting +x..."); + PutIRC("MODE " + GetNetwork()->GetIRCSock()->GetNick() + " +x"); + } - void WhoAmI() { - m_bRequestedWhoami = true; - PutQ("WHOAMI"); - } + void WhoAmI() { + m_bRequestedWhoami = true; + PutQ("WHOAMI"); + } - void Auth(const CString& sUsername = "", const CString& sPassword = "") { - if (m_bAuthed) return; + void Auth(const CString& sUsername = "", const CString& sPassword = "") { + if (m_bAuthed) return; - if (!sUsername.empty()) SetUsername(sUsername); - if (!sPassword.empty()) SetPassword(sPassword); + if (!sUsername.empty()) SetUsername(sUsername); + if (!sPassword.empty()) SetPassword(sPassword); - if (m_sUsername.empty() || m_sPassword.empty()) { - PutModule( - "You have to set a username and password to use this module! " - "See 'help' for details."); - return; - } + if (m_sUsername.empty() || m_sPassword.empty()) { + PutModule( + "You have to set a username and password to use this module! " + "See 'help' for details."); + return; + } - if (m_bUseChallenge) { - PutModule("Auth: Requesting CHALLENGE..."); - m_bRequestedChallenge = true; - PutQ("CHALLENGE"); - } else { - PutModule("Auth: Sending AUTH request..."); - PutQ("AUTH " + m_sUsername + " " + m_sPassword); - } - } + if (m_bUseChallenge) { + PutModule("Auth: Requesting CHALLENGE..."); + m_bRequestedChallenge = true; + PutQ("CHALLENGE"); + } else { + PutModule("Auth: Sending AUTH request..."); + PutQ("AUTH " + m_sUsername + " " + m_sPassword); + } + } - void ChallengeAuth(CString sChallenge) { - if (m_bAuthed) return; + void ChallengeAuth(CString sChallenge) { + if (m_bAuthed) return; - CString sUsername = m_sUsername.AsLower() - .Replace_n("[", "{") - .Replace_n("]", "}") - .Replace_n("\\", "|"); - CString sPasswordHash = m_sPassword.Left(10).SHA256(); - CString sKey = CString(sUsername + ":" + sPasswordHash).SHA256(); - CString sResponse = HMAC_SHA256(sKey, sChallenge); + CString sUsername = m_sUsername.AsLower() + .Replace_n("[", "{") + .Replace_n("]", "}") + .Replace_n("\\", "|"); + CString sPasswordHash = m_sPassword.Left(10).SHA256(); + CString sKey = CString(sUsername + ":" + sPasswordHash).SHA256(); + CString sResponse = HMAC_SHA256(sKey, sChallenge); - PutModule("Auth: Received challenge, sending CHALLENGEAUTH request..."); - PutQ("CHALLENGEAUTH " + m_sUsername + " " + sResponse + - " HMAC-SHA-256"); - } + PutModule("Auth: Received challenge, sending CHALLENGEAUTH request..."); + PutQ("CHALLENGEAUTH " + m_sUsername + " " + sResponse + + " HMAC-SHA-256"); + } - EModRet HandleMessage(const CNick& Nick, CString sMessage) { - if (!Nick.NickEquals("Q") || - !Nick.GetHost().Equals("CServe.quakenet.org")) - return CONTINUE; + EModRet HandleMessage(const CNick& Nick, CString sMessage) { + if (!Nick.NickEquals("Q") || + !Nick.GetHost().Equals("CServe.quakenet.org")) + return CONTINUE; - sMessage.Trim(); + sMessage.Trim(); #if Q_DEBUG_COMMUNICATION - PutModule("[ZNC <-- Q] " + sMessage); + PutModule("[ZNC <-- Q] " + sMessage); #endif - // WHOAMI - if (sMessage.find("WHOAMI is only available to authed users") != - CString::npos) { - m_bAuthed = false; - Auth(); - m_bCatchResponse = m_bRequestedWhoami; - } else if (sMessage.find("Information for user") != CString::npos) { - m_bAuthed = true; - m_msChanModes.clear(); - m_bCatchResponse = m_bRequestedWhoami; - m_bRequestedWhoami = true; - } else if (m_bRequestedWhoami && sMessage.WildCmp("#*")) { - CString sChannel = sMessage.Token(0); - CString sFlags = sMessage.Token(1, true).Trim_n().TrimLeft_n("+"); - m_msChanModes[sChannel] = sFlags; - } else if (m_bRequestedWhoami && m_bCatchResponse && - (sMessage.Equals("End of list.") || - sMessage.Equals( - "account, or HELLO to create an account."))) { - m_bRequestedWhoami = m_bCatchResponse = false; - return HALT; - } + // WHOAMI + if (sMessage.find("WHOAMI is only available to authed users") != + CString::npos) { + m_bAuthed = false; + Auth(); + m_bCatchResponse = m_bRequestedWhoami; + } else if (sMessage.find("Information for user") != CString::npos) { + m_bAuthed = true; + m_msChanModes.clear(); + m_bCatchResponse = m_bRequestedWhoami; + m_bRequestedWhoami = true; + } else if (m_bRequestedWhoami && sMessage.WildCmp("#*")) { + CString sChannel = sMessage.Token(0); + CString sFlags = sMessage.Token(1, true).Trim_n().TrimLeft_n("+"); + m_msChanModes[sChannel] = sFlags; + } else if (m_bRequestedWhoami && m_bCatchResponse && + (sMessage.Equals("End of list.") || + sMessage.Equals( + "account, or HELLO to create an account."))) { + m_bRequestedWhoami = m_bCatchResponse = false; + return HALT; + } - // AUTH - else if (sMessage.Equals("Username or password incorrect.")) { - m_bAuthed = false; - PutModule("Auth failed: " + sMessage); - return HALT; - } else if (sMessage.WildCmp("You are now logged in as *.")) { - m_bAuthed = true; - PutModule("Auth successful: " + sMessage); - WhoAmI(); - return HALT; - } else if (m_bRequestedChallenge && - sMessage.Token(0).Equals("CHALLENGE")) { - m_bRequestedChallenge = false; - if (sMessage.find("not available once you have authed") != - CString::npos) { - m_bAuthed = true; - } else { - if (sMessage.find("HMAC-SHA-256") != CString::npos) { - ChallengeAuth(sMessage.Token(1)); - } else { - PutModule( - "Auth failed: Q does not support HMAC-SHA-256 for " - "CHALLENGEAUTH, falling back to standard AUTH."); - SetUseChallenge(false); - Auth(); - } - } - return HALT; - } + // AUTH + else if (sMessage.Equals("Username or password incorrect.")) { + m_bAuthed = false; + PutModule("Auth failed: " + sMessage); + return HALT; + } else if (sMessage.WildCmp("You are now logged in as *.")) { + m_bAuthed = true; + PutModule("Auth successful: " + sMessage); + WhoAmI(); + return HALT; + } else if (m_bRequestedChallenge && + sMessage.Token(0).Equals("CHALLENGE")) { + m_bRequestedChallenge = false; + if (sMessage.find("not available once you have authed") != + CString::npos) { + m_bAuthed = true; + } else { + if (sMessage.find("HMAC-SHA-256") != CString::npos) { + ChallengeAuth(sMessage.Token(1)); + } else { + PutModule( + "Auth failed: Q does not support HMAC-SHA-256 for " + "CHALLENGEAUTH, falling back to standard AUTH."); + SetUseChallenge(false); + Auth(); + } + } + return HALT; + } - // prevent buffering of Q's responses - return !m_bCatchResponse && GetUser()->IsUserAttached() ? CONTINUE - : HALT; - } + // prevent buffering of Q's responses + return !m_bCatchResponse && GetUser()->IsUserAttached() ? CONTINUE + : HALT; + } - void HandleNeed(const CChan& Channel, const CString& sPerms) { - MCString::iterator it = m_msChanModes.find(Channel.GetName()); - if (it == m_msChanModes.end()) return; - CString sModes = it->second; + void HandleNeed(const CChan& Channel, const CString& sPerms) { + MCString::iterator it = m_msChanModes.find(Channel.GetName()); + if (it == m_msChanModes.end()) return; + CString sModes = it->second; - bool bMaster = (sModes.find("m") != CString::npos) || - (sModes.find("n") != CString::npos); + bool bMaster = (sModes.find("m") != CString::npos) || + (sModes.find("n") != CString::npos); - if (sPerms.find("o") != CString::npos) { - bool bOp = (sModes.find("o") != CString::npos); - bool bAutoOp = (sModes.find("a") != CString::npos); - if (bMaster || bOp) { - if (!bAutoOp) { - PutModule("RequestPerms: Requesting op on " + - Channel.GetName()); - PutQ("OP " + Channel.GetName()); - } - return; - } - } + if (sPerms.find("o") != CString::npos) { + bool bOp = (sModes.find("o") != CString::npos); + bool bAutoOp = (sModes.find("a") != CString::npos); + if (bMaster || bOp) { + if (!bAutoOp) { + PutModule("RequestPerms: Requesting op on " + + Channel.GetName()); + PutQ("OP " + Channel.GetName()); + } + return; + } + } - if (sPerms.find("v") != CString::npos) { - bool bVoice = (sModes.find("v") != CString::npos); - bool bAutoVoice = (sModes.find("g") != CString::npos); - if (bMaster || bVoice) { - if (!bAutoVoice) { - PutModule("RequestPerms: Requesting voice on " + - Channel.GetName()); - PutQ("VOICE " + Channel.GetName()); - } - return; - } - } - } + if (sPerms.find("v") != CString::npos) { + bool bVoice = (sModes.find("v") != CString::npos); + bool bAutoVoice = (sModes.find("g") != CString::npos); + if (bMaster || bVoice) { + if (!bAutoVoice) { + PutModule("RequestPerms: Requesting voice on " + + Channel.GetName()); + PutQ("VOICE " + Channel.GetName()); + } + return; + } + } + } - /* Utility Functions */ - bool IsIRCConnected() { - CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); - return pIRCSock && pIRCSock->IsAuthed(); - } + /* Utility Functions */ + bool IsIRCConnected() { + CIRCSock* pIRCSock = GetNetwork()->GetIRCSock(); + return pIRCSock && pIRCSock->IsAuthed(); + } - bool IsSelf(const CNick& Nick) { - return Nick.NickEquals(GetNetwork()->GetCurNick()); - } + bool IsSelf(const CNick& Nick) { + return Nick.NickEquals(GetNetwork()->GetCurNick()); + } - bool PackHex(const CString& sHex, CString& sPackedHex) { - if (sHex.length() % 2) return false; + bool PackHex(const CString& sHex, CString& sPackedHex) { + if (sHex.length() % 2) return false; - sPackedHex.clear(); + sPackedHex.clear(); - CString::size_type len = sHex.length() / 2; - for (CString::size_type i = 0; i < len; i++) { - unsigned int value; - int n = sscanf(&sHex[i * 2], "%02x", &value); - if (n != 1 || value > 0xff) return false; - sPackedHex += (unsigned char)value; - } + CString::size_type len = sHex.length() / 2; + for (CString::size_type i = 0; i < len; i++) { + unsigned int value; + int n = sscanf(&sHex[i * 2], "%02x", &value); + if (n != 1 || value > 0xff) return false; + sPackedHex += (unsigned char)value; + } - return true; - } + return true; + } - CString HMAC_SHA256(const CString& sKey, const CString& sData) { - CString sRealKey; - if (sKey.length() > 64) - PackHex(sKey.SHA256(), sRealKey); - else - sRealKey = sKey; + CString HMAC_SHA256(const CString& sKey, const CString& sData) { + CString sRealKey; + if (sKey.length() > 64) + PackHex(sKey.SHA256(), sRealKey); + else + sRealKey = sKey; - CString sOuterKey, sInnerKey; - CString::size_type iKeyLength = sRealKey.length(); - for (unsigned int i = 0; i < 64; i++) { - char r = (i < iKeyLength ? sRealKey[i] : '\0'); - sOuterKey += r ^ 0x5c; - sInnerKey += r ^ 0x36; - } + CString sOuterKey, sInnerKey; + CString::size_type iKeyLength = sRealKey.length(); + for (unsigned int i = 0; i < 64; i++) { + char r = (i < iKeyLength ? sRealKey[i] : '\0'); + sOuterKey += r ^ 0x5c; + sInnerKey += r ^ 0x36; + } - CString sInnerHash; - PackHex(CString(sInnerKey + sData).SHA256(), sInnerHash); - return CString(sOuterKey + sInnerHash).SHA256(); - } + CString sInnerHash; + PackHex(CString(sInnerKey + sData).SHA256(), sInnerHash); + return CString(sOuterKey + sInnerHash).SHA256(); + } - /* Settings */ - CString m_sUsername; - CString m_sPassword; - bool m_bUseCloakedHost{}; - bool m_bUseChallenge{}; - bool m_bRequestPerms{}; - bool m_bJoinOnInvite{}; - bool m_bJoinAfterCloaked{}; + /* Settings */ + CString m_sUsername; + CString m_sPassword; + bool m_bUseCloakedHost{}; + bool m_bUseChallenge{}; + bool m_bRequestPerms{}; + bool m_bJoinOnInvite{}; + bool m_bJoinAfterCloaked{}; - void SetUsername(const CString& sUsername) { - m_sUsername = sUsername; - SetNV("Username", sUsername); - } + void SetUsername(const CString& sUsername) { + m_sUsername = sUsername; + SetNV("Username", sUsername); + } - void SetPassword(const CString& sPassword) { - m_sPassword = sPassword; - SetNV("Password", sPassword); - } + void SetPassword(const CString& sPassword) { + m_sPassword = sPassword; + SetNV("Password", sPassword); + } - void SetUseCloakedHost(const bool bUseCloakedHost) { - m_bUseCloakedHost = bUseCloakedHost; - SetNV("UseCloakedHost", CString(bUseCloakedHost)); + void SetUseCloakedHost(const bool bUseCloakedHost) { + m_bUseCloakedHost = bUseCloakedHost; + SetNV("UseCloakedHost", CString(bUseCloakedHost)); - if (!m_bCloaked && m_bUseCloakedHost && IsIRCConnected()) Cloak(); - } + if (!m_bCloaked && m_bUseCloakedHost && IsIRCConnected()) Cloak(); + } - void SetUseChallenge(const bool bUseChallenge) { - m_bUseChallenge = bUseChallenge; - SetNV("UseChallenge", CString(bUseChallenge)); - } + void SetUseChallenge(const bool bUseChallenge) { + m_bUseChallenge = bUseChallenge; + SetNV("UseChallenge", CString(bUseChallenge)); + } - void SetRequestPerms(const bool bRequestPerms) { - m_bRequestPerms = bRequestPerms; - SetNV("RequestPerms", CString(bRequestPerms)); - } + void SetRequestPerms(const bool bRequestPerms) { + m_bRequestPerms = bRequestPerms; + SetNV("RequestPerms", CString(bRequestPerms)); + } - void SetJoinOnInvite(const bool bJoinOnInvite) { - m_bJoinOnInvite = bJoinOnInvite; - SetNV("JoinOnInvite", CString(bJoinOnInvite)); - } + void SetJoinOnInvite(const bool bJoinOnInvite) { + m_bJoinOnInvite = bJoinOnInvite; + SetNV("JoinOnInvite", CString(bJoinOnInvite)); + } - void SetJoinAfterCloaked(const bool bJoinAfterCloaked) { - m_bJoinAfterCloaked = bJoinAfterCloaked; - SetNV("JoinAfterCloaked", CString(bJoinAfterCloaked)); - } + void SetJoinAfterCloaked(const bool bJoinAfterCloaked) { + m_bJoinAfterCloaked = bJoinAfterCloaked; + SetNV("JoinAfterCloaked", CString(bJoinAfterCloaked)); + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("Q"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Please provide your username and password for Q."); + Info.SetWikiPage("Q"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("Please provide your username and password for Q."); } NETWORKMODULEDEFS(CQModule, "Auths you with QuakeNet's Q bot.") diff --git a/modules/raw.cpp b/modules/raw.cpp index 114ca24b..ff53350d 100644 --- a/modules/raw.cpp +++ b/modules/raw.cpp @@ -18,26 +18,26 @@ class CRawMod : public CModule { public: - MODCONSTRUCTOR(CRawMod) {} - virtual ~CRawMod() {} + MODCONSTRUCTOR(CRawMod) {} + virtual ~CRawMod() {} - EModRet OnRaw(CString& sLine) override { - PutModule("IRC -> [" + sLine + "]"); - return CONTINUE; - } + EModRet OnRaw(CString& sLine) override { + PutModule("IRC -> [" + sLine + "]"); + return CONTINUE; + } - void OnModCommand(const CString& sCommand) override { PutIRC(sCommand); } + void OnModCommand(const CString& sCommand) override { PutIRC(sCommand); } - EModRet OnUserRaw(CString& sLine) override { - PutModule("YOU -> [" + sLine + "]"); - return CONTINUE; - } + EModRet OnUserRaw(CString& sLine) override { + PutModule("YOU -> [" + sLine + "]"); + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("raw"); - Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("raw"); + Info.AddType(CModInfo::UserModule); } NETWORKMODULEDEFS(CRawMod, "View all of the raw traffic") diff --git a/modules/route_replies.cpp b/modules/route_replies.cpp index 1f996f78..24c603d0 100644 --- a/modules/route_replies.cpp +++ b/modules/route_replies.cpp @@ -18,14 +18,14 @@ #include struct reply { - const char* szReply; - bool bLastResponse; + const char* szReply; + bool bLastResponse; }; // TODO this list is far from complete, no errors are handled static const struct { - const char* szRequest; - struct reply vReplies[19]; + const char* szRequest; + struct reply vReplies[19]; } vRouteReplies[] = { {"WHO", {{"402", true}, /* rfc1459 ERR_NOSUCHSERVER */ @@ -182,272 +182,272 @@ static const struct { class CRouteTimeout : public CTimer { public: - CRouteTimeout(CModule* pModule, unsigned int uInterval, - unsigned int uCycles, const CString& sLabel, - const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CRouteTimeout() {} + CRouteTimeout(CModule* pModule, unsigned int uInterval, + unsigned int uCycles, const CString& sLabel, + const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + virtual ~CRouteTimeout() {} protected: - void RunJob() override; + void RunJob() override; }; struct queued_req { - CString sLine; - const struct reply* reply; + CString sLine; + const struct reply* reply; }; typedef std::map> requestQueue; class CRouteRepliesMod : public CModule { public: - MODCONSTRUCTOR(CRouteRepliesMod) { - m_pDoing = nullptr; - m_pReplies = nullptr; + MODCONSTRUCTOR(CRouteRepliesMod) { + m_pDoing = nullptr; + m_pReplies = nullptr; - AddHelpCommand(); - AddCommand("Silent", static_cast( - &CRouteRepliesMod::SilentCommand), - "[yes|no]", - "Decides whether to show the timeout messages or not"); - } + AddHelpCommand(); + AddCommand("Silent", static_cast( + &CRouteRepliesMod::SilentCommand), + "[yes|no]", + "Decides whether to show the timeout messages or not"); + } - virtual ~CRouteRepliesMod() { - requestQueue::iterator it; + virtual ~CRouteRepliesMod() { + requestQueue::iterator it; - while (!m_vsPending.empty()) { - it = m_vsPending.begin(); + while (!m_vsPending.empty()) { + it = m_vsPending.begin(); - while (!it->second.empty()) { - PutIRC(it->second[0].sLine); - it->second.erase(it->second.begin()); - } + while (!it->second.empty()) { + PutIRC(it->second[0].sLine); + it->second.erase(it->second.begin()); + } - m_vsPending.erase(it); - } - } + m_vsPending.erase(it); + } + } - void OnIRCConnected() override { - m_pDoing = nullptr; - m_pReplies = nullptr; - m_vsPending.clear(); + void OnIRCConnected() override { + m_pDoing = nullptr; + m_pReplies = nullptr; + m_vsPending.clear(); - // No way we get a reply, so stop the timer (If it's running) - RemTimer("RouteTimeout"); - } + // No way we get a reply, so stop the timer (If it's running) + RemTimer("RouteTimeout"); + } - void OnIRCDisconnected() override { - OnIRCConnected(); // Let's keep it in one place - } + void OnIRCDisconnected() override { + OnIRCConnected(); // Let's keep it in one place + } - void OnClientDisconnect() override { - requestQueue::iterator it; + void OnClientDisconnect() override { + requestQueue::iterator it; - if (GetClient() == m_pDoing) { - // The replies which aren't received yet will be - // broadcasted to everyone, but at least nothing breaks - RemTimer("RouteTimeout"); - m_pDoing = nullptr; - m_pReplies = nullptr; - } + if (GetClient() == m_pDoing) { + // The replies which aren't received yet will be + // broadcasted to everyone, but at least nothing breaks + RemTimer("RouteTimeout"); + m_pDoing = nullptr; + m_pReplies = nullptr; + } - it = m_vsPending.find(GetClient()); + it = m_vsPending.find(GetClient()); - if (it != m_vsPending.end()) m_vsPending.erase(it); + if (it != m_vsPending.end()) m_vsPending.erase(it); - SendRequest(); - } + SendRequest(); + } - EModRet OnRaw(CString& sLine) override { - CString sCmd = sLine.Token(1).AsUpper(); - size_t i = 0; + EModRet OnRaw(CString& sLine) override { + CString sCmd = sLine.Token(1).AsUpper(); + size_t i = 0; - if (!m_pReplies) return CONTINUE; + if (!m_pReplies) return CONTINUE; - // Is this a "not enough arguments" error? - if (sCmd == "461") { - // :server 461 nick WHO :Not enough parameters - CString sOrigCmd = sLine.Token(3); + // Is this a "not enough arguments" error? + if (sCmd == "461") { + // :server 461 nick WHO :Not enough parameters + CString sOrigCmd = sLine.Token(3); - if (m_sLastRequest.Token(0).Equals(sOrigCmd)) { - // This is the reply to the last request - if (RouteReply(sLine, true)) return HALTCORE; - return CONTINUE; - } - } + if (m_sLastRequest.Token(0).Equals(sOrigCmd)) { + // This is the reply to the last request + if (RouteReply(sLine, true)) return HALTCORE; + return CONTINUE; + } + } - while (m_pReplies[i].szReply != nullptr) { - if (m_pReplies[i].szReply == sCmd) { - if (RouteReply(sLine, m_pReplies[i].bLastResponse)) - return HALTCORE; - return CONTINUE; - } - i++; - } + while (m_pReplies[i].szReply != nullptr) { + if (m_pReplies[i].szReply == sCmd) { + if (RouteReply(sLine, m_pReplies[i].bLastResponse)) + return HALTCORE; + return CONTINUE; + } + i++; + } - // TODO HALTCORE is wrong, it should not be passed to - // the clients, but the core itself should still handle it! + // TODO HALTCORE is wrong, it should not be passed to + // the clients, but the core itself should still handle it! - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserRaw(CString& sLine) override { - CString sCmd = sLine.Token(0).AsUpper(); + EModRet OnUserRaw(CString& sLine) override { + CString sCmd = sLine.Token(0).AsUpper(); - if (!GetNetwork()->GetIRCSock()) return CONTINUE; + if (!GetNetwork()->GetIRCSock()) return CONTINUE; - if (sCmd.Equals("MODE")) { - // Check if this is a mode request that needs to be handled + if (sCmd.Equals("MODE")) { + // Check if this is a mode request that needs to be handled - // If there are arguments to a mode change, - // we must not route it. - if (!sLine.Token(3, true).empty()) return CONTINUE; + // If there are arguments to a mode change, + // we must not route it. + if (!sLine.Token(3, true).empty()) return CONTINUE; - // Grab the mode change parameter - CString sMode = sLine.Token(2); + // Grab the mode change parameter + CString sMode = sLine.Token(2); - // If this is a channel mode request, znc core replies to it - if (sMode.empty()) return CONTINUE; + // If this is a channel mode request, znc core replies to it + if (sMode.empty()) return CONTINUE; - // Check if this is a mode change or a specific - // mode request (the later needs to be routed). - sMode.TrimPrefix("+"); - if (sMode.length() != 1) return CONTINUE; + // Check if this is a mode change or a specific + // mode request (the later needs to be routed). + sMode.TrimPrefix("+"); + if (sMode.length() != 1) return CONTINUE; - // Now just check if it's one of the supported modes - switch (sMode[0]) { - case 'I': - case 'b': - case 'e': - break; - default: - return CONTINUE; - } + // Now just check if it's one of the supported modes + switch (sMode[0]) { + case 'I': + case 'b': + case 'e': + break; + default: + return CONTINUE; + } - // Ok, this looks like we should route it. - // Fall through to the next loop - } + // Ok, this looks like we should route it. + // Fall through to the next loop + } - for (size_t i = 0; vRouteReplies[i].szRequest != nullptr; i++) { - if (vRouteReplies[i].szRequest == sCmd) { - struct queued_req req = {sLine, vRouteReplies[i].vReplies}; - m_vsPending[GetClient()].push_back(req); - SendRequest(); + for (size_t i = 0; vRouteReplies[i].szRequest != nullptr; i++) { + if (vRouteReplies[i].szRequest == sCmd) { + struct queued_req req = {sLine, vRouteReplies[i].vReplies}; + m_vsPending[GetClient()].push_back(req); + SendRequest(); - return HALTCORE; - } - } + return HALTCORE; + } + } - return CONTINUE; - } + return CONTINUE; + } - void Timeout() { - // The timer will be deleted after this by the event loop + void Timeout() { + // The timer will be deleted after this by the event loop - if (!GetNV("silent_timeouts").ToBool()) { - PutModule( - "This module hit a timeout which is probably a connectivity " - "issue."); - PutModule( - "However, if you can provide steps to reproduce this issue, " - "please do report a bug."); - PutModule("To disable this message, do \"/msg " + GetModNick() + - " silent yes\""); - PutModule("Last request: " + m_sLastRequest); - PutModule("Expected replies: "); + if (!GetNV("silent_timeouts").ToBool()) { + PutModule( + "This module hit a timeout which is probably a connectivity " + "issue."); + PutModule( + "However, if you can provide steps to reproduce this issue, " + "please do report a bug."); + PutModule("To disable this message, do \"/msg " + GetModNick() + + " silent yes\""); + PutModule("Last request: " + m_sLastRequest); + PutModule("Expected replies: "); - for (size_t i = 0; m_pReplies[i].szReply != nullptr; i++) { - if (m_pReplies[i].bLastResponse) - PutModule(m_pReplies[i].szReply + CString(" (last)")); - else - PutModule(m_pReplies[i].szReply); - } - } + for (size_t i = 0; m_pReplies[i].szReply != nullptr; i++) { + if (m_pReplies[i].bLastResponse) + PutModule(m_pReplies[i].szReply + CString(" (last)")); + else + PutModule(m_pReplies[i].szReply); + } + } - m_pDoing = nullptr; - m_pReplies = nullptr; - SendRequest(); - } + m_pDoing = nullptr; + m_pReplies = nullptr; + SendRequest(); + } private: - bool RouteReply(const CString& sLine, bool bFinished = false) { - if (!m_pDoing) return false; + bool RouteReply(const CString& sLine, bool bFinished = false) { + if (!m_pDoing) return false; - // TODO: RouteReply(const CMessage& Message, bool bFinished = false) - m_pDoing->PutClient(CMessage(sLine)); + // TODO: RouteReply(const CMessage& Message, bool bFinished = false) + m_pDoing->PutClient(CMessage(sLine)); - if (bFinished) { - // Stop the timeout - RemTimer("RouteTimeout"); + if (bFinished) { + // Stop the timeout + RemTimer("RouteTimeout"); - m_pDoing = nullptr; - m_pReplies = nullptr; - SendRequest(); - } + m_pDoing = nullptr; + m_pReplies = nullptr; + SendRequest(); + } - return true; - } + return true; + } - void SendRequest() { - requestQueue::iterator it; + void SendRequest() { + requestQueue::iterator it; - if (m_pDoing || m_pReplies) return; + if (m_pDoing || m_pReplies) return; - if (m_vsPending.empty()) return; + if (m_vsPending.empty()) return; - it = m_vsPending.begin(); + it = m_vsPending.begin(); - if (it->second.empty()) { - m_vsPending.erase(it); - SendRequest(); - return; - } + if (it->second.empty()) { + m_vsPending.erase(it); + SendRequest(); + return; + } - // When we are called from the timer, we need to remove it. - // We can't delete it (segfault on return), thus we - // just stop it. The main loop will delete it. - CTimer* pTimer = FindTimer("RouteTimeout"); - if (pTimer) { - pTimer->Stop(); - UnlinkTimer(pTimer); - } - AddTimer( - new CRouteTimeout(this, 60, 1, "RouteTimeout", - "Recover from missing / wrong server replies")); + // When we are called from the timer, we need to remove it. + // We can't delete it (segfault on return), thus we + // just stop it. The main loop will delete it. + CTimer* pTimer = FindTimer("RouteTimeout"); + if (pTimer) { + pTimer->Stop(); + UnlinkTimer(pTimer); + } + AddTimer( + new CRouteTimeout(this, 60, 1, "RouteTimeout", + "Recover from missing / wrong server replies")); - m_pDoing = it->first; - m_pReplies = it->second[0].reply; - m_sLastRequest = it->second[0].sLine; - PutIRC(it->second[0].sLine); - it->second.erase(it->second.begin()); - } + m_pDoing = it->first; + m_pReplies = it->second[0].reply; + m_sLastRequest = it->second[0].sLine; + PutIRC(it->second[0].sLine); + it->second.erase(it->second.begin()); + } - void SilentCommand(const CString& sLine) { - const CString sValue = sLine.Token(1); + void SilentCommand(const CString& sLine) { + const CString sValue = sLine.Token(1); - if (!sValue.empty()) { - SetNV("silent_timeouts", sValue); - } + if (!sValue.empty()) { + SetNV("silent_timeouts", sValue); + } - CString sPrefix = GetNV("silent_timeouts").ToBool() ? "dis" : "en"; - PutModule("Timeout messages are " + sPrefix + "abled."); - } + CString sPrefix = GetNV("silent_timeouts").ToBool() ? "dis" : "en"; + PutModule("Timeout messages are " + sPrefix + "abled."); + } - CClient* m_pDoing; - const struct reply* m_pReplies; - requestQueue m_vsPending; - // This field is only used for display purpose. - CString m_sLastRequest; + CClient* m_pDoing; + const struct reply* m_pReplies; + requestQueue m_vsPending; + // This field is only used for display purpose. + CString m_sLastRequest; }; void CRouteTimeout::RunJob() { - CRouteRepliesMod* pMod = (CRouteRepliesMod*)GetModule(); - pMod->Timeout(); + CRouteRepliesMod* pMod = (CRouteRepliesMod*)GetModule(); + pMod->Timeout(); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("route_replies"); + Info.SetWikiPage("route_replies"); } NETWORKMODULEDEFS(CRouteRepliesMod, diff --git a/modules/sample.cpp b/modules/sample.cpp index 315b773e..0e535912 100644 --- a/modules/sample.cpp +++ b/modules/sample.cpp @@ -23,304 +23,304 @@ using std::vector; #ifdef HAVE_PTHREAD class CSampleJob : public CModuleJob { public: - CSampleJob(CModule* pModule) - : CModuleJob(pModule, "sample", "Message the user after a delay") {} + CSampleJob(CModule* pModule) + : CModuleJob(pModule, "sample", "Message the user after a delay") {} - ~CSampleJob() { - if (wasCancelled()) { - GetModule()->PutModule("Sample job cancelled"); - } else { - GetModule()->PutModule("Sample job destroyed"); - } - } + ~CSampleJob() { + if (wasCancelled()) { + GetModule()->PutModule("Sample job cancelled"); + } else { + GetModule()->PutModule("Sample job destroyed"); + } + } - void runThread() override { - // Cannot safely use GetModule() in here, because this runs in its - // own thread and such an access would require synchronisation - // between this thread and the main thread! + void runThread() override { + // Cannot safely use GetModule() in here, because this runs in its + // own thread and such an access would require synchronisation + // between this thread and the main thread! - for (int i = 0; i < 10; i++) { - // Regularly check if we were cancelled - if (wasCancelled()) return; - sleep(1); - } - } + for (int i = 0; i < 10; i++) { + // Regularly check if we were cancelled + if (wasCancelled()) return; + sleep(1); + } + } - void runMain() override { GetModule()->PutModule("Sample job done"); } + void runMain() override { GetModule()->PutModule("Sample job done"); } }; #endif class CSampleTimer : public CTimer { public: - CSampleTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CSampleTimer() {} + CSampleTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + virtual ~CSampleTimer() {} private: protected: - void RunJob() override { GetModule()->PutModule("TEST!!!!"); } + void RunJob() override { GetModule()->PutModule("TEST!!!!"); } }; class CSampleMod : public CModule { public: - MODCONSTRUCTOR(CSampleMod) {} + MODCONSTRUCTOR(CSampleMod) {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - PutModule("I'm being loaded with the arguments: [" + sArgs + "]"); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + PutModule("I'm being loaded with the arguments: [" + sArgs + "]"); // AddTimer(new CSampleTimer(this, 300, 0, "Sample", "Sample timer for sample // things.")); // AddTimer(new CSampleTimer(this, 5, 20, "Another", "Another sample timer.")); // AddTimer(new CSampleTimer(this, 25000, 5, "Third", "A third sample timer.")); #ifdef HAVE_PTHREAD - AddJob(new CSampleJob(this)); + AddJob(new CSampleJob(this)); #endif - return true; - } + return true; + } - virtual ~CSampleMod() { PutModule("I'm being unloaded!"); } + virtual ~CSampleMod() { PutModule("I'm being unloaded!"); } - bool OnBoot() override { - // This is called when the app starts up (only modules that are loaded - // in the config will get this event) - return true; - } + bool OnBoot() override { + // This is called when the app starts up (only modules that are loaded + // in the config will get this event) + return true; + } - void OnIRCConnected() override { PutModule("You got connected BoyOh."); } + void OnIRCConnected() override { PutModule("You got connected BoyOh."); } - void OnIRCDisconnected() override { - PutModule("You got disconnected BoyOh."); - } + void OnIRCDisconnected() override { + PutModule("You got disconnected BoyOh."); + } - EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, - CString& sRealName) override { - sRealName += " - ZNC"; - return CONTINUE; - } + EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, + CString& sRealName) override { + sRealName += " - ZNC"; + return CONTINUE; + } - EModRet OnBroadcast(CString& sMessage) override { - PutModule("------ [" + sMessage + "]"); - sMessage = "======== [" + sMessage + "] ========"; - return CONTINUE; - } + EModRet OnBroadcast(CString& sMessage) override { + PutModule("------ [" + sMessage + "]"); + sMessage = "======== [" + sMessage + "] ========"; + return CONTINUE; + } - void OnChanPermission(const CNick& OpNick, const CNick& Nick, - CChan& Channel, unsigned char uMode, bool bAdded, - bool bNoChange) override { - PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + - "] set mode [" + Channel.GetName() + - ((bAdded) ? "] +" : "] -") + CString(uMode) + " " + - Nick.GetNick()); - } + void OnChanPermission(const CNick& OpNick, const CNick& Nick, + CChan& Channel, unsigned char uMode, bool bAdded, + bool bNoChange) override { + PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + + "] set mode [" + Channel.GetName() + + ((bAdded) ? "] +" : "] -") + CString(uMode) + " " + + Nick.GetNick()); + } - void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + - "] opped [" + Nick.GetNick() + "] on [" + Channel.GetName() + - "]"); - } + void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + + "] opped [" + Nick.GetNick() + "] on [" + Channel.GetName() + + "]"); + } - void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + - "] deopped [" + Nick.GetNick() + "] on [" + - Channel.GetName() + "]"); - } + void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + + "] deopped [" + Nick.GetNick() + "] on [" + + Channel.GetName() + "]"); + } - void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + - "] voiced [" + Nick.GetNick() + "] on [" + Channel.GetName() + - "]"); - } + void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + + "] voiced [" + Nick.GetNick() + "] on [" + Channel.GetName() + + "]"); + } - void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, - bool bNoChange) override { - PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + - "] devoiced [" + Nick.GetNick() + "] on [" + - Channel.GetName() + "]"); - } + void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, + bool bNoChange) override { + PutModule(((bNoChange) ? "[0] [" : "[1] [") + OpNick.GetNick() + + "] devoiced [" + Nick.GetNick() + "] on [" + + Channel.GetName() + "]"); + } - void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override { - PutModule("* " + OpNick.GetNick() + " sets mode: " + sModes + " " + - sArgs + " (" + Channel.GetName() + ")"); - } + void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override { + PutModule("* " + OpNick.GetNick() + " sets mode: " + sModes + " " + + sArgs + " (" + Channel.GetName() + ")"); + } - EModRet OnRaw(CString& sLine) override { - // PutModule("OnRaw() [" + sLine + "]"); - return CONTINUE; - } + EModRet OnRaw(CString& sLine) override { + // PutModule("OnRaw() [" + sLine + "]"); + return CONTINUE; + } - EModRet OnUserRaw(CString& sLine) override { - // PutModule("UserRaw() [" + sLine + "]"); - return CONTINUE; - } + EModRet OnUserRaw(CString& sLine) override { + // PutModule("UserRaw() [" + sLine + "]"); + return CONTINUE; + } - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override { - PutModule("[" + OpNick.GetNick() + "] kicked [" + sKickedNick + - "] from [" + Channel.GetName() + "] with the msg [" + - sMessage + "]"); - } + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override { + PutModule("[" + OpNick.GetNick() + "] kicked [" + sKickedNick + + "] from [" + Channel.GetName() + "] with the msg [" + + sMessage + "]"); + } - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override { - PutModule("* Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + - Nick.GetHost() + ") (" + sMessage + ")"); - } + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override { + PutModule("* Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + + Nick.GetHost() + ") (" + sMessage + ")"); + } - EModRet OnTimerAutoJoin(CChan& Channel) override { - PutModule("Attempting to join " + Channel.GetName()); - return CONTINUE; - } + EModRet OnTimerAutoJoin(CChan& Channel) override { + PutModule("Attempting to join " + Channel.GetName()); + return CONTINUE; + } - void OnJoin(const CNick& Nick, CChan& Channel) override { - PutModule("* Joins: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + - Nick.GetHost() + ")"); - } + void OnJoin(const CNick& Nick, CChan& Channel) override { + PutModule("* Joins: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + + Nick.GetHost() + ")"); + } - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override { - PutModule("* Parts: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + - Nick.GetHost() + ")"); - } + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override { + PutModule("* Parts: " + Nick.GetNick() + " (" + Nick.GetIdent() + "!" + + Nick.GetHost() + ")"); + } - EModRet OnInvite(const CNick& Nick, const CString& sChan) override { - if (sChan.Equals("#test")) { - PutModule(Nick.GetNick() + " invited us to " + sChan + - ", ignoring invites to " + sChan); - return HALT; - } + EModRet OnInvite(const CNick& Nick, const CString& sChan) override { + if (sChan.Equals("#test")) { + PutModule(Nick.GetNick() + " invited us to " + sChan + + ", ignoring invites to " + sChan); + return HALT; + } - PutModule(Nick.GetNick() + " invited us to " + sChan); - return CONTINUE; - } + PutModule(Nick.GetNick() + " invited us to " + sChan); + return CONTINUE; + } - void OnNick(const CNick& OldNick, const CString& sNewNick, - const vector& vChans) override { - PutModule("* " + OldNick.GetNick() + " is now known as " + sNewNick); - } + void OnNick(const CNick& OldNick, const CString& sNewNick, + const vector& vChans) override { + PutModule("* " + OldNick.GetNick() + " is now known as " + sNewNick); + } - EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { - PutModule("[" + sTarget + "] userctcpreply [" + sMessage + "]"); - sMessage = "\037" + sMessage + "\037"; + EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { + PutModule("[" + sTarget + "] userctcpreply [" + sMessage + "]"); + sMessage = "\037" + sMessage + "\037"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] ctcpreply [" + sMessage + "]"); + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] ctcpreply [" + sMessage + "]"); - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { - PutModule("[" + sTarget + "] userctcp [" + sMessage + "]"); + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { + PutModule("[" + sTarget + "] userctcp [" + sMessage + "]"); - return CONTINUE; - } + return CONTINUE; + } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] privctcp [" + sMessage + "]"); - sMessage = "\002" + sMessage + "\002"; + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] privctcp [" + sMessage + "]"); + sMessage = "\002" + sMessage + "\002"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] chanctcp [" + sMessage + "] to [" + - Channel.GetName() + "]"); - sMessage = "\00311,5 " + sMessage + " \003"; + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] chanctcp [" + sMessage + "] to [" + + Channel.GetName() + "]"); + sMessage = "\00311,5 " + sMessage + " \003"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - PutModule("[" + sTarget + "] usernotice [" + sMessage + "]"); - sMessage = "\037" + sMessage + "\037"; + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + PutModule("[" + sTarget + "] usernotice [" + sMessage + "]"); + sMessage = "\037" + sMessage + "\037"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] privnotice [" + sMessage + "]"); - sMessage = "\002" + sMessage + "\002"; + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] privnotice [" + sMessage + "]"); + sMessage = "\002" + sMessage + "\002"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] channotice [" + sMessage + - "] to [" + Channel.GetName() + "]"); - sMessage = "\00311,5 " + sMessage + " \003"; + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] channotice [" + sMessage + + "] to [" + Channel.GetName() + "]"); + sMessage = "\00311,5 " + sMessage + " \003"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { - PutModule("* " + Nick.GetNick() + " changes topic on " + - Channel.GetName() + " to '" + sTopic + "'"); + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { + PutModule("* " + Nick.GetNick() + " changes topic on " + + Channel.GetName() + " to '" + sTopic + "'"); - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserTopic(CString& sTarget, CString& sTopic) override { - PutModule("* " + GetClient()->GetNick() + " changed topic on " + - sTarget + " to '" + sTopic + "'"); + EModRet OnUserTopic(CString& sTarget, CString& sTopic) override { + PutModule("* " + GetClient()->GetNick() + " changed topic on " + + sTarget + " to '" + sTopic + "'"); - return CONTINUE; - } + return CONTINUE; + } - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - PutModule("[" + sTarget + "] usermsg [" + sMessage + "]"); - sMessage = "Sample: \0034" + sMessage + "\003"; + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + PutModule("[" + sTarget + "] usermsg [" + sMessage + "]"); + sMessage = "Sample: \0034" + sMessage + "\003"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - PutModule("[" + Nick.GetNick() + "] privmsg [" + sMessage + "]"); - sMessage = "\002" + sMessage + "\002"; + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + PutModule("[" + Nick.GetNick() + "] privmsg [" + sMessage + "]"); + sMessage = "\002" + sMessage + "\002"; - return CONTINUE; - } + return CONTINUE; + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - if (sMessage == "!ping") { - PutIRC("PRIVMSG " + Channel.GetName() + " :PONG?"); - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + if (sMessage == "!ping") { + PutIRC("PRIVMSG " + Channel.GetName() + " :PONG?"); + } - sMessage = "x " + sMessage + " x"; + sMessage = "x " + sMessage + " x"; - PutModule(sMessage); + PutModule(sMessage); - return CONTINUE; - } + return CONTINUE; + } - void OnModCommand(const CString& sCommand) override { - if (sCommand.Equals("TIMERS")) { - ListTimers(); - } - } + void OnModCommand(const CString& sCommand) override { + if (sCommand.Equals("TIMERS")) { + ListTimers(); + } + } - EModRet OnStatusCommand(CString& sCommand) override { - if (sCommand.Equals("SAMPLE")) { - PutModule("Hi, I'm your friendly sample module."); - return HALT; - } + EModRet OnStatusCommand(CString& sCommand) override { + if (sCommand.Equals("SAMPLE")) { + PutModule("Hi, I'm your friendly sample module."); + return HALT; + } - return CONTINUE; - } + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("sample"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Description of module arguments goes here."); + Info.SetWikiPage("sample"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("Description of module arguments goes here."); } MODULEDEFS(CSampleMod, "To be used as a sample for writing modules") diff --git a/modules/sasl.cpp b/modules/sasl.cpp index dfa6f2cc..a714c134 100644 --- a/modules/sasl.cpp +++ b/modules/sasl.cpp @@ -19,9 +19,9 @@ #include static const struct { - const char* szName; - const char* szDescription; - const bool bDefault; + const char* szName; + const char* szDescription; + const bool bDefault; } SupportedMechanisms[] = { {"EXTERNAL", "TLS certificate, for use with the *cert module", true}, {"PLAIN", @@ -34,272 +34,272 @@ static const struct { class Mechanisms : public VCString { public: - void SetIndex(unsigned int uiIndex) { m_uiIndex = uiIndex; } + void SetIndex(unsigned int uiIndex) { m_uiIndex = uiIndex; } - unsigned int GetIndex() const { return m_uiIndex; } + unsigned int GetIndex() const { return m_uiIndex; } - bool HasNext() const { return size() > (m_uiIndex + 1); } + bool HasNext() const { return size() > (m_uiIndex + 1); } - void IncrementIndex() { m_uiIndex++; } + void IncrementIndex() { m_uiIndex++; } - CString GetCurrent() const { return at(m_uiIndex); } + CString GetCurrent() const { return at(m_uiIndex); } - CString GetNext() const { - if (HasNext()) { - return at(m_uiIndex + 1); - } + CString GetNext() const { + if (HasNext()) { + return at(m_uiIndex + 1); + } - return ""; - } + return ""; + } private: - unsigned int m_uiIndex = 0; + unsigned int m_uiIndex = 0; }; class CSASLMod : public CModule { public: - MODCONSTRUCTOR(CSASLMod) { - AddCommand("Help", - static_cast(&CSASLMod::PrintHelp), - "search", "Generate this output"); - AddCommand("Set", static_cast(&CSASLMod::Set), - " []", - "Set username and password for the mechanisms that need " - "them. Password is optional"); - AddCommand("Mechanism", static_cast( - &CSASLMod::SetMechanismCommand), - "[mechanism[ ...]]", - "Set the mechanisms to be attempted (in order)"); - AddCommand( - "RequireAuth", - static_cast(&CSASLMod::RequireAuthCommand), - "[yes|no]", "Don't connect unless SASL authentication succeeds"); + MODCONSTRUCTOR(CSASLMod) { + AddCommand("Help", + static_cast(&CSASLMod::PrintHelp), + "search", "Generate this output"); + AddCommand("Set", static_cast(&CSASLMod::Set), + " []", + "Set username and password for the mechanisms that need " + "them. Password is optional"); + AddCommand("Mechanism", static_cast( + &CSASLMod::SetMechanismCommand), + "[mechanism[ ...]]", + "Set the mechanisms to be attempted (in order)"); + AddCommand( + "RequireAuth", + static_cast(&CSASLMod::RequireAuthCommand), + "[yes|no]", "Don't connect unless SASL authentication succeeds"); - m_bAuthenticated = false; - } + m_bAuthenticated = false; + } - void PrintHelp(const CString& sLine) { - HandleHelpCommand(sLine); + void PrintHelp(const CString& sLine) { + HandleHelpCommand(sLine); - CTable Mechanisms; - Mechanisms.AddColumn("Mechanism"); - Mechanisms.AddColumn("Description"); + CTable Mechanisms; + Mechanisms.AddColumn("Mechanism"); + Mechanisms.AddColumn("Description"); - for (const auto& it : SupportedMechanisms) { - Mechanisms.AddRow(); - Mechanisms.SetCell("Mechanism", it.szName); - Mechanisms.SetCell("Description", it.szDescription); - } + for (const auto& it : SupportedMechanisms) { + Mechanisms.AddRow(); + Mechanisms.SetCell("Mechanism", it.szName); + Mechanisms.SetCell("Description", it.szDescription); + } - PutModule("The following mechanisms are available:"); - PutModule(Mechanisms); - } + PutModule("The following mechanisms are available:"); + PutModule(Mechanisms); + } - void Set(const CString& sLine) { - SetNV("username", sLine.Token(1)); - SetNV("password", sLine.Token(2)); + void Set(const CString& sLine) { + SetNV("username", sLine.Token(1)); + SetNV("password", sLine.Token(2)); - PutModule("Username has been set to [" + GetNV("username") + "]"); - PutModule("Password has been set to [" + GetNV("password") + "]"); - } + PutModule("Username has been set to [" + GetNV("username") + "]"); + PutModule("Password has been set to [" + GetNV("password") + "]"); + } - void SetMechanismCommand(const CString& sLine) { - CString sMechanisms = sLine.Token(1, true).AsUpper(); + void SetMechanismCommand(const CString& sLine) { + CString sMechanisms = sLine.Token(1, true).AsUpper(); - if (!sMechanisms.empty()) { - VCString vsMechanisms; - sMechanisms.Split(" ", vsMechanisms); + if (!sMechanisms.empty()) { + VCString vsMechanisms; + sMechanisms.Split(" ", vsMechanisms); - for (const CString& sMechanism : vsMechanisms) { - if (!SupportsMechanism(sMechanism)) { - PutModule("Unsupported mechanism: " + sMechanism); - return; - } - } + for (const CString& sMechanism : vsMechanisms) { + if (!SupportsMechanism(sMechanism)) { + PutModule("Unsupported mechanism: " + sMechanism); + return; + } + } - SetNV(NV_MECHANISMS, sMechanisms); - } + SetNV(NV_MECHANISMS, sMechanisms); + } - PutModule("Current mechanisms set: " + GetMechanismsString()); - } + PutModule("Current mechanisms set: " + GetMechanismsString()); + } - void RequireAuthCommand(const CString& sLine) { - if (!sLine.Token(1).empty()) { - SetNV(NV_REQUIRE_AUTH, sLine.Token(1)); - } + void RequireAuthCommand(const CString& sLine) { + if (!sLine.Token(1).empty()) { + SetNV(NV_REQUIRE_AUTH, sLine.Token(1)); + } - if (GetNV(NV_REQUIRE_AUTH).ToBool()) { - PutModule("We require SASL negotiation to connect"); - } else { - PutModule("We will connect even if SASL fails"); - } - } + if (GetNV(NV_REQUIRE_AUTH).ToBool()) { + PutModule("We require SASL negotiation to connect"); + } else { + PutModule("We will connect even if SASL fails"); + } + } - bool SupportsMechanism(const CString& sMechanism) const { - for (const auto& it : SupportedMechanisms) { - if (sMechanism.Equals(it.szName)) { - return true; - } - } + bool SupportsMechanism(const CString& sMechanism) const { + for (const auto& it : SupportedMechanisms) { + if (sMechanism.Equals(it.szName)) { + return true; + } + } - return false; - } + return false; + } - CString GetMechanismsString() const { - if (GetNV(NV_MECHANISMS).empty()) { - CString sDefaults = ""; + CString GetMechanismsString() const { + if (GetNV(NV_MECHANISMS).empty()) { + CString sDefaults = ""; - for (const auto& it : SupportedMechanisms) { - if (it.bDefault) { - if (!sDefaults.empty()) { - sDefaults += " "; - } + for (const auto& it : SupportedMechanisms) { + if (it.bDefault) { + if (!sDefaults.empty()) { + sDefaults += " "; + } - sDefaults += it.szName; - } - } + sDefaults += it.szName; + } + } - return sDefaults; - } + return sDefaults; + } - return GetNV(NV_MECHANISMS); - } + return GetNV(NV_MECHANISMS); + } - bool CheckRequireAuth() { - if (!m_bAuthenticated && GetNV(NV_REQUIRE_AUTH).ToBool()) { - GetNetwork()->SetIRCConnectEnabled(false); - PutModule("Disabling network, we require authentication."); - PutModule("Use 'RequireAuth no' to disable."); - return true; - } + bool CheckRequireAuth() { + if (!m_bAuthenticated && GetNV(NV_REQUIRE_AUTH).ToBool()) { + GetNetwork()->SetIRCConnectEnabled(false); + PutModule("Disabling network, we require authentication."); + PutModule("Use 'RequireAuth no' to disable."); + return true; + } - return false; - } + return false; + } - void Authenticate(const CString& sLine) { - if (m_Mechanisms.GetCurrent().Equals("PLAIN") && sLine.Equals("+")) { - CString sAuthLine = GetNV("username") + '\0' + GetNV("username") + - '\0' + GetNV("password"); - sAuthLine.Base64Encode(); - PutIRC("AUTHENTICATE " + sAuthLine); - } else { - /* Send blank authenticate for other mechanisms (like EXTERNAL). */ - PutIRC("AUTHENTICATE +"); - } - } + void Authenticate(const CString& sLine) { + if (m_Mechanisms.GetCurrent().Equals("PLAIN") && sLine.Equals("+")) { + CString sAuthLine = GetNV("username") + '\0' + GetNV("username") + + '\0' + GetNV("password"); + sAuthLine.Base64Encode(); + PutIRC("AUTHENTICATE " + sAuthLine); + } else { + /* Send blank authenticate for other mechanisms (like EXTERNAL). */ + PutIRC("AUTHENTICATE +"); + } + } - bool OnServerCapAvailable(const CString& sCap) override { - return sCap.Equals("sasl"); - } + bool OnServerCapAvailable(const CString& sCap) override { + return sCap.Equals("sasl"); + } - void OnServerCapResult(const CString& sCap, bool bSuccess) override { - if (sCap.Equals("sasl")) { - if (bSuccess) { - GetMechanismsString().Split(" ", m_Mechanisms); + void OnServerCapResult(const CString& sCap, bool bSuccess) override { + if (sCap.Equals("sasl")) { + if (bSuccess) { + GetMechanismsString().Split(" ", m_Mechanisms); - if (m_Mechanisms.empty()) { - CheckRequireAuth(); - return; - } + if (m_Mechanisms.empty()) { + CheckRequireAuth(); + return; + } - GetNetwork()->GetIRCSock()->PauseCap(); + GetNetwork()->GetIRCSock()->PauseCap(); - m_Mechanisms.SetIndex(0); - PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent()); - } else { - CheckRequireAuth(); - } - } - } + m_Mechanisms.SetIndex(0); + PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent()); + } else { + CheckRequireAuth(); + } + } + } - EModRet OnRaw(CString& sLine) override { - if (sLine.Token(0).Equals("AUTHENTICATE")) { - Authenticate(sLine.Token(1, true)); - } else if (sLine.Token(1).Equals("903")) { - /* SASL success! */ - GetNetwork()->GetIRCSock()->ResumeCap(); - m_bAuthenticated = true; - DEBUG("sasl: Authenticated with mechanism [" - << m_Mechanisms.GetCurrent() << "]"); - } else if (sLine.Token(1).Equals("904") || - sLine.Token(1).Equals("905")) { - DEBUG("sasl: Mechanism [" << m_Mechanisms.GetCurrent() - << "] failed."); - PutModule(m_Mechanisms.GetCurrent() + " mechanism failed."); + EModRet OnRaw(CString& sLine) override { + if (sLine.Token(0).Equals("AUTHENTICATE")) { + Authenticate(sLine.Token(1, true)); + } else if (sLine.Token(1).Equals("903")) { + /* SASL success! */ + GetNetwork()->GetIRCSock()->ResumeCap(); + m_bAuthenticated = true; + DEBUG("sasl: Authenticated with mechanism [" + << m_Mechanisms.GetCurrent() << "]"); + } else if (sLine.Token(1).Equals("904") || + sLine.Token(1).Equals("905")) { + DEBUG("sasl: Mechanism [" << m_Mechanisms.GetCurrent() + << "] failed."); + PutModule(m_Mechanisms.GetCurrent() + " mechanism failed."); - if (m_Mechanisms.HasNext()) { - m_Mechanisms.IncrementIndex(); - PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent()); - } else { - CheckRequireAuth(); - GetNetwork()->GetIRCSock()->ResumeCap(); - } - } else if (sLine.Token(1).Equals("906")) { - /* CAP wasn't paused? */ - DEBUG("sasl: Reached 906."); - CheckRequireAuth(); - } else if (sLine.Token(1).Equals("907")) { - m_bAuthenticated = true; - GetNetwork()->GetIRCSock()->ResumeCap(); - DEBUG("sasl: Received 907 -- We are already registered"); - } else { - return CONTINUE; - } + if (m_Mechanisms.HasNext()) { + m_Mechanisms.IncrementIndex(); + PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent()); + } else { + CheckRequireAuth(); + GetNetwork()->GetIRCSock()->ResumeCap(); + } + } else if (sLine.Token(1).Equals("906")) { + /* CAP wasn't paused? */ + DEBUG("sasl: Reached 906."); + CheckRequireAuth(); + } else if (sLine.Token(1).Equals("907")) { + m_bAuthenticated = true; + GetNetwork()->GetIRCSock()->ResumeCap(); + DEBUG("sasl: Received 907 -- We are already registered"); + } else { + return CONTINUE; + } - return HALT; - } + return HALT; + } - void OnIRCConnected() override { - /* Just incase something slipped through, perhaps the server doesn't - * respond to our CAP negotiation. */ + void OnIRCConnected() override { + /* Just incase something slipped through, perhaps the server doesn't + * respond to our CAP negotiation. */ - CheckRequireAuth(); - } + CheckRequireAuth(); + } - void OnIRCDisconnected() override { m_bAuthenticated = false; } + void OnIRCDisconnected() override { m_bAuthenticated = false; } - CString GetWebMenuTitle() override { return "SASL"; } + CString GetWebMenuTitle() override { return "SASL"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName != "index") { - // only accept requests to index - return false; - } + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName != "index") { + // only accept requests to index + return false; + } - if (WebSock.IsPost()) { - SetNV("username", WebSock.GetParam("username")); - CString sPassword = WebSock.GetParam("password"); - if (!sPassword.empty()) { - SetNV("password", sPassword); - } - SetNV(NV_REQUIRE_AUTH, WebSock.GetParam("require_auth")); - SetNV(NV_MECHANISMS, WebSock.GetParam("mechanisms")); - } + if (WebSock.IsPost()) { + SetNV("username", WebSock.GetParam("username")); + CString sPassword = WebSock.GetParam("password"); + if (!sPassword.empty()) { + SetNV("password", sPassword); + } + SetNV(NV_REQUIRE_AUTH, WebSock.GetParam("require_auth")); + SetNV(NV_MECHANISMS, WebSock.GetParam("mechanisms")); + } - Tmpl["Username"] = GetNV("username"); - Tmpl["Password"] = GetNV("password"); - Tmpl["RequireAuth"] = GetNV(NV_REQUIRE_AUTH); - Tmpl["Mechanisms"] = GetMechanismsString(); + Tmpl["Username"] = GetNV("username"); + Tmpl["Password"] = GetNV("password"); + Tmpl["RequireAuth"] = GetNV(NV_REQUIRE_AUTH); + Tmpl["Mechanisms"] = GetMechanismsString(); - for (const auto& it : SupportedMechanisms) { - CTemplate& Row = Tmpl.AddRow("MechanismLoop"); - CString sName(it.szName); - Row["Name"] = sName; - Row["Description"] = CString(it.szDescription); - } + for (const auto& it : SupportedMechanisms) { + CTemplate& Row = Tmpl.AddRow("MechanismLoop"); + CString sName(it.szName); + Row["Name"] = sName; + Row["Description"] = CString(it.szDescription); + } - return true; - } + return true; + } private: - Mechanisms m_Mechanisms; - bool m_bAuthenticated; + Mechanisms m_Mechanisms; + bool m_bAuthenticated; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("sasl"); + Info.SetWikiPage("sasl"); } NETWORKMODULEDEFS(CSASLMod, diff --git a/modules/savebuff.cpp b/modules/savebuff.cpp index 386c4366..a4369948 100644 --- a/modules/savebuff.cpp +++ b/modules/savebuff.cpp @@ -46,320 +46,320 @@ class CSaveBuff; class CSaveBuffJob : public CTimer { public: - CSaveBuffJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, - const CString& sLabel, const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + CSaveBuffJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, + const CString& sLabel, const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CSaveBuffJob() {} + virtual ~CSaveBuffJob() {} protected: - void RunJob() override; + void RunJob() override; }; class CSaveBuff : public CModule { public: - MODCONSTRUCTOR(CSaveBuff) { - m_bBootError = false; + MODCONSTRUCTOR(CSaveBuff) { + m_bBootError = false; - AddHelpCommand(); - AddCommand("SetPass", static_cast( - &CSaveBuff::OnSetPassCommand), - "", "Sets the password"); - AddCommand("Replay", static_cast( - &CSaveBuff::OnReplayCommand), - "", "Replays the buffer"); - AddCommand("Save", static_cast( - &CSaveBuff::OnSaveCommand), - "", "Saves all buffers"); - } - virtual ~CSaveBuff() { - if (!m_bBootError) { - SaveBuffersToDisk(); - } - } + AddHelpCommand(); + AddCommand("SetPass", static_cast( + &CSaveBuff::OnSetPassCommand), + "", "Sets the password"); + AddCommand("Replay", static_cast( + &CSaveBuff::OnReplayCommand), + "", "Replays the buffer"); + AddCommand("Save", static_cast( + &CSaveBuff::OnSaveCommand), + "", "Saves all buffers"); + } + virtual ~CSaveBuff() { + if (!m_bBootError) { + SaveBuffersToDisk(); + } + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { - if (sArgs == CRYPT_ASK_PASS) { - char* pPass = getpass("Enter pass for savebuff: "); - if (pPass) - m_sPassword = CBlowfish::MD5(pPass); - else { - m_bBootError = true; - sMessage = "Nothing retrieved from console. aborting"; - } - } else if (sArgs.empty()) - m_sPassword = CBlowfish::MD5(CRYPT_LAME_PASS); - else - m_sPassword = CBlowfish::MD5(sArgs); + bool OnLoad(const CString& sArgs, CString& sMessage) override { + if (sArgs == CRYPT_ASK_PASS) { + char* pPass = getpass("Enter pass for savebuff: "); + if (pPass) + m_sPassword = CBlowfish::MD5(pPass); + else { + m_bBootError = true; + sMessage = "Nothing retrieved from console. aborting"; + } + } else if (sArgs.empty()) + m_sPassword = CBlowfish::MD5(CRYPT_LAME_PASS); + else + m_sPassword = CBlowfish::MD5(sArgs); - AddTimer(new CSaveBuffJob( - this, 60, 0, "SaveBuff", - "Saves the current buffer to disk every 1 minute")); + AddTimer(new CSaveBuffJob( + this, 60, 0, "SaveBuff", + "Saves the current buffer to disk every 1 minute")); - return (!m_bBootError); - } + return (!m_bBootError); + } - bool OnBoot() override { - CDir saveDir(GetSavePath()); - for (CFile* pFile : saveDir) { - CString sName; - CString sBuffer; + bool OnBoot() override { + CDir saveDir(GetSavePath()); + for (CFile* pFile : saveDir) { + CString sName; + CString sBuffer; - EBufferType eType = - DecryptBuffer(pFile->GetLongName(), sBuffer, sName); - switch (eType) { - case InvalidBuffer: - m_sPassword = ""; - CUtils::PrintError("[" + GetModName() + - ".so] Failed to Decrypt [" + - pFile->GetLongName() + "]"); - if (!sName.empty()) { - PutUser(":***!znc@znc.in PRIVMSG " + sName + - " :Failed to decrypt this buffer, did you " - "change the encryption pass?"); - } - break; - case ChanBuffer: - if (CChan* pChan = GetNetwork()->FindChan(sName)) { - BootStrap(pChan, sBuffer); - } - break; - case QueryBuffer: - if (CQuery* pQuery = GetNetwork()->AddQuery(sName)) { - BootStrap(pQuery, sBuffer); - } - break; - default: - break; - } - } - return true; - } + EBufferType eType = + DecryptBuffer(pFile->GetLongName(), sBuffer, sName); + switch (eType) { + case InvalidBuffer: + m_sPassword = ""; + CUtils::PrintError("[" + GetModName() + + ".so] Failed to Decrypt [" + + pFile->GetLongName() + "]"); + if (!sName.empty()) { + PutUser(":***!znc@znc.in PRIVMSG " + sName + + " :Failed to decrypt this buffer, did you " + "change the encryption pass?"); + } + break; + case ChanBuffer: + if (CChan* pChan = GetNetwork()->FindChan(sName)) { + BootStrap(pChan, sBuffer); + } + break; + case QueryBuffer: + if (CQuery* pQuery = GetNetwork()->AddQuery(sName)) { + BootStrap(pQuery, sBuffer); + } + break; + default: + break; + } + } + return true; + } - template - void BootStrap(T* pTarget, const CString& sContent) { - if (!pTarget->GetBuffer().IsEmpty()) - return; // in this case the module was probably reloaded + template + void BootStrap(T* pTarget, const CString& sContent) { + if (!pTarget->GetBuffer().IsEmpty()) + return; // in this case the module was probably reloaded - VCString vsLines; - VCString::iterator it; + VCString vsLines; + VCString::iterator it; - sContent.Split("\n", vsLines); + sContent.Split("\n", vsLines); - for (it = vsLines.begin(); it != vsLines.end(); ++it) { - CString sLine(*it); - sLine.Trim(); - if (sLine[0] == '@' && it + 1 != vsLines.end()) { - CString sTimestamp = sLine.Token(0); - sTimestamp.TrimLeft("@"); - timeval ts; - ts.tv_sec = sTimestamp.Token(0, false, ",").ToLongLong(); - ts.tv_usec = sTimestamp.Token(1, false, ",").ToLong(); + for (it = vsLines.begin(); it != vsLines.end(); ++it) { + CString sLine(*it); + sLine.Trim(); + if (sLine[0] == '@' && it + 1 != vsLines.end()) { + CString sTimestamp = sLine.Token(0); + sTimestamp.TrimLeft("@"); + timeval ts; + ts.tv_sec = sTimestamp.Token(0, false, ",").ToLongLong(); + ts.tv_usec = sTimestamp.Token(1, false, ",").ToLong(); - CString sFormat = sLine.Token(1, true); + CString sFormat = sLine.Token(1, true); - CString sText(*++it); - sText.Trim(); + CString sText(*++it); + sText.Trim(); - pTarget->AddBuffer(sFormat, sText, &ts); - } else { - // Old format, escape the line and use as is. - pTarget->AddBuffer(_NAMEDFMT(sLine)); - } - } - } + pTarget->AddBuffer(sFormat, sText, &ts); + } else { + // Old format, escape the line and use as is. + pTarget->AddBuffer(_NAMEDFMT(sLine)); + } + } + } - void SaveBufferToDisk(const CBuffer& Buffer, const CString& sPath, - const CString& sHeader) { - CFile File(sPath); - CString sContent = sHeader + "\n"; + void SaveBufferToDisk(const CBuffer& Buffer, const CString& sPath, + const CString& sHeader) { + CFile File(sPath); + CString sContent = sHeader + "\n"; - size_t uSize = Buffer.Size(); - for (unsigned int uIdx = 0; uIdx < uSize; uIdx++) { - const CBufLine& Line = Buffer.GetBufLine(uIdx); - timeval ts = Line.GetTime(); - sContent += "@" + CString(ts.tv_sec) + "," + CString(ts.tv_usec) + - " " + Line.GetFormat() + "\n" + Line.GetText() + "\n"; - } + size_t uSize = Buffer.Size(); + for (unsigned int uIdx = 0; uIdx < uSize; uIdx++) { + const CBufLine& Line = Buffer.GetBufLine(uIdx); + timeval ts = Line.GetTime(); + sContent += "@" + CString(ts.tv_sec) + "," + CString(ts.tv_usec) + + " " + Line.GetFormat() + "\n" + Line.GetText() + "\n"; + } - CBlowfish c(m_sPassword, BF_ENCRYPT); - sContent = c.Crypt(sContent); + CBlowfish c(m_sPassword, BF_ENCRYPT); + sContent = c.Crypt(sContent); - if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { - File.Chmod(0600); - File.Write(sContent); - } - File.Close(); - } + if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { + File.Chmod(0600); + File.Write(sContent); + } + File.Close(); + } - void SaveBuffersToDisk() { - if (!m_sPassword.empty()) { - set ssPaths; + void SaveBuffersToDisk() { + if (!m_sPassword.empty()) { + set ssPaths; - const vector& vChans = GetNetwork()->GetChans(); - for (CChan* pChan : vChans) { - CString sPath = GetPath(pChan->GetName()); - SaveBufferToDisk(pChan->GetBuffer(), sPath, - CHAN_VERIFICATION_TOKEN + pChan->GetName()); - ssPaths.insert(sPath); - } + const vector& vChans = GetNetwork()->GetChans(); + for (CChan* pChan : vChans) { + CString sPath = GetPath(pChan->GetName()); + SaveBufferToDisk(pChan->GetBuffer(), sPath, + CHAN_VERIFICATION_TOKEN + pChan->GetName()); + ssPaths.insert(sPath); + } - const vector& vQueries = GetNetwork()->GetQueries(); - for (CQuery* pQuery : vQueries) { - CString sPath = GetPath(pQuery->GetName()); - SaveBufferToDisk(pQuery->GetBuffer(), sPath, - QUERY_VERIFICATION_TOKEN + pQuery->GetName()); - ssPaths.insert(sPath); - } + const vector& vQueries = GetNetwork()->GetQueries(); + for (CQuery* pQuery : vQueries) { + CString sPath = GetPath(pQuery->GetName()); + SaveBufferToDisk(pQuery->GetBuffer(), sPath, + QUERY_VERIFICATION_TOKEN + pQuery->GetName()); + ssPaths.insert(sPath); + } - // cleanup leftovers ie. cleared buffers - CDir saveDir(GetSavePath()); - for (CFile* pFile : saveDir) { - if (ssPaths.count(pFile->GetLongName()) == 0) { - pFile->Delete(); - } - } - } else { - PutModule( - "Password is unset usually meaning the decryption failed. You " - "can setpass to the appropriate pass and things should start " - "working, or setpass to a new pass and save to reinstantiate"); - } - } + // cleanup leftovers ie. cleared buffers + CDir saveDir(GetSavePath()); + for (CFile* pFile : saveDir) { + if (ssPaths.count(pFile->GetLongName()) == 0) { + pFile->Delete(); + } + } + } else { + PutModule( + "Password is unset usually meaning the decryption failed. You " + "can setpass to the appropriate pass and things should start " + "working, or setpass to a new pass and save to reinstantiate"); + } + } - void OnSetPassCommand(const CString& sCmdLine) { - CString sArgs = sCmdLine.Token(1, true); + void OnSetPassCommand(const CString& sCmdLine) { + CString sArgs = sCmdLine.Token(1, true); - if (sArgs.empty()) sArgs = CRYPT_LAME_PASS; + if (sArgs.empty()) sArgs = CRYPT_LAME_PASS; - PutModule("Password set to [" + sArgs + "]"); - m_sPassword = CBlowfish::MD5(sArgs); - } + PutModule("Password set to [" + sArgs + "]"); + m_sPassword = CBlowfish::MD5(sArgs); + } - void OnModCommand(const CString& sCmdLine) override { - CString sCommand = sCmdLine.Token(0); - CString sArgs = sCmdLine.Token(1, true); + void OnModCommand(const CString& sCmdLine) override { + CString sCommand = sCmdLine.Token(0); + CString sArgs = sCmdLine.Token(1, true); - if (sCommand.Equals("dumpbuff")) { - // for testing purposes - hidden from help - CString sFile; - CString sName; - if (DecryptBuffer(GetPath(sArgs), sFile, sName)) { - VCString vsLines; - sFile.Split("\n", vsLines); + if (sCommand.Equals("dumpbuff")) { + // for testing purposes - hidden from help + CString sFile; + CString sName; + if (DecryptBuffer(GetPath(sArgs), sFile, sName)) { + VCString vsLines; + sFile.Split("\n", vsLines); - for (const CString& sLine : vsLines) { - PutModule("[" + sLine.Trim_n() + "]"); - } - } - PutModule("//!-- EOF " + sArgs); - } else { - HandleCommand(sCmdLine); - } - } + for (const CString& sLine : vsLines) { + PutModule("[" + sLine.Trim_n() + "]"); + } + } + PutModule("//!-- EOF " + sArgs); + } else { + HandleCommand(sCmdLine); + } + } - void OnReplayCommand(const CString& sCmdLine) { - CString sArgs = sCmdLine.Token(1, true); + void OnReplayCommand(const CString& sCmdLine) { + CString sArgs = sCmdLine.Token(1, true); - Replay(sArgs); - PutModule("Replayed " + sArgs); - } + Replay(sArgs); + PutModule("Replayed " + sArgs); + } - void OnSaveCommand(const CString& sCmdLine) { - SaveBuffersToDisk(); - PutModule("Done."); - } + void OnSaveCommand(const CString& sCmdLine) { + SaveBuffersToDisk(); + PutModule("Done."); + } - void Replay(const CString& sBuffer) { - CString sFile; - CString sName; - PutUser(":***!znc@znc.in PRIVMSG " + sBuffer + " :Buffer Playback..."); - if (DecryptBuffer(GetPath(sBuffer), sFile, sName)) { - VCString vsLines; - sFile.Split("\n", vsLines); + void Replay(const CString& sBuffer) { + CString sFile; + CString sName; + PutUser(":***!znc@znc.in PRIVMSG " + sBuffer + " :Buffer Playback..."); + if (DecryptBuffer(GetPath(sBuffer), sFile, sName)) { + VCString vsLines; + sFile.Split("\n", vsLines); - for (const CString& sLine : vsLines) { - PutUser(sLine.Trim_n()); - } - } - PutUser(":***!znc@znc.in PRIVMSG " + sBuffer + " :Playback Complete."); - } + for (const CString& sLine : vsLines) { + PutUser(sLine.Trim_n()); + } + } + PutUser(":***!znc@znc.in PRIVMSG " + sBuffer + " :Playback Complete."); + } - CString GetPath(const CString& sTarget) const { - CString sBuffer = GetUser()->GetUserName() + sTarget.AsLower(); - CString sRet = GetSavePath(); - sRet += "/" + CBlowfish::MD5(sBuffer, true); - return (sRet); - } + CString GetPath(const CString& sTarget) const { + CString sBuffer = GetUser()->GetUserName() + sTarget.AsLower(); + CString sRet = GetSavePath(); + sRet += "/" + CBlowfish::MD5(sBuffer, true); + return (sRet); + } - CString FindLegacyBufferName(const CString& sPath) const { - const vector& vChans = GetNetwork()->GetChans(); - for (CChan* pChan : vChans) { - const CString& sName = pChan->GetName(); - if (GetPath(sName).Equals(sPath)) { - return sName; - } - } - return CString(); - } + CString FindLegacyBufferName(const CString& sPath) const { + const vector& vChans = GetNetwork()->GetChans(); + for (CChan* pChan : vChans) { + const CString& sName = pChan->GetName(); + if (GetPath(sName).Equals(sPath)) { + return sName; + } + } + return CString(); + } private: - bool m_bBootError; - CString m_sPassword; + bool m_bBootError; + CString m_sPassword; - enum EBufferType { - InvalidBuffer = 0, - EmptyBuffer, - ChanBuffer, - QueryBuffer - }; + enum EBufferType { + InvalidBuffer = 0, + EmptyBuffer, + ChanBuffer, + QueryBuffer + }; - EBufferType DecryptBuffer(const CString& sPath, CString& sBuffer, - CString& sName) { - CString sContent; - sBuffer = ""; + EBufferType DecryptBuffer(const CString& sPath, CString& sBuffer, + CString& sName) { + CString sContent; + sBuffer = ""; - CFile File(sPath); + CFile File(sPath); - if (sPath.empty() || !File.Open() || !File.ReadFile(sContent)) - return EmptyBuffer; + if (sPath.empty() || !File.Open() || !File.ReadFile(sContent)) + return EmptyBuffer; - File.Close(); + File.Close(); - if (!sContent.empty()) { - CBlowfish c(m_sPassword, BF_DECRYPT); - sBuffer = c.Crypt(sContent); + if (!sContent.empty()) { + CBlowfish c(m_sPassword, BF_DECRYPT); + sBuffer = c.Crypt(sContent); - if (sBuffer.TrimPrefix(LEGACY_VERIFICATION_TOKEN)) { - sName = FindLegacyBufferName(sPath); - return ChanBuffer; - } else if (sBuffer.TrimPrefix(CHAN_VERIFICATION_TOKEN)) { - sName = sBuffer.FirstLine(); - if (sBuffer.TrimLeft(sName + "\n")) return ChanBuffer; - } else if (sBuffer.TrimPrefix(QUERY_VERIFICATION_TOKEN)) { - sName = sBuffer.FirstLine(); - if (sBuffer.TrimLeft(sName + "\n")) return QueryBuffer; - } + if (sBuffer.TrimPrefix(LEGACY_VERIFICATION_TOKEN)) { + sName = FindLegacyBufferName(sPath); + return ChanBuffer; + } else if (sBuffer.TrimPrefix(CHAN_VERIFICATION_TOKEN)) { + sName = sBuffer.FirstLine(); + if (sBuffer.TrimLeft(sName + "\n")) return ChanBuffer; + } else if (sBuffer.TrimPrefix(QUERY_VERIFICATION_TOKEN)) { + sName = sBuffer.FirstLine(); + if (sBuffer.TrimLeft(sName + "\n")) return QueryBuffer; + } - PutModule("Unable to decode Encrypted file [" + sPath + "]"); - return InvalidBuffer; - } - return EmptyBuffer; - } + PutModule("Unable to decode Encrypted file [" + sPath + "]"); + return InvalidBuffer; + } + return EmptyBuffer; + } }; void CSaveBuffJob::RunJob() { - CSaveBuff* p = (CSaveBuff*)GetModule(); - p->SaveBuffersToDisk(); + CSaveBuff* p = (CSaveBuff*)GetModule(); + p->SaveBuffersToDisk(); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("savebuff"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "This user module takes up to one arguments. Either --ask-pass or the " - "password itself (which may contain spaces) or nothing"); + Info.SetWikiPage("savebuff"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "This user module takes up to one arguments. Either --ask-pass or the " + "password itself (which may contain spaces) or nothing"); } NETWORKMODULEDEFS(CSaveBuff, diff --git a/modules/schat.cpp b/modules/schat.cpp index 709f97e6..faaf13ee 100644 --- a/modules/schat.cpp +++ b/modules/schat.cpp @@ -35,431 +35,431 @@ class CSChat; class CRemMarkerJob : public CTimer { public: - CRemMarkerJob(CModule* pModule, unsigned int uInterval, - unsigned int uCycles, const CString& sLabel, - const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + CRemMarkerJob(CModule* pModule, unsigned int uInterval, + unsigned int uCycles, const CString& sLabel, + const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CRemMarkerJob() {} - void SetNick(const CString& sNick) { m_sNick = sNick; } + virtual ~CRemMarkerJob() {} + void SetNick(const CString& sNick) { m_sNick = sNick; } protected: - void RunJob() override; - CString m_sNick; + void RunJob() override; + CString m_sNick; }; class CSChatSock : public CSocket { public: - CSChatSock(CSChat* pMod, const CString& sChatNick); - CSChatSock(CSChat* pMod, const CString& sChatNick, const CString& sHost, - u_short iPort, int iTimeout = 60); - ~CSChatSock() {} + CSChatSock(CSChat* pMod, const CString& sChatNick); + CSChatSock(CSChat* pMod, const CString& sChatNick, const CString& sHost, + u_short iPort, int iTimeout = 60); + ~CSChatSock() {} - Csock* GetSockObj(const CS_STRING& sHostname, u_short iPort) override { - CSChatSock* p = - new CSChatSock(m_pModule, m_sChatNick, sHostname, iPort); - return (p); - } + Csock* GetSockObj(const CS_STRING& sHostname, u_short iPort) override { + CSChatSock* p = + new CSChatSock(m_pModule, m_sChatNick, sHostname, iPort); + return (p); + } - bool ConnectionFrom(const CS_STRING& sHost, u_short iPort) override { - Close(); // close the listener after the first connection - return (true); - } + bool ConnectionFrom(const CS_STRING& sHost, u_short iPort) override { + Close(); // close the listener after the first connection + return (true); + } - void Connected() override; - void Timeout() override; + void Connected() override; + void Timeout() override; - const CString& GetChatNick() const { return (m_sChatNick); } + const CString& GetChatNick() const { return (m_sChatNick); } - void PutQuery(const CString& sText); + void PutQuery(const CString& sText); - void ReadLine(const CS_STRING& sLine) override; - void Disconnected() override; + void ReadLine(const CS_STRING& sLine) override; + void Disconnected() override; - void AddLine(const CString& sLine) { - m_vBuffer.insert(m_vBuffer.begin(), sLine); - if (m_vBuffer.size() > 200) m_vBuffer.pop_back(); - } + void AddLine(const CString& sLine) { + m_vBuffer.insert(m_vBuffer.begin(), sLine); + if (m_vBuffer.size() > 200) m_vBuffer.pop_back(); + } - void DumpBuffer() { - if (m_vBuffer.empty()) { - // Always show a message to the user, so he knows - // this schat still exists. - ReadLine("*** Reattached."); - } else { - // Buffer playback - vector::reverse_iterator it = m_vBuffer.rbegin(); - for (; it != m_vBuffer.rend(); ++it) ReadLine(*it); + void DumpBuffer() { + if (m_vBuffer.empty()) { + // Always show a message to the user, so he knows + // this schat still exists. + ReadLine("*** Reattached."); + } else { + // Buffer playback + vector::reverse_iterator it = m_vBuffer.rbegin(); + for (; it != m_vBuffer.rend(); ++it) ReadLine(*it); - m_vBuffer.clear(); - } - } + m_vBuffer.clear(); + } + } private: - CSChat* m_pModule; - CString m_sChatNick; - VCString m_vBuffer; + CSChat* m_pModule; + CString m_sChatNick; + VCString m_vBuffer; }; class CSChat : public CModule { public: - MODCONSTRUCTOR(CSChat) {} - virtual ~CSChat() {} + MODCONSTRUCTOR(CSChat) {} + virtual ~CSChat() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - m_sPemFile = sArgs; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + m_sPemFile = sArgs; - if (m_sPemFile.empty()) { - m_sPemFile = CZNC::Get().GetPemLocation(); - } + if (m_sPemFile.empty()) { + m_sPemFile = CZNC::Get().GetPemLocation(); + } - if (!CFile::Exists(m_sPemFile)) { - sMessage = "Unable to load pem file [" + m_sPemFile + "]"; - return false; - } + if (!CFile::Exists(m_sPemFile)) { + sMessage = "Unable to load pem file [" + m_sPemFile + "]"; + return false; + } - return true; - } + return true; + } - void OnClientLogin() override { - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CSChatSock* p = (CSChatSock*)*it; + void OnClientLogin() override { + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CSChatSock* p = (CSChatSock*)*it; - if (p->GetType() == CSChatSock::LISTENER) continue; + if (p->GetType() == CSChatSock::LISTENER) continue; - p->DumpBuffer(); - } - } + p->DumpBuffer(); + } + } - EModRet OnUserRaw(CString& sLine) override { - if (sLine.StartsWith("schat ")) { - OnModCommand("chat " + sLine.substr(6)); - return (HALT); + EModRet OnUserRaw(CString& sLine) override { + if (sLine.StartsWith("schat ")) { + OnModCommand("chat " + sLine.substr(6)); + return (HALT); - } else if (sLine.Equals("schat")) { - PutModule("SChat User Area ..."); - OnModCommand("help"); - return (HALT); - } + } else if (sLine.Equals("schat")) { + PutModule("SChat User Area ..."); + OnModCommand("help"); + return (HALT); + } - return (CONTINUE); - } + return (CONTINUE); + } - void OnModCommand(const CString& sCommand) override { - CString sCom = sCommand.Token(0); - CString sArgs = sCommand.Token(1, true); + void OnModCommand(const CString& sCommand) override { + CString sCom = sCommand.Token(0); + CString sArgs = sCommand.Token(1, true); - if (sCom.Equals("chat") && !sArgs.empty()) { - CString sNick = "(s)" + sArgs; - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CSChatSock* pSock = (CSChatSock*)*it; + if (sCom.Equals("chat") && !sArgs.empty()) { + CString sNick = "(s)" + sArgs; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CSChatSock* pSock = (CSChatSock*)*it; - if (pSock->GetChatNick().Equals(sNick)) { - PutModule("Already Connected to [" + sArgs + "]"); - return; - } - } + if (pSock->GetChatNick().Equals(sNick)) { + PutModule("Already Connected to [" + sArgs + "]"); + return; + } + } - CSChatSock* pSock = new CSChatSock(this, sNick); - pSock->SetCipher("HIGH"); - pSock->SetPemLocation(m_sPemFile); + CSChatSock* pSock = new CSChatSock(this, sNick); + pSock->SetCipher("HIGH"); + pSock->SetPemLocation(m_sPemFile); - u_short iPort = GetManager()->ListenRand( - pSock->GetSockName() + "::LISTENER", GetUser()->GetLocalDCCIP(), - true, SOMAXCONN, pSock, 60); + u_short iPort = GetManager()->ListenRand( + pSock->GetSockName() + "::LISTENER", GetUser()->GetLocalDCCIP(), + true, SOMAXCONN, pSock, 60); - if (iPort == 0) { - PutModule("Failed to start chat!"); - return; - } + if (iPort == 0) { + PutModule("Failed to start chat!"); + return; + } - stringstream s; - s << "PRIVMSG " << sArgs << " :\001"; - s << "DCC SCHAT chat "; - s << CUtils::GetLongIP(GetUser()->GetLocalDCCIP()); - s << " " << iPort << "\001"; + stringstream s; + s << "PRIVMSG " << sArgs << " :\001"; + s << "DCC SCHAT chat "; + s << CUtils::GetLongIP(GetUser()->GetLocalDCCIP()); + s << " " << iPort << "\001"; - PutIRC(s.str()); + PutIRC(s.str()); - } else if (sCom.Equals("list")) { - CTable Table; - Table.AddColumn("Nick"); - Table.AddColumn("Created"); - Table.AddColumn("Host"); - Table.AddColumn("Port"); - Table.AddColumn("Status"); - Table.AddColumn("Cipher"); + } else if (sCom.Equals("list")) { + CTable Table; + Table.AddColumn("Nick"); + Table.AddColumn("Created"); + Table.AddColumn("Host"); + Table.AddColumn("Port"); + Table.AddColumn("Status"); + Table.AddColumn("Cipher"); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - Table.AddRow(); + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + Table.AddRow(); - CSChatSock* pSock = (CSChatSock*)*it; - Table.SetCell("Nick", pSock->GetChatNick()); - unsigned long long iStartTime = pSock->GetStartTime(); - time_t iTime = iStartTime / 1000; - char* pTime = ctime(&iTime); - if (pTime) { - CString sTime = pTime; - sTime.Trim(); - Table.SetCell("Created", sTime); - } + CSChatSock* pSock = (CSChatSock*)*it; + Table.SetCell("Nick", pSock->GetChatNick()); + unsigned long long iStartTime = pSock->GetStartTime(); + time_t iTime = iStartTime / 1000; + char* pTime = ctime(&iTime); + if (pTime) { + CString sTime = pTime; + sTime.Trim(); + Table.SetCell("Created", sTime); + } - if (pSock->GetType() != CSChatSock::LISTENER) { - Table.SetCell("Status", "Established"); - Table.SetCell("Host", pSock->GetRemoteIP()); - Table.SetCell("Port", CString(pSock->GetRemotePort())); - SSL_SESSION* pSession = pSock->GetSSLSession(); - if (pSession && pSession->cipher && pSession->cipher->name) - Table.SetCell("Cipher", pSession->cipher->name); + if (pSock->GetType() != CSChatSock::LISTENER) { + Table.SetCell("Status", "Established"); + Table.SetCell("Host", pSock->GetRemoteIP()); + Table.SetCell("Port", CString(pSock->GetRemotePort())); + SSL_SESSION* pSession = pSock->GetSSLSession(); + if (pSession && pSession->cipher && pSession->cipher->name) + Table.SetCell("Cipher", pSession->cipher->name); - } else { - Table.SetCell("Status", "Waiting"); - Table.SetCell("Port", CString(pSock->GetLocalPort())); - } - } - if (Table.size()) { - PutModule(Table); - } else - PutModule("No SDCCs currently in session"); + } else { + Table.SetCell("Status", "Waiting"); + Table.SetCell("Port", CString(pSock->GetLocalPort())); + } + } + if (Table.size()) { + PutModule(Table); + } else + PutModule("No SDCCs currently in session"); - } else if (sCom.Equals("close")) { - if (!sArgs.StartsWith("(s)")) sArgs = "(s)" + sArgs; + } else if (sCom.Equals("close")) { + if (!sArgs.StartsWith("(s)")) sArgs = "(s)" + sArgs; - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - CSChatSock* pSock = (CSChatSock*)*it; + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + CSChatSock* pSock = (CSChatSock*)*it; - if (sArgs.Equals(pSock->GetChatNick())) { - pSock->Close(); - return; - } - } - PutModule("No Such Chat [" + sArgs + "]"); - } else if (sCom.Equals("showsocks") && GetUser()->IsAdmin()) { - CTable Table; - Table.AddColumn("SockName"); - Table.AddColumn("Created"); - Table.AddColumn("LocalIP:Port"); - Table.AddColumn("RemoteIP:Port"); - Table.AddColumn("Type"); - Table.AddColumn("Cipher"); + if (sArgs.Equals(pSock->GetChatNick())) { + pSock->Close(); + return; + } + } + PutModule("No Such Chat [" + sArgs + "]"); + } else if (sCom.Equals("showsocks") && GetUser()->IsAdmin()) { + CTable Table; + Table.AddColumn("SockName"); + Table.AddColumn("Created"); + Table.AddColumn("LocalIP:Port"); + Table.AddColumn("RemoteIP:Port"); + Table.AddColumn("Type"); + Table.AddColumn("Cipher"); - set::const_iterator it; - for (it = BeginSockets(); it != EndSockets(); ++it) { - Table.AddRow(); - Csock* pSock = *it; - Table.SetCell("SockName", pSock->GetSockName()); - unsigned long long iStartTime = pSock->GetStartTime(); - time_t iTime = iStartTime / 1000; - char* pTime = ctime(&iTime); - if (pTime) { - CString sTime = pTime; - sTime.Trim(); - Table.SetCell("Created", sTime); - } + set::const_iterator it; + for (it = BeginSockets(); it != EndSockets(); ++it) { + Table.AddRow(); + Csock* pSock = *it; + Table.SetCell("SockName", pSock->GetSockName()); + unsigned long long iStartTime = pSock->GetStartTime(); + time_t iTime = iStartTime / 1000; + char* pTime = ctime(&iTime); + if (pTime) { + CString sTime = pTime; + sTime.Trim(); + Table.SetCell("Created", sTime); + } - if (pSock->GetType() != Csock::LISTENER) { - if (pSock->GetType() == Csock::OUTBOUND) - Table.SetCell("Type", "Outbound"); - else - Table.SetCell("Type", "Inbound"); - Table.SetCell("LocalIP:Port", - pSock->GetLocalIP() + ":" + - CString(pSock->GetLocalPort())); - Table.SetCell("RemoteIP:Port", - pSock->GetRemoteIP() + ":" + - CString(pSock->GetRemotePort())); - SSL_SESSION* pSession = pSock->GetSSLSession(); - if (pSession && pSession->cipher && pSession->cipher->name) - Table.SetCell("Cipher", pSession->cipher->name); - else - Table.SetCell("Cipher", "None"); + if (pSock->GetType() != Csock::LISTENER) { + if (pSock->GetType() == Csock::OUTBOUND) + Table.SetCell("Type", "Outbound"); + else + Table.SetCell("Type", "Inbound"); + Table.SetCell("LocalIP:Port", + pSock->GetLocalIP() + ":" + + CString(pSock->GetLocalPort())); + Table.SetCell("RemoteIP:Port", + pSock->GetRemoteIP() + ":" + + CString(pSock->GetRemotePort())); + SSL_SESSION* pSession = pSock->GetSSLSession(); + if (pSession && pSession->cipher && pSession->cipher->name) + Table.SetCell("Cipher", pSession->cipher->name); + else + Table.SetCell("Cipher", "None"); - } else { - Table.SetCell("Type", "Listener"); - Table.SetCell("LocalIP:Port", - pSock->GetLocalIP() + ":" + - CString(pSock->GetLocalPort())); - Table.SetCell("RemoteIP:Port", "0.0.0.0:0"); - } - } - if (Table.size()) - PutModule(Table); - else - PutModule("Error Finding Sockets"); + } else { + Table.SetCell("Type", "Listener"); + Table.SetCell("LocalIP:Port", + pSock->GetLocalIP() + ":" + + CString(pSock->GetLocalPort())); + Table.SetCell("RemoteIP:Port", "0.0.0.0:0"); + } + } + if (Table.size()) + PutModule(Table); + else + PutModule("Error Finding Sockets"); - } else if (sCom.Equals("help")) { - PutModule("Commands are:"); - PutModule(" help - This text."); - PutModule(" chat - Chat a nick."); - PutModule(" list - List current chats."); - PutModule(" close - Close a chat to a nick."); - PutModule(" timers - Shows related timers."); - if (GetUser()->IsAdmin()) { - PutModule(" showsocks - Shows all socket connections."); - } - } else if (sCom.Equals("timers")) - ListTimers(); - else - PutModule("Unknown command [" + sCom + "] [" + sArgs + "]"); - } + } else if (sCom.Equals("help")) { + PutModule("Commands are:"); + PutModule(" help - This text."); + PutModule(" chat - Chat a nick."); + PutModule(" list - List current chats."); + PutModule(" close - Close a chat to a nick."); + PutModule(" timers - Shows related timers."); + if (GetUser()->IsAdmin()) { + PutModule(" showsocks - Shows all socket connections."); + } + } else if (sCom.Equals("timers")) + ListTimers(); + else + PutModule("Unknown command [" + sCom + "] [" + sArgs + "]"); + } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - if (sMessage.StartsWith("DCC SCHAT ")) { - // chat ip port - unsigned long iIP = sMessage.Token(3).ToULong(); - unsigned short iPort = sMessage.Token(4).ToUShort(); + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + if (sMessage.StartsWith("DCC SCHAT ")) { + // chat ip port + unsigned long iIP = sMessage.Token(3).ToULong(); + unsigned short iPort = sMessage.Token(4).ToUShort(); - if (iIP > 0 && iPort > 0) { - pair pTmp; - CString sMask; + if (iIP > 0 && iPort > 0) { + pair pTmp; + CString sMask; - pTmp.first = iIP; - pTmp.second = iPort; - sMask = "(s)" + Nick.GetNick() + "!" + "(s)" + Nick.GetNick() + - "@" + CUtils::GetIP(iIP); + pTmp.first = iIP; + pTmp.second = iPort; + sMask = "(s)" + Nick.GetNick() + "!" + "(s)" + Nick.GetNick() + + "@" + CUtils::GetIP(iIP); - m_siiWaitingChats["(s)" + Nick.GetNick()] = pTmp; - SendToUser(sMask, "*** Incoming DCC SCHAT, Accept ? (yes/no)"); - CRemMarkerJob* p = new CRemMarkerJob( - this, 60, 1, "Remove (s)" + Nick.GetNick(), - "Removes this nicks entry for waiting DCC."); - p->SetNick("(s)" + Nick.GetNick()); - AddTimer(p); - return (HALT); - } - } + m_siiWaitingChats["(s)" + Nick.GetNick()] = pTmp; + SendToUser(sMask, "*** Incoming DCC SCHAT, Accept ? (yes/no)"); + CRemMarkerJob* p = new CRemMarkerJob( + this, 60, 1, "Remove (s)" + Nick.GetNick(), + "Removes this nicks entry for waiting DCC."); + p->SetNick("(s)" + Nick.GetNick()); + AddTimer(p); + return (HALT); + } + } - return (CONTINUE); - } + return (CONTINUE); + } - void AcceptSDCC(const CString& sNick, u_long iIP, u_short iPort) { - CSChatSock* p = - new CSChatSock(this, sNick, CUtils::GetIP(iIP), iPort, 60); - GetManager()->Connect(CUtils::GetIP(iIP), iPort, p->GetSockName(), 60, - true, GetUser()->GetLocalDCCIP(), p); - RemTimer("Remove " + - sNick); // delete any associated timer to this nick - } + void AcceptSDCC(const CString& sNick, u_long iIP, u_short iPort) { + CSChatSock* p = + new CSChatSock(this, sNick, CUtils::GetIP(iIP), iPort, 60); + GetManager()->Connect(CUtils::GetIP(iIP), iPort, p->GetSockName(), 60, + true, GetUser()->GetLocalDCCIP(), p); + RemTimer("Remove " + + sNick); // delete any associated timer to this nick + } - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - if (sTarget.Left(3) == "(s)") { - CString sSockName = GetModName().AsUpper() + "::" + sTarget; - CSChatSock* p = (CSChatSock*)FindSocket(sSockName); - if (!p) { - map>::iterator it; - it = m_siiWaitingChats.find(sTarget); + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + if (sTarget.Left(3) == "(s)") { + CString sSockName = GetModName().AsUpper() + "::" + sTarget; + CSChatSock* p = (CSChatSock*)FindSocket(sSockName); + if (!p) { + map>::iterator it; + it = m_siiWaitingChats.find(sTarget); - if (it != m_siiWaitingChats.end()) { - if (!sMessage.Equals("yes")) - SendToUser(sTarget + "!" + sTarget + "@" + - CUtils::GetIP(it->second.first), - "Refusing to accept DCC SCHAT!"); - else - AcceptSDCC(sTarget, it->second.first, - it->second.second); + if (it != m_siiWaitingChats.end()) { + if (!sMessage.Equals("yes")) + SendToUser(sTarget + "!" + sTarget + "@" + + CUtils::GetIP(it->second.first), + "Refusing to accept DCC SCHAT!"); + else + AcceptSDCC(sTarget, it->second.first, + it->second.second); - m_siiWaitingChats.erase(it); - return (HALT); - } - PutModule("No such SCHAT to [" + sTarget + "]"); - } else - p->Write(sMessage + "\n"); + m_siiWaitingChats.erase(it); + return (HALT); + } + PutModule("No such SCHAT to [" + sTarget + "]"); + } else + p->Write(sMessage + "\n"); - return (HALT); - } - return (CONTINUE); - } + return (HALT); + } + return (CONTINUE); + } - void RemoveMarker(const CString& sNick) { - map>::iterator it = - m_siiWaitingChats.find(sNick); - if (it != m_siiWaitingChats.end()) m_siiWaitingChats.erase(it); - } + void RemoveMarker(const CString& sNick) { + map>::iterator it = + m_siiWaitingChats.find(sNick); + if (it != m_siiWaitingChats.end()) m_siiWaitingChats.erase(it); + } - void SendToUser(const CString& sFrom, const CString& sText) { - //:*schat!znc@znc.in PRIVMSG Jim : - CString sSend = ":" + sFrom + " PRIVMSG " + GetNetwork()->GetCurNick() + - " :" + sText; - PutUser(sSend); - } + void SendToUser(const CString& sFrom, const CString& sText) { + //:*schat!znc@znc.in PRIVMSG Jim : + CString sSend = ":" + sFrom + " PRIVMSG " + GetNetwork()->GetCurNick() + + " :" + sText; + PutUser(sSend); + } - bool IsAttached() { return (GetNetwork()->IsUserAttached()); } + bool IsAttached() { return (GetNetwork()->IsUserAttached()); } private: - map> m_siiWaitingChats; - CString m_sPemFile; + map> m_siiWaitingChats; + CString m_sPemFile; }; //////////////////// methods //////////////// CSChatSock::CSChatSock(CSChat* pMod, const CString& sChatNick) : CSocket(pMod) { - m_pModule = pMod; - m_sChatNick = sChatNick; - SetSockName(pMod->GetModName().AsUpper() + "::" + m_sChatNick); + m_pModule = pMod; + m_sChatNick = sChatNick; + SetSockName(pMod->GetModName().AsUpper() + "::" + m_sChatNick); } CSChatSock::CSChatSock(CSChat* pMod, const CString& sChatNick, const CString& sHost, u_short iPort, int iTimeout) : CSocket(pMod, sHost, iPort, iTimeout) { - m_pModule = pMod; - EnableReadLine(); - m_sChatNick = sChatNick; - SetSockName(pMod->GetModName().AsUpper() + "::" + m_sChatNick); + m_pModule = pMod; + EnableReadLine(); + m_sChatNick = sChatNick; + SetSockName(pMod->GetModName().AsUpper() + "::" + m_sChatNick); } void CSChatSock::PutQuery(const CString& sText) { - m_pModule->SendToUser(m_sChatNick + "!" + m_sChatNick + "@" + GetRemoteIP(), - sText); + m_pModule->SendToUser(m_sChatNick + "!" + m_sChatNick + "@" + GetRemoteIP(), + sText); } void CSChatSock::ReadLine(const CS_STRING& sLine) { - if (m_pModule) { - CString sText = sLine; + if (m_pModule) { + CString sText = sLine; - sText.TrimRight("\r\n"); + sText.TrimRight("\r\n"); - if (m_pModule->IsAttached()) - PutQuery(sText); - else - AddLine(m_pModule->GetUser()->AddTimestamp(sText)); - } + if (m_pModule->IsAttached()) + PutQuery(sText); + else + AddLine(m_pModule->GetUser()->AddTimestamp(sText)); + } } void CSChatSock::Disconnected() { - if (m_pModule) PutQuery("*** Disconnected."); + if (m_pModule) PutQuery("*** Disconnected."); } void CSChatSock::Connected() { - SetTimeout(0); - if (m_pModule) PutQuery("*** Connected."); + SetTimeout(0); + if (m_pModule) PutQuery("*** Connected."); } void CSChatSock::Timeout() { - if (m_pModule) { - if (GetType() == LISTENER) - m_pModule->PutModule("Timeout while waiting for [" + m_sChatNick + - "]"); - else - PutQuery("*** Connection Timed out."); - } + if (m_pModule) { + if (GetType() == LISTENER) + m_pModule->PutModule("Timeout while waiting for [" + m_sChatNick + + "]"); + else + PutQuery("*** Connection Timed out."); + } } void CRemMarkerJob::RunJob() { - CSChat* p = (CSChat*)GetModule(); - p->RemoveMarker(m_sNick); + CSChat* p = (CSChat*)GetModule(); + p->RemoveMarker(m_sNick); - // store buffer + // store buffer } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("schat"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("Path to .pem file, if differs from main ZNC's one"); + Info.SetWikiPage("schat"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("Path to .pem file, if differs from main ZNC's one"); } NETWORKMODULEDEFS(CSChat, "Secure cross platform (:P) chat system") diff --git a/modules/send_raw.cpp b/modules/send_raw.cpp index 63140209..952eae9d 100644 --- a/modules/send_raw.cpp +++ b/modules/send_raw.cpp @@ -21,139 +21,139 @@ using std::vector; using std::map; class CSendRaw_Mod : public CModule { - void SendClient(const CString& sLine) { - CUser* pUser = CZNC::Get().FindUser(sLine.Token(1)); + void SendClient(const CString& sLine) { + CUser* pUser = CZNC::Get().FindUser(sLine.Token(1)); - if (pUser) { - CIRCNetwork* pNetwork = pUser->FindNetwork(sLine.Token(2)); + if (pUser) { + CIRCNetwork* pNetwork = pUser->FindNetwork(sLine.Token(2)); - if (pNetwork) { - pNetwork->PutUser(sLine.Token(3, true)); - PutModule("Sent [" + sLine.Token(3, true) + "] to " + - pUser->GetUserName() + "/" + pNetwork->GetName()); - } else { - PutModule("Network [" + sLine.Token(2) + - "] not found for user [" + sLine.Token(1) + "]"); - } - } else { - PutModule("User [" + sLine.Token(1) + "] not found"); - } - } + if (pNetwork) { + pNetwork->PutUser(sLine.Token(3, true)); + PutModule("Sent [" + sLine.Token(3, true) + "] to " + + pUser->GetUserName() + "/" + pNetwork->GetName()); + } else { + PutModule("Network [" + sLine.Token(2) + + "] not found for user [" + sLine.Token(1) + "]"); + } + } else { + PutModule("User [" + sLine.Token(1) + "] not found"); + } + } - void SendServer(const CString& sLine) { - CUser* pUser = CZNC::Get().FindUser(sLine.Token(1)); + void SendServer(const CString& sLine) { + CUser* pUser = CZNC::Get().FindUser(sLine.Token(1)); - if (pUser) { - CIRCNetwork* pNetwork = pUser->FindNetwork(sLine.Token(2)); + if (pUser) { + CIRCNetwork* pNetwork = pUser->FindNetwork(sLine.Token(2)); - if (pNetwork) { - pNetwork->PutIRC(sLine.Token(3, true)); - PutModule("Sent [" + sLine.Token(3, true) + - "] to IRC Server of " + pUser->GetUserName() + "/" + - pNetwork->GetName()); - } else { - PutModule("Network [" + sLine.Token(2) + - "] not found for user [" + sLine.Token(1) + "]"); - } - } else { - PutModule("User [" + sLine.Token(1) + "] not found"); - } - } + if (pNetwork) { + pNetwork->PutIRC(sLine.Token(3, true)); + PutModule("Sent [" + sLine.Token(3, true) + + "] to IRC Server of " + pUser->GetUserName() + "/" + + pNetwork->GetName()); + } else { + PutModule("Network [" + sLine.Token(2) + + "] not found for user [" + sLine.Token(1) + "]"); + } + } else { + PutModule("User [" + sLine.Token(1) + "] not found"); + } + } - void CurrentClient(const CString& sLine) { - CString sData = sLine.Token(1, true); - GetClient()->PutClient(sData); - } + void CurrentClient(const CString& sLine) { + CString sData = sLine.Token(1, true); + GetClient()->PutClient(sData); + } public: - virtual ~CSendRaw_Mod() {} + virtual ~CSendRaw_Mod() {} - bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { - if (!GetUser()->IsAdmin()) { - sErrorMsg = "You must have admin privileges to load this module"; - return false; - } + bool OnLoad(const CString& sArgs, CString& sErrorMsg) override { + if (!GetUser()->IsAdmin()) { + sErrorMsg = "You must have admin privileges to load this module"; + return false; + } - return true; - } + return true; + } - CString GetWebMenuTitle() override { return "Send Raw"; } - bool WebRequiresAdmin() override { return true; } + CString GetWebMenuTitle() override { return "Send Raw"; } + bool WebRequiresAdmin() override { return true; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - if (WebSock.IsPost()) { - CUser* pUser = CZNC::Get().FindUser( - WebSock.GetParam("network").Token(0, false, "/")); - if (!pUser) { - WebSock.GetSession()->AddError("User not found"); - return true; - } + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + if (WebSock.IsPost()) { + CUser* pUser = CZNC::Get().FindUser( + WebSock.GetParam("network").Token(0, false, "/")); + if (!pUser) { + WebSock.GetSession()->AddError("User not found"); + return true; + } - CIRCNetwork* pNetwork = pUser->FindNetwork( - WebSock.GetParam("network").Token(1, false, "/")); - if (!pNetwork) { - WebSock.GetSession()->AddError("Network not found"); - return true; - } + CIRCNetwork* pNetwork = pUser->FindNetwork( + WebSock.GetParam("network").Token(1, false, "/")); + if (!pNetwork) { + WebSock.GetSession()->AddError("Network not found"); + return true; + } - bool bToServer = WebSock.GetParam("send_to") == "server"; - const CString sLine = WebSock.GetParam("line"); + bool bToServer = WebSock.GetParam("send_to") == "server"; + const CString sLine = WebSock.GetParam("line"); - Tmpl["user"] = pUser->GetUserName(); - Tmpl[bToServer ? "to_server" : "to_client"] = "true"; - Tmpl["line"] = sLine; + Tmpl["user"] = pUser->GetUserName(); + Tmpl[bToServer ? "to_server" : "to_client"] = "true"; + Tmpl["line"] = sLine; - if (bToServer) { - pNetwork->PutIRC(sLine); - } else { - pNetwork->PutUser(sLine); - } + if (bToServer) { + pNetwork->PutIRC(sLine); + } else { + pNetwork->PutUser(sLine); + } - WebSock.GetSession()->AddSuccess("Line sent"); - } + WebSock.GetSession()->AddSuccess("Line sent"); + } - const map& msUsers = CZNC::Get().GetUserMap(); - for (const auto& it : msUsers) { - CTemplate& l = Tmpl.AddRow("UserLoop"); - l["Username"] = it.second->GetUserName(); + const map& msUsers = CZNC::Get().GetUserMap(); + for (const auto& it : msUsers) { + CTemplate& l = Tmpl.AddRow("UserLoop"); + l["Username"] = it.second->GetUserName(); - vector vNetworks = it.second->GetNetworks(); - for (const CIRCNetwork* pNetwork : vNetworks) { - CTemplate& NetworkLoop = l.AddRow("NetworkLoop"); - NetworkLoop["Username"] = it.second->GetUserName(); - NetworkLoop["Network"] = pNetwork->GetName(); - } - } + vector vNetworks = it.second->GetNetworks(); + for (const CIRCNetwork* pNetwork : vNetworks) { + CTemplate& NetworkLoop = l.AddRow("NetworkLoop"); + NetworkLoop["Username"] = it.second->GetUserName(); + NetworkLoop["Network"] = pNetwork->GetName(); + } + } - return true; - } + return true; + } - return false; - } + return false; + } - MODCONSTRUCTOR(CSendRaw_Mod) { - AddHelpCommand(); - AddCommand("Client", static_cast( - &CSendRaw_Mod::SendClient), - "[user] [network] [data to send]", - "The data will be sent to the user's IRC client(s)"); - AddCommand( - "Server", - static_cast(&CSendRaw_Mod::SendServer), - "[user] [network] [data to send]", - "The data will be sent to the IRC server the user is connected to"); - AddCommand( - "Current", - static_cast(&CSendRaw_Mod::CurrentClient), - "[data to send]", "The data will be sent to your current client"); - } + MODCONSTRUCTOR(CSendRaw_Mod) { + AddHelpCommand(); + AddCommand("Client", static_cast( + &CSendRaw_Mod::SendClient), + "[user] [network] [data to send]", + "The data will be sent to the user's IRC client(s)"); + AddCommand( + "Server", + static_cast(&CSendRaw_Mod::SendServer), + "[user] [network] [data to send]", + "The data will be sent to the IRC server the user is connected to"); + AddCommand( + "Current", + static_cast(&CSendRaw_Mod::CurrentClient), + "[data to send]", "The data will be sent to your current client"); + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("send_raw"); + Info.SetWikiPage("send_raw"); } USERMODULEDEFS(CSendRaw_Mod, diff --git a/modules/shell.cpp b/modules/shell.cpp index 0b30ca6d..58b1a742 100644 --- a/modules/shell.cpp +++ b/modules/shell.cpp @@ -26,126 +26,126 @@ class CShellMod; class CShellSock : public CExecSock { public: - CShellSock(CShellMod* pShellMod, CClient* pClient, const CString& sExec) - : CExecSock() { - EnableReadLine(); - m_pParent = pShellMod; - m_pClient = pClient; + CShellSock(CShellMod* pShellMod, CClient* pClient, const CString& sExec) + : CExecSock() { + EnableReadLine(); + m_pParent = pShellMod; + m_pClient = pClient; - if (Execute(sExec) == -1) { - CString s = "Failed to execute: "; - s += strerror(errno); - ReadLine(s); - return; - } + if (Execute(sExec) == -1) { + CString s = "Failed to execute: "; + s += strerror(errno); + ReadLine(s); + return; + } - // Get rid of that write fd, we aren't going to use it - // (And clients expecting input will fail this way). - close(GetWSock()); - SetWSock(open("/dev/null", O_WRONLY)); - } - // These next two function's bodies are at the bottom of the file since they - // reference CShellMod - void ReadLine(const CString& sData) override; - void Disconnected() override; + // Get rid of that write fd, we aren't going to use it + // (And clients expecting input will fail this way). + close(GetWSock()); + SetWSock(open("/dev/null", O_WRONLY)); + } + // These next two function's bodies are at the bottom of the file since they + // reference CShellMod + void ReadLine(const CString& sData) override; + void Disconnected() override; - CShellMod* m_pParent; + CShellMod* m_pParent; private: - CClient* m_pClient; + CClient* m_pClient; }; class CShellMod : public CModule { public: - MODCONSTRUCTOR(CShellMod) { m_sPath = CZNC::Get().GetHomePath(); } + MODCONSTRUCTOR(CShellMod) { m_sPath = CZNC::Get().GetHomePath(); } - virtual ~CShellMod() { - vector vSocks = GetManager()->FindSocksByName("SHELL"); + virtual ~CShellMod() { + vector vSocks = GetManager()->FindSocksByName("SHELL"); - for (unsigned int a = 0; a < vSocks.size(); a++) { - GetManager()->DelSockByAddr(vSocks[a]); - } - } + for (unsigned int a = 0; a < vSocks.size(); a++) { + GetManager()->DelSockByAddr(vSocks[a]); + } + } - bool OnLoad(const CString& sArgs, CString& sMessage) override { + bool OnLoad(const CString& sArgs, CString& sMessage) override { #ifndef MOD_SHELL_ALLOW_EVERYONE - if (!GetUser()->IsAdmin()) { - sMessage = "You must be admin to use the shell module"; - return false; - } + if (!GetUser()->IsAdmin()) { + sMessage = "You must be admin to use the shell module"; + return false; + } #endif - return true; - } + return true; + } - void OnModCommand(const CString& sLine) override { - CString sCommand = sLine.Token(0); - if (sCommand.Equals("cd")) { - CString sArg = sLine.Token(1, true); - CString sPath = CDir::ChangeDir( - m_sPath, - (sArg.empty() ? CString(CZNC::Get().GetHomePath()) : sArg), - CZNC::Get().GetHomePath()); - CFile Dir(sPath); + void OnModCommand(const CString& sLine) override { + CString sCommand = sLine.Token(0); + if (sCommand.Equals("cd")) { + CString sArg = sLine.Token(1, true); + CString sPath = CDir::ChangeDir( + m_sPath, + (sArg.empty() ? CString(CZNC::Get().GetHomePath()) : sArg), + CZNC::Get().GetHomePath()); + CFile Dir(sPath); - if (Dir.IsDir()) { - m_sPath = sPath; - } else if (Dir.Exists()) { - PutShell("cd: not a directory [" + sPath + "]"); - } else { - PutShell("cd: no such directory [" + sPath + "]"); - } + if (Dir.IsDir()) { + m_sPath = sPath; + } else if (Dir.Exists()) { + PutShell("cd: not a directory [" + sPath + "]"); + } else { + PutShell("cd: no such directory [" + sPath + "]"); + } - PutShell("znc$"); - } else { - RunCommand(sLine); - } - } + PutShell("znc$"); + } else { + RunCommand(sLine); + } + } - void PutShell(const CString& sMsg) { - CString sPath = m_sPath.Replace_n(" ", "_"); - CString sSource = ":" + GetModNick() + "!shell@" + sPath; - CString sLine = - sSource + " PRIVMSG " + GetClient()->GetNick() + " :" + sMsg; - GetClient()->PutClient(sLine); - } + void PutShell(const CString& sMsg) { + CString sPath = m_sPath.Replace_n(" ", "_"); + CString sSource = ":" + GetModNick() + "!shell@" + sPath; + CString sLine = + sSource + " PRIVMSG " + GetClient()->GetNick() + " :" + sMsg; + GetClient()->PutClient(sLine); + } - void RunCommand(const CString& sCommand) { - GetManager()->AddSock( - new CShellSock(this, GetClient(), - "cd " + m_sPath + " && " + sCommand), - "SHELL"); - } + void RunCommand(const CString& sCommand) { + GetManager()->AddSock( + new CShellSock(this, GetClient(), + "cd " + m_sPath + " && " + sCommand), + "SHELL"); + } private: - CString m_sPath; + CString m_sPath; }; void CShellSock::ReadLine(const CString& sData) { - CString sLine = sData; + CString sLine = sData; - sLine.TrimRight("\r\n"); - sLine.Replace("\t", " "); + sLine.TrimRight("\r\n"); + sLine.Replace("\t", " "); - m_pParent->SetClient(m_pClient); - m_pParent->PutShell(sLine); - m_pParent->SetClient(nullptr); + m_pParent->SetClient(m_pClient); + m_pParent->PutShell(sLine); + m_pParent->SetClient(nullptr); } void CShellSock::Disconnected() { - // If there is some incomplete line in the buffer, read it - // (e.g. echo echo -n "hi" triggered this) - CString& sBuffer = GetInternalReadBuffer(); - if (!sBuffer.empty()) ReadLine(sBuffer); + // If there is some incomplete line in the buffer, read it + // (e.g. echo echo -n "hi" triggered this) + CString& sBuffer = GetInternalReadBuffer(); + if (!sBuffer.empty()) ReadLine(sBuffer); - m_pParent->SetClient(m_pClient); - m_pParent->PutShell("znc$"); - m_pParent->SetClient(nullptr); + m_pParent->SetClient(m_pClient); + m_pParent->PutShell("znc$"); + m_pParent->SetClient(nullptr); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("shell"); + Info.SetWikiPage("shell"); } #ifdef MOD_SHELL_ALLOW_EVERYONE diff --git a/modules/simple_away.cpp b/modules/simple_away.cpp index 87d55610..a3ed8568 100644 --- a/modules/simple_away.cpp +++ b/modules/simple_away.cpp @@ -25,233 +25,233 @@ class CSimpleAway; class CSimpleAwayJob : public CTimer { public: - CSimpleAwayJob(CModule* pModule, unsigned int uInterval, - unsigned int uCycles, const CString& sLabel, - const CString& sDescription) - : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + CSimpleAwayJob(CModule* pModule, unsigned int uInterval, + unsigned int uCycles, const CString& sLabel, + const CString& sDescription) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} - virtual ~CSimpleAwayJob() {} + virtual ~CSimpleAwayJob() {} protected: - void RunJob() override; + void RunJob() override; }; class CSimpleAway : public CModule { private: - CString m_sReason; - unsigned int m_iAwayWait; - unsigned int m_iMinClients; - bool m_bClientSetAway; - bool m_bWeSetAway; + CString m_sReason; + unsigned int m_iAwayWait; + unsigned int m_iMinClients; + bool m_bClientSetAway; + bool m_bWeSetAway; public: - MODCONSTRUCTOR(CSimpleAway) { - m_sReason = SIMPLE_AWAY_DEFAULT_REASON; - m_iAwayWait = SIMPLE_AWAY_DEFAULT_TIME; - m_iMinClients = 1; - m_bClientSetAway = false; - m_bWeSetAway = false; + MODCONSTRUCTOR(CSimpleAway) { + m_sReason = SIMPLE_AWAY_DEFAULT_REASON; + m_iAwayWait = SIMPLE_AWAY_DEFAULT_TIME; + m_iMinClients = 1; + m_bClientSetAway = false; + m_bWeSetAway = false; - AddHelpCommand(); - AddCommand("Reason", static_cast( - &CSimpleAway::OnReasonCommand), - "[]", - "Prints or sets the away reason (%awaytime% is replaced " - "with the time you were set away, supports substitutions " - "using ExpandString)"); - AddCommand( - "Timer", - static_cast(&CSimpleAway::OnTimerCommand), - "", "Prints the current time to wait before setting you away"); - AddCommand("SetTimer", static_cast( - &CSimpleAway::OnSetTimerCommand), - "", - "Sets the time to wait before setting you away"); - AddCommand("DisableTimer", static_cast( - &CSimpleAway::OnDisableTimerCommand), - "", "Disables the wait time before setting you away"); - AddCommand( - "MinClients", static_cast( - &CSimpleAway::OnMinClientsCommand), - "", "Get or set the minimum number of clients before going away"); - } + AddHelpCommand(); + AddCommand("Reason", static_cast( + &CSimpleAway::OnReasonCommand), + "[]", + "Prints or sets the away reason (%awaytime% is replaced " + "with the time you were set away, supports substitutions " + "using ExpandString)"); + AddCommand( + "Timer", + static_cast(&CSimpleAway::OnTimerCommand), + "", "Prints the current time to wait before setting you away"); + AddCommand("SetTimer", static_cast( + &CSimpleAway::OnSetTimerCommand), + "", + "Sets the time to wait before setting you away"); + AddCommand("DisableTimer", static_cast( + &CSimpleAway::OnDisableTimerCommand), + "", "Disables the wait time before setting you away"); + AddCommand( + "MinClients", static_cast( + &CSimpleAway::OnMinClientsCommand), + "", "Get or set the minimum number of clients before going away"); + } - virtual ~CSimpleAway() {} + virtual ~CSimpleAway() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override { - CString sReasonArg; + bool OnLoad(const CString& sArgs, CString& sMessage) override { + CString sReasonArg; - // Load AwayWait - CString sFirstArg = sArgs.Token(0); - if (sFirstArg.Equals("-notimer")) { - SetAwayWait(0); - sReasonArg = sArgs.Token(1, true); - } else if (sFirstArg.Equals("-timer")) { - SetAwayWait(sArgs.Token(1).ToUInt()); - sReasonArg = sArgs.Token(2, true); - } else { - CString sAwayWait = GetNV("awaywait"); - if (!sAwayWait.empty()) SetAwayWait(sAwayWait.ToUInt(), false); - sReasonArg = sArgs; - } + // Load AwayWait + CString sFirstArg = sArgs.Token(0); + if (sFirstArg.Equals("-notimer")) { + SetAwayWait(0); + sReasonArg = sArgs.Token(1, true); + } else if (sFirstArg.Equals("-timer")) { + SetAwayWait(sArgs.Token(1).ToUInt()); + sReasonArg = sArgs.Token(2, true); + } else { + CString sAwayWait = GetNV("awaywait"); + if (!sAwayWait.empty()) SetAwayWait(sAwayWait.ToUInt(), false); + sReasonArg = sArgs; + } - // Load Reason - if (!sReasonArg.empty()) { - SetReason(sReasonArg); - } else { - CString sSavedReason = GetNV("reason"); - if (!sSavedReason.empty()) SetReason(sSavedReason, false); - } + // Load Reason + if (!sReasonArg.empty()) { + SetReason(sReasonArg); + } else { + CString sSavedReason = GetNV("reason"); + if (!sSavedReason.empty()) SetReason(sSavedReason, false); + } - // MinClients - CString sMinClients = GetNV("minclients"); - if (!sMinClients.empty()) SetMinClients(sMinClients.ToUInt(), false); + // MinClients + CString sMinClients = GetNV("minclients"); + if (!sMinClients.empty()) SetMinClients(sMinClients.ToUInt(), false); - // Set away on load, required if loaded via webadmin - if (GetNetwork()->IsIRCConnected() && MinClientsConnected()) - SetAway(false); + // Set away on load, required if loaded via webadmin + if (GetNetwork()->IsIRCConnected() && MinClientsConnected()) + SetAway(false); - return true; - } + return true; + } - void OnIRCConnected() override { - if (MinClientsConnected()) - SetBack(); - else - SetAway(false); - } + void OnIRCConnected() override { + if (MinClientsConnected()) + SetBack(); + else + SetAway(false); + } - void OnClientLogin() override { - if (MinClientsConnected()) SetBack(); - } + void OnClientLogin() override { + if (MinClientsConnected()) SetBack(); + } - void OnClientDisconnect() override { - /* There might still be other clients */ - if (!MinClientsConnected()) SetAway(); - } + void OnClientDisconnect() override { + /* There might still be other clients */ + if (!MinClientsConnected()) SetAway(); + } - void OnReasonCommand(const CString& sLine) { - CString sReason = sLine.Token(1, true); + void OnReasonCommand(const CString& sLine) { + CString sReason = sLine.Token(1, true); - if (!sReason.empty()) { - SetReason(sReason); - PutModule("Away reason set"); - } else { - PutModule("Away reason: " + m_sReason); - PutModule("Current away reason would be: " + ExpandReason()); - } - } + if (!sReason.empty()) { + SetReason(sReason); + PutModule("Away reason set"); + } else { + PutModule("Away reason: " + m_sReason); + PutModule("Current away reason would be: " + ExpandReason()); + } + } - void OnTimerCommand(const CString& sLine) { - PutModule("Current timer setting: " + CString(m_iAwayWait) + - " seconds"); - } + void OnTimerCommand(const CString& sLine) { + PutModule("Current timer setting: " + CString(m_iAwayWait) + + " seconds"); + } - void OnSetTimerCommand(const CString& sLine) { - SetAwayWait(sLine.Token(1).ToUInt()); + void OnSetTimerCommand(const CString& sLine) { + SetAwayWait(sLine.Token(1).ToUInt()); - if (m_iAwayWait == 0) - PutModule("Timer disabled"); - else - PutModule("Timer set to " + CString(m_iAwayWait) + " seconds"); - } + if (m_iAwayWait == 0) + PutModule("Timer disabled"); + else + PutModule("Timer set to " + CString(m_iAwayWait) + " seconds"); + } - void OnDisableTimerCommand(const CString& sLine) { - SetAwayWait(0); - PutModule("Timer disabled"); - } + void OnDisableTimerCommand(const CString& sLine) { + SetAwayWait(0); + PutModule("Timer disabled"); + } - void OnMinClientsCommand(const CString& sLine) { - if (sLine.Token(1).empty()) { - PutModule("Current MinClients setting: " + CString(m_iMinClients)); - } else { - SetMinClients(sLine.Token(1).ToUInt()); - PutModule("MinClients set to " + CString(m_iMinClients)); - } - } + void OnMinClientsCommand(const CString& sLine) { + if (sLine.Token(1).empty()) { + PutModule("Current MinClients setting: " + CString(m_iMinClients)); + } else { + SetMinClients(sLine.Token(1).ToUInt()); + PutModule("MinClients set to " + CString(m_iMinClients)); + } + } - EModRet OnUserRaw(CString& sLine) override { - if (!sLine.Token(0).Equals("AWAY")) return CONTINUE; + EModRet OnUserRaw(CString& sLine) override { + if (!sLine.Token(0).Equals("AWAY")) return CONTINUE; - // If a client set us away, we don't touch that away message - const CString sArg = sLine.Token(1, true).Trim_n(" "); - if (sArg.empty() || sArg == ":") - m_bClientSetAway = false; - else - m_bClientSetAway = true; + // If a client set us away, we don't touch that away message + const CString sArg = sLine.Token(1, true).Trim_n(" "); + if (sArg.empty() || sArg == ":") + m_bClientSetAway = false; + else + m_bClientSetAway = true; - m_bWeSetAway = false; + m_bWeSetAway = false; - return CONTINUE; - } + return CONTINUE; + } - void SetAway(bool bTimer = true) { - if (bTimer) { - RemTimer("simple_away"); - AddTimer(new CSimpleAwayJob(this, m_iAwayWait, 1, "simple_away", - "Sets you away after detach")); - } else { - if (!m_bClientSetAway) { - PutIRC("AWAY :" + ExpandReason()); - m_bWeSetAway = true; - } - } - } + void SetAway(bool bTimer = true) { + if (bTimer) { + RemTimer("simple_away"); + AddTimer(new CSimpleAwayJob(this, m_iAwayWait, 1, "simple_away", + "Sets you away after detach")); + } else { + if (!m_bClientSetAway) { + PutIRC("AWAY :" + ExpandReason()); + m_bWeSetAway = true; + } + } + } - void SetBack() { - RemTimer("simple_away"); - if (m_bWeSetAway) { - PutIRC("AWAY"); - m_bWeSetAway = false; - } - } + void SetBack() { + RemTimer("simple_away"); + if (m_bWeSetAway) { + PutIRC("AWAY"); + m_bWeSetAway = false; + } + } private: - bool MinClientsConnected() { - return GetNetwork()->GetClients().size() >= m_iMinClients; - } + bool MinClientsConnected() { + return GetNetwork()->GetClients().size() >= m_iMinClients; + } - CString ExpandReason() { - CString sReason = m_sReason; - if (sReason.empty()) sReason = SIMPLE_AWAY_DEFAULT_REASON; + CString ExpandReason() { + CString sReason = m_sReason; + if (sReason.empty()) sReason = SIMPLE_AWAY_DEFAULT_REASON; - time_t iTime = time(nullptr); - CString sTime = CUtils::CTime(iTime, GetUser()->GetTimezone()); - sReason.Replace("%awaytime%", sTime); - sReason = ExpandString(sReason); - sReason.Replace("%s", sTime); // Backwards compatibility with previous - // syntax, where %s was substituted with - // sTime. ZNC <= 1.6.x + time_t iTime = time(nullptr); + CString sTime = CUtils::CTime(iTime, GetUser()->GetTimezone()); + sReason.Replace("%awaytime%", sTime); + sReason = ExpandString(sReason); + sReason.Replace("%s", sTime); // Backwards compatibility with previous + // syntax, where %s was substituted with + // sTime. ZNC <= 1.6.x - return sReason; - } + return sReason; + } - /* Settings */ - void SetReason(CString& sReason, bool bSave = true) { - if (bSave) SetNV("reason", sReason); - m_sReason = sReason; - } + /* Settings */ + void SetReason(CString& sReason, bool bSave = true) { + if (bSave) SetNV("reason", sReason); + m_sReason = sReason; + } - void SetAwayWait(unsigned int iAwayWait, bool bSave = true) { - if (bSave) SetNV("awaywait", CString(iAwayWait)); - m_iAwayWait = iAwayWait; - } + void SetAwayWait(unsigned int iAwayWait, bool bSave = true) { + if (bSave) SetNV("awaywait", CString(iAwayWait)); + m_iAwayWait = iAwayWait; + } - void SetMinClients(unsigned int iMinClients, bool bSave = true) { - if (bSave) SetNV("minclients", CString(iMinClients)); - m_iMinClients = iMinClients; - } + void SetMinClients(unsigned int iMinClients, bool bSave = true) { + if (bSave) SetNV("minclients", CString(iMinClients)); + m_iMinClients = iMinClients; + } }; void CSimpleAwayJob::RunJob() { ((CSimpleAway*)GetModule())->SetAway(false); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("simple_away"); - Info.SetHasArgs(true); - Info.SetArgsHelpText( - "You might enter up to 3 arguments, like -notimer awaymessage or " - "-timer 5 awaymessage."); + Info.SetWikiPage("simple_away"); + Info.SetHasArgs(true); + Info.SetArgsHelpText( + "You might enter up to 3 arguments, like -notimer awaymessage or " + "-timer 5 awaymessage."); } NETWORKMODULEDEFS(CSimpleAway, diff --git a/modules/stickychan.cpp b/modules/stickychan.cpp index 01c644f2..6a375098 100644 --- a/modules/stickychan.cpp +++ b/modules/stickychan.cpp @@ -21,231 +21,231 @@ using std::vector; class CStickyChan : public CModule { public: - MODCONSTRUCTOR(CStickyChan) { - AddHelpCommand(); - AddCommand("Stick", static_cast( - &CStickyChan::OnStickCommand), - "<#channel> [key]", "Sticks a channel"); - AddCommand("Unstick", static_cast( - &CStickyChan::OnUnstickCommand), - "<#channel>", "Unsticks a channel"); - AddCommand("List", static_cast( - &CStickyChan::OnListCommand), - "", "Lists sticky channels"); - } - virtual ~CStickyChan() {} + MODCONSTRUCTOR(CStickyChan) { + AddHelpCommand(); + AddCommand("Stick", static_cast( + &CStickyChan::OnStickCommand), + "<#channel> [key]", "Sticks a channel"); + AddCommand("Unstick", static_cast( + &CStickyChan::OnUnstickCommand), + "<#channel>", "Unsticks a channel"); + AddCommand("List", static_cast( + &CStickyChan::OnListCommand), + "", "Lists sticky channels"); + } + virtual ~CStickyChan() {} - bool OnLoad(const CString& sArgs, CString& sMessage) override; + bool OnLoad(const CString& sArgs, CString& sMessage) override; - EModRet OnUserPart(CString& sChannel, CString& sMessage) override { - if (!GetNetwork()) { - return CONTINUE; - } + EModRet OnUserPart(CString& sChannel, CString& sMessage) override { + if (!GetNetwork()) { + return CONTINUE; + } - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - if (sChannel.Equals(it->first)) { - CChan* pChan = GetNetwork()->FindChan(sChannel); + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + if (sChannel.Equals(it->first)) { + CChan* pChan = GetNetwork()->FindChan(sChannel); - if (pChan) { - pChan->JoinUser(); - return HALT; - } - } - } + if (pChan) { + pChan->JoinUser(); + return HALT; + } + } + } - return CONTINUE; - } + return CONTINUE; + } - virtual void OnMode(const CNick& pOpNick, CChan& Channel, char uMode, - const CString& sArg, bool bAdded, - bool bNoChange) override { - if (uMode == CChan::M_Key) { - if (bAdded) { - // We ignore channel key "*" because of some broken nets. - if (sArg != "*") { - SetNV(Channel.GetName(), sArg, true); - } - } else { - SetNV(Channel.GetName(), "", true); - } - } - } + virtual void OnMode(const CNick& pOpNick, CChan& Channel, char uMode, + const CString& sArg, bool bAdded, + bool bNoChange) override { + if (uMode == CChan::M_Key) { + if (bAdded) { + // We ignore channel key "*" because of some broken nets. + if (sArg != "*") { + SetNV(Channel.GetName(), sArg, true); + } + } else { + SetNV(Channel.GetName(), "", true); + } + } + } - void OnStickCommand(const CString& sCommand) { - CString sChannel = sCommand.Token(1).AsLower(); - if (sChannel.empty()) { - PutModule("Usage: Stick <#channel> [key]"); - return; - } - SetNV(sChannel, sCommand.Token(2), true); - PutModule("Stuck " + sChannel); - } + void OnStickCommand(const CString& sCommand) { + CString sChannel = sCommand.Token(1).AsLower(); + if (sChannel.empty()) { + PutModule("Usage: Stick <#channel> [key]"); + return; + } + SetNV(sChannel, sCommand.Token(2), true); + PutModule("Stuck " + sChannel); + } - void OnUnstickCommand(const CString& sCommand) { - CString sChannel = sCommand.Token(1); - if (sChannel.empty()) { - PutModule("Usage: Unstick <#channel>"); - return; - } - DelNV(sChannel, true); - PutModule("Unstuck " + sChannel); - } + void OnUnstickCommand(const CString& sCommand) { + CString sChannel = sCommand.Token(1); + if (sChannel.empty()) { + PutModule("Usage: Unstick <#channel>"); + return; + } + DelNV(sChannel, true); + PutModule("Unstuck " + sChannel); + } - void OnListCommand(const CString& sCommand) { - int i = 1; - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it, i++) { - if (it->second.empty()) - PutModule(CString(i) + ": " + it->first); - else - PutModule(CString(i) + ": " + it->first + " (" + it->second + - ")"); - } - PutModule(" -- End of List"); - } + void OnListCommand(const CString& sCommand) { + int i = 1; + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it, i++) { + if (it->second.empty()) + PutModule(CString(i) + ": " + it->first); + else + PutModule(CString(i) + ": " + it->first + " (" + it->second + + ")"); + } + PutModule(" -- End of List"); + } - void RunJob() { - CIRCNetwork* pNetwork = GetNetwork(); - if (!pNetwork->GetIRCSock()) return; + void RunJob() { + CIRCNetwork* pNetwork = GetNetwork(); + if (!pNetwork->GetIRCSock()) return; - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - CChan* pChan = pNetwork->FindChan(it->first); - if (!pChan) { - pChan = new CChan(it->first, pNetwork, true); - if (!it->second.empty()) pChan->SetKey(it->second); - if (!pNetwork->AddChan(pChan)) { - /* AddChan() deleted that channel */ - PutModule("Could not join [" + it->first + - "] (# prefix missing?)"); - continue; - } - } - if (!pChan->IsOn() && pNetwork->IsIRCConnected()) { - PutModule("Joining [" + pChan->GetName() + "]"); - PutIRC("JOIN " + pChan->GetName() + - (pChan->GetKey().empty() ? "" : " " + pChan->GetKey())); - } - } - } + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + CChan* pChan = pNetwork->FindChan(it->first); + if (!pChan) { + pChan = new CChan(it->first, pNetwork, true); + if (!it->second.empty()) pChan->SetKey(it->second); + if (!pNetwork->AddChan(pChan)) { + /* AddChan() deleted that channel */ + PutModule("Could not join [" + it->first + + "] (# prefix missing?)"); + continue; + } + } + if (!pChan->IsOn() && pNetwork->IsIRCConnected()) { + PutModule("Joining [" + pChan->GetName() + "]"); + PutIRC("JOIN " + pChan->GetName() + + (pChan->GetKey().empty() ? "" : " " + pChan->GetKey())); + } + } + } - CString GetWebMenuTitle() override { return "Sticky Chans"; } + CString GetWebMenuTitle() override { return "Sticky Chans"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "index") { - bool bSubmitted = (WebSock.GetParam("submitted").ToInt() != 0); + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "index") { + bool bSubmitted = (WebSock.GetParam("submitted").ToInt() != 0); - const vector& Channels = GetNetwork()->GetChans(); - for (CChan* pChan : Channels) { - const CString sChan = pChan->GetName(); - bool bStick = FindNV(sChan) != EndNV(); + const vector& Channels = GetNetwork()->GetChans(); + for (CChan* pChan : Channels) { + const CString sChan = pChan->GetName(); + bool bStick = FindNV(sChan) != EndNV(); - if (bSubmitted) { - bool bNewStick = - WebSock.GetParam("stick_" + sChan).ToBool(); - if (bNewStick && !bStick) - SetNV(sChan, ""); // no password support for now unless - // chansaver is active too - else if (!bNewStick && bStick) { - MCString::iterator it = FindNV(sChan); - if (it != EndNV()) DelNV(it); - } - bStick = bNewStick; - } + if (bSubmitted) { + bool bNewStick = + WebSock.GetParam("stick_" + sChan).ToBool(); + if (bNewStick && !bStick) + SetNV(sChan, ""); // no password support for now unless + // chansaver is active too + else if (!bNewStick && bStick) { + MCString::iterator it = FindNV(sChan); + if (it != EndNV()) DelNV(it); + } + bStick = bNewStick; + } - CTemplate& Row = Tmpl.AddRow("ChannelLoop"); - Row["Name"] = sChan; - Row["Sticky"] = CString(bStick); - } + CTemplate& Row = Tmpl.AddRow("ChannelLoop"); + Row["Name"] = sChan; + Row["Sticky"] = CString(bStick); + } - if (bSubmitted) { - WebSock.GetSession()->AddSuccess("Changes have been saved!"); - } + if (bSubmitted) { + WebSock.GetSession()->AddSuccess("Changes have been saved!"); + } - return true; - } + return true; + } - return false; - } + return false; + } - bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - if (sPageName == "webadmin/channel") { - CString sChan = Tmpl["ChanName"]; - bool bStick = FindNV(sChan) != EndNV(); - if (Tmpl["WebadminAction"].Equals("display")) { - Tmpl["Sticky"] = CString(bStick); - } else if (WebSock.GetParam("embed_stickychan_presented") - .ToBool()) { - bool bNewStick = - WebSock.GetParam("embed_stickychan_sticky").ToBool(); - if (bNewStick && !bStick) { - // no password support for now unless chansaver is active - // too - SetNV(sChan, ""); - WebSock.GetSession()->AddSuccess("Channel become sticky!"); - } else if (!bNewStick && bStick) { - DelNV(sChan); - WebSock.GetSession()->AddSuccess( - "Channel stopped being sticky!"); - } - } - return true; - } - return false; - } + bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + if (sPageName == "webadmin/channel") { + CString sChan = Tmpl["ChanName"]; + bool bStick = FindNV(sChan) != EndNV(); + if (Tmpl["WebadminAction"].Equals("display")) { + Tmpl["Sticky"] = CString(bStick); + } else if (WebSock.GetParam("embed_stickychan_presented") + .ToBool()) { + bool bNewStick = + WebSock.GetParam("embed_stickychan_sticky").ToBool(); + if (bNewStick && !bStick) { + // no password support for now unless chansaver is active + // too + SetNV(sChan, ""); + WebSock.GetSession()->AddSuccess("Channel become sticky!"); + } else if (!bNewStick && bStick) { + DelNV(sChan); + WebSock.GetSession()->AddSuccess( + "Channel stopped being sticky!"); + } + } + return true; + } + return false; + } - EModRet OnRaw(CString& sLine) override { - CString sNumeric = sLine.Token(1); + EModRet OnRaw(CString& sLine) override { + CString sNumeric = sLine.Token(1); - if (sNumeric.Equals("479")) { - // ERR_BADCHANNAME (juped channels or illegal channel name - ircd - // hybrid) - // prevent the module from getting into an infinite loop of trying - // to join it. - // :irc.network.net 479 mynick #channel :Illegal channel name + if (sNumeric.Equals("479")) { + // ERR_BADCHANNAME (juped channels or illegal channel name - ircd + // hybrid) + // prevent the module from getting into an infinite loop of trying + // to join it. + // :irc.network.net 479 mynick #channel :Illegal channel name - CString sChannel = sLine.Token(3); - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - if (sChannel.Equals(it->first)) { - PutModule("Channel [" + sChannel + - "] cannot be joined, it is an illegal channel " - "name. Unsticking."); - OnUnstickCommand("unstick " + sChannel); - return CONTINUE; - } - } - } + CString sChannel = sLine.Token(3); + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + if (sChannel.Equals(it->first)) { + PutModule("Channel [" + sChannel + + "] cannot be joined, it is an illegal channel " + "name. Unsticking."); + OnUnstickCommand("unstick " + sChannel); + return CONTINUE; + } + } + } - return CONTINUE; - } + return CONTINUE; + } }; static void RunTimer(CModule* pModule, CFPTimer* pTimer) { - ((CStickyChan*)pModule)->RunJob(); + ((CStickyChan*)pModule)->RunJob(); } bool CStickyChan::OnLoad(const CString& sArgs, CString& sMessage) { - VCString vsChans; - sArgs.Split(",", vsChans, false); + VCString vsChans; + sArgs.Split(",", vsChans, false); - for (const CString& s : vsChans) { - CString sChan = s.Token(0); - CString sKey = s.Token(1, true); - SetNV(sChan, sKey); - } + for (const CString& s : vsChans) { + CString sChan = s.Token(0); + CString sKey = s.Token(1, true); + SetNV(sChan, sKey); + } - // Since we now have these channels added, clear the argument list - SetArgs(""); + // Since we now have these channels added, clear the argument list + SetArgs(""); - AddTimer(RunTimer, "StickyChanTimer", 15); - return (true); + AddTimer(RunTimer, "StickyChanTimer", 15); + return (true); } template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("stickychan"); - Info.SetHasArgs(true); - Info.SetArgsHelpText("List of channels, separated by comma."); + Info.SetWikiPage("stickychan"); + Info.SetHasArgs(true); + Info.SetArgsHelpText("List of channels, separated by comma."); } NETWORKMODULEDEFS(CStickyChan, diff --git a/modules/stripcontrols.cpp b/modules/stripcontrols.cpp index 4173e4c9..4f7bd2b0 100644 --- a/modules/stripcontrols.cpp +++ b/modules/stripcontrols.cpp @@ -18,45 +18,45 @@ class CStripControlsMod : public CModule { public: - MODCONSTRUCTOR(CStripControlsMod) {} + MODCONSTRUCTOR(CStripControlsMod) {} - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - sMessage.StripControls(); - return CONTINUE; - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + sMessage.StripControls(); + return CONTINUE; + } }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("stripcontrols"); - Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("stripcontrols"); + Info.AddType(CModInfo::UserModule); } NETWORKMODULEDEFS(CStripControlsMod, diff --git a/modules/watch.cpp b/modules/watch.cpp index d60fbdd9..66980199 100644 --- a/modules/watch.cpp +++ b/modules/watch.cpp @@ -23,733 +23,733 @@ using std::set; class CWatchSource { public: - CWatchSource(const CString& sSource, bool bNegated) { - m_sSource = sSource; - m_bNegated = bNegated; - } - virtual ~CWatchSource() {} + CWatchSource(const CString& sSource, bool bNegated) { + m_sSource = sSource; + m_bNegated = bNegated; + } + virtual ~CWatchSource() {} - // Getters - const CString& GetSource() const { return m_sSource; } - bool IsNegated() const { return m_bNegated; } - // !Getters + // Getters + const CString& GetSource() const { return m_sSource; } + bool IsNegated() const { return m_bNegated; } + // !Getters - // Setters - // !Setters + // Setters + // !Setters private: protected: - bool m_bNegated; - CString m_sSource; + bool m_bNegated; + CString m_sSource; }; class CWatchEntry { public: - CWatchEntry(const CString& sHostMask, const CString& sTarget, - const CString& sPattern) { - m_bDisabled = false; - m_bDetachedClientOnly = false; - m_bDetachedChannelOnly = false; - m_sPattern = (sPattern.size()) ? sPattern : "*"; + CWatchEntry(const CString& sHostMask, const CString& sTarget, + const CString& sPattern) { + m_bDisabled = false; + m_bDetachedClientOnly = false; + m_bDetachedChannelOnly = false; + m_sPattern = (sPattern.size()) ? sPattern : "*"; - CNick Nick; - Nick.Parse(sHostMask); + CNick Nick; + Nick.Parse(sHostMask); - m_sHostMask = (Nick.GetNick().size()) ? Nick.GetNick() : "*"; - m_sHostMask += "!"; - m_sHostMask += (Nick.GetIdent().size()) ? Nick.GetIdent() : "*"; - m_sHostMask += "@"; - m_sHostMask += (Nick.GetHost().size()) ? Nick.GetHost() : "*"; + m_sHostMask = (Nick.GetNick().size()) ? Nick.GetNick() : "*"; + m_sHostMask += "!"; + m_sHostMask += (Nick.GetIdent().size()) ? Nick.GetIdent() : "*"; + m_sHostMask += "@"; + m_sHostMask += (Nick.GetHost().size()) ? Nick.GetHost() : "*"; - if (sTarget.size()) { - m_sTarget = sTarget; - } else { - m_sTarget = "$"; - m_sTarget += Nick.GetNick(); - } - } - virtual ~CWatchEntry() {} + if (sTarget.size()) { + m_sTarget = sTarget; + } else { + m_sTarget = "$"; + m_sTarget += Nick.GetNick(); + } + } + virtual ~CWatchEntry() {} - bool IsMatch(const CNick& Nick, const CString& sText, - const CString& sSource, const CIRCNetwork* pNetwork) { - if (IsDisabled()) { - return false; - } + bool IsMatch(const CNick& Nick, const CString& sText, + const CString& sSource, const CIRCNetwork* pNetwork) { + if (IsDisabled()) { + return false; + } - bool bGoodSource = true; + bool bGoodSource = true; - if (!sSource.empty() && !m_vsSources.empty()) { - bGoodSource = false; + if (!sSource.empty() && !m_vsSources.empty()) { + bGoodSource = false; - for (unsigned int a = 0; a < m_vsSources.size(); a++) { - const CWatchSource& WatchSource = m_vsSources[a]; + for (unsigned int a = 0; a < m_vsSources.size(); a++) { + const CWatchSource& WatchSource = m_vsSources[a]; - if (sSource.WildCmp(WatchSource.GetSource(), - CString::CaseInsensitive)) { - if (WatchSource.IsNegated()) { - return false; - } else { - bGoodSource = true; - } - } - } - } + if (sSource.WildCmp(WatchSource.GetSource(), + CString::CaseInsensitive)) { + if (WatchSource.IsNegated()) { + return false; + } else { + bGoodSource = true; + } + } + } + } - if (!bGoodSource) return false; - if (!Nick.GetHostMask().WildCmp(m_sHostMask, CString::CaseInsensitive)) - return false; - return (sText.WildCmp(pNetwork->ExpandString(m_sPattern), - CString::CaseInsensitive)); - } + if (!bGoodSource) return false; + if (!Nick.GetHostMask().WildCmp(m_sHostMask, CString::CaseInsensitive)) + return false; + return (sText.WildCmp(pNetwork->ExpandString(m_sPattern), + CString::CaseInsensitive)); + } - bool operator==(const CWatchEntry& WatchEntry) { - return (GetHostMask().Equals(WatchEntry.GetHostMask()) && - GetTarget().Equals(WatchEntry.GetTarget()) && - GetPattern().Equals(WatchEntry.GetPattern())); - } + bool operator==(const CWatchEntry& WatchEntry) { + return (GetHostMask().Equals(WatchEntry.GetHostMask()) && + GetTarget().Equals(WatchEntry.GetTarget()) && + GetPattern().Equals(WatchEntry.GetPattern())); + } - // Getters - const CString& GetHostMask() const { return m_sHostMask; } - const CString& GetTarget() const { return m_sTarget; } - const CString& GetPattern() const { return m_sPattern; } - bool IsDisabled() const { return m_bDisabled; } - bool IsDetachedClientOnly() const { return m_bDetachedClientOnly; } - bool IsDetachedChannelOnly() const { return m_bDetachedChannelOnly; } - const vector& GetSources() const { return m_vsSources; } - CString GetSourcesStr() const { - CString sRet; + // Getters + const CString& GetHostMask() const { return m_sHostMask; } + const CString& GetTarget() const { return m_sTarget; } + const CString& GetPattern() const { return m_sPattern; } + bool IsDisabled() const { return m_bDisabled; } + bool IsDetachedClientOnly() const { return m_bDetachedClientOnly; } + bool IsDetachedChannelOnly() const { return m_bDetachedChannelOnly; } + const vector& GetSources() const { return m_vsSources; } + CString GetSourcesStr() const { + CString sRet; - for (unsigned int a = 0; a < m_vsSources.size(); a++) { - const CWatchSource& WatchSource = m_vsSources[a]; + for (unsigned int a = 0; a < m_vsSources.size(); a++) { + const CWatchSource& WatchSource = m_vsSources[a]; - if (a) { - sRet += " "; - } + if (a) { + sRet += " "; + } - if (WatchSource.IsNegated()) { - sRet += "!"; - } + if (WatchSource.IsNegated()) { + sRet += "!"; + } - sRet += WatchSource.GetSource(); - } + sRet += WatchSource.GetSource(); + } - return sRet; - } - // !Getters + return sRet; + } + // !Getters - // Setters - void SetHostMask(const CString& s) { m_sHostMask = s; } - void SetTarget(const CString& s) { m_sTarget = s; } - void SetPattern(const CString& s) { m_sPattern = s; } - void SetDisabled(bool b = true) { m_bDisabled = b; } - void SetDetachedClientOnly(bool b = true) { m_bDetachedClientOnly = b; } - void SetDetachedChannelOnly(bool b = true) { m_bDetachedChannelOnly = b; } - void SetSources(const CString& sSources) { - VCString vsSources; - VCString::iterator it; - sSources.Split(" ", vsSources, false); + // Setters + void SetHostMask(const CString& s) { m_sHostMask = s; } + void SetTarget(const CString& s) { m_sTarget = s; } + void SetPattern(const CString& s) { m_sPattern = s; } + void SetDisabled(bool b = true) { m_bDisabled = b; } + void SetDetachedClientOnly(bool b = true) { m_bDetachedClientOnly = b; } + void SetDetachedChannelOnly(bool b = true) { m_bDetachedChannelOnly = b; } + void SetSources(const CString& sSources) { + VCString vsSources; + VCString::iterator it; + sSources.Split(" ", vsSources, false); - m_vsSources.clear(); + m_vsSources.clear(); - for (it = vsSources.begin(); it != vsSources.end(); ++it) { - if (it->at(0) == '!' && it->size() > 1) { - m_vsSources.push_back(CWatchSource(it->substr(1), true)); - } else { - m_vsSources.push_back(CWatchSource(*it, false)); - } - } - } - // !Setters + for (it = vsSources.begin(); it != vsSources.end(); ++it) { + if (it->at(0) == '!' && it->size() > 1) { + m_vsSources.push_back(CWatchSource(it->substr(1), true)); + } else { + m_vsSources.push_back(CWatchSource(*it, false)); + } + } + } + // !Setters private: protected: - CString m_sHostMask; - CString m_sTarget; - CString m_sPattern; - bool m_bDisabled; - bool m_bDetachedClientOnly; - bool m_bDetachedChannelOnly; - vector m_vsSources; + CString m_sHostMask; + CString m_sTarget; + CString m_sPattern; + bool m_bDisabled; + bool m_bDetachedClientOnly; + bool m_bDetachedChannelOnly; + vector m_vsSources; }; class CWatcherMod : public CModule { public: - MODCONSTRUCTOR(CWatcherMod) { - m_Buffer.SetLineCount(500); - Load(); - } + MODCONSTRUCTOR(CWatcherMod) { + m_Buffer.SetLineCount(500); + Load(); + } - virtual ~CWatcherMod() {} + virtual ~CWatcherMod() {} - void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, - const CString& sArgs) override { - Process(OpNick, "* " + OpNick.GetNick() + " sets mode: " + sModes + - " " + sArgs + " on " + Channel.GetName(), - Channel.GetName()); - } + void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, + const CString& sArgs) override { + Process(OpNick, "* " + OpNick.GetNick() + " sets mode: " + sModes + + " " + sArgs + " on " + Channel.GetName(), + Channel.GetName()); + } - void OnClientLogin() override { - MCString msParams; - msParams["target"] = GetNetwork()->GetCurNick(); + void OnClientLogin() override { + MCString msParams; + msParams["target"] = GetNetwork()->GetCurNick(); - size_t uSize = m_Buffer.Size(); - for (unsigned int uIdx = 0; uIdx < uSize; uIdx++) { - PutUser(m_Buffer.GetLine(uIdx, *GetClient(), msParams)); - } - m_Buffer.Clear(); - } + size_t uSize = m_Buffer.Size(); + for (unsigned int uIdx = 0; uIdx < uSize; uIdx++) { + PutUser(m_Buffer.GetLine(uIdx, *GetClient(), msParams)); + } + m_Buffer.Clear(); + } - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, - const CString& sMessage) override { - Process(OpNick, - "* " + OpNick.GetNick() + " kicked " + sKickedNick + " from " + - Channel.GetName() + " because [" + sMessage + "]", - Channel.GetName()); - } + void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, + const CString& sMessage) override { + Process(OpNick, + "* " + OpNick.GetNick() + " kicked " + sKickedNick + " from " + + Channel.GetName() + " because [" + sMessage + "]", + Channel.GetName()); + } - void OnQuit(const CNick& Nick, const CString& sMessage, - const vector& vChans) override { - Process(Nick, "* Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + - "@" + Nick.GetHost() + - ") " - "(" + - sMessage + ")", - ""); - } + void OnQuit(const CNick& Nick, const CString& sMessage, + const vector& vChans) override { + Process(Nick, "* Quits: " + Nick.GetNick() + " (" + Nick.GetIdent() + + "@" + Nick.GetHost() + + ") " + "(" + + sMessage + ")", + ""); + } - void OnJoin(const CNick& Nick, CChan& Channel) override { - Process(Nick, "* " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + - Nick.GetHost() + ") joins " + Channel.GetName(), - Channel.GetName()); - } + void OnJoin(const CNick& Nick, CChan& Channel) override { + Process(Nick, "* " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + + Nick.GetHost() + ") joins " + Channel.GetName(), + Channel.GetName()); + } - void OnPart(const CNick& Nick, CChan& Channel, - const CString& sMessage) override { - Process(Nick, "* " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + - Nick.GetHost() + ") parts " + Channel.GetName() + - "(" + sMessage + ")", - Channel.GetName()); - } + void OnPart(const CNick& Nick, CChan& Channel, + const CString& sMessage) override { + Process(Nick, "* " + Nick.GetNick() + " (" + Nick.GetIdent() + "@" + + Nick.GetHost() + ") parts " + Channel.GetName() + + "(" + sMessage + ")", + Channel.GetName()); + } - void OnNick(const CNick& OldNick, const CString& sNewNick, - const vector& vChans) override { - Process(OldNick, - "* " + OldNick.GetNick() + " is now known as " + sNewNick, ""); - } + void OnNick(const CNick& OldNick, const CString& sNewNick, + const vector& vChans) override { + Process(OldNick, + "* " + OldNick.GetNick() + " is now known as " + sNewNick, ""); + } - EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { - Process(Nick, "* CTCP: " + Nick.GetNick() + " reply [" + sMessage + "]", - "priv"); - return CONTINUE; - } + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { + Process(Nick, "* CTCP: " + Nick.GetNick() + " reply [" + sMessage + "]", + "priv"); + return CONTINUE; + } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - Process(Nick, "* CTCP: " + Nick.GetNick() + " [" + sMessage + "]", - "priv"); - return CONTINUE; - } + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + Process(Nick, "* CTCP: " + Nick.GetNick() + " [" + sMessage + "]", + "priv"); + return CONTINUE; + } - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Process(Nick, "* CTCP: " + Nick.GetNick() + " [" + sMessage + - "] to " - "[" + - Channel.GetName() + "]", - Channel.GetName()); - return CONTINUE; - } + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Process(Nick, "* CTCP: " + Nick.GetNick() + " [" + sMessage + + "] to " + "[" + + Channel.GetName() + "]", + Channel.GetName()); + return CONTINUE; + } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - Process(Nick, "-" + Nick.GetNick() + "- " + sMessage, "priv"); - return CONTINUE; - } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + Process(Nick, "-" + Nick.GetNick() + "- " + sMessage, "priv"); + return CONTINUE; + } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Process(Nick, "-" + Nick.GetNick() + ":" + Channel.GetName() + "- " + - sMessage, - Channel.GetName()); - return CONTINUE; - } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Process(Nick, "-" + Nick.GetNick() + ":" + Channel.GetName() + "- " + + sMessage, + Channel.GetName()); + return CONTINUE; + } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - Process(Nick, "<" + Nick.GetNick() + "> " + sMessage, "priv"); - return CONTINUE; - } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + Process(Nick, "<" + Nick.GetNick() + "> " + sMessage, "priv"); + return CONTINUE; + } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - Process(Nick, "<" + Nick.GetNick() + ":" + Channel.GetName() + "> " + - sMessage, - Channel.GetName()); - return CONTINUE; - } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + Process(Nick, "<" + Nick.GetNick() + ":" + Channel.GetName() + "> " + + sMessage, + Channel.GetName()); + return CONTINUE; + } - void OnModCommand(const CString& sCommand) override { - CString sCmdName = sCommand.Token(0); - if (sCmdName.Equals("ADD") || sCmdName.Equals("WATCH")) { - Watch(sCommand.Token(1), sCommand.Token(2), - sCommand.Token(3, true)); - } else if (sCmdName.Equals("HELP")) { - Help(); - } else if (sCmdName.Equals("LIST")) { - List(); - } else if (sCmdName.Equals("DUMP")) { - Dump(); - } else if (sCmdName.Equals("ENABLE")) { - CString sTok = sCommand.Token(1); + void OnModCommand(const CString& sCommand) override { + CString sCmdName = sCommand.Token(0); + if (sCmdName.Equals("ADD") || sCmdName.Equals("WATCH")) { + Watch(sCommand.Token(1), sCommand.Token(2), + sCommand.Token(3, true)); + } else if (sCmdName.Equals("HELP")) { + Help(); + } else if (sCmdName.Equals("LIST")) { + List(); + } else if (sCmdName.Equals("DUMP")) { + Dump(); + } else if (sCmdName.Equals("ENABLE")) { + CString sTok = sCommand.Token(1); - if (sTok == "*") { - SetDisabled(~0, false); - } else { - SetDisabled(sTok.ToUInt(), false); - } - } else if (sCmdName.Equals("DISABLE")) { - CString sTok = sCommand.Token(1); + if (sTok == "*") { + SetDisabled(~0, false); + } else { + SetDisabled(sTok.ToUInt(), false); + } + } else if (sCmdName.Equals("DISABLE")) { + CString sTok = sCommand.Token(1); - if (sTok == "*") { - SetDisabled(~0, true); - } else { - SetDisabled(sTok.ToUInt(), true); - } - } else if (sCmdName.Equals("SETDETACHEDCLIENTONLY")) { - CString sTok = sCommand.Token(1); - bool bDetachedClientOnly = sCommand.Token(2).ToBool(); + if (sTok == "*") { + SetDisabled(~0, true); + } else { + SetDisabled(sTok.ToUInt(), true); + } + } else if (sCmdName.Equals("SETDETACHEDCLIENTONLY")) { + CString sTok = sCommand.Token(1); + bool bDetachedClientOnly = sCommand.Token(2).ToBool(); - if (sTok == "*") { - SetDetachedClientOnly(~0, bDetachedClientOnly); - } else { - SetDetachedClientOnly(sTok.ToUInt(), bDetachedClientOnly); - } - } else if (sCmdName.Equals("SETDETACHEDCHANNELONLY")) { - CString sTok = sCommand.Token(1); - bool bDetachedchannelOnly = sCommand.Token(2).ToBool(); + if (sTok == "*") { + SetDetachedClientOnly(~0, bDetachedClientOnly); + } else { + SetDetachedClientOnly(sTok.ToUInt(), bDetachedClientOnly); + } + } else if (sCmdName.Equals("SETDETACHEDCHANNELONLY")) { + CString sTok = sCommand.Token(1); + bool bDetachedchannelOnly = sCommand.Token(2).ToBool(); - if (sTok == "*") { - SetDetachedChannelOnly(~0, bDetachedchannelOnly); - } else { - SetDetachedChannelOnly(sTok.ToUInt(), bDetachedchannelOnly); - } - } else if (sCmdName.Equals("SETSOURCES")) { - SetSources(sCommand.Token(1).ToUInt(), sCommand.Token(2, true)); - } else if (sCmdName.Equals("CLEAR")) { - m_lsWatchers.clear(); - PutModule("All entries cleared."); - Save(); - } else if (sCmdName.Equals("BUFFER")) { - CString sCount = sCommand.Token(1); + if (sTok == "*") { + SetDetachedChannelOnly(~0, bDetachedchannelOnly); + } else { + SetDetachedChannelOnly(sTok.ToUInt(), bDetachedchannelOnly); + } + } else if (sCmdName.Equals("SETSOURCES")) { + SetSources(sCommand.Token(1).ToUInt(), sCommand.Token(2, true)); + } else if (sCmdName.Equals("CLEAR")) { + m_lsWatchers.clear(); + PutModule("All entries cleared."); + Save(); + } else if (sCmdName.Equals("BUFFER")) { + CString sCount = sCommand.Token(1); - if (sCount.size()) { - m_Buffer.SetLineCount(sCount.ToUInt()); - } + if (sCount.size()) { + m_Buffer.SetLineCount(sCount.ToUInt()); + } - PutModule("Buffer count is set to [" + - CString(m_Buffer.GetLineCount()) + "]"); - } else if (sCmdName.Equals("DEL")) { - Remove(sCommand.Token(1).ToUInt()); - } else { - PutModule("Unknown command: [" + sCmdName + "]"); - } - } + PutModule("Buffer count is set to [" + + CString(m_Buffer.GetLineCount()) + "]"); + } else if (sCmdName.Equals("DEL")) { + Remove(sCommand.Token(1).ToUInt()); + } else { + PutModule("Unknown command: [" + sCmdName + "]"); + } + } private: - void Process(const CNick& Nick, const CString& sMessage, - const CString& sSource) { - set sHandledTargets; - CIRCNetwork* pNetwork = GetNetwork(); - CChan* pChannel = pNetwork->FindChan(sSource); - - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - CWatchEntry& WatchEntry = *it; - - if (pNetwork->IsUserAttached() && - WatchEntry.IsDetachedClientOnly()) { - continue; - } - - if (pChannel && !pChannel->IsDetached() && - WatchEntry.IsDetachedChannelOnly()) { - continue; - } - - if (WatchEntry.IsMatch(Nick, sMessage, sSource, pNetwork) && - sHandledTargets.count(WatchEntry.GetTarget()) < 1) { - if (pNetwork->IsUserAttached()) { - pNetwork->PutUser(":" + WatchEntry.GetTarget() + - "!watch@znc.in PRIVMSG " + - pNetwork->GetCurNick() + " :" + sMessage); - } else { - m_Buffer.AddLine( - ":" + _NAMEDFMT(WatchEntry.GetTarget()) + - "!watch@znc.in PRIVMSG {target} :{text}", - sMessage); - } - sHandledTargets.insert(WatchEntry.GetTarget()); - } - } - } - - void SetDisabled(unsigned int uIdx, bool bDisabled) { - if (uIdx == (unsigned int)~0) { - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - (*it).SetDisabled(bDisabled); - } - - PutModule(((bDisabled) ? "Disabled all entries." - : "Enabled all entries.")); - Save(); - return; - } - - uIdx--; // "convert" index to zero based - if (uIdx >= m_lsWatchers.size()) { - PutModule("Invalid Id"); - return; - } - - list::iterator it = m_lsWatchers.begin(); - for (unsigned int a = 0; a < uIdx; a++) ++it; - - (*it).SetDisabled(bDisabled); - PutModule("Id " + CString(uIdx + 1) + - ((bDisabled) ? " Disabled" : " Enabled")); - Save(); - } - - void SetDetachedClientOnly(unsigned int uIdx, bool bDetachedClientOnly) { - if (uIdx == (unsigned int)~0) { - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - (*it).SetDetachedClientOnly(bDetachedClientOnly); - } - - PutModule(CString("Set DetachedClientOnly for all entries to: ") + - ((bDetachedClientOnly) ? "Yes" : "No")); - Save(); - return; - } - - uIdx--; // "convert" index to zero based - if (uIdx >= m_lsWatchers.size()) { - PutModule("Invalid Id"); - return; - } - - list::iterator it = m_lsWatchers.begin(); - for (unsigned int a = 0; a < uIdx; a++) ++it; - - (*it).SetDetachedClientOnly(bDetachedClientOnly); - PutModule("Id " + CString(uIdx + 1) + " set to: " + - ((bDetachedClientOnly) ? "Yes" : "No")); - Save(); - } - - void SetDetachedChannelOnly(unsigned int uIdx, bool bDetachedChannelOnly) { - if (uIdx == (unsigned int)~0) { - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - (*it).SetDetachedChannelOnly(bDetachedChannelOnly); - } - - PutModule(CString("Set DetachedChannelOnly for all entries to: ") + - ((bDetachedChannelOnly) ? "Yes" : "No")); - Save(); - return; - } - - uIdx--; // "convert" index to zero based - if (uIdx >= m_lsWatchers.size()) { - PutModule("Invalid Id"); - return; - } - - list::iterator it = m_lsWatchers.begin(); - for (unsigned int a = 0; a < uIdx; a++) ++it; - - (*it).SetDetachedChannelOnly(bDetachedChannelOnly); - PutModule("Id " + CString(uIdx + 1) + " set to: " + - ((bDetachedChannelOnly) ? "Yes" : "No")); - Save(); - } - - void List() { - CTable Table; - Table.AddColumn("Id"); - Table.AddColumn("HostMask"); - Table.AddColumn("Target"); - Table.AddColumn("Pattern"); - Table.AddColumn("Sources"); - Table.AddColumn("Off"); - Table.AddColumn("DetachedClientOnly"); - Table.AddColumn("DetachedChannelOnly"); - - unsigned int uIdx = 1; - - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it, uIdx++) { - CWatchEntry& WatchEntry = *it; - - Table.AddRow(); - Table.SetCell("Id", CString(uIdx)); - Table.SetCell("HostMask", WatchEntry.GetHostMask()); - Table.SetCell("Target", WatchEntry.GetTarget()); - Table.SetCell("Pattern", WatchEntry.GetPattern()); - Table.SetCell("Sources", WatchEntry.GetSourcesStr()); - Table.SetCell("Off", (WatchEntry.IsDisabled()) ? "Off" : ""); - Table.SetCell("DetachedClientOnly", - (WatchEntry.IsDetachedClientOnly()) ? "Yes" : "No"); - Table.SetCell("DetachedChannelOnly", - (WatchEntry.IsDetachedChannelOnly()) ? "Yes" : "No"); - } - - if (Table.size()) { - PutModule(Table); - } else { - PutModule("You have no entries."); - } - } - - void Dump() { - if (m_lsWatchers.empty()) { - PutModule("You have no entries."); - return; - } - - PutModule("---------------"); - PutModule("/msg " + GetModNick() + " CLEAR"); - - unsigned int uIdx = 1; - - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it, uIdx++) { - CWatchEntry& WatchEntry = *it; - - PutModule("/msg " + GetModNick() + " ADD " + - WatchEntry.GetHostMask() + " " + WatchEntry.GetTarget() + - " " + WatchEntry.GetPattern()); - - if (WatchEntry.GetSourcesStr().size()) { - PutModule("/msg " + GetModNick() + " SETSOURCES " + - CString(uIdx) + " " + WatchEntry.GetSourcesStr()); - } - - if (WatchEntry.IsDisabled()) { - PutModule("/msg " + GetModNick() + " DISABLE " + CString(uIdx)); - } - - if (WatchEntry.IsDetachedClientOnly()) { - PutModule("/msg " + GetModNick() + " SETDETACHEDCLIENTONLY " + - CString(uIdx) + " TRUE"); - } - - if (WatchEntry.IsDetachedChannelOnly()) { - PutModule("/msg " + GetModNick() + " SETDETACHEDCHANNELONLY " + - CString(uIdx) + " TRUE"); - } - } - - PutModule("---------------"); - } - - void SetSources(unsigned int uIdx, const CString& sSources) { - uIdx--; // "convert" index to zero based - if (uIdx >= m_lsWatchers.size()) { - PutModule("Invalid Id"); - return; - } - - list::iterator it = m_lsWatchers.begin(); - for (unsigned int a = 0; a < uIdx; a++) ++it; - - (*it).SetSources(sSources); - PutModule("Sources set for Id " + CString(uIdx + 1) + "."); - Save(); - } - - void Remove(unsigned int uIdx) { - uIdx--; // "convert" index to zero based - if (uIdx >= m_lsWatchers.size()) { - PutModule("Invalid Id"); - return; - } - - list::iterator it = m_lsWatchers.begin(); - for (unsigned int a = 0; a < uIdx; a++) ++it; - - m_lsWatchers.erase(it); - PutModule("Id " + CString(uIdx + 1) + " Removed."); - Save(); - } - - void Help() { - CTable Table; - - Table.AddColumn("Command"); - Table.AddColumn("Description"); - - Table.AddRow(); - Table.SetCell("Command", "Add [Target] [Pattern]"); - Table.SetCell("Description", "Used to add an entry to watch for."); - - Table.AddRow(); - Table.SetCell("Command", "List"); - Table.SetCell("Description", "List all entries being watched."); - - Table.AddRow(); - Table.SetCell("Command", "Dump"); - Table.SetCell("Description", - "Dump a list of all current entries to be used later."); - - Table.AddRow(); - Table.SetCell("Command", "Del "); - Table.SetCell("Description", - "Deletes Id from the list of watched entries."); - - Table.AddRow(); - Table.SetCell("Command", "Clear"); - Table.SetCell("Description", "Delete all entries."); - - Table.AddRow(); - Table.SetCell("Command", "Enable "); - Table.SetCell("Description", "Enable a disabled entry."); - - Table.AddRow(); - Table.SetCell("Command", "Disable "); - Table.SetCell("Description", "Disable (but don't delete) an entry."); - - Table.AddRow(); - Table.SetCell("Command", - "SetDetachedClientOnly "); - Table.SetCell("Description", - "Enable or disable detached client only for an entry."); - - Table.AddRow(); - Table.SetCell("Command", - "SetDetachedChannelOnly "); - Table.SetCell("Description", - "Enable or disable detached channel only for an entry."); - - Table.AddRow(); - Table.SetCell("Command", "Buffer [Count]"); - Table.SetCell("Description", - "Show/Set the amount of buffered lines while detached."); - - Table.AddRow(); - Table.SetCell("Command", "SetSources [#chan priv #foo* !#bar]"); - Table.SetCell("Description", - "Set the source channels that you care about."); - - Table.AddRow(); - Table.SetCell("Command", "Help"); - Table.SetCell("Description", "This help."); - - PutModule(Table); - } - - void Watch(const CString& sHostMask, const CString& sTarget, - const CString& sPattern, bool bNotice = false) { - CString sMessage; - - if (sHostMask.size()) { - CWatchEntry WatchEntry(sHostMask, sTarget, sPattern); - - bool bExists = false; - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - if (*it == WatchEntry) { - sMessage = "Entry for [" + WatchEntry.GetHostMask() + - "] already exists."; - bExists = true; - break; - } - } - - if (!bExists) { - sMessage = "Adding entry: [" + WatchEntry.GetHostMask() + - "] watching for " - "[" + - WatchEntry.GetPattern() + "] -> [" + - WatchEntry.GetTarget() + "]"; - m_lsWatchers.push_back(WatchEntry); - } - } else { - sMessage = "Watch: Not enough arguments. Try Help"; - } - - if (bNotice) { - PutModNotice(sMessage); - } else { - PutModule(sMessage); - } - Save(); - } - - void Save() { - ClearNV(false); - for (list::iterator it = m_lsWatchers.begin(); - it != m_lsWatchers.end(); ++it) { - CWatchEntry& WatchEntry = *it; - CString sSave; - - sSave = WatchEntry.GetHostMask() + "\n"; - sSave += WatchEntry.GetTarget() + "\n"; - sSave += WatchEntry.GetPattern() + "\n"; - sSave += (WatchEntry.IsDisabled() ? "disabled\n" : "enabled\n"); - sSave += CString(WatchEntry.IsDetachedClientOnly()) + "\n"; - sSave += CString(WatchEntry.IsDetachedChannelOnly()) + "\n"; - sSave += WatchEntry.GetSourcesStr(); - // Without this, loading fails if GetSourcesStr() - // returns an empty string - sSave += " "; - - SetNV(sSave, "", false); - } - - SaveRegistry(); - } - - void Load() { - // Just to make sure we dont mess up badly - m_lsWatchers.clear(); - - bool bWarn = false; - - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - VCString vList; - it->first.Split("\n", vList); - - // Backwards compatibility with the old save format - if (vList.size() != 5 && vList.size() != 7) { - bWarn = true; - continue; - } - - CWatchEntry WatchEntry(vList[0], vList[1], vList[2]); - if (vList[3].Equals("disabled")) - WatchEntry.SetDisabled(true); - else - WatchEntry.SetDisabled(false); - - // Backwards compatibility with the old save format - if (vList.size() == 5) { - WatchEntry.SetSources(vList[4]); - } else { - WatchEntry.SetDetachedClientOnly(vList[4].ToBool()); - WatchEntry.SetDetachedChannelOnly(vList[5].ToBool()); - WatchEntry.SetSources(vList[6]); - } - m_lsWatchers.push_back(WatchEntry); - } - - if (bWarn) PutModule("WARNING: malformed entry found while loading"); - } - - list m_lsWatchers; - CBuffer m_Buffer; + void Process(const CNick& Nick, const CString& sMessage, + const CString& sSource) { + set sHandledTargets; + CIRCNetwork* pNetwork = GetNetwork(); + CChan* pChannel = pNetwork->FindChan(sSource); + + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + CWatchEntry& WatchEntry = *it; + + if (pNetwork->IsUserAttached() && + WatchEntry.IsDetachedClientOnly()) { + continue; + } + + if (pChannel && !pChannel->IsDetached() && + WatchEntry.IsDetachedChannelOnly()) { + continue; + } + + if (WatchEntry.IsMatch(Nick, sMessage, sSource, pNetwork) && + sHandledTargets.count(WatchEntry.GetTarget()) < 1) { + if (pNetwork->IsUserAttached()) { + pNetwork->PutUser(":" + WatchEntry.GetTarget() + + "!watch@znc.in PRIVMSG " + + pNetwork->GetCurNick() + " :" + sMessage); + } else { + m_Buffer.AddLine( + ":" + _NAMEDFMT(WatchEntry.GetTarget()) + + "!watch@znc.in PRIVMSG {target} :{text}", + sMessage); + } + sHandledTargets.insert(WatchEntry.GetTarget()); + } + } + } + + void SetDisabled(unsigned int uIdx, bool bDisabled) { + if (uIdx == (unsigned int)~0) { + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + (*it).SetDisabled(bDisabled); + } + + PutModule(((bDisabled) ? "Disabled all entries." + : "Enabled all entries.")); + Save(); + return; + } + + uIdx--; // "convert" index to zero based + if (uIdx >= m_lsWatchers.size()) { + PutModule("Invalid Id"); + return; + } + + list::iterator it = m_lsWatchers.begin(); + for (unsigned int a = 0; a < uIdx; a++) ++it; + + (*it).SetDisabled(bDisabled); + PutModule("Id " + CString(uIdx + 1) + + ((bDisabled) ? " Disabled" : " Enabled")); + Save(); + } + + void SetDetachedClientOnly(unsigned int uIdx, bool bDetachedClientOnly) { + if (uIdx == (unsigned int)~0) { + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + (*it).SetDetachedClientOnly(bDetachedClientOnly); + } + + PutModule(CString("Set DetachedClientOnly for all entries to: ") + + ((bDetachedClientOnly) ? "Yes" : "No")); + Save(); + return; + } + + uIdx--; // "convert" index to zero based + if (uIdx >= m_lsWatchers.size()) { + PutModule("Invalid Id"); + return; + } + + list::iterator it = m_lsWatchers.begin(); + for (unsigned int a = 0; a < uIdx; a++) ++it; + + (*it).SetDetachedClientOnly(bDetachedClientOnly); + PutModule("Id " + CString(uIdx + 1) + " set to: " + + ((bDetachedClientOnly) ? "Yes" : "No")); + Save(); + } + + void SetDetachedChannelOnly(unsigned int uIdx, bool bDetachedChannelOnly) { + if (uIdx == (unsigned int)~0) { + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + (*it).SetDetachedChannelOnly(bDetachedChannelOnly); + } + + PutModule(CString("Set DetachedChannelOnly for all entries to: ") + + ((bDetachedChannelOnly) ? "Yes" : "No")); + Save(); + return; + } + + uIdx--; // "convert" index to zero based + if (uIdx >= m_lsWatchers.size()) { + PutModule("Invalid Id"); + return; + } + + list::iterator it = m_lsWatchers.begin(); + for (unsigned int a = 0; a < uIdx; a++) ++it; + + (*it).SetDetachedChannelOnly(bDetachedChannelOnly); + PutModule("Id " + CString(uIdx + 1) + " set to: " + + ((bDetachedChannelOnly) ? "Yes" : "No")); + Save(); + } + + void List() { + CTable Table; + Table.AddColumn("Id"); + Table.AddColumn("HostMask"); + Table.AddColumn("Target"); + Table.AddColumn("Pattern"); + Table.AddColumn("Sources"); + Table.AddColumn("Off"); + Table.AddColumn("DetachedClientOnly"); + Table.AddColumn("DetachedChannelOnly"); + + unsigned int uIdx = 1; + + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it, uIdx++) { + CWatchEntry& WatchEntry = *it; + + Table.AddRow(); + Table.SetCell("Id", CString(uIdx)); + Table.SetCell("HostMask", WatchEntry.GetHostMask()); + Table.SetCell("Target", WatchEntry.GetTarget()); + Table.SetCell("Pattern", WatchEntry.GetPattern()); + Table.SetCell("Sources", WatchEntry.GetSourcesStr()); + Table.SetCell("Off", (WatchEntry.IsDisabled()) ? "Off" : ""); + Table.SetCell("DetachedClientOnly", + (WatchEntry.IsDetachedClientOnly()) ? "Yes" : "No"); + Table.SetCell("DetachedChannelOnly", + (WatchEntry.IsDetachedChannelOnly()) ? "Yes" : "No"); + } + + if (Table.size()) { + PutModule(Table); + } else { + PutModule("You have no entries."); + } + } + + void Dump() { + if (m_lsWatchers.empty()) { + PutModule("You have no entries."); + return; + } + + PutModule("---------------"); + PutModule("/msg " + GetModNick() + " CLEAR"); + + unsigned int uIdx = 1; + + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it, uIdx++) { + CWatchEntry& WatchEntry = *it; + + PutModule("/msg " + GetModNick() + " ADD " + + WatchEntry.GetHostMask() + " " + WatchEntry.GetTarget() + + " " + WatchEntry.GetPattern()); + + if (WatchEntry.GetSourcesStr().size()) { + PutModule("/msg " + GetModNick() + " SETSOURCES " + + CString(uIdx) + " " + WatchEntry.GetSourcesStr()); + } + + if (WatchEntry.IsDisabled()) { + PutModule("/msg " + GetModNick() + " DISABLE " + CString(uIdx)); + } + + if (WatchEntry.IsDetachedClientOnly()) { + PutModule("/msg " + GetModNick() + " SETDETACHEDCLIENTONLY " + + CString(uIdx) + " TRUE"); + } + + if (WatchEntry.IsDetachedChannelOnly()) { + PutModule("/msg " + GetModNick() + " SETDETACHEDCHANNELONLY " + + CString(uIdx) + " TRUE"); + } + } + + PutModule("---------------"); + } + + void SetSources(unsigned int uIdx, const CString& sSources) { + uIdx--; // "convert" index to zero based + if (uIdx >= m_lsWatchers.size()) { + PutModule("Invalid Id"); + return; + } + + list::iterator it = m_lsWatchers.begin(); + for (unsigned int a = 0; a < uIdx; a++) ++it; + + (*it).SetSources(sSources); + PutModule("Sources set for Id " + CString(uIdx + 1) + "."); + Save(); + } + + void Remove(unsigned int uIdx) { + uIdx--; // "convert" index to zero based + if (uIdx >= m_lsWatchers.size()) { + PutModule("Invalid Id"); + return; + } + + list::iterator it = m_lsWatchers.begin(); + for (unsigned int a = 0; a < uIdx; a++) ++it; + + m_lsWatchers.erase(it); + PutModule("Id " + CString(uIdx + 1) + " Removed."); + Save(); + } + + void Help() { + CTable Table; + + Table.AddColumn("Command"); + Table.AddColumn("Description"); + + Table.AddRow(); + Table.SetCell("Command", "Add [Target] [Pattern]"); + Table.SetCell("Description", "Used to add an entry to watch for."); + + Table.AddRow(); + Table.SetCell("Command", "List"); + Table.SetCell("Description", "List all entries being watched."); + + Table.AddRow(); + Table.SetCell("Command", "Dump"); + Table.SetCell("Description", + "Dump a list of all current entries to be used later."); + + Table.AddRow(); + Table.SetCell("Command", "Del "); + Table.SetCell("Description", + "Deletes Id from the list of watched entries."); + + Table.AddRow(); + Table.SetCell("Command", "Clear"); + Table.SetCell("Description", "Delete all entries."); + + Table.AddRow(); + Table.SetCell("Command", "Enable "); + Table.SetCell("Description", "Enable a disabled entry."); + + Table.AddRow(); + Table.SetCell("Command", "Disable "); + Table.SetCell("Description", "Disable (but don't delete) an entry."); + + Table.AddRow(); + Table.SetCell("Command", + "SetDetachedClientOnly "); + Table.SetCell("Description", + "Enable or disable detached client only for an entry."); + + Table.AddRow(); + Table.SetCell("Command", + "SetDetachedChannelOnly "); + Table.SetCell("Description", + "Enable or disable detached channel only for an entry."); + + Table.AddRow(); + Table.SetCell("Command", "Buffer [Count]"); + Table.SetCell("Description", + "Show/Set the amount of buffered lines while detached."); + + Table.AddRow(); + Table.SetCell("Command", "SetSources [#chan priv #foo* !#bar]"); + Table.SetCell("Description", + "Set the source channels that you care about."); + + Table.AddRow(); + Table.SetCell("Command", "Help"); + Table.SetCell("Description", "This help."); + + PutModule(Table); + } + + void Watch(const CString& sHostMask, const CString& sTarget, + const CString& sPattern, bool bNotice = false) { + CString sMessage; + + if (sHostMask.size()) { + CWatchEntry WatchEntry(sHostMask, sTarget, sPattern); + + bool bExists = false; + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + if (*it == WatchEntry) { + sMessage = "Entry for [" + WatchEntry.GetHostMask() + + "] already exists."; + bExists = true; + break; + } + } + + if (!bExists) { + sMessage = "Adding entry: [" + WatchEntry.GetHostMask() + + "] watching for " + "[" + + WatchEntry.GetPattern() + "] -> [" + + WatchEntry.GetTarget() + "]"; + m_lsWatchers.push_back(WatchEntry); + } + } else { + sMessage = "Watch: Not enough arguments. Try Help"; + } + + if (bNotice) { + PutModNotice(sMessage); + } else { + PutModule(sMessage); + } + Save(); + } + + void Save() { + ClearNV(false); + for (list::iterator it = m_lsWatchers.begin(); + it != m_lsWatchers.end(); ++it) { + CWatchEntry& WatchEntry = *it; + CString sSave; + + sSave = WatchEntry.GetHostMask() + "\n"; + sSave += WatchEntry.GetTarget() + "\n"; + sSave += WatchEntry.GetPattern() + "\n"; + sSave += (WatchEntry.IsDisabled() ? "disabled\n" : "enabled\n"); + sSave += CString(WatchEntry.IsDetachedClientOnly()) + "\n"; + sSave += CString(WatchEntry.IsDetachedChannelOnly()) + "\n"; + sSave += WatchEntry.GetSourcesStr(); + // Without this, loading fails if GetSourcesStr() + // returns an empty string + sSave += " "; + + SetNV(sSave, "", false); + } + + SaveRegistry(); + } + + void Load() { + // Just to make sure we dont mess up badly + m_lsWatchers.clear(); + + bool bWarn = false; + + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + VCString vList; + it->first.Split("\n", vList); + + // Backwards compatibility with the old save format + if (vList.size() != 5 && vList.size() != 7) { + bWarn = true; + continue; + } + + CWatchEntry WatchEntry(vList[0], vList[1], vList[2]); + if (vList[3].Equals("disabled")) + WatchEntry.SetDisabled(true); + else + WatchEntry.SetDisabled(false); + + // Backwards compatibility with the old save format + if (vList.size() == 5) { + WatchEntry.SetSources(vList[4]); + } else { + WatchEntry.SetDetachedClientOnly(vList[4].ToBool()); + WatchEntry.SetDetachedChannelOnly(vList[5].ToBool()); + WatchEntry.SetSources(vList[6]); + } + m_lsWatchers.push_back(WatchEntry); + } + + if (bWarn) PutModule("WARNING: malformed entry found while loading"); + } + + list m_lsWatchers; + CBuffer m_Buffer; }; template <> void TModInfo(CModInfo& Info) { - Info.SetWikiPage("watch"); + Info.SetWikiPage("watch"); } NETWORKMODULEDEFS(CWatcherMod, diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 33fae584..dc27b9c7 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -35,1996 +35,1996 @@ using std::map; } */ struct FOR_EACH_MODULE_Type { - enum { - AtGlobal, - AtUser, - AtNetwork, - } where; - CModules CMtemp; - CModules& CMuser; - CModules& CMnet; - FOR_EACH_MODULE_Type(CUser* pUser) - : CMuser(pUser ? pUser->GetModules() : CMtemp), CMnet(CMtemp) { - where = AtGlobal; - } - FOR_EACH_MODULE_Type(CIRCNetwork* pNetwork) - : CMuser(pNetwork ? pNetwork->GetUser()->GetModules() : CMtemp), - CMnet(pNetwork ? pNetwork->GetModules() : CMtemp) { - where = AtGlobal; - } - FOR_EACH_MODULE_Type(std::pair arg) - : CMuser(arg.first ? arg.first->GetModules() : CMtemp), - CMnet(arg.second ? arg.second->GetModules() : CMtemp) { - where = AtGlobal; - } - operator bool() { return false; } + enum { + AtGlobal, + AtUser, + AtNetwork, + } where; + CModules CMtemp; + CModules& CMuser; + CModules& CMnet; + FOR_EACH_MODULE_Type(CUser* pUser) + : CMuser(pUser ? pUser->GetModules() : CMtemp), CMnet(CMtemp) { + where = AtGlobal; + } + FOR_EACH_MODULE_Type(CIRCNetwork* pNetwork) + : CMuser(pNetwork ? pNetwork->GetUser()->GetModules() : CMtemp), + CMnet(pNetwork ? pNetwork->GetModules() : CMtemp) { + where = AtGlobal; + } + FOR_EACH_MODULE_Type(std::pair arg) + : CMuser(arg.first ? arg.first->GetModules() : CMtemp), + CMnet(arg.second ? arg.second->GetModules() : CMtemp) { + where = AtGlobal; + } + operator bool() { return false; } }; inline bool FOR_EACH_MODULE_CanContinue(FOR_EACH_MODULE_Type& state, CModules::iterator& i) { - if (state.where == FOR_EACH_MODULE_Type::AtGlobal && - i == CZNC::Get().GetModules().end()) { - i = state.CMuser.begin(); - state.where = FOR_EACH_MODULE_Type::AtUser; - } - if (state.where == FOR_EACH_MODULE_Type::AtUser && - i == state.CMuser.end()) { - i = state.CMnet.begin(); - state.where = FOR_EACH_MODULE_Type::AtNetwork; - } - return !(state.where == FOR_EACH_MODULE_Type::AtNetwork && - i == state.CMnet.end()); + if (state.where == FOR_EACH_MODULE_Type::AtGlobal && + i == CZNC::Get().GetModules().end()) { + i = state.CMuser.begin(); + state.where = FOR_EACH_MODULE_Type::AtUser; + } + if (state.where == FOR_EACH_MODULE_Type::AtUser && + i == state.CMuser.end()) { + i = state.CMnet.begin(); + state.where = FOR_EACH_MODULE_Type::AtNetwork; + } + return !(state.where == FOR_EACH_MODULE_Type::AtNetwork && + i == state.CMnet.end()); } #define FOR_EACH_MODULE(I, pUserOrNetwork) \ - if (FOR_EACH_MODULE_Type FOR_EACH_MODULE_Var = pUserOrNetwork) { \ - } else \ - for (CModules::iterator I = CZNC::Get().GetModules().begin(); \ - FOR_EACH_MODULE_CanContinue(FOR_EACH_MODULE_Var, I); ++I) + if (FOR_EACH_MODULE_Type FOR_EACH_MODULE_Var = pUserOrNetwork) { \ + } else \ + for (CModules::iterator I = CZNC::Get().GetModules().begin(); \ + FOR_EACH_MODULE_CanContinue(FOR_EACH_MODULE_Var, I); ++I) class CWebAdminMod : public CModule { public: - MODCONSTRUCTOR(CWebAdminMod) { - VPair vParams; - vParams.push_back(make_pair("user", "")); - AddSubPage(std::make_shared("settings", "Global Settings", - CWebSubPage::F_ADMIN)); - AddSubPage(std::make_shared("edituser", "Your Settings", - vParams)); - AddSubPage( - std::make_shared("traffic", "Traffic Info", vParams)); - AddSubPage(std::make_shared("listusers", "Manage Users", - CWebSubPage::F_ADMIN)); - } + MODCONSTRUCTOR(CWebAdminMod) { + VPair vParams; + vParams.push_back(make_pair("user", "")); + AddSubPage(std::make_shared("settings", "Global Settings", + CWebSubPage::F_ADMIN)); + AddSubPage(std::make_shared("edituser", "Your Settings", + vParams)); + AddSubPage( + std::make_shared("traffic", "Traffic Info", vParams)); + AddSubPage(std::make_shared("listusers", "Manage Users", + CWebSubPage::F_ADMIN)); + } - virtual ~CWebAdminMod() {} + virtual ~CWebAdminMod() {} - bool OnLoad(const CString& sArgStr, CString& sMessage) override { - if (sArgStr.empty() || CModInfo::GlobalModule != GetType()) return true; + bool OnLoad(const CString& sArgStr, CString& sMessage) override { + if (sArgStr.empty() || CModInfo::GlobalModule != GetType()) return true; - // We don't accept any arguments, but for backwards - // compatibility we have to do some magic here. - sMessage = "Arguments converted to new syntax"; + // We don't accept any arguments, but for backwards + // compatibility we have to do some magic here. + sMessage = "Arguments converted to new syntax"; - bool bSSL = false; - bool bIPv6 = false; - bool bShareIRCPorts = true; - unsigned short uPort = 8080; - CString sArgs(sArgStr); - CString sPort; - CString sListenHost; - CString sURIPrefix; + bool bSSL = false; + bool bIPv6 = false; + bool bShareIRCPorts = true; + unsigned short uPort = 8080; + CString sArgs(sArgStr); + CString sPort; + CString sListenHost; + CString sURIPrefix; - while (sArgs.Left(1) == "-") { - CString sOpt = sArgs.Token(0); - sArgs = sArgs.Token(1, true); + while (sArgs.Left(1) == "-") { + CString sOpt = sArgs.Token(0); + sArgs = sArgs.Token(1, true); - if (sOpt.Equals("-IPV6")) { - bIPv6 = true; - } else if (sOpt.Equals("-IPV4")) { - bIPv6 = false; - } else if (sOpt.Equals("-noircport")) { - bShareIRCPorts = false; - } else { - // Uhm... Unknown option? Let's just ignore all - // arguments, older versions would have returned - // an error and denied loading - return true; - } - } + if (sOpt.Equals("-IPV6")) { + bIPv6 = true; + } else if (sOpt.Equals("-IPV4")) { + bIPv6 = false; + } else if (sOpt.Equals("-noircport")) { + bShareIRCPorts = false; + } else { + // Uhm... Unknown option? Let's just ignore all + // arguments, older versions would have returned + // an error and denied loading + return true; + } + } - // No arguments left: Only port sharing - if (sArgs.empty() && bShareIRCPorts) return true; + // No arguments left: Only port sharing + if (sArgs.empty() && bShareIRCPorts) return true; - if (sArgs.find(" ") != CString::npos) { - sListenHost = sArgs.Token(0); - sPort = sArgs.Token(1, true); - } else { - sPort = sArgs; - } + if (sArgs.find(" ") != CString::npos) { + sListenHost = sArgs.Token(0); + sPort = sArgs.Token(1, true); + } else { + sPort = sArgs; + } - if (sPort.Left(1) == "+") { - sPort.TrimLeft("+"); - bSSL = true; - } + if (sPort.Left(1) == "+") { + sPort.TrimLeft("+"); + bSSL = true; + } - if (!sPort.empty()) { - uPort = sPort.ToUShort(); - } + if (!sPort.empty()) { + uPort = sPort.ToUShort(); + } - if (!bShareIRCPorts) { - // Make all existing listeners IRC-only - const vector& vListeners = CZNC::Get().GetListeners(); - for (CListener* pListener : vListeners) { - pListener->SetAcceptType(CListener::ACCEPT_IRC); - } - } + if (!bShareIRCPorts) { + // Make all existing listeners IRC-only + const vector& vListeners = CZNC::Get().GetListeners(); + for (CListener* pListener : vListeners) { + pListener->SetAcceptType(CListener::ACCEPT_IRC); + } + } - // Now turn that into a listener instance - CListener* pListener = new CListener( - uPort, sListenHost, sURIPrefix, bSSL, - (!bIPv6 ? ADDR_IPV4ONLY : ADDR_ALL), CListener::ACCEPT_HTTP); + // Now turn that into a listener instance + CListener* pListener = new CListener( + uPort, sListenHost, sURIPrefix, bSSL, + (!bIPv6 ? ADDR_IPV4ONLY : ADDR_ALL), CListener::ACCEPT_HTTP); - if (!pListener->Listen()) { - sMessage = "Failed to add backwards-compatible listener"; - return false; - } - CZNC::Get().AddListener(pListener); + if (!pListener->Listen()) { + sMessage = "Failed to add backwards-compatible listener"; + return false; + } + CZNC::Get().AddListener(pListener); - SetArgs(""); - return true; - } + SetArgs(""); + return true; + } - CUser* GetNewUser(CWebSock& WebSock, CUser* pUser) { - std::shared_ptr spSession = WebSock.GetSession(); - CString sUsername = WebSock.GetParam("newuser"); + CUser* GetNewUser(CWebSock& WebSock, CUser* pUser) { + std::shared_ptr spSession = WebSock.GetSession(); + CString sUsername = WebSock.GetParam("newuser"); - if (sUsername.empty()) { - sUsername = WebSock.GetParam("user"); - } + if (sUsername.empty()) { + sUsername = WebSock.GetParam("user"); + } - if (sUsername.empty()) { - WebSock.PrintErrorPage("Invalid Submission [Username is required]"); - return nullptr; - } + if (sUsername.empty()) { + WebSock.PrintErrorPage("Invalid Submission [Username is required]"); + return nullptr; + } - if (pUser) { - /* If we are editing a user we must not change the user name */ - sUsername = pUser->GetUserName(); - } + if (pUser) { + /* If we are editing a user we must not change the user name */ + sUsername = pUser->GetUserName(); + } - CString sArg = WebSock.GetParam("password"); + CString sArg = WebSock.GetParam("password"); - if (sArg != WebSock.GetParam("password2")) { - WebSock.PrintErrorPage( - "Invalid Submission [Passwords do not match]"); - return nullptr; - } + if (sArg != WebSock.GetParam("password2")) { + WebSock.PrintErrorPage( + "Invalid Submission [Passwords do not match]"); + return nullptr; + } - CUser* pNewUser = new CUser(sUsername); + CUser* pNewUser = new CUser(sUsername); - if (!sArg.empty()) { - CString sSalt = CUtils::GetSalt(); - CString sHash = CUser::SaltedHash(sArg, sSalt); - pNewUser->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); - } + if (!sArg.empty()) { + CString sSalt = CUtils::GetSalt(); + CString sHash = CUser::SaltedHash(sArg, sSalt); + pNewUser->SetPass(sHash, CUser::HASH_DEFAULT, sSalt); + } - VCString vsArgs; + VCString vsArgs; - WebSock.GetRawParam("allowedips").Split("\n", vsArgs); - if (vsArgs.size()) { - for (const CString& sHost : vsArgs) { - pNewUser->AddAllowedHost(sHost.Trim_n()); - } - } else { - pNewUser->AddAllowedHost("*"); - } + WebSock.GetRawParam("allowedips").Split("\n", vsArgs); + if (vsArgs.size()) { + for (const CString& sHost : vsArgs) { + pNewUser->AddAllowedHost(sHost.Trim_n()); + } + } else { + pNewUser->AddAllowedHost("*"); + } - WebSock.GetRawParam("ctcpreplies").Split("\n", vsArgs); - for (const CString& sReply : vsArgs) { - pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(), - sReply.Token(1, true).Trim_n()); - } + WebSock.GetRawParam("ctcpreplies").Split("\n", vsArgs); + for (const CString& sReply : vsArgs) { + pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(), + sReply.Token(1, true).Trim_n()); + } - sArg = WebSock.GetParam("nick"); - if (!sArg.empty()) { - pNewUser->SetNick(sArg); - } - sArg = WebSock.GetParam("altnick"); - if (!sArg.empty()) { - pNewUser->SetAltNick(sArg); - } - sArg = WebSock.GetParam("statusprefix"); - if (!sArg.empty()) { - pNewUser->SetStatusPrefix(sArg); - } - sArg = WebSock.GetParam("ident"); - if (!sArg.empty()) { - pNewUser->SetIdent(sArg); - } - sArg = WebSock.GetParam("realname"); - if (!sArg.empty()) { - pNewUser->SetRealName(sArg); - } - sArg = WebSock.GetParam("quitmsg"); - if (!sArg.empty()) { - pNewUser->SetQuitMsg(sArg); - } - sArg = WebSock.GetParam("chanmodes"); - if (!sArg.empty()) { - pNewUser->SetDefaultChanModes(sArg); - } - sArg = WebSock.GetParam("timestampformat"); - if (!sArg.empty()) { - pNewUser->SetTimestampFormat(sArg); - } + sArg = WebSock.GetParam("nick"); + if (!sArg.empty()) { + pNewUser->SetNick(sArg); + } + sArg = WebSock.GetParam("altnick"); + if (!sArg.empty()) { + pNewUser->SetAltNick(sArg); + } + sArg = WebSock.GetParam("statusprefix"); + if (!sArg.empty()) { + pNewUser->SetStatusPrefix(sArg); + } + sArg = WebSock.GetParam("ident"); + if (!sArg.empty()) { + pNewUser->SetIdent(sArg); + } + sArg = WebSock.GetParam("realname"); + if (!sArg.empty()) { + pNewUser->SetRealName(sArg); + } + sArg = WebSock.GetParam("quitmsg"); + if (!sArg.empty()) { + pNewUser->SetQuitMsg(sArg); + } + sArg = WebSock.GetParam("chanmodes"); + if (!sArg.empty()) { + pNewUser->SetDefaultChanModes(sArg); + } + sArg = WebSock.GetParam("timestampformat"); + if (!sArg.empty()) { + pNewUser->SetTimestampFormat(sArg); + } - sArg = WebSock.GetParam("bindhost"); - // To change BindHosts be admin or don't have DenySetBindHost - if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) { - CString sArg2 = WebSock.GetParam("dccbindhost"); - if (!sArg.empty()) { - pNewUser->SetBindHost(sArg); - } - if (!sArg2.empty()) { - pNewUser->SetDCCBindHost(sArg2); - } - } else if (pUser) { - pNewUser->SetBindHost(pUser->GetBindHost()); - pNewUser->SetDCCBindHost(pUser->GetDCCBindHost()); - } + sArg = WebSock.GetParam("bindhost"); + // To change BindHosts be admin or don't have DenySetBindHost + if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) { + CString sArg2 = WebSock.GetParam("dccbindhost"); + if (!sArg.empty()) { + pNewUser->SetBindHost(sArg); + } + if (!sArg2.empty()) { + pNewUser->SetDCCBindHost(sArg2); + } + } else if (pUser) { + pNewUser->SetBindHost(pUser->GetBindHost()); + pNewUser->SetDCCBindHost(pUser->GetDCCBindHost()); + } - sArg = WebSock.GetParam("chanbufsize"); - if (!sArg.empty()) { - // First apply the old limit in case the new one is too high - if (pUser) - pNewUser->SetChanBufferSize(pUser->GetChanBufferSize(), true); - pNewUser->SetChanBufferSize(sArg.ToUInt(), spSession->IsAdmin()); - } + sArg = WebSock.GetParam("chanbufsize"); + if (!sArg.empty()) { + // First apply the old limit in case the new one is too high + if (pUser) + pNewUser->SetChanBufferSize(pUser->GetChanBufferSize(), true); + pNewUser->SetChanBufferSize(sArg.ToUInt(), spSession->IsAdmin()); + } - sArg = WebSock.GetParam("querybufsize"); - if (!sArg.empty()) { - // First apply the old limit in case the new one is too high - if (pUser) - pNewUser->SetQueryBufferSize(pUser->GetQueryBufferSize(), true); - pNewUser->SetQueryBufferSize(sArg.ToUInt(), spSession->IsAdmin()); - } + sArg = WebSock.GetParam("querybufsize"); + if (!sArg.empty()) { + // First apply the old limit in case the new one is too high + if (pUser) + pNewUser->SetQueryBufferSize(pUser->GetQueryBufferSize(), true); + pNewUser->SetQueryBufferSize(sArg.ToUInt(), spSession->IsAdmin()); + } - pNewUser->SetSkinName(WebSock.GetParam("skin")); - pNewUser->SetAutoClearChanBuffer( - WebSock.GetParam("autoclearchanbuffer").ToBool()); - pNewUser->SetMultiClients(WebSock.GetParam("multiclients").ToBool()); - pNewUser->SetTimestampAppend( - WebSock.GetParam("appendtimestamp").ToBool()); - pNewUser->SetTimestampPrepend( - WebSock.GetParam("prependtimestamp").ToBool()); - pNewUser->SetTimezone(WebSock.GetParam("timezone")); - pNewUser->SetJoinTries(WebSock.GetParam("jointries").ToUInt()); - pNewUser->SetMaxJoins(WebSock.GetParam("maxjoins").ToUInt()); - pNewUser->SetAutoClearQueryBuffer( - WebSock.GetParam("autoclearquerybuffer").ToBool()); - pNewUser->SetMaxQueryBuffers( - WebSock.GetParam("maxquerybuffers").ToUInt()); + pNewUser->SetSkinName(WebSock.GetParam("skin")); + pNewUser->SetAutoClearChanBuffer( + WebSock.GetParam("autoclearchanbuffer").ToBool()); + pNewUser->SetMultiClients(WebSock.GetParam("multiclients").ToBool()); + pNewUser->SetTimestampAppend( + WebSock.GetParam("appendtimestamp").ToBool()); + pNewUser->SetTimestampPrepend( + WebSock.GetParam("prependtimestamp").ToBool()); + pNewUser->SetTimezone(WebSock.GetParam("timezone")); + pNewUser->SetJoinTries(WebSock.GetParam("jointries").ToUInt()); + pNewUser->SetMaxJoins(WebSock.GetParam("maxjoins").ToUInt()); + pNewUser->SetAutoClearQueryBuffer( + WebSock.GetParam("autoclearquerybuffer").ToBool()); + pNewUser->SetMaxQueryBuffers( + WebSock.GetParam("maxquerybuffers").ToUInt()); #ifdef HAVE_ICU - CString sEncodingUtf = WebSock.GetParam("encoding_utf"); - if (sEncodingUtf == "legacy") { - pNewUser->SetClientEncoding(""); - } - CString sEncoding = WebSock.GetParam("encoding"); - if (sEncoding.empty()) { - sEncoding = "UTF-8"; - } - if (sEncodingUtf == "send") { - pNewUser->SetClientEncoding("^" + sEncoding); - } else if (sEncodingUtf == "receive") { - pNewUser->SetClientEncoding("*" + sEncoding); - } else if (sEncodingUtf == "simple") { - pNewUser->SetClientEncoding(sEncoding); - } + CString sEncodingUtf = WebSock.GetParam("encoding_utf"); + if (sEncodingUtf == "legacy") { + pNewUser->SetClientEncoding(""); + } + CString sEncoding = WebSock.GetParam("encoding"); + if (sEncoding.empty()) { + sEncoding = "UTF-8"; + } + if (sEncodingUtf == "send") { + pNewUser->SetClientEncoding("^" + sEncoding); + } else if (sEncodingUtf == "receive") { + pNewUser->SetClientEncoding("*" + sEncoding); + } else if (sEncodingUtf == "simple") { + pNewUser->SetClientEncoding(sEncoding); + } #endif - if (spSession->IsAdmin()) { - pNewUser->SetDenyLoadMod(WebSock.GetParam("denyloadmod").ToBool()); - pNewUser->SetDenySetBindHost( - WebSock.GetParam("denysetbindhost").ToBool()); - sArg = WebSock.GetParam("maxnetworks"); - if (!sArg.empty()) pNewUser->SetMaxNetworks(sArg.ToUInt()); - } else if (pUser) { - pNewUser->SetDenyLoadMod(pUser->DenyLoadMod()); - pNewUser->SetDenySetBindHost(pUser->DenySetBindHost()); - pNewUser->SetMaxNetworks(pUser->MaxNetworks()); - } - - // If pUser is not nullptr, we are editing an existing user. - // Users must not be able to change their own admin flag. - if (pUser != CZNC::Get().FindUser(WebSock.GetUser())) { - pNewUser->SetAdmin(WebSock.GetParam("isadmin").ToBool()); - } else if (pUser) { - pNewUser->SetAdmin(pUser->IsAdmin()); - } - - if (spSession->IsAdmin() || (pUser && !pUser->DenyLoadMod())) { - WebSock.GetParamValues("loadmod", vsArgs); - - // disallow unload webadmin from itself - if (CModInfo::UserModule == GetType() && - pUser == CZNC::Get().FindUser(WebSock.GetUser())) { - bool bLoadedWebadmin = false; - for (const CString& s : vsArgs) { - CString sModName = s.TrimRight_n("\r"); - if (sModName == GetModName()) { - bLoadedWebadmin = true; - break; - } - } - if (!bLoadedWebadmin) { - vsArgs.push_back(GetModName()); - } - } - - for (const CString& s : vsArgs) { - CString sModRet; - CString sModName = s.TrimRight_n("\r"); - CString sModLoadError; - - if (!sModName.empty()) { - CString sArgs = WebSock.GetParam("modargs_" + sModName); - - try { - if (!pNewUser->GetModules().LoadModule( - sModName, sArgs, CModInfo::UserModule, pNewUser, - nullptr, sModRet)) { - sModLoadError = "Unable to load module [" + - sModName + "] [" + sModRet + "]"; - } - } catch (...) { - sModLoadError = "Unable to load module [" + sModName + - "] [" + sArgs + "]"; - } - - if (!sModLoadError.empty()) { - DEBUG(sModLoadError); - spSession->AddError(sModLoadError); - } - } - } - } else if (pUser) { - CModules& Modules = pUser->GetModules(); - - for (const CModule* pMod : Modules) { - CString sModName = pMod->GetModName(); - CString sArgs = pMod->GetArgs(); - CString sModRet; - CString sModLoadError; - - try { - if (!pNewUser->GetModules().LoadModule( - sModName, sArgs, CModInfo::UserModule, pNewUser, - nullptr, sModRet)) { - sModLoadError = "Unable to load module [" + sModName + - "] [" + sModRet + "]"; - } - } catch (...) { - sModLoadError = "Unable to load module [" + sModName + "]"; - } - - if (!sModLoadError.empty()) { - DEBUG(sModLoadError); - spSession->AddError(sModLoadError); - } - } - } - - return pNewUser; - } - - CString SafeGetUserNameParam(CWebSock& WebSock) { - CString sUserName = WebSock.GetParam("user"); // check for POST param - if (sUserName.empty() && !WebSock.IsPost()) { - // if no POST param named user has been given and we are not - // saving this form, fall back to using the GET parameter. - sUserName = WebSock.GetParam("user", false); - } - return sUserName; - } - - CString SafeGetNetworkParam(CWebSock& WebSock) { - CString sNetwork = WebSock.GetParam("network"); // check for POST param - if (sNetwork.empty() && !WebSock.IsPost()) { - // if no POST param named user has been given and we are not - // saving this form, fall back to using the GET parameter. - sNetwork = WebSock.GetParam("network", false); - } - return sNetwork; - } - - CUser* SafeGetUserFromParam(CWebSock& WebSock) { - return CZNC::Get().FindUser(SafeGetUserNameParam(WebSock)); - } - - CIRCNetwork* SafeGetNetworkFromParam(CWebSock& WebSock) { - CUser* pUser = CZNC::Get().FindUser(SafeGetUserNameParam(WebSock)); - CIRCNetwork* pNetwork = nullptr; - - if (pUser) { - pNetwork = pUser->FindNetwork(SafeGetNetworkParam(WebSock)); - } - - return pNetwork; - } - - CString GetWebMenuTitle() override { return "webadmin"; } - bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, - CTemplate& Tmpl) override { - std::shared_ptr spSession = WebSock.GetSession(); - - if (sPageName == "settings") { - // Admin Check - if (!spSession->IsAdmin()) { - return false; - } - - return SettingsPage(WebSock, Tmpl); - } else if (sPageName == "adduser") { - // Admin Check - if (!spSession->IsAdmin()) { - return false; - } - - return UserPage(WebSock, Tmpl); - } else if (sPageName == "addnetwork") { - CUser* pUser = SafeGetUserFromParam(WebSock); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || spSession->GetUser() != pUser)) { - return false; - } - - if (pUser) { - return NetworkPage(WebSock, Tmpl, pUser); - } - - WebSock.PrintErrorPage("No such username"); - return true; - } else if (sPageName == "editnetwork") { - CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || !pNetwork || - spSession->GetUser() != pNetwork->GetUser())) { - return false; - } - - if (!pNetwork) { - WebSock.PrintErrorPage("No such username or network"); - return true; - } - - return NetworkPage(WebSock, Tmpl, pNetwork->GetUser(), pNetwork); - - } else if (sPageName == "delnetwork") { - CString sUser = WebSock.GetParam("user"); - if (sUser.empty() && !WebSock.IsPost()) { - sUser = WebSock.GetParam("user", false); - } - - CUser* pUser = CZNC::Get().FindUser(sUser); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || spSession->GetUser() != pUser)) { - return false; - } - - return DelNetwork(WebSock, pUser, Tmpl); - } else if (sPageName == "editchan") { - CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || !pNetwork || - spSession->GetUser() != pNetwork->GetUser())) { - return false; - } - - if (!pNetwork) { - WebSock.PrintErrorPage("No such username or network"); - return true; - } - - CString sChan = WebSock.GetParam("name"); - if (sChan.empty() && !WebSock.IsPost()) { - sChan = WebSock.GetParam("name", false); - } - CChan* pChan = pNetwork->FindChan(sChan); - if (!pChan) { - WebSock.PrintErrorPage("No such channel"); - return true; - } - - return ChanPage(WebSock, Tmpl, pNetwork, pChan); - } else if (sPageName == "addchan") { - CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || !pNetwork || - spSession->GetUser() != pNetwork->GetUser())) { - return false; - } - - if (pNetwork) { - return ChanPage(WebSock, Tmpl, pNetwork); - } - - WebSock.PrintErrorPage("No such username or network"); - return true; - } else if (sPageName == "delchan") { - CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || !pNetwork || - spSession->GetUser() != pNetwork->GetUser())) { - return false; - } - - if (pNetwork) { - return DelChan(WebSock, pNetwork); - } - - WebSock.PrintErrorPage("No such username or network"); - return true; - } else if (sPageName == "deluser") { - if (!spSession->IsAdmin()) { - return false; - } - - if (!WebSock.IsPost()) { - // Show the "Are you sure?" page: - - CString sUser = WebSock.GetParam("user", false); - CUser* pUser = CZNC::Get().FindUser(sUser); - - if (!pUser) { - WebSock.PrintErrorPage("No such username"); - return true; - } - - Tmpl.SetFile("del_user.tmpl"); - Tmpl["Username"] = sUser; - return true; - } - - // The "Are you sure?" page has been submitted with "Yes", - // so we actually delete the user now: - - CString sUser = WebSock.GetParam("user"); - CUser* pUser = CZNC::Get().FindUser(sUser); - - if (pUser && pUser == spSession->GetUser()) { - WebSock.PrintErrorPage( - "Please don't delete yourself, suicide is not the answer!"); - return true; - } else if (CZNC::Get().DeleteUser(sUser)) { - WebSock.Redirect(GetWebPath() + "listusers"); - return true; - } - - WebSock.PrintErrorPage("No such username"); - return true; - } else if (sPageName == "edituser") { - CString sUserName = SafeGetUserNameParam(WebSock); - CUser* pUser = CZNC::Get().FindUser(sUserName); - - if (!pUser) { - if (sUserName.empty()) { - pUser = spSession->GetUser(); - } // else: the "no such user" message will be printed. - } - - // Admin||Self Check - if (!spSession->IsAdmin() && - (!spSession->GetUser() || spSession->GetUser() != pUser)) { - return false; - } - - if (pUser) { - return UserPage(WebSock, Tmpl, pUser); - } - - WebSock.PrintErrorPage("No such username"); - return true; - } else if (sPageName == "listusers" && spSession->IsAdmin()) { - return ListUsersPage(WebSock, Tmpl); - } else if (sPageName == "traffic") { - return TrafficPage(WebSock, Tmpl); - } else if (sPageName == "index") { - return true; - } else if (sPageName == "add_listener") { - // Admin Check - if (!spSession->IsAdmin()) { - return false; - } - - return AddListener(WebSock, Tmpl); - } else if (sPageName == "del_listener") { - // Admin Check - if (!spSession->IsAdmin()) { - return false; - } - - return DelListener(WebSock, Tmpl); - } - - return false; - } - - bool ChanPage(CWebSock& WebSock, CTemplate& Tmpl, CIRCNetwork* pNetwork, - CChan* pChan = nullptr) { - std::shared_ptr spSession = WebSock.GetSession(); - Tmpl.SetFile("add_edit_chan.tmpl"); - CUser* pUser = pNetwork->GetUser(); - - if (!pUser) { - WebSock.PrintErrorPage("That user doesn't exist"); - return true; - } - - if (!WebSock.GetParam("submitted").ToUInt()) { - Tmpl["User"] = pUser->GetUserName(); - Tmpl["Network"] = pNetwork->GetName(); - - CTemplate& breadUser = Tmpl.AddRow("BreadCrumbs"); - breadUser["Text"] = "Edit User [" + pUser->GetUserName() + "]"; - breadUser["URL"] = - GetWebPath() + "edituser?user=" + pUser->GetUserName(); - CTemplate& breadNet = Tmpl.AddRow("BreadCrumbs"); - breadNet["Text"] = "Edit Network [" + pNetwork->GetName() + "]"; - breadNet["URL"] = GetWebPath() + "editnetwork?user=" + - pUser->GetUserName() + "&network=" + - pNetwork->GetName(); - CTemplate& breadChan = Tmpl.AddRow("BreadCrumbs"); - - if (pChan) { - Tmpl["Action"] = "editchan"; - Tmpl["Edit"] = "true"; - Tmpl["Title"] = - "Edit Channel" + CString(" [" + pChan->GetName() + "]") + - " of Network [" + pNetwork->GetName() + "] of User [" + - pNetwork->GetUser()->GetUserName() + "]"; - Tmpl["ChanName"] = pChan->GetName(); - Tmpl["BufferSize"] = CString(pChan->GetBufferCount()); - Tmpl["DefModes"] = pChan->GetDefaultModes(); - Tmpl["Key"] = pChan->GetKey(); - breadChan["Text"] = "Edit Channel [" + pChan->GetName() + "]"; - - if (pChan->InConfig()) { - Tmpl["InConfig"] = "true"; - } - } else { - Tmpl["Action"] = "addchan"; - Tmpl["Title"] = - "Add Channel" + - CString(" for User [" + pUser->GetUserName() + "]"); - Tmpl["BufferSize"] = CString(pUser->GetBufferCount()); - Tmpl["DefModes"] = CString(pUser->GetDefaultChanModes()); - Tmpl["InConfig"] = "true"; - breadChan["Text"] = "Add Channel"; - } - - // o1 used to be AutoCycle which was removed - - CTemplate& o2 = Tmpl.AddRow("OptionLoop"); - o2["Name"] = "autoclearchanbuffer"; - o2["DisplayName"] = "Auto Clear Chan Buffer"; - o2["Tooltip"] = "Automatically Clear Channel Buffer After Playback"; - if ((pChan && pChan->AutoClearChanBuffer()) || - (!pChan && pUser->AutoClearChanBuffer())) { - o2["Checked"] = "true"; - } - - CTemplate& o3 = Tmpl.AddRow("OptionLoop"); - o3["Name"] = "detached"; - o3["DisplayName"] = "Detached"; - if (pChan && pChan->IsDetached()) { - o3["Checked"] = "true"; - } - - CTemplate& o4 = Tmpl.AddRow("OptionLoop"); - o4["Name"] = "disabled"; - o4["DisplayName"] = "Disabled"; - if (pChan && pChan->IsDisabled()) { - o4["Checked"] = "true"; - } - - FOR_EACH_MODULE(i, pNetwork) { - CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); - mod.insert(Tmpl.begin(), Tmpl.end()); - mod["WebadminAction"] = "display"; - if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/channel", - mod)) { - mod["Embed"] = WebSock.FindTmpl(*i, "WebadminChan.tmpl"); - mod["ModName"] = (*i)->GetModName(); - } - } - - return true; - } - - CString sChanName = WebSock.GetParam("name").Trim_n(); - - if (!pChan) { - if (sChanName.empty()) { - WebSock.PrintErrorPage("Channel name is a required argument"); - return true; - } - - // This could change the channel name and e.g. add a "#" prefix - pChan = new CChan(sChanName, pNetwork, true); - - if (pNetwork->FindChan(pChan->GetName())) { - WebSock.PrintErrorPage("Channel [" + pChan->GetName() + - "] already exists"); - delete pChan; - return true; - } - - if (!pNetwork->AddChan(pChan)) { - WebSock.PrintErrorPage("Could not add channel [" + sChanName + - "]"); - return true; - } - } - - if (WebSock.GetParam("buffersize").empty()) { - pChan->ResetBufferCount(); - } else { - unsigned int uBufferSize = WebSock.GetParam("buffersize").ToUInt(); - if (pChan->GetBufferCount() != uBufferSize) { - pChan->SetBufferCount(uBufferSize, spSession->IsAdmin()); - } - } - pChan->SetDefaultModes(WebSock.GetParam("defmodes")); - pChan->SetInConfig(WebSock.GetParam("save").ToBool()); - bool bAutoClearChanBuffer = - WebSock.GetParam("autoclearchanbuffer").ToBool(); - if (pChan->AutoClearChanBuffer() != bAutoClearChanBuffer) { - pChan->SetAutoClearChanBuffer( - WebSock.GetParam("autoclearchanbuffer").ToBool()); - } - pChan->SetKey(WebSock.GetParam("key")); - - bool bDetached = WebSock.GetParam("detached").ToBool(); - if (pChan->IsDetached() != bDetached) { - if (bDetached) { - pChan->DetachUser(); - } else { - pChan->AttachUser(); - } - } - - bool bDisabled = WebSock.GetParam("disabled").ToBool(); - if (bDisabled) - pChan->Disable(); - else - pChan->Enable(); - - CTemplate TmplMod; - TmplMod["User"] = pUser->GetUserName(); - TmplMod["ChanName"] = pChan->GetName(); - TmplMod["WebadminAction"] = "change"; - FOR_EACH_MODULE(it, pNetwork) { - (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/channel", TmplMod); - } - - if (!CZNC::Get().WriteConfig()) { - WebSock.PrintErrorPage( - "Channel added/modified, but config was not written"); - return true; - } - - if (WebSock.HasParam("submit_return")) { - WebSock.Redirect(GetWebPath() + "editnetwork?user=" + - pUser->GetUserName().Escape_n(CString::EURL) + - "&network=" + - pNetwork->GetName().Escape_n(CString::EURL)); - } else { - WebSock.Redirect( - GetWebPath() + "editchan?user=" + - pUser->GetUserName().Escape_n(CString::EURL) + "&network=" + - pNetwork->GetName().Escape_n(CString::EURL) + "&name=" + - pChan->GetName().Escape_n(CString::EURL)); - } - return true; - } - - bool NetworkPage(CWebSock& WebSock, CTemplate& Tmpl, CUser* pUser, - CIRCNetwork* pNetwork = nullptr) { - std::shared_ptr spSession = WebSock.GetSession(); - Tmpl.SetFile("add_edit_network.tmpl"); - - if (!WebSock.GetParam("submitted").ToUInt()) { - Tmpl["Username"] = pUser->GetUserName(); - - set ssNetworkMods; - CZNC::Get().GetModules().GetAvailableMods(ssNetworkMods, - CModInfo::NetworkModule); - for (const CModInfo& Info : ssNetworkMods) { - CTemplate& l = Tmpl.AddRow("ModuleLoop"); - - l["Name"] = Info.GetName(); - l["Description"] = Info.GetDescription(); - l["Wiki"] = Info.GetWikiPage(); - l["HasArgs"] = CString(Info.GetHasArgs()); - l["ArgsHelpText"] = Info.GetArgsHelpText(); - - if (pNetwork) { - CModule* pModule = - pNetwork->GetModules().FindModule(Info.GetName()); - if (pModule) { - l["Checked"] = "true"; - l["Args"] = pModule->GetArgs(); - } - } - - // Check if module is loaded globally - l["CanBeLoadedGlobally"] = - CString(Info.SupportsType(CModInfo::GlobalModule)); - l["LoadedGlobally"] = - CString(CZNC::Get().GetModules().FindModule( - Info.GetName()) != nullptr); - - // Check if module is loaded by user - l["CanBeLoadedByUser"] = - CString(Info.SupportsType(CModInfo::UserModule)); - l["LoadedByUser"] = CString( - pUser->GetModules().FindModule(Info.GetName()) != nullptr); - - if (!spSession->IsAdmin() && pUser->DenyLoadMod()) { - l["Disabled"] = "true"; - } - } - - // To change BindHosts be admin or don't have DenySetBindHost - if (spSession->IsAdmin() || - !spSession->GetUser()->DenySetBindHost()) { - Tmpl["BindHostEdit"] = "true"; - if (pNetwork) { - Tmpl["BindHost"] = pNetwork->GetBindHost(); - } - } - - CTemplate& breadUser = Tmpl.AddRow("BreadCrumbs"); - breadUser["Text"] = "Edit User [" + pUser->GetUserName() + "]"; - breadUser["URL"] = - GetWebPath() + "edituser?user=" + pUser->GetUserName(); - CTemplate& breadNet = Tmpl.AddRow("BreadCrumbs"); - - if (pNetwork) { - Tmpl["Action"] = "editnetwork"; - Tmpl["Edit"] = "true"; - Tmpl["Title"] = "Edit Network" + - CString(" [" + pNetwork->GetName() + "]") + - " of User [" + pUser->GetUserName() + "]"; - Tmpl["Name"] = pNetwork->GetName(); - - Tmpl["Nick"] = pNetwork->GetNick(); - Tmpl["AltNick"] = pNetwork->GetAltNick(); - Tmpl["Ident"] = pNetwork->GetIdent(); - Tmpl["RealName"] = pNetwork->GetRealName(); - - Tmpl["QuitMsg"] = pNetwork->GetQuitMsg(); - - Tmpl["FloodProtection"] = CString( - CIRCSock::IsFloodProtected(pNetwork->GetFloodRate())); - Tmpl["FloodRate"] = CString(pNetwork->GetFloodRate()); - Tmpl["FloodBurst"] = CString(pNetwork->GetFloodBurst()); - - Tmpl["JoinDelay"] = CString(pNetwork->GetJoinDelay()); - - Tmpl["IRCConnectEnabled"] = - CString(pNetwork->GetIRCConnectEnabled()); - - breadNet["Text"] = "Edit Network [" + pNetwork->GetName() + "]"; - - const vector& vServers = pNetwork->GetServers(); - for (const CServer* pServer : vServers) { - CTemplate& l = Tmpl.AddRow("ServerLoop"); - l["Server"] = pServer->GetString(); - } - - const vector& Channels = pNetwork->GetChans(); - for (const CChan* pChan : Channels) { - CTemplate& l = Tmpl.AddRow("ChannelLoop"); - - l["Network"] = pNetwork->GetName(); - l["Username"] = pUser->GetUserName(); - l["Name"] = pChan->GetName(); - l["Perms"] = pChan->GetPermStr(); - l["CurModes"] = pChan->GetModeString(); - l["DefModes"] = pChan->GetDefaultModes(); - if (pChan->HasBufferCountSet()) { - l["BufferSize"] = CString(pChan->GetBufferCount()); - } else { - l["BufferSize"] = - CString(pChan->GetBufferCount()) + " (default)"; - } - l["Options"] = pChan->GetOptions(); - - if (pChan->InConfig()) { - l["InConfig"] = "true"; - } - } - for (const CString& sFP : pNetwork->GetTrustedFingerprints()) { - CTemplate& l = Tmpl.AddRow("TrustedFingerprints"); - l["FP"] = sFP; - } - } else { - if (!spSession->IsAdmin() && !pUser->HasSpaceForNewNetwork()) { - WebSock.PrintErrorPage( - "Network number limit reached. Ask an admin to " - "increase the limit for you, or delete unneeded " - "networks from Your Settings."); - return true; - } - - Tmpl["Action"] = "addnetwork"; - Tmpl["Title"] = - "Add Network for User [" + pUser->GetUserName() + "]"; - Tmpl["IRCConnectEnabled"] = "true"; - Tmpl["FloodProtection"] = "true"; - Tmpl["FloodRate"] = "1.0"; - Tmpl["FloodBurst"] = "4"; - Tmpl["JoinDelay"] = "0"; - breadNet["Text"] = "Add Network"; - } - - FOR_EACH_MODULE(i, make_pair(pUser, pNetwork)) { - CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); - mod.insert(Tmpl.begin(), Tmpl.end()); - mod["WebadminAction"] = "display"; - if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/network", - mod)) { - mod["Embed"] = WebSock.FindTmpl(*i, "WebadminNetwork.tmpl"); - mod["ModName"] = (*i)->GetModName(); - } - } + if (spSession->IsAdmin()) { + pNewUser->SetDenyLoadMod(WebSock.GetParam("denyloadmod").ToBool()); + pNewUser->SetDenySetBindHost( + WebSock.GetParam("denysetbindhost").ToBool()); + sArg = WebSock.GetParam("maxnetworks"); + if (!sArg.empty()) pNewUser->SetMaxNetworks(sArg.ToUInt()); + } else if (pUser) { + pNewUser->SetDenyLoadMod(pUser->DenyLoadMod()); + pNewUser->SetDenySetBindHost(pUser->DenySetBindHost()); + pNewUser->SetMaxNetworks(pUser->MaxNetworks()); + } + + // If pUser is not nullptr, we are editing an existing user. + // Users must not be able to change their own admin flag. + if (pUser != CZNC::Get().FindUser(WebSock.GetUser())) { + pNewUser->SetAdmin(WebSock.GetParam("isadmin").ToBool()); + } else if (pUser) { + pNewUser->SetAdmin(pUser->IsAdmin()); + } + + if (spSession->IsAdmin() || (pUser && !pUser->DenyLoadMod())) { + WebSock.GetParamValues("loadmod", vsArgs); + + // disallow unload webadmin from itself + if (CModInfo::UserModule == GetType() && + pUser == CZNC::Get().FindUser(WebSock.GetUser())) { + bool bLoadedWebadmin = false; + for (const CString& s : vsArgs) { + CString sModName = s.TrimRight_n("\r"); + if (sModName == GetModName()) { + bLoadedWebadmin = true; + break; + } + } + if (!bLoadedWebadmin) { + vsArgs.push_back(GetModName()); + } + } + + for (const CString& s : vsArgs) { + CString sModRet; + CString sModName = s.TrimRight_n("\r"); + CString sModLoadError; + + if (!sModName.empty()) { + CString sArgs = WebSock.GetParam("modargs_" + sModName); + + try { + if (!pNewUser->GetModules().LoadModule( + sModName, sArgs, CModInfo::UserModule, pNewUser, + nullptr, sModRet)) { + sModLoadError = "Unable to load module [" + + sModName + "] [" + sModRet + "]"; + } + } catch (...) { + sModLoadError = "Unable to load module [" + sModName + + "] [" + sArgs + "]"; + } + + if (!sModLoadError.empty()) { + DEBUG(sModLoadError); + spSession->AddError(sModLoadError); + } + } + } + } else if (pUser) { + CModules& Modules = pUser->GetModules(); + + for (const CModule* pMod : Modules) { + CString sModName = pMod->GetModName(); + CString sArgs = pMod->GetArgs(); + CString sModRet; + CString sModLoadError; + + try { + if (!pNewUser->GetModules().LoadModule( + sModName, sArgs, CModInfo::UserModule, pNewUser, + nullptr, sModRet)) { + sModLoadError = "Unable to load module [" + sModName + + "] [" + sModRet + "]"; + } + } catch (...) { + sModLoadError = "Unable to load module [" + sModName + "]"; + } + + if (!sModLoadError.empty()) { + DEBUG(sModLoadError); + spSession->AddError(sModLoadError); + } + } + } + + return pNewUser; + } + + CString SafeGetUserNameParam(CWebSock& WebSock) { + CString sUserName = WebSock.GetParam("user"); // check for POST param + if (sUserName.empty() && !WebSock.IsPost()) { + // if no POST param named user has been given and we are not + // saving this form, fall back to using the GET parameter. + sUserName = WebSock.GetParam("user", false); + } + return sUserName; + } + + CString SafeGetNetworkParam(CWebSock& WebSock) { + CString sNetwork = WebSock.GetParam("network"); // check for POST param + if (sNetwork.empty() && !WebSock.IsPost()) { + // if no POST param named user has been given and we are not + // saving this form, fall back to using the GET parameter. + sNetwork = WebSock.GetParam("network", false); + } + return sNetwork; + } + + CUser* SafeGetUserFromParam(CWebSock& WebSock) { + return CZNC::Get().FindUser(SafeGetUserNameParam(WebSock)); + } + + CIRCNetwork* SafeGetNetworkFromParam(CWebSock& WebSock) { + CUser* pUser = CZNC::Get().FindUser(SafeGetUserNameParam(WebSock)); + CIRCNetwork* pNetwork = nullptr; + + if (pUser) { + pNetwork = pUser->FindNetwork(SafeGetNetworkParam(WebSock)); + } + + return pNetwork; + } + + CString GetWebMenuTitle() override { return "webadmin"; } + bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, + CTemplate& Tmpl) override { + std::shared_ptr spSession = WebSock.GetSession(); + + if (sPageName == "settings") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return SettingsPage(WebSock, Tmpl); + } else if (sPageName == "adduser") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return UserPage(WebSock, Tmpl); + } else if (sPageName == "addnetwork") { + CUser* pUser = SafeGetUserFromParam(WebSock); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || spSession->GetUser() != pUser)) { + return false; + } + + if (pUser) { + return NetworkPage(WebSock, Tmpl, pUser); + } + + WebSock.PrintErrorPage("No such username"); + return true; + } else if (sPageName == "editnetwork") { + CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || !pNetwork || + spSession->GetUser() != pNetwork->GetUser())) { + return false; + } + + if (!pNetwork) { + WebSock.PrintErrorPage("No such username or network"); + return true; + } + + return NetworkPage(WebSock, Tmpl, pNetwork->GetUser(), pNetwork); + + } else if (sPageName == "delnetwork") { + CString sUser = WebSock.GetParam("user"); + if (sUser.empty() && !WebSock.IsPost()) { + sUser = WebSock.GetParam("user", false); + } + + CUser* pUser = CZNC::Get().FindUser(sUser); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || spSession->GetUser() != pUser)) { + return false; + } + + return DelNetwork(WebSock, pUser, Tmpl); + } else if (sPageName == "editchan") { + CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || !pNetwork || + spSession->GetUser() != pNetwork->GetUser())) { + return false; + } + + if (!pNetwork) { + WebSock.PrintErrorPage("No such username or network"); + return true; + } + + CString sChan = WebSock.GetParam("name"); + if (sChan.empty() && !WebSock.IsPost()) { + sChan = WebSock.GetParam("name", false); + } + CChan* pChan = pNetwork->FindChan(sChan); + if (!pChan) { + WebSock.PrintErrorPage("No such channel"); + return true; + } + + return ChanPage(WebSock, Tmpl, pNetwork, pChan); + } else if (sPageName == "addchan") { + CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || !pNetwork || + spSession->GetUser() != pNetwork->GetUser())) { + return false; + } + + if (pNetwork) { + return ChanPage(WebSock, Tmpl, pNetwork); + } + + WebSock.PrintErrorPage("No such username or network"); + return true; + } else if (sPageName == "delchan") { + CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock); + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || !pNetwork || + spSession->GetUser() != pNetwork->GetUser())) { + return false; + } + + if (pNetwork) { + return DelChan(WebSock, pNetwork); + } + + WebSock.PrintErrorPage("No such username or network"); + return true; + } else if (sPageName == "deluser") { + if (!spSession->IsAdmin()) { + return false; + } + + if (!WebSock.IsPost()) { + // Show the "Are you sure?" page: + + CString sUser = WebSock.GetParam("user", false); + CUser* pUser = CZNC::Get().FindUser(sUser); + + if (!pUser) { + WebSock.PrintErrorPage("No such username"); + return true; + } + + Tmpl.SetFile("del_user.tmpl"); + Tmpl["Username"] = sUser; + return true; + } + + // The "Are you sure?" page has been submitted with "Yes", + // so we actually delete the user now: + + CString sUser = WebSock.GetParam("user"); + CUser* pUser = CZNC::Get().FindUser(sUser); + + if (pUser && pUser == spSession->GetUser()) { + WebSock.PrintErrorPage( + "Please don't delete yourself, suicide is not the answer!"); + return true; + } else if (CZNC::Get().DeleteUser(sUser)) { + WebSock.Redirect(GetWebPath() + "listusers"); + return true; + } + + WebSock.PrintErrorPage("No such username"); + return true; + } else if (sPageName == "edituser") { + CString sUserName = SafeGetUserNameParam(WebSock); + CUser* pUser = CZNC::Get().FindUser(sUserName); + + if (!pUser) { + if (sUserName.empty()) { + pUser = spSession->GetUser(); + } // else: the "no such user" message will be printed. + } + + // Admin||Self Check + if (!spSession->IsAdmin() && + (!spSession->GetUser() || spSession->GetUser() != pUser)) { + return false; + } + + if (pUser) { + return UserPage(WebSock, Tmpl, pUser); + } + + WebSock.PrintErrorPage("No such username"); + return true; + } else if (sPageName == "listusers" && spSession->IsAdmin()) { + return ListUsersPage(WebSock, Tmpl); + } else if (sPageName == "traffic") { + return TrafficPage(WebSock, Tmpl); + } else if (sPageName == "index") { + return true; + } else if (sPageName == "add_listener") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return AddListener(WebSock, Tmpl); + } else if (sPageName == "del_listener") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return DelListener(WebSock, Tmpl); + } + + return false; + } + + bool ChanPage(CWebSock& WebSock, CTemplate& Tmpl, CIRCNetwork* pNetwork, + CChan* pChan = nullptr) { + std::shared_ptr spSession = WebSock.GetSession(); + Tmpl.SetFile("add_edit_chan.tmpl"); + CUser* pUser = pNetwork->GetUser(); + + if (!pUser) { + WebSock.PrintErrorPage("That user doesn't exist"); + return true; + } + + if (!WebSock.GetParam("submitted").ToUInt()) { + Tmpl["User"] = pUser->GetUserName(); + Tmpl["Network"] = pNetwork->GetName(); + + CTemplate& breadUser = Tmpl.AddRow("BreadCrumbs"); + breadUser["Text"] = "Edit User [" + pUser->GetUserName() + "]"; + breadUser["URL"] = + GetWebPath() + "edituser?user=" + pUser->GetUserName(); + CTemplate& breadNet = Tmpl.AddRow("BreadCrumbs"); + breadNet["Text"] = "Edit Network [" + pNetwork->GetName() + "]"; + breadNet["URL"] = GetWebPath() + "editnetwork?user=" + + pUser->GetUserName() + "&network=" + + pNetwork->GetName(); + CTemplate& breadChan = Tmpl.AddRow("BreadCrumbs"); + + if (pChan) { + Tmpl["Action"] = "editchan"; + Tmpl["Edit"] = "true"; + Tmpl["Title"] = + "Edit Channel" + CString(" [" + pChan->GetName() + "]") + + " of Network [" + pNetwork->GetName() + "] of User [" + + pNetwork->GetUser()->GetUserName() + "]"; + Tmpl["ChanName"] = pChan->GetName(); + Tmpl["BufferSize"] = CString(pChan->GetBufferCount()); + Tmpl["DefModes"] = pChan->GetDefaultModes(); + Tmpl["Key"] = pChan->GetKey(); + breadChan["Text"] = "Edit Channel [" + pChan->GetName() + "]"; + + if (pChan->InConfig()) { + Tmpl["InConfig"] = "true"; + } + } else { + Tmpl["Action"] = "addchan"; + Tmpl["Title"] = + "Add Channel" + + CString(" for User [" + pUser->GetUserName() + "]"); + Tmpl["BufferSize"] = CString(pUser->GetBufferCount()); + Tmpl["DefModes"] = CString(pUser->GetDefaultChanModes()); + Tmpl["InConfig"] = "true"; + breadChan["Text"] = "Add Channel"; + } + + // o1 used to be AutoCycle which was removed + + CTemplate& o2 = Tmpl.AddRow("OptionLoop"); + o2["Name"] = "autoclearchanbuffer"; + o2["DisplayName"] = "Auto Clear Chan Buffer"; + o2["Tooltip"] = "Automatically Clear Channel Buffer After Playback"; + if ((pChan && pChan->AutoClearChanBuffer()) || + (!pChan && pUser->AutoClearChanBuffer())) { + o2["Checked"] = "true"; + } + + CTemplate& o3 = Tmpl.AddRow("OptionLoop"); + o3["Name"] = "detached"; + o3["DisplayName"] = "Detached"; + if (pChan && pChan->IsDetached()) { + o3["Checked"] = "true"; + } + + CTemplate& o4 = Tmpl.AddRow("OptionLoop"); + o4["Name"] = "disabled"; + o4["DisplayName"] = "Disabled"; + if (pChan && pChan->IsDisabled()) { + o4["Checked"] = "true"; + } + + FOR_EACH_MODULE(i, pNetwork) { + CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); + mod.insert(Tmpl.begin(), Tmpl.end()); + mod["WebadminAction"] = "display"; + if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/channel", + mod)) { + mod["Embed"] = WebSock.FindTmpl(*i, "WebadminChan.tmpl"); + mod["ModName"] = (*i)->GetModName(); + } + } + + return true; + } + + CString sChanName = WebSock.GetParam("name").Trim_n(); + + if (!pChan) { + if (sChanName.empty()) { + WebSock.PrintErrorPage("Channel name is a required argument"); + return true; + } + + // This could change the channel name and e.g. add a "#" prefix + pChan = new CChan(sChanName, pNetwork, true); + + if (pNetwork->FindChan(pChan->GetName())) { + WebSock.PrintErrorPage("Channel [" + pChan->GetName() + + "] already exists"); + delete pChan; + return true; + } + + if (!pNetwork->AddChan(pChan)) { + WebSock.PrintErrorPage("Could not add channel [" + sChanName + + "]"); + return true; + } + } + + if (WebSock.GetParam("buffersize").empty()) { + pChan->ResetBufferCount(); + } else { + unsigned int uBufferSize = WebSock.GetParam("buffersize").ToUInt(); + if (pChan->GetBufferCount() != uBufferSize) { + pChan->SetBufferCount(uBufferSize, spSession->IsAdmin()); + } + } + pChan->SetDefaultModes(WebSock.GetParam("defmodes")); + pChan->SetInConfig(WebSock.GetParam("save").ToBool()); + bool bAutoClearChanBuffer = + WebSock.GetParam("autoclearchanbuffer").ToBool(); + if (pChan->AutoClearChanBuffer() != bAutoClearChanBuffer) { + pChan->SetAutoClearChanBuffer( + WebSock.GetParam("autoclearchanbuffer").ToBool()); + } + pChan->SetKey(WebSock.GetParam("key")); + + bool bDetached = WebSock.GetParam("detached").ToBool(); + if (pChan->IsDetached() != bDetached) { + if (bDetached) { + pChan->DetachUser(); + } else { + pChan->AttachUser(); + } + } + + bool bDisabled = WebSock.GetParam("disabled").ToBool(); + if (bDisabled) + pChan->Disable(); + else + pChan->Enable(); + + CTemplate TmplMod; + TmplMod["User"] = pUser->GetUserName(); + TmplMod["ChanName"] = pChan->GetName(); + TmplMod["WebadminAction"] = "change"; + FOR_EACH_MODULE(it, pNetwork) { + (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/channel", TmplMod); + } + + if (!CZNC::Get().WriteConfig()) { + WebSock.PrintErrorPage( + "Channel added/modified, but config was not written"); + return true; + } + + if (WebSock.HasParam("submit_return")) { + WebSock.Redirect(GetWebPath() + "editnetwork?user=" + + pUser->GetUserName().Escape_n(CString::EURL) + + "&network=" + + pNetwork->GetName().Escape_n(CString::EURL)); + } else { + WebSock.Redirect( + GetWebPath() + "editchan?user=" + + pUser->GetUserName().Escape_n(CString::EURL) + "&network=" + + pNetwork->GetName().Escape_n(CString::EURL) + "&name=" + + pChan->GetName().Escape_n(CString::EURL)); + } + return true; + } + + bool NetworkPage(CWebSock& WebSock, CTemplate& Tmpl, CUser* pUser, + CIRCNetwork* pNetwork = nullptr) { + std::shared_ptr spSession = WebSock.GetSession(); + Tmpl.SetFile("add_edit_network.tmpl"); + + if (!WebSock.GetParam("submitted").ToUInt()) { + Tmpl["Username"] = pUser->GetUserName(); + + set ssNetworkMods; + CZNC::Get().GetModules().GetAvailableMods(ssNetworkMods, + CModInfo::NetworkModule); + for (const CModInfo& Info : ssNetworkMods) { + CTemplate& l = Tmpl.AddRow("ModuleLoop"); + + l["Name"] = Info.GetName(); + l["Description"] = Info.GetDescription(); + l["Wiki"] = Info.GetWikiPage(); + l["HasArgs"] = CString(Info.GetHasArgs()); + l["ArgsHelpText"] = Info.GetArgsHelpText(); + + if (pNetwork) { + CModule* pModule = + pNetwork->GetModules().FindModule(Info.GetName()); + if (pModule) { + l["Checked"] = "true"; + l["Args"] = pModule->GetArgs(); + } + } + + // Check if module is loaded globally + l["CanBeLoadedGlobally"] = + CString(Info.SupportsType(CModInfo::GlobalModule)); + l["LoadedGlobally"] = + CString(CZNC::Get().GetModules().FindModule( + Info.GetName()) != nullptr); + + // Check if module is loaded by user + l["CanBeLoadedByUser"] = + CString(Info.SupportsType(CModInfo::UserModule)); + l["LoadedByUser"] = CString( + pUser->GetModules().FindModule(Info.GetName()) != nullptr); + + if (!spSession->IsAdmin() && pUser->DenyLoadMod()) { + l["Disabled"] = "true"; + } + } + + // To change BindHosts be admin or don't have DenySetBindHost + if (spSession->IsAdmin() || + !spSession->GetUser()->DenySetBindHost()) { + Tmpl["BindHostEdit"] = "true"; + if (pNetwork) { + Tmpl["BindHost"] = pNetwork->GetBindHost(); + } + } + + CTemplate& breadUser = Tmpl.AddRow("BreadCrumbs"); + breadUser["Text"] = "Edit User [" + pUser->GetUserName() + "]"; + breadUser["URL"] = + GetWebPath() + "edituser?user=" + pUser->GetUserName(); + CTemplate& breadNet = Tmpl.AddRow("BreadCrumbs"); + + if (pNetwork) { + Tmpl["Action"] = "editnetwork"; + Tmpl["Edit"] = "true"; + Tmpl["Title"] = "Edit Network" + + CString(" [" + pNetwork->GetName() + "]") + + " of User [" + pUser->GetUserName() + "]"; + Tmpl["Name"] = pNetwork->GetName(); + + Tmpl["Nick"] = pNetwork->GetNick(); + Tmpl["AltNick"] = pNetwork->GetAltNick(); + Tmpl["Ident"] = pNetwork->GetIdent(); + Tmpl["RealName"] = pNetwork->GetRealName(); + + Tmpl["QuitMsg"] = pNetwork->GetQuitMsg(); + + Tmpl["FloodProtection"] = CString( + CIRCSock::IsFloodProtected(pNetwork->GetFloodRate())); + Tmpl["FloodRate"] = CString(pNetwork->GetFloodRate()); + Tmpl["FloodBurst"] = CString(pNetwork->GetFloodBurst()); + + Tmpl["JoinDelay"] = CString(pNetwork->GetJoinDelay()); + + Tmpl["IRCConnectEnabled"] = + CString(pNetwork->GetIRCConnectEnabled()); + + breadNet["Text"] = "Edit Network [" + pNetwork->GetName() + "]"; + + const vector& vServers = pNetwork->GetServers(); + for (const CServer* pServer : vServers) { + CTemplate& l = Tmpl.AddRow("ServerLoop"); + l["Server"] = pServer->GetString(); + } + + const vector& Channels = pNetwork->GetChans(); + for (const CChan* pChan : Channels) { + CTemplate& l = Tmpl.AddRow("ChannelLoop"); + + l["Network"] = pNetwork->GetName(); + l["Username"] = pUser->GetUserName(); + l["Name"] = pChan->GetName(); + l["Perms"] = pChan->GetPermStr(); + l["CurModes"] = pChan->GetModeString(); + l["DefModes"] = pChan->GetDefaultModes(); + if (pChan->HasBufferCountSet()) { + l["BufferSize"] = CString(pChan->GetBufferCount()); + } else { + l["BufferSize"] = + CString(pChan->GetBufferCount()) + " (default)"; + } + l["Options"] = pChan->GetOptions(); + + if (pChan->InConfig()) { + l["InConfig"] = "true"; + } + } + for (const CString& sFP : pNetwork->GetTrustedFingerprints()) { + CTemplate& l = Tmpl.AddRow("TrustedFingerprints"); + l["FP"] = sFP; + } + } else { + if (!spSession->IsAdmin() && !pUser->HasSpaceForNewNetwork()) { + WebSock.PrintErrorPage( + "Network number limit reached. Ask an admin to " + "increase the limit for you, or delete unneeded " + "networks from Your Settings."); + return true; + } + + Tmpl["Action"] = "addnetwork"; + Tmpl["Title"] = + "Add Network for User [" + pUser->GetUserName() + "]"; + Tmpl["IRCConnectEnabled"] = "true"; + Tmpl["FloodProtection"] = "true"; + Tmpl["FloodRate"] = "1.0"; + Tmpl["FloodBurst"] = "4"; + Tmpl["JoinDelay"] = "0"; + breadNet["Text"] = "Add Network"; + } + + FOR_EACH_MODULE(i, make_pair(pUser, pNetwork)) { + CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); + mod.insert(Tmpl.begin(), Tmpl.end()); + mod["WebadminAction"] = "display"; + if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/network", + mod)) { + mod["Embed"] = WebSock.FindTmpl(*i, "WebadminNetwork.tmpl"); + mod["ModName"] = (*i)->GetModName(); + } + } #ifdef HAVE_ICU - for (const CString& sEncoding : CUtils::GetEncodings()) { - CTemplate& l = Tmpl.AddRow("EncodingLoop"); - l["Encoding"] = sEncoding; - } - const CString sEncoding = - pNetwork ? pNetwork->GetEncoding() : "^UTF-8"; - if (sEncoding.empty()) { - Tmpl["EncodingUtf"] = "legacy"; - } else if (sEncoding[0] == '*') { - Tmpl["EncodingUtf"] = "receive"; - Tmpl["Encoding"] = sEncoding.substr(1); - } else if (sEncoding[0] == '^') { - Tmpl["EncodingUtf"] = "send"; - Tmpl["Encoding"] = sEncoding.substr(1); - } else { - Tmpl["EncodingUtf"] = "simple"; - Tmpl["Encoding"] = sEncoding; - } + for (const CString& sEncoding : CUtils::GetEncodings()) { + CTemplate& l = Tmpl.AddRow("EncodingLoop"); + l["Encoding"] = sEncoding; + } + const CString sEncoding = + pNetwork ? pNetwork->GetEncoding() : "^UTF-8"; + if (sEncoding.empty()) { + Tmpl["EncodingUtf"] = "legacy"; + } else if (sEncoding[0] == '*') { + Tmpl["EncodingUtf"] = "receive"; + Tmpl["Encoding"] = sEncoding.substr(1); + } else if (sEncoding[0] == '^') { + Tmpl["EncodingUtf"] = "send"; + Tmpl["Encoding"] = sEncoding.substr(1); + } else { + Tmpl["EncodingUtf"] = "simple"; + Tmpl["Encoding"] = sEncoding; + } #else - Tmpl["EncodingDisabled"] = "true"; - Tmpl["EncodingUtf"] = "legacy"; + Tmpl["EncodingDisabled"] = "true"; + Tmpl["EncodingUtf"] = "legacy"; #endif - return true; - } + return true; + } - CString sName = WebSock.GetParam("name").Trim_n(); - if (sName.empty()) { - WebSock.PrintErrorPage("Network name is a required argument"); - return true; - } - if (!pNetwork && !spSession->IsAdmin() && - !pUser->HasSpaceForNewNetwork()) { - WebSock.PrintErrorPage( - "Network number limit reached. Ask an admin to increase the " - "limit for you, or delete few old ones from Your Settings"); - return true; - } - if (!pNetwork || pNetwork->GetName() != sName) { - CString sNetworkAddError; - CIRCNetwork* pOldNetwork = pNetwork; - pNetwork = pUser->AddNetwork(sName, sNetworkAddError); - if (!pNetwork) { - WebSock.PrintErrorPage(sNetworkAddError); - return true; - } - if (pOldNetwork) { - for (CModule* pModule : pOldNetwork->GetModules()) { - CString sPath = pUser->GetUserPath() + "/networks/" + - sName + "/moddata/" + pModule->GetModName(); - pModule->MoveRegistry(sPath); - } - pNetwork->Clone(*pOldNetwork, false); - pUser->DeleteNetwork(pOldNetwork->GetName()); - } - } + CString sName = WebSock.GetParam("name").Trim_n(); + if (sName.empty()) { + WebSock.PrintErrorPage("Network name is a required argument"); + return true; + } + if (!pNetwork && !spSession->IsAdmin() && + !pUser->HasSpaceForNewNetwork()) { + WebSock.PrintErrorPage( + "Network number limit reached. Ask an admin to increase the " + "limit for you, or delete few old ones from Your Settings"); + return true; + } + if (!pNetwork || pNetwork->GetName() != sName) { + CString sNetworkAddError; + CIRCNetwork* pOldNetwork = pNetwork; + pNetwork = pUser->AddNetwork(sName, sNetworkAddError); + if (!pNetwork) { + WebSock.PrintErrorPage(sNetworkAddError); + return true; + } + if (pOldNetwork) { + for (CModule* pModule : pOldNetwork->GetModules()) { + CString sPath = pUser->GetUserPath() + "/networks/" + + sName + "/moddata/" + pModule->GetModName(); + pModule->MoveRegistry(sPath); + } + pNetwork->Clone(*pOldNetwork, false); + pUser->DeleteNetwork(pOldNetwork->GetName()); + } + } - CString sArg; + CString sArg; - pNetwork->SetNick(WebSock.GetParam("nick")); - pNetwork->SetAltNick(WebSock.GetParam("altnick")); - pNetwork->SetIdent(WebSock.GetParam("ident")); - pNetwork->SetRealName(WebSock.GetParam("realname")); + pNetwork->SetNick(WebSock.GetParam("nick")); + pNetwork->SetAltNick(WebSock.GetParam("altnick")); + pNetwork->SetIdent(WebSock.GetParam("ident")); + pNetwork->SetRealName(WebSock.GetParam("realname")); - pNetwork->SetQuitMsg(WebSock.GetParam("quitmsg")); + pNetwork->SetQuitMsg(WebSock.GetParam("quitmsg")); - pNetwork->SetIRCConnectEnabled(WebSock.GetParam("doconnect").ToBool()); + pNetwork->SetIRCConnectEnabled(WebSock.GetParam("doconnect").ToBool()); - sArg = WebSock.GetParam("bindhost"); - // To change BindHosts be admin or don't have DenySetBindHost - if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) { - pNetwork->SetBindHost(WebSock.GetParam("bindhost")); - } + sArg = WebSock.GetParam("bindhost"); + // To change BindHosts be admin or don't have DenySetBindHost + if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) { + pNetwork->SetBindHost(WebSock.GetParam("bindhost")); + } - if (WebSock.GetParam("floodprotection").ToBool()) { - pNetwork->SetFloodRate(WebSock.GetParam("floodrate").ToDouble()); - pNetwork->SetFloodBurst(WebSock.GetParam("floodburst").ToUShort()); - } else { - pNetwork->SetFloodRate(-1); - } + if (WebSock.GetParam("floodprotection").ToBool()) { + pNetwork->SetFloodRate(WebSock.GetParam("floodrate").ToDouble()); + pNetwork->SetFloodBurst(WebSock.GetParam("floodburst").ToUShort()); + } else { + pNetwork->SetFloodRate(-1); + } - pNetwork->SetJoinDelay(WebSock.GetParam("joindelay").ToUShort()); + pNetwork->SetJoinDelay(WebSock.GetParam("joindelay").ToUShort()); #ifdef HAVE_ICU - CString sEncodingUtf = WebSock.GetParam("encoding_utf"); - if (sEncodingUtf == "legacy") { - pNetwork->SetEncoding(""); - } - CString sEncoding = WebSock.GetParam("encoding"); - if (sEncoding.empty()) { - sEncoding = "UTF-8"; - } - if (sEncodingUtf == "send") { - pNetwork->SetEncoding("^" + sEncoding); - } else if (sEncodingUtf == "receive") { - pNetwork->SetEncoding("*" + sEncoding); - } else if (sEncodingUtf == "simple") { - pNetwork->SetEncoding(sEncoding); - } + CString sEncodingUtf = WebSock.GetParam("encoding_utf"); + if (sEncodingUtf == "legacy") { + pNetwork->SetEncoding(""); + } + CString sEncoding = WebSock.GetParam("encoding"); + if (sEncoding.empty()) { + sEncoding = "UTF-8"; + } + if (sEncodingUtf == "send") { + pNetwork->SetEncoding("^" + sEncoding); + } else if (sEncodingUtf == "receive") { + pNetwork->SetEncoding("*" + sEncoding); + } else if (sEncodingUtf == "simple") { + pNetwork->SetEncoding(sEncoding); + } #endif - VCString vsArgs; + VCString vsArgs; - pNetwork->DelServers(); - WebSock.GetRawParam("servers").Split("\n", vsArgs); - for (const CString& sServer : vsArgs) { - pNetwork->AddServer(sServer.Trim_n()); - } + pNetwork->DelServers(); + WebSock.GetRawParam("servers").Split("\n", vsArgs); + for (const CString& sServer : vsArgs) { + pNetwork->AddServer(sServer.Trim_n()); + } - WebSock.GetRawParam("fingerprints").Split("\n", vsArgs); - pNetwork->ClearTrustedFingerprints(); - for (const CString& sFP : vsArgs) { - pNetwork->AddTrustedFingerprint(sFP); - } + WebSock.GetRawParam("fingerprints").Split("\n", vsArgs); + pNetwork->ClearTrustedFingerprints(); + for (const CString& sFP : vsArgs) { + pNetwork->AddTrustedFingerprint(sFP); + } - WebSock.GetParamValues("channel", vsArgs); - for (const CString& sChan : vsArgs) { - CChan* pChan = pNetwork->FindChan(sChan.TrimRight_n("\r")); - if (pChan) { - pChan->SetInConfig(WebSock.GetParam("save_" + sChan).ToBool()); - } - } + WebSock.GetParamValues("channel", vsArgs); + for (const CString& sChan : vsArgs) { + CChan* pChan = pNetwork->FindChan(sChan.TrimRight_n("\r")); + if (pChan) { + pChan->SetInConfig(WebSock.GetParam("save_" + sChan).ToBool()); + } + } - set ssArgs; - WebSock.GetParamValues("loadmod", ssArgs); - if (spSession->IsAdmin() || !pUser->DenyLoadMod()) { - for (const CString& s : ssArgs) { - CString sModRet; - CString sModName = s.TrimRight_n("\r"); - CString sModLoadError; + set ssArgs; + WebSock.GetParamValues("loadmod", ssArgs); + if (spSession->IsAdmin() || !pUser->DenyLoadMod()) { + for (const CString& s : ssArgs) { + CString sModRet; + CString sModName = s.TrimRight_n("\r"); + CString sModLoadError; - if (!sModName.empty()) { - CString sArgs = WebSock.GetParam("modargs_" + sModName); + if (!sModName.empty()) { + CString sArgs = WebSock.GetParam("modargs_" + sModName); - CModule* pMod = pNetwork->GetModules().FindModule(sModName); + CModule* pMod = pNetwork->GetModules().FindModule(sModName); - if (!pMod) { - if (!pNetwork->GetModules().LoadModule( - sModName, sArgs, CModInfo::NetworkModule, pUser, - pNetwork, sModRet)) { - sModLoadError = "Unable to load module [" + - sModName + "] [" + sModRet + "]"; - } - } else if (pMod->GetArgs() != sArgs) { - if (!pNetwork->GetModules().ReloadModule( - sModName, sArgs, pUser, pNetwork, sModRet)) { - sModLoadError = "Unable to reload module [" + - sModName + "] [" + sModRet + "]"; - } - } + if (!pMod) { + if (!pNetwork->GetModules().LoadModule( + sModName, sArgs, CModInfo::NetworkModule, pUser, + pNetwork, sModRet)) { + sModLoadError = "Unable to load module [" + + sModName + "] [" + sModRet + "]"; + } + } else if (pMod->GetArgs() != sArgs) { + if (!pNetwork->GetModules().ReloadModule( + sModName, sArgs, pUser, pNetwork, sModRet)) { + sModLoadError = "Unable to reload module [" + + sModName + "] [" + sModRet + "]"; + } + } - if (!sModLoadError.empty()) { - DEBUG(sModLoadError); - WebSock.GetSession()->AddError(sModLoadError); - } - } - } - } + if (!sModLoadError.empty()) { + DEBUG(sModLoadError); + WebSock.GetSession()->AddError(sModLoadError); + } + } + } + } - const CModules& vCurMods = pNetwork->GetModules(); - set ssUnloadMods; + const CModules& vCurMods = pNetwork->GetModules(); + set ssUnloadMods; - for (const CModule* pCurMod : vCurMods) { - if (ssArgs.find(pCurMod->GetModName()) == ssArgs.end() && - pCurMod->GetModName() != GetModName()) { - ssUnloadMods.insert(pCurMod->GetModName()); - } - } + for (const CModule* pCurMod : vCurMods) { + if (ssArgs.find(pCurMod->GetModName()) == ssArgs.end() && + pCurMod->GetModName() != GetModName()) { + ssUnloadMods.insert(pCurMod->GetModName()); + } + } - for (const CString& sMod : ssUnloadMods) { - pNetwork->GetModules().UnloadModule(sMod); - } + for (const CString& sMod : ssUnloadMods) { + pNetwork->GetModules().UnloadModule(sMod); + } - CTemplate TmplMod; - TmplMod["Username"] = pUser->GetUserName(); - TmplMod["Name"] = pNetwork->GetName(); - TmplMod["WebadminAction"] = "change"; - FOR_EACH_MODULE(it, make_pair(pUser, pNetwork)) { - (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/network", TmplMod); - } + CTemplate TmplMod; + TmplMod["Username"] = pUser->GetUserName(); + TmplMod["Name"] = pNetwork->GetName(); + TmplMod["WebadminAction"] = "change"; + FOR_EACH_MODULE(it, make_pair(pUser, pNetwork)) { + (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/network", TmplMod); + } - if (!CZNC::Get().WriteConfig()) { - WebSock.PrintErrorPage( - "Network added/modified, but config was not written"); - return true; - } + if (!CZNC::Get().WriteConfig()) { + WebSock.PrintErrorPage( + "Network added/modified, but config was not written"); + return true; + } - if (WebSock.HasParam("submit_return")) { - WebSock.Redirect(GetWebPath() + "edituser?user=" + - pUser->GetUserName().Escape_n(CString::EURL)); - } else { - WebSock.Redirect(GetWebPath() + "editnetwork?user=" + - pUser->GetUserName().Escape_n(CString::EURL) + - "&network=" + - pNetwork->GetName().Escape_n(CString::EURL)); - } - return true; - } + if (WebSock.HasParam("submit_return")) { + WebSock.Redirect(GetWebPath() + "edituser?user=" + + pUser->GetUserName().Escape_n(CString::EURL)); + } else { + WebSock.Redirect(GetWebPath() + "editnetwork?user=" + + pUser->GetUserName().Escape_n(CString::EURL) + + "&network=" + + pNetwork->GetName().Escape_n(CString::EURL)); + } + return true; + } - bool DelNetwork(CWebSock& WebSock, CUser* pUser, CTemplate& Tmpl) { - CString sNetwork = WebSock.GetParam("name"); - if (sNetwork.empty() && !WebSock.IsPost()) { - sNetwork = WebSock.GetParam("name", false); - } + bool DelNetwork(CWebSock& WebSock, CUser* pUser, CTemplate& Tmpl) { + CString sNetwork = WebSock.GetParam("name"); + if (sNetwork.empty() && !WebSock.IsPost()) { + sNetwork = WebSock.GetParam("name", false); + } - if (!pUser) { - WebSock.PrintErrorPage("That user doesn't exist"); - return true; - } + if (!pUser) { + WebSock.PrintErrorPage("That user doesn't exist"); + return true; + } - if (sNetwork.empty()) { - WebSock.PrintErrorPage("That network doesn't exist for this user"); - return true; - } + if (sNetwork.empty()) { + WebSock.PrintErrorPage("That network doesn't exist for this user"); + return true; + } - if (!WebSock.IsPost()) { - // Show the "Are you sure?" page: + if (!WebSock.IsPost()) { + // Show the "Are you sure?" page: - Tmpl.SetFile("del_network.tmpl"); - Tmpl["Username"] = pUser->GetUserName(); - Tmpl["Network"] = sNetwork; - return true; - } + Tmpl.SetFile("del_network.tmpl"); + Tmpl["Username"] = pUser->GetUserName(); + Tmpl["Network"] = sNetwork; + return true; + } - pUser->DeleteNetwork(sNetwork); + pUser->DeleteNetwork(sNetwork); - if (!CZNC::Get().WriteConfig()) { - WebSock.PrintErrorPage( - "Network deleted, but config was not written"); - return true; - } + if (!CZNC::Get().WriteConfig()) { + WebSock.PrintErrorPage( + "Network deleted, but config was not written"); + return true; + } - WebSock.Redirect(GetWebPath() + "edituser?user=" + - pUser->GetUserName().Escape_n(CString::EURL)); - return false; - } + WebSock.Redirect(GetWebPath() + "edituser?user=" + + pUser->GetUserName().Escape_n(CString::EURL)); + return false; + } - bool DelChan(CWebSock& WebSock, CIRCNetwork* pNetwork) { - CString sChan = WebSock.GetParam("name", false); + bool DelChan(CWebSock& WebSock, CIRCNetwork* pNetwork) { + CString sChan = WebSock.GetParam("name", false); - if (sChan.empty()) { - WebSock.PrintErrorPage("That channel doesn't exist for this user"); - return true; - } + if (sChan.empty()) { + WebSock.PrintErrorPage("That channel doesn't exist for this user"); + return true; + } - pNetwork->DelChan(sChan); - pNetwork->PutIRC("PART " + sChan); + pNetwork->DelChan(sChan); + pNetwork->PutIRC("PART " + sChan); - if (!CZNC::Get().WriteConfig()) { - WebSock.PrintErrorPage( - "Channel deleted, but config was not written"); - return true; - } + if (!CZNC::Get().WriteConfig()) { + WebSock.PrintErrorPage( + "Channel deleted, but config was not written"); + return true; + } - WebSock.Redirect( - GetWebPath() + "editnetwork?user=" + - pNetwork->GetUser()->GetUserName().Escape_n(CString::EURL) + - "&network=" + pNetwork->GetName().Escape_n(CString::EURL)); - return false; - } + WebSock.Redirect( + GetWebPath() + "editnetwork?user=" + + pNetwork->GetUser()->GetUserName().Escape_n(CString::EURL) + + "&network=" + pNetwork->GetName().Escape_n(CString::EURL)); + return false; + } - bool UserPage(CWebSock& WebSock, CTemplate& Tmpl, CUser* pUser = nullptr) { - std::shared_ptr spSession = WebSock.GetSession(); - Tmpl.SetFile("add_edit_user.tmpl"); + bool UserPage(CWebSock& WebSock, CTemplate& Tmpl, CUser* pUser = nullptr) { + std::shared_ptr spSession = WebSock.GetSession(); + Tmpl.SetFile("add_edit_user.tmpl"); - if (!WebSock.GetParam("submitted").ToUInt()) { - if (pUser) { - Tmpl["Action"] = "edituser"; - Tmpl["Title"] = "Edit User [" + pUser->GetUserName() + "]"; - Tmpl["Edit"] = "true"; - } else { - CString sUsername = WebSock.GetParam("clone", false); - pUser = CZNC::Get().FindUser(sUsername); + if (!WebSock.GetParam("submitted").ToUInt()) { + if (pUser) { + Tmpl["Action"] = "edituser"; + Tmpl["Title"] = "Edit User [" + pUser->GetUserName() + "]"; + Tmpl["Edit"] = "true"; + } else { + CString sUsername = WebSock.GetParam("clone", false); + pUser = CZNC::Get().FindUser(sUsername); - if (pUser) { - Tmpl["Title"] = "Clone User [" + pUser->GetUserName() + "]"; - Tmpl["Clone"] = "true"; - Tmpl["CloneUsername"] = pUser->GetUserName(); - } - } + if (pUser) { + Tmpl["Title"] = "Clone User [" + pUser->GetUserName() + "]"; + Tmpl["Clone"] = "true"; + Tmpl["CloneUsername"] = pUser->GetUserName(); + } + } - Tmpl["ImAdmin"] = CString(spSession->IsAdmin()); + Tmpl["ImAdmin"] = CString(spSession->IsAdmin()); - if (pUser) { - Tmpl["Username"] = pUser->GetUserName(); - Tmpl["Nick"] = pUser->GetNick(); - Tmpl["AltNick"] = pUser->GetAltNick(); - Tmpl["StatusPrefix"] = pUser->GetStatusPrefix(); - Tmpl["Ident"] = pUser->GetIdent(); - Tmpl["RealName"] = pUser->GetRealName(); - Tmpl["QuitMsg"] = pUser->GetQuitMsg(); - Tmpl["DefaultChanModes"] = pUser->GetDefaultChanModes(); - Tmpl["ChanBufferSize"] = CString(pUser->GetChanBufferSize()); - Tmpl["QueryBufferSize"] = CString(pUser->GetQueryBufferSize()); - Tmpl["TimestampFormat"] = pUser->GetTimestampFormat(); - Tmpl["Timezone"] = pUser->GetTimezone(); - Tmpl["JoinTries"] = CString(pUser->JoinTries()); - Tmpl["MaxNetworks"] = CString(pUser->MaxNetworks()); - Tmpl["MaxJoins"] = CString(pUser->MaxJoins()); - Tmpl["MaxQueryBuffers"] = CString(pUser->MaxQueryBuffers()); + if (pUser) { + Tmpl["Username"] = pUser->GetUserName(); + Tmpl["Nick"] = pUser->GetNick(); + Tmpl["AltNick"] = pUser->GetAltNick(); + Tmpl["StatusPrefix"] = pUser->GetStatusPrefix(); + Tmpl["Ident"] = pUser->GetIdent(); + Tmpl["RealName"] = pUser->GetRealName(); + Tmpl["QuitMsg"] = pUser->GetQuitMsg(); + Tmpl["DefaultChanModes"] = pUser->GetDefaultChanModes(); + Tmpl["ChanBufferSize"] = CString(pUser->GetChanBufferSize()); + Tmpl["QueryBufferSize"] = CString(pUser->GetQueryBufferSize()); + Tmpl["TimestampFormat"] = pUser->GetTimestampFormat(); + Tmpl["Timezone"] = pUser->GetTimezone(); + Tmpl["JoinTries"] = CString(pUser->JoinTries()); + Tmpl["MaxNetworks"] = CString(pUser->MaxNetworks()); + Tmpl["MaxJoins"] = CString(pUser->MaxJoins()); + Tmpl["MaxQueryBuffers"] = CString(pUser->MaxQueryBuffers()); - const set& ssAllowedHosts = pUser->GetAllowedHosts(); - for (const CString& sHost : ssAllowedHosts) { - CTemplate& l = Tmpl.AddRow("AllowedHostLoop"); - l["Host"] = sHost; - } + const set& ssAllowedHosts = pUser->GetAllowedHosts(); + for (const CString& sHost : ssAllowedHosts) { + CTemplate& l = Tmpl.AddRow("AllowedHostLoop"); + l["Host"] = sHost; + } - const vector& vNetworks = pUser->GetNetworks(); - for (const CIRCNetwork* pNetwork : vNetworks) { - CTemplate& l = Tmpl.AddRow("NetworkLoop"); - l["Name"] = pNetwork->GetName(); - l["Username"] = pUser->GetUserName(); - l["Clients"] = CString(pNetwork->GetClients().size()); - l["IRCNick"] = pNetwork->GetIRCNick().GetNick(); - CServer* pServer = pNetwork->GetCurrentServer(); - if (pServer) { - l["Server"] = pServer->GetName() + ":" + - (pServer->IsSSL() ? "+" : "") + - CString(pServer->GetPort()); - } - } + const vector& vNetworks = pUser->GetNetworks(); + for (const CIRCNetwork* pNetwork : vNetworks) { + CTemplate& l = Tmpl.AddRow("NetworkLoop"); + l["Name"] = pNetwork->GetName(); + l["Username"] = pUser->GetUserName(); + l["Clients"] = CString(pNetwork->GetClients().size()); + l["IRCNick"] = pNetwork->GetIRCNick().GetNick(); + CServer* pServer = pNetwork->GetCurrentServer(); + if (pServer) { + l["Server"] = pServer->GetName() + ":" + + (pServer->IsSSL() ? "+" : "") + + CString(pServer->GetPort()); + } + } - const MCString& msCTCPReplies = pUser->GetCTCPReplies(); - for (const auto& it : msCTCPReplies) { - CTemplate& l = Tmpl.AddRow("CTCPLoop"); - l["CTCP"] = it.first + " " + it.second; - } - } else { - Tmpl["Action"] = "adduser"; - Tmpl["Title"] = "Add User"; - Tmpl["StatusPrefix"] = "*"; - } + const MCString& msCTCPReplies = pUser->GetCTCPReplies(); + for (const auto& it : msCTCPReplies) { + CTemplate& l = Tmpl.AddRow("CTCPLoop"); + l["CTCP"] = it.first + " " + it.second; + } + } else { + Tmpl["Action"] = "adduser"; + Tmpl["Title"] = "Add User"; + Tmpl["StatusPrefix"] = "*"; + } - SCString ssTimezones = CUtils::GetTimezones(); - for (const CString& sTZ : ssTimezones) { - CTemplate& l = Tmpl.AddRow("TZLoop"); - l["TZ"] = sTZ; - } + SCString ssTimezones = CUtils::GetTimezones(); + for (const CString& sTZ : ssTimezones) { + CTemplate& l = Tmpl.AddRow("TZLoop"); + l["TZ"] = sTZ; + } #ifdef HAVE_ICU - for (const CString& sEncoding : CUtils::GetEncodings()) { - CTemplate& l = Tmpl.AddRow("EncodingLoop"); - l["Encoding"] = sEncoding; - } - const CString sEncoding = - pUser ? pUser->GetClientEncoding() : "^UTF-8"; - if (sEncoding.empty()) { - Tmpl["EncodingUtf"] = "legacy"; - } else if (sEncoding[0] == '*') { - Tmpl["EncodingUtf"] = "receive"; - Tmpl["Encoding"] = sEncoding.substr(1); - } else if (sEncoding[0] == '^') { - Tmpl["EncodingUtf"] = "send"; - Tmpl["Encoding"] = sEncoding.substr(1); - } else { - Tmpl["EncodingUtf"] = "simple"; - Tmpl["Encoding"] = sEncoding; - } + for (const CString& sEncoding : CUtils::GetEncodings()) { + CTemplate& l = Tmpl.AddRow("EncodingLoop"); + l["Encoding"] = sEncoding; + } + const CString sEncoding = + pUser ? pUser->GetClientEncoding() : "^UTF-8"; + if (sEncoding.empty()) { + Tmpl["EncodingUtf"] = "legacy"; + } else if (sEncoding[0] == '*') { + Tmpl["EncodingUtf"] = "receive"; + Tmpl["Encoding"] = sEncoding.substr(1); + } else if (sEncoding[0] == '^') { + Tmpl["EncodingUtf"] = "send"; + Tmpl["Encoding"] = sEncoding.substr(1); + } else { + Tmpl["EncodingUtf"] = "simple"; + Tmpl["Encoding"] = sEncoding; + } #else - Tmpl["EncodingDisabled"] = "true"; - Tmpl["EncodingUtf"] = "legacy"; + Tmpl["EncodingDisabled"] = "true"; + Tmpl["EncodingUtf"] = "legacy"; #endif - // To change BindHosts be admin or don't have DenySetBindHost - if (spSession->IsAdmin() || - !spSession->GetUser()->DenySetBindHost()) { - Tmpl["BindHostEdit"] = "true"; - if (pUser) { - Tmpl["BindHost"] = pUser->GetBindHost(); - Tmpl["DCCBindHost"] = pUser->GetDCCBindHost(); - } - } - - vector vDirs; - WebSock.GetAvailSkins(vDirs); - - for (const CString& SubDir : vDirs) { - CTemplate& l = Tmpl.AddRow("SkinLoop"); - l["Name"] = SubDir; - - if (pUser && SubDir == pUser->GetSkinName()) { - l["Checked"] = "true"; - } - } - - set ssUserMods; - CZNC::Get().GetModules().GetAvailableMods(ssUserMods); - - for (const CModInfo& Info : ssUserMods) { - CTemplate& l = Tmpl.AddRow("ModuleLoop"); - - l["Name"] = Info.GetName(); - l["Description"] = Info.GetDescription(); - l["Wiki"] = Info.GetWikiPage(); - l["HasArgs"] = CString(Info.GetHasArgs()); - l["ArgsHelpText"] = Info.GetArgsHelpText(); - - CModule* pModule = nullptr; - if (pUser) { - pModule = pUser->GetModules().FindModule(Info.GetName()); - // Check if module is loaded by all or some networks - const vector& userNetworks = - pUser->GetNetworks(); - unsigned int networksWithRenderedModuleCount = 0; - for (const CIRCNetwork* pCurrentNetwork : userNetworks) { - const CModules& networkModules = - pCurrentNetwork->GetModules(); - if (networkModules.FindModule(Info.GetName())) { - networksWithRenderedModuleCount++; - } - } - l["CanBeLoadedByNetwork"] = - CString(Info.SupportsType(CModInfo::NetworkModule)); - l["LoadedByAllNetworks"] = CString( - networksWithRenderedModuleCount == userNetworks.size()); - l["LoadedBySomeNetworks"] = - CString(networksWithRenderedModuleCount != 0); - } - if (pModule) { - l["Checked"] = "true"; - l["Args"] = pModule->GetArgs(); - if (CModInfo::UserModule == GetType() && - Info.GetName() == GetModName()) { - l["Disabled"] = "true"; - } - } - l["CanBeLoadedGlobally"] = - CString(Info.SupportsType(CModInfo::GlobalModule)); - // Check if module is loaded globally - l["LoadedGlobally"] = - CString(CZNC::Get().GetModules().FindModule( - Info.GetName()) != nullptr); - - if (!spSession->IsAdmin() && pUser && pUser->DenyLoadMod()) { - l["Disabled"] = "true"; - } - } - - CTemplate& o1 = Tmpl.AddRow("OptionLoop"); - o1["Name"] = "autoclearchanbuffer"; - o1["DisplayName"] = "Auto Clear Chan Buffer"; - o1["Tooltip"] = - "Automatically Clear Channel Buffer After Playback (the " - "default value for new channels)"; - if (!pUser || pUser->AutoClearChanBuffer()) { - o1["Checked"] = "true"; - } - - /* o2 used to be auto cycle which was removed */ - - CTemplate& o4 = Tmpl.AddRow("OptionLoop"); - o4["Name"] = "multiclients"; - o4["DisplayName"] = "Multi Clients"; - if (!pUser || pUser->MultiClients()) { - o4["Checked"] = "true"; - } - - CTemplate& o7 = Tmpl.AddRow("OptionLoop"); - o7["Name"] = "appendtimestamp"; - o7["DisplayName"] = "Append Timestamps"; - if (pUser && pUser->GetTimestampAppend()) { - o7["Checked"] = "true"; - } - - CTemplate& o8 = Tmpl.AddRow("OptionLoop"); - o8["Name"] = "prependtimestamp"; - o8["DisplayName"] = "Prepend Timestamps"; - if (pUser && pUser->GetTimestampPrepend()) { - o8["Checked"] = "true"; - } - - if (spSession->IsAdmin()) { - CTemplate& o9 = Tmpl.AddRow("OptionLoop"); - o9["Name"] = "denyloadmod"; - o9["DisplayName"] = "Deny LoadMod"; - if (pUser && pUser->DenyLoadMod()) { - o9["Checked"] = "true"; - } - - CTemplate& o10 = Tmpl.AddRow("OptionLoop"); - o10["Name"] = "isadmin"; - o10["DisplayName"] = "Admin"; - if (pUser && pUser->IsAdmin()) { - o10["Checked"] = "true"; - } - if (pUser && pUser == CZNC::Get().FindUser(WebSock.GetUser())) { - o10["Disabled"] = "true"; - } - - CTemplate& o11 = Tmpl.AddRow("OptionLoop"); - o11["Name"] = "denysetbindhost"; - o11["DisplayName"] = "Deny SetBindHost"; - if (pUser && pUser->DenySetBindHost()) { - o11["Checked"] = "true"; - } - } - - CTemplate& o12 = Tmpl.AddRow("OptionLoop"); - o12["Name"] = "autoclearquerybuffer"; - o12["DisplayName"] = "Auto Clear Query Buffer"; - o12["Tooltip"] = "Automatically Clear Query Buffer After Playback"; - if (!pUser || pUser->AutoClearQueryBuffer()) { - o12["Checked"] = "true"; - } - - FOR_EACH_MODULE(i, pUser) { - CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); - mod.insert(Tmpl.begin(), Tmpl.end()); - mod["WebadminAction"] = "display"; - if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/user", mod)) { - mod["Embed"] = WebSock.FindTmpl(*i, "WebadminUser.tmpl"); - mod["ModName"] = (*i)->GetModName(); - } - } - - return true; - } - - /* If pUser is nullptr, we are adding a user, else we are editing this - * one */ - - CString sUsername = WebSock.GetParam("user"); - if (!pUser && CZNC::Get().FindUser(sUsername)) { - WebSock.PrintErrorPage("Invalid Submission [User " + sUsername + - " already exists]"); - return true; - } - - CUser* pNewUser = GetNewUser(WebSock, pUser); - if (!pNewUser) { - WebSock.PrintErrorPage("Invalid user settings"); - return true; - } - - CString sErr; - CString sAction; - - if (!pUser) { - CString sClone = WebSock.GetParam("clone"); - if (CUser* pCloneUser = CZNC::Get().FindUser(sClone)) { - pNewUser->CloneNetworks(*pCloneUser); - } - - // Add User Submission - if (!CZNC::Get().AddUser(pNewUser, sErr)) { - delete pNewUser; - WebSock.PrintErrorPage("Invalid submission [" + sErr + "]"); - return true; - } - - pUser = pNewUser; - sAction = "added"; - } else { - // Edit User Submission - if (!pUser->Clone(*pNewUser, sErr, false)) { - delete pNewUser; - WebSock.PrintErrorPage("Invalid Submission [" + sErr + "]"); - return true; - } - - delete pNewUser; - sAction = "edited"; - } - - CTemplate TmplMod; - TmplMod["Username"] = sUsername; - TmplMod["WebadminAction"] = "change"; - FOR_EACH_MODULE(it, pUser) { - (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/user", TmplMod); - } - - if (!CZNC::Get().WriteConfig()) { - WebSock.PrintErrorPage("User " + sAction + - ", but config was not written"); - return true; - } - - if (spSession->IsAdmin() && WebSock.HasParam("submit_return")) { - WebSock.Redirect(GetWebPath() + "listusers"); - } else { - WebSock.Redirect(GetWebPath() + "edituser?user=" + - pUser->GetUserName()); - } - - /* we don't want the template to be printed while we redirect */ - return false; - } - - bool ListUsersPage(CWebSock& WebSock, CTemplate& Tmpl) { - std::shared_ptr spSession = WebSock.GetSession(); - const map& msUsers = CZNC::Get().GetUserMap(); - Tmpl["Title"] = "Manage Users"; - Tmpl["Action"] = "listusers"; - - for (const auto& it : msUsers) { - CTemplate& l = Tmpl.AddRow("UserLoop"); - CUser* pUser = it.second; - - l["Username"] = pUser->GetUserName(); - l["Clients"] = CString(pUser->GetAllClients().size()); - l["Networks"] = CString(pUser->GetNetworks().size()); - - if (pUser == spSession->GetUser()) { - l["IsSelf"] = "true"; - } - } - - return true; - } - - bool TrafficPage(CWebSock& WebSock, CTemplate& Tmpl) { - std::shared_ptr spSession = WebSock.GetSession(); - Tmpl["Title"] = "Traffic Info"; - Tmpl["Uptime"] = CZNC::Get().GetUptime(); - - const map& msUsers = CZNC::Get().GetUserMap(); - Tmpl["TotalUsers"] = CString(msUsers.size()); - - size_t uiNetworks = 0, uiAttached = 0, uiClients = 0, uiServers = 0; - - for (const auto& it : msUsers) { - CUser* pUser = it.second; - - if (!spSession->IsAdmin() && spSession->GetUser() != it.second) { - continue; - } - - vector vNetworks = pUser->GetNetworks(); - - for (const CIRCNetwork* pNetwork : vNetworks) { - uiNetworks++; - - if (pNetwork->IsIRCConnected()) { - uiServers++; - } - - if (pNetwork->IsNetworkAttached()) { - uiAttached++; - } - - uiClients += pNetwork->GetClients().size(); - } - - uiClients += pUser->GetUserClients().size(); - } - - Tmpl["TotalNetworks"] = CString(uiNetworks); - Tmpl["AttachedNetworks"] = CString(uiAttached); - Tmpl["TotalCConnections"] = CString(uiClients); - Tmpl["TotalIRCConnections"] = CString(uiServers); - - CZNC::TrafficStatsPair Users, ZNC, Total; - CZNC::TrafficStatsMap traffic = - CZNC::Get().GetTrafficStats(Users, ZNC, Total); - - for (const auto& it : traffic) { - if (!spSession->IsAdmin() && - !spSession->GetUser()->GetUserName().Equals(it.first)) { - continue; - } - - CTemplate& l = Tmpl.AddRow("TrafficLoop"); - - l["Username"] = it.first; - l["In"] = CString::ToByteStr(it.second.first); - l["Out"] = CString::ToByteStr(it.second.second); - l["Total"] = CString::ToByteStr(it.second.first + it.second.second); - - CZNC::TrafficStatsPair NetworkTotal; - CZNC::TrafficStatsMap NetworkTraffic = - CZNC::Get().GetNetworkTrafficStats(it.first, NetworkTotal); - for (const auto& it2 : NetworkTraffic) { - CTemplate& l2 = Tmpl.AddRow("TrafficLoop"); - - l2["Network"] = it2.first; - l2["In"] = CString::ToByteStr(it2.second.first); - l2["Out"] = CString::ToByteStr(it2.second.second); - l2["Total"] = - CString::ToByteStr(it2.second.first + it2.second.second); - } - } - - Tmpl["UserIn"] = CString::ToByteStr(Users.first); - Tmpl["UserOut"] = CString::ToByteStr(Users.second); - Tmpl["UserTotal"] = CString::ToByteStr(Users.first + Users.second); - - Tmpl["ZNCIn"] = CString::ToByteStr(ZNC.first); - Tmpl["ZNCOut"] = CString::ToByteStr(ZNC.second); - Tmpl["ZNCTotal"] = CString::ToByteStr(ZNC.first + ZNC.second); - - Tmpl["AllIn"] = CString::ToByteStr(Total.first); - Tmpl["AllOut"] = CString::ToByteStr(Total.second); - Tmpl["AllTotal"] = CString::ToByteStr(Total.first + Total.second); - - return true; - } - - bool AddListener(CWebSock& WebSock, CTemplate& Tmpl) { - unsigned short uPort = WebSock.GetParam("port").ToUShort(); - CString sHost = WebSock.GetParam("host"); - CString sURIPrefix = WebSock.GetParam("uriprefix"); - if (sHost == "*") sHost = ""; - bool bSSL = WebSock.GetParam("ssl").ToBool(); - bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); - bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); - bool bIRC = WebSock.GetParam("irc").ToBool(); - bool bWeb = WebSock.GetParam("web").ToBool(); - - EAddrType eAddr = ADDR_ALL; - if (bIPv4) { - if (bIPv6) { - eAddr = ADDR_ALL; - } else { - eAddr = ADDR_IPV4ONLY; - } - } else { - if (bIPv6) { - eAddr = ADDR_IPV6ONLY; - } else { - WebSock.GetSession()->AddError( - "Choose either IPv4 or IPv6 or both."); - return SettingsPage(WebSock, Tmpl); - } - } - - CListener::EAcceptType eAccept; - if (bIRC) { - if (bWeb) { - eAccept = CListener::ACCEPT_ALL; - } else { - eAccept = CListener::ACCEPT_IRC; - } - } else { - if (bWeb) { - eAccept = CListener::ACCEPT_HTTP; - } else { - WebSock.GetSession()->AddError( - "Choose either IRC or Web or both."); - return SettingsPage(WebSock, Tmpl); - } - } - - CString sMessage; - if (CZNC::Get().AddListener(uPort, sHost, sURIPrefix, bSSL, eAddr, - eAccept, sMessage)) { - if (!sMessage.empty()) { - WebSock.GetSession()->AddSuccess(sMessage); - } - if (!CZNC::Get().WriteConfig()) { - WebSock.GetSession()->AddError( - "Port changed, but config was not written"); - } - } else { - WebSock.GetSession()->AddError(sMessage); - } - - return SettingsPage(WebSock, Tmpl); - } - - bool DelListener(CWebSock& WebSock, CTemplate& Tmpl) { - unsigned short uPort = WebSock.GetParam("port").ToUShort(); - CString sHost = WebSock.GetParam("host"); - bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); - bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); - - EAddrType eAddr = ADDR_ALL; - if (bIPv4) { - if (bIPv6) { - eAddr = ADDR_ALL; - } else { - eAddr = ADDR_IPV4ONLY; - } - } else { - if (bIPv6) { - eAddr = ADDR_IPV6ONLY; - } else { - WebSock.GetSession()->AddError("Invalid request."); - return SettingsPage(WebSock, Tmpl); - } - } - - CListener* pListener = CZNC::Get().FindListener(uPort, sHost, eAddr); - if (pListener) { - CZNC::Get().DelListener(pListener); - if (!CZNC::Get().WriteConfig()) { - WebSock.GetSession()->AddError( - "Port changed, but config was not written"); - } - } else { - WebSock.GetSession()->AddError( - "The specified listener was not found."); - } - - return SettingsPage(WebSock, Tmpl); - } - - bool SettingsPage(CWebSock& WebSock, CTemplate& Tmpl) { - Tmpl.SetFile("settings.tmpl"); - if (!WebSock.GetParam("submitted").ToUInt()) { - Tmpl["Action"] = "settings"; - Tmpl["Title"] = "Settings"; - Tmpl["StatusPrefix"] = CZNC::Get().GetStatusPrefix(); - Tmpl["MaxBufferSize"] = CString(CZNC::Get().GetMaxBufferSize()); - Tmpl["ConnectDelay"] = CString(CZNC::Get().GetConnectDelay()); - Tmpl["ServerThrottle"] = CString(CZNC::Get().GetServerThrottle()); - Tmpl["AnonIPLimit"] = CString(CZNC::Get().GetAnonIPLimit()); - Tmpl["ProtectWebSessions"] = - CString(CZNC::Get().GetProtectWebSessions()); - Tmpl["HideVersion"] = CString(CZNC::Get().GetHideVersion()); - - const VCString& vsMotd = CZNC::Get().GetMotd(); - for (const CString& sMotd : vsMotd) { - CTemplate& l = Tmpl.AddRow("MOTDLoop"); - l["Line"] = sMotd; - } - - const vector& vpListeners = CZNC::Get().GetListeners(); - for (const CListener* pListener : vpListeners) { - CTemplate& l = Tmpl.AddRow("ListenLoop"); - - l["Port"] = CString(pListener->GetPort()); - l["BindHost"] = pListener->GetBindHost(); - - l["IsWeb"] = CString(pListener->GetAcceptType() != - CListener::ACCEPT_IRC); - l["IsIRC"] = CString(pListener->GetAcceptType() != - CListener::ACCEPT_HTTP); - - l["URIPrefix"] = pListener->GetURIPrefix() + "/"; - - // simple protection for user from shooting his own foot - // TODO check also for hosts/families - // such check is only here, user still can forge HTTP request to - // delete web port - l["SuggestDeletion"] = - CString(pListener->GetPort() != WebSock.GetLocalPort()); + // To change BindHosts be admin or don't have DenySetBindHost + if (spSession->IsAdmin() || + !spSession->GetUser()->DenySetBindHost()) { + Tmpl["BindHostEdit"] = "true"; + if (pUser) { + Tmpl["BindHost"] = pUser->GetBindHost(); + Tmpl["DCCBindHost"] = pUser->GetDCCBindHost(); + } + } + + vector vDirs; + WebSock.GetAvailSkins(vDirs); + + for (const CString& SubDir : vDirs) { + CTemplate& l = Tmpl.AddRow("SkinLoop"); + l["Name"] = SubDir; + + if (pUser && SubDir == pUser->GetSkinName()) { + l["Checked"] = "true"; + } + } + + set ssUserMods; + CZNC::Get().GetModules().GetAvailableMods(ssUserMods); + + for (const CModInfo& Info : ssUserMods) { + CTemplate& l = Tmpl.AddRow("ModuleLoop"); + + l["Name"] = Info.GetName(); + l["Description"] = Info.GetDescription(); + l["Wiki"] = Info.GetWikiPage(); + l["HasArgs"] = CString(Info.GetHasArgs()); + l["ArgsHelpText"] = Info.GetArgsHelpText(); + + CModule* pModule = nullptr; + if (pUser) { + pModule = pUser->GetModules().FindModule(Info.GetName()); + // Check if module is loaded by all or some networks + const vector& userNetworks = + pUser->GetNetworks(); + unsigned int networksWithRenderedModuleCount = 0; + for (const CIRCNetwork* pCurrentNetwork : userNetworks) { + const CModules& networkModules = + pCurrentNetwork->GetModules(); + if (networkModules.FindModule(Info.GetName())) { + networksWithRenderedModuleCount++; + } + } + l["CanBeLoadedByNetwork"] = + CString(Info.SupportsType(CModInfo::NetworkModule)); + l["LoadedByAllNetworks"] = CString( + networksWithRenderedModuleCount == userNetworks.size()); + l["LoadedBySomeNetworks"] = + CString(networksWithRenderedModuleCount != 0); + } + if (pModule) { + l["Checked"] = "true"; + l["Args"] = pModule->GetArgs(); + if (CModInfo::UserModule == GetType() && + Info.GetName() == GetModName()) { + l["Disabled"] = "true"; + } + } + l["CanBeLoadedGlobally"] = + CString(Info.SupportsType(CModInfo::GlobalModule)); + // Check if module is loaded globally + l["LoadedGlobally"] = + CString(CZNC::Get().GetModules().FindModule( + Info.GetName()) != nullptr); + + if (!spSession->IsAdmin() && pUser && pUser->DenyLoadMod()) { + l["Disabled"] = "true"; + } + } + + CTemplate& o1 = Tmpl.AddRow("OptionLoop"); + o1["Name"] = "autoclearchanbuffer"; + o1["DisplayName"] = "Auto Clear Chan Buffer"; + o1["Tooltip"] = + "Automatically Clear Channel Buffer After Playback (the " + "default value for new channels)"; + if (!pUser || pUser->AutoClearChanBuffer()) { + o1["Checked"] = "true"; + } + + /* o2 used to be auto cycle which was removed */ + + CTemplate& o4 = Tmpl.AddRow("OptionLoop"); + o4["Name"] = "multiclients"; + o4["DisplayName"] = "Multi Clients"; + if (!pUser || pUser->MultiClients()) { + o4["Checked"] = "true"; + } + + CTemplate& o7 = Tmpl.AddRow("OptionLoop"); + o7["Name"] = "appendtimestamp"; + o7["DisplayName"] = "Append Timestamps"; + if (pUser && pUser->GetTimestampAppend()) { + o7["Checked"] = "true"; + } + + CTemplate& o8 = Tmpl.AddRow("OptionLoop"); + o8["Name"] = "prependtimestamp"; + o8["DisplayName"] = "Prepend Timestamps"; + if (pUser && pUser->GetTimestampPrepend()) { + o8["Checked"] = "true"; + } + + if (spSession->IsAdmin()) { + CTemplate& o9 = Tmpl.AddRow("OptionLoop"); + o9["Name"] = "denyloadmod"; + o9["DisplayName"] = "Deny LoadMod"; + if (pUser && pUser->DenyLoadMod()) { + o9["Checked"] = "true"; + } + + CTemplate& o10 = Tmpl.AddRow("OptionLoop"); + o10["Name"] = "isadmin"; + o10["DisplayName"] = "Admin"; + if (pUser && pUser->IsAdmin()) { + o10["Checked"] = "true"; + } + if (pUser && pUser == CZNC::Get().FindUser(WebSock.GetUser())) { + o10["Disabled"] = "true"; + } + + CTemplate& o11 = Tmpl.AddRow("OptionLoop"); + o11["Name"] = "denysetbindhost"; + o11["DisplayName"] = "Deny SetBindHost"; + if (pUser && pUser->DenySetBindHost()) { + o11["Checked"] = "true"; + } + } + + CTemplate& o12 = Tmpl.AddRow("OptionLoop"); + o12["Name"] = "autoclearquerybuffer"; + o12["DisplayName"] = "Auto Clear Query Buffer"; + o12["Tooltip"] = "Automatically Clear Query Buffer After Playback"; + if (!pUser || pUser->AutoClearQueryBuffer()) { + o12["Checked"] = "true"; + } + + FOR_EACH_MODULE(i, pUser) { + CTemplate& mod = Tmpl.AddRow("EmbeddedModuleLoop"); + mod.insert(Tmpl.begin(), Tmpl.end()); + mod["WebadminAction"] = "display"; + if ((*i)->OnEmbeddedWebRequest(WebSock, "webadmin/user", mod)) { + mod["Embed"] = WebSock.FindTmpl(*i, "WebadminUser.tmpl"); + mod["ModName"] = (*i)->GetModName(); + } + } + + return true; + } + + /* If pUser is nullptr, we are adding a user, else we are editing this + * one */ + + CString sUsername = WebSock.GetParam("user"); + if (!pUser && CZNC::Get().FindUser(sUsername)) { + WebSock.PrintErrorPage("Invalid Submission [User " + sUsername + + " already exists]"); + return true; + } + + CUser* pNewUser = GetNewUser(WebSock, pUser); + if (!pNewUser) { + WebSock.PrintErrorPage("Invalid user settings"); + return true; + } + + CString sErr; + CString sAction; + + if (!pUser) { + CString sClone = WebSock.GetParam("clone"); + if (CUser* pCloneUser = CZNC::Get().FindUser(sClone)) { + pNewUser->CloneNetworks(*pCloneUser); + } + + // Add User Submission + if (!CZNC::Get().AddUser(pNewUser, sErr)) { + delete pNewUser; + WebSock.PrintErrorPage("Invalid submission [" + sErr + "]"); + return true; + } + + pUser = pNewUser; + sAction = "added"; + } else { + // Edit User Submission + if (!pUser->Clone(*pNewUser, sErr, false)) { + delete pNewUser; + WebSock.PrintErrorPage("Invalid Submission [" + sErr + "]"); + return true; + } + + delete pNewUser; + sAction = "edited"; + } + + CTemplate TmplMod; + TmplMod["Username"] = sUsername; + TmplMod["WebadminAction"] = "change"; + FOR_EACH_MODULE(it, pUser) { + (*it)->OnEmbeddedWebRequest(WebSock, "webadmin/user", TmplMod); + } + + if (!CZNC::Get().WriteConfig()) { + WebSock.PrintErrorPage("User " + sAction + + ", but config was not written"); + return true; + } + + if (spSession->IsAdmin() && WebSock.HasParam("submit_return")) { + WebSock.Redirect(GetWebPath() + "listusers"); + } else { + WebSock.Redirect(GetWebPath() + "edituser?user=" + + pUser->GetUserName()); + } + + /* we don't want the template to be printed while we redirect */ + return false; + } + + bool ListUsersPage(CWebSock& WebSock, CTemplate& Tmpl) { + std::shared_ptr spSession = WebSock.GetSession(); + const map& msUsers = CZNC::Get().GetUserMap(); + Tmpl["Title"] = "Manage Users"; + Tmpl["Action"] = "listusers"; + + for (const auto& it : msUsers) { + CTemplate& l = Tmpl.AddRow("UserLoop"); + CUser* pUser = it.second; + + l["Username"] = pUser->GetUserName(); + l["Clients"] = CString(pUser->GetAllClients().size()); + l["Networks"] = CString(pUser->GetNetworks().size()); + + if (pUser == spSession->GetUser()) { + l["IsSelf"] = "true"; + } + } + + return true; + } + + bool TrafficPage(CWebSock& WebSock, CTemplate& Tmpl) { + std::shared_ptr spSession = WebSock.GetSession(); + Tmpl["Title"] = "Traffic Info"; + Tmpl["Uptime"] = CZNC::Get().GetUptime(); + + const map& msUsers = CZNC::Get().GetUserMap(); + Tmpl["TotalUsers"] = CString(msUsers.size()); + + size_t uiNetworks = 0, uiAttached = 0, uiClients = 0, uiServers = 0; + + for (const auto& it : msUsers) { + CUser* pUser = it.second; + + if (!spSession->IsAdmin() && spSession->GetUser() != it.second) { + continue; + } + + vector vNetworks = pUser->GetNetworks(); + + for (const CIRCNetwork* pNetwork : vNetworks) { + uiNetworks++; + + if (pNetwork->IsIRCConnected()) { + uiServers++; + } + + if (pNetwork->IsNetworkAttached()) { + uiAttached++; + } + + uiClients += pNetwork->GetClients().size(); + } + + uiClients += pUser->GetUserClients().size(); + } + + Tmpl["TotalNetworks"] = CString(uiNetworks); + Tmpl["AttachedNetworks"] = CString(uiAttached); + Tmpl["TotalCConnections"] = CString(uiClients); + Tmpl["TotalIRCConnections"] = CString(uiServers); + + CZNC::TrafficStatsPair Users, ZNC, Total; + CZNC::TrafficStatsMap traffic = + CZNC::Get().GetTrafficStats(Users, ZNC, Total); + + for (const auto& it : traffic) { + if (!spSession->IsAdmin() && + !spSession->GetUser()->GetUserName().Equals(it.first)) { + continue; + } + + CTemplate& l = Tmpl.AddRow("TrafficLoop"); + + l["Username"] = it.first; + l["In"] = CString::ToByteStr(it.second.first); + l["Out"] = CString::ToByteStr(it.second.second); + l["Total"] = CString::ToByteStr(it.second.first + it.second.second); + + CZNC::TrafficStatsPair NetworkTotal; + CZNC::TrafficStatsMap NetworkTraffic = + CZNC::Get().GetNetworkTrafficStats(it.first, NetworkTotal); + for (const auto& it2 : NetworkTraffic) { + CTemplate& l2 = Tmpl.AddRow("TrafficLoop"); + + l2["Network"] = it2.first; + l2["In"] = CString::ToByteStr(it2.second.first); + l2["Out"] = CString::ToByteStr(it2.second.second); + l2["Total"] = + CString::ToByteStr(it2.second.first + it2.second.second); + } + } + + Tmpl["UserIn"] = CString::ToByteStr(Users.first); + Tmpl["UserOut"] = CString::ToByteStr(Users.second); + Tmpl["UserTotal"] = CString::ToByteStr(Users.first + Users.second); + + Tmpl["ZNCIn"] = CString::ToByteStr(ZNC.first); + Tmpl["ZNCOut"] = CString::ToByteStr(ZNC.second); + Tmpl["ZNCTotal"] = CString::ToByteStr(ZNC.first + ZNC.second); + + Tmpl["AllIn"] = CString::ToByteStr(Total.first); + Tmpl["AllOut"] = CString::ToByteStr(Total.second); + Tmpl["AllTotal"] = CString::ToByteStr(Total.first + Total.second); + + return true; + } + + bool AddListener(CWebSock& WebSock, CTemplate& Tmpl) { + unsigned short uPort = WebSock.GetParam("port").ToUShort(); + CString sHost = WebSock.GetParam("host"); + CString sURIPrefix = WebSock.GetParam("uriprefix"); + if (sHost == "*") sHost = ""; + bool bSSL = WebSock.GetParam("ssl").ToBool(); + bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); + bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); + bool bIRC = WebSock.GetParam("irc").ToBool(); + bool bWeb = WebSock.GetParam("web").ToBool(); + + EAddrType eAddr = ADDR_ALL; + if (bIPv4) { + if (bIPv6) { + eAddr = ADDR_ALL; + } else { + eAddr = ADDR_IPV4ONLY; + } + } else { + if (bIPv6) { + eAddr = ADDR_IPV6ONLY; + } else { + WebSock.GetSession()->AddError( + "Choose either IPv4 or IPv6 or both."); + return SettingsPage(WebSock, Tmpl); + } + } + + CListener::EAcceptType eAccept; + if (bIRC) { + if (bWeb) { + eAccept = CListener::ACCEPT_ALL; + } else { + eAccept = CListener::ACCEPT_IRC; + } + } else { + if (bWeb) { + eAccept = CListener::ACCEPT_HTTP; + } else { + WebSock.GetSession()->AddError( + "Choose either IRC or Web or both."); + return SettingsPage(WebSock, Tmpl); + } + } + + CString sMessage; + if (CZNC::Get().AddListener(uPort, sHost, sURIPrefix, bSSL, eAddr, + eAccept, sMessage)) { + if (!sMessage.empty()) { + WebSock.GetSession()->AddSuccess(sMessage); + } + if (!CZNC::Get().WriteConfig()) { + WebSock.GetSession()->AddError( + "Port changed, but config was not written"); + } + } else { + WebSock.GetSession()->AddError(sMessage); + } + + return SettingsPage(WebSock, Tmpl); + } + + bool DelListener(CWebSock& WebSock, CTemplate& Tmpl) { + unsigned short uPort = WebSock.GetParam("port").ToUShort(); + CString sHost = WebSock.GetParam("host"); + bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); + bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); + + EAddrType eAddr = ADDR_ALL; + if (bIPv4) { + if (bIPv6) { + eAddr = ADDR_ALL; + } else { + eAddr = ADDR_IPV4ONLY; + } + } else { + if (bIPv6) { + eAddr = ADDR_IPV6ONLY; + } else { + WebSock.GetSession()->AddError("Invalid request."); + return SettingsPage(WebSock, Tmpl); + } + } + + CListener* pListener = CZNC::Get().FindListener(uPort, sHost, eAddr); + if (pListener) { + CZNC::Get().DelListener(pListener); + if (!CZNC::Get().WriteConfig()) { + WebSock.GetSession()->AddError( + "Port changed, but config was not written"); + } + } else { + WebSock.GetSession()->AddError( + "The specified listener was not found."); + } + + return SettingsPage(WebSock, Tmpl); + } + + bool SettingsPage(CWebSock& WebSock, CTemplate& Tmpl) { + Tmpl.SetFile("settings.tmpl"); + if (!WebSock.GetParam("submitted").ToUInt()) { + Tmpl["Action"] = "settings"; + Tmpl["Title"] = "Settings"; + Tmpl["StatusPrefix"] = CZNC::Get().GetStatusPrefix(); + Tmpl["MaxBufferSize"] = CString(CZNC::Get().GetMaxBufferSize()); + Tmpl["ConnectDelay"] = CString(CZNC::Get().GetConnectDelay()); + Tmpl["ServerThrottle"] = CString(CZNC::Get().GetServerThrottle()); + Tmpl["AnonIPLimit"] = CString(CZNC::Get().GetAnonIPLimit()); + Tmpl["ProtectWebSessions"] = + CString(CZNC::Get().GetProtectWebSessions()); + Tmpl["HideVersion"] = CString(CZNC::Get().GetHideVersion()); + + const VCString& vsMotd = CZNC::Get().GetMotd(); + for (const CString& sMotd : vsMotd) { + CTemplate& l = Tmpl.AddRow("MOTDLoop"); + l["Line"] = sMotd; + } + + const vector& vpListeners = CZNC::Get().GetListeners(); + for (const CListener* pListener : vpListeners) { + CTemplate& l = Tmpl.AddRow("ListenLoop"); + + l["Port"] = CString(pListener->GetPort()); + l["BindHost"] = pListener->GetBindHost(); + + l["IsWeb"] = CString(pListener->GetAcceptType() != + CListener::ACCEPT_IRC); + l["IsIRC"] = CString(pListener->GetAcceptType() != + CListener::ACCEPT_HTTP); + + l["URIPrefix"] = pListener->GetURIPrefix() + "/"; + + // simple protection for user from shooting his own foot + // TODO check also for hosts/families + // such check is only here, user still can forge HTTP request to + // delete web port + l["SuggestDeletion"] = + CString(pListener->GetPort() != WebSock.GetLocalPort()); #ifdef HAVE_LIBSSL - if (pListener->IsSSL()) { - l["IsSSL"] = "true"; - } + if (pListener->IsSSL()) { + l["IsSSL"] = "true"; + } #endif #ifdef HAVE_IPV6 - switch (pListener->GetAddrType()) { - case ADDR_IPV4ONLY: - l["IsIPV4"] = "true"; - break; - case ADDR_IPV6ONLY: - l["IsIPV6"] = "true"; - break; - case ADDR_ALL: - l["IsIPV4"] = "true"; - l["IsIPV6"] = "true"; - break; - } + switch (pListener->GetAddrType()) { + case ADDR_IPV4ONLY: + l["IsIPV4"] = "true"; + break; + case ADDR_IPV6ONLY: + l["IsIPV6"] = "true"; + break; + case ADDR_ALL: + l["IsIPV4"] = "true"; + l["IsIPV6"] = "true"; + break; + } #else - l["IsIPV4"] = "true"; + l["IsIPV4"] = "true"; #endif - } + } - vector vDirs; - WebSock.GetAvailSkins(vDirs); + vector vDirs; + WebSock.GetAvailSkins(vDirs); - for (const CString& SubDir : vDirs) { - CTemplate& l = Tmpl.AddRow("SkinLoop"); - l["Name"] = SubDir; + for (const CString& SubDir : vDirs) { + CTemplate& l = Tmpl.AddRow("SkinLoop"); + l["Name"] = SubDir; - if (SubDir == CZNC::Get().GetSkinName()) { - l["Checked"] = "true"; - } - } + if (SubDir == CZNC::Get().GetSkinName()) { + l["Checked"] = "true"; + } + } - set ssGlobalMods; - CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, - CModInfo::GlobalModule); + set ssGlobalMods; + CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, + CModInfo::GlobalModule); - for (const CModInfo& Info : ssGlobalMods) { - CTemplate& l = Tmpl.AddRow("ModuleLoop"); + for (const CModInfo& Info : ssGlobalMods) { + CTemplate& l = Tmpl.AddRow("ModuleLoop"); - CModule* pModule = - CZNC::Get().GetModules().FindModule(Info.GetName()); - if (pModule) { - l["Checked"] = "true"; - l["Args"] = pModule->GetArgs(); - if (CModInfo::GlobalModule == GetType() && - Info.GetName() == GetModName()) { - l["Disabled"] = "true"; - } - } + CModule* pModule = + CZNC::Get().GetModules().FindModule(Info.GetName()); + if (pModule) { + l["Checked"] = "true"; + l["Args"] = pModule->GetArgs(); + if (CModInfo::GlobalModule == GetType() && + Info.GetName() == GetModName()) { + l["Disabled"] = "true"; + } + } - l["Name"] = Info.GetName(); - l["Description"] = Info.GetDescription(); - l["Wiki"] = Info.GetWikiPage(); - l["HasArgs"] = CString(Info.GetHasArgs()); - l["ArgsHelpText"] = Info.GetArgsHelpText(); + l["Name"] = Info.GetName(); + l["Description"] = Info.GetDescription(); + l["Wiki"] = Info.GetWikiPage(); + l["HasArgs"] = CString(Info.GetHasArgs()); + l["ArgsHelpText"] = Info.GetArgsHelpText(); - // Check if the module is loaded by all or some users, and/or by - // all or some networks - unsigned int usersWithRenderedModuleCount = 0; - unsigned int networksWithRenderedModuleCount = 0; - unsigned int networksCount = 0; - const map& allUsers = CZNC::Get().GetUserMap(); - for (const auto& it : allUsers) { - const CUser* pUser = it.second; + // Check if the module is loaded by all or some users, and/or by + // all or some networks + unsigned int usersWithRenderedModuleCount = 0; + unsigned int networksWithRenderedModuleCount = 0; + unsigned int networksCount = 0; + const map& allUsers = CZNC::Get().GetUserMap(); + for (const auto& it : allUsers) { + const CUser* pUser = it.second; - // Count users which has loaded a render module - const CModules& userModules = pUser->GetModules(); - if (userModules.FindModule(Info.GetName())) { - usersWithRenderedModuleCount++; - } - // Count networks which has loaded a render module - const vector& userNetworks = - pUser->GetNetworks(); - networksCount += userNetworks.size(); - for (const CIRCNetwork* pCurrentNetwork : userNetworks) { - if (pCurrentNetwork->GetModules().FindModule( - Info.GetName())) { - networksWithRenderedModuleCount++; - } - } - } - l["CanBeLoadedByNetwork"] = - CString(Info.SupportsType(CModInfo::NetworkModule)); - l["LoadedByAllNetworks"] = - CString(networksWithRenderedModuleCount == networksCount); - l["LoadedBySomeNetworks"] = - CString(networksWithRenderedModuleCount != 0); + // Count users which has loaded a render module + const CModules& userModules = pUser->GetModules(); + if (userModules.FindModule(Info.GetName())) { + usersWithRenderedModuleCount++; + } + // Count networks which has loaded a render module + const vector& userNetworks = + pUser->GetNetworks(); + networksCount += userNetworks.size(); + for (const CIRCNetwork* pCurrentNetwork : userNetworks) { + if (pCurrentNetwork->GetModules().FindModule( + Info.GetName())) { + networksWithRenderedModuleCount++; + } + } + } + l["CanBeLoadedByNetwork"] = + CString(Info.SupportsType(CModInfo::NetworkModule)); + l["LoadedByAllNetworks"] = + CString(networksWithRenderedModuleCount == networksCount); + l["LoadedBySomeNetworks"] = + CString(networksWithRenderedModuleCount != 0); - l["CanBeLoadedByUser"] = - CString(Info.SupportsType(CModInfo::UserModule)); - l["LoadedByAllUsers"] = - CString(usersWithRenderedModuleCount == allUsers.size()); - l["LoadedBySomeUsers"] = - CString(usersWithRenderedModuleCount != 0); - } + l["CanBeLoadedByUser"] = + CString(Info.SupportsType(CModInfo::UserModule)); + l["LoadedByAllUsers"] = + CString(usersWithRenderedModuleCount == allUsers.size()); + l["LoadedBySomeUsers"] = + CString(usersWithRenderedModuleCount != 0); + } - return true; - } + return true; + } - CString sArg; - sArg = WebSock.GetParam("statusprefix"); - CZNC::Get().SetStatusPrefix(sArg); - sArg = WebSock.GetParam("maxbufsize"); - CZNC::Get().SetMaxBufferSize(sArg.ToUInt()); - sArg = WebSock.GetParam("connectdelay"); - CZNC::Get().SetConnectDelay(sArg.ToUInt()); - sArg = WebSock.GetParam("serverthrottle"); - CZNC::Get().SetServerThrottle(sArg.ToUInt()); - sArg = WebSock.GetParam("anoniplimit"); - CZNC::Get().SetAnonIPLimit(sArg.ToUInt()); - sArg = WebSock.GetParam("protectwebsessions"); - CZNC::Get().SetProtectWebSessions(sArg.ToBool()); - sArg = WebSock.GetParam("hideversion"); - CZNC::Get().SetHideVersion(sArg.ToBool()); + CString sArg; + sArg = WebSock.GetParam("statusprefix"); + CZNC::Get().SetStatusPrefix(sArg); + sArg = WebSock.GetParam("maxbufsize"); + CZNC::Get().SetMaxBufferSize(sArg.ToUInt()); + sArg = WebSock.GetParam("connectdelay"); + CZNC::Get().SetConnectDelay(sArg.ToUInt()); + sArg = WebSock.GetParam("serverthrottle"); + CZNC::Get().SetServerThrottle(sArg.ToUInt()); + sArg = WebSock.GetParam("anoniplimit"); + CZNC::Get().SetAnonIPLimit(sArg.ToUInt()); + sArg = WebSock.GetParam("protectwebsessions"); + CZNC::Get().SetProtectWebSessions(sArg.ToBool()); + sArg = WebSock.GetParam("hideversion"); + CZNC::Get().SetHideVersion(sArg.ToBool()); - VCString vsArgs; - WebSock.GetRawParam("motd").Split("\n", vsArgs); - CZNC::Get().ClearMotd(); + VCString vsArgs; + WebSock.GetRawParam("motd").Split("\n", vsArgs); + CZNC::Get().ClearMotd(); - for (const CString& sMotd : vsArgs) { - CZNC::Get().AddMotd(sMotd.TrimRight_n()); - } + for (const CString& sMotd : vsArgs) { + CZNC::Get().AddMotd(sMotd.TrimRight_n()); + } - CZNC::Get().SetSkinName(WebSock.GetParam("skin")); + CZNC::Get().SetSkinName(WebSock.GetParam("skin")); - set ssArgs; - WebSock.GetParamValues("loadmod", ssArgs); + set ssArgs; + WebSock.GetParamValues("loadmod", ssArgs); - for (const CString& s : ssArgs) { - CString sModRet; - CString sModName = s.TrimRight_n("\r"); - CString sModLoadError; + for (const CString& s : ssArgs) { + CString sModRet; + CString sModName = s.TrimRight_n("\r"); + CString sModLoadError; - if (!sModName.empty()) { - CString sArgs = WebSock.GetParam("modargs_" + sModName); + if (!sModName.empty()) { + CString sArgs = WebSock.GetParam("modargs_" + sModName); - CModule* pMod = CZNC::Get().GetModules().FindModule(sModName); - if (!pMod) { - if (!CZNC::Get().GetModules().LoadModule( - sModName, sArgs, CModInfo::GlobalModule, nullptr, - nullptr, sModRet)) { - sModLoadError = "Unable to load module [" + sModName + - "] [" + sModRet + "]"; - } - } else if (pMod->GetArgs() != sArgs) { - if (!CZNC::Get().GetModules().ReloadModule( - sModName, sArgs, nullptr, nullptr, sModRet)) { - sModLoadError = "Unable to reload module [" + sModName + - "] [" + sModRet + "]"; - } - } + CModule* pMod = CZNC::Get().GetModules().FindModule(sModName); + if (!pMod) { + if (!CZNC::Get().GetModules().LoadModule( + sModName, sArgs, CModInfo::GlobalModule, nullptr, + nullptr, sModRet)) { + sModLoadError = "Unable to load module [" + sModName + + "] [" + sModRet + "]"; + } + } else if (pMod->GetArgs() != sArgs) { + if (!CZNC::Get().GetModules().ReloadModule( + sModName, sArgs, nullptr, nullptr, sModRet)) { + sModLoadError = "Unable to reload module [" + sModName + + "] [" + sModRet + "]"; + } + } - if (!sModLoadError.empty()) { - DEBUG(sModLoadError); - WebSock.GetSession()->AddError(sModLoadError); - } - } - } + if (!sModLoadError.empty()) { + DEBUG(sModLoadError); + WebSock.GetSession()->AddError(sModLoadError); + } + } + } - const CModules& vCurMods = CZNC::Get().GetModules(); - set ssUnloadMods; + const CModules& vCurMods = CZNC::Get().GetModules(); + set ssUnloadMods; - for (const CModule* pCurMod : vCurMods) { - if (ssArgs.find(pCurMod->GetModName()) == ssArgs.end() && - (CModInfo::GlobalModule != GetType() || - pCurMod->GetModName() != GetModName())) { - ssUnloadMods.insert(pCurMod->GetModName()); - } - } + for (const CModule* pCurMod : vCurMods) { + if (ssArgs.find(pCurMod->GetModName()) == ssArgs.end() && + (CModInfo::GlobalModule != GetType() || + pCurMod->GetModName() != GetModName())) { + ssUnloadMods.insert(pCurMod->GetModName()); + } + } - for (const CString& sMod : ssUnloadMods) { - CZNC::Get().GetModules().UnloadModule(sMod); - } + for (const CString& sMod : ssUnloadMods) { + CZNC::Get().GetModules().UnloadModule(sMod); + } - if (!CZNC::Get().WriteConfig()) { - WebSock.GetSession()->AddError( - "Settings changed, but config was not written"); - } + if (!CZNC::Get().WriteConfig()) { + WebSock.GetSession()->AddError( + "Settings changed, but config was not written"); + } - WebSock.Redirect(GetWebPath() + "settings"); - /* we don't want the template to be printed while we redirect */ - return false; - } + WebSock.Redirect(GetWebPath() + "settings"); + /* we don't want the template to be printed while we redirect */ + return false; + } }; template <> void TModInfo(CModInfo& Info) { - Info.AddType(CModInfo::UserModule); - Info.SetWikiPage("webadmin"); + Info.AddType(CModInfo::UserModule); + Info.SetWikiPage("webadmin"); } GLOBALMODULEDEFS(CWebAdminMod, "Web based administration module.") diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 6439df71..64926d4e 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -25,69 +25,69 @@ CBufLine::CBufLine(const CMessage& Format, const CString& sText) CBufLine::CBufLine(const CString& sFormat, const CString& sText, const timeval* ts, const MCString& mssTags) : m_sText(sText) { - m_Message.Parse(sFormat); - m_Message.SetTags(mssTags); + m_Message.Parse(sFormat); + m_Message.SetTags(mssTags); - if (ts == nullptr) - UpdateTime(); - else - m_Message.SetTime(*ts); + if (ts == nullptr) + UpdateTime(); + else + m_Message.SetTime(*ts); } CBufLine::~CBufLine() {} void CBufLine::UpdateTime() { - timeval tv; - if (0 != gettimeofday(&tv, nullptr)) { - tv.tv_sec = time(nullptr); - tv.tv_usec = 0; - } - m_Message.SetTime(tv); + timeval tv; + if (0 != gettimeofday(&tv, nullptr)) { + tv.tv_sec = time(nullptr); + tv.tv_usec = 0; + } + m_Message.SetTime(tv); } CMessage CBufLine::ToMessage(const CClient& Client, const MCString& mssParams) const { - CMessage Line = m_Message; + CMessage Line = m_Message; - CString sSender = Line.GetNick().GetNickMask(); - Line.SetNick(CNick(CString::NamedFormat(sSender, mssParams))); + CString sSender = Line.GetNick().GetNickMask(); + Line.SetNick(CNick(CString::NamedFormat(sSender, mssParams))); - MCString mssThisParams = mssParams; - if (Client.HasServerTime()) { - mssThisParams["text"] = m_sText; - } else { - mssThisParams["text"] = - Client.GetUser()->AddTimestamp(Line.GetTime().tv_sec, m_sText); - } + MCString mssThisParams = mssParams; + if (Client.HasServerTime()) { + mssThisParams["text"] = m_sText; + } else { + mssThisParams["text"] = + Client.GetUser()->AddTimestamp(Line.GetTime().tv_sec, m_sText); + } - // make a copy of params, because the following loop modifies the original - VCString vsParams = Line.GetParams(); - for (unsigned int uIdx = 0; uIdx < vsParams.size(); ++uIdx) { - Line.SetParam(uIdx, - CString::NamedFormat(vsParams[uIdx], mssThisParams)); - } + // make a copy of params, because the following loop modifies the original + VCString vsParams = Line.GetParams(); + for (unsigned int uIdx = 0; uIdx < vsParams.size(); ++uIdx) { + Line.SetParam(uIdx, + CString::NamedFormat(vsParams[uIdx], mssThisParams)); + } - return Line; + return Line; } CString CBufLine::GetLine(const CClient& Client, const MCString& mssParams) const { - CMessage Line = ToMessage(Client, mssParams); + CMessage Line = ToMessage(Client, mssParams); - // Note: Discard all tags (except the time tag, conditionally) to - // keep the same behavior as ZNC versions 1.6 and earlier had. See - // CClient::PutClient(CMessage) documentation for more details. - Line.SetTags(MCString::EmptyMap); + // Note: Discard all tags (except the time tag, conditionally) to + // keep the same behavior as ZNC versions 1.6 and earlier had. See + // CClient::PutClient(CMessage) documentation for more details. + Line.SetTags(MCString::EmptyMap); - if (Client.HasServerTime()) { - CString sTime = m_Message.GetTag("time"); - if (sTime.empty()) { - sTime = CUtils::FormatServerTime(m_Message.GetTime()); - } - Line.SetTag("time", sTime); - } + if (Client.HasServerTime()) { + CString sTime = m_Message.GetTag("time"); + if (sTime.empty()) { + sTime = CUtils::FormatServerTime(m_Message.GetTime()); + } + Line.SetTag("time", sTime); + } - return Line.ToString(); + return Line.ToString(); } CBuffer::CBuffer(unsigned int uLineCount) : m_uLineCount(uLineCount) {} @@ -96,84 +96,84 @@ CBuffer::~CBuffer() {} CBuffer::size_type CBuffer::AddLine(const CMessage& Format, const CString& sText) { - if (!m_uLineCount) { - return 0; - } + if (!m_uLineCount) { + return 0; + } - while (size() >= m_uLineCount) { - erase(begin()); - } + while (size() >= m_uLineCount) { + erase(begin()); + } - push_back(CBufLine(Format, sText)); - return size(); + push_back(CBufLine(Format, sText)); + return size(); } CBuffer::size_type CBuffer::UpdateLine(const CString& sCommand, const CMessage& Format, const CString& sText) { - for (CBufLine& Line : *this) { - if (Line.GetCommand().Equals(sCommand)) { - Line = CBufLine(Format, sText); - return size(); - } - } + for (CBufLine& Line : *this) { + if (Line.GetCommand().Equals(sCommand)) { + Line = CBufLine(Format, sText); + return size(); + } + } - return AddLine(Format, sText); + return AddLine(Format, sText); } CBuffer::size_type CBuffer::UpdateExactLine(const CMessage& Format, const CString& sText) { - for (CBufLine& Line : *this) { - if (Line.Equals(Format)) { - return size(); - } - } + for (CBufLine& Line : *this) { + if (Line.Equals(Format)) { + return size(); + } + } - return AddLine(Format, sText); + return AddLine(Format, sText); } CBuffer::size_type CBuffer::AddLine(const CString& sFormat, const CString& sText, const timeval* ts, const MCString& mssTags) { - CMessage Message(sFormat); - if (ts) { - Message.SetTime(*ts); - } - Message.SetTags(mssTags); - return AddLine(Message, sText); + CMessage Message(sFormat); + if (ts) { + Message.SetTime(*ts); + } + Message.SetTags(mssTags); + return AddLine(Message, sText); } CBuffer::size_type CBuffer::UpdateLine(const CString& sMatch, const CString& sFormat, const CString& sText) { - return UpdateLine(CMessage(sMatch).GetCommand(), CMessage(sFormat), sText); + return UpdateLine(CMessage(sMatch).GetCommand(), CMessage(sFormat), sText); } CBuffer::size_type CBuffer::UpdateExactLine(const CString& sFormat, const CString& sText) { - return UpdateExactLine(CMessage(sFormat, sText)); + return UpdateExactLine(CMessage(sFormat, sText)); } const CBufLine& CBuffer::GetBufLine(unsigned int uIdx) const { - return (*this)[uIdx]; + return (*this)[uIdx]; } CString CBuffer::GetLine(size_type uIdx, const CClient& Client, const MCString& msParams) const { - return (*this)[uIdx].GetLine(Client, msParams); + return (*this)[uIdx].GetLine(Client, msParams); } bool CBuffer::SetLineCount(unsigned int u, bool bForce) { - if (!bForce && u > CZNC::Get().GetMaxBufferSize()) { - return false; - } + if (!bForce && u > CZNC::Get().GetMaxBufferSize()) { + return false; + } - m_uLineCount = u; + m_uLineCount = u; - // We may need to shrink the buffer if the allowed size got smaller - while (size() > m_uLineCount) { - erase(begin()); - } + // We may need to shrink the buffer if the allowed size got smaller + while (size() > m_uLineCount) { + erase(begin()); + } - return true; + return true; } diff --git a/src/Chan.cpp b/src/Chan.cpp index e099d74b..b0eebb60 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -49,670 +49,670 @@ CChan::CChan(const CString& sName, CIRCNetwork* pNetwork, bool bInConfig, m_Buffer(), m_bModeKnown(false), m_musModes() { - if (!m_pNetwork->IsChan(m_sName)) { - m_sName = "#" + m_sName; - } + if (!m_pNetwork->IsChan(m_sName)) { + m_sName = "#" + m_sName; + } - m_Nick.SetNetwork(m_pNetwork); - m_Buffer.SetLineCount(m_pNetwork->GetUser()->GetChanBufferSize(), true); + m_Nick.SetNetwork(m_pNetwork); + m_Buffer.SetLineCount(m_pNetwork->GetUser()->GetChanBufferSize(), true); - if (pConfig) { - CString sValue; - if (pConfig->FindStringEntry("buffer", sValue)) - SetBufferCount(sValue.ToUInt(), true); - if (pConfig->FindStringEntry("autoclearchanbuffer", sValue)) - SetAutoClearChanBuffer(sValue.ToBool()); - if (pConfig->FindStringEntry("keepbuffer", sValue)) - // XXX Compatibility crap, added in 0.207 - SetAutoClearChanBuffer(!sValue.ToBool()); - if (pConfig->FindStringEntry("detached", sValue)) - SetDetached(sValue.ToBool()); - if (pConfig->FindStringEntry("disabled", sValue)) - if (sValue.ToBool()) Disable(); - if (pConfig->FindStringEntry("autocycle", sValue)) - if (sValue.Equals("true")) - CUtils::PrintError( - "WARNING: AutoCycle has been removed, instead try -> " - "LoadModule = autocycle " + - sName); - if (pConfig->FindStringEntry("key", sValue)) SetKey(sValue); - if (pConfig->FindStringEntry("modes", sValue)) SetDefaultModes(sValue); - } + if (pConfig) { + CString sValue; + if (pConfig->FindStringEntry("buffer", sValue)) + SetBufferCount(sValue.ToUInt(), true); + if (pConfig->FindStringEntry("autoclearchanbuffer", sValue)) + SetAutoClearChanBuffer(sValue.ToBool()); + if (pConfig->FindStringEntry("keepbuffer", sValue)) + // XXX Compatibility crap, added in 0.207 + SetAutoClearChanBuffer(!sValue.ToBool()); + if (pConfig->FindStringEntry("detached", sValue)) + SetDetached(sValue.ToBool()); + if (pConfig->FindStringEntry("disabled", sValue)) + if (sValue.ToBool()) Disable(); + if (pConfig->FindStringEntry("autocycle", sValue)) + if (sValue.Equals("true")) + CUtils::PrintError( + "WARNING: AutoCycle has been removed, instead try -> " + "LoadModule = autocycle " + + sName); + if (pConfig->FindStringEntry("key", sValue)) SetKey(sValue); + if (pConfig->FindStringEntry("modes", sValue)) SetDefaultModes(sValue); + } } CChan::~CChan() { ClearNicks(); } void CChan::Reset() { - m_bIsOn = false; - m_bModeKnown = false; - m_musModes.clear(); - m_sTopic = ""; - m_sTopicOwner = ""; - m_ulTopicDate = 0; - m_ulCreationDate = 0; - m_Nick.Reset(); - ClearNicks(); - ResetJoinTries(); + m_bIsOn = false; + m_bModeKnown = false; + m_musModes.clear(); + m_sTopic = ""; + m_sTopicOwner = ""; + m_ulTopicDate = 0; + m_ulCreationDate = 0; + m_Nick.Reset(); + ClearNicks(); + ResetJoinTries(); } CConfig CChan::ToConfig() const { - CConfig config; + CConfig config; - if (m_bHasBufferCountSet) - config.AddKeyValuePair("Buffer", CString(GetBufferCount())); - if (m_bHasAutoClearChanBufferSet) - config.AddKeyValuePair("AutoClearChanBuffer", - CString(AutoClearChanBuffer())); - if (IsDetached()) config.AddKeyValuePair("Detached", "true"); - if (IsDisabled()) config.AddKeyValuePair("Disabled", "true"); - if (!GetKey().empty()) config.AddKeyValuePair("Key", GetKey()); - if (!GetDefaultModes().empty()) - config.AddKeyValuePair("Modes", GetDefaultModes()); + if (m_bHasBufferCountSet) + config.AddKeyValuePair("Buffer", CString(GetBufferCount())); + if (m_bHasAutoClearChanBufferSet) + config.AddKeyValuePair("AutoClearChanBuffer", + CString(AutoClearChanBuffer())); + if (IsDetached()) config.AddKeyValuePair("Detached", "true"); + if (IsDisabled()) config.AddKeyValuePair("Disabled", "true"); + if (!GetKey().empty()) config.AddKeyValuePair("Key", GetKey()); + if (!GetDefaultModes().empty()) + config.AddKeyValuePair("Modes", GetDefaultModes()); - return config; + return config; } void CChan::Clone(CChan& chan) { - // We assume that m_sName and m_pNetwork are equal - SetBufferCount(chan.GetBufferCount(), true); - SetAutoClearChanBuffer(chan.AutoClearChanBuffer()); - SetKey(chan.GetKey()); - SetDefaultModes(chan.GetDefaultModes()); + // We assume that m_sName and m_pNetwork are equal + SetBufferCount(chan.GetBufferCount(), true); + SetAutoClearChanBuffer(chan.AutoClearChanBuffer()); + SetKey(chan.GetKey()); + SetDefaultModes(chan.GetDefaultModes()); - if (IsDetached() != chan.IsDetached()) { - // Only send something if it makes sense - // (= Only detach if client is on the channel - // and only attach if we are on the channel) - if (IsOn()) { - if (IsDetached()) { - AttachUser(); - } else { - DetachUser(); - } - } - SetDetached(chan.IsDetached()); - } + if (IsDetached() != chan.IsDetached()) { + // Only send something if it makes sense + // (= Only detach if client is on the channel + // and only attach if we are on the channel) + if (IsOn()) { + if (IsDetached()) { + AttachUser(); + } else { + DetachUser(); + } + } + SetDetached(chan.IsDetached()); + } } void CChan::Cycle() const { - m_pNetwork->PutIRC("PART " + GetName() + "\r\nJOIN " + GetName() + " " + - GetKey()); + m_pNetwork->PutIRC("PART " + GetName() + "\r\nJOIN " + GetName() + " " + + GetKey()); } void CChan::JoinUser(const CString& sKey) { - if (!IsOn() && !sKey.empty()) { - SetKey(sKey); - } - m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); + if (!IsOn() && !sKey.empty()) { + SetKey(sKey); + } + m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); } void CChan::AttachUser(CClient* pClient) { - m_pNetwork->PutUser( - ":" + m_pNetwork->GetIRCNick().GetNickMask() + " JOIN :" + GetName(), - pClient); + m_pNetwork->PutUser( + ":" + m_pNetwork->GetIRCNick().GetNickMask() + " JOIN :" + GetName(), + pClient); - if (!GetTopic().empty()) { - m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 332 " + - m_pNetwork->GetIRCNick().GetNick() + " " + - GetName() + " :" + GetTopic(), - pClient); - m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 333 " + - m_pNetwork->GetIRCNick().GetNick() + " " + - GetName() + " " + GetTopicOwner() + " " + - CString(GetTopicDate()), - pClient); - } + if (!GetTopic().empty()) { + m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 332 " + + m_pNetwork->GetIRCNick().GetNick() + " " + + GetName() + " :" + GetTopic(), + pClient); + m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 333 " + + m_pNetwork->GetIRCNick().GetNick() + " " + + GetName() + " " + GetTopicOwner() + " " + + CString(GetTopicDate()), + pClient); + } - CString sPre = ":" + m_pNetwork->GetIRCServer() + " 353 " + - m_pNetwork->GetIRCNick().GetNick() + " " + - GetModeForNames() + " " + GetName() + " :"; - CString sLine = sPre; - CString sPerm, sNick; + CString sPre = ":" + m_pNetwork->GetIRCServer() + " 353 " + + m_pNetwork->GetIRCNick().GetNick() + " " + + GetModeForNames() + " " + GetName() + " :"; + CString sLine = sPre; + CString sPerm, sNick; - const vector& vpClients = m_pNetwork->GetClients(); - for (CClient* pEachClient : vpClients) { - CClient* pThisClient; - if (!pClient) - pThisClient = pEachClient; - else - pThisClient = pClient; + const vector& vpClients = m_pNetwork->GetClients(); + for (CClient* pEachClient : vpClients) { + CClient* pThisClient; + if (!pClient) + pThisClient = pEachClient; + else + pThisClient = pClient; - for (map::iterator a = m_msNicks.begin(); - a != m_msNicks.end(); ++a) { - if (pThisClient->HasNamesx()) { - sPerm = a->second.GetPermStr(); - } else { - char c = a->second.GetPermChar(); - sPerm = ""; - if (c != '\0') { - sPerm += c; - } - } - if (pThisClient->HasUHNames() && !a->second.GetIdent().empty() && - !a->second.GetHost().empty()) { - sNick = a->first + "!" + a->second.GetIdent() + "@" + - a->second.GetHost(); - } else { - sNick = a->first; - } + for (map::iterator a = m_msNicks.begin(); + a != m_msNicks.end(); ++a) { + if (pThisClient->HasNamesx()) { + sPerm = a->second.GetPermStr(); + } else { + char c = a->second.GetPermChar(); + sPerm = ""; + if (c != '\0') { + sPerm += c; + } + } + if (pThisClient->HasUHNames() && !a->second.GetIdent().empty() && + !a->second.GetHost().empty()) { + sNick = a->first + "!" + a->second.GetIdent() + "@" + + a->second.GetHost(); + } else { + sNick = a->first; + } - sLine += sPerm + sNick; + sLine += sPerm + sNick; - if (sLine.size() >= 490 || a == (--m_msNicks.end())) { - m_pNetwork->PutUser(sLine, pThisClient); - sLine = sPre; - } else { - sLine += " "; - } - } + if (sLine.size() >= 490 || a == (--m_msNicks.end())) { + m_pNetwork->PutUser(sLine, pThisClient); + sLine = sPre; + } else { + sLine += " "; + } + } - if (pClient) // We only want to do this for one client - break; - } + if (pClient) // We only want to do this for one client + break; + } - m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 366 " + - m_pNetwork->GetIRCNick().GetNick() + " " + - GetName() + " :End of /NAMES list.", - pClient); - m_bDetached = false; + m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 366 " + + m_pNetwork->GetIRCNick().GetNick() + " " + + GetName() + " :End of /NAMES list.", + pClient); + m_bDetached = false; - // Send Buffer - SendBuffer(pClient); + // Send Buffer + SendBuffer(pClient); } void CChan::DetachUser() { - if (!m_bDetached) { - m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + - " PART " + GetName()); - m_bDetached = true; - } + if (!m_bDetached) { + m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + + " PART " + GetName()); + m_bDetached = true; + } } CString CChan::GetModeString() const { - CString sModes, sArgs; + CString sModes, sArgs; - for (const auto& it : m_musModes) { - sModes += it.first; - if (it.second.size()) { - sArgs += " " + it.second; - } - } + for (const auto& it : m_musModes) { + sModes += it.first; + if (it.second.size()) { + sArgs += " " + it.second; + } + } - return sModes.empty() ? sModes : CString("+" + sModes + sArgs); + return sModes.empty() ? sModes : CString("+" + sModes + sArgs); } CString CChan::GetModeForNames() const { - CString sMode; + CString sMode; - for (const auto& it : m_musModes) { - if (it.first == 's') { - sMode = "@"; - } else if ((it.first == 'p') && sMode.empty()) { - sMode = "*"; - } - } + for (const auto& it : m_musModes) { + if (it.first == 's') { + sMode = "@"; + } else if ((it.first == 'p') && sMode.empty()) { + sMode = "*"; + } + } - return (sMode.empty() ? "=" : sMode); + return (sMode.empty() ? "=" : sMode); } void CChan::SetModes(const CString& sModes) { - m_musModes.clear(); - ModeChange(sModes); + m_musModes.clear(); + ModeChange(sModes); } void CChan::SetAutoClearChanBuffer(bool b) { - m_bHasAutoClearChanBufferSet = true; - m_bAutoClearChanBuffer = b; + m_bHasAutoClearChanBufferSet = true; + m_bAutoClearChanBuffer = b; - if (m_bAutoClearChanBuffer && !IsDetached() && m_pNetwork->IsUserOnline()) { - ClearBuffer(); - } + if (m_bAutoClearChanBuffer && !IsDetached() && m_pNetwork->IsUserOnline()) { + ClearBuffer(); + } } void CChan::InheritAutoClearChanBuffer(bool b) { - if (!m_bHasAutoClearChanBufferSet) { - m_bAutoClearChanBuffer = b; + if (!m_bHasAutoClearChanBufferSet) { + m_bAutoClearChanBuffer = b; - if (m_bAutoClearChanBuffer && !IsDetached() && - m_pNetwork->IsUserOnline()) { - ClearBuffer(); - } - } + if (m_bAutoClearChanBuffer && !IsDetached() && + m_pNetwork->IsUserOnline()) { + ClearBuffer(); + } + } } void CChan::ResetAutoClearChanBuffer() { - SetAutoClearChanBuffer(m_pNetwork->GetUser()->AutoClearChanBuffer()); - m_bHasAutoClearChanBufferSet = false; + SetAutoClearChanBuffer(m_pNetwork->GetUser()->AutoClearChanBuffer()); + m_bHasAutoClearChanBufferSet = false; } void CChan::OnWho(const CString& sNick, const CString& sIdent, const CString& sHost) { - CNick* pNick = FindNick(sNick); + CNick* pNick = FindNick(sNick); - if (pNick) { - pNick->SetIdent(sIdent); - pNick->SetHost(sHost); - } + if (pNick) { + pNick->SetIdent(sIdent); + pNick->SetHost(sHost); + } } void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { - CString sModeArg = sModes.Token(0); - CString sArgs = sModes.Token(1, true); - bool bAdd = true; + CString sModeArg = sModes.Token(0); + CString sArgs = sModes.Token(1, true); + bool bAdd = true; - /* Try to find a CNick* from this channel so that pOpNick->HasPerm() - * works as expected. */ - if (pOpNick) { - CNick* OpNick = FindNick(pOpNick->GetNick()); - /* If nothing was found, use the original pOpNick, else use the - * CNick* from FindNick() */ - if (OpNick) pOpNick = OpNick; - } + /* Try to find a CNick* from this channel so that pOpNick->HasPerm() + * works as expected. */ + if (pOpNick) { + CNick* OpNick = FindNick(pOpNick->GetNick()); + /* If nothing was found, use the original pOpNick, else use the + * CNick* from FindNick() */ + if (OpNick) pOpNick = OpNick; + } - NETWORKMODULECALL(OnRawMode2(pOpNick, *this, sModeArg, sArgs), - m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); + NETWORKMODULECALL(OnRawMode2(pOpNick, *this, sModeArg, sArgs), + m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); - for (unsigned int a = 0; a < sModeArg.size(); a++) { - const unsigned char& uMode = sModeArg[a]; + for (unsigned int a = 0; a < sModeArg.size(); a++) { + const unsigned char& uMode = sModeArg[a]; - if (uMode == '+') { - bAdd = true; - } else if (uMode == '-') { - bAdd = false; - } else if (m_pNetwork->GetIRCSock()->IsPermMode(uMode)) { - CString sArg = GetModeArg(sArgs); - CNick* pNick = FindNick(sArg); - if (pNick) { - unsigned char uPerm = - m_pNetwork->GetIRCSock()->GetPermFromMode(uMode); + if (uMode == '+') { + bAdd = true; + } else if (uMode == '-') { + bAdd = false; + } else if (m_pNetwork->GetIRCSock()->IsPermMode(uMode)) { + CString sArg = GetModeArg(sArgs); + CNick* pNick = FindNick(sArg); + if (pNick) { + unsigned char uPerm = + m_pNetwork->GetIRCSock()->GetPermFromMode(uMode); - if (uPerm) { - bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); + if (uPerm) { + bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); - if (bAdd) { - pNick->AddPerm(uPerm); + if (bAdd) { + pNick->AddPerm(uPerm); - if (pNick->NickEquals(m_pNetwork->GetCurNick())) { - AddPerm(uPerm); - } - } else { - pNick->RemPerm(uPerm); + if (pNick->NickEquals(m_pNetwork->GetCurNick())) { + AddPerm(uPerm); + } + } else { + pNick->RemPerm(uPerm); - if (pNick->NickEquals(m_pNetwork->GetCurNick())) { - RemPerm(uPerm); - } - } + if (pNick->NickEquals(m_pNetwork->GetCurNick())) { + RemPerm(uPerm); + } + } - NETWORKMODULECALL(OnChanPermission2(pOpNick, *pNick, *this, - uMode, bAdd, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, - nullptr, NOTHING); + NETWORKMODULECALL(OnChanPermission2(pOpNick, *pNick, *this, + uMode, bAdd, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, + nullptr, NOTHING); - if (uMode == CChan::M_Op) { - if (bAdd) { - NETWORKMODULECALL( - OnOp2(pOpNick, *pNick, *this, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - NOTHING); - } else { - NETWORKMODULECALL( - OnDeop2(pOpNick, *pNick, *this, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - NOTHING); - } - } else if (uMode == CChan::M_Voice) { - if (bAdd) { - NETWORKMODULECALL( - OnVoice2(pOpNick, *pNick, *this, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - NOTHING); - } else { - NETWORKMODULECALL( - OnDevoice2(pOpNick, *pNick, *this, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - NOTHING); - } - } - } - } - } else { - bool bList = false; - CString sArg; + if (uMode == CChan::M_Op) { + if (bAdd) { + NETWORKMODULECALL( + OnOp2(pOpNick, *pNick, *this, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + NOTHING); + } else { + NETWORKMODULECALL( + OnDeop2(pOpNick, *pNick, *this, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + NOTHING); + } + } else if (uMode == CChan::M_Voice) { + if (bAdd) { + NETWORKMODULECALL( + OnVoice2(pOpNick, *pNick, *this, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + NOTHING); + } else { + NETWORKMODULECALL( + OnDevoice2(pOpNick, *pNick, *this, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + NOTHING); + } + } + } + } + } else { + bool bList = false; + CString sArg; - switch (m_pNetwork->GetIRCSock()->GetModeType(uMode)) { - case CIRCSock::ListArg: - bList = true; - sArg = GetModeArg(sArgs); - break; - case CIRCSock::HasArg: - sArg = GetModeArg(sArgs); - break; - case CIRCSock::NoArg: - break; - case CIRCSock::ArgWhenSet: - if (bAdd) { - sArg = GetModeArg(sArgs); - } + switch (m_pNetwork->GetIRCSock()->GetModeType(uMode)) { + case CIRCSock::ListArg: + bList = true; + sArg = GetModeArg(sArgs); + break; + case CIRCSock::HasArg: + sArg = GetModeArg(sArgs); + break; + case CIRCSock::NoArg: + break; + case CIRCSock::ArgWhenSet: + if (bAdd) { + sArg = GetModeArg(sArgs); + } - break; - } + break; + } - bool bNoChange; - if (bList) { - bNoChange = false; - } else if (bAdd) { - bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; - } else { - bNoChange = !HasMode(uMode); - } - NETWORKMODULECALL( - OnMode2(pOpNick, *this, uMode, sArg, bAdd, bNoChange), - m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); + bool bNoChange; + if (bList) { + bNoChange = false; + } else if (bAdd) { + bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; + } else { + bNoChange = !HasMode(uMode); + } + NETWORKMODULECALL( + OnMode2(pOpNick, *this, uMode, sArg, bAdd, bNoChange), + m_pNetwork->GetUser(), m_pNetwork, nullptr, NOTHING); - if (!bList) { - (bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); - } + if (!bList) { + (bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); + } - // This is called when we join (ZNC requests the channel modes - // on join) *and* when someone changes the channel keys. - // We ignore channel key "*" because of some broken nets. - if (uMode == M_Key && !bNoChange && bAdd && sArg != "*") { - SetKey(sArg); - } - } - } + // This is called when we join (ZNC requests the channel modes + // on join) *and* when someone changes the channel keys. + // We ignore channel key "*" because of some broken nets. + if (uMode == M_Key && !bNoChange && bAdd && sArg != "*") { + SetKey(sArg); + } + } + } } CString CChan::GetOptions() const { - VCString vsRet; + VCString vsRet; - if (IsDetached()) { - vsRet.push_back("Detached"); - } + if (IsDetached()) { + vsRet.push_back("Detached"); + } - if (AutoClearChanBuffer()) { - if (HasAutoClearChanBufferSet()) { - vsRet.push_back("AutoClearChanBuffer"); - } else { - vsRet.push_back("AutoClearChanBuffer (default)"); - } - } + if (AutoClearChanBuffer()) { + if (HasAutoClearChanBufferSet()) { + vsRet.push_back("AutoClearChanBuffer"); + } else { + vsRet.push_back("AutoClearChanBuffer (default)"); + } + } - return CString(", ").Join(vsRet.begin(), vsRet.end()); + return CString(", ").Join(vsRet.begin(), vsRet.end()); } CString CChan::GetModeArg(unsigned char uMode) const { - if (uMode) { - map::const_iterator it = m_musModes.find(uMode); + if (uMode) { + map::const_iterator it = m_musModes.find(uMode); - if (it != m_musModes.end()) { - return it->second; - } - } + if (it != m_musModes.end()) { + return it->second; + } + } - return ""; + return ""; } bool CChan::HasMode(unsigned char uMode) const { - return (uMode && m_musModes.find(uMode) != m_musModes.end()); + return (uMode && m_musModes.find(uMode) != m_musModes.end()); } bool CChan::AddMode(unsigned char uMode, const CString& sArg) { - m_musModes[uMode] = sArg; - return true; + m_musModes[uMode] = sArg; + return true; } bool CChan::RemMode(unsigned char uMode) { - if (!HasMode(uMode)) { - return false; - } + if (!HasMode(uMode)) { + return false; + } - m_musModes.erase(uMode); - return true; + m_musModes.erase(uMode); + return true; } CString CChan::GetModeArg(CString& sArgs) const { - CString sRet = sArgs.substr(0, sArgs.find(' ')); - sArgs = (sRet.size() < sArgs.size()) ? sArgs.substr(sRet.size() + 1) : ""; - return sRet; + CString sRet = sArgs.substr(0, sArgs.find(' ')); + sArgs = (sRet.size() < sArgs.size()) ? sArgs.substr(sRet.size() + 1) : ""; + return sRet; } void CChan::ClearNicks() { m_msNicks.clear(); } int CChan::AddNicks(const CString& sNicks) { - int iRet = 0; - VCString vsNicks; + int iRet = 0; + VCString vsNicks; - sNicks.Split(" ", vsNicks, false); + sNicks.Split(" ", vsNicks, false); - for (const CString& sNick : vsNicks) { - if (AddNick(sNick)) { - iRet++; - } - } + for (const CString& sNick : vsNicks) { + if (AddNick(sNick)) { + iRet++; + } + } - return iRet; + return iRet; } bool CChan::AddNick(const CString& sNick) { - const char* p = sNick.c_str(); - CString sPrefix, sTmp, sIdent, sHost; + const char* p = sNick.c_str(); + CString sPrefix, sTmp, sIdent, sHost; - while (m_pNetwork->GetIRCSock()->IsPermChar(*p)) { - sPrefix += *p; + while (m_pNetwork->GetIRCSock()->IsPermChar(*p)) { + sPrefix += *p; - if (!*++p) { - return false; - } - } + if (!*++p) { + return false; + } + } - sTmp = p; + sTmp = p; - // The UHNames extension gets us nick!ident@host instead of just plain nick - sIdent = sTmp.Token(1, true, "!"); - sHost = sIdent.Token(1, true, "@"); - sIdent = sIdent.Token(0, false, "@"); - // Get the nick - sTmp = sTmp.Token(0, false, "!"); + // The UHNames extension gets us nick!ident@host instead of just plain nick + sIdent = sTmp.Token(1, true, "!"); + sHost = sIdent.Token(1, true, "@"); + sIdent = sIdent.Token(0, false, "@"); + // Get the nick + sTmp = sTmp.Token(0, false, "!"); - CNick tmpNick(sTmp); - CNick* pNick = FindNick(sTmp); - if (!pNick) { - pNick = &tmpNick; - pNick->SetNetwork(m_pNetwork); - } + CNick tmpNick(sTmp); + CNick* pNick = FindNick(sTmp); + if (!pNick) { + pNick = &tmpNick; + pNick->SetNetwork(m_pNetwork); + } - if (!sIdent.empty()) pNick->SetIdent(sIdent); - if (!sHost.empty()) pNick->SetHost(sHost); + if (!sIdent.empty()) pNick->SetIdent(sIdent); + if (!sHost.empty()) pNick->SetHost(sHost); - for (CString::size_type i = 0; i < sPrefix.length(); i++) { - pNick->AddPerm(sPrefix[i]); - } + for (CString::size_type i = 0; i < sPrefix.length(); i++) { + pNick->AddPerm(sPrefix[i]); + } - if (pNick->NickEquals(m_pNetwork->GetCurNick())) { - for (CString::size_type i = 0; i < sPrefix.length(); i++) { - AddPerm(sPrefix[i]); - } - } + if (pNick->NickEquals(m_pNetwork->GetCurNick())) { + for (CString::size_type i = 0; i < sPrefix.length(); i++) { + AddPerm(sPrefix[i]); + } + } - m_msNicks[pNick->GetNick()] = *pNick; + m_msNicks[pNick->GetNick()] = *pNick; - return true; + return true; } map CChan::GetPermCounts() const { - map mRet; + map mRet; - for (const auto& it : m_msNicks) { - CString sPerms = it.second.GetPermStr(); + for (const auto& it : m_msNicks) { + CString sPerms = it.second.GetPermStr(); - for (unsigned int p = 0; p < sPerms.size(); p++) { - mRet[sPerms[p]]++; - } - } + for (unsigned int p = 0; p < sPerms.size(); p++) { + mRet[sPerms[p]]++; + } + } - return mRet; + return mRet; } bool CChan::RemNick(const CString& sNick) { - map::iterator it; - set::iterator it2; + map::iterator it; + set::iterator it2; - it = m_msNicks.find(sNick); - if (it == m_msNicks.end()) { - return false; - } + it = m_msNicks.find(sNick); + if (it == m_msNicks.end()) { + return false; + } - m_msNicks.erase(it); + m_msNicks.erase(it); - return true; + return true; } bool CChan::ChangeNick(const CString& sOldNick, const CString& sNewNick) { - map::iterator it = m_msNicks.find(sOldNick); + map::iterator it = m_msNicks.find(sOldNick); - if (it == m_msNicks.end()) { - return false; - } + if (it == m_msNicks.end()) { + return false; + } - // Rename this nick - it->second.SetNick(sNewNick); + // Rename this nick + it->second.SetNick(sNewNick); - // Insert a new element into the map then erase the old one, do this to - // change the key to the new nick - m_msNicks[sNewNick] = it->second; - m_msNicks.erase(it); + // Insert a new element into the map then erase the old one, do this to + // change the key to the new nick + m_msNicks[sNewNick] = it->second; + m_msNicks.erase(it); - return true; + return true; } const CNick* CChan::FindNick(const CString& sNick) const { - map::const_iterator it = m_msNicks.find(sNick); - return (it != m_msNicks.end()) ? &it->second : nullptr; + map::const_iterator it = m_msNicks.find(sNick); + return (it != m_msNicks.end()) ? &it->second : nullptr; } CNick* CChan::FindNick(const CString& sNick) { - map::iterator it = m_msNicks.find(sNick); - return (it != m_msNicks.end()) ? &it->second : nullptr; + map::iterator it = m_msNicks.find(sNick); + return (it != m_msNicks.end()) ? &it->second : nullptr; } void CChan::SendBuffer(CClient* pClient) { - SendBuffer(pClient, m_Buffer); - if (AutoClearChanBuffer()) { - ClearBuffer(); - } + SendBuffer(pClient, m_Buffer); + if (AutoClearChanBuffer()) { + ClearBuffer(); + } } void CChan::SendBuffer(CClient* pClient, const CBuffer& Buffer) { - if (m_pNetwork && m_pNetwork->IsUserAttached()) { - // in the event that pClient is nullptr, need to send this to all - // clients for the user I'm presuming here that pClient is listed - // inside vClients thus vClients at this point can't be empty. - // - // This loop has to be cycled twice to maintain the existing behavior - // which is - // 1. OnChanBufferStarting - // 2. OnChanBufferPlayLine - // 3. ClearBuffer() if not keeping the buffer - // 4. OnChanBufferEnding - // - // With the exception of ClearBuffer(), this needs to happen per - // client, and if pClient is not nullptr, the loops break after the - // first iteration. - // - // Rework this if you like ... - if (!Buffer.IsEmpty()) { - const vector& vClients = m_pNetwork->GetClients(); - for (CClient* pEachClient : vClients) { - CClient* pUseClient = (pClient ? pClient : pEachClient); + if (m_pNetwork && m_pNetwork->IsUserAttached()) { + // in the event that pClient is nullptr, need to send this to all + // clients for the user I'm presuming here that pClient is listed + // inside vClients thus vClients at this point can't be empty. + // + // This loop has to be cycled twice to maintain the existing behavior + // which is + // 1. OnChanBufferStarting + // 2. OnChanBufferPlayLine + // 3. ClearBuffer() if not keeping the buffer + // 4. OnChanBufferEnding + // + // With the exception of ClearBuffer(), this needs to happen per + // client, and if pClient is not nullptr, the loops break after the + // first iteration. + // + // Rework this if you like ... + if (!Buffer.IsEmpty()) { + const vector& vClients = m_pNetwork->GetClients(); + for (CClient* pEachClient : vClients) { + CClient* pUseClient = (pClient ? pClient : pEachClient); - bool bWasPlaybackActive = pUseClient->IsPlaybackActive(); - pUseClient->SetPlaybackActive(true); + bool bWasPlaybackActive = pUseClient->IsPlaybackActive(); + pUseClient->SetPlaybackActive(true); - bool bSkipStatusMsg = pUseClient->HasServerTime(); - NETWORKMODULECALL(OnChanBufferStarting(*this, *pUseClient), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - &bSkipStatusMsg); + bool bSkipStatusMsg = pUseClient->HasServerTime(); + NETWORKMODULECALL(OnChanBufferStarting(*this, *pUseClient), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + &bSkipStatusMsg); - if (!bSkipStatusMsg) { - m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + - " :Buffer Playback...", - pUseClient); - } + if (!bSkipStatusMsg) { + m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + + " :Buffer Playback...", + pUseClient); + } - bool bBatch = pUseClient->HasBatch(); - CString sBatchName = GetName().MD5(); + bool bBatch = pUseClient->HasBatch(); + CString sBatchName = GetName().MD5(); - if (bBatch) { - m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + - " znc.in/playback " + GetName(), - pUseClient); - } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + + " znc.in/playback " + GetName(), + pUseClient); + } - size_t uSize = Buffer.Size(); - for (size_t uIdx = 0; uIdx < uSize; uIdx++) { - const CBufLine& BufLine = Buffer.GetBufLine(uIdx); - CMessage Message = - BufLine.ToMessage(*pUseClient, MCString::EmptyMap); - Message.SetChan(this); - Message.SetNetwork(m_pNetwork); - Message.SetClient(pClient); - if (bBatch) { - Message.SetTag("batch", sBatchName); - } - bool bNotShowThisLine = false; - NETWORKMODULECALL(OnChanBufferPlayMessage(Message), - m_pNetwork->GetUser(), m_pNetwork, - nullptr, &bNotShowThisLine); - if (bNotShowThisLine) continue; - m_pNetwork->PutUser(Message, pUseClient); - } + size_t uSize = Buffer.Size(); + for (size_t uIdx = 0; uIdx < uSize; uIdx++) { + const CBufLine& BufLine = Buffer.GetBufLine(uIdx); + CMessage Message = + BufLine.ToMessage(*pUseClient, MCString::EmptyMap); + Message.SetChan(this); + Message.SetNetwork(m_pNetwork); + Message.SetClient(pClient); + if (bBatch) { + Message.SetTag("batch", sBatchName); + } + bool bNotShowThisLine = false; + NETWORKMODULECALL(OnChanBufferPlayMessage(Message), + m_pNetwork->GetUser(), m_pNetwork, + nullptr, &bNotShowThisLine); + if (bNotShowThisLine) continue; + m_pNetwork->PutUser(Message, pUseClient); + } - bSkipStatusMsg = pUseClient->HasServerTime(); - NETWORKMODULECALL(OnChanBufferEnding(*this, *pUseClient), - m_pNetwork->GetUser(), m_pNetwork, nullptr, - &bSkipStatusMsg); - if (!bSkipStatusMsg) { - m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + - " :Playback Complete.", - pUseClient); - } + bSkipStatusMsg = pUseClient->HasServerTime(); + NETWORKMODULECALL(OnChanBufferEnding(*this, *pUseClient), + m_pNetwork->GetUser(), m_pNetwork, nullptr, + &bSkipStatusMsg); + if (!bSkipStatusMsg) { + m_pNetwork->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + + " :Playback Complete.", + pUseClient); + } - if (bBatch) { - m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, - pUseClient); - } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, + pUseClient); + } - pUseClient->SetPlaybackActive(bWasPlaybackActive); + pUseClient->SetPlaybackActive(bWasPlaybackActive); - if (pClient) break; - } - } - } + if (pClient) break; + } + } + } } void CChan::Enable() { - ResetJoinTries(); - m_bDisabled = false; + ResetJoinTries(); + m_bDisabled = false; } void CChan::SetKey(const CString& s) { - if (m_sKey != s) { - m_sKey = s; - if (m_bInConfig) { - CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); - } - } + if (m_sKey != s) { + m_sKey = s; + if (m_bInConfig) { + CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); + } + } } void CChan::SetInConfig(bool b) { - if (m_bInConfig != b) { - m_bInConfig = b; - CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); - } + if (m_bInConfig != b) { + m_bInConfig = b; + CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); + } } void CChan::ResetBufferCount() { - SetBufferCount(m_pNetwork->GetUser()->GetBufferCount()); - m_bHasBufferCountSet = false; + SetBufferCount(m_pNetwork->GetUser()->GetBufferCount()); + m_bHasBufferCountSet = false; } diff --git a/src/Client.cpp b/src/Client.cpp index 962a2074..79338959 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -26,297 +26,297 @@ using std::map; using std::vector; #define CALLMOD(MOD, CLIENT, USER, NETWORK, FUNC) \ - { \ - CModule* pModule = nullptr; \ - if (NETWORK && (pModule = (NETWORK)->GetModules().FindModule(MOD))) { \ - try { \ - pModule->SetClient(CLIENT); \ - pModule->FUNC; \ - pModule->SetClient(nullptr); \ - } catch (const CModule::EModException& e) { \ - if (e == CModule::UNLOAD) { \ - (NETWORK)->GetModules().UnloadModule(MOD); \ - } \ - } \ - } else if ((pModule = (USER)->GetModules().FindModule(MOD))) { \ - try { \ - pModule->SetClient(CLIENT); \ - pModule->SetNetwork(NETWORK); \ - pModule->FUNC; \ - pModule->SetClient(nullptr); \ - pModule->SetNetwork(nullptr); \ - } catch (const CModule::EModException& e) { \ - if (e == CModule::UNLOAD) { \ - (USER)->GetModules().UnloadModule(MOD); \ - } \ - } \ - } else if ((pModule = CZNC::Get().GetModules().FindModule(MOD))) { \ - try { \ - pModule->SetClient(CLIENT); \ - pModule->SetNetwork(NETWORK); \ - pModule->SetUser(USER); \ - pModule->FUNC; \ - pModule->SetClient(nullptr); \ - pModule->SetNetwork(nullptr); \ - pModule->SetUser(nullptr); \ - } catch (const CModule::EModException& e) { \ - if (e == CModule::UNLOAD) { \ - CZNC::Get().GetModules().UnloadModule(MOD); \ - } \ - } \ - } else { \ - PutStatus("No such module [" + MOD + "]"); \ - } \ - } + { \ + CModule* pModule = nullptr; \ + if (NETWORK && (pModule = (NETWORK)->GetModules().FindModule(MOD))) { \ + try { \ + pModule->SetClient(CLIENT); \ + pModule->FUNC; \ + pModule->SetClient(nullptr); \ + } catch (const CModule::EModException& e) { \ + if (e == CModule::UNLOAD) { \ + (NETWORK)->GetModules().UnloadModule(MOD); \ + } \ + } \ + } else if ((pModule = (USER)->GetModules().FindModule(MOD))) { \ + try { \ + pModule->SetClient(CLIENT); \ + pModule->SetNetwork(NETWORK); \ + pModule->FUNC; \ + pModule->SetClient(nullptr); \ + pModule->SetNetwork(nullptr); \ + } catch (const CModule::EModException& e) { \ + if (e == CModule::UNLOAD) { \ + (USER)->GetModules().UnloadModule(MOD); \ + } \ + } \ + } else if ((pModule = CZNC::Get().GetModules().FindModule(MOD))) { \ + try { \ + pModule->SetClient(CLIENT); \ + pModule->SetNetwork(NETWORK); \ + pModule->SetUser(USER); \ + pModule->FUNC; \ + pModule->SetClient(nullptr); \ + pModule->SetNetwork(nullptr); \ + pModule->SetUser(nullptr); \ + } catch (const CModule::EModException& e) { \ + if (e == CModule::UNLOAD) { \ + CZNC::Get().GetModules().UnloadModule(MOD); \ + } \ + } \ + } else { \ + PutStatus("No such module [" + MOD + "]"); \ + } \ + } CClient::~CClient() { - if (m_spAuth) { - CClientAuth* pAuth = (CClientAuth*)&(*m_spAuth); - pAuth->Invalidate(); - } - if (m_pUser != nullptr) { - m_pUser->AddBytesRead(GetBytesRead()); - m_pUser->AddBytesWritten(GetBytesWritten()); - } + if (m_spAuth) { + CClientAuth* pAuth = (CClientAuth*)&(*m_spAuth); + pAuth->Invalidate(); + } + if (m_pUser != nullptr) { + m_pUser->AddBytesRead(GetBytesRead()); + m_pUser->AddBytesWritten(GetBytesWritten()); + } } void CClient::SendRequiredPasswordNotice() { - PutClient(":irc.znc.in 464 " + GetNick() + " :Password required"); - PutClient( - ":irc.znc.in NOTICE AUTH :*** " - "You need to send your password. " - "Configure your client to send a server password."); - PutClient( - ":irc.znc.in NOTICE AUTH :*** " - "To connect now, you can use /quote PASS :, " - "or /quote PASS /: to connect to a " - "specific network."); + PutClient(":irc.znc.in 464 " + GetNick() + " :Password required"); + PutClient( + ":irc.znc.in NOTICE AUTH :*** " + "You need to send your password. " + "Configure your client to send a server password."); + PutClient( + ":irc.znc.in NOTICE AUTH :*** " + "To connect now, you can use /quote PASS :, " + "or /quote PASS /: to connect to a " + "specific network."); } void CClient::ReadLine(const CString& sData) { - CString sLine = sData; + CString sLine = sData; - sLine.TrimRight("\n\r"); + sLine.TrimRight("\n\r"); - DEBUG("(" << GetFullName() << ") CLI -> ZNC [" << sLine << "]"); + DEBUG("(" << GetFullName() << ") CLI -> ZNC [" << sLine << "]"); - MCString mssTags; - if (sLine.StartsWith("@")) { - mssTags = CUtils::GetMessageTags(sLine); - sLine = sLine.Token(1, true); - } + MCString mssTags; + if (sLine.StartsWith("@")) { + mssTags = CUtils::GetMessageTags(sLine); + sLine = sLine.Token(1, true); + } - bool bReturn = false; - if (IsAttached()) { - NETWORKMODULECALL(OnUserRaw(sLine), m_pUser, m_pNetwork, this, - &bReturn); - } else { - GLOBALMODULECALL(OnUnknownUserRaw(this, sLine), &bReturn); - } - if (bReturn) return; + bool bReturn = false; + if (IsAttached()) { + NETWORKMODULECALL(OnUserRaw(sLine), m_pUser, m_pNetwork, this, + &bReturn); + } else { + GLOBALMODULECALL(OnUnknownUserRaw(this, sLine), &bReturn); + } + if (bReturn) return; - CMessage Message(sLine); - Message.SetClient(this); - Message.SetTags(mssTags); + CMessage Message(sLine); + Message.SetClient(this); + Message.SetTags(mssTags); - if (IsAttached()) { - NETWORKMODULECALL(OnUserRawMessage(Message), m_pUser, m_pNetwork, this, - &bReturn); - } else { - GLOBALMODULECALL(OnUnknownUserRawMessage(Message), &bReturn); - } - if (bReturn) return; + if (IsAttached()) { + NETWORKMODULECALL(OnUserRawMessage(Message), m_pUser, m_pNetwork, this, + &bReturn); + } else { + GLOBALMODULECALL(OnUnknownUserRawMessage(Message), &bReturn); + } + if (bReturn) return; - CString sCommand = Message.GetCommand(); + CString sCommand = Message.GetCommand(); - if (!IsAttached()) { - // The following commands happen before authentication with ZNC - if (sCommand.Equals("PASS")) { - m_bGotPass = true; + if (!IsAttached()) { + // The following commands happen before authentication with ZNC + if (sCommand.Equals("PASS")) { + m_bGotPass = true; - CString sAuthLine = Message.GetParam(0); - ParsePass(sAuthLine); + CString sAuthLine = Message.GetParam(0); + ParsePass(sAuthLine); - AuthUser(); - // Don't forward this msg. ZNC has already registered us. - return; - } else if (sCommand.Equals("NICK")) { - CString sNick = Message.GetParam(0); + AuthUser(); + // Don't forward this msg. ZNC has already registered us. + return; + } else if (sCommand.Equals("NICK")) { + CString sNick = Message.GetParam(0); - m_sNick = sNick; - m_bGotNick = true; + m_sNick = sNick; + m_bGotNick = true; - AuthUser(); - // Don't forward this msg. ZNC will handle nick changes until auth - // is complete - return; - } else if (sCommand.Equals("USER")) { - CString sAuthLine = Message.GetParam(0); + AuthUser(); + // Don't forward this msg. ZNC will handle nick changes until auth + // is complete + return; + } else if (sCommand.Equals("USER")) { + CString sAuthLine = Message.GetParam(0); - if (m_sUser.empty() && !sAuthLine.empty()) { - ParseUser(sAuthLine); - } + if (m_sUser.empty() && !sAuthLine.empty()) { + ParseUser(sAuthLine); + } - m_bGotUser = true; - if (m_bGotPass) { - AuthUser(); - } else if (!m_bInCap) { - SendRequiredPasswordNotice(); - } + m_bGotUser = true; + if (m_bGotPass) { + AuthUser(); + } else if (!m_bInCap) { + SendRequiredPasswordNotice(); + } - // Don't forward this msg. ZNC has already registered us. - return; - } - } + // Don't forward this msg. ZNC has already registered us. + return; + } + } - if (Message.GetType() == CMessage::Type::Capability) { - HandleCap(Message); + if (Message.GetType() == CMessage::Type::Capability) { + HandleCap(Message); - // Don't let the client talk to the server directly about CAP, - // we don't want anything enabled that ZNC does not support. - return; - } + // Don't let the client talk to the server directly about CAP, + // we don't want anything enabled that ZNC does not support. + return; + } - if (!m_pUser) { - // Only CAP, NICK, USER and PASS are allowed before login - return; - } + if (!m_pUser) { + // Only CAP, NICK, USER and PASS are allowed before login + return; + } - switch (Message.GetType()) { - case CMessage::Type::Action: - bReturn = OnActionMessage(Message); - break; - case CMessage::Type::CTCP: - bReturn = OnCTCPMessage(Message); - break; - case CMessage::Type::Join: - bReturn = OnJoinMessage(Message); - break; - case CMessage::Type::Mode: - bReturn = OnModeMessage(Message); - break; - case CMessage::Type::Notice: - bReturn = OnNoticeMessage(Message); - break; - case CMessage::Type::Part: - bReturn = OnPartMessage(Message); - break; - case CMessage::Type::Ping: - bReturn = OnPingMessage(Message); - break; - case CMessage::Type::Pong: - bReturn = OnPongMessage(Message); - break; - case CMessage::Type::Quit: - bReturn = OnQuitMessage(Message); - break; - case CMessage::Type::Text: - bReturn = OnTextMessage(Message); - break; - case CMessage::Type::Topic: - bReturn = OnTopicMessage(Message); - break; - default: - bReturn = OnOtherMessage(Message); - break; - } + switch (Message.GetType()) { + case CMessage::Type::Action: + bReturn = OnActionMessage(Message); + break; + case CMessage::Type::CTCP: + bReturn = OnCTCPMessage(Message); + break; + case CMessage::Type::Join: + bReturn = OnJoinMessage(Message); + break; + case CMessage::Type::Mode: + bReturn = OnModeMessage(Message); + break; + case CMessage::Type::Notice: + bReturn = OnNoticeMessage(Message); + break; + case CMessage::Type::Part: + bReturn = OnPartMessage(Message); + break; + case CMessage::Type::Ping: + bReturn = OnPingMessage(Message); + break; + case CMessage::Type::Pong: + bReturn = OnPongMessage(Message); + break; + case CMessage::Type::Quit: + bReturn = OnQuitMessage(Message); + break; + case CMessage::Type::Text: + bReturn = OnTextMessage(Message); + break; + case CMessage::Type::Topic: + bReturn = OnTopicMessage(Message); + break; + default: + bReturn = OnOtherMessage(Message); + break; + } - if (bReturn) return; + if (bReturn) return; - PutIRC(Message.ToString(CMessage::ExcludePrefix | CMessage::ExcludeTags)); + PutIRC(Message.ToString(CMessage::ExcludePrefix | CMessage::ExcludeTags)); } void CClient::SetNick(const CString& s) { m_sNick = s; } void CClient::SetNetwork(CIRCNetwork* pNetwork, bool bDisconnect, bool bReconnect) { - if (bDisconnect) { - if (m_pNetwork) { - m_pNetwork->ClientDisconnected(this); + if (bDisconnect) { + if (m_pNetwork) { + m_pNetwork->ClientDisconnected(this); - // Tell the client they are no longer in these channels. - const vector& vChans = m_pNetwork->GetChans(); - for (const CChan* pChan : vChans) { - if (!(pChan->IsDetached())) { - PutClient(":" + m_pNetwork->GetIRCNick().GetNickMask() + - " PART " + pChan->GetName()); - } - } - } else if (m_pUser) { - m_pUser->UserDisconnected(this); - } - } + // Tell the client they are no longer in these channels. + const vector& vChans = m_pNetwork->GetChans(); + for (const CChan* pChan : vChans) { + if (!(pChan->IsDetached())) { + PutClient(":" + m_pNetwork->GetIRCNick().GetNickMask() + + " PART " + pChan->GetName()); + } + } + } else if (m_pUser) { + m_pUser->UserDisconnected(this); + } + } - m_pNetwork = pNetwork; + m_pNetwork = pNetwork; - if (bReconnect) { - if (m_pNetwork) { - m_pNetwork->ClientConnected(this); - } else if (m_pUser) { - m_pUser->UserConnected(this); - } - } + if (bReconnect) { + if (m_pNetwork) { + m_pNetwork->ClientConnected(this); + } else if (m_pUser) { + m_pUser->UserConnected(this); + } + } } const vector& CClient::GetClients() const { - if (m_pNetwork) { - return m_pNetwork->GetClients(); - } + if (m_pNetwork) { + return m_pNetwork->GetClients(); + } - return m_pUser->GetUserClients(); + return m_pUser->GetUserClients(); } const CIRCSock* CClient::GetIRCSock() const { - if (m_pNetwork) { - return m_pNetwork->GetIRCSock(); - } + if (m_pNetwork) { + return m_pNetwork->GetIRCSock(); + } - return nullptr; + return nullptr; } CIRCSock* CClient::GetIRCSock() { - if (m_pNetwork) { - return m_pNetwork->GetIRCSock(); - } + if (m_pNetwork) { + return m_pNetwork->GetIRCSock(); + } - return nullptr; + return nullptr; } void CClient::StatusCTCP(const CString& sLine) { - CString sCommand = sLine.Token(0); + CString sCommand = sLine.Token(0); - if (sCommand.Equals("PING")) { - PutStatusNotice("\001PING " + sLine.Token(1, true) + "\001"); - } else if (sCommand.Equals("VERSION")) { - PutStatusNotice("\001VERSION " + CZNC::GetTag() + "\001"); - } + if (sCommand.Equals("PING")) { + PutStatusNotice("\001PING " + sLine.Token(1, true) + "\001"); + } else if (sCommand.Equals("VERSION")) { + PutStatusNotice("\001VERSION " + CZNC::GetTag() + "\001"); + } } bool CClient::SendMotd() { - const VCString& vsMotd = CZNC::Get().GetMotd(); + const VCString& vsMotd = CZNC::Get().GetMotd(); - if (!vsMotd.size()) { - return false; - } + if (!vsMotd.size()) { + return false; + } - for (const CString& sLine : vsMotd) { - if (m_pNetwork) { - PutStatusNotice(m_pNetwork->ExpandString(sLine)); - } else { - PutStatusNotice(m_pUser->ExpandString(sLine)); - } - } + for (const CString& sLine : vsMotd) { + if (m_pNetwork) { + PutStatusNotice(m_pNetwork->ExpandString(sLine)); + } else { + PutStatusNotice(m_pUser->ExpandString(sLine)); + } + } - return true; + return true; } void CClient::AuthUser() { - if (!m_bGotNick || !m_bGotUser || !m_bGotPass || m_bInCap || IsAttached()) - return; + if (!m_bGotNick || !m_bGotUser || !m_bGotPass || m_bInCap || IsAttached()) + return; - m_spAuth = std::make_shared(this, m_sUser, m_sPass); + m_spAuth = std::make_shared(this, m_sUser, m_sPass); - CZNC::Get().AuthUser(m_spAuth); + CZNC::Get().AuthUser(m_spAuth); } CClientAuth::CClientAuth(CClient* pClient, const CString& sUsername, @@ -324,107 +324,107 @@ CClientAuth::CClientAuth(CClient* pClient, const CString& sUsername, : CAuthBase(sUsername, sPassword, pClient), m_pClient(pClient) {} void CClientAuth::RefusedLogin(const CString& sReason) { - if (m_pClient) { - m_pClient->RefuseLogin(sReason); - } + if (m_pClient) { + m_pClient->RefuseLogin(sReason); + } } CString CAuthBase::GetRemoteIP() const { - if (m_pSock) return m_pSock->GetRemoteIP(); - return ""; + if (m_pSock) return m_pSock->GetRemoteIP(); + return ""; } void CAuthBase::Invalidate() { m_pSock = nullptr; } void CAuthBase::AcceptLogin(CUser& User) { - if (m_pSock) { - AcceptedLogin(User); - Invalidate(); - } + if (m_pSock) { + AcceptedLogin(User); + Invalidate(); + } } void CAuthBase::RefuseLogin(const CString& sReason) { - if (!m_pSock) return; + if (!m_pSock) return; - CUser* pUser = CZNC::Get().FindUser(GetUsername()); + CUser* pUser = CZNC::Get().FindUser(GetUsername()); - // If the username is valid, notify that user that someone tried to - // login. Use sReason because there are other reasons than "wrong - // password" for a login to be rejected (e.g. fail2ban). - if (pUser) { - pUser->PutStatus("A client from [" + GetRemoteIP() + - "] attempted " - "to login as you, but was rejected [" + - sReason + "]."); - } + // If the username is valid, notify that user that someone tried to + // login. Use sReason because there are other reasons than "wrong + // password" for a login to be rejected (e.g. fail2ban). + if (pUser) { + pUser->PutStatus("A client from [" + GetRemoteIP() + + "] attempted " + "to login as you, but was rejected [" + + sReason + "]."); + } - GLOBALMODULECALL(OnFailedLogin(GetUsername(), GetRemoteIP()), NOTHING); - RefusedLogin(sReason); - Invalidate(); + GLOBALMODULECALL(OnFailedLogin(GetUsername(), GetRemoteIP()), NOTHING); + RefusedLogin(sReason); + Invalidate(); } void CClient::RefuseLogin(const CString& sReason) { - PutStatus("Bad username and/or password."); - PutClient(":irc.znc.in 464 " + GetNick() + " :" + sReason); - Close(Csock::CLT_AFTERWRITE); + PutStatus("Bad username and/or password."); + PutClient(":irc.znc.in 464 " + GetNick() + " :" + sReason); + Close(Csock::CLT_AFTERWRITE); } void CClientAuth::AcceptedLogin(CUser& User) { - if (m_pClient) { - m_pClient->AcceptLogin(User); - } + if (m_pClient) { + m_pClient->AcceptLogin(User); + } } void CClient::AcceptLogin(CUser& User) { - m_sPass = ""; - m_pUser = &User; + m_sPass = ""; + m_pUser = &User; - // Set our proper timeout and set back our proper timeout mode - // (constructor set a different timeout and mode) - SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ); + // Set our proper timeout and set back our proper timeout mode + // (constructor set a different timeout and mode) + SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ); - SetSockName("USR::" + m_pUser->GetUserName()); - SetEncoding(m_pUser->GetClientEncoding()); + SetSockName("USR::" + m_pUser->GetUserName()); + SetEncoding(m_pUser->GetClientEncoding()); - if (!m_sNetwork.empty()) { - m_pNetwork = m_pUser->FindNetwork(m_sNetwork); - if (!m_pNetwork) { - PutStatus("Network (" + m_sNetwork + ") doesn't exist."); - } - } else if (!m_pUser->GetNetworks().empty()) { - // If a user didn't supply a network, and they have a network called - // "default" then automatically use this network. - m_pNetwork = m_pUser->FindNetwork("default"); - // If no "default" network, try "user" network. It's for compatibility - // with early network stuff in ZNC, which converted old configs to - // "user" network. - if (!m_pNetwork) m_pNetwork = m_pUser->FindNetwork("user"); - // Otherwise, just try any network of the user. - if (!m_pNetwork) m_pNetwork = *m_pUser->GetNetworks().begin(); - if (m_pNetwork && m_pUser->GetNetworks().size() > 1) { - PutStatusNotice( - "You have several networks configured, but no network was " - "specified for the connection."); - PutStatusNotice("Selecting network [" + m_pNetwork->GetName() + - "]. To see list of all configured networks, use " - "/znc ListNetworks"); - PutStatusNotice( - "If you want to choose another network, use /znc JumpNetwork " - ", or connect to ZNC with username " + - m_pUser->GetUserName() + "/ (instead of just " + - m_pUser->GetUserName() + ")"); - } - } else { - PutStatusNotice( - "You have no networks configured. Use /znc AddNetwork to " - "add one."); - } + if (!m_sNetwork.empty()) { + m_pNetwork = m_pUser->FindNetwork(m_sNetwork); + if (!m_pNetwork) { + PutStatus("Network (" + m_sNetwork + ") doesn't exist."); + } + } else if (!m_pUser->GetNetworks().empty()) { + // If a user didn't supply a network, and they have a network called + // "default" then automatically use this network. + m_pNetwork = m_pUser->FindNetwork("default"); + // If no "default" network, try "user" network. It's for compatibility + // with early network stuff in ZNC, which converted old configs to + // "user" network. + if (!m_pNetwork) m_pNetwork = m_pUser->FindNetwork("user"); + // Otherwise, just try any network of the user. + if (!m_pNetwork) m_pNetwork = *m_pUser->GetNetworks().begin(); + if (m_pNetwork && m_pUser->GetNetworks().size() > 1) { + PutStatusNotice( + "You have several networks configured, but no network was " + "specified for the connection."); + PutStatusNotice("Selecting network [" + m_pNetwork->GetName() + + "]. To see list of all configured networks, use " + "/znc ListNetworks"); + PutStatusNotice( + "If you want to choose another network, use /znc JumpNetwork " + ", or connect to ZNC with username " + + m_pUser->GetUserName() + "/ (instead of just " + + m_pUser->GetUserName() + ")"); + } + } else { + PutStatusNotice( + "You have no networks configured. Use /znc AddNetwork to " + "add one."); + } - SetNetwork(m_pNetwork, false); + SetNetwork(m_pNetwork, false); - SendMotd(); + SendMotd(); - NETWORKMODULECALL(OnClientLogin(), m_pUser, m_pNetwork, this, NOTHING); + NETWORKMODULECALL(OnClientLogin(), m_pUser, m_pNetwork, this, NOTHING); } void CClient::Timeout() { PutClient("ERROR :Closing link [Timeout]"); } @@ -432,900 +432,900 @@ void CClient::Timeout() { PutClient("ERROR :Closing link [Timeout]"); } void CClient::Connected() { DEBUG(GetSockName() << " == Connected();"); } void CClient::ConnectionRefused() { - DEBUG(GetSockName() << " == ConnectionRefused()"); + DEBUG(GetSockName() << " == ConnectionRefused()"); } void CClient::Disconnected() { - DEBUG(GetSockName() << " == Disconnected()"); - CIRCNetwork* pNetwork = m_pNetwork; - SetNetwork(nullptr, true, false); + DEBUG(GetSockName() << " == Disconnected()"); + CIRCNetwork* pNetwork = m_pNetwork; + SetNetwork(nullptr, true, false); - if (m_pUser) { - NETWORKMODULECALL(OnClientDisconnect(), m_pUser, pNetwork, this, - NOTHING); - } + if (m_pUser) { + NETWORKMODULECALL(OnClientDisconnect(), m_pUser, pNetwork, this, + NOTHING); + } } void CClient::ReachedMaxBuffer() { - DEBUG(GetSockName() << " == ReachedMaxBuffer()"); - if (IsAttached()) { - PutClient("ERROR :Closing link [Too long raw line]"); - } - Close(); + DEBUG(GetSockName() << " == ReachedMaxBuffer()"); + if (IsAttached()) { + PutClient("ERROR :Closing link [Too long raw line]"); + } + Close(); } void CClient::BouncedOff() { - PutStatusNotice( - "You are being disconnected because another user just authenticated as " - "you."); - Close(Csock::CLT_AFTERWRITE); + PutStatusNotice( + "You are being disconnected because another user just authenticated as " + "you."); + Close(Csock::CLT_AFTERWRITE); } void CClient::PutIRC(const CString& sLine) { - if (m_pNetwork) { - m_pNetwork->PutIRC(sLine); - } + if (m_pNetwork) { + m_pNetwork->PutIRC(sLine); + } } CString CClient::GetFullName() const { - if (!m_pUser) return GetRemoteIP(); - CString sFullName = m_pUser->GetUserName(); - if (!m_sIdentifier.empty()) sFullName += "@" + m_sIdentifier; - if (m_pNetwork) sFullName += "/" + m_pNetwork->GetName(); - return sFullName; + if (!m_pUser) return GetRemoteIP(); + CString sFullName = m_pUser->GetUserName(); + if (!m_sIdentifier.empty()) sFullName += "@" + m_sIdentifier; + if (m_pNetwork) sFullName += "/" + m_pNetwork->GetName(); + return sFullName; } void CClient::PutClient(const CString& sLine) { - bool bReturn = false; - CString sCopy = sLine; - NETWORKMODULECALL(OnSendToClient(sCopy, *this), m_pUser, m_pNetwork, this, - &bReturn); - if (bReturn) return; - DEBUG("(" << GetFullName() << ") ZNC -> CLI [" << sCopy << "]"); - Write(sCopy + "\r\n"); + bool bReturn = false; + CString sCopy = sLine; + NETWORKMODULECALL(OnSendToClient(sCopy, *this), m_pUser, m_pNetwork, this, + &bReturn); + if (bReturn) return; + DEBUG("(" << GetFullName() << ") ZNC -> CLI [" << sCopy << "]"); + Write(sCopy + "\r\n"); } bool CClient::PutClient(const CMessage& Message) { - if (!m_bAwayNotify && Message.GetType() == CMessage::Type::Away) { - return false; - } else if (!m_bAccountNotify && - Message.GetType() == CMessage::Type::Account) { - return false; - } + if (!m_bAwayNotify && Message.GetType() == CMessage::Type::Away) { + return false; + } else if (!m_bAccountNotify && + Message.GetType() == CMessage::Type::Account) { + return false; + } - CMessage Msg(Message); + CMessage Msg(Message); - const CIRCSock* pIRCSock = GetIRCSock(); - if (pIRCSock) { - if (Msg.GetType() == CMessage::Type::Numeric) { - unsigned int uCode = Msg.As().GetCode(); + const CIRCSock* pIRCSock = GetIRCSock(); + if (pIRCSock) { + if (Msg.GetType() == CMessage::Type::Numeric) { + unsigned int uCode = Msg.As().GetCode(); - if (uCode == 352) { // RPL_WHOREPLY - if (!m_bNamesx && pIRCSock->HasNamesx()) { - // The server has NAMESX, but the client doesn't, so we need - // to remove extra prefixes - CString sNick = Msg.GetParam(6); - if (sNick.size() > 1 && pIRCSock->IsPermChar(sNick[1])) { - CString sNewNick = sNick; - size_t pos = - sNick.find_first_not_of(pIRCSock->GetPerms()); - if (pos >= 2 && pos != CString::npos) { - sNewNick = sNick[0] + sNick.substr(pos); - } - Msg.SetParam(6, sNewNick); - } - } - } else if (uCode == 353) { // RPL_NAMES - if ((!m_bNamesx && pIRCSock->HasNamesx()) || - (!m_bUHNames && pIRCSock->HasUHNames())) { - // The server has either UHNAMES or NAMESX, but the client - // is missing either or both - CString sNicks = Msg.GetParam(3); - VCString vsNicks; - sNicks.Split(" ", vsNicks, false); + if (uCode == 352) { // RPL_WHOREPLY + if (!m_bNamesx && pIRCSock->HasNamesx()) { + // The server has NAMESX, but the client doesn't, so we need + // to remove extra prefixes + CString sNick = Msg.GetParam(6); + if (sNick.size() > 1 && pIRCSock->IsPermChar(sNick[1])) { + CString sNewNick = sNick; + size_t pos = + sNick.find_first_not_of(pIRCSock->GetPerms()); + if (pos >= 2 && pos != CString::npos) { + sNewNick = sNick[0] + sNick.substr(pos); + } + Msg.SetParam(6, sNewNick); + } + } + } else if (uCode == 353) { // RPL_NAMES + if ((!m_bNamesx && pIRCSock->HasNamesx()) || + (!m_bUHNames && pIRCSock->HasUHNames())) { + // The server has either UHNAMES or NAMESX, but the client + // is missing either or both + CString sNicks = Msg.GetParam(3); + VCString vsNicks; + sNicks.Split(" ", vsNicks, false); - for (CString& sNick : vsNicks) { - if (sNick.empty()) break; + for (CString& sNick : vsNicks) { + if (sNick.empty()) break; - if (!m_bNamesx && pIRCSock->HasNamesx() && - pIRCSock->IsPermChar(sNick[0])) { - // The server has NAMESX, but the client doesn't, so - // we just use the first perm char - size_t pos = - sNick.find_first_not_of(pIRCSock->GetPerms()); - if (pos >= 2 && pos != CString::npos) { - sNick = sNick[0] + sNick.substr(pos); - } - } + if (!m_bNamesx && pIRCSock->HasNamesx() && + pIRCSock->IsPermChar(sNick[0])) { + // The server has NAMESX, but the client doesn't, so + // we just use the first perm char + size_t pos = + sNick.find_first_not_of(pIRCSock->GetPerms()); + if (pos >= 2 && pos != CString::npos) { + sNick = sNick[0] + sNick.substr(pos); + } + } - if (!m_bUHNames && pIRCSock->HasUHNames()) { - // The server has UHNAMES, but the client doesn't, - // so we strip away ident and host - sNick = sNick.Token(0, false, "!"); - } - } + if (!m_bUHNames && pIRCSock->HasUHNames()) { + // The server has UHNAMES, but the client doesn't, + // so we strip away ident and host + sNick = sNick.Token(0, false, "!"); + } + } - Msg.SetParam( - 3, CString(" ").Join(vsNicks.begin(), vsNicks.end())); - } - } - } else if (Msg.GetType() == CMessage::Type::Join) { - if (!m_bExtendedJoin && pIRCSock->HasExtendedJoin()) { - Msg.SetParams({Msg.As().GetTarget()}); - } - } - } + Msg.SetParam( + 3, CString(" ").Join(vsNicks.begin(), vsNicks.end())); + } + } + } else if (Msg.GetType() == CMessage::Type::Join) { + if (!m_bExtendedJoin && pIRCSock->HasExtendedJoin()) { + Msg.SetParams({Msg.As().GetTarget()}); + } + } + } - CString sLine = Msg.ToString(CMessage::ExcludeTags); + CString sLine = Msg.ToString(CMessage::ExcludeTags); - // TODO: introduce a module hook that gives control over the tags that are - // sent - MCString mssTags; + // TODO: introduce a module hook that gives control over the tags that are + // sent + MCString mssTags; - if (HasServerTime()) { - CString sServerTime = Msg.GetTag("time"); - if (!sServerTime.empty()) { - mssTags["time"] = sServerTime; - } else { - mssTags["time"] = CUtils::FormatServerTime(Msg.GetTime()); - } - } + if (HasServerTime()) { + CString sServerTime = Msg.GetTag("time"); + if (!sServerTime.empty()) { + mssTags["time"] = sServerTime; + } else { + mssTags["time"] = CUtils::FormatServerTime(Msg.GetTime()); + } + } - if (HasBatch()) { - CString sBatch = Msg.GetTag("batch"); - if (!sBatch.empty()) { - mssTags["batch"] = sBatch; - } - } + if (HasBatch()) { + CString sBatch = Msg.GetTag("batch"); + if (!sBatch.empty()) { + mssTags["batch"] = sBatch; + } + } - if (!mssTags.empty()) { - CUtils::SetMessageTags(sLine, mssTags); - } + if (!mssTags.empty()) { + CUtils::SetMessageTags(sLine, mssTags); + } - PutClient(sLine); - return true; + PutClient(sLine); + return true; } void CClient::PutStatusNotice(const CString& sLine) { - PutModNotice("status", sLine); + PutModNotice("status", sLine); } unsigned int CClient::PutStatus(const CTable& table) { - unsigned int idx = 0; - CString sLine; - while (table.GetLine(idx++, sLine)) PutStatus(sLine); - return idx - 1; + unsigned int idx = 0; + CString sLine; + while (table.GetLine(idx++, sLine)) PutStatus(sLine); + return idx - 1; } void CClient::PutStatus(const CString& sLine) { PutModule("status", sLine); } void CClient::PutModNotice(const CString& sModule, const CString& sLine) { - if (!m_pUser) { - return; - } + if (!m_pUser) { + return; + } - DEBUG("(" << GetFullName() - << ") ZNC -> CLI [:" + m_pUser->GetStatusPrefix() + - ((sModule.empty()) ? "status" : sModule) + - "!znc@znc.in NOTICE " << GetNick() << " :" << sLine - << "]"); - Write(":" + m_pUser->GetStatusPrefix() + - ((sModule.empty()) ? "status" : sModule) + "!znc@znc.in NOTICE " + - GetNick() + " :" + sLine + "\r\n"); + DEBUG("(" << GetFullName() + << ") ZNC -> CLI [:" + m_pUser->GetStatusPrefix() + + ((sModule.empty()) ? "status" : sModule) + + "!znc@znc.in NOTICE " << GetNick() << " :" << sLine + << "]"); + Write(":" + m_pUser->GetStatusPrefix() + + ((sModule.empty()) ? "status" : sModule) + "!znc@znc.in NOTICE " + + GetNick() + " :" + sLine + "\r\n"); } void CClient::PutModule(const CString& sModule, const CString& sLine) { - if (!m_pUser) { - return; - } + if (!m_pUser) { + return; + } - DEBUG("(" << GetFullName() - << ") ZNC -> CLI [:" + m_pUser->GetStatusPrefix() + - ((sModule.empty()) ? "status" : sModule) + - "!znc@znc.in PRIVMSG " << GetNick() << " :" << sLine - << "]"); + DEBUG("(" << GetFullName() + << ") ZNC -> CLI [:" + m_pUser->GetStatusPrefix() + + ((sModule.empty()) ? "status" : sModule) + + "!znc@znc.in PRIVMSG " << GetNick() << " :" << sLine + << "]"); - VCString vsLines; - sLine.Split("\n", vsLines); - for (const CString& s : vsLines) { - Write(":" + m_pUser->GetStatusPrefix() + - ((sModule.empty()) ? "status" : sModule) + - "!znc@znc.in PRIVMSG " + GetNick() + " :" + s + "\r\n"); - } + VCString vsLines; + sLine.Split("\n", vsLines); + for (const CString& s : vsLines) { + Write(":" + m_pUser->GetStatusPrefix() + + ((sModule.empty()) ? "status" : sModule) + + "!znc@znc.in PRIVMSG " + GetNick() + " :" + s + "\r\n"); + } } CString CClient::GetNick(bool bAllowIRCNick) const { - CString sRet; + CString sRet; - const CIRCSock* pSock = GetIRCSock(); - if (bAllowIRCNick && pSock && pSock->IsAuthed()) { - sRet = pSock->GetNick(); - } + const CIRCSock* pSock = GetIRCSock(); + if (bAllowIRCNick && pSock && pSock->IsAuthed()) { + sRet = pSock->GetNick(); + } - return (sRet.empty()) ? m_sNick : sRet; + return (sRet.empty()) ? m_sNick : sRet; } CString CClient::GetNickMask() const { - if (GetIRCSock() && GetIRCSock()->IsAuthed()) { - return GetIRCSock()->GetNickMask(); - } + if (GetIRCSock() && GetIRCSock()->IsAuthed()) { + return GetIRCSock()->GetNickMask(); + } - CString sHost = - m_pNetwork ? m_pNetwork->GetBindHost() : m_pUser->GetBindHost(); - if (sHost.empty()) { - sHost = "irc.znc.in"; - } + CString sHost = + m_pNetwork ? m_pNetwork->GetBindHost() : m_pUser->GetBindHost(); + if (sHost.empty()) { + sHost = "irc.znc.in"; + } - return GetNick() + "!" + - (m_pNetwork ? m_pNetwork->GetIdent() : m_pUser->GetIdent()) + "@" + - sHost; + return GetNick() + "!" + + (m_pNetwork ? m_pNetwork->GetIdent() : m_pUser->GetIdent()) + "@" + + sHost; } bool CClient::IsValidIdentifier(const CString& sIdentifier) { - // ^[-\w]+$ + // ^[-\w]+$ - if (sIdentifier.empty()) { - return false; - } + if (sIdentifier.empty()) { + return false; + } - const char* p = sIdentifier.c_str(); - while (*p) { - if (*p != '_' && *p != '-' && !isalnum(*p)) { - return false; - } + const char* p = sIdentifier.c_str(); + while (*p) { + if (*p != '_' && *p != '-' && !isalnum(*p)) { + return false; + } - p++; - } + p++; + } - return true; + return true; } void CClient::RespondCap(const CString& sResponse) { - PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse); + PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse); } void CClient::HandleCap(const CMessage& Message) { - CString sSubCmd = Message.GetParam(0); + CString sSubCmd = Message.GetParam(0); - if (sSubCmd.Equals("LS")) { - SCString ssOfferCaps; - for (const auto& it : m_mCoreCaps) { - bool bServerDependent = std::get<0>(it.second); - if (!bServerDependent || - m_ssServerDependentCaps.count(it.first) > 0) - ssOfferCaps.insert(it.first); - } - GLOBALMODULECALL(OnClientCapLs(this, ssOfferCaps), NOTHING); - CString sRes = - CString(" ").Join(ssOfferCaps.begin(), ssOfferCaps.end()); - RespondCap("LS :" + sRes); - m_bInCap = true; - if (Message.GetParam(1).ToInt() >= 302) { - m_bCapNotify = true; - } - } else if (sSubCmd.Equals("END")) { - m_bInCap = false; - if (!IsAttached()) { - if (!m_pUser && m_bGotUser && !m_bGotPass) { - SendRequiredPasswordNotice(); - } else { - AuthUser(); - } - } - } else if (sSubCmd.Equals("REQ")) { - VCString vsTokens; - Message.GetParam(1).Split(" ", vsTokens, false); + if (sSubCmd.Equals("LS")) { + SCString ssOfferCaps; + for (const auto& it : m_mCoreCaps) { + bool bServerDependent = std::get<0>(it.second); + if (!bServerDependent || + m_ssServerDependentCaps.count(it.first) > 0) + ssOfferCaps.insert(it.first); + } + GLOBALMODULECALL(OnClientCapLs(this, ssOfferCaps), NOTHING); + CString sRes = + CString(" ").Join(ssOfferCaps.begin(), ssOfferCaps.end()); + RespondCap("LS :" + sRes); + m_bInCap = true; + if (Message.GetParam(1).ToInt() >= 302) { + m_bCapNotify = true; + } + } else if (sSubCmd.Equals("END")) { + m_bInCap = false; + if (!IsAttached()) { + if (!m_pUser && m_bGotUser && !m_bGotPass) { + SendRequiredPasswordNotice(); + } else { + AuthUser(); + } + } + } else if (sSubCmd.Equals("REQ")) { + VCString vsTokens; + Message.GetParam(1).Split(" ", vsTokens, false); - for (const CString& sToken : vsTokens) { - bool bVal = true; - CString sCap = sToken; - if (sCap.TrimPrefix("-")) bVal = false; + for (const CString& sToken : vsTokens) { + bool bVal = true; + CString sCap = sToken; + if (sCap.TrimPrefix("-")) bVal = false; - bool bAccepted = false; - const auto& it = m_mCoreCaps.find(sCap); - if (m_mCoreCaps.end() != it) { - bool bServerDependent = std::get<0>(it->second); - bAccepted = !bServerDependent || - m_ssServerDependentCaps.count(sCap) > 0; - } - GLOBALMODULECALL(IsClientCapSupported(this, sCap, bVal), - &bAccepted); + bool bAccepted = false; + const auto& it = m_mCoreCaps.find(sCap); + if (m_mCoreCaps.end() != it) { + bool bServerDependent = std::get<0>(it->second); + bAccepted = !bServerDependent || + m_ssServerDependentCaps.count(sCap) > 0; + } + GLOBALMODULECALL(IsClientCapSupported(this, sCap, bVal), + &bAccepted); - if (!bAccepted) { - // Some unsupported capability is requested - RespondCap("NAK :" + Message.GetParam(1)); - return; - } - } + if (!bAccepted) { + // Some unsupported capability is requested + RespondCap("NAK :" + Message.GetParam(1)); + return; + } + } - // All is fine, we support what was requested - for (const CString& sToken : vsTokens) { - bool bVal = true; - CString sCap = sToken; - if (sCap.TrimPrefix("-")) bVal = false; + // All is fine, we support what was requested + for (const CString& sToken : vsTokens) { + bool bVal = true; + CString sCap = sToken; + if (sCap.TrimPrefix("-")) bVal = false; - auto handler_it = m_mCoreCaps.find(sCap); - if (m_mCoreCaps.end() != handler_it) { - const auto& handler = std::get<1>(handler_it->second); - handler(bVal); - } - GLOBALMODULECALL(OnClientCapRequest(this, sCap, bVal), NOTHING); + auto handler_it = m_mCoreCaps.find(sCap); + if (m_mCoreCaps.end() != handler_it) { + const auto& handler = std::get<1>(handler_it->second); + handler(bVal); + } + GLOBALMODULECALL(OnClientCapRequest(this, sCap, bVal), NOTHING); - if (bVal) { - m_ssAcceptedCaps.insert(sCap); - } else { - m_ssAcceptedCaps.erase(sCap); - } - } + if (bVal) { + m_ssAcceptedCaps.insert(sCap); + } else { + m_ssAcceptedCaps.erase(sCap); + } + } - RespondCap("ACK :" + Message.GetParam(1)); - } else if (sSubCmd.Equals("LIST")) { - CString sList = - CString(" ").Join(m_ssAcceptedCaps.begin(), m_ssAcceptedCaps.end()); - RespondCap("LIST :" + sList); - } else { - PutClient(":irc.znc.in 410 " + GetNick() + " " + sSubCmd + - " :Invalid CAP subcommand"); - } + RespondCap("ACK :" + Message.GetParam(1)); + } else if (sSubCmd.Equals("LIST")) { + CString sList = + CString(" ").Join(m_ssAcceptedCaps.begin(), m_ssAcceptedCaps.end()); + RespondCap("LIST :" + sList); + } else { + PutClient(":irc.znc.in 410 " + GetNick() + " " + sSubCmd + + " :Invalid CAP subcommand"); + } } void CClient::ParsePass(const CString& sAuthLine) { - // [user[@identifier][/network]:]password + // [user[@identifier][/network]:]password - const size_t uColon = sAuthLine.find(":"); - if (uColon != CString::npos) { - m_sPass = sAuthLine.substr(uColon + 1); + const size_t uColon = sAuthLine.find(":"); + if (uColon != CString::npos) { + m_sPass = sAuthLine.substr(uColon + 1); - ParseUser(sAuthLine.substr(0, uColon)); - } else { - m_sPass = sAuthLine; - } + ParseUser(sAuthLine.substr(0, uColon)); + } else { + m_sPass = sAuthLine; + } } void CClient::ParseUser(const CString& sAuthLine) { - // user[@identifier][/network] + // user[@identifier][/network] - const size_t uSlash = sAuthLine.rfind("/"); - if (uSlash != CString::npos) { - m_sNetwork = sAuthLine.substr(uSlash + 1); + const size_t uSlash = sAuthLine.rfind("/"); + if (uSlash != CString::npos) { + m_sNetwork = sAuthLine.substr(uSlash + 1); - ParseIdentifier(sAuthLine.substr(0, uSlash)); - } else { - ParseIdentifier(sAuthLine); - } + ParseIdentifier(sAuthLine.substr(0, uSlash)); + } else { + ParseIdentifier(sAuthLine); + } } void CClient::ParseIdentifier(const CString& sAuthLine) { - // user[@identifier] + // user[@identifier] - const size_t uAt = sAuthLine.rfind("@"); - if (uAt != CString::npos) { - const CString sId = sAuthLine.substr(uAt + 1); + const size_t uAt = sAuthLine.rfind("@"); + if (uAt != CString::npos) { + const CString sId = sAuthLine.substr(uAt + 1); - if (IsValidIdentifier(sId)) { - m_sIdentifier = sId; - m_sUser = sAuthLine.substr(0, uAt); - } else { - m_sUser = sAuthLine; - } - } else { - m_sUser = sAuthLine; - } + if (IsValidIdentifier(sId)) { + m_sIdentifier = sId; + m_sUser = sAuthLine.substr(0, uAt); + } else { + m_sUser = sAuthLine; + } + } else { + m_sUser = sAuthLine; + } } void CClient::NotifyServerDependentCaps(const SCString& ssCaps) { - for (const CString& sCap : ssCaps) { - const auto& it = m_mCoreCaps.find(sCap); - if (m_mCoreCaps.end() != it) { - bool bServerDependent = std::get<0>(it->second); - if (bServerDependent) { - m_ssServerDependentCaps.insert(sCap); - } - } - } + for (const CString& sCap : ssCaps) { + const auto& it = m_mCoreCaps.find(sCap); + if (m_mCoreCaps.end() != it) { + bool bServerDependent = std::get<0>(it->second); + if (bServerDependent) { + m_ssServerDependentCaps.insert(sCap); + } + } + } - if (HasCapNotify() && !m_ssServerDependentCaps.empty()) { - CString sCaps = CString(" ").Join(m_ssServerDependentCaps.begin(), - m_ssServerDependentCaps.end()); - PutClient(":irc.znc.in CAP " + GetNick() + " NEW :" + sCaps); - } + if (HasCapNotify() && !m_ssServerDependentCaps.empty()) { + CString sCaps = CString(" ").Join(m_ssServerDependentCaps.begin(), + m_ssServerDependentCaps.end()); + PutClient(":irc.znc.in CAP " + GetNick() + " NEW :" + sCaps); + } } void CClient::ClearServerDependentCaps() { - if (HasCapNotify() && !m_ssServerDependentCaps.empty()) { - CString sCaps = CString(" ").Join(m_ssServerDependentCaps.begin(), - m_ssServerDependentCaps.end()); - PutClient(":irc.znc.in CAP " + GetNick() + " DEL :" + sCaps); + if (HasCapNotify() && !m_ssServerDependentCaps.empty()) { + CString sCaps = CString(" ").Join(m_ssServerDependentCaps.begin(), + m_ssServerDependentCaps.end()); + PutClient(":irc.znc.in CAP " + GetNick() + " DEL :" + sCaps); - for (const CString& sCap : m_ssServerDependentCaps) { - const auto& it = m_mCoreCaps.find(sCap); - if (m_mCoreCaps.end() != it) { - const auto& handler = std::get<1>(it->second); - handler(false); - } - } - } + for (const CString& sCap : m_ssServerDependentCaps) { + const auto& it = m_mCoreCaps.find(sCap); + if (m_mCoreCaps.end() != it) { + const auto& handler = std::get<1>(it->second); + handler(false); + } + } + } - m_ssServerDependentCaps.clear(); + m_ssServerDependentCaps.clear(); } template void CClient::AddBuffer(const T& Message) { - const CString sTarget = Message.GetTarget(); + const CString sTarget = Message.GetTarget(); - T Format; - Format.Clone(Message); - Format.SetNick(CNick(_NAMEDFMT(GetNickMask()))); - Format.SetTarget(_NAMEDFMT(sTarget)); - Format.SetText("{text}"); + T Format; + Format.Clone(Message); + Format.SetNick(CNick(_NAMEDFMT(GetNickMask()))); + Format.SetTarget(_NAMEDFMT(sTarget)); + Format.SetText("{text}"); - CChan* pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline()) { - pChan->AddBuffer(Format, Message.GetText()); - } - } else if (Message.GetType() != CMessage::Type::Notice) { - if (!m_pUser->AutoClearQueryBuffer() || !m_pNetwork->IsUserOnline()) { - CQuery* pQuery = m_pNetwork->AddQuery(sTarget); - if (pQuery) { - pQuery->AddBuffer(Format, Message.GetText()); - } - } - } + CChan* pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline()) { + pChan->AddBuffer(Format, Message.GetText()); + } + } else if (Message.GetType() != CMessage::Type::Notice) { + if (!m_pUser->AutoClearQueryBuffer() || !m_pNetwork->IsUserOnline()) { + CQuery* pQuery = m_pNetwork->AddQuery(sTarget); + if (pQuery) { + pQuery->AddBuffer(Format, Message.GetText()); + } + } + } } void CClient::EchoMessage(const CMessage& Message) { - for (CClient* pClient : GetClients()) { - if (pClient->HasEchoMessage() || - (pClient != this && (m_pNetwork->IsChan(Message.GetParam(0)) || - pClient->HasSelfMessage()))) { - pClient->PutClient(":" + GetNickMask() + " " + - Message.ToString(CMessage::ExcludePrefix)); - } - } + for (CClient* pClient : GetClients()) { + if (pClient->HasEchoMessage() || + (pClient != this && (m_pNetwork->IsChan(Message.GetParam(0)) || + pClient->HasSelfMessage()))) { + pClient->PutClient(":" + GetNickMask() + " " + + Message.ToString(CMessage::ExcludePrefix)); + } + } } set CClient::MatchChans(const CString& sPatterns) const { - VCString vsPatterns; - sPatterns.Replace_n(",", " ") - .Split(" ", vsPatterns, false, "", "", true, true); + VCString vsPatterns; + sPatterns.Replace_n(",", " ") + .Split(" ", vsPatterns, false, "", "", true, true); - set sChans; - for (const CString& sPattern : vsPatterns) { - vector vChans = m_pNetwork->FindChans(sPattern); - sChans.insert(vChans.begin(), vChans.end()); - } - return sChans; + set sChans; + for (const CString& sPattern : vsPatterns) { + vector vChans = m_pNetwork->FindChans(sPattern); + sChans.insert(vChans.begin(), vChans.end()); + } + return sChans; } unsigned int CClient::AttachChans(const std::set& sChans) { - unsigned int uAttached = 0; - for (CChan* pChan : sChans) { - if (!pChan->IsDetached()) continue; - uAttached++; - pChan->AttachUser(); - } - return uAttached; + unsigned int uAttached = 0; + for (CChan* pChan : sChans) { + if (!pChan->IsDetached()) continue; + uAttached++; + pChan->AttachUser(); + } + return uAttached; } unsigned int CClient::DetachChans(const std::set& sChans) { - unsigned int uDetached = 0; - for (CChan* pChan : sChans) { - if (pChan->IsDetached()) continue; - uDetached++; - pChan->DetachUser(); - } - return uDetached; + unsigned int uDetached = 0; + for (CChan* pChan : sChans) { + if (pChan->IsDetached()) continue; + uDetached++; + pChan->DetachUser(); + } + return uDetached; } bool CClient::OnActionMessage(CActionMessage& Message) { - CString sTargets = Message.GetTarget(); + CString sTargets = Message.GetTarget(); - VCString vTargets; - sTargets.Split(",", vTargets, false); + VCString vTargets; + sTargets.Split(",", vTargets, false); - for (CString& sTarget : vTargets) { - Message.SetTarget(sTarget); + for (CString& sTarget : vTargets) { + Message.SetTarget(sTarget); - bool bContinue = false; - NETWORKMODULECALL(OnUserActionMessage(Message), m_pUser, m_pNetwork, - this, &bContinue); - if (bContinue) continue; + bool bContinue = false; + NETWORKMODULECALL(OnUserActionMessage(Message), m_pUser, m_pNetwork, + this, &bContinue); + if (bContinue) continue; - if (m_pNetwork) { - AddBuffer(Message); - EchoMessage(Message); - PutIRC(Message.ToString(CMessage::ExcludePrefix | - CMessage::ExcludeTags)); - } - } + if (m_pNetwork) { + AddBuffer(Message); + EchoMessage(Message); + PutIRC(Message.ToString(CMessage::ExcludePrefix | + CMessage::ExcludeTags)); + } + } - return true; + return true; } bool CClient::OnCTCPMessage(CCTCPMessage& Message) { - CString sTargets = Message.GetTarget(); + CString sTargets = Message.GetTarget(); - VCString vTargets; - sTargets.Split(",", vTargets, false); + VCString vTargets; + sTargets.Split(",", vTargets, false); - if (Message.IsReply()) { - CString sCTCP = Message.GetText(); - if (sCTCP.Token(0) == "VERSION") { - // There are 2 different scenarios: - // - // a) CTCP reply for VERSION is not set. - // 1. ZNC receives CTCP VERSION from someone - // 2. ZNC forwards CTCP VERSION to client - // 3. Client replies with something - // 4. ZNC adds itself to the reply - // 5. ZNC sends the modified reply to whoever asked - // - // b) CTCP reply for VERSION is set. - // 1. ZNC receives CTCP VERSION from someone - // 2. ZNC replies with the configured reply (or just drops it if - // empty), without forwarding anything to client - // 3. Client does not see any CTCP request, and does not reply - // - // So, if user doesn't want "via ZNC" in CTCP VERSION reply, they - // can set custom reply. - // - // See more bikeshedding at github issues #820 and #1012 - Message.SetText(sCTCP + " via " + CZNC::GetTag(false)); - } - } + if (Message.IsReply()) { + CString sCTCP = Message.GetText(); + if (sCTCP.Token(0) == "VERSION") { + // There are 2 different scenarios: + // + // a) CTCP reply for VERSION is not set. + // 1. ZNC receives CTCP VERSION from someone + // 2. ZNC forwards CTCP VERSION to client + // 3. Client replies with something + // 4. ZNC adds itself to the reply + // 5. ZNC sends the modified reply to whoever asked + // + // b) CTCP reply for VERSION is set. + // 1. ZNC receives CTCP VERSION from someone + // 2. ZNC replies with the configured reply (or just drops it if + // empty), without forwarding anything to client + // 3. Client does not see any CTCP request, and does not reply + // + // So, if user doesn't want "via ZNC" in CTCP VERSION reply, they + // can set custom reply. + // + // See more bikeshedding at github issues #820 and #1012 + Message.SetText(sCTCP + " via " + CZNC::GetTag(false)); + } + } - for (CString& sTarget : vTargets) { - Message.SetTarget(sTarget); + for (CString& sTarget : vTargets) { + Message.SetTarget(sTarget); - bool bContinue = false; - if (Message.IsReply()) { - NETWORKMODULECALL(OnUserCTCPReplyMessage(Message), m_pUser, - m_pNetwork, this, &bContinue); - } else { - NETWORKMODULECALL(OnUserCTCPMessage(Message), m_pUser, m_pNetwork, - this, &bContinue); - } - if (bContinue) continue; + bool bContinue = false; + if (Message.IsReply()) { + NETWORKMODULECALL(OnUserCTCPReplyMessage(Message), m_pUser, + m_pNetwork, this, &bContinue); + } else { + NETWORKMODULECALL(OnUserCTCPMessage(Message), m_pUser, m_pNetwork, + this, &bContinue); + } + if (bContinue) continue; - if (!GetIRCSock()) { - // Some lagmeters do a NOTICE to their own nick, ignore those. - if (!sTarget.Equals(m_sNick)) - PutStatus("Your CTCP to [" + Message.GetTarget() + - "] got lost, " - "you are not connected to IRC!"); - continue; - } + if (!GetIRCSock()) { + // Some lagmeters do a NOTICE to their own nick, ignore those. + if (!sTarget.Equals(m_sNick)) + PutStatus("Your CTCP to [" + Message.GetTarget() + + "] got lost, " + "you are not connected to IRC!"); + continue; + } - if (m_pNetwork) { - AddBuffer(Message); - EchoMessage(Message); - PutIRC(Message.ToString(CMessage::ExcludePrefix | - CMessage::ExcludeTags)); - } - } + if (m_pNetwork) { + AddBuffer(Message); + EchoMessage(Message); + PutIRC(Message.ToString(CMessage::ExcludePrefix | + CMessage::ExcludeTags)); + } + } - return true; + return true; } bool CClient::OnJoinMessage(CJoinMessage& Message) { - CString sChans = Message.GetTarget(); - CString sKeys = Message.GetKey(); + CString sChans = Message.GetTarget(); + CString sKeys = Message.GetKey(); - VCString vsChans; - sChans.Split(",", vsChans, false); - sChans.clear(); + VCString vsChans; + sChans.Split(",", vsChans, false); + sChans.clear(); - VCString vsKeys; - sKeys.Split(",", vsKeys, true); - sKeys.clear(); + VCString vsKeys; + sKeys.Split(",", vsKeys, true); + sKeys.clear(); - for (unsigned int a = 0; a < vsChans.size(); a++) { - Message.SetTarget(vsChans[a]); - Message.SetKey((a < vsKeys.size()) ? vsKeys[a] : ""); - bool bContinue = false; - NETWORKMODULECALL(OnUserJoinMessage(Message), m_pUser, m_pNetwork, this, - &bContinue); - if (bContinue) continue; + for (unsigned int a = 0; a < vsChans.size(); a++) { + Message.SetTarget(vsChans[a]); + Message.SetKey((a < vsKeys.size()) ? vsKeys[a] : ""); + bool bContinue = false; + NETWORKMODULECALL(OnUserJoinMessage(Message), m_pUser, m_pNetwork, this, + &bContinue); + if (bContinue) continue; - CString sChannel = Message.GetTarget(); - CString sKey = Message.GetKey(); + CString sChannel = Message.GetTarget(); + CString sKey = Message.GetKey(); - CChan* pChan = m_pNetwork ? m_pNetwork->FindChan(sChannel) : nullptr; - if (pChan) { - if (pChan->IsDetached()) - pChan->AttachUser(this); - else - pChan->JoinUser(sKey); - continue; - } + CChan* pChan = m_pNetwork ? m_pNetwork->FindChan(sChannel) : nullptr; + if (pChan) { + if (pChan->IsDetached()) + pChan->AttachUser(this); + else + pChan->JoinUser(sKey); + continue; + } - if (!sChannel.empty()) { - sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); + if (!sChannel.empty()) { + sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); - if (!vsKeys.empty()) { - sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); - } - } - } + if (!vsKeys.empty()) { + sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); + } + } + } - Message.SetTarget(sChans); - Message.SetKey(sKeys); + Message.SetTarget(sChans); + Message.SetKey(sKeys); - return sChans.empty(); + return sChans.empty(); } bool CClient::OnModeMessage(CModeMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sModes = Message.GetModes(); + CString sTarget = Message.GetTarget(); + CString sModes = Message.GetModes(); - if (m_pNetwork && m_pNetwork->IsChan(sTarget) && sModes.empty()) { - // If we are on that channel and already received a - // /mode reply from the server, we can answer this - // request ourself. + if (m_pNetwork && m_pNetwork->IsChan(sTarget) && sModes.empty()) { + // If we are on that channel and already received a + // /mode reply from the server, we can answer this + // request ourself. - CChan* pChan = m_pNetwork->FindChan(sTarget); - if (pChan && pChan->IsOn() && !pChan->GetModeString().empty()) { - PutClient(":" + m_pNetwork->GetIRCServer() + " 324 " + GetNick() + - " " + sTarget + " " + pChan->GetModeString()); - if (pChan->GetCreationDate() > 0) { - PutClient(":" + m_pNetwork->GetIRCServer() + " 329 " + - GetNick() + " " + sTarget + " " + - CString(pChan->GetCreationDate())); - } - return true; - } - } + CChan* pChan = m_pNetwork->FindChan(sTarget); + if (pChan && pChan->IsOn() && !pChan->GetModeString().empty()) { + PutClient(":" + m_pNetwork->GetIRCServer() + " 324 " + GetNick() + + " " + sTarget + " " + pChan->GetModeString()); + if (pChan->GetCreationDate() > 0) { + PutClient(":" + m_pNetwork->GetIRCServer() + " 329 " + + GetNick() + " " + sTarget + " " + + CString(pChan->GetCreationDate())); + } + return true; + } + } - return false; + return false; } bool CClient::OnNoticeMessage(CNoticeMessage& Message) { - CString sTargets = Message.GetTarget(); + CString sTargets = Message.GetTarget(); - VCString vTargets; - sTargets.Split(",", vTargets, false); + VCString vTargets; + sTargets.Split(",", vTargets, false); - for (CString& sTarget : vTargets) { - Message.SetTarget(sTarget); + for (CString& sTarget : vTargets) { + Message.SetTarget(sTarget); - if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { - if (!sTarget.Equals("status")) { - CALLMOD(sTarget, this, m_pUser, m_pNetwork, - OnModNotice(Message.GetText())); - } - continue; - } + if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { + if (!sTarget.Equals("status")) { + CALLMOD(sTarget, this, m_pUser, m_pNetwork, + OnModNotice(Message.GetText())); + } + continue; + } - bool bContinue = false; - NETWORKMODULECALL(OnUserNoticeMessage(Message), m_pUser, m_pNetwork, - this, &bContinue); - if (bContinue) continue; + bool bContinue = false; + NETWORKMODULECALL(OnUserNoticeMessage(Message), m_pUser, m_pNetwork, + this, &bContinue); + if (bContinue) continue; - if (!GetIRCSock()) { - // Some lagmeters do a NOTICE to their own nick, ignore those. - if (!sTarget.Equals(m_sNick)) - PutStatus("Your notice to [" + Message.GetTarget() + - "] got lost, " - "you are not connected to IRC!"); - continue; - } + if (!GetIRCSock()) { + // Some lagmeters do a NOTICE to their own nick, ignore those. + if (!sTarget.Equals(m_sNick)) + PutStatus("Your notice to [" + Message.GetTarget() + + "] got lost, " + "you are not connected to IRC!"); + continue; + } - if (m_pNetwork) { - AddBuffer(Message); - EchoMessage(Message); - PutIRC(Message.ToString(CMessage::ExcludePrefix | - CMessage::ExcludeTags)); - } - } + if (m_pNetwork) { + AddBuffer(Message); + EchoMessage(Message); + PutIRC(Message.ToString(CMessage::ExcludePrefix | + CMessage::ExcludeTags)); + } + } - return true; + return true; } bool CClient::OnPartMessage(CPartMessage& Message) { - CString sChans = Message.GetTarget(); + CString sChans = Message.GetTarget(); - VCString vsChans; - sChans.Split(",", vsChans, false); - sChans.clear(); + VCString vsChans; + sChans.Split(",", vsChans, false); + sChans.clear(); - for (CString& sChan : vsChans) { - bool bContinue = false; - Message.SetTarget(sChan); - NETWORKMODULECALL(OnUserPartMessage(Message), m_pUser, m_pNetwork, this, - &bContinue); - if (bContinue) continue; + for (CString& sChan : vsChans) { + bool bContinue = false; + Message.SetTarget(sChan); + NETWORKMODULECALL(OnUserPartMessage(Message), m_pUser, m_pNetwork, this, + &bContinue); + if (bContinue) continue; - sChan = Message.GetTarget(); + sChan = Message.GetTarget(); - CChan* pChan = m_pNetwork ? m_pNetwork->FindChan(sChan) : nullptr; + CChan* pChan = m_pNetwork ? m_pNetwork->FindChan(sChan) : nullptr; - if (pChan && !pChan->IsOn()) { - PutStatusNotice("Removing channel [" + sChan + "]"); - m_pNetwork->DelChan(sChan); - } else { - sChans += (sChans.empty()) ? sChan : CString("," + sChan); - } - } + if (pChan && !pChan->IsOn()) { + PutStatusNotice("Removing channel [" + sChan + "]"); + m_pNetwork->DelChan(sChan); + } else { + sChans += (sChans.empty()) ? sChan : CString("," + sChan); + } + } - if (sChans.empty()) { - return true; - } + if (sChans.empty()) { + return true; + } - Message.SetTarget(sChans); + Message.SetTarget(sChans); - return false; + return false; } bool CClient::OnPingMessage(CMessage& Message) { - // All PONGs are generated by ZNC. We will still forward this to - // the ircd, but all PONGs from irc will be blocked. - if (!Message.GetParams().empty()) - PutClient(":irc.znc.in PONG irc.znc.in " + Message.GetParams(0)); - else - PutClient(":irc.znc.in PONG irc.znc.in"); - return false; + // All PONGs are generated by ZNC. We will still forward this to + // the ircd, but all PONGs from irc will be blocked. + if (!Message.GetParams().empty()) + PutClient(":irc.znc.in PONG irc.znc.in " + Message.GetParams(0)); + else + PutClient(":irc.znc.in PONG irc.znc.in"); + return false; } bool CClient::OnPongMessage(CMessage& Message) { - // Block PONGs, we already responded to the pings - return true; + // Block PONGs, we already responded to the pings + return true; } bool CClient::OnQuitMessage(CQuitMessage& Message) { - bool bReturn = false; - NETWORKMODULECALL(OnUserQuitMessage(Message), m_pUser, m_pNetwork, this, - &bReturn); - if (!bReturn) { - Close(Csock::CLT_AFTERWRITE); // Treat a client quit as a detach - } - // Don't forward this msg. We don't want the client getting us - // disconnected. - return true; + bool bReturn = false; + NETWORKMODULECALL(OnUserQuitMessage(Message), m_pUser, m_pNetwork, this, + &bReturn); + if (!bReturn) { + Close(Csock::CLT_AFTERWRITE); // Treat a client quit as a detach + } + // Don't forward this msg. We don't want the client getting us + // disconnected. + return true; } bool CClient::OnTextMessage(CTextMessage& Message) { - CString sTargets = Message.GetTarget(); + CString sTargets = Message.GetTarget(); - VCString vTargets; - sTargets.Split(",", vTargets, false); + VCString vTargets; + sTargets.Split(",", vTargets, false); - for (CString& sTarget : vTargets) { - Message.SetTarget(sTarget); + for (CString& sTarget : vTargets) { + Message.SetTarget(sTarget); - if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { - EchoMessage(Message); - if (sTarget.Equals("status")) { - CString sMsg = Message.GetText(); - UserCommand(sMsg); - } else { - CALLMOD(sTarget, this, m_pUser, m_pNetwork, - OnModCommand(Message.GetText())); - } - continue; - } + if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { + EchoMessage(Message); + if (sTarget.Equals("status")) { + CString sMsg = Message.GetText(); + UserCommand(sMsg); + } else { + CALLMOD(sTarget, this, m_pUser, m_pNetwork, + OnModCommand(Message.GetText())); + } + continue; + } - bool bContinue = false; - NETWORKMODULECALL(OnUserTextMessage(Message), m_pUser, m_pNetwork, this, - &bContinue); - if (bContinue) continue; + bool bContinue = false; + NETWORKMODULECALL(OnUserTextMessage(Message), m_pUser, m_pNetwork, this, + &bContinue); + if (bContinue) continue; - if (!GetIRCSock()) { - // Some lagmeters do a PRIVMSG to their own nick, ignore those. - if (!sTarget.Equals(m_sNick)) - PutStatus("Your message to [" + Message.GetTarget() + - "] got lost, " - "you are not connected to IRC!"); - continue; - } + if (!GetIRCSock()) { + // Some lagmeters do a PRIVMSG to their own nick, ignore those. + if (!sTarget.Equals(m_sNick)) + PutStatus("Your message to [" + Message.GetTarget() + + "] got lost, " + "you are not connected to IRC!"); + continue; + } - if (m_pNetwork) { - AddBuffer(Message); - EchoMessage(Message); - PutIRC(Message.ToString(CMessage::ExcludePrefix | - CMessage::ExcludeTags)); - } - } + if (m_pNetwork) { + AddBuffer(Message); + EchoMessage(Message); + PutIRC(Message.ToString(CMessage::ExcludePrefix | + CMessage::ExcludeTags)); + } + } - return true; + return true; } bool CClient::OnTopicMessage(CTopicMessage& Message) { - bool bReturn = false; - CString sChan = Message.GetTarget(); - CString sTopic = Message.GetTopic(); + bool bReturn = false; + CString sChan = Message.GetTarget(); + CString sTopic = Message.GetTopic(); - if (!sTopic.empty()) { - NETWORKMODULECALL(OnUserTopicMessage(Message), m_pUser, m_pNetwork, - this, &bReturn); - } else { - NETWORKMODULECALL(OnUserTopicRequest(sChan), m_pUser, m_pNetwork, this, - &bReturn); - Message.SetTarget(sChan); - } + if (!sTopic.empty()) { + NETWORKMODULECALL(OnUserTopicMessage(Message), m_pUser, m_pNetwork, + this, &bReturn); + } else { + NETWORKMODULECALL(OnUserTopicRequest(sChan), m_pUser, m_pNetwork, this, + &bReturn); + Message.SetTarget(sChan); + } - return bReturn; + return bReturn; } bool CClient::OnOtherMessage(CMessage& Message) { - const CString& sCommand = Message.GetCommand(); + const CString& sCommand = Message.GetCommand(); - if (sCommand.Equals("ZNC")) { - CString sTarget = Message.GetParam(0); - CString sModCommand; + if (sCommand.Equals("ZNC")) { + CString sTarget = Message.GetParam(0); + CString sModCommand; - if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { - sModCommand = Message.GetParams(1); - } else { - sTarget = "status"; - sModCommand = Message.GetParams(0); - } + if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { + sModCommand = Message.GetParams(1); + } else { + sTarget = "status"; + sModCommand = Message.GetParams(0); + } - if (sTarget.Equals("status")) { - if (sModCommand.empty()) - PutStatus("Hello. How may I help you?"); - else - UserCommand(sModCommand); - } else { - if (sModCommand.empty()) - CALLMOD(sTarget, this, m_pUser, m_pNetwork, - PutModule("Hello. How may I help you?")) - else - CALLMOD(sTarget, this, m_pUser, m_pNetwork, - OnModCommand(sModCommand)) - } - return true; - } else if (sCommand.Equals("ATTACH")) { - if (!m_pNetwork) { - return true; - } + if (sTarget.Equals("status")) { + if (sModCommand.empty()) + PutStatus("Hello. How may I help you?"); + else + UserCommand(sModCommand); + } else { + if (sModCommand.empty()) + CALLMOD(sTarget, this, m_pUser, m_pNetwork, + PutModule("Hello. How may I help you?")) + else + CALLMOD(sTarget, this, m_pUser, m_pNetwork, + OnModCommand(sModCommand)) + } + return true; + } else if (sCommand.Equals("ATTACH")) { + if (!m_pNetwork) { + return true; + } - CString sPatterns = Message.GetParams(0); + CString sPatterns = Message.GetParams(0); - if (sPatterns.empty()) { - PutStatusNotice("Usage: /attach <#chans|queries>"); - return true; - } + if (sPatterns.empty()) { + PutStatusNotice("Usage: /attach <#chans|queries>"); + return true; + } - set sChans = MatchChans(sPatterns); - unsigned int uAttachedChans = AttachChans(sChans); + set sChans = MatchChans(sPatterns); + unsigned int uAttachedChans = AttachChans(sChans); - PutStatusNotice("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatusNotice("Attached [" + CString(uAttachedChans) + "] channels"); + PutStatusNotice("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatusNotice("Attached [" + CString(uAttachedChans) + "] channels"); - return true; - } else if (sCommand.Equals("DETACH")) { - if (!m_pNetwork) { - return true; - } + return true; + } else if (sCommand.Equals("DETACH")) { + if (!m_pNetwork) { + return true; + } - CString sPatterns = Message.GetParams(0); + CString sPatterns = Message.GetParams(0); - if (sPatterns.empty()) { - PutStatusNotice("Usage: /detach <#chans>"); - return true; - } + if (sPatterns.empty()) { + PutStatusNotice("Usage: /detach <#chans>"); + return true; + } - set sChans = MatchChans(sPatterns); - unsigned int uDetached = DetachChans(sChans); + set sChans = MatchChans(sPatterns); + unsigned int uDetached = DetachChans(sChans); - PutStatusNotice("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatusNotice("Detached [" + CString(uDetached) + "] channels"); + PutStatusNotice("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatusNotice("Detached [" + CString(uDetached) + "] channels"); - return true; - } else if (sCommand.Equals("PROTOCTL")) { - for (const CString& sParam : Message.GetParams()) { - if (sParam == "NAMESX") { - m_bNamesx = true; - } else if (sParam == "UHNAMES") { - m_bUHNames = true; - } - } - return true; // If the server understands it, we already enabled namesx - // / uhnames - } + return true; + } else if (sCommand.Equals("PROTOCTL")) { + for (const CString& sParam : Message.GetParams()) { + if (sParam == "NAMESX") { + m_bNamesx = true; + } else if (sParam == "UHNAMES") { + m_bUHNames = true; + } + } + return true; // If the server understands it, we already enabled namesx + // / uhnames + } - return false; + return false; } diff --git a/src/ClientCommand.cpp b/src/ClientCommand.cpp index ebedbcca..61c72585 100644 --- a/src/ClientCommand.cpp +++ b/src/ClientCommand.cpp @@ -28,1851 +28,1851 @@ using std::set; using std::map; void CClient::UserCommand(CString& sLine) { - if (!m_pUser) { - return; - } - - if (sLine.empty()) { - return; - } - - bool bReturn = false; - NETWORKMODULECALL(OnStatusCommand(sLine), m_pUser, m_pNetwork, this, - &bReturn); - if (bReturn) return; - - const CString sCommand = sLine.Token(0); - - if (sCommand.Equals("HELP")) { - HelpUser(sLine.Token(1)); - } else if (sCommand.Equals("LISTNICKS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sChan = sLine.Token(1); - - if (sChan.empty()) { - PutStatus("Usage: ListNicks <#chan>"); - return; - } - - CChan* pChan = m_pNetwork->FindChan(sChan); - - if (!pChan) { - PutStatus("You are not on [" + sChan + "]"); - return; - } - - if (!pChan->IsOn()) { - PutStatus("You are not on [" + sChan + "] [trying]"); - return; - } - - const map& msNicks = pChan->GetNicks(); - CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); - const CString& sPerms = (pIRCSock) ? pIRCSock->GetPerms() : ""; - - if (msNicks.empty()) { - PutStatus("No nicks on [" + sChan + "]"); - return; - } - - CTable Table; - - for (unsigned int p = 0; p < sPerms.size(); p++) { - CString sPerm; - sPerm += sPerms[p]; - Table.AddColumn(sPerm); - } - - Table.AddColumn("Nick"); - Table.AddColumn("Ident"); - Table.AddColumn("Host"); - - for (const auto& it : msNicks) { - Table.AddRow(); - - for (unsigned int b = 0; b < sPerms.size(); b++) { - if (it.second.HasPerm(sPerms[b])) { - CString sPerm; - sPerm += sPerms[b]; - Table.SetCell(sPerm, sPerm); - } - } - - Table.SetCell("Nick", it.second.GetNick()); - Table.SetCell("Ident", it.second.GetIdent()); - Table.SetCell("Host", it.second.GetHost()); - } - - PutStatus(Table); - } else if (sCommand.Equals("ATTACH")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sPatterns = sLine.Token(1, true); - - if (sPatterns.empty()) { - PutStatus("Usage: Attach <#chans|queries>"); - return; - } - - set sChans = MatchChans(sPatterns); - unsigned int uAttachedChans = AttachChans(sChans); - - PutStatus("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatus("Attached [" + CString(uAttachedChans) + "] channels"); - } else if (sCommand.Equals("DETACH")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sPatterns = sLine.Token(1, true); - - if (sPatterns.empty()) { - PutStatus("Usage: Detach <#chans>"); - return; - } - - set sChans = MatchChans(sPatterns); - unsigned int uDetached = DetachChans(sChans); - - PutStatus("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatus("Detached [" + CString(uDetached) + "] channels"); - } else if (sCommand.Equals("VERSION")) { - PutStatus(CZNC::GetTag()); - PutStatus(CZNC::GetCompileOptionsString()); - } else if (sCommand.Equals("MOTD") || sCommand.Equals("ShowMOTD")) { - if (!SendMotd()) { - PutStatus("There is no MOTD set."); - } - } else if (m_pUser->IsAdmin() && sCommand.Equals("Rehash")) { - CString sRet; - - if (CZNC::Get().RehashConfig(sRet)) { - PutStatus("Rehashing succeeded!"); - } else { - PutStatus("Rehashing failed: " + sRet); - } - } else if (m_pUser->IsAdmin() && sCommand.Equals("SaveConfig")) { - if (CZNC::Get().WriteConfig()) { - PutStatus("Wrote config to [" + CZNC::Get().GetConfigFile() + "]"); - } else { - PutStatus("Error while trying to write config."); - } - } else if (sCommand.Equals("LISTCLIENTS")) { - CUser* pUser = m_pUser; - CString sNick = sLine.Token(1); - - if (!sNick.empty()) { - if (!m_pUser->IsAdmin()) { - PutStatus("Usage: ListClients"); - return; - } - - pUser = CZNC::Get().FindUser(sNick); - - if (!pUser) { - PutStatus("No such user [" + sNick + "]"); - return; - } - } - - vector vClients = pUser->GetAllClients(); - - if (vClients.empty()) { - PutStatus("No clients are connected"); - return; - } - - CTable Table; - Table.AddColumn("Host"); - Table.AddColumn("Network"); - Table.AddColumn("Identifier"); - - for (const CClient* pClient : vClients) { - Table.AddRow(); - Table.SetCell("Host", pClient->GetRemoteIP()); - if (pClient->GetNetwork()) { - Table.SetCell("Network", pClient->GetNetwork()->GetName()); - } - Table.SetCell("Identifier", pClient->GetIdentifier()); - } - - PutStatus(Table); - } else if (m_pUser->IsAdmin() && sCommand.Equals("LISTUSERS")) { - const map& msUsers = CZNC::Get().GetUserMap(); - CTable Table; - Table.AddColumn("Username"); - Table.AddColumn("Networks"); - Table.AddColumn("Clients"); - - for (const auto& it : msUsers) { - Table.AddRow(); - Table.SetCell("Username", it.first); - Table.SetCell("Networks", CString(it.second->GetNetworks().size())); - Table.SetCell("Clients", - CString(it.second->GetAllClients().size())); - } - - PutStatus(Table); - } else if (m_pUser->IsAdmin() && sCommand.Equals("LISTALLUSERNETWORKS")) { - const map& msUsers = CZNC::Get().GetUserMap(); - CTable Table; - Table.AddColumn("Username"); - Table.AddColumn("Network"); - Table.AddColumn("Clients"); - Table.AddColumn("OnIRC"); - Table.AddColumn("IRC Server"); - Table.AddColumn("IRC User"); - Table.AddColumn("Channels"); - - for (const auto& it : msUsers) { - Table.AddRow(); - Table.SetCell("Username", it.first); - Table.SetCell("Network", "N/A"); - Table.SetCell("Clients", - CString(it.second->GetUserClients().size())); - - const vector& vNetworks = it.second->GetNetworks(); - - for (const CIRCNetwork* pNetwork : vNetworks) { - Table.AddRow(); - if (pNetwork == vNetworks.back()) { - Table.SetCell("Username", "`-"); - } else { - Table.SetCell("Username", "|-"); - } - Table.SetCell("Network", pNetwork->GetName()); - Table.SetCell("Clients", - CString(pNetwork->GetClients().size())); - if (pNetwork->IsIRCConnected()) { - Table.SetCell("OnIRC", "Yes"); - Table.SetCell("IRC Server", pNetwork->GetIRCServer()); - Table.SetCell("IRC User", - pNetwork->GetIRCNick().GetNickMask()); - Table.SetCell("Channels", - CString(pNetwork->GetChans().size())); - } else { - Table.SetCell("OnIRC", "No"); - } - } - } - - PutStatus(Table); - } else if (m_pUser->IsAdmin() && sCommand.Equals("SetMOTD")) { - CString sMessage = sLine.Token(1, true); - - if (sMessage.empty()) { - PutStatus("Usage: SetMOTD "); - } else { - CZNC::Get().SetMotd(sMessage); - PutStatus("MOTD set to [" + sMessage + "]"); - } - } else if (m_pUser->IsAdmin() && sCommand.Equals("AddMOTD")) { - CString sMessage = sLine.Token(1, true); - - if (sMessage.empty()) { - PutStatus("Usage: AddMOTD "); - } else { - CZNC::Get().AddMotd(sMessage); - PutStatus("Added [" + sMessage + "] to MOTD"); - } - } else if (m_pUser->IsAdmin() && sCommand.Equals("ClearMOTD")) { - CZNC::Get().ClearMotd(); - PutStatus("Cleared MOTD"); - } else if (m_pUser->IsAdmin() && sCommand.Equals("BROADCAST")) { - CZNC::Get().Broadcast(sLine.Token(1, true)); - } else if (m_pUser->IsAdmin() && - (sCommand.Equals("SHUTDOWN") || sCommand.Equals("RESTART"))) { - bool bRestart = sCommand.Equals("RESTART"); - CString sMessage = sLine.Token(1, true); - bool bForce = false; - - if (sMessage.Token(0).Equals("FORCE")) { - bForce = true; - sMessage = sMessage.Token(1, true); - } - - if (sMessage.empty()) { - sMessage = (bRestart ? "ZNC is being restarted NOW!" - : "ZNC is being shut down NOW!"); - } - - if (!CZNC::Get().WriteConfig() && !bForce) { - PutStatus( - "ERROR: Writing config file to disk failed! Aborting. Use " + - sCommand.AsUpper() + " FORCE to ignore."); - } else { - CZNC::Get().Broadcast(sMessage); - throw CException(bRestart ? CException::EX_Restart - : CException::EX_Shutdown); - } - } else if (sCommand.Equals("JUMP") || sCommand.Equals("CONNECT")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - if (!m_pNetwork->HasServers()) { - PutStatus("You don't have any servers added."); - return; - } - - CString sArgs = sLine.Token(1, true); - sArgs.Trim(); - CServer* pServer = nullptr; - - if (!sArgs.empty()) { - pServer = m_pNetwork->FindServer(sArgs); - if (!pServer) { - PutStatus("Server [" + sArgs + "] not found"); - return; - } - m_pNetwork->SetNextServer(pServer); - - // If we are already connecting to some server, - // we have to abort that attempt - Csock* pIRCSock = GetIRCSock(); - if (pIRCSock && !pIRCSock->IsConnected()) { - pIRCSock->Close(); - } - } - - if (!pServer) { - pServer = m_pNetwork->GetNextServer(false); - } - - if (GetIRCSock()) { - GetIRCSock()->Quit(); - if (pServer) - PutStatus("Connecting to [" + pServer->GetName() + "]..."); - else - PutStatus("Jumping to the next server in the list..."); - } else { - if (pServer) - PutStatus("Connecting to [" + pServer->GetName() + "]..."); - else - PutStatus("Connecting..."); - } - - m_pNetwork->SetIRCConnectEnabled(true); - return; - } else if (sCommand.Equals("DISCONNECT")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - if (GetIRCSock()) { - CString sQuitMsg = sLine.Token(1, true); - GetIRCSock()->Quit(sQuitMsg); - } - - m_pNetwork->SetIRCConnectEnabled(false); - PutStatus("Disconnected from IRC. Use 'connect' to reconnect."); - return; - } else if (sCommand.Equals("ENABLECHAN")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sPatterns = sLine.Token(1, true); - - if (sPatterns.empty()) { - PutStatus("Usage: EnableChan <#chans>"); - } else { - set sChans = MatchChans(sPatterns); - - unsigned int uEnabled = 0; - for (CChan* pChan : sChans) { - if (!pChan->IsDisabled()) continue; - uEnabled++; - pChan->Enable(); - } - - PutStatus("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatus("Enabled [" + CString(uEnabled) + "] channels"); - } - } else if (sCommand.Equals("DISABLECHAN")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sPatterns = sLine.Token(1, true); - - if (sPatterns.empty()) { - PutStatus("Usage: DisableChan <#chans>"); - } else { - set sChans = MatchChans(sPatterns); - - unsigned int uDisabled = 0; - for (CChan* pChan : sChans) { - if (pChan->IsDisabled()) continue; - uDisabled++; - pChan->Disable(); - } - - PutStatus("There were [" + CString(sChans.size()) + - "] channels matching [" + sPatterns + "]"); - PutStatus("Disabled [" + CString(uDisabled) + "] channels"); - } - } else if (sCommand.Equals("SHOWCHAN")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sChan = sLine.Token(1, true); - if (sChan.empty()) { - PutStatus("Usage: ShowChan <#chan>"); - return; - } - - CChan* pChan = m_pNetwork->FindChan(sChan); - if (!pChan) { - PutStatus("No such channel [" + sChan + "]"); - return; - } - sChan = pChan->GetPermStr() + pChan->GetName(); - CString sStatus = pChan->IsOn() - ? (pChan->IsDetached() ? "Detached" : "Joined") - : (pChan->IsDisabled() ? "Disabled" : "Trying"); - - CTable Table; - Table.AddColumn(sChan); - Table.AddColumn(sStatus); - - Table.AddRow(); - Table.SetCell(sChan, "InConfig"); - Table.SetCell(sStatus, CString(pChan->InConfig() ? "yes" : "no")); - - Table.AddRow(); - Table.SetCell(sChan, "Buffer"); - Table.SetCell( - sStatus, - CString(pChan->GetBuffer().Size()) + "/" + - CString(pChan->GetBufferCount()) + - CString(pChan->HasBufferCountSet() ? "" : " (default)")); - - Table.AddRow(); - Table.SetCell(sChan, "AutoClearChanBuffer"); - Table.SetCell( - sStatus, - CString(pChan->AutoClearChanBuffer() ? "yes" : "no") + - CString(pChan->HasAutoClearChanBufferSet() ? "" - : " (default)")); - - if (pChan->IsOn()) { - Table.AddRow(); - Table.SetCell(sChan, "Topic"); - Table.SetCell(sStatus, pChan->GetTopic()); - - Table.AddRow(); - Table.SetCell(sChan, "Modes"); - Table.SetCell(sStatus, pChan->GetModeString()); - - Table.AddRow(); - Table.SetCell(sChan, "Users"); - - VCString vsUsers; - vsUsers.push_back("All: " + CString(pChan->GetNickCount())); - - CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); - const CString& sPerms = pIRCSock ? pIRCSock->GetPerms() : ""; - map mPerms = pChan->GetPermCounts(); - for (char cPerm : sPerms) { - vsUsers.push_back(CString(cPerm) + ": " + - CString(mPerms[cPerm])); - } - Table.SetCell(sStatus, - CString(", ").Join(vsUsers.begin(), vsUsers.end())); - } - - PutStatus(Table); - } else if (sCommand.Equals("LISTCHANS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CIRCNetwork* pNetwork = m_pNetwork; - - const CString sNick = sLine.Token(1); - const CString sNetwork = sLine.Token(2); - - if (!sNick.empty()) { - if (!m_pUser->IsAdmin()) { - PutStatus("Usage: ListChans"); - return; - } - - CUser* pUser = CZNC::Get().FindUser(sNick); - - if (!pUser) { - PutStatus("No such user [" + sNick + "]"); - return; - } - - pNetwork = pUser->FindNetwork(sNetwork); - if (!pNetwork) { - PutStatus("No such network for user [" + sNetwork + "]"); - return; - } - } - - const vector& vChans = pNetwork->GetChans(); - - if (vChans.empty()) { - PutStatus("There are no channels defined."); - return; - } - - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Status"); - - unsigned int uNumDetached = 0, uNumDisabled = 0, uNumJoined = 0; - - for (const CChan* pChan : vChans) { - Table.AddRow(); - Table.SetCell("Name", pChan->GetPermStr() + pChan->GetName()); - Table.SetCell( - "Status", - ((pChan->IsOn()) - ? ((pChan->IsDetached()) ? "Detached" : "Joined") - : ((pChan->IsDisabled()) ? "Disabled" : "Trying"))); - - if (pChan->IsDetached()) uNumDetached++; - if (pChan->IsOn()) uNumJoined++; - if (pChan->IsDisabled()) uNumDisabled++; - } - - PutStatus(Table); - PutStatus("Total: " + CString(vChans.size()) + " - Joined: " + - CString(uNumJoined) + " - Detached: " + - CString(uNumDetached) + " - Disabled: " + - CString(uNumDisabled)); - } else if (sCommand.Equals("ADDNETWORK")) { - if (!m_pUser->IsAdmin() && !m_pUser->HasSpaceForNewNetwork()) { - PutStatus( - "Network number limit reached. Ask an admin to increase the " - "limit for you, or delete unneeded networks using /znc " - "DelNetwork "); - return; - } - - CString sNetwork = sLine.Token(1); - - if (sNetwork.empty()) { - PutStatus("Usage: AddNetwork "); - return; - } - if (!CIRCNetwork::IsValidNetwork(sNetwork)) { - PutStatus("Network name should be alphanumeric"); - return; - } - - CString sNetworkAddError; - if (m_pUser->AddNetwork(sNetwork, sNetworkAddError)) { - PutStatus("Network added. Use /znc JumpNetwork " + sNetwork + - ", or connect to ZNC with username " + - m_pUser->GetUserName() + "/" + sNetwork + - " (instead of just " + m_pUser->GetUserName() + - ") to connect to it."); - } else { - PutStatus("Unable to add that network"); - PutStatus(sNetworkAddError); - } - } else if (sCommand.Equals("DELNETWORK")) { - CString sNetwork = sLine.Token(1); - - if (sNetwork.empty()) { - PutStatus("Usage: DelNetwork "); - return; - } - - if (m_pNetwork && m_pNetwork->GetName().Equals(sNetwork)) { - SetNetwork(nullptr); - } - - if (m_pUser->DeleteNetwork(sNetwork)) { - PutStatus("Network deleted"); - } else { - PutStatus("Failed to delete network"); - PutStatus("Perhaps this network doesn't exist"); - } - } else if (sCommand.Equals("LISTNETWORKS")) { - CUser* pUser = m_pUser; - - if (m_pUser->IsAdmin() && !sLine.Token(1).empty()) { - pUser = CZNC::Get().FindUser(sLine.Token(1)); - - if (!pUser) { - PutStatus("User not found " + sLine.Token(1)); - return; - } - } - - const vector& vNetworks = pUser->GetNetworks(); - - CTable Table; - Table.AddColumn("Network"); - Table.AddColumn("OnIRC"); - Table.AddColumn("IRC Server"); - Table.AddColumn("IRC User"); - Table.AddColumn("Channels"); - - for (const CIRCNetwork* pNetwork : vNetworks) { - Table.AddRow(); - Table.SetCell("Network", pNetwork->GetName()); - if (pNetwork->IsIRCConnected()) { - Table.SetCell("OnIRC", "Yes"); - Table.SetCell("IRC Server", pNetwork->GetIRCServer()); - Table.SetCell("IRC User", pNetwork->GetIRCNick().GetNickMask()); - Table.SetCell("Channels", CString(pNetwork->GetChans().size())); - } else { - Table.SetCell("OnIRC", "No"); - } - } - - if (PutStatus(Table) == 0) { - PutStatus("No networks"); - } - } else if (sCommand.Equals("MOVENETWORK")) { - if (!m_pUser->IsAdmin()) { - PutStatus("Access Denied."); - return; - } - - CString sOldUser = sLine.Token(1); - CString sOldNetwork = sLine.Token(2); - CString sNewUser = sLine.Token(3); - CString sNewNetwork = sLine.Token(4); - - if (sOldUser.empty() || sOldNetwork.empty() || sNewUser.empty()) { - PutStatus( - "Usage: MoveNetwork [new " - "network]"); - return; - } - if (sNewNetwork.empty()) { - sNewNetwork = sOldNetwork; - } - - CUser* pOldUser = CZNC::Get().FindUser(sOldUser); - if (!pOldUser) { - PutStatus("Old user [" + sOldUser + "] not found."); - return; - } - - CIRCNetwork* pOldNetwork = pOldUser->FindNetwork(sOldNetwork); - if (!pOldNetwork) { - PutStatus("Old network [" + sOldNetwork + "] not found."); - return; - } - - CUser* pNewUser = CZNC::Get().FindUser(sNewUser); - if (!pNewUser) { - PutStatus("New user [" + sOldUser + "] not found."); - return; - } - - if (pNewUser->FindNetwork(sNewNetwork)) { - PutStatus("User [" + sNewUser + "] already has network [" + - sNewNetwork + "]."); - return; - } - - if (!CIRCNetwork::IsValidNetwork(sNewNetwork)) { - PutStatus("Invalid network name [" + sNewNetwork + "]"); - return; - } - - const CModules& vMods = pOldNetwork->GetModules(); - for (CModule* pMod : vMods) { - CString sOldModPath = pOldNetwork->GetNetworkPath() + "/moddata/" + - pMod->GetModName(); - CString sNewModPath = pNewUser->GetUserPath() + "/networks/" + - sNewNetwork + "/moddata/" + - pMod->GetModName(); - - CDir oldDir(sOldModPath); - for (CFile* pFile : oldDir) { - if (pFile->GetShortName() != ".registry") { - PutStatus("Some files seem to be in [" + sOldModPath + - "]. You might want to move them to [" + - sNewModPath + "]"); - break; - } - } - - pMod->MoveRegistry(sNewModPath); - } - - CString sNetworkAddError; - CIRCNetwork* pNewNetwork = - pNewUser->AddNetwork(sNewNetwork, sNetworkAddError); - - if (!pNewNetwork) { - PutStatus("Error adding network:" + sNetworkAddError); - return; - } - - pNewNetwork->Clone(*pOldNetwork, false); - - if (m_pNetwork && m_pNetwork->GetName().Equals(sOldNetwork) && - m_pUser == pOldUser) { - SetNetwork(nullptr); - } - - if (pOldUser->DeleteNetwork(sOldNetwork)) { - PutStatus("Success."); - } else { - PutStatus( - "Copied the network to new user, but failed to delete old " - "network"); - } - } else if (sCommand.Equals("JUMPNETWORK")) { - CString sNetwork = sLine.Token(1); - - if (sNetwork.empty()) { - PutStatus("No network supplied."); - return; - } - - if (m_pNetwork && (m_pNetwork->GetName() == sNetwork)) { - PutStatus("You are already connected with this network."); - return; - } - - CIRCNetwork* pNetwork = m_pUser->FindNetwork(sNetwork); - if (pNetwork) { - PutStatus("Switched to " + sNetwork); - SetNetwork(pNetwork); - } else { - PutStatus("You don't have a network named " + sNetwork); - } - } else if (sCommand.Equals("ADDSERVER")) { - CString sServer = sLine.Token(1); - - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - if (sServer.empty()) { - PutStatus("Usage: AddServer [[+]port] [pass]"); - return; - } - - if (m_pNetwork->AddServer(sLine.Token(1, true))) { - PutStatus("Server added"); - } else { - PutStatus("Unable to add that server"); - PutStatus( - "Perhaps the server is already added or openssl is disabled?"); - } - } else if (sCommand.Equals("REMSERVER") || sCommand.Equals("DELSERVER")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sServer = sLine.Token(1); - unsigned short uPort = sLine.Token(2).ToUShort(); - CString sPass = sLine.Token(3); - - if (sServer.empty()) { - PutStatus("Usage: DelServer [port] [pass]"); - return; - } - - if (!m_pNetwork->HasServers()) { - PutStatus("You don't have any servers added."); - return; - } - - if (m_pNetwork->DelServer(sServer, uPort, sPass)) { - PutStatus("Server removed"); - } else { - PutStatus("No such server"); - } - } else if (sCommand.Equals("LISTSERVERS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - if (m_pNetwork->HasServers()) { - const vector& vServers = m_pNetwork->GetServers(); - CServer* pCurServ = m_pNetwork->GetCurrentServer(); - CTable Table; - Table.AddColumn("Host"); - Table.AddColumn("Port"); - Table.AddColumn("SSL"); - Table.AddColumn("Pass"); - - for (const CServer* pServer : vServers) { - Table.AddRow(); - Table.SetCell("Host", pServer->GetName() + - (pServer == pCurServ ? "*" : "")); - Table.SetCell("Port", CString(pServer->GetPort())); - Table.SetCell("SSL", (pServer->IsSSL()) ? "SSL" : ""); - Table.SetCell("Pass", pServer->GetPass()); - } - - PutStatus(Table); - } else { - PutStatus("You don't have any servers added."); - } - } else if (sCommand.Equals("AddTrustedServerFingerprint")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - CString sFP = sLine.Token(1); - if (sFP.empty()) { - PutStatus("Usage: AddTrustedServerFingerprint "); - return; - } - m_pNetwork->AddTrustedFingerprint(sFP); - PutStatus("Done."); - } else if (sCommand.Equals("DelTrustedServerFingerprint")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - CString sFP = sLine.Token(1); - if (sFP.empty()) { - PutStatus("Usage: DelTrustedServerFingerprint "); - return; - } - m_pNetwork->DelTrustedFingerprint(sFP); - PutStatus("Done."); - } else if (sCommand.Equals("ListTrustedServerFingerprints")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - const SCString& ssFPs = m_pNetwork->GetTrustedFingerprints(); - if (ssFPs.empty()) { - PutStatus("No fingerprints added."); - } else { - int k = 0; - for (const CString& sFP : ssFPs) { - PutStatus(CString(++k) + ". " + sFP); - } - } - } else if (sCommand.Equals("TOPICS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - const vector& vChans = m_pNetwork->GetChans(); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Set By"); - Table.AddColumn("Topic"); - - for (const CChan* pChan : vChans) { - Table.AddRow(); - Table.SetCell("Name", pChan->GetName()); - Table.SetCell("Set By", pChan->GetTopicOwner()); - Table.SetCell("Topic", pChan->GetTopic()); - } - - PutStatus(Table); - } else if (sCommand.Equals("LISTMODS") || sCommand.Equals("LISTMODULES")) { - if (m_pUser->IsAdmin()) { - CModules& GModules = CZNC::Get().GetModules(); - - if (!GModules.size()) { - PutStatus("No global modules loaded."); - } else { - PutStatus("Global modules:"); - CTable GTable; - GTable.AddColumn("Name"); - GTable.AddColumn("Arguments"); - - for (const CModule* pMod : GModules) { - GTable.AddRow(); - GTable.SetCell("Name", pMod->GetModName()); - GTable.SetCell("Arguments", pMod->GetArgs()); - } - - PutStatus(GTable); - } - } - - CModules& Modules = m_pUser->GetModules(); - - if (!Modules.size()) { - PutStatus("Your user has no modules loaded."); - } else { - PutStatus("User modules:"); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Arguments"); - - for (const CModule* pMod : Modules) { - Table.AddRow(); - Table.SetCell("Name", pMod->GetModName()); - Table.SetCell("Arguments", pMod->GetArgs()); - } - - PutStatus(Table); - } - - if (m_pNetwork) { - CModules& NetworkModules = m_pNetwork->GetModules(); - if (NetworkModules.empty()) { - PutStatus("This network has no modules loaded."); - } else { - PutStatus("Network modules:"); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Arguments"); - - for (const CModule* pMod : NetworkModules) { - Table.AddRow(); - Table.SetCell("Name", pMod->GetModName()); - Table.SetCell("Arguments", pMod->GetArgs()); - } - - PutStatus(Table); - } - } - - return; - } else if (sCommand.Equals("LISTAVAILMODS") || - sCommand.Equals("LISTAVAILABLEMODULES")) { - if (m_pUser->DenyLoadMod()) { - PutStatus("Access Denied."); - return; - } - - if (m_pUser->IsAdmin()) { - set ssGlobalMods; - CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, - CModInfo::GlobalModule); - - if (ssGlobalMods.empty()) { - PutStatus("No global modules available."); - } else { - PutStatus("Global modules:"); - CTable GTable; - GTable.AddColumn("Name"); - GTable.AddColumn("Description"); - - for (const CModInfo& Info : ssGlobalMods) { - GTable.AddRow(); - GTable.SetCell( - "Name", - (CZNC::Get().GetModules().FindModule(Info.GetName()) - ? "*" - : " ") + - Info.GetName()); - GTable.SetCell("Description", - Info.GetDescription().Ellipsize(128)); - } - - PutStatus(GTable); - } - } - - set ssUserMods; - CZNC::Get().GetModules().GetAvailableMods(ssUserMods); - - if (ssUserMods.empty()) { - PutStatus("No user modules available."); - } else { - PutStatus("User modules:"); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Description"); - - for (const CModInfo& Info : ssUserMods) { - Table.AddRow(); - Table.SetCell( - "Name", - (m_pUser->GetModules().FindModule(Info.GetName()) ? "*" - : " ") + - Info.GetName()); - Table.SetCell("Description", - Info.GetDescription().Ellipsize(128)); - } - - PutStatus(Table); - } - - set ssNetworkMods; - CZNC::Get().GetModules().GetAvailableMods(ssNetworkMods, - CModInfo::NetworkModule); - - if (ssNetworkMods.empty()) { - PutStatus("No network modules available."); - } else { - PutStatus("Network modules:"); - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Description"); - - for (const CModInfo& Info : ssNetworkMods) { - Table.AddRow(); - Table.SetCell( - "Name", - ((m_pNetwork && - m_pNetwork->GetModules().FindModule(Info.GetName())) - ? "*" - : " ") + - Info.GetName()); - Table.SetCell("Description", - Info.GetDescription().Ellipsize(128)); - } - - PutStatus(Table); - } - return; - } else if (sCommand.Equals("LOADMOD") || sCommand.Equals("LOADMODULE")) { - CModInfo::EModuleType eType; - CString sType = sLine.Token(1); - CString sMod = sLine.Token(2); - CString sArgs = sLine.Token(3, true); - - // TODO use proper library for parsing arguments - if (sType.Equals("--type=global")) { - eType = CModInfo::GlobalModule; - } else if (sType.Equals("--type=user")) { - eType = CModInfo::UserModule; - } else if (sType.Equals("--type=network")) { - eType = CModInfo::NetworkModule; - } else { - sMod = sType; - sArgs = sLine.Token(2, true); - sType = "default"; - // Will be set correctly later - eType = CModInfo::UserModule; - } - - if (m_pUser->DenyLoadMod()) { - PutStatus("Unable to load [" + sMod + "]: Access Denied."); - return; - } - - if (sMod.empty()) { - PutStatus( - "Usage: LoadMod [--type=global|user|network] [args]"); - return; - } - - CModInfo ModInfo; - CString sRetMsg; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { - PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + - "]"); - return; - } - - if (sType.Equals("default")) { - eType = ModInfo.GetDefaultType(); - } - - if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { - PutStatus("Unable to load global module [" + sMod + - "]: Access Denied."); - return; - } - - if (eType == CModInfo::NetworkModule && !m_pNetwork) { - PutStatus("Unable to load network module [" + sMod + - "] Not connected with a network."); - return; - } - - CString sModRet; - bool b = false; - - switch (eType) { - case CModInfo::GlobalModule: - b = CZNC::Get().GetModules().LoadModule( - sMod, sArgs, eType, nullptr, nullptr, sModRet); - break; - case CModInfo::UserModule: - b = m_pUser->GetModules().LoadModule(sMod, sArgs, eType, - m_pUser, nullptr, sModRet); - break; - case CModInfo::NetworkModule: - b = m_pNetwork->GetModules().LoadModule( - sMod, sArgs, eType, m_pUser, m_pNetwork, sModRet); - break; - default: - sModRet = - "Unable to load module [" + sMod + "]: Unknown module type"; - } - - if (b) sModRet = "Loaded module [" + sMod + "] " + sModRet; - - PutStatus(sModRet); - return; - } else if (sCommand.Equals("UNLOADMOD") || - sCommand.Equals("UNLOADMODULE")) { - CModInfo::EModuleType eType = CModInfo::UserModule; - CString sType = sLine.Token(1); - CString sMod = sLine.Token(2); - - // TODO use proper library for parsing arguments - if (sType.Equals("--type=global")) { - eType = CModInfo::GlobalModule; - } else if (sType.Equals("--type=user")) { - eType = CModInfo::UserModule; - } else if (sType.Equals("--type=network")) { - eType = CModInfo::NetworkModule; - } else { - sMod = sType; - sType = "default"; - } - - if (m_pUser->DenyLoadMod()) { - PutStatus("Unable to unload [" + sMod + "] Access Denied."); - return; - } - - if (sMod.empty()) { - PutStatus("Usage: UnloadMod [--type=global|user|network] "); - return; - } - - if (sType.Equals("default")) { - CModInfo ModInfo; - CString sRetMsg; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { - PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + - "]"); - return; - } - - eType = ModInfo.GetDefaultType(); - } - - if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { - PutStatus("Unable to unload global module [" + sMod + - "]: Access Denied."); - return; - } - - if (eType == CModInfo::NetworkModule && !m_pNetwork) { - PutStatus("Unable to unload network module [" + sMod + - "] Not connected with a network."); - return; - } - - CString sModRet; - - switch (eType) { - case CModInfo::GlobalModule: - CZNC::Get().GetModules().UnloadModule(sMod, sModRet); - break; - case CModInfo::UserModule: - m_pUser->GetModules().UnloadModule(sMod, sModRet); - break; - case CModInfo::NetworkModule: - m_pNetwork->GetModules().UnloadModule(sMod, sModRet); - break; - default: - sModRet = "Unable to unload module [" + sMod + - "]: Unknown module type"; - } - - PutStatus(sModRet); - return; - } else if (sCommand.Equals("RELOADMOD") || - sCommand.Equals("RELOADMODULE")) { - CModInfo::EModuleType eType; - CString sType = sLine.Token(1); - CString sMod = sLine.Token(2); - CString sArgs = sLine.Token(3, true); - - if (m_pUser->DenyLoadMod()) { - PutStatus("Unable to reload modules. Access Denied."); - return; - } - - // TODO use proper library for parsing arguments - if (sType.Equals("--type=global")) { - eType = CModInfo::GlobalModule; - } else if (sType.Equals("--type=user")) { - eType = CModInfo::UserModule; - } else if (sType.Equals("--type=network")) { - eType = CModInfo::NetworkModule; - } else { - sMod = sType; - sArgs = sLine.Token(2, true); - sType = "default"; - // Will be set correctly later - eType = CModInfo::UserModule; - } - - if (sMod.empty()) { - PutStatus( - "Usage: ReloadMod [--type=global|user|network] " - "[args]"); - return; - } - - if (sType.Equals("default")) { - CModInfo ModInfo; - CString sRetMsg; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { - PutStatus("Unable to find modinfo for [" + sMod + "] [" + - sRetMsg + "]"); - return; - } - - eType = ModInfo.GetDefaultType(); - } - - if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { - PutStatus("Unable to reload global module [" + sMod + - "]: Access Denied."); - return; - } - - if (eType == CModInfo::NetworkModule && !m_pNetwork) { - PutStatus("Unable to load network module [" + sMod + - "] Not connected with a network."); - return; - } - - CString sModRet; - - switch (eType) { - case CModInfo::GlobalModule: - CZNC::Get().GetModules().ReloadModule(sMod, sArgs, nullptr, - nullptr, sModRet); - break; - case CModInfo::UserModule: - m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, - nullptr, sModRet); - break; - case CModInfo::NetworkModule: - m_pNetwork->GetModules().ReloadModule(sMod, sArgs, m_pUser, - m_pNetwork, sModRet); - break; - default: - sModRet = "Unable to reload module [" + sMod + - "]: Unknown module type"; - } - - PutStatus(sModRet); - return; - } else if ((sCommand.Equals("UPDATEMOD") || - sCommand.Equals("UPDATEMODULE")) && - m_pUser->IsAdmin()) { - CString sMod = sLine.Token(1); - - if (sMod.empty()) { - PutStatus("Usage: UpdateMod "); - return; - } - - PutStatus("Reloading [" + sMod + "] everywhere"); - if (CZNC::Get().UpdateModule(sMod)) { - PutStatus("Done"); - } else { - PutStatus("Done, but there were errors, [" + sMod + - "] could not be loaded everywhere."); - } - } else if ((sCommand.Equals("SETBINDHOST") || - sCommand.Equals("SETVHOST")) && - (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command. Try " - "SetUserBindHost instead"); - return; - } - CString sArg = sLine.Token(1); - - if (sArg.empty()) { - PutStatus("Usage: SetBindHost "); - return; - } - - if (sArg.Equals(m_pNetwork->GetBindHost())) { - PutStatus("You already have this bind host!"); - return; - } - - m_pNetwork->SetBindHost(sArg); - PutStatus("Set bind host for network [" + m_pNetwork->GetName() + - "] to [" + m_pNetwork->GetBindHost() + "]"); - } else if (sCommand.Equals("SETUSERBINDHOST") && - (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { - CString sArg = sLine.Token(1); - - if (sArg.empty()) { - PutStatus("Usage: SetUserBindHost "); - return; - } - - if (sArg.Equals(m_pUser->GetBindHost())) { - PutStatus("You already have this bind host!"); - return; - } - - m_pUser->SetBindHost(sArg); - PutStatus("Set bind host to [" + m_pUser->GetBindHost() + "]"); - } else if ((sCommand.Equals("CLEARBINDHOST") || - sCommand.Equals("CLEARVHOST")) && - (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command. Try " - "ClearUserBindHost instead"); - return; - } - m_pNetwork->SetBindHost(""); - PutStatus("Bind host cleared for this network."); - } else if (sCommand.Equals("CLEARUSERBINDHOST") && - (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { - m_pUser->SetBindHost(""); - PutStatus("Bind host cleared for your user."); - } else if (sCommand.Equals("SHOWBINDHOST")) { - PutStatus("This user's default bind host " + - (m_pUser->GetBindHost().empty() - ? "not set" - : "is [" + m_pUser->GetBindHost() + "]")); - if (m_pNetwork) { - PutStatus("This network's bind host " + - (m_pNetwork->GetBindHost().empty() - ? "not set" - : "is [" + m_pNetwork->GetBindHost() + "]")); - } - } else if (sCommand.Equals("PLAYBUFFER")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sBuffer = sLine.Token(1); - - if (sBuffer.empty()) { - PutStatus("Usage: PlayBuffer <#chan|query>"); - return; - } - - if (m_pNetwork->IsChan(sBuffer)) { - CChan* pChan = m_pNetwork->FindChan(sBuffer); - - if (!pChan) { - PutStatus("You are not on [" + sBuffer + "]"); - return; - } - - if (!pChan->IsOn()) { - PutStatus("You are not on [" + sBuffer + "] [trying]"); - return; - } - - if (pChan->GetBuffer().IsEmpty()) { - PutStatus("The buffer for [" + sBuffer + "] is empty"); - return; - } - - pChan->SendBuffer(this); - } else { - CQuery* pQuery = m_pNetwork->FindQuery(sBuffer); - - if (!pQuery) { - PutStatus("No active query with [" + sBuffer + "]"); - return; - } - - if (pQuery->GetBuffer().IsEmpty()) { - PutStatus("The buffer for [" + sBuffer + "] is empty"); - return; - } - - pQuery->SendBuffer(this); - } - } else if (sCommand.Equals("CLEARBUFFER")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sBuffer = sLine.Token(1); - - if (sBuffer.empty()) { - PutStatus("Usage: ClearBuffer <#chan|query>"); - return; - } - - unsigned int uMatches = 0; - vector vChans = m_pNetwork->FindChans(sBuffer); - for (CChan* pChan : vChans) { - uMatches++; - - pChan->ClearBuffer(); - } - - vector vQueries = m_pNetwork->FindQueries(sBuffer); - for (CQuery* pQuery : vQueries) { - uMatches++; - - m_pNetwork->DelQuery(pQuery->GetName()); - } - - PutStatus("[" + CString(uMatches) + "] buffers matching [" + sBuffer + - "] have been cleared"); - } else if (sCommand.Equals("CLEARALLCHANNELBUFFERS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - for (CChan* pChan : m_pNetwork->GetChans()) { - pChan->ClearBuffer(); - } - PutStatus("All channel buffers have been cleared"); - } else if (sCommand.Equals("CLEARALLQUERYBUFFERS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - m_pNetwork->ClearQueryBuffer(); - PutStatus("All query buffers have been cleared"); - } else if (sCommand.Equals("CLEARALLBUFFERS")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - for (CChan* pChan : m_pNetwork->GetChans()) { - pChan->ClearBuffer(); - } - m_pNetwork->ClearQueryBuffer(); - PutStatus("All buffers have been cleared"); - } else if (sCommand.Equals("SETBUFFER")) { - if (!m_pNetwork) { - PutStatus( - "You must be connected with a network to use this command"); - return; - } - - CString sBuffer = sLine.Token(1); - - if (sBuffer.empty()) { - PutStatus("Usage: SetBuffer <#chan|query> [linecount]"); - return; - } - - unsigned int uLineCount = sLine.Token(2).ToUInt(); - unsigned int uMatches = 0, uFail = 0; - vector vChans = m_pNetwork->FindChans(sBuffer); - for (CChan* pChan : vChans) { - uMatches++; - - if (!pChan->SetBufferCount(uLineCount)) uFail++; - } - - vector vQueries = m_pNetwork->FindQueries(sBuffer); - for (CQuery* pQuery : vQueries) { - uMatches++; - - if (!pQuery->SetBufferCount(uLineCount)) uFail++; - } - - PutStatus("BufferCount for [" + CString(uMatches - uFail) + - "] buffer was set to [" + CString(uLineCount) + "]"); - if (uFail > 0) { - PutStatus("Setting BufferCount failed for [" + CString(uFail) + - "] buffers, " - "max buffer count is " + - CString(CZNC::Get().GetMaxBufferSize())); - } - } else if (m_pUser->IsAdmin() && sCommand.Equals("TRAFFIC")) { - CZNC::TrafficStatsPair Users, ZNC, Total; - CZNC::TrafficStatsMap traffic = - CZNC::Get().GetTrafficStats(Users, ZNC, Total); - - CTable Table; - Table.AddColumn("Username"); - Table.AddColumn("In"); - Table.AddColumn("Out"); - Table.AddColumn("Total"); - - for (const auto& it : traffic) { - Table.AddRow(); - Table.SetCell("Username", it.first); - Table.SetCell("In", CString::ToByteStr(it.second.first)); - Table.SetCell("Out", CString::ToByteStr(it.second.second)); - Table.SetCell("Total", CString::ToByteStr(it.second.first + - it.second.second)); - } - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(Users.first)); - Table.SetCell("Out", CString::ToByteStr(Users.second)); - Table.SetCell("Total", CString::ToByteStr(Users.first + Users.second)); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(ZNC.first)); - Table.SetCell("Out", CString::ToByteStr(ZNC.second)); - Table.SetCell("Total", CString::ToByteStr(ZNC.first + ZNC.second)); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(Total.first)); - Table.SetCell("Out", CString::ToByteStr(Total.second)); - Table.SetCell("Total", CString::ToByteStr(Total.first + Total.second)); - - PutStatus(Table); - } else if (sCommand.Equals("UPTIME")) { - PutStatus("Running for " + CZNC::Get().GetUptime()); - } else if (m_pUser->IsAdmin() && - (sCommand.Equals("LISTPORTS") || sCommand.Equals("ADDPORT") || - sCommand.Equals("DELPORT"))) { - UserPortCommand(sLine); - } else { - PutStatus("Unknown command [" + sCommand + "] try 'Help'"); - } + if (!m_pUser) { + return; + } + + if (sLine.empty()) { + return; + } + + bool bReturn = false; + NETWORKMODULECALL(OnStatusCommand(sLine), m_pUser, m_pNetwork, this, + &bReturn); + if (bReturn) return; + + const CString sCommand = sLine.Token(0); + + if (sCommand.Equals("HELP")) { + HelpUser(sLine.Token(1)); + } else if (sCommand.Equals("LISTNICKS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sChan = sLine.Token(1); + + if (sChan.empty()) { + PutStatus("Usage: ListNicks <#chan>"); + return; + } + + CChan* pChan = m_pNetwork->FindChan(sChan); + + if (!pChan) { + PutStatus("You are not on [" + sChan + "]"); + return; + } + + if (!pChan->IsOn()) { + PutStatus("You are not on [" + sChan + "] [trying]"); + return; + } + + const map& msNicks = pChan->GetNicks(); + CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); + const CString& sPerms = (pIRCSock) ? pIRCSock->GetPerms() : ""; + + if (msNicks.empty()) { + PutStatus("No nicks on [" + sChan + "]"); + return; + } + + CTable Table; + + for (unsigned int p = 0; p < sPerms.size(); p++) { + CString sPerm; + sPerm += sPerms[p]; + Table.AddColumn(sPerm); + } + + Table.AddColumn("Nick"); + Table.AddColumn("Ident"); + Table.AddColumn("Host"); + + for (const auto& it : msNicks) { + Table.AddRow(); + + for (unsigned int b = 0; b < sPerms.size(); b++) { + if (it.second.HasPerm(sPerms[b])) { + CString sPerm; + sPerm += sPerms[b]; + Table.SetCell(sPerm, sPerm); + } + } + + Table.SetCell("Nick", it.second.GetNick()); + Table.SetCell("Ident", it.second.GetIdent()); + Table.SetCell("Host", it.second.GetHost()); + } + + PutStatus(Table); + } else if (sCommand.Equals("ATTACH")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sPatterns = sLine.Token(1, true); + + if (sPatterns.empty()) { + PutStatus("Usage: Attach <#chans|queries>"); + return; + } + + set sChans = MatchChans(sPatterns); + unsigned int uAttachedChans = AttachChans(sChans); + + PutStatus("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatus("Attached [" + CString(uAttachedChans) + "] channels"); + } else if (sCommand.Equals("DETACH")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sPatterns = sLine.Token(1, true); + + if (sPatterns.empty()) { + PutStatus("Usage: Detach <#chans>"); + return; + } + + set sChans = MatchChans(sPatterns); + unsigned int uDetached = DetachChans(sChans); + + PutStatus("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatus("Detached [" + CString(uDetached) + "] channels"); + } else if (sCommand.Equals("VERSION")) { + PutStatus(CZNC::GetTag()); + PutStatus(CZNC::GetCompileOptionsString()); + } else if (sCommand.Equals("MOTD") || sCommand.Equals("ShowMOTD")) { + if (!SendMotd()) { + PutStatus("There is no MOTD set."); + } + } else if (m_pUser->IsAdmin() && sCommand.Equals("Rehash")) { + CString sRet; + + if (CZNC::Get().RehashConfig(sRet)) { + PutStatus("Rehashing succeeded!"); + } else { + PutStatus("Rehashing failed: " + sRet); + } + } else if (m_pUser->IsAdmin() && sCommand.Equals("SaveConfig")) { + if (CZNC::Get().WriteConfig()) { + PutStatus("Wrote config to [" + CZNC::Get().GetConfigFile() + "]"); + } else { + PutStatus("Error while trying to write config."); + } + } else if (sCommand.Equals("LISTCLIENTS")) { + CUser* pUser = m_pUser; + CString sNick = sLine.Token(1); + + if (!sNick.empty()) { + if (!m_pUser->IsAdmin()) { + PutStatus("Usage: ListClients"); + return; + } + + pUser = CZNC::Get().FindUser(sNick); + + if (!pUser) { + PutStatus("No such user [" + sNick + "]"); + return; + } + } + + vector vClients = pUser->GetAllClients(); + + if (vClients.empty()) { + PutStatus("No clients are connected"); + return; + } + + CTable Table; + Table.AddColumn("Host"); + Table.AddColumn("Network"); + Table.AddColumn("Identifier"); + + for (const CClient* pClient : vClients) { + Table.AddRow(); + Table.SetCell("Host", pClient->GetRemoteIP()); + if (pClient->GetNetwork()) { + Table.SetCell("Network", pClient->GetNetwork()->GetName()); + } + Table.SetCell("Identifier", pClient->GetIdentifier()); + } + + PutStatus(Table); + } else if (m_pUser->IsAdmin() && sCommand.Equals("LISTUSERS")) { + const map& msUsers = CZNC::Get().GetUserMap(); + CTable Table; + Table.AddColumn("Username"); + Table.AddColumn("Networks"); + Table.AddColumn("Clients"); + + for (const auto& it : msUsers) { + Table.AddRow(); + Table.SetCell("Username", it.first); + Table.SetCell("Networks", CString(it.second->GetNetworks().size())); + Table.SetCell("Clients", + CString(it.second->GetAllClients().size())); + } + + PutStatus(Table); + } else if (m_pUser->IsAdmin() && sCommand.Equals("LISTALLUSERNETWORKS")) { + const map& msUsers = CZNC::Get().GetUserMap(); + CTable Table; + Table.AddColumn("Username"); + Table.AddColumn("Network"); + Table.AddColumn("Clients"); + Table.AddColumn("OnIRC"); + Table.AddColumn("IRC Server"); + Table.AddColumn("IRC User"); + Table.AddColumn("Channels"); + + for (const auto& it : msUsers) { + Table.AddRow(); + Table.SetCell("Username", it.first); + Table.SetCell("Network", "N/A"); + Table.SetCell("Clients", + CString(it.second->GetUserClients().size())); + + const vector& vNetworks = it.second->GetNetworks(); + + for (const CIRCNetwork* pNetwork : vNetworks) { + Table.AddRow(); + if (pNetwork == vNetworks.back()) { + Table.SetCell("Username", "`-"); + } else { + Table.SetCell("Username", "|-"); + } + Table.SetCell("Network", pNetwork->GetName()); + Table.SetCell("Clients", + CString(pNetwork->GetClients().size())); + if (pNetwork->IsIRCConnected()) { + Table.SetCell("OnIRC", "Yes"); + Table.SetCell("IRC Server", pNetwork->GetIRCServer()); + Table.SetCell("IRC User", + pNetwork->GetIRCNick().GetNickMask()); + Table.SetCell("Channels", + CString(pNetwork->GetChans().size())); + } else { + Table.SetCell("OnIRC", "No"); + } + } + } + + PutStatus(Table); + } else if (m_pUser->IsAdmin() && sCommand.Equals("SetMOTD")) { + CString sMessage = sLine.Token(1, true); + + if (sMessage.empty()) { + PutStatus("Usage: SetMOTD "); + } else { + CZNC::Get().SetMotd(sMessage); + PutStatus("MOTD set to [" + sMessage + "]"); + } + } else if (m_pUser->IsAdmin() && sCommand.Equals("AddMOTD")) { + CString sMessage = sLine.Token(1, true); + + if (sMessage.empty()) { + PutStatus("Usage: AddMOTD "); + } else { + CZNC::Get().AddMotd(sMessage); + PutStatus("Added [" + sMessage + "] to MOTD"); + } + } else if (m_pUser->IsAdmin() && sCommand.Equals("ClearMOTD")) { + CZNC::Get().ClearMotd(); + PutStatus("Cleared MOTD"); + } else if (m_pUser->IsAdmin() && sCommand.Equals("BROADCAST")) { + CZNC::Get().Broadcast(sLine.Token(1, true)); + } else if (m_pUser->IsAdmin() && + (sCommand.Equals("SHUTDOWN") || sCommand.Equals("RESTART"))) { + bool bRestart = sCommand.Equals("RESTART"); + CString sMessage = sLine.Token(1, true); + bool bForce = false; + + if (sMessage.Token(0).Equals("FORCE")) { + bForce = true; + sMessage = sMessage.Token(1, true); + } + + if (sMessage.empty()) { + sMessage = (bRestart ? "ZNC is being restarted NOW!" + : "ZNC is being shut down NOW!"); + } + + if (!CZNC::Get().WriteConfig() && !bForce) { + PutStatus( + "ERROR: Writing config file to disk failed! Aborting. Use " + + sCommand.AsUpper() + " FORCE to ignore."); + } else { + CZNC::Get().Broadcast(sMessage); + throw CException(bRestart ? CException::EX_Restart + : CException::EX_Shutdown); + } + } else if (sCommand.Equals("JUMP") || sCommand.Equals("CONNECT")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + if (!m_pNetwork->HasServers()) { + PutStatus("You don't have any servers added."); + return; + } + + CString sArgs = sLine.Token(1, true); + sArgs.Trim(); + CServer* pServer = nullptr; + + if (!sArgs.empty()) { + pServer = m_pNetwork->FindServer(sArgs); + if (!pServer) { + PutStatus("Server [" + sArgs + "] not found"); + return; + } + m_pNetwork->SetNextServer(pServer); + + // If we are already connecting to some server, + // we have to abort that attempt + Csock* pIRCSock = GetIRCSock(); + if (pIRCSock && !pIRCSock->IsConnected()) { + pIRCSock->Close(); + } + } + + if (!pServer) { + pServer = m_pNetwork->GetNextServer(false); + } + + if (GetIRCSock()) { + GetIRCSock()->Quit(); + if (pServer) + PutStatus("Connecting to [" + pServer->GetName() + "]..."); + else + PutStatus("Jumping to the next server in the list..."); + } else { + if (pServer) + PutStatus("Connecting to [" + pServer->GetName() + "]..."); + else + PutStatus("Connecting..."); + } + + m_pNetwork->SetIRCConnectEnabled(true); + return; + } else if (sCommand.Equals("DISCONNECT")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + if (GetIRCSock()) { + CString sQuitMsg = sLine.Token(1, true); + GetIRCSock()->Quit(sQuitMsg); + } + + m_pNetwork->SetIRCConnectEnabled(false); + PutStatus("Disconnected from IRC. Use 'connect' to reconnect."); + return; + } else if (sCommand.Equals("ENABLECHAN")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sPatterns = sLine.Token(1, true); + + if (sPatterns.empty()) { + PutStatus("Usage: EnableChan <#chans>"); + } else { + set sChans = MatchChans(sPatterns); + + unsigned int uEnabled = 0; + for (CChan* pChan : sChans) { + if (!pChan->IsDisabled()) continue; + uEnabled++; + pChan->Enable(); + } + + PutStatus("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatus("Enabled [" + CString(uEnabled) + "] channels"); + } + } else if (sCommand.Equals("DISABLECHAN")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sPatterns = sLine.Token(1, true); + + if (sPatterns.empty()) { + PutStatus("Usage: DisableChan <#chans>"); + } else { + set sChans = MatchChans(sPatterns); + + unsigned int uDisabled = 0; + for (CChan* pChan : sChans) { + if (pChan->IsDisabled()) continue; + uDisabled++; + pChan->Disable(); + } + + PutStatus("There were [" + CString(sChans.size()) + + "] channels matching [" + sPatterns + "]"); + PutStatus("Disabled [" + CString(uDisabled) + "] channels"); + } + } else if (sCommand.Equals("SHOWCHAN")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sChan = sLine.Token(1, true); + if (sChan.empty()) { + PutStatus("Usage: ShowChan <#chan>"); + return; + } + + CChan* pChan = m_pNetwork->FindChan(sChan); + if (!pChan) { + PutStatus("No such channel [" + sChan + "]"); + return; + } + sChan = pChan->GetPermStr() + pChan->GetName(); + CString sStatus = pChan->IsOn() + ? (pChan->IsDetached() ? "Detached" : "Joined") + : (pChan->IsDisabled() ? "Disabled" : "Trying"); + + CTable Table; + Table.AddColumn(sChan); + Table.AddColumn(sStatus); + + Table.AddRow(); + Table.SetCell(sChan, "InConfig"); + Table.SetCell(sStatus, CString(pChan->InConfig() ? "yes" : "no")); + + Table.AddRow(); + Table.SetCell(sChan, "Buffer"); + Table.SetCell( + sStatus, + CString(pChan->GetBuffer().Size()) + "/" + + CString(pChan->GetBufferCount()) + + CString(pChan->HasBufferCountSet() ? "" : " (default)")); + + Table.AddRow(); + Table.SetCell(sChan, "AutoClearChanBuffer"); + Table.SetCell( + sStatus, + CString(pChan->AutoClearChanBuffer() ? "yes" : "no") + + CString(pChan->HasAutoClearChanBufferSet() ? "" + : " (default)")); + + if (pChan->IsOn()) { + Table.AddRow(); + Table.SetCell(sChan, "Topic"); + Table.SetCell(sStatus, pChan->GetTopic()); + + Table.AddRow(); + Table.SetCell(sChan, "Modes"); + Table.SetCell(sStatus, pChan->GetModeString()); + + Table.AddRow(); + Table.SetCell(sChan, "Users"); + + VCString vsUsers; + vsUsers.push_back("All: " + CString(pChan->GetNickCount())); + + CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); + const CString& sPerms = pIRCSock ? pIRCSock->GetPerms() : ""; + map mPerms = pChan->GetPermCounts(); + for (char cPerm : sPerms) { + vsUsers.push_back(CString(cPerm) + ": " + + CString(mPerms[cPerm])); + } + Table.SetCell(sStatus, + CString(", ").Join(vsUsers.begin(), vsUsers.end())); + } + + PutStatus(Table); + } else if (sCommand.Equals("LISTCHANS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CIRCNetwork* pNetwork = m_pNetwork; + + const CString sNick = sLine.Token(1); + const CString sNetwork = sLine.Token(2); + + if (!sNick.empty()) { + if (!m_pUser->IsAdmin()) { + PutStatus("Usage: ListChans"); + return; + } + + CUser* pUser = CZNC::Get().FindUser(sNick); + + if (!pUser) { + PutStatus("No such user [" + sNick + "]"); + return; + } + + pNetwork = pUser->FindNetwork(sNetwork); + if (!pNetwork) { + PutStatus("No such network for user [" + sNetwork + "]"); + return; + } + } + + const vector& vChans = pNetwork->GetChans(); + + if (vChans.empty()) { + PutStatus("There are no channels defined."); + return; + } + + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Status"); + + unsigned int uNumDetached = 0, uNumDisabled = 0, uNumJoined = 0; + + for (const CChan* pChan : vChans) { + Table.AddRow(); + Table.SetCell("Name", pChan->GetPermStr() + pChan->GetName()); + Table.SetCell( + "Status", + ((pChan->IsOn()) + ? ((pChan->IsDetached()) ? "Detached" : "Joined") + : ((pChan->IsDisabled()) ? "Disabled" : "Trying"))); + + if (pChan->IsDetached()) uNumDetached++; + if (pChan->IsOn()) uNumJoined++; + if (pChan->IsDisabled()) uNumDisabled++; + } + + PutStatus(Table); + PutStatus("Total: " + CString(vChans.size()) + " - Joined: " + + CString(uNumJoined) + " - Detached: " + + CString(uNumDetached) + " - Disabled: " + + CString(uNumDisabled)); + } else if (sCommand.Equals("ADDNETWORK")) { + if (!m_pUser->IsAdmin() && !m_pUser->HasSpaceForNewNetwork()) { + PutStatus( + "Network number limit reached. Ask an admin to increase the " + "limit for you, or delete unneeded networks using /znc " + "DelNetwork "); + return; + } + + CString sNetwork = sLine.Token(1); + + if (sNetwork.empty()) { + PutStatus("Usage: AddNetwork "); + return; + } + if (!CIRCNetwork::IsValidNetwork(sNetwork)) { + PutStatus("Network name should be alphanumeric"); + return; + } + + CString sNetworkAddError; + if (m_pUser->AddNetwork(sNetwork, sNetworkAddError)) { + PutStatus("Network added. Use /znc JumpNetwork " + sNetwork + + ", or connect to ZNC with username " + + m_pUser->GetUserName() + "/" + sNetwork + + " (instead of just " + m_pUser->GetUserName() + + ") to connect to it."); + } else { + PutStatus("Unable to add that network"); + PutStatus(sNetworkAddError); + } + } else if (sCommand.Equals("DELNETWORK")) { + CString sNetwork = sLine.Token(1); + + if (sNetwork.empty()) { + PutStatus("Usage: DelNetwork "); + return; + } + + if (m_pNetwork && m_pNetwork->GetName().Equals(sNetwork)) { + SetNetwork(nullptr); + } + + if (m_pUser->DeleteNetwork(sNetwork)) { + PutStatus("Network deleted"); + } else { + PutStatus("Failed to delete network"); + PutStatus("Perhaps this network doesn't exist"); + } + } else if (sCommand.Equals("LISTNETWORKS")) { + CUser* pUser = m_pUser; + + if (m_pUser->IsAdmin() && !sLine.Token(1).empty()) { + pUser = CZNC::Get().FindUser(sLine.Token(1)); + + if (!pUser) { + PutStatus("User not found " + sLine.Token(1)); + return; + } + } + + const vector& vNetworks = pUser->GetNetworks(); + + CTable Table; + Table.AddColumn("Network"); + Table.AddColumn("OnIRC"); + Table.AddColumn("IRC Server"); + Table.AddColumn("IRC User"); + Table.AddColumn("Channels"); + + for (const CIRCNetwork* pNetwork : vNetworks) { + Table.AddRow(); + Table.SetCell("Network", pNetwork->GetName()); + if (pNetwork->IsIRCConnected()) { + Table.SetCell("OnIRC", "Yes"); + Table.SetCell("IRC Server", pNetwork->GetIRCServer()); + Table.SetCell("IRC User", pNetwork->GetIRCNick().GetNickMask()); + Table.SetCell("Channels", CString(pNetwork->GetChans().size())); + } else { + Table.SetCell("OnIRC", "No"); + } + } + + if (PutStatus(Table) == 0) { + PutStatus("No networks"); + } + } else if (sCommand.Equals("MOVENETWORK")) { + if (!m_pUser->IsAdmin()) { + PutStatus("Access Denied."); + return; + } + + CString sOldUser = sLine.Token(1); + CString sOldNetwork = sLine.Token(2); + CString sNewUser = sLine.Token(3); + CString sNewNetwork = sLine.Token(4); + + if (sOldUser.empty() || sOldNetwork.empty() || sNewUser.empty()) { + PutStatus( + "Usage: MoveNetwork [new " + "network]"); + return; + } + if (sNewNetwork.empty()) { + sNewNetwork = sOldNetwork; + } + + CUser* pOldUser = CZNC::Get().FindUser(sOldUser); + if (!pOldUser) { + PutStatus("Old user [" + sOldUser + "] not found."); + return; + } + + CIRCNetwork* pOldNetwork = pOldUser->FindNetwork(sOldNetwork); + if (!pOldNetwork) { + PutStatus("Old network [" + sOldNetwork + "] not found."); + return; + } + + CUser* pNewUser = CZNC::Get().FindUser(sNewUser); + if (!pNewUser) { + PutStatus("New user [" + sOldUser + "] not found."); + return; + } + + if (pNewUser->FindNetwork(sNewNetwork)) { + PutStatus("User [" + sNewUser + "] already has network [" + + sNewNetwork + "]."); + return; + } + + if (!CIRCNetwork::IsValidNetwork(sNewNetwork)) { + PutStatus("Invalid network name [" + sNewNetwork + "]"); + return; + } + + const CModules& vMods = pOldNetwork->GetModules(); + for (CModule* pMod : vMods) { + CString sOldModPath = pOldNetwork->GetNetworkPath() + "/moddata/" + + pMod->GetModName(); + CString sNewModPath = pNewUser->GetUserPath() + "/networks/" + + sNewNetwork + "/moddata/" + + pMod->GetModName(); + + CDir oldDir(sOldModPath); + for (CFile* pFile : oldDir) { + if (pFile->GetShortName() != ".registry") { + PutStatus("Some files seem to be in [" + sOldModPath + + "]. You might want to move them to [" + + sNewModPath + "]"); + break; + } + } + + pMod->MoveRegistry(sNewModPath); + } + + CString sNetworkAddError; + CIRCNetwork* pNewNetwork = + pNewUser->AddNetwork(sNewNetwork, sNetworkAddError); + + if (!pNewNetwork) { + PutStatus("Error adding network:" + sNetworkAddError); + return; + } + + pNewNetwork->Clone(*pOldNetwork, false); + + if (m_pNetwork && m_pNetwork->GetName().Equals(sOldNetwork) && + m_pUser == pOldUser) { + SetNetwork(nullptr); + } + + if (pOldUser->DeleteNetwork(sOldNetwork)) { + PutStatus("Success."); + } else { + PutStatus( + "Copied the network to new user, but failed to delete old " + "network"); + } + } else if (sCommand.Equals("JUMPNETWORK")) { + CString sNetwork = sLine.Token(1); + + if (sNetwork.empty()) { + PutStatus("No network supplied."); + return; + } + + if (m_pNetwork && (m_pNetwork->GetName() == sNetwork)) { + PutStatus("You are already connected with this network."); + return; + } + + CIRCNetwork* pNetwork = m_pUser->FindNetwork(sNetwork); + if (pNetwork) { + PutStatus("Switched to " + sNetwork); + SetNetwork(pNetwork); + } else { + PutStatus("You don't have a network named " + sNetwork); + } + } else if (sCommand.Equals("ADDSERVER")) { + CString sServer = sLine.Token(1); + + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + if (sServer.empty()) { + PutStatus("Usage: AddServer [[+]port] [pass]"); + return; + } + + if (m_pNetwork->AddServer(sLine.Token(1, true))) { + PutStatus("Server added"); + } else { + PutStatus("Unable to add that server"); + PutStatus( + "Perhaps the server is already added or openssl is disabled?"); + } + } else if (sCommand.Equals("REMSERVER") || sCommand.Equals("DELSERVER")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sServer = sLine.Token(1); + unsigned short uPort = sLine.Token(2).ToUShort(); + CString sPass = sLine.Token(3); + + if (sServer.empty()) { + PutStatus("Usage: DelServer [port] [pass]"); + return; + } + + if (!m_pNetwork->HasServers()) { + PutStatus("You don't have any servers added."); + return; + } + + if (m_pNetwork->DelServer(sServer, uPort, sPass)) { + PutStatus("Server removed"); + } else { + PutStatus("No such server"); + } + } else if (sCommand.Equals("LISTSERVERS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + if (m_pNetwork->HasServers()) { + const vector& vServers = m_pNetwork->GetServers(); + CServer* pCurServ = m_pNetwork->GetCurrentServer(); + CTable Table; + Table.AddColumn("Host"); + Table.AddColumn("Port"); + Table.AddColumn("SSL"); + Table.AddColumn("Pass"); + + for (const CServer* pServer : vServers) { + Table.AddRow(); + Table.SetCell("Host", pServer->GetName() + + (pServer == pCurServ ? "*" : "")); + Table.SetCell("Port", CString(pServer->GetPort())); + Table.SetCell("SSL", (pServer->IsSSL()) ? "SSL" : ""); + Table.SetCell("Pass", pServer->GetPass()); + } + + PutStatus(Table); + } else { + PutStatus("You don't have any servers added."); + } + } else if (sCommand.Equals("AddTrustedServerFingerprint")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + CString sFP = sLine.Token(1); + if (sFP.empty()) { + PutStatus("Usage: AddTrustedServerFingerprint "); + return; + } + m_pNetwork->AddTrustedFingerprint(sFP); + PutStatus("Done."); + } else if (sCommand.Equals("DelTrustedServerFingerprint")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + CString sFP = sLine.Token(1); + if (sFP.empty()) { + PutStatus("Usage: DelTrustedServerFingerprint "); + return; + } + m_pNetwork->DelTrustedFingerprint(sFP); + PutStatus("Done."); + } else if (sCommand.Equals("ListTrustedServerFingerprints")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + const SCString& ssFPs = m_pNetwork->GetTrustedFingerprints(); + if (ssFPs.empty()) { + PutStatus("No fingerprints added."); + } else { + int k = 0; + for (const CString& sFP : ssFPs) { + PutStatus(CString(++k) + ". " + sFP); + } + } + } else if (sCommand.Equals("TOPICS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + const vector& vChans = m_pNetwork->GetChans(); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Set By"); + Table.AddColumn("Topic"); + + for (const CChan* pChan : vChans) { + Table.AddRow(); + Table.SetCell("Name", pChan->GetName()); + Table.SetCell("Set By", pChan->GetTopicOwner()); + Table.SetCell("Topic", pChan->GetTopic()); + } + + PutStatus(Table); + } else if (sCommand.Equals("LISTMODS") || sCommand.Equals("LISTMODULES")) { + if (m_pUser->IsAdmin()) { + CModules& GModules = CZNC::Get().GetModules(); + + if (!GModules.size()) { + PutStatus("No global modules loaded."); + } else { + PutStatus("Global modules:"); + CTable GTable; + GTable.AddColumn("Name"); + GTable.AddColumn("Arguments"); + + for (const CModule* pMod : GModules) { + GTable.AddRow(); + GTable.SetCell("Name", pMod->GetModName()); + GTable.SetCell("Arguments", pMod->GetArgs()); + } + + PutStatus(GTable); + } + } + + CModules& Modules = m_pUser->GetModules(); + + if (!Modules.size()) { + PutStatus("Your user has no modules loaded."); + } else { + PutStatus("User modules:"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Arguments"); + + for (const CModule* pMod : Modules) { + Table.AddRow(); + Table.SetCell("Name", pMod->GetModName()); + Table.SetCell("Arguments", pMod->GetArgs()); + } + + PutStatus(Table); + } + + if (m_pNetwork) { + CModules& NetworkModules = m_pNetwork->GetModules(); + if (NetworkModules.empty()) { + PutStatus("This network has no modules loaded."); + } else { + PutStatus("Network modules:"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Arguments"); + + for (const CModule* pMod : NetworkModules) { + Table.AddRow(); + Table.SetCell("Name", pMod->GetModName()); + Table.SetCell("Arguments", pMod->GetArgs()); + } + + PutStatus(Table); + } + } + + return; + } else if (sCommand.Equals("LISTAVAILMODS") || + sCommand.Equals("LISTAVAILABLEMODULES")) { + if (m_pUser->DenyLoadMod()) { + PutStatus("Access Denied."); + return; + } + + if (m_pUser->IsAdmin()) { + set ssGlobalMods; + CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, + CModInfo::GlobalModule); + + if (ssGlobalMods.empty()) { + PutStatus("No global modules available."); + } else { + PutStatus("Global modules:"); + CTable GTable; + GTable.AddColumn("Name"); + GTable.AddColumn("Description"); + + for (const CModInfo& Info : ssGlobalMods) { + GTable.AddRow(); + GTable.SetCell( + "Name", + (CZNC::Get().GetModules().FindModule(Info.GetName()) + ? "*" + : " ") + + Info.GetName()); + GTable.SetCell("Description", + Info.GetDescription().Ellipsize(128)); + } + + PutStatus(GTable); + } + } + + set ssUserMods; + CZNC::Get().GetModules().GetAvailableMods(ssUserMods); + + if (ssUserMods.empty()) { + PutStatus("No user modules available."); + } else { + PutStatus("User modules:"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Description"); + + for (const CModInfo& Info : ssUserMods) { + Table.AddRow(); + Table.SetCell( + "Name", + (m_pUser->GetModules().FindModule(Info.GetName()) ? "*" + : " ") + + Info.GetName()); + Table.SetCell("Description", + Info.GetDescription().Ellipsize(128)); + } + + PutStatus(Table); + } + + set ssNetworkMods; + CZNC::Get().GetModules().GetAvailableMods(ssNetworkMods, + CModInfo::NetworkModule); + + if (ssNetworkMods.empty()) { + PutStatus("No network modules available."); + } else { + PutStatus("Network modules:"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Description"); + + for (const CModInfo& Info : ssNetworkMods) { + Table.AddRow(); + Table.SetCell( + "Name", + ((m_pNetwork && + m_pNetwork->GetModules().FindModule(Info.GetName())) + ? "*" + : " ") + + Info.GetName()); + Table.SetCell("Description", + Info.GetDescription().Ellipsize(128)); + } + + PutStatus(Table); + } + return; + } else if (sCommand.Equals("LOADMOD") || sCommand.Equals("LOADMODULE")) { + CModInfo::EModuleType eType; + CString sType = sLine.Token(1); + CString sMod = sLine.Token(2); + CString sArgs = sLine.Token(3, true); + + // TODO use proper library for parsing arguments + if (sType.Equals("--type=global")) { + eType = CModInfo::GlobalModule; + } else if (sType.Equals("--type=user")) { + eType = CModInfo::UserModule; + } else if (sType.Equals("--type=network")) { + eType = CModInfo::NetworkModule; + } else { + sMod = sType; + sArgs = sLine.Token(2, true); + sType = "default"; + // Will be set correctly later + eType = CModInfo::UserModule; + } + + if (m_pUser->DenyLoadMod()) { + PutStatus("Unable to load [" + sMod + "]: Access Denied."); + return; + } + + if (sMod.empty()) { + PutStatus( + "Usage: LoadMod [--type=global|user|network] [args]"); + return; + } + + CModInfo ModInfo; + CString sRetMsg; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { + PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + + "]"); + return; + } + + if (sType.Equals("default")) { + eType = ModInfo.GetDefaultType(); + } + + if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { + PutStatus("Unable to load global module [" + sMod + + "]: Access Denied."); + return; + } + + if (eType == CModInfo::NetworkModule && !m_pNetwork) { + PutStatus("Unable to load network module [" + sMod + + "] Not connected with a network."); + return; + } + + CString sModRet; + bool b = false; + + switch (eType) { + case CModInfo::GlobalModule: + b = CZNC::Get().GetModules().LoadModule( + sMod, sArgs, eType, nullptr, nullptr, sModRet); + break; + case CModInfo::UserModule: + b = m_pUser->GetModules().LoadModule(sMod, sArgs, eType, + m_pUser, nullptr, sModRet); + break; + case CModInfo::NetworkModule: + b = m_pNetwork->GetModules().LoadModule( + sMod, sArgs, eType, m_pUser, m_pNetwork, sModRet); + break; + default: + sModRet = + "Unable to load module [" + sMod + "]: Unknown module type"; + } + + if (b) sModRet = "Loaded module [" + sMod + "] " + sModRet; + + PutStatus(sModRet); + return; + } else if (sCommand.Equals("UNLOADMOD") || + sCommand.Equals("UNLOADMODULE")) { + CModInfo::EModuleType eType = CModInfo::UserModule; + CString sType = sLine.Token(1); + CString sMod = sLine.Token(2); + + // TODO use proper library for parsing arguments + if (sType.Equals("--type=global")) { + eType = CModInfo::GlobalModule; + } else if (sType.Equals("--type=user")) { + eType = CModInfo::UserModule; + } else if (sType.Equals("--type=network")) { + eType = CModInfo::NetworkModule; + } else { + sMod = sType; + sType = "default"; + } + + if (m_pUser->DenyLoadMod()) { + PutStatus("Unable to unload [" + sMod + "] Access Denied."); + return; + } + + if (sMod.empty()) { + PutStatus("Usage: UnloadMod [--type=global|user|network] "); + return; + } + + if (sType.Equals("default")) { + CModInfo ModInfo; + CString sRetMsg; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { + PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + + "]"); + return; + } + + eType = ModInfo.GetDefaultType(); + } + + if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { + PutStatus("Unable to unload global module [" + sMod + + "]: Access Denied."); + return; + } + + if (eType == CModInfo::NetworkModule && !m_pNetwork) { + PutStatus("Unable to unload network module [" + sMod + + "] Not connected with a network."); + return; + } + + CString sModRet; + + switch (eType) { + case CModInfo::GlobalModule: + CZNC::Get().GetModules().UnloadModule(sMod, sModRet); + break; + case CModInfo::UserModule: + m_pUser->GetModules().UnloadModule(sMod, sModRet); + break; + case CModInfo::NetworkModule: + m_pNetwork->GetModules().UnloadModule(sMod, sModRet); + break; + default: + sModRet = "Unable to unload module [" + sMod + + "]: Unknown module type"; + } + + PutStatus(sModRet); + return; + } else if (sCommand.Equals("RELOADMOD") || + sCommand.Equals("RELOADMODULE")) { + CModInfo::EModuleType eType; + CString sType = sLine.Token(1); + CString sMod = sLine.Token(2); + CString sArgs = sLine.Token(3, true); + + if (m_pUser->DenyLoadMod()) { + PutStatus("Unable to reload modules. Access Denied."); + return; + } + + // TODO use proper library for parsing arguments + if (sType.Equals("--type=global")) { + eType = CModInfo::GlobalModule; + } else if (sType.Equals("--type=user")) { + eType = CModInfo::UserModule; + } else if (sType.Equals("--type=network")) { + eType = CModInfo::NetworkModule; + } else { + sMod = sType; + sArgs = sLine.Token(2, true); + sType = "default"; + // Will be set correctly later + eType = CModInfo::UserModule; + } + + if (sMod.empty()) { + PutStatus( + "Usage: ReloadMod [--type=global|user|network] " + "[args]"); + return; + } + + if (sType.Equals("default")) { + CModInfo ModInfo; + CString sRetMsg; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { + PutStatus("Unable to find modinfo for [" + sMod + "] [" + + sRetMsg + "]"); + return; + } + + eType = ModInfo.GetDefaultType(); + } + + if (eType == CModInfo::GlobalModule && !m_pUser->IsAdmin()) { + PutStatus("Unable to reload global module [" + sMod + + "]: Access Denied."); + return; + } + + if (eType == CModInfo::NetworkModule && !m_pNetwork) { + PutStatus("Unable to load network module [" + sMod + + "] Not connected with a network."); + return; + } + + CString sModRet; + + switch (eType) { + case CModInfo::GlobalModule: + CZNC::Get().GetModules().ReloadModule(sMod, sArgs, nullptr, + nullptr, sModRet); + break; + case CModInfo::UserModule: + m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, + nullptr, sModRet); + break; + case CModInfo::NetworkModule: + m_pNetwork->GetModules().ReloadModule(sMod, sArgs, m_pUser, + m_pNetwork, sModRet); + break; + default: + sModRet = "Unable to reload module [" + sMod + + "]: Unknown module type"; + } + + PutStatus(sModRet); + return; + } else if ((sCommand.Equals("UPDATEMOD") || + sCommand.Equals("UPDATEMODULE")) && + m_pUser->IsAdmin()) { + CString sMod = sLine.Token(1); + + if (sMod.empty()) { + PutStatus("Usage: UpdateMod "); + return; + } + + PutStatus("Reloading [" + sMod + "] everywhere"); + if (CZNC::Get().UpdateModule(sMod)) { + PutStatus("Done"); + } else { + PutStatus("Done, but there were errors, [" + sMod + + "] could not be loaded everywhere."); + } + } else if ((sCommand.Equals("SETBINDHOST") || + sCommand.Equals("SETVHOST")) && + (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command. Try " + "SetUserBindHost instead"); + return; + } + CString sArg = sLine.Token(1); + + if (sArg.empty()) { + PutStatus("Usage: SetBindHost "); + return; + } + + if (sArg.Equals(m_pNetwork->GetBindHost())) { + PutStatus("You already have this bind host!"); + return; + } + + m_pNetwork->SetBindHost(sArg); + PutStatus("Set bind host for network [" + m_pNetwork->GetName() + + "] to [" + m_pNetwork->GetBindHost() + "]"); + } else if (sCommand.Equals("SETUSERBINDHOST") && + (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { + CString sArg = sLine.Token(1); + + if (sArg.empty()) { + PutStatus("Usage: SetUserBindHost "); + return; + } + + if (sArg.Equals(m_pUser->GetBindHost())) { + PutStatus("You already have this bind host!"); + return; + } + + m_pUser->SetBindHost(sArg); + PutStatus("Set bind host to [" + m_pUser->GetBindHost() + "]"); + } else if ((sCommand.Equals("CLEARBINDHOST") || + sCommand.Equals("CLEARVHOST")) && + (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command. Try " + "ClearUserBindHost instead"); + return; + } + m_pNetwork->SetBindHost(""); + PutStatus("Bind host cleared for this network."); + } else if (sCommand.Equals("CLEARUSERBINDHOST") && + (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost())) { + m_pUser->SetBindHost(""); + PutStatus("Bind host cleared for your user."); + } else if (sCommand.Equals("SHOWBINDHOST")) { + PutStatus("This user's default bind host " + + (m_pUser->GetBindHost().empty() + ? "not set" + : "is [" + m_pUser->GetBindHost() + "]")); + if (m_pNetwork) { + PutStatus("This network's bind host " + + (m_pNetwork->GetBindHost().empty() + ? "not set" + : "is [" + m_pNetwork->GetBindHost() + "]")); + } + } else if (sCommand.Equals("PLAYBUFFER")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sBuffer = sLine.Token(1); + + if (sBuffer.empty()) { + PutStatus("Usage: PlayBuffer <#chan|query>"); + return; + } + + if (m_pNetwork->IsChan(sBuffer)) { + CChan* pChan = m_pNetwork->FindChan(sBuffer); + + if (!pChan) { + PutStatus("You are not on [" + sBuffer + "]"); + return; + } + + if (!pChan->IsOn()) { + PutStatus("You are not on [" + sBuffer + "] [trying]"); + return; + } + + if (pChan->GetBuffer().IsEmpty()) { + PutStatus("The buffer for [" + sBuffer + "] is empty"); + return; + } + + pChan->SendBuffer(this); + } else { + CQuery* pQuery = m_pNetwork->FindQuery(sBuffer); + + if (!pQuery) { + PutStatus("No active query with [" + sBuffer + "]"); + return; + } + + if (pQuery->GetBuffer().IsEmpty()) { + PutStatus("The buffer for [" + sBuffer + "] is empty"); + return; + } + + pQuery->SendBuffer(this); + } + } else if (sCommand.Equals("CLEARBUFFER")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sBuffer = sLine.Token(1); + + if (sBuffer.empty()) { + PutStatus("Usage: ClearBuffer <#chan|query>"); + return; + } + + unsigned int uMatches = 0; + vector vChans = m_pNetwork->FindChans(sBuffer); + for (CChan* pChan : vChans) { + uMatches++; + + pChan->ClearBuffer(); + } + + vector vQueries = m_pNetwork->FindQueries(sBuffer); + for (CQuery* pQuery : vQueries) { + uMatches++; + + m_pNetwork->DelQuery(pQuery->GetName()); + } + + PutStatus("[" + CString(uMatches) + "] buffers matching [" + sBuffer + + "] have been cleared"); + } else if (sCommand.Equals("CLEARALLCHANNELBUFFERS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + for (CChan* pChan : m_pNetwork->GetChans()) { + pChan->ClearBuffer(); + } + PutStatus("All channel buffers have been cleared"); + } else if (sCommand.Equals("CLEARALLQUERYBUFFERS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + m_pNetwork->ClearQueryBuffer(); + PutStatus("All query buffers have been cleared"); + } else if (sCommand.Equals("CLEARALLBUFFERS")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + for (CChan* pChan : m_pNetwork->GetChans()) { + pChan->ClearBuffer(); + } + m_pNetwork->ClearQueryBuffer(); + PutStatus("All buffers have been cleared"); + } else if (sCommand.Equals("SETBUFFER")) { + if (!m_pNetwork) { + PutStatus( + "You must be connected with a network to use this command"); + return; + } + + CString sBuffer = sLine.Token(1); + + if (sBuffer.empty()) { + PutStatus("Usage: SetBuffer <#chan|query> [linecount]"); + return; + } + + unsigned int uLineCount = sLine.Token(2).ToUInt(); + unsigned int uMatches = 0, uFail = 0; + vector vChans = m_pNetwork->FindChans(sBuffer); + for (CChan* pChan : vChans) { + uMatches++; + + if (!pChan->SetBufferCount(uLineCount)) uFail++; + } + + vector vQueries = m_pNetwork->FindQueries(sBuffer); + for (CQuery* pQuery : vQueries) { + uMatches++; + + if (!pQuery->SetBufferCount(uLineCount)) uFail++; + } + + PutStatus("BufferCount for [" + CString(uMatches - uFail) + + "] buffer was set to [" + CString(uLineCount) + "]"); + if (uFail > 0) { + PutStatus("Setting BufferCount failed for [" + CString(uFail) + + "] buffers, " + "max buffer count is " + + CString(CZNC::Get().GetMaxBufferSize())); + } + } else if (m_pUser->IsAdmin() && sCommand.Equals("TRAFFIC")) { + CZNC::TrafficStatsPair Users, ZNC, Total; + CZNC::TrafficStatsMap traffic = + CZNC::Get().GetTrafficStats(Users, ZNC, Total); + + CTable Table; + Table.AddColumn("Username"); + Table.AddColumn("In"); + Table.AddColumn("Out"); + Table.AddColumn("Total"); + + for (const auto& it : traffic) { + Table.AddRow(); + Table.SetCell("Username", it.first); + Table.SetCell("In", CString::ToByteStr(it.second.first)); + Table.SetCell("Out", CString::ToByteStr(it.second.second)); + Table.SetCell("Total", CString::ToByteStr(it.second.first + + it.second.second)); + } + + Table.AddRow(); + Table.SetCell("Username", ""); + Table.SetCell("In", CString::ToByteStr(Users.first)); + Table.SetCell("Out", CString::ToByteStr(Users.second)); + Table.SetCell("Total", CString::ToByteStr(Users.first + Users.second)); + + Table.AddRow(); + Table.SetCell("Username", ""); + Table.SetCell("In", CString::ToByteStr(ZNC.first)); + Table.SetCell("Out", CString::ToByteStr(ZNC.second)); + Table.SetCell("Total", CString::ToByteStr(ZNC.first + ZNC.second)); + + Table.AddRow(); + Table.SetCell("Username", ""); + Table.SetCell("In", CString::ToByteStr(Total.first)); + Table.SetCell("Out", CString::ToByteStr(Total.second)); + Table.SetCell("Total", CString::ToByteStr(Total.first + Total.second)); + + PutStatus(Table); + } else if (sCommand.Equals("UPTIME")) { + PutStatus("Running for " + CZNC::Get().GetUptime()); + } else if (m_pUser->IsAdmin() && + (sCommand.Equals("LISTPORTS") || sCommand.Equals("ADDPORT") || + sCommand.Equals("DELPORT"))) { + UserPortCommand(sLine); + } else { + PutStatus("Unknown command [" + sCommand + "] try 'Help'"); + } } void CClient::UserPortCommand(CString& sLine) { - const CString sCommand = sLine.Token(0); + const CString sCommand = sLine.Token(0); - if (sCommand.Equals("LISTPORTS")) { - CTable Table; - Table.AddColumn("Port"); - Table.AddColumn("BindHost"); - Table.AddColumn("SSL"); - Table.AddColumn("Proto"); - Table.AddColumn("IRC/Web"); - Table.AddColumn("URIPrefix"); + if (sCommand.Equals("LISTPORTS")) { + CTable Table; + Table.AddColumn("Port"); + Table.AddColumn("BindHost"); + Table.AddColumn("SSL"); + Table.AddColumn("Proto"); + Table.AddColumn("IRC/Web"); + Table.AddColumn("URIPrefix"); - vector::const_iterator it; - const vector& vpListeners = CZNC::Get().GetListeners(); + vector::const_iterator it; + const vector& vpListeners = CZNC::Get().GetListeners(); - for (const CListener* pListener : vpListeners) { - Table.AddRow(); - Table.SetCell("Port", CString(pListener->GetPort())); - Table.SetCell("BindHost", (pListener->GetBindHost().empty() - ? CString("*") - : pListener->GetBindHost())); - Table.SetCell("SSL", CString(pListener->IsSSL())); + for (const CListener* pListener : vpListeners) { + Table.AddRow(); + Table.SetCell("Port", CString(pListener->GetPort())); + Table.SetCell("BindHost", (pListener->GetBindHost().empty() + ? CString("*") + : pListener->GetBindHost())); + Table.SetCell("SSL", CString(pListener->IsSSL())); - EAddrType eAddr = pListener->GetAddrType(); - Table.SetCell("Proto", - (eAddr == ADDR_ALL - ? "All" - : (eAddr == ADDR_IPV4ONLY ? "IPv4" : "IPv6"))); + EAddrType eAddr = pListener->GetAddrType(); + Table.SetCell("Proto", + (eAddr == ADDR_ALL + ? "All" + : (eAddr == ADDR_IPV4ONLY ? "IPv4" : "IPv6"))); - CListener::EAcceptType eAccept = pListener->GetAcceptType(); - Table.SetCell( - "IRC/Web", - (eAccept == CListener::ACCEPT_ALL - ? "All" - : (eAccept == CListener::ACCEPT_IRC ? "IRC" : "Web"))); - Table.SetCell("URIPrefix", pListener->GetURIPrefix() + "/"); - } + CListener::EAcceptType eAccept = pListener->GetAcceptType(); + Table.SetCell( + "IRC/Web", + (eAccept == CListener::ACCEPT_ALL + ? "All" + : (eAccept == CListener::ACCEPT_IRC ? "IRC" : "Web"))); + Table.SetCell("URIPrefix", pListener->GetURIPrefix() + "/"); + } - PutStatus(Table); + PutStatus(Table); - return; - } + return; + } - CString sPort = sLine.Token(1); - CString sAddr = sLine.Token(2); - EAddrType eAddr = ADDR_ALL; + CString sPort = sLine.Token(1); + CString sAddr = sLine.Token(2); + EAddrType eAddr = ADDR_ALL; - if (sAddr.Equals("IPV4")) { - eAddr = ADDR_IPV4ONLY; - } else if (sAddr.Equals("IPV6")) { - eAddr = ADDR_IPV6ONLY; - } else if (sAddr.Equals("ALL")) { - eAddr = ADDR_ALL; - } else { - sAddr.clear(); - } + if (sAddr.Equals("IPV4")) { + eAddr = ADDR_IPV4ONLY; + } else if (sAddr.Equals("IPV6")) { + eAddr = ADDR_IPV6ONLY; + } else if (sAddr.Equals("ALL")) { + eAddr = ADDR_ALL; + } else { + sAddr.clear(); + } - unsigned short uPort = sPort.ToUShort(); + unsigned short uPort = sPort.ToUShort(); - if (sCommand.Equals("ADDPORT")) { - CListener::EAcceptType eAccept = CListener::ACCEPT_ALL; - CString sAccept = sLine.Token(3); + if (sCommand.Equals("ADDPORT")) { + CListener::EAcceptType eAccept = CListener::ACCEPT_ALL; + CString sAccept = sLine.Token(3); - if (sAccept.Equals("WEB")) { - eAccept = CListener::ACCEPT_HTTP; - } else if (sAccept.Equals("IRC")) { - eAccept = CListener::ACCEPT_IRC; - } else if (sAccept.Equals("ALL")) { - eAccept = CListener::ACCEPT_ALL; - } else { - sAccept.clear(); - } + if (sAccept.Equals("WEB")) { + eAccept = CListener::ACCEPT_HTTP; + } else if (sAccept.Equals("IRC")) { + eAccept = CListener::ACCEPT_IRC; + } else if (sAccept.Equals("ALL")) { + eAccept = CListener::ACCEPT_ALL; + } else { + sAccept.clear(); + } - if (sPort.empty() || sAddr.empty() || sAccept.empty()) { - PutStatus( - "Usage: AddPort <[+]port> " - "[bindhost [uriprefix]]"); - } else { - bool bSSL = (sPort.StartsWith("+")); - const CString sBindHost = sLine.Token(4); - const CString sURIPrefix = sLine.Token(5); + if (sPort.empty() || sAddr.empty() || sAccept.empty()) { + PutStatus( + "Usage: AddPort <[+]port> " + "[bindhost [uriprefix]]"); + } else { + bool bSSL = (sPort.StartsWith("+")); + const CString sBindHost = sLine.Token(4); + const CString sURIPrefix = sLine.Token(5); - CListener* pListener = new CListener(uPort, sBindHost, sURIPrefix, - bSSL, eAddr, eAccept); + CListener* pListener = new CListener(uPort, sBindHost, sURIPrefix, + bSSL, eAddr, eAccept); - if (!pListener->Listen()) { - delete pListener; - PutStatus("Unable to bind [" + CString(strerror(errno)) + "]"); - } else { - if (CZNC::Get().AddListener(pListener)) - PutStatus("Port Added"); - else - PutStatus("Error?!"); - } - } - } else if (sCommand.Equals("DELPORT")) { - if (sPort.empty() || sAddr.empty()) { - PutStatus("Usage: DelPort [bindhost]"); - } else { - const CString sBindHost = sLine.Token(3); + if (!pListener->Listen()) { + delete pListener; + PutStatus("Unable to bind [" + CString(strerror(errno)) + "]"); + } else { + if (CZNC::Get().AddListener(pListener)) + PutStatus("Port Added"); + else + PutStatus("Error?!"); + } + } + } else if (sCommand.Equals("DELPORT")) { + if (sPort.empty() || sAddr.empty()) { + PutStatus("Usage: DelPort [bindhost]"); + } else { + const CString sBindHost = sLine.Token(3); - CListener* pListener = - CZNC::Get().FindListener(uPort, sBindHost, eAddr); + CListener* pListener = + CZNC::Get().FindListener(uPort, sBindHost, eAddr); - if (pListener) { - CZNC::Get().DelListener(pListener); - PutStatus("Deleted Port"); - } else { - PutStatus("Unable to find a matching port"); - } - } - } + if (pListener) { + CZNC::Get().DelListener(pListener); + PutStatus("Deleted Port"); + } else { + PutStatus("Unable to find a matching port"); + } + } + } } static void AddCommandHelp(CTable& Table, const CString& sCmd, const CString& sArgs, const CString& sDesc, const CString& sFilter = "") { - if (sFilter.empty() || sCmd.StartsWith(sFilter) || - sCmd.AsLower().WildCmp(sFilter.AsLower())) { - Table.AddRow(); - Table.SetCell("Command", sCmd + " " + sArgs); - Table.SetCell("Description", sDesc); - } + if (sFilter.empty() || sCmd.StartsWith(sFilter) || + sCmd.AsLower().WildCmp(sFilter.AsLower())) { + Table.AddRow(); + Table.SetCell("Command", sCmd + " " + sArgs); + Table.SetCell("Description", sDesc); + } } void CClient::HelpUser(const CString& sFilter) { - CTable Table; - Table.AddColumn("Command"); - Table.AddColumn("Description"); + CTable Table; + Table.AddColumn("Command"); + Table.AddColumn("Description"); - if (sFilter.empty()) { - PutStatus( - "In the following list all occurrences of <#chan> support " - "wildcards (* and ?)"); - PutStatus("(Except ListNicks)"); - } + if (sFilter.empty()) { + PutStatus( + "In the following list all occurrences of <#chan> support " + "wildcards (* and ?)"); + PutStatus("(Except ListNicks)"); + } - AddCommandHelp(Table, "Version", "", "Print which version of ZNC this is", - sFilter); + AddCommandHelp(Table, "Version", "", "Print which version of ZNC this is", + sFilter); - AddCommandHelp(Table, "ListMods", "", "List all loaded modules", sFilter); - AddCommandHelp(Table, "ListAvailMods", "", "List all available modules", - sFilter); - if (!m_pUser->IsAdmin()) { - // If they are an admin we will add this command below with an argument - AddCommandHelp(Table, "ListChans", "", "List all channels", sFilter); - } - AddCommandHelp(Table, "ListNicks", "<#chan>", "List all nicks on a channel", - sFilter); - if (!m_pUser->IsAdmin()) { - AddCommandHelp(Table, "ListClients", "", - "List all clients connected to your ZNC user", sFilter); - } - AddCommandHelp(Table, "ListServers", "", - "List all servers of current IRC network", sFilter); + AddCommandHelp(Table, "ListMods", "", "List all loaded modules", sFilter); + AddCommandHelp(Table, "ListAvailMods", "", "List all available modules", + sFilter); + if (!m_pUser->IsAdmin()) { + // If they are an admin we will add this command below with an argument + AddCommandHelp(Table, "ListChans", "", "List all channels", sFilter); + } + AddCommandHelp(Table, "ListNicks", "<#chan>", "List all nicks on a channel", + sFilter); + if (!m_pUser->IsAdmin()) { + AddCommandHelp(Table, "ListClients", "", + "List all clients connected to your ZNC user", sFilter); + } + AddCommandHelp(Table, "ListServers", "", + "List all servers of current IRC network", sFilter); - AddCommandHelp(Table, "AddNetwork", "", "Add a network to your user", - sFilter); - AddCommandHelp(Table, "DelNetwork", "", - "Delete a network from your user", sFilter); - AddCommandHelp(Table, "ListNetworks", "", "List all networks", sFilter); - if (m_pUser->IsAdmin()) { - AddCommandHelp(Table, "MoveNetwork", - " [new network]", - "Move an IRC network from one user to another", sFilter); - } - AddCommandHelp(Table, "JumpNetwork", "", - "Jump to another network (Alternatively, you can connect to " - "ZNC several times, using `user/network` as username)", - sFilter); + AddCommandHelp(Table, "AddNetwork", "", "Add a network to your user", + sFilter); + AddCommandHelp(Table, "DelNetwork", "", + "Delete a network from your user", sFilter); + AddCommandHelp(Table, "ListNetworks", "", "List all networks", sFilter); + if (m_pUser->IsAdmin()) { + AddCommandHelp(Table, "MoveNetwork", + " [new network]", + "Move an IRC network from one user to another", sFilter); + } + AddCommandHelp(Table, "JumpNetwork", "", + "Jump to another network (Alternatively, you can connect to " + "ZNC several times, using `user/network` as username)", + sFilter); - AddCommandHelp(Table, "AddServer", " [[+]port] [pass]", - "Add a server to the list of alternate/backup servers of " - "current IRC network.", - sFilter); - AddCommandHelp(Table, "DelServer", " [port] [pass]", - "Remove a server from the list of alternate/backup servers " - "of current IRC network", - sFilter); + AddCommandHelp(Table, "AddServer", " [[+]port] [pass]", + "Add a server to the list of alternate/backup servers of " + "current IRC network.", + sFilter); + AddCommandHelp(Table, "DelServer", " [port] [pass]", + "Remove a server from the list of alternate/backup servers " + "of current IRC network", + sFilter); - AddCommandHelp(Table, "AddTrustedServerFingerprint", "", - "Add a trusted server SSL certificate fingerprint (SHA-256) " - "to current IRC network.", - sFilter); - AddCommandHelp( - Table, "DelTrustedServerFingerprint", "", - "Delete a trusted server SSL certificate from current IRC network.", - sFilter); - AddCommandHelp( - Table, "ListTrustedServerFingerprints", "", - "List all trusted server SSL certificates of current IRC network.", - sFilter); + AddCommandHelp(Table, "AddTrustedServerFingerprint", "", + "Add a trusted server SSL certificate fingerprint (SHA-256) " + "to current IRC network.", + sFilter); + AddCommandHelp( + Table, "DelTrustedServerFingerprint", "", + "Delete a trusted server SSL certificate from current IRC network.", + sFilter); + AddCommandHelp( + Table, "ListTrustedServerFingerprints", "", + "List all trusted server SSL certificates of current IRC network.", + sFilter); - AddCommandHelp(Table, "ShowChan", "<#chan>", "Show channel details", - sFilter); - AddCommandHelp(Table, "EnableChan", "<#chans>", "Enable channels", sFilter); - AddCommandHelp(Table, "DisableChan", "<#chans>", "Disable channels", - sFilter); - AddCommandHelp(Table, "Attach", "<#chans>", "Attach to channels", sFilter); - AddCommandHelp(Table, "Detach", "<#chans>", "Detach from channels", - sFilter); - AddCommandHelp(Table, "Topics", "", "Show topics in all your channels", - sFilter); + AddCommandHelp(Table, "ShowChan", "<#chan>", "Show channel details", + sFilter); + AddCommandHelp(Table, "EnableChan", "<#chans>", "Enable channels", sFilter); + AddCommandHelp(Table, "DisableChan", "<#chans>", "Disable channels", + sFilter); + AddCommandHelp(Table, "Attach", "<#chans>", "Attach to channels", sFilter); + AddCommandHelp(Table, "Detach", "<#chans>", "Detach from channels", + sFilter); + AddCommandHelp(Table, "Topics", "", "Show topics in all your channels", + sFilter); - AddCommandHelp(Table, "PlayBuffer", "<#chan|query>", - "Play back the specified buffer", sFilter); - AddCommandHelp(Table, "ClearBuffer", "<#chan|query>", - "Clear the specified buffer", sFilter); - AddCommandHelp(Table, "ClearAllBuffers", "", - "Clear all channel and query buffers", sFilter); - AddCommandHelp(Table, "ClearAllChannelBuffers", "", - "Clear the channel buffers", sFilter); - AddCommandHelp(Table, "ClearAllQueryBuffers", "", "Clear the query buffers", - sFilter); - AddCommandHelp(Table, "SetBuffer", "<#chan|query> [linecount]", - "Set the buffer count", sFilter); + AddCommandHelp(Table, "PlayBuffer", "<#chan|query>", + "Play back the specified buffer", sFilter); + AddCommandHelp(Table, "ClearBuffer", "<#chan|query>", + "Clear the specified buffer", sFilter); + AddCommandHelp(Table, "ClearAllBuffers", "", + "Clear all channel and query buffers", sFilter); + AddCommandHelp(Table, "ClearAllChannelBuffers", "", + "Clear the channel buffers", sFilter); + AddCommandHelp(Table, "ClearAllQueryBuffers", "", "Clear the query buffers", + sFilter); + AddCommandHelp(Table, "SetBuffer", "<#chan|query> [linecount]", + "Set the buffer count", sFilter); - if (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost()) { - AddCommandHelp(Table, "SetBindHost", "", - "Set the bind host for this connection", sFilter); - AddCommandHelp(Table, "SetUserBindHost", "", - "Set the default bind host for this user", sFilter); - AddCommandHelp(Table, "ClearBindHost", "", - "Clear the bind host for this connection", sFilter); - AddCommandHelp(Table, "ClearUserBindHost", "", - "Clear the default bind host for this user", sFilter); - } + if (m_pUser->IsAdmin() || !m_pUser->DenySetBindHost()) { + AddCommandHelp(Table, "SetBindHost", "", + "Set the bind host for this connection", sFilter); + AddCommandHelp(Table, "SetUserBindHost", "", + "Set the default bind host for this user", sFilter); + AddCommandHelp(Table, "ClearBindHost", "", + "Clear the bind host for this connection", sFilter); + AddCommandHelp(Table, "ClearUserBindHost", "", + "Clear the default bind host for this user", sFilter); + } - AddCommandHelp(Table, "ShowBindHost", "", - "Show currently selected bind host", sFilter); - AddCommandHelp(Table, "Jump", "[server]", - "Jump to the next or the specified server", sFilter); - AddCommandHelp(Table, "Disconnect", "[message]", "Disconnect from IRC", - sFilter); - AddCommandHelp(Table, "Connect", "", "Reconnect to IRC", sFilter); - AddCommandHelp(Table, "Uptime", "", - "Show for how long ZNC has been running", sFilter); + AddCommandHelp(Table, "ShowBindHost", "", + "Show currently selected bind host", sFilter); + AddCommandHelp(Table, "Jump", "[server]", + "Jump to the next or the specified server", sFilter); + AddCommandHelp(Table, "Disconnect", "[message]", "Disconnect from IRC", + sFilter); + AddCommandHelp(Table, "Connect", "", "Reconnect to IRC", sFilter); + AddCommandHelp(Table, "Uptime", "", + "Show for how long ZNC has been running", sFilter); - if (!m_pUser->DenyLoadMod()) { - AddCommandHelp(Table, "LoadMod", - "[--type=global|user|network] ", "Load a module", - sFilter); - AddCommandHelp(Table, "UnloadMod", - "[--type=global|user|network] ", - "Unload a module", sFilter); - AddCommandHelp(Table, "ReloadMod", - "[--type=global|user|network] ", - "Reload a module", sFilter); - if (m_pUser->IsAdmin()) { - AddCommandHelp(Table, "UpdateMod", "", - "Reload a module everywhere", sFilter); - } - } + if (!m_pUser->DenyLoadMod()) { + AddCommandHelp(Table, "LoadMod", + "[--type=global|user|network] ", "Load a module", + sFilter); + AddCommandHelp(Table, "UnloadMod", + "[--type=global|user|network] ", + "Unload a module", sFilter); + AddCommandHelp(Table, "ReloadMod", + "[--type=global|user|network] ", + "Reload a module", sFilter); + if (m_pUser->IsAdmin()) { + AddCommandHelp(Table, "UpdateMod", "", + "Reload a module everywhere", sFilter); + } + } - AddCommandHelp(Table, "ShowMOTD", "", "Show ZNC's message of the day", - sFilter); + AddCommandHelp(Table, "ShowMOTD", "", "Show ZNC's message of the day", + sFilter); - if (m_pUser->IsAdmin()) { - AddCommandHelp(Table, "SetMOTD", "", - "Set ZNC's message of the day", sFilter); - AddCommandHelp(Table, "AddMOTD", "", - "Append to ZNC's MOTD", sFilter); - AddCommandHelp(Table, "ClearMOTD", "", "Clear ZNC's MOTD", sFilter); - AddCommandHelp(Table, "ListPorts", "", "Show all active listeners", - sFilter); - AddCommandHelp( - Table, "AddPort", - "<[+]port> [bindhost [uriprefix]]", - "Add another port for ZNC to listen on", sFilter); - AddCommandHelp(Table, "DelPort", " [bindhost]", - "Remove a port from ZNC", sFilter); - AddCommandHelp( - Table, "Rehash", "", - "Reload global settings, modules, and listeners from znc.conf", - sFilter); - AddCommandHelp(Table, "SaveConfig", "", - "Save the current settings to disk", sFilter); - AddCommandHelp(Table, "ListUsers", "", - "List all ZNC users and their connection status", - sFilter); - AddCommandHelp(Table, "ListAllUserNetworks", "", - "List all ZNC users and their networks", sFilter); - AddCommandHelp(Table, "ListChans", "[user ]", - "List all channels", sFilter); - AddCommandHelp(Table, "ListClients", "[user]", - "List all connected clients", sFilter); - AddCommandHelp(Table, "Traffic", "", - "Show basic traffic stats for all ZNC users", sFilter); - AddCommandHelp(Table, "Broadcast", "[message]", - "Broadcast a message to all ZNC users", sFilter); - AddCommandHelp(Table, "Shutdown", "[message]", - "Shut down ZNC completely", sFilter); - AddCommandHelp(Table, "Restart", "[message]", "Restart ZNC", sFilter); - } + if (m_pUser->IsAdmin()) { + AddCommandHelp(Table, "SetMOTD", "", + "Set ZNC's message of the day", sFilter); + AddCommandHelp(Table, "AddMOTD", "", + "Append to ZNC's MOTD", sFilter); + AddCommandHelp(Table, "ClearMOTD", "", "Clear ZNC's MOTD", sFilter); + AddCommandHelp(Table, "ListPorts", "", "Show all active listeners", + sFilter); + AddCommandHelp( + Table, "AddPort", + "<[+]port> [bindhost [uriprefix]]", + "Add another port for ZNC to listen on", sFilter); + AddCommandHelp(Table, "DelPort", " [bindhost]", + "Remove a port from ZNC", sFilter); + AddCommandHelp( + Table, "Rehash", "", + "Reload global settings, modules, and listeners from znc.conf", + sFilter); + AddCommandHelp(Table, "SaveConfig", "", + "Save the current settings to disk", sFilter); + AddCommandHelp(Table, "ListUsers", "", + "List all ZNC users and their connection status", + sFilter); + AddCommandHelp(Table, "ListAllUserNetworks", "", + "List all ZNC users and their networks", sFilter); + AddCommandHelp(Table, "ListChans", "[user ]", + "List all channels", sFilter); + AddCommandHelp(Table, "ListClients", "[user]", + "List all connected clients", sFilter); + AddCommandHelp(Table, "Traffic", "", + "Show basic traffic stats for all ZNC users", sFilter); + AddCommandHelp(Table, "Broadcast", "[message]", + "Broadcast a message to all ZNC users", sFilter); + AddCommandHelp(Table, "Shutdown", "[message]", + "Shut down ZNC completely", sFilter); + AddCommandHelp(Table, "Restart", "[message]", "Restart ZNC", sFilter); + } - if (Table.empty()) { - PutStatus("No matches for '" + sFilter + "'"); - } else { - PutStatus(Table); - } + if (Table.empty()) { + PutStatus("No matches for '" + sFilter + "'"); + } else { + PutStatus(Table); + } } diff --git a/src/Config.cpp b/src/Config.cpp index ce1cfc6b..b147266b 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -20,12 +20,12 @@ #include struct ConfigStackEntry { - CString sTag; - CString sName; - CConfig Config; + CString sTag; + CString sName; + CConfig Config; - ConfigStackEntry(const CString& Tag, const CString Name) - : sTag(Tag), sName(Name), Config() {} + ConfigStackEntry(const CString& Tag, const CString Name) + : sTag(Tag), sName(Name), Config() {} }; CConfigEntry::CConfigEntry() : m_pSubConfig(nullptr) {} @@ -34,159 +34,159 @@ CConfigEntry::CConfigEntry(const CConfig& Config) : m_pSubConfig(new CConfig(Config)) {} CConfigEntry::CConfigEntry(const CConfigEntry& other) : m_pSubConfig(nullptr) { - if (other.m_pSubConfig) m_pSubConfig = new CConfig(*other.m_pSubConfig); + if (other.m_pSubConfig) m_pSubConfig = new CConfig(*other.m_pSubConfig); } CConfigEntry::~CConfigEntry() { delete m_pSubConfig; } CConfigEntry& CConfigEntry::operator=(const CConfigEntry& other) { - delete m_pSubConfig; - if (other.m_pSubConfig) - m_pSubConfig = new CConfig(*other.m_pSubConfig); - else - m_pSubConfig = nullptr; - return *this; + delete m_pSubConfig; + if (other.m_pSubConfig) + m_pSubConfig = new CConfig(*other.m_pSubConfig); + else + m_pSubConfig = nullptr; + return *this; } bool CConfig::Parse(CFile& file, CString& sErrorMsg) { - CString sLine; - unsigned int uLineNum = 0; - CConfig* pActiveConfig = this; - std::stack ConfigStack; - bool bCommented = false; // support for /**/ style comments + CString sLine; + unsigned int uLineNum = 0; + CConfig* pActiveConfig = this; + std::stack ConfigStack; + bool bCommented = false; // support for /**/ style comments - if (!file.Seek(0)) { - sErrorMsg = "Could not seek to the beginning of the config."; - return false; - } + if (!file.Seek(0)) { + sErrorMsg = "Could not seek to the beginning of the config."; + return false; + } - while (file.ReadLine(sLine)) { - uLineNum++; + while (file.ReadLine(sLine)) { + uLineNum++; #define ERROR(arg) \ - do { \ - std::stringstream stream; \ - stream << "Error on line " << uLineNum << ": " << arg; \ - sErrorMsg = stream.str(); \ - m_SubConfigs.clear(); \ - m_ConfigEntries.clear(); \ - return false; \ - } while (0) + do { \ + std::stringstream stream; \ + stream << "Error on line " << uLineNum << ": " << arg; \ + sErrorMsg = stream.str(); \ + m_SubConfigs.clear(); \ + m_ConfigEntries.clear(); \ + return false; \ + } while (0) - // Remove all leading spaces and trailing line endings - sLine.TrimLeft(); - sLine.TrimRight("\r\n"); + // Remove all leading spaces and trailing line endings + sLine.TrimLeft(); + sLine.TrimRight("\r\n"); - if (bCommented || sLine.StartsWith("/*")) { - /* Does this comment end on the same line again? */ - bCommented = (!sLine.EndsWith("*/")); + if (bCommented || sLine.StartsWith("/*")) { + /* Does this comment end on the same line again? */ + bCommented = (!sLine.EndsWith("*/")); - continue; - } + continue; + } - if ((sLine.empty()) || (sLine.StartsWith("#")) || - (sLine.StartsWith("//"))) { - continue; - } + if ((sLine.empty()) || (sLine.StartsWith("#")) || + (sLine.StartsWith("//"))) { + continue; + } - if ((sLine.StartsWith("<")) && (sLine.EndsWith(">"))) { - sLine.LeftChomp(); - sLine.RightChomp(); - sLine.Trim(); + if ((sLine.StartsWith("<")) && (sLine.EndsWith(">"))) { + sLine.LeftChomp(); + sLine.RightChomp(); + sLine.Trim(); - CString sTag = sLine.Token(0); - CString sValue = sLine.Token(1, true); + CString sTag = sLine.Token(0); + CString sValue = sLine.Token(1, true); - sTag.Trim(); - sValue.Trim(); + sTag.Trim(); + sValue.Trim(); - if (sTag.TrimPrefix("/")) { - if (!sValue.empty()) - ERROR("Malformated closing tag. Expected \"\"."); - if (ConfigStack.empty()) - ERROR("Closing tag \"" << sTag << "\" which is not open."); + if (sTag.TrimPrefix("/")) { + if (!sValue.empty()) + ERROR("Malformated closing tag. Expected \"\"."); + if (ConfigStack.empty()) + ERROR("Closing tag \"" << sTag << "\" which is not open."); - const struct ConfigStackEntry& entry = ConfigStack.top(); - CConfig myConfig(entry.Config); - CString sName(entry.sName); + const struct ConfigStackEntry& entry = ConfigStack.top(); + CConfig myConfig(entry.Config); + CString sName(entry.sName); - if (!sTag.Equals(entry.sTag)) - ERROR("Closing tag \"" << sTag << "\" which is not open."); + if (!sTag.Equals(entry.sTag)) + ERROR("Closing tag \"" << sTag << "\" which is not open."); - // This breaks entry - ConfigStack.pop(); + // This breaks entry + ConfigStack.pop(); - if (ConfigStack.empty()) - pActiveConfig = this; - else - pActiveConfig = &ConfigStack.top().Config; + if (ConfigStack.empty()) + pActiveConfig = this; + else + pActiveConfig = &ConfigStack.top().Config; - SubConfig& conf = pActiveConfig->m_SubConfigs[sTag.AsLower()]; - SubConfig::const_iterator it = conf.find(sName); + SubConfig& conf = pActiveConfig->m_SubConfigs[sTag.AsLower()]; + SubConfig::const_iterator it = conf.find(sName); - if (it != conf.end()) - ERROR("Duplicate entry for tag \"" << sTag << "\" name \"" - << sName << "\"."); + if (it != conf.end()) + ERROR("Duplicate entry for tag \"" << sTag << "\" name \"" + << sName << "\"."); - conf[sName] = CConfigEntry(myConfig); - } else { - if (sValue.empty()) - ERROR("Empty block name at begin of block."); - ConfigStack.push(ConfigStackEntry(sTag.AsLower(), sValue)); - pActiveConfig = &ConfigStack.top().Config; - } + conf[sName] = CConfigEntry(myConfig); + } else { + if (sValue.empty()) + ERROR("Empty block name at begin of block."); + ConfigStack.push(ConfigStackEntry(sTag.AsLower(), sValue)); + pActiveConfig = &ConfigStack.top().Config; + } - continue; - } + continue; + } - // If we have a regular line, figure out where it goes - CString sName = sLine.Token(0, false, "="); - CString sValue = sLine.Token(1, true, "="); + // If we have a regular line, figure out where it goes + CString sName = sLine.Token(0, false, "="); + CString sValue = sLine.Token(1, true, "="); - // Only remove the first space, people might want - // leading spaces (e.g. in the MOTD). - sValue.TrimPrefix(" "); + // Only remove the first space, people might want + // leading spaces (e.g. in the MOTD). + sValue.TrimPrefix(" "); - // We don't have any names with spaces, trim all - // leading/trailing spaces. - sName.Trim(); + // We don't have any names with spaces, trim all + // leading/trailing spaces. + sName.Trim(); - if (sName.empty() || sValue.empty()) ERROR("Malformed line"); + if (sName.empty() || sValue.empty()) ERROR("Malformed line"); - CString sNameLower = sName.AsLower(); - pActiveConfig->m_ConfigEntries[sNameLower].push_back(sValue); - } + CString sNameLower = sName.AsLower(); + pActiveConfig->m_ConfigEntries[sNameLower].push_back(sValue); + } - if (bCommented) ERROR("Comment not closed at end of file."); + if (bCommented) ERROR("Comment not closed at end of file."); - if (!ConfigStack.empty()) { - const CString& sTag = ConfigStack.top().sTag; - ERROR( - "Not all tags are closed at the end of the file. Inner-most open " - "tag is \"" - << sTag << "\"."); - } + if (!ConfigStack.empty()) { + const CString& sTag = ConfigStack.top().sTag; + ERROR( + "Not all tags are closed at the end of the file. Inner-most open " + "tag is \"" + << sTag << "\"."); + } - return true; + return true; } void CConfig::Write(CFile& File, unsigned int iIndentation) { - CString sIndentation = CString(iIndentation, '\t'); + CString sIndentation = CString(iIndentation, '\t'); - for (const auto& it : m_ConfigEntries) { - for (const CString& sValue : it.second) { - File.Write(sIndentation + it.first + " = " + sValue + "\n"); - } - } + for (const auto& it : m_ConfigEntries) { + for (const CString& sValue : it.second) { + File.Write(sIndentation + it.first + " = " + sValue + "\n"); + } + } - for (const auto& it : m_SubConfigs) { - for (const auto& it2 : it.second) { - File.Write("\n"); + for (const auto& it : m_SubConfigs) { + for (const auto& it2 : it.second) { + File.Write("\n"); - File.Write(sIndentation + "<" + it.first + " " + it2.first + ">\n"); - it2.second.m_pSubConfig->Write(File, iIndentation + 1); - File.Write(sIndentation + "\n"); - } - } + File.Write(sIndentation + "<" + it.first + " " + it2.first + ">\n"); + it2.second.m_pSubConfig->Write(File, iIndentation + 1); + File.Write(sIndentation + "\n"); + } + } } diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index 55e37b8a..ab697209 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -42,108 +42,108 @@ CFile::CFile(const CString& sLongName) m_bHadError(false), m_sLongName(""), m_sShortName("") { - SetFileName(sLongName); + SetFileName(sLongName); } CFile::~CFile() { Close(); } void CFile::SetFileName(const CString& sLongName) { - if (sLongName.StartsWith("~/")) { - m_sLongName = CFile::GetHomePath() + sLongName.substr(1); - } else - m_sLongName = sLongName; + if (sLongName.StartsWith("~/")) { + m_sLongName = CFile::GetHomePath() + sLongName.substr(1); + } else + m_sLongName = sLongName; - m_sShortName = sLongName; - m_sShortName.TrimRight("/"); + m_sShortName = sLongName; + m_sShortName.TrimRight("/"); - CString::size_type uPos = m_sShortName.rfind('/'); - if (uPos != CString::npos) { - m_sShortName = m_sShortName.substr(uPos + 1); - } + CString::size_type uPos = m_sShortName.rfind('/'); + if (uPos != CString::npos) { + m_sShortName = m_sShortName.substr(uPos + 1); + } } bool CFile::IsDir(const CString& sLongName, bool bUseLstat) { - if (sLongName.Equals("/")) - return CFile::FType(sLongName, FT_DIRECTORY, bUseLstat); + if (sLongName.Equals("/")) + return CFile::FType(sLongName, FT_DIRECTORY, bUseLstat); - // Some OS don't like trailing slashes for directories - return CFile::FType(sLongName.TrimRight_n("/"), FT_DIRECTORY, bUseLstat); + // Some OS don't like trailing slashes for directories + return CFile::FType(sLongName.TrimRight_n("/"), FT_DIRECTORY, bUseLstat); } bool CFile::IsReg(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_REGULAR, bUseLstat); + return CFile::FType(sLongName, FT_REGULAR, bUseLstat); } bool CFile::IsChr(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_CHARACTER, bUseLstat); + return CFile::FType(sLongName, FT_CHARACTER, bUseLstat); } bool CFile::IsBlk(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_BLOCK, bUseLstat); + return CFile::FType(sLongName, FT_BLOCK, bUseLstat); } bool CFile::IsFifo(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_FIFO, bUseLstat); + return CFile::FType(sLongName, FT_FIFO, bUseLstat); } bool CFile::IsLnk(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_LINK, bUseLstat); + return CFile::FType(sLongName, FT_LINK, bUseLstat); } bool CFile::IsSock(const CString& sLongName, bool bUseLstat) { - return CFile::FType(sLongName, FT_SOCK, bUseLstat); + return CFile::FType(sLongName, FT_SOCK, bUseLstat); } bool CFile::IsReg(bool bUseLstat) const { - return CFile::IsReg(m_sLongName, bUseLstat); + return CFile::IsReg(m_sLongName, bUseLstat); } bool CFile::IsDir(bool bUseLstat) const { - return CFile::IsDir(m_sLongName, bUseLstat); + return CFile::IsDir(m_sLongName, bUseLstat); } bool CFile::IsChr(bool bUseLstat) const { - return CFile::IsChr(m_sLongName, bUseLstat); + return CFile::IsChr(m_sLongName, bUseLstat); } bool CFile::IsBlk(bool bUseLstat) const { - return CFile::IsBlk(m_sLongName, bUseLstat); + return CFile::IsBlk(m_sLongName, bUseLstat); } bool CFile::IsFifo(bool bUseLstat) const { - return CFile::IsFifo(m_sLongName, bUseLstat); + return CFile::IsFifo(m_sLongName, bUseLstat); } bool CFile::IsLnk(bool bUseLstat) const { - return CFile::IsLnk(m_sLongName, bUseLstat); + return CFile::IsLnk(m_sLongName, bUseLstat); } bool CFile::IsSock(bool bUseLstat) const { - return CFile::IsSock(m_sLongName, bUseLstat); + return CFile::IsSock(m_sLongName, bUseLstat); } // for gettin file types, using fstat instead bool CFile::FType(const CString& sFileName, EFileTypes eType, bool bUseLstat) { - struct stat st; + struct stat st; - if (!bUseLstat) { - if (stat(sFileName.c_str(), &st) != 0) { - return false; - } - } else { - if (lstat(sFileName.c_str(), &st) != 0) { - return false; - } - } + if (!bUseLstat) { + if (stat(sFileName.c_str(), &st) != 0) { + return false; + } + } else { + if (lstat(sFileName.c_str(), &st) != 0) { + return false; + } + } - switch (eType) { - case FT_REGULAR: - return S_ISREG(st.st_mode); - case FT_DIRECTORY: - return S_ISDIR(st.st_mode); - case FT_CHARACTER: - return S_ISCHR(st.st_mode); - case FT_BLOCK: - return S_ISBLK(st.st_mode); - case FT_FIFO: - return S_ISFIFO(st.st_mode); - case FT_LINK: - return S_ISLNK(st.st_mode); - case FT_SOCK: - return S_ISSOCK(st.st_mode); - default: - break; - } - return false; + switch (eType) { + case FT_REGULAR: + return S_ISREG(st.st_mode); + case FT_DIRECTORY: + return S_ISDIR(st.st_mode); + case FT_CHARACTER: + return S_ISCHR(st.st_mode); + case FT_BLOCK: + return S_ISBLK(st.st_mode); + case FT_FIFO: + return S_ISFIFO(st.st_mode); + case FT_LINK: + return S_ISLNK(st.st_mode); + case FT_SOCK: + return S_ISSOCK(st.st_mode); + default: + break; + } + return false; } // @@ -157,323 +157,323 @@ time_t CFile::GetCTime() const { return CFile::GetCTime(m_sLongName); } uid_t CFile::GetUID() const { return CFile::GetUID(m_sLongName); } gid_t CFile::GetGID() const { return CFile::GetGID(m_sLongName); } bool CFile::Exists(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) == 0); + struct stat st; + return (stat(sFile.c_str(), &st) == 0); } off_t CFile::GetSize(const CString& sFile) { - struct stat st; - if (stat(sFile.c_str(), &st) != 0) { - return 0; - } + struct stat st; + if (stat(sFile.c_str(), &st) != 0) { + return 0; + } - return (S_ISREG(st.st_mode)) ? st.st_size : 0; + return (S_ISREG(st.st_mode)) ? st.st_size : 0; } time_t CFile::GetATime(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_atime; + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_atime; } time_t CFile::GetMTime(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_mtime; + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_mtime; } time_t CFile::GetCTime(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_ctime; + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_ctime; } uid_t CFile::GetUID(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) != 0) ? -1 : (int)st.st_uid; + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? -1 : (int)st.st_uid; } gid_t CFile::GetGID(const CString& sFile) { - struct stat st; - return (stat(sFile.c_str(), &st) != 0) ? -1 : (int)st.st_gid; + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? -1 : (int)st.st_gid; } int CFile::GetInfo(const CString& sFile, struct stat& st) { - return stat(sFile.c_str(), &st); + return stat(sFile.c_str(), &st); } // // Functions to manipulate the file on the filesystem // bool CFile::Delete() { - if (CFile::Delete(m_sLongName)) return true; - m_bHadError = true; - return false; + if (CFile::Delete(m_sLongName)) return true; + m_bHadError = true; + return false; } bool CFile::Move(const CString& sNewFileName, bool bOverwrite) { - if (CFile::Move(m_sLongName, sNewFileName, bOverwrite)) return true; - m_bHadError = true; - return false; + if (CFile::Move(m_sLongName, sNewFileName, bOverwrite)) return true; + m_bHadError = true; + return false; } bool CFile::Copy(const CString& sNewFileName, bool bOverwrite) { - if (CFile::Copy(m_sLongName, sNewFileName, bOverwrite)) return true; - m_bHadError = true; - return false; + if (CFile::Copy(m_sLongName, sNewFileName, bOverwrite)) return true; + m_bHadError = true; + return false; } bool CFile::Delete(const CString& sFileName) { - return (unlink(sFileName.c_str()) == 0) ? true : false; + return (unlink(sFileName.c_str()) == 0) ? true : false; } bool CFile::Move(const CString& sOldFileName, const CString& sNewFileName, bool bOverwrite) { - if (CFile::Exists(sNewFileName)) { - if (!bOverwrite) { - errno = EEXIST; - return false; - } + if (CFile::Exists(sNewFileName)) { + if (!bOverwrite) { + errno = EEXIST; + return false; + } #ifdef _WIN32 - // rename() never overwrites files on Windows. - DWORD dFlags = MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED | - MOVEFILE_REPLACE_EXISTING; - return (::MoveFileExA(sOldFileName.c_str(), sNewFileName.c_str(), - dFlags) != 0); + // rename() never overwrites files on Windows. + DWORD dFlags = MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED | + MOVEFILE_REPLACE_EXISTING; + return (::MoveFileExA(sOldFileName.c_str(), sNewFileName.c_str(), + dFlags) != 0); #endif - } + } - return (rename(sOldFileName.c_str(), sNewFileName.c_str()) == 0); + return (rename(sOldFileName.c_str(), sNewFileName.c_str()) == 0); } bool CFile::Copy(const CString& sOldFileName, const CString& sNewFileName, bool bOverwrite) { - if ((!bOverwrite) && (CFile::Exists(sNewFileName))) { - errno = EEXIST; - return false; - } + if ((!bOverwrite) && (CFile::Exists(sNewFileName))) { + errno = EEXIST; + return false; + } - CFile OldFile(sOldFileName); - CFile NewFile(sNewFileName); + CFile OldFile(sOldFileName); + CFile NewFile(sNewFileName); - if (!OldFile.Open()) { - return false; - } + if (!OldFile.Open()) { + return false; + } - if (!NewFile.Open(O_WRONLY | O_CREAT | O_TRUNC)) { - return false; - } + if (!NewFile.Open(O_WRONLY | O_CREAT | O_TRUNC)) { + return false; + } - char szBuf[8192]; - ssize_t len = 0; + char szBuf[8192]; + ssize_t len = 0; - while ((len = OldFile.Read(szBuf, 8192))) { - if (len < 0) { - DEBUG("CFile::Copy() failed: " << strerror(errno)); - OldFile.Close(); + while ((len = OldFile.Read(szBuf, 8192))) { + if (len < 0) { + DEBUG("CFile::Copy() failed: " << strerror(errno)); + OldFile.Close(); - // That file is only a partial copy, get rid of it - NewFile.Close(); - NewFile.Delete(); + // That file is only a partial copy, get rid of it + NewFile.Close(); + NewFile.Delete(); - return false; - } - NewFile.Write(szBuf, len); - } + return false; + } + NewFile.Write(szBuf, len); + } - OldFile.Close(); - NewFile.Close(); + OldFile.Close(); + NewFile.Close(); - struct stat st; - GetInfo(sOldFileName, st); - Chmod(sNewFileName, st.st_mode); + struct stat st; + GetInfo(sOldFileName, st); + Chmod(sNewFileName, st.st_mode); - return true; + return true; } bool CFile::Chmod(mode_t mode) { - if (m_iFD == -1) { - errno = EBADF; - return false; - } - if (fchmod(m_iFD, mode) != 0) { - m_bHadError = true; - return false; - } - return true; + if (m_iFD == -1) { + errno = EBADF; + return false; + } + if (fchmod(m_iFD, mode) != 0) { + m_bHadError = true; + return false; + } + return true; } bool CFile::Chmod(const CString& sFile, mode_t mode) { - return (chmod(sFile.c_str(), mode) == 0); + return (chmod(sFile.c_str(), mode) == 0); } bool CFile::Seek(off_t uPos) { - /* This sets errno in case m_iFD == -1 */ - errno = EBADF; + /* This sets errno in case m_iFD == -1 */ + errno = EBADF; - if (m_iFD != -1 && lseek(m_iFD, uPos, SEEK_SET) == uPos) { - ClearBuffer(); - return true; - } - m_bHadError = true; + if (m_iFD != -1 && lseek(m_iFD, uPos, SEEK_SET) == uPos) { + ClearBuffer(); + return true; + } + m_bHadError = true; - return false; + return false; } bool CFile::Truncate() { - /* This sets errno in case m_iFD == -1 */ - errno = EBADF; + /* This sets errno in case m_iFD == -1 */ + errno = EBADF; - if (m_iFD != -1 && ftruncate(m_iFD, 0) == 0) { - ClearBuffer(); - return true; - } + if (m_iFD != -1 && ftruncate(m_iFD, 0) == 0) { + ClearBuffer(); + return true; + } - m_bHadError = true; + m_bHadError = true; - return false; + return false; } bool CFile::Sync() { - /* This sets errno in case m_iFD == -1 */ - errno = EBADF; + /* This sets errno in case m_iFD == -1 */ + errno = EBADF; - if (m_iFD != -1 && fsync(m_iFD) == 0) return true; - m_bHadError = true; - return false; + if (m_iFD != -1 && fsync(m_iFD) == 0) return true; + m_bHadError = true; + return false; } bool CFile::Open(const CString& sFileName, int iFlags, mode_t iMode) { - SetFileName(sFileName); - return Open(iFlags, iMode); + SetFileName(sFileName); + return Open(iFlags, iMode); } bool CFile::Open(int iFlags, mode_t iMode) { - if (m_iFD != -1) { - errno = EEXIST; - m_bHadError = true; - return false; - } + if (m_iFD != -1) { + errno = EEXIST; + m_bHadError = true; + return false; + } - // We never want to get a controlling TTY through this -> O_NOCTTY - iMode |= O_NOCTTY; + // We never want to get a controlling TTY through this -> O_NOCTTY + iMode |= O_NOCTTY; - // Some weird OS from MS needs O_BINARY or else it generates fake EOFs - // when reading ^Z from a file. - iMode |= O_BINARY; + // Some weird OS from MS needs O_BINARY or else it generates fake EOFs + // when reading ^Z from a file. + iMode |= O_BINARY; - m_iFD = open(m_sLongName.c_str(), iFlags, iMode); - if (m_iFD < 0) { - m_bHadError = true; - return false; - } + m_iFD = open(m_sLongName.c_str(), iFlags, iMode); + if (m_iFD < 0) { + m_bHadError = true; + return false; + } - /* Make sure this FD isn't given to childs */ - SetFdCloseOnExec(m_iFD); + /* Make sure this FD isn't given to childs */ + SetFdCloseOnExec(m_iFD); - return true; + return true; } ssize_t CFile::Read(char* pszBuffer, int iBytes) { - if (m_iFD == -1) { - errno = EBADF; - return -1; - } + if (m_iFD == -1) { + errno = EBADF; + return -1; + } - ssize_t res = read(m_iFD, pszBuffer, iBytes); - if (res != iBytes) m_bHadError = true; - return res; + ssize_t res = read(m_iFD, pszBuffer, iBytes); + if (res != iBytes) m_bHadError = true; + return res; } bool CFile::ReadLine(CString& sData, const CString& sDelimiter) { - char buff[4096]; - ssize_t iBytes; + char buff[4096]; + ssize_t iBytes; - if (m_iFD == -1) { - errno = EBADF; - return false; - } + if (m_iFD == -1) { + errno = EBADF; + return false; + } - do { - CString::size_type iFind = m_sBuffer.find(sDelimiter); - if (iFind != CString::npos) { - // We found a line, return it - sData = m_sBuffer.substr(0, iFind + sDelimiter.length()); - m_sBuffer.erase(0, iFind + sDelimiter.length()); - return true; - } + do { + CString::size_type iFind = m_sBuffer.find(sDelimiter); + if (iFind != CString::npos) { + // We found a line, return it + sData = m_sBuffer.substr(0, iFind + sDelimiter.length()); + m_sBuffer.erase(0, iFind + sDelimiter.length()); + return true; + } - iBytes = read(m_iFD, buff, sizeof(buff)); + iBytes = read(m_iFD, buff, sizeof(buff)); - if (iBytes > 0) { - m_sBuffer.append(buff, iBytes); - } - } while (iBytes > 0); + if (iBytes > 0) { + m_sBuffer.append(buff, iBytes); + } + } while (iBytes > 0); - // We are at the end of the file or an error happened + // We are at the end of the file or an error happened - if (!m_sBuffer.empty()) { - // ..but there is still some partial line in the buffer - sData = m_sBuffer; - m_sBuffer.clear(); - return true; - } + if (!m_sBuffer.empty()) { + // ..but there is still some partial line in the buffer + sData = m_sBuffer; + m_sBuffer.clear(); + return true; + } - // Nothing left for reading :( - return false; + // Nothing left for reading :( + return false; } bool CFile::ReadFile(CString& sData, size_t iMaxSize) { - char buff[4096]; - size_t iBytesRead = 0; + char buff[4096]; + size_t iBytesRead = 0; - sData.clear(); + sData.clear(); - while (iBytesRead < iMaxSize) { - ssize_t iBytes = Read(buff, sizeof(buff)); + while (iBytesRead < iMaxSize) { + ssize_t iBytes = Read(buff, sizeof(buff)); - if (iBytes < 0) - // Error - return false; + if (iBytes < 0) + // Error + return false; - if (iBytes == 0) - // EOF - return true; + if (iBytes == 0) + // EOF + return true; - sData.append(buff, iBytes); - iBytesRead += iBytes; - } + sData.append(buff, iBytes); + iBytesRead += iBytes; + } - // Buffer limit reached - return false; + // Buffer limit reached + return false; } ssize_t CFile::Write(const char* pszBuffer, size_t iBytes) { - if (m_iFD == -1) { - errno = EBADF; - return -1; - } + if (m_iFD == -1) { + errno = EBADF; + return -1; + } - ssize_t res = write(m_iFD, pszBuffer, iBytes); - if (-1 == res) m_bHadError = true; - return res; + ssize_t res = write(m_iFD, pszBuffer, iBytes); + if (-1 == res) m_bHadError = true; + return res; } ssize_t CFile::Write(const CString& sData) { - return Write(sData.data(), sData.size()); + return Write(sData.data(), sData.size()); } void CFile::Close() { - if (m_iFD >= 0) { - if (close(m_iFD) < 0) { - m_bHadError = true; - DEBUG("CFile::Close(): close() failed with [" << strerror(errno) - << "]"); - } - } - m_iFD = -1; - ClearBuffer(); + if (m_iFD >= 0) { + if (close(m_iFD) < 0) { + m_bHadError = true; + DEBUG("CFile::Close(): close() failed with [" << strerror(errno) + << "]"); + } + } + m_iFD = -1; + ClearBuffer(); } void CFile::ClearBuffer() { m_sBuffer.clear(); } bool CFile::TryExLock(const CString& sLockFile, int iFlags) { - Open(sLockFile, iFlags); - return TryExLock(); + Open(sLockFile, iFlags); + return TryExLock(); } bool CFile::TryExLock() { return Lock(F_WRLCK, false); } @@ -483,199 +483,199 @@ bool CFile::ExLock() { return Lock(F_WRLCK, true); } bool CFile::UnLock() { return Lock(F_UNLCK, true); } bool CFile::Lock(short iType, bool bBlocking) { - struct flock fl; + struct flock fl; - if (m_iFD == -1) { - return false; - } + if (m_iFD == -1) { + return false; + } - fl.l_type = iType; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - return (fcntl(m_iFD, (bBlocking ? F_SETLKW : F_SETLK), &fl) != -1); + fl.l_type = iType; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + return (fcntl(m_iFD, (bBlocking ? F_SETLKW : F_SETLK), &fl) != -1); } bool CFile::IsOpen() const { return (m_iFD != -1); } CString CFile::GetLongName() const { return m_sLongName; } CString CFile::GetShortName() const { return m_sShortName; } CString CFile::GetDir() const { - CString sDir(m_sLongName); + CString sDir(m_sLongName); - while (!sDir.empty() && !sDir.EndsWith("/") && !sDir.EndsWith("\\")) { - sDir.RightChomp(); - } + while (!sDir.empty() && !sDir.EndsWith("/") && !sDir.EndsWith("\\")) { + sDir.RightChomp(); + } - return sDir; + return sDir; } void CFile::InitHomePath(const CString& sFallback) { - const char* home = getenv("HOME"); + const char* home = getenv("HOME"); - m_sHomePath.clear(); - if (home) { - m_sHomePath = home; - } + m_sHomePath.clear(); + if (home) { + m_sHomePath = home; + } - if (m_sHomePath.empty()) { - const struct passwd* pUserInfo = getpwuid(getuid()); + if (m_sHomePath.empty()) { + const struct passwd* pUserInfo = getpwuid(getuid()); - if (pUserInfo) { - m_sHomePath = pUserInfo->pw_dir; - } - } + if (pUserInfo) { + m_sHomePath = pUserInfo->pw_dir; + } + } - if (m_sHomePath.empty()) { - m_sHomePath = sFallback; - } + if (m_sHomePath.empty()) { + m_sHomePath = sFallback; + } } CString CDir::ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHome) { - CString sHomeDir(sHome); + CString sHomeDir(sHome); - if (sHomeDir.empty()) { - sHomeDir = CFile::GetHomePath(); - } + if (sHomeDir.empty()) { + sHomeDir = CFile::GetHomePath(); + } - if (sAdd == "~") { - return sHomeDir; - } + if (sAdd == "~") { + return sHomeDir; + } - CString sAddDir(sAdd); + CString sAddDir(sAdd); - if (sAddDir.StartsWith("~/")) { - sAddDir.LeftChomp(); - sAddDir = sHomeDir + sAddDir; - } + if (sAddDir.StartsWith("~/")) { + sAddDir.LeftChomp(); + sAddDir = sHomeDir + sAddDir; + } - CString sRet = ((sAddDir.size()) && (sAddDir[0] == '/')) ? "" : sPath; - sAddDir += "/"; - CString sCurDir; + CString sRet = ((sAddDir.size()) && (sAddDir[0] == '/')) ? "" : sPath; + sAddDir += "/"; + CString sCurDir; - sRet.TrimSuffix("/"); + sRet.TrimSuffix("/"); - for (unsigned int a = 0; a < sAddDir.size(); a++) { - switch (sAddDir[a]) { - case '/': - if (sCurDir == "..") { - sRet = sRet.substr(0, sRet.rfind('/')); - } else if ((sCurDir != "") && (sCurDir != ".")) { - sRet += "/" + sCurDir; - } + for (unsigned int a = 0; a < sAddDir.size(); a++) { + switch (sAddDir[a]) { + case '/': + if (sCurDir == "..") { + sRet = sRet.substr(0, sRet.rfind('/')); + } else if ((sCurDir != "") && (sCurDir != ".")) { + sRet += "/" + sCurDir; + } - sCurDir = ""; - break; - default: - sCurDir += sAddDir[a]; - break; - } - } + sCurDir = ""; + break; + default: + sCurDir += sAddDir[a]; + break; + } + } - return (sRet.empty()) ? "/" : sRet; + return (sRet.empty()) ? "/" : sRet; } CString CDir::CheckPathPrefix(const CString& sPath, const CString& sAdd, const CString& sHomeDir) { - CString sPrefix = sPath.Replace_n("//", "/").TrimRight_n("/") + "/"; - CString sAbsolutePath = ChangeDir(sPrefix, sAdd, sHomeDir); + CString sPrefix = sPath.Replace_n("//", "/").TrimRight_n("/") + "/"; + CString sAbsolutePath = ChangeDir(sPrefix, sAdd, sHomeDir); - if (!sAbsolutePath.StartsWith(sPrefix)) return ""; - return sAbsolutePath; + if (!sAbsolutePath.StartsWith(sPrefix)) return ""; + return sAbsolutePath; } bool CDir::MakeDir(const CString& sPath, mode_t iMode) { - CString sDir; - VCString dirs; - VCString::iterator it; + CString sDir; + VCString dirs; + VCString::iterator it; - // Just in case someone tries this... - if (sPath.empty()) { - errno = ENOENT; - return false; - } + // Just in case someone tries this... + if (sPath.empty()) { + errno = ENOENT; + return false; + } - // If this is an absolute path, we need to handle this now! - if (sPath.StartsWith("/")) sDir = "/"; + // If this is an absolute path, we need to handle this now! + if (sPath.StartsWith("/")) sDir = "/"; - // For every single subpath, do... - sPath.Split("/", dirs, false); - for (it = dirs.begin(); it != dirs.end(); ++it) { - // Add this to the path we already created - sDir += *it; + // For every single subpath, do... + sPath.Split("/", dirs, false); + for (it = dirs.begin(); it != dirs.end(); ++it) { + // Add this to the path we already created + sDir += *it; - int i = mkdir(sDir.c_str(), iMode); + int i = mkdir(sDir.c_str(), iMode); - if (i != 0) { - // All errors except EEXIST are fatal - if (errno != EEXIST) return false; + if (i != 0) { + // All errors except EEXIST are fatal + if (errno != EEXIST) return false; - // If it's EEXIST we have to make sure it's a dir - if (!CFile::IsDir(sDir)) return false; - } + // If it's EEXIST we have to make sure it's a dir + if (!CFile::IsDir(sDir)) return false; + } - sDir += "/"; - } + sDir += "/"; + } - // All went well - return true; + // All went well + return true; } int CExecSock::popen2(int& iReadFD, int& iWriteFD, const CString& sCommand) { - int rpipes[2] = {-1, -1}; - int wpipes[2] = {-1, -1}; - iReadFD = -1; - iWriteFD = -1; + int rpipes[2] = {-1, -1}; + int wpipes[2] = {-1, -1}; + iReadFD = -1; + iWriteFD = -1; - if (pipe(rpipes) < 0) return -1; + if (pipe(rpipes) < 0) return -1; - if (pipe(wpipes) < 0) { - close(rpipes[0]); - close(rpipes[1]); - return -1; - } + if (pipe(wpipes) < 0) { + close(rpipes[0]); + close(rpipes[1]); + return -1; + } - int iPid = fork(); + int iPid = fork(); - if (iPid == -1) { - close(rpipes[0]); - close(rpipes[1]); - close(wpipes[0]); - close(wpipes[1]); - return -1; - } + if (iPid == -1) { + close(rpipes[0]); + close(rpipes[1]); + close(wpipes[0]); + close(wpipes[1]); + return -1; + } - if (iPid == 0) { - close(wpipes[1]); - close(rpipes[0]); - dup2(wpipes[0], 0); - dup2(rpipes[1], 1); - dup2(rpipes[1], 2); - close(wpipes[0]); - close(rpipes[1]); - const char* pArgv[] = {"sh", "-c", sCommand.c_str(), nullptr}; - execvp("sh", (char* const*)pArgv); - // if execvp returns, there was an error - perror("execvp"); - exit(1); - } + if (iPid == 0) { + close(wpipes[1]); + close(rpipes[0]); + dup2(wpipes[0], 0); + dup2(rpipes[1], 1); + dup2(rpipes[1], 2); + close(wpipes[0]); + close(rpipes[1]); + const char* pArgv[] = {"sh", "-c", sCommand.c_str(), nullptr}; + execvp("sh", (char* const*)pArgv); + // if execvp returns, there was an error + perror("execvp"); + exit(1); + } - close(wpipes[0]); - close(rpipes[1]); + close(wpipes[0]); + close(rpipes[1]); - iWriteFD = wpipes[1]; - iReadFD = rpipes[0]; + iWriteFD = wpipes[1]; + iReadFD = rpipes[0]; - return iPid; + return iPid; } void CExecSock::close2(int iPid, int iReadFD, int iWriteFD) { - close(iReadFD); - close(iWriteFD); - time_t iNow = time(nullptr); - while (waitpid(iPid, nullptr, WNOHANG) == 0) { - if ((time(nullptr) - iNow) > 5) break; // giveup - usleep(100); - } - return; + close(iReadFD); + close(iWriteFD); + time_t iNow = time(nullptr); + while (waitpid(iPid, nullptr, WNOHANG) == 0) { + if ((time(nullptr) - iNow) > 5) break; // giveup + usleep(100); + } + return; } diff --git a/src/HTTPSock.cpp b/src/HTTPSock.cpp index 46293962..a909fe9a 100644 --- a/src/HTTPSock.cpp +++ b/src/HTTPSock.cpp @@ -30,7 +30,7 @@ using std::set; CHTTPSock::CHTTPSock(CModule* pMod, const CString& sURIPrefix) : CHTTPSock(pMod, sURIPrefix, "", 0) { - Init(); + Init(); } CHTTPSock::CHTTPSock(CModule* pMod, const CString& sURIPrefix, @@ -60,467 +60,467 @@ CHTTPSock::CHTTPSock(CModule* pMod, const CString& sURIPrefix, m_msRequestCookies(), m_msResponseCookies(), m_sURIPrefix(sURIPrefix) { - Init(); + Init(); } void CHTTPSock::Init() { - EnableReadLine(); - SetMaxBufferThreshold(10240); + EnableReadLine(); + SetMaxBufferThreshold(10240); } CHTTPSock::~CHTTPSock() {} void CHTTPSock::ReadData(const char* data, size_t len) { - if (!m_bDone && m_bGotHeader && m_bPost) { - m_sPostData.append(data, len); - CheckPost(); - } + if (!m_bDone && m_bGotHeader && m_bPost) { + m_sPostData.append(data, len); + CheckPost(); + } } bool CHTTPSock::SendCookie(const CString& sKey, const CString& sValue) { - if (!sKey.empty() && !sValue.empty()) { - if (m_msRequestCookies.find(sKey) == m_msRequestCookies.end() || - m_msRequestCookies[sKey].StrCmp(sValue) != 0) { - // only queue a Set-Cookie to be sent if the client didn't send a - // Cookie header of the same name+value. - m_msResponseCookies[sKey] = sValue; - } - return true; - } + if (!sKey.empty() && !sValue.empty()) { + if (m_msRequestCookies.find(sKey) == m_msRequestCookies.end() || + m_msRequestCookies[sKey].StrCmp(sValue) != 0) { + // only queue a Set-Cookie to be sent if the client didn't send a + // Cookie header of the same name+value. + m_msResponseCookies[sKey] = sValue; + } + return true; + } - return false; + return false; } CString CHTTPSock::GetRequestCookie(const CString& sKey) const { - MCString::const_iterator it = m_msRequestCookies.find(sKey); + MCString::const_iterator it = m_msRequestCookies.find(sKey); - return it != m_msRequestCookies.end() ? it->second : ""; + return it != m_msRequestCookies.end() ? it->second : ""; } void CHTTPSock::CheckPost() { - if (m_sPostData.size() >= m_uPostLen) { - ParseParams(m_sPostData.Left(m_uPostLen), m_msvsPOSTParams); - GetPage(); - m_sPostData.clear(); - m_bDone = true; - } + if (m_sPostData.size() >= m_uPostLen) { + ParseParams(m_sPostData.Left(m_uPostLen), m_msvsPOSTParams); + GetPage(); + m_sPostData.clear(); + m_bDone = true; + } } void CHTTPSock::ReadLine(const CString& sData) { - if (m_bGotHeader) { - return; - } + if (m_bGotHeader) { + return; + } - CString sLine = sData; - sLine.TrimRight("\r\n"); + CString sLine = sData; + sLine.TrimRight("\r\n"); - CString sName = sLine.Token(0); + CString sName = sLine.Token(0); - if (sName.Equals("GET")) { - m_bPost = false; - m_sURI = sLine.Token(1); - m_bHTTP10Client = sLine.Token(2).Equals("HTTP/1.0"); - ParseURI(); - } else if (sName.Equals("POST")) { - m_bPost = true; - m_sURI = sLine.Token(1); - ParseURI(); - } else if (sName.Equals("Cookie:")) { - VCString vsNV; + if (sName.Equals("GET")) { + m_bPost = false; + m_sURI = sLine.Token(1); + m_bHTTP10Client = sLine.Token(2).Equals("HTTP/1.0"); + ParseURI(); + } else if (sName.Equals("POST")) { + m_bPost = true; + m_sURI = sLine.Token(1); + ParseURI(); + } else if (sName.Equals("Cookie:")) { + VCString vsNV; - sLine.Token(1, true).Split(";", vsNV, false, "", "", true, true); + sLine.Token(1, true).Split(";", vsNV, false, "", "", true, true); - for (const CString& s : vsNV) { - m_msRequestCookies[s.Token(0, false, "=") - .Escape_n(CString::EURL, CString::EASCII)] = - s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); - } - } else if (sName.Equals("Authorization:")) { - CString sUnhashed; - sLine.Token(2).Base64Decode(sUnhashed); - m_sUser = sUnhashed.Token(0, false, ":"); - m_sPass = sUnhashed.Token(1, true, ":"); - m_bBasicAuth = true; - // Postpone authorization attempt until end of headers, because cookies - // should be read before that, otherwise session id will be overwritten - // in GetSession() - } else if (sName.Equals("Content-Length:")) { - m_uPostLen = sLine.Token(1).ToULong(); - if (m_uPostLen > MAX_POST_SIZE) - PrintErrorPage(413, "Request Entity Too Large", - "The request you sent was too large."); - } else if (sName.Equals("X-Forwarded-For:")) { - // X-Forwarded-For: client, proxy1, proxy2 - if (m_sForwardedIP.empty()) { - const VCString& vsTrustedProxies = CZNC::Get().GetTrustedProxies(); - CString sIP = GetRemoteIP(); + for (const CString& s : vsNV) { + m_msRequestCookies[s.Token(0, false, "=") + .Escape_n(CString::EURL, CString::EASCII)] = + s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); + } + } else if (sName.Equals("Authorization:")) { + CString sUnhashed; + sLine.Token(2).Base64Decode(sUnhashed); + m_sUser = sUnhashed.Token(0, false, ":"); + m_sPass = sUnhashed.Token(1, true, ":"); + m_bBasicAuth = true; + // Postpone authorization attempt until end of headers, because cookies + // should be read before that, otherwise session id will be overwritten + // in GetSession() + } else if (sName.Equals("Content-Length:")) { + m_uPostLen = sLine.Token(1).ToULong(); + if (m_uPostLen > MAX_POST_SIZE) + PrintErrorPage(413, "Request Entity Too Large", + "The request you sent was too large."); + } else if (sName.Equals("X-Forwarded-For:")) { + // X-Forwarded-For: client, proxy1, proxy2 + if (m_sForwardedIP.empty()) { + const VCString& vsTrustedProxies = CZNC::Get().GetTrustedProxies(); + CString sIP = GetRemoteIP(); - VCString vsIPs; - sLine.Token(1, true).Split(",", vsIPs, false, "", "", false, true); + VCString vsIPs; + sLine.Token(1, true).Split(",", vsIPs, false, "", "", false, true); - while (!vsIPs.empty()) { - // sIP told us that it got connection from vsIPs.back() - // check if sIP is trusted proxy - bool bTrusted = false; - for (const CString& sTrustedProxy : vsTrustedProxies) { - if (sIP.WildCmp(sTrustedProxy)) { - bTrusted = true; - break; - } - } - if (bTrusted) { - // sIP is trusted proxy, so use vsIPs.back() as new sIP - sIP = vsIPs.back(); - vsIPs.pop_back(); - } else { - break; - } - } + while (!vsIPs.empty()) { + // sIP told us that it got connection from vsIPs.back() + // check if sIP is trusted proxy + bool bTrusted = false; + for (const CString& sTrustedProxy : vsTrustedProxies) { + if (sIP.WildCmp(sTrustedProxy)) { + bTrusted = true; + break; + } + } + if (bTrusted) { + // sIP is trusted proxy, so use vsIPs.back() as new sIP + sIP = vsIPs.back(); + vsIPs.pop_back(); + } else { + break; + } + } - // either sIP is not trusted proxy, or it's in the beginning of the - // X-Forwarded-For list in both cases use it as the endpoind - m_sForwardedIP = sIP; - } - } else if (sName.Equals("If-None-Match:")) { - // this is for proper client cache support (HTTP 304) on static files: - m_sIfNoneMatch = sLine.Token(1, true); - } else if (sName.Equals("Accept-Encoding:") && !m_bHTTP10Client) { - SCString ssEncodings; - // trimming whitespace from the tokens is important: - sLine.Token(1, true) - .Split(",", ssEncodings, false, "", "", false, true); - m_bAcceptGzip = (ssEncodings.find("gzip") != ssEncodings.end()); - } else if (sLine.empty()) { - if (m_bBasicAuth && !m_bLoggedIn) { - m_bLoggedIn = OnLogin(m_sUser, m_sPass, true); - // After successful login ReadLine("") will be called again to - // trigger "else" block Failed login sends error and closes socket, - // so no infinite loop here - } else { - m_bGotHeader = true; + // either sIP is not trusted proxy, or it's in the beginning of the + // X-Forwarded-For list in both cases use it as the endpoind + m_sForwardedIP = sIP; + } + } else if (sName.Equals("If-None-Match:")) { + // this is for proper client cache support (HTTP 304) on static files: + m_sIfNoneMatch = sLine.Token(1, true); + } else if (sName.Equals("Accept-Encoding:") && !m_bHTTP10Client) { + SCString ssEncodings; + // trimming whitespace from the tokens is important: + sLine.Token(1, true) + .Split(",", ssEncodings, false, "", "", false, true); + m_bAcceptGzip = (ssEncodings.find("gzip") != ssEncodings.end()); + } else if (sLine.empty()) { + if (m_bBasicAuth && !m_bLoggedIn) { + m_bLoggedIn = OnLogin(m_sUser, m_sPass, true); + // After successful login ReadLine("") will be called again to + // trigger "else" block Failed login sends error and closes socket, + // so no infinite loop here + } else { + m_bGotHeader = true; - if (m_bPost) { - m_sPostData = GetInternalReadBuffer(); - CheckPost(); - } else { - GetPage(); - } + if (m_bPost) { + m_sPostData = GetInternalReadBuffer(); + CheckPost(); + } else { + GetPage(); + } - DisableReadLine(); - } - } + DisableReadLine(); + } + } } CString CHTTPSock::GetRemoteIP() const { - if (!m_sForwardedIP.empty()) { - return m_sForwardedIP; - } + if (!m_sForwardedIP.empty()) { + return m_sForwardedIP; + } - return CSocket::GetRemoteIP(); + return CSocket::GetRemoteIP(); } CString CHTTPSock::GetDate(time_t stamp) { - struct tm tm; - std::stringstream stream; - const char* wkday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - const char* month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + struct tm tm; + std::stringstream stream; + const char* wkday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + const char* month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - if (stamp == 0) time(&stamp); - gmtime_r(&stamp, &tm); + if (stamp == 0) time(&stamp); + gmtime_r(&stamp, &tm); - stream << wkday[tm.tm_wday] << ", "; - stream << std::setfill('0') << std::setw(2) << tm.tm_mday << " "; - stream << month[tm.tm_mon] << " "; - stream << std::setfill('0') << std::setw(4) << tm.tm_year + 1900 << " "; - stream << std::setfill('0') << std::setw(2) << tm.tm_hour << ":"; - stream << std::setfill('0') << std::setw(2) << tm.tm_min << ":"; - stream << std::setfill('0') << std::setw(2) << tm.tm_sec << " GMT"; + stream << wkday[tm.tm_wday] << ", "; + stream << std::setfill('0') << std::setw(2) << tm.tm_mday << " "; + stream << month[tm.tm_mon] << " "; + stream << std::setfill('0') << std::setw(4) << tm.tm_year + 1900 << " "; + stream << std::setfill('0') << std::setw(2) << tm.tm_hour << ":"; + stream << std::setfill('0') << std::setw(2) << tm.tm_min << ":"; + stream << std::setfill('0') << std::setw(2) << tm.tm_sec << " GMT"; - return stream.str(); + return stream.str(); } void CHTTPSock::GetPage() { - DEBUG("Page Request [" << m_sURI << "] "); + DEBUG("Page Request [" << m_sURI << "] "); - // Check that the requested path starts with the prefix. Strip it if so. - if (!m_sURI.TrimPrefix(m_sURIPrefix)) { - DEBUG("INVALID path => Does not start with prefix [" + m_sURIPrefix + - "]"); - DEBUG("Expected prefix: " << m_sURIPrefix); - DEBUG("Requested path: " << m_sURI); - Redirect("/"); - } else { - OnPageRequest(m_sURI); - } + // Check that the requested path starts with the prefix. Strip it if so. + if (!m_sURI.TrimPrefix(m_sURIPrefix)) { + DEBUG("INVALID path => Does not start with prefix [" + m_sURIPrefix + + "]"); + DEBUG("Expected prefix: " << m_sURIPrefix); + DEBUG("Requested path: " << m_sURI); + Redirect("/"); + } else { + OnPageRequest(m_sURI); + } } #ifdef HAVE_ZLIB static bool InitZlibStream(z_stream* zStrm, const char* buf) { - memset(zStrm, 0, sizeof(z_stream)); - zStrm->next_in = (Bytef*)buf; + memset(zStrm, 0, sizeof(z_stream)); + zStrm->next_in = (Bytef*)buf; - // "15" is the default value for good compression, - // the weird "+ 16" means "please generate a gzip header and trailer". - const int WINDOW_BITS = 15 + 16; - const int MEMLEVEL = 8; + // "15" is the default value for good compression, + // the weird "+ 16" means "please generate a gzip header and trailer". + const int WINDOW_BITS = 15 + 16; + const int MEMLEVEL = 8; - return (deflateInit2(zStrm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, WINDOW_BITS, - MEMLEVEL, Z_DEFAULT_STRATEGY) == Z_OK); + return (deflateInit2(zStrm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, WINDOW_BITS, + MEMLEVEL, Z_DEFAULT_STRATEGY) == Z_OK); } #endif void CHTTPSock::PrintPage(const CString& sPage) { #ifdef HAVE_ZLIB - if (m_bAcceptGzip && !SentHeader()) { - char szBuf[4096]; - z_stream zStrm; - int zStatus, zFlush = Z_NO_FLUSH; + if (m_bAcceptGzip && !SentHeader()) { + char szBuf[4096]; + z_stream zStrm; + int zStatus, zFlush = Z_NO_FLUSH; - if (InitZlibStream(&zStrm, sPage.c_str())) { - DEBUG("- Sending gzip-compressed."); - AddHeader("Content-Encoding", "gzip"); - PrintHeader(0); // we do not know the compressed data's length + if (InitZlibStream(&zStrm, sPage.c_str())) { + DEBUG("- Sending gzip-compressed."); + AddHeader("Content-Encoding", "gzip"); + PrintHeader(0); // we do not know the compressed data's length - zStrm.avail_in = sPage.size(); - do { - if (zStrm.avail_in == 0) { - zFlush = Z_FINISH; - } + zStrm.avail_in = sPage.size(); + do { + if (zStrm.avail_in == 0) { + zFlush = Z_FINISH; + } - zStrm.next_out = (Bytef*)szBuf; - zStrm.avail_out = sizeof(szBuf); + zStrm.next_out = (Bytef*)szBuf; + zStrm.avail_out = sizeof(szBuf); - zStatus = deflate(&zStrm, zFlush); + zStatus = deflate(&zStrm, zFlush); - if ((zStatus == Z_OK || zStatus == Z_STREAM_END) && - zStrm.avail_out < sizeof(szBuf)) { - Write(szBuf, sizeof(szBuf) - zStrm.avail_out); - } - } while (zStatus == Z_OK); + if ((zStatus == Z_OK || zStatus == Z_STREAM_END) && + zStrm.avail_out < sizeof(szBuf)) { + Write(szBuf, sizeof(szBuf) - zStrm.avail_out); + } + } while (zStatus == Z_OK); - Close(Csock::CLT_AFTERWRITE); - deflateEnd(&zStrm); - return; - } + Close(Csock::CLT_AFTERWRITE); + deflateEnd(&zStrm); + return; + } - } // else: fall through + } // else: fall through #endif - if (!SentHeader()) { - PrintHeader(sPage.length()); - } else { - DEBUG("PrintPage(): Header was already sent"); - } + if (!SentHeader()) { + PrintHeader(sPage.length()); + } else { + DEBUG("PrintPage(): Header was already sent"); + } - Write(sPage); - Close(Csock::CLT_AFTERWRITE); + Write(sPage); + Close(Csock::CLT_AFTERWRITE); } bool CHTTPSock::PrintFile(const CString& sFileName, CString sContentType) { - CString sFilePath = sFileName; + CString sFilePath = sFileName; - if (!m_sDocRoot.empty()) { - sFilePath.TrimLeft("/"); + if (!m_sDocRoot.empty()) { + sFilePath.TrimLeft("/"); - sFilePath = CDir::CheckPathPrefix(m_sDocRoot, sFilePath, m_sDocRoot); + sFilePath = CDir::CheckPathPrefix(m_sDocRoot, sFilePath, m_sDocRoot); - if (sFilePath.empty()) { - PrintErrorPage(403, "Forbidden", - "You don't have permission to access that file on " - "this server."); - DEBUG("THIS FILE: [" << sFilePath << "] does not live in ..."); - DEBUG("DOCUMENT ROOT: [" << m_sDocRoot << "]"); - return false; - } - } + if (sFilePath.empty()) { + PrintErrorPage(403, "Forbidden", + "You don't have permission to access that file on " + "this server."); + DEBUG("THIS FILE: [" << sFilePath << "] does not live in ..."); + DEBUG("DOCUMENT ROOT: [" << m_sDocRoot << "]"); + return false; + } + } - CFile File(sFilePath); + CFile File(sFilePath); - if (!File.Open()) { - PrintNotFound(); - return false; - } + if (!File.Open()) { + PrintNotFound(); + return false; + } - if (sContentType.empty()) { - if (sFileName.EndsWith(".html") || sFileName.EndsWith(".htm")) { - sContentType = "text/html; charset=utf-8"; - } else if (sFileName.EndsWith(".css")) { - sContentType = "text/css; charset=utf-8"; - } else if (sFileName.EndsWith(".js")) { - sContentType = "application/x-javascript; charset=utf-8"; - } else if (sFileName.EndsWith(".jpg")) { - sContentType = "image/jpeg"; - } else if (sFileName.EndsWith(".gif")) { - sContentType = "image/gif"; - } else if (sFileName.EndsWith(".ico")) { - sContentType = "image/x-icon"; - } else if (sFileName.EndsWith(".png")) { - sContentType = "image/png"; - } else if (sFileName.EndsWith(".bmp")) { - sContentType = "image/bmp"; - } else { - sContentType = "text/plain; charset=utf-8"; - } - } + if (sContentType.empty()) { + if (sFileName.EndsWith(".html") || sFileName.EndsWith(".htm")) { + sContentType = "text/html; charset=utf-8"; + } else if (sFileName.EndsWith(".css")) { + sContentType = "text/css; charset=utf-8"; + } else if (sFileName.EndsWith(".js")) { + sContentType = "application/x-javascript; charset=utf-8"; + } else if (sFileName.EndsWith(".jpg")) { + sContentType = "image/jpeg"; + } else if (sFileName.EndsWith(".gif")) { + sContentType = "image/gif"; + } else if (sFileName.EndsWith(".ico")) { + sContentType = "image/x-icon"; + } else if (sFileName.EndsWith(".png")) { + sContentType = "image/png"; + } else if (sFileName.EndsWith(".bmp")) { + sContentType = "image/bmp"; + } else { + sContentType = "text/plain; charset=utf-8"; + } + } - const time_t iMTime = File.GetMTime(); - bool bNotModified = false; - CString sETag; + const time_t iMTime = File.GetMTime(); + bool bNotModified = false; + CString sETag; - if (iMTime > 0 && !m_bHTTP10Client) { - sETag = "-" + CString(iMTime); // lighttpd style ETag + if (iMTime > 0 && !m_bHTTP10Client) { + sETag = "-" + CString(iMTime); // lighttpd style ETag - AddHeader("Last-Modified", GetDate(iMTime)); - AddHeader("ETag", "\"" + sETag + "\""); - AddHeader("Cache-Control", "public"); + AddHeader("Last-Modified", GetDate(iMTime)); + AddHeader("ETag", "\"" + sETag + "\""); + AddHeader("Cache-Control", "public"); - if (!m_sIfNoneMatch.empty()) { - m_sIfNoneMatch.Trim("\\\"'"); - bNotModified = - (m_sIfNoneMatch.Equals(sETag, CString::CaseSensitive)); - } - } + if (!m_sIfNoneMatch.empty()) { + m_sIfNoneMatch.Trim("\\\"'"); + bNotModified = + (m_sIfNoneMatch.Equals(sETag, CString::CaseSensitive)); + } + } - if (bNotModified) { - PrintHeader(0, sContentType, 304, "Not Modified"); - } else { - off_t iSize = File.GetSize(); + if (bNotModified) { + PrintHeader(0, sContentType, 304, "Not Modified"); + } else { + off_t iSize = File.GetSize(); - // Don't try to send files over 16 MiB, because it might block - // the whole process and use huge amounts of memory. - if (iSize > 16 * 1024 * 1024) { - DEBUG("- Abort: File is over 16 MiB big: " << iSize); - PrintErrorPage(500, "Internal Server Error", "File too big"); - return true; - } + // Don't try to send files over 16 MiB, because it might block + // the whole process and use huge amounts of memory. + if (iSize > 16 * 1024 * 1024) { + DEBUG("- Abort: File is over 16 MiB big: " << iSize); + PrintErrorPage(500, "Internal Server Error", "File too big"); + return true; + } #ifdef HAVE_ZLIB - bool bGzip = m_bAcceptGzip && (sContentType.StartsWith("text/") || - sFileName.EndsWith(".js")); + bool bGzip = m_bAcceptGzip && (sContentType.StartsWith("text/") || + sFileName.EndsWith(".js")); - if (bGzip) { - DEBUG("- Sending gzip-compressed."); - AddHeader("Content-Encoding", "gzip"); - PrintHeader( - 0, - sContentType); // we do not know the compressed data's length - WriteFileGzipped(File); - } else + if (bGzip) { + DEBUG("- Sending gzip-compressed."); + AddHeader("Content-Encoding", "gzip"); + PrintHeader( + 0, + sContentType); // we do not know the compressed data's length + WriteFileGzipped(File); + } else #endif - { - PrintHeader(iSize, sContentType); - WriteFileUncompressed(File); - } - } + { + PrintHeader(iSize, sContentType); + WriteFileUncompressed(File); + } + } - DEBUG("- ETag: [" << sETag << "] / If-None-Match [" << m_sIfNoneMatch - << "]"); + DEBUG("- ETag: [" << sETag << "] / If-None-Match [" << m_sIfNoneMatch + << "]"); - Close(Csock::CLT_AFTERWRITE); + Close(Csock::CLT_AFTERWRITE); - return true; + return true; } void CHTTPSock::WriteFileUncompressed(CFile& File) { - char szBuf[4096]; - off_t iLen = 0; - ssize_t i = 0; - off_t iSize = File.GetSize(); + char szBuf[4096]; + off_t iLen = 0; + ssize_t i = 0; + off_t iSize = File.GetSize(); - // while we haven't reached iSize and read() succeeds... - while (iLen < iSize && (i = File.Read(szBuf, sizeof(szBuf))) > 0) { - Write(szBuf, i); - iLen += i; - } + // while we haven't reached iSize and read() succeeds... + while (iLen < iSize && (i = File.Read(szBuf, sizeof(szBuf))) > 0) { + Write(szBuf, i); + iLen += i; + } - if (i < 0) { - DEBUG("- Error while reading file: " << strerror(errno)); - } + if (i < 0) { + DEBUG("- Error while reading file: " << strerror(errno)); + } } #ifdef HAVE_ZLIB void CHTTPSock::WriteFileGzipped(CFile& File) { - char szBufIn[8192]; - char szBufOut[8192]; - off_t iFileSize = File.GetSize(), iFileReadTotal = 0; - z_stream zStrm; - int zFlush = Z_NO_FLUSH; - int zStatus; + char szBufIn[8192]; + char szBufOut[8192]; + off_t iFileSize = File.GetSize(), iFileReadTotal = 0; + z_stream zStrm; + int zFlush = Z_NO_FLUSH; + int zStatus; - if (!InitZlibStream(&zStrm, szBufIn)) { - DEBUG("- Error initializing zlib!"); - return; - } + if (!InitZlibStream(&zStrm, szBufIn)) { + DEBUG("- Error initializing zlib!"); + return; + } - do { - ssize_t iFileRead = 0; + do { + ssize_t iFileRead = 0; - if (zStrm.avail_in == 0) { - // input buffer is empty, try to read more data from file. - // if there is no more data, finish the stream. + if (zStrm.avail_in == 0) { + // input buffer is empty, try to read more data from file. + // if there is no more data, finish the stream. - if (iFileReadTotal < iFileSize) { - iFileRead = File.Read(szBufIn, sizeof(szBufIn)); + if (iFileReadTotal < iFileSize) { + iFileRead = File.Read(szBufIn, sizeof(szBufIn)); - if (iFileRead < 1) { - // wtf happened? better quit compressing. - iFileReadTotal = iFileSize; - zFlush = Z_FINISH; - } else { - iFileReadTotal += iFileRead; + if (iFileRead < 1) { + // wtf happened? better quit compressing. + iFileReadTotal = iFileSize; + zFlush = Z_FINISH; + } else { + iFileReadTotal += iFileRead; - zStrm.next_in = (Bytef*)szBufIn; - zStrm.avail_in = iFileRead; - } - } else { - zFlush = Z_FINISH; - } - } + zStrm.next_in = (Bytef*)szBufIn; + zStrm.avail_in = iFileRead; + } + } else { + zFlush = Z_FINISH; + } + } - zStrm.next_out = (Bytef*)szBufOut; - zStrm.avail_out = sizeof(szBufOut); + zStrm.next_out = (Bytef*)szBufOut; + zStrm.avail_out = sizeof(szBufOut); - zStatus = deflate(&zStrm, zFlush); + zStatus = deflate(&zStrm, zFlush); - if ((zStatus == Z_OK || zStatus == Z_STREAM_END) && - zStrm.avail_out < sizeof(szBufOut)) { - // there's data in the buffer: - Write(szBufOut, sizeof(szBufOut) - zStrm.avail_out); - } + if ((zStatus == Z_OK || zStatus == Z_STREAM_END) && + zStrm.avail_out < sizeof(szBufOut)) { + // there's data in the buffer: + Write(szBufOut, sizeof(szBufOut) - zStrm.avail_out); + } - } while (zStatus == Z_OK); + } while (zStatus == Z_OK); - deflateEnd(&zStrm); + deflateEnd(&zStrm); } #endif void CHTTPSock::ParseURI() { - ParseParams(m_sURI.Token(1, true, "?"), m_msvsGETParams); - m_sURI = m_sURI.Token(0, false, "?"); + ParseParams(m_sURI.Token(1, true, "?"), m_msvsGETParams); + m_sURI = m_sURI.Token(0, false, "?"); } CString CHTTPSock::GetPath() const { return m_sURI.Token(0, false, "?"); } void CHTTPSock::ParseParams(const CString& sParams, map& msvsParams) { - msvsParams.clear(); + msvsParams.clear(); - VCString vsPairs; - sParams.Split("&", vsPairs, true); + VCString vsPairs; + sParams.Split("&", vsPairs, true); - for (const CString& sPair : vsPairs) { - CString sName = - sPair.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII); - CString sValue = - sPair.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); + for (const CString& sPair : vsPairs) { + CString sName = + sPair.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII); + CString sValue = + sPair.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); - msvsParams[sName].push_back(sValue); - } + msvsParams[sName].push_back(sValue); + } } void CHTTPSock::SetDocRoot(const CString& s) { - m_sDocRoot = s + "/"; - m_sDocRoot.Replace("//", "/"); + m_sDocRoot = s + "/"; + m_sDocRoot.Replace("//", "/"); } const CString& CHTTPSock::GetDocRoot() const { return m_sDocRoot; } @@ -536,251 +536,251 @@ const CString& CHTTPSock::GetParamString() const { return m_sPostData; } const CString& CHTTPSock::GetURIPrefix() const { return m_sURIPrefix; } bool CHTTPSock::HasParam(const CString& sName, bool bPost) const { - if (bPost) return (m_msvsPOSTParams.find(sName) != m_msvsPOSTParams.end()); - return (m_msvsGETParams.find(sName) != m_msvsGETParams.end()); + if (bPost) return (m_msvsPOSTParams.find(sName) != m_msvsPOSTParams.end()); + return (m_msvsGETParams.find(sName) != m_msvsGETParams.end()); } CString CHTTPSock::GetRawParam(const CString& sName, bool bPost) const { - if (bPost) return GetRawParam(sName, m_msvsPOSTParams); - return GetRawParam(sName, m_msvsGETParams); + if (bPost) return GetRawParam(sName, m_msvsPOSTParams); + return GetRawParam(sName, m_msvsGETParams); } CString CHTTPSock::GetRawParam(const CString& sName, const map& msvsParams) { - CString sRet; + CString sRet; - map::const_iterator it = msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != msvsParams.end() && it->second.size() > 0) { - sRet = it->second[0]; - } + if (it != msvsParams.end() && it->second.size() > 0) { + sRet = it->second[0]; + } - return sRet; + return sRet; } CString CHTTPSock::GetParam(const CString& sName, bool bPost, const CString& sFilter) const { - if (bPost) return GetParam(sName, m_msvsPOSTParams, sFilter); - return GetParam(sName, m_msvsGETParams, sFilter); + if (bPost) return GetParam(sName, m_msvsPOSTParams, sFilter); + return GetParam(sName, m_msvsGETParams, sFilter); } CString CHTTPSock::GetParam(const CString& sName, const map& msvsParams, const CString& sFilter) { - CString sRet = GetRawParam(sName, msvsParams); - sRet.Trim(); + CString sRet = GetRawParam(sName, msvsParams); + sRet.Trim(); - for (size_t i = 0; i < sFilter.length(); i++) { - sRet.Replace(CString(sFilter.at(i)), ""); - } + for (size_t i = 0; i < sFilter.length(); i++) { + sRet.Replace(CString(sFilter.at(i)), ""); + } - return sRet; + return sRet; } size_t CHTTPSock::GetParamValues(const CString& sName, set& ssRet, bool bPost, const CString& sFilter) const { - if (bPost) return GetParamValues(sName, ssRet, m_msvsPOSTParams, sFilter); - return GetParamValues(sName, ssRet, m_msvsGETParams, sFilter); + if (bPost) return GetParamValues(sName, ssRet, m_msvsPOSTParams, sFilter); + return GetParamValues(sName, ssRet, m_msvsGETParams, sFilter); } size_t CHTTPSock::GetParamValues(const CString& sName, set& ssRet, const map& msvsParams, const CString& sFilter) { - ssRet.clear(); + ssRet.clear(); - map::const_iterator it = msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != msvsParams.end()) { - for (CString sParam : it->second) { - sParam.Trim(); + if (it != msvsParams.end()) { + for (CString sParam : it->second) { + sParam.Trim(); - for (size_t i = 0; i < sFilter.length(); i++) { - sParam.Replace(CString(sFilter.at(i)), ""); - } - ssRet.insert(sParam); - } - } + for (size_t i = 0; i < sFilter.length(); i++) { + sParam.Replace(CString(sFilter.at(i)), ""); + } + ssRet.insert(sParam); + } + } - return ssRet.size(); + return ssRet.size(); } size_t CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, bool bPost, const CString& sFilter) const { - if (bPost) return GetParamValues(sName, vsRet, m_msvsPOSTParams, sFilter); - return GetParamValues(sName, vsRet, m_msvsGETParams, sFilter); + if (bPost) return GetParamValues(sName, vsRet, m_msvsPOSTParams, sFilter); + return GetParamValues(sName, vsRet, m_msvsGETParams, sFilter); } size_t CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const map& msvsParams, const CString& sFilter) { - vsRet.clear(); + vsRet.clear(); - map::const_iterator it = msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != msvsParams.end()) { - for (CString sParam : it->second) { - sParam.Trim(); + if (it != msvsParams.end()) { + for (CString sParam : it->second) { + sParam.Trim(); - for (size_t i = 0; i < sFilter.length(); i++) { - sParam.Replace(CString(sFilter.at(i)), ""); - } - vsRet.push_back(sParam); - } - } + for (size_t i = 0; i < sFilter.length(); i++) { + sParam.Replace(CString(sFilter.at(i)), ""); + } + vsRet.push_back(sParam); + } + } - return vsRet.size(); + return vsRet.size(); } const map& CHTTPSock::GetParams(bool bPost) const { - if (bPost) return m_msvsPOSTParams; - return m_msvsGETParams; + if (bPost) return m_msvsPOSTParams; + return m_msvsGETParams; } bool CHTTPSock::IsPost() const { return m_bPost; } bool CHTTPSock::PrintNotFound() { - return PrintErrorPage(404, "Not Found", - "The requested URL was not found on this server."); + return PrintErrorPage(404, "Not Found", + "The requested URL was not found on this server."); } bool CHTTPSock::PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage) { - if (SentHeader()) { - DEBUG("PrintErrorPage(): Header was already sent"); - return false; - } + if (SentHeader()) { + DEBUG("PrintErrorPage(): Header was already sent"); + return false; + } - CString sPage = - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "" + - CString(uStatusId) + " " + sStatusMsg.Escape_n(CString::EHTML) + - "\r\n" - "\r\n" - "\r\n" - "

" + - sStatusMsg.Escape_n(CString::EHTML) + - "

\r\n" - "

" + - sMessage.Escape_n(CString::EHTML) + - "

\r\n" - "
\r\n" - "

" + - CZNC::GetTag(false, /* bHTML = */ true) + - "

\r\n" - "\r\n" - "\r\n"; + CString sPage = + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "" + + CString(uStatusId) + " " + sStatusMsg.Escape_n(CString::EHTML) + + "\r\n" + "\r\n" + "\r\n" + "

" + + sStatusMsg.Escape_n(CString::EHTML) + + "

\r\n" + "

" + + sMessage.Escape_n(CString::EHTML) + + "

\r\n" + "
\r\n" + "

" + + CZNC::GetTag(false, /* bHTML = */ true) + + "

\r\n" + "\r\n" + "\r\n"; - PrintHeader(sPage.length(), "text/html; charset=utf-8", uStatusId, - sStatusMsg); - Write(sPage); - Close(Csock::CLT_AFTERWRITE); + PrintHeader(sPage.length(), "text/html; charset=utf-8", uStatusId, + sStatusMsg); + Write(sPage); + Close(Csock::CLT_AFTERWRITE); - return true; + return true; } bool CHTTPSock::ForceLogin() { - if (m_bLoggedIn) { - return true; - } + if (m_bLoggedIn) { + return true; + } - if (SentHeader()) { - DEBUG("ForceLogin(): Header was already sent!"); - return false; - } + if (SentHeader()) { + DEBUG("ForceLogin(): Header was already sent!"); + return false; + } - AddHeader("WWW-Authenticate", - "Basic realm=\"" + CZNC::GetTag(false) + "\""); - PrintErrorPage(401, "Unauthorized", "You need to login to view this page."); + AddHeader("WWW-Authenticate", + "Basic realm=\"" + CZNC::GetTag(false) + "\""); + PrintErrorPage(401, "Unauthorized", "You need to login to view this page."); - return false; + return false; } bool CHTTPSock::OnLogin(const CString& sUser, const CString& sPass, bool bBasic) { - return false; + return false; } bool CHTTPSock::SentHeader() const { return m_bSentHeader; } bool CHTTPSock::PrintHeader(off_t uContentLength, const CString& sContentType, unsigned int uStatusId, const CString& sStatusMsg) { - if (SentHeader()) { - DEBUG("PrintHeader(): Header was already sent!"); - return false; - } + if (SentHeader()) { + DEBUG("PrintHeader(): Header was already sent!"); + return false; + } - if (!sContentType.empty()) { - m_sContentType = sContentType; - } + if (!sContentType.empty()) { + m_sContentType = sContentType; + } - if (m_sContentType.empty()) { - m_sContentType = "text/html; charset=utf-8"; - } + if (m_sContentType.empty()) { + m_sContentType = "text/html; charset=utf-8"; + } - DEBUG("- " << uStatusId << " (" << sStatusMsg << ") [" << m_sContentType - << "]"); + DEBUG("- " << uStatusId << " (" << sStatusMsg << ") [" << m_sContentType + << "]"); - Write("HTTP/" + CString(m_bHTTP10Client ? "1.0 " : "1.1 ") + - CString(uStatusId) + " " + sStatusMsg + "\r\n"); - Write("Date: " + GetDate() + "\r\n"); - Write("Server: " + CZNC::GetTag(false) + "\r\n"); - if (uContentLength > 0) { - Write("Content-Length: " + CString(uContentLength) + "\r\n"); - } - Write("Content-Type: " + m_sContentType + "\r\n"); + Write("HTTP/" + CString(m_bHTTP10Client ? "1.0 " : "1.1 ") + + CString(uStatusId) + " " + sStatusMsg + "\r\n"); + Write("Date: " + GetDate() + "\r\n"); + Write("Server: " + CZNC::GetTag(false) + "\r\n"); + if (uContentLength > 0) { + Write("Content-Length: " + CString(uContentLength) + "\r\n"); + } + Write("Content-Type: " + m_sContentType + "\r\n"); - for (const auto& it : m_msResponseCookies) { - Write("Set-Cookie: " + it.first.Escape_n(CString::EURL) + "=" + - it.second.Escape_n(CString::EURL) + "; HttpOnly; path=/;" + - (GetSSL() ? "Secure;" : "") + "\r\n"); - } + for (const auto& it : m_msResponseCookies) { + Write("Set-Cookie: " + it.first.Escape_n(CString::EURL) + "=" + + it.second.Escape_n(CString::EURL) + "; HttpOnly; path=/;" + + (GetSSL() ? "Secure;" : "") + "\r\n"); + } - for (const auto& it : m_msHeaders) { - Write(it.first + ": " + it.second + "\r\n"); - } + for (const auto& it : m_msHeaders) { + Write(it.first + ": " + it.second + "\r\n"); + } - Write("Connection: Close\r\n"); + Write("Connection: Close\r\n"); - Write("\r\n"); - m_bSentHeader = true; + Write("\r\n"); + m_bSentHeader = true; - return true; + return true; } void CHTTPSock::SetContentType(const CString& sContentType) { - m_sContentType = sContentType; + m_sContentType = sContentType; } void CHTTPSock::AddHeader(const CString& sName, const CString& sValue) { - m_msHeaders[sName] = sValue; + m_msHeaders[sName] = sValue; } bool CHTTPSock::Redirect(const CString& sURL) { - if (SentHeader()) { - DEBUG("Redirect() - Header was already sent"); - return false; - } else if (!sURL.StartsWith("/")) { - // HTTP/1.1 only admits absolute URIs for the Location header. - DEBUG("Redirect to relative URI [" + sURL + "] is not allowed."); - return false; - } else { - CString location = m_sURIPrefix + sURL; + if (SentHeader()) { + DEBUG("Redirect() - Header was already sent"); + return false; + } else if (!sURL.StartsWith("/")) { + // HTTP/1.1 only admits absolute URIs for the Location header. + DEBUG("Redirect to relative URI [" + sURL + "] is not allowed."); + return false; + } else { + CString location = m_sURIPrefix + sURL; - DEBUG("- Redirect to [" << location - << "] with prefix [" + m_sURIPrefix + "]"); - AddHeader("Location", location); - PrintErrorPage(302, "Found", "The document has moved here."); + DEBUG("- Redirect to [" << location + << "] with prefix [" + m_sURIPrefix + "]"); + AddHeader("Location", location); + PrintErrorPage(302, "Found", "The document has moved here."); - return true; - } + return true; + } } void CHTTPSock::Connected() { SetTimeout(120); } diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index de108a60..07bb9f55 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -31,95 +31,95 @@ using std::set; class CIRCNetworkPingTimer : public CCron { public: - CIRCNetworkPingTimer(CIRCNetwork* pNetwork) - : CCron(), m_pNetwork(pNetwork) { - SetName("CIRCNetworkPingTimer::" + - m_pNetwork->GetUser()->GetUserName() + "::" + - m_pNetwork->GetName()); - Start(CIRCNetwork::PING_SLACK); - } + CIRCNetworkPingTimer(CIRCNetwork* pNetwork) + : CCron(), m_pNetwork(pNetwork) { + SetName("CIRCNetworkPingTimer::" + + m_pNetwork->GetUser()->GetUserName() + "::" + + m_pNetwork->GetName()); + Start(CIRCNetwork::PING_SLACK); + } - virtual ~CIRCNetworkPingTimer() {} + virtual ~CIRCNetworkPingTimer() {} - CIRCNetworkPingTimer(const CIRCNetworkPingTimer&) = delete; - CIRCNetworkPingTimer& operator=(const CIRCNetworkPingTimer&) = delete; + CIRCNetworkPingTimer(const CIRCNetworkPingTimer&) = delete; + CIRCNetworkPingTimer& operator=(const CIRCNetworkPingTimer&) = delete; protected: - void RunJob() override { - CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); + void RunJob() override { + CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); - if (pIRCSock && - pIRCSock->GetTimeSinceLastDataTransaction() >= - CIRCNetwork::PING_FREQUENCY) { - pIRCSock->PutIRC("PING :ZNC"); - } + if (pIRCSock && + pIRCSock->GetTimeSinceLastDataTransaction() >= + CIRCNetwork::PING_FREQUENCY) { + pIRCSock->PutIRC("PING :ZNC"); + } - const vector& vClients = m_pNetwork->GetClients(); - for (CClient* pClient : vClients) { - if (pClient->GetTimeSinceLastDataTransaction() >= - CIRCNetwork::PING_FREQUENCY) { - pClient->PutClient("PING :ZNC"); - } - } - } + const vector& vClients = m_pNetwork->GetClients(); + for (CClient* pClient : vClients) { + if (pClient->GetTimeSinceLastDataTransaction() >= + CIRCNetwork::PING_FREQUENCY) { + pClient->PutClient("PING :ZNC"); + } + } + } private: - CIRCNetwork* m_pNetwork; + CIRCNetwork* m_pNetwork; }; class CIRCNetworkJoinTimer : public CCron { public: - CIRCNetworkJoinTimer(CIRCNetwork* pNetwork) - : CCron(), m_bDelayed(false), m_pNetwork(pNetwork) { - SetName("CIRCNetworkJoinTimer::" + - m_pNetwork->GetUser()->GetUserName() + "::" + - m_pNetwork->GetName()); - Start(CIRCNetwork::JOIN_FREQUENCY); - } + CIRCNetworkJoinTimer(CIRCNetwork* pNetwork) + : CCron(), m_bDelayed(false), m_pNetwork(pNetwork) { + SetName("CIRCNetworkJoinTimer::" + + m_pNetwork->GetUser()->GetUserName() + "::" + + m_pNetwork->GetName()); + Start(CIRCNetwork::JOIN_FREQUENCY); + } - virtual ~CIRCNetworkJoinTimer() {} + virtual ~CIRCNetworkJoinTimer() {} - CIRCNetworkJoinTimer(const CIRCNetworkJoinTimer&) = delete; - CIRCNetworkJoinTimer& operator=(const CIRCNetworkJoinTimer&) = delete; + CIRCNetworkJoinTimer(const CIRCNetworkJoinTimer&) = delete; + CIRCNetworkJoinTimer& operator=(const CIRCNetworkJoinTimer&) = delete; - void Delay(unsigned short int uDelay) { - m_bDelayed = true; - Start(uDelay); - } + void Delay(unsigned short int uDelay) { + m_bDelayed = true; + Start(uDelay); + } protected: - void RunJob() override { - if (m_bDelayed) { - m_bDelayed = false; - Start(CIRCNetwork::JOIN_FREQUENCY); - } - if (m_pNetwork->IsIRCConnected()) { - m_pNetwork->JoinChans(); - } - } + void RunJob() override { + if (m_bDelayed) { + m_bDelayed = false; + Start(CIRCNetwork::JOIN_FREQUENCY); + } + if (m_pNetwork->IsIRCConnected()) { + m_pNetwork->JoinChans(); + } + } private: - bool m_bDelayed; - CIRCNetwork* m_pNetwork; + bool m_bDelayed; + CIRCNetwork* m_pNetwork; }; bool CIRCNetwork::IsValidNetwork(const CString& sNetwork) { - // ^[-\w]+$ + // ^[-\w]+$ - if (sNetwork.empty()) { - return false; - } + if (sNetwork.empty()) { + return false; + } - const char* p = sNetwork.c_str(); - while (*p) { - if (*p != '_' && *p != '-' && !isalnum(*p)) { - return false; - } + const char* p = sNetwork.c_str(); + while (*p) { + if (*p != '_' && *p != '-' && !isalnum(*p)) { + return false; + } - p++; - } + p++; + } - return true; + return true; } CIRCNetwork::CIRCNetwork(CUser* pUser, const CString& sName) @@ -155,572 +155,572 @@ CIRCNetwork::CIRCNetwork(CUser* pUser, const CString& sName) m_uJoinDelay(0), m_uBytesRead(0), m_uBytesWritten(0) { - SetUser(pUser); + SetUser(pUser); - // This should be more than enough raws, especially since we are buffering - // the MOTD separately - m_RawBuffer.SetLineCount(100, true); - // This should be more than enough motd lines - m_MotdBuffer.SetLineCount(200, true); - m_NoticeBuffer.SetLineCount(250, true); + // This should be more than enough raws, especially since we are buffering + // the MOTD separately + m_RawBuffer.SetLineCount(100, true); + // This should be more than enough motd lines + m_MotdBuffer.SetLineCount(200, true); + m_NoticeBuffer.SetLineCount(250, true); - m_pPingTimer = new CIRCNetworkPingTimer(this); - CZNC::Get().GetManager().AddCron(m_pPingTimer); + m_pPingTimer = new CIRCNetworkPingTimer(this); + CZNC::Get().GetManager().AddCron(m_pPingTimer); - m_pJoinTimer = new CIRCNetworkJoinTimer(this); - CZNC::Get().GetManager().AddCron(m_pJoinTimer); + m_pJoinTimer = new CIRCNetworkJoinTimer(this); + CZNC::Get().GetManager().AddCron(m_pJoinTimer); - SetIRCConnectEnabled(true); + SetIRCConnectEnabled(true); } CIRCNetwork::CIRCNetwork(CUser* pUser, const CIRCNetwork& Network) : CIRCNetwork(pUser, "") { - Clone(Network); + Clone(Network); } void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneName) { - if (bCloneName) { - m_sName = Network.GetName(); - } + if (bCloneName) { + m_sName = Network.GetName(); + } - m_fFloodRate = Network.GetFloodRate(); - m_uFloodBurst = Network.GetFloodBurst(); - m_uJoinDelay = Network.GetJoinDelay(); + m_fFloodRate = Network.GetFloodRate(); + m_uFloodBurst = Network.GetFloodBurst(); + m_uJoinDelay = Network.GetJoinDelay(); - SetNick(Network.GetNick()); - SetAltNick(Network.GetAltNick()); - SetIdent(Network.GetIdent()); - SetRealName(Network.GetRealName()); - SetBindHost(Network.GetBindHost()); - SetEncoding(Network.GetEncoding()); - SetQuitMsg(Network.GetQuitMsg()); - m_ssTrustedFingerprints = Network.m_ssTrustedFingerprints; + SetNick(Network.GetNick()); + SetAltNick(Network.GetAltNick()); + SetIdent(Network.GetIdent()); + SetRealName(Network.GetRealName()); + SetBindHost(Network.GetBindHost()); + SetEncoding(Network.GetEncoding()); + SetQuitMsg(Network.GetQuitMsg()); + m_ssTrustedFingerprints = Network.m_ssTrustedFingerprints; - // Servers - const vector& vServers = Network.GetServers(); - CString sServer; - CServer* pCurServ = GetCurrentServer(); + // Servers + const vector& vServers = Network.GetServers(); + CString sServer; + CServer* pCurServ = GetCurrentServer(); - if (pCurServ) { - sServer = pCurServ->GetName(); - } + if (pCurServ) { + sServer = pCurServ->GetName(); + } - DelServers(); + DelServers(); - for (CServer* pServer : vServers) { - AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), - pServer->IsSSL()); - } + for (CServer* pServer : vServers) { + AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(), + pServer->IsSSL()); + } - m_uServerIdx = 0; - for (size_t a = 0; a < m_vServers.size(); a++) { - if (sServer.Equals(m_vServers[a]->GetName())) { - m_uServerIdx = a + 1; - break; - } - } - if (m_uServerIdx == 0) { - m_uServerIdx = m_vServers.size(); - CIRCSock* pSock = GetIRCSock(); + m_uServerIdx = 0; + for (size_t a = 0; a < m_vServers.size(); a++) { + if (sServer.Equals(m_vServers[a]->GetName())) { + m_uServerIdx = a + 1; + break; + } + } + if (m_uServerIdx == 0) { + m_uServerIdx = m_vServers.size(); + CIRCSock* pSock = GetIRCSock(); - if (pSock) { - PutStatus( - "Jumping servers because this server is no longer in the list"); - pSock->Quit(); - } - } - // !Servers + if (pSock) { + PutStatus( + "Jumping servers because this server is no longer in the list"); + pSock->Quit(); + } + } + // !Servers - // Chans - const vector& vChans = Network.GetChans(); - for (CChan* pNewChan : vChans) { - CChan* pChan = FindChan(pNewChan->GetName()); + // Chans + const vector& vChans = Network.GetChans(); + for (CChan* pNewChan : vChans) { + CChan* pChan = FindChan(pNewChan->GetName()); - if (pChan) { - pChan->SetInConfig(pNewChan->InConfig()); - } else { - AddChan(pNewChan->GetName(), pNewChan->InConfig()); - } - } + if (pChan) { + pChan->SetInConfig(pNewChan->InConfig()); + } else { + AddChan(pNewChan->GetName(), pNewChan->InConfig()); + } + } - for (CChan* pChan : m_vChans) { - CChan* pNewChan = Network.FindChan(pChan->GetName()); + for (CChan* pChan : m_vChans) { + CChan* pNewChan = Network.FindChan(pChan->GetName()); - if (!pNewChan) { - pChan->SetInConfig(false); - } else { - pChan->Clone(*pNewChan); - } - } - // !Chans + if (!pNewChan) { + pChan->SetInConfig(false); + } else { + pChan->Clone(*pNewChan); + } + } + // !Chans - // Modules - set ssUnloadMods; - CModules& vCurMods = GetModules(); - const CModules& vNewMods = Network.GetModules(); + // Modules + set ssUnloadMods; + CModules& vCurMods = GetModules(); + const CModules& vNewMods = Network.GetModules(); - for (CModule* pNewMod : vNewMods) { - CString sModRet; - CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); + for (CModule* pNewMod : vNewMods) { + CString sModRet; + CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); - if (!pCurMod) { - vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), - CModInfo::NetworkModule, m_pUser, this, - sModRet); - } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { - vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), - m_pUser, this, sModRet); - } - } + if (!pCurMod) { + vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), + CModInfo::NetworkModule, m_pUser, this, + sModRet); + } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { + vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), + m_pUser, this, sModRet); + } + } - for (CModule* pCurMod : vCurMods) { - CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); + for (CModule* pCurMod : vCurMods) { + CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); - if (!pNewMod) { - ssUnloadMods.insert(pCurMod->GetModName()); - } - } + if (!pNewMod) { + ssUnloadMods.insert(pCurMod->GetModName()); + } + } - for (const CString& sMod : ssUnloadMods) { - vCurMods.UnloadModule(sMod); - } - // !Modules + for (const CString& sMod : ssUnloadMods) { + vCurMods.UnloadModule(sMod); + } + // !Modules - SetIRCConnectEnabled(Network.GetIRCConnectEnabled()); + SetIRCConnectEnabled(Network.GetIRCConnectEnabled()); } CIRCNetwork::~CIRCNetwork() { - if (m_pIRCSock) { - CZNC::Get().GetManager().DelSockByAddr(m_pIRCSock); - m_pIRCSock = nullptr; - } + if (m_pIRCSock) { + CZNC::Get().GetManager().DelSockByAddr(m_pIRCSock); + m_pIRCSock = nullptr; + } - // Delete clients - while (!m_vClients.empty()) { - CZNC::Get().GetManager().DelSockByAddr(m_vClients[0]); - } - m_vClients.clear(); + // Delete clients + while (!m_vClients.empty()) { + CZNC::Get().GetManager().DelSockByAddr(m_vClients[0]); + } + m_vClients.clear(); - // Delete servers - DelServers(); + // Delete servers + DelServers(); - // Delete modules (this unloads all modules) - delete m_pModules; - m_pModules = nullptr; + // Delete modules (this unloads all modules) + delete m_pModules; + m_pModules = nullptr; - // Delete Channels - for (CChan* pChan : m_vChans) { - delete pChan; - } - m_vChans.clear(); + // Delete Channels + for (CChan* pChan : m_vChans) { + delete pChan; + } + m_vChans.clear(); - // Delete Queries - for (CQuery* pQuery : m_vQueries) { - delete pQuery; - } - m_vQueries.clear(); + // Delete Queries + for (CQuery* pQuery : m_vQueries) { + delete pQuery; + } + m_vQueries.clear(); - CUser* pUser = GetUser(); - SetUser(nullptr); + CUser* pUser = GetUser(); + SetUser(nullptr); - // Make sure we are not in the connection queue - CZNC::Get().GetConnectionQueue().remove(this); + // Make sure we are not in the connection queue + CZNC::Get().GetConnectionQueue().remove(this); - CZNC::Get().GetManager().DelCronByAddr(m_pPingTimer); - CZNC::Get().GetManager().DelCronByAddr(m_pJoinTimer); + CZNC::Get().GetManager().DelCronByAddr(m_pPingTimer); + CZNC::Get().GetManager().DelCronByAddr(m_pJoinTimer); - if (pUser) { - pUser->AddBytesRead(m_uBytesRead); - pUser->AddBytesWritten(m_uBytesWritten); - } else { - CZNC::Get().AddBytesRead(m_uBytesRead); - CZNC::Get().AddBytesWritten(m_uBytesWritten); - } + if (pUser) { + pUser->AddBytesRead(m_uBytesRead); + pUser->AddBytesWritten(m_uBytesWritten); + } else { + CZNC::Get().AddBytesRead(m_uBytesRead); + CZNC::Get().AddBytesWritten(m_uBytesWritten); + } } void CIRCNetwork::DelServers() { - for (CServer* pServer : m_vServers) { - delete pServer; - } - m_vServers.clear(); + for (CServer* pServer : m_vServers) { + delete pServer; + } + m_vServers.clear(); } CString CIRCNetwork::GetNetworkPath() const { - CString sNetworkPath = m_pUser->GetUserPath() + "/networks/" + m_sName; + CString sNetworkPath = m_pUser->GetUserPath() + "/networks/" + m_sName; - if (!CFile::Exists(sNetworkPath)) { - CDir::MakeDir(sNetworkPath); - } + if (!CFile::Exists(sNetworkPath)) { + CDir::MakeDir(sNetworkPath); + } - return sNetworkPath; + return sNetworkPath; } template struct TOption { - const char* name; - void (CIRCNetwork::*pSetter)(T); + const char* name; + void (CIRCNetwork::*pSetter)(T); }; bool CIRCNetwork::ParseConfig(CConfig* pConfig, CString& sError, bool bUpgrade) { - VCString vsList; + VCString vsList; - if (!bUpgrade) { - TOption StringOptions[] = { - {"nick", &CIRCNetwork::SetNick}, - {"altnick", &CIRCNetwork::SetAltNick}, - {"ident", &CIRCNetwork::SetIdent}, - {"realname", &CIRCNetwork::SetRealName}, - {"bindhost", &CIRCNetwork::SetBindHost}, - {"encoding", &CIRCNetwork::SetEncoding}, - {"quitmsg", &CIRCNetwork::SetQuitMsg}, - }; - TOption BoolOptions[] = { - {"ircconnectenabled", &CIRCNetwork::SetIRCConnectEnabled}, - }; - TOption DoubleOptions[] = { - {"floodrate", &CIRCNetwork::SetFloodRate}, - }; - TOption SUIntOptions[] = { - {"floodburst", &CIRCNetwork::SetFloodBurst}, - {"joindelay", &CIRCNetwork::SetJoinDelay}, - }; + if (!bUpgrade) { + TOption StringOptions[] = { + {"nick", &CIRCNetwork::SetNick}, + {"altnick", &CIRCNetwork::SetAltNick}, + {"ident", &CIRCNetwork::SetIdent}, + {"realname", &CIRCNetwork::SetRealName}, + {"bindhost", &CIRCNetwork::SetBindHost}, + {"encoding", &CIRCNetwork::SetEncoding}, + {"quitmsg", &CIRCNetwork::SetQuitMsg}, + }; + TOption BoolOptions[] = { + {"ircconnectenabled", &CIRCNetwork::SetIRCConnectEnabled}, + }; + TOption DoubleOptions[] = { + {"floodrate", &CIRCNetwork::SetFloodRate}, + }; + TOption SUIntOptions[] = { + {"floodburst", &CIRCNetwork::SetFloodBurst}, + {"joindelay", &CIRCNetwork::SetJoinDelay}, + }; - for (const auto& Option : StringOptions) { - CString sValue; - if (pConfig->FindStringEntry(Option.name, sValue)) - (this->*Option.pSetter)(sValue); - } + for (const auto& Option : StringOptions) { + CString sValue; + if (pConfig->FindStringEntry(Option.name, sValue)) + (this->*Option.pSetter)(sValue); + } - for (const auto& Option : BoolOptions) { - CString sValue; - if (pConfig->FindStringEntry(Option.name, sValue)) - (this->*Option.pSetter)(sValue.ToBool()); - } + for (const auto& Option : BoolOptions) { + CString sValue; + if (pConfig->FindStringEntry(Option.name, sValue)) + (this->*Option.pSetter)(sValue.ToBool()); + } - for (const auto& Option : DoubleOptions) { - double fValue; - if (pConfig->FindDoubleEntry(Option.name, fValue)) - (this->*Option.pSetter)(fValue); - } + for (const auto& Option : DoubleOptions) { + double fValue; + if (pConfig->FindDoubleEntry(Option.name, fValue)) + (this->*Option.pSetter)(fValue); + } - for (const auto& Option : SUIntOptions) { - unsigned short value; - if (pConfig->FindUShortEntry(Option.name, value)) - (this->*Option.pSetter)(value); - } + for (const auto& Option : SUIntOptions) { + unsigned short value; + if (pConfig->FindUShortEntry(Option.name, value)) + (this->*Option.pSetter)(value); + } - pConfig->FindStringVector("loadmodule", vsList); - for (const CString& sValue : vsList) { - CString sModName = sValue.Token(0); - CString sNotice = "Loading network module [" + sModName + "]"; + pConfig->FindStringVector("loadmodule", vsList); + for (const CString& sValue : vsList) { + CString sModName = sValue.Token(0); + CString sNotice = "Loading network module [" + sModName + "]"; - // XXX Legacy crap, added in ZNC 0.203, modified in 0.207 - // Note that 0.203 == 0.207 - if (sModName == "away") { - sNotice = - "NOTICE: [away] was renamed, loading [awaystore] instead"; - sModName = "awaystore"; - } + // XXX Legacy crap, added in ZNC 0.203, modified in 0.207 + // Note that 0.203 == 0.207 + if (sModName == "away") { + sNotice = + "NOTICE: [away] was renamed, loading [awaystore] instead"; + sModName = "awaystore"; + } - // XXX Legacy crap, added in ZNC 0.207 - if (sModName == "autoaway") { - sNotice = - "NOTICE: [autoaway] was renamed, loading [awaystore] " - "instead"; - sModName = "awaystore"; - } + // XXX Legacy crap, added in ZNC 0.207 + if (sModName == "autoaway") { + sNotice = + "NOTICE: [autoaway] was renamed, loading [awaystore] " + "instead"; + sModName = "awaystore"; + } - // XXX Legacy crap, added in 1.1; fakeonline module was dropped in - // 1.0 and returned in 1.1 - if (sModName == "fakeonline") { - sNotice = - "NOTICE: [fakeonline] was renamed, loading " - "[modules_online] instead"; - sModName = "modules_online"; - } + // XXX Legacy crap, added in 1.1; fakeonline module was dropped in + // 1.0 and returned in 1.1 + if (sModName == "fakeonline") { + sNotice = + "NOTICE: [fakeonline] was renamed, loading " + "[modules_online] instead"; + sModName = "modules_online"; + } - CString sModRet; - CString sArgs = sValue.Token(1, true); + CString sModRet; + CString sArgs = sValue.Token(1, true); - bool bModRet = LoadModule(sModName, sArgs, sNotice, sModRet); + bool bModRet = LoadModule(sModName, sArgs, sNotice, sModRet); - if (!bModRet) { - // XXX The awaynick module was retired in 1.6 (still available - // as external module) - if (sModName == "awaynick") { - // load simple_away instead, unless it's already on the list - bool bFound = false; - for (const CString& sLoadMod : vsList) { - if (sLoadMod.Token(0).Equals("simple_away")) { - bFound = true; - } - } - if (!bFound) { - sNotice = - "Loading network module [simple_away] instead"; - sModName = "simple_away"; - // not a fatal error if simple_away is not available - LoadModule(sModName, sArgs, sNotice, sModRet); - } - } else { - sError = sModRet; - return false; - } - } - } - } + if (!bModRet) { + // XXX The awaynick module was retired in 1.6 (still available + // as external module) + if (sModName == "awaynick") { + // load simple_away instead, unless it's already on the list + bool bFound = false; + for (const CString& sLoadMod : vsList) { + if (sLoadMod.Token(0).Equals("simple_away")) { + bFound = true; + } + } + if (!bFound) { + sNotice = + "Loading network module [simple_away] instead"; + sModName = "simple_away"; + // not a fatal error if simple_away is not available + LoadModule(sModName, sArgs, sNotice, sModRet); + } + } else { + sError = sModRet; + return false; + } + } + } + } - pConfig->FindStringVector("server", vsList); - for (const CString& sServer : vsList) { - CUtils::PrintAction("Adding server [" + sServer + "]"); - CUtils::PrintStatus(AddServer(sServer)); - } + pConfig->FindStringVector("server", vsList); + for (const CString& sServer : vsList) { + CUtils::PrintAction("Adding server [" + sServer + "]"); + CUtils::PrintStatus(AddServer(sServer)); + } - pConfig->FindStringVector("trustedserverfingerprint", vsList); - for (const CString& sFP : vsList) { - AddTrustedFingerprint(sFP); - } + pConfig->FindStringVector("trustedserverfingerprint", vsList); + for (const CString& sFP : vsList) { + AddTrustedFingerprint(sFP); + } - pConfig->FindStringVector("chan", vsList); - for (const CString& sChan : vsList) { - AddChan(sChan, true); - } + pConfig->FindStringVector("chan", vsList); + for (const CString& sChan : vsList) { + AddChan(sChan, true); + } - CConfig::SubConfig subConf; - CConfig::SubConfig::const_iterator subIt; + CConfig::SubConfig subConf; + CConfig::SubConfig::const_iterator subIt; - pConfig->FindSubConfig("chan", subConf); - for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) { - const CString& sChanName = subIt->first; - CConfig* pSubConf = subIt->second.m_pSubConfig; - CChan* pChan = new CChan(sChanName, this, true, pSubConf); + pConfig->FindSubConfig("chan", subConf); + for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) { + const CString& sChanName = subIt->first; + CConfig* pSubConf = subIt->second.m_pSubConfig; + CChan* pChan = new CChan(sChanName, this, true, pSubConf); - if (!pSubConf->empty()) { - sError = "Unhandled lines in config for User [" + - m_pUser->GetUserName() + "], Network [" + GetName() + - "], Channel [" + sChanName + "]!"; - CUtils::PrintError(sError); + if (!pSubConf->empty()) { + sError = "Unhandled lines in config for User [" + + m_pUser->GetUserName() + "], Network [" + GetName() + + "], Channel [" + sChanName + "]!"; + CUtils::PrintError(sError); - CZNC::DumpConfig(pSubConf); - delete pChan; - return false; - } + CZNC::DumpConfig(pSubConf); + delete pChan; + return false; + } - // Save the channel name, because AddChan - // deletes the CChannel*, if adding fails - sError = pChan->GetName(); - if (!AddChan(pChan)) { - sError = "Channel [" + sError + "] defined more than once"; - CUtils::PrintError(sError); - return false; - } - sError.clear(); - } + // Save the channel name, because AddChan + // deletes the CChannel*, if adding fails + sError = pChan->GetName(); + if (!AddChan(pChan)) { + sError = "Channel [" + sError + "] defined more than once"; + CUtils::PrintError(sError); + return false; + } + sError.clear(); + } - return true; + return true; } CConfig CIRCNetwork::ToConfig() const { - CConfig config; + CConfig config; - if (!m_sNick.empty()) { - config.AddKeyValuePair("Nick", m_sNick); - } + if (!m_sNick.empty()) { + config.AddKeyValuePair("Nick", m_sNick); + } - if (!m_sAltNick.empty()) { - config.AddKeyValuePair("AltNick", m_sAltNick); - } + if (!m_sAltNick.empty()) { + config.AddKeyValuePair("AltNick", m_sAltNick); + } - if (!m_sIdent.empty()) { - config.AddKeyValuePair("Ident", m_sIdent); - } + if (!m_sIdent.empty()) { + config.AddKeyValuePair("Ident", m_sIdent); + } - if (!m_sRealName.empty()) { - config.AddKeyValuePair("RealName", m_sRealName); - } - if (!m_sBindHost.empty()) { - config.AddKeyValuePair("BindHost", m_sBindHost); - } + if (!m_sRealName.empty()) { + config.AddKeyValuePair("RealName", m_sRealName); + } + if (!m_sBindHost.empty()) { + config.AddKeyValuePair("BindHost", m_sBindHost); + } - config.AddKeyValuePair("IRCConnectEnabled", - CString(GetIRCConnectEnabled())); - config.AddKeyValuePair("FloodRate", CString(GetFloodRate())); - config.AddKeyValuePair("FloodBurst", CString(GetFloodBurst())); - config.AddKeyValuePair("JoinDelay", CString(GetJoinDelay())); - config.AddKeyValuePair("Encoding", m_sEncoding); + config.AddKeyValuePair("IRCConnectEnabled", + CString(GetIRCConnectEnabled())); + config.AddKeyValuePair("FloodRate", CString(GetFloodRate())); + config.AddKeyValuePair("FloodBurst", CString(GetFloodBurst())); + config.AddKeyValuePair("JoinDelay", CString(GetJoinDelay())); + config.AddKeyValuePair("Encoding", m_sEncoding); - if (!m_sQuitMsg.empty()) { - config.AddKeyValuePair("QuitMsg", m_sQuitMsg); - } + if (!m_sQuitMsg.empty()) { + config.AddKeyValuePair("QuitMsg", m_sQuitMsg); + } - // Modules - const CModules& Mods = GetModules(); + // Modules + const CModules& Mods = GetModules(); - if (!Mods.empty()) { - for (CModule* pMod : Mods) { - CString sArgs = pMod->GetArgs(); + if (!Mods.empty()) { + for (CModule* pMod : Mods) { + CString sArgs = pMod->GetArgs(); - if (!sArgs.empty()) { - sArgs = " " + sArgs; - } + if (!sArgs.empty()) { + sArgs = " " + sArgs; + } - config.AddKeyValuePair("LoadModule", pMod->GetModName() + sArgs); - } - } + config.AddKeyValuePair("LoadModule", pMod->GetModName() + sArgs); + } + } - // Servers - for (CServer* pServer : m_vServers) { - config.AddKeyValuePair("Server", pServer->GetString()); - } + // Servers + for (CServer* pServer : m_vServers) { + config.AddKeyValuePair("Server", pServer->GetString()); + } - for (const CString& sFP : m_ssTrustedFingerprints) { - config.AddKeyValuePair("TrustedServerFingerprint", sFP); - } + for (const CString& sFP : m_ssTrustedFingerprints) { + config.AddKeyValuePair("TrustedServerFingerprint", sFP); + } - // Chans - for (CChan* pChan : m_vChans) { - if (pChan->InConfig()) { - config.AddSubConfig("Chan", pChan->GetName(), pChan->ToConfig()); - } - } + // Chans + for (CChan* pChan : m_vChans) { + if (pChan->InConfig()) { + config.AddSubConfig("Chan", pChan->GetName(), pChan->ToConfig()); + } + } - return config; + return config; } void CIRCNetwork::BounceAllClients() { - for (CClient* pClient : m_vClients) { - pClient->BouncedOff(); - } + for (CClient* pClient : m_vClients) { + pClient->BouncedOff(); + } - m_vClients.clear(); + m_vClients.clear(); } bool CIRCNetwork::IsUserOnline() const { - for (CClient* pClient : m_vClients) { - if (!pClient->IsAway()) { - return true; - } - } + for (CClient* pClient : m_vClients) { + if (!pClient->IsAway()) { + return true; + } + } - return false; + return false; } void CIRCNetwork::ClientConnected(CClient* pClient) { - if (!m_pUser->MultiClients()) { - BounceAllClients(); - } + if (!m_pUser->MultiClients()) { + BounceAllClients(); + } - m_vClients.push_back(pClient); + m_vClients.push_back(pClient); - size_t uIdx, uSize; + size_t uIdx, uSize; - if (m_pIRCSock) { - pClient->NotifyServerDependentCaps(m_pIRCSock->GetAcceptedCaps()); - } + if (m_pIRCSock) { + pClient->NotifyServerDependentCaps(m_pIRCSock->GetAcceptedCaps()); + } - pClient->SetPlaybackActive(true); + pClient->SetPlaybackActive(true); - if (m_RawBuffer.IsEmpty()) { - pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + - " :- Welcome to ZNC -"); - } else { - const CString& sClientNick = pClient->GetNick(false); - MCString msParams; - msParams["target"] = sClientNick; + if (m_RawBuffer.IsEmpty()) { + pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + + " :- Welcome to ZNC -"); + } else { + const CString& sClientNick = pClient->GetNick(false); + MCString msParams; + msParams["target"] = sClientNick; - uSize = m_RawBuffer.Size(); - for (uIdx = 0; uIdx < uSize; uIdx++) { - pClient->PutClient(m_RawBuffer.GetLine(uIdx, *pClient, msParams)); - } + uSize = m_RawBuffer.Size(); + for (uIdx = 0; uIdx < uSize; uIdx++) { + pClient->PutClient(m_RawBuffer.GetLine(uIdx, *pClient, msParams)); + } - const CNick& Nick = GetIRCNick(); - if (sClientNick != Nick.GetNick()) { // case-sensitive match - pClient->PutClient(":" + sClientNick + "!" + Nick.GetIdent() + "@" + - Nick.GetHost() + " NICK :" + Nick.GetNick()); - pClient->SetNick(Nick.GetNick()); - } - } + const CNick& Nick = GetIRCNick(); + if (sClientNick != Nick.GetNick()) { // case-sensitive match + pClient->PutClient(":" + sClientNick + "!" + Nick.GetIdent() + "@" + + Nick.GetHost() + " NICK :" + Nick.GetNick()); + pClient->SetNick(Nick.GetNick()); + } + } - MCString msParams; - msParams["target"] = GetIRCNick().GetNick(); + MCString msParams; + msParams["target"] = GetIRCNick().GetNick(); - // Send the cached MOTD - uSize = m_MotdBuffer.Size(); - if (uSize > 0) { - for (uIdx = 0; uIdx < uSize; uIdx++) { - pClient->PutClient(m_MotdBuffer.GetLine(uIdx, *pClient, msParams)); - } - } + // Send the cached MOTD + uSize = m_MotdBuffer.Size(); + if (uSize > 0) { + for (uIdx = 0; uIdx < uSize; uIdx++) { + pClient->PutClient(m_MotdBuffer.GetLine(uIdx, *pClient, msParams)); + } + } - if (GetIRCSock() != nullptr) { - CString sUserMode(""); - const set& scUserModes = GetIRCSock()->GetUserModes(); - for (unsigned char cMode : scUserModes) { - sUserMode += cMode; - } - if (!sUserMode.empty()) { - pClient->PutClient(":" + GetIRCNick().GetNickMask() + " MODE " + - GetIRCNick().GetNick() + " :+" + sUserMode); - } - } + if (GetIRCSock() != nullptr) { + CString sUserMode(""); + const set& scUserModes = GetIRCSock()->GetUserModes(); + for (unsigned char cMode : scUserModes) { + sUserMode += cMode; + } + if (!sUserMode.empty()) { + pClient->PutClient(":" + GetIRCNick().GetNickMask() + " MODE " + + GetIRCNick().GetNick() + " :+" + sUserMode); + } + } - if (m_bIRCAway) { - // If they want to know their away reason they'll have to whois - // themselves. At least we can tell them their away status... - pClient->PutClient(":irc.znc.in 306 " + GetIRCNick().GetNick() + - " :You have been marked as being away"); - } + if (m_bIRCAway) { + // If they want to know their away reason they'll have to whois + // themselves. At least we can tell them their away status... + pClient->PutClient(":irc.znc.in 306 " + GetIRCNick().GetNick() + + " :You have been marked as being away"); + } - const vector& vChans = GetChans(); - for (CChan* pChan : vChans) { - if ((pChan->IsOn()) && (!pChan->IsDetached())) { - pChan->AttachUser(pClient); - } - } + const vector& vChans = GetChans(); + for (CChan* pChan : vChans) { + if ((pChan->IsOn()) && (!pChan->IsDetached())) { + pChan->AttachUser(pClient); + } + } - bool bClearQuery = m_pUser->AutoClearQueryBuffer(); - for (CQuery* pQuery : m_vQueries) { - pQuery->SendBuffer(pClient); - if (bClearQuery) { - delete pQuery; - } - } - if (bClearQuery) { - m_vQueries.clear(); - } + bool bClearQuery = m_pUser->AutoClearQueryBuffer(); + for (CQuery* pQuery : m_vQueries) { + pQuery->SendBuffer(pClient); + if (bClearQuery) { + delete pQuery; + } + } + if (bClearQuery) { + m_vQueries.clear(); + } - uSize = m_NoticeBuffer.Size(); - for (uIdx = 0; uIdx < uSize; uIdx++) { - const CBufLine& BufLine = m_NoticeBuffer.GetBufLine(uIdx); - CMessage Message(BufLine.GetLine(*pClient, msParams)); - Message.SetNetwork(this); - Message.SetClient(pClient); - Message.SetTime(BufLine.GetTime()); - Message.SetTags(BufLine.GetTags()); - bool bContinue = false; - NETWORKMODULECALL(OnPrivBufferPlayMessage(Message), m_pUser, this, - nullptr, &bContinue); - if (bContinue) continue; - pClient->PutClient(Message); - } - m_NoticeBuffer.Clear(); + uSize = m_NoticeBuffer.Size(); + for (uIdx = 0; uIdx < uSize; uIdx++) { + const CBufLine& BufLine = m_NoticeBuffer.GetBufLine(uIdx); + CMessage Message(BufLine.GetLine(*pClient, msParams)); + Message.SetNetwork(this); + Message.SetClient(pClient); + Message.SetTime(BufLine.GetTime()); + Message.SetTags(BufLine.GetTags()); + bool bContinue = false; + NETWORKMODULECALL(OnPrivBufferPlayMessage(Message), m_pUser, this, + nullptr, &bContinue); + if (bContinue) continue; + pClient->PutClient(Message); + } + m_NoticeBuffer.Clear(); - pClient->SetPlaybackActive(false); + pClient->SetPlaybackActive(false); - // Tell them why they won't connect - if (!GetIRCConnectEnabled()) - pClient->PutStatus( - "You are currently disconnected from IRC. " - "Use 'connect' to reconnect."); + // Tell them why they won't connect + if (!GetIRCConnectEnabled()) + pClient->PutStatus( + "You are currently disconnected from IRC. " + "Use 'connect' to reconnect."); } void CIRCNetwork::ClientDisconnected(CClient* pClient) { - auto it = std::find(m_vClients.begin(), m_vClients.end(), pClient); - if (it != m_vClients.end()) { - m_vClients.erase(it); - } - pClient->ClearServerDependentCaps(); + auto it = std::find(m_vClients.begin(), m_vClients.end(), pClient); + if (it != m_vClients.end()) { + m_vClients.erase(it); + } + pClient->ClearServerDependentCaps(); } CUser* CIRCNetwork::GetUser() const { return m_pUser; } @@ -729,106 +729,106 @@ const CString& CIRCNetwork::GetName() const { return m_sName; } std::vector CIRCNetwork::FindClients( const CString& sIdentifier) const { - std::vector vClients; - for (CClient* pClient : m_vClients) { - if (pClient->GetIdentifier().Equals(sIdentifier)) { - vClients.push_back(pClient); - } - } + std::vector vClients; + for (CClient* pClient : m_vClients) { + if (pClient->GetIdentifier().Equals(sIdentifier)) { + vClients.push_back(pClient); + } + } - return vClients; + return vClients; } void CIRCNetwork::SetUser(CUser* pUser) { - for (CClient* pClient : m_vClients) { - pClient->PutStatus( - "This network is being deleted or moved to another user."); - pClient->SetNetwork(nullptr); - } + for (CClient* pClient : m_vClients) { + pClient->PutStatus( + "This network is being deleted or moved to another user."); + pClient->SetNetwork(nullptr); + } - m_vClients.clear(); + m_vClients.clear(); - if (m_pUser) { - m_pUser->RemoveNetwork(this); - } + if (m_pUser) { + m_pUser->RemoveNetwork(this); + } - m_pUser = pUser; - if (m_pUser) { - m_pUser->AddNetwork(this); - } + m_pUser = pUser; + if (m_pUser) { + m_pUser->AddNetwork(this); + } } bool CIRCNetwork::SetName(const CString& sName) { - if (IsValidNetwork(sName)) { - m_sName = sName; - return true; - } + if (IsValidNetwork(sName)) { + m_sName = sName; + return true; + } - return false; + return false; } bool CIRCNetwork::PutUser(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutClient(sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutClient(sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CIRCNetwork::PutUser(const CMessage& Message, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutClient(Message); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutClient(Message); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CIRCNetwork::PutStatus(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutStatus(sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutStatus(sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CIRCNetwork::PutModule(const CString& sModule, const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutModule(sModule, sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutModule(sModule, sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } // Channels @@ -836,161 +836,161 @@ bool CIRCNetwork::PutModule(const CString& sModule, const CString& sLine, const vector& CIRCNetwork::GetChans() const { return m_vChans; } CChan* CIRCNetwork::FindChan(CString sName) const { - if (GetIRCSock()) { - // See - // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-3.16 - sName.TrimLeft(GetIRCSock()->GetISupport("STATUSMSG", "")); - } + if (GetIRCSock()) { + // See + // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-3.16 + sName.TrimLeft(GetIRCSock()->GetISupport("STATUSMSG", "")); + } - for (CChan* pChan : m_vChans) { - if (sName.Equals(pChan->GetName())) { - return pChan; - } - } + for (CChan* pChan : m_vChans) { + if (sName.Equals(pChan->GetName())) { + return pChan; + } + } - return nullptr; + return nullptr; } std::vector CIRCNetwork::FindChans(const CString& sWild) const { - std::vector vChans; - vChans.reserve(m_vChans.size()); - const CString sLower = sWild.AsLower(); - for (CChan* pChan : m_vChans) { - if (pChan->GetName().AsLower().WildCmp(sLower)) vChans.push_back(pChan); - } - return vChans; + std::vector vChans; + vChans.reserve(m_vChans.size()); + const CString sLower = sWild.AsLower(); + for (CChan* pChan : m_vChans) { + if (pChan->GetName().AsLower().WildCmp(sLower)) vChans.push_back(pChan); + } + return vChans; } bool CIRCNetwork::AddChan(CChan* pChan) { - if (!pChan) { - return false; - } + if (!pChan) { + return false; + } - for (CChan* pEachChan : m_vChans) { - if (pEachChan->GetName().Equals(pChan->GetName())) { - delete pChan; - return false; - } - } + for (CChan* pEachChan : m_vChans) { + if (pEachChan->GetName().Equals(pChan->GetName())) { + delete pChan; + return false; + } + } - m_vChans.push_back(pChan); - return true; + m_vChans.push_back(pChan); + return true; } bool CIRCNetwork::AddChan(const CString& sName, bool bInConfig) { - if (sName.empty() || FindChan(sName)) { - return false; - } + if (sName.empty() || FindChan(sName)) { + return false; + } - CChan* pChan = new CChan(sName, this, bInConfig); - m_vChans.push_back(pChan); - return true; + CChan* pChan = new CChan(sName, this, bInConfig); + m_vChans.push_back(pChan); + return true; } bool CIRCNetwork::DelChan(const CString& sName) { - for (vector::iterator a = m_vChans.begin(); a != m_vChans.end(); - ++a) { - if (sName.Equals((*a)->GetName())) { - delete *a; - m_vChans.erase(a); - return true; - } - } + for (vector::iterator a = m_vChans.begin(); a != m_vChans.end(); + ++a) { + if (sName.Equals((*a)->GetName())) { + delete *a; + m_vChans.erase(a); + return true; + } + } - return false; + return false; } void CIRCNetwork::JoinChans() { - // Avoid divsion by zero, it's bad! - if (m_vChans.empty()) return; + // Avoid divsion by zero, it's bad! + if (m_vChans.empty()) return; - // We start at a random offset into the channel list so that if your - // first 3 channels are invite-only and you got MaxJoins == 3, ZNC will - // still be able to join the rest of your channels. - unsigned int start = rand() % m_vChans.size(); - unsigned int uJoins = m_pUser->MaxJoins(); - set sChans; - for (unsigned int a = 0; a < m_vChans.size(); a++) { - unsigned int idx = (start + a) % m_vChans.size(); - CChan* pChan = m_vChans[idx]; - if (!pChan->IsOn() && !pChan->IsDisabled()) { - if (!JoinChan(pChan)) continue; + // We start at a random offset into the channel list so that if your + // first 3 channels are invite-only and you got MaxJoins == 3, ZNC will + // still be able to join the rest of your channels. + unsigned int start = rand() % m_vChans.size(); + unsigned int uJoins = m_pUser->MaxJoins(); + set sChans; + for (unsigned int a = 0; a < m_vChans.size(); a++) { + unsigned int idx = (start + a) % m_vChans.size(); + CChan* pChan = m_vChans[idx]; + if (!pChan->IsOn() && !pChan->IsDisabled()) { + if (!JoinChan(pChan)) continue; - sChans.insert(pChan); + sChans.insert(pChan); - // Limit the number of joins - if (uJoins != 0 && --uJoins == 0) { - // Reset the timer. - m_pJoinTimer->Reset(); - break; - } - } - } + // Limit the number of joins + if (uJoins != 0 && --uJoins == 0) { + // Reset the timer. + m_pJoinTimer->Reset(); + break; + } + } + } - while (!sChans.empty()) JoinChans(sChans); + while (!sChans.empty()) JoinChans(sChans); } void CIRCNetwork::JoinChans(set& sChans) { - CString sKeys, sJoin; - bool bHaveKey = false; - size_t uiJoinLength = strlen("JOIN "); + CString sKeys, sJoin; + bool bHaveKey = false; + size_t uiJoinLength = strlen("JOIN "); - while (!sChans.empty()) { - set::iterator it = sChans.begin(); - const CString& sName = (*it)->GetName(); - const CString& sKey = (*it)->GetKey(); - size_t len = sName.length() + sKey.length(); - len += 2; // two comma + while (!sChans.empty()) { + set::iterator it = sChans.begin(); + const CString& sName = (*it)->GetName(); + const CString& sKey = (*it)->GetKey(); + size_t len = sName.length() + sKey.length(); + len += 2; // two comma - if (!sKeys.empty() && uiJoinLength + len >= 512) break; + if (!sKeys.empty() && uiJoinLength + len >= 512) break; - if (!sJoin.empty()) { - sJoin += ","; - sKeys += ","; - } - uiJoinLength += len; - sJoin += sName; - if (!sKey.empty()) { - sKeys += sKey; - bHaveKey = true; - } - sChans.erase(it); - } + if (!sJoin.empty()) { + sJoin += ","; + sKeys += ","; + } + uiJoinLength += len; + sJoin += sName; + if (!sKey.empty()) { + sKeys += sKey; + bHaveKey = true; + } + sChans.erase(it); + } - if (bHaveKey) - PutIRC("JOIN " + sJoin + " " + sKeys); - else - PutIRC("JOIN " + sJoin); + if (bHaveKey) + PutIRC("JOIN " + sJoin + " " + sKeys); + else + PutIRC("JOIN " + sJoin); } bool CIRCNetwork::JoinChan(CChan* pChan) { - bool bReturn = false; - NETWORKMODULECALL(OnJoining(*pChan), m_pUser, this, nullptr, &bReturn); + bool bReturn = false; + NETWORKMODULECALL(OnJoining(*pChan), m_pUser, this, nullptr, &bReturn); - if (bReturn) return false; + if (bReturn) return false; - if (m_pUser->JoinTries() != 0 && - pChan->GetJoinTries() >= m_pUser->JoinTries()) { - PutStatus("The channel " + pChan->GetName() + - " could not be joined, disabling it."); - pChan->Disable(); - } else { - pChan->IncJoinTries(); - bool bFailed = false; - NETWORKMODULECALL(OnTimerAutoJoin(*pChan), m_pUser, this, nullptr, - &bFailed); - if (bFailed) return false; - return true; - } - return false; + if (m_pUser->JoinTries() != 0 && + pChan->GetJoinTries() >= m_pUser->JoinTries()) { + PutStatus("The channel " + pChan->GetName() + + " could not be joined, disabling it."); + pChan->Disable(); + } else { + pChan->IncJoinTries(); + bool bFailed = false; + NETWORKMODULECALL(OnTimerAutoJoin(*pChan), m_pUser, this, nullptr, + &bFailed); + if (bFailed) return false; + return true; + } + return false; } bool CIRCNetwork::IsChan(const CString& sChan) const { - if (sChan.empty()) return false; // There is no way this is a chan - if (GetChanPrefixes().empty()) - return true; // We can't know, so we allow everything - // Thanks to the above if (empty), we can do sChan[0] - return GetChanPrefixes().find(sChan[0]) != CString::npos; + if (sChan.empty()) return false; // There is no way this is a chan + if (GetChanPrefixes().empty()) + return true; // We can't know, so we allow everything + // Thanks to the above if (empty), we can do sChan[0] + return GetChanPrefixes().find(sChan[0]) != CString::npos; } // Queries @@ -998,58 +998,58 @@ bool CIRCNetwork::IsChan(const CString& sChan) const { const vector& CIRCNetwork::GetQueries() const { return m_vQueries; } CQuery* CIRCNetwork::FindQuery(const CString& sName) const { - for (CQuery* pQuery : m_vQueries) { - if (sName.Equals(pQuery->GetName())) { - return pQuery; - } - } + for (CQuery* pQuery : m_vQueries) { + if (sName.Equals(pQuery->GetName())) { + return pQuery; + } + } - return nullptr; + return nullptr; } std::vector CIRCNetwork::FindQueries(const CString& sWild) const { - std::vector vQueries; - vQueries.reserve(m_vQueries.size()); - const CString sLower = sWild.AsLower(); - for (CQuery* pQuery : m_vQueries) { - if (pQuery->GetName().AsLower().WildCmp(sLower)) - vQueries.push_back(pQuery); - } - return vQueries; + std::vector vQueries; + vQueries.reserve(m_vQueries.size()); + const CString sLower = sWild.AsLower(); + for (CQuery* pQuery : m_vQueries) { + if (pQuery->GetName().AsLower().WildCmp(sLower)) + vQueries.push_back(pQuery); + } + return vQueries; } CQuery* CIRCNetwork::AddQuery(const CString& sName) { - if (sName.empty()) { - return nullptr; - } + if (sName.empty()) { + return nullptr; + } - CQuery* pQuery = FindQuery(sName); - if (!pQuery) { - pQuery = new CQuery(sName, this); - m_vQueries.push_back(pQuery); + CQuery* pQuery = FindQuery(sName); + if (!pQuery) { + pQuery = new CQuery(sName, this); + m_vQueries.push_back(pQuery); - if (m_pUser->MaxQueryBuffers() > 0) { - while (m_vQueries.size() > m_pUser->MaxQueryBuffers()) { - delete *m_vQueries.begin(); - m_vQueries.erase(m_vQueries.begin()); - } - } - } + if (m_pUser->MaxQueryBuffers() > 0) { + while (m_vQueries.size() > m_pUser->MaxQueryBuffers()) { + delete *m_vQueries.begin(); + m_vQueries.erase(m_vQueries.begin()); + } + } + } - return pQuery; + return pQuery; } bool CIRCNetwork::DelQuery(const CString& sName) { - for (vector::iterator a = m_vQueries.begin(); - a != m_vQueries.end(); ++a) { - if (sName.Equals((*a)->GetName())) { - delete *a; - m_vQueries.erase(a); - return true; - } - } + for (vector::iterator a = m_vQueries.begin(); + a != m_vQueries.end(); ++a) { + if (sName.Equals((*a)->GetName())) { + delete *a; + m_vQueries.erase(a); + return true; + } + } - return false; + return false; } // Server list @@ -1057,443 +1057,443 @@ bool CIRCNetwork::DelQuery(const CString& sName) { const vector& CIRCNetwork::GetServers() const { return m_vServers; } CServer* CIRCNetwork::FindServer(const CString& sName) const { - for (CServer* pServer : m_vServers) { - if (sName.Equals(pServer->GetName())) { - return pServer; - } - } + for (CServer* pServer : m_vServers) { + if (sName.Equals(pServer->GetName())) { + return pServer; + } + } - return nullptr; + return nullptr; } bool CIRCNetwork::DelServer(const CString& sName, unsigned short uPort, const CString& sPass) { - if (sName.empty()) { - return false; - } + if (sName.empty()) { + return false; + } - unsigned int a = 0; - bool bSawCurrentServer = false; - CServer* pCurServer = GetCurrentServer(); + unsigned int a = 0; + bool bSawCurrentServer = false; + CServer* pCurServer = GetCurrentServer(); - for (vector::iterator it = m_vServers.begin(); - it != m_vServers.end(); ++it, a++) { - CServer* pServer = *it; + for (vector::iterator it = m_vServers.begin(); + it != m_vServers.end(); ++it, a++) { + CServer* pServer = *it; - if (pServer == pCurServer) bSawCurrentServer = true; + if (pServer == pCurServer) bSawCurrentServer = true; - if (!pServer->GetName().Equals(sName)) continue; + if (!pServer->GetName().Equals(sName)) continue; - if (uPort != 0 && pServer->GetPort() != uPort) continue; + if (uPort != 0 && pServer->GetPort() != uPort) continue; - if (!sPass.empty() && pServer->GetPass() != sPass) continue; + if (!sPass.empty() && pServer->GetPass() != sPass) continue; - m_vServers.erase(it); + m_vServers.erase(it); - if (pServer == pCurServer) { - CIRCSock* pIRCSock = GetIRCSock(); + if (pServer == pCurServer) { + CIRCSock* pIRCSock = GetIRCSock(); - // Make sure we don't skip the next server in the list! - if (m_uServerIdx) { - m_uServerIdx--; - } + // Make sure we don't skip the next server in the list! + if (m_uServerIdx) { + m_uServerIdx--; + } - if (pIRCSock) { - pIRCSock->Quit(); - PutStatus("Your current server was removed, jumping..."); - } - } else if (!bSawCurrentServer) { - // Our current server comes after the server which we - // are removing. This means that it now got a different - // index in m_vServers! - m_uServerIdx--; - } + if (pIRCSock) { + pIRCSock->Quit(); + PutStatus("Your current server was removed, jumping..."); + } + } else if (!bSawCurrentServer) { + // Our current server comes after the server which we + // are removing. This means that it now got a different + // index in m_vServers! + m_uServerIdx--; + } - delete pServer; + delete pServer; - return true; - } + return true; + } - return false; + return false; } bool CIRCNetwork::AddServer(const CString& sName) { - if (sName.empty()) { - return false; - } + if (sName.empty()) { + return false; + } - bool bSSL = false; - CString sLine = sName; - sLine.Trim(); + bool bSSL = false; + CString sLine = sName; + sLine.Trim(); - CString sHost = sLine.Token(0); - CString sPort = sLine.Token(1); + CString sHost = sLine.Token(0); + CString sPort = sLine.Token(1); - if (sPort.TrimPrefix("+")) { - bSSL = true; - } + if (sPort.TrimPrefix("+")) { + bSSL = true; + } - unsigned short uPort = sPort.ToUShort(); - CString sPass = sLine.Token(2, true); + unsigned short uPort = sPort.ToUShort(); + CString sPass = sLine.Token(2, true); - return AddServer(sHost, uPort, sPass, bSSL); + return AddServer(sHost, uPort, sPass, bSSL); } bool CIRCNetwork::AddServer(const CString& sName, unsigned short uPort, const CString& sPass, bool bSSL) { #ifndef HAVE_LIBSSL - if (bSSL) { - return false; - } + if (bSSL) { + return false; + } #endif - if (sName.empty()) { - return false; - } + if (sName.empty()) { + return false; + } - if (!uPort) { - uPort = 6667; - } + if (!uPort) { + uPort = 6667; + } - // Check if server is already added - for (CServer* pServer : m_vServers) { - if (!sName.Equals(pServer->GetName())) continue; + // Check if server is already added + for (CServer* pServer : m_vServers) { + if (!sName.Equals(pServer->GetName())) continue; - if (uPort != pServer->GetPort()) continue; + if (uPort != pServer->GetPort()) continue; - if (sPass != pServer->GetPass()) continue; + if (sPass != pServer->GetPass()) continue; - if (bSSL != pServer->IsSSL()) continue; + if (bSSL != pServer->IsSSL()) continue; - // Server is already added - return false; - } + // Server is already added + return false; + } - CServer* pServer = new CServer(sName, uPort, sPass, bSSL); - m_vServers.push_back(pServer); + CServer* pServer = new CServer(sName, uPort, sPass, bSSL); + m_vServers.push_back(pServer); - CheckIRCConnect(); + CheckIRCConnect(); - return true; + return true; } CServer* CIRCNetwork::GetNextServer(bool bAdvance) { - if (m_vServers.empty()) { - return nullptr; - } + if (m_vServers.empty()) { + return nullptr; + } - if (m_uServerIdx >= m_vServers.size()) { - m_uServerIdx = 0; - } + if (m_uServerIdx >= m_vServers.size()) { + m_uServerIdx = 0; + } - if (bAdvance) { - return m_vServers[m_uServerIdx++]; - } else { - return m_vServers[m_uServerIdx]; - } + if (bAdvance) { + return m_vServers[m_uServerIdx++]; + } else { + return m_vServers[m_uServerIdx]; + } } CServer* CIRCNetwork::GetCurrentServer() const { - size_t uIdx = (m_uServerIdx) ? m_uServerIdx - 1 : 0; + size_t uIdx = (m_uServerIdx) ? m_uServerIdx - 1 : 0; - if (uIdx >= m_vServers.size()) { - return nullptr; - } + if (uIdx >= m_vServers.size()) { + return nullptr; + } - return m_vServers[uIdx]; + return m_vServers[uIdx]; } void CIRCNetwork::SetIRCServer(const CString& s) { m_sIRCServer = s; } bool CIRCNetwork::SetNextServer(const CServer* pServer) { - for (unsigned int a = 0; a < m_vServers.size(); a++) { - if (m_vServers[a] == pServer) { - m_uServerIdx = a; - return true; - } - } + for (unsigned int a = 0; a < m_vServers.size(); a++) { + if (m_vServers[a] == pServer) { + m_uServerIdx = a; + return true; + } + } - return false; + return false; } bool CIRCNetwork::IsLastServer() const { - return (m_uServerIdx >= m_vServers.size()); + return (m_uServerIdx >= m_vServers.size()); } const CString& CIRCNetwork::GetIRCServer() const { return m_sIRCServer; } const CNick& CIRCNetwork::GetIRCNick() const { return m_IRCNick; } void CIRCNetwork::SetIRCNick(const CNick& n) { - m_IRCNick = n; + m_IRCNick = n; - for (CClient* pClient : m_vClients) { - pClient->SetNick(n.GetNick()); - } + for (CClient* pClient : m_vClients) { + pClient->SetNick(n.GetNick()); + } } CString CIRCNetwork::GetCurNick() const { - const CIRCSock* pIRCSock = GetIRCSock(); + const CIRCSock* pIRCSock = GetIRCSock(); - if (pIRCSock) { - return pIRCSock->GetNick(); - } + if (pIRCSock) { + return pIRCSock->GetNick(); + } - if (!m_vClients.empty()) { - return m_vClients[0]->GetNick(); - } + if (!m_vClients.empty()) { + return m_vClients[0]->GetNick(); + } - return ""; + return ""; } bool CIRCNetwork::Connect() { - if (!GetIRCConnectEnabled() || m_pIRCSock || !HasServers()) return false; + if (!GetIRCConnectEnabled() || m_pIRCSock || !HasServers()) return false; - CServer* pServer = GetNextServer(); - if (!pServer) return false; + CServer* pServer = GetNextServer(); + if (!pServer) return false; - if (CZNC::Get().GetServerThrottle(pServer->GetName())) { - // Can't connect right now, schedule retry later - CZNC::Get().AddNetworkToQueue(this); - return false; - } + if (CZNC::Get().GetServerThrottle(pServer->GetName())) { + // Can't connect right now, schedule retry later + CZNC::Get().AddNetworkToQueue(this); + return false; + } - CZNC::Get().AddServerThrottle(pServer->GetName()); + CZNC::Get().AddServerThrottle(pServer->GetName()); - bool bSSL = pServer->IsSSL(); + bool bSSL = pServer->IsSSL(); #ifndef HAVE_LIBSSL - if (bSSL) { - PutStatus("Cannot connect to [" + pServer->GetString(false) + - "], ZNC is not compiled with SSL."); - CZNC::Get().AddNetworkToQueue(this); - return false; - } + if (bSSL) { + PutStatus("Cannot connect to [" + pServer->GetString(false) + + "], ZNC is not compiled with SSL."); + CZNC::Get().AddNetworkToQueue(this); + return false; + } #endif - CIRCSock* pIRCSock = new CIRCSock(this); - pIRCSock->SetPass(pServer->GetPass()); - pIRCSock->SetSSLTrustedPeerFingerprints(m_ssTrustedFingerprints); + CIRCSock* pIRCSock = new CIRCSock(this); + pIRCSock->SetPass(pServer->GetPass()); + pIRCSock->SetSSLTrustedPeerFingerprints(m_ssTrustedFingerprints); - DEBUG("Connecting user/network [" << m_pUser->GetUserName() << "/" - << m_sName << "]"); + DEBUG("Connecting user/network [" << m_pUser->GetUserName() << "/" + << m_sName << "]"); - bool bAbort = false; - NETWORKMODULECALL(OnIRCConnecting(pIRCSock), m_pUser, this, nullptr, - &bAbort); - if (bAbort) { - DEBUG("Some module aborted the connection attempt"); - PutStatus("Some module aborted the connection attempt"); - delete pIRCSock; - CZNC::Get().AddNetworkToQueue(this); - return false; - } + bool bAbort = false; + NETWORKMODULECALL(OnIRCConnecting(pIRCSock), m_pUser, this, nullptr, + &bAbort); + if (bAbort) { + DEBUG("Some module aborted the connection attempt"); + PutStatus("Some module aborted the connection attempt"); + delete pIRCSock; + CZNC::Get().AddNetworkToQueue(this); + return false; + } - CString sSockName = "IRC::" + m_pUser->GetUserName() + "::" + m_sName; - CZNC::Get().GetManager().Connect(pServer->GetName(), pServer->GetPort(), - sSockName, 120, bSSL, GetBindHost(), - pIRCSock); + CString sSockName = "IRC::" + m_pUser->GetUserName() + "::" + m_sName; + CZNC::Get().GetManager().Connect(pServer->GetName(), pServer->GetPort(), + sSockName, 120, bSSL, GetBindHost(), + pIRCSock); - return true; + return true; } bool CIRCNetwork::IsIRCConnected() const { - const CIRCSock* pSock = GetIRCSock(); - return (pSock && pSock->IsAuthed()); + const CIRCSock* pSock = GetIRCSock(); + return (pSock && pSock->IsAuthed()); } void CIRCNetwork::SetIRCSocket(CIRCSock* pIRCSock) { m_pIRCSock = pIRCSock; } void CIRCNetwork::IRCConnected() { - const SCString& ssCaps = m_pIRCSock->GetAcceptedCaps(); - for (CClient* pClient : m_vClients) { - pClient->NotifyServerDependentCaps(ssCaps); - } - if (m_uJoinDelay > 0) { - m_pJoinTimer->Delay(m_uJoinDelay); - } else { - JoinChans(); - } + const SCString& ssCaps = m_pIRCSock->GetAcceptedCaps(); + for (CClient* pClient : m_vClients) { + pClient->NotifyServerDependentCaps(ssCaps); + } + if (m_uJoinDelay > 0) { + m_pJoinTimer->Delay(m_uJoinDelay); + } else { + JoinChans(); + } } void CIRCNetwork::IRCDisconnected() { - for (CClient* pClient : m_vClients) { - pClient->ClearServerDependentCaps(); - } - m_pIRCSock = nullptr; + for (CClient* pClient : m_vClients) { + pClient->ClearServerDependentCaps(); + } + m_pIRCSock = nullptr; - SetIRCServer(""); - m_bIRCAway = false; + SetIRCServer(""); + m_bIRCAway = false; - // Get the reconnect going - CheckIRCConnect(); + // Get the reconnect going + CheckIRCConnect(); } void CIRCNetwork::SetIRCConnectEnabled(bool b) { - m_bIRCConnectEnabled = b; + m_bIRCConnectEnabled = b; - if (m_bIRCConnectEnabled) { - CheckIRCConnect(); - } else if (GetIRCSock()) { - if (GetIRCSock()->IsConnected()) { - GetIRCSock()->Quit(); - } else { - GetIRCSock()->Close(); - } - } + if (m_bIRCConnectEnabled) { + CheckIRCConnect(); + } else if (GetIRCSock()) { + if (GetIRCSock()->IsConnected()) { + GetIRCSock()->Quit(); + } else { + GetIRCSock()->Close(); + } + } } void CIRCNetwork::CheckIRCConnect() { - // Do we want to connect? - if (GetIRCConnectEnabled() && GetIRCSock() == nullptr) - CZNC::Get().AddNetworkToQueue(this); + // Do we want to connect? + if (GetIRCConnectEnabled() && GetIRCSock() == nullptr) + CZNC::Get().AddNetworkToQueue(this); } bool CIRCNetwork::PutIRC(const CString& sLine) { - CIRCSock* pIRCSock = GetIRCSock(); + CIRCSock* pIRCSock = GetIRCSock(); - if (!pIRCSock) { - return false; - } + if (!pIRCSock) { + return false; + } - pIRCSock->PutIRC(sLine); - return true; + pIRCSock->PutIRC(sLine); + return true; } void CIRCNetwork::ClearQueryBuffer() { - std::for_each(m_vQueries.begin(), m_vQueries.end(), - std::default_delete()); - m_vQueries.clear(); + std::for_each(m_vQueries.begin(), m_vQueries.end(), + std::default_delete()); + m_vQueries.clear(); } const CString& CIRCNetwork::GetNick(const bool bAllowDefault) const { - if (m_sNick.empty()) { - return m_pUser->GetNick(bAllowDefault); - } + if (m_sNick.empty()) { + return m_pUser->GetNick(bAllowDefault); + } - return m_sNick; + return m_sNick; } const CString& CIRCNetwork::GetAltNick(const bool bAllowDefault) const { - if (m_sAltNick.empty()) { - return m_pUser->GetAltNick(bAllowDefault); - } + if (m_sAltNick.empty()) { + return m_pUser->GetAltNick(bAllowDefault); + } - return m_sAltNick; + return m_sAltNick; } const CString& CIRCNetwork::GetIdent(const bool bAllowDefault) const { - if (m_sIdent.empty()) { - return m_pUser->GetIdent(bAllowDefault); - } + if (m_sIdent.empty()) { + return m_pUser->GetIdent(bAllowDefault); + } - return m_sIdent; + return m_sIdent; } CString CIRCNetwork::GetRealName() const { - if (m_sRealName.empty()) { - return m_pUser->GetRealName(); - } + if (m_sRealName.empty()) { + return m_pUser->GetRealName(); + } - return m_sRealName; + return m_sRealName; } const CString& CIRCNetwork::GetBindHost() const { - if (m_sBindHost.empty()) { - return m_pUser->GetBindHost(); - } + if (m_sBindHost.empty()) { + return m_pUser->GetBindHost(); + } - return m_sBindHost; + return m_sBindHost; } const CString& CIRCNetwork::GetEncoding() const { return m_sEncoding; } CString CIRCNetwork::GetQuitMsg() const { - if (m_sQuitMsg.empty()) { - return m_pUser->GetQuitMsg(); - } + if (m_sQuitMsg.empty()) { + return m_pUser->GetQuitMsg(); + } - return m_sQuitMsg; + return m_sQuitMsg; } void CIRCNetwork::SetNick(const CString& s) { - if (m_pUser->GetNick().Equals(s)) { - m_sNick = ""; - } else { - m_sNick = s; - } + if (m_pUser->GetNick().Equals(s)) { + m_sNick = ""; + } else { + m_sNick = s; + } } void CIRCNetwork::SetAltNick(const CString& s) { - if (m_pUser->GetAltNick().Equals(s)) { - m_sAltNick = ""; - } else { - m_sAltNick = s; - } + if (m_pUser->GetAltNick().Equals(s)) { + m_sAltNick = ""; + } else { + m_sAltNick = s; + } } void CIRCNetwork::SetIdent(const CString& s) { - if (m_pUser->GetIdent().Equals(s)) { - m_sIdent = ""; - } else { - m_sIdent = s; - } + if (m_pUser->GetIdent().Equals(s)) { + m_sIdent = ""; + } else { + m_sIdent = s; + } } void CIRCNetwork::SetRealName(const CString& s) { - if (m_pUser->GetRealName().Equals(s)) { - m_sRealName = ""; - } else { - m_sRealName = s; - } + if (m_pUser->GetRealName().Equals(s)) { + m_sRealName = ""; + } else { + m_sRealName = s; + } } void CIRCNetwork::SetBindHost(const CString& s) { - if (m_pUser->GetBindHost().Equals(s)) { - m_sBindHost = ""; - } else { - m_sBindHost = s; - } + if (m_pUser->GetBindHost().Equals(s)) { + m_sBindHost = ""; + } else { + m_sBindHost = s; + } } void CIRCNetwork::SetEncoding(const CString& s) { m_sEncoding = s; } void CIRCNetwork::SetQuitMsg(const CString& s) { - if (m_pUser->GetQuitMsg().Equals(s)) { - m_sQuitMsg = ""; - } else { - m_sQuitMsg = s; - } + if (m_pUser->GetQuitMsg().Equals(s)) { + m_sQuitMsg = ""; + } else { + m_sQuitMsg = s; + } } CString CIRCNetwork::ExpandString(const CString& sStr) const { - CString sRet; - return ExpandString(sStr, sRet); + CString sRet; + return ExpandString(sStr, sRet); } CString& CIRCNetwork::ExpandString(const CString& sStr, CString& sRet) const { - sRet = sStr; + sRet = sStr; - sRet.Replace("%altnick%", GetAltNick()); - sRet.Replace("%bindhost%", GetBindHost()); - sRet.Replace("%defnick%", GetNick()); - sRet.Replace("%ident%", GetIdent()); - sRet.Replace("%network%", GetName()); - sRet.Replace("%nick%", GetCurNick()); - sRet.Replace("%realname%", GetRealName()); + sRet.Replace("%altnick%", GetAltNick()); + sRet.Replace("%bindhost%", GetBindHost()); + sRet.Replace("%defnick%", GetNick()); + sRet.Replace("%ident%", GetIdent()); + sRet.Replace("%network%", GetName()); + sRet.Replace("%nick%", GetCurNick()); + sRet.Replace("%realname%", GetRealName()); - return m_pUser->ExpandString(sRet, sRet); + return m_pUser->ExpandString(sRet, sRet); } bool CIRCNetwork::LoadModule(const CString& sModName, const CString& sArgs, const CString& sNotice, CString& sError) { - CUtils::PrintAction(sNotice); - CString sModRet; + CUtils::PrintAction(sNotice); + CString sModRet; - bool bModRet = GetModules().LoadModule( - sModName, sArgs, CModInfo::NetworkModule, GetUser(), this, sModRet); + bool bModRet = GetModules().LoadModule( + sModName, sArgs, CModInfo::NetworkModule, GetUser(), this, sModRet); - CUtils::PrintStatus(bModRet, sModRet); - if (!bModRet) { - sError = sModRet; - } - return bModRet; + CUtils::PrintStatus(bModRet, sModRet); + if (!bModRet) { + sError = sModRet; + } + return bModRet; } diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index e9c014aa..7875e4ab 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -27,8 +27,8 @@ using std::vector; using std::map; #define IRCSOCKMODULECALL(macFUNC, macEXITER) \ - NETWORKMODULECALL(macFUNC, m_pNetwork->GetUser(), m_pNetwork, nullptr, \ - macEXITER) + NETWORKMODULECALL(macFUNC, m_pNetwork->GetUser(), m_pNetwork, nullptr, \ + macEXITER) // These are used in OnGeneralCTCP() const time_t CIRCSock::m_uCTCPFloodTime = 5; const unsigned int CIRCSock::m_uCTCPFloodCount = 5; @@ -39,24 +39,24 @@ const unsigned int CIRCSock::m_uCTCPFloodCount = 5; static const double FLOOD_MINIMAL_RATE = 0.3; class CIRCFloodTimer : public CCron { - CIRCSock* m_pSock; + CIRCSock* m_pSock; public: - CIRCFloodTimer(CIRCSock* pSock) : m_pSock(pSock) { - StartMaxCycles(m_pSock->m_fFloodRate, 0); - } - CIRCFloodTimer(const CIRCFloodTimer&) = delete; - CIRCFloodTimer& operator=(const CIRCFloodTimer&) = delete; - void RunJob() override { - if (m_pSock->m_iSendsAllowed < m_pSock->m_uFloodBurst) { - m_pSock->m_iSendsAllowed++; - } - m_pSock->TrySend(); - } + CIRCFloodTimer(CIRCSock* pSock) : m_pSock(pSock) { + StartMaxCycles(m_pSock->m_fFloodRate, 0); + } + CIRCFloodTimer(const CIRCFloodTimer&) = delete; + CIRCFloodTimer& operator=(const CIRCFloodTimer&) = delete; + void RunJob() override { + if (m_pSock->m_iSendsAllowed < m_pSock->m_uFloodBurst) { + m_pSock->m_iSendsAllowed++; + } + m_pSock->TrySend(); + } }; bool CIRCSock::IsFloodProtected(double fRate) { - return fRate > FLOOD_MINIMAL_RATE; + return fRate > FLOOD_MINIMAL_RATE; } CIRCSock::CIRCSock(CIRCNetwork* pNetwork) @@ -88,1381 +88,1381 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork) m_uFloodBurst(pNetwork->GetFloodBurst()), m_fFloodRate(pNetwork->GetFloodRate()), m_bFloodProtection(IsFloodProtected(pNetwork->GetFloodRate())) { - EnableReadLine(); - m_Nick.SetIdent(m_pNetwork->GetIdent()); - m_Nick.SetHost(m_pNetwork->GetBindHost()); - SetEncoding(m_pNetwork->GetEncoding()); + EnableReadLine(); + m_Nick.SetIdent(m_pNetwork->GetIdent()); + m_Nick.SetHost(m_pNetwork->GetBindHost()); + SetEncoding(m_pNetwork->GetEncoding()); - m_mueChanModes['b'] = ListArg; - m_mueChanModes['e'] = ListArg; - m_mueChanModes['I'] = ListArg; - m_mueChanModes['k'] = HasArg; - m_mueChanModes['l'] = ArgWhenSet; - m_mueChanModes['p'] = NoArg; - m_mueChanModes['s'] = NoArg; - m_mueChanModes['t'] = NoArg; - m_mueChanModes['i'] = NoArg; - m_mueChanModes['n'] = NoArg; + m_mueChanModes['b'] = ListArg; + m_mueChanModes['e'] = ListArg; + m_mueChanModes['I'] = ListArg; + m_mueChanModes['k'] = HasArg; + m_mueChanModes['l'] = ArgWhenSet; + m_mueChanModes['p'] = NoArg; + m_mueChanModes['s'] = NoArg; + m_mueChanModes['t'] = NoArg; + m_mueChanModes['i'] = NoArg; + m_mueChanModes['n'] = NoArg; - pNetwork->SetIRCSocket(this); + pNetwork->SetIRCSocket(this); - // RFC says a line can have 512 chars max + 512 chars for message tags, but - // we don't care ;) - SetMaxBufferThreshold(2048); - if (m_bFloodProtection) { - AddCron(new CIRCFloodTimer(this)); - } + // RFC says a line can have 512 chars max + 512 chars for message tags, but + // we don't care ;) + SetMaxBufferThreshold(2048); + if (m_bFloodProtection) { + AddCron(new CIRCFloodTimer(this)); + } } CIRCSock::~CIRCSock() { - if (!m_bAuthed) { - IRCSOCKMODULECALL(OnIRCConnectionError(this), NOTHING); - } + if (!m_bAuthed) { + IRCSOCKMODULECALL(OnIRCConnectionError(this), NOTHING); + } - const vector& vChans = m_pNetwork->GetChans(); - for (CChan* pChan : vChans) { - pChan->Reset(); - } + const vector& vChans = m_pNetwork->GetChans(); + for (CChan* pChan : vChans) { + pChan->Reset(); + } - m_pNetwork->IRCDisconnected(); + m_pNetwork->IRCDisconnected(); - for (const auto& it : m_msChans) { - delete it.second; - } + for (const auto& it : m_msChans) { + delete it.second; + } - Quit(); - m_msChans.clear(); - m_pNetwork->AddBytesRead(GetBytesRead()); - m_pNetwork->AddBytesWritten(GetBytesWritten()); + Quit(); + m_msChans.clear(); + m_pNetwork->AddBytesRead(GetBytesRead()); + m_pNetwork->AddBytesWritten(GetBytesWritten()); } void CIRCSock::Quit(const CString& sQuitMsg) { - if (!m_bAuthed) { - Close(CLT_NOW); - return; - } - if (!sQuitMsg.empty()) { - PutIRC("QUIT :" + sQuitMsg); - } else { - PutIRC("QUIT :" + m_pNetwork->ExpandString(m_pNetwork->GetQuitMsg())); - } - Close(CLT_AFTERWRITE); + if (!m_bAuthed) { + Close(CLT_NOW); + return; + } + if (!sQuitMsg.empty()) { + PutIRC("QUIT :" + sQuitMsg); + } else { + PutIRC("QUIT :" + m_pNetwork->ExpandString(m_pNetwork->GetQuitMsg())); + } + Close(CLT_AFTERWRITE); } void CIRCSock::ReadLine(const CString& sData) { - CString sLine = sData; + CString sLine = sData; - sLine.TrimRight("\n\r"); + sLine.TrimRight("\n\r"); - DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" - << m_pNetwork->GetName() << ") IRC -> ZNC [" << sLine << "]"); + DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" + << m_pNetwork->GetName() << ") IRC -> ZNC [" << sLine << "]"); - bool bReturn = false; - IRCSOCKMODULECALL(OnRaw(sLine), &bReturn); - if (bReturn) return; + bool bReturn = false; + IRCSOCKMODULECALL(OnRaw(sLine), &bReturn); + if (bReturn) return; - CMessage Message(sLine); - Message.SetNetwork(m_pNetwork); + CMessage Message(sLine); + Message.SetNetwork(m_pNetwork); - IRCSOCKMODULECALL(OnRawMessage(Message), &bReturn); - if (bReturn) return; + IRCSOCKMODULECALL(OnRawMessage(Message), &bReturn); + if (bReturn) return; - switch (Message.GetType()) { - case CMessage::Type::Account: - bReturn = OnAccountMessage(Message); - break; - case CMessage::Type::Action: - bReturn = OnActionMessage(Message); - break; - case CMessage::Type::Away: - bReturn = OnAwayMessage(Message); - break; - case CMessage::Type::Capability: - bReturn = OnCapabilityMessage(Message); - break; - case CMessage::Type::CTCP: - bReturn = OnCTCPMessage(Message); - break; - case CMessage::Type::Error: - bReturn = OnErrorMessage(Message); - break; - case CMessage::Type::Invite: - bReturn = OnInviteMessage(Message); - break; - case CMessage::Type::Join: - bReturn = OnJoinMessage(Message); - break; - case CMessage::Type::Kick: - bReturn = OnKickMessage(Message); - break; - case CMessage::Type::Mode: - bReturn = OnModeMessage(Message); - break; - case CMessage::Type::Nick: - bReturn = OnNickMessage(Message); - break; - case CMessage::Type::Notice: - bReturn = OnNoticeMessage(Message); - break; - case CMessage::Type::Numeric: - bReturn = OnNumericMessage(Message); - break; - case CMessage::Type::Part: - bReturn = OnPartMessage(Message); - break; - case CMessage::Type::Ping: - bReturn = OnPingMessage(Message); - break; - case CMessage::Type::Pong: - bReturn = OnPongMessage(Message); - break; - case CMessage::Type::Quit: - bReturn = OnQuitMessage(Message); - break; - case CMessage::Type::Text: - bReturn = OnTextMessage(Message); - break; - case CMessage::Type::Topic: - bReturn = OnTopicMessage(Message); - break; - case CMessage::Type::Wallops: - bReturn = OnWallopsMessage(Message); - break; - default: - break; - } - if (bReturn) return; + switch (Message.GetType()) { + case CMessage::Type::Account: + bReturn = OnAccountMessage(Message); + break; + case CMessage::Type::Action: + bReturn = OnActionMessage(Message); + break; + case CMessage::Type::Away: + bReturn = OnAwayMessage(Message); + break; + case CMessage::Type::Capability: + bReturn = OnCapabilityMessage(Message); + break; + case CMessage::Type::CTCP: + bReturn = OnCTCPMessage(Message); + break; + case CMessage::Type::Error: + bReturn = OnErrorMessage(Message); + break; + case CMessage::Type::Invite: + bReturn = OnInviteMessage(Message); + break; + case CMessage::Type::Join: + bReturn = OnJoinMessage(Message); + break; + case CMessage::Type::Kick: + bReturn = OnKickMessage(Message); + break; + case CMessage::Type::Mode: + bReturn = OnModeMessage(Message); + break; + case CMessage::Type::Nick: + bReturn = OnNickMessage(Message); + break; + case CMessage::Type::Notice: + bReturn = OnNoticeMessage(Message); + break; + case CMessage::Type::Numeric: + bReturn = OnNumericMessage(Message); + break; + case CMessage::Type::Part: + bReturn = OnPartMessage(Message); + break; + case CMessage::Type::Ping: + bReturn = OnPingMessage(Message); + break; + case CMessage::Type::Pong: + bReturn = OnPongMessage(Message); + break; + case CMessage::Type::Quit: + bReturn = OnQuitMessage(Message); + break; + case CMessage::Type::Text: + bReturn = OnTextMessage(Message); + break; + case CMessage::Type::Topic: + bReturn = OnTopicMessage(Message); + break; + case CMessage::Type::Wallops: + bReturn = OnWallopsMessage(Message); + break; + default: + break; + } + if (bReturn) return; - m_pNetwork->PutUser(Message); + m_pNetwork->PutUser(Message); } void CIRCSock::SendNextCap() { - if (!m_uCapPaused) { - if (m_ssPendingCaps.empty()) { - // We already got all needed ACK/NAK replies. - PutIRC("CAP END"); - } else { - CString sCap = *m_ssPendingCaps.begin(); - m_ssPendingCaps.erase(m_ssPendingCaps.begin()); - PutIRC("CAP REQ :" + sCap); - } - } + if (!m_uCapPaused) { + if (m_ssPendingCaps.empty()) { + // We already got all needed ACK/NAK replies. + PutIRC("CAP END"); + } else { + CString sCap = *m_ssPendingCaps.begin(); + m_ssPendingCaps.erase(m_ssPendingCaps.begin()); + PutIRC("CAP REQ :" + sCap); + } + } } void CIRCSock::PauseCap() { ++m_uCapPaused; } void CIRCSock::ResumeCap() { - --m_uCapPaused; - SendNextCap(); + --m_uCapPaused; + SendNextCap(); } bool CIRCSock::OnServerCapAvailable(const CString& sCap) { - bool bResult = false; - IRCSOCKMODULECALL(OnServerCapAvailable(sCap), &bResult); - return bResult; + bool bResult = false; + IRCSOCKMODULECALL(OnServerCapAvailable(sCap), &bResult); + return bResult; } // #124: OnChanMsg(): nick doesn't have perms static void FixupChanNick(CNick& Nick, CChan* pChan) { - // A channel nick has up-to-date channel perms, but might be - // lacking (usernames-in-host) the associated ident & host. - // An incoming message, on the other hand, has normally a full - // nick!ident@host prefix. Sync the two so that channel nicks - // get the potentially missing piece of info and module hooks - // get the perms. - CNick* pChanNick = pChan->FindNick(Nick.GetNick()); - if (pChanNick) { - if (!Nick.GetIdent().empty()) { - pChanNick->SetIdent(Nick.GetIdent()); - } - if (!Nick.GetHost().empty()) { - pChanNick->SetHost(Nick.GetHost()); - } - Nick.Clone(*pChanNick); - } + // A channel nick has up-to-date channel perms, but might be + // lacking (usernames-in-host) the associated ident & host. + // An incoming message, on the other hand, has normally a full + // nick!ident@host prefix. Sync the two so that channel nicks + // get the potentially missing piece of info and module hooks + // get the perms. + CNick* pChanNick = pChan->FindNick(Nick.GetNick()); + if (pChanNick) { + if (!Nick.GetIdent().empty()) { + pChanNick->SetIdent(Nick.GetIdent()); + } + if (!Nick.GetHost().empty()) { + pChanNick->SetHost(Nick.GetHost()); + } + Nick.Clone(*pChanNick); + } } bool CIRCSock::OnAccountMessage(CMessage& Message) { - // TODO: IRCSOCKMODULECALL(OnAccountMessage(Message)) ? - return false; + // TODO: IRCSOCKMODULECALL(OnAccountMessage(Message)) ? + return false; } bool CIRCSock::OnActionMessage(CActionMessage& Message) { - bool bResult = false; - CChan* pChan = nullptr; - CString sTarget = Message.GetTarget(); - if (sTarget.Equals(GetNick())) { - IRCSOCKMODULECALL(OnPrivCTCPMessage(Message), &bResult); - if (bResult) return true; - IRCSOCKMODULECALL(OnPrivActionMessage(Message), &bResult); - if (bResult) return true; + bool bResult = false; + CChan* pChan = nullptr; + CString sTarget = Message.GetTarget(); + if (sTarget.Equals(GetNick())) { + IRCSOCKMODULECALL(OnPrivCTCPMessage(Message), &bResult); + if (bResult) return true; + IRCSOCKMODULECALL(OnPrivActionMessage(Message), &bResult); + if (bResult) return true; - if (!m_pNetwork->IsUserOnline() || - !m_pNetwork->GetUser()->AutoClearQueryBuffer()) { - const CNick& Nick = Message.GetNick(); - CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick()); - if (pQuery) { - CActionMessage Format; - Format.Clone(Message); - Format.SetNick(_NAMEDFMT(Nick.GetNickMask())); - Format.SetTarget("{target}"); - Format.SetText("{text}"); - pQuery->AddBuffer(Format, Message.GetText()); - } - } - } else { - pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - Message.SetChan(pChan); - FixupChanNick(Message.GetNick(), pChan); - IRCSOCKMODULECALL(OnChanCTCPMessage(Message), &bResult); - if (bResult) return true; - IRCSOCKMODULECALL(OnChanActionMessage(Message), &bResult); - if (bResult) return true; + if (!m_pNetwork->IsUserOnline() || + !m_pNetwork->GetUser()->AutoClearQueryBuffer()) { + const CNick& Nick = Message.GetNick(); + CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick()); + if (pQuery) { + CActionMessage Format; + Format.Clone(Message); + Format.SetNick(_NAMEDFMT(Nick.GetNickMask())); + Format.SetTarget("{target}"); + Format.SetText("{text}"); + pQuery->AddBuffer(Format, Message.GetText()); + } + } + } else { + pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + Message.SetChan(pChan); + FixupChanNick(Message.GetNick(), pChan); + IRCSOCKMODULECALL(OnChanCTCPMessage(Message), &bResult); + if (bResult) return true; + IRCSOCKMODULECALL(OnChanActionMessage(Message), &bResult); + if (bResult) return true; - if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || - pChan->IsDetached()) { - CActionMessage Format; - Format.Clone(Message); - Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); - Format.SetTarget(_NAMEDFMT(Message.GetTarget())); - Format.SetText("{text}"); - pChan->AddBuffer(Format, Message.GetText()); - } - } - } + if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || + pChan->IsDetached()) { + CActionMessage Format; + Format.Clone(Message); + Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); + Format.SetTarget(_NAMEDFMT(Message.GetTarget())); + Format.SetText("{text}"); + pChan->AddBuffer(Format, Message.GetText()); + } + } + } - return (pChan && pChan->IsDetached()); + return (pChan && pChan->IsDetached()); } bool CIRCSock::OnAwayMessage(CMessage& Message) { - // TODO: IRCSOCKMODULECALL(OnAwayMessage(Message)) ? - return false; + // TODO: IRCSOCKMODULECALL(OnAwayMessage(Message)) ? + return false; } bool CIRCSock::OnCapabilityMessage(CMessage& Message) { - // CAPs are supported only before authorization. - if (!m_bAuthed) { - // The first parameter is most likely "*". No idea why, the - // CAP spec don't mention this, but all implementations - // I've seen add this extra asterisk - CString sSubCmd = Message.GetParam(1); + // CAPs are supported only before authorization. + if (!m_bAuthed) { + // The first parameter is most likely "*". No idea why, the + // CAP spec don't mention this, but all implementations + // I've seen add this extra asterisk + CString sSubCmd = Message.GetParam(1); - // If the caplist of a reply is too long, it's split - // into multiple replies. A "*" is prepended to show - // that the list was split into multiple replies. - // This is useful mainly for LS. For ACK and NAK - // replies, there's no real need for this, because - // we request only 1 capability per line. - // If we will need to support broken servers or will - // send several requests per line, need to delay ACK - // actions until all ACK lines are received and - // to recognize past request of NAK by 100 chars - // of this reply. - CString sArgs; - if (Message.GetParam(2) == "*") { - sArgs = Message.GetParam(3); - } else { - sArgs = Message.GetParam(2); - } + // If the caplist of a reply is too long, it's split + // into multiple replies. A "*" is prepended to show + // that the list was split into multiple replies. + // This is useful mainly for LS. For ACK and NAK + // replies, there's no real need for this, because + // we request only 1 capability per line. + // If we will need to support broken servers or will + // send several requests per line, need to delay ACK + // actions until all ACK lines are received and + // to recognize past request of NAK by 100 chars + // of this reply. + CString sArgs; + if (Message.GetParam(2) == "*") { + sArgs = Message.GetParam(3); + } else { + sArgs = Message.GetParam(2); + } - std::map> mSupportedCaps = { - {"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }}, - {"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }}, - {"away-notify", [this](bool bVal) { m_bAwayNotify = bVal; }}, - {"account-notify", [this](bool bVal) { m_bAccountNotify = bVal; }}, - {"extended-join", [this](bool bVal) { m_bExtendedJoin = bVal; }}, - {"server-time", [this](bool bVal) { m_bServerTime = bVal; }}, - {"znc.in/server-time-iso", - [this](bool bVal) { m_bServerTime = bVal; }}, - }; + std::map> mSupportedCaps = { + {"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }}, + {"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }}, + {"away-notify", [this](bool bVal) { m_bAwayNotify = bVal; }}, + {"account-notify", [this](bool bVal) { m_bAccountNotify = bVal; }}, + {"extended-join", [this](bool bVal) { m_bExtendedJoin = bVal; }}, + {"server-time", [this](bool bVal) { m_bServerTime = bVal; }}, + {"znc.in/server-time-iso", + [this](bool bVal) { m_bServerTime = bVal; }}, + }; - if (sSubCmd == "LS") { - VCString vsTokens; - sArgs.Split(" ", vsTokens, false); + if (sSubCmd == "LS") { + VCString vsTokens; + sArgs.Split(" ", vsTokens, false); - for (const CString& sCap : vsTokens) { - if (OnServerCapAvailable(sCap) || mSupportedCaps.count(sCap)) { - m_ssPendingCaps.insert(sCap); - } - } - } else if (sSubCmd == "ACK") { - sArgs.Trim(); - IRCSOCKMODULECALL(OnServerCapResult(sArgs, true), NOTHING); - const auto& it = mSupportedCaps.find(sArgs); - if (it != mSupportedCaps.end()) { - it->second(true); - } - m_ssAcceptedCaps.insert(sArgs); - } else if (sSubCmd == "NAK") { - // This should work because there's no [known] - // capability with length of name more than 100 characters. - sArgs.Trim(); - IRCSOCKMODULECALL(OnServerCapResult(sArgs, false), NOTHING); - } + for (const CString& sCap : vsTokens) { + if (OnServerCapAvailable(sCap) || mSupportedCaps.count(sCap)) { + m_ssPendingCaps.insert(sCap); + } + } + } else if (sSubCmd == "ACK") { + sArgs.Trim(); + IRCSOCKMODULECALL(OnServerCapResult(sArgs, true), NOTHING); + const auto& it = mSupportedCaps.find(sArgs); + if (it != mSupportedCaps.end()) { + it->second(true); + } + m_ssAcceptedCaps.insert(sArgs); + } else if (sSubCmd == "NAK") { + // This should work because there's no [known] + // capability with length of name more than 100 characters. + sArgs.Trim(); + IRCSOCKMODULECALL(OnServerCapResult(sArgs, false), NOTHING); + } - SendNextCap(); - } - // Don't forward any CAP stuff to the client - return true; + SendNextCap(); + } + // Don't forward any CAP stuff to the client + return true; } bool CIRCSock::OnCTCPMessage(CCTCPMessage& Message) { - bool bResult = false; - CChan* pChan = nullptr; - CString sTarget = Message.GetTarget(); - if (sTarget.Equals(GetNick())) { - if (Message.IsReply()) { - IRCSOCKMODULECALL(OnCTCPReplyMessage(Message), &bResult); - return bResult; - } else { - IRCSOCKMODULECALL(OnPrivCTCPMessage(Message), &bResult); - if (bResult) return true; - } - } else { - pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - Message.SetChan(pChan); - FixupChanNick(Message.GetNick(), pChan); - IRCSOCKMODULECALL(OnChanCTCPMessage(Message), &bResult); - if (bResult) return true; - } - } + bool bResult = false; + CChan* pChan = nullptr; + CString sTarget = Message.GetTarget(); + if (sTarget.Equals(GetNick())) { + if (Message.IsReply()) { + IRCSOCKMODULECALL(OnCTCPReplyMessage(Message), &bResult); + return bResult; + } else { + IRCSOCKMODULECALL(OnPrivCTCPMessage(Message), &bResult); + if (bResult) return true; + } + } else { + pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + Message.SetChan(pChan); + FixupChanNick(Message.GetNick(), pChan); + IRCSOCKMODULECALL(OnChanCTCPMessage(Message), &bResult); + if (bResult) return true; + } + } - const CNick& Nick = Message.GetNick(); - const CString& sMessage = Message.GetText(); - const MCString& mssCTCPReplies = m_pNetwork->GetUser()->GetCTCPReplies(); - CString sQuery = sMessage.Token(0).AsUpper(); - MCString::const_iterator it = mssCTCPReplies.find(sQuery); - bool bHaveReply = false; - CString sReply; + const CNick& Nick = Message.GetNick(); + const CString& sMessage = Message.GetText(); + const MCString& mssCTCPReplies = m_pNetwork->GetUser()->GetCTCPReplies(); + CString sQuery = sMessage.Token(0).AsUpper(); + MCString::const_iterator it = mssCTCPReplies.find(sQuery); + bool bHaveReply = false; + CString sReply; - if (it != mssCTCPReplies.end()) { - sReply = m_pNetwork->ExpandString(it->second); - bHaveReply = true; + if (it != mssCTCPReplies.end()) { + sReply = m_pNetwork->ExpandString(it->second); + bHaveReply = true; - if (sReply.empty()) { - return true; - } - } + if (sReply.empty()) { + return true; + } + } - if (!bHaveReply && !m_pNetwork->IsUserAttached()) { - if (sQuery == "VERSION") { - sReply = CZNC::GetTag(false); - } else if (sQuery == "PING") { - sReply = sMessage.Token(1, true); - } - } + if (!bHaveReply && !m_pNetwork->IsUserAttached()) { + if (sQuery == "VERSION") { + sReply = CZNC::GetTag(false); + } else if (sQuery == "PING") { + sReply = sMessage.Token(1, true); + } + } - if (!sReply.empty()) { - time_t now = time(nullptr); - // If the last CTCP is older than m_uCTCPFloodTime, reset the counter - if (m_lastCTCP + m_uCTCPFloodTime < now) m_uNumCTCP = 0; - m_lastCTCP = now; - // If we are over the limit, don't reply to this CTCP - if (m_uNumCTCP >= m_uCTCPFloodCount) { - DEBUG("CTCP flood detected - not replying to query"); - return true; - } - m_uNumCTCP++; + if (!sReply.empty()) { + time_t now = time(nullptr); + // If the last CTCP is older than m_uCTCPFloodTime, reset the counter + if (m_lastCTCP + m_uCTCPFloodTime < now) m_uNumCTCP = 0; + m_lastCTCP = now; + // If we are over the limit, don't reply to this CTCP + if (m_uNumCTCP >= m_uCTCPFloodCount) { + DEBUG("CTCP flood detected - not replying to query"); + return true; + } + m_uNumCTCP++; - PutIRC("NOTICE " + Nick.GetNick() + " :\001" + sQuery + " " + sReply + - "\001"); - return true; - } + PutIRC("NOTICE " + Nick.GetNick() + " :\001" + sQuery + " " + sReply + + "\001"); + return true; + } - return (pChan && pChan->IsDetached()); + return (pChan && pChan->IsDetached()); } bool CIRCSock::OnErrorMessage(CMessage& Message) { - // ERROR :Closing Link: nick[24.24.24.24] (Excess Flood) - CString sError = Message.GetParam(0); - m_pNetwork->PutStatus("Error from Server [" + sError + "]"); - return true; + // ERROR :Closing Link: nick[24.24.24.24] (Excess Flood) + CString sError = Message.GetParam(0); + m_pNetwork->PutStatus("Error from Server [" + sError + "]"); + return true; } bool CIRCSock::OnInviteMessage(CMessage& Message) { - bool bResult = false; - IRCSOCKMODULECALL(OnInvite(Message.GetNick(), Message.GetParam(1)), - &bResult); - return bResult; + bool bResult = false; + IRCSOCKMODULECALL(OnInvite(Message.GetNick(), Message.GetParam(1)), + &bResult); + return bResult; } bool CIRCSock::OnJoinMessage(CJoinMessage& Message) { - const CNick& Nick = Message.GetNick(); - CString sChan = Message.GetParam(0); - CChan* pChan = nullptr; + const CNick& Nick = Message.GetNick(); + CString sChan = Message.GetParam(0); + CChan* pChan = nullptr; - if (Nick.NickEquals(GetNick())) { - m_pNetwork->AddChan(sChan, false); - pChan = m_pNetwork->FindChan(sChan); - if (pChan) { - pChan->Enable(); - pChan->SetIsOn(true); - PutIRC("MODE " + sChan); - } - } else { - pChan = m_pNetwork->FindChan(sChan); - } + if (Nick.NickEquals(GetNick())) { + m_pNetwork->AddChan(sChan, false); + pChan = m_pNetwork->FindChan(sChan); + if (pChan) { + pChan->Enable(); + pChan->SetIsOn(true); + PutIRC("MODE " + sChan); + } + } else { + pChan = m_pNetwork->FindChan(sChan); + } - if (pChan) { - pChan->AddNick(Nick.GetNickMask()); - Message.SetChan(pChan); - IRCSOCKMODULECALL(OnJoinMessage(Message), NOTHING); + if (pChan) { + pChan->AddNick(Nick.GetNickMask()); + Message.SetChan(pChan); + IRCSOCKMODULECALL(OnJoinMessage(Message), NOTHING); - if (pChan->IsDetached()) { - return true; - } - } + if (pChan->IsDetached()) { + return true; + } + } - return false; + return false; } bool CIRCSock::OnKickMessage(CKickMessage& Message) { - CString sChan = Message.GetParam(0); - CString sKickedNick = Message.GetKickedNick(); + CString sChan = Message.GetParam(0); + CString sKickedNick = Message.GetKickedNick(); - CChan* pChan = m_pNetwork->FindChan(sChan); + CChan* pChan = m_pNetwork->FindChan(sChan); - if (pChan) { - Message.SetChan(pChan); - IRCSOCKMODULECALL(OnKickMessage(Message), NOTHING); - // do not remove the nick till after the OnKick call, so modules - // can do Chan.FindNick or something to get more info. - pChan->RemNick(sKickedNick); - } + if (pChan) { + Message.SetChan(pChan); + IRCSOCKMODULECALL(OnKickMessage(Message), NOTHING); + // do not remove the nick till after the OnKick call, so modules + // can do Chan.FindNick or something to get more info. + pChan->RemNick(sKickedNick); + } - if (GetNick().Equals(sKickedNick) && pChan) { - pChan->SetIsOn(false); + if (GetNick().Equals(sKickedNick) && pChan) { + pChan->SetIsOn(false); - // Don't try to rejoin! - pChan->Disable(); - } + // Don't try to rejoin! + pChan->Disable(); + } - return (pChan && pChan->IsDetached()); + return (pChan && pChan->IsDetached()); } bool CIRCSock::OnModeMessage(CModeMessage& Message) { - const CNick& Nick = Message.GetNick(); - CString sTarget = Message.GetTarget(); - CString sModes = Message.GetModes(); + const CNick& Nick = Message.GetNick(); + CString sTarget = Message.GetTarget(); + CString sModes = Message.GetModes(); - CChan* pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - pChan->ModeChange(sModes, &Nick); + CChan* pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + pChan->ModeChange(sModes, &Nick); - if (pChan->IsDetached()) { - return true; - } - } else if (sTarget == m_Nick.GetNick()) { - CString sModeArg = sModes.Token(0); - bool bAdd = true; - /* no module call defined (yet?) - MODULECALL(OnRawUserMode(*pOpNick, *this, sModeArg, sArgs), - m_pNetwork->GetUser(), nullptr, ); - */ - for (unsigned int a = 0; a < sModeArg.size(); a++) { - const unsigned char& uMode = sModeArg[a]; + if (pChan->IsDetached()) { + return true; + } + } else if (sTarget == m_Nick.GetNick()) { + CString sModeArg = sModes.Token(0); + bool bAdd = true; + /* no module call defined (yet?) + MODULECALL(OnRawUserMode(*pOpNick, *this, sModeArg, sArgs), + m_pNetwork->GetUser(), nullptr, ); + */ + for (unsigned int a = 0; a < sModeArg.size(); a++) { + const unsigned char& uMode = sModeArg[a]; - if (uMode == '+') { - bAdd = true; - } else if (uMode == '-') { - bAdd = false; - } else { - if (bAdd) { - m_scUserModes.insert(uMode); - } else { - m_scUserModes.erase(uMode); - } - } - } - } - return false; + if (uMode == '+') { + bAdd = true; + } else if (uMode == '-') { + bAdd = false; + } else { + if (bAdd) { + m_scUserModes.insert(uMode); + } else { + m_scUserModes.erase(uMode); + } + } + } + } + return false; } bool CIRCSock::OnNickMessage(CNickMessage& Message) { - const CNick& Nick = Message.GetNick(); - CString sNewNick = Message.GetNewNick(); - bool bIsVisible = false; + const CNick& Nick = Message.GetNick(); + CString sNewNick = Message.GetNewNick(); + bool bIsVisible = false; - vector vFoundChans; - const vector& vChans = m_pNetwork->GetChans(); + vector vFoundChans; + const vector& vChans = m_pNetwork->GetChans(); - for (CChan* pChan : vChans) { - if (pChan->ChangeNick(Nick.GetNick(), sNewNick)) { - vFoundChans.push_back(pChan); + for (CChan* pChan : vChans) { + if (pChan->ChangeNick(Nick.GetNick(), sNewNick)) { + vFoundChans.push_back(pChan); - if (!pChan->IsDetached()) { - bIsVisible = true; - } - } - } + if (!pChan->IsDetached()) { + bIsVisible = true; + } + } + } - if (Nick.NickEquals(GetNick())) { - // We are changing our own nick, the clients always must see this! - bIsVisible = false; - SetNick(sNewNick); - m_pNetwork->PutUser(Message); - } + if (Nick.NickEquals(GetNick())) { + // We are changing our own nick, the clients always must see this! + bIsVisible = false; + SetNick(sNewNick); + m_pNetwork->PutUser(Message); + } - IRCSOCKMODULECALL(OnNickMessage(Message, vFoundChans), NOTHING); + IRCSOCKMODULECALL(OnNickMessage(Message, vFoundChans), NOTHING); - return !bIsVisible; + return !bIsVisible; } bool CIRCSock::OnNoticeMessage(CNoticeMessage& Message) { - CString sTarget = Message.GetTarget(); - bool bResult = false; + CString sTarget = Message.GetTarget(); + bool bResult = false; - if (sTarget.Equals(GetNick())) { - IRCSOCKMODULECALL(OnPrivNoticeMessage(Message), &bResult); - if (bResult) return true; + if (sTarget.Equals(GetNick())) { + IRCSOCKMODULECALL(OnPrivNoticeMessage(Message), &bResult); + if (bResult) return true; - if (!m_pNetwork->IsUserOnline()) { - // If the user is detached, add to the buffer - CNoticeMessage Format; - Format.Clone(Message); - Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetNickMask()))); - Format.SetTarget("{target}"); - Format.SetText("{text}"); - m_pNetwork->AddNoticeBuffer(Format, Message.GetText()); - } + if (!m_pNetwork->IsUserOnline()) { + // If the user is detached, add to the buffer + CNoticeMessage Format; + Format.Clone(Message); + Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetNickMask()))); + Format.SetTarget("{target}"); + Format.SetText("{text}"); + m_pNetwork->AddNoticeBuffer(Format, Message.GetText()); + } - return false; - } else { - CChan* pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - Message.SetChan(pChan); - FixupChanNick(Message.GetNick(), pChan); - IRCSOCKMODULECALL(OnChanNoticeMessage(Message), &bResult); - if (bResult) return true; + return false; + } else { + CChan* pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + Message.SetChan(pChan); + FixupChanNick(Message.GetNick(), pChan); + IRCSOCKMODULECALL(OnChanNoticeMessage(Message), &bResult); + if (bResult) return true; - if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || - pChan->IsDetached()) { - CNoticeMessage Format; - Format.Clone(Message); - Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); - Format.SetTarget(_NAMEDFMT(Message.GetTarget())); - Format.SetText("{text}"); - pChan->AddBuffer(Format, Message.GetText()); - } - } + if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || + pChan->IsDetached()) { + CNoticeMessage Format; + Format.Clone(Message); + Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); + Format.SetTarget(_NAMEDFMT(Message.GetTarget())); + Format.SetText("{text}"); + pChan->AddBuffer(Format, Message.GetText()); + } + } - return (pChan && pChan->IsDetached()); - } + return (pChan && pChan->IsDetached()); + } } static CMessage BufferMessage(const CNumericMessage& Message) { - CMessage Format(Message); - Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetHostMask()))); - Format.SetParam(0, "{target}"); - unsigned uParams = Format.GetParams().size(); - for (unsigned int i = 1; i < uParams; ++i) { - Format.SetParam(i, _NAMEDFMT(Format.GetParam(i))); - } - return Format; + CMessage Format(Message); + Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetHostMask()))); + Format.SetParam(0, "{target}"); + unsigned uParams = Format.GetParams().size(); + for (unsigned int i = 1; i < uParams; ++i) { + Format.SetParam(i, _NAMEDFMT(Format.GetParam(i))); + } + return Format; } bool CIRCSock::OnNumericMessage(CNumericMessage& Message) { - const CString& sCmd = Message.GetCommand(); - CString sServer = Message.GetNick().GetHostMask(); - unsigned int uRaw = Message.GetCode(); - CString sNick = Message.GetParam(0); + const CString& sCmd = Message.GetCommand(); + CString sServer = Message.GetNick().GetHostMask(); + unsigned int uRaw = Message.GetCode(); + CString sNick = Message.GetParam(0); - bool bResult = false; - IRCSOCKMODULECALL(OnNumericMessage(Message), &bResult); - if (bResult) return true; + bool bResult = false; + IRCSOCKMODULECALL(OnNumericMessage(Message), &bResult); + if (bResult) return true; - switch (uRaw) { - case 1: { // :irc.server.com 001 nick :Welcome to the Internet Relay - if (m_bAuthed && sServer == "irc.znc.in") { - // m_bAuthed == true => we already received another 001 => we - // might be in a traffic loop - m_pNetwork->PutStatus( - "ZNC seems to be connected to itself, disconnecting..."); - Quit(); - return true; - } + switch (uRaw) { + case 1: { // :irc.server.com 001 nick :Welcome to the Internet Relay + if (m_bAuthed && sServer == "irc.znc.in") { + // m_bAuthed == true => we already received another 001 => we + // might be in a traffic loop + m_pNetwork->PutStatus( + "ZNC seems to be connected to itself, disconnecting..."); + Quit(); + return true; + } - m_pNetwork->SetIRCServer(sServer); - // Now that we are connected, let nature take its course - SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ); - PutIRC("WHO " + sNick); + m_pNetwork->SetIRCServer(sServer); + // Now that we are connected, let nature take its course + SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ); + PutIRC("WHO " + sNick); - m_bAuthed = true; - m_pNetwork->PutStatus("Connected!"); + m_bAuthed = true; + m_pNetwork->PutStatus("Connected!"); - const vector& vClients = m_pNetwork->GetClients(); + const vector& vClients = m_pNetwork->GetClients(); - for (CClient* pClient : vClients) { - CString sClientNick = pClient->GetNick(false); + for (CClient* pClient : vClients) { + CString sClientNick = pClient->GetNick(false); - if (!sClientNick.Equals(sNick)) { - // If they connected with a nick that doesn't match the one - // we got on irc, then we need to update them - pClient->PutClient(":" + sClientNick + "!" + - m_Nick.GetIdent() + "@" + - m_Nick.GetHost() + " NICK :" + sNick); - } - } + if (!sClientNick.Equals(sNick)) { + // If they connected with a nick that doesn't match the one + // we got on irc, then we need to update them + pClient->PutClient(":" + sClientNick + "!" + + m_Nick.GetIdent() + "@" + + m_Nick.GetHost() + " NICK :" + sNick); + } + } - SetNick(sNick); + SetNick(sNick); - IRCSOCKMODULECALL(OnIRCConnected(), NOTHING); + IRCSOCKMODULECALL(OnIRCConnected(), NOTHING); - m_pNetwork->ClearRawBuffer(); - m_pNetwork->AddRawBuffer(BufferMessage(Message)); + m_pNetwork->ClearRawBuffer(); + m_pNetwork->AddRawBuffer(BufferMessage(Message)); - m_pNetwork->IRCConnected(); + m_pNetwork->IRCConnected(); - break; - } - case 5: - ParseISupport(Message); - m_pNetwork->UpdateExactRawBuffer(BufferMessage(Message)); - break; - case 10: { // :irc.server.com 010 nick : - CString sHost = Message.GetParam(1); - CString sPort = Message.GetParam(2); - CString sInfo = Message.GetParam(3); - m_pNetwork->PutStatus( - "Server [" + m_pNetwork->GetCurrentServer()->GetString(false) + - "] redirects us to [" + sHost + ":" + sPort + - "] with reason [" + sInfo + "]"); - m_pNetwork->PutStatus( - "Perhaps you want to add it as a new server."); - // Don't send server redirects to the client - return true; - } - case 2: - case 3: - case 4: - case 250: // highest connection count - case 251: // user count - case 252: // oper count - case 254: // channel count - case 255: // client count - case 265: // local users - case 266: // global users - m_pNetwork->UpdateRawBuffer(sCmd, BufferMessage(Message)); - break; - case 305: - m_pNetwork->SetIRCAway(false); - break; - case 306: - m_pNetwork->SetIRCAway(true); - break; - case 324: { // MODE - // :irc.server.com 324 nick #chan +nstk key - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + break; + } + case 5: + ParseISupport(Message); + m_pNetwork->UpdateExactRawBuffer(BufferMessage(Message)); + break; + case 10: { // :irc.server.com 010 nick : + CString sHost = Message.GetParam(1); + CString sPort = Message.GetParam(2); + CString sInfo = Message.GetParam(3); + m_pNetwork->PutStatus( + "Server [" + m_pNetwork->GetCurrentServer()->GetString(false) + + "] redirects us to [" + sHost + ":" + sPort + + "] with reason [" + sInfo + "]"); + m_pNetwork->PutStatus( + "Perhaps you want to add it as a new server."); + // Don't send server redirects to the client + return true; + } + case 2: + case 3: + case 4: + case 250: // highest connection count + case 251: // user count + case 252: // oper count + case 254: // channel count + case 255: // client count + case 265: // local users + case 266: // global users + m_pNetwork->UpdateRawBuffer(sCmd, BufferMessage(Message)); + break; + case 305: + m_pNetwork->SetIRCAway(false); + break; + case 306: + m_pNetwork->SetIRCAway(true); + break; + case 324: { // MODE + // :irc.server.com 324 nick #chan +nstk key + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - pChan->SetModes(Message.GetParams(2)); + if (pChan) { + pChan->SetModes(Message.GetParams(2)); - // We don't SetModeKnown(true) here, - // because a 329 will follow - if (!pChan->IsModeKnown()) { - // When we JOIN, we send a MODE - // request. This makes sure the - // reply isn't forwarded. - return true; - } - if (pChan->IsDetached()) { - return true; - } - } - } break; - case 329: { - // :irc.server.com 329 nick #chan 1234567890 - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + // We don't SetModeKnown(true) here, + // because a 329 will follow + if (!pChan->IsModeKnown()) { + // When we JOIN, we send a MODE + // request. This makes sure the + // reply isn't forwarded. + return true; + } + if (pChan->IsDetached()) { + return true; + } + } + } break; + case 329: { + // :irc.server.com 329 nick #chan 1234567890 + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - unsigned long ulDate = Message.GetParam(2).ToULong(); - pChan->SetCreationDate(ulDate); + if (pChan) { + unsigned long ulDate = Message.GetParam(2).ToULong(); + pChan->SetCreationDate(ulDate); - if (!pChan->IsModeKnown()) { - pChan->SetModeKnown(true); - // When we JOIN, we send a MODE - // request. This makes sure the - // reply isn't forwarded. - return true; - } - if (pChan->IsDetached()) { - return true; - } - } - } break; - case 331: { - // :irc.server.com 331 yournick #chan :No topic is set. - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + if (!pChan->IsModeKnown()) { + pChan->SetModeKnown(true); + // When we JOIN, we send a MODE + // request. This makes sure the + // reply isn't forwarded. + return true; + } + if (pChan->IsDetached()) { + return true; + } + } + } break; + case 331: { + // :irc.server.com 331 yournick #chan :No topic is set. + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - pChan->SetTopic(""); - if (pChan->IsDetached()) { - return true; - } - } + if (pChan) { + pChan->SetTopic(""); + if (pChan->IsDetached()) { + return true; + } + } - break; - } - case 332: { - // :irc.server.com 332 yournick #chan :This is a topic - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + break; + } + case 332: { + // :irc.server.com 332 yournick #chan :This is a topic + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - CString sTopic = Message.GetParam(2); - pChan->SetTopic(sTopic); - if (pChan->IsDetached()) { - return true; - } - } + if (pChan) { + CString sTopic = Message.GetParam(2); + pChan->SetTopic(sTopic); + if (pChan->IsDetached()) { + return true; + } + } - break; - } - case 333: { - // :irc.server.com 333 yournick #chan setternick 1112320796 - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + break; + } + case 333: { + // :irc.server.com 333 yournick #chan setternick 1112320796 + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - sNick = Message.GetParam(2); - unsigned long ulDate = Message.GetParam(3).ToULong(); + if (pChan) { + sNick = Message.GetParam(2); + unsigned long ulDate = Message.GetParam(3).ToULong(); - pChan->SetTopicOwner(sNick); - pChan->SetTopicDate(ulDate); + pChan->SetTopicOwner(sNick); + pChan->SetTopicDate(ulDate); - if (pChan->IsDetached()) { - return true; - } - } + if (pChan->IsDetached()) { + return true; + } + } - break; - } - case 352: { // WHO - // :irc.yourserver.com 352 yournick #chan ident theirhost.com irc.theirserver.com theirnick H :0 Real Name - sNick = Message.GetParam(5); - CString sChan = Message.GetParam(1); - CString sIdent = Message.GetParam(2); - CString sHost = Message.GetParam(3); + break; + } + case 352: { // WHO + // :irc.yourserver.com 352 yournick #chan ident theirhost.com irc.theirserver.com theirnick H :0 Real Name + sNick = Message.GetParam(5); + CString sChan = Message.GetParam(1); + CString sIdent = Message.GetParam(2); + CString sHost = Message.GetParam(3); - if (sNick.Equals(GetNick())) { - m_Nick.SetIdent(sIdent); - m_Nick.SetHost(sHost); - } + if (sNick.Equals(GetNick())) { + m_Nick.SetIdent(sIdent); + m_Nick.SetHost(sHost); + } - m_pNetwork->SetIRCNick(m_Nick); - m_pNetwork->SetIRCServer(sServer); + m_pNetwork->SetIRCNick(m_Nick); + m_pNetwork->SetIRCServer(sServer); - const vector& vChans = m_pNetwork->GetChans(); + const vector& vChans = m_pNetwork->GetChans(); - for (CChan* pChan : vChans) { - pChan->OnWho(sNick, sIdent, sHost); - } + for (CChan* pChan : vChans) { + pChan->OnWho(sNick, sIdent, sHost); + } - CChan* pChan = m_pNetwork->FindChan(sChan); - if (pChan && pChan->IsDetached()) { - return true; - } + CChan* pChan = m_pNetwork->FindChan(sChan); + if (pChan && pChan->IsDetached()) { + return true; + } - break; - } - case 353: { // NAMES - // :irc.server.com 353 nick @ #chan :nick1 nick2 - // Todo: allow for non @+= server msgs - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(2)); - // If we don't know that channel, some client might have - // requested a /names for it and we really should forward this. - if (pChan) { - CString sNicks = Message.GetParam(3); - pChan->AddNicks(sNicks); - if (pChan->IsDetached()) { - return true; - } - } + break; + } + case 353: { // NAMES + // :irc.server.com 353 nick @ #chan :nick1 nick2 + // Todo: allow for non @+= server msgs + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(2)); + // If we don't know that channel, some client might have + // requested a /names for it and we really should forward this. + if (pChan) { + CString sNicks = Message.GetParam(3); + pChan->AddNicks(sNicks); + if (pChan->IsDetached()) { + return true; + } + } - break; - } - case 366: { // end of names list - // :irc.server.com 366 nick #chan :End of /NAMES list. - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + break; + } + case 366: { // end of names list + // :irc.server.com 366 nick #chan :End of /NAMES list. + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (pChan) { - if (pChan->IsOn()) { - // If we are the only one in the chan, set our default modes - if (pChan->GetNickCount() == 1) { - CString sModes = pChan->GetDefaultModes(); + if (pChan) { + if (pChan->IsOn()) { + // If we are the only one in the chan, set our default modes + if (pChan->GetNickCount() == 1) { + CString sModes = pChan->GetDefaultModes(); - if (sModes.empty()) { - sModes = - m_pNetwork->GetUser()->GetDefaultChanModes(); - } + if (sModes.empty()) { + sModes = + m_pNetwork->GetUser()->GetDefaultChanModes(); + } - if (!sModes.empty()) { - PutIRC("MODE " + pChan->GetName() + " " + sModes); - } - } - } - if (pChan->IsDetached()) { - // don't put it to clients - return true; - } - } + if (!sModes.empty()) { + PutIRC("MODE " + pChan->GetName() + " " + sModes); + } + } + } + if (pChan->IsDetached()) { + // don't put it to clients + return true; + } + } - break; - } - case 375: // begin motd - case 422: // MOTD File is missing - if (m_pNetwork->GetIRCServer().Equals(sServer)) { - m_pNetwork->ClearMotdBuffer(); - } - case 372: // motd - case 376: // end motd - if (m_pNetwork->GetIRCServer().Equals(sServer)) { - m_pNetwork->AddMotdBuffer(BufferMessage(Message)); - } - break; - case 437: - // :irc.server.net 437 * badnick :Nick/channel is temporarily unavailable - // :irc.server.net 437 mynick badnick :Nick/channel is temporarily unavailable - // :irc.server.net 437 mynick badnick :Cannot change nickname while banned on channel - if (m_pNetwork->IsChan(Message.GetParam(1)) || sNick != "*") break; - case 432: - // :irc.server.com 432 * nick :Erroneous Nickname: Illegal chars - case 433: { - CString sBadNick = Message.GetParam(1); + break; + } + case 375: // begin motd + case 422: // MOTD File is missing + if (m_pNetwork->GetIRCServer().Equals(sServer)) { + m_pNetwork->ClearMotdBuffer(); + } + case 372: // motd + case 376: // end motd + if (m_pNetwork->GetIRCServer().Equals(sServer)) { + m_pNetwork->AddMotdBuffer(BufferMessage(Message)); + } + break; + case 437: + // :irc.server.net 437 * badnick :Nick/channel is temporarily unavailable + // :irc.server.net 437 mynick badnick :Nick/channel is temporarily unavailable + // :irc.server.net 437 mynick badnick :Cannot change nickname while banned on channel + if (m_pNetwork->IsChan(Message.GetParam(1)) || sNick != "*") break; + case 432: + // :irc.server.com 432 * nick :Erroneous Nickname: Illegal chars + case 433: { + CString sBadNick = Message.GetParam(1); - if (!m_bAuthed) { - SendAltNick(sBadNick); - return true; - } - break; - } - case 451: - // :irc.server.com 451 CAP :You have not registered - // Servers that dont support CAP will give us this error, dont send - // it to the client - if (sNick.Equals("CAP")) return true; - case 470: { - // :irc.unreal.net 470 mynick [Link] #chan1 has become full, so you are automatically being transferred to the linked channel #chan2 - // :mccaffrey.freenode.net 470 mynick #electronics ##electronics :Forwarding to another channel + if (!m_bAuthed) { + SendAltNick(sBadNick); + return true; + } + break; + } + case 451: + // :irc.server.com 451 CAP :You have not registered + // Servers that dont support CAP will give us this error, dont send + // it to the client + if (sNick.Equals("CAP")) return true; + case 470: { + // :irc.unreal.net 470 mynick [Link] #chan1 has become full, so you are automatically being transferred to the linked channel #chan2 + // :mccaffrey.freenode.net 470 mynick #electronics ##electronics :Forwarding to another channel - // freenode style numeric - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); - if (!pChan) { - // unreal style numeric - pChan = m_pNetwork->FindChan(Message.GetParam(2)); - } - if (pChan) { - pChan->Disable(); - m_pNetwork->PutStatus("Channel [" + pChan->GetName() + - "] is linked to " - "another channel and was thus disabled."); - } - break; - } - case 670: - // :hydra.sector5d.org 670 kylef :STARTTLS successful, go ahead with TLS handshake - // - // 670 is a response to `STARTTLS` telling the client to switch to - // TLS - if (!GetSSL()) { - StartTLS(); - m_pNetwork->PutStatus("Switched to SSL (STARTTLS)"); - } + // freenode style numeric + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1)); + if (!pChan) { + // unreal style numeric + pChan = m_pNetwork->FindChan(Message.GetParam(2)); + } + if (pChan) { + pChan->Disable(); + m_pNetwork->PutStatus("Channel [" + pChan->GetName() + + "] is linked to " + "another channel and was thus disabled."); + } + break; + } + case 670: + // :hydra.sector5d.org 670 kylef :STARTTLS successful, go ahead with TLS handshake + // + // 670 is a response to `STARTTLS` telling the client to switch to + // TLS + if (!GetSSL()) { + StartTLS(); + m_pNetwork->PutStatus("Switched to SSL (STARTTLS)"); + } - return true; - } + return true; + } - return false; + return false; } bool CIRCSock::OnPartMessage(CPartMessage& Message) { - const CNick& Nick = Message.GetNick(); - CString sChan = Message.GetTarget(); + const CNick& Nick = Message.GetNick(); + CString sChan = Message.GetTarget(); - CChan* pChan = m_pNetwork->FindChan(sChan); - bool bDetached = false; - if (pChan) { - pChan->RemNick(Nick.GetNick()); - Message.SetChan(pChan); - IRCSOCKMODULECALL(OnPartMessage(Message), NOTHING); + CChan* pChan = m_pNetwork->FindChan(sChan); + bool bDetached = false; + if (pChan) { + pChan->RemNick(Nick.GetNick()); + Message.SetChan(pChan); + IRCSOCKMODULECALL(OnPartMessage(Message), NOTHING); - if (pChan->IsDetached()) bDetached = true; - } + if (pChan->IsDetached()) bDetached = true; + } - if (Nick.NickEquals(GetNick())) { - m_pNetwork->DelChan(sChan); - } + if (Nick.NickEquals(GetNick())) { + m_pNetwork->DelChan(sChan); + } - /* - * We use this boolean because - * m_pNetwork->DelChan() will delete this channel - * and thus we would dereference an - * already-freed pointer! - */ - return bDetached; + /* + * We use this boolean because + * m_pNetwork->DelChan() will delete this channel + * and thus we would dereference an + * already-freed pointer! + */ + return bDetached; } bool CIRCSock::OnPingMessage(CMessage& Message) { - // Generate a reply and don't forward this to any user, - // we don't want any PING forwarded - PutIRCQuick("PONG " + Message.GetParam(0)); - return true; + // Generate a reply and don't forward this to any user, + // we don't want any PING forwarded + PutIRCQuick("PONG " + Message.GetParam(0)); + return true; } bool CIRCSock::OnPongMessage(CMessage& Message) { - // Block PONGs, we already responded to the pings - return true; + // Block PONGs, we already responded to the pings + return true; } bool CIRCSock::OnQuitMessage(CQuitMessage& Message) { - const CNick& Nick = Message.GetNick(); - bool bIsVisible = false; + const CNick& Nick = Message.GetNick(); + bool bIsVisible = false; - if (Nick.NickEquals(GetNick())) { - m_pNetwork->PutStatus("You quit [" + Message.GetReason() + "]"); - // We don't call module hooks and we don't - // forward this quit to clients (Some clients - // disconnect if they receive such a QUIT) - return true; - } + if (Nick.NickEquals(GetNick())) { + m_pNetwork->PutStatus("You quit [" + Message.GetReason() + "]"); + // We don't call module hooks and we don't + // forward this quit to clients (Some clients + // disconnect if they receive such a QUIT) + return true; + } - vector vFoundChans; - const vector& vChans = m_pNetwork->GetChans(); + vector vFoundChans; + const vector& vChans = m_pNetwork->GetChans(); - for (CChan* pChan : vChans) { - if (pChan->RemNick(Nick.GetNick())) { - vFoundChans.push_back(pChan); + for (CChan* pChan : vChans) { + if (pChan->RemNick(Nick.GetNick())) { + vFoundChans.push_back(pChan); - if (!pChan->IsDetached()) { - bIsVisible = true; - } - } - } + if (!pChan->IsDetached()) { + bIsVisible = true; + } + } + } - IRCSOCKMODULECALL(OnQuitMessage(Message, vFoundChans), NOTHING); + IRCSOCKMODULECALL(OnQuitMessage(Message, vFoundChans), NOTHING); - return !bIsVisible; + return !bIsVisible; } bool CIRCSock::OnTextMessage(CTextMessage& Message) { - bool bResult = false; - CChan* pChan = nullptr; - CString sTarget = Message.GetTarget(); + bool bResult = false; + CChan* pChan = nullptr; + CString sTarget = Message.GetTarget(); - if (sTarget.Equals(GetNick())) { - IRCSOCKMODULECALL(OnPrivMessage(Message), &bResult); - if (bResult) return true; + if (sTarget.Equals(GetNick())) { + IRCSOCKMODULECALL(OnPrivMessage(Message), &bResult); + if (bResult) return true; - if (!m_pNetwork->IsUserOnline() || - !m_pNetwork->GetUser()->AutoClearQueryBuffer()) { - const CNick& Nick = Message.GetNick(); - CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick()); - if (pQuery) { - CTextMessage Format; - Format.Clone(Message); - Format.SetNick(_NAMEDFMT(Nick.GetNickMask())); - Format.SetTarget("{target}"); - Format.SetText("{text}"); - pQuery->AddBuffer(Format, Message.GetText()); - } - } - } else { - pChan = m_pNetwork->FindChan(sTarget); - if (pChan) { - Message.SetChan(pChan); - FixupChanNick(Message.GetNick(), pChan); - IRCSOCKMODULECALL(OnChanMessage(Message), &bResult); - if (bResult) return true; + if (!m_pNetwork->IsUserOnline() || + !m_pNetwork->GetUser()->AutoClearQueryBuffer()) { + const CNick& Nick = Message.GetNick(); + CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick()); + if (pQuery) { + CTextMessage Format; + Format.Clone(Message); + Format.SetNick(_NAMEDFMT(Nick.GetNickMask())); + Format.SetTarget("{target}"); + Format.SetText("{text}"); + pQuery->AddBuffer(Format, Message.GetText()); + } + } + } else { + pChan = m_pNetwork->FindChan(sTarget); + if (pChan) { + Message.SetChan(pChan); + FixupChanNick(Message.GetNick(), pChan); + IRCSOCKMODULECALL(OnChanMessage(Message), &bResult); + if (bResult) return true; - if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || - pChan->IsDetached()) { - CTextMessage Format; - Format.Clone(Message); - Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); - Format.SetTarget(_NAMEDFMT(Message.GetTarget())); - Format.SetText("{text}"); - pChan->AddBuffer(Format, Message.GetText()); - } - } - } + if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || + pChan->IsDetached()) { + CTextMessage Format; + Format.Clone(Message); + Format.SetNick(_NAMEDFMT(Message.GetNick().GetNickMask())); + Format.SetTarget(_NAMEDFMT(Message.GetTarget())); + Format.SetText("{text}"); + pChan->AddBuffer(Format, Message.GetText()); + } + } + } - return (pChan && pChan->IsDetached()); + return (pChan && pChan->IsDetached()); } bool CIRCSock::OnTopicMessage(CTopicMessage& Message) { - const CNick& Nick = Message.GetNick(); - CChan* pChan = m_pNetwork->FindChan(Message.GetParam(0)); + const CNick& Nick = Message.GetNick(); + CChan* pChan = m_pNetwork->FindChan(Message.GetParam(0)); - if (pChan) { - Message.SetChan(pChan); - bool bReturn = false; - IRCSOCKMODULECALL(OnTopicMessage(Message), &bReturn); - if (bReturn) return true; + if (pChan) { + Message.SetChan(pChan); + bool bReturn = false; + IRCSOCKMODULECALL(OnTopicMessage(Message), &bReturn); + if (bReturn) return true; - pChan->SetTopicOwner(Nick.GetNick()); - pChan->SetTopicDate((unsigned long)time(nullptr)); - pChan->SetTopic(Message.GetTopic()); - } + pChan->SetTopicOwner(Nick.GetNick()); + pChan->SetTopicDate((unsigned long)time(nullptr)); + pChan->SetTopic(Message.GetTopic()); + } - return (pChan && pChan->IsDetached()); + return (pChan && pChan->IsDetached()); } bool CIRCSock::OnWallopsMessage(CMessage& Message) { - // :blub!dummy@rox-8DBEFE92 WALLOPS :this is a test - CString sMsg = Message.GetParam(0); + // :blub!dummy@rox-8DBEFE92 WALLOPS :this is a test + CString sMsg = Message.GetParam(0); - if (!m_pNetwork->IsUserOnline()) { - CMessage Format(Message); - Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetHostMask()))); - Format.SetParam(0, "{text}"); - m_pNetwork->AddNoticeBuffer(Format, sMsg); - } - return false; + if (!m_pNetwork->IsUserOnline()) { + CMessage Format(Message); + Format.SetNick(CNick(_NAMEDFMT(Message.GetNick().GetHostMask()))); + Format.SetParam(0, "{text}"); + m_pNetwork->AddNoticeBuffer(Format, sMsg); + } + return false; } void CIRCSock::PutIRC(const CString& sLine) { - // Only print if the line won't get sent immediately (same condition as in - // TrySend()!) - if (m_bFloodProtection && m_iSendsAllowed <= 0) { - DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" - << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine - << "] (queued)"); - } - m_vsSendQueue.push_back(sLine); - TrySend(); + // Only print if the line won't get sent immediately (same condition as in + // TrySend()!) + if (m_bFloodProtection && m_iSendsAllowed <= 0) { + DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" + << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine + << "] (queued)"); + } + m_vsSendQueue.push_back(sLine); + TrySend(); } void CIRCSock::PutIRCQuick(const CString& sLine) { - // Only print if the line won't get sent immediately (same condition as in - // TrySend()!) - if (m_bFloodProtection && m_iSendsAllowed <= 0) { - DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" - << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine - << "] (queued to front)"); - } - m_vsSendQueue.push_front(sLine); - TrySend(); + // Only print if the line won't get sent immediately (same condition as in + // TrySend()!) + if (m_bFloodProtection && m_iSendsAllowed <= 0) { + DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" + << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine + << "] (queued to front)"); + } + m_vsSendQueue.push_front(sLine); + TrySend(); } void CIRCSock::TrySend() { - // This condition must be the same as in PutIRC() and PutIRCQuick()! - while (!m_vsSendQueue.empty() && - (!m_bFloodProtection || m_iSendsAllowed > 0)) { - m_iSendsAllowed--; - bool bSkip = false; - CString& sLine = m_vsSendQueue.front(); - IRCSOCKMODULECALL(OnSendToIRC(sLine), &bSkip); - if (!bSkip) { - ; - DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" - << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine - << "]"); - Write(sLine + "\r\n"); - } - m_vsSendQueue.pop_front(); - } + // This condition must be the same as in PutIRC() and PutIRCQuick()! + while (!m_vsSendQueue.empty() && + (!m_bFloodProtection || m_iSendsAllowed > 0)) { + m_iSendsAllowed--; + bool bSkip = false; + CString& sLine = m_vsSendQueue.front(); + IRCSOCKMODULECALL(OnSendToIRC(sLine), &bSkip); + if (!bSkip) { + ; + DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" + << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine + << "]"); + Write(sLine + "\r\n"); + } + m_vsSendQueue.pop_front(); + } } void CIRCSock::SetNick(const CString& sNick) { - m_Nick.SetNick(sNick); - m_pNetwork->SetIRCNick(m_Nick); + m_Nick.SetNick(sNick); + m_pNetwork->SetIRCNick(m_Nick); } void CIRCSock::Connected() { - DEBUG(GetSockName() << " == Connected()"); + DEBUG(GetSockName() << " == Connected()"); - CString sPass = m_sPass; - CString sNick = m_pNetwork->GetNick(); - CString sIdent = m_pNetwork->GetIdent(); - CString sRealName = m_pNetwork->GetRealName(); + CString sPass = m_sPass; + CString sNick = m_pNetwork->GetNick(); + CString sIdent = m_pNetwork->GetIdent(); + CString sRealName = m_pNetwork->GetRealName(); - bool bReturn = false; - IRCSOCKMODULECALL(OnIRCRegistration(sPass, sNick, sIdent, sRealName), - &bReturn); - if (bReturn) return; + bool bReturn = false; + IRCSOCKMODULECALL(OnIRCRegistration(sPass, sNick, sIdent, sRealName), + &bReturn); + if (bReturn) return; - PutIRC("CAP LS"); + PutIRC("CAP LS"); - if (!sPass.empty()) { - PutIRC("PASS " + sPass); - } + if (!sPass.empty()) { + PutIRC("PASS " + sPass); + } - PutIRC("NICK " + sNick); - PutIRC("USER " + sIdent + " \"" + sIdent + "\" \"" + sIdent + "\" :" + - sRealName); + PutIRC("NICK " + sNick); + PutIRC("USER " + sIdent + " \"" + sIdent + "\" \"" + sIdent + "\" :" + + sRealName); - // SendAltNick() needs this - m_Nick.SetNick(sNick); + // SendAltNick() needs this + m_Nick.SetNick(sNick); } void CIRCSock::Disconnected() { - IRCSOCKMODULECALL(OnIRCDisconnected(), NOTHING); + IRCSOCKMODULECALL(OnIRCDisconnected(), NOTHING); - DEBUG(GetSockName() << " == Disconnected()"); - if (!m_pNetwork->GetUser()->IsBeingDeleted() && - m_pNetwork->GetIRCConnectEnabled() && - m_pNetwork->GetServers().size() != 0) { - m_pNetwork->PutStatus("Disconnected from IRC. Reconnecting..."); - } - m_pNetwork->ClearRawBuffer(); - m_pNetwork->ClearMotdBuffer(); + DEBUG(GetSockName() << " == Disconnected()"); + if (!m_pNetwork->GetUser()->IsBeingDeleted() && + m_pNetwork->GetIRCConnectEnabled() && + m_pNetwork->GetServers().size() != 0) { + m_pNetwork->PutStatus("Disconnected from IRC. Reconnecting..."); + } + m_pNetwork->ClearRawBuffer(); + m_pNetwork->ClearMotdBuffer(); - CString sPrefix = m_pNetwork->GetUser()->GetStatusPrefix(); - for (CChan* pChan : m_pNetwork->GetChans()) { - if (pChan->IsOn()) { - m_pNetwork->PutUser( - ":" + sPrefix + "status!znc@znc.in KICK " + pChan->GetName() + - " " + GetNick() + - " :You have been disconnected from the IRC server"); - } - } + CString sPrefix = m_pNetwork->GetUser()->GetStatusPrefix(); + for (CChan* pChan : m_pNetwork->GetChans()) { + if (pChan->IsOn()) { + m_pNetwork->PutUser( + ":" + sPrefix + "status!znc@znc.in KICK " + pChan->GetName() + + " " + GetNick() + + " :You have been disconnected from the IRC server"); + } + } - ResetChans(); + ResetChans(); - // send a "reset user modes" cmd to the client. - // otherwise, on reconnect, it might think it still - // had user modes that it actually doesn't have. - CString sUserMode; - for (unsigned char cMode : m_scUserModes) { - sUserMode += cMode; - } - if (!sUserMode.empty()) { - m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + - " MODE " + m_pNetwork->GetIRCNick().GetNick() + - " :-" + sUserMode); - } + // send a "reset user modes" cmd to the client. + // otherwise, on reconnect, it might think it still + // had user modes that it actually doesn't have. + CString sUserMode; + for (unsigned char cMode : m_scUserModes) { + sUserMode += cMode; + } + if (!sUserMode.empty()) { + m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + + " MODE " + m_pNetwork->GetIRCNick().GetNick() + + " :-" + sUserMode); + } - // also clear the user modes in our space: - m_scUserModes.clear(); + // also clear the user modes in our space: + m_scUserModes.clear(); } void CIRCSock::SockError(int iErrno, const CString& sDescription) { - CString sError = sDescription; + CString sError = sDescription; - DEBUG(GetSockName() << " == SockError(" << iErrno << " " << sError << ")"); - if (!m_pNetwork->GetUser()->IsBeingDeleted()) { - if (GetConState() != CST_OK) { - m_pNetwork->PutStatus("Cannot connect to IRC (" + sError + - "). Retrying..."); - } else { - m_pNetwork->PutStatus("Disconnected from IRC (" + sError + - "). Reconnecting..."); - } + DEBUG(GetSockName() << " == SockError(" << iErrno << " " << sError << ")"); + if (!m_pNetwork->GetUser()->IsBeingDeleted()) { + if (GetConState() != CST_OK) { + m_pNetwork->PutStatus("Cannot connect to IRC (" + sError + + "). Retrying..."); + } else { + m_pNetwork->PutStatus("Disconnected from IRC (" + sError + + "). Reconnecting..."); + } #ifdef HAVE_LIBSSL - if (iErrno == errnoBadSSLCert) { - // Stringify bad cert - X509* pCert = GetX509(); - if (pCert) { - BIO* mem = BIO_new(BIO_s_mem()); - X509_print(mem, pCert); - X509_free(pCert); - char* pCertStr = nullptr; - long iLen = BIO_get_mem_data(mem, &pCertStr); - CString sCert(pCertStr, iLen); - BIO_free(mem); + if (iErrno == errnoBadSSLCert) { + // Stringify bad cert + X509* pCert = GetX509(); + if (pCert) { + BIO* mem = BIO_new(BIO_s_mem()); + X509_print(mem, pCert); + X509_free(pCert); + char* pCertStr = nullptr; + long iLen = BIO_get_mem_data(mem, &pCertStr); + CString sCert(pCertStr, iLen); + BIO_free(mem); - VCString vsCert; - sCert.Split("\n", vsCert); - for (const CString& s : vsCert) { - // It shouldn't contain any bad characters, but let's be - // safe... - m_pNetwork->PutStatus("|" + s.Escape_n(CString::EDEBUG)); - } - CString sSHA1; - if (GetPeerFingerprint(sSHA1)) - m_pNetwork->PutStatus( - "SHA1: " + - sSHA1.Escape_n(CString::EHEXCOLON, CString::EHEXCOLON)); - CString sSHA256 = GetSSLPeerFingerprint(); - m_pNetwork->PutStatus("SHA-256: " + sSHA256); - m_pNetwork->PutStatus( - "If you trust this certificate, do /znc " - "AddTrustedServerFingerprint " + - sSHA256); - } - } + VCString vsCert; + sCert.Split("\n", vsCert); + for (const CString& s : vsCert) { + // It shouldn't contain any bad characters, but let's be + // safe... + m_pNetwork->PutStatus("|" + s.Escape_n(CString::EDEBUG)); + } + CString sSHA1; + if (GetPeerFingerprint(sSHA1)) + m_pNetwork->PutStatus( + "SHA1: " + + sSHA1.Escape_n(CString::EHEXCOLON, CString::EHEXCOLON)); + CString sSHA256 = GetSSLPeerFingerprint(); + m_pNetwork->PutStatus("SHA-256: " + sSHA256); + m_pNetwork->PutStatus( + "If you trust this certificate, do /znc " + "AddTrustedServerFingerprint " + + sSHA256); + } + } #endif - } - m_pNetwork->ClearRawBuffer(); - m_pNetwork->ClearMotdBuffer(); + } + m_pNetwork->ClearRawBuffer(); + m_pNetwork->ClearMotdBuffer(); - ResetChans(); - m_scUserModes.clear(); + ResetChans(); + m_scUserModes.clear(); } void CIRCSock::Timeout() { - DEBUG(GetSockName() << " == Timeout()"); - if (!m_pNetwork->GetUser()->IsBeingDeleted()) { - m_pNetwork->PutStatus("IRC connection timed out. Reconnecting..."); - } - m_pNetwork->ClearRawBuffer(); - m_pNetwork->ClearMotdBuffer(); + DEBUG(GetSockName() << " == Timeout()"); + if (!m_pNetwork->GetUser()->IsBeingDeleted()) { + m_pNetwork->PutStatus("IRC connection timed out. Reconnecting..."); + } + m_pNetwork->ClearRawBuffer(); + m_pNetwork->ClearMotdBuffer(); - ResetChans(); - m_scUserModes.clear(); + ResetChans(); + m_scUserModes.clear(); } void CIRCSock::ConnectionRefused() { - DEBUG(GetSockName() << " == ConnectionRefused()"); - if (!m_pNetwork->GetUser()->IsBeingDeleted()) { - m_pNetwork->PutStatus("Connection Refused. Reconnecting..."); - } - m_pNetwork->ClearRawBuffer(); - m_pNetwork->ClearMotdBuffer(); + DEBUG(GetSockName() << " == ConnectionRefused()"); + if (!m_pNetwork->GetUser()->IsBeingDeleted()) { + m_pNetwork->PutStatus("Connection Refused. Reconnecting..."); + } + m_pNetwork->ClearRawBuffer(); + m_pNetwork->ClearMotdBuffer(); } void CIRCSock::ReachedMaxBuffer() { - DEBUG(GetSockName() << " == ReachedMaxBuffer()"); - m_pNetwork->PutStatus("Received a too long line from the IRC server!"); - Quit(); + DEBUG(GetSockName() << " == ReachedMaxBuffer()"); + m_pNetwork->PutStatus("Received a too long line from the IRC server!"); + Quit(); } void CIRCSock::ParseISupport(const CMessage& Message) { - const VCString vsParams = Message.GetParams(); + const VCString vsParams = Message.GetParams(); - for (size_t i = 1; i < vsParams.size() - 1; ++i) { - const CString& sParam = vsParams[i]; - CString sName = sParam.Token(0, false, "="); - CString sValue = sParam.Token(1, true, "="); + for (size_t i = 1; i < vsParams.size() - 1; ++i) { + const CString& sParam = vsParams[i]; + CString sName = sParam.Token(0, false, "="); + CString sValue = sParam.Token(1, true, "="); - if (0 < sName.length() && ':' == sName[0]) { - break; - } + if (0 < sName.length() && ':' == sName[0]) { + break; + } - m_mISupport[sName] = sValue; + m_mISupport[sName] = sValue; - if (sName.Equals("PREFIX")) { - CString sPrefixes = sValue.Token(1, false, ")"); - CString sPermModes = sValue.Token(0, false, ")"); - sPermModes.TrimLeft("("); + if (sName.Equals("PREFIX")) { + CString sPrefixes = sValue.Token(1, false, ")"); + CString sPermModes = sValue.Token(0, false, ")"); + sPermModes.TrimLeft("("); - if (!sPrefixes.empty() && sPermModes.size() == sPrefixes.size()) { - m_sPerms = sPrefixes; - m_sPermModes = sPermModes; - } - } else if (sName.Equals("CHANTYPES")) { - m_pNetwork->SetChanPrefixes(sValue); - } else if (sName.Equals("NICKLEN")) { - unsigned int uMax = sValue.ToUInt(); + if (!sPrefixes.empty() && sPermModes.size() == sPrefixes.size()) { + m_sPerms = sPrefixes; + m_sPermModes = sPermModes; + } + } else if (sName.Equals("CHANTYPES")) { + m_pNetwork->SetChanPrefixes(sValue); + } else if (sName.Equals("NICKLEN")) { + unsigned int uMax = sValue.ToUInt(); - if (uMax) { - m_uMaxNickLen = uMax; - } - } else if (sName.Equals("CHANMODES")) { - if (!sValue.empty()) { - m_mueChanModes.clear(); + if (uMax) { + m_uMaxNickLen = uMax; + } + } else if (sName.Equals("CHANMODES")) { + if (!sValue.empty()) { + m_mueChanModes.clear(); - for (unsigned int a = 0; a < 4; a++) { - CString sModes = sValue.Token(a, false, ","); + for (unsigned int a = 0; a < 4; a++) { + CString sModes = sValue.Token(a, false, ","); - for (unsigned int b = 0; b < sModes.size(); b++) { - m_mueChanModes[sModes[b]] = (EChanModeArgs)a; - } - } - } - } else if (sName.Equals("NAMESX")) { - if (m_bNamesx) continue; - m_bNamesx = true; - PutIRC("PROTOCTL NAMESX"); - } else if (sName.Equals("UHNAMES")) { - if (m_bUHNames) continue; - m_bUHNames = true; - PutIRC("PROTOCTL UHNAMES"); - } - } + for (unsigned int b = 0; b < sModes.size(); b++) { + m_mueChanModes[sModes[b]] = (EChanModeArgs)a; + } + } + } + } else if (sName.Equals("NAMESX")) { + if (m_bNamesx) continue; + m_bNamesx = true; + PutIRC("PROTOCTL NAMESX"); + } else if (sName.Equals("UHNAMES")) { + if (m_bUHNames) continue; + m_bUHNames = true; + PutIRC("PROTOCTL UHNAMES"); + } + } } CString CIRCSock::GetISupport(const CString& sKey, const CString& sDefault) const { - MCString::const_iterator i = m_mISupport.find(sKey.AsUpper()); - if (i == m_mISupport.end()) { - return sDefault; - } else { - return i->second; - } + MCString::const_iterator i = m_mISupport.find(sKey.AsUpper()); + if (i == m_mISupport.end()) { + return sDefault; + } else { + return i->second; + } } void CIRCSock::SendAltNick(const CString& sBadNick) { - const CString& sLastNick = m_Nick.GetNick(); + const CString& sLastNick = m_Nick.GetNick(); - // We don't know the maximum allowed nick length yet, but we know which - // nick we sent last. If sBadNick is shorter than that, we assume the - // server truncated our nick. - if (sBadNick.length() < sLastNick.length()) - m_uMaxNickLen = (unsigned int)sBadNick.length(); + // We don't know the maximum allowed nick length yet, but we know which + // nick we sent last. If sBadNick is shorter than that, we assume the + // server truncated our nick. + if (sBadNick.length() < sLastNick.length()) + m_uMaxNickLen = (unsigned int)sBadNick.length(); - unsigned int uMax = m_uMaxNickLen; + unsigned int uMax = m_uMaxNickLen; - const CString& sConfNick = m_pNetwork->GetNick(); - const CString& sAltNick = m_pNetwork->GetAltNick(); - CString sNewNick = sConfNick.Left(uMax - 1); + const CString& sConfNick = m_pNetwork->GetNick(); + const CString& sAltNick = m_pNetwork->GetAltNick(); + CString sNewNick = sConfNick.Left(uMax - 1); - if (sLastNick.Equals(sConfNick)) { - if ((!sAltNick.empty()) && (!sConfNick.Equals(sAltNick))) { - sNewNick = sAltNick; - } else { - sNewNick += "-"; - } - } else if (sLastNick.Equals(sAltNick) && !sAltNick.Equals(sNewNick + "-")) { - sNewNick += "-"; - } else if (sLastNick.Equals(sNewNick + "-") && - !sAltNick.Equals(sNewNick + "|")) { - sNewNick += "|"; - } else if (sLastNick.Equals(sNewNick + "|") && - !sAltNick.Equals(sNewNick + "^")) { - sNewNick += "^"; - } else if (sLastNick.Equals(sNewNick + "^") && - !sAltNick.Equals(sNewNick + "a")) { - sNewNick += "a"; - } else { - char cLetter = 0; - if (sBadNick.empty()) { - m_pNetwork->PutUser("No free nick available"); - Quit(); - return; - } + if (sLastNick.Equals(sConfNick)) { + if ((!sAltNick.empty()) && (!sConfNick.Equals(sAltNick))) { + sNewNick = sAltNick; + } else { + sNewNick += "-"; + } + } else if (sLastNick.Equals(sAltNick) && !sAltNick.Equals(sNewNick + "-")) { + sNewNick += "-"; + } else if (sLastNick.Equals(sNewNick + "-") && + !sAltNick.Equals(sNewNick + "|")) { + sNewNick += "|"; + } else if (sLastNick.Equals(sNewNick + "|") && + !sAltNick.Equals(sNewNick + "^")) { + sNewNick += "^"; + } else if (sLastNick.Equals(sNewNick + "^") && + !sAltNick.Equals(sNewNick + "a")) { + sNewNick += "a"; + } else { + char cLetter = 0; + if (sBadNick.empty()) { + m_pNetwork->PutUser("No free nick available"); + Quit(); + return; + } - cLetter = sBadNick.back(); + cLetter = sBadNick.back(); - if (cLetter == 'z') { - m_pNetwork->PutUser("No free nick found"); - Quit(); - return; - } + if (cLetter == 'z') { + m_pNetwork->PutUser("No free nick found"); + Quit(); + return; + } - sNewNick = sConfNick.Left(uMax - 1) + ++cLetter; - if (sNewNick.Equals(sAltNick)) - sNewNick = sConfNick.Left(uMax - 1) + ++cLetter; - } - PutIRC("NICK " + sNewNick); - m_Nick.SetNick(sNewNick); + sNewNick = sConfNick.Left(uMax - 1) + ++cLetter; + if (sNewNick.Equals(sAltNick)) + sNewNick = sConfNick.Left(uMax - 1) + ++cLetter; + } + PutIRC("NICK " + sNewNick); + m_Nick.SetNick(sNewNick); } unsigned char CIRCSock::GetPermFromMode(unsigned char uMode) const { - if (m_sPermModes.size() == m_sPerms.size()) { - for (unsigned int a = 0; a < m_sPermModes.size(); a++) { - if (m_sPermModes[a] == uMode) { - return m_sPerms[a]; - } - } - } + if (m_sPermModes.size() == m_sPerms.size()) { + for (unsigned int a = 0; a < m_sPermModes.size(); a++) { + if (m_sPermModes[a] == uMode) { + return m_sPerms[a]; + } + } + } - return 0; + return 0; } CIRCSock::EChanModeArgs CIRCSock::GetModeType(unsigned char uMode) const { - map::const_iterator it = - m_mueChanModes.find(uMode); + map::const_iterator it = + m_mueChanModes.find(uMode); - if (it == m_mueChanModes.end()) { - return NoArg; - } + if (it == m_mueChanModes.end()) { + return NoArg; + } - return it->second; + return it->second; } void CIRCSock::ResetChans() { - for (const auto& it : m_msChans) { - it.second->Reset(); - } + for (const auto& it : m_msChans) { + it.second->Reset(); + } } diff --git a/src/Listener.cpp b/src/Listener.cpp index 3f18d73c..dffd6ab1 100644 --- a/src/Listener.cpp +++ b/src/Listener.cpp @@ -18,34 +18,34 @@ #include CListener::~CListener() { - if (m_pListener) CZNC::Get().GetManager().DelSockByAddr(m_pListener); + if (m_pListener) CZNC::Get().GetManager().DelSockByAddr(m_pListener); } bool CListener::Listen() { - if (!m_uPort || m_pListener) { - errno = EINVAL; - return false; - } + if (!m_uPort || m_pListener) { + errno = EINVAL; + return false; + } - m_pListener = new CRealListener(*this); + m_pListener = new CRealListener(*this); - bool bSSL = false; + bool bSSL = false; #ifdef HAVE_LIBSSL - if (IsSSL()) { - bSSL = true; - m_pListener->SetPemLocation(CZNC::Get().GetPemLocation()); - m_pListener->SetKeyLocation(CZNC::Get().GetKeyLocation()); - m_pListener->SetDHParamLocation(CZNC::Get().GetDHParamLocation()); - } + if (IsSSL()) { + bSSL = true; + m_pListener->SetPemLocation(CZNC::Get().GetPemLocation()); + m_pListener->SetKeyLocation(CZNC::Get().GetKeyLocation()); + m_pListener->SetDHParamLocation(CZNC::Get().GetDHParamLocation()); + } #endif - // If e.g. getaddrinfo() fails, the following might not set errno. - // Make sure there is a consistent error message, not something random - // which might even be "Error: Success". - errno = EINVAL; - return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", - m_sBindHost, bSSL, SOMAXCONN, - m_pListener, 0, m_eAddr); + // If e.g. getaddrinfo() fails, the following might not set errno. + // Make sure there is a consistent error message, not something random + // which might even be "Error: Success". + errno = EINVAL; + return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", + m_sBindHost, bSSL, SOMAXCONN, + m_pListener, 0, m_eAddr); } void CListener::ResetRealListener() { m_pListener = nullptr; } @@ -53,42 +53,42 @@ void CListener::ResetRealListener() { m_pListener = nullptr; } CRealListener::~CRealListener() { m_Listener.ResetRealListener(); } bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) { - bool bHostAllowed = CZNC::Get().IsHostAllowed(sHost); - DEBUG(GetSockName() << " == ConnectionFrom(" << sHost << ", " << uPort - << ") [" << (bHostAllowed ? "Allowed" : "Not allowed") - << "]"); - return bHostAllowed; + bool bHostAllowed = CZNC::Get().IsHostAllowed(sHost); + DEBUG(GetSockName() << " == ConnectionFrom(" << sHost << ", " << uPort + << ") [" << (bHostAllowed ? "Allowed" : "Not allowed") + << "]"); + return bHostAllowed; } Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) { - CIncomingConnection* pClient = new CIncomingConnection( - sHost, uPort, m_Listener.GetAcceptType(), m_Listener.GetURIPrefix()); - if (CZNC::Get().AllowConnectionFrom(sHost)) { - GLOBALMODULECALL(OnClientConnect(pClient, sHost, uPort), NOTHING); - } else { - pClient->Write( - ":irc.znc.in 464 unknown-nick :Too many anonymous connections from " - "your IP\r\n"); - pClient->Close(Csock::CLT_AFTERWRITE); - GLOBALMODULECALL(OnFailedLogin("", sHost), NOTHING); - } - return pClient; + CIncomingConnection* pClient = new CIncomingConnection( + sHost, uPort, m_Listener.GetAcceptType(), m_Listener.GetURIPrefix()); + if (CZNC::Get().AllowConnectionFrom(sHost)) { + GLOBALMODULECALL(OnClientConnect(pClient, sHost, uPort), NOTHING); + } else { + pClient->Write( + ":irc.znc.in 464 unknown-nick :Too many anonymous connections from " + "your IP\r\n"); + pClient->Close(Csock::CLT_AFTERWRITE); + GLOBALMODULECALL(OnFailedLogin("", sHost), NOTHING); + } + return pClient; } void CRealListener::SockError(int iErrno, const CString& sDescription) { - DEBUG(GetSockName() << " == SockError(" << sDescription << ", " - << strerror(iErrno) << ")"); - if (iErrno == EMFILE) { - // We have too many open fds, let's close this listening port to be able - // to continue - // to work, next rehash will (try to) reopen it. - CZNC::Get().Broadcast( - "We hit the FD limit, closing listening socket on [" + - GetLocalIP() + " : " + CString(GetLocalPort()) + "]"); - CZNC::Get().Broadcast( - "An admin has to rehash to reopen the listening port"); - Close(); - } + DEBUG(GetSockName() << " == SockError(" << sDescription << ", " + << strerror(iErrno) << ")"); + if (iErrno == EMFILE) { + // We have too many open fds, let's close this listening port to be able + // to continue + // to work, next rehash will (try to) reopen it. + CZNC::Get().Broadcast( + "We hit the FD limit, closing listening socket on [" + + GetLocalIP() + " : " + CString(GetLocalPort()) + "]"); + CZNC::Get().Broadcast( + "An admin has to rehash to reopen the listening port"); + Close(); + } } CIncomingConnection::CIncomingConnection(const CString& sHostname, @@ -98,71 +98,71 @@ CIncomingConnection::CIncomingConnection(const CString& sHostname, : CZNCSock(sHostname, uPort), m_eAcceptType(eAcceptType), m_sURIPrefix(sURIPrefix) { - // The socket will time out in 120 secs, no matter what. - // This has to be fixed up later, if desired. - SetTimeout(120, 0); + // The socket will time out in 120 secs, no matter what. + // This has to be fixed up later, if desired. + SetTimeout(120, 0); - SetEncoding("UTF-8"); - EnableReadLine(); + SetEncoding("UTF-8"); + EnableReadLine(); } void CIncomingConnection::ReachedMaxBuffer() { - if (GetCloseType() != CLT_DONT) return; // Already closing + if (GetCloseType() != CLT_DONT) return; // Already closing - // We don't actually SetMaxBufferThreshold() because that would be - // inherited by sockets after SwapSockByAddr(). - if (GetInternalReadBuffer().length() <= 4096) return; + // We don't actually SetMaxBufferThreshold() because that would be + // inherited by sockets after SwapSockByAddr(). + if (GetInternalReadBuffer().length() <= 4096) return; - // We should never get here with legitimate requests :/ - Close(); + // We should never get here with legitimate requests :/ + Close(); } void CIncomingConnection::ReadLine(const CString& sLine) { - bool bIsHTTP = (sLine.WildCmp("GET * HTTP/1.?\r\n") || - sLine.WildCmp("POST * HTTP/1.?\r\n")); - bool bAcceptHTTP = (m_eAcceptType == CListener::ACCEPT_ALL) || - (m_eAcceptType == CListener::ACCEPT_HTTP); - bool bAcceptIRC = (m_eAcceptType == CListener::ACCEPT_ALL) || - (m_eAcceptType == CListener::ACCEPT_IRC); - Csock* pSock = nullptr; + bool bIsHTTP = (sLine.WildCmp("GET * HTTP/1.?\r\n") || + sLine.WildCmp("POST * HTTP/1.?\r\n")); + bool bAcceptHTTP = (m_eAcceptType == CListener::ACCEPT_ALL) || + (m_eAcceptType == CListener::ACCEPT_HTTP); + bool bAcceptIRC = (m_eAcceptType == CListener::ACCEPT_ALL) || + (m_eAcceptType == CListener::ACCEPT_IRC); + Csock* pSock = nullptr; - if (!bIsHTTP) { - // Let's assume it's an IRC connection + if (!bIsHTTP) { + // Let's assume it's an IRC connection - if (!bAcceptIRC) { - Write("ERROR :We don't take kindly to your types around here!\r\n"); - Close(CLT_AFTERWRITE); + if (!bAcceptIRC) { + Write("ERROR :We don't take kindly to your types around here!\r\n"); + Close(CLT_AFTERWRITE); - DEBUG("Refused IRC connection to non IRC port"); - return; - } + DEBUG("Refused IRC connection to non IRC port"); + return; + } - pSock = new CClient(); - CZNC::Get().GetManager().SwapSockByAddr(pSock, this); + pSock = new CClient(); + CZNC::Get().GetManager().SwapSockByAddr(pSock, this); - // And don't forget to give it some sane name / timeout - pSock->SetSockName("USR::???"); - } else { - // This is a HTTP request, let the webmods handle it + // And don't forget to give it some sane name / timeout + pSock->SetSockName("USR::???"); + } else { + // This is a HTTP request, let the webmods handle it - if (!bAcceptHTTP) { - Write( - "HTTP/1.0 403 Access Denied\r\n\r\nWeb Access is not " - "enabled.\r\n"); - Close(CLT_AFTERWRITE); + if (!bAcceptHTTP) { + Write( + "HTTP/1.0 403 Access Denied\r\n\r\nWeb Access is not " + "enabled.\r\n"); + Close(CLT_AFTERWRITE); - DEBUG("Refused HTTP connection to non HTTP port"); - return; - } + DEBUG("Refused HTTP connection to non HTTP port"); + return; + } - pSock = new CWebSock(m_sURIPrefix); - CZNC::Get().GetManager().SwapSockByAddr(pSock, this); + pSock = new CWebSock(m_sURIPrefix); + CZNC::Get().GetManager().SwapSockByAddr(pSock, this); - // And don't forget to give it some sane name / timeout - pSock->SetSockName("WebMod::Client"); - } + // And don't forget to give it some sane name / timeout + pSock->SetSockName("WebMod::Client"); + } - // TODO can we somehow get rid of this? - pSock->ReadLine(sLine); - pSock->PushBuff("", 0, true); + // TODO can we somehow get rid of this? + pSock->ReadLine(sLine); + pSock->PushBuff("", 0, true); } diff --git a/src/MD5.cpp b/src/MD5.cpp index dd740c54..9f2cdaa7 100644 --- a/src/MD5.cpp +++ b/src/MD5.cpp @@ -32,181 +32,181 @@ CMD5::CMD5(const char* szText, uint32 nTextLen) { MakeHash(szText, nTextLen); } CMD5::~CMD5() {} #define GET_UINT32(n, b, i) \ - { \ - (n) = ((uint32)(b)[(i)]) | ((uint32)(b)[(i)+1] << 8) | \ - ((uint32)(b)[(i)+2] << 16) | ((uint32)(b)[(i)+3] << 24); \ - } + { \ + (n) = ((uint32)(b)[(i)]) | ((uint32)(b)[(i)+1] << 8) | \ + ((uint32)(b)[(i)+2] << 16) | ((uint32)(b)[(i)+3] << 24); \ + } #define PUT_UINT32(n, b, i) \ - { \ - (b)[(i)] = (uint8)((n)); \ - (b)[(i)+1] = (uint8)((n) >> 8); \ - (b)[(i)+2] = (uint8)((n) >> 16); \ - (b)[(i)+3] = (uint8)((n) >> 24); \ - } + { \ + (b)[(i)] = (uint8)((n)); \ + (b)[(i)+1] = (uint8)((n) >> 8); \ + (b)[(i)+2] = (uint8)((n) >> 16); \ + (b)[(i)+3] = (uint8)((n) >> 24); \ + } void CMD5::md5_starts(md5_context* ctx) const { - ctx->total[0] = 0; - ctx->total[1] = 0; + ctx->total[0] = 0; + ctx->total[1] = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; } void CMD5::md5_process(md5_context* ctx, const uint8 data[64]) const { - uint32 X[16], A, B, C, D; + uint32 X[16], A, B, C, D; - GET_UINT32(X[0], data, 0); - GET_UINT32(X[1], data, 4); - GET_UINT32(X[2], data, 8); - GET_UINT32(X[3], data, 12); - GET_UINT32(X[4], data, 16); - GET_UINT32(X[5], data, 20); - GET_UINT32(X[6], data, 24); - GET_UINT32(X[7], data, 28); - GET_UINT32(X[8], data, 32); - GET_UINT32(X[9], data, 36); - GET_UINT32(X[10], data, 40); - GET_UINT32(X[11], data, 44); - GET_UINT32(X[12], data, 48); - GET_UINT32(X[13], data, 52); - GET_UINT32(X[14], data, 56); - GET_UINT32(X[15], data, 60); + GET_UINT32(X[0], data, 0); + GET_UINT32(X[1], data, 4); + GET_UINT32(X[2], data, 8); + GET_UINT32(X[3], data, 12); + GET_UINT32(X[4], data, 16); + GET_UINT32(X[5], data, 20); + GET_UINT32(X[6], data, 24); + GET_UINT32(X[7], data, 28); + GET_UINT32(X[8], data, 32); + GET_UINT32(X[9], data, 36); + GET_UINT32(X[10], data, 40); + GET_UINT32(X[11], data, 44); + GET_UINT32(X[12], data, 48); + GET_UINT32(X[13], data, 52); + GET_UINT32(X[14], data, 56); + GET_UINT32(X[15], data, 60); #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define P(a, b, c, d, k, s, t) \ - a += F(b, c, d) + X[k] + t; \ - a = S(a, s) + b; + a += F(b, c, d) + X[k] + t; \ + a = S(a, s) + b; - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; #define F(x, y, z) (z ^ (x & (y ^ z))) - P(A, B, C, D, 0, 7, 0xD76AA478); - P(D, A, B, C, 1, 12, 0xE8C7B756); - P(C, D, A, B, 2, 17, 0x242070DB); - P(B, C, D, A, 3, 22, 0xC1BDCEEE); - P(A, B, C, D, 4, 7, 0xF57C0FAF); - P(D, A, B, C, 5, 12, 0x4787C62A); - P(C, D, A, B, 6, 17, 0xA8304613); - P(B, C, D, A, 7, 22, 0xFD469501); - P(A, B, C, D, 8, 7, 0x698098D8); - P(D, A, B, C, 9, 12, 0x8B44F7AF); - P(C, D, A, B, 10, 17, 0xFFFF5BB1); - P(B, C, D, A, 11, 22, 0x895CD7BE); - P(A, B, C, D, 12, 7, 0x6B901122); - P(D, A, B, C, 13, 12, 0xFD987193); - P(C, D, A, B, 14, 17, 0xA679438E); - P(B, C, D, A, 15, 22, 0x49B40821); + P(A, B, C, D, 0, 7, 0xD76AA478); + P(D, A, B, C, 1, 12, 0xE8C7B756); + P(C, D, A, B, 2, 17, 0x242070DB); + P(B, C, D, A, 3, 22, 0xC1BDCEEE); + P(A, B, C, D, 4, 7, 0xF57C0FAF); + P(D, A, B, C, 5, 12, 0x4787C62A); + P(C, D, A, B, 6, 17, 0xA8304613); + P(B, C, D, A, 7, 22, 0xFD469501); + P(A, B, C, D, 8, 7, 0x698098D8); + P(D, A, B, C, 9, 12, 0x8B44F7AF); + P(C, D, A, B, 10, 17, 0xFFFF5BB1); + P(B, C, D, A, 11, 22, 0x895CD7BE); + P(A, B, C, D, 12, 7, 0x6B901122); + P(D, A, B, C, 13, 12, 0xFD987193); + P(C, D, A, B, 14, 17, 0xA679438E); + P(B, C, D, A, 15, 22, 0x49B40821); #undef F #define F(x, y, z) (y ^ (z & (x ^ y))) - P(A, B, C, D, 1, 5, 0xF61E2562); - P(D, A, B, C, 6, 9, 0xC040B340); - P(C, D, A, B, 11, 14, 0x265E5A51); - P(B, C, D, A, 0, 20, 0xE9B6C7AA); - P(A, B, C, D, 5, 5, 0xD62F105D); - P(D, A, B, C, 10, 9, 0x02441453); - P(C, D, A, B, 15, 14, 0xD8A1E681); - P(B, C, D, A, 4, 20, 0xE7D3FBC8); - P(A, B, C, D, 9, 5, 0x21E1CDE6); - P(D, A, B, C, 14, 9, 0xC33707D6); - P(C, D, A, B, 3, 14, 0xF4D50D87); - P(B, C, D, A, 8, 20, 0x455A14ED); - P(A, B, C, D, 13, 5, 0xA9E3E905); - P(D, A, B, C, 2, 9, 0xFCEFA3F8); - P(C, D, A, B, 7, 14, 0x676F02D9); - P(B, C, D, A, 12, 20, 0x8D2A4C8A); + P(A, B, C, D, 1, 5, 0xF61E2562); + P(D, A, B, C, 6, 9, 0xC040B340); + P(C, D, A, B, 11, 14, 0x265E5A51); + P(B, C, D, A, 0, 20, 0xE9B6C7AA); + P(A, B, C, D, 5, 5, 0xD62F105D); + P(D, A, B, C, 10, 9, 0x02441453); + P(C, D, A, B, 15, 14, 0xD8A1E681); + P(B, C, D, A, 4, 20, 0xE7D3FBC8); + P(A, B, C, D, 9, 5, 0x21E1CDE6); + P(D, A, B, C, 14, 9, 0xC33707D6); + P(C, D, A, B, 3, 14, 0xF4D50D87); + P(B, C, D, A, 8, 20, 0x455A14ED); + P(A, B, C, D, 13, 5, 0xA9E3E905); + P(D, A, B, C, 2, 9, 0xFCEFA3F8); + P(C, D, A, B, 7, 14, 0x676F02D9); + P(B, C, D, A, 12, 20, 0x8D2A4C8A); #undef F #define F(x, y, z) (x ^ y ^ z) - P(A, B, C, D, 5, 4, 0xFFFA3942); - P(D, A, B, C, 8, 11, 0x8771F681); - P(C, D, A, B, 11, 16, 0x6D9D6122); - P(B, C, D, A, 14, 23, 0xFDE5380C); - P(A, B, C, D, 1, 4, 0xA4BEEA44); - P(D, A, B, C, 4, 11, 0x4BDECFA9); - P(C, D, A, B, 7, 16, 0xF6BB4B60); - P(B, C, D, A, 10, 23, 0xBEBFBC70); - P(A, B, C, D, 13, 4, 0x289B7EC6); - P(D, A, B, C, 0, 11, 0xEAA127FA); - P(C, D, A, B, 3, 16, 0xD4EF3085); - P(B, C, D, A, 6, 23, 0x04881D05); - P(A, B, C, D, 9, 4, 0xD9D4D039); - P(D, A, B, C, 12, 11, 0xE6DB99E5); - P(C, D, A, B, 15, 16, 0x1FA27CF8); - P(B, C, D, A, 2, 23, 0xC4AC5665); + P(A, B, C, D, 5, 4, 0xFFFA3942); + P(D, A, B, C, 8, 11, 0x8771F681); + P(C, D, A, B, 11, 16, 0x6D9D6122); + P(B, C, D, A, 14, 23, 0xFDE5380C); + P(A, B, C, D, 1, 4, 0xA4BEEA44); + P(D, A, B, C, 4, 11, 0x4BDECFA9); + P(C, D, A, B, 7, 16, 0xF6BB4B60); + P(B, C, D, A, 10, 23, 0xBEBFBC70); + P(A, B, C, D, 13, 4, 0x289B7EC6); + P(D, A, B, C, 0, 11, 0xEAA127FA); + P(C, D, A, B, 3, 16, 0xD4EF3085); + P(B, C, D, A, 6, 23, 0x04881D05); + P(A, B, C, D, 9, 4, 0xD9D4D039); + P(D, A, B, C, 12, 11, 0xE6DB99E5); + P(C, D, A, B, 15, 16, 0x1FA27CF8); + P(B, C, D, A, 2, 23, 0xC4AC5665); #undef F #define F(x, y, z) (y ^ (x | ~z)) - P(A, B, C, D, 0, 6, 0xF4292244); - P(D, A, B, C, 7, 10, 0x432AFF97); - P(C, D, A, B, 14, 15, 0xAB9423A7); - P(B, C, D, A, 5, 21, 0xFC93A039); - P(A, B, C, D, 12, 6, 0x655B59C3); - P(D, A, B, C, 3, 10, 0x8F0CCC92); - P(C, D, A, B, 10, 15, 0xFFEFF47D); - P(B, C, D, A, 1, 21, 0x85845DD1); - P(A, B, C, D, 8, 6, 0x6FA87E4F); - P(D, A, B, C, 15, 10, 0xFE2CE6E0); - P(C, D, A, B, 6, 15, 0xA3014314); - P(B, C, D, A, 13, 21, 0x4E0811A1); - P(A, B, C, D, 4, 6, 0xF7537E82); - P(D, A, B, C, 11, 10, 0xBD3AF235); - P(C, D, A, B, 2, 15, 0x2AD7D2BB); - P(B, C, D, A, 9, 21, 0xEB86D391); + P(A, B, C, D, 0, 6, 0xF4292244); + P(D, A, B, C, 7, 10, 0x432AFF97); + P(C, D, A, B, 14, 15, 0xAB9423A7); + P(B, C, D, A, 5, 21, 0xFC93A039); + P(A, B, C, D, 12, 6, 0x655B59C3); + P(D, A, B, C, 3, 10, 0x8F0CCC92); + P(C, D, A, B, 10, 15, 0xFFEFF47D); + P(B, C, D, A, 1, 21, 0x85845DD1); + P(A, B, C, D, 8, 6, 0x6FA87E4F); + P(D, A, B, C, 15, 10, 0xFE2CE6E0); + P(C, D, A, B, 6, 15, 0xA3014314); + P(B, C, D, A, 13, 21, 0x4E0811A1); + P(A, B, C, D, 4, 6, 0xF7537E82); + P(D, A, B, C, 11, 10, 0xBD3AF235); + P(C, D, A, B, 2, 15, 0x2AD7D2BB); + P(B, C, D, A, 9, 21, 0xEB86D391); #undef F - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; } void CMD5::md5_update(md5_context* ctx, const uint8* input, uint32 length) const { - uint32 left, fill; + uint32 left, fill; - if (!length) return; + if (!length) return; - left = ctx->total[0] & 0x3F; - fill = 64 - left; + left = ctx->total[0] & 0x3F; + fill = 64 - left; - ctx->total[0] += length; - ctx->total[0] &= 0xFFFFFFFF; + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; - if (ctx->total[0] < length) ctx->total[1]++; + if (ctx->total[0] < length) ctx->total[1]++; - if (left && length >= fill) { - memcpy((void*)(ctx->buffer + left), (void*)input, fill); - md5_process(ctx, ctx->buffer); - length -= fill; - input += fill; - left = 0; - } + if (left && length >= fill) { + memcpy((void*)(ctx->buffer + left), (void*)input, fill); + md5_process(ctx, ctx->buffer); + length -= fill; + input += fill; + left = 0; + } - while (length >= 64) { - md5_process(ctx, input); - length -= 64; - input += 64; - } + while (length >= 64) { + md5_process(ctx, input); + length -= 64; + input += 64; + } - if (length) { - memcpy((void*)(ctx->buffer + left), (void*)input, length); - } + if (length) { + memcpy((void*)(ctx->buffer + left), (void*)input, length); + } } static const uint8 md5_padding[64] = { @@ -215,41 +215,41 @@ static const uint8 md5_padding[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void CMD5::md5_finish(md5_context* ctx, uint8 digest[16]) const { - uint32 last, padn; - uint32 high, low; - uint8 msglen[8]; + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; - high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); - PUT_UINT32(low, msglen, 0); - PUT_UINT32(high, msglen, 4); + PUT_UINT32(low, msglen, 0); + PUT_UINT32(high, msglen, 4); - last = ctx->total[0] & 0x3F; - padn = (last < 56) ? (56 - last) : (120 - last); + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); - md5_update(ctx, md5_padding, padn); - md5_update(ctx, msglen, 8); + md5_update(ctx, md5_padding, padn); + md5_update(ctx, msglen, 8); - PUT_UINT32(ctx->state[0], digest, 0); - PUT_UINT32(ctx->state[1], digest, 4); - PUT_UINT32(ctx->state[2], digest, 8); - PUT_UINT32(ctx->state[3], digest, 12); + PUT_UINT32(ctx->state[0], digest, 0); + PUT_UINT32(ctx->state[1], digest, 4); + PUT_UINT32(ctx->state[2], digest, 8); + PUT_UINT32(ctx->state[3], digest, 12); } char* CMD5::MakeHash(const char* szText, uint32 nTextLen) { - md5_context ctx; - unsigned char md5sum[16]; + md5_context ctx; + unsigned char md5sum[16]; - md5_starts(&ctx); - md5_update(&ctx, (uint8*)szText, nTextLen); - md5_finish(&ctx, md5sum); + md5_starts(&ctx); + md5_update(&ctx, (uint8*)szText, nTextLen); + md5_finish(&ctx, md5sum); - sprintf(m_szMD5, - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], - md5sum[6], md5sum[7], md5sum[8], md5sum[9], md5sum[10], md5sum[11], - md5sum[12], md5sum[13], md5sum[14], md5sum[15]); + sprintf(m_szMD5, + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], + md5sum[6], md5sum[7], md5sum[8], md5sum[9], md5sum[10], md5sum[11], + md5sum[12], md5sum[13], md5sum[14], md5sum[15]); - return m_szMD5; + return m_szMD5; } diff --git a/src/Message.cpp b/src/Message.cpp index dac57564..55d4e94c 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -18,8 +18,8 @@ #include CMessage::CMessage(const CString& sMessage) { - Parse(sMessage); - InitTime(); + Parse(sMessage); + InitTime(); } CMessage::CMessage(const CNick& Nick, const CString& sCommand, @@ -28,254 +28,254 @@ CMessage::CMessage(const CNick& Nick, const CString& sCommand, m_sCommand(sCommand), m_vsParams(vsParams), m_mssTags(mssTags) { - InitTime(); + InitTime(); } bool CMessage::Equals(const CMessage& Other) const { - return m_Nick.NickEquals(Other.GetNick().GetNick()) && - m_sCommand.Equals(Other.GetCommand()) && - m_vsParams == Other.GetParams(); + return m_Nick.NickEquals(Other.GetNick().GetNick()) && + m_sCommand.Equals(Other.GetCommand()) && + m_vsParams == Other.GetParams(); } void CMessage::Clone(const CMessage& Message) { - if (&Message != this) { - *this = Message; - } + if (&Message != this) { + *this = Message; + } } void CMessage::SetCommand(const CString& sCommand) { - m_sCommand = sCommand; - InitType(); + m_sCommand = sCommand; + InitType(); } CString CMessage::GetParams(unsigned int uIdx, unsigned int uLen) const { - if (m_vsParams.empty() || uLen == 0) { - return ""; - } - if (uLen > m_vsParams.size() - uIdx - 1) { - uLen = m_vsParams.size() - uIdx; - } - VCString vsParams; - unsigned uParams = m_vsParams.size(); - for (unsigned int i = uIdx; i < uIdx + uLen; ++i) { - CString sParam = m_vsParams[i]; - if (i == uParams - 1 && - (m_bColon || sParam.empty() || sParam.StartsWith(":") || - sParam.Contains(" "))) { - sParam = ":" + sParam; - } - vsParams.push_back(sParam); - } - return CString(" ").Join(vsParams.begin(), vsParams.end()); + if (m_vsParams.empty() || uLen == 0) { + return ""; + } + if (uLen > m_vsParams.size() - uIdx - 1) { + uLen = m_vsParams.size() - uIdx; + } + VCString vsParams; + unsigned uParams = m_vsParams.size(); + for (unsigned int i = uIdx; i < uIdx + uLen; ++i) { + CString sParam = m_vsParams[i]; + if (i == uParams - 1 && + (m_bColon || sParam.empty() || sParam.StartsWith(":") || + sParam.Contains(" "))) { + sParam = ":" + sParam; + } + vsParams.push_back(sParam); + } + return CString(" ").Join(vsParams.begin(), vsParams.end()); } void CMessage::SetParams(const VCString& vsParams) { - m_vsParams = vsParams; - m_bColon = false; + m_vsParams = vsParams; + m_bColon = false; - if (m_eType == Type::Text || m_eType == Type::Notice || - m_eType == Type::Action || m_eType == Type::CTCP) { - InitType(); - } + if (m_eType == Type::Text || m_eType == Type::Notice || + m_eType == Type::Action || m_eType == Type::CTCP) { + InitType(); + } } CString CMessage::GetParam(unsigned int uIdx) const { - if (uIdx >= m_vsParams.size()) { - return ""; - } - return m_vsParams[uIdx]; + if (uIdx >= m_vsParams.size()) { + return ""; + } + return m_vsParams[uIdx]; } void CMessage::SetParam(unsigned int uIdx, const CString& sParam) { - if (uIdx >= m_vsParams.size()) { - m_vsParams.resize(uIdx + 1); - } - m_vsParams[uIdx] = sParam; + if (uIdx >= m_vsParams.size()) { + m_vsParams.resize(uIdx + 1); + } + m_vsParams[uIdx] = sParam; - if (uIdx == 1 && (m_eType == Type::Text || m_eType == Type::Notice || - m_eType == Type::Action || m_eType == Type::CTCP)) { - InitType(); - } + if (uIdx == 1 && (m_eType == Type::Text || m_eType == Type::Notice || + m_eType == Type::Action || m_eType == Type::CTCP)) { + InitType(); + } } CString CMessage::GetTag(const CString& sKey) const { - MCString::const_iterator it = m_mssTags.find(sKey); - if (it != m_mssTags.end()) { - return it->second; - } - return ""; + MCString::const_iterator it = m_mssTags.find(sKey); + if (it != m_mssTags.end()) { + return it->second; + } + return ""; } void CMessage::SetTag(const CString& sKey, const CString& sValue) { - m_mssTags[sKey] = sValue; + m_mssTags[sKey] = sValue; } CString CMessage::ToString(unsigned int uFlags) const { - CString sMessage; + CString sMessage; - // - if (!(uFlags & ExcludeTags) && !m_mssTags.empty()) { - CString sTags; - for (const auto& it : m_mssTags) { - if (!sTags.empty()) { - sTags += ";"; - } - sTags += it.first; - if (!it.second.empty()) - sTags += "=" + it.second.Escape_n(CString::EMSGTAG); - } - sMessage = "@" + sTags; - } + // + if (!(uFlags & ExcludeTags) && !m_mssTags.empty()) { + CString sTags; + for (const auto& it : m_mssTags) { + if (!sTags.empty()) { + sTags += ";"; + } + sTags += it.first; + if (!it.second.empty()) + sTags += "=" + it.second.Escape_n(CString::EMSGTAG); + } + sMessage = "@" + sTags; + } - // - if (!(uFlags & ExcludePrefix)) { - CString sPrefix = m_Nick.GetHostMask(); - if (!sPrefix.empty()) { - if (!sMessage.empty()) { - sMessage += " "; - } - sMessage += ":" + sPrefix; - } - } + // + if (!(uFlags & ExcludePrefix)) { + CString sPrefix = m_Nick.GetHostMask(); + if (!sPrefix.empty()) { + if (!sMessage.empty()) { + sMessage += " "; + } + sMessage += ":" + sPrefix; + } + } - // - if (!m_sCommand.empty()) { - if (!sMessage.empty()) { - sMessage += " "; - } - sMessage += m_sCommand; - } + // + if (!m_sCommand.empty()) { + if (!sMessage.empty()) { + sMessage += " "; + } + sMessage += m_sCommand; + } - // - if (!m_vsParams.empty()) { - if (!sMessage.empty()) { - sMessage += " "; - } - sMessage += GetParams(0); - } + // + if (!m_vsParams.empty()) { + if (!sMessage.empty()) { + sMessage += " "; + } + sMessage += GetParams(0); + } - return sMessage; + return sMessage; } void CMessage::Parse(CString sMessage) { - // - m_mssTags.clear(); - if (sMessage.StartsWith("@")) { - VCString vsTags; - sMessage.Token(0).TrimPrefix_n("@").Split(";", vsTags, false); - for (const CString& sTag : vsTags) { - CString sKey = sTag.Token(0, false, "=", true); - CString sValue = sTag.Token(1, true, "=", true); - m_mssTags[sKey] = - sValue.Escape(CString::EMSGTAG, CString::CString::EASCII); - } - sMessage = sMessage.Token(1, true); - } + // + m_mssTags.clear(); + if (sMessage.StartsWith("@")) { + VCString vsTags; + sMessage.Token(0).TrimPrefix_n("@").Split(";", vsTags, false); + for (const CString& sTag : vsTags) { + CString sKey = sTag.Token(0, false, "=", true); + CString sValue = sTag.Token(1, true, "=", true); + m_mssTags[sKey] = + sValue.Escape(CString::EMSGTAG, CString::CString::EASCII); + } + sMessage = sMessage.Token(1, true); + } - // ::= [':' ] - // ::= | [ '!' ] [ '@' ] - // ::= { } | - // ::= ' ' { ' ' } - // ::= [ ':' | ] - // ::= - // ::= + // ::= [':' ] + // ::= | [ '!' ] [ '@' ] + // ::= { } | + // ::= ' ' { ' ' } + // ::= [ ':' | ] + // ::= + // ::= - // - if (sMessage.TrimPrefix(":")) { - m_Nick.Parse(sMessage.Token(0)); - sMessage = sMessage.Token(1, true); - } + // + if (sMessage.TrimPrefix(":")) { + m_Nick.Parse(sMessage.Token(0)); + sMessage = sMessage.Token(1, true); + } - // - m_sCommand = sMessage.Token(0); - sMessage = sMessage.Token(1, true); + // + m_sCommand = sMessage.Token(0); + sMessage = sMessage.Token(1, true); - // - m_bColon = false; - m_vsParams.clear(); - while (!sMessage.empty()) { - m_bColon = sMessage.TrimPrefix(":"); - if (m_bColon) { - m_vsParams.push_back(sMessage); - sMessage.clear(); - } else { - m_vsParams.push_back(sMessage.Token(0)); - sMessage = sMessage.Token(1, true); - } - } + // + m_bColon = false; + m_vsParams.clear(); + while (!sMessage.empty()) { + m_bColon = sMessage.TrimPrefix(":"); + if (m_bColon) { + m_vsParams.push_back(sMessage); + sMessage.clear(); + } else { + m_vsParams.push_back(sMessage.Token(0)); + sMessage = sMessage.Token(1, true); + } + } - InitType(); + InitType(); } void CMessage::InitTime() { - auto it = m_mssTags.find("time"); - if (it != m_mssTags.end()) { - m_time = CUtils::ParseServerTime(it->second); - return; - } + auto it = m_mssTags.find("time"); + if (it != m_mssTags.end()) { + m_time = CUtils::ParseServerTime(it->second); + return; + } #ifdef HAVE_CLOCK_GETTIME - timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { - m_time.tv_sec = ts.tv_sec; - m_time.tv_usec = ts.tv_nsec / 1000; - return; - } + timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { + m_time.tv_sec = ts.tv_sec; + m_time.tv_usec = ts.tv_nsec / 1000; + return; + } #endif - if (!gettimeofday(&m_time, nullptr)) { - m_time.tv_sec = time(nullptr); - m_time.tv_usec = 0; - } + if (!gettimeofday(&m_time, nullptr)) { + m_time.tv_sec = time(nullptr); + m_time.tv_usec = 0; + } } void CMessage::InitType() { - if (m_sCommand.length() == 3 && isdigit(m_sCommand[0]) && - isdigit(m_sCommand[1]) && isdigit(m_sCommand[2])) { - m_eType = Type::Numeric; - } else if (m_sCommand.Equals("PRIVMSG")) { - CString sParam = GetParam(1); - if (sParam.TrimPrefix("\001") && sParam.EndsWith("\001")) { - if (sParam.StartsWith("ACTION ")) { - m_eType = Type::Action; - } else { - m_eType = Type::CTCP; - } - } else { - m_eType = Type::Text; - } - } else if (m_sCommand.Equals("NOTICE")) { - CString sParam = GetParam(1); - if (sParam.StartsWith("\001") && sParam.EndsWith("\001")) { - m_eType = Type::CTCP; - } else { - m_eType = Type::Notice; - } - } else { - std::map mTypes = { - {"ACCOUNT", Type::Account}, - {"AWAY", Type::Away}, - {"CAP", Type::Capability}, - {"ERROR", Type::Error}, - {"INVITE", Type::Invite}, - {"JOIN", Type::Join}, - {"KICK", Type::Kick}, - {"MODE", Type::Mode}, - {"NICK", Type::Nick}, - {"PART", Type::Part}, - {"PING", Type::Ping}, - {"PONG", Type::Pong}, - {"QUIT", Type::Quit}, - {"TOPIC", Type::Topic}, - {"WALLOPS", Type::Wallops}, - }; - auto it = mTypes.find(m_sCommand.AsUpper()); - if (it != mTypes.end()) { - m_eType = it->second; - } else { - m_eType = Type::Unknown; - } - } + if (m_sCommand.length() == 3 && isdigit(m_sCommand[0]) && + isdigit(m_sCommand[1]) && isdigit(m_sCommand[2])) { + m_eType = Type::Numeric; + } else if (m_sCommand.Equals("PRIVMSG")) { + CString sParam = GetParam(1); + if (sParam.TrimPrefix("\001") && sParam.EndsWith("\001")) { + if (sParam.StartsWith("ACTION ")) { + m_eType = Type::Action; + } else { + m_eType = Type::CTCP; + } + } else { + m_eType = Type::Text; + } + } else if (m_sCommand.Equals("NOTICE")) { + CString sParam = GetParam(1); + if (sParam.StartsWith("\001") && sParam.EndsWith("\001")) { + m_eType = Type::CTCP; + } else { + m_eType = Type::Notice; + } + } else { + std::map mTypes = { + {"ACCOUNT", Type::Account}, + {"AWAY", Type::Away}, + {"CAP", Type::Capability}, + {"ERROR", Type::Error}, + {"INVITE", Type::Invite}, + {"JOIN", Type::Join}, + {"KICK", Type::Kick}, + {"MODE", Type::Mode}, + {"NICK", Type::Nick}, + {"PART", Type::Part}, + {"PING", Type::Ping}, + {"PONG", Type::Pong}, + {"QUIT", Type::Quit}, + {"TOPIC", Type::Topic}, + {"WALLOPS", Type::Wallops}, + }; + auto it = mTypes.find(m_sCommand.AsUpper()); + if (it != mTypes.end()) { + m_eType = it->second; + } else { + m_eType = Type::Unknown; + } + } } diff --git a/src/Modules.cpp b/src/Modules.cpp index fcfc79c8..b62dcb36 100644 --- a/src/Modules.cpp +++ b/src/Modules.cpp @@ -35,79 +35,79 @@ bool ZNC_NO_NEED_TO_DO_ANYTHING_ON_MODULE_CALL_EXITER; #endif #define MODUNLOADCHK(func) \ - for (CModule * pMod : *this) { \ - try { \ - CClient* pOldClient = pMod->GetClient(); \ - pMod->SetClient(m_pClient); \ - CUser* pOldUser = nullptr; \ - if (m_pUser) { \ - pOldUser = pMod->GetUser(); \ - pMod->SetUser(m_pUser); \ - } \ - CIRCNetwork* pNetwork = nullptr; \ - if (m_pNetwork) { \ - pNetwork = pMod->GetNetwork(); \ - pMod->SetNetwork(m_pNetwork); \ - } \ - pMod->func; \ - if (m_pUser) pMod->SetUser(pOldUser); \ - if (m_pNetwork) pMod->SetNetwork(pNetwork); \ - pMod->SetClient(pOldClient); \ - } catch (const CModule::EModException& e) { \ - if (e == CModule::UNLOAD) { \ - UnloadModule(pMod->GetModName()); \ - } \ - } \ - } + for (CModule * pMod : *this) { \ + try { \ + CClient* pOldClient = pMod->GetClient(); \ + pMod->SetClient(m_pClient); \ + CUser* pOldUser = nullptr; \ + if (m_pUser) { \ + pOldUser = pMod->GetUser(); \ + pMod->SetUser(m_pUser); \ + } \ + CIRCNetwork* pNetwork = nullptr; \ + if (m_pNetwork) { \ + pNetwork = pMod->GetNetwork(); \ + pMod->SetNetwork(m_pNetwork); \ + } \ + pMod->func; \ + if (m_pUser) pMod->SetUser(pOldUser); \ + if (m_pNetwork) pMod->SetNetwork(pNetwork); \ + pMod->SetClient(pOldClient); \ + } catch (const CModule::EModException& e) { \ + if (e == CModule::UNLOAD) { \ + UnloadModule(pMod->GetModName()); \ + } \ + } \ + } #define MODHALTCHK(func) \ - bool bHaltCore = false; \ - for (CModule * pMod : *this) { \ - try { \ - CModule::EModRet e = CModule::CONTINUE; \ - CClient* pOldClient = pMod->GetClient(); \ - pMod->SetClient(m_pClient); \ - CUser* pOldUser = nullptr; \ - if (m_pUser) { \ - pOldUser = pMod->GetUser(); \ - pMod->SetUser(m_pUser); \ - } \ - CIRCNetwork* pNetwork = nullptr; \ - if (m_pNetwork) { \ - pNetwork = pMod->GetNetwork(); \ - pMod->SetNetwork(m_pNetwork); \ - } \ - e = pMod->func; \ - if (m_pUser) pMod->SetUser(pOldUser); \ - if (m_pNetwork) pMod->SetNetwork(pNetwork); \ - pMod->SetClient(pOldClient); \ - if (e == CModule::HALTMODS) { \ - break; \ - } else if (e == CModule::HALTCORE) { \ - bHaltCore = true; \ - } else if (e == CModule::HALT) { \ - bHaltCore = true; \ - break; \ - } \ - } catch (const CModule::EModException& e) { \ - if (e == CModule::UNLOAD) { \ - UnloadModule(pMod->GetModName()); \ - } \ - } \ - } \ - return bHaltCore; + bool bHaltCore = false; \ + for (CModule * pMod : *this) { \ + try { \ + CModule::EModRet e = CModule::CONTINUE; \ + CClient* pOldClient = pMod->GetClient(); \ + pMod->SetClient(m_pClient); \ + CUser* pOldUser = nullptr; \ + if (m_pUser) { \ + pOldUser = pMod->GetUser(); \ + pMod->SetUser(m_pUser); \ + } \ + CIRCNetwork* pNetwork = nullptr; \ + if (m_pNetwork) { \ + pNetwork = pMod->GetNetwork(); \ + pMod->SetNetwork(m_pNetwork); \ + } \ + e = pMod->func; \ + if (m_pUser) pMod->SetUser(pOldUser); \ + if (m_pNetwork) pMod->SetNetwork(pNetwork); \ + pMod->SetClient(pOldClient); \ + if (e == CModule::HALTMODS) { \ + break; \ + } else if (e == CModule::HALTCORE) { \ + bHaltCore = true; \ + } else if (e == CModule::HALT) { \ + bHaltCore = true; \ + break; \ + } \ + } catch (const CModule::EModException& e) { \ + if (e == CModule::UNLOAD) { \ + UnloadModule(pMod->GetModName()); \ + } \ + } \ + } \ + return bHaltCore; /////////////////// Timer /////////////////// CTimer::CTimer(CModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription) : CCron(), m_pModule(pModule), m_sDescription(sDescription) { - SetName(sLabel); + SetName(sLabel); - if (uCycles) { - StartMaxCycles(uInterval, uCycles); - } else { - Start(uInterval); - } + if (uCycles) { + StartMaxCycles(uInterval, uCycles); + } else { + Start(uInterval); + } } CTimer::~CTimer() { m_pModule->UnlinkTimer(this); } @@ -141,29 +141,29 @@ CModule::CModule(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, m_mssRegistry(), m_vSubPages(), m_mCommands() { - if (m_pNetwork) { - m_sSavePath = m_pNetwork->GetNetworkPath() + "/moddata/" + m_sModName; - } else if (m_pUser) { - m_sSavePath = m_pUser->GetUserPath() + "/moddata/" + m_sModName; - } else { - m_sSavePath = CZNC::Get().GetZNCPath() + "/moddata/" + m_sModName; - } - LoadRegistry(); + if (m_pNetwork) { + m_sSavePath = m_pNetwork->GetNetworkPath() + "/moddata/" + m_sModName; + } else if (m_pUser) { + m_sSavePath = m_pUser->GetUserPath() + "/moddata/" + m_sModName; + } else { + m_sSavePath = CZNC::Get().GetZNCPath() + "/moddata/" + m_sModName; + } + LoadRegistry(); } CModule::~CModule() { - while (!m_sTimers.empty()) { - RemTimer(*m_sTimers.begin()); - } + while (!m_sTimers.empty()) { + RemTimer(*m_sTimers.begin()); + } - while (!m_sSockets.empty()) { - RemSocket(*m_sSockets.begin()); - } + while (!m_sSockets.empty()) { + RemSocket(*m_sSockets.begin()); + } - SaveRegistry(); + SaveRegistry(); #ifdef HAVE_PTHREAD - CancelJobs(m_sJobs); + CancelJobs(m_sJobs); #endif } @@ -172,422 +172,422 @@ void CModule::SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } void CModule::SetClient(CClient* pClient) { m_pClient = pClient; } CString CModule::ExpandString(const CString& sStr) const { - CString sRet; - return ExpandString(sStr, sRet); + CString sRet; + return ExpandString(sStr, sRet); } CString& CModule::ExpandString(const CString& sStr, CString& sRet) const { - sRet = sStr; + sRet = sStr; - if (m_pNetwork) { - return m_pNetwork->ExpandString(sRet, sRet); - } + if (m_pNetwork) { + return m_pNetwork->ExpandString(sRet, sRet); + } - if (m_pUser) { - return m_pUser->ExpandString(sRet, sRet); - } + if (m_pUser) { + return m_pUser->ExpandString(sRet, sRet); + } - return sRet; + return sRet; } const CString& CModule::GetSavePath() const { - if (!CFile::Exists(m_sSavePath)) { - CDir::MakeDir(m_sSavePath); - } - return m_sSavePath; + if (!CFile::Exists(m_sSavePath)) { + CDir::MakeDir(m_sSavePath); + } + return m_sSavePath; } CString CModule::GetWebPath() { - switch (m_eType) { - case CModInfo::GlobalModule: - return "/mods/global/" + GetModName() + "/"; - case CModInfo::UserModule: - return "/mods/user/" + GetModName() + "/"; - case CModInfo::NetworkModule: - return "/mods/network/" + m_pNetwork->GetName() + "/" + - GetModName() + "/"; - default: - return "/"; - } + switch (m_eType) { + case CModInfo::GlobalModule: + return "/mods/global/" + GetModName() + "/"; + case CModInfo::UserModule: + return "/mods/user/" + GetModName() + "/"; + case CModInfo::NetworkModule: + return "/mods/network/" + m_pNetwork->GetName() + "/" + + GetModName() + "/"; + default: + return "/"; + } } CString CModule::GetWebFilesPath() { - switch (m_eType) { - case CModInfo::GlobalModule: - return "/modfiles/global/" + GetModName() + "/"; - case CModInfo::UserModule: - return "/modfiles/user/" + GetModName() + "/"; - case CModInfo::NetworkModule: - return "/modfiles/network/" + m_pNetwork->GetName() + "/" + - GetModName() + "/"; - default: - return "/"; - } + switch (m_eType) { + case CModInfo::GlobalModule: + return "/modfiles/global/" + GetModName() + "/"; + case CModInfo::UserModule: + return "/modfiles/user/" + GetModName() + "/"; + case CModInfo::NetworkModule: + return "/modfiles/network/" + m_pNetwork->GetName() + "/" + + GetModName() + "/"; + default: + return "/"; + } } bool CModule::LoadRegistry() { - // CString sPrefix = (m_pUser) ? m_pUser->GetUserName() : ".global"; - return (m_mssRegistry.ReadFromDisk(GetSavePath() + "/.registry") == - MCString::MCS_SUCCESS); + // CString sPrefix = (m_pUser) ? m_pUser->GetUserName() : ".global"; + return (m_mssRegistry.ReadFromDisk(GetSavePath() + "/.registry") == + MCString::MCS_SUCCESS); } bool CModule::SaveRegistry() const { - // CString sPrefix = (m_pUser) ? m_pUser->GetUserName() : ".global"; - return (m_mssRegistry.WriteToDisk(GetSavePath() + "/.registry", 0600) == - MCString::MCS_SUCCESS); + // CString sPrefix = (m_pUser) ? m_pUser->GetUserName() : ".global"; + return (m_mssRegistry.WriteToDisk(GetSavePath() + "/.registry", 0600) == + MCString::MCS_SUCCESS); } bool CModule::MoveRegistry(const CString& sPath) { - if (m_sSavePath != sPath) { - CFile fOldNVFile = CFile(m_sSavePath + "/.registry"); - if (!fOldNVFile.Exists()) { - return false; - } - if (!CFile::Exists(sPath) && !CDir::MakeDir(sPath)) { - return false; - } - fOldNVFile.Copy(sPath + "/.registry"); - m_sSavePath = sPath; - return true; - } - return false; + if (m_sSavePath != sPath) { + CFile fOldNVFile = CFile(m_sSavePath + "/.registry"); + if (!fOldNVFile.Exists()) { + return false; + } + if (!CFile::Exists(sPath) && !CDir::MakeDir(sPath)) { + return false; + } + fOldNVFile.Copy(sPath + "/.registry"); + m_sSavePath = sPath; + return true; + } + return false; } bool CModule::SetNV(const CString& sName, const CString& sValue, bool bWriteToDisk) { - m_mssRegistry[sName] = sValue; - if (bWriteToDisk) { - return SaveRegistry(); - } + m_mssRegistry[sName] = sValue; + if (bWriteToDisk) { + return SaveRegistry(); + } - return true; + return true; } CString CModule::GetNV(const CString& sName) const { - MCString::const_iterator it = m_mssRegistry.find(sName); + MCString::const_iterator it = m_mssRegistry.find(sName); - if (it != m_mssRegistry.end()) { - return it->second; - } + if (it != m_mssRegistry.end()) { + return it->second; + } - return ""; + return ""; } bool CModule::DelNV(const CString& sName, bool bWriteToDisk) { - MCString::iterator it = m_mssRegistry.find(sName); + MCString::iterator it = m_mssRegistry.find(sName); - if (it != m_mssRegistry.end()) { - m_mssRegistry.erase(it); - } else { - return false; - } + if (it != m_mssRegistry.end()) { + m_mssRegistry.erase(it); + } else { + return false; + } - if (bWriteToDisk) { - return SaveRegistry(); - } + if (bWriteToDisk) { + return SaveRegistry(); + } - return true; + return true; } bool CModule::ClearNV(bool bWriteToDisk) { - m_mssRegistry.clear(); + m_mssRegistry.clear(); - if (bWriteToDisk) { - return SaveRegistry(); - } - return true; + if (bWriteToDisk) { + return SaveRegistry(); + } + return true; } bool CModule::AddTimer(CTimer* pTimer) { - if ((!pTimer) || - (!pTimer->GetName().empty() && FindTimer(pTimer->GetName()))) { - delete pTimer; - return false; - } + if ((!pTimer) || + (!pTimer->GetName().empty() && FindTimer(pTimer->GetName()))) { + delete pTimer; + return false; + } - if (!m_sTimers.insert(pTimer).second) - // Was already added - return true; + if (!m_sTimers.insert(pTimer).second) + // Was already added + return true; - m_pManager->AddCron(pTimer); - return true; + m_pManager->AddCron(pTimer); + return true; } bool CModule::AddTimer(FPTimer_t pFBCallback, const CString& sLabel, u_int uInterval, u_int uCycles, const CString& sDescription) { - CFPTimer* pTimer = - new CFPTimer(this, uInterval, uCycles, sLabel, sDescription); - pTimer->SetFPCallback(pFBCallback); + CFPTimer* pTimer = + new CFPTimer(this, uInterval, uCycles, sLabel, sDescription); + pTimer->SetFPCallback(pFBCallback); - return AddTimer(pTimer); + return AddTimer(pTimer); } bool CModule::RemTimer(CTimer* pTimer) { - if (m_sTimers.erase(pTimer) == 0) return false; - m_pManager->DelCronByAddr(pTimer); - return true; + if (m_sTimers.erase(pTimer) == 0) return false; + m_pManager->DelCronByAddr(pTimer); + return true; } bool CModule::RemTimer(const CString& sLabel) { - CTimer* pTimer = FindTimer(sLabel); - if (!pTimer) return false; - return RemTimer(pTimer); + CTimer* pTimer = FindTimer(sLabel); + if (!pTimer) return false; + return RemTimer(pTimer); } bool CModule::UnlinkTimer(CTimer* pTimer) { return m_sTimers.erase(pTimer); } CTimer* CModule::FindTimer(const CString& sLabel) { - if (sLabel.empty()) { - return nullptr; - } + if (sLabel.empty()) { + return nullptr; + } - for (CTimer* pTimer : m_sTimers) { - if (pTimer->GetName().Equals(sLabel)) { - return pTimer; - } - } + for (CTimer* pTimer : m_sTimers) { + if (pTimer->GetName().Equals(sLabel)) { + return pTimer; + } + } - return nullptr; + return nullptr; } void CModule::ListTimers() { - if (m_sTimers.empty()) { - PutModule("You have no timers running."); - return; - } + if (m_sTimers.empty()) { + PutModule("You have no timers running."); + return; + } - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("Secs"); - Table.AddColumn("Cycles"); - Table.AddColumn("Description"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("Secs"); + Table.AddColumn("Cycles"); + Table.AddColumn("Description"); - for (const CTimer* pTimer : m_sTimers) { - unsigned int uCycles = pTimer->GetCyclesLeft(); - timeval Interval = pTimer->GetInterval(); + for (const CTimer* pTimer : m_sTimers) { + unsigned int uCycles = pTimer->GetCyclesLeft(); + timeval Interval = pTimer->GetInterval(); - Table.AddRow(); - Table.SetCell("Name", pTimer->GetName()); - Table.SetCell( - "Secs", CString(Interval.tv_sec) + "seconds" + - (Interval.tv_usec - ? " " + CString(Interval.tv_usec) + " microseconds" - : "")); - Table.SetCell("Cycles", ((uCycles) ? CString(uCycles) : "INF")); - Table.SetCell("Description", pTimer->GetDescription()); - } + Table.AddRow(); + Table.SetCell("Name", pTimer->GetName()); + Table.SetCell( + "Secs", CString(Interval.tv_sec) + "seconds" + + (Interval.tv_usec + ? " " + CString(Interval.tv_usec) + " microseconds" + : "")); + Table.SetCell("Cycles", ((uCycles) ? CString(uCycles) : "INF")); + Table.SetCell("Description", pTimer->GetDescription()); + } - PutModule(Table); + PutModule(Table); } bool CModule::AddSocket(CSocket* pSocket) { - if (!pSocket) { - return false; - } + if (!pSocket) { + return false; + } - m_sSockets.insert(pSocket); - return true; + m_sSockets.insert(pSocket); + return true; } bool CModule::RemSocket(CSocket* pSocket) { - if (m_sSockets.erase(pSocket)) { - m_pManager->DelSockByAddr(pSocket); - return true; - } + if (m_sSockets.erase(pSocket)) { + m_pManager->DelSockByAddr(pSocket); + return true; + } - return false; + return false; } bool CModule::RemSocket(const CString& sSockName) { - for (CSocket* pSocket : m_sSockets) { - if (pSocket->GetSockName().Equals(sSockName)) { - m_sSockets.erase(pSocket); - m_pManager->DelSockByAddr(pSocket); - return true; - } - } + for (CSocket* pSocket : m_sSockets) { + if (pSocket->GetSockName().Equals(sSockName)) { + m_sSockets.erase(pSocket); + m_pManager->DelSockByAddr(pSocket); + return true; + } + } - return false; + return false; } bool CModule::UnlinkSocket(CSocket* pSocket) { - return m_sSockets.erase(pSocket); + return m_sSockets.erase(pSocket); } CSocket* CModule::FindSocket(const CString& sSockName) { - for (CSocket* pSocket : m_sSockets) { - if (pSocket->GetSockName().Equals(sSockName)) { - return pSocket; - } - } + for (CSocket* pSocket : m_sSockets) { + if (pSocket->GetSockName().Equals(sSockName)) { + return pSocket; + } + } - return nullptr; + return nullptr; } void CModule::ListSockets() { - if (m_sSockets.empty()) { - PutModule("You have no open sockets."); - return; - } + if (m_sSockets.empty()) { + PutModule("You have no open sockets."); + return; + } - CTable Table; - Table.AddColumn("Name"); - Table.AddColumn("State"); - Table.AddColumn("LocalPort"); - Table.AddColumn("SSL"); - Table.AddColumn("RemoteIP"); - Table.AddColumn("RemotePort"); + CTable Table; + Table.AddColumn("Name"); + Table.AddColumn("State"); + Table.AddColumn("LocalPort"); + Table.AddColumn("SSL"); + Table.AddColumn("RemoteIP"); + Table.AddColumn("RemotePort"); - for (const CSocket* pSocket : m_sSockets) { - Table.AddRow(); - Table.SetCell("Name", pSocket->GetSockName()); + for (const CSocket* pSocket : m_sSockets) { + Table.AddRow(); + Table.SetCell("Name", pSocket->GetSockName()); - if (pSocket->GetType() == CSocket::LISTENER) { - Table.SetCell("State", "Listening"); - } else { - Table.SetCell("State", (pSocket->IsConnected() ? "Connected" : "")); - } + if (pSocket->GetType() == CSocket::LISTENER) { + Table.SetCell("State", "Listening"); + } else { + Table.SetCell("State", (pSocket->IsConnected() ? "Connected" : "")); + } - Table.SetCell("LocalPort", CString(pSocket->GetLocalPort())); - Table.SetCell("SSL", (pSocket->GetSSL() ? "yes" : "no")); - Table.SetCell("RemoteIP", pSocket->GetRemoteIP()); - Table.SetCell("RemotePort", (pSocket->GetRemotePort()) - ? CString(pSocket->GetRemotePort()) - : CString("")); - } + Table.SetCell("LocalPort", CString(pSocket->GetLocalPort())); + Table.SetCell("SSL", (pSocket->GetSSL() ? "yes" : "no")); + Table.SetCell("RemoteIP", pSocket->GetRemoteIP()); + Table.SetCell("RemotePort", (pSocket->GetRemotePort()) + ? CString(pSocket->GetRemotePort()) + : CString("")); + } - PutModule(Table); + PutModule(Table); } #ifdef HAVE_PTHREAD CModuleJob::~CModuleJob() { m_pModule->UnlinkJob(this); } void CModule::AddJob(CModuleJob* pJob) { - CThreadPool::Get().addJob(pJob); - m_sJobs.insert(pJob); + CThreadPool::Get().addJob(pJob); + m_sJobs.insert(pJob); } void CModule::CancelJob(CModuleJob* pJob) { - if (pJob == nullptr) return; - // Destructor calls UnlinkJob and removes the job from m_sJobs - CThreadPool::Get().cancelJob(pJob); + if (pJob == nullptr) return; + // Destructor calls UnlinkJob and removes the job from m_sJobs + CThreadPool::Get().cancelJob(pJob); } bool CModule::CancelJob(const CString& sJobName) { - for (CModuleJob* pJob : m_sJobs) { - if (pJob->GetName().Equals(sJobName)) { - CancelJob(pJob); - return true; - } - } - return false; + for (CModuleJob* pJob : m_sJobs) { + if (pJob->GetName().Equals(sJobName)) { + CancelJob(pJob); + return true; + } + } + return false; } void CModule::CancelJobs(const std::set& sJobs) { - set sPlainJobs(sJobs.begin(), sJobs.end()); + set sPlainJobs(sJobs.begin(), sJobs.end()); - // Destructor calls UnlinkJob and removes the jobs from m_sJobs - CThreadPool::Get().cancelJobs(sPlainJobs); + // Destructor calls UnlinkJob and removes the jobs from m_sJobs + CThreadPool::Get().cancelJobs(sPlainJobs); } bool CModule::UnlinkJob(CModuleJob* pJob) { return 0 != m_sJobs.erase(pJob); } #endif bool CModule::AddCommand(const CModCommand& Command) { - if (Command.GetFunction() == nullptr) return false; - if (Command.GetCommand().Contains(" ")) return false; - if (FindCommand(Command.GetCommand()) != nullptr) return false; + if (Command.GetFunction() == nullptr) return false; + if (Command.GetCommand().Contains(" ")) return false; + if (FindCommand(Command.GetCommand()) != nullptr) return false; - m_mCommands[Command.GetCommand()] = Command; - return true; + m_mCommands[Command.GetCommand()] = Command; + return true; } bool CModule::AddCommand(const CString& sCmd, CModCommand::ModCmdFunc func, const CString& sArgs, const CString& sDesc) { - CModCommand cmd(sCmd, this, func, sArgs, sDesc); - return AddCommand(cmd); + CModCommand cmd(sCmd, this, func, sArgs, sDesc); + return AddCommand(cmd); } bool CModule::AddCommand(const CString& sCmd, const CString& sArgs, const CString& sDesc, std::function func) { - CModCommand cmd(sCmd, std::move(func), sArgs, sDesc); - return AddCommand(std::move(cmd)); + CModCommand cmd(sCmd, std::move(func), sArgs, sDesc); + return AddCommand(std::move(cmd)); } void CModule::AddHelpCommand() { - AddCommand("Help", &CModule::HandleHelpCommand, "search", - "Generate this output"); + AddCommand("Help", &CModule::HandleHelpCommand, "search", + "Generate this output"); } bool CModule::RemCommand(const CString& sCmd) { - return m_mCommands.erase(sCmd) > 0; + return m_mCommands.erase(sCmd) > 0; } const CModCommand* CModule::FindCommand(const CString& sCmd) const { - for (const auto& it : m_mCommands) { - if (!it.first.Equals(sCmd)) continue; - return &it.second; - } - return nullptr; + for (const auto& it : m_mCommands) { + if (!it.first.Equals(sCmd)) continue; + return &it.second; + } + return nullptr; } bool CModule::HandleCommand(const CString& sLine) { - const CString& sCmd = sLine.Token(0); - const CModCommand* pCmd = FindCommand(sCmd); + const CString& sCmd = sLine.Token(0); + const CModCommand* pCmd = FindCommand(sCmd); - if (pCmd) { - pCmd->Call(sLine); - return true; - } + if (pCmd) { + pCmd->Call(sLine); + return true; + } - OnUnknownModCommand(sLine); + OnUnknownModCommand(sLine); - return false; + return false; } void CModule::HandleHelpCommand(const CString& sLine) { - CString sFilter = sLine.Token(1).AsLower(); - CTable Table; + CString sFilter = sLine.Token(1).AsLower(); + CTable Table; - CModCommand::InitHelp(Table); - for (const auto& it : m_mCommands) { - CString sCmd = it.second.GetCommand().AsLower(); - if (sFilter.empty() || - (sCmd.StartsWith(sFilter, CString::CaseSensitive)) || - sCmd.WildCmp(sFilter)) { - it.second.AddHelp(Table); - } - } - if (Table.empty()) { - PutModule("No matches for '" + sFilter + "'"); - } else { - PutModule(Table); - } + CModCommand::InitHelp(Table); + for (const auto& it : m_mCommands) { + CString sCmd = it.second.GetCommand().AsLower(); + if (sFilter.empty() || + (sCmd.StartsWith(sFilter, CString::CaseSensitive)) || + sCmd.WildCmp(sFilter)) { + it.second.AddHelp(Table); + } + } + if (Table.empty()) { + PutModule("No matches for '" + sFilter + "'"); + } else { + PutModule(Table); + } } CString CModule::GetModNick() const { - return ((m_pUser) ? m_pUser->GetStatusPrefix() : "*") + m_sModName; + return ((m_pUser) ? m_pUser->GetStatusPrefix() : "*") + m_sModName; } // Webmods bool CModule::OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) { - return false; + return false; } bool CModule::OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl) { - return false; + return false; } bool CModule::OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl) { - return false; + return false; } // !Webmods bool CModule::OnLoad(const CString& sArgs, CString& sMessage) { - sMessage = ""; - return true; + sMessage = ""; + return true; } bool CModule::OnBoot() { return true; } void CModule::OnPreRehash() {} @@ -595,45 +595,45 @@ void CModule::OnPostRehash() {} void CModule::OnIRCDisconnected() {} void CModule::OnIRCConnected() {} CModule::EModRet CModule::OnIRCConnecting(CIRCSock* IRCSock) { - return CONTINUE; + return CONTINUE; } void CModule::OnIRCConnectionError(CIRCSock* IRCSock) {} CModule::EModRet CModule::OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnBroadcast(CString& sMessage) { return CONTINUE; } void CModule::OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) { - if (pOpNick) - OnChanPermission(*pOpNick, Nick, Channel, uMode, bAdded, bNoChange); + if (pOpNick) + OnChanPermission(*pOpNick, Nick, Channel, uMode, bAdded, bNoChange); } void CModule::OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - if (pOpNick) OnOp(*pOpNick, Nick, Channel, bNoChange); + if (pOpNick) OnOp(*pOpNick, Nick, Channel, bNoChange); } void CModule::OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - if (pOpNick) OnDeop(*pOpNick, Nick, Channel, bNoChange); + if (pOpNick) OnDeop(*pOpNick, Nick, Channel, bNoChange); } void CModule::OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - if (pOpNick) OnVoice(*pOpNick, Nick, Channel, bNoChange); + if (pOpNick) OnVoice(*pOpNick, Nick, Channel, bNoChange); } void CModule::OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - if (pOpNick) OnDevoice(*pOpNick, Nick, Channel, bNoChange); + if (pOpNick) OnDevoice(*pOpNick, Nick, Channel, bNoChange); } void CModule::OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, const CString& sArgs) { - if (pOpNick) OnRawMode(*pOpNick, Channel, sModes, sArgs); + if (pOpNick) OnRawMode(*pOpNick, Channel, sModes, sArgs); } void CModule::OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) { - if (pOpNick) OnMode(*pOpNick, Channel, uMode, sArg, bAdded, bNoChange); + if (pOpNick) OnMode(*pOpNick, Channel, uMode, sArg, bAdded, bNoChange); } void CModule::OnChanPermission(const CNick& pOpNick, const CNick& Nick, @@ -655,315 +655,315 @@ void CModule::OnMode(const CNick& pOpNick, CChan& Channel, char uMode, CModule::EModRet CModule::OnRaw(CString& sLine) { return CONTINUE; } CModule::EModRet CModule::OnRawMessage(CMessage& Message) { return CONTINUE; } CModule::EModRet CModule::OnNumericMessage(CNumericMessage& Message) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnStatusCommand(CString& sCommand) { - return CONTINUE; + return CONTINUE; } void CModule::OnModNotice(const CString& sMessage) {} void CModule::OnModCTCP(const CString& sMessage) {} void CModule::OnModCommand(const CString& sCommand) { HandleCommand(sCommand); } void CModule::OnUnknownModCommand(const CString& sLine) { - if (m_mCommands.empty()) - // This function is only called if OnModCommand wasn't - // overriden, so no false warnings for modules which don't use - // CModCommand for command handling. - PutModule("This module doesn't implement any commands."); - else - PutModule("Unknown command!"); + if (m_mCommands.empty()) + // This function is only called if OnModCommand wasn't + // overriden, so no false warnings for modules which don't use + // CModCommand for command handling. + PutModule("This module doesn't implement any commands."); + else + PutModule("Unknown command!"); } void CModule::OnQuit(const CNick& Nick, const CString& sMessage, const vector& vChans) {} void CModule::OnQuitMessage(CQuitMessage& Message, const vector& vChans) { - OnQuit(Message.GetNick(), Message.GetReason(), vChans); + OnQuit(Message.GetNick(), Message.GetReason(), vChans); } void CModule::OnNick(const CNick& Nick, const CString& sNewNick, const vector& vChans) {} void CModule::OnNickMessage(CNickMessage& Message, const vector& vChans) { - OnNick(Message.GetNick(), Message.GetNewNick(), vChans); + OnNick(Message.GetNick(), Message.GetNewNick(), vChans); } void CModule::OnKick(const CNick& Nick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) {} void CModule::OnKickMessage(CKickMessage& Message) { - OnKick(Message.GetNick(), Message.GetKickedNick(), *Message.GetChan(), - Message.GetReason()); + OnKick(Message.GetNick(), Message.GetKickedNick(), *Message.GetChan(), + Message.GetReason()); } CModule::EModRet CModule::OnJoining(CChan& Channel) { return CONTINUE; } void CModule::OnJoin(const CNick& Nick, CChan& Channel) {} void CModule::OnJoinMessage(CJoinMessage& Message) { - OnJoin(Message.GetNick(), *Message.GetChan()); + OnJoin(Message.GetNick(), *Message.GetChan()); } void CModule::OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) {} void CModule::OnPartMessage(CPartMessage& Message) { - OnPart(Message.GetNick(), *Message.GetChan(), Message.GetReason()); + OnPart(Message.GetNick(), *Message.GetChan(), Message.GetReason()); } CModule::EModRet CModule::OnInvite(const CNick& Nick, const CString& sChan) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanBufferStarting(CChan& Chan, CClient& Client) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanBufferEnding(CChan& Chan, CClient& Client) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnPrivBufferPlayLine(CClient& Client, CString& sLine) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanBufferPlayLine2(CChan& Chan, CClient& Client, CString& sLine, const timeval& tv) { - return OnChanBufferPlayLine(Chan, Client, sLine); + return OnChanBufferPlayLine(Chan, Client, sLine); } CModule::EModRet CModule::OnPrivBufferPlayLine2(CClient& Client, CString& sLine, const timeval& tv) { - return OnPrivBufferPlayLine(Client, sLine); + return OnPrivBufferPlayLine(Client, sLine); } CModule::EModRet CModule::OnChanBufferPlayMessage(CMessage& Message) { - CString sOriginal, sModified; - sOriginal = sModified = Message.ToString(CMessage::ExcludeTags); - EModRet ret = OnChanBufferPlayLine2( - *Message.GetChan(), *Message.GetClient(), sModified, Message.GetTime()); - if (sOriginal != sModified) { - Message.Parse(sModified); - } - return ret; + CString sOriginal, sModified; + sOriginal = sModified = Message.ToString(CMessage::ExcludeTags); + EModRet ret = OnChanBufferPlayLine2( + *Message.GetChan(), *Message.GetClient(), sModified, Message.GetTime()); + if (sOriginal != sModified) { + Message.Parse(sModified); + } + return ret; } CModule::EModRet CModule::OnPrivBufferPlayMessage(CMessage& Message) { - CString sOriginal, sModified; - sOriginal = sModified = Message.ToString(CMessage::ExcludeTags); - EModRet ret = OnPrivBufferPlayLine2(*Message.GetClient(), sModified, - Message.GetTime()); - if (sOriginal != sModified) { - Message.Parse(sModified); - } - return ret; + CString sOriginal, sModified; + sOriginal = sModified = Message.ToString(CMessage::ExcludeTags); + EModRet ret = OnPrivBufferPlayLine2(*Message.GetClient(), sModified, + Message.GetTime()); + if (sOriginal != sModified) { + Message.Parse(sModified); + } + return ret; } void CModule::OnClientLogin() {} void CModule::OnClientDisconnect() {} CModule::EModRet CModule::OnUserRaw(CString& sLine) { return CONTINUE; } CModule::EModRet CModule::OnUserRawMessage(CMessage& Message) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserCTCPReply(CString& sTarget, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserCTCPReplyMessage(CCTCPMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sText = Message.GetText(); - EModRet ret = OnUserCTCPReply(sTarget, sText); - Message.SetTarget(sTarget); - Message.SetText(sText); - return ret; + CString sTarget = Message.GetTarget(); + CString sText = Message.GetText(); + EModRet ret = OnUserCTCPReply(sTarget, sText); + Message.SetTarget(sTarget); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnUserCTCP(CString& sTarget, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserCTCPMessage(CCTCPMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sText = Message.GetText(); - EModRet ret = OnUserCTCP(sTarget, sText); - Message.SetTarget(sTarget); - Message.SetText(sText); - return ret; + CString sTarget = Message.GetTarget(); + CString sText = Message.GetText(); + EModRet ret = OnUserCTCP(sTarget, sText); + Message.SetTarget(sTarget); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnUserAction(CString& sTarget, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserActionMessage(CActionMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sText = Message.GetText(); - EModRet ret = OnUserAction(sTarget, sText); - Message.SetTarget(sTarget); - Message.SetText(sText); - return ret; + CString sTarget = Message.GetTarget(); + CString sText = Message.GetText(); + EModRet ret = OnUserAction(sTarget, sText); + Message.SetTarget(sTarget); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnUserMsg(CString& sTarget, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserTextMessage(CTextMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sText = Message.GetText(); - EModRet ret = OnUserMsg(sTarget, sText); - Message.SetTarget(sTarget); - Message.SetText(sText); - return ret; + CString sTarget = Message.GetTarget(); + CString sText = Message.GetText(); + EModRet ret = OnUserMsg(sTarget, sText); + Message.SetTarget(sTarget); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnUserNotice(CString& sTarget, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserNoticeMessage(CNoticeMessage& Message) { - CString sTarget = Message.GetTarget(); - CString sText = Message.GetText(); - EModRet ret = OnUserNotice(sTarget, sText); - Message.SetTarget(sTarget); - Message.SetText(sText); - return ret; + CString sTarget = Message.GetTarget(); + CString sText = Message.GetText(); + EModRet ret = OnUserNotice(sTarget, sText); + Message.SetTarget(sTarget); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnUserJoin(CString& sChannel, CString& sKey) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserJoinMessage(CJoinMessage& Message) { - CString sChan = Message.GetTarget(); - CString sKey = Message.GetKey(); - EModRet ret = OnUserJoin(sChan, sKey); - Message.SetTarget(sChan); - Message.SetKey(sKey); - return ret; + CString sChan = Message.GetTarget(); + CString sKey = Message.GetKey(); + EModRet ret = OnUserJoin(sChan, sKey); + Message.SetTarget(sChan); + Message.SetKey(sKey); + return ret; } CModule::EModRet CModule::OnUserPart(CString& sChannel, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserPartMessage(CPartMessage& Message) { - CString sChan = Message.GetTarget(); - CString sReason = Message.GetReason(); - EModRet ret = OnUserPart(sChan, sReason); - Message.SetTarget(sChan); - Message.SetReason(sReason); - return ret; + CString sChan = Message.GetTarget(); + CString sReason = Message.GetReason(); + EModRet ret = OnUserPart(sChan, sReason); + Message.SetTarget(sChan); + Message.SetReason(sReason); + return ret; } CModule::EModRet CModule::OnUserTopic(CString& sChannel, CString& sTopic) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserTopicMessage(CTopicMessage& Message) { - CString sChan = Message.GetTarget(); - CString sTopic = Message.GetTopic(); - EModRet ret = OnUserTopic(sChan, sTopic); - Message.SetTarget(sChan); - Message.SetTopic(sTopic); - return ret; + CString sChan = Message.GetTarget(); + CString sTopic = Message.GetTopic(); + EModRet ret = OnUserTopic(sChan, sTopic); + Message.SetTarget(sChan); + Message.SetTopic(sTopic); + return ret; } CModule::EModRet CModule::OnUserTopicRequest(CString& sChannel) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUserQuit(CString& sMessage) { return CONTINUE; } CModule::EModRet CModule::OnUserQuitMessage(CQuitMessage& Message) { - CString sReason = Message.GetReason(); - EModRet ret = OnUserQuit(sReason); - Message.SetReason(sReason); - return ret; + CString sReason = Message.GetReason(); + EModRet ret = OnUserQuit(sReason); + Message.SetReason(sReason); + return ret; } CModule::EModRet CModule::OnCTCPReply(CNick& Nick, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnCTCPReplyMessage(CCTCPMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnCTCPReply(Message.GetNick(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnCTCPReply(Message.GetNick(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnPrivCTCP(CNick& Nick, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnPrivCTCPMessage(CCTCPMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnPrivCTCP(Message.GetNick(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnPrivCTCP(Message.GetNick(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanCTCPMessage(CCTCPMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnChanCTCP(Message.GetNick(), *Message.GetChan(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnChanCTCP(Message.GetNick(), *Message.GetChan(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnPrivAction(CNick& Nick, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnPrivActionMessage(CActionMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnPrivAction(Message.GetNick(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnPrivAction(Message.GetNick(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanActionMessage(CActionMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnChanAction(Message.GetNick(), *Message.GetChan(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnChanAction(Message.GetNick(), *Message.GetChan(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnPrivMsg(CNick& Nick, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnPrivMessage(CTextMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnPrivMsg(Message.GetNick(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnPrivMsg(Message.GetNick(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanMessage(CTextMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnChanMsg(Message.GetNick(), *Message.GetChan(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnChanMsg(Message.GetNick(), *Message.GetChan(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnPrivNotice(CNick& Nick, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnPrivNoticeMessage(CNoticeMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnPrivNotice(Message.GetNick(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnPrivNotice(Message.GetNick(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnChanNoticeMessage(CNoticeMessage& Message) { - CString sText = Message.GetText(); - EModRet ret = OnChanNotice(Message.GetNick(), *Message.GetChan(), sText); - Message.SetText(sText); - return ret; + CString sText = Message.GetText(); + EModRet ret = OnChanNotice(Message.GetNick(), *Message.GetChan(), sText); + Message.SetText(sText); + return ret; } CModule::EModRet CModule::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnTopicMessage(CTopicMessage& Message) { - CString sTopic = Message.GetTopic(); - EModRet ret = OnTopic(Message.GetNick(), *Message.GetChan(), sTopic); - Message.SetTopic(sTopic); - return ret; + CString sTopic = Message.GetTopic(); + EModRet ret = OnTopic(Message.GetNick(), *Message.GetChan(), sTopic); + Message.SetTopic(sTopic); + return ret; } CModule::EModRet CModule::OnTimerAutoJoin(CChan& Channel) { return CONTINUE; } CModule::EModRet CModule::OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnDeleteNetwork(CIRCNetwork& Network) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnSendToClient(CString& sLine, CClient& Client) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnSendToIRC(CString& sLine) { return CONTINUE; } @@ -971,73 +971,73 @@ bool CModule::OnServerCapAvailable(const CString& sCap) { return false; } void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {} bool CModule::PutIRC(const CString& sLine) { - return (m_pNetwork) ? m_pNetwork->PutIRC(sLine) : false; + return (m_pNetwork) ? m_pNetwork->PutIRC(sLine) : false; } bool CModule::PutUser(const CString& sLine) { - return (m_pNetwork) ? m_pNetwork->PutUser(sLine, m_pClient) : false; + return (m_pNetwork) ? m_pNetwork->PutUser(sLine, m_pClient) : false; } bool CModule::PutStatus(const CString& sLine) { - return (m_pNetwork) ? m_pNetwork->PutStatus(sLine, m_pClient) : false; + return (m_pNetwork) ? m_pNetwork->PutStatus(sLine, m_pClient) : false; } unsigned int CModule::PutModule(const CTable& table) { - if (!m_pUser) return 0; + if (!m_pUser) return 0; - unsigned int idx = 0; - CString sLine; - while (table.GetLine(idx++, sLine)) PutModule(sLine); - return idx - 1; + unsigned int idx = 0; + CString sLine; + while (table.GetLine(idx++, sLine)) PutModule(sLine); + return idx - 1; } bool CModule::PutModule(const CString& sLine) { - if (m_pClient) { - m_pClient->PutModule(GetModName(), sLine); - return true; - } + if (m_pClient) { + m_pClient->PutModule(GetModName(), sLine); + return true; + } - if (m_pNetwork) { - return m_pNetwork->PutModule(GetModName(), sLine); - } + if (m_pNetwork) { + return m_pNetwork->PutModule(GetModName(), sLine); + } - if (m_pUser) { - return m_pUser->PutModule(GetModName(), sLine); - } + if (m_pUser) { + return m_pUser->PutModule(GetModName(), sLine); + } - return false; + return false; } bool CModule::PutModNotice(const CString& sLine) { - if (!m_pUser) return false; + if (!m_pUser) return false; - if (m_pClient) { - m_pClient->PutModNotice(GetModName(), sLine); - return true; - } + if (m_pClient) { + m_pClient->PutModNotice(GetModName(), sLine); + return true; + } - return m_pUser->PutModNotice(GetModName(), sLine); + return m_pUser->PutModNotice(GetModName(), sLine); } /////////////////// // Global Module // /////////////////// CModule::EModRet CModule::OnAddUser(CUser& User, CString& sErrorRet) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnDeleteUser(CUser& User) { return CONTINUE; } void CModule::OnClientConnect(CZNCSock* pClient, const CString& sHost, unsigned short uPort) {} CModule::EModRet CModule::OnLoginAttempt(std::shared_ptr Auth) { - return CONTINUE; + return CONTINUE; } void CModule::OnFailedLogin(const CString& sUsername, const CString& sRemoteIP) {} CModule::EModRet CModule::OnUnknownUserRaw(CClient* pClient, CString& sLine) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnUnknownUserRawMessage(CMessage& Message) { - return CONTINUE; + return CONTINUE; } void CModule::OnClientCapLs(CClient* pClient, SCString& ssCaps) {} bool CModule::IsClientCapSupported(CClient* pClient, const CString& sCap, bool bState) { - return false; + return false; } void CModule::OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState) {} @@ -1045,16 +1045,16 @@ CModule::EModRet CModule::OnModuleLoading(const CString& sModName, const CString& sArgs, CModInfo::EModuleType eType, bool& bSuccess, CString& sRetMsg) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg) { - return CONTINUE; + return CONTINUE; } CModule::EModRet CModule::OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg) { - return CONTINUE; + return CONTINUE; } void CModule::OnGetAvailableMods(set& ssMods, CModInfo::EModuleType eType) {} @@ -1065,869 +1065,869 @@ CModules::CModules() CModules::~CModules() { UnloadAll(); } void CModules::UnloadAll() { - while (size()) { - CString sRetMsg; - CString sModName = back()->GetModName(); - UnloadModule(sModName, sRetMsg); - } + while (size()) { + CString sRetMsg; + CString sModName = back()->GetModName(); + UnloadModule(sModName, sRetMsg); + } } bool CModules::OnBoot() { - for (CModule* pMod : *this) { - try { - if (!pMod->OnBoot()) { - return true; - } - } catch (const CModule::EModException& e) { - if (e == CModule::UNLOAD) { - UnloadModule(pMod->GetModName()); - } - } - } + for (CModule* pMod : *this) { + try { + if (!pMod->OnBoot()) { + return true; + } + } catch (const CModule::EModException& e) { + if (e == CModule::UNLOAD) { + UnloadModule(pMod->GetModName()); + } + } + } - return false; + return false; } bool CModules::OnPreRehash() { - MODUNLOADCHK(OnPreRehash()); - return false; + MODUNLOADCHK(OnPreRehash()); + return false; } bool CModules::OnPostRehash() { - MODUNLOADCHK(OnPostRehash()); - return false; + MODUNLOADCHK(OnPostRehash()); + return false; } bool CModules::OnIRCConnected() { - MODUNLOADCHK(OnIRCConnected()); - return false; + MODUNLOADCHK(OnIRCConnected()); + return false; } bool CModules::OnIRCConnecting(CIRCSock* pIRCSock) { - MODHALTCHK(OnIRCConnecting(pIRCSock)); + MODHALTCHK(OnIRCConnecting(pIRCSock)); } bool CModules::OnIRCConnectionError(CIRCSock* pIRCSock) { - MODUNLOADCHK(OnIRCConnectionError(pIRCSock)); - return false; + MODUNLOADCHK(OnIRCConnectionError(pIRCSock)); + return false; } bool CModules::OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName) { - MODHALTCHK(OnIRCRegistration(sPass, sNick, sIdent, sRealName)); + MODHALTCHK(OnIRCRegistration(sPass, sNick, sIdent, sRealName)); } bool CModules::OnBroadcast(CString& sMessage) { - MODHALTCHK(OnBroadcast(sMessage)); + MODHALTCHK(OnBroadcast(sMessage)); } bool CModules::OnIRCDisconnected() { - MODUNLOADCHK(OnIRCDisconnected()); - return false; + MODUNLOADCHK(OnIRCDisconnected()); + return false; } bool CModules::OnChanPermission2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) { - MODUNLOADCHK( - OnChanPermission2(pOpNick, Nick, Channel, uMode, bAdded, bNoChange)); - return false; + MODUNLOADCHK( + OnChanPermission2(pOpNick, Nick, Channel, uMode, bAdded, bNoChange)); + return false; } bool CModules::OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) { - MODUNLOADCHK( - OnChanPermission(OpNick, Nick, Channel, uMode, bAdded, bNoChange)); - return false; + MODUNLOADCHK( + OnChanPermission(OpNick, Nick, Channel, uMode, bAdded, bNoChange)); + return false; } bool CModules::OnOp2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnOp2(pOpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnOp2(pOpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnOp(OpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnOp(OpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnDeop2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnDeop2(pOpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnDeop2(pOpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnDeop(OpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnDeop(OpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnVoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnVoice2(pOpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnVoice2(pOpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnVoice(OpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnVoice(OpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnDevoice2(const CNick* pOpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnDevoice2(pOpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnDevoice2(pOpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) { - MODUNLOADCHK(OnDevoice(OpNick, Nick, Channel, bNoChange)); - return false; + MODUNLOADCHK(OnDevoice(OpNick, Nick, Channel, bNoChange)); + return false; } bool CModules::OnRawMode2(const CNick* pOpNick, CChan& Channel, const CString& sModes, const CString& sArgs) { - MODUNLOADCHK(OnRawMode2(pOpNick, Channel, sModes, sArgs)); - return false; + MODUNLOADCHK(OnRawMode2(pOpNick, Channel, sModes, sArgs)); + return false; } bool CModules::OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs) { - MODUNLOADCHK(OnRawMode(OpNick, Channel, sModes, sArgs)); - return false; + MODUNLOADCHK(OnRawMode(OpNick, Channel, sModes, sArgs)); + return false; } bool CModules::OnMode2(const CNick* pOpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) { - MODUNLOADCHK(OnMode2(pOpNick, Channel, uMode, sArg, bAdded, bNoChange)); - return false; + MODUNLOADCHK(OnMode2(pOpNick, Channel, uMode, sArg, bAdded, bNoChange)); + return false; } bool CModules::OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) { - MODUNLOADCHK(OnMode(OpNick, Channel, uMode, sArg, bAdded, bNoChange)); - return false; + MODUNLOADCHK(OnMode(OpNick, Channel, uMode, sArg, bAdded, bNoChange)); + return false; } bool CModules::OnRaw(CString& sLine) { MODHALTCHK(OnRaw(sLine)); } bool CModules::OnRawMessage(CMessage& Message) { - MODHALTCHK(OnRawMessage(Message)); + MODHALTCHK(OnRawMessage(Message)); } bool CModules::OnNumericMessage(CNumericMessage& Message) { - MODHALTCHK(OnNumericMessage(Message)); + MODHALTCHK(OnNumericMessage(Message)); } bool CModules::OnClientLogin() { - MODUNLOADCHK(OnClientLogin()); - return false; + MODUNLOADCHK(OnClientLogin()); + return false; } bool CModules::OnClientDisconnect() { - MODUNLOADCHK(OnClientDisconnect()); - return false; + MODUNLOADCHK(OnClientDisconnect()); + return false; } bool CModules::OnUserRaw(CString& sLine) { MODHALTCHK(OnUserRaw(sLine)); } bool CModules::OnUserRawMessage(CMessage& Message) { - MODHALTCHK(OnUserRawMessage(Message)); + MODHALTCHK(OnUserRawMessage(Message)); } bool CModules::OnUserCTCPReply(CString& sTarget, CString& sMessage) { - MODHALTCHK(OnUserCTCPReply(sTarget, sMessage)); + MODHALTCHK(OnUserCTCPReply(sTarget, sMessage)); } bool CModules::OnUserCTCPReplyMessage(CCTCPMessage& Message) { - MODHALTCHK(OnUserCTCPReplyMessage(Message)); + MODHALTCHK(OnUserCTCPReplyMessage(Message)); } bool CModules::OnUserCTCP(CString& sTarget, CString& sMessage) { - MODHALTCHK(OnUserCTCP(sTarget, sMessage)); + MODHALTCHK(OnUserCTCP(sTarget, sMessage)); } bool CModules::OnUserCTCPMessage(CCTCPMessage& Message) { - MODHALTCHK(OnUserCTCPMessage(Message)); + MODHALTCHK(OnUserCTCPMessage(Message)); } bool CModules::OnUserAction(CString& sTarget, CString& sMessage) { - MODHALTCHK(OnUserAction(sTarget, sMessage)); + MODHALTCHK(OnUserAction(sTarget, sMessage)); } bool CModules::OnUserActionMessage(CActionMessage& Message) { - MODHALTCHK(OnUserActionMessage(Message)); + MODHALTCHK(OnUserActionMessage(Message)); } bool CModules::OnUserMsg(CString& sTarget, CString& sMessage) { - MODHALTCHK(OnUserMsg(sTarget, sMessage)); + MODHALTCHK(OnUserMsg(sTarget, sMessage)); } bool CModules::OnUserTextMessage(CTextMessage& Message) { - MODHALTCHK(OnUserTextMessage(Message)); + MODHALTCHK(OnUserTextMessage(Message)); } bool CModules::OnUserNotice(CString& sTarget, CString& sMessage) { - MODHALTCHK(OnUserNotice(sTarget, sMessage)); + MODHALTCHK(OnUserNotice(sTarget, sMessage)); } bool CModules::OnUserNoticeMessage(CNoticeMessage& Message) { - MODHALTCHK(OnUserNoticeMessage(Message)); + MODHALTCHK(OnUserNoticeMessage(Message)); } bool CModules::OnUserJoin(CString& sChannel, CString& sKey) { - MODHALTCHK(OnUserJoin(sChannel, sKey)); + MODHALTCHK(OnUserJoin(sChannel, sKey)); } bool CModules::OnUserJoinMessage(CJoinMessage& Message) { - MODHALTCHK(OnUserJoinMessage(Message)); + MODHALTCHK(OnUserJoinMessage(Message)); } bool CModules::OnUserPart(CString& sChannel, CString& sMessage) { - MODHALTCHK(OnUserPart(sChannel, sMessage)); + MODHALTCHK(OnUserPart(sChannel, sMessage)); } bool CModules::OnUserPartMessage(CPartMessage& Message) { - MODHALTCHK(OnUserPartMessage(Message)); + MODHALTCHK(OnUserPartMessage(Message)); } bool CModules::OnUserTopic(CString& sChannel, CString& sTopic) { - MODHALTCHK(OnUserTopic(sChannel, sTopic)); + MODHALTCHK(OnUserTopic(sChannel, sTopic)); } bool CModules::OnUserTopicMessage(CTopicMessage& Message) { - MODHALTCHK(OnUserTopicMessage(Message)); + MODHALTCHK(OnUserTopicMessage(Message)); } bool CModules::OnUserTopicRequest(CString& sChannel) { - MODHALTCHK(OnUserTopicRequest(sChannel)); + MODHALTCHK(OnUserTopicRequest(sChannel)); } bool CModules::OnUserQuit(CString& sMessage) { - MODHALTCHK(OnUserQuit(sMessage)); + MODHALTCHK(OnUserQuit(sMessage)); } bool CModules::OnUserQuitMessage(CQuitMessage& Message) { - MODHALTCHK(OnUserQuitMessage(Message)); + MODHALTCHK(OnUserQuitMessage(Message)); } bool CModules::OnQuit(const CNick& Nick, const CString& sMessage, const vector& vChans) { - MODUNLOADCHK(OnQuit(Nick, sMessage, vChans)); - return false; + MODUNLOADCHK(OnQuit(Nick, sMessage, vChans)); + return false; } bool CModules::OnQuitMessage(CQuitMessage& Message, const vector& vChans) { - MODUNLOADCHK(OnQuitMessage(Message, vChans)); - return false; + MODUNLOADCHK(OnQuitMessage(Message, vChans)); + return false; } bool CModules::OnNick(const CNick& Nick, const CString& sNewNick, const vector& vChans) { - MODUNLOADCHK(OnNick(Nick, sNewNick, vChans)); - return false; + MODUNLOADCHK(OnNick(Nick, sNewNick, vChans)); + return false; } bool CModules::OnNickMessage(CNickMessage& Message, const vector& vChans) { - MODUNLOADCHK(OnNickMessage(Message, vChans)); - return false; + MODUNLOADCHK(OnNickMessage(Message, vChans)); + return false; } bool CModules::OnKick(const CNick& Nick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) { - MODUNLOADCHK(OnKick(Nick, sKickedNick, Channel, sMessage)); - return false; + MODUNLOADCHK(OnKick(Nick, sKickedNick, Channel, sMessage)); + return false; } bool CModules::OnKickMessage(CKickMessage& Message) { - MODUNLOADCHK(OnKickMessage(Message)); - return false; + MODUNLOADCHK(OnKickMessage(Message)); + return false; } bool CModules::OnJoining(CChan& Channel) { MODHALTCHK(OnJoining(Channel)); } bool CModules::OnJoin(const CNick& Nick, CChan& Channel) { - MODUNLOADCHK(OnJoin(Nick, Channel)); - return false; + MODUNLOADCHK(OnJoin(Nick, Channel)); + return false; } bool CModules::OnJoinMessage(CJoinMessage& Message) { - MODUNLOADCHK(OnJoinMessage(Message)); - return false; + MODUNLOADCHK(OnJoinMessage(Message)); + return false; } bool CModules::OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) { - MODUNLOADCHK(OnPart(Nick, Channel, sMessage)); - return false; + MODUNLOADCHK(OnPart(Nick, Channel, sMessage)); + return false; } bool CModules::OnPartMessage(CPartMessage& Message) { - MODUNLOADCHK(OnPartMessage(Message)); - return false; + MODUNLOADCHK(OnPartMessage(Message)); + return false; } bool CModules::OnInvite(const CNick& Nick, const CString& sChan) { - MODHALTCHK(OnInvite(Nick, sChan)); + MODHALTCHK(OnInvite(Nick, sChan)); } bool CModules::OnChanBufferStarting(CChan& Chan, CClient& Client) { - MODHALTCHK(OnChanBufferStarting(Chan, Client)); + MODHALTCHK(OnChanBufferStarting(Chan, Client)); } bool CModules::OnChanBufferEnding(CChan& Chan, CClient& Client) { - MODHALTCHK(OnChanBufferEnding(Chan, Client)); + MODHALTCHK(OnChanBufferEnding(Chan, Client)); } bool CModules::OnChanBufferPlayLine2(CChan& Chan, CClient& Client, CString& sLine, const timeval& tv) { - MODHALTCHK(OnChanBufferPlayLine2(Chan, Client, sLine, tv)); + MODHALTCHK(OnChanBufferPlayLine2(Chan, Client, sLine, tv)); } bool CModules::OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine) { - MODHALTCHK(OnChanBufferPlayLine(Chan, Client, sLine)); + MODHALTCHK(OnChanBufferPlayLine(Chan, Client, sLine)); } bool CModules::OnPrivBufferPlayLine2(CClient& Client, CString& sLine, const timeval& tv) { - MODHALTCHK(OnPrivBufferPlayLine2(Client, sLine, tv)); + MODHALTCHK(OnPrivBufferPlayLine2(Client, sLine, tv)); } bool CModules::OnPrivBufferPlayLine(CClient& Client, CString& sLine) { - MODHALTCHK(OnPrivBufferPlayLine(Client, sLine)); + MODHALTCHK(OnPrivBufferPlayLine(Client, sLine)); } bool CModules::OnChanBufferPlayMessage(CMessage& Message) { - MODHALTCHK(OnChanBufferPlayMessage(Message)); + MODHALTCHK(OnChanBufferPlayMessage(Message)); } bool CModules::OnPrivBufferPlayMessage(CMessage& Message) { - MODHALTCHK(OnPrivBufferPlayMessage(Message)); + MODHALTCHK(OnPrivBufferPlayMessage(Message)); } bool CModules::OnCTCPReply(CNick& Nick, CString& sMessage) { - MODHALTCHK(OnCTCPReply(Nick, sMessage)); + MODHALTCHK(OnCTCPReply(Nick, sMessage)); } bool CModules::OnCTCPReplyMessage(CCTCPMessage& Message) { - MODHALTCHK(OnCTCPReplyMessage(Message)); + MODHALTCHK(OnCTCPReplyMessage(Message)); } bool CModules::OnPrivCTCP(CNick& Nick, CString& sMessage) { - MODHALTCHK(OnPrivCTCP(Nick, sMessage)); + MODHALTCHK(OnPrivCTCP(Nick, sMessage)); } bool CModules::OnPrivCTCPMessage(CCTCPMessage& Message) { - MODHALTCHK(OnPrivCTCPMessage(Message)); + MODHALTCHK(OnPrivCTCPMessage(Message)); } bool CModules::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { - MODHALTCHK(OnChanCTCP(Nick, Channel, sMessage)); + MODHALTCHK(OnChanCTCP(Nick, Channel, sMessage)); } bool CModules::OnChanCTCPMessage(CCTCPMessage& Message) { - MODHALTCHK(OnChanCTCPMessage(Message)); + MODHALTCHK(OnChanCTCPMessage(Message)); } bool CModules::OnPrivAction(CNick& Nick, CString& sMessage) { - MODHALTCHK(OnPrivAction(Nick, sMessage)); + MODHALTCHK(OnPrivAction(Nick, sMessage)); } bool CModules::OnPrivActionMessage(CActionMessage& Message) { - MODHALTCHK(OnPrivActionMessage(Message)); + MODHALTCHK(OnPrivActionMessage(Message)); } bool CModules::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) { - MODHALTCHK(OnChanAction(Nick, Channel, sMessage)); + MODHALTCHK(OnChanAction(Nick, Channel, sMessage)); } bool CModules::OnChanActionMessage(CActionMessage& Message) { - MODHALTCHK(OnChanActionMessage(Message)); + MODHALTCHK(OnChanActionMessage(Message)); } bool CModules::OnPrivMsg(CNick& Nick, CString& sMessage) { - MODHALTCHK(OnPrivMsg(Nick, sMessage)); + MODHALTCHK(OnPrivMsg(Nick, sMessage)); } bool CModules::OnPrivMessage(CTextMessage& Message) { - MODHALTCHK(OnPrivMessage(Message)); + MODHALTCHK(OnPrivMessage(Message)); } bool CModules::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { - MODHALTCHK(OnChanMsg(Nick, Channel, sMessage)); + MODHALTCHK(OnChanMsg(Nick, Channel, sMessage)); } bool CModules::OnChanMessage(CTextMessage& Message) { - MODHALTCHK(OnChanMessage(Message)); + MODHALTCHK(OnChanMessage(Message)); } bool CModules::OnPrivNotice(CNick& Nick, CString& sMessage) { - MODHALTCHK(OnPrivNotice(Nick, sMessage)); + MODHALTCHK(OnPrivNotice(Nick, sMessage)); } bool CModules::OnPrivNoticeMessage(CNoticeMessage& Message) { - MODHALTCHK(OnPrivNoticeMessage(Message)); + MODHALTCHK(OnPrivNoticeMessage(Message)); } bool CModules::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) { - MODHALTCHK(OnChanNotice(Nick, Channel, sMessage)); + MODHALTCHK(OnChanNotice(Nick, Channel, sMessage)); } bool CModules::OnChanNoticeMessage(CNoticeMessage& Message) { - MODHALTCHK(OnChanNoticeMessage(Message)); + MODHALTCHK(OnChanNoticeMessage(Message)); } bool CModules::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) { - MODHALTCHK(OnTopic(Nick, Channel, sTopic)); + MODHALTCHK(OnTopic(Nick, Channel, sTopic)); } bool CModules::OnTopicMessage(CTopicMessage& Message) { - MODHALTCHK(OnTopicMessage(Message)); + MODHALTCHK(OnTopicMessage(Message)); } bool CModules::OnTimerAutoJoin(CChan& Channel) { - MODHALTCHK(OnTimerAutoJoin(Channel)); + MODHALTCHK(OnTimerAutoJoin(Channel)); } bool CModules::OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) { - MODHALTCHK(OnAddNetwork(Network, sErrorRet)); + MODHALTCHK(OnAddNetwork(Network, sErrorRet)); } bool CModules::OnDeleteNetwork(CIRCNetwork& Network) { - MODHALTCHK(OnDeleteNetwork(Network)); + MODHALTCHK(OnDeleteNetwork(Network)); } bool CModules::OnSendToClient(CString& sLine, CClient& Client) { - MODHALTCHK(OnSendToClient(sLine, Client)); + MODHALTCHK(OnSendToClient(sLine, Client)); } bool CModules::OnSendToIRC(CString& sLine) { MODHALTCHK(OnSendToIRC(sLine)); } bool CModules::OnStatusCommand(CString& sCommand) { - MODHALTCHK(OnStatusCommand(sCommand)); + MODHALTCHK(OnStatusCommand(sCommand)); } bool CModules::OnModCommand(const CString& sCommand) { - MODUNLOADCHK(OnModCommand(sCommand)); - return false; + MODUNLOADCHK(OnModCommand(sCommand)); + return false; } bool CModules::OnModNotice(const CString& sMessage) { - MODUNLOADCHK(OnModNotice(sMessage)); - return false; + MODUNLOADCHK(OnModNotice(sMessage)); + return false; } bool CModules::OnModCTCP(const CString& sMessage) { - MODUNLOADCHK(OnModCTCP(sMessage)); - return false; + MODUNLOADCHK(OnModCTCP(sMessage)); + return false; } // Why MODHALTCHK works only with functions returning EModRet ? :( bool CModules::OnServerCapAvailable(const CString& sCap) { - bool bResult = false; - for (CModule* pMod : *this) { - try { - CClient* pOldClient = pMod->GetClient(); - pMod->SetClient(m_pClient); - if (m_pUser) { - CUser* pOldUser = pMod->GetUser(); - pMod->SetUser(m_pUser); - bResult |= pMod->OnServerCapAvailable(sCap); - pMod->SetUser(pOldUser); - } else { - // WTF? Is that possible? - bResult |= pMod->OnServerCapAvailable(sCap); - } - pMod->SetClient(pOldClient); - } catch (const CModule::EModException& e) { - if (CModule::UNLOAD == e) { - UnloadModule(pMod->GetModName()); - } - } - } - return bResult; + bool bResult = false; + for (CModule* pMod : *this) { + try { + CClient* pOldClient = pMod->GetClient(); + pMod->SetClient(m_pClient); + if (m_pUser) { + CUser* pOldUser = pMod->GetUser(); + pMod->SetUser(m_pUser); + bResult |= pMod->OnServerCapAvailable(sCap); + pMod->SetUser(pOldUser); + } else { + // WTF? Is that possible? + bResult |= pMod->OnServerCapAvailable(sCap); + } + pMod->SetClient(pOldClient); + } catch (const CModule::EModException& e) { + if (CModule::UNLOAD == e) { + UnloadModule(pMod->GetModName()); + } + } + } + return bResult; } bool CModules::OnServerCapResult(const CString& sCap, bool bSuccess) { - MODUNLOADCHK(OnServerCapResult(sCap, bSuccess)); - return false; + MODUNLOADCHK(OnServerCapResult(sCap, bSuccess)); + return false; } //////////////////// // Global Modules // //////////////////// bool CModules::OnAddUser(CUser& User, CString& sErrorRet) { - MODHALTCHK(OnAddUser(User, sErrorRet)); + MODHALTCHK(OnAddUser(User, sErrorRet)); } bool CModules::OnDeleteUser(CUser& User) { MODHALTCHK(OnDeleteUser(User)); } bool CModules::OnClientConnect(CZNCSock* pClient, const CString& sHost, unsigned short uPort) { - MODUNLOADCHK(OnClientConnect(pClient, sHost, uPort)); - return false; + MODUNLOADCHK(OnClientConnect(pClient, sHost, uPort)); + return false; } bool CModules::OnLoginAttempt(std::shared_ptr Auth) { - MODHALTCHK(OnLoginAttempt(Auth)); + MODHALTCHK(OnLoginAttempt(Auth)); } bool CModules::OnFailedLogin(const CString& sUsername, const CString& sRemoteIP) { - MODUNLOADCHK(OnFailedLogin(sUsername, sRemoteIP)); - return false; + MODUNLOADCHK(OnFailedLogin(sUsername, sRemoteIP)); + return false; } bool CModules::OnUnknownUserRaw(CClient* pClient, CString& sLine) { - MODHALTCHK(OnUnknownUserRaw(pClient, sLine)); + MODHALTCHK(OnUnknownUserRaw(pClient, sLine)); } bool CModules::OnUnknownUserRawMessage(CMessage& Message) { - MODHALTCHK(OnUnknownUserRawMessage(Message)); + MODHALTCHK(OnUnknownUserRawMessage(Message)); } bool CModules::OnClientCapLs(CClient* pClient, SCString& ssCaps) { - MODUNLOADCHK(OnClientCapLs(pClient, ssCaps)); - return false; + MODUNLOADCHK(OnClientCapLs(pClient, ssCaps)); + return false; } // Maybe create new macro for this? bool CModules::IsClientCapSupported(CClient* pClient, const CString& sCap, bool bState) { - bool bResult = false; - for (CModule* pMod : *this) { - try { - CClient* pOldClient = pMod->GetClient(); - pMod->SetClient(m_pClient); - if (m_pUser) { - CUser* pOldUser = pMod->GetUser(); - pMod->SetUser(m_pUser); - bResult |= pMod->IsClientCapSupported(pClient, sCap, bState); - pMod->SetUser(pOldUser); - } else { - // WTF? Is that possible? - bResult |= pMod->IsClientCapSupported(pClient, sCap, bState); - } - pMod->SetClient(pOldClient); - } catch (const CModule::EModException& e) { - if (CModule::UNLOAD == e) { - UnloadModule(pMod->GetModName()); - } - } - } - return bResult; + bool bResult = false; + for (CModule* pMod : *this) { + try { + CClient* pOldClient = pMod->GetClient(); + pMod->SetClient(m_pClient); + if (m_pUser) { + CUser* pOldUser = pMod->GetUser(); + pMod->SetUser(m_pUser); + bResult |= pMod->IsClientCapSupported(pClient, sCap, bState); + pMod->SetUser(pOldUser); + } else { + // WTF? Is that possible? + bResult |= pMod->IsClientCapSupported(pClient, sCap, bState); + } + pMod->SetClient(pOldClient); + } catch (const CModule::EModException& e) { + if (CModule::UNLOAD == e) { + UnloadModule(pMod->GetModName()); + } + } + } + return bResult; } bool CModules::OnClientCapRequest(CClient* pClient, const CString& sCap, bool bState) { - MODUNLOADCHK(OnClientCapRequest(pClient, sCap, bState)); - return false; + MODUNLOADCHK(OnClientCapRequest(pClient, sCap, bState)); + return false; } bool CModules::OnModuleLoading(const CString& sModName, const CString& sArgs, CModInfo::EModuleType eType, bool& bSuccess, CString& sRetMsg) { - MODHALTCHK(OnModuleLoading(sModName, sArgs, eType, bSuccess, sRetMsg)); + MODHALTCHK(OnModuleLoading(sModName, sArgs, eType, bSuccess, sRetMsg)); } bool CModules::OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg) { - MODHALTCHK(OnModuleUnloading(pModule, bSuccess, sRetMsg)); + MODHALTCHK(OnModuleUnloading(pModule, bSuccess, sRetMsg)); } bool CModules::OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg) { - MODHALTCHK(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg)); + MODHALTCHK(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg)); } bool CModules::OnGetAvailableMods(set& ssMods, CModInfo::EModuleType eType) { - MODUNLOADCHK(OnGetAvailableMods(ssMods, eType)); - return false; + MODUNLOADCHK(OnGetAvailableMods(ssMods, eType)); + return false; } CModule* CModules::FindModule(const CString& sModule) const { - for (CModule* pMod : *this) { - if (sModule.Equals(pMod->GetModName())) { - return pMod; - } - } + for (CModule* pMod : *this) { + if (sModule.Equals(pMod->GetModName())) { + return pMod; + } + } - return nullptr; + return nullptr; } bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg) { - sRetMsg = ""; + sRetMsg = ""; - if (FindModule(sModule) != nullptr) { - sRetMsg = "Module [" + sModule + "] already loaded."; - return false; - } + if (FindModule(sModule) != nullptr) { + sRetMsg = "Module [" + sModule + "] already loaded."; + return false; + } - bool bSuccess; - bool bHandled = false; - _GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, eType, bSuccess, sRetMsg), - pUser, pNetwork, nullptr, &bHandled); - if (bHandled) return bSuccess; + bool bSuccess; + bool bHandled = false; + _GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, eType, bSuccess, sRetMsg), + pUser, pNetwork, nullptr, &bHandled); + if (bHandled) return bSuccess; - CString sModPath, sDataPath; - bool bVersionMismatch; - CModInfo Info; + CString sModPath, sDataPath; + bool bVersionMismatch; + CModInfo Info; - if (!FindModPath(sModule, sModPath, sDataPath)) { - sRetMsg = "Unable to find module [" + sModule + "]"; - return false; - } + if (!FindModPath(sModule, sModPath, sDataPath)) { + sRetMsg = "Unable to find module [" + sModule + "]"; + return false; + } - ModHandle p = - OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); + ModHandle p = + OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); - if (!p) return false; + if (!p) return false; - if (bVersionMismatch) { - dlclose(p); - sRetMsg = "Version mismatch, recompile this module."; - return false; - } + if (bVersionMismatch) { + dlclose(p); + sRetMsg = "Version mismatch, recompile this module."; + return false; + } - if (!Info.SupportsType(eType)) { - dlclose(p); - sRetMsg = "Module [" + sModule + "] does not support module type [" + - CModInfo::ModuleTypeToString(eType) + "]."; - return false; - } + if (!Info.SupportsType(eType)) { + dlclose(p); + sRetMsg = "Module [" + sModule + "] does not support module type [" + + CModInfo::ModuleTypeToString(eType) + "]."; + return false; + } - if (!pUser && eType == CModInfo::UserModule) { - dlclose(p); - sRetMsg = "Module [" + sModule + "] requires a user."; - return false; - } + if (!pUser && eType == CModInfo::UserModule) { + dlclose(p); + sRetMsg = "Module [" + sModule + "] requires a user."; + return false; + } - if (!pNetwork && eType == CModInfo::NetworkModule) { - dlclose(p); - sRetMsg = "Module [" + sModule + "] requires a network."; - return false; - } + if (!pNetwork && eType == CModInfo::NetworkModule) { + dlclose(p); + sRetMsg = "Module [" + sModule + "] requires a network."; + return false; + } - CModule* pModule = - Info.GetLoader()(p, pUser, pNetwork, sModule, sDataPath, eType); - pModule->SetDescription(Info.GetDescription()); - pModule->SetArgs(sArgs); - pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); - push_back(pModule); + CModule* pModule = + Info.GetLoader()(p, pUser, pNetwork, sModule, sDataPath, eType); + pModule->SetDescription(Info.GetDescription()); + pModule->SetArgs(sArgs); + pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); + push_back(pModule); - bool bLoaded; - try { - bLoaded = pModule->OnLoad(sArgs, sRetMsg); - } catch (const CModule::EModException&) { - bLoaded = false; - sRetMsg = "Caught an exception"; - } + bool bLoaded; + try { + bLoaded = pModule->OnLoad(sArgs, sRetMsg); + } catch (const CModule::EModException&) { + bLoaded = false; + sRetMsg = "Caught an exception"; + } - if (!bLoaded) { - UnloadModule(sModule, sModPath); - if (!sRetMsg.empty()) - sRetMsg = "Module [" + sModule + "] aborted: " + sRetMsg; - else - sRetMsg = "Module [" + sModule + "] aborted."; - return false; - } + if (!bLoaded) { + UnloadModule(sModule, sModPath); + if (!sRetMsg.empty()) + sRetMsg = "Module [" + sModule + "] aborted: " + sRetMsg; + else + sRetMsg = "Module [" + sModule + "] aborted."; + return false; + } - if (!sRetMsg.empty()) { - sRetMsg += " "; - } - sRetMsg += "[" + sModPath + "]"; - return true; + if (!sRetMsg.empty()) { + sRetMsg += " "; + } + sRetMsg += "[" + sModPath + "]"; + return true; } bool CModules::UnloadModule(const CString& sModule) { - CString s; - return UnloadModule(sModule, s); + CString s; + return UnloadModule(sModule, s); } bool CModules::UnloadModule(const CString& sModule, CString& sRetMsg) { - // Make a copy incase the reference passed in is from CModule::GetModName() - CString sMod = sModule; + // Make a copy incase the reference passed in is from CModule::GetModName() + CString sMod = sModule; - CModule* pModule = FindModule(sMod); - sRetMsg = ""; + CModule* pModule = FindModule(sMod); + sRetMsg = ""; - if (!pModule) { - sRetMsg = "Module [" + sMod + "] not loaded."; - return false; - } + if (!pModule) { + sRetMsg = "Module [" + sMod + "] not loaded."; + return false; + } - bool bSuccess; - bool bHandled = false; - _GLOBALMODULECALL(OnModuleUnloading(pModule, bSuccess, sRetMsg), - pModule->GetUser(), pModule->GetNetwork(), nullptr, - &bHandled); - if (bHandled) return bSuccess; + bool bSuccess; + bool bHandled = false; + _GLOBALMODULECALL(OnModuleUnloading(pModule, bSuccess, sRetMsg), + pModule->GetUser(), pModule->GetNetwork(), nullptr, + &bHandled); + if (bHandled) return bSuccess; - ModHandle p = pModule->GetDLL(); + ModHandle p = pModule->GetDLL(); - if (p) { - delete pModule; + if (p) { + delete pModule; - for (iterator it = begin(); it != end(); ++it) { - if (*it == pModule) { - erase(it); - break; - } - } + for (iterator it = begin(); it != end(); ++it) { + if (*it == pModule) { + erase(it); + break; + } + } - dlclose(p); - sRetMsg = "Module [" + sMod + "] unloaded"; + dlclose(p); + sRetMsg = "Module [" + sMod + "] unloaded"; - return true; - } + return true; + } - sRetMsg = "Unable to unload module [" + sMod + "]"; - return false; + sRetMsg = "Unable to unload module [" + sMod + "]"; + return false; } bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg) { - // Make a copy incase the reference passed in is from CModule::GetModName() - CString sMod = sModule; + // Make a copy incase the reference passed in is from CModule::GetModName() + CString sMod = sModule; - CModule* pModule = FindModule(sMod); + CModule* pModule = FindModule(sMod); - if (!pModule) { - sRetMsg = "Module [" + sMod + "] not loaded"; - return false; - } + if (!pModule) { + sRetMsg = "Module [" + sMod + "] not loaded"; + return false; + } - CModInfo::EModuleType eType = pModule->GetType(); - pModule = nullptr; + CModInfo::EModuleType eType = pModule->GetType(); + pModule = nullptr; - sRetMsg = ""; - if (!UnloadModule(sMod, sRetMsg)) { - return false; - } + sRetMsg = ""; + if (!UnloadModule(sMod, sRetMsg)) { + return false; + } - if (!LoadModule(sMod, sArgs, eType, pUser, pNetwork, sRetMsg)) { - return false; - } + if (!LoadModule(sMod, sArgs, eType, pUser, pNetwork, sRetMsg)) { + return false; + } - sRetMsg = "Reloaded module [" + sMod + "]"; - return true; + sRetMsg = "Reloaded module [" + sMod + "]"; + return true; } bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule, CString& sRetMsg) { - CString sModPath, sTmp; + CString sModPath, sTmp; - bool bSuccess; - bool bHandled = false; - GLOBALMODULECALL(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg), - &bHandled); - if (bHandled) return bSuccess; + bool bSuccess; + bool bHandled = false; + GLOBALMODULECALL(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg), + &bHandled); + if (bHandled) return bSuccess; - if (!FindModPath(sModule, sModPath, sTmp)) { - sRetMsg = "Unable to find module [" + sModule + "]"; - return false; - } + if (!FindModPath(sModule, sModPath, sTmp)) { + sRetMsg = "Unable to find module [" + sModule + "]"; + return false; + } - return GetModPathInfo(ModInfo, sModule, sModPath, sRetMsg); + return GetModPathInfo(ModInfo, sModule, sModPath, sRetMsg); } bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString& sRetMsg) { - bool bVersionMismatch; + bool bVersionMismatch; - ModHandle p = - OpenModule(sModule, sModPath, bVersionMismatch, ModInfo, sRetMsg); + ModHandle p = + OpenModule(sModule, sModPath, bVersionMismatch, ModInfo, sRetMsg); - if (!p) return false; + if (!p) return false; - ModInfo.SetName(sModule); - ModInfo.SetPath(sModPath); + ModInfo.SetName(sModule); + ModInfo.SetPath(sModPath); - if (bVersionMismatch) { - ModInfo.SetDescription( - "--- Version mismatch, recompile this module. ---"); - } + if (bVersionMismatch) { + ModInfo.SetDescription( + "--- Version mismatch, recompile this module. ---"); + } - dlclose(p); + dlclose(p); - return true; + return true; } void CModules::GetAvailableMods(set& ssMods, CModInfo::EModuleType eType) { - ssMods.clear(); + ssMods.clear(); - unsigned int a = 0; - CDir Dir; + unsigned int a = 0; + CDir Dir; - ModDirList dirs = GetModDirs(); + ModDirList dirs = GetModDirs(); - while (!dirs.empty()) { - Dir.FillByWildcard(dirs.front().first, "*.so"); - dirs.pop(); + while (!dirs.empty()) { + Dir.FillByWildcard(dirs.front().first, "*.so"); + dirs.pop(); - for (a = 0; a < Dir.size(); a++) { - CFile& File = *Dir[a]; - CString sName = File.GetShortName(); - CString sPath = File.GetLongName(); - CModInfo ModInfo; - sName.RightChomp(3); + for (a = 0; a < Dir.size(); a++) { + CFile& File = *Dir[a]; + CString sName = File.GetShortName(); + CString sPath = File.GetLongName(); + CModInfo ModInfo; + sName.RightChomp(3); - CString sIgnoreRetMsg; - if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) { - if (ModInfo.SupportsType(eType)) { - ssMods.insert(ModInfo); - } - } - } - } + CString sIgnoreRetMsg; + if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) { + if (ModInfo.SupportsType(eType)) { + ssMods.insert(ModInfo); + } + } + } + } - GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NOTHING); + GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NOTHING); } void CModules::GetDefaultMods(set& ssMods, CModInfo::EModuleType eType) { - GetAvailableMods(ssMods, eType); + GetAvailableMods(ssMods, eType); - const map ns = { - {"chansaver", CModInfo::UserModule}, - {"controlpanel", CModInfo::UserModule}, - {"simple_away", CModInfo::NetworkModule}, - {"webadmin", CModInfo::GlobalModule}}; + const map ns = { + {"chansaver", CModInfo::UserModule}, + {"controlpanel", CModInfo::UserModule}, + {"simple_away", CModInfo::NetworkModule}, + {"webadmin", CModInfo::GlobalModule}}; - auto it = ssMods.begin(); - while (it != ssMods.end()) { - auto it2 = ns.find(it->GetName()); - if (it2 != ns.end() && it2->second == eType) { - ++it; - } else { - it = ssMods.erase(it); - } - } + auto it = ssMods.begin(); + while (it != ssMods.end()) { + auto it2 = ns.find(it->GetName()); + if (it2 != ns.end() && it2->second == eType) { + ++it; + } else { + it = ssMods.erase(it); + } + } } bool CModules::FindModPath(const CString& sModule, CString& sModPath, CString& sDataPath) { - CString sMod = sModule; - CString sDir = sMod; - if (!sModule.Contains(".")) sMod += ".so"; + CString sMod = sModule; + CString sDir = sMod; + if (!sModule.Contains(".")) sMod += ".so"; - ModDirList dirs = GetModDirs(); + ModDirList dirs = GetModDirs(); - while (!dirs.empty()) { - sModPath = dirs.front().first + sMod; - sDataPath = dirs.front().second; - dirs.pop(); + while (!dirs.empty()) { + sModPath = dirs.front().first + sMod; + sDataPath = dirs.front().second; + dirs.pop(); - if (CFile::Exists(sModPath)) { - sDataPath += sDir; - return true; - } - } + if (CFile::Exists(sModPath)) { + sDataPath += sDir; + return true; + } + } - return false; + return false; } CModules::ModDirList CModules::GetModDirs() { - ModDirList ret; - CString sDir; + ModDirList ret; + CString sDir; #ifdef RUN_FROM_SOURCE - // ./modules - sDir = CZNC::Get().GetCurPath() + "/modules/"; - ret.push(std::make_pair(sDir, sDir + "data/")); + // ./modules + sDir = CZNC::Get().GetCurPath() + "/modules/"; + ret.push(std::make_pair(sDir, sDir + "data/")); #endif - // ~/.znc/modules - sDir = CZNC::Get().GetModPath() + "/"; - ret.push(std::make_pair(sDir, sDir)); + // ~/.znc/modules + sDir = CZNC::Get().GetModPath() + "/"; + ret.push(std::make_pair(sDir, sDir)); - // and (/lib/znc) - ret.push(std::make_pair(_MODDIR_ + CString("/"), - _DATADIR_ + CString("/modules/"))); + // and (/lib/znc) + ret.push(std::make_pair(_MODDIR_ + CString("/"), + _DATADIR_ + CString("/modules/"))); - return ret; + return ret; } ModHandle CModules::OpenModule(const CString& sModule, const CString& sModPath, bool& bVersionMismatch, CModInfo& Info, CString& sRetMsg) { - // Some sane defaults in case anything errors out below - bVersionMismatch = false; - sRetMsg.clear(); + // Some sane defaults in case anything errors out below + bVersionMismatch = false; + sRetMsg.clear(); - for (unsigned int a = 0; a < sModule.length(); a++) { - if (((sModule[a] < '0') || (sModule[a] > '9')) && - ((sModule[a] < 'a') || (sModule[a] > 'z')) && - ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) { - sRetMsg = - "Module names can only contain letters, numbers and " - "underscores, [" + - sModule + "] is invalid."; - return nullptr; - } - } + for (unsigned int a = 0; a < sModule.length(); a++) { + if (((sModule[a] < '0') || (sModule[a] > '9')) && + ((sModule[a] < 'a') || (sModule[a] > 'z')) && + ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) { + sRetMsg = + "Module names can only contain letters, numbers and " + "underscores, [" + + sModule + "] is invalid."; + return nullptr; + } + } - // The second argument to dlopen() has a long history. It seems clear - // that (despite what the man page says) we must include either of - // RTLD_NOW and RTLD_LAZY and either of RTLD_GLOBAL and RTLD_LOCAL. - // - // RTLD_NOW vs. RTLD_LAZY: We use RTLD_NOW to avoid ZNC dying due to - // failed symbol lookups later on. Doesn't really seem to have much of a - // performance impact. - // - // RTLD_GLOBAL vs. RTLD_LOCAL: If perl is loaded with RTLD_LOCAL and later - // on loads own modules (which it apparently does with RTLD_LAZY), we will - // die in a name lookup since one of perl's symbols isn't found. That's - // worse than any theoretical issue with RTLD_GLOBAL. - ModHandle p = dlopen((sModPath).c_str(), RTLD_NOW | RTLD_GLOBAL); + // The second argument to dlopen() has a long history. It seems clear + // that (despite what the man page says) we must include either of + // RTLD_NOW and RTLD_LAZY and either of RTLD_GLOBAL and RTLD_LOCAL. + // + // RTLD_NOW vs. RTLD_LAZY: We use RTLD_NOW to avoid ZNC dying due to + // failed symbol lookups later on. Doesn't really seem to have much of a + // performance impact. + // + // RTLD_GLOBAL vs. RTLD_LOCAL: If perl is loaded with RTLD_LOCAL and later + // on loads own modules (which it apparently does with RTLD_LAZY), we will + // die in a name lookup since one of perl's symbols isn't found. That's + // worse than any theoretical issue with RTLD_GLOBAL. + ModHandle p = dlopen((sModPath).c_str(), RTLD_NOW | RTLD_GLOBAL); - if (!p) { - // dlerror() returns pointer to static buffer, which may be overwritten - // very soon with another dl call also it may just return null. - const char* cDlError = dlerror(); - CString sDlError = cDlError ? cDlError : "Unknown error"; - sRetMsg = "Unable to open module [" + sModule + "] [" + sDlError + "]"; - return nullptr; - } + if (!p) { + // dlerror() returns pointer to static buffer, which may be overwritten + // very soon with another dl call also it may just return null. + const char* cDlError = dlerror(); + CString sDlError = cDlError ? cDlError : "Unknown error"; + sRetMsg = "Unable to open module [" + sModule + "] [" + sDlError + "]"; + return nullptr; + } - typedef bool (*InfoFP)(double, CModInfo&); - InfoFP ZNCModInfo = (InfoFP)dlsym(p, "ZNCModInfo"); + typedef bool (*InfoFP)(double, CModInfo&); + InfoFP ZNCModInfo = (InfoFP)dlsym(p, "ZNCModInfo"); - if (!ZNCModInfo) { - dlclose(p); - sRetMsg = "Could not find ZNCModInfo() in module [" + sModule + "]"; - return nullptr; - } + if (!ZNCModInfo) { + dlclose(p); + sRetMsg = "Could not find ZNCModInfo() in module [" + sModule + "]"; + return nullptr; + } - if (ZNCModInfo(CModule::GetCoreVersion(), Info)) { - sRetMsg = ""; - bVersionMismatch = false; - } else { - bVersionMismatch = true; - sRetMsg = "Version mismatch, recompile this module."; - } + if (ZNCModInfo(CModule::GetCoreVersion(), Info)) { + sRetMsg = ""; + bVersionMismatch = false; + } else { + bVersionMismatch = true; + sRetMsg = "Version mismatch, recompile this module."; + } - return p; + return p; } CModCommand::CModCommand() : m_sCmd(), m_pFunc(nullptr), m_sArgs(), m_sDesc() {} @@ -1950,20 +1950,20 @@ CModCommand::CModCommand(const CModCommand& other) m_sDesc(other.m_sDesc) {} CModCommand& CModCommand::operator=(const CModCommand& other) { - m_sCmd = other.m_sCmd; - m_pFunc = other.m_pFunc; - m_sArgs = other.m_sArgs; - m_sDesc = other.m_sDesc; - return *this; + m_sCmd = other.m_sCmd; + m_pFunc = other.m_pFunc; + m_sArgs = other.m_sArgs; + m_sDesc = other.m_sDesc; + return *this; } void CModCommand::InitHelp(CTable& Table) { - Table.AddColumn("Command"); - Table.AddColumn("Description"); + Table.AddColumn("Command"); + Table.AddColumn("Description"); } void CModCommand::AddHelp(CTable& Table) const { - Table.AddRow(); - Table.SetCell("Command", GetCommand() + " " + GetArgs()); - Table.SetCell("Description", GetDescription()); + Table.AddRow(); + Table.SetCell("Command", GetCommand() + " " + GetArgs()); + Table.SetCell("Description", GetDescription()); } diff --git a/src/Nick.cpp b/src/Nick.cpp index 5d380852..8ef43f27 100644 --- a/src/Nick.cpp +++ b/src/Nick.cpp @@ -34,56 +34,56 @@ CNick::CNick(const CString& sNick) : CNick() { Parse(sNick); } CNick::~CNick() {} void CNick::Reset() { - m_sChanPerms.clear(); - m_pNetwork = nullptr; + m_sChanPerms.clear(); + m_pNetwork = nullptr; } void CNick::Parse(const CString& sNickMask) { - if (sNickMask.empty()) { - return; - } + if (sNickMask.empty()) { + return; + } - CString::size_type uPos = sNickMask.find('!'); + CString::size_type uPos = sNickMask.find('!'); - if (uPos == CString::npos) { - m_sNick = sNickMask.substr((sNickMask[0] == ':')); - return; - } + if (uPos == CString::npos) { + m_sNick = sNickMask.substr((sNickMask[0] == ':')); + return; + } - m_sNick = - sNickMask.substr((sNickMask[0] == ':'), uPos - (sNickMask[0] == ':')); - m_sHost = sNickMask.substr(uPos + 1); + m_sNick = + sNickMask.substr((sNickMask[0] == ':'), uPos - (sNickMask[0] == ':')); + m_sHost = sNickMask.substr(uPos + 1); - if ((uPos = m_sHost.find('@')) != CString::npos) { - m_sIdent = m_sHost.substr(0, uPos); - m_sHost = m_sHost.substr(uPos + 1); - } + if ((uPos = m_sHost.find('@')) != CString::npos) { + m_sIdent = m_sHost.substr(0, uPos); + m_sHost = m_sHost.substr(uPos + 1); + } } size_t CNick::GetCommonChans(vector& vRetChans, CIRCNetwork* pNetwork) const { - vRetChans.clear(); + vRetChans.clear(); - const vector& vChans = pNetwork->GetChans(); + const vector& vChans = pNetwork->GetChans(); - for (CChan* pChan : vChans) { - const map& msNicks = pChan->GetNicks(); + for (CChan* pChan : vChans) { + const map& msNicks = pChan->GetNicks(); - for (const auto& it : msNicks) { - if (it.first.Equals(m_sNick)) { - vRetChans.push_back(pChan); - continue; - } - } - } + for (const auto& it : msNicks) { + if (it.first.Equals(m_sNick)) { + vRetChans.push_back(pChan); + continue; + } + } + } - return vRetChans.size(); + return vRetChans.size(); } bool CNick::NickEquals(const CString& nickname) const { - // TODO add proper IRC case mapping here - // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-3.1 - return m_sNick.Equals(nickname); + // TODO add proper IRC case mapping here + // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-3.1 + return m_sNick.Equals(nickname); } void CNick::SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; } @@ -92,92 +92,92 @@ void CNick::SetIdent(const CString& s) { m_sIdent = s; } void CNick::SetHost(const CString& s) { m_sHost = s; } bool CNick::HasPerm(unsigned char uPerm) const { - return (uPerm && m_sChanPerms.find(uPerm) != CString::npos); + return (uPerm && m_sChanPerms.find(uPerm) != CString::npos); } bool CNick::AddPerm(unsigned char uPerm) { - if (!uPerm || HasPerm(uPerm)) { - return false; - } + if (!uPerm || HasPerm(uPerm)) { + return false; + } - m_sChanPerms.append(1, uPerm); + m_sChanPerms.append(1, uPerm); - return true; + return true; } bool CNick::RemPerm(unsigned char uPerm) { - CString::size_type uPos = m_sChanPerms.find(uPerm); - if (uPos == CString::npos) { - return false; - } + CString::size_type uPos = m_sChanPerms.find(uPerm); + if (uPos == CString::npos) { + return false; + } - m_sChanPerms.erase(uPos, 1); + m_sChanPerms.erase(uPos, 1); - return true; + return true; } unsigned char CNick::GetPermChar() const { - CIRCSock* pIRCSock = (!m_pNetwork) ? nullptr : m_pNetwork->GetIRCSock(); - const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms(); + CIRCSock* pIRCSock = (!m_pNetwork) ? nullptr : m_pNetwork->GetIRCSock(); + const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms(); - for (unsigned int a = 0; a < sChanPerms.size(); a++) { - const unsigned char& c = sChanPerms[a]; - if (HasPerm(c)) { - return c; - } - } + for (unsigned int a = 0; a < sChanPerms.size(); a++) { + const unsigned char& c = sChanPerms[a]; + if (HasPerm(c)) { + return c; + } + } - return '\0'; + return '\0'; } CString CNick::GetPermStr() const { - CIRCSock* pIRCSock = (!m_pNetwork) ? nullptr : m_pNetwork->GetIRCSock(); - const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms(); - CString sRet; + CIRCSock* pIRCSock = (!m_pNetwork) ? nullptr : m_pNetwork->GetIRCSock(); + const CString& sChanPerms = (!pIRCSock) ? "@+" : pIRCSock->GetPerms(); + CString sRet; - for (unsigned int a = 0; a < sChanPerms.size(); a++) { - const unsigned char& c = sChanPerms[a]; + for (unsigned int a = 0; a < sChanPerms.size(); a++) { + const unsigned char& c = sChanPerms[a]; - if (HasPerm(c)) { - sRet += c; - } - } + if (HasPerm(c)) { + sRet += c; + } + } - return sRet; + return sRet; } const CString& CNick::GetNick() const { return m_sNick; } const CString& CNick::GetIdent() const { return m_sIdent; } const CString& CNick::GetHost() const { return m_sHost; } CString CNick::GetNickMask() const { - CString sRet = m_sNick; + CString sRet = m_sNick; - if (!m_sHost.empty()) { - if (!m_sIdent.empty()) sRet += "!" + m_sIdent; - sRet += "@" + m_sHost; - } + if (!m_sHost.empty()) { + if (!m_sIdent.empty()) sRet += "!" + m_sIdent; + sRet += "@" + m_sHost; + } - return sRet; + return sRet; } CString CNick::GetHostMask() const { - CString sRet = m_sNick; + CString sRet = m_sNick; - if (!m_sIdent.empty()) { - sRet += "!" + m_sIdent; - } + if (!m_sIdent.empty()) { + sRet += "!" + m_sIdent; + } - if (!m_sHost.empty()) { - sRet += "@" + m_sHost; - } + if (!m_sHost.empty()) { + sRet += "@" + m_sHost; + } - return (sRet); + return (sRet); } void CNick::Clone(const CNick& SourceNick) { - SetNick(SourceNick.GetNick()); - SetIdent(SourceNick.GetIdent()); - SetHost(SourceNick.GetHost()); + SetNick(SourceNick.GetNick()); + SetIdent(SourceNick.GetIdent()); + SetHost(SourceNick.GetHost()); - m_sChanPerms = SourceNick.m_sChanPerms; - m_pNetwork = SourceNick.m_pNetwork; + m_sChanPerms = SourceNick.m_sChanPerms; + m_pNetwork = SourceNick.m_pNetwork; } diff --git a/src/Query.cpp b/src/Query.cpp index 07b68bf2..2f7b7f68 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -23,7 +23,7 @@ using std::vector; CQuery::CQuery(const CString& sName, CIRCNetwork* pNetwork) : m_sName(sName), m_pNetwork(pNetwork), m_Buffer() { - SetBufferCount(m_pNetwork->GetUser()->GetQueryBufferSize(), true); + SetBufferCount(m_pNetwork->GetUser()->GetQueryBufferSize(), true); } CQuery::~CQuery() {} @@ -31,61 +31,61 @@ CQuery::~CQuery() {} void CQuery::SendBuffer(CClient* pClient) { SendBuffer(pClient, m_Buffer); } void CQuery::SendBuffer(CClient* pClient, const CBuffer& Buffer) { - if (m_pNetwork && m_pNetwork->IsUserAttached()) { - // Based on CChan::SendBuffer() - if (!Buffer.IsEmpty()) { - const vector& vClients = m_pNetwork->GetClients(); - for (CClient* pEachClient : vClients) { - CClient* pUseClient = (pClient ? pClient : pEachClient); + if (m_pNetwork && m_pNetwork->IsUserAttached()) { + // Based on CChan::SendBuffer() + if (!Buffer.IsEmpty()) { + const vector& vClients = m_pNetwork->GetClients(); + for (CClient* pEachClient : vClients) { + CClient* pUseClient = (pClient ? pClient : pEachClient); - MCString msParams; - msParams["target"] = pUseClient->GetNick(); + MCString msParams; + msParams["target"] = pUseClient->GetNick(); - bool bWasPlaybackActive = pUseClient->IsPlaybackActive(); - pUseClient->SetPlaybackActive(true); + bool bWasPlaybackActive = pUseClient->IsPlaybackActive(); + pUseClient->SetPlaybackActive(true); - bool bBatch = pUseClient->HasBatch(); - CString sBatchName = m_sName.MD5(); + bool bBatch = pUseClient->HasBatch(); + CString sBatchName = m_sName.MD5(); - if (bBatch) { - m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + - " znc.in/playback " + m_sName, - pUseClient); - } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH +" + sBatchName + + " znc.in/playback " + m_sName, + pUseClient); + } - size_t uSize = Buffer.Size(); - for (size_t uIdx = 0; uIdx < uSize; uIdx++) { - const CBufLine& BufLine = Buffer.GetBufLine(uIdx); - CMessage Message = BufLine.ToMessage(*pUseClient, msParams); - if (!pUseClient->HasEchoMessage() && - !pUseClient->HasSelfMessage()) { - if (Message.GetNick().NickEquals( - pUseClient->GetNick())) { - continue; - } - } - Message.SetNetwork(m_pNetwork); - Message.SetClient(pUseClient); - if (bBatch) { - Message.SetTag("batch", sBatchName); - } - bool bContinue = false; - NETWORKMODULECALL(OnPrivBufferPlayMessage(Message), - m_pNetwork->GetUser(), m_pNetwork, - nullptr, &bContinue); - if (bContinue) continue; - m_pNetwork->PutUser(Message, pUseClient); - } + size_t uSize = Buffer.Size(); + for (size_t uIdx = 0; uIdx < uSize; uIdx++) { + const CBufLine& BufLine = Buffer.GetBufLine(uIdx); + CMessage Message = BufLine.ToMessage(*pUseClient, msParams); + if (!pUseClient->HasEchoMessage() && + !pUseClient->HasSelfMessage()) { + if (Message.GetNick().NickEquals( + pUseClient->GetNick())) { + continue; + } + } + Message.SetNetwork(m_pNetwork); + Message.SetClient(pUseClient); + if (bBatch) { + Message.SetTag("batch", sBatchName); + } + bool bContinue = false; + NETWORKMODULECALL(OnPrivBufferPlayMessage(Message), + m_pNetwork->GetUser(), m_pNetwork, + nullptr, &bContinue); + if (bContinue) continue; + m_pNetwork->PutUser(Message, pUseClient); + } - if (bBatch) { - m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, - pUseClient); - } + if (bBatch) { + m_pNetwork->PutUser(":znc.in BATCH -" + sBatchName, + pUseClient); + } - pUseClient->SetPlaybackActive(bWasPlaybackActive); + pUseClient->SetPlaybackActive(bWasPlaybackActive); - if (pClient) break; - } - } - } + if (pClient) break; + } + } + } } diff --git a/src/SHA256.cpp b/src/SHA256.cpp index 25083f8c..7f36537f 100644 --- a/src/SHA256.cpp +++ b/src/SHA256.cpp @@ -47,36 +47,36 @@ #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) #define UNPACK32(x, str) \ - { \ - *((str)+3) = (uint8_t)((x)); \ - *((str)+2) = (uint8_t)((x) >> 8); \ - *((str)+1) = (uint8_t)((x) >> 16); \ - *((str)+0) = (uint8_t)((x) >> 24); \ - } + { \ + *((str)+3) = (uint8_t)((x)); \ + *((str)+2) = (uint8_t)((x) >> 8); \ + *((str)+1) = (uint8_t)((x) >> 16); \ + *((str)+0) = (uint8_t)((x) >> 24); \ + } #define PACK32(str, x) \ - { \ - *(x) = ((uint32_t) * ((str)+3)) | ((uint32_t) * ((str)+2) << 8) | \ - ((uint32_t) * ((str)+1) << 16) | \ - ((uint32_t) * ((str)+0) << 24); \ - } + { \ + *(x) = ((uint32_t) * ((str)+3)) | ((uint32_t) * ((str)+2) << 8) | \ + ((uint32_t) * ((str)+1) << 16) | \ + ((uint32_t) * ((str)+0) << 24); \ + } /* Macros used for loops unrolling */ #define SHA256_SCR(i) \ - { \ - w[i] = \ - SHA256_F4(w[i - 2]) + w[i - 7] + SHA256_F3(w[i - 15]) + w[i - 16]; \ - } + { \ + w[i] = \ + SHA256_F4(w[i - 2]) + w[i - 7] + SHA256_F3(w[i - 15]) + w[i - 16]; \ + } #define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ - { \ - t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + \ - sha256_k[j] + w[j]; \ - t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ - wv[d] += t1; \ - wv[h] = t1 + t2; \ - } + { \ + t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + \ + sha256_k[j] + w[j]; \ + t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ + wv[d] += t1; \ + wv[h] = t1 + t2; \ + } uint32_t sha256_h0[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; @@ -98,117 +98,117 @@ uint32_t sha256_k[64] = { static void sha256_transf(sha256_ctx* ctx, const unsigned char* message, size_t block_nb) { - uint32_t w[64]; - uint32_t wv[8]; - uint32_t t1, t2; - const unsigned char* sub_block; - int i; + uint32_t w[64]; + uint32_t wv[8]; + uint32_t t1, t2; + const unsigned char* sub_block; + int i; - int j; + int j; - for (i = 0; i < (int)block_nb; i++) { - sub_block = message + (i << 6); + for (i = 0; i < (int)block_nb; i++) { + sub_block = message + (i << 6); - for (j = 0; j < 16; j++) { - PACK32(&sub_block[j << 2], &w[j]); - } + for (j = 0; j < 16; j++) { + PACK32(&sub_block[j << 2], &w[j]); + } - for (j = 16; j < 64; j++) { - SHA256_SCR(j); - } + for (j = 16; j < 64; j++) { + SHA256_SCR(j); + } - for (j = 0; j < 8; j++) { - wv[j] = ctx->h[j]; - } + for (j = 0; j < 8; j++) { + wv[j] = ctx->h[j]; + } - for (j = 0; j < 64; j++) { - t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + - sha256_k[j] + w[j]; - t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); - wv[7] = wv[6]; - wv[6] = wv[5]; - wv[5] = wv[4]; - wv[4] = wv[3] + t1; - wv[3] = wv[2]; - wv[2] = wv[1]; - wv[1] = wv[0]; - wv[0] = t1 + t2; - } + for (j = 0; j < 64; j++) { + t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + + sha256_k[j] + w[j]; + t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); + wv[7] = wv[6]; + wv[6] = wv[5]; + wv[5] = wv[4]; + wv[4] = wv[3] + t1; + wv[3] = wv[2]; + wv[2] = wv[1]; + wv[1] = wv[0]; + wv[0] = t1 + t2; + } - for (j = 0; j < 8; j++) { - ctx->h[j] += wv[j]; - } - } + for (j = 0; j < 8; j++) { + ctx->h[j] += wv[j]; + } + } } void sha256(const unsigned char* message, size_t len, unsigned char* digest) { - sha256_ctx ctx; + sha256_ctx ctx; - sha256_init(&ctx); - sha256_update(&ctx, message, len); - sha256_final(&ctx, digest); + sha256_init(&ctx); + sha256_update(&ctx, message, len); + sha256_final(&ctx, digest); } void sha256_init(sha256_ctx* ctx) { - int i; - for (i = 0; i < 8; i++) { - ctx->h[i] = sha256_h0[i]; - } + int i; + for (i = 0; i < 8; i++) { + ctx->h[i] = sha256_h0[i]; + } - ctx->len = 0; - ctx->tot_len = 0; + ctx->len = 0; + ctx->tot_len = 0; } void sha256_update(sha256_ctx* ctx, const unsigned char* message, size_t len) { - size_t block_nb; - size_t new_len, rem_len, tmp_len; - const unsigned char* shifted_message; + size_t block_nb; + size_t new_len, rem_len, tmp_len; + const unsigned char* shifted_message; - tmp_len = SHA256_BLOCK_SIZE - ctx->len; - rem_len = len < tmp_len ? len : tmp_len; + tmp_len = SHA256_BLOCK_SIZE - ctx->len; + rem_len = len < tmp_len ? len : tmp_len; - memcpy(&ctx->block[ctx->len], message, rem_len); + memcpy(&ctx->block[ctx->len], message, rem_len); - if (ctx->len + len < SHA256_BLOCK_SIZE) { - ctx->len += len; - return; - } + if (ctx->len + len < SHA256_BLOCK_SIZE) { + ctx->len += len; + return; + } - new_len = len - rem_len; - block_nb = new_len / SHA256_BLOCK_SIZE; + new_len = len - rem_len; + block_nb = new_len / SHA256_BLOCK_SIZE; - shifted_message = message + rem_len; + shifted_message = message + rem_len; - sha256_transf(ctx, ctx->block, 1); - sha256_transf(ctx, shifted_message, block_nb); + sha256_transf(ctx, ctx->block, 1); + sha256_transf(ctx, shifted_message, block_nb); - rem_len = new_len % SHA256_BLOCK_SIZE; + rem_len = new_len % SHA256_BLOCK_SIZE; - memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len); + memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len); - ctx->len = rem_len; - ctx->tot_len += (block_nb + 1) << 6; + ctx->len = rem_len; + ctx->tot_len += (block_nb + 1) << 6; } void sha256_final(sha256_ctx* ctx, unsigned char* digest) { - unsigned int block_nb; - unsigned int pm_len; - size_t len_b; + unsigned int block_nb; + unsigned int pm_len; + size_t len_b; - int i; + int i; - block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); + block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); - len_b = (ctx->tot_len + ctx->len) << 3; - pm_len = block_nb << 6; + len_b = (ctx->tot_len + ctx->len) << 3; + pm_len = block_nb << 6; - memset(ctx->block + ctx->len, 0, pm_len - ctx->len); - ctx->block[ctx->len] = 0x80; - UNPACK32(len_b, ctx->block + pm_len - 4); + memset(ctx->block + ctx->len, 0, pm_len - ctx->len); + ctx->block[ctx->len] = 0x80; + UNPACK32(len_b, ctx->block + pm_len - 4); - sha256_transf(ctx, ctx->block, block_nb); + sha256_transf(ctx, ctx->block, block_nb); - for (i = 0; i < 8; i++) { - UNPACK32(ctx->h[i], &digest[i << 2]); - } + for (i = 0; i < 8; i++) { + UNPACK32(ctx->h[i], &digest[i << 2]); + } } diff --git a/src/SSLVerifyHost.cpp b/src/SSLVerifyHost.cpp index 5de1e309..1c09e360 100644 --- a/src/SSLVerifyHost.cpp +++ b/src/SSLVerifyHost.cpp @@ -52,61 +52,61 @@ namespace ZNC_Curl { /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because its behavior is altered by the current locale. */ inline char Curl_raw_toupper(char in) { - switch (in) { - case 'a': - return 'A'; - case 'b': - return 'B'; - case 'c': - return 'C'; - case 'd': - return 'D'; - case 'e': - return 'E'; - case 'f': - return 'F'; - case 'g': - return 'G'; - case 'h': - return 'H'; - case 'i': - return 'I'; - case 'j': - return 'J'; - case 'k': - return 'K'; - case 'l': - return 'L'; - case 'm': - return 'M'; - case 'n': - return 'N'; - case 'o': - return 'O'; - case 'p': - return 'P'; - case 'q': - return 'Q'; - case 'r': - return 'R'; - case 's': - return 'S'; - case 't': - return 'T'; - case 'u': - return 'U'; - case 'v': - return 'V'; - case 'w': - return 'W'; - case 'x': - return 'X'; - case 'y': - return 'Y'; - case 'z': - return 'Z'; - } - return in; + switch (in) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + } + return in; } /* @@ -119,30 +119,30 @@ inline char Curl_raw_toupper(char in) { * non-ascii. */ static int Curl_raw_equal(const char* first, const char* second) { - while (*first && *second) { - if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) - /* get out of the loop as soon as they don't match */ - break; - first++; - second++; - } - /* we do the comparison here (possibly again), just to make sure that if the - loop above is skipped because one of the strings reached zero, we must - not - return this as a successful match */ - return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second)); + while (*first && *second) { + if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) + /* get out of the loop as soon as they don't match */ + break; + first++; + second++; + } + /* we do the comparison here (possibly again), just to make sure that if the + loop above is skipped because one of the strings reached zero, we must + not + return this as a successful match */ + return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second)); } static int Curl_raw_nequal(const char* first, const char* second, size_t max) { - while (*first && *second && max) { - if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) { - break; - } - max--; - first++; - second++; - } - if (0 == max) return 1; /* they are equal this far */ - return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); + while (*first && *second && max) { + if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) { + break; + } + max--; + first++; + second++; + } + if (0 == max) return 1; /* they are equal this far */ + return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); } static const int CURL_HOST_NOMATCH = 0; @@ -169,87 +169,87 @@ static const int CURL_HOST_MATCH = 1; */ static int hostmatch(char* hostname, char* pattern) { - const char* pattern_label_end, *pattern_wildcard, *hostname_label_end; - int wildcard_enabled; - size_t prefixlen, suffixlen; - struct in_addr ignored; + const char* pattern_label_end, *pattern_wildcard, *hostname_label_end; + int wildcard_enabled; + size_t prefixlen, suffixlen; + struct in_addr ignored; #ifdef ENABLE_IPV6 - struct sockaddr_in6 si6; + struct sockaddr_in6 si6; #endif - /* normalize pattern and hostname by stripping off trailing dots */ - size_t len = strlen(hostname); - if (hostname[len - 1] == '.') hostname[len - 1] = 0; - len = strlen(pattern); - if (pattern[len - 1] == '.') pattern[len - 1] = 0; + /* normalize pattern and hostname by stripping off trailing dots */ + size_t len = strlen(hostname); + if (hostname[len - 1] == '.') hostname[len - 1] = 0; + len = strlen(pattern); + if (pattern[len - 1] == '.') pattern[len - 1] = 0; - pattern_wildcard = strchr(pattern, '*'); - if (pattern_wildcard == nullptr) - return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH - : CURL_HOST_NOMATCH; + pattern_wildcard = strchr(pattern, '*'); + if (pattern_wildcard == nullptr) + return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH + : CURL_HOST_NOMATCH; - /* detect IP address as hostname and fail the match if so */ - if (inet_pton(AF_INET, hostname, &ignored) > 0) return CURL_HOST_NOMATCH; + /* detect IP address as hostname and fail the match if so */ + if (inet_pton(AF_INET, hostname, &ignored) > 0) return CURL_HOST_NOMATCH; #ifdef ENABLE_IPV6 - else if (Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) - return CURL_HOST_NOMATCH; + else if (Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) + return CURL_HOST_NOMATCH; #endif - /* We require at least 2 dots in pattern to avoid too wide wildcard - match. */ - wildcard_enabled = 1; - pattern_label_end = strchr(pattern, '.'); - if (pattern_label_end == nullptr || - strchr(pattern_label_end + 1, '.') == nullptr || - pattern_wildcard > pattern_label_end || - Curl_raw_nequal(pattern, "xn--", 4)) { - wildcard_enabled = 0; - } - if (!wildcard_enabled) - return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH - : CURL_HOST_NOMATCH; + /* We require at least 2 dots in pattern to avoid too wide wildcard + match. */ + wildcard_enabled = 1; + pattern_label_end = strchr(pattern, '.'); + if (pattern_label_end == nullptr || + strchr(pattern_label_end + 1, '.') == nullptr || + pattern_wildcard > pattern_label_end || + Curl_raw_nequal(pattern, "xn--", 4)) { + wildcard_enabled = 0; + } + if (!wildcard_enabled) + return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH + : CURL_HOST_NOMATCH; - hostname_label_end = strchr(hostname, '.'); - if (hostname_label_end == nullptr || - !Curl_raw_equal(pattern_label_end, hostname_label_end)) - return CURL_HOST_NOMATCH; + hostname_label_end = strchr(hostname, '.'); + if (hostname_label_end == nullptr || + !Curl_raw_equal(pattern_label_end, hostname_label_end)) + return CURL_HOST_NOMATCH; - /* The wildcard must match at least one character, so the left-most - label of the hostname is at least as large as the left-most label - of the pattern. */ - if (hostname_label_end - hostname < pattern_label_end - pattern) - return CURL_HOST_NOMATCH; + /* The wildcard must match at least one character, so the left-most + label of the hostname is at least as large as the left-most label + of the pattern. */ + if (hostname_label_end - hostname < pattern_label_end - pattern) + return CURL_HOST_NOMATCH; - prefixlen = pattern_wildcard - pattern; - suffixlen = pattern_label_end - (pattern_wildcard + 1); - return Curl_raw_nequal(pattern, hostname, prefixlen) && - Curl_raw_nequal(pattern_wildcard + 1, - hostname_label_end - suffixlen, suffixlen) - ? CURL_HOST_MATCH - : CURL_HOST_NOMATCH; + prefixlen = pattern_wildcard - pattern; + suffixlen = pattern_label_end - (pattern_wildcard + 1); + return Curl_raw_nequal(pattern, hostname, prefixlen) && + Curl_raw_nequal(pattern_wildcard + 1, + hostname_label_end - suffixlen, suffixlen) + ? CURL_HOST_MATCH + : CURL_HOST_NOMATCH; } static int Curl_cert_hostcheck(const char* match_pattern, const char* hostname) { - char* matchp; - char* hostp; - int res = 0; - if (!match_pattern || !*match_pattern || !hostname || - !*hostname) /* sanity check */ - ; - else { - matchp = strdup(match_pattern); - if (matchp) { - hostp = strdup(hostname); - if (hostp) { - if (hostmatch(hostp, matchp) == CURL_HOST_MATCH) res = 1; - free(hostp); - } - free(matchp); - } - } + char* matchp; + char* hostp; + int res = 0; + if (!match_pattern || !*match_pattern || !hostname || + !*hostname) /* sanity check */ + ; + else { + matchp = strdup(match_pattern); + if (matchp) { + hostp = strdup(hostname); + if (hostp) { + if (hostmatch(hostp, matchp) == CURL_HOST_MATCH) res = 1; + free(hostp); + } + free(matchp); + } + } - return res; + return res; } // @@ -278,11 +278,11 @@ namespace ZNC_iSECPartners { */ typedef enum { - MatchFound, - MatchNotFound, - NoSANPresent, - MalformedCertificate, - Error + MatchFound, + MatchNotFound, + NoSANPresent, + MalformedCertificate, + Error } HostnameValidationResult; #define HOSTNAME_MAX_SIZE 255 @@ -297,45 +297,45 @@ typedef enum { */ static HostnameValidationResult matches_common_name(const char* hostname, const X509* server_cert) { - int common_name_loc = -1; - X509_NAME_ENTRY* common_name_entry = nullptr; - ASN1_STRING* common_name_asn1 = nullptr; - char* common_name_str = nullptr; + int common_name_loc = -1; + X509_NAME_ENTRY* common_name_entry = nullptr; + ASN1_STRING* common_name_asn1 = nullptr; + char* common_name_str = nullptr; - // Find the position of the CN field in the Subject field of the certificate - common_name_loc = X509_NAME_get_index_by_NID( - X509_get_subject_name((X509*)server_cert), NID_commonName, -1); - if (common_name_loc < 0) { - return Error; - } + // Find the position of the CN field in the Subject field of the certificate + common_name_loc = X509_NAME_get_index_by_NID( + X509_get_subject_name((X509*)server_cert), NID_commonName, -1); + if (common_name_loc < 0) { + return Error; + } - // Extract the CN field - common_name_entry = X509_NAME_get_entry( - X509_get_subject_name((X509*)server_cert), common_name_loc); - if (common_name_entry == nullptr) { - return Error; - } + // Extract the CN field + common_name_entry = X509_NAME_get_entry( + X509_get_subject_name((X509*)server_cert), common_name_loc); + if (common_name_entry == nullptr) { + return Error; + } - // Convert the CN field to a C string - common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); - if (common_name_asn1 == nullptr) { - return Error; - } - common_name_str = (char*)ASN1_STRING_data(common_name_asn1); + // Convert the CN field to a C string + common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == nullptr) { + return Error; + } + common_name_str = (char*)ASN1_STRING_data(common_name_asn1); - // Make sure there isn't an embedded NUL character in the CN - if (ASN1_STRING_length(common_name_asn1) != - static_cast(strlen(common_name_str))) { - return MalformedCertificate; - } + // Make sure there isn't an embedded NUL character in the CN + if (ASN1_STRING_length(common_name_asn1) != + static_cast(strlen(common_name_str))) { + return MalformedCertificate; + } - DEBUG("SSLVerifyHost: Found CN " << common_name_str); - // Compare expected hostname with the CN - if (ZNC_Curl::Curl_cert_hostcheck(common_name_str, hostname)) { - return MatchFound; - } else { - return MatchNotFound; - } + DEBUG("SSLVerifyHost: Found CN " << common_name_str); + // Compare expected hostname with the CN + if (ZNC_Curl::Curl_cert_hostcheck(common_name_str, hostname)) { + return MatchFound; + } else { + return MatchNotFound; + } } /** @@ -348,44 +348,44 @@ static HostnameValidationResult matches_common_name(const char* hostname, */ static HostnameValidationResult matches_subject_alternative_name( const char* hostname, const X509* server_cert) { - HostnameValidationResult result = MatchNotFound; - int i; - int san_names_nb = -1; - STACK_OF(GENERAL_NAME)* san_names = nullptr; + HostnameValidationResult result = MatchNotFound; + int i; + int san_names_nb = -1; + STACK_OF(GENERAL_NAME)* san_names = nullptr; - // Try to extract the names within the SAN extension from the certificate - san_names = reinterpret_cast(X509_get_ext_d2i( - (X509*)server_cert, NID_subject_alt_name, nullptr, nullptr)); - if (san_names == nullptr) { - return NoSANPresent; - } - san_names_nb = sk_GENERAL_NAME_num(san_names); + // Try to extract the names within the SAN extension from the certificate + san_names = reinterpret_cast(X509_get_ext_d2i( + (X509*)server_cert, NID_subject_alt_name, nullptr, nullptr)); + if (san_names == nullptr) { + return NoSANPresent; + } + san_names_nb = sk_GENERAL_NAME_num(san_names); - // Check each name within the extension - for (i = 0; i < san_names_nb; i++) { - const GENERAL_NAME* current_name = sk_GENERAL_NAME_value(san_names, i); + // Check each name within the extension + for (i = 0; i < san_names_nb; i++) { + const GENERAL_NAME* current_name = sk_GENERAL_NAME_value(san_names, i); - if (current_name->type == GEN_DNS) { - // Current name is a DNS name, let's check it - char* dns_name = (char*)ASN1_STRING_data(current_name->d.dNSName); + if (current_name->type == GEN_DNS) { + // Current name is a DNS name, let's check it + char* dns_name = (char*)ASN1_STRING_data(current_name->d.dNSName); - // Make sure there isn't an embedded NUL character in the DNS name - if (ASN1_STRING_length(current_name->d.dNSName) != - static_cast(strlen(dns_name))) { - result = MalformedCertificate; - break; - } else { // Compare expected hostname with the DNS name - DEBUG("SSLVerifyHost: Found SAN " << dns_name); - if (ZNC_Curl::Curl_cert_hostcheck(dns_name, hostname)) { - result = MatchFound; - break; - } - } - } - } - sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free); + // Make sure there isn't an embedded NUL character in the DNS name + if (ASN1_STRING_length(current_name->d.dNSName) != + static_cast(strlen(dns_name))) { + result = MalformedCertificate; + break; + } else { // Compare expected hostname with the DNS name + DEBUG("SSLVerifyHost: Found SAN " << dns_name); + if (ZNC_Curl::Curl_cert_hostcheck(dns_name, hostname)) { + result = MatchFound; + break; + } + } + } + } + sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free); - return result; + return result; } /** @@ -401,18 +401,18 @@ static HostnameValidationResult matches_subject_alternative_name( */ static HostnameValidationResult validate_hostname(const char* hostname, const X509* server_cert) { - HostnameValidationResult result; + HostnameValidationResult result; - if ((hostname == nullptr) || (server_cert == nullptr)) return Error; + if ((hostname == nullptr) || (server_cert == nullptr)) return Error; - // First try the Subject Alternative Names extension - result = matches_subject_alternative_name(hostname, server_cert); - if (result == NoSANPresent) { - // Extension was not found: try the Common Name - result = matches_common_name(hostname, server_cert); - } + // First try the Subject Alternative Names extension + result = matches_subject_alternative_name(hostname, server_cert); + if (result == NoSANPresent) { + // Extension was not found: try the Common Name + result = matches_common_name(hostname, server_cert); + } - return result; + return result; } // @@ -423,26 +423,26 @@ static HostnameValidationResult validate_hostname(const char* hostname, bool ZNC_SSLVerifyHost(const CString& sHost, const X509* pCert, CString& sError) { - DEBUG("SSLVerifyHost: checking " << sHost); - ZNC_iSECPartners::HostnameValidationResult eResult = - ZNC_iSECPartners::validate_hostname(sHost.c_str(), pCert); - switch (eResult) { - case ZNC_iSECPartners::MatchFound: - DEBUG("SSLVerifyHost: verified"); - return true; - case ZNC_iSECPartners::MatchNotFound: - DEBUG("SSLVerifyHost: host doesn't match"); - sError = "hostname doesn't match"; - return false; - case ZNC_iSECPartners::MalformedCertificate: - DEBUG("SSLVerifyHost: malformed cert"); - sError = "malformed hostname in certificate"; - return false; - default: - DEBUG("SSLVerifyHost: error"); - sError = "hostname verification error"; - return false; - } + DEBUG("SSLVerifyHost: checking " << sHost); + ZNC_iSECPartners::HostnameValidationResult eResult = + ZNC_iSECPartners::validate_hostname(sHost.c_str(), pCert); + switch (eResult) { + case ZNC_iSECPartners::MatchFound: + DEBUG("SSLVerifyHost: verified"); + return true; + case ZNC_iSECPartners::MatchNotFound: + DEBUG("SSLVerifyHost: host doesn't match"); + sError = "hostname doesn't match"; + return false; + case ZNC_iSECPartners::MalformedCertificate: + DEBUG("SSLVerifyHost: malformed cert"); + sError = "malformed hostname in certificate"; + return false; + default: + DEBUG("SSLVerifyHost: error"); + sError = "hostname verification error"; + return false; + } } #endif /* HAVE_LIBSSL */ diff --git a/src/Server.cpp b/src/Server.cpp index 93c0c09c..24a8ca84 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -26,7 +26,7 @@ CServer::CServer(const CString& sName, unsigned short uPort, CServer::~CServer() {} bool CServer::IsValidHostName(const CString& sHostName) { - return (!sHostName.empty() && !sHostName.Contains(" ")); + return (!sHostName.empty() && !sHostName.Contains(" ")); } const CString& CServer::GetName() const { return m_sName; } @@ -35,7 +35,7 @@ const CString& CServer::GetPass() const { return m_sPass; } bool CServer::IsSSL() const { return m_bSSL; } CString CServer::GetString(bool bIncludePassword) const { - return m_sName + " " + CString(m_bSSL ? "+" : "") + CString(m_uPort) + - CString(bIncludePassword ? (m_sPass.empty() ? "" : " " + m_sPass) - : ""); + return m_sName + " " + CString(m_bSSL ? "+" : "") + CString(m_uPort) + + CString(bIncludePassword ? (m_sPass.empty() ? "" : " " + m_sPass) + : ""); } diff --git a/src/Socket.cpp b/src/Socket.cpp index 83d2ea04..5f063fe9 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -32,17 +32,17 @@ // https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 // at 22 Dec 2014 static CString ZNC_DefaultCipher() { - return "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-" - "RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-" - "GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-" - "SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-" - "AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-" - "RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-" - "RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-" - "AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:" - "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-" - "CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-" - "DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; + return "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-" + "RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-" + "GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-" + "SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-" + "AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-" + "RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-" + "RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-" + "AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:" + "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-" + "CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-" + "DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; } #endif @@ -52,14 +52,14 @@ CZNCSock::CZNCSock(int timeout) m_ssTrustedFingerprints(), m_ssCertVerificationErrors() { #ifdef HAVE_LIBSSL - DisableSSLCompression(); - FollowSSLCipherServerPreference(); - DisableSSLProtocols(CZNC::Get().GetDisabledSSLProtocols()); - CString sCipher = CZNC::Get().GetSSLCiphers(); - if (sCipher.empty()) { - sCipher = ZNC_DefaultCipher(); - } - SetCipher(sCipher); + DisableSSLCompression(); + FollowSSLCipherServerPreference(); + DisableSSLProtocols(CZNC::Get().GetDisabledSSLProtocols()); + CString sCipher = CZNC::Get().GetSSLCiphers(); + if (sCipher.empty()) { + sCipher = ZNC_DefaultCipher(); + } + SetCipher(sCipher); #endif } @@ -69,311 +69,311 @@ CZNCSock::CZNCSock(const CString& sHost, u_short port, int timeout) m_ssTrustedFingerprints(), m_ssCertVerificationErrors() { #ifdef HAVE_LIBSSL - DisableSSLCompression(); - FollowSSLCipherServerPreference(); - DisableSSLProtocols(CZNC::Get().GetDisabledSSLProtocols()); + DisableSSLCompression(); + FollowSSLCipherServerPreference(); + DisableSSLProtocols(CZNC::Get().GetDisabledSSLProtocols()); #endif } unsigned int CSockManager::GetAnonConnectionCount(const CString& sIP) const { - const_iterator it; - unsigned int ret = 0; + const_iterator it; + unsigned int ret = 0; - for (it = begin(); it != end(); ++it) { - Csock* pSock = *it; - // Logged in CClients have "USR::" as their sockname - if (pSock->GetType() == Csock::INBOUND && pSock->GetRemoteIP() == sIP && - !pSock->GetSockName().StartsWith("USR::")) { - ret++; - } - } + for (it = begin(); it != end(); ++it) { + Csock* pSock = *it; + // Logged in CClients have "USR::" as their sockname + if (pSock->GetType() == Csock::INBOUND && pSock->GetRemoteIP() == sIP && + !pSock->GetSockName().StartsWith("USR::")) { + ret++; + } + } - DEBUG("There are [" << ret << "] clients from [" << sIP << "]"); + DEBUG("There are [" << ret << "] clients from [" << sIP << "]"); - return ret; + return ret; } int CZNCSock::ConvertAddress(const struct sockaddr_storage* pAddr, socklen_t iAddrLen, CString& sIP, u_short* piPort) const { - int ret = Csock::ConvertAddress(pAddr, iAddrLen, sIP, piPort); - if (ret == 0) sIP.TrimPrefix("::ffff:"); - return ret; + int ret = Csock::ConvertAddress(pAddr, iAddrLen, sIP, piPort); + if (ret == 0) sIP.TrimPrefix("::ffff:"); + return ret; } #ifdef HAVE_LIBSSL int CZNCSock::VerifyPeerCertificate(int iPreVerify, X509_STORE_CTX* pStoreCTX) { - if (iPreVerify == 0) { - m_ssCertVerificationErrors.insert( - X509_verify_cert_error_string(X509_STORE_CTX_get_error(pStoreCTX))); - } - return 1; + if (iPreVerify == 0) { + m_ssCertVerificationErrors.insert( + X509_verify_cert_error_string(X509_STORE_CTX_get_error(pStoreCTX))); + } + return 1; } void CZNCSock::SSLHandShakeFinished() { - if (GetType() != ETConn::OUTBOUND) { - return; - } + if (GetType() != ETConn::OUTBOUND) { + return; + } - X509* pCert = GetX509(); - if (!pCert) { - DEBUG(GetSockName() + ": No cert"); - CallSockError(errnoBadSSLCert, "Anonymous SSL cert is not allowed"); - Close(); - return; - } - CString sHostVerifyError; - if (!ZNC_SSLVerifyHost(m_sHostToVerifySSL, pCert, sHostVerifyError)) { - m_ssCertVerificationErrors.insert(sHostVerifyError); - } - X509_free(pCert); - if (m_ssCertVerificationErrors.empty()) { - DEBUG(GetSockName() + ": Good cert"); - return; - } - CString sFP = GetSSLPeerFingerprint(); - if (m_ssTrustedFingerprints.count(sFP) != 0) { - DEBUG(GetSockName() + ": Cert explicitly trusted by user: " << sFP); - return; - } - DEBUG(GetSockName() + ": Bad cert"); - CString sErrorMsg = "Invalid SSL certificate: "; - sErrorMsg += CString(", ").Join(begin(m_ssCertVerificationErrors), - end(m_ssCertVerificationErrors)); - CallSockError(errnoBadSSLCert, sErrorMsg); - Close(); + X509* pCert = GetX509(); + if (!pCert) { + DEBUG(GetSockName() + ": No cert"); + CallSockError(errnoBadSSLCert, "Anonymous SSL cert is not allowed"); + Close(); + return; + } + CString sHostVerifyError; + if (!ZNC_SSLVerifyHost(m_sHostToVerifySSL, pCert, sHostVerifyError)) { + m_ssCertVerificationErrors.insert(sHostVerifyError); + } + X509_free(pCert); + if (m_ssCertVerificationErrors.empty()) { + DEBUG(GetSockName() + ": Good cert"); + return; + } + CString sFP = GetSSLPeerFingerprint(); + if (m_ssTrustedFingerprints.count(sFP) != 0) { + DEBUG(GetSockName() + ": Cert explicitly trusted by user: " << sFP); + return; + } + DEBUG(GetSockName() + ": Bad cert"); + CString sErrorMsg = "Invalid SSL certificate: "; + sErrorMsg += CString(", ").Join(begin(m_ssCertVerificationErrors), + end(m_ssCertVerificationErrors)); + CallSockError(errnoBadSSLCert, sErrorMsg); + Close(); } bool CZNCSock::SNIConfigureClient(CString& sHostname) { - sHostname = m_sHostToVerifySSL; - return true; + sHostname = m_sHostToVerifySSL; + return true; } #endif CString CZNCSock::GetSSLPeerFingerprint() const { #ifdef HAVE_LIBSSL - // Csocket's version returns insecure SHA-1 - // This one is SHA-256 - const EVP_MD* evp = EVP_sha256(); - X509* pCert = GetX509(); - if (!pCert) { - DEBUG(GetSockName() + ": GetSSLPeerFingerprint: Anonymous cert"); - return ""; - } - unsigned char buf[256 / 8]; - unsigned int _32 = 256 / 8; - int iSuccess = X509_digest(pCert, evp, buf, &_32); - X509_free(pCert); - if (!iSuccess) { - DEBUG(GetSockName() + ": GetSSLPeerFingerprint: Couldn't find digest"); - return ""; - } - return CString(reinterpret_cast(buf), sizeof buf) - .Escape_n(CString::EASCII, CString::EHEXCOLON); + // Csocket's version returns insecure SHA-1 + // This one is SHA-256 + const EVP_MD* evp = EVP_sha256(); + X509* pCert = GetX509(); + if (!pCert) { + DEBUG(GetSockName() + ": GetSSLPeerFingerprint: Anonymous cert"); + return ""; + } + unsigned char buf[256 / 8]; + unsigned int _32 = 256 / 8; + int iSuccess = X509_digest(pCert, evp, buf, &_32); + X509_free(pCert); + if (!iSuccess) { + DEBUG(GetSockName() + ": GetSSLPeerFingerprint: Couldn't find digest"); + return ""; + } + return CString(reinterpret_cast(buf), sizeof buf) + .Escape_n(CString::EASCII, CString::EHEXCOLON); #else - return ""; + return ""; #endif } #ifdef HAVE_PTHREAD class CSockManager::CThreadMonitorFD : public CSMonitorFD { public: - CThreadMonitorFD() { Add(CThreadPool::Get().getReadFD(), ECT_Read); } + CThreadMonitorFD() { Add(CThreadPool::Get().getReadFD(), ECT_Read); } - bool FDsThatTriggered(const std::map& miiReadyFds) override { - if (miiReadyFds.find(CThreadPool::Get().getReadFD())->second) { - CThreadPool::Get().handlePipeReadable(); - } - return true; - } + bool FDsThatTriggered(const std::map& miiReadyFds) override { + if (miiReadyFds.find(CThreadPool::Get().getReadFD())->second) { + CThreadPool::Get().handlePipeReadable(); + } + return true; + } }; #endif #ifdef HAVE_THREADED_DNS void CSockManager::CDNSJob::runThread() { - int iCount = 0; - while (true) { - addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_ADDRCONFIG; - iRes = getaddrinfo(sHostname.c_str(), nullptr, &hints, &aiResult); - if (EAGAIN != iRes) { - break; - } + int iCount = 0; + while (true) { + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_ADDRCONFIG; + iRes = getaddrinfo(sHostname.c_str(), nullptr, &hints, &aiResult); + if (EAGAIN != iRes) { + break; + } - iCount++; - if (iCount > 5) { - iRes = ETIMEDOUT; - break; - } - sleep(5); // wait 5 seconds before next try - } + iCount++; + if (iCount > 5) { + iRes = ETIMEDOUT; + break; + } + sleep(5); // wait 5 seconds before next try + } } void CSockManager::CDNSJob::runMain() { - if (0 != this->iRes) { - DEBUG("Error in threaded DNS: " << gai_strerror(this->iRes)); - if (this->aiResult) { - DEBUG("And aiResult is not nullptr..."); - } - // just for case. Maybe to call freeaddrinfo()? - this->aiResult = nullptr; - } - pManager->SetTDNSThreadFinished(this->task, this->bBind, this->aiResult); + if (0 != this->iRes) { + DEBUG("Error in threaded DNS: " << gai_strerror(this->iRes)); + if (this->aiResult) { + DEBUG("And aiResult is not nullptr..."); + } + // just for case. Maybe to call freeaddrinfo()? + this->aiResult = nullptr; + } + pManager->SetTDNSThreadFinished(this->task, this->bBind, this->aiResult); } void CSockManager::StartTDNSThread(TDNSTask* task, bool bBind) { - CString sHostname = bBind ? task->sBindhost : task->sHostname; - CDNSJob* arg = new CDNSJob; - arg->sHostname = sHostname; - arg->task = task; - arg->bBind = bBind; - arg->pManager = this; + CString sHostname = bBind ? task->sBindhost : task->sHostname; + CDNSJob* arg = new CDNSJob; + arg->sHostname = sHostname; + arg->task = task; + arg->bBind = bBind; + arg->pManager = this; - CThreadPool::Get().addJob(arg); + CThreadPool::Get().addJob(arg); } static CString RandomFromSet(const SCString& sSet, std::default_random_engine& gen) { - std::uniform_int_distribution<> distr(0, sSet.size() - 1); - auto it = sSet.cbegin(); - std::advance(it, distr(gen)); - return *it; + std::uniform_int_distribution<> distr(0, sSet.size() - 1); + auto it = sSet.cbegin(); + std::advance(it, distr(gen)); + return *it; } static std::tuple RandomFrom2SetsWithBias( const SCString& ss4, const SCString& ss6, std::default_random_engine& gen) { - // It's not quite what RFC says how to choose between IPv4 and IPv6, but - // proper way is harder to implement. - // It would require to maintain some state between Csock objects. - bool bUseIPv6; - if (ss4.empty()) { - bUseIPv6 = true; - } else if (ss6.empty()) { - bUseIPv6 = false; - } else { - // Let's prefer IPv6 :) - std::discrete_distribution<> d({2, 3}); - bUseIPv6 = d(gen); - } - const SCString& sSet = bUseIPv6 ? ss6 : ss4; - return std::make_tuple(RandomFromSet(sSet, gen), bUseIPv6); + // It's not quite what RFC says how to choose between IPv4 and IPv6, but + // proper way is harder to implement. + // It would require to maintain some state between Csock objects. + bool bUseIPv6; + if (ss4.empty()) { + bUseIPv6 = true; + } else if (ss6.empty()) { + bUseIPv6 = false; + } else { + // Let's prefer IPv6 :) + std::discrete_distribution<> d({2, 3}); + bUseIPv6 = d(gen); + } + const SCString& sSet = bUseIPv6 ? ss6 : ss4; + return std::make_tuple(RandomFromSet(sSet, gen), bUseIPv6); } void CSockManager::SetTDNSThreadFinished(TDNSTask* task, bool bBind, addrinfo* aiResult) { - if (bBind) { - task->aiBind = aiResult; - task->bDoneBind = true; - } else { - task->aiTarget = aiResult; - task->bDoneTarget = true; - } + if (bBind) { + task->aiBind = aiResult; + task->bDoneBind = true; + } else { + task->aiTarget = aiResult; + task->bDoneTarget = true; + } - // Now that something is done, check if everything we needed is done - if (!task->bDoneBind || !task->bDoneTarget) { - return; - } + // Now that something is done, check if everything we needed is done + if (!task->bDoneBind || !task->bDoneTarget) { + return; + } - // All needed DNS is done, now collect the results - SCString ssTargets4; - SCString ssTargets6; - for (addrinfo* ai = task->aiTarget; ai; ai = ai->ai_next) { - char s[INET6_ADDRSTRLEN] = {}; - getnameinfo(ai->ai_addr, ai->ai_addrlen, s, sizeof(s), nullptr, 0, - NI_NUMERICHOST); - switch (ai->ai_family) { - case AF_INET: - ssTargets4.insert(s); - break; + // All needed DNS is done, now collect the results + SCString ssTargets4; + SCString ssTargets6; + for (addrinfo* ai = task->aiTarget; ai; ai = ai->ai_next) { + char s[INET6_ADDRSTRLEN] = {}; + getnameinfo(ai->ai_addr, ai->ai_addrlen, s, sizeof(s), nullptr, 0, + NI_NUMERICHOST); + switch (ai->ai_family) { + case AF_INET: + ssTargets4.insert(s); + break; #ifdef HAVE_IPV6 - case AF_INET6: - ssTargets6.insert(s); - break; + case AF_INET6: + ssTargets6.insert(s); + break; #endif - } - } - SCString ssBinds4; - SCString ssBinds6; - for (addrinfo* ai = task->aiBind; ai; ai = ai->ai_next) { - char s[INET6_ADDRSTRLEN] = {}; - getnameinfo(ai->ai_addr, ai->ai_addrlen, s, sizeof(s), nullptr, 0, - NI_NUMERICHOST); - switch (ai->ai_family) { - case AF_INET: - ssBinds4.insert(s); - break; + } + } + SCString ssBinds4; + SCString ssBinds6; + for (addrinfo* ai = task->aiBind; ai; ai = ai->ai_next) { + char s[INET6_ADDRSTRLEN] = {}; + getnameinfo(ai->ai_addr, ai->ai_addrlen, s, sizeof(s), nullptr, 0, + NI_NUMERICHOST); + switch (ai->ai_family) { + case AF_INET: + ssBinds4.insert(s); + break; #ifdef HAVE_IPV6 - case AF_INET6: - ssBinds6.insert(s); - break; + case AF_INET6: + ssBinds6.insert(s); + break; #endif - } - } - if (task->aiTarget) freeaddrinfo(task->aiTarget); - if (task->aiBind) freeaddrinfo(task->aiBind); + } + } + if (task->aiTarget) freeaddrinfo(task->aiTarget); + if (task->aiBind) freeaddrinfo(task->aiBind); - CString sBindhost; - CString sTargetHost; - std::random_device rd; - std::default_random_engine gen(rd()); + CString sBindhost; + CString sTargetHost; + std::random_device rd; + std::default_random_engine gen(rd()); - try { - if (ssTargets4.empty() && ssTargets6.empty()) { - throw "Can't resolve server hostname"; - } else if (task->sBindhost.empty()) { - // Choose random target - std::tie(sTargetHost, std::ignore) = - RandomFrom2SetsWithBias(ssTargets4, ssTargets6, gen); - } else if (ssBinds4.empty() && ssBinds6.empty()) { - throw "Can't resolve bind hostname. Try /znc ClearBindHost and /znc ClearUserBindHost"; - } else if (ssBinds4.empty()) { - if (ssTargets6.empty()) { - throw "Server address is IPv4-only, but bindhost is IPv6-only"; - } else { - // Choose random target and bindhost from IPv6-only sets - sTargetHost = RandomFromSet(ssTargets6, gen); - sBindhost = RandomFromSet(ssBinds6, gen); - } - } else if (ssBinds6.empty()) { - if (ssTargets4.empty()) { - throw "Server address is IPv6-only, but bindhost is IPv4-only"; - } else { - // Choose random target and bindhost from IPv4-only sets - sTargetHost = RandomFromSet(ssTargets4, gen); - sBindhost = RandomFromSet(ssBinds4, gen); - } - } else { - // Choose random target - bool bUseIPv6; - std::tie(sTargetHost, bUseIPv6) = - RandomFrom2SetsWithBias(ssTargets4, ssTargets6, gen); - // Choose random bindhost matching chosen target - const SCString& ssBinds = bUseIPv6 ? ssBinds6 : ssBinds4; - sBindhost = RandomFromSet(ssBinds, gen); - } + try { + if (ssTargets4.empty() && ssTargets6.empty()) { + throw "Can't resolve server hostname"; + } else if (task->sBindhost.empty()) { + // Choose random target + std::tie(sTargetHost, std::ignore) = + RandomFrom2SetsWithBias(ssTargets4, ssTargets6, gen); + } else if (ssBinds4.empty() && ssBinds6.empty()) { + throw "Can't resolve bind hostname. Try /znc ClearBindHost and /znc ClearUserBindHost"; + } else if (ssBinds4.empty()) { + if (ssTargets6.empty()) { + throw "Server address is IPv4-only, but bindhost is IPv6-only"; + } else { + // Choose random target and bindhost from IPv6-only sets + sTargetHost = RandomFromSet(ssTargets6, gen); + sBindhost = RandomFromSet(ssBinds6, gen); + } + } else if (ssBinds6.empty()) { + if (ssTargets4.empty()) { + throw "Server address is IPv6-only, but bindhost is IPv4-only"; + } else { + // Choose random target and bindhost from IPv4-only sets + sTargetHost = RandomFromSet(ssTargets4, gen); + sBindhost = RandomFromSet(ssBinds4, gen); + } + } else { + // Choose random target + bool bUseIPv6; + std::tie(sTargetHost, bUseIPv6) = + RandomFrom2SetsWithBias(ssTargets4, ssTargets6, gen); + // Choose random bindhost matching chosen target + const SCString& ssBinds = bUseIPv6 ? ssBinds6 : ssBinds4; + sBindhost = RandomFromSet(ssBinds, gen); + } - DEBUG("TDNS: " << task->sSockName << ", connecting to [" << sTargetHost - << "] using bindhost [" << sBindhost << "]"); - FinishConnect(sTargetHost, task->iPort, task->sSockName, task->iTimeout, - task->bSSL, sBindhost, task->pcSock); - } catch (const char* s) { - DEBUG(task->sSockName << ", dns resolving error: " << s); - task->pcSock->SetSockName(task->sSockName); - task->pcSock->SockError(-1, s); - delete task->pcSock; - } + DEBUG("TDNS: " << task->sSockName << ", connecting to [" << sTargetHost + << "] using bindhost [" << sBindhost << "]"); + FinishConnect(sTargetHost, task->iPort, task->sSockName, task->iTimeout, + task->bSSL, sBindhost, task->pcSock); + } catch (const char* s) { + DEBUG(task->sSockName << ", dns resolving error: " << s); + task->pcSock->SetSockName(task->sSockName); + task->pcSock->SockError(-1, s); + delete task->pcSock; + } - delete task; + delete task; } #endif /* HAVE_THREADED_DNS */ CSockManager::CSockManager() { #ifdef HAVE_PTHREAD - MonitorFD(new CThreadMonitorFD()); + MonitorFD(new CThreadMonitorFD()); #endif } @@ -382,30 +382,30 @@ CSockManager::~CSockManager() {} void CSockManager::Connect(const CString& sHostname, u_short iPort, const CString& sSockName, int iTimeout, bool bSSL, const CString& sBindHost, CZNCSock* pcSock) { - if (pcSock) { - pcSock->SetHostToVerifySSL(sHostname); - } + if (pcSock) { + pcSock->SetHostToVerifySSL(sHostname); + } #ifdef HAVE_THREADED_DNS - DEBUG("TDNS: initiating resolving of [" << sHostname << "] and bindhost [" - << sBindHost << "]"); - TDNSTask* task = new TDNSTask; - task->sHostname = sHostname; - task->iPort = iPort; - task->sSockName = sSockName; - task->iTimeout = iTimeout; - task->bSSL = bSSL; - task->sBindhost = sBindHost; - task->pcSock = pcSock; - if (sBindHost.empty()) { - task->bDoneBind = true; - } else { - StartTDNSThread(task, true); - } - StartTDNSThread(task, false); + DEBUG("TDNS: initiating resolving of [" << sHostname << "] and bindhost [" + << sBindHost << "]"); + TDNSTask* task = new TDNSTask; + task->sHostname = sHostname; + task->iPort = iPort; + task->sSockName = sSockName; + task->iTimeout = iTimeout; + task->bSSL = bSSL; + task->sBindhost = sBindHost; + task->pcSock = pcSock; + if (sBindHost.empty()) { + task->bDoneBind = true; + } else { + StartTDNSThread(task, true); + } + StartTDNSThread(task, false); #else /* HAVE_THREADED_DNS */ - // Just let Csocket handle DNS itself - FinishConnect(sHostname, iPort, sSockName, iTimeout, bSSL, sBindHost, - pcSock); + // Just let Csocket handle DNS itself + FinishConnect(sHostname, iPort, sSockName, iTimeout, bSSL, sBindHost, + pcSock); #endif } @@ -413,137 +413,137 @@ void CSockManager::FinishConnect(const CString& sHostname, u_short iPort, const CString& sSockName, int iTimeout, bool bSSL, const CString& sBindHost, CZNCSock* pcSock) { - CSConnection C(sHostname, iPort, iTimeout); + CSConnection C(sHostname, iPort, iTimeout); - C.SetSockName(sSockName); - C.SetIsSSL(bSSL); - C.SetBindHost(sBindHost); + C.SetSockName(sSockName); + C.SetIsSSL(bSSL); + C.SetBindHost(sBindHost); #ifdef HAVE_LIBSSL - CString sCipher = CZNC::Get().GetSSLCiphers(); - if (sCipher.empty()) { - sCipher = ZNC_DefaultCipher(); - } - C.SetCipher(sCipher); + CString sCipher = CZNC::Get().GetSSLCiphers(); + if (sCipher.empty()) { + sCipher = ZNC_DefaultCipher(); + } + C.SetCipher(sCipher); #endif - TSocketManager::Connect(C, pcSock); + TSocketManager::Connect(C, pcSock); } /////////////////// CSocket /////////////////// CSocket::CSocket(CModule* pModule) : CZNCSock(), m_pModule(pModule) { - if (m_pModule) m_pModule->AddSocket(this); - EnableReadLine(); - SetMaxBufferThreshold(10240); + if (m_pModule) m_pModule->AddSocket(this); + EnableReadLine(); + SetMaxBufferThreshold(10240); } CSocket::CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout) : CZNCSock(sHostname, uPort, iTimeout), m_pModule(pModule) { - if (m_pModule) m_pModule->AddSocket(this); - EnableReadLine(); - SetMaxBufferThreshold(10240); + if (m_pModule) m_pModule->AddSocket(this); + EnableReadLine(); + SetMaxBufferThreshold(10240); } CSocket::~CSocket() { - CUser* pUser = nullptr; - CIRCNetwork* pNetwork = nullptr; + CUser* pUser = nullptr; + CIRCNetwork* pNetwork = nullptr; - // CWebSock could cause us to have a nullptr pointer here - if (m_pModule) { - pUser = m_pModule->GetUser(); - pNetwork = m_pModule->GetNetwork(); - m_pModule->UnlinkSocket(this); - } + // CWebSock could cause us to have a nullptr pointer here + if (m_pModule) { + pUser = m_pModule->GetUser(); + pNetwork = m_pModule->GetNetwork(); + m_pModule->UnlinkSocket(this); + } - if (pNetwork && m_pModule && - (m_pModule->GetType() == CModInfo::NetworkModule)) { - pNetwork->AddBytesWritten(GetBytesWritten()); - pNetwork->AddBytesRead(GetBytesRead()); - } else if (pUser && m_pModule && - (m_pModule->GetType() == CModInfo::UserModule)) { - pUser->AddBytesWritten(GetBytesWritten()); - pUser->AddBytesRead(GetBytesRead()); - } else { - CZNC::Get().AddBytesWritten(GetBytesWritten()); - CZNC::Get().AddBytesRead(GetBytesRead()); - } + if (pNetwork && m_pModule && + (m_pModule->GetType() == CModInfo::NetworkModule)) { + pNetwork->AddBytesWritten(GetBytesWritten()); + pNetwork->AddBytesRead(GetBytesRead()); + } else if (pUser && m_pModule && + (m_pModule->GetType() == CModInfo::UserModule)) { + pUser->AddBytesWritten(GetBytesWritten()); + pUser->AddBytesRead(GetBytesRead()); + } else { + CZNC::Get().AddBytesWritten(GetBytesWritten()); + CZNC::Get().AddBytesRead(GetBytesRead()); + } } void CSocket::ReachedMaxBuffer() { - DEBUG(GetSockName() << " == ReachedMaxBuffer()"); - if (m_pModule) - m_pModule->PutModule( - "Some socket reached its max buffer limit and was closed!"); - Close(); + DEBUG(GetSockName() << " == ReachedMaxBuffer()"); + if (m_pModule) + m_pModule->PutModule( + "Some socket reached its max buffer limit and was closed!"); + Close(); } void CSocket::SockError(int iErrno, const CString& sDescription) { - DEBUG(GetSockName() << " == SockError(" << sDescription << ", " - << strerror(iErrno) << ")"); - if (iErrno == EMFILE) { - // We have too many open fds, this can cause a busy loop. - Close(); - } + DEBUG(GetSockName() << " == SockError(" << sDescription << ", " + << strerror(iErrno) << ")"); + if (iErrno == EMFILE) { + // We have too many open fds, this can cause a busy loop. + Close(); + } } bool CSocket::ConnectionFrom(const CString& sHost, unsigned short uPort) { - return CZNC::Get().AllowConnectionFrom(sHost); + return CZNC::Get().AllowConnectionFrom(sHost); } bool CSocket::Connect(const CString& sHostname, unsigned short uPort, bool bSSL, unsigned int uTimeout) { - if (!m_pModule) { - DEBUG( - "ERROR: CSocket::Connect called on instance without m_pModule " - "handle!"); - return false; - } + if (!m_pModule) { + DEBUG( + "ERROR: CSocket::Connect called on instance without m_pModule " + "handle!"); + return false; + } - CUser* pUser = m_pModule->GetUser(); - CString sSockName = "MOD::C::" + m_pModule->GetModName(); - CString sBindHost; + CUser* pUser = m_pModule->GetUser(); + CString sSockName = "MOD::C::" + m_pModule->GetModName(); + CString sBindHost; - if (pUser) { - sSockName += "::" + pUser->GetUserName(); - sBindHost = pUser->GetBindHost(); - CIRCNetwork* pNetwork = m_pModule->GetNetwork(); - if (pNetwork) { - sSockName += "::" + pNetwork->GetName(); - sBindHost = pNetwork->GetBindHost(); - } - } + if (pUser) { + sSockName += "::" + pUser->GetUserName(); + sBindHost = pUser->GetBindHost(); + CIRCNetwork* pNetwork = m_pModule->GetNetwork(); + if (pNetwork) { + sSockName += "::" + pNetwork->GetName(); + sBindHost = pNetwork->GetBindHost(); + } + } - // Don't overwrite the socket name if one is already set - if (!GetSockName().empty()) { - sSockName = GetSockName(); - } + // Don't overwrite the socket name if one is already set + if (!GetSockName().empty()) { + sSockName = GetSockName(); + } - m_pModule->GetManager()->Connect(sHostname, uPort, sSockName, uTimeout, - bSSL, sBindHost, this); - return true; + m_pModule->GetManager()->Connect(sHostname, uPort, sSockName, uTimeout, + bSSL, sBindHost, this); + return true; } bool CSocket::Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout) { - if (!m_pModule) { - DEBUG( - "ERROR: CSocket::Listen called on instance without m_pModule " - "handle!"); - return false; - } + if (!m_pModule) { + DEBUG( + "ERROR: CSocket::Listen called on instance without m_pModule " + "handle!"); + return false; + } - CUser* pUser = m_pModule->GetUser(); - CString sSockName = "MOD::L::" + m_pModule->GetModName(); + CUser* pUser = m_pModule->GetUser(); + CString sSockName = "MOD::L::" + m_pModule->GetModName(); - if (pUser) { - sSockName += "::" + pUser->GetUserName(); - } - // Don't overwrite the socket name if one is already set - if (!GetSockName().empty()) { - sSockName = GetSockName(); - } + if (pUser) { + sSockName += "::" + pUser->GetUserName(); + } + // Don't overwrite the socket name if one is already set + if (!GetSockName().empty()) { + sSockName = GetSockName(); + } - return m_pModule->GetManager()->ListenAll(uPort, sSockName, bSSL, SOMAXCONN, - this); + return m_pModule->GetManager()->ListenAll(uPort, sSockName, bSSL, SOMAXCONN, + this); } CModule* CSocket::GetModule() const { return m_pModule; } @@ -554,32 +554,32 @@ void CIRCSocket::IcuExtToUCallback(UConverterToUnicodeArgs* toArgs, const char* codeUnits, int32_t length, UConverterCallbackReason reason, UErrorCode* err) { - // From http://www.mirc.com/colors.html - // The Control+O key combination in mIRC inserts ascii character 15, - // which turns off all previous attributes, including color, bold, - // underline, and italics. - // - // \x02 bold - // \x03 mIRC-compatible color - // \x04 RRGGBB color - // \x0F normal/reset (turn off bold, colors, etc.) - // \x12 reverse (weechat) - // \x16 reverse (mirc, kvirc) - // \x1D italic - // \x1F underline - // Also see http://www.visualirc.net/tech-attrs.php - // - // Keep in sync with CUser::AddTimestamp and CIRCSocket::IcuExtFromUCallback - static const std::set scAllowedChars = { - '\x02', '\x03', '\x04', '\x0F', '\x12', '\x16', '\x1D', '\x1F'}; - if (reason == UCNV_ILLEGAL && length == 1 && - scAllowedChars.count(*codeUnits)) { - *err = U_ZERO_ERROR; - UChar c = *codeUnits; - ucnv_cbToUWriteUChars(toArgs, &c, 1, 0, err); - return; - } - Csock::IcuExtToUCallback(toArgs, codeUnits, length, reason, err); + // From http://www.mirc.com/colors.html + // The Control+O key combination in mIRC inserts ascii character 15, + // which turns off all previous attributes, including color, bold, + // underline, and italics. + // + // \x02 bold + // \x03 mIRC-compatible color + // \x04 RRGGBB color + // \x0F normal/reset (turn off bold, colors, etc.) + // \x12 reverse (weechat) + // \x16 reverse (mirc, kvirc) + // \x1D italic + // \x1F underline + // Also see http://www.visualirc.net/tech-attrs.php + // + // Keep in sync with CUser::AddTimestamp and CIRCSocket::IcuExtFromUCallback + static const std::set scAllowedChars = { + '\x02', '\x03', '\x04', '\x0F', '\x12', '\x16', '\x1D', '\x1F'}; + if (reason == UCNV_ILLEGAL && length == 1 && + scAllowedChars.count(*codeUnits)) { + *err = U_ZERO_ERROR; + UChar c = *codeUnits; + ucnv_cbToUWriteUChars(toArgs, &c, 1, 0, err); + return; + } + Csock::IcuExtToUCallback(toArgs, codeUnits, length, reason, err); } void CIRCSocket::IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs, @@ -587,16 +587,16 @@ void CIRCSocket::IcuExtFromUCallback(UConverterFromUnicodeArgs* fromArgs, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { - // See comment in CIRCSocket::IcuExtToUCallback - static const std::set scAllowedChars = {0x02, 0x03, 0x04, 0x0F, - 0x12, 0x16, 0x1D, 0x1F}; - if (reason == UCNV_ILLEGAL && scAllowedChars.count(codePoint)) { - *err = U_ZERO_ERROR; - char c = codePoint; - ucnv_cbFromUWriteBytes(fromArgs, &c, 1, 0, err); - return; - } - Csock::IcuExtFromUCallback(fromArgs, codeUnits, length, codePoint, reason, - err); + // See comment in CIRCSocket::IcuExtToUCallback + static const std::set scAllowedChars = {0x02, 0x03, 0x04, 0x0F, + 0x12, 0x16, 0x1D, 0x1F}; + if (reason == UCNV_ILLEGAL && scAllowedChars.count(codePoint)) { + *err = U_ZERO_ERROR; + char c = codePoint; + ucnv_cbFromUWriteBytes(fromArgs, &c, 1, 0, err); + return; + } + Csock::IcuExtFromUCallback(fromArgs, codeUnits, length, codePoint, reason, + err); } #endif diff --git a/src/Template.cpp b/src/Template.cpp index 86148c4a..5f06bf1b 100644 --- a/src/Template.cpp +++ b/src/Template.cpp @@ -27,899 +27,899 @@ using std::pair; using std::map; void CTemplateOptions::Parse(const CString& sLine) { - CString sName = sLine.Token(0, false, "=").Trim_n().AsUpper(); - CString sValue = sLine.Token(1, true, "=").Trim_n(); + CString sName = sLine.Token(0, false, "=").Trim_n().AsUpper(); + CString sValue = sLine.Token(1, true, "=").Trim_n(); - if (sName == "ESC") { - m_eEscapeTo = CString::ToEscape(sValue); - } else if (sName == "ESCFROM") { - m_eEscapeFrom = CString::ToEscape(sValue); - } + if (sName == "ESC") { + m_eEscapeTo = CString::ToEscape(sValue); + } else if (sName == "ESCFROM") { + m_eEscapeFrom = CString::ToEscape(sValue); + } } CTemplate* CTemplateLoopContext::GetRow(unsigned int uIndex) { - size_t uSize = m_pvRows->size(); + size_t uSize = m_pvRows->size(); - if (uIndex < uSize) { - if (m_bReverse) { - return (*m_pvRows)[uSize - uIndex - 1]; - } else { - return (*m_pvRows)[uIndex]; - } - } + if (uIndex < uSize) { + if (m_bReverse) { + return (*m_pvRows)[uSize - uIndex - 1]; + } else { + return (*m_pvRows)[uIndex]; + } + } - return nullptr; + return nullptr; } CString CTemplateLoopContext::GetValue(const CString& sName, bool bFromIf) { - CTemplate* pTemplate = GetCurRow(); + CTemplate* pTemplate = GetCurRow(); - if (!pTemplate) { - DEBUG("Loop [" + GetName() + "] has no row index [" + - CString(GetRowIndex()) + "]"); - return ""; - } + if (!pTemplate) { + DEBUG("Loop [" + GetName() + "] has no row index [" + + CString(GetRowIndex()) + "]"); + return ""; + } - if (sName.Equals("__ID__")) { - return CString(GetRowIndex() + 1); - } else if (sName.Equals("__COUNT__")) { - return CString(GetRowCount()); - } else if (sName.Equals("__ODD__")) { - return ((GetRowIndex() % 2) ? "" : "1"); - } else if (sName.Equals("__EVEN__")) { - return ((GetRowIndex() % 2) ? "1" : ""); - } else if (sName.Equals("__FIRST__")) { - return ((GetRowIndex() == 0) ? "1" : ""); - } else if (sName.Equals("__LAST__")) { - return ((GetRowIndex() == m_pvRows->size() - 1) ? "1" : ""); - } else if (sName.Equals("__OUTER__")) { - return ((GetRowIndex() == 0 || GetRowIndex() == m_pvRows->size() - 1) - ? "1" - : ""); - } else if (sName.Equals("__INNER__")) { - return ((GetRowIndex() == 0 || GetRowIndex() == m_pvRows->size() - 1) - ? "" - : "1"); - } + if (sName.Equals("__ID__")) { + return CString(GetRowIndex() + 1); + } else if (sName.Equals("__COUNT__")) { + return CString(GetRowCount()); + } else if (sName.Equals("__ODD__")) { + return ((GetRowIndex() % 2) ? "" : "1"); + } else if (sName.Equals("__EVEN__")) { + return ((GetRowIndex() % 2) ? "1" : ""); + } else if (sName.Equals("__FIRST__")) { + return ((GetRowIndex() == 0) ? "1" : ""); + } else if (sName.Equals("__LAST__")) { + return ((GetRowIndex() == m_pvRows->size() - 1) ? "1" : ""); + } else if (sName.Equals("__OUTER__")) { + return ((GetRowIndex() == 0 || GetRowIndex() == m_pvRows->size() - 1) + ? "1" + : ""); + } else if (sName.Equals("__INNER__")) { + return ((GetRowIndex() == 0 || GetRowIndex() == m_pvRows->size() - 1) + ? "" + : "1"); + } - return pTemplate->GetValue(sName, bFromIf); + return pTemplate->GetValue(sName, bFromIf); } CTemplate::~CTemplate() { - for (const auto& it : m_mvLoops) { - const vector& vLoop = it.second; - for (CTemplate* pTemplate : vLoop) { - delete pTemplate; - } - } + for (const auto& it : m_mvLoops) { + const vector& vLoop = it.second; + for (CTemplate* pTemplate : vLoop) { + delete pTemplate; + } + } - for (CTemplateLoopContext* pContext : m_vLoopContexts) { - delete pContext; - } + for (CTemplateLoopContext* pContext : m_vLoopContexts) { + delete pContext; + } } void CTemplate::Init() { - /* We have no CConfig in ZNC land - * Hmm... Actually, we do have it now. - CString sPath(CConfig::GetValue("WebFilesPath")); + /* We have no CConfig in ZNC land + * Hmm... Actually, we do have it now. + CString sPath(CConfig::GetValue("WebFilesPath")); - if (!sPath.empty()) { - SetPath(sPath); - } - */ + if (!sPath.empty()) { + SetPath(sPath); + } + */ - ClearPaths(); - m_pParent = nullptr; + ClearPaths(); + m_pParent = nullptr; } CString CTemplate::ExpandFile(const CString& sFilename, bool bFromInc) { - /*if (sFilename.StartsWith("/") || sFilename.StartsWith("./")) { - return sFilename; - }*/ + /*if (sFilename.StartsWith("/") || sFilename.StartsWith("./")) { + return sFilename; + }*/ - CString sFile(ResolveLiteral(sFilename).TrimLeft_n("/")); + CString sFile(ResolveLiteral(sFilename).TrimLeft_n("/")); - for (auto& it : m_lsbPaths) { - CString& sRoot = it.first; - CString sFilePath(CDir::ChangeDir(sRoot, sFile)); + for (auto& it : m_lsbPaths) { + CString& sRoot = it.first; + CString sFilePath(CDir::ChangeDir(sRoot, sFile)); - // Make sure path ends with a slash because "/foo/pub*" matches - // "/foo/public_keep_out/" but "/foo/pub/*" doesn't - if (!sRoot.empty() && !sRoot.EndsWith("/")) { - sRoot += "/"; - } + // Make sure path ends with a slash because "/foo/pub*" matches + // "/foo/public_keep_out/" but "/foo/pub/*" doesn't + if (!sRoot.empty() && !sRoot.EndsWith("/")) { + sRoot += "/"; + } - if (it.second && !bFromInc) { - DEBUG("\t\tSkipping path (not from INC) [" + sFilePath + "]"); - continue; - } + if (it.second && !bFromInc) { + DEBUG("\t\tSkipping path (not from INC) [" + sFilePath + "]"); + continue; + } - if (CFile::Exists(sFilePath)) { - if (sRoot.empty() || sFilePath.StartsWith(sRoot)) { - DEBUG(" Found [" + sFilePath + "]"); - return sFilePath; - } else { - DEBUG("\t\tOutside of root [" + sFilePath + "] !~ [" + sRoot + - "]"); - } - } - } + if (CFile::Exists(sFilePath)) { + if (sRoot.empty() || sFilePath.StartsWith(sRoot)) { + DEBUG(" Found [" + sFilePath + "]"); + return sFilePath; + } else { + DEBUG("\t\tOutside of root [" + sFilePath + "] !~ [" + sRoot + + "]"); + } + } + } - switch (m_lsbPaths.size()) { - case 0: - DEBUG("Unable to find [" + sFile + "] using the current directory"); - break; - case 1: - DEBUG("Unable to find [" + sFile + "] in the defined path [" + - m_lsbPaths.begin()->first + "]"); - break; - default: - DEBUG("Unable to find [" + sFile + "] in any of the " + - CString(m_lsbPaths.size()) + " defined paths"); - } + switch (m_lsbPaths.size()) { + case 0: + DEBUG("Unable to find [" + sFile + "] using the current directory"); + break; + case 1: + DEBUG("Unable to find [" + sFile + "] in the defined path [" + + m_lsbPaths.begin()->first + "]"); + break; + default: + DEBUG("Unable to find [" + sFile + "] in any of the " + + CString(m_lsbPaths.size()) + " defined paths"); + } - return ""; + return ""; } void CTemplate::SetPath(const CString& sPaths) { - VCString vsDirs; - sPaths.Split(":", vsDirs, false); + VCString vsDirs; + sPaths.Split(":", vsDirs, false); - for (const CString& sDir : vsDirs) { - AppendPath(sDir, false); - } + for (const CString& sDir : vsDirs) { + AppendPath(sDir, false); + } } CString CTemplate::MakePath(const CString& sPath) const { - CString sRet(CDir::ChangeDir("./", sPath + "/")); + CString sRet(CDir::ChangeDir("./", sPath + "/")); - if (!sRet.empty() && !sRet.EndsWith("/")) { - sRet += "/"; - } + if (!sRet.empty() && !sRet.EndsWith("/")) { + sRet += "/"; + } - return sRet; + return sRet; } void CTemplate::PrependPath(const CString& sPath, bool bIncludesOnly) { - DEBUG("CTemplate::PrependPath(" + sPath + ") == [" + MakePath(sPath) + "]"); - m_lsbPaths.push_front(make_pair(MakePath(sPath), bIncludesOnly)); + DEBUG("CTemplate::PrependPath(" + sPath + ") == [" + MakePath(sPath) + "]"); + m_lsbPaths.push_front(make_pair(MakePath(sPath), bIncludesOnly)); } void CTemplate::AppendPath(const CString& sPath, bool bIncludesOnly) { - DEBUG("CTemplate::AppendPath(" + sPath + ") == [" + MakePath(sPath) + "]"); - m_lsbPaths.push_back(make_pair(MakePath(sPath), bIncludesOnly)); + DEBUG("CTemplate::AppendPath(" + sPath + ") == [" + MakePath(sPath) + "]"); + m_lsbPaths.push_back(make_pair(MakePath(sPath), bIncludesOnly)); } void CTemplate::RemovePath(const CString& sPath) { - DEBUG("CTemplate::RemovePath(" + sPath + ") == [" + - CDir::ChangeDir("./", sPath + "/") + "]"); + DEBUG("CTemplate::RemovePath(" + sPath + ") == [" + + CDir::ChangeDir("./", sPath + "/") + "]"); - for (const auto& it : m_lsbPaths) { - if (it.first == sPath) { - m_lsbPaths.remove(it); - RemovePath( - sPath); // @todo probably shouldn't use recursion, being lazy - return; - } - } + for (const auto& it : m_lsbPaths) { + if (it.first == sPath) { + m_lsbPaths.remove(it); + RemovePath( + sPath); // @todo probably shouldn't use recursion, being lazy + return; + } + } } void CTemplate::ClearPaths() { m_lsbPaths.clear(); } bool CTemplate::SetFile(const CString& sFileName) { - m_sFileName = ExpandFile(sFileName, false); - PrependPath(sFileName + "/.."); + m_sFileName = ExpandFile(sFileName, false); + PrependPath(sFileName + "/.."); - if (sFileName.empty()) { - DEBUG("CTemplate::SetFile() - Filename is empty"); - return false; - } + if (sFileName.empty()) { + DEBUG("CTemplate::SetFile() - Filename is empty"); + return false; + } - if (m_sFileName.empty()) { - DEBUG("CTemplate::SetFile() - [" + sFileName + "] does not exist"); - return false; - } + if (m_sFileName.empty()) { + DEBUG("CTemplate::SetFile() - [" + sFileName + "] does not exist"); + return false; + } - DEBUG("Set template file to [" + m_sFileName + "]"); + DEBUG("Set template file to [" + m_sFileName + "]"); - return true; + return true; } class CLoopSorter { - CString m_sType; + CString m_sType; public: - CLoopSorter(const CString& sType) : m_sType(sType) {} - bool operator()(CTemplate* pTemplate1, CTemplate* pTemplate2) { - return (pTemplate1->GetValue(m_sType, false) < - pTemplate2->GetValue(m_sType, false)); - } + CLoopSorter(const CString& sType) : m_sType(sType) {} + bool operator()(CTemplate* pTemplate1, CTemplate* pTemplate2) { + return (pTemplate1->GetValue(m_sType, false) < + pTemplate2->GetValue(m_sType, false)); + } }; CTemplate& CTemplate::AddRow(const CString& sName) { - CTemplate* pTmpl = new CTemplate(m_spOptions, this); - m_mvLoops[sName].push_back(pTmpl); + CTemplate* pTmpl = new CTemplate(m_spOptions, this); + m_mvLoops[sName].push_back(pTmpl); - return *pTmpl; + return *pTmpl; } CTemplate* CTemplate::GetRow(const CString& sName, unsigned int uIndex) { - vector* pvLoop = GetLoop(sName); + vector* pvLoop = GetLoop(sName); - if (pvLoop) { - if (pvLoop->size() > uIndex) { - return (*pvLoop)[uIndex]; - } - } + if (pvLoop) { + if (pvLoop->size() > uIndex) { + return (*pvLoop)[uIndex]; + } + } - return nullptr; + return nullptr; } vector* CTemplate::GetLoop(const CString& sName) { - CTemplateLoopContext* pContext = GetCurLoopContext(); + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (pContext) { - CTemplate* pTemplate = pContext->GetCurRow(); + if (pContext) { + CTemplate* pTemplate = pContext->GetCurRow(); - if (pTemplate) { - return pTemplate->GetLoop(sName); - } - } + if (pTemplate) { + return pTemplate->GetLoop(sName); + } + } - map>::iterator it = m_mvLoops.find(sName); + map>::iterator it = m_mvLoops.find(sName); - if (it != m_mvLoops.end()) { - return &(it->second); - } + if (it != m_mvLoops.end()) { + return &(it->second); + } - return nullptr; + return nullptr; } bool CTemplate::PrintString(CString& sRet) { - sRet.clear(); - stringstream sStream; - bool bRet = Print(sStream); + sRet.clear(); + stringstream sStream; + bool bRet = Print(sStream); - sRet = sStream.str(); + sRet = sStream.str(); - return bRet; + return bRet; } bool CTemplate::Print(ostream& oOut) { return Print(m_sFileName, oOut); } bool CTemplate::Print(const CString& sFileName, ostream& oOut) { - if (sFileName.empty()) { - DEBUG("Empty filename in CTemplate::Print()"); - return false; - } + if (sFileName.empty()) { + DEBUG("Empty filename in CTemplate::Print()"); + return false; + } - CFile File(sFileName); + CFile File(sFileName); - if (!File.Open()) { - DEBUG("Unable to open file [" + sFileName + "] in CTemplate::Print()"); - return false; - } + if (!File.Open()) { + DEBUG("Unable to open file [" + sFileName + "] in CTemplate::Print()"); + return false; + } - CString sLine; - CString sSetBlockVar; - bool bValidLastIf = false; - bool bInSetBlock = false; - unsigned long uFilePos = 0; - unsigned long uCurPos = 0; - unsigned int uLineNum = 0; - unsigned int uNestedIfs = 0; - unsigned int uSkip = 0; - bool bLoopCont = false; - bool bLoopBreak = false; - bool bExit = false; + CString sLine; + CString sSetBlockVar; + bool bValidLastIf = false; + bool bInSetBlock = false; + unsigned long uFilePos = 0; + unsigned long uCurPos = 0; + unsigned int uLineNum = 0; + unsigned int uNestedIfs = 0; + unsigned int uSkip = 0; + bool bLoopCont = false; + bool bLoopBreak = false; + bool bExit = false; - while (File.ReadLine(sLine)) { - CString sOutput; - bool bFoundATag = false; - bool bTmplLoopHasData = false; - uLineNum++; - CString::size_type iPos = 0; - uCurPos = uFilePos; - CString::size_type uLineSize = sLine.size(); - bool bBroke = false; + while (File.ReadLine(sLine)) { + CString sOutput; + bool bFoundATag = false; + bool bTmplLoopHasData = false; + uLineNum++; + CString::size_type iPos = 0; + uCurPos = uFilePos; + CString::size_type uLineSize = sLine.size(); + bool bBroke = false; - while (1) { - iPos = sLine.find(""); + CString::size_type iPos2 = sLine.find("?>"); - // Make sure our tmpl tag is ended properly - if (iPos2 == CString::npos) { - DEBUG("Template tag not ended properly in file [" + sFileName + - "] [Parse(sArgs); - } else if (sAction.Equals("ADDROW")) { - CString sLoopName = sArgs.Token(0); - MCString msRow; + if (!uSkip) { + if (sAction.Equals("INC")) { + if (!Print(ExpandFile(sArgs, true), oOut)) { + DEBUG("Unable to print INC'd file [" + sArgs + "]"); + return false; + } + } else if (sAction.Equals("SETOPTION")) { + m_spOptions->Parse(sArgs); + } else if (sAction.Equals("ADDROW")) { + CString sLoopName = sArgs.Token(0); + MCString msRow; - if (sArgs.Token(1, true, " ").OptionSplit(msRow)) { - CTemplate& NewRow = AddRow(sLoopName); + if (sArgs.Token(1, true, " ").OptionSplit(msRow)) { + CTemplate& NewRow = AddRow(sLoopName); - for (const auto& it : msRow) { - NewRow[it.first] = it.second; - } - } - } else if (sAction.Equals("SET")) { - CString sName = sArgs.Token(0); - CString sValue = sArgs.Token(1, true); + for (const auto& it : msRow) { + NewRow[it.first] = it.second; + } + } + } else if (sAction.Equals("SET")) { + CString sName = sArgs.Token(0); + CString sValue = sArgs.Token(1, true); - (*this)[sName] = sValue; - } else if (sAction.Equals("JOIN")) { - VCString vsArgs; - // sArgs.Split(" ", vsArgs, false, "\"", "\""); - sArgs.QuoteSplit(vsArgs); + (*this)[sName] = sValue; + } else if (sAction.Equals("JOIN")) { + VCString vsArgs; + // sArgs.Split(" ", vsArgs, false, "\"", "\""); + sArgs.QuoteSplit(vsArgs); - if (vsArgs.size() > 1) { - CString sDelim = vsArgs[0]; - bool bFoundOne = false; - CString::EEscape eEscape = CString::EASCII; + if (vsArgs.size() > 1) { + CString sDelim = vsArgs[0]; + bool bFoundOne = false; + CString::EEscape eEscape = CString::EASCII; - for (const CString& sArg : vsArgs) { - if (sArg.StartsWith("ESC=")) { - eEscape = - CString::ToEscape(sArg.LeftChomp_n(4)); - } else { - CString sValue = GetValue(sArg); + for (const CString& sArg : vsArgs) { + if (sArg.StartsWith("ESC=")) { + eEscape = + CString::ToEscape(sArg.LeftChomp_n(4)); + } else { + CString sValue = GetValue(sArg); - if (!sValue.empty()) { - if (bFoundOne) { - sOutput += sDelim; - } + if (!sValue.empty()) { + if (bFoundOne) { + sOutput += sDelim; + } - sOutput += sValue.Escape_n(eEscape); - bFoundOne = true; - } - } - } - } - } else if (sAction.Equals("SETBLOCK")) { - sSetBlockVar = sArgs; - bInSetBlock = true; - } else if (sAction.Equals("EXPAND")) { - sOutput += ExpandFile(sArgs, true); - } else if (sAction.Equals("VAR")) { - sOutput += GetValue(sArgs); - } else if (sAction.Equals("LT")) { - sOutput += ""; - } else if (sAction.Equals("CONTINUE")) { - CTemplateLoopContext* pContext = GetCurLoopContext(); + sOutput += sValue.Escape_n(eEscape); + bFoundOne = true; + } + } + } + } + } else if (sAction.Equals("SETBLOCK")) { + sSetBlockVar = sArgs; + bInSetBlock = true; + } else if (sAction.Equals("EXPAND")) { + sOutput += ExpandFile(sArgs, true); + } else if (sAction.Equals("VAR")) { + sOutput += GetValue(sArgs); + } else if (sAction.Equals("LT")) { + sOutput += ""; + } else if (sAction.Equals("CONTINUE")) { + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (pContext) { - uSkip++; - bLoopCont = true; + if (pContext) { + uSkip++; + bLoopCont = true; - break; - } else { - DEBUG("[" + sFileName + ":" + - CString(uCurPos - iPos2 - 4) + - "] must be used inside of a " - "loop!"); - } - } else if (sAction.Equals("BREAK")) { - // break from loop - CTemplateLoopContext* pContext = GetCurLoopContext(); + break; + } else { + DEBUG("[" + sFileName + ":" + + CString(uCurPos - iPos2 - 4) + + "] must be used inside of a " + "loop!"); + } + } else if (sAction.Equals("BREAK")) { + // break from loop + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (pContext) { - uSkip++; - bLoopBreak = true; + if (pContext) { + uSkip++; + bLoopBreak = true; - break; - } else { - DEBUG( - "[" + sFileName + ":" + - CString(uCurPos - iPos2 - 4) + - "] must be used inside of a loop!"); - } - } else if (sAction.Equals("EXIT")) { - bExit = true; - } else if (sAction.Equals("DEBUG")) { - DEBUG("CTemplate DEBUG [" + sFileName + "@" + - CString(uCurPos - iPos2 - 4) + "b] -> [" + sArgs + - "]"); - } else if (sAction.Equals("LOOP")) { - CTemplateLoopContext* pContext = GetCurLoopContext(); + break; + } else { + DEBUG( + "[" + sFileName + ":" + + CString(uCurPos - iPos2 - 4) + + "] must be used inside of a loop!"); + } + } else if (sAction.Equals("EXIT")) { + bExit = true; + } else if (sAction.Equals("DEBUG")) { + DEBUG("CTemplate DEBUG [" + sFileName + "@" + + CString(uCurPos - iPos2 - 4) + "b] -> [" + sArgs + + "]"); + } else if (sAction.Equals("LOOP")) { + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (!pContext || - pContext->GetFilePosition() != uCurPos) { - // we are at a brand new loop (be it new or a first - // pass at an inner loop) + if (!pContext || + pContext->GetFilePosition() != uCurPos) { + // we are at a brand new loop (be it new or a first + // pass at an inner loop) - CString sLoopName = sArgs.Token(0); - bool bReverse = (sArgs.Token(1).Equals("REVERSE")); - bool bSort = (sArgs.Token(1).StartsWith("SORT")); - vector* pvLoop = GetLoop(sLoopName); + CString sLoopName = sArgs.Token(0); + bool bReverse = (sArgs.Token(1).Equals("REVERSE")); + bool bSort = (sArgs.Token(1).StartsWith("SORT")); + vector* pvLoop = GetLoop(sLoopName); - if (bSort && pvLoop != nullptr && - pvLoop->size() > 1) { - CString sKey; + if (bSort && pvLoop != nullptr && + pvLoop->size() > 1) { + CString sKey; - if (sArgs.Token(1) - .TrimPrefix_n("SORT") - .StartsWith("ASC=")) { - sKey = - sArgs.Token(1).TrimPrefix_n("SORTASC="); - } else if (sArgs.Token(1) - .TrimPrefix_n("SORT") - .StartsWith("DESC=")) { - sKey = sArgs.Token(1) - .TrimPrefix_n("SORTDESC="); - bReverse = true; - } + if (sArgs.Token(1) + .TrimPrefix_n("SORT") + .StartsWith("ASC=")) { + sKey = + sArgs.Token(1).TrimPrefix_n("SORTASC="); + } else if (sArgs.Token(1) + .TrimPrefix_n("SORT") + .StartsWith("DESC=")) { + sKey = sArgs.Token(1) + .TrimPrefix_n("SORTDESC="); + bReverse = true; + } - if (!sKey.empty()) { - std::sort(pvLoop->begin(), pvLoop->end(), - CLoopSorter(sKey)); - } - } + if (!sKey.empty()) { + std::sort(pvLoop->begin(), pvLoop->end(), + CLoopSorter(sKey)); + } + } - if (pvLoop) { - // If we found data for this loop, add it to our - // context vector - // unsigned long uBeforeLoopTag = uCurPos - - // iPos2 - 4; - unsigned long uAfterLoopTag = uCurPos; + if (pvLoop) { + // If we found data for this loop, add it to our + // context vector + // unsigned long uBeforeLoopTag = uCurPos - + // iPos2 - 4; + unsigned long uAfterLoopTag = uCurPos; - for (CString::size_type t = 0; t < sLine.size(); - t++) { - char c = sLine[t]; - if (c == '\r' || c == '\n') { - uAfterLoopTag++; - } else { - break; - } - } + for (CString::size_type t = 0; t < sLine.size(); + t++) { + char c = sLine[t]; + if (c == '\r' || c == '\n') { + uAfterLoopTag++; + } else { + break; + } + } - m_vLoopContexts.push_back( - new CTemplateLoopContext(uAfterLoopTag, - sLoopName, - bReverse, pvLoop)); - } else { - // If we don't have data, just skip this loop - // and everything inside - uSkip++; - } - } - } else if (sAction.Equals("IF")) { - if (ValidIf(sArgs)) { - uNestedIfs++; - bValidLastIf = true; - } else { - uSkip++; - bValidLastIf = false; - } - } else if (sAction.Equals("REM")) { - uSkip++; - } else { - bNotFound = true; - } - } else if (sAction.Equals("REM")) { - uSkip++; - } else if (sAction.Equals("IF")) { - uSkip++; - } else if (sAction.Equals("LOOP")) { - uSkip++; - } + m_vLoopContexts.push_back( + new CTemplateLoopContext(uAfterLoopTag, + sLoopName, + bReverse, pvLoop)); + } else { + // If we don't have data, just skip this loop + // and everything inside + uSkip++; + } + } + } else if (sAction.Equals("IF")) { + if (ValidIf(sArgs)) { + uNestedIfs++; + bValidLastIf = true; + } else { + uSkip++; + bValidLastIf = false; + } + } else if (sAction.Equals("REM")) { + uSkip++; + } else { + bNotFound = true; + } + } else if (sAction.Equals("REM")) { + uSkip++; + } else if (sAction.Equals("IF")) { + uSkip++; + } else if (sAction.Equals("LOOP")) { + uSkip++; + } - if (sAction.Equals("ENDIF")) { - if (uSkip) { - uSkip--; - } else { - uNestedIfs--; - } - } else if (sAction.Equals("ENDREM")) { - if (uSkip) { - uSkip--; - } - } else if (sAction.Equals("ENDSETBLOCK")) { - bInSetBlock = false; - sSetBlockVar = ""; - } else if (sAction.Equals("ENDLOOP")) { - if (bLoopCont && uSkip == 1) { - uSkip--; - bLoopCont = false; - } + if (sAction.Equals("ENDIF")) { + if (uSkip) { + uSkip--; + } else { + uNestedIfs--; + } + } else if (sAction.Equals("ENDREM")) { + if (uSkip) { + uSkip--; + } + } else if (sAction.Equals("ENDSETBLOCK")) { + bInSetBlock = false; + sSetBlockVar = ""; + } else if (sAction.Equals("ENDLOOP")) { + if (bLoopCont && uSkip == 1) { + uSkip--; + bLoopCont = false; + } - if (bLoopBreak && uSkip == 1) { - uSkip--; - } + if (bLoopBreak && uSkip == 1) { + uSkip--; + } - if (uSkip) { - uSkip--; - } else { - // We are at the end of the loop so we need to inc the - // index - CTemplateLoopContext* pContext = GetCurLoopContext(); + if (uSkip) { + uSkip--; + } else { + // We are at the end of the loop so we need to inc the + // index + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (pContext) { - pContext->IncRowIndex(); + if (pContext) { + pContext->IncRowIndex(); - // If we didn't go out of bounds we need to seek - // back to the top of our loop - if (!bLoopBreak && pContext->GetCurRow()) { - uCurPos = pContext->GetFilePosition(); - uFilePos = uCurPos; - uLineSize = 0; + // If we didn't go out of bounds we need to seek + // back to the top of our loop + if (!bLoopBreak && pContext->GetCurRow()) { + uCurPos = pContext->GetFilePosition(); + uFilePos = uCurPos; + uLineSize = 0; - File.Seek(uCurPos); - bBroke = true; + File.Seek(uCurPos); + bBroke = true; - if (!sOutput.Trim_n().empty()) { - pContext->SetHasData(); - } + if (!sOutput.Trim_n().empty()) { + pContext->SetHasData(); + } - break; - } else { - if (sOutput.Trim_n().empty()) { - sOutput.clear(); - } + break; + } else { + if (sOutput.Trim_n().empty()) { + sOutput.clear(); + } - bTmplLoopHasData = pContext->HasData(); - DelCurLoopContext(); - bLoopBreak = false; - } - } - } - } else if (sAction.Equals("ELSE")) { - if (!bValidLastIf && uSkip == 1) { - CString sArg = sArgs.Token(0); + bTmplLoopHasData = pContext->HasData(); + DelCurLoopContext(); + bLoopBreak = false; + } + } + } + } else if (sAction.Equals("ELSE")) { + if (!bValidLastIf && uSkip == 1) { + CString sArg = sArgs.Token(0); - if (sArg.empty() || (sArg.Equals("IF") && - ValidIf(sArgs.Token(1, true)))) { - uSkip = 0; - bValidLastIf = true; - } - } else if (!uSkip) { - uSkip = 1; - } - } else if (bNotFound) { - // Unknown tag that isn't being skipped... - vector>& - vspTagHandlers = GetTagHandlers(); + if (sArg.empty() || (sArg.Equals("IF") && + ValidIf(sArgs.Token(1, true)))) { + uSkip = 0; + bValidLastIf = true; + } + } else if (!uSkip) { + uSkip = 1; + } + } else if (bNotFound) { + // Unknown tag that isn't being skipped... + vector>& + vspTagHandlers = GetTagHandlers(); - if (!vspTagHandlers.empty()) { - // @todo this should go up to the top to grab handlers - CTemplate* pTmpl = GetCurTemplate(); - CString sCustomOutput; + if (!vspTagHandlers.empty()) { + // @todo this should go up to the top to grab handlers + CTemplate* pTmpl = GetCurTemplate(); + CString sCustomOutput; - for (const auto& spTagHandler : vspTagHandlers) { - if (spTagHandler->HandleTag(*pTmpl, sAction, sArgs, - sCustomOutput)) { - sOutput += sCustomOutput; - bNotFound = false; - break; - } - } + for (const auto& spTagHandler : vspTagHandlers) { + if (spTagHandler->HandleTag(*pTmpl, sAction, sArgs, + sCustomOutput)) { + sOutput += sCustomOutput; + bNotFound = false; + break; + } + } - if (bNotFound) { - DEBUG("Unknown/Unhandled tag [" + sAction + "]"); - } - } - } + if (bNotFound) { + DEBUG("Unknown/Unhandled tag [" + sAction + "]"); + } + } + } - continue; - } + continue; + } - DEBUG("Malformed tag on line " + CString(uLineNum) + " of [" - << File.GetLongName() + "]"); - DEBUG("--------------- [" + sLine + "]"); - } + DEBUG("Malformed tag on line " + CString(uLineNum) + " of [" + << File.GetLongName() + "]"); + DEBUG("--------------- [" + sLine + "]"); + } - if (!bBroke) { - uFilePos += uLineSize; + if (!bBroke) { + uFilePos += uLineSize; - if (!uSkip) { - sOutput += sLine; - } - } + if (!uSkip) { + sOutput += sLine; + } + } - if (!bFoundATag || bTmplLoopHasData || - sOutput.find_first_not_of(" \t\r\n") != CString::npos) { - if (bInSetBlock) { - CString sName = sSetBlockVar.Token(0); - // CString sValue = sSetBlockVar.Token(1, true); - (*this)[sName] += sOutput; - } else { - oOut << sOutput; - } - } + if (!bFoundATag || bTmplLoopHasData || + sOutput.find_first_not_of(" \t\r\n") != CString::npos) { + if (bInSetBlock) { + CString sName = sSetBlockVar.Token(0); + // CString sValue = sSetBlockVar.Token(1, true); + (*this)[sName] += sOutput; + } else { + oOut << sOutput; + } + } - if (bExit) { - break; - } - } + if (bExit) { + break; + } + } - oOut.flush(); + oOut.flush(); - return true; + return true; } void CTemplate::DelCurLoopContext() { - if (m_vLoopContexts.empty()) { - return; - } + if (m_vLoopContexts.empty()) { + return; + } - delete m_vLoopContexts.back(); - m_vLoopContexts.pop_back(); + delete m_vLoopContexts.back(); + m_vLoopContexts.pop_back(); } CTemplateLoopContext* CTemplate::GetCurLoopContext() { - if (!m_vLoopContexts.empty()) { - return m_vLoopContexts.back(); - } + if (!m_vLoopContexts.empty()) { + return m_vLoopContexts.back(); + } - return nullptr; + return nullptr; } bool CTemplate::ValidIf(const CString& sArgs) { - CString sArgStr = sArgs; - // sArgStr.Replace(" ", "", "\"", "\"", true); - sArgStr.Replace(" &&", "&&", "\"", "\"", false); - sArgStr.Replace("&& ", "&&", "\"", "\"", false); - sArgStr.Replace(" ||", "||", "\"", "\"", false); - sArgStr.Replace("|| ", "||", "\"", "\"", false); + CString sArgStr = sArgs; + // sArgStr.Replace(" ", "", "\"", "\"", true); + sArgStr.Replace(" &&", "&&", "\"", "\"", false); + sArgStr.Replace("&& ", "&&", "\"", "\"", false); + sArgStr.Replace(" ||", "||", "\"", "\"", false); + sArgStr.Replace("|| ", "||", "\"", "\"", false); - CString::size_type uOrPos = sArgStr.find("||"); - CString::size_type uAndPos = sArgStr.find("&&"); + CString::size_type uOrPos = sArgStr.find("||"); + CString::size_type uAndPos = sArgStr.find("&&"); - while (uOrPos != CString::npos || uAndPos != CString::npos || - !sArgStr.empty()) { - bool bAnd = false; + while (uOrPos != CString::npos || uAndPos != CString::npos || + !sArgStr.empty()) { + bool bAnd = false; - if (uAndPos < uOrPos) { - bAnd = true; - } + if (uAndPos < uOrPos) { + bAnd = true; + } - CString sExpr = sArgStr.Token(0, false, ((bAnd) ? "&&" : "||")); - sArgStr = sArgStr.Token(1, true, ((bAnd) ? "&&" : "||")); + CString sExpr = sArgStr.Token(0, false, ((bAnd) ? "&&" : "||")); + sArgStr = sArgStr.Token(1, true, ((bAnd) ? "&&" : "||")); - if (ValidExpr(sExpr)) { - if (!bAnd) { - return true; - } - } else { - if (bAnd) { - return false; - } - } + if (ValidExpr(sExpr)) { + if (!bAnd) { + return true; + } + } else { + if (bAnd) { + return false; + } + } - uOrPos = sArgStr.find("||"); - uAndPos = sArgStr.find("&&"); - } + uOrPos = sArgStr.find("||"); + uAndPos = sArgStr.find("&&"); + } - return false; + return false; } bool CTemplate::ValidExpr(const CString& sExpression) { - bool bNegate = false; - CString sExpr(sExpression); - CString sName; - CString sValue; + bool bNegate = false; + CString sExpr(sExpression); + CString sName; + CString sValue; - if (sExpr.TrimPrefix("!")) { - bNegate = true; - } + if (sExpr.TrimPrefix("!")) { + bNegate = true; + } - if (sExpr.Contains("!=")) { - sName = sExpr.Token(0, false, "!=").Trim_n(); - sValue = sExpr.Token(1, true, "!=", false, "\"", "\"", true).Trim_n(); - bNegate = !bNegate; - } else if (sExpr.Contains("==")) { - sName = sExpr.Token(0, false, "==").Trim_n(); - sValue = sExpr.Token(1, true, "==", false, "\"", "\"", true).Trim_n(); - } else if (sExpr.Contains(">=")) { - sName = sExpr.Token(0, false, ">=").Trim_n(); - sValue = sExpr.Token(1, true, ">=", false, "\"", "\"", true).Trim_n(); - return (GetValue(sName, true).ToLong() >= sValue.ToLong()); - } else if (sExpr.Contains("<=")) { - sName = sExpr.Token(0, false, "<=").Trim_n(); - sValue = sExpr.Token(1, true, "<=", false, "\"", "\"", true).Trim_n(); - return (GetValue(sName, true).ToLong() <= sValue.ToLong()); - } else if (sExpr.Contains(">")) { - sName = sExpr.Token(0, false, ">").Trim_n(); - sValue = sExpr.Token(1, true, ">", false, "\"", "\"", true).Trim_n(); - return (GetValue(sName, true).ToLong() > sValue.ToLong()); - } else if (sExpr.Contains("<")) { - sName = sExpr.Token(0, false, "<").Trim_n(); - sValue = sExpr.Token(1, true, "<", false, "\"", "\"", true).Trim_n(); - return (GetValue(sName, true).ToLong() < sValue.ToLong()); - } else { - sName = sExpr.Trim_n(); - } + if (sExpr.Contains("!=")) { + sName = sExpr.Token(0, false, "!=").Trim_n(); + sValue = sExpr.Token(1, true, "!=", false, "\"", "\"", true).Trim_n(); + bNegate = !bNegate; + } else if (sExpr.Contains("==")) { + sName = sExpr.Token(0, false, "==").Trim_n(); + sValue = sExpr.Token(1, true, "==", false, "\"", "\"", true).Trim_n(); + } else if (sExpr.Contains(">=")) { + sName = sExpr.Token(0, false, ">=").Trim_n(); + sValue = sExpr.Token(1, true, ">=", false, "\"", "\"", true).Trim_n(); + return (GetValue(sName, true).ToLong() >= sValue.ToLong()); + } else if (sExpr.Contains("<=")) { + sName = sExpr.Token(0, false, "<=").Trim_n(); + sValue = sExpr.Token(1, true, "<=", false, "\"", "\"", true).Trim_n(); + return (GetValue(sName, true).ToLong() <= sValue.ToLong()); + } else if (sExpr.Contains(">")) { + sName = sExpr.Token(0, false, ">").Trim_n(); + sValue = sExpr.Token(1, true, ">", false, "\"", "\"", true).Trim_n(); + return (GetValue(sName, true).ToLong() > sValue.ToLong()); + } else if (sExpr.Contains("<")) { + sName = sExpr.Token(0, false, "<").Trim_n(); + sValue = sExpr.Token(1, true, "<", false, "\"", "\"", true).Trim_n(); + return (GetValue(sName, true).ToLong() < sValue.ToLong()); + } else { + sName = sExpr.Trim_n(); + } - if (sValue.empty()) { - return (bNegate != IsTrue(sName)); - } + if (sValue.empty()) { + return (bNegate != IsTrue(sName)); + } - sValue = ResolveLiteral(sValue); + sValue = ResolveLiteral(sValue); - return (bNegate != GetValue(sName, true).Equals(sValue)); + return (bNegate != GetValue(sName, true).Equals(sValue)); } bool CTemplate::IsTrue(const CString& sName) { - if (HasLoop(sName)) { - return true; - } + if (HasLoop(sName)) { + return true; + } - return GetValue(sName, true).ToBool(); + return GetValue(sName, true).ToBool(); } bool CTemplate::HasLoop(const CString& sName) { - return (GetLoop(sName) != nullptr); + return (GetLoop(sName) != nullptr); } CTemplate* CTemplate::GetParent(bool bRoot) { - if (!bRoot) { - return m_pParent; - } + if (!bRoot) { + return m_pParent; + } - return (m_pParent) ? m_pParent->GetParent(bRoot) : this; + return (m_pParent) ? m_pParent->GetParent(bRoot) : this; } CTemplate* CTemplate::GetCurTemplate() { - CTemplateLoopContext* pContext = GetCurLoopContext(); + CTemplateLoopContext* pContext = GetCurLoopContext(); - if (!pContext) { - return this; - } + if (!pContext) { + return this; + } - return pContext->GetCurRow(); + return pContext->GetCurRow(); } CString CTemplate::ResolveLiteral(const CString& sString) { - if (sString.StartsWith("**")) { - // Allow string to start with a literal * by using two in a row - return sString.substr(1); - } else if (sString.StartsWith("*")) { - // If it starts with only one * then treat it as a var and do a lookup - return GetValue(sString.substr(1)); - } + if (sString.StartsWith("**")) { + // Allow string to start with a literal * by using two in a row + return sString.substr(1); + } else if (sString.StartsWith("*")) { + // If it starts with only one * then treat it as a var and do a lookup + return GetValue(sString.substr(1)); + } - return sString; + return sString; } CString CTemplate::GetValue(const CString& sArgs, bool bFromIf) { - CTemplateLoopContext* pContext = GetCurLoopContext(); - CString sName = sArgs.Token(0); - CString sRest = sArgs.Token(1, true); - CString sRet; + CTemplateLoopContext* pContext = GetCurLoopContext(); + CString sName = sArgs.Token(0); + CString sRest = sArgs.Token(1, true); + CString sRet; - while (sRest.Replace(" =", "=", "\"", "\"")) { - } - while (sRest.Replace("= ", "=", "\"", "\"")) { - } + while (sRest.Replace(" =", "=", "\"", "\"")) { + } + while (sRest.Replace("= ", "=", "\"", "\"")) { + } - VCString vArgs; - MCString msArgs; - // sRest.Split(" ", vArgs, false, "\"", "\""); - sRest.QuoteSplit(vArgs); + VCString vArgs; + MCString msArgs; + // sRest.Split(" ", vArgs, false, "\"", "\""); + sRest.QuoteSplit(vArgs); - for (const CString& sArg : vArgs) { - msArgs[sArg.Token(0, false, "=").AsUpper()] = sArg.Token(1, true, "="); - } + for (const CString& sArg : vArgs) { + msArgs[sArg.Token(0, false, "=").AsUpper()] = sArg.Token(1, true, "="); + } - /* We have no CConfig in ZNC land + /* We have no CConfig in ZNC land * Hmm... Actually, we do have it now. if (msArgs.find("CONFIG") != msArgs.end()) { sRet = CConfig::GetValue(sName); } else*/ if (msArgs.find("ROWS") != msArgs.end()) { - vector* pLoop = GetLoop(sName); - sRet = CString((pLoop) ? pLoop->size() : 0); - } else if (msArgs.find("TOP") == msArgs.end() && pContext) { - sRet = pContext->GetValue(sArgs, bFromIf); + vector* pLoop = GetLoop(sName); + sRet = CString((pLoop) ? pLoop->size() : 0); + } else if (msArgs.find("TOP") == msArgs.end() && pContext) { + sRet = pContext->GetValue(sArgs, bFromIf); - if (!sRet.empty()) { - return sRet; - } - } else { - if (sName.TrimPrefix("*")) { - MCString::iterator it = find(sName); - sName = (it != end()) ? it->second : ""; - } + if (!sRet.empty()) { + return sRet; + } + } else { + if (sName.TrimPrefix("*")) { + MCString::iterator it = find(sName); + sName = (it != end()) ? it->second : ""; + } - MCString::iterator it = find(sName); - sRet = (it != end()) ? it->second : ""; - } + MCString::iterator it = find(sName); + sRet = (it != end()) ? it->second : ""; + } - vector>& vspTagHandlers = - GetTagHandlers(); + vector>& vspTagHandlers = + GetTagHandlers(); - if (!vspTagHandlers - .empty()) { // @todo this should go up to the top to grab handlers - CTemplate* pTmpl = GetCurTemplate(); + if (!vspTagHandlers + .empty()) { // @todo this should go up to the top to grab handlers + CTemplate* pTmpl = GetCurTemplate(); - if (sRet.empty()) { - for (const auto& spTagHandler : vspTagHandlers) { - CString sCustomOutput; + if (sRet.empty()) { + for (const auto& spTagHandler : vspTagHandlers) { + CString sCustomOutput; - if (!bFromIf && - spTagHandler->HandleVar(*pTmpl, sArgs.Token(0), - sArgs.Token(1, true), - sCustomOutput)) { - sRet = sCustomOutput; - break; - } else if (bFromIf && - spTagHandler->HandleIf(*pTmpl, sArgs.Token(0), - sArgs.Token(1, true), - sCustomOutput)) { - sRet = sCustomOutput; - break; - } - } - } + if (!bFromIf && + spTagHandler->HandleVar(*pTmpl, sArgs.Token(0), + sArgs.Token(1, true), + sCustomOutput)) { + sRet = sCustomOutput; + break; + } else if (bFromIf && + spTagHandler->HandleIf(*pTmpl, sArgs.Token(0), + sArgs.Token(1, true), + sCustomOutput)) { + sRet = sCustomOutput; + break; + } + } + } - for (const auto& spTagHandler : vspTagHandlers) { - if (spTagHandler->HandleValue(*pTmpl, sRet, msArgs)) { - break; - } - } - } + for (const auto& spTagHandler : vspTagHandlers) { + if (spTagHandler->HandleValue(*pTmpl, sRet, msArgs)) { + break; + } + } + } - if (!bFromIf) { - if (sRet.empty()) { - sRet = ResolveLiteral(msArgs["DEFAULT"]); - } + if (!bFromIf) { + if (sRet.empty()) { + sRet = ResolveLiteral(msArgs["DEFAULT"]); + } - MCString::iterator it = msArgs.find("ESC"); + MCString::iterator it = msArgs.find("ESC"); - if (it != msArgs.end()) { - VCString vsEscs; - it->second.Split(",", vsEscs, false); + if (it != msArgs.end()) { + VCString vsEscs; + it->second.Split(",", vsEscs, false); - for (const CString& sEsc : vsEscs) { - sRet.Escape(CString::ToEscape(sEsc)); - } - } else { - sRet.Escape(m_spOptions->GetEscapeFrom(), - m_spOptions->GetEscapeTo()); - } - } + for (const CString& sEsc : vsEscs) { + sRet.Escape(CString::ToEscape(sEsc)); + } + } else { + sRet.Escape(m_spOptions->GetEscapeFrom(), + m_spOptions->GetEscapeTo()); + } + } - return sRet; + return sRet; } diff --git a/src/Threads.cpp b/src/Threads.cpp index 677e03e5..a7c3b076 100644 --- a/src/Threads.cpp +++ b/src/Threads.cpp @@ -29,10 +29,10 @@ static const size_t MAX_IDLE_THREADS = 3; static const size_t MAX_TOTAL_THREADS = 20; CThreadPool& CThreadPool::Get() { - // Beware! The following is not thread-safe! This function must - // be called once any thread is started. - static CThreadPool pool; - return pool; + // Beware! The following is not thread-safe! This function must + // be called once any thread is started. + static CThreadPool pool; + return pool; } CThreadPool::CThreadPool() @@ -45,232 +45,232 @@ CThreadPool::CThreadPool() m_num_idle(0), m_iJobPipe{0, 0}, m_jobs() { - if (pipe(m_iJobPipe)) { - DEBUG("Ouch, can't open pipe for thread pool: " << strerror(errno)); - exit(1); - } + if (pipe(m_iJobPipe)) { + DEBUG("Ouch, can't open pipe for thread pool: " << strerror(errno)); + exit(1); + } } void CThreadPool::jobDone(CJob* job) { - // This must be called with the mutex locked! + // This must be called with the mutex locked! - enum CJob::EJobState oldState = job->m_eState; - job->m_eState = CJob::DONE; + enum CJob::EJobState oldState = job->m_eState; + job->m_eState = CJob::DONE; - if (oldState == CJob::CANCELLED) { - // Signal the main thread that cancellation is done - m_cancellationCond.notify_one(); - return; - } + if (oldState == CJob::CANCELLED) { + // Signal the main thread that cancellation is done + m_cancellationCond.notify_one(); + return; + } - // This write() must succeed because POSIX guarantees that writes of - // less than PIPE_BUF are atomic (and PIPE_BUF is at least 512). - // (Yes, this really wants to write a pointer(!) to the pipe. - size_t w = write(m_iJobPipe[1], &job, sizeof(job)); - if (w != sizeof(job)) { - DEBUG( - "Something bad happened during write() to a pipe for thread pool, " - "wrote " - << w << " bytes: " << strerror(errno)); - exit(1); - } + // This write() must succeed because POSIX guarantees that writes of + // less than PIPE_BUF are atomic (and PIPE_BUF is at least 512). + // (Yes, this really wants to write a pointer(!) to the pipe. + size_t w = write(m_iJobPipe[1], &job, sizeof(job)); + if (w != sizeof(job)) { + DEBUG( + "Something bad happened during write() to a pipe for thread pool, " + "wrote " + << w << " bytes: " << strerror(errno)); + exit(1); + } } void CThreadPool::handlePipeReadable() const { finishJob(getJobFromPipe()); } CJob* CThreadPool::getJobFromPipe() const { - CJob* a = nullptr; - ssize_t need = sizeof(a); - ssize_t r = read(m_iJobPipe[0], &a, need); - if (r != need) { - DEBUG( - "Something bad happened during read() from a pipe for thread pool: " - << strerror(errno)); - exit(1); - } - return a; + CJob* a = nullptr; + ssize_t need = sizeof(a); + ssize_t r = read(m_iJobPipe[0], &a, need); + if (r != need) { + DEBUG( + "Something bad happened during read() from a pipe for thread pool: " + << strerror(errno)); + exit(1); + } + return a; } void CThreadPool::finishJob(CJob* job) const { - job->runMain(); - delete job; + job->runMain(); + delete job; } CThreadPool::~CThreadPool() { - CMutexLocker guard(m_mutex); - m_done = true; + CMutexLocker guard(m_mutex); + m_done = true; - while (m_num_threads > 0) { - m_cond.notify_all(); - m_exit_cond.wait(m_mutex); - } + while (m_num_threads > 0) { + m_cond.notify_all(); + m_exit_cond.wait(m_mutex); + } } bool CThreadPool::threadNeeded() const { - if (m_num_idle > MAX_IDLE_THREADS) return false; - return !m_done; + if (m_num_idle > MAX_IDLE_THREADS) return false; + return !m_done; } void CThreadPool::threadFunc() { - CMutexLocker guard(m_mutex); - // m_num_threads was already increased - m_num_idle++; + CMutexLocker guard(m_mutex); + // m_num_threads was already increased + m_num_idle++; - while (true) { - while (m_jobs.empty()) { - if (!threadNeeded()) break; - m_cond.wait(m_mutex); - } - if (!threadNeeded()) break; + while (true) { + while (m_jobs.empty()) { + if (!threadNeeded()) break; + m_cond.wait(m_mutex); + } + if (!threadNeeded()) break; - // Figure out a job to do - CJob* job = m_jobs.front(); - m_jobs.pop_front(); + // Figure out a job to do + CJob* job = m_jobs.front(); + m_jobs.pop_front(); - // Now do the actual job - m_num_idle--; - job->m_eState = CJob::RUNNING; - guard.unlock(); + // Now do the actual job + m_num_idle--; + job->m_eState = CJob::RUNNING; + guard.unlock(); - job->runThread(); + job->runThread(); - guard.lock(); - jobDone(job); - m_num_idle++; - } - assert(m_num_threads > 0 && m_num_idle > 0); - m_num_threads--; - m_num_idle--; + guard.lock(); + jobDone(job); + m_num_idle++; + } + assert(m_num_threads > 0 && m_num_idle > 0); + m_num_threads--; + m_num_idle--; - if (m_num_threads == 0 && m_done) m_exit_cond.notify_one(); + if (m_num_threads == 0 && m_done) m_exit_cond.notify_one(); } void CThreadPool::addJob(CJob* job) { - CMutexLocker guard(m_mutex); - m_jobs.push_back(job); + CMutexLocker guard(m_mutex); + m_jobs.push_back(job); - // Do we already have a thread which can handle this job? - if (m_num_idle > 0) { - m_cond.notify_one(); - return; - } + // Do we already have a thread which can handle this job? + if (m_num_idle > 0) { + m_cond.notify_one(); + return; + } - if (m_num_threads >= MAX_TOTAL_THREADS) - // We can't start a new thread. The job will be handled once - // some thread finishes its current job. - return; + if (m_num_threads >= MAX_TOTAL_THREADS) + // We can't start a new thread. The job will be handled once + // some thread finishes its current job. + return; - // Start a new thread for our pool - m_num_threads++; - std::thread([this]() { threadFunc(); }).detach(); + // Start a new thread for our pool + m_num_threads++; + std::thread([this]() { threadFunc(); }).detach(); } void CThreadPool::cancelJob(CJob* job) { - std::set jobs; - jobs.insert(job); - cancelJobs(jobs); + std::set jobs; + jobs.insert(job); + cancelJobs(jobs); } void CThreadPool::cancelJobs(const std::set& jobs) { - // Thanks to the mutex, jobs cannot change state anymore. There are - // three different states which can occur: - // - // READY: The job is still in our list of pending jobs and no threads - // got it yet. Just clean up. - // - // DONE: The job finished running and was already written to the pipe - // that is used for waking up finished jobs. We can just read from the - // pipe until we see this job. - // - // RUNNING: This is the complicated case. The job is currently being - // executed. We change its state to CANCELLED so that wasCancelled() - // returns true. Afterwards we wait on a CV for the job to have finished - // running. This CV is signaled by jobDone() which checks the job's - // status and sees that the job was cancelled. It signals to us that - // cancellation is done by changing the job's status to DONE. + // Thanks to the mutex, jobs cannot change state anymore. There are + // three different states which can occur: + // + // READY: The job is still in our list of pending jobs and no threads + // got it yet. Just clean up. + // + // DONE: The job finished running and was already written to the pipe + // that is used for waking up finished jobs. We can just read from the + // pipe until we see this job. + // + // RUNNING: This is the complicated case. The job is currently being + // executed. We change its state to CANCELLED so that wasCancelled() + // returns true. Afterwards we wait on a CV for the job to have finished + // running. This CV is signaled by jobDone() which checks the job's + // status and sees that the job was cancelled. It signals to us that + // cancellation is done by changing the job's status to DONE. - CMutexLocker guard(m_mutex); - std::set wait, finished, deleteLater; - std::set::const_iterator it; + CMutexLocker guard(m_mutex); + std::set wait, finished, deleteLater; + std::set::const_iterator it; - // Start cancelling all jobs - for (it = jobs.begin(); it != jobs.end(); ++it) { - switch ((*it)->m_eState) { - case CJob::READY: { - (*it)->m_eState = CJob::CANCELLED; + // Start cancelling all jobs + for (it = jobs.begin(); it != jobs.end(); ++it) { + switch ((*it)->m_eState) { + case CJob::READY: { + (*it)->m_eState = CJob::CANCELLED; - // Job wasn't started yet, must be in the queue - std::list::iterator it2 = - std::find(m_jobs.begin(), m_jobs.end(), *it); - assert(it2 != m_jobs.end()); - m_jobs.erase(it2); - deleteLater.insert(*it); - continue; - } + // Job wasn't started yet, must be in the queue + std::list::iterator it2 = + std::find(m_jobs.begin(), m_jobs.end(), *it); + assert(it2 != m_jobs.end()); + m_jobs.erase(it2); + deleteLater.insert(*it); + continue; + } - case CJob::RUNNING: - (*it)->m_eState = CJob::CANCELLED; - wait.insert(*it); - continue; + case CJob::RUNNING: + (*it)->m_eState = CJob::CANCELLED; + wait.insert(*it); + continue; - case CJob::DONE: - (*it)->m_eState = CJob::CANCELLED; - finished.insert(*it); - continue; + case CJob::DONE: + (*it)->m_eState = CJob::CANCELLED; + finished.insert(*it); + continue; - case CJob::CANCELLED: - default: - assert(0); - } - } + case CJob::CANCELLED: + default: + assert(0); + } + } - // Now wait for cancellation to be done + // Now wait for cancellation to be done - // Collect jobs that really were cancelled. Finished cancellation is - // signaled by changing their state to DONE. - while (!wait.empty()) { - it = wait.begin(); - while (it != wait.end()) { - if ((*it)->m_eState != CJob::CANCELLED) { - assert((*it)->m_eState == CJob::DONE); - // Re-set state for the destructor - (*it)->m_eState = CJob::CANCELLED; - deleteLater.insert(*it); - wait.erase(it++); - } else - it++; - } + // Collect jobs that really were cancelled. Finished cancellation is + // signaled by changing their state to DONE. + while (!wait.empty()) { + it = wait.begin(); + while (it != wait.end()) { + if ((*it)->m_eState != CJob::CANCELLED) { + assert((*it)->m_eState == CJob::DONE); + // Re-set state for the destructor + (*it)->m_eState = CJob::CANCELLED; + deleteLater.insert(*it); + wait.erase(it++); + } else + it++; + } - if (wait.empty()) break; + if (wait.empty()) break; - // Then wait for more to be done - m_cancellationCond.wait(m_mutex); - } + // Then wait for more to be done + m_cancellationCond.wait(m_mutex); + } - // We must call destructors with m_mutex unlocked so that they can call - // wasCancelled() - guard.unlock(); + // We must call destructors with m_mutex unlocked so that they can call + // wasCancelled() + guard.unlock(); - // Handle finished jobs. They must already be in the pipe. - while (!finished.empty()) { - CJob* job = getJobFromPipe(); - if (finished.erase(job) > 0) { - assert(job->m_eState == CJob::CANCELLED); - delete job; - } else - finishJob(job); - } + // Handle finished jobs. They must already be in the pipe. + while (!finished.empty()) { + CJob* job = getJobFromPipe(); + if (finished.erase(job) > 0) { + assert(job->m_eState == CJob::CANCELLED); + delete job; + } else + finishJob(job); + } - // Delete things that still need to be deleted - while (!deleteLater.empty()) { - delete *deleteLater.begin(); - deleteLater.erase(deleteLater.begin()); - } + // Delete things that still need to be deleted + while (!deleteLater.empty()) { + delete *deleteLater.begin(); + deleteLater.erase(deleteLater.begin()); + } } bool CJob::wasCancelled() const { - CMutexLocker guard(CThreadPool::Get().m_mutex); - return m_eState == CANCELLED; + CMutexLocker guard(CThreadPool::Get().m_mutex); + return m_eState == CANCELLED; } #endif // HAVE_PTHREAD diff --git a/src/User.cpp b/src/User.cpp index db7cb661..1a507ea9 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -30,29 +30,29 @@ using std::set; class CUserTimer : public CCron { public: - CUserTimer(CUser* pUser) : CCron(), m_pUser(pUser) { - SetName("CUserTimer::" + m_pUser->GetUserName()); - Start(CIRCNetwork::PING_SLACK); - } - virtual ~CUserTimer() {} + CUserTimer(CUser* pUser) : CCron(), m_pUser(pUser) { + SetName("CUserTimer::" + m_pUser->GetUserName()); + Start(CIRCNetwork::PING_SLACK); + } + virtual ~CUserTimer() {} - CUserTimer(const CUserTimer&) = delete; - CUserTimer& operator=(const CUserTimer&) = delete; + CUserTimer(const CUserTimer&) = delete; + CUserTimer& operator=(const CUserTimer&) = delete; private: protected: - void RunJob() override { - const vector& vUserClients = m_pUser->GetUserClients(); + void RunJob() override { + const vector& vUserClients = m_pUser->GetUserClients(); - for (CClient* pUserClient : vUserClients) { - if (pUserClient->GetTimeSinceLastDataTransaction() >= - CIRCNetwork::PING_FREQUENCY) { - pUserClient->PutClient("PING :ZNC"); - } - } - } + for (CClient* pUserClient : vUserClients) { + if (pUserClient->GetTimeSinceLastDataTransaction() >= + CIRCNetwork::PING_FREQUENCY) { + pUserClient->PutClient("PING :ZNC"); + } + } + } - CUser* m_pUser; + CUser* m_pUser; }; CUser::CUser(const CString& sUserName) @@ -98,764 +98,764 @@ CUser::CUser(const CString& sUserName) m_uMaxJoins(0), m_sSkinName(""), m_pModules(new CModules) { - m_pUserTimer = new CUserTimer(this); - CZNC::Get().GetManager().AddCron(m_pUserTimer); + m_pUserTimer = new CUserTimer(this); + CZNC::Get().GetManager().AddCron(m_pUserTimer); } CUser::~CUser() { - // Delete networks - while (!m_vIRCNetworks.empty()) { - delete *m_vIRCNetworks.begin(); - } + // Delete networks + while (!m_vIRCNetworks.empty()) { + delete *m_vIRCNetworks.begin(); + } - // Delete clients - while (!m_vClients.empty()) { - CZNC::Get().GetManager().DelSockByAddr(m_vClients[0]); - } - m_vClients.clear(); + // Delete clients + while (!m_vClients.empty()) { + CZNC::Get().GetManager().DelSockByAddr(m_vClients[0]); + } + m_vClients.clear(); - // Delete modules (unloads all modules!) - delete m_pModules; - m_pModules = nullptr; + // Delete modules (unloads all modules!) + delete m_pModules; + m_pModules = nullptr; - CZNC::Get().GetManager().DelCronByAddr(m_pUserTimer); + CZNC::Get().GetManager().DelCronByAddr(m_pUserTimer); - CZNC::Get().AddBytesRead(m_uBytesRead); - CZNC::Get().AddBytesWritten(m_uBytesWritten); + CZNC::Get().AddBytesRead(m_uBytesRead); + CZNC::Get().AddBytesWritten(m_uBytesWritten); } template struct TOption { - const char* name; - void (CUser::*pSetter)(T); + const char* name; + void (CUser::*pSetter)(T); }; bool CUser::ParseConfig(CConfig* pConfig, CString& sError) { - TOption StringOptions[] = { - {"nick", &CUser::SetNick}, - {"quitmsg", &CUser::SetQuitMsg}, - {"altnick", &CUser::SetAltNick}, - {"ident", &CUser::SetIdent}, - {"realname", &CUser::SetRealName}, - {"chanmodes", &CUser::SetDefaultChanModes}, - {"bindhost", &CUser::SetBindHost}, - {"vhost", &CUser::SetBindHost}, - {"dccbindhost", &CUser::SetDCCBindHost}, - {"dccvhost", &CUser::SetDCCBindHost}, - {"timestampformat", &CUser::SetTimestampFormat}, - {"skin", &CUser::SetSkinName}, - {"clientencoding", &CUser::SetClientEncoding}, - }; - TOption UIntOptions[] = { - {"jointries", &CUser::SetJoinTries}, - {"maxnetworks", &CUser::SetMaxNetworks}, - {"maxquerybuffers", &CUser::SetMaxQueryBuffers}, - {"maxjoins", &CUser::SetMaxJoins}, - }; - TOption BoolOptions[] = { - {"keepbuffer", - &CUser::SetKeepBuffer}, // XXX compatibility crap from pre-0.207 - {"autoclearchanbuffer", &CUser::SetAutoClearChanBuffer}, - {"autoclearquerybuffer", &CUser::SetAutoClearQueryBuffer}, - {"multiclients", &CUser::SetMultiClients}, - {"denyloadmod", &CUser::SetDenyLoadMod}, - {"admin", &CUser::SetAdmin}, - {"denysetbindhost", &CUser::SetDenySetBindHost}, - {"denysetvhost", &CUser::SetDenySetBindHost}, - {"appendtimestamp", &CUser::SetTimestampAppend}, - {"prependtimestamp", &CUser::SetTimestampPrepend}, - }; + TOption StringOptions[] = { + {"nick", &CUser::SetNick}, + {"quitmsg", &CUser::SetQuitMsg}, + {"altnick", &CUser::SetAltNick}, + {"ident", &CUser::SetIdent}, + {"realname", &CUser::SetRealName}, + {"chanmodes", &CUser::SetDefaultChanModes}, + {"bindhost", &CUser::SetBindHost}, + {"vhost", &CUser::SetBindHost}, + {"dccbindhost", &CUser::SetDCCBindHost}, + {"dccvhost", &CUser::SetDCCBindHost}, + {"timestampformat", &CUser::SetTimestampFormat}, + {"skin", &CUser::SetSkinName}, + {"clientencoding", &CUser::SetClientEncoding}, + }; + TOption UIntOptions[] = { + {"jointries", &CUser::SetJoinTries}, + {"maxnetworks", &CUser::SetMaxNetworks}, + {"maxquerybuffers", &CUser::SetMaxQueryBuffers}, + {"maxjoins", &CUser::SetMaxJoins}, + }; + TOption BoolOptions[] = { + {"keepbuffer", + &CUser::SetKeepBuffer}, // XXX compatibility crap from pre-0.207 + {"autoclearchanbuffer", &CUser::SetAutoClearChanBuffer}, + {"autoclearquerybuffer", &CUser::SetAutoClearQueryBuffer}, + {"multiclients", &CUser::SetMultiClients}, + {"denyloadmod", &CUser::SetDenyLoadMod}, + {"admin", &CUser::SetAdmin}, + {"denysetbindhost", &CUser::SetDenySetBindHost}, + {"denysetvhost", &CUser::SetDenySetBindHost}, + {"appendtimestamp", &CUser::SetTimestampAppend}, + {"prependtimestamp", &CUser::SetTimestampPrepend}, + }; - for (const auto& Option : StringOptions) { - CString sValue; - if (pConfig->FindStringEntry(Option.name, sValue)) - (this->*Option.pSetter)(sValue); - } - for (const auto& Option : UIntOptions) { - CString sValue; - if (pConfig->FindStringEntry(Option.name, sValue)) - (this->*Option.pSetter)(sValue.ToUInt()); - } - for (const auto& Option : BoolOptions) { - CString sValue; - if (pConfig->FindStringEntry(Option.name, sValue)) - (this->*Option.pSetter)(sValue.ToBool()); - } + for (const auto& Option : StringOptions) { + CString sValue; + if (pConfig->FindStringEntry(Option.name, sValue)) + (this->*Option.pSetter)(sValue); + } + for (const auto& Option : UIntOptions) { + CString sValue; + if (pConfig->FindStringEntry(Option.name, sValue)) + (this->*Option.pSetter)(sValue.ToUInt()); + } + for (const auto& Option : BoolOptions) { + CString sValue; + if (pConfig->FindStringEntry(Option.name, sValue)) + (this->*Option.pSetter)(sValue.ToBool()); + } - VCString vsList; - pConfig->FindStringVector("allow", vsList); - for (const CString& sHost : vsList) { - AddAllowedHost(sHost); - } - pConfig->FindStringVector("ctcpreply", vsList); - for (const CString& sReply : vsList) { - AddCTCPReply(sReply.Token(0), sReply.Token(1, true)); - } + VCString vsList; + pConfig->FindStringVector("allow", vsList); + for (const CString& sHost : vsList) { + AddAllowedHost(sHost); + } + pConfig->FindStringVector("ctcpreply", vsList); + for (const CString& sReply : vsList) { + AddCTCPReply(sReply.Token(0), sReply.Token(1, true)); + } - CString sValue; + CString sValue; - CString sDCCLookupValue; - pConfig->FindStringEntry("dcclookupmethod", sDCCLookupValue); - if (pConfig->FindStringEntry("bouncedccs", sValue)) { - if (sValue.ToBool()) { - CUtils::PrintAction("Loading Module [bouncedcc]"); - CString sModRet; - bool bModRet = GetModules().LoadModule( - "bouncedcc", "", CModInfo::UserModule, this, nullptr, sModRet); + CString sDCCLookupValue; + pConfig->FindStringEntry("dcclookupmethod", sDCCLookupValue); + if (pConfig->FindStringEntry("bouncedccs", sValue)) { + if (sValue.ToBool()) { + CUtils::PrintAction("Loading Module [bouncedcc]"); + CString sModRet; + bool bModRet = GetModules().LoadModule( + "bouncedcc", "", CModInfo::UserModule, this, nullptr, sModRet); - CUtils::PrintStatus(bModRet, sModRet); - if (!bModRet) { - sError = sModRet; - return false; - } + CUtils::PrintStatus(bModRet, sModRet); + if (!bModRet) { + sError = sModRet; + return false; + } - if (sDCCLookupValue.Equals("Client")) { - GetModules().FindModule("bouncedcc")->SetNV("UseClientIP", "1"); - } - } - } - if (pConfig->FindStringEntry("buffer", sValue)) - SetBufferCount(sValue.ToUInt(), true); - if (pConfig->FindStringEntry("chanbuffersize", sValue)) - SetChanBufferSize(sValue.ToUInt(), true); - if (pConfig->FindStringEntry("querybuffersize", sValue)) - SetQueryBufferSize(sValue.ToUInt(), true); - if (pConfig->FindStringEntry("awaysuffix", sValue)) { - CUtils::PrintMessage( - "WARNING: AwaySuffix has been deprecated, instead try -> " - "LoadModule = awaynick %nick%_" + - sValue); - } - if (pConfig->FindStringEntry("autocycle", sValue)) { - if (sValue.Equals("true")) - CUtils::PrintError( - "WARNING: AutoCycle has been removed, instead try -> " - "LoadModule = autocycle"); - } - if (pConfig->FindStringEntry("keepnick", sValue)) { - if (sValue.Equals("true")) - CUtils::PrintError( - "WARNING: KeepNick has been deprecated, instead try -> " - "LoadModule = keepnick"); - } - if (pConfig->FindStringEntry("statusprefix", sValue)) { - if (!SetStatusPrefix(sValue)) { - sError = "Invalid StatusPrefix [" + sValue + - "] Must be 1-5 chars, no spaces."; - CUtils::PrintError(sError); - return false; - } - } - if (pConfig->FindStringEntry("timezone", sValue)) { - SetTimezone(sValue); - } - if (pConfig->FindStringEntry("timezoneoffset", sValue)) { - if (fabs(sValue.ToDouble()) > 0.1) { - CUtils::PrintError( - "WARNING: TimezoneOffset has been deprecated, now you can set " - "your timezone by name"); - } - } - if (pConfig->FindStringEntry("timestamp", sValue)) { - if (!sValue.Trim_n().Equals("true")) { - if (sValue.Trim_n().Equals("append")) { - SetTimestampAppend(true); - SetTimestampPrepend(false); - } else if (sValue.Trim_n().Equals("prepend")) { - SetTimestampAppend(false); - SetTimestampPrepend(true); - } else if (sValue.Trim_n().Equals("false")) { - SetTimestampAppend(false); - SetTimestampPrepend(false); - } else { - SetTimestampFormat(sValue); - } - } - } - pConfig->FindStringEntry("pass", sValue); - // There are different formats for this available: - // Pass = - // Pass = - - // Pass = plain# - // Pass = # - // Pass = ### - // 'Salted hash' means hash of 'password' + 'salt' - // Possible hashes are md5 and sha256 - if (sValue.TrimSuffix("-")) { - SetPass(sValue.Trim_n(), CUser::HASH_MD5); - } else { - CString sMethod = sValue.Token(0, false, "#"); - CString sPass = sValue.Token(1, true, "#"); - if (sMethod == "md5" || sMethod == "sha256") { - CUser::eHashType type = CUser::HASH_MD5; - if (sMethod == "sha256") type = CUser::HASH_SHA256; + if (sDCCLookupValue.Equals("Client")) { + GetModules().FindModule("bouncedcc")->SetNV("UseClientIP", "1"); + } + } + } + if (pConfig->FindStringEntry("buffer", sValue)) + SetBufferCount(sValue.ToUInt(), true); + if (pConfig->FindStringEntry("chanbuffersize", sValue)) + SetChanBufferSize(sValue.ToUInt(), true); + if (pConfig->FindStringEntry("querybuffersize", sValue)) + SetQueryBufferSize(sValue.ToUInt(), true); + if (pConfig->FindStringEntry("awaysuffix", sValue)) { + CUtils::PrintMessage( + "WARNING: AwaySuffix has been deprecated, instead try -> " + "LoadModule = awaynick %nick%_" + + sValue); + } + if (pConfig->FindStringEntry("autocycle", sValue)) { + if (sValue.Equals("true")) + CUtils::PrintError( + "WARNING: AutoCycle has been removed, instead try -> " + "LoadModule = autocycle"); + } + if (pConfig->FindStringEntry("keepnick", sValue)) { + if (sValue.Equals("true")) + CUtils::PrintError( + "WARNING: KeepNick has been deprecated, instead try -> " + "LoadModule = keepnick"); + } + if (pConfig->FindStringEntry("statusprefix", sValue)) { + if (!SetStatusPrefix(sValue)) { + sError = "Invalid StatusPrefix [" + sValue + + "] Must be 1-5 chars, no spaces."; + CUtils::PrintError(sError); + return false; + } + } + if (pConfig->FindStringEntry("timezone", sValue)) { + SetTimezone(sValue); + } + if (pConfig->FindStringEntry("timezoneoffset", sValue)) { + if (fabs(sValue.ToDouble()) > 0.1) { + CUtils::PrintError( + "WARNING: TimezoneOffset has been deprecated, now you can set " + "your timezone by name"); + } + } + if (pConfig->FindStringEntry("timestamp", sValue)) { + if (!sValue.Trim_n().Equals("true")) { + if (sValue.Trim_n().Equals("append")) { + SetTimestampAppend(true); + SetTimestampPrepend(false); + } else if (sValue.Trim_n().Equals("prepend")) { + SetTimestampAppend(false); + SetTimestampPrepend(true); + } else if (sValue.Trim_n().Equals("false")) { + SetTimestampAppend(false); + SetTimestampPrepend(false); + } else { + SetTimestampFormat(sValue); + } + } + } + pConfig->FindStringEntry("pass", sValue); + // There are different formats for this available: + // Pass = + // Pass = - + // Pass = plain# + // Pass = # + // Pass = ### + // 'Salted hash' means hash of 'password' + 'salt' + // Possible hashes are md5 and sha256 + if (sValue.TrimSuffix("-")) { + SetPass(sValue.Trim_n(), CUser::HASH_MD5); + } else { + CString sMethod = sValue.Token(0, false, "#"); + CString sPass = sValue.Token(1, true, "#"); + if (sMethod == "md5" || sMethod == "sha256") { + CUser::eHashType type = CUser::HASH_MD5; + if (sMethod == "sha256") type = CUser::HASH_SHA256; - CString sSalt = sPass.Token(1, false, "#"); - sPass = sPass.Token(0, false, "#"); - SetPass(sPass, type, sSalt); - } else if (sMethod == "plain") { - SetPass(sPass, CUser::HASH_NONE); - } else { - SetPass(sValue, CUser::HASH_NONE); - } - } - CConfig::SubConfig subConf; - CConfig::SubConfig::const_iterator subIt; - pConfig->FindSubConfig("pass", subConf); - if (!sValue.empty() && !subConf.empty()) { - sError = "Password defined more than once"; - CUtils::PrintError(sError); - return false; - } - subIt = subConf.begin(); - if (subIt != subConf.end()) { - CConfig* pSubConf = subIt->second.m_pSubConfig; - CString sHash; - CString sMethod; - CString sSalt; - CUser::eHashType method; - pSubConf->FindStringEntry("hash", sHash); - pSubConf->FindStringEntry("method", sMethod); - pSubConf->FindStringEntry("salt", sSalt); - if (sMethod.empty() || sMethod.Equals("plain")) - method = CUser::HASH_NONE; - else if (sMethod.Equals("md5")) - method = CUser::HASH_MD5; - else if (sMethod.Equals("sha256")) - method = CUser::HASH_SHA256; - else { - sError = "Invalid hash method"; - CUtils::PrintError(sError); - return false; - } + CString sSalt = sPass.Token(1, false, "#"); + sPass = sPass.Token(0, false, "#"); + SetPass(sPass, type, sSalt); + } else if (sMethod == "plain") { + SetPass(sPass, CUser::HASH_NONE); + } else { + SetPass(sValue, CUser::HASH_NONE); + } + } + CConfig::SubConfig subConf; + CConfig::SubConfig::const_iterator subIt; + pConfig->FindSubConfig("pass", subConf); + if (!sValue.empty() && !subConf.empty()) { + sError = "Password defined more than once"; + CUtils::PrintError(sError); + return false; + } + subIt = subConf.begin(); + if (subIt != subConf.end()) { + CConfig* pSubConf = subIt->second.m_pSubConfig; + CString sHash; + CString sMethod; + CString sSalt; + CUser::eHashType method; + pSubConf->FindStringEntry("hash", sHash); + pSubConf->FindStringEntry("method", sMethod); + pSubConf->FindStringEntry("salt", sSalt); + if (sMethod.empty() || sMethod.Equals("plain")) + method = CUser::HASH_NONE; + else if (sMethod.Equals("md5")) + method = CUser::HASH_MD5; + else if (sMethod.Equals("sha256")) + method = CUser::HASH_SHA256; + else { + sError = "Invalid hash method"; + CUtils::PrintError(sError); + return false; + } - SetPass(sHash, method, sSalt); - if (!pSubConf->empty()) { - sError = "Unhandled lines in config!"; - CUtils::PrintError(sError); + SetPass(sHash, method, sSalt); + if (!pSubConf->empty()) { + sError = "Unhandled lines in config!"; + CUtils::PrintError(sError); - CZNC::DumpConfig(pSubConf); - return false; - } - ++subIt; - } - if (subIt != subConf.end()) { - sError = "Password defined more than once"; - CUtils::PrintError(sError); - return false; - } + CZNC::DumpConfig(pSubConf); + return false; + } + ++subIt; + } + if (subIt != subConf.end()) { + sError = "Password defined more than once"; + CUtils::PrintError(sError); + return false; + } - pConfig->FindSubConfig("network", subConf); - for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) { - const CString& sNetworkName = subIt->first; + pConfig->FindSubConfig("network", subConf); + for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) { + const CString& sNetworkName = subIt->first; - CUtils::PrintMessage("Loading network [" + sNetworkName + "]"); + CUtils::PrintMessage("Loading network [" + sNetworkName + "]"); - CIRCNetwork* pNetwork = FindNetwork(sNetworkName); + CIRCNetwork* pNetwork = FindNetwork(sNetworkName); - if (!pNetwork) { - pNetwork = new CIRCNetwork(this, sNetworkName); - } + if (!pNetwork) { + pNetwork = new CIRCNetwork(this, sNetworkName); + } - if (!pNetwork->ParseConfig(subIt->second.m_pSubConfig, sError)) { - return false; - } - } + if (!pNetwork->ParseConfig(subIt->second.m_pSubConfig, sError)) { + return false; + } + } - if (pConfig->FindStringVector("server", vsList, false) || - pConfig->FindStringVector("chan", vsList, false) || - pConfig->FindSubConfig("chan", subConf, false)) { - CIRCNetwork* pNetwork = FindNetwork("default"); - if (!pNetwork) { - CString sErrorDummy; - pNetwork = AddNetwork("default", sErrorDummy); - } + if (pConfig->FindStringVector("server", vsList, false) || + pConfig->FindStringVector("chan", vsList, false) || + pConfig->FindSubConfig("chan", subConf, false)) { + CIRCNetwork* pNetwork = FindNetwork("default"); + if (!pNetwork) { + CString sErrorDummy; + pNetwork = AddNetwork("default", sErrorDummy); + } - if (pNetwork) { - CUtils::PrintMessage( - "NOTICE: Found deprecated config, upgrading to a network"); + if (pNetwork) { + CUtils::PrintMessage( + "NOTICE: Found deprecated config, upgrading to a network"); - if (!pNetwork->ParseConfig(pConfig, sError, true)) { - return false; - } - } - } + if (!pNetwork->ParseConfig(pConfig, sError, true)) { + return false; + } + } + } - pConfig->FindStringVector("loadmodule", vsList); - for (const CString& sMod : vsList) { - CString sModName = sMod.Token(0); - CString sNotice = "Loading user module [" + sModName + "]"; + pConfig->FindStringVector("loadmodule", vsList); + for (const CString& sMod : vsList) { + CString sModName = sMod.Token(0); + CString sNotice = "Loading user module [" + sModName + "]"; - // XXX Legacy crap, added in ZNC 0.089 - if (sModName == "discon_kick") { - sNotice = - "NOTICE: [discon_kick] was renamed, loading [disconkick] " - "instead"; - sModName = "disconkick"; - } + // XXX Legacy crap, added in ZNC 0.089 + if (sModName == "discon_kick") { + sNotice = + "NOTICE: [discon_kick] was renamed, loading [disconkick] " + "instead"; + sModName = "disconkick"; + } - // XXX Legacy crap, added in ZNC 0.099 - if (sModName == "fixfreenode") { - sNotice = - "NOTICE: [fixfreenode] doesn't do anything useful anymore, " - "ignoring it"; - CUtils::PrintMessage(sNotice); - continue; - } + // XXX Legacy crap, added in ZNC 0.099 + if (sModName == "fixfreenode") { + sNotice = + "NOTICE: [fixfreenode] doesn't do anything useful anymore, " + "ignoring it"; + CUtils::PrintMessage(sNotice); + continue; + } - // XXX Legacy crap, added in ZNC 0.207 - if (sModName == "admin") { - sNotice = - "NOTICE: [admin] module was renamed, loading [controlpanel] " - "instead"; - sModName = "controlpanel"; - } + // XXX Legacy crap, added in ZNC 0.207 + if (sModName == "admin") { + sNotice = + "NOTICE: [admin] module was renamed, loading [controlpanel] " + "instead"; + sModName = "controlpanel"; + } - // XXX Legacy crap, should have been added ZNC 0.207, but added only in - // 1.1 :( - if (sModName == "away") { - sNotice = "NOTICE: [away] was renamed, loading [awaystore] instead"; - sModName = "awaystore"; - } + // XXX Legacy crap, should have been added ZNC 0.207, but added only in + // 1.1 :( + if (sModName == "away") { + sNotice = "NOTICE: [away] was renamed, loading [awaystore] instead"; + sModName = "awaystore"; + } - // XXX Legacy crap, added in 1.1; fakeonline module was dropped in 1.0 - // and returned in 1.1 - if (sModName == "fakeonline") { - sNotice = - "NOTICE: [fakeonline] was renamed, loading [modules_online] " - "instead"; - sModName = "modules_online"; - } + // XXX Legacy crap, added in 1.1; fakeonline module was dropped in 1.0 + // and returned in 1.1 + if (sModName == "fakeonline") { + sNotice = + "NOTICE: [fakeonline] was renamed, loading [modules_online] " + "instead"; + sModName = "modules_online"; + } - // XXX Legacy crap, added in 1.3 - if (sModName == "charset") { - CUtils::PrintAction( - "NOTICE: Charset support was moved to core, importing old " - "charset module settings"); - size_t uIndex = 1; - if (sMod.Token(uIndex).Equals("-force")) { - uIndex++; - } - VCString vsClient, vsServer; - sMod.Token(uIndex).Split(",", vsClient); - sMod.Token(uIndex + 1).Split(",", vsServer); - if (vsClient.empty() || vsServer.empty()) { - CUtils::PrintStatus( - false, "charset module was loaded with wrong parameters."); - continue; - } - SetClientEncoding(vsClient[0]); - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - pNetwork->SetEncoding(vsServer[0]); - } - CUtils::PrintStatus(true, "Using [" + vsClient[0] + - "] for clients, and [" + vsServer[0] + - "] for servers"); - continue; - } + // XXX Legacy crap, added in 1.3 + if (sModName == "charset") { + CUtils::PrintAction( + "NOTICE: Charset support was moved to core, importing old " + "charset module settings"); + size_t uIndex = 1; + if (sMod.Token(uIndex).Equals("-force")) { + uIndex++; + } + VCString vsClient, vsServer; + sMod.Token(uIndex).Split(",", vsClient); + sMod.Token(uIndex + 1).Split(",", vsServer); + if (vsClient.empty() || vsServer.empty()) { + CUtils::PrintStatus( + false, "charset module was loaded with wrong parameters."); + continue; + } + SetClientEncoding(vsClient[0]); + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + pNetwork->SetEncoding(vsServer[0]); + } + CUtils::PrintStatus(true, "Using [" + vsClient[0] + + "] for clients, and [" + vsServer[0] + + "] for servers"); + continue; + } - // XXX Legacy crap, added in 1.7 - if (sModName == "disconkick") { - sNotice = - "NOTICE: [disconkick] is integrated to core now, ignoring it"; - CUtils::PrintMessage(sNotice); - continue; - } + // XXX Legacy crap, added in 1.7 + if (sModName == "disconkick") { + sNotice = + "NOTICE: [disconkick] is integrated to core now, ignoring it"; + CUtils::PrintMessage(sNotice); + continue; + } - CString sModRet; - CString sArgs = sMod.Token(1, true); + CString sModRet; + CString sArgs = sMod.Token(1, true); - bool bModRet = LoadModule(sModName, sArgs, sNotice, sModRet); + bool bModRet = LoadModule(sModName, sArgs, sNotice, sModRet); - CUtils::PrintStatus(bModRet, sModRet); - if (!bModRet) { - // XXX The awaynick module was retired in 1.6 (still available as - // external module) - if (sModName == "awaynick") { - // load simple_away instead, unless it's already on the list - if (std::find(vsList.begin(), vsList.end(), "simple_away") == - vsList.end()) { - sNotice = "Loading [simple_away] module instead"; - sModName = "simple_away"; - // not a fatal error if simple_away is not available - LoadModule(sModName, sArgs, sNotice, sModRet); - } - } else { - sError = sModRet; - return false; - } - } - continue; - } + CUtils::PrintStatus(bModRet, sModRet); + if (!bModRet) { + // XXX The awaynick module was retired in 1.6 (still available as + // external module) + if (sModName == "awaynick") { + // load simple_away instead, unless it's already on the list + if (std::find(vsList.begin(), vsList.end(), "simple_away") == + vsList.end()) { + sNotice = "Loading [simple_away] module instead"; + sModName = "simple_away"; + // not a fatal error if simple_away is not available + LoadModule(sModName, sArgs, sNotice, sModRet); + } + } else { + sError = sModRet; + return false; + } + } + continue; + } - // Move ircconnectenabled to the networks - if (pConfig->FindStringEntry("ircconnectenabled", sValue)) { - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - pNetwork->SetIRCConnectEnabled(sValue.ToBool()); - } - } + // Move ircconnectenabled to the networks + if (pConfig->FindStringEntry("ircconnectenabled", sValue)) { + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + pNetwork->SetIRCConnectEnabled(sValue.ToBool()); + } + } - return true; + return true; } CIRCNetwork* CUser::AddNetwork(const CString& sNetwork, CString& sErrorRet) { - if (!CIRCNetwork::IsValidNetwork(sNetwork)) { - sErrorRet = - "Invalid network name. It should be alphanumeric. Not to be " - "confused with server name"; - return nullptr; - } else if (FindNetwork(sNetwork)) { - sErrorRet = "Network [" + sNetwork.Token(0) + "] already exists"; - return nullptr; - } + if (!CIRCNetwork::IsValidNetwork(sNetwork)) { + sErrorRet = + "Invalid network name. It should be alphanumeric. Not to be " + "confused with server name"; + return nullptr; + } else if (FindNetwork(sNetwork)) { + sErrorRet = "Network [" + sNetwork.Token(0) + "] already exists"; + return nullptr; + } - CIRCNetwork* pNetwork = new CIRCNetwork(this, sNetwork); + CIRCNetwork* pNetwork = new CIRCNetwork(this, sNetwork); - bool bCancel = false; - USERMODULECALL(OnAddNetwork(*pNetwork, sErrorRet), this, nullptr, &bCancel); - if (bCancel) { - RemoveNetwork(pNetwork); - delete pNetwork; - return nullptr; - } + bool bCancel = false; + USERMODULECALL(OnAddNetwork(*pNetwork, sErrorRet), this, nullptr, &bCancel); + if (bCancel) { + RemoveNetwork(pNetwork); + delete pNetwork; + return nullptr; + } - return pNetwork; + return pNetwork; } bool CUser::AddNetwork(CIRCNetwork* pNetwork) { - if (FindNetwork(pNetwork->GetName())) { - return false; - } + if (FindNetwork(pNetwork->GetName())) { + return false; + } - m_vIRCNetworks.push_back(pNetwork); + m_vIRCNetworks.push_back(pNetwork); - return true; + return true; } void CUser::RemoveNetwork(CIRCNetwork* pNetwork) { - auto it = std::find(m_vIRCNetworks.begin(), m_vIRCNetworks.end(), pNetwork); - if (it != m_vIRCNetworks.end()) { - m_vIRCNetworks.erase(it); - } + auto it = std::find(m_vIRCNetworks.begin(), m_vIRCNetworks.end(), pNetwork); + if (it != m_vIRCNetworks.end()) { + m_vIRCNetworks.erase(it); + } } bool CUser::DeleteNetwork(const CString& sNetwork) { - CIRCNetwork* pNetwork = FindNetwork(sNetwork); + CIRCNetwork* pNetwork = FindNetwork(sNetwork); - if (pNetwork) { - bool bCancel = false; - USERMODULECALL(OnDeleteNetwork(*pNetwork), this, nullptr, &bCancel); - if (!bCancel) { - delete pNetwork; - return true; - } - } + if (pNetwork) { + bool bCancel = false; + USERMODULECALL(OnDeleteNetwork(*pNetwork), this, nullptr, &bCancel); + if (!bCancel) { + delete pNetwork; + return true; + } + } - return false; + return false; } CIRCNetwork* CUser::FindNetwork(const CString& sNetwork) const { - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - if (pNetwork->GetName().Equals(sNetwork)) { - return pNetwork; - } - } + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + if (pNetwork->GetName().Equals(sNetwork)) { + return pNetwork; + } + } - return nullptr; + return nullptr; } const vector& CUser::GetNetworks() const { - return m_vIRCNetworks; + return m_vIRCNetworks; } CString CUser::ExpandString(const CString& sStr) const { - CString sRet; - return ExpandString(sStr, sRet); + CString sRet; + return ExpandString(sStr, sRet); } CString& CUser::ExpandString(const CString& sStr, CString& sRet) const { - CString sTime = CUtils::CTime(time(nullptr), m_sTimezone); + CString sTime = CUtils::CTime(time(nullptr), m_sTimezone); - sRet = sStr; - sRet.Replace("%altnick%", GetAltNick()); - sRet.Replace("%bindhost%", GetBindHost()); - sRet.Replace("%defnick%", GetNick()); - sRet.Replace("%ident%", GetIdent()); - sRet.Replace("%nick%", GetNick()); - sRet.Replace("%realname%", GetRealName()); - sRet.Replace("%time%", sTime); - sRet.Replace("%uptime%", CZNC::Get().GetUptime()); - sRet.Replace("%user%", GetUserName()); - sRet.Replace("%version%", CZNC::GetVersion()); - sRet.Replace("%vhost%", GetBindHost()); + sRet = sStr; + sRet.Replace("%altnick%", GetAltNick()); + sRet.Replace("%bindhost%", GetBindHost()); + sRet.Replace("%defnick%", GetNick()); + sRet.Replace("%ident%", GetIdent()); + sRet.Replace("%nick%", GetNick()); + sRet.Replace("%realname%", GetRealName()); + sRet.Replace("%time%", sTime); + sRet.Replace("%uptime%", CZNC::Get().GetUptime()); + sRet.Replace("%user%", GetUserName()); + sRet.Replace("%version%", CZNC::GetVersion()); + sRet.Replace("%vhost%", GetBindHost()); - // Allows for escaping ExpandString if necessary, or to prevent - // defaults from kicking in if you don't want them. - sRet.Replace("%empty%", ""); - // The following lines do not exist. You must be on DrUgS! - sRet.Replace("%znc%", "All your IRC are belong to ZNC"); - // Chosen by fair zocchihedron dice roll by SilverLeo - sRet.Replace("%rand%", "42"); + // Allows for escaping ExpandString if necessary, or to prevent + // defaults from kicking in if you don't want them. + sRet.Replace("%empty%", ""); + // The following lines do not exist. You must be on DrUgS! + sRet.Replace("%znc%", "All your IRC are belong to ZNC"); + // Chosen by fair zocchihedron dice roll by SilverLeo + sRet.Replace("%rand%", "42"); - return sRet; + return sRet; } CString CUser::AddTimestamp(const CString& sStr) const { - time_t tm; - return AddTimestamp(time(&tm), sStr); + time_t tm; + return AddTimestamp(time(&tm), sStr); } CString CUser::AddTimestamp(time_t tm, const CString& sStr) const { - CString sRet = sStr; + CString sRet = sStr; - if (!GetTimestampFormat().empty() && - (m_bAppendTimestamp || m_bPrependTimestamp)) { - CString sTimestamp = - CUtils::FormatTime(tm, GetTimestampFormat(), m_sTimezone); - if (sTimestamp.empty()) { - return sRet; - } + if (!GetTimestampFormat().empty() && + (m_bAppendTimestamp || m_bPrependTimestamp)) { + CString sTimestamp = + CUtils::FormatTime(tm, GetTimestampFormat(), m_sTimezone); + if (sTimestamp.empty()) { + return sRet; + } - if (m_bPrependTimestamp) { - sRet = sTimestamp; - sRet += " " + sStr; - } - if (m_bAppendTimestamp) { - // From http://www.mirc.com/colors.html - // The Control+O key combination in mIRC inserts ascii character 15, - // which turns off all previous attributes, including color, bold, - // underline, and italics. - // - // \x02 bold - // \x03 mIRC-compatible color - // \x04 RRGGBB color - // \x0F normal/reset (turn off bold, colors, etc.) - // \x12 reverse (weechat) - // \x16 reverse (mirc, kvirc) - // \x1D italic - // \x1F underline - // Also see http://www.visualirc.net/tech-attrs.php - // - // Keep in sync with CIRCSocket::IcuExt__UCallback - if (CString::npos != - sRet.find_first_of("\x02\x03\x04\x0F\x12\x16\x1D\x1F")) { - sRet += "\x0F"; - } + if (m_bPrependTimestamp) { + sRet = sTimestamp; + sRet += " " + sStr; + } + if (m_bAppendTimestamp) { + // From http://www.mirc.com/colors.html + // The Control+O key combination in mIRC inserts ascii character 15, + // which turns off all previous attributes, including color, bold, + // underline, and italics. + // + // \x02 bold + // \x03 mIRC-compatible color + // \x04 RRGGBB color + // \x0F normal/reset (turn off bold, colors, etc.) + // \x12 reverse (weechat) + // \x16 reverse (mirc, kvirc) + // \x1D italic + // \x1F underline + // Also see http://www.visualirc.net/tech-attrs.php + // + // Keep in sync with CIRCSocket::IcuExt__UCallback + if (CString::npos != + sRet.find_first_of("\x02\x03\x04\x0F\x12\x16\x1D\x1F")) { + sRet += "\x0F"; + } - sRet += " " + sTimestamp; - } - } + sRet += " " + sTimestamp; + } + } - return sRet; + return sRet; } void CUser::BounceAllClients() { - for (CClient* pClient : m_vClients) { - pClient->BouncedOff(); - } + for (CClient* pClient : m_vClients) { + pClient->BouncedOff(); + } - m_vClients.clear(); + m_vClients.clear(); } void CUser::UserConnected(CClient* pClient) { - if (!MultiClients()) { - BounceAllClients(); - } + if (!MultiClients()) { + BounceAllClients(); + } - pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + - " :- Welcome to ZNC -"); + pClient->PutClient(":irc.znc.in 001 " + pClient->GetNick() + + " :- Welcome to ZNC -"); - m_vClients.push_back(pClient); + m_vClients.push_back(pClient); } void CUser::UserDisconnected(CClient* pClient) { - auto it = std::find(m_vClients.begin(), m_vClients.end(), pClient); - if (it != m_vClients.end()) { - m_vClients.erase(it); - } + auto it = std::find(m_vClients.begin(), m_vClients.end(), pClient); + if (it != m_vClients.end()) { + m_vClients.erase(it); + } } void CUser::CloneNetworks(const CUser& User) { - const vector& vNetworks = User.GetNetworks(); - for (CIRCNetwork* pUserNetwork : vNetworks) { - CIRCNetwork* pNetwork = FindNetwork(pUserNetwork->GetName()); + const vector& vNetworks = User.GetNetworks(); + for (CIRCNetwork* pUserNetwork : vNetworks) { + CIRCNetwork* pNetwork = FindNetwork(pUserNetwork->GetName()); - if (pNetwork) { - pNetwork->Clone(*pUserNetwork); - } else { - new CIRCNetwork(this, *pUserNetwork); - } - } + if (pNetwork) { + pNetwork->Clone(*pUserNetwork); + } else { + new CIRCNetwork(this, *pUserNetwork); + } + } - set ssDeleteNetworks; - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - if (!(User.FindNetwork(pNetwork->GetName()))) { - ssDeleteNetworks.insert(pNetwork->GetName()); - } - } + set ssDeleteNetworks; + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + if (!(User.FindNetwork(pNetwork->GetName()))) { + ssDeleteNetworks.insert(pNetwork->GetName()); + } + } - for (const CString& sNetwork : ssDeleteNetworks) { - // 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. - const vector& vClients = FindNetwork(sNetwork)->GetClients(); + for (const CString& sNetwork : ssDeleteNetworks) { + // 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. + const vector& vClients = FindNetwork(sNetwork)->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(nullptr); - } + 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(nullptr); + } - DeleteNetwork(sNetwork); - } + DeleteNetwork(sNetwork); + } } bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks) { - sErrorRet.clear(); + sErrorRet.clear(); - if (!User.IsValid(sErrorRet, true)) { - return false; - } + if (!User.IsValid(sErrorRet, true)) { + return false; + } - // user names can only specified for the constructor, changing it later - // on breaks too much stuff (e.g. lots of paths depend on the user name) - if (GetUserName() != User.GetUserName()) { - DEBUG("Ignoring username in CUser::Clone(), old username [" - << GetUserName() << "]; New username [" << User.GetUserName() - << "]"); - } + // user names can only specified for the constructor, changing it later + // on breaks too much stuff (e.g. lots of paths depend on the user name) + if (GetUserName() != User.GetUserName()) { + DEBUG("Ignoring username in CUser::Clone(), old username [" + << GetUserName() << "]; New username [" << User.GetUserName() + << "]"); + } - if (!User.GetPass().empty()) { - SetPass(User.GetPass(), User.GetPassHashType(), User.GetPassSalt()); - } + if (!User.GetPass().empty()) { + SetPass(User.GetPass(), User.GetPassHashType(), User.GetPassSalt()); + } - SetNick(User.GetNick(false)); - SetAltNick(User.GetAltNick(false)); - SetIdent(User.GetIdent(false)); - SetRealName(User.GetRealName()); - SetStatusPrefix(User.GetStatusPrefix()); - SetBindHost(User.GetBindHost()); - SetDCCBindHost(User.GetDCCBindHost()); - SetQuitMsg(User.GetQuitMsg()); - SetSkinName(User.GetSkinName()); - SetDefaultChanModes(User.GetDefaultChanModes()); - SetChanBufferSize(User.GetChanBufferSize(), true); - SetQueryBufferSize(User.GetQueryBufferSize(), true); - SetJoinTries(User.JoinTries()); - SetMaxNetworks(User.MaxNetworks()); - SetMaxQueryBuffers(User.MaxQueryBuffers()); - SetMaxJoins(User.MaxJoins()); - SetClientEncoding(User.GetClientEncoding()); + SetNick(User.GetNick(false)); + SetAltNick(User.GetAltNick(false)); + SetIdent(User.GetIdent(false)); + SetRealName(User.GetRealName()); + SetStatusPrefix(User.GetStatusPrefix()); + SetBindHost(User.GetBindHost()); + SetDCCBindHost(User.GetDCCBindHost()); + SetQuitMsg(User.GetQuitMsg()); + SetSkinName(User.GetSkinName()); + SetDefaultChanModes(User.GetDefaultChanModes()); + SetChanBufferSize(User.GetChanBufferSize(), true); + SetQueryBufferSize(User.GetQueryBufferSize(), true); + SetJoinTries(User.JoinTries()); + SetMaxNetworks(User.MaxNetworks()); + SetMaxQueryBuffers(User.MaxQueryBuffers()); + SetMaxJoins(User.MaxJoins()); + SetClientEncoding(User.GetClientEncoding()); - // Allowed Hosts - m_ssAllowedHosts.clear(); - const set& ssHosts = User.GetAllowedHosts(); - for (const CString& sHost : ssHosts) { - AddAllowedHost(sHost); - } + // Allowed Hosts + m_ssAllowedHosts.clear(); + const set& ssHosts = User.GetAllowedHosts(); + for (const CString& sHost : ssHosts) { + AddAllowedHost(sHost); + } - for (CClient* pSock : m_vClients) { - if (!IsHostAllowed(pSock->GetRemoteIP())) { - pSock->PutStatusNotice( - "You are being disconnected because your IP is no longer " - "allowed to connect to this user"); - pSock->Close(); - } - } + for (CClient* pSock : m_vClients) { + if (!IsHostAllowed(pSock->GetRemoteIP())) { + pSock->PutStatusNotice( + "You are being disconnected because your IP is no longer " + "allowed to connect to this user"); + pSock->Close(); + } + } - // !Allowed Hosts + // !Allowed Hosts - // Networks - if (bCloneNetworks) { - CloneNetworks(User); - } - // !Networks + // Networks + if (bCloneNetworks) { + CloneNetworks(User); + } + // !Networks - // CTCP Replies - m_mssCTCPReplies.clear(); - const MCString& msReplies = User.GetCTCPReplies(); - for (const auto& it : msReplies) { - AddCTCPReply(it.first, it.second); - } - // !CTCP Replies + // CTCP Replies + m_mssCTCPReplies.clear(); + const MCString& msReplies = User.GetCTCPReplies(); + for (const auto& it : msReplies) { + AddCTCPReply(it.first, it.second); + } + // !CTCP Replies - // Flags - SetAutoClearChanBuffer(User.AutoClearChanBuffer()); - SetAutoClearQueryBuffer(User.AutoClearQueryBuffer()); - SetMultiClients(User.MultiClients()); - SetDenyLoadMod(User.DenyLoadMod()); - SetAdmin(User.IsAdmin()); - SetDenySetBindHost(User.DenySetBindHost()); - SetTimestampAppend(User.GetTimestampAppend()); - SetTimestampPrepend(User.GetTimestampPrepend()); - SetTimestampFormat(User.GetTimestampFormat()); - SetTimezone(User.GetTimezone()); - // !Flags + // Flags + SetAutoClearChanBuffer(User.AutoClearChanBuffer()); + SetAutoClearQueryBuffer(User.AutoClearQueryBuffer()); + SetMultiClients(User.MultiClients()); + SetDenyLoadMod(User.DenyLoadMod()); + SetAdmin(User.IsAdmin()); + SetDenySetBindHost(User.DenySetBindHost()); + SetTimestampAppend(User.GetTimestampAppend()); + SetTimestampPrepend(User.GetTimestampPrepend()); + SetTimestampFormat(User.GetTimestampFormat()); + SetTimezone(User.GetTimezone()); + // !Flags - // Modules - set ssUnloadMods; - CModules& vCurMods = GetModules(); - const CModules& vNewMods = User.GetModules(); + // Modules + set ssUnloadMods; + CModules& vCurMods = GetModules(); + const CModules& vNewMods = User.GetModules(); - for (CModule* pNewMod : vNewMods) { - CString sModRet; - CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); + for (CModule* pNewMod : vNewMods) { + CString sModRet; + CModule* pCurMod = vCurMods.FindModule(pNewMod->GetModName()); - if (!pCurMod) { - vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), - CModInfo::UserModule, this, nullptr, sModRet); - } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { - vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), - this, nullptr, sModRet); - } - } + if (!pCurMod) { + vCurMods.LoadModule(pNewMod->GetModName(), pNewMod->GetArgs(), + CModInfo::UserModule, this, nullptr, sModRet); + } else if (pNewMod->GetArgs() != pCurMod->GetArgs()) { + vCurMods.ReloadModule(pNewMod->GetModName(), pNewMod->GetArgs(), + this, nullptr, sModRet); + } + } - for (CModule* pCurMod : vCurMods) { - CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); + for (CModule* pCurMod : vCurMods) { + CModule* pNewMod = vNewMods.FindModule(pCurMod->GetModName()); - if (!pNewMod) { - ssUnloadMods.insert(pCurMod->GetModName()); - } - } + if (!pNewMod) { + ssUnloadMods.insert(pCurMod->GetModName()); + } + } - for (const CString& sMod : ssUnloadMods) { - vCurMods.UnloadModule(sMod); - } - // !Modules + for (const CString& sMod : ssUnloadMods) { + vCurMods.UnloadModule(sMod); + } + // !Modules - return true; + return true; } const set& CUser::GetAllowedHosts() const { return m_ssAllowedHosts; } bool CUser::AddAllowedHost(const CString& sHostMask) { - if (sHostMask.empty() || - m_ssAllowedHosts.find(sHostMask) != m_ssAllowedHosts.end()) { - return false; - } + if (sHostMask.empty() || + m_ssAllowedHosts.find(sHostMask) != m_ssAllowedHosts.end()) { + return false; + } - m_ssAllowedHosts.insert(sHostMask); - return true; + m_ssAllowedHosts.insert(sHostMask); + return true; } bool CUser::RemAllowedHost(const CString& sHostMask) { - return m_ssAllowedHosts.erase(sHostMask) > 0; + return m_ssAllowedHosts.erase(sHostMask) > 0; } void CUser::ClearAllowedHosts() { m_ssAllowedHosts.clear(); } bool CUser::IsHostAllowed(const CString& sHostMask) const { - if (m_ssAllowedHosts.empty()) { - return true; - } + if (m_ssAllowedHosts.empty()) { + return true; + } - for (const CString& sHost : m_ssAllowedHosts) { - if (sHostMask.WildCmp(sHost)) { - return true; - } - } + for (const CString& sHost : m_ssAllowedHosts) { + if (sHostMask.WildCmp(sHost)) { + return true; + } + } - return false; + return false; } const CString& CUser::GetTimestampFormat() const { return m_sTimestampFormat; } @@ -863,152 +863,152 @@ bool CUser::GetTimestampAppend() const { return m_bAppendTimestamp; } bool CUser::GetTimestampPrepend() const { return m_bPrependTimestamp; } bool CUser::IsValidUserName(const CString& sUserName) { - // /^[a-zA-Z][a-zA-Z@._\-]*$/ - const char* p = sUserName.c_str(); + // /^[a-zA-Z][a-zA-Z@._\-]*$/ + const char* p = sUserName.c_str(); - if (sUserName.empty()) { - return false; - } + if (sUserName.empty()) { + return false; + } - if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z')) { - return false; - } + if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z')) { + return false; + } - while (*p) { - if (*p != '@' && *p != '.' && *p != '-' && *p != '_' && !isalnum(*p)) { - return false; - } + while (*p) { + if (*p != '@' && *p != '.' && *p != '-' && *p != '_' && !isalnum(*p)) { + return false; + } - p++; - } + p++; + } - return true; + return true; } bool CUser::IsValid(CString& sErrMsg, bool bSkipPass) const { - sErrMsg.clear(); + sErrMsg.clear(); - if (!bSkipPass && m_sPass.empty()) { - sErrMsg = "Pass is empty"; - return false; - } + if (!bSkipPass && m_sPass.empty()) { + sErrMsg = "Pass is empty"; + return false; + } - if (m_sUserName.empty()) { - sErrMsg = "Username is empty"; - return false; - } + if (m_sUserName.empty()) { + sErrMsg = "Username is empty"; + return false; + } - if (!CUser::IsValidUserName(m_sUserName)) { - sErrMsg = "Username is invalid"; - return false; - } + if (!CUser::IsValidUserName(m_sUserName)) { + sErrMsg = "Username is invalid"; + return false; + } - return true; + return true; } CConfig CUser::ToConfig() const { - CConfig config; - CConfig passConfig; + CConfig config; + CConfig passConfig; - CString sHash; - switch (m_eHashType) { - case HASH_NONE: - sHash = "Plain"; - break; - case HASH_MD5: - sHash = "MD5"; - break; - case HASH_SHA256: - sHash = "SHA256"; - break; - } - passConfig.AddKeyValuePair("Salt", m_sPassSalt); - passConfig.AddKeyValuePair("Method", sHash); - passConfig.AddKeyValuePair("Hash", GetPass()); - config.AddSubConfig("Pass", "password", passConfig); + CString sHash; + switch (m_eHashType) { + case HASH_NONE: + sHash = "Plain"; + break; + case HASH_MD5: + sHash = "MD5"; + break; + case HASH_SHA256: + sHash = "SHA256"; + break; + } + passConfig.AddKeyValuePair("Salt", m_sPassSalt); + passConfig.AddKeyValuePair("Method", sHash); + passConfig.AddKeyValuePair("Hash", GetPass()); + config.AddSubConfig("Pass", "password", passConfig); - config.AddKeyValuePair("Nick", GetNick()); - config.AddKeyValuePair("AltNick", GetAltNick()); - config.AddKeyValuePair("Ident", GetIdent()); - if (!m_sRealName.empty()) { - config.AddKeyValuePair("RealName", GetRealName()); - } - config.AddKeyValuePair("BindHost", GetBindHost()); - config.AddKeyValuePair("DCCBindHost", GetDCCBindHost()); - config.AddKeyValuePair("QuitMsg", GetQuitMsg()); - if (CZNC::Get().GetStatusPrefix() != GetStatusPrefix()) - config.AddKeyValuePair("StatusPrefix", GetStatusPrefix()); - config.AddKeyValuePair("Skin", GetSkinName()); - config.AddKeyValuePair("ChanModes", GetDefaultChanModes()); - config.AddKeyValuePair("ChanBufferSize", CString(GetChanBufferSize())); - config.AddKeyValuePair("QueryBufferSize", CString(GetQueryBufferSize())); - config.AddKeyValuePair("AutoClearChanBuffer", - CString(AutoClearChanBuffer())); - config.AddKeyValuePair("AutoClearQueryBuffer", - CString(AutoClearQueryBuffer())); - config.AddKeyValuePair("MultiClients", CString(MultiClients())); - config.AddKeyValuePair("DenyLoadMod", CString(DenyLoadMod())); - config.AddKeyValuePair("Admin", CString(IsAdmin())); - config.AddKeyValuePair("DenySetBindHost", CString(DenySetBindHost())); - config.AddKeyValuePair("TimestampFormat", GetTimestampFormat()); - config.AddKeyValuePair("AppendTimestamp", CString(GetTimestampAppend())); - config.AddKeyValuePair("PrependTimestamp", CString(GetTimestampPrepend())); - config.AddKeyValuePair("Timezone", m_sTimezone); - config.AddKeyValuePair("JoinTries", CString(m_uMaxJoinTries)); - config.AddKeyValuePair("MaxNetworks", CString(m_uMaxNetworks)); - config.AddKeyValuePair("MaxQueryBuffers", CString(m_uMaxQueryBuffers)); - config.AddKeyValuePair("MaxJoins", CString(m_uMaxJoins)); - config.AddKeyValuePair("ClientEncoding", GetClientEncoding()); + config.AddKeyValuePair("Nick", GetNick()); + config.AddKeyValuePair("AltNick", GetAltNick()); + config.AddKeyValuePair("Ident", GetIdent()); + if (!m_sRealName.empty()) { + config.AddKeyValuePair("RealName", GetRealName()); + } + config.AddKeyValuePair("BindHost", GetBindHost()); + config.AddKeyValuePair("DCCBindHost", GetDCCBindHost()); + config.AddKeyValuePair("QuitMsg", GetQuitMsg()); + if (CZNC::Get().GetStatusPrefix() != GetStatusPrefix()) + config.AddKeyValuePair("StatusPrefix", GetStatusPrefix()); + config.AddKeyValuePair("Skin", GetSkinName()); + config.AddKeyValuePair("ChanModes", GetDefaultChanModes()); + config.AddKeyValuePair("ChanBufferSize", CString(GetChanBufferSize())); + config.AddKeyValuePair("QueryBufferSize", CString(GetQueryBufferSize())); + config.AddKeyValuePair("AutoClearChanBuffer", + CString(AutoClearChanBuffer())); + config.AddKeyValuePair("AutoClearQueryBuffer", + CString(AutoClearQueryBuffer())); + config.AddKeyValuePair("MultiClients", CString(MultiClients())); + config.AddKeyValuePair("DenyLoadMod", CString(DenyLoadMod())); + config.AddKeyValuePair("Admin", CString(IsAdmin())); + config.AddKeyValuePair("DenySetBindHost", CString(DenySetBindHost())); + config.AddKeyValuePair("TimestampFormat", GetTimestampFormat()); + config.AddKeyValuePair("AppendTimestamp", CString(GetTimestampAppend())); + config.AddKeyValuePair("PrependTimestamp", CString(GetTimestampPrepend())); + config.AddKeyValuePair("Timezone", m_sTimezone); + config.AddKeyValuePair("JoinTries", CString(m_uMaxJoinTries)); + config.AddKeyValuePair("MaxNetworks", CString(m_uMaxNetworks)); + config.AddKeyValuePair("MaxQueryBuffers", CString(m_uMaxQueryBuffers)); + config.AddKeyValuePair("MaxJoins", CString(m_uMaxJoins)); + config.AddKeyValuePair("ClientEncoding", GetClientEncoding()); - // Allow Hosts - if (!m_ssAllowedHosts.empty()) { - for (const CString& sHost : m_ssAllowedHosts) { - config.AddKeyValuePair("Allow", sHost); - } - } + // Allow Hosts + if (!m_ssAllowedHosts.empty()) { + for (const CString& sHost : m_ssAllowedHosts) { + config.AddKeyValuePair("Allow", sHost); + } + } - // CTCP Replies - if (!m_mssCTCPReplies.empty()) { - for (const auto& itb : m_mssCTCPReplies) { - config.AddKeyValuePair("CTCPReply", - itb.first.AsUpper() + " " + itb.second); - } - } + // CTCP Replies + if (!m_mssCTCPReplies.empty()) { + for (const auto& itb : m_mssCTCPReplies) { + config.AddKeyValuePair("CTCPReply", + itb.first.AsUpper() + " " + itb.second); + } + } - // Modules - const CModules& Mods = GetModules(); + // Modules + const CModules& Mods = GetModules(); - if (!Mods.empty()) { - for (CModule* pMod : Mods) { - CString sArgs = pMod->GetArgs(); + if (!Mods.empty()) { + for (CModule* pMod : Mods) { + CString sArgs = pMod->GetArgs(); - if (!sArgs.empty()) { - sArgs = " " + sArgs; - } + if (!sArgs.empty()) { + sArgs = " " + sArgs; + } - config.AddKeyValuePair("LoadModule", pMod->GetModName() + sArgs); - } - } + config.AddKeyValuePair("LoadModule", pMod->GetModName() + sArgs); + } + } - // Networks - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - config.AddSubConfig("Network", pNetwork->GetName(), - pNetwork->ToConfig()); - } + // Networks + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + config.AddSubConfig("Network", pNetwork->GetName(), + pNetwork->ToConfig()); + } - return config; + return config; } bool CUser::CheckPass(const CString& sPass) const { - switch (m_eHashType) { - case HASH_MD5: - return m_sPass.Equals(CUtils::SaltedMD5Hash(sPass, m_sPassSalt)); - case HASH_SHA256: - return m_sPass.Equals(CUtils::SaltedSHA256Hash(sPass, m_sPassSalt)); - case HASH_NONE: - default: - return (sPass == m_sPass); - } + switch (m_eHashType) { + case HASH_MD5: + return m_sPass.Equals(CUtils::SaltedMD5Hash(sPass, m_sPassSalt)); + case HASH_SHA256: + return m_sPass.Equals(CUtils::SaltedSHA256Hash(sPass, m_sPassSalt)); + case HASH_NONE: + default: + return (sPass == m_sPass); + } } /*CClient* CUser::GetClient() { @@ -1029,190 +1029,190 @@ bool CUser::CheckPass(const CString& sPass) const { }*/ CString CUser::GetLocalDCCIP() const { - if (!GetDCCBindHost().empty()) return GetDCCBindHost(); + if (!GetDCCBindHost().empty()) return GetDCCBindHost(); - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - CIRCSock* pIRCSock = pNetwork->GetIRCSock(); - if (pIRCSock) { - return pIRCSock->GetLocalIP(); - } - } + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + CIRCSock* pIRCSock = pNetwork->GetIRCSock(); + if (pIRCSock) { + return pIRCSock->GetLocalIP(); + } + } - if (!GetAllClients().empty()) { - return GetAllClients()[0]->GetLocalIP(); - } + if (!GetAllClients().empty()) { + return GetAllClients()[0]->GetLocalIP(); + } - return ""; + return ""; } bool CUser::PutUser(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutClient(sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutClient(sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CUser::PutAllUser(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - PutUser(sLine, pClient, pSkipClient); + PutUser(sLine, pClient, pSkipClient); - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - if (pNetwork->PutUser(sLine, pClient, pSkipClient)) { - return true; - } - } + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + if (pNetwork->PutUser(sLine, pClient, pSkipClient)) { + return true; + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CUser::PutStatus(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - vector vClients = GetAllClients(); - for (CClient* pEachClient : vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutStatus(sLine); + vector vClients = GetAllClients(); + for (CClient* pEachClient : vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutStatus(sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CUser::PutStatusNotice(const CString& sLine, CClient* pClient, CClient* pSkipClient) { - vector vClients = GetAllClients(); - for (CClient* pEachClient : vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutStatusNotice(sLine); + vector vClients = GetAllClients(); + for (CClient* pEachClient : vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutStatusNotice(sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CUser::PutModule(const CString& sModule, const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutModule(sModule, sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutModule(sModule, sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } bool CUser::PutModNotice(const CString& sModule, const CString& sLine, CClient* pClient, CClient* pSkipClient) { - for (CClient* pEachClient : m_vClients) { - if ((!pClient || pClient == pEachClient) && - pSkipClient != pEachClient) { - pEachClient->PutModNotice(sModule, sLine); + for (CClient* pEachClient : m_vClients) { + if ((!pClient || pClient == pEachClient) && + pSkipClient != pEachClient) { + pEachClient->PutModNotice(sModule, sLine); - if (pClient) { - return true; - } - } - } + if (pClient) { + return true; + } + } + } - return (pClient == nullptr); + return (pClient == nullptr); } CString CUser::MakeCleanUserName(const CString& sUserName) { - return sUserName.Token(0, false, "@").Replace_n(".", ""); + return sUserName.Token(0, false, "@").Replace_n(".", ""); } bool CUser::IsUserAttached() const { - if (!m_vClients.empty()) { - return true; - } + if (!m_vClients.empty()) { + return true; + } - for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { - if (pNetwork->IsUserAttached()) { - return true; - } - } + for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { + if (pNetwork->IsUserAttached()) { + return true; + } + } - return false; + return false; } bool CUser::LoadModule(const CString& sModName, const CString& sArgs, const CString& sNotice, CString& sError) { - bool bModRet = true; - CString sModRet; + bool bModRet = true; + CString sModRet; - CModInfo ModInfo; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sModName, sModRet)) { - sError = "Unable to find modinfo [" + sModName + "] [" + sModRet + "]"; - return false; - } + CModInfo ModInfo; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sModName, sModRet)) { + sError = "Unable to find modinfo [" + sModName + "] [" + sModRet + "]"; + return false; + } - CUtils::PrintAction(sNotice); + CUtils::PrintAction(sNotice); - if (!ModInfo.SupportsType(CModInfo::UserModule) && - ModInfo.SupportsType(CModInfo::NetworkModule)) { - CUtils::PrintMessage( - "NOTICE: Module [" + sModName + - "] is a network module, loading module for all networks in user."); + if (!ModInfo.SupportsType(CModInfo::UserModule) && + ModInfo.SupportsType(CModInfo::NetworkModule)) { + CUtils::PrintMessage( + "NOTICE: Module [" + sModName + + "] is a network module, loading module for all networks in user."); - // Do they have old NV? - CFile fNVFile = - CFile(GetUserPath() + "/moddata/" + sModName + "/.registry"); + // Do they have old NV? + CFile fNVFile = + CFile(GetUserPath() + "/moddata/" + sModName + "/.registry"); - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - // Check whether the network already has this module loaded (#954) - if (pNetwork->GetModules().FindModule(sModName)) { - continue; - } + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + // Check whether the network already has this module loaded (#954) + if (pNetwork->GetModules().FindModule(sModName)) { + continue; + } - if (fNVFile.Exists()) { - CString sNetworkModPath = - pNetwork->GetNetworkPath() + "/moddata/" + sModName; - if (!CFile::Exists(sNetworkModPath)) { - CDir::MakeDir(sNetworkModPath); - } + if (fNVFile.Exists()) { + CString sNetworkModPath = + pNetwork->GetNetworkPath() + "/moddata/" + sModName; + if (!CFile::Exists(sNetworkModPath)) { + CDir::MakeDir(sNetworkModPath); + } - fNVFile.Copy(sNetworkModPath + "/.registry"); - } + fNVFile.Copy(sNetworkModPath + "/.registry"); + } - bModRet = pNetwork->GetModules().LoadModule( - sModName, sArgs, CModInfo::NetworkModule, this, pNetwork, - sModRet); - if (!bModRet) { - break; - } - } - } else { - bModRet = GetModules().LoadModule(sModName, sArgs, CModInfo::UserModule, - this, nullptr, sModRet); - } + bModRet = pNetwork->GetModules().LoadModule( + sModName, sArgs, CModInfo::NetworkModule, this, pNetwork, + sModRet); + if (!bModRet) { + break; + } + } + } else { + bModRet = GetModules().LoadModule(sModName, sArgs, CModInfo::UserModule, + this, nullptr, sModRet); + } - if (!bModRet) { - sError = sModRet; - } - return bModRet; + if (!bModRet) { + sError = sModRet; + } + return bModRet; } // Setters @@ -1223,9 +1223,9 @@ void CUser::SetRealName(const CString& s) { m_sRealName = s; } void CUser::SetBindHost(const CString& s) { m_sBindHost = s; } void CUser::SetDCCBindHost(const CString& s) { m_sDCCBindHost = s; } void CUser::SetPass(const CString& s, eHashType eHash, const CString& sSalt) { - m_sPass = s; - m_eHashType = eHash; - m_sPassSalt = sSalt; + m_sPass = s; + m_eHashType = eHash; + m_sPassSalt = sSalt; } void CUser::SetMultiClients(bool b) { m_bMultiClients = b; } void CUser::SetDenyLoadMod(bool b) { m_bDenyLoadMod = b; } @@ -1235,99 +1235,99 @@ void CUser::SetDefaultChanModes(const CString& s) { m_sDefaultChanModes = s; } void CUser::SetClientEncoding(const CString& s) { m_sClientEncoding = s; } void CUser::SetQuitMsg(const CString& s) { m_sQuitMsg = s; } void CUser::SetAutoClearChanBuffer(bool b) { - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - for (CChan* pChan : pNetwork->GetChans()) { - pChan->InheritAutoClearChanBuffer(b); - } - } - m_bAutoClearChanBuffer = b; + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + for (CChan* pChan : pNetwork->GetChans()) { + pChan->InheritAutoClearChanBuffer(b); + } + } + m_bAutoClearChanBuffer = b; } void CUser::SetAutoClearQueryBuffer(bool b) { m_bAutoClearQueryBuffer = b; } bool CUser::SetBufferCount(unsigned int u, bool bForce) { - return SetChanBufferSize(u, bForce); + return SetChanBufferSize(u, bForce); } bool CUser::SetChanBufferSize(unsigned int u, bool bForce) { - if (!bForce && u > CZNC::Get().GetMaxBufferSize()) return false; - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - for (CChan* pChan : pNetwork->GetChans()) { - pChan->InheritBufferCount(u, bForce); - } - } - m_uChanBufferSize = u; - return true; + if (!bForce && u > CZNC::Get().GetMaxBufferSize()) return false; + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + for (CChan* pChan : pNetwork->GetChans()) { + pChan->InheritBufferCount(u, bForce); + } + } + m_uChanBufferSize = u; + return true; } bool CUser::SetQueryBufferSize(unsigned int u, bool bForce) { - if (!bForce && u > CZNC::Get().GetMaxBufferSize()) return false; - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - for (CQuery* pQuery : pNetwork->GetQueries()) { - pQuery->SetBufferCount(u, bForce); - } - } - m_uQueryBufferSize = u; - return true; + if (!bForce && u > CZNC::Get().GetMaxBufferSize()) return false; + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + for (CQuery* pQuery : pNetwork->GetQueries()) { + pQuery->SetBufferCount(u, bForce); + } + } + m_uQueryBufferSize = u; + return true; } bool CUser::AddCTCPReply(const CString& sCTCP, const CString& sReply) { - // Reject CTCP requests containing spaces - if (sCTCP.find_first_of(' ') != CString::npos) { - return false; - } - // Reject empty CTCP requests - if (sCTCP.empty()) { - return false; - } - m_mssCTCPReplies[sCTCP.AsUpper()] = sReply; - return true; + // Reject CTCP requests containing spaces + if (sCTCP.find_first_of(' ') != CString::npos) { + return false; + } + // Reject empty CTCP requests + if (sCTCP.empty()) { + return false; + } + m_mssCTCPReplies[sCTCP.AsUpper()] = sReply; + return true; } bool CUser::DelCTCPReply(const CString& sCTCP) { - return m_mssCTCPReplies.erase(sCTCP.AsUpper()) > 0; + return m_mssCTCPReplies.erase(sCTCP.AsUpper()) > 0; } bool CUser::SetStatusPrefix(const CString& s) { - if ((!s.empty()) && (s.length() < 6) && (!s.Contains(" "))) { - m_sStatusPrefix = (s.empty()) ? "*" : s; - return true; - } + if ((!s.empty()) && (s.length() < 6) && (!s.Contains(" "))) { + m_sStatusPrefix = (s.empty()) ? "*" : s; + return true; + } - return false; + return false; } // !Setters // Getters vector CUser::GetAllClients() const { - vector vClients; + vector vClients; - for (CIRCNetwork* pNetwork : m_vIRCNetworks) { - for (CClient* pClient : pNetwork->GetClients()) { - vClients.push_back(pClient); - } - } + for (CIRCNetwork* pNetwork : m_vIRCNetworks) { + for (CClient* pClient : pNetwork->GetClients()) { + vClients.push_back(pClient); + } + } - for (CClient* pClient : m_vClients) { - vClients.push_back(pClient); - } + for (CClient* pClient : m_vClients) { + vClients.push_back(pClient); + } - return vClients; + return vClients; } const CString& CUser::GetUserName() const { return m_sUserName; } const CString& CUser::GetCleanUserName() const { return m_sCleanUserName; } const CString& CUser::GetNick(bool bAllowDefault) const { - return (bAllowDefault && m_sNick.empty()) ? GetCleanUserName() : m_sNick; + return (bAllowDefault && m_sNick.empty()) ? GetCleanUserName() : m_sNick; } const CString& CUser::GetAltNick(bool bAllowDefault) const { - return (bAllowDefault && m_sAltNick.empty()) ? GetCleanUserName() - : m_sAltNick; + return (bAllowDefault && m_sAltNick.empty()) ? GetCleanUserName() + : m_sAltNick; } const CString& CUser::GetIdent(bool bAllowDefault) const { - return (bAllowDefault && m_sIdent.empty()) ? GetCleanUserName() : m_sIdent; + return (bAllowDefault && m_sIdent.empty()) ? GetCleanUserName() : m_sIdent; } CString CUser::GetRealName() const { - return (!m_sRealName.Trim_n().empty()) ? m_sRealName : CZNC::GetTag(false); + return (!m_sRealName.Trim_n().empty()) ? m_sRealName : CZNC::GetTag(false); } const CString& CUser::GetBindHost() const { return m_sBindHost; } const CString& CUser::GetDCCBindHost() const { return m_sDCCBindHost; } @@ -1340,15 +1340,15 @@ bool CUser::DenySetBindHost() const { return m_bDenySetBindHost; } bool CUser::MultiClients() const { return m_bMultiClients; } const CString& CUser::GetStatusPrefix() const { return m_sStatusPrefix; } const CString& CUser::GetDefaultChanModes() const { - return m_sDefaultChanModes; + return m_sDefaultChanModes; } const CString& CUser::GetClientEncoding() const { return m_sClientEncoding; } bool CUser::HasSpaceForNewNetwork() const { - return GetNetworks().size() < MaxNetworks(); + return GetNetworks().size() < MaxNetworks(); } CString CUser::GetQuitMsg() const { - return (!m_sQuitMsg.Trim_n().empty()) ? m_sQuitMsg : CZNC::GetTag(false); + return (!m_sQuitMsg.Trim_n().empty()) ? m_sQuitMsg : CZNC::GetTag(false); } const MCString& CUser::GetCTCPReplies() const { return m_mssCTCPReplies; } unsigned int CUser::GetBufferCount() const { return GetChanBufferSize(); } @@ -1360,25 +1360,25 @@ bool CUser::AutoClearQueryBuffer() const { return m_bAutoClearQueryBuffer; } // m_sSkinName : CZNC::Get().GetSkinName(); } CString CUser::GetSkinName() const { return m_sSkinName; } const CString& CUser::GetUserPath() const { - if (!CFile::Exists(m_sUserPath)) { - CDir::MakeDir(m_sUserPath); - } - return m_sUserPath; + if (!CFile::Exists(m_sUserPath)) { + CDir::MakeDir(m_sUserPath); + } + return m_sUserPath; } // !Getters unsigned long long CUser::BytesRead() const { - unsigned long long uBytes = m_uBytesRead; - for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { - uBytes += pNetwork->BytesRead(); - } - return uBytes; + unsigned long long uBytes = m_uBytesRead; + for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { + uBytes += pNetwork->BytesRead(); + } + return uBytes; } unsigned long long CUser::BytesWritten() const { - unsigned long long uBytes = m_uBytesWritten; - for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { - uBytes += pNetwork->BytesWritten(); - } - return uBytes; + unsigned long long uBytes = m_uBytesWritten; + for (const CIRCNetwork* pNetwork : m_vIRCNetworks) { + uBytes += pNetwork->BytesWritten(); + } + return uBytes; } diff --git a/src/Utils.cpp b/src/Utils.cpp index 8f721eb8..bd7db211 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -56,120 +56,120 @@ constexpr const char* szDefaultDH2048 = "-----END DH PARAMETERS-----\n"; void CUtils::GenerateCert(FILE* pOut, const CString& sHost) { - EVP_PKEY* pKey = nullptr; - X509* pCert = nullptr; - X509_NAME* pName = nullptr; - const int days = 365; - const int years = 10; + EVP_PKEY* pKey = nullptr; + X509* pCert = nullptr; + X509_NAME* pName = nullptr; + const int days = 365; + const int years = 10; - unsigned int uSeed = (unsigned int)time(nullptr); - int serial = (rand_r(&uSeed) % 9999); + unsigned int uSeed = (unsigned int)time(nullptr); + int serial = (rand_r(&uSeed) % 9999); - RSA* pRSA = RSA_generate_key(2048, 0x10001, nullptr, nullptr); - if ((pKey = EVP_PKEY_new())) { - if (!EVP_PKEY_assign_RSA(pKey, pRSA)) { - EVP_PKEY_free(pKey); - return; - } + RSA* pRSA = RSA_generate_key(2048, 0x10001, nullptr, nullptr); + if ((pKey = EVP_PKEY_new())) { + if (!EVP_PKEY_assign_RSA(pKey, pRSA)) { + EVP_PKEY_free(pKey); + return; + } - PEM_write_RSAPrivateKey(pOut, pRSA, nullptr, nullptr, 0, nullptr, - nullptr); + PEM_write_RSAPrivateKey(pOut, pRSA, nullptr, nullptr, 0, nullptr, + nullptr); - if (!(pCert = X509_new())) { - EVP_PKEY_free(pKey); - return; - } + if (!(pCert = X509_new())) { + EVP_PKEY_free(pKey); + return; + } - X509_set_version(pCert, 2); - ASN1_INTEGER_set(X509_get_serialNumber(pCert), serial); - X509_gmtime_adj(X509_get_notBefore(pCert), 0); - X509_gmtime_adj(X509_get_notAfter(pCert), - (long)60 * 60 * 24 * days * years); - X509_set_pubkey(pCert, pKey); + X509_set_version(pCert, 2); + ASN1_INTEGER_set(X509_get_serialNumber(pCert), serial); + X509_gmtime_adj(X509_get_notBefore(pCert), 0); + X509_gmtime_adj(X509_get_notAfter(pCert), + (long)60 * 60 * 24 * days * years); + X509_set_pubkey(pCert, pKey); - pName = X509_get_subject_name(pCert); + pName = X509_get_subject_name(pCert); - const char* pLogName = getenv("LOGNAME"); - const char* pHostName = nullptr; + const char* pLogName = getenv("LOGNAME"); + const char* pHostName = nullptr; - if (!sHost.empty()) { - pHostName = sHost.c_str(); - } + if (!sHost.empty()) { + pHostName = sHost.c_str(); + } - if (!pHostName) { - pHostName = getenv("HOSTNAME"); - } + if (!pHostName) { + pHostName = getenv("HOSTNAME"); + } - if (!pLogName) { - pLogName = "Unknown"; - } + if (!pLogName) { + pLogName = "Unknown"; + } - if (!pHostName) { - pHostName = "host.unknown"; - } + if (!pHostName) { + pHostName = "host.unknown"; + } - CString sEmailAddr = pLogName; - sEmailAddr += "@"; - sEmailAddr += pHostName; + CString sEmailAddr = pLogName; + sEmailAddr += "@"; + sEmailAddr += pHostName; - X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, - (unsigned char*)pLogName, -1, -1, 0); - X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, - (unsigned char*)pHostName, -1, -1, 0); - X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, - (unsigned char*)sEmailAddr.c_str(), -1, -1, - 0); + X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, + (unsigned char*)pLogName, -1, -1, 0); + X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, + (unsigned char*)pHostName, -1, -1, 0); + X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, + (unsigned char*)sEmailAddr.c_str(), -1, -1, + 0); - X509_set_subject_name(pCert, pName); - X509_set_issuer_name(pCert, pName); + X509_set_subject_name(pCert, pName); + X509_set_issuer_name(pCert, pName); - if (!X509_sign(pCert, pKey, EVP_sha256())) { - X509_free(pCert); - EVP_PKEY_free(pKey); - return; - } + if (!X509_sign(pCert, pKey, EVP_sha256())) { + X509_free(pCert); + EVP_PKEY_free(pKey); + return; + } - PEM_write_X509(pOut, pCert); - X509_free(pCert); - EVP_PKEY_free(pKey); + PEM_write_X509(pOut, pCert); + X509_free(pCert); + EVP_PKEY_free(pKey); - fprintf(pOut, "%s", szDefaultDH2048); - } + fprintf(pOut, "%s", szDefaultDH2048); + } } #endif /* HAVE_LIBSSL */ CString CUtils::GetIP(unsigned long addr) { - char szBuf[16]; - memset((char*)szBuf, 0, 16); + char szBuf[16]; + memset((char*)szBuf, 0, 16); - if (addr >= (1 << 24)) { - unsigned long ip[4]; - ip[0] = addr >> 24 & 255; - ip[1] = addr >> 16 & 255; - ip[2] = addr >> 8 & 255; - ip[3] = addr & 255; - sprintf(szBuf, "%lu.%lu.%lu.%lu", ip[0], ip[1], ip[2], ip[3]); - } + if (addr >= (1 << 24)) { + unsigned long ip[4]; + ip[0] = addr >> 24 & 255; + ip[1] = addr >> 16 & 255; + ip[2] = addr >> 8 & 255; + ip[3] = addr & 255; + sprintf(szBuf, "%lu.%lu.%lu.%lu", ip[0], ip[1], ip[2], ip[3]); + } - return szBuf; + return szBuf; } unsigned long CUtils::GetLongIP(const CString& sIP) { - unsigned long ret; - char ip[4][4]; - unsigned int i; + unsigned long ret; + char ip[4][4]; + unsigned int i; - i = sscanf(sIP.c_str(), "%3[0-9].%3[0-9].%3[0-9].%3[0-9]", ip[0], ip[1], - ip[2], ip[3]); - if (i != 4) return 0; + i = sscanf(sIP.c_str(), "%3[0-9].%3[0-9].%3[0-9].%3[0-9]", ip[0], ip[1], + ip[2], ip[3]); + if (i != 4) return 0; - // Beware that atoi("200") << 24 would overflow and turn negative! - ret = atol(ip[0]) << 24; - ret += atol(ip[1]) << 16; - ret += atol(ip[2]) << 8; - ret += atol(ip[3]) << 0; + // Beware that atoi("200") << 24 would overflow and turn negative! + ret = atol(ip[0]) << 24; + ret += atol(ip[1]) << 16; + ret += atol(ip[2]) << 8; + ret += atol(ip[3]) << 0; - return ret; + return ret; } // If you change this here and in GetSaltedHashPass(), @@ -177,143 +177,143 @@ unsigned long CUtils::GetLongIP(const CString& sIP) { // TODO refactor this const CString CUtils::sDefaultHash = "sha256"; CString CUtils::GetSaltedHashPass(CString& sSalt) { - sSalt = GetSalt(); + sSalt = GetSalt(); - while (true) { - CString pass1; - do { - pass1 = CUtils::GetPass("Enter password"); - } while (pass1.empty()); + while (true) { + CString pass1; + do { + pass1 = CUtils::GetPass("Enter password"); + } while (pass1.empty()); - CString pass2 = CUtils::GetPass("Confirm password"); + CString pass2 = CUtils::GetPass("Confirm password"); - if (!pass1.Equals(pass2, CString::CaseSensitive)) { - CUtils::PrintError("The supplied passwords did not match"); - } else { - // Construct the salted pass - return SaltedSHA256Hash(pass1, sSalt); - } - } + if (!pass1.Equals(pass2, CString::CaseSensitive)) { + CUtils::PrintError("The supplied passwords did not match"); + } else { + // Construct the salted pass + return SaltedSHA256Hash(pass1, sSalt); + } + } } CString CUtils::GetSalt() { return CString::RandomString(20); } CString CUtils::SaltedMD5Hash(const CString& sPass, const CString& sSalt) { - return CString(sPass + sSalt).MD5(); + return CString(sPass + sSalt).MD5(); } CString CUtils::SaltedSHA256Hash(const CString& sPass, const CString& sSalt) { - return CString(sPass + sSalt).SHA256(); + return CString(sPass + sSalt).SHA256(); } CString CUtils::GetPass(const CString& sPrompt) { #ifdef HAVE_TCSETATTR - // Disable echo - struct termios t; - tcgetattr(1, &t); - struct termios t2 = t; - t2.c_lflag &= ~ECHO; - tcsetattr(1, TCSANOW, &t2); - // Read pass - CString r; - GetInput(sPrompt, r); - // Restore echo and go to new line - tcsetattr(1, TCSANOW, &t); - fprintf(stdout, "\n"); - fflush(stdout); - return r; + // Disable echo + struct termios t; + tcgetattr(1, &t); + struct termios t2 = t; + t2.c_lflag &= ~ECHO; + tcsetattr(1, TCSANOW, &t2); + // Read pass + CString r; + GetInput(sPrompt, r); + // Restore echo and go to new line + tcsetattr(1, TCSANOW, &t); + fprintf(stdout, "\n"); + fflush(stdout); + return r; #else - PrintPrompt(sPrompt); + PrintPrompt(sPrompt); #ifdef HAVE_GETPASSPHRASE - return getpassphrase(""); + return getpassphrase(""); #else - return getpass(""); + return getpass(""); #endif #endif } bool CUtils::GetBoolInput(const CString& sPrompt, bool bDefault) { - return CUtils::GetBoolInput(sPrompt, &bDefault); + return CUtils::GetBoolInput(sPrompt, &bDefault); } bool CUtils::GetBoolInput(const CString& sPrompt, bool* pbDefault) { - CString sRet, sDefault; + CString sRet, sDefault; - if (pbDefault) { - sDefault = (*pbDefault) ? "yes" : "no"; - } + if (pbDefault) { + sDefault = (*pbDefault) ? "yes" : "no"; + } - while (true) { - GetInput(sPrompt, sRet, sDefault, "yes/no"); + while (true) { + GetInput(sPrompt, sRet, sDefault, "yes/no"); - if (sRet.Equals("y") || sRet.Equals("yes")) { - return true; - } else if (sRet.Equals("n") || sRet.Equals("no")) { - return false; - } - } + if (sRet.Equals("y") || sRet.Equals("yes")) { + return true; + } else if (sRet.Equals("n") || sRet.Equals("no")) { + return false; + } + } } bool CUtils::GetNumInput(const CString& sPrompt, unsigned int& uRet, unsigned int uMin, unsigned int uMax, unsigned int uDefault) { - if (uMin > uMax) { - return false; - } + if (uMin > uMax) { + return false; + } - CString sDefault = (uDefault != (unsigned int)~0) ? CString(uDefault) : ""; - CString sNum, sHint; + CString sDefault = (uDefault != (unsigned int)~0) ? CString(uDefault) : ""; + CString sNum, sHint; - if (uMax != (unsigned int)~0) { - sHint = CString(uMin) + " to " + CString(uMax); - } else if (uMin > 0) { - sHint = CString(uMin) + " and up"; - } + if (uMax != (unsigned int)~0) { + sHint = CString(uMin) + " to " + CString(uMax); + } else if (uMin > 0) { + sHint = CString(uMin) + " and up"; + } - while (true) { - GetInput(sPrompt, sNum, sDefault, sHint); - if (sNum.empty()) { - return false; - } + while (true) { + GetInput(sPrompt, sNum, sDefault, sHint); + if (sNum.empty()) { + return false; + } - uRet = sNum.ToUInt(); + uRet = sNum.ToUInt(); - if ((uRet >= uMin && uRet <= uMax)) { - break; - } + if ((uRet >= uMin && uRet <= uMax)) { + break; + } - CUtils::PrintError("Number must be " + sHint); - } + CUtils::PrintError("Number must be " + sHint); + } - return true; + return true; } bool CUtils::GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault, const CString& sHint) { - CString sExtra; - CString sInput; - sExtra += (!sHint.empty()) ? (" (" + sHint + ")") : ""; - sExtra += (!sDefault.empty()) ? (" [" + sDefault + "]") : ""; + CString sExtra; + CString sInput; + sExtra += (!sHint.empty()) ? (" (" + sHint + ")") : ""; + sExtra += (!sDefault.empty()) ? (" [" + sDefault + "]") : ""; - PrintPrompt(sPrompt + sExtra); - char szBuf[1024]; - memset(szBuf, 0, 1024); - if (fgets(szBuf, 1024, stdin) == nullptr) { - // Reading failed (Error? EOF?) - PrintError("Error while reading from stdin. Exiting..."); - exit(-1); - } - sInput = szBuf; + PrintPrompt(sPrompt + sExtra); + char szBuf[1024]; + memset(szBuf, 0, 1024); + if (fgets(szBuf, 1024, stdin) == nullptr) { + // Reading failed (Error? EOF?) + PrintError("Error while reading from stdin. Exiting..."); + exit(-1); + } + sInput = szBuf; - sInput.TrimSuffix("\n"); + sInput.TrimSuffix("\n"); - if (sInput.empty()) { - sRet = sDefault; - } else { - sRet = sInput; - } + if (sInput.empty()) { + sRet = sDefault; + } else { + sRet = sInput; + } - return !sRet.empty(); + return !sRet.empty(); } #define BOLD "\033[1m" @@ -326,73 +326,73 @@ bool CUtils::GetInput(const CString& sPrompt, CString& sRet, #define DFL "\033[39m" void CUtils::PrintError(const CString& sMessage) { - if (CDebug::StdoutIsTTY()) - fprintf(stdout, BOLD BLU "[" RED " ** " BLU "]" DFL NORM " %s\n", - sMessage.c_str()); - else - fprintf(stdout, "%s\n", sMessage.c_str()); - fflush(stdout); + if (CDebug::StdoutIsTTY()) + fprintf(stdout, BOLD BLU "[" RED " ** " BLU "]" DFL NORM " %s\n", + sMessage.c_str()); + else + fprintf(stdout, "%s\n", sMessage.c_str()); + fflush(stdout); } void CUtils::PrintPrompt(const CString& sMessage) { - if (CDebug::StdoutIsTTY()) - fprintf(stdout, BOLD BLU "[" YEL " ?? " BLU "]" DFL NORM " %s: ", - sMessage.c_str()); - else - fprintf(stdout, "[ ?? ] %s: ", sMessage.c_str()); - fflush(stdout); + if (CDebug::StdoutIsTTY()) + fprintf(stdout, BOLD BLU "[" YEL " ?? " BLU "]" DFL NORM " %s: ", + sMessage.c_str()); + else + fprintf(stdout, "[ ?? ] %s: ", sMessage.c_str()); + fflush(stdout); } void CUtils::PrintMessage(const CString& sMessage, bool bStrong) { - if (CDebug::StdoutIsTTY()) { - if (bStrong) - fprintf(stdout, - BOLD BLU "[" YEL " ** " BLU "]" DFL BOLD " %s" NORM "\n", - sMessage.c_str()); - else - fprintf(stdout, BOLD BLU "[" YEL " ** " BLU "]" DFL NORM " %s\n", - sMessage.c_str()); - } else - fprintf(stdout, "%s\n", sMessage.c_str()); + if (CDebug::StdoutIsTTY()) { + if (bStrong) + fprintf(stdout, + BOLD BLU "[" YEL " ** " BLU "]" DFL BOLD " %s" NORM "\n", + sMessage.c_str()); + else + fprintf(stdout, BOLD BLU "[" YEL " ** " BLU "]" DFL NORM " %s\n", + sMessage.c_str()); + } else + fprintf(stdout, "%s\n", sMessage.c_str()); - fflush(stdout); + fflush(stdout); } void CUtils::PrintAction(const CString& sMessage) { - if (CDebug::StdoutIsTTY()) - fprintf(stdout, BOLD BLU "[ .. " BLU "]" DFL NORM " %s...\n", - sMessage.c_str()); - else - fprintf(stdout, "%s... ", sMessage.c_str()); - fflush(stdout); + if (CDebug::StdoutIsTTY()) + fprintf(stdout, BOLD BLU "[ .. " BLU "]" DFL NORM " %s...\n", + sMessage.c_str()); + else + fprintf(stdout, "%s... ", sMessage.c_str()); + fflush(stdout); } void CUtils::PrintStatus(bool bSuccess, const CString& sMessage) { - if (CDebug::StdoutIsTTY()) { - if (bSuccess) { - if (!sMessage.empty()) - fprintf(stdout, - BOLD BLU "[" GRN " >> " BLU "]" DFL NORM " %s\n", - sMessage.c_str()); - } else { - fprintf(stdout, sMessage.empty() ? " failed\n" : BOLD BLU - "[" RED " !! " BLU "]" DFL NORM BOLD RED - " %s" DFL NORM "\n", - sMessage.c_str()); - } - } else { - if (bSuccess) { - fprintf(stdout, "%s\n", sMessage.c_str()); - } else { - if (!sMessage.empty()) { - fprintf(stdout, "[ %s ]", sMessage.c_str()); - } + if (CDebug::StdoutIsTTY()) { + if (bSuccess) { + if (!sMessage.empty()) + fprintf(stdout, + BOLD BLU "[" GRN " >> " BLU "]" DFL NORM " %s\n", + sMessage.c_str()); + } else { + fprintf(stdout, sMessage.empty() ? " failed\n" : BOLD BLU + "[" RED " !! " BLU "]" DFL NORM BOLD RED + " %s" DFL NORM "\n", + sMessage.c_str()); + } + } else { + if (bSuccess) { + fprintf(stdout, "%s\n", sMessage.c_str()); + } else { + if (!sMessage.empty()) { + fprintf(stdout, "[ %s ]", sMessage.c_str()); + } - fprintf(stdout, "\n"); - } - } + fprintf(stdout, "\n"); + } + } - fflush(stdout); + fflush(stdout); } namespace { @@ -407,267 +407,267 @@ namespace { * ahead/east of GMT.)" */ inline CString FixGMT(CString sTZ) { - if (sTZ.length() >= 4 && sTZ.StartsWith("GMT")) { - if (sTZ[3] == '+') { - sTZ[3] = '-'; - } else if (sTZ[3] == '-') { - sTZ[3] = '+'; - } - } - return sTZ; + if (sTZ.length() >= 4 && sTZ.StartsWith("GMT")) { + if (sTZ[3] == '+') { + sTZ[3] = '-'; + } else if (sTZ[3] == '-') { + sTZ[3] = '+'; + } + } + return sTZ; } } CString CUtils::CTime(time_t t, const CString& sTimezone) { - char s[30] = {}; // should have at least 26 bytes - if (sTimezone.empty()) { - ctime_r(&t, s); - // ctime() adds a trailing newline - return CString(s).Trim_n(); - } - CString sTZ = FixGMT(sTimezone); + char s[30] = {}; // should have at least 26 bytes + if (sTimezone.empty()) { + ctime_r(&t, s); + // ctime() adds a trailing newline + return CString(s).Trim_n(); + } + CString sTZ = FixGMT(sTimezone); - // backup old value - char* oldTZ = getenv("TZ"); - if (oldTZ) oldTZ = strdup(oldTZ); - setenv("TZ", sTZ.c_str(), 1); - tzset(); + // backup old value + char* oldTZ = getenv("TZ"); + if (oldTZ) oldTZ = strdup(oldTZ); + setenv("TZ", sTZ.c_str(), 1); + tzset(); - ctime_r(&t, s); + ctime_r(&t, s); - // restore old value - if (oldTZ) { - setenv("TZ", oldTZ, 1); - free(oldTZ); - } else { - unsetenv("TZ"); - } - tzset(); + // restore old value + if (oldTZ) { + setenv("TZ", oldTZ, 1); + free(oldTZ); + } else { + unsetenv("TZ"); + } + tzset(); - return CString(s).Trim_n(); + return CString(s).Trim_n(); } CString CUtils::FormatTime(time_t t, const CString& sFormat, const CString& sTimezone) { - char s[1024] = {}; - tm m; - if (sTimezone.empty()) { - localtime_r(&t, &m); - strftime(s, sizeof(s), sFormat.c_str(), &m); - return s; - } - CString sTZ = FixGMT(sTimezone); + char s[1024] = {}; + tm m; + if (sTimezone.empty()) { + localtime_r(&t, &m); + strftime(s, sizeof(s), sFormat.c_str(), &m); + return s; + } + CString sTZ = FixGMT(sTimezone); - // backup old value - char* oldTZ = getenv("TZ"); - if (oldTZ) oldTZ = strdup(oldTZ); - setenv("TZ", sTZ.c_str(), 1); - tzset(); + // backup old value + char* oldTZ = getenv("TZ"); + if (oldTZ) oldTZ = strdup(oldTZ); + setenv("TZ", sTZ.c_str(), 1); + tzset(); - localtime_r(&t, &m); - strftime(s, sizeof(s), sFormat.c_str(), &m); + localtime_r(&t, &m); + strftime(s, sizeof(s), sFormat.c_str(), &m); - // restore old value - if (oldTZ) { - setenv("TZ", oldTZ, 1); - free(oldTZ); - } else { - unsetenv("TZ"); - } - tzset(); + // restore old value + if (oldTZ) { + setenv("TZ", oldTZ, 1); + free(oldTZ); + } else { + unsetenv("TZ"); + } + tzset(); - return s; + return s; } CString CUtils::FormatServerTime(const timeval& tv) { - CString s_msec(tv.tv_usec / 1000); - while (s_msec.length() < 3) { - s_msec = "0" + s_msec; - } - // TODO support leap seconds properly - // TODO support message-tags properly - struct tm stm; - memset(&stm, 0, sizeof(stm)); - // OpenBSD has tv_sec as int, so explicitly convert it to time_t to make - // gmtime_r() happy - const time_t secs = tv.tv_sec; - gmtime_r(&secs, &stm); - char sTime[20] = {}; - strftime(sTime, sizeof(sTime), "%Y-%m-%dT%H:%M:%S", &stm); - return CString(sTime) + "." + s_msec + "Z"; + CString s_msec(tv.tv_usec / 1000); + while (s_msec.length() < 3) { + s_msec = "0" + s_msec; + } + // TODO support leap seconds properly + // TODO support message-tags properly + struct tm stm; + memset(&stm, 0, sizeof(stm)); + // OpenBSD has tv_sec as int, so explicitly convert it to time_t to make + // gmtime_r() happy + const time_t secs = tv.tv_sec; + gmtime_r(&secs, &stm); + char sTime[20] = {}; + strftime(sTime, sizeof(sTime), "%Y-%m-%dT%H:%M:%S", &stm); + return CString(sTime) + "." + s_msec + "Z"; } timeval CUtils::ParseServerTime(const CString& sTime) { - struct tm stm; - memset(&stm, 0, sizeof(stm)); - const char* cp = strptime(sTime.c_str(), "%Y-%m-%dT%H:%M:%S", &stm); - struct timeval tv; - memset(&tv, 0, sizeof(tv)); - if (cp) { - tv.tv_sec = mktime(&stm); - CString s_usec(cp); - if (s_usec.TrimPrefix(".") && s_usec.TrimSuffix("Z")) { - tv.tv_usec = s_usec.ToULong() * 1000; - } - } - return tv; + struct tm stm; + memset(&stm, 0, sizeof(stm)); + const char* cp = strptime(sTime.c_str(), "%Y-%m-%dT%H:%M:%S", &stm); + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + if (cp) { + tv.tv_sec = mktime(&stm); + CString s_usec(cp); + if (s_usec.TrimPrefix(".") && s_usec.TrimSuffix("Z")) { + tv.tv_usec = s_usec.ToULong() * 1000; + } + } + return tv; } namespace { void FillTimezones(const CString& sPath, SCString& result, const CString& sPrefix) { - CDir Dir; - Dir.Fill(sPath); - for (CFile* pFile : Dir) { - CString sName = pFile->GetShortName(); - CString sFile = pFile->GetLongName(); - if (sName == "posix" || sName == "right") - continue; // these 2 dirs contain the same filenames - if (sName.EndsWith(".tab") || sName == "posixrules" || - sName == "localtime") - continue; - if (pFile->IsDir()) { - if (sName == "Etc") { - FillTimezones(sFile, result, sPrefix); - } else { - FillTimezones(sFile, result, sPrefix + sName + "/"); - } - } else { - result.insert(sPrefix + sName); - } - } + CDir Dir; + Dir.Fill(sPath); + for (CFile* pFile : Dir) { + CString sName = pFile->GetShortName(); + CString sFile = pFile->GetLongName(); + if (sName == "posix" || sName == "right") + continue; // these 2 dirs contain the same filenames + if (sName.EndsWith(".tab") || sName == "posixrules" || + sName == "localtime") + continue; + if (pFile->IsDir()) { + if (sName == "Etc") { + FillTimezones(sFile, result, sPrefix); + } else { + FillTimezones(sFile, result, sPrefix + sName + "/"); + } + } else { + result.insert(sPrefix + sName); + } + } } } SCString CUtils::GetTimezones() { - static SCString result; - if (result.empty()) { - FillTimezones("/usr/share/zoneinfo", result, ""); - } - return result; + static SCString result; + if (result.empty()) { + FillTimezones("/usr/share/zoneinfo", result, ""); + } + return result; } SCString CUtils::GetEncodings() { - static SCString ssResult; + static SCString ssResult; #ifdef HAVE_ICU - if (ssResult.empty()) { - for (int i = 0; i < ucnv_countAvailable(); ++i) { - const char* pConvName = ucnv_getAvailableName(i); - ssResult.insert(pConvName); - icu::ErrorCode e; - for (int st = 0; st < ucnv_countStandards(); ++st) { - const char* pStdName = ucnv_getStandard(st, e); - icu::LocalUEnumerationPointer ue( - ucnv_openStandardNames(pConvName, pStdName, e)); - while (const char* pStdConvNameEnum = - uenum_next(ue.getAlias(), nullptr, e)) { - ssResult.insert(pStdConvNameEnum); - } - } - } - } + if (ssResult.empty()) { + for (int i = 0; i < ucnv_countAvailable(); ++i) { + const char* pConvName = ucnv_getAvailableName(i); + ssResult.insert(pConvName); + icu::ErrorCode e; + for (int st = 0; st < ucnv_countStandards(); ++st) { + const char* pStdName = ucnv_getStandard(st, e); + icu::LocalUEnumerationPointer ue( + ucnv_openStandardNames(pConvName, pStdName, e)); + while (const char* pStdConvNameEnum = + uenum_next(ue.getAlias(), nullptr, e)) { + ssResult.insert(pStdConvNameEnum); + } + } + } + } #endif - return ssResult; + return ssResult; } MCString CUtils::GetMessageTags(const CString& sLine) { - if (sLine.StartsWith("@")) { - return CMessage(sLine).GetTags(); - } - return MCString::EmptyMap; + if (sLine.StartsWith("@")) { + return CMessage(sLine).GetTags(); + } + return MCString::EmptyMap; } void CUtils::SetMessageTags(CString& sLine, const MCString& mssTags) { - CMessage Message(sLine); - Message.SetTags(mssTags); - sLine = Message.ToString(); + CMessage Message(sLine); + Message.SetTags(mssTags); + sLine = Message.ToString(); } bool CTable::AddColumn(const CString& sName) { - for (const CString& sHeader : m_vsHeaders) { - if (sHeader.Equals(sName)) { - return false; - } - } + for (const CString& sHeader : m_vsHeaders) { + if (sHeader.Equals(sName)) { + return false; + } + } - m_vsHeaders.push_back(sName); + m_vsHeaders.push_back(sName); - return true; + return true; } CTable::size_type CTable::AddRow() { - // Don't add a row if no headers are defined - if (m_vsHeaders.empty()) { - return (size_type)-1; - } + // Don't add a row if no headers are defined + if (m_vsHeaders.empty()) { + return (size_type)-1; + } - // Add a vector with enough space for each column - push_back(vector(m_vsHeaders.size())); - return size() - 1; + // Add a vector with enough space for each column + push_back(vector(m_vsHeaders.size())); + return size() - 1; } bool CTable::SetCell(const CString& sColumn, const CString& sValue, size_type uRowIdx) { - if (uRowIdx == (size_type)~0) { - if (empty()) { - return false; - } + if (uRowIdx == (size_type)~0) { + if (empty()) { + return false; + } - uRowIdx = size() - 1; - } + uRowIdx = size() - 1; + } - unsigned int uColIdx = GetColumnIndex(sColumn); + unsigned int uColIdx = GetColumnIndex(sColumn); - if (uColIdx == (unsigned int)-1) return false; + if (uColIdx == (unsigned int)-1) return false; - (*this)[uRowIdx][uColIdx] = sValue; + (*this)[uRowIdx][uColIdx] = sValue; - return true; + return true; } bool CTable::GetLine(unsigned int uIdx, CString& sLine) const { - if (empty()) { - return false; - } - if (m_vsOutput.empty()) { - m_vsOutput = Render(); - } - if (uIdx >= m_vsOutput.size()) { - return false; - } - sLine = m_vsOutput[uIdx]; - return true; + if (empty()) { + return false; + } + if (m_vsOutput.empty()) { + m_vsOutput = Render(); + } + if (uIdx >= m_vsOutput.size()) { + return false; + } + sLine = m_vsOutput[uIdx]; + return true; } VCString CTable::Render() const { - VCString vsOutput; - vsOutput.reserve((m_vsHeaders.size() + 1) * size() + 1); - for (const VCString& vsRow : *this) { - vsOutput.emplace_back("------"); - for (unsigned int i = 0; i < m_vsHeaders.size(); ++i) { - if (!vsRow[i].empty()) { - vsOutput.emplace_back(m_vsHeaders[i] + ": " + vsRow[i]); - } - } - } - vsOutput.emplace_back("------"); - return vsOutput; + VCString vsOutput; + vsOutput.reserve((m_vsHeaders.size() + 1) * size() + 1); + for (const VCString& vsRow : *this) { + vsOutput.emplace_back("------"); + for (unsigned int i = 0; i < m_vsHeaders.size(); ++i) { + if (!vsRow[i].empty()) { + vsOutput.emplace_back(m_vsHeaders[i] + ": " + vsRow[i]); + } + } + } + vsOutput.emplace_back("------"); + return vsOutput; } unsigned int CTable::GetColumnIndex(const CString& sName) const { - for (unsigned int i = 0; i < m_vsHeaders.size(); i++) { - if (m_vsHeaders[i] == sName) return i; - } + for (unsigned int i = 0; i < m_vsHeaders.size(); i++) { + if (m_vsHeaders[i] == sName) return i; + } - DEBUG("CTable::GetColumnIndex(" + sName + ") failed"); + DEBUG("CTable::GetColumnIndex(" + sName + ") failed"); - return (unsigned int)-1; + return (unsigned int)-1; } void CTable::Clear() { - clear(); - m_vsHeaders.clear(); - m_vsOutput.clear(); + clear(); + m_vsHeaders.clear(); + m_vsOutput.clear(); } #ifdef HAVE_LIBSSL @@ -677,63 +677,63 @@ CBlowfish::CBlowfish(const CString& sPassword, int iEncrypt, m_bkey(), m_iEncrypt(iEncrypt), m_num(0) { - if (sIvec.length() >= 8) { - memcpy(m_ivec, sIvec.data(), 8); - } + if (sIvec.length() >= 8) { + memcpy(m_ivec, sIvec.data(), 8); + } - BF_set_key(&m_bkey, (unsigned int)sPassword.length(), - (unsigned char*)sPassword.data()); + BF_set_key(&m_bkey, (unsigned int)sPassword.length(), + (unsigned char*)sPassword.data()); } CBlowfish::~CBlowfish() { free(m_ivec); } //! output must be freed unsigned char* CBlowfish::MD5(const unsigned char* input, u_int ilen) { - unsigned char* output = (unsigned char*)malloc(MD5_DIGEST_LENGTH); - ::MD5(input, ilen, output); - return output; + unsigned char* output = (unsigned char*)malloc(MD5_DIGEST_LENGTH); + ::MD5(input, ilen, output); + return output; } //! returns an md5 of the CString (not hex encoded) CString CBlowfish::MD5(const CString& sInput, bool bHexEncode) { - CString sRet; - unsigned char* data = - MD5((const unsigned char*)sInput.data(), (unsigned int)sInput.length()); + CString sRet; + unsigned char* data = + MD5((const unsigned char*)sInput.data(), (unsigned int)sInput.length()); - if (!bHexEncode) { - sRet.append((const char*)data, MD5_DIGEST_LENGTH); - } else { - for (int a = 0; a < MD5_DIGEST_LENGTH; a++) { - sRet += g_HexDigits[data[a] >> 4]; - sRet += g_HexDigits[data[a] & 0xf]; - } - } + if (!bHexEncode) { + sRet.append((const char*)data, MD5_DIGEST_LENGTH); + } else { + for (int a = 0; a < MD5_DIGEST_LENGTH; a++) { + sRet += g_HexDigits[data[a] >> 4]; + sRet += g_HexDigits[data[a] & 0xf]; + } + } - free(data); - return sRet; + free(data); + return sRet; } //! output must be the same size as input void CBlowfish::Crypt(unsigned char* input, unsigned char* output, u_int uBytes) { - BF_cfb64_encrypt(input, output, uBytes, &m_bkey, m_ivec, &m_num, - m_iEncrypt); + BF_cfb64_encrypt(input, output, uBytes, &m_bkey, m_ivec, &m_num, + m_iEncrypt); } //! must free result unsigned char* CBlowfish::Crypt(unsigned char* input, u_int uBytes) { - unsigned char* buff = (unsigned char*)malloc(uBytes); - Crypt(input, buff, uBytes); - return buff; + unsigned char* buff = (unsigned char*)malloc(uBytes); + Crypt(input, buff, uBytes); + return buff; } CString CBlowfish::Crypt(const CString& sData) { - unsigned char* buff = - Crypt((unsigned char*)sData.data(), (unsigned int)sData.length()); - CString sOutput; - sOutput.append((const char*)buff, sData.length()); - free(buff); - return sOutput; + unsigned char* buff = + Crypt((unsigned char*)sData.data(), (unsigned int)sData.length()); + CString sOutput; + sOutput.append((const char*)buff, sData.length()); + free(buff); + return sOutput; } #endif // HAVE_LIBSSL diff --git a/src/WebModules.cpp b/src/WebModules.cpp index 2b0b1eef..43eddd0d 100644 --- a/src/WebModules.cpp +++ b/src/WebModules.cpp @@ -34,16 +34,16 @@ const unsigned int CWebSock::m_uiMaxSessions = 5; // We need this class to make sure the contained maps and their content is // destroyed in the order that we want. struct CSessionManager { - // Sessions are valid for a day, (24h, ...) - CSessionManager() : m_mspSessions(24 * 60 * 60 * 1000), m_mIPSessions() {} - ~CSessionManager() { - // Make sure all sessions are destroyed before any of our maps - // are destroyed - m_mspSessions.Clear(); - } + // Sessions are valid for a day, (24h, ...) + CSessionManager() : m_mspSessions(24 * 60 * 60 * 1000), m_mIPSessions() {} + ~CSessionManager() { + // Make sure all sessions are destroyed before any of our maps + // are destroyed + m_mspSessions.Clear(); + } - CWebSessionMap m_mspSessions; - std::multimap m_mIPSessions; + CWebSessionMap m_mspSessions; + std::multimap m_mIPSessions; }; typedef std::multimap::iterator mIPSessionsIterator; @@ -51,42 +51,42 @@ static CSessionManager Sessions; class CWebAuth : public CAuthBase { public: - CWebAuth(CWebSock* pWebSock, const CString& sUsername, - const CString& sPassword, bool bBasic); - virtual ~CWebAuth() {} + CWebAuth(CWebSock* pWebSock, const CString& sUsername, + const CString& sPassword, bool bBasic); + virtual ~CWebAuth() {} - CWebAuth(const CWebAuth&) = delete; - CWebAuth& operator=(const CWebAuth&) = delete; + CWebAuth(const CWebAuth&) = delete; + CWebAuth& operator=(const CWebAuth&) = delete; - void SetWebSock(CWebSock* pWebSock) { m_pWebSock = pWebSock; } - void AcceptedLogin(CUser& User) override; - void RefusedLogin(const CString& sReason) override; - void Invalidate() override; + void SetWebSock(CWebSock* pWebSock) { m_pWebSock = pWebSock; } + void AcceptedLogin(CUser& User) override; + void RefusedLogin(const CString& sReason) override; + void Invalidate() override; private: protected: - CWebSock* m_pWebSock; - bool m_bBasic; + CWebSock* m_pWebSock; + bool m_bBasic; }; void CWebSock::FinishUserSessions(const CUser& User) { - Sessions.m_mspSessions.FinishUserSessions(User); + Sessions.m_mspSessions.FinishUserSessions(User); } CWebSession::~CWebSession() { - // Find our entry in mIPSessions - pair p = - Sessions.m_mIPSessions.equal_range(m_sIP); - mIPSessionsIterator it = p.first; - mIPSessionsIterator end = p.second; + // Find our entry in mIPSessions + pair p = + Sessions.m_mIPSessions.equal_range(m_sIP); + mIPSessionsIterator it = p.first; + mIPSessionsIterator end = p.second; - while (it != end) { - if (it->second == this) { - Sessions.m_mIPSessions.erase(it++); - } else { - ++it; - } - } + while (it != end) { + if (it->second == this) { + Sessions.m_mIPSessions.erase(it++); + } else { + ++it; + } + } } CZNCTagHandler::CZNCTagHandler(CWebSock& WebSock) @@ -94,13 +94,13 @@ CZNCTagHandler::CZNCTagHandler(CWebSock& WebSock) bool CZNCTagHandler::HandleTag(CTemplate& Tmpl, const CString& sName, const CString& sArgs, CString& sOutput) { - if (sName.Equals("URLPARAM")) { - // sOutput = CZNC::Get() - sOutput = m_WebSock.GetParam(sArgs.Token(0), false); - return true; - } + if (sName.Equals("URLPARAM")) { + // sOutput = CZNC::Get() + sOutput = m_WebSock.GetParam(sArgs.Token(0), false); + return true; + } - return false; + return false; } CWebSession::CWebSession(const CString& sId, const CString& sIP) @@ -110,8 +110,8 @@ CWebSession::CWebSession(const CString& sId, const CString& sIP) m_vsErrorMsgs(), m_vsSuccessMsgs(), m_tmLastActive() { - Sessions.m_mIPSessions.insert(make_pair(sIP, this)); - UpdateLastActive(); + Sessions.m_mIPSessions.insert(make_pair(sIP, this)); + UpdateLastActive(); } void CWebSession::UpdateLastActive() { time(&m_tmLastActive); } @@ -125,90 +125,90 @@ CWebAuth::CWebAuth(CWebSock* pWebSock, const CString& sUsername, m_bBasic(bBasic) {} void CWebSession::ClearMessageLoops() { - m_vsErrorMsgs.clear(); - m_vsSuccessMsgs.clear(); + m_vsErrorMsgs.clear(); + m_vsSuccessMsgs.clear(); } void CWebSession::FillMessageLoops(CTemplate& Tmpl) { - for (const CString& sMessage : m_vsErrorMsgs) { - CTemplate& Row = Tmpl.AddRow("ErrorLoop"); - Row["Message"] = sMessage; - } + for (const CString& sMessage : m_vsErrorMsgs) { + CTemplate& Row = Tmpl.AddRow("ErrorLoop"); + Row["Message"] = sMessage; + } - for (const CString& sMessage : m_vsSuccessMsgs) { - CTemplate& Row = Tmpl.AddRow("SuccessLoop"); - Row["Message"] = sMessage; - } + for (const CString& sMessage : m_vsSuccessMsgs) { + CTemplate& Row = Tmpl.AddRow("SuccessLoop"); + Row["Message"] = sMessage; + } } size_t CWebSession::AddError(const CString& sMessage) { - m_vsErrorMsgs.push_back(sMessage); - return m_vsErrorMsgs.size(); + m_vsErrorMsgs.push_back(sMessage); + return m_vsErrorMsgs.size(); } size_t CWebSession::AddSuccess(const CString& sMessage) { - m_vsSuccessMsgs.push_back(sMessage); - return m_vsSuccessMsgs.size(); + m_vsSuccessMsgs.push_back(sMessage); + return m_vsSuccessMsgs.size(); } void CWebSessionMap::FinishUserSessions(const CUser& User) { - iterator it = m_mItems.begin(); + iterator it = m_mItems.begin(); - while (it != m_mItems.end()) { - if (it->second.second->GetUser() == &User) { - m_mItems.erase(it++); - } else { - ++it; - } - } + while (it != m_mItems.end()) { + if (it->second.second->GetUser() == &User) { + m_mItems.erase(it++); + } else { + ++it; + } + } } void CWebAuth::AcceptedLogin(CUser& User) { - if (m_pWebSock) { - std::shared_ptr spSession = m_pWebSock->GetSession(); + if (m_pWebSock) { + std::shared_ptr spSession = m_pWebSock->GetSession(); - spSession->SetUser(&User); + spSession->SetUser(&User); - m_pWebSock->SetLoggedIn(true); - m_pWebSock->UnPauseRead(); - if (m_bBasic) { - m_pWebSock->ReadLine(""); - } else { - m_pWebSock->Redirect("/?cookie_check=true"); - } + m_pWebSock->SetLoggedIn(true); + m_pWebSock->UnPauseRead(); + if (m_bBasic) { + m_pWebSock->ReadLine(""); + } else { + m_pWebSock->Redirect("/?cookie_check=true"); + } - DEBUG("Successful login attempt ==> USER [" + User.GetUserName() + - "] ==> SESSION [" + spSession->GetId() + "]"); - } + DEBUG("Successful login attempt ==> USER [" + User.GetUserName() + + "] ==> SESSION [" + spSession->GetId() + "]"); + } } void CWebAuth::RefusedLogin(const CString& sReason) { - if (m_pWebSock) { - std::shared_ptr spSession = m_pWebSock->GetSession(); + if (m_pWebSock) { + std::shared_ptr spSession = m_pWebSock->GetSession(); - spSession->AddError("Invalid login!"); - spSession->SetUser(nullptr); + spSession->AddError("Invalid login!"); + spSession->SetUser(nullptr); - m_pWebSock->SetLoggedIn(false); - m_pWebSock->UnPauseRead(); - if (m_bBasic) { - m_pWebSock->AddHeader("WWW-Authenticate", "Basic realm=\"ZNC\""); - m_pWebSock->CHTTPSock::PrintErrorPage( - 401, "Unauthorized", - "HTTP Basic authentication attemped with invalid credentials"); - // Why CWebSock makes this function protected?.. - } else { - m_pWebSock->Redirect("/?cookie_check=true"); - } + m_pWebSock->SetLoggedIn(false); + m_pWebSock->UnPauseRead(); + if (m_bBasic) { + m_pWebSock->AddHeader("WWW-Authenticate", "Basic realm=\"ZNC\""); + m_pWebSock->CHTTPSock::PrintErrorPage( + 401, "Unauthorized", + "HTTP Basic authentication attemped with invalid credentials"); + // Why CWebSock makes this function protected?.. + } else { + m_pWebSock->Redirect("/?cookie_check=true"); + } - DEBUG("UNSUCCESSFUL login attempt ==> REASON [" + sReason + - "] ==> SESSION [" + spSession->GetId() + "]"); - } + DEBUG("UNSUCCESSFUL login attempt ==> REASON [" + sReason + + "] ==> SESSION [" + spSession->GetId() + "]"); + } } void CWebAuth::Invalidate() { - CAuthBase::Invalidate(); - m_pWebSock = nullptr; + CAuthBase::Invalidate(); + m_pWebSock = nullptr; } CWebSock::CWebSock(const CString& sURIPrefix) @@ -220,782 +220,782 @@ CWebSock::CWebSock(const CString& sURIPrefix) m_sPath(""), m_sPage(""), m_spSession() { - m_Template.AddTagHandler(std::make_shared(*this)); + m_Template.AddTagHandler(std::make_shared(*this)); } CWebSock::~CWebSock() { - if (m_spAuth) { - m_spAuth->Invalidate(); - } + if (m_spAuth) { + m_spAuth->Invalidate(); + } - // we have to account for traffic here because CSocket does - // not have a valid CModule* pointer. - CUser* pUser = GetSession()->GetUser(); - if (pUser) { - pUser->AddBytesWritten(GetBytesWritten()); - pUser->AddBytesRead(GetBytesRead()); - } else { - CZNC::Get().AddBytesWritten(GetBytesWritten()); - CZNC::Get().AddBytesRead(GetBytesRead()); - } + // we have to account for traffic here because CSocket does + // not have a valid CModule* pointer. + CUser* pUser = GetSession()->GetUser(); + if (pUser) { + pUser->AddBytesWritten(GetBytesWritten()); + pUser->AddBytesRead(GetBytesRead()); + } else { + CZNC::Get().AddBytesWritten(GetBytesWritten()); + CZNC::Get().AddBytesRead(GetBytesRead()); + } - // bytes have been accounted for, so make sure they don't get again: - ResetBytesWritten(); - ResetBytesRead(); + // bytes have been accounted for, so make sure they don't get again: + ResetBytesWritten(); + ResetBytesRead(); } void CWebSock::GetAvailSkins(VCString& vRet) const { - vRet.clear(); + vRet.clear(); - CString sRoot(GetSkinPath("_default_")); + CString sRoot(GetSkinPath("_default_")); - sRoot.TrimRight("/"); - sRoot.TrimRight("_default_"); - sRoot.TrimRight("/"); + sRoot.TrimRight("/"); + sRoot.TrimRight("_default_"); + sRoot.TrimRight("/"); - if (!sRoot.empty()) { - sRoot += "/"; - } + if (!sRoot.empty()) { + sRoot += "/"; + } - if (!sRoot.empty() && CFile::IsDir(sRoot)) { - CDir Dir(sRoot); + if (!sRoot.empty() && CFile::IsDir(sRoot)) { + CDir Dir(sRoot); - for (const CFile* pSubDir : Dir) { - if (pSubDir->IsDir() && pSubDir->GetShortName() == "_default_") { - vRet.push_back(pSubDir->GetShortName()); - break; - } - } + for (const CFile* pSubDir : Dir) { + if (pSubDir->IsDir() && pSubDir->GetShortName() == "_default_") { + vRet.push_back(pSubDir->GetShortName()); + break; + } + } - for (const CFile* pSubDir : Dir) { - if (pSubDir->IsDir() && pSubDir->GetShortName() != "_default_" && - pSubDir->GetShortName() != ".svn") { - vRet.push_back(pSubDir->GetShortName()); - } - } - } + for (const CFile* pSubDir : Dir) { + if (pSubDir->IsDir() && pSubDir->GetShortName() != "_default_" && + pSubDir->GetShortName() != ".svn") { + vRet.push_back(pSubDir->GetShortName()); + } + } + } } VCString CWebSock::GetDirs(CModule* pModule, bool bIsTemplate) { - CString sHomeSkinsDir(CZNC::Get().GetZNCPath() + "/webskins/"); - CString sSkinName(GetSkinName()); - VCString vsResult; + CString sHomeSkinsDir(CZNC::Get().GetZNCPath() + "/webskins/"); + CString sSkinName(GetSkinName()); + VCString vsResult; - // Module specific paths + // Module specific paths - if (pModule) { - const CString& sModName(pModule->GetModName()); + if (pModule) { + const CString& sModName(pModule->GetModName()); - // 1. ~/.znc/webskins//mods// - // - if (!sSkinName.empty()) { - vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + - "/"); - } + // 1. ~/.znc/webskins//mods// + // + if (!sSkinName.empty()) { + vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + + "/"); + } - // 2. ~/.znc/webskins/_default_/mods// - // - vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + - "/"); + // 2. ~/.znc/webskins/_default_/mods// + // + vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + + "/"); - // 3. ./modules//tmpl/ - // - vsResult.push_back(pModule->GetModDataDir() + "/tmpl/"); + // 3. ./modules//tmpl/ + // + vsResult.push_back(pModule->GetModDataDir() + "/tmpl/"); - // 4. ~/.znc/webskins//mods// - // - if (!sSkinName.empty()) { - vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + - "/"); - } + // 4. ~/.znc/webskins//mods// + // + if (!sSkinName.empty()) { + vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + + "/"); + } - // 5. ~/.znc/webskins/_default_/mods// - // - vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + - "/"); - } + // 5. ~/.znc/webskins/_default_/mods// + // + vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + + "/"); + } - // 6. ~/.znc/webskins// - // - if (!sSkinName.empty()) { - vsResult.push_back(GetSkinPath(sSkinName) + - CString(bIsTemplate ? "/tmpl/" : "/")); - } + // 6. ~/.znc/webskins// + // + if (!sSkinName.empty()) { + vsResult.push_back(GetSkinPath(sSkinName) + + CString(bIsTemplate ? "/tmpl/" : "/")); + } - // 7. ~/.znc/webskins/_default_/ - // - vsResult.push_back(GetSkinPath("_default_") + - CString(bIsTemplate ? "/tmpl/" : "/")); + // 7. ~/.znc/webskins/_default_/ + // + vsResult.push_back(GetSkinPath("_default_") + + CString(bIsTemplate ? "/tmpl/" : "/")); - return vsResult; + return vsResult; } CString CWebSock::FindTmpl(CModule* pModule, const CString& sName) { - VCString vsDirs = GetDirs(pModule, true); - CString sFile = pModule->GetModName() + "_" + sName; - for (const CString& sDir : vsDirs) { - if (CFile::Exists(CDir::ChangeDir(sDir, sFile))) { - m_Template.AppendPath(sDir); - return sFile; - } - } - return sName; + VCString vsDirs = GetDirs(pModule, true); + CString sFile = pModule->GetModName() + "_" + sName; + for (const CString& sDir : vsDirs) { + if (CFile::Exists(CDir::ChangeDir(sDir, sFile))) { + m_Template.AppendPath(sDir); + return sFile; + } + } + return sName; } void CWebSock::SetPaths(CModule* pModule, bool bIsTemplate) { - m_Template.ClearPaths(); + m_Template.ClearPaths(); - VCString vsDirs = GetDirs(pModule, bIsTemplate); - for (const CString& sDir : vsDirs) { - m_Template.AppendPath(sDir); - } + VCString vsDirs = GetDirs(pModule, bIsTemplate); + for (const CString& sDir : vsDirs) { + m_Template.AppendPath(sDir); + } - m_bPathsSet = true; + m_bPathsSet = true; } void CWebSock::SetVars() { - m_Template["SessionUser"] = GetUser(); - m_Template["SessionIP"] = GetRemoteIP(); - m_Template["Tag"] = CZNC::GetTag(GetSession()->GetUser() != nullptr, true); - m_Template["Version"] = CZNC::GetVersion(); - m_Template["SkinName"] = GetSkinName(); - m_Template["_CSRF_Check"] = GetCSRFCheck(); - m_Template["URIPrefix"] = GetURIPrefix(); + m_Template["SessionUser"] = GetUser(); + m_Template["SessionIP"] = GetRemoteIP(); + m_Template["Tag"] = CZNC::GetTag(GetSession()->GetUser() != nullptr, true); + m_Template["Version"] = CZNC::GetVersion(); + m_Template["SkinName"] = GetSkinName(); + m_Template["_CSRF_Check"] = GetCSRFCheck(); + m_Template["URIPrefix"] = GetURIPrefix(); - if (GetSession()->IsAdmin()) { - m_Template["IsAdmin"] = "true"; - } + if (GetSession()->IsAdmin()) { + m_Template["IsAdmin"] = "true"; + } - GetSession()->FillMessageLoops(m_Template); - GetSession()->ClearMessageLoops(); + GetSession()->FillMessageLoops(m_Template); + GetSession()->ClearMessageLoops(); - // Global Mods - CModules& vgMods = CZNC::Get().GetModules(); - for (CModule* pgMod : vgMods) { - AddModLoop("GlobalModLoop", *pgMod); - } + // Global Mods + CModules& vgMods = CZNC::Get().GetModules(); + for (CModule* pgMod : vgMods) { + AddModLoop("GlobalModLoop", *pgMod); + } - // User Mods - if (IsLoggedIn()) { - CModules& vMods = GetSession()->GetUser()->GetModules(); + // User Mods + if (IsLoggedIn()) { + CModules& vMods = GetSession()->GetUser()->GetModules(); - for (CModule* pMod : vMods) { - AddModLoop("UserModLoop", *pMod); - } + for (CModule* pMod : vMods) { + AddModLoop("UserModLoop", *pMod); + } - vector vNetworks = GetSession()->GetUser()->GetNetworks(); - for (CIRCNetwork* pNetwork : vNetworks) { - CModules& vnMods = pNetwork->GetModules(); + vector vNetworks = GetSession()->GetUser()->GetNetworks(); + for (CIRCNetwork* pNetwork : vNetworks) { + CModules& vnMods = pNetwork->GetModules(); - CTemplate& Row = m_Template.AddRow("NetworkModLoop"); - Row["NetworkName"] = pNetwork->GetName(); + CTemplate& Row = m_Template.AddRow("NetworkModLoop"); + Row["NetworkName"] = pNetwork->GetName(); - for (CModule* pnMod : vnMods) { - AddModLoop("ModLoop", *pnMod, &Row); - } - } - } + for (CModule* pnMod : vnMods) { + AddModLoop("ModLoop", *pnMod, &Row); + } + } + } - if (IsLoggedIn()) { - m_Template["LoggedIn"] = "true"; - } + if (IsLoggedIn()) { + m_Template["LoggedIn"] = "true"; + } } bool CWebSock::AddModLoop(const CString& sLoopName, CModule& Module, CTemplate* pTemplate) { - if (!pTemplate) { - pTemplate = &m_Template; - } + if (!pTemplate) { + pTemplate = &m_Template; + } - CString sTitle(Module.GetWebMenuTitle()); + CString sTitle(Module.GetWebMenuTitle()); - if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && - !Module.WebRequiresAdmin())) && - (GetSession()->IsAdmin() || !Module.WebRequiresAdmin())) { - CTemplate& Row = pTemplate->AddRow(sLoopName); - bool bActiveModule = false; + if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && + !Module.WebRequiresAdmin())) && + (GetSession()->IsAdmin() || !Module.WebRequiresAdmin())) { + CTemplate& Row = pTemplate->AddRow(sLoopName); + bool bActiveModule = false; - Row["ModName"] = Module.GetModName(); - Row["ModPath"] = Module.GetWebPath(); - Row["Title"] = sTitle; + Row["ModName"] = Module.GetModName(); + Row["ModPath"] = Module.GetWebPath(); + Row["Title"] = sTitle; - if (m_sModName == Module.GetModName()) { - CString sModuleType = GetPath().Token(1, false, "/"); - if (sModuleType == "global" && - Module.GetType() == CModInfo::GlobalModule) { - bActiveModule = true; - } else if (sModuleType == "user" && - Module.GetType() == CModInfo::UserModule) { - bActiveModule = true; - } else if (sModuleType == "network" && - Module.GetType() == CModInfo::NetworkModule) { - CIRCNetwork* Network = Module.GetNetwork(); - if (Network) { - CString sNetworkName = GetPath().Token(2, false, "/"); - if (sNetworkName == Network->GetName()) { - bActiveModule = true; - } - } else { - bActiveModule = true; - } - } - } + if (m_sModName == Module.GetModName()) { + CString sModuleType = GetPath().Token(1, false, "/"); + if (sModuleType == "global" && + Module.GetType() == CModInfo::GlobalModule) { + bActiveModule = true; + } else if (sModuleType == "user" && + Module.GetType() == CModInfo::UserModule) { + bActiveModule = true; + } else if (sModuleType == "network" && + Module.GetType() == CModInfo::NetworkModule) { + CIRCNetwork* Network = Module.GetNetwork(); + if (Network) { + CString sNetworkName = GetPath().Token(2, false, "/"); + if (sNetworkName == Network->GetName()) { + bActiveModule = true; + } + } else { + bActiveModule = true; + } + } + } - if (bActiveModule) { - Row["Active"] = "true"; - } + if (bActiveModule) { + Row["Active"] = "true"; + } - if (Module.GetUser()) { - Row["Username"] = Module.GetUser()->GetUserName(); - } + if (Module.GetUser()) { + Row["Username"] = Module.GetUser()->GetUserName(); + } - VWebSubPages& vSubPages = Module.GetSubPages(); + VWebSubPages& vSubPages = Module.GetSubPages(); - for (TWebSubPage& SubPage : vSubPages) { - // bActive is whether or not the current url matches this subpage - // (params will be checked below) - bool bActive = (m_sModName == Module.GetModName() && - m_sPage == SubPage->GetName() && bActiveModule); + for (TWebSubPage& SubPage : vSubPages) { + // bActive is whether or not the current url matches this subpage + // (params will be checked below) + bool bActive = (m_sModName == Module.GetModName() && + m_sPage == SubPage->GetName() && bActiveModule); - if (SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { - // Don't add admin-only subpages to requests from non-admin - // users - continue; - } + if (SubPage->RequiresAdmin() && !GetSession()->IsAdmin()) { + // Don't add admin-only subpages to requests from non-admin + // users + continue; + } - CTemplate& SubRow = Row.AddRow("SubPageLoop"); + CTemplate& SubRow = Row.AddRow("SubPageLoop"); - SubRow["ModName"] = Module.GetModName(); - SubRow["ModPath"] = Module.GetWebPath(); - SubRow["PageName"] = SubPage->GetName(); - SubRow["Title"] = SubPage->GetTitle().empty() ? SubPage->GetName() - : SubPage->GetTitle(); + SubRow["ModName"] = Module.GetModName(); + SubRow["ModPath"] = Module.GetWebPath(); + SubRow["PageName"] = SubPage->GetName(); + SubRow["Title"] = SubPage->GetTitle().empty() ? SubPage->GetName() + : SubPage->GetTitle(); - CString& sParams = SubRow["Params"]; + CString& sParams = SubRow["Params"]; - const VPair& vParams = SubPage->GetParams(); - for (const pair& ssNV : vParams) { - if (!sParams.empty()) { - sParams += "&"; - } + const VPair& vParams = SubPage->GetParams(); + for (const pair& ssNV : vParams) { + if (!sParams.empty()) { + sParams += "&"; + } - if (!ssNV.first.empty()) { - if (!ssNV.second.empty()) { - sParams += ssNV.first.Escape_n(CString::EURL); - sParams += "="; - sParams += ssNV.second.Escape_n(CString::EURL); - } + if (!ssNV.first.empty()) { + if (!ssNV.second.empty()) { + sParams += ssNV.first.Escape_n(CString::EURL); + sParams += "="; + sParams += ssNV.second.Escape_n(CString::EURL); + } - if (bActive && GetParam(ssNV.first, false) != ssNV.second) { - bActive = false; - } - } - } + if (bActive && GetParam(ssNV.first, false) != ssNV.second) { + bActive = false; + } + } + } - if (bActive) { - SubRow["Active"] = "true"; - } - } + if (bActive) { + SubRow["Active"] = "true"; + } + } - return true; - } + return true; + } - return false; + return false; } CWebSock::EPageReqResult CWebSock::PrintStaticFile(const CString& sPath, CString& sPageRet, CModule* pModule) { - SetPaths(pModule); - CString sFile = m_Template.ExpandFile(sPath.TrimLeft_n("/")); - DEBUG("About to print [" + sFile + "]"); - // Either PrintFile() fails and sends an error page or it suceeds and - // sends a result. In both cases we don't have anything more to do. - PrintFile(sFile); - return PAGE_DONE; + SetPaths(pModule); + CString sFile = m_Template.ExpandFile(sPath.TrimLeft_n("/")); + DEBUG("About to print [" + sFile + "]"); + // Either PrintFile() fails and sends an error page or it suceeds and + // sends a result. In both cases we don't have anything more to do. + PrintFile(sFile); + return PAGE_DONE; } CWebSock::EPageReqResult CWebSock::PrintTemplate(const CString& sPageName, CString& sPageRet, CModule* pModule) { - SetVars(); + SetVars(); - m_Template["PageName"] = sPageName; + m_Template["PageName"] = sPageName; - if (pModule) { - m_Template["ModName"] = pModule->GetModName(); + if (pModule) { + m_Template["ModName"] = pModule->GetModName(); - if (m_Template.find("Title") == m_Template.end()) { - m_Template["Title"] = pModule->GetWebMenuTitle(); - } + if (m_Template.find("Title") == m_Template.end()) { + m_Template["Title"] = pModule->GetWebMenuTitle(); + } - std::vector* breadcrumbs = - m_Template.GetLoop("BreadCrumbs"); - if (breadcrumbs->size() == 1 && - m_Template["Title"] != pModule->GetModName()) { - // Module didn't add its own breadcrumbs, so add a generic one... - // But it'll be useless if it's the same as module name - CTemplate& bread = m_Template.AddRow("BreadCrumbs"); - bread["Text"] = m_Template["Title"]; - } - } + std::vector* breadcrumbs = + m_Template.GetLoop("BreadCrumbs"); + if (breadcrumbs->size() == 1 && + m_Template["Title"] != pModule->GetModName()) { + // Module didn't add its own breadcrumbs, so add a generic one... + // But it'll be useless if it's the same as module name + CTemplate& bread = m_Template.AddRow("BreadCrumbs"); + bread["Text"] = m_Template["Title"]; + } + } - if (!m_bPathsSet) { - SetPaths(pModule, true); - } + if (!m_bPathsSet) { + SetPaths(pModule, true); + } - if (m_Template.GetFileName().empty() && - !m_Template.SetFile(sPageName + ".tmpl")) { - return PAGE_NOTFOUND; - } + if (m_Template.GetFileName().empty() && + !m_Template.SetFile(sPageName + ".tmpl")) { + return PAGE_NOTFOUND; + } - if (m_Template.PrintString(sPageRet)) { - return PAGE_PRINT; - } else { - return PAGE_NOTFOUND; - } + if (m_Template.PrintString(sPageRet)) { + return PAGE_PRINT; + } else { + return PAGE_NOTFOUND; + } } CString CWebSock::GetSkinPath(const CString& sSkinName) { - CString sRet = CZNC::Get().GetZNCPath() + "/webskins/" + sSkinName; + CString sRet = CZNC::Get().GetZNCPath() + "/webskins/" + sSkinName; - if (!CFile::IsDir(sRet)) { - sRet = CZNC::Get().GetCurPath() + "/webskins/" + sSkinName; + if (!CFile::IsDir(sRet)) { + sRet = CZNC::Get().GetCurPath() + "/webskins/" + sSkinName; - if (!CFile::IsDir(sRet)) { - sRet = CString(_SKINDIR_) + "/" + sSkinName; - } - } + if (!CFile::IsDir(sRet)) { + sRet = CString(_SKINDIR_) + "/" + sSkinName; + } + } - return sRet + "/"; + return sRet + "/"; } bool CWebSock::ForceLogin() { - if (GetSession()->IsLoggedIn()) { - return true; - } + if (GetSession()->IsLoggedIn()) { + return true; + } - GetSession()->AddError("You must login to view that page"); - Redirect("/"); - return false; + GetSession()->AddError("You must login to view that page"); + Redirect("/"); + return false; } CString CWebSock::GetRequestCookie(const CString& sKey) { - const CString sPrefixedKey = CString(GetLocalPort()) + "-" + sKey; - CString sRet; + const CString sPrefixedKey = CString(GetLocalPort()) + "-" + sKey; + CString sRet; - if (!m_sModName.empty()) { - sRet = CHTTPSock::GetRequestCookie("Mod-" + m_sModName + "-" + - sPrefixedKey); - } + if (!m_sModName.empty()) { + sRet = CHTTPSock::GetRequestCookie("Mod-" + m_sModName + "-" + + sPrefixedKey); + } - if (sRet.empty()) { - return CHTTPSock::GetRequestCookie(sPrefixedKey); - } + if (sRet.empty()) { + return CHTTPSock::GetRequestCookie(sPrefixedKey); + } - return sRet; + return sRet; } bool CWebSock::SendCookie(const CString& sKey, const CString& sValue) { - const CString sPrefixedKey = CString(GetLocalPort()) + "-" + sKey; + const CString sPrefixedKey = CString(GetLocalPort()) + "-" + sKey; - if (!m_sModName.empty()) { - return CHTTPSock::SendCookie("Mod-" + m_sModName + "-" + sPrefixedKey, - sValue); - } + if (!m_sModName.empty()) { + return CHTTPSock::SendCookie("Mod-" + m_sModName + "-" + sPrefixedKey, + sValue); + } - return CHTTPSock::SendCookie(sPrefixedKey, sValue); + return CHTTPSock::SendCookie(sPrefixedKey, sValue); } void CWebSock::OnPageRequest(const CString& sURI) { - CString sPageRet; - EPageReqResult eRet = OnPageRequestInternal(sURI, sPageRet); - switch (eRet) { - case PAGE_PRINT: - PrintPage(sPageRet); - break; - case PAGE_DEFERRED: - // Something else will later call Close() - break; - case PAGE_DONE: - // Redirect or something like that, it's done, just make sure - // the connection will be closed - Close(CLT_AFTERWRITE); - break; - case PAGE_NOTFOUND: - default: - PrintNotFound(); - break; - } + CString sPageRet; + EPageReqResult eRet = OnPageRequestInternal(sURI, sPageRet); + switch (eRet) { + case PAGE_PRINT: + PrintPage(sPageRet); + break; + case PAGE_DEFERRED: + // Something else will later call Close() + break; + case PAGE_DONE: + // Redirect or something like that, it's done, just make sure + // the connection will be closed + Close(CLT_AFTERWRITE); + break; + case PAGE_NOTFOUND: + default: + PrintNotFound(); + break; + } } CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CString& sPageRet) { - // Check that their session really belongs to their IP address. IP-based - // authentication is bad, but here it's just an extra layer that makes - // stealing cookies harder to pull off. - // - // When their IP is wrong, we give them an invalid cookie. This makes - // sure that they will get a new cookie on their next request. - if (CZNC::Get().GetProtectWebSessions() && - GetSession()->GetIP() != GetRemoteIP()) { - DEBUG("Expected IP: " << GetSession()->GetIP()); - DEBUG("Remote IP: " << GetRemoteIP()); - SendCookie("SessionId", "WRONG_IP_FOR_SESSION"); - PrintErrorPage(403, "Access denied", - "This session does not belong to your IP."); - return PAGE_DONE; - } + // Check that their session really belongs to their IP address. IP-based + // authentication is bad, but here it's just an extra layer that makes + // stealing cookies harder to pull off. + // + // When their IP is wrong, we give them an invalid cookie. This makes + // sure that they will get a new cookie on their next request. + if (CZNC::Get().GetProtectWebSessions() && + GetSession()->GetIP() != GetRemoteIP()) { + DEBUG("Expected IP: " << GetSession()->GetIP()); + DEBUG("Remote IP: " << GetRemoteIP()); + SendCookie("SessionId", "WRONG_IP_FOR_SESSION"); + PrintErrorPage(403, "Access denied", + "This session does not belong to your IP."); + return PAGE_DONE; + } - // Check that they really POSTed from one our forms by checking if they - // know the "secret" CSRF check value. Don't do this for login since - // CSRF against the login form makes no sense and the login form does a - // cookies-enabled check which would break otherwise. - // Don't do this, if user authenticated using http-basic auth, because: - // 1. they obviously know the password, - // 2. it's easier to automate some tasks e.g. user creation, without need to - // care about cookies and csrf - if (IsPost() && !m_bBasicAuth && - GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") { - DEBUG("Expected _CSRF_Check: " << GetCSRFCheck()); - DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check")); - PrintErrorPage( - 403, "Access denied", - "POST requests need to send " - "a secret token to prevent cross-site request forgery attacks."); - return PAGE_DONE; - } + // Check that they really POSTed from one our forms by checking if they + // know the "secret" CSRF check value. Don't do this for login since + // CSRF against the login form makes no sense and the login form does a + // cookies-enabled check which would break otherwise. + // Don't do this, if user authenticated using http-basic auth, because: + // 1. they obviously know the password, + // 2. it's easier to automate some tasks e.g. user creation, without need to + // care about cookies and csrf + if (IsPost() && !m_bBasicAuth && + GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") { + DEBUG("Expected _CSRF_Check: " << GetCSRFCheck()); + DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check")); + PrintErrorPage( + 403, "Access denied", + "POST requests need to send " + "a secret token to prevent cross-site request forgery attacks."); + return PAGE_DONE; + } - SendCookie("SessionId", GetSession()->GetId()); + SendCookie("SessionId", GetSession()->GetId()); - if (GetSession()->IsLoggedIn()) { - m_sUser = GetSession()->GetUser()->GetUserName(); - m_bLoggedIn = true; - } + if (GetSession()->IsLoggedIn()) { + m_sUser = GetSession()->GetUser()->GetUserName(); + m_bLoggedIn = true; + } - // Handle the static pages that don't require a login - if (sURI == "/") { - if (!m_bLoggedIn && GetParam("cookie_check", false).ToBool() && - GetRequestCookie("SessionId").empty()) { - GetSession()->AddError( - "Your browser does not have cookies enabled for this site!"); - } - return PrintTemplate("index", sPageRet); - } else if (sURI == "/favicon.ico") { - return PrintStaticFile("/pub/favicon.ico", sPageRet); - } else if (sURI == "/robots.txt") { - return PrintStaticFile("/pub/robots.txt", sPageRet); - } else if (sURI == "/logout") { - GetSession()->SetUser(nullptr); - SetLoggedIn(false); - Redirect("/"); + // Handle the static pages that don't require a login + if (sURI == "/") { + if (!m_bLoggedIn && GetParam("cookie_check", false).ToBool() && + GetRequestCookie("SessionId").empty()) { + GetSession()->AddError( + "Your browser does not have cookies enabled for this site!"); + } + return PrintTemplate("index", sPageRet); + } else if (sURI == "/favicon.ico") { + return PrintStaticFile("/pub/favicon.ico", sPageRet); + } else if (sURI == "/robots.txt") { + return PrintStaticFile("/pub/robots.txt", sPageRet); + } else if (sURI == "/logout") { + GetSession()->SetUser(nullptr); + SetLoggedIn(false); + Redirect("/"); - // We already sent a reply - return PAGE_DONE; - } else if (sURI == "/login") { - if (GetParam("submitted").ToBool()) { - m_sUser = GetParam("user"); - m_sPass = GetParam("pass"); - m_bLoggedIn = OnLogin(m_sUser, m_sPass, false); + // We already sent a reply + return PAGE_DONE; + } else if (sURI == "/login") { + if (GetParam("submitted").ToBool()) { + m_sUser = GetParam("user"); + m_sPass = GetParam("pass"); + m_bLoggedIn = OnLogin(m_sUser, m_sPass, false); - // AcceptedLogin()/RefusedLogin() will call Redirect() - return PAGE_DEFERRED; - } + // AcceptedLogin()/RefusedLogin() will call Redirect() + return PAGE_DEFERRED; + } - Redirect("/"); // the login form is here - return PAGE_DONE; - } else if (sURI.StartsWith("/pub/")) { - return PrintStaticFile(sURI, sPageRet); - } else if (sURI.StartsWith("/skinfiles/")) { - CString sSkinName = sURI.substr(11); - CString::size_type uPathStart = sSkinName.find("/"); - if (uPathStart != CString::npos) { - CString sFilePath = sSkinName.substr(uPathStart + 1); - sSkinName.erase(uPathStart); + Redirect("/"); // the login form is here + return PAGE_DONE; + } else if (sURI.StartsWith("/pub/")) { + return PrintStaticFile(sURI, sPageRet); + } else if (sURI.StartsWith("/skinfiles/")) { + CString sSkinName = sURI.substr(11); + CString::size_type uPathStart = sSkinName.find("/"); + if (uPathStart != CString::npos) { + CString sFilePath = sSkinName.substr(uPathStart + 1); + sSkinName.erase(uPathStart); - m_Template.ClearPaths(); - m_Template.AppendPath(GetSkinPath(sSkinName) + "pub"); + m_Template.ClearPaths(); + m_Template.AppendPath(GetSkinPath(sSkinName) + "pub"); - if (PrintFile(m_Template.ExpandFile(sFilePath))) { - return PAGE_DONE; - } else { - return PAGE_NOTFOUND; - } - } - return PAGE_NOTFOUND; - } else if (sURI.StartsWith("/mods/") || sURI.StartsWith("/modfiles/")) { - // Make sure modules are treated as directories - if (!sURI.EndsWith("/") && !sURI.Contains(".") && - !sURI.TrimLeft_n("/mods/").TrimLeft_n("/").Contains("/")) { - Redirect(sURI + "/"); - return PAGE_DONE; - } + if (PrintFile(m_Template.ExpandFile(sFilePath))) { + return PAGE_DONE; + } else { + return PAGE_NOTFOUND; + } + } + return PAGE_NOTFOUND; + } else if (sURI.StartsWith("/mods/") || sURI.StartsWith("/modfiles/")) { + // Make sure modules are treated as directories + if (!sURI.EndsWith("/") && !sURI.Contains(".") && + !sURI.TrimLeft_n("/mods/").TrimLeft_n("/").Contains("/")) { + Redirect(sURI + "/"); + return PAGE_DONE; + } - // The URI looks like: - // /mods/[type]/([network]/)?[module][/page][?arg1=val1&arg2=val2...] + // The URI looks like: + // /mods/[type]/([network]/)?[module][/page][?arg1=val1&arg2=val2...] - m_sPath = GetPath().TrimLeft_n("/"); + m_sPath = GetPath().TrimLeft_n("/"); - m_sPath.TrimPrefix("mods/"); - m_sPath.TrimPrefix("modfiles/"); + m_sPath.TrimPrefix("mods/"); + m_sPath.TrimPrefix("modfiles/"); - CString sType = m_sPath.Token(0, false, "/"); - m_sPath = m_sPath.Token(1, true, "/"); + CString sType = m_sPath.Token(0, false, "/"); + m_sPath = m_sPath.Token(1, true, "/"); - CModInfo::EModuleType eModType; - if (sType.Equals("global")) { - eModType = CModInfo::GlobalModule; - } else if (sType.Equals("user")) { - eModType = CModInfo::UserModule; - } else if (sType.Equals("network")) { - eModType = CModInfo::NetworkModule; - } else { - PrintErrorPage(403, "Forbidden", - "Unknown module type [" + sType + "]"); - return PAGE_DONE; - } + CModInfo::EModuleType eModType; + if (sType.Equals("global")) { + eModType = CModInfo::GlobalModule; + } else if (sType.Equals("user")) { + eModType = CModInfo::UserModule; + } else if (sType.Equals("network")) { + eModType = CModInfo::NetworkModule; + } else { + PrintErrorPage(403, "Forbidden", + "Unknown module type [" + sType + "]"); + return PAGE_DONE; + } - if ((eModType != CModInfo::GlobalModule) && !ForceLogin()) { - // Make sure we have a valid user - return PAGE_DONE; - } + if ((eModType != CModInfo::GlobalModule) && !ForceLogin()) { + // Make sure we have a valid user + return PAGE_DONE; + } - CIRCNetwork* pNetwork = nullptr; - if (eModType == CModInfo::NetworkModule) { - CString sNetwork = m_sPath.Token(0, false, "/"); - m_sPath = m_sPath.Token(1, true, "/"); + CIRCNetwork* pNetwork = nullptr; + if (eModType == CModInfo::NetworkModule) { + CString sNetwork = m_sPath.Token(0, false, "/"); + m_sPath = m_sPath.Token(1, true, "/"); - pNetwork = GetSession()->GetUser()->FindNetwork(sNetwork); + pNetwork = GetSession()->GetUser()->FindNetwork(sNetwork); - if (!pNetwork) { - PrintErrorPage(404, "Not Found", - "Network [" + sNetwork + "] not found."); - return PAGE_DONE; - } - } + if (!pNetwork) { + PrintErrorPage(404, "Not Found", + "Network [" + sNetwork + "] not found."); + return PAGE_DONE; + } + } - m_sModName = m_sPath.Token(0, false, "/"); - m_sPage = m_sPath.Token(1, true, "/"); + m_sModName = m_sPath.Token(0, false, "/"); + m_sPage = m_sPath.Token(1, true, "/"); - if (m_sPage.empty()) { - m_sPage = "index"; - } + if (m_sPage.empty()) { + m_sPage = "index"; + } - DEBUG("Path [" + m_sPath + "], Module [" + m_sModName + "], Page [" + - m_sPage + "]"); + DEBUG("Path [" + m_sPath + "], Module [" + m_sModName + "], Page [" + + m_sPage + "]"); - CModule* pModule = nullptr; + CModule* pModule = nullptr; - switch (eModType) { - case CModInfo::GlobalModule: - pModule = CZNC::Get().GetModules().FindModule(m_sModName); - break; - case CModInfo::UserModule: - pModule = GetSession()->GetUser()->GetModules().FindModule( - m_sModName); - break; - case CModInfo::NetworkModule: - pModule = pNetwork->GetModules().FindModule(m_sModName); - break; - } + switch (eModType) { + case CModInfo::GlobalModule: + pModule = CZNC::Get().GetModules().FindModule(m_sModName); + break; + case CModInfo::UserModule: + pModule = GetSession()->GetUser()->GetModules().FindModule( + m_sModName); + break; + case CModInfo::NetworkModule: + pModule = pNetwork->GetModules().FindModule(m_sModName); + break; + } - if (!pModule) return PAGE_NOTFOUND; + if (!pModule) return PAGE_NOTFOUND; - m_Template["ModPath"] = pModule->GetWebPath(); - m_Template["ModFilesPath"] = pModule->GetWebFilesPath(); + m_Template["ModPath"] = pModule->GetWebPath(); + m_Template["ModFilesPath"] = pModule->GetWebFilesPath(); - if (pModule->WebRequiresLogin() && !ForceLogin()) { - return PAGE_PRINT; - } else if (pModule->WebRequiresAdmin() && !GetSession()->IsAdmin()) { - PrintErrorPage(403, "Forbidden", - "You need to be an admin to access this module"); - return PAGE_DONE; - } else if (pModule->GetType() != CModInfo::GlobalModule && - pModule->GetUser() != GetSession()->GetUser()) { - PrintErrorPage(403, "Forbidden", - "You must login as " + - pModule->GetUser()->GetUserName() + - " in order to view this page"); - return PAGE_DONE; - } else if (pModule->OnWebPreRequest(*this, m_sPage)) { - return PAGE_DEFERRED; - } + if (pModule->WebRequiresLogin() && !ForceLogin()) { + return PAGE_PRINT; + } else if (pModule->WebRequiresAdmin() && !GetSession()->IsAdmin()) { + PrintErrorPage(403, "Forbidden", + "You need to be an admin to access this module"); + return PAGE_DONE; + } else if (pModule->GetType() != CModInfo::GlobalModule && + pModule->GetUser() != GetSession()->GetUser()) { + PrintErrorPage(403, "Forbidden", + "You must login as " + + pModule->GetUser()->GetUserName() + + " in order to view this page"); + return PAGE_DONE; + } else if (pModule->OnWebPreRequest(*this, m_sPage)) { + return PAGE_DEFERRED; + } - VWebSubPages& vSubPages = pModule->GetSubPages(); + VWebSubPages& vSubPages = pModule->GetSubPages(); - for (TWebSubPage& SubPage : vSubPages) { - bool bActive = (m_sModName == pModule->GetModName() && - m_sPage == SubPage->GetName()); + for (TWebSubPage& SubPage : vSubPages) { + bool bActive = (m_sModName == pModule->GetModName() && + m_sPage == SubPage->GetName()); - if (bActive && SubPage->RequiresAdmin() && - !GetSession()->IsAdmin()) { - PrintErrorPage(403, "Forbidden", - "You need to be an admin to access this page"); - return PAGE_DONE; - } - } + if (bActive && SubPage->RequiresAdmin() && + !GetSession()->IsAdmin()) { + PrintErrorPage(403, "Forbidden", + "You need to be an admin to access this page"); + return PAGE_DONE; + } + } - if (pModule && pModule->GetType() != CModInfo::GlobalModule && - (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { - AddModLoop("UserModLoop", *pModule); - } + if (pModule && pModule->GetType() != CModInfo::GlobalModule && + (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { + AddModLoop("UserModLoop", *pModule); + } - if (sURI.StartsWith("/modfiles/")) { - m_Template.AppendPath(GetSkinPath(GetSkinName()) + "/mods/" + - m_sModName + "/files/"); - m_Template.AppendPath(pModule->GetModDataDir() + "/files/"); + if (sURI.StartsWith("/modfiles/")) { + m_Template.AppendPath(GetSkinPath(GetSkinName()) + "/mods/" + + m_sModName + "/files/"); + m_Template.AppendPath(pModule->GetModDataDir() + "/files/"); - if (PrintFile(m_Template.ExpandFile(m_sPage.TrimLeft_n("/")))) { - return PAGE_PRINT; - } else { - return PAGE_NOTFOUND; - } - } else { - SetPaths(pModule, true); + if (PrintFile(m_Template.ExpandFile(m_sPage.TrimLeft_n("/")))) { + return PAGE_PRINT; + } else { + return PAGE_NOTFOUND; + } + } else { + SetPaths(pModule, true); - CTemplate& breadModule = m_Template.AddRow("BreadCrumbs"); - breadModule["Text"] = pModule->GetModName(); - breadModule["URL"] = pModule->GetWebPath(); + CTemplate& breadModule = m_Template.AddRow("BreadCrumbs"); + breadModule["Text"] = pModule->GetModName(); + breadModule["URL"] = pModule->GetWebPath(); - /* if a module returns false from OnWebRequest, it does not - want the template to be printed, usually because it did a - redirect. */ - if (pModule->OnWebRequest(*this, m_sPage, m_Template)) { - // If they already sent a reply, let's assume - // they did what they wanted to do. - if (SentHeader()) { - return PAGE_DONE; - } - return PrintTemplate(m_sPage, sPageRet, pModule); - } + /* if a module returns false from OnWebRequest, it does not + want the template to be printed, usually because it did a + redirect. */ + if (pModule->OnWebRequest(*this, m_sPage, m_Template)) { + // If they already sent a reply, let's assume + // they did what they wanted to do. + if (SentHeader()) { + return PAGE_DONE; + } + return PrintTemplate(m_sPage, sPageRet, pModule); + } - if (!SentHeader()) { - PrintErrorPage( - 404, "Not Implemented", - "The requested module does not acknowledge web requests"); - } - return PAGE_DONE; - } - } else { - CString sPage(sURI.Trim_n("/")); - if (sPage.length() < 32) { - for (unsigned int a = 0; a < sPage.length(); a++) { - unsigned char c = sPage[a]; + if (!SentHeader()) { + PrintErrorPage( + 404, "Not Implemented", + "The requested module does not acknowledge web requests"); + } + return PAGE_DONE; + } + } else { + CString sPage(sURI.Trim_n("/")); + if (sPage.length() < 32) { + for (unsigned int a = 0; a < sPage.length(); a++) { + unsigned char c = sPage[a]; - if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && - (c < 'A' || c > 'Z') && c != '_') { - return PAGE_NOTFOUND; - } - } + if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && + (c < 'A' || c > 'Z') && c != '_') { + return PAGE_NOTFOUND; + } + } - return PrintTemplate(sPage, sPageRet); - } - } + return PrintTemplate(sPage, sPageRet); + } + } - return PAGE_NOTFOUND; + return PAGE_NOTFOUND; } void CWebSock::PrintErrorPage(const CString& sMessage) { - m_Template.SetFile("Error.tmpl"); + m_Template.SetFile("Error.tmpl"); - m_Template["Action"] = "error"; - m_Template["Title"] = "Error"; - m_Template["Error"] = sMessage; + m_Template["Action"] = "error"; + m_Template["Title"] = "Error"; + m_Template["Error"] = sMessage; } static inline bool compareLastActive( const std::pair& first, const std::pair& second) { - return first.second->GetLastActive() < second.second->GetLastActive(); + return first.second->GetLastActive() < second.second->GetLastActive(); } std::shared_ptr CWebSock::GetSession() { - if (m_spSession) { - return m_spSession; - } + if (m_spSession) { + return m_spSession; + } - const CString sCookieSessionId = GetRequestCookie("SessionId"); - std::shared_ptr* pSession = - Sessions.m_mspSessions.GetItem(sCookieSessionId); + const CString sCookieSessionId = GetRequestCookie("SessionId"); + std::shared_ptr* pSession = + Sessions.m_mspSessions.GetItem(sCookieSessionId); - if (pSession != nullptr) { - // Refresh the timeout - Sessions.m_mspSessions.AddItem((*pSession)->GetId(), *pSession); - (*pSession)->UpdateLastActive(); - m_spSession = *pSession; - DEBUG("Found existing session from cookie: [" + sCookieSessionId + - "] IsLoggedIn(" + - CString((*pSession)->IsLoggedIn() - ? "true, " + ((*pSession)->GetUser()->GetUserName()) - : "false") + - ")"); - return *pSession; - } + if (pSession != nullptr) { + // Refresh the timeout + Sessions.m_mspSessions.AddItem((*pSession)->GetId(), *pSession); + (*pSession)->UpdateLastActive(); + m_spSession = *pSession; + DEBUG("Found existing session from cookie: [" + sCookieSessionId + + "] IsLoggedIn(" + + CString((*pSession)->IsLoggedIn() + ? "true, " + ((*pSession)->GetUser()->GetUserName()) + : "false") + + ")"); + return *pSession; + } - if (Sessions.m_mIPSessions.count(GetRemoteIP()) > m_uiMaxSessions) { - pair p = - Sessions.m_mIPSessions.equal_range(GetRemoteIP()); - mIPSessionsIterator it = - std::min_element(p.first, p.second, compareLastActive); - DEBUG("Remote IP: " << GetRemoteIP() << "; discarding session [" - << it->second->GetId() << "]"); - Sessions.m_mspSessions.RemItem(it->second->GetId()); - } + if (Sessions.m_mIPSessions.count(GetRemoteIP()) > m_uiMaxSessions) { + pair p = + Sessions.m_mIPSessions.equal_range(GetRemoteIP()); + mIPSessionsIterator it = + std::min_element(p.first, p.second, compareLastActive); + DEBUG("Remote IP: " << GetRemoteIP() << "; discarding session [" + << it->second->GetId() << "]"); + Sessions.m_mspSessions.RemItem(it->second->GetId()); + } - CString sSessionID; - do { - sSessionID = CString::RandomString(32); - sSessionID += ":" + GetRemoteIP() + ":" + CString(GetRemotePort()); - sSessionID += ":" + GetLocalIP() + ":" + CString(GetLocalPort()); - sSessionID += ":" + CString(time(nullptr)); - sSessionID = sSessionID.SHA256(); + CString sSessionID; + do { + sSessionID = CString::RandomString(32); + sSessionID += ":" + GetRemoteIP() + ":" + CString(GetRemotePort()); + sSessionID += ":" + GetLocalIP() + ":" + CString(GetLocalPort()); + sSessionID += ":" + CString(time(nullptr)); + sSessionID = sSessionID.SHA256(); - DEBUG("Auto generated session: [" + sSessionID + "]"); - } while (Sessions.m_mspSessions.HasItem(sSessionID)); + DEBUG("Auto generated session: [" + sSessionID + "]"); + } while (Sessions.m_mspSessions.HasItem(sSessionID)); - std::shared_ptr spSession( - new CWebSession(sSessionID, GetRemoteIP())); - Sessions.m_mspSessions.AddItem(spSession->GetId(), spSession); + std::shared_ptr spSession( + new CWebSession(sSessionID, GetRemoteIP())); + Sessions.m_mspSessions.AddItem(spSession->GetId(), spSession); - m_spSession = spSession; + m_spSession = spSession; - return spSession; + return spSession; } CString CWebSock::GetCSRFCheck() { - std::shared_ptr pSession = GetSession(); - return pSession->GetId().MD5(); + std::shared_ptr pSession = GetSession(); + return pSession->GetId().MD5(); } bool CWebSock::OnLogin(const CString& sUser, const CString& sPass, bool bBasic) { - DEBUG("=================== CWebSock::OnLogin(), basic auth? " - << std::boolalpha << bBasic); - m_spAuth = std::make_shared(this, sUser, sPass, bBasic); + DEBUG("=================== CWebSock::OnLogin(), basic auth? " + << std::boolalpha << bBasic); + m_spAuth = std::make_shared(this, sUser, sPass, bBasic); - // Some authentication module could need some time, block this socket - // until then. CWebAuth will UnPauseRead(). - PauseRead(); - CZNC::Get().AuthUser(m_spAuth); + // Some authentication module could need some time, block this socket + // until then. CWebAuth will UnPauseRead(). + PauseRead(); + CZNC::Get().AuthUser(m_spAuth); - // If CWebAuth already set this, don't change it. - return IsLoggedIn(); + // If CWebAuth already set this, don't change it. + return IsLoggedIn(); } Csock* CWebSock::GetSockObj(const CString& sHost, unsigned short uPort) { - // All listening is done by CListener, thus CWebSock should never have - // to listen, but since GetSockObj() is pure virtual... - DEBUG("CWebSock::GetSockObj() called - this should never happen!"); - return nullptr; + // All listening is done by CListener, thus CWebSock should never have + // to listen, but since GetSockObj() is pure virtual... + DEBUG("CWebSock::GetSockObj() called - this should never happen!"); + return nullptr; } CString CWebSock::GetSkinName() { - std::shared_ptr spSession = GetSession(); + std::shared_ptr spSession = GetSession(); - if (spSession->IsLoggedIn() && - !spSession->GetUser()->GetSkinName().empty()) { - return spSession->GetUser()->GetSkinName(); - } + if (spSession->IsLoggedIn() && + !spSession->GetUser()->GetSkinName().empty()) { + return spSession->GetUser()->GetSkinName(); + } - return CZNC::Get().GetSkinName(); + return CZNC::Get().GetSkinName(); } diff --git a/src/ZNCDebug.cpp b/src/ZNCDebug.cpp index 82efa73e..802230d4 100644 --- a/src/ZNCDebug.cpp +++ b/src/ZNCDebug.cpp @@ -29,17 +29,17 @@ bool CDebug::debug = #endif CDebugStream::~CDebugStream() { - timeval tTime; - gettimeofday(&tTime, nullptr); - time_t tSec = (time_t)tTime.tv_sec; // some systems (e.g. openbsd) define - // tv_sec as long int instead of time_t - tm tM; - tzset(); // localtime_r requires this - localtime_r(&tSec, &tM); - char sTime[20] = {}; - strftime(sTime, sizeof(sTime), "%Y-%m-%d %H:%M:%S", &tM); - char sUsec[7] = {}; - snprintf(sUsec, sizeof(sUsec), "%06lu", (unsigned long int)tTime.tv_usec); - std::cout << "[" << sTime << "." << sUsec << "] " - << CString(this->str()).Escape_n(CString::EDEBUG) << std::endl; + timeval tTime; + gettimeofday(&tTime, nullptr); + time_t tSec = (time_t)tTime.tv_sec; // some systems (e.g. openbsd) define + // tv_sec as long int instead of time_t + tm tM; + tzset(); // localtime_r requires this + localtime_r(&tSec, &tM); + char sTime[20] = {}; + strftime(sTime, sizeof(sTime), "%Y-%m-%d %H:%M:%S", &tM); + char sUsec[7] = {}; + snprintf(sUsec, sizeof(sUsec), "%06lu", (unsigned long int)tTime.tv_usec); + std::cout << "[" << sTime << "." << sUsec << "] " + << CString(this->str()).Escape_n(CString::EDEBUG) << std::endl; } diff --git a/src/ZNCString.cpp b/src/ZNCString.cpp index e6fd8106..a185cc85 100644 --- a/src/ZNCString.cpp +++ b/src/ZNCString.cpp @@ -24,568 +24,568 @@ using std::stringstream; CString::CString(char c) : string() { - stringstream s; - s << c; - *this = s.str(); + stringstream s; + s << c; + *this = s.str(); } CString::CString(unsigned char c) : string() { - stringstream s; - s << c; - *this = s.str(); + stringstream s; + s << c; + *this = s.str(); } CString::CString(short i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(unsigned short i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(int i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(unsigned int i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(long i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(unsigned long i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(long long i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(unsigned long long i) : string() { - stringstream s; - s << i; - *this = s.str(); + stringstream s; + s << i; + *this = s.str(); } CString::CString(double i, int precision) : string() { - stringstream s; - s.precision(precision); - s << std::fixed << i; - *this = s.str(); + stringstream s; + s.precision(precision); + s << std::fixed << i; + *this = s.str(); } CString::CString(float i, int precision) : string() { - stringstream s; - s.precision(precision); - s << std::fixed << i; - *this = s.str(); + stringstream s; + s.precision(precision); + s << std::fixed << i; + *this = s.str(); } unsigned char* CString::strnchr(const unsigned char* src, unsigned char c, unsigned int iMaxBytes, unsigned char* pFill, unsigned int* piCount) const { - for (unsigned int a = 0; a < iMaxBytes && *src; a++, src++) { - if (pFill) { - pFill[a] = *src; - } + for (unsigned int a = 0; a < iMaxBytes && *src; a++, src++) { + if (pFill) { + pFill[a] = *src; + } - if (*src == c) { - if (pFill) { - pFill[a + 1] = 0; - } + if (*src == c) { + if (pFill) { + pFill[a + 1] = 0; + } - if (piCount) { - *piCount = a; - } + if (piCount) { + *piCount = a; + } - return (unsigned char*)src; - } - } + return (unsigned char*)src; + } + } - if (pFill) { - *pFill = 0; - } + if (pFill) { + *pFill = 0; + } - if (piCount) { - *piCount = 0; - } + if (piCount) { + *piCount = 0; + } - return nullptr; + return nullptr; } int CString::CaseCmp(const CString& s, CString::size_type uLen) const { - if (uLen != CString::npos) { - return strncasecmp(c_str(), s.c_str(), uLen); - } - return strcasecmp(c_str(), s.c_str()); + if (uLen != CString::npos) { + return strncasecmp(c_str(), s.c_str(), uLen); + } + return strcasecmp(c_str(), s.c_str()); } int CString::StrCmp(const CString& s, CString::size_type uLen) const { - if (uLen != CString::npos) { - return strncmp(c_str(), s.c_str(), uLen); - } - return strcmp(c_str(), s.c_str()); + if (uLen != CString::npos) { + return strncmp(c_str(), s.c_str(), uLen); + } + return strcmp(c_str(), s.c_str()); } bool CString::Equals(const CString& s, CaseSensitivity cs) const { - if (cs == CaseSensitive) { - return (StrCmp(s) == 0); - } else { - return (CaseCmp(s) == 0); - } + if (cs == CaseSensitive) { + return (StrCmp(s) == 0); + } else { + return (CaseCmp(s) == 0); + } } bool CString::Equals(const CString& s, bool bCaseSensitive, CString::size_type uLen) const { - if (bCaseSensitive) { - return (StrCmp(s, uLen) == 0); - } else { - return (CaseCmp(s, uLen) == 0); - } + if (bCaseSensitive) { + return (StrCmp(s, uLen) == 0); + } else { + return (CaseCmp(s, uLen) == 0); + } } bool CString::WildCmp(const CString& sWild, const CString& sString, CaseSensitivity cs) { - // avoid a copy when cs == CaseSensitive (C++ deliberately specifies that - // binding a temporary object to a reference to const on the stack - // lengthens the lifetime of the temporary to the lifetime of the reference - // itself) - const CString& sWld = (cs == CaseSensitive ? sWild : sWild.AsLower()); - const CString& sStr = (cs == CaseSensitive ? sString : sString.AsLower()); + // avoid a copy when cs == CaseSensitive (C++ deliberately specifies that + // binding a temporary object to a reference to const on the stack + // lengthens the lifetime of the temporary to the lifetime of the reference + // itself) + const CString& sWld = (cs == CaseSensitive ? sWild : sWild.AsLower()); + const CString& sStr = (cs == CaseSensitive ? sString : sString.AsLower()); - // Written by Jack Handy - jakkhandy@hotmail.com - const char* wild = sWld.c_str(), *CString = sStr.c_str(); - const char* cp = nullptr, *mp = nullptr; + // Written by Jack Handy - jakkhandy@hotmail.com + const char* wild = sWld.c_str(), *CString = sStr.c_str(); + const char* cp = nullptr, *mp = nullptr; - while ((*CString) && (*wild != '*')) { - if ((*wild != *CString) && (*wild != '?')) { - return false; - } + while ((*CString) && (*wild != '*')) { + if ((*wild != *CString) && (*wild != '?')) { + return false; + } - wild++; - CString++; - } + wild++; + CString++; + } - while (*CString) { - if (*wild == '*') { - if (!*++wild) { - return true; - } + while (*CString) { + if (*wild == '*') { + if (!*++wild) { + return true; + } - mp = wild; - cp = CString + 1; - } else if ((*wild == *CString) || (*wild == '?')) { - wild++; - CString++; - } else { - wild = mp; - CString = cp++; - } - } + mp = wild; + cp = CString + 1; + } else if ((*wild == *CString) || (*wild == '?')) { + wild++; + CString++; + } else { + wild = mp; + CString = cp++; + } + } - while (*wild == '*') { - wild++; - } + while (*wild == '*') { + wild++; + } - return (*wild == 0); + return (*wild == 0); } bool CString::WildCmp(const CString& sWild, CaseSensitivity cs) const { - return CString::WildCmp(sWild, *this, cs); + return CString::WildCmp(sWild, *this, cs); } CString& CString::MakeUpper() { - for (char& c : *this) { - // TODO use unicode - c = (char)toupper(c); - } + for (char& c : *this) { + // TODO use unicode + c = (char)toupper(c); + } - return *this; + return *this; } CString& CString::MakeLower() { - for (char& c : *this) { - // TODO use unicode - c = (char)tolower(c); - } + for (char& c : *this) { + // TODO use unicode + c = (char)tolower(c); + } - return *this; + return *this; } CString CString::AsUpper() const { - CString sRet = *this; - sRet.MakeUpper(); - return sRet; + CString sRet = *this; + sRet.MakeUpper(); + return sRet; } CString CString::AsLower() const { - CString sRet = *this; - sRet.MakeLower(); - return sRet; + CString sRet = *this; + sRet.MakeLower(); + return sRet; } CString::EEscape CString::ToEscape(const CString& sEsc) { - if (sEsc.Equals("ASCII")) { - return EASCII; - } else if (sEsc.Equals("HTML")) { - return EHTML; - } else if (sEsc.Equals("URL")) { - return EURL; - } else if (sEsc.Equals("SQL")) { - return ESQL; - } else if (sEsc.Equals("NAMEDFMT")) { - return ENAMEDFMT; - } else if (sEsc.Equals("DEBUG")) { - return EDEBUG; - } else if (sEsc.Equals("MSGTAG")) { - return EMSGTAG; - } else if (sEsc.Equals("HEXCOLON")) { - return EHEXCOLON; - } + if (sEsc.Equals("ASCII")) { + return EASCII; + } else if (sEsc.Equals("HTML")) { + return EHTML; + } else if (sEsc.Equals("URL")) { + return EURL; + } else if (sEsc.Equals("SQL")) { + return ESQL; + } else if (sEsc.Equals("NAMEDFMT")) { + return ENAMEDFMT; + } else if (sEsc.Equals("DEBUG")) { + return EDEBUG; + } else if (sEsc.Equals("MSGTAG")) { + return EMSGTAG; + } else if (sEsc.Equals("HEXCOLON")) { + return EHEXCOLON; + } - return EASCII; + return EASCII; } CString CString::Escape_n(EEscape eFrom, EEscape eTo) const { - CString sRet; - const char szHex[] = "0123456789ABCDEF"; - const unsigned char* pStart = (const unsigned char*)data(); - const unsigned char* p = (const unsigned char*)data(); - size_type iLength = length(); - sRet.reserve(iLength * 3); - unsigned char pTmp[21]; - unsigned int iCounted = 0; + CString sRet; + const char szHex[] = "0123456789ABCDEF"; + const unsigned char* pStart = (const unsigned char*)data(); + const unsigned char* p = (const unsigned char*)data(); + size_type iLength = length(); + sRet.reserve(iLength * 3); + unsigned char pTmp[21]; + unsigned int iCounted = 0; - for (unsigned int a = 0; a < iLength; a++, p = pStart + a) { - unsigned char ch = 0; + for (unsigned int a = 0; a < iLength; a++, p = pStart + a) { + unsigned char ch = 0; - switch (eFrom) { - case EHTML: - if ((*p == '&') && - (strnchr((unsigned char*)p, ';', sizeof(pTmp) - 1, pTmp, - &iCounted))) { - // please note that we do not have any Unicode or UTF-8 - // support here at all. + switch (eFrom) { + case EHTML: + if ((*p == '&') && + (strnchr((unsigned char*)p, ';', sizeof(pTmp) - 1, pTmp, + &iCounted))) { + // please note that we do not have any Unicode or UTF-8 + // support here at all. - if ((iCounted >= 3) && - (pTmp[1] == '#')) { // do XML and HTML a < - int base = 10; + if ((iCounted >= 3) && + (pTmp[1] == '#')) { // do XML and HTML a < + int base = 10; - if ((pTmp[2] & 0xDF) == 'X') { - base = 16; - } + if ((pTmp[2] & 0xDF) == 'X') { + base = 16; + } - char* endptr = nullptr; - unsigned long int b = - strtol((const char*)(pTmp + 2 + (base == 16)), - &endptr, base); + char* endptr = nullptr; + unsigned long int b = + strtol((const char*)(pTmp + 2 + (base == 16)), + &endptr, base); - if ((*endptr == ';') && (b <= 255)) { - // incase they do something like � - ch = (unsigned char)b; - a += iCounted; - break; - } - } + if ((*endptr == ';') && (b <= 255)) { + // incase they do something like � + ch = (unsigned char)b; + a += iCounted; + break; + } + } - if (ch == 0) { - if (!strncasecmp((const char*)&pTmp, "<", 2)) - ch = '<'; - else if (!strncasecmp((const char*)&pTmp, ">", 2)) - ch = '>'; - else if (!strncasecmp((const char*)&pTmp, """, 4)) - ch = '"'; - else if (!strncasecmp((const char*)&pTmp, "&", 3)) - ch = '&'; - } + if (ch == 0) { + if (!strncasecmp((const char*)&pTmp, "<", 2)) + ch = '<'; + else if (!strncasecmp((const char*)&pTmp, ">", 2)) + ch = '>'; + else if (!strncasecmp((const char*)&pTmp, """, 4)) + ch = '"'; + else if (!strncasecmp((const char*)&pTmp, "&", 3)) + ch = '&'; + } - if (ch > 0) { - a += iCounted; - } else { - ch = *p; // Not a valid escape, just record the & - } - } else { - ch = *p; - } - break; - case EASCII: - ch = *p; - break; - case EURL: - if (*p == '%' && (a + 2) < iLength && isxdigit(*(p + 1)) && - isxdigit(*(p + 2))) { - p++; - if (isdigit(*p)) { - ch = (unsigned char)((*p - '0') << 4); - } else { - ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); - } + if (ch > 0) { + a += iCounted; + } else { + ch = *p; // Not a valid escape, just record the & + } + } else { + ch = *p; + } + break; + case EASCII: + ch = *p; + break; + case EURL: + if (*p == '%' && (a + 2) < iLength && isxdigit(*(p + 1)) && + isxdigit(*(p + 2))) { + p++; + if (isdigit(*p)) { + ch = (unsigned char)((*p - '0') << 4); + } else { + ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); + } - p++; - if (isdigit(*p)) { - ch |= (unsigned char)(*p - '0'); - } else { - ch |= (unsigned char)(tolower(*p) - 'a' + 10); - } + p++; + if (isdigit(*p)) { + ch |= (unsigned char)(*p - '0'); + } else { + ch |= (unsigned char)(tolower(*p) - 'a' + 10); + } - a += 2; - } else if (pStart[a] == '+') { - ch = ' '; - } else { - ch = *p; - } + a += 2; + } else if (pStart[a] == '+') { + ch = ' '; + } else { + ch = *p; + } - break; - case ESQL: - if (*p != '\\' || iLength < (a + 1)) { - ch = *p; - } else { - a++; - p++; + break; + case ESQL: + if (*p != '\\' || iLength < (a + 1)) { + ch = *p; + } else { + a++; + p++; - if (*p == 'n') { - ch = '\n'; - } else if (*p == 'r') { - ch = '\r'; - } else if (*p == '0') { - ch = '\0'; - } else if (*p == 't') { - ch = '\t'; - } else if (*p == 'b') { - ch = '\b'; - } else { - ch = *p; - } - } + if (*p == 'n') { + ch = '\n'; + } else if (*p == 'r') { + ch = '\r'; + } else if (*p == '0') { + ch = '\0'; + } else if (*p == 't') { + ch = '\t'; + } else if (*p == 'b') { + ch = '\b'; + } else { + ch = *p; + } + } - break; - case ENAMEDFMT: - if (*p != '\\' || iLength < (a + 1)) { - ch = *p; - } else { - a++; - p++; - ch = *p; - } + break; + case ENAMEDFMT: + if (*p != '\\' || iLength < (a + 1)) { + ch = *p; + } else { + a++; + p++; + ch = *p; + } - break; - case EDEBUG: - if (*p == '\\' && (a + 3) < iLength && *(p + 1) == 'x' && - isxdigit(*(p + 2)) && isxdigit(*(p + 3))) { - p += 2; - if (isdigit(*p)) { - ch = (unsigned char)((*p - '0') << 4); - } else { - ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); - } + break; + case EDEBUG: + if (*p == '\\' && (a + 3) < iLength && *(p + 1) == 'x' && + isxdigit(*(p + 2)) && isxdigit(*(p + 3))) { + p += 2; + if (isdigit(*p)) { + ch = (unsigned char)((*p - '0') << 4); + } else { + ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); + } - p++; - if (isdigit(*p)) { - ch |= (unsigned char)(*p - '0'); - } else { - ch |= (unsigned char)(tolower(*p) - 'a' + 10); - } + p++; + if (isdigit(*p)) { + ch |= (unsigned char)(*p - '0'); + } else { + ch |= (unsigned char)(tolower(*p) - 'a' + 10); + } - a += 3; - } else if (*p == '\\' && a + 1 < iLength && *(p + 1) == '.') { - a++; - p++; - ch = '\\'; - } else { - ch = *p; - } + a += 3; + } else if (*p == '\\' && a + 1 < iLength && *(p + 1) == '.') { + a++; + p++; + ch = '\\'; + } else { + ch = *p; + } - break; - case EMSGTAG: - if (*p != '\\' || iLength < (a + 1)) { - ch = *p; - } else { - a++; - p++; + break; + case EMSGTAG: + if (*p != '\\' || iLength < (a + 1)) { + ch = *p; + } else { + a++; + p++; - if (*p == ':') { - ch = ';'; - } else if (*p == 's') { - ch = ' '; - } else if (*p == '0') { - ch = '\0'; - } else if (*p == '\\') { - ch = '\\'; - } else if (*p == 'r') { - ch = '\r'; - } else if (*p == 'n') { - ch = '\n'; - } else { - ch = *p; - } - } + if (*p == ':') { + ch = ';'; + } else if (*p == 's') { + ch = ' '; + } else if (*p == '0') { + ch = '\0'; + } else if (*p == '\\') { + ch = '\\'; + } else if (*p == 'r') { + ch = '\r'; + } else if (*p == 'n') { + ch = '\n'; + } else { + ch = *p; + } + } - break; - case EHEXCOLON: { - while (!isxdigit(*p) && a < iLength) { - a++; - p++; - } - if (a == iLength) { - continue; - } - if (isdigit(*p)) { - ch = (unsigned char)((*p - '0') << 4); - } else { - ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); - } - a++; - p++; - while (!isxdigit(*p) && a < iLength) { - a++; - p++; - } - if (a == iLength) { - continue; - } - if (isdigit(*p)) { - ch |= (unsigned char)(*p - '0'); - } else { - ch |= (unsigned char)(tolower(*p) - 'a' + 10); - } - } break; - } + break; + case EHEXCOLON: { + while (!isxdigit(*p) && a < iLength) { + a++; + p++; + } + if (a == iLength) { + continue; + } + if (isdigit(*p)) { + ch = (unsigned char)((*p - '0') << 4); + } else { + ch = (unsigned char)((tolower(*p) - 'a' + 10) << 4); + } + a++; + p++; + while (!isxdigit(*p) && a < iLength) { + a++; + p++; + } + if (a == iLength) { + continue; + } + if (isdigit(*p)) { + ch |= (unsigned char)(*p - '0'); + } else { + ch |= (unsigned char)(tolower(*p) - 'a' + 10); + } + } break; + } - switch (eTo) { - case EHTML: - if (ch == '<') - sRet += "<"; - else if (ch == '>') - sRet += ">"; - else if (ch == '"') - sRet += """; - else if (ch == '&') - sRet += "&"; - else { - sRet += ch; - } + switch (eTo) { + case EHTML: + if (ch == '<') + sRet += "<"; + else if (ch == '>') + sRet += ">"; + else if (ch == '"') + sRet += """; + else if (ch == '&') + sRet += "&"; + else { + sRet += ch; + } - break; - case EASCII: - sRet += ch; - break; - case EURL: - if (isalnum(ch) || ch == '_' || ch == '.' || ch == '-') { - sRet += ch; - } else if (ch == ' ') { - sRet += '+'; - } else { - sRet += '%'; - sRet += szHex[ch >> 4]; - sRet += szHex[ch & 0xf]; - } + break; + case EASCII: + sRet += ch; + break; + case EURL: + if (isalnum(ch) || ch == '_' || ch == '.' || ch == '-') { + sRet += ch; + } else if (ch == ' ') { + sRet += '+'; + } else { + sRet += '%'; + sRet += szHex[ch >> 4]; + sRet += szHex[ch & 0xf]; + } - break; - case ESQL: - if (ch == '\0') { - sRet += '\\'; - sRet += '0'; - } else if (ch == '\n') { - sRet += '\\'; - sRet += 'n'; - } else if (ch == '\t') { - sRet += '\\'; - sRet += 't'; - } else if (ch == '\r') { - sRet += '\\'; - sRet += 'r'; - } else if (ch == '\b') { - sRet += '\\'; - sRet += 'b'; - } else if (ch == '\"') { - sRet += '\\'; - sRet += '\"'; - } else if (ch == '\'') { - sRet += '\\'; - sRet += '\''; - } else if (ch == '\\') { - sRet += '\\'; - sRet += '\\'; - } else { - sRet += ch; - } + break; + case ESQL: + if (ch == '\0') { + sRet += '\\'; + sRet += '0'; + } else if (ch == '\n') { + sRet += '\\'; + sRet += 'n'; + } else if (ch == '\t') { + sRet += '\\'; + sRet += 't'; + } else if (ch == '\r') { + sRet += '\\'; + sRet += 'r'; + } else if (ch == '\b') { + sRet += '\\'; + sRet += 'b'; + } else if (ch == '\"') { + sRet += '\\'; + sRet += '\"'; + } else if (ch == '\'') { + sRet += '\\'; + sRet += '\''; + } else if (ch == '\\') { + sRet += '\\'; + sRet += '\\'; + } else { + sRet += ch; + } - break; - case ENAMEDFMT: - if (ch == '\\') { - sRet += '\\'; - sRet += '\\'; - } else if (ch == '{') { - sRet += '\\'; - sRet += '{'; - } else if (ch == '}') { - sRet += '\\'; - sRet += '}'; - } else { - sRet += ch; - } + break; + case ENAMEDFMT: + if (ch == '\\') { + sRet += '\\'; + sRet += '\\'; + } else if (ch == '{') { + sRet += '\\'; + sRet += '{'; + } else if (ch == '}') { + sRet += '\\'; + sRet += '}'; + } else { + sRet += ch; + } - break; - case EDEBUG: - if (ch < 0x20 || ch == 0x7F) { - sRet += "\\x"; - sRet += szHex[ch >> 4]; - sRet += szHex[ch & 0xf]; - } else if (ch == '\\') { - sRet += "\\."; - } else { - sRet += ch; - } + break; + case EDEBUG: + if (ch < 0x20 || ch == 0x7F) { + sRet += "\\x"; + sRet += szHex[ch >> 4]; + sRet += szHex[ch & 0xf]; + } else if (ch == '\\') { + sRet += "\\."; + } else { + sRet += ch; + } - break; - case EMSGTAG: - if (ch == ';') { - sRet += '\\'; - sRet += ':'; - } else if (ch == ' ') { - sRet += '\\'; - sRet += 's'; - } else if (ch == '\0') { - sRet += '\\'; - sRet += '0'; - } else if (ch == '\\') { - sRet += '\\'; - sRet += '\\'; - } else if (ch == '\r') { - sRet += '\\'; - sRet += 'r'; - } else if (ch == '\n') { - sRet += '\\'; - sRet += 'n'; - } else { - sRet += ch; - } + break; + case EMSGTAG: + if (ch == ';') { + sRet += '\\'; + sRet += ':'; + } else if (ch == ' ') { + sRet += '\\'; + sRet += 's'; + } else if (ch == '\0') { + sRet += '\\'; + sRet += '0'; + } else if (ch == '\\') { + sRet += '\\'; + sRet += '\\'; + } else if (ch == '\r') { + sRet += '\\'; + sRet += 'r'; + } else if (ch == '\n') { + sRet += '\\'; + sRet += 'n'; + } else { + sRet += ch; + } - break; - case EHEXCOLON: { - sRet += tolower(szHex[ch >> 4]); - sRet += tolower(szHex[ch & 0xf]); - sRet += ":"; - } break; - } - } + break; + case EHEXCOLON: { + sRet += tolower(szHex[ch >> 4]); + sRet += tolower(szHex[ch & 0xf]); + sRet += ":"; + } break; + } + } - if (eTo == EHEXCOLON) { - sRet.TrimRight(":"); - } + if (eTo == EHEXCOLON) { + sRet.TrimRight(":"); + } - return sRet; + return sRet; } CString CString::Escape_n(EEscape eTo) const { return Escape_n(EASCII, eTo); } CString& CString::Escape(EEscape eFrom, EEscape eTo) { - return (*this = Escape_n(eFrom, eTo)); + return (*this = Escape_n(eFrom, eTo)); } CString& CString::Escape(EEscape eTo) { return (*this = Escape_n(eTo)); } @@ -593,850 +593,850 @@ CString& CString::Escape(EEscape eTo) { return (*this = Escape_n(eTo)); } CString CString::Replace_n(const CString& sReplace, const CString& sWith, const CString& sLeft, const CString& sRight, bool bRemoveDelims) const { - CString sRet = *this; - CString::Replace(sRet, sReplace, sWith, sLeft, sRight, bRemoveDelims); - return sRet; + CString sRet = *this; + CString::Replace(sRet, sReplace, sWith, sLeft, sRight, bRemoveDelims); + return sRet; } unsigned int CString::Replace(const CString& sReplace, const CString& sWith, const CString& sLeft, const CString& sRight, bool bRemoveDelims) { - return CString::Replace(*this, sReplace, sWith, sLeft, sRight, - bRemoveDelims); + return CString::Replace(*this, sReplace, sWith, sLeft, sRight, + bRemoveDelims); } unsigned int CString::Replace(CString& sStr, const CString& sReplace, const CString& sWith, const CString& sLeft, const CString& sRight, bool bRemoveDelims) { - unsigned int uRet = 0; - CString sCopy = sStr; - sStr.clear(); + unsigned int uRet = 0; + CString sCopy = sStr; + sStr.clear(); - size_type uReplaceWidth = sReplace.length(); - size_type uLeftWidth = sLeft.length(); - size_type uRightWidth = sRight.length(); - const char* p = sCopy.c_str(); - bool bInside = false; + size_type uReplaceWidth = sReplace.length(); + size_type uLeftWidth = sLeft.length(); + size_type uRightWidth = sRight.length(); + const char* p = sCopy.c_str(); + bool bInside = false; - while (*p) { - if (!bInside && uLeftWidth && - strncmp(p, sLeft.c_str(), uLeftWidth) == 0) { - if (!bRemoveDelims) { - sStr += sLeft; - } + while (*p) { + if (!bInside && uLeftWidth && + strncmp(p, sLeft.c_str(), uLeftWidth) == 0) { + if (!bRemoveDelims) { + sStr += sLeft; + } - p += uLeftWidth - 1; - bInside = true; - } else if (bInside && uRightWidth && - strncmp(p, sRight.c_str(), uRightWidth) == 0) { - if (!bRemoveDelims) { - sStr += sRight; - } + p += uLeftWidth - 1; + bInside = true; + } else if (bInside && uRightWidth && + strncmp(p, sRight.c_str(), uRightWidth) == 0) { + if (!bRemoveDelims) { + sStr += sRight; + } - p += uRightWidth - 1; - bInside = false; - } else if (!bInside && - strncmp(p, sReplace.c_str(), uReplaceWidth) == 0) { - sStr += sWith; - p += uReplaceWidth - 1; - uRet++; - } else { - sStr.append(p, 1); - } + p += uRightWidth - 1; + bInside = false; + } else if (!bInside && + strncmp(p, sReplace.c_str(), uReplaceWidth) == 0) { + sStr += sWith; + p += uReplaceWidth - 1; + uRet++; + } else { + sStr.append(p, 1); + } - p++; - } + p++; + } - return uRet; + return uRet; } CString CString::Token(size_t uPos, bool bRest, const CString& sSep, bool bAllowEmpty, const CString& sLeft, const CString& sRight, bool bTrimQuotes) const { - VCString vsTokens; - if (Split(sSep, vsTokens, bAllowEmpty, sLeft, sRight, bTrimQuotes) > uPos) { - CString sRet; + VCString vsTokens; + if (Split(sSep, vsTokens, bAllowEmpty, sLeft, sRight, bTrimQuotes) > uPos) { + CString sRet; - for (size_t a = uPos; a < vsTokens.size(); a++) { - if (a > uPos) { - sRet += sSep; - } + for (size_t a = uPos; a < vsTokens.size(); a++) { + if (a > uPos) { + sRet += sSep; + } - sRet += vsTokens[a]; + sRet += vsTokens[a]; - if (!bRest) { - break; - } - } + if (!bRest) { + break; + } + } - return sRet; - } + return sRet; + } - return Token(uPos, bRest, sSep, bAllowEmpty); + return Token(uPos, bRest, sSep, bAllowEmpty); } CString CString::Token(size_t uPos, bool bRest, const CString& sSep, bool bAllowEmpty) const { - const char* sep_str = sSep.c_str(); - size_t sep_len = sSep.length(); - const char* str = c_str(); - size_t str_len = length(); - size_t start_pos = 0; - size_t end_pos; + const char* sep_str = sSep.c_str(); + size_t sep_len = sSep.length(); + const char* str = c_str(); + size_t str_len = length(); + size_t start_pos = 0; + size_t end_pos; - if (!bAllowEmpty) { - while (strncmp(&str[start_pos], sep_str, sep_len) == 0) { - start_pos += sep_len; - } - } + if (!bAllowEmpty) { + while (strncmp(&str[start_pos], sep_str, sep_len) == 0) { + start_pos += sep_len; + } + } - // First, find the start of our token - while (uPos != 0 && start_pos < str_len) { - bool bFoundSep = false; + // First, find the start of our token + while (uPos != 0 && start_pos < str_len) { + bool bFoundSep = false; - while (strncmp(&str[start_pos], sep_str, sep_len) == 0 && - (!bFoundSep || !bAllowEmpty)) { - start_pos += sep_len; - bFoundSep = true; - } + while (strncmp(&str[start_pos], sep_str, sep_len) == 0 && + (!bFoundSep || !bAllowEmpty)) { + start_pos += sep_len; + bFoundSep = true; + } - if (bFoundSep) { - uPos--; - } else { - start_pos++; - } - } + if (bFoundSep) { + uPos--; + } else { + start_pos++; + } + } - // String is over? - if (start_pos >= str_len) return ""; + // String is over? + if (start_pos >= str_len) return ""; - // If they want everything from here on, give it to them - if (bRest) { - return substr(start_pos); - } + // If they want everything from here on, give it to them + if (bRest) { + return substr(start_pos); + } - // Now look for the end of the token they want - end_pos = start_pos; - while (end_pos < str_len) { - if (strncmp(&str[end_pos], sep_str, sep_len) == 0) - return substr(start_pos, end_pos - start_pos); + // Now look for the end of the token they want + end_pos = start_pos; + while (end_pos < str_len) { + if (strncmp(&str[end_pos], sep_str, sep_len) == 0) + return substr(start_pos, end_pos - start_pos); - end_pos++; - } + end_pos++; + } - // They want the last token in the string, not something in between - return substr(start_pos); + // They want the last token in the string, not something in between + return substr(start_pos); } CString CString::Ellipsize(unsigned int uLen) const { - if (uLen >= size()) { - return *this; - } + if (uLen >= size()) { + return *this; + } - string sRet; + string sRet; - // @todo this looks suspect - if (uLen < 4) { - for (unsigned int a = 0; a < uLen; a++) { - sRet += "."; - } + // @todo this looks suspect + if (uLen < 4) { + for (unsigned int a = 0; a < uLen; a++) { + sRet += "."; + } - return sRet; - } + return sRet; + } - sRet = substr(0, uLen - 3) + "..."; + sRet = substr(0, uLen - 3) + "..."; - return sRet; + return sRet; } CString CString::Left(size_type uCount) const { - uCount = (uCount > length()) ? length() : uCount; - return substr(0, uCount); + uCount = (uCount > length()) ? length() : uCount; + return substr(0, uCount); } CString CString::Right(size_type uCount) const { - uCount = (uCount > length()) ? length() : uCount; - return substr(length() - uCount, uCount); + uCount = (uCount > length()) ? length() : uCount; + return substr(length() - uCount, uCount); } CString::size_type CString::URLSplit(MCString& msRet) const { - msRet.clear(); + msRet.clear(); - VCString vsPairs; - Split("&", vsPairs); + VCString vsPairs; + Split("&", vsPairs); - for (const CString& sPair : vsPairs) { - msRet[sPair.Token(0, false, "=") - .Escape(CString::EURL, CString::EASCII)] = - sPair.Token(1, true, "=").Escape(CString::EURL, CString::EASCII); - } + for (const CString& sPair : vsPairs) { + msRet[sPair.Token(0, false, "=") + .Escape(CString::EURL, CString::EASCII)] = + sPair.Token(1, true, "=").Escape(CString::EURL, CString::EASCII); + } - return msRet.size(); + return msRet.size(); } CString::size_type CString::OptionSplit(MCString& msRet, bool bUpperKeys) const { - CString sName; - CString sCopy(*this); - msRet.clear(); + CString sName; + CString sCopy(*this); + msRet.clear(); - while (!sCopy.empty()) { - sName = sCopy.Token(0, false, "=", false, "\"", "\"", false).Trim_n(); - sCopy = - sCopy.Token(1, true, "=", false, "\"", "\"", false).TrimLeft_n(); + while (!sCopy.empty()) { + sName = sCopy.Token(0, false, "=", false, "\"", "\"", false).Trim_n(); + sCopy = + sCopy.Token(1, true, "=", false, "\"", "\"", false).TrimLeft_n(); - if (sName.empty()) { - continue; - } + if (sName.empty()) { + continue; + } - VCString vsNames; - sName.Split(" ", vsNames, false, "\"", "\""); + VCString vsNames; + sName.Split(" ", vsNames, false, "\"", "\""); - for (unsigned int a = 0; a < vsNames.size(); a++) { - CString sKeyName = vsNames[a]; + for (unsigned int a = 0; a < vsNames.size(); a++) { + CString sKeyName = vsNames[a]; - if (bUpperKeys) { - sKeyName.MakeUpper(); - } + if (bUpperKeys) { + sKeyName.MakeUpper(); + } - if ((a + 1) == vsNames.size()) { - msRet[sKeyName] = sCopy.Token(0, false, " ", false, "\"", "\""); - sCopy = sCopy.Token(1, true, " ", false, "\"", "\"", false); - } else { - msRet[sKeyName] = ""; - } - } - } + if ((a + 1) == vsNames.size()) { + msRet[sKeyName] = sCopy.Token(0, false, " ", false, "\"", "\""); + sCopy = sCopy.Token(1, true, " ", false, "\"", "\"", false); + } else { + msRet[sKeyName] = ""; + } + } + } - return msRet.size(); + return msRet.size(); } CString::size_type CString::QuoteSplit(VCString& vsRet) const { - vsRet.clear(); - return Split(" ", vsRet, false, "\"", "\"", true); + vsRet.clear(); + return Split(" ", vsRet, false, "\"", "\"", true); } CString::size_type CString::Split(const CString& sDelim, VCString& vsRet, bool bAllowEmpty, const CString& sLeft, const CString& sRight, bool bTrimQuotes, bool bTrimWhiteSpace) const { - vsRet.clear(); + vsRet.clear(); - if (empty()) { - return 0; - } + if (empty()) { + return 0; + } - CString sTmp; - bool bInside = false; - size_type uDelimLen = sDelim.length(); - size_type uLeftLen = sLeft.length(); - size_type uRightLen = sRight.length(); - const char* p = c_str(); + CString sTmp; + bool bInside = false; + size_type uDelimLen = sDelim.length(); + size_type uLeftLen = sLeft.length(); + size_type uRightLen = sRight.length(); + const char* p = c_str(); - if (!bAllowEmpty) { - while (strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { - p += uDelimLen; - } - } + if (!bAllowEmpty) { + while (strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { + p += uDelimLen; + } + } - while (*p) { - if (uLeftLen && uRightLen && !bInside && - strncasecmp(p, sLeft.c_str(), uLeftLen) == 0) { - if (!bTrimQuotes) { - sTmp += sLeft; - } + while (*p) { + if (uLeftLen && uRightLen && !bInside && + strncasecmp(p, sLeft.c_str(), uLeftLen) == 0) { + if (!bTrimQuotes) { + sTmp += sLeft; + } - p += uLeftLen; - bInside = true; - continue; - } + p += uLeftLen; + bInside = true; + continue; + } - if (uLeftLen && uRightLen && bInside && - strncasecmp(p, sRight.c_str(), uRightLen) == 0) { - if (!bTrimQuotes) { - sTmp += sRight; - } + if (uLeftLen && uRightLen && bInside && + strncasecmp(p, sRight.c_str(), uRightLen) == 0) { + if (!bTrimQuotes) { + sTmp += sRight; + } - p += uRightLen; - bInside = false; - continue; - } + p += uRightLen; + bInside = false; + continue; + } - if (uDelimLen && !bInside && - strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { - if (bTrimWhiteSpace) { - sTmp.Trim(); - } + if (uDelimLen && !bInside && + strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { + if (bTrimWhiteSpace) { + sTmp.Trim(); + } - vsRet.push_back(sTmp); - sTmp.clear(); - p += uDelimLen; + vsRet.push_back(sTmp); + sTmp.clear(); + p += uDelimLen; - if (!bAllowEmpty) { - while (strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { - p += uDelimLen; - } - } + if (!bAllowEmpty) { + while (strncasecmp(p, sDelim.c_str(), uDelimLen) == 0) { + p += uDelimLen; + } + } - bInside = false; - continue; - } else { - sTmp += *p; - } + bInside = false; + continue; + } else { + sTmp += *p; + } - p++; - } + p++; + } - if (!sTmp.empty()) { - if (bTrimWhiteSpace) { - sTmp.Trim(); - } + if (!sTmp.empty()) { + if (bTrimWhiteSpace) { + sTmp.Trim(); + } - vsRet.push_back(sTmp); - } + vsRet.push_back(sTmp); + } - return vsRet.size(); + return vsRet.size(); } CString::size_type CString::Split(const CString& sDelim, SCString& ssRet, bool bAllowEmpty, const CString& sLeft, const CString& sRight, bool bTrimQuotes, bool bTrimWhiteSpace) const { - VCString vsTokens; + VCString vsTokens; - Split(sDelim, vsTokens, bAllowEmpty, sLeft, sRight, bTrimQuotes, - bTrimWhiteSpace); + Split(sDelim, vsTokens, bAllowEmpty, sLeft, sRight, bTrimQuotes, + bTrimWhiteSpace); - ssRet.clear(); + ssRet.clear(); - for (const CString& sToken : vsTokens) { - ssRet.insert(sToken); - } + for (const CString& sToken : vsTokens) { + ssRet.insert(sToken); + } - return ssRet.size(); + return ssRet.size(); } CString CString::NamedFormat(const CString& sFormat, const MCString& msValues) { - CString sRet; + CString sRet; - CString sKey; - bool bEscape = false; - bool bParam = false; - const char* p = sFormat.c_str(); + CString sKey; + bool bEscape = false; + bool bParam = false; + const char* p = sFormat.c_str(); - while (*p) { - if (!bParam) { - if (bEscape) { - sRet += *p; - bEscape = false; - } else if (*p == '\\') { - bEscape = true; - } else if (*p == '{') { - bParam = true; - sKey.clear(); - } else { - sRet += *p; - } + while (*p) { + if (!bParam) { + if (bEscape) { + sRet += *p; + bEscape = false; + } else if (*p == '\\') { + bEscape = true; + } else if (*p == '{') { + bParam = true; + sKey.clear(); + } else { + sRet += *p; + } - } else { - if (bEscape) { - sKey += *p; - bEscape = false; - } else if (*p == '\\') { - bEscape = true; - } else if (*p == '}') { - bParam = false; - MCString::const_iterator it = msValues.find(sKey); - if (it != msValues.end()) { - sRet += (*it).second; - } - } else { - sKey += *p; - } - } + } else { + if (bEscape) { + sKey += *p; + bEscape = false; + } else if (*p == '\\') { + bEscape = true; + } else if (*p == '}') { + bParam = false; + MCString::const_iterator it = msValues.find(sKey); + if (it != msValues.end()) { + sRet += (*it).second; + } + } else { + sKey += *p; + } + } - p++; - } + p++; + } - return sRet; + return sRet; } CString CString::RandomString(unsigned int uLength) { - const char chars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!?.,:;/*-+_()"; - // -1 because sizeof() includes the trailing '\0' byte - const size_t len = sizeof(chars) / sizeof(chars[0]) - 1; - size_t p; - CString sRet; + const char chars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789!?.,:;/*-+_()"; + // -1 because sizeof() includes the trailing '\0' byte + const size_t len = sizeof(chars) / sizeof(chars[0]) - 1; + size_t p; + CString sRet; - for (unsigned int a = 0; a < uLength; a++) { - p = (size_t)(len * (rand() / (RAND_MAX + 1.0))); - sRet += chars[p]; - } + for (unsigned int a = 0; a < uLength; a++) { + p = (size_t)(len * (rand() / (RAND_MAX + 1.0))); + sRet += chars[p]; + } - return sRet; + return sRet; } bool CString::Base64Encode(unsigned int uWrap) { - CString sCopy(*this); - return sCopy.Base64Encode(*this, uWrap); + CString sCopy(*this); + return sCopy.Base64Encode(*this, uWrap); } unsigned long CString::Base64Decode() { - CString sCopy(*this); - return sCopy.Base64Decode(*this); + CString sCopy(*this); + return sCopy.Base64Decode(*this); } CString CString::Base64Encode_n(unsigned int uWrap) const { - CString sRet; - Base64Encode(sRet, uWrap); - return sRet; + CString sRet; + Base64Encode(sRet, uWrap); + return sRet; } CString CString::Base64Decode_n() const { - CString sRet; - Base64Decode(sRet); - return sRet; + CString sRet; + Base64Decode(sRet); + return sRet; } bool CString::Base64Encode(CString& sRet, unsigned int uWrap) const { - const char b64table[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - sRet.clear(); - size_t len = size(); - const unsigned char* input = (const unsigned char*)c_str(); - unsigned char* output, *p; - size_t i = 0, mod = len % 3, toalloc; - toalloc = (len / 3) * 4 + (3 - mod) % 3 + 1 + 8; + const char b64table[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + sRet.clear(); + size_t len = size(); + const unsigned char* input = (const unsigned char*)c_str(); + unsigned char* output, *p; + size_t i = 0, mod = len % 3, toalloc; + toalloc = (len / 3) * 4 + (3 - mod) % 3 + 1 + 8; - if (uWrap) { - toalloc += len / 57; - if (len % 57) { - toalloc++; - } - } + if (uWrap) { + toalloc += len / 57; + if (len % 57) { + toalloc++; + } + } - if (toalloc < len) { - return 0; - } + if (toalloc < len) { + return 0; + } - p = output = new unsigned char[toalloc]; + p = output = new unsigned char[toalloc]; - while (i < len - mod) { - *p++ = b64table[input[i++] >> 2]; - *p++ = b64table[((input[i - 1] << 4) | (input[i] >> 4)) & 0x3f]; - *p++ = b64table[((input[i] << 2) | (input[i + 1] >> 6)) & 0x3f]; - *p++ = b64table[input[i + 1] & 0x3f]; - i += 2; + while (i < len - mod) { + *p++ = b64table[input[i++] >> 2]; + *p++ = b64table[((input[i - 1] << 4) | (input[i] >> 4)) & 0x3f]; + *p++ = b64table[((input[i] << 2) | (input[i + 1] >> 6)) & 0x3f]; + *p++ = b64table[input[i + 1] & 0x3f]; + i += 2; - if (uWrap && !(i % 57)) { - *p++ = '\n'; - } - } + if (uWrap && !(i % 57)) { + *p++ = '\n'; + } + } - if (!mod) { - if (uWrap && i % 57) { - *p++ = '\n'; - } - } else { - *p++ = b64table[input[i++] >> 2]; - *p++ = b64table[((input[i - 1] << 4) | (input[i] >> 4)) & 0x3f]; - if (mod == 1) { - *p++ = '='; - } else { - *p++ = b64table[(input[i] << 2) & 0x3f]; - } + if (!mod) { + if (uWrap && i % 57) { + *p++ = '\n'; + } + } else { + *p++ = b64table[input[i++] >> 2]; + *p++ = b64table[((input[i - 1] << 4) | (input[i] >> 4)) & 0x3f]; + if (mod == 1) { + *p++ = '='; + } else { + *p++ = b64table[(input[i] << 2) & 0x3f]; + } - *p++ = '='; + *p++ = '='; - if (uWrap) { - *p++ = '\n'; - } - } + if (uWrap) { + *p++ = '\n'; + } + } - *p = 0; - sRet = (char*)output; - delete[] output; - return true; + *p = 0; + sRet = (char*)output; + delete[] output; + return true; } unsigned long CString::Base64Decode(CString& sRet) const { - CString sTmp(*this); - // remove new lines - sTmp.Replace("\r", ""); - sTmp.Replace("\n", ""); + CString sTmp(*this); + // remove new lines + sTmp.Replace("\r", ""); + sTmp.Replace("\n", ""); - const char* in = sTmp.c_str(); - char c, c1, *p; - unsigned long i; - unsigned long uLen = sTmp.size(); - char* out = new char[uLen + 1]; + const char* in = sTmp.c_str(); + char c, c1, *p; + unsigned long i; + unsigned long uLen = sTmp.size(); + char* out = new char[uLen + 1]; - for (i = 0, p = out; i < uLen; i++) { - c = (char)base64_table[(unsigned char)in[i++]]; - c1 = (char)base64_table[(unsigned char)in[i++]]; - *p++ = char((c << 2) | ((c1 >> 4) & 0x3)); + for (i = 0, p = out; i < uLen; i++) { + c = (char)base64_table[(unsigned char)in[i++]]; + c1 = (char)base64_table[(unsigned char)in[i++]]; + *p++ = char((c << 2) | ((c1 >> 4) & 0x3)); - if (i < uLen) { - if (in[i] == '=') { - break; - } - c = (char)base64_table[(unsigned char)in[i]]; - *p++ = char(((c1 << 4) & 0xf0) | ((c >> 2) & 0xf)); - } + if (i < uLen) { + if (in[i] == '=') { + break; + } + c = (char)base64_table[(unsigned char)in[i]]; + *p++ = char(((c1 << 4) & 0xf0) | ((c >> 2) & 0xf)); + } - if (++i < uLen) { - if (in[i] == '=') { - break; - } - *p++ = char(((c << 6) & 0xc0) | - (char)base64_table[(unsigned char)in[i]]); - } - } + if (++i < uLen) { + if (in[i] == '=') { + break; + } + *p++ = char(((c << 6) & 0xc0) | + (char)base64_table[(unsigned char)in[i]]); + } + } - *p = '\0'; - unsigned long uRet = p - out; - sRet.clear(); - sRet.append(out, uRet); - delete[] out; + *p = '\0'; + unsigned long uRet = p - out; + sRet.clear(); + sRet.append(out, uRet); + delete[] out; - return uRet; + return uRet; } CString CString::MD5() const { return (const char*)CMD5(*this); } CString CString::SHA256() const { - unsigned char digest[SHA256_DIGEST_SIZE]; - char digest_hex[SHA256_DIGEST_SIZE * 2 + 1]; - const unsigned char* message = (const unsigned char*)c_str(); + unsigned char digest[SHA256_DIGEST_SIZE]; + char digest_hex[SHA256_DIGEST_SIZE * 2 + 1]; + const unsigned char* message = (const unsigned char*)c_str(); - sha256(message, length(), digest); + sha256(message, length(), digest); - snprintf(digest_hex, sizeof(digest_hex), - "%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x%02x%02x", - digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], - digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], - digest[12], digest[13], digest[14], digest[15], digest[16], - digest[17], digest[18], digest[19], digest[20], digest[21], - digest[22], digest[23], digest[24], digest[25], digest[26], - digest[27], digest[28], digest[29], digest[30], digest[31]); + snprintf(digest_hex, sizeof(digest_hex), + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x", + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], + digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], + digest[12], digest[13], digest[14], digest[15], digest[16], + digest[17], digest[18], digest[19], digest[20], digest[21], + digest[22], digest[23], digest[24], digest[25], digest[26], + digest[27], digest[28], digest[29], digest[30], digest[31]); - return digest_hex; + return digest_hex; } #ifdef HAVE_LIBSSL CString CString::Encrypt_n(const CString& sPass, const CString& sIvec) const { - CString sRet; - sRet.Encrypt(sPass, sIvec); - return sRet; + CString sRet; + sRet.Encrypt(sPass, sIvec); + return sRet; } CString CString::Decrypt_n(const CString& sPass, const CString& sIvec) const { - CString sRet; - sRet.Decrypt(sPass, sIvec); - return sRet; + CString sRet; + sRet.Decrypt(sPass, sIvec); + return sRet; } void CString::Encrypt(const CString& sPass, const CString& sIvec) { - Crypt(sPass, true, sIvec); + Crypt(sPass, true, sIvec); } void CString::Decrypt(const CString& sPass, const CString& sIvec) { - Crypt(sPass, false, sIvec); + Crypt(sPass, false, sIvec); } void CString::Crypt(const CString& sPass, bool bEncrypt, const CString& sIvec) { - unsigned char szIvec[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - BF_KEY bKey; + unsigned char szIvec[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + BF_KEY bKey; - if (sIvec.length() >= 8) { - memcpy(szIvec, sIvec.data(), 8); - } + if (sIvec.length() >= 8) { + memcpy(szIvec, sIvec.data(), 8); + } - BF_set_key(&bKey, (unsigned int)sPass.length(), - (unsigned char*)sPass.data()); - unsigned int uPad = (length() % 8); + BF_set_key(&bKey, (unsigned int)sPass.length(), + (unsigned char*)sPass.data()); + unsigned int uPad = (length() % 8); - if (uPad) { - uPad = 8 - uPad; - append(uPad, '\0'); - } + if (uPad) { + uPad = 8 - uPad; + append(uPad, '\0'); + } - size_t uLen = length(); - unsigned char* szBuff = (unsigned char*)malloc(uLen); - BF_cbc_encrypt((const unsigned char*)data(), szBuff, uLen, &bKey, szIvec, - ((bEncrypt) ? BF_ENCRYPT : BF_DECRYPT)); + size_t uLen = length(); + unsigned char* szBuff = (unsigned char*)malloc(uLen); + BF_cbc_encrypt((const unsigned char*)data(), szBuff, uLen, &bKey, szIvec, + ((bEncrypt) ? BF_ENCRYPT : BF_DECRYPT)); - clear(); - append((const char*)szBuff, uLen); - free(szBuff); + clear(); + append((const char*)szBuff, uLen); + free(szBuff); } #endif // HAVE_LIBSSL CString CString::ToPercent(double d) { - char szRet[32]; - snprintf(szRet, 32, "%.02f%%", d); - return szRet; + char szRet[32]; + snprintf(szRet, 32, "%.02f%%", d); + return szRet; } CString CString::ToByteStr(unsigned long long d) { - const unsigned long long KiB = 1024; - const unsigned long long MiB = KiB * 1024; - const unsigned long long GiB = MiB * 1024; - const unsigned long long TiB = GiB * 1024; + const unsigned long long KiB = 1024; + const unsigned long long MiB = KiB * 1024; + const unsigned long long GiB = MiB * 1024; + const unsigned long long TiB = GiB * 1024; - if (d > TiB) { - return CString(d / TiB) + " TiB"; - } else if (d > GiB) { - return CString(d / GiB) + " GiB"; - } else if (d > MiB) { - return CString(d / MiB) + " MiB"; - } else if (d > KiB) { - return CString(d / KiB) + " KiB"; - } + if (d > TiB) { + return CString(d / TiB) + " TiB"; + } else if (d > GiB) { + return CString(d / GiB) + " GiB"; + } else if (d > MiB) { + return CString(d / MiB) + " MiB"; + } else if (d > KiB) { + return CString(d / KiB) + " KiB"; + } - return CString(d) + " B"; + return CString(d) + " B"; } CString CString::ToTimeStr(unsigned long s) { - const unsigned long m = 60; - const unsigned long h = m * 60; - const unsigned long d = h * 24; - const unsigned long w = d * 7; - const unsigned long y = d * 365; - CString sRet; + const unsigned long m = 60; + const unsigned long h = m * 60; + const unsigned long d = h * 24; + const unsigned long w = d * 7; + const unsigned long y = d * 365; + CString sRet; #define TIMESPAN(time, str) \ - if (s >= time) { \ - sRet += CString(s / time) + str " "; \ - s = s % time; \ - } - TIMESPAN(y, "y"); - TIMESPAN(w, "w"); - TIMESPAN(d, "d"); - TIMESPAN(h, "h"); - TIMESPAN(m, "m"); - TIMESPAN(1, "s"); + if (s >= time) { \ + sRet += CString(s / time) + str " "; \ + s = s % time; \ + } + TIMESPAN(y, "y"); + TIMESPAN(w, "w"); + TIMESPAN(d, "d"); + TIMESPAN(h, "h"); + TIMESPAN(m, "m"); + TIMESPAN(1, "s"); - if (sRet.empty()) return "0s"; + if (sRet.empty()) return "0s"; - return sRet.RightChomp_n(); + return sRet.RightChomp_n(); } bool CString::ToBool() const { - CString sTrimmed = Trim_n(); - return (!sTrimmed.Trim_n("0").empty() && !sTrimmed.Equals("false") && - !sTrimmed.Equals("off") && !sTrimmed.Equals("no") && - !sTrimmed.Equals("n")); + CString sTrimmed = Trim_n(); + return (!sTrimmed.Trim_n("0").empty() && !sTrimmed.Equals("false") && + !sTrimmed.Equals("off") && !sTrimmed.Equals("no") && + !sTrimmed.Equals("n")); } short CString::ToShort() const { - return (short int)strtol(this->c_str(), (char**)nullptr, 10); + return (short int)strtol(this->c_str(), (char**)nullptr, 10); } unsigned short CString::ToUShort() const { - return (unsigned short int)strtoul(this->c_str(), (char**)nullptr, 10); + return (unsigned short int)strtoul(this->c_str(), (char**)nullptr, 10); } unsigned int CString::ToUInt() const { - return (unsigned int)strtoul(this->c_str(), (char**)nullptr, 10); + return (unsigned int)strtoul(this->c_str(), (char**)nullptr, 10); } int CString::ToInt() const { - return (int)strtol(this->c_str(), (char**)nullptr, 10); + return (int)strtol(this->c_str(), (char**)nullptr, 10); } long CString::ToLong() const { - return strtol(this->c_str(), (char**)nullptr, 10); + return strtol(this->c_str(), (char**)nullptr, 10); } unsigned long CString::ToULong() const { return strtoul(c_str(), nullptr, 10); } unsigned long long CString::ToULongLong() const { - return strtoull(c_str(), nullptr, 10); + return strtoull(c_str(), nullptr, 10); } long long CString::ToLongLong() const { return strtoll(c_str(), nullptr, 10); } double CString::ToDouble() const { return strtod(c_str(), nullptr); } bool CString::Trim(const CString& s) { - bool bLeft = TrimLeft(s); - return (TrimRight(s) || bLeft); + bool bLeft = TrimLeft(s); + return (TrimRight(s) || bLeft); } bool CString::TrimLeft(const CString& s) { - size_type i = find_first_not_of(s); + size_type i = find_first_not_of(s); - if (i == 0) return false; + if (i == 0) return false; - if (i != npos) - this->erase(0, i); - else - this->clear(); + if (i != npos) + this->erase(0, i); + else + this->clear(); - return true; + return true; } bool CString::TrimRight(const CString& s) { - size_type i = find_last_not_of(s); + size_type i = find_last_not_of(s); - if (i + 1 == length()) return false; + if (i + 1 == length()) return false; - if (i != npos) - this->erase(i + 1, npos); - else - this->clear(); + if (i != npos) + this->erase(i + 1, npos); + else + this->clear(); - return true; + return true; } CString CString::Trim_n(const CString& s) const { - CString sRet = *this; - sRet.Trim(s); - return sRet; + CString sRet = *this; + sRet.Trim(s); + return sRet; } CString CString::TrimLeft_n(const CString& s) const { - CString sRet = *this; - sRet.TrimLeft(s); - return sRet; + CString sRet = *this; + sRet.TrimLeft(s); + return sRet; } CString CString::TrimRight_n(const CString& s) const { - CString sRet = *this; - sRet.TrimRight(s); - return sRet; + CString sRet = *this; + sRet.TrimRight(s); + return sRet; } bool CString::TrimPrefix(const CString& sPrefix) { - if (StartsWith(sPrefix)) { - LeftChomp(sPrefix.length()); - return true; - } else { - return false; - } + if (StartsWith(sPrefix)) { + LeftChomp(sPrefix.length()); + return true; + } else { + return false; + } } bool CString::TrimSuffix(const CString& sSuffix) { - if (Right(sSuffix.length()).Equals(sSuffix)) { - RightChomp(sSuffix.length()); - return true; - } else { - return false; - } + if (Right(sSuffix.length()).Equals(sSuffix)) { + RightChomp(sSuffix.length()); + return true; + } else { + return false; + } } size_t CString::Find(const CString& s, CaseSensitivity cs) const { - if (cs == CaseSensitive) { - return find(s); - } else { - return AsLower().find(s.AsLower()); - } + if (cs == CaseSensitive) { + return find(s); + } else { + return AsLower().find(s.AsLower()); + } } bool CString::StartsWith(const CString& sPrefix, CaseSensitivity cs) const { - return Left(sPrefix.length()).Equals(sPrefix, cs); + return Left(sPrefix.length()).Equals(sPrefix, cs); } bool CString::EndsWith(const CString& sSuffix, CaseSensitivity cs) const { - return Right(sSuffix.length()).Equals(sSuffix, cs); + return Right(sSuffix.length()).Equals(sSuffix, cs); } bool CString::Contains(const CString& s, CaseSensitivity cs) const { - return Find(s, cs) != npos; + return Find(s, cs) != npos; } CString CString::TrimPrefix_n(const CString& sPrefix) const { - CString sRet = *this; - sRet.TrimPrefix(sPrefix); - return sRet; + CString sRet = *this; + sRet.TrimPrefix(sPrefix); + return sRet; } CString CString::TrimSuffix_n(const CString& sSuffix) const { - CString sRet = *this; - sRet.TrimSuffix(sSuffix); - return sRet; + CString sRet = *this; + sRet.TrimSuffix(sSuffix); + return sRet; } CString CString::LeftChomp_n(size_type uLen) const { - CString sRet = *this; - sRet.LeftChomp(uLen); - return sRet; + CString sRet = *this; + sRet.LeftChomp(uLen); + return sRet; } CString CString::RightChomp_n(size_type uLen) const { - CString sRet = *this; - sRet.RightChomp(uLen); - return sRet; + CString sRet = *this; + sRet.RightChomp(uLen); + return sRet; } bool CString::LeftChomp(size_type uLen) { - bool bRet = false; + bool bRet = false; - while ((uLen--) && (length())) { - erase(0, 1); - bRet = true; - } + while ((uLen--) && (length())) { + erase(0, 1); + bRet = true; + } - return bRet; + return bRet; } bool CString::RightChomp(size_type uLen) { - bool bRet = false; + bool bRet = false; - while ((uLen--) && (length())) { - erase(length() - 1); - bRet = true; - } + while ((uLen--) && (length())) { + erase(length() - 1); + bRet = true; + } - return bRet; + return bRet; } CString CString::StripControls_n() const { - CString sRet; - const unsigned char* pStart = (const unsigned char*)data(); - unsigned char ch = *pStart; - size_type iLength = length(); - sRet.reserve(iLength); - bool colorCode = false; - unsigned int digits = 0; - bool comma = false; + CString sRet; + const unsigned char* pStart = (const unsigned char*)data(); + unsigned char ch = *pStart; + size_type iLength = length(); + sRet.reserve(iLength); + bool colorCode = false; + unsigned int digits = 0; + bool comma = false; - for (unsigned int a = 0; a < iLength; a++, ch = pStart[a]) { - // Color code. Format: \x03([0-9]{1,2}(,[0-9]{1,2})?)? - if (ch == 0x03) { - colorCode = true; - digits = 0; - comma = false; - continue; - } - if (colorCode) { - if (isdigit(ch) && digits < 2) { - digits++; - continue; - } - if (ch == ',' && !comma && digits > 0) { - comma = true; - digits = 0; - continue; - } + for (unsigned int a = 0; a < iLength; a++, ch = pStart[a]) { + // Color code. Format: \x03([0-9]{1,2}(,[0-9]{1,2})?)? + if (ch == 0x03) { + colorCode = true; + digits = 0; + comma = false; + continue; + } + if (colorCode) { + if (isdigit(ch) && digits < 2) { + digits++; + continue; + } + if (ch == ',' && !comma && digits > 0) { + comma = true; + digits = 0; + continue; + } - colorCode = false; + colorCode = false; - if (digits == 0 && comma) { - // There was a ',' which wasn't followed by digits, we should - // print it. - sRet += ','; - } - } - // CO controls codes - if (ch < 0x20 || ch == 0x7F) continue; - sRet += ch; - } - if (colorCode && digits == 0 && comma) { - sRet += ','; - } + if (digits == 0 && comma) { + // There was a ',' which wasn't followed by digits, we should + // print it. + sRet += ','; + } + } + // CO controls codes + if (ch < 0x20 || ch == 0x7F) continue; + sRet += ch; + } + if (colorCode && digits == 0 && comma) { + sRet += ','; + } - sRet.reserve(0); - return sRet; + sRet.reserve(0); + return sRet; } CString& CString::StripControls() { return (*this = StripControls_n()); } @@ -1446,102 +1446,102 @@ const MCString MCString::EmptyMap; MCString::status_t MCString::WriteToDisk(const CString& sPath, mode_t iMode) const { - CFile cFile(sPath); + CFile cFile(sPath); - if (this->empty()) { - if (!cFile.Exists()) return MCS_SUCCESS; - if (cFile.Delete()) return MCS_SUCCESS; - } + if (this->empty()) { + if (!cFile.Exists()) return MCS_SUCCESS; + if (cFile.Delete()) return MCS_SUCCESS; + } - if (!cFile.Open(O_WRONLY | O_CREAT | O_TRUNC, iMode)) { - return MCS_EOPEN; - } + if (!cFile.Open(O_WRONLY | O_CREAT | O_TRUNC, iMode)) { + return MCS_EOPEN; + } - for (const auto& it : *this) { - CString sKey = it.first; - CString sValue = it.second; - if (!WriteFilter(sKey, sValue)) { - return MCS_EWRITEFIL; - } + for (const auto& it : *this) { + CString sKey = it.first; + CString sValue = it.second; + if (!WriteFilter(sKey, sValue)) { + return MCS_EWRITEFIL; + } - if (sKey.empty()) { - continue; - } + if (sKey.empty()) { + continue; + } - if (cFile.Write(Encode(sKey) + " " + Encode(sValue) + "\n") <= 0) { - return MCS_EWRITE; - } - } + if (cFile.Write(Encode(sKey) + " " + Encode(sValue) + "\n") <= 0) { + return MCS_EWRITE; + } + } - cFile.Close(); + cFile.Close(); - return MCS_SUCCESS; + return MCS_SUCCESS; } MCString::status_t MCString::ReadFromDisk(const CString& sPath) { - clear(); - CFile cFile(sPath); - if (!cFile.Open(O_RDONLY)) { - return MCS_EOPEN; - } + clear(); + CFile cFile(sPath); + if (!cFile.Open(O_RDONLY)) { + return MCS_EOPEN; + } - CString sBuffer; + CString sBuffer; - while (cFile.ReadLine(sBuffer)) { - sBuffer.Trim(); - CString sKey = sBuffer.Token(0); - CString sValue = sBuffer.Token(1); - Decode(sKey); - Decode(sValue); + while (cFile.ReadLine(sBuffer)) { + sBuffer.Trim(); + CString sKey = sBuffer.Token(0); + CString sValue = sBuffer.Token(1); + Decode(sKey); + Decode(sValue); - if (!ReadFilter(sKey, sValue)) return MCS_EREADFIL; + if (!ReadFilter(sKey, sValue)) return MCS_EREADFIL; - (*this)[sKey] = sValue; - } - cFile.Close(); + (*this)[sKey] = sValue; + } + cFile.Close(); - return MCS_SUCCESS; + return MCS_SUCCESS; } static const char hexdigits[] = "0123456789abcdef"; CString& MCString::Encode(CString& sValue) const { - CString sTmp; - for (unsigned char c : sValue) { - // isalnum() needs unsigned char as argument and this code - // assumes unsigned, too. - if (isalnum(c)) { - sTmp += c; - } else { - sTmp += "%"; - sTmp += hexdigits[c >> 4]; - sTmp += hexdigits[c & 0xf]; - sTmp += ";"; - } - } - sValue = sTmp; - return sValue; + CString sTmp; + for (unsigned char c : sValue) { + // isalnum() needs unsigned char as argument and this code + // assumes unsigned, too. + if (isalnum(c)) { + sTmp += c; + } else { + sTmp += "%"; + sTmp += hexdigits[c >> 4]; + sTmp += hexdigits[c & 0xf]; + sTmp += ";"; + } + } + sValue = sTmp; + return sValue; } CString& MCString::Decode(CString& sValue) const { - const char* pTmp = sValue.c_str(); - char* endptr; - CString sTmp; + const char* pTmp = sValue.c_str(); + char* endptr; + CString sTmp; - while (*pTmp) { - if (*pTmp != '%') { - sTmp += *pTmp++; - } else { - char ch = (char)strtol(pTmp + 1, &endptr, 16); - if (*endptr == ';') { - sTmp += ch; - pTmp = ++endptr; - } else { - sTmp += *pTmp++; - } - } - } + while (*pTmp) { + if (*pTmp != '%') { + sTmp += *pTmp++; + } else { + char ch = (char)strtol(pTmp + 1, &endptr, 16); + if (*endptr == ';') { + sTmp += ch; + pTmp = ++endptr; + } else { + sTmp += *pTmp++; + } + } + } - sValue = sTmp; - return sValue; + sValue = sTmp; + return sValue; } diff --git a/src/main.cpp b/src/main.cpp index 46935974..861d9dbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,51 +27,51 @@ static std::vector> lock_cs; static void locking_callback(int mode, int type, const char* file, int line) { - if (mode & CRYPTO_LOCK) { - lock_cs[type]->lock(); - } else { - lock_cs[type]->unlock(); - } + if (mode & CRYPTO_LOCK) { + lock_cs[type]->lock(); + } else { + lock_cs[type]->unlock(); + } } static unsigned long thread_id_callback() { - return (unsigned long)pthread_self(); + return (unsigned long)pthread_self(); } static CRYPTO_dynlock_value* dyn_create_callback(const char* file, int line) { - return (CRYPTO_dynlock_value*)new CMutex; + return (CRYPTO_dynlock_value*)new CMutex; } static void dyn_lock_callback(int mode, CRYPTO_dynlock_value* dlock, const char* file, int line) { - CMutex* mtx = (CMutex*)dlock; + CMutex* mtx = (CMutex*)dlock; - if (mode & CRYPTO_LOCK) { - mtx->lock(); - } else { - mtx->unlock(); - } + if (mode & CRYPTO_LOCK) { + mtx->lock(); + } else { + mtx->unlock(); + } } static void dyn_destroy_callback(CRYPTO_dynlock_value* dlock, const char* file, int line) { - CMutex* mtx = (CMutex*)dlock; + CMutex* mtx = (CMutex*)dlock; - delete mtx; + delete mtx; } static void thread_setup() { - lock_cs.resize(CRYPTO_num_locks()); + lock_cs.resize(CRYPTO_num_locks()); - for (std::unique_ptr& mtx : lock_cs) - mtx = std::unique_ptr(new CMutex()); + for (std::unique_ptr& mtx : lock_cs) + mtx = std::unique_ptr(new CMutex()); - CRYPTO_set_id_callback(&thread_id_callback); - CRYPTO_set_locking_callback(&locking_callback); + CRYPTO_set_id_callback(&thread_id_callback); + CRYPTO_set_locking_callback(&locking_callback); - CRYPTO_set_dynlock_create_callback(&dyn_create_callback); - CRYPTO_set_dynlock_lock_callback(&dyn_lock_callback); - CRYPTO_set_dynlock_destroy_callback(&dyn_destroy_callback); + CRYPTO_set_dynlock_create_callback(&dyn_create_callback); + CRYPTO_set_dynlock_lock_callback(&dyn_lock_callback); + CRYPTO_set_dynlock_destroy_callback(&dyn_destroy_callback); } #else @@ -90,16 +90,16 @@ using std::set; #define optional_argument 2 struct option { - const char* a; - int opt; - int* flag; - int val; + const char* a; + int opt; + int* flag; + int val; }; static inline int getopt_long(int argc, char* const argv[], const char* optstring, const struct option*, int*) { - return getopt(argc, argv, optstring); + return getopt(argc, argv, optstring); } #endif @@ -117,400 +117,400 @@ static const struct option g_LongOpts[] = { {nullptr, 0, nullptr, 0}}; static void GenerateHelp(const char* appname) { - CUtils::PrintMessage("USAGE: " + CString(appname) + " [options]"); - CUtils::PrintMessage("Options are:"); - CUtils::PrintMessage( - "\t-h, --help List available command line options (this page)"); - CUtils::PrintMessage( - "\t-v, --version Output version information and exit"); - CUtils::PrintMessage("\t-f, --foreground Don't fork into the background"); - CUtils::PrintMessage( - "\t-D, --debug Output debugging information (Implies -f)"); - CUtils::PrintMessage( - "\t-n, --no-color Don't use escape sequences in the output"); - CUtils::PrintMessage( - "\t-r, --allow-root Don't complain if ZNC is run as root"); - CUtils::PrintMessage( - "\t-c, --makeconf Interactively create a new config"); - CUtils::PrintMessage( - "\t-s, --makepass Generates a password for use in config"); + CUtils::PrintMessage("USAGE: " + CString(appname) + " [options]"); + CUtils::PrintMessage("Options are:"); + CUtils::PrintMessage( + "\t-h, --help List available command line options (this page)"); + CUtils::PrintMessage( + "\t-v, --version Output version information and exit"); + CUtils::PrintMessage("\t-f, --foreground Don't fork into the background"); + CUtils::PrintMessage( + "\t-D, --debug Output debugging information (Implies -f)"); + CUtils::PrintMessage( + "\t-n, --no-color Don't use escape sequences in the output"); + CUtils::PrintMessage( + "\t-r, --allow-root Don't complain if ZNC is run as root"); + CUtils::PrintMessage( + "\t-c, --makeconf Interactively create a new config"); + CUtils::PrintMessage( + "\t-s, --makepass Generates a password for use in config"); #ifdef HAVE_LIBSSL - CUtils::PrintMessage( - "\t-p, --makepem Generates a pemfile for use with SSL"); + CUtils::PrintMessage( + "\t-p, --makepem Generates a pemfile for use with SSL"); #endif /* HAVE_LIBSSL */ - CUtils::PrintMessage( - "\t-d, --datadir Set a different ZNC repository (default is " - "~/.znc)"); + CUtils::PrintMessage( + "\t-d, --datadir Set a different ZNC repository (default is " + "~/.znc)"); } class CSignalHandler { public: - CSignalHandler(CZNC* pZNC) { - sigset_t signals; - sigfillset(&signals); - pthread_sigmask(SIG_SETMASK, &signals, nullptr); - m_thread = std::thread([=]() { HandleSignals(pZNC); }); - } - ~CSignalHandler() { - pthread_cancel(m_thread.native_handle()); - m_thread.join(); - } + CSignalHandler(CZNC* pZNC) { + sigset_t signals; + sigfillset(&signals); + pthread_sigmask(SIG_SETMASK, &signals, nullptr); + m_thread = std::thread([=]() { HandleSignals(pZNC); }); + } + ~CSignalHandler() { + pthread_cancel(m_thread.native_handle()); + m_thread.join(); + } private: - void HandleSignals(CZNC* pZNC) { - sigset_t signals; - sigemptyset(&signals); - sigaddset(&signals, SIGHUP); - sigaddset(&signals, SIGUSR1); - sigaddset(&signals, SIGINT); - sigaddset(&signals, SIGQUIT); - sigaddset(&signals, SIGTERM); - sigaddset(&signals, SIGPIPE); - // Handle only these signals specially; the rest will have their default - // action, but in this thread - pthread_sigmask(SIG_SETMASK, &signals, nullptr); - while (true) { - int sig; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr); - // This thread can be cancelled, but only during this function. - // Such cancel will be the only way to finish this thread. - if (sigwait(&signals, &sig) == -1) continue; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr); - switch (sig) { - case SIGHUP: - pZNC->SetConfigState(CZNC::ECONFIG_NEED_REHASH); - break; - case SIGUSR1: - pZNC->SetConfigState(CZNC::ECONFIG_NEED_VERBOSE_WRITE); - break; - case SIGINT: - case SIGQUIT: - case SIGTERM: - pZNC->SetConfigState(CZNC::ECONFIG_NEED_QUIT); - // Reset handler to default by: - // * not blocking it - // * not waiting for it - // So, if ^C is pressed, but for some reason it didn't work, - // second ^C will kill the process for sure. - sigdelset(&signals, sig); - pthread_sigmask(SIG_SETMASK, &signals, nullptr); - break; - case SIGPIPE: - default: - break; - } - } - } + void HandleSignals(CZNC* pZNC) { + sigset_t signals; + sigemptyset(&signals); + sigaddset(&signals, SIGHUP); + sigaddset(&signals, SIGUSR1); + sigaddset(&signals, SIGINT); + sigaddset(&signals, SIGQUIT); + sigaddset(&signals, SIGTERM); + sigaddset(&signals, SIGPIPE); + // Handle only these signals specially; the rest will have their default + // action, but in this thread + pthread_sigmask(SIG_SETMASK, &signals, nullptr); + while (true) { + int sig; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr); + // This thread can be cancelled, but only during this function. + // Such cancel will be the only way to finish this thread. + if (sigwait(&signals, &sig) == -1) continue; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr); + switch (sig) { + case SIGHUP: + pZNC->SetConfigState(CZNC::ECONFIG_NEED_REHASH); + break; + case SIGUSR1: + pZNC->SetConfigState(CZNC::ECONFIG_NEED_VERBOSE_WRITE); + break; + case SIGINT: + case SIGQUIT: + case SIGTERM: + pZNC->SetConfigState(CZNC::ECONFIG_NEED_QUIT); + // Reset handler to default by: + // * not blocking it + // * not waiting for it + // So, if ^C is pressed, but for some reason it didn't work, + // second ^C will kill the process for sure. + sigdelset(&signals, sig); + pthread_sigmask(SIG_SETMASK, &signals, nullptr); + break; + case SIGPIPE: + default: + break; + } + } + } - std::thread m_thread; + std::thread m_thread; }; static bool isRoot() { - // User root? If one of these were root, we could switch the others to root, - // too - return (geteuid() == 0 || getuid() == 0); + // User root? If one of these were root, we could switch the others to root, + // too + return (geteuid() == 0 || getuid() == 0); } static void seedPRNG() { - struct timeval tv; - unsigned int seed; + struct timeval tv; + unsigned int seed; - // Try to find a seed which can't be as easily guessed as only time() + // Try to find a seed which can't be as easily guessed as only time() - if (gettimeofday(&tv, nullptr) == 0) { - seed = (unsigned int)tv.tv_sec; + if (gettimeofday(&tv, nullptr) == 0) { + seed = (unsigned int)tv.tv_sec; - // This is in [0:1e6], which means that roughly 20 bits are - // actually used, let's try to shuffle the high bits. - seed ^= uint32_t((tv.tv_usec << 10) | tv.tv_usec); - } else - seed = (unsigned int)time(nullptr); + // This is in [0:1e6], which means that roughly 20 bits are + // actually used, let's try to shuffle the high bits. + seed ^= uint32_t((tv.tv_usec << 10) | tv.tv_usec); + } else + seed = (unsigned int)time(nullptr); - seed ^= rand(); - seed ^= getpid(); + seed ^= rand(); + seed ^= getpid(); - srand(seed); + srand(seed); } int main(int argc, char** argv) { - CString sConfig; - CString sDataDir = ""; + CString sConfig; + CString sDataDir = ""; - thread_setup(); + thread_setup(); - seedPRNG(); - CDebug::SetStdoutIsTTY(isatty(1)); + seedPRNG(); + CDebug::SetStdoutIsTTY(isatty(1)); - int iArg, iOptIndex = -1; - bool bMakeConf = false; - bool bMakePass = false; - bool bAllowRoot = false; - bool bForeground = false; + int iArg, iOptIndex = -1; + bool bMakeConf = false; + bool bMakePass = false; + bool bAllowRoot = false; + bool bForeground = false; #ifdef ALWAYS_RUN_IN_FOREGROUND - bForeground = true; + bForeground = true; #endif #ifdef HAVE_LIBSSL - bool bMakePem = false; + bool bMakePem = false; #endif - CZNC::CreateInstance(); + CZNC::CreateInstance(); - while ((iArg = getopt_long(argc, argv, "hvnrcspd:Df", g_LongOpts, - &iOptIndex)) != -1) { - switch (iArg) { - case 'h': - GenerateHelp(argv[0]); - return 0; - case 'v': - cout << CZNC::GetTag() << endl; - cout << CZNC::GetCompileOptionsString() << endl; - return 0; - case 'n': - CDebug::SetStdoutIsTTY(false); - break; - case 'r': - bAllowRoot = true; - break; - case 'c': - bMakeConf = true; - break; - case 's': - bMakePass = true; - break; - case 'p': + while ((iArg = getopt_long(argc, argv, "hvnrcspd:Df", g_LongOpts, + &iOptIndex)) != -1) { + switch (iArg) { + case 'h': + GenerateHelp(argv[0]); + return 0; + case 'v': + cout << CZNC::GetTag() << endl; + cout << CZNC::GetCompileOptionsString() << endl; + return 0; + case 'n': + CDebug::SetStdoutIsTTY(false); + break; + case 'r': + bAllowRoot = true; + break; + case 'c': + bMakeConf = true; + break; + case 's': + bMakePass = true; + break; + case 'p': #ifdef HAVE_LIBSSL - bMakePem = true; - break; + bMakePem = true; + break; #else - CUtils::PrintError("ZNC is compiled without SSL support."); - return 1; + CUtils::PrintError("ZNC is compiled without SSL support."); + return 1; #endif /* HAVE_LIBSSL */ - case 'd': - sDataDir = CString(optarg); - break; - case 'f': - bForeground = true; - break; - case 'D': - bForeground = true; - CDebug::SetDebug(true); - break; - case '?': - default: - GenerateHelp(argv[0]); - return 1; - } - } + case 'd': + sDataDir = CString(optarg); + break; + case 'f': + bForeground = true; + break; + case 'D': + bForeground = true; + CDebug::SetDebug(true); + break; + case '?': + default: + GenerateHelp(argv[0]); + return 1; + } + } - if (optind < argc) { - CUtils::PrintError("Unrecognized command line arguments."); - CUtils::PrintError("Did you mean to run `/znc " + - CString(argv[optind]) + "' in IRC client instead?"); - CUtils::PrintError("Hint: `/znc " + CString(argv[optind]) + - "' is an alias for `/msg *status " + - CString(argv[optind]) + "'"); - return 1; - } + if (optind < argc) { + CUtils::PrintError("Unrecognized command line arguments."); + CUtils::PrintError("Did you mean to run `/znc " + + CString(argv[optind]) + "' in IRC client instead?"); + CUtils::PrintError("Hint: `/znc " + CString(argv[optind]) + + "' is an alias for `/msg *status " + + CString(argv[optind]) + "'"); + return 1; + } - CZNC* pZNC = &CZNC::Get(); - pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir); + CZNC* pZNC = &CZNC::Get(); + pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir); #ifdef HAVE_LIBSSL - if (bMakePem) { - pZNC->WritePemFile(); + if (bMakePem) { + pZNC->WritePemFile(); - CZNC::DestroyInstance(); - return 0; - } + CZNC::DestroyInstance(); + return 0; + } #endif /* HAVE_LIBSSL */ - if (bMakePass) { - CString sSalt; - CUtils::PrintMessage("Type your new password."); - CString sHash = CUtils::GetSaltedHashPass(sSalt); - CUtils::PrintMessage("Kill ZNC process, if it's running."); - CUtils::PrintMessage( - "Then replace password in the section of your config with " - "this:"); - // Not PrintMessage(), to remove [**] from the beginning, to ease - // copypasting - std::cout << "" << std::endl; - std::cout << "\tMethod = " << CUtils::sDefaultHash << std::endl; - std::cout << "\tHash = " << sHash << std::endl; - std::cout << "\tSalt = " << sSalt << std::endl; - std::cout << "" << std::endl; - CUtils::PrintMessage( - "After that start ZNC again, and you should be able to login with " - "the new password."); + if (bMakePass) { + CString sSalt; + CUtils::PrintMessage("Type your new password."); + CString sHash = CUtils::GetSaltedHashPass(sSalt); + CUtils::PrintMessage("Kill ZNC process, if it's running."); + CUtils::PrintMessage( + "Then replace password in the section of your config with " + "this:"); + // Not PrintMessage(), to remove [**] from the beginning, to ease + // copypasting + std::cout << "" << std::endl; + std::cout << "\tMethod = " << CUtils::sDefaultHash << std::endl; + std::cout << "\tHash = " << sHash << std::endl; + std::cout << "\tSalt = " << sSalt << std::endl; + std::cout << "" << std::endl; + CUtils::PrintMessage( + "After that start ZNC again, and you should be able to login with " + "the new password."); - CZNC::DestroyInstance(); - return 0; - } + CZNC::DestroyInstance(); + return 0; + } - { - set ssGlobalMods; - set ssUserMods; - set ssNetworkMods; - CUtils::PrintAction("Checking for list of available modules"); - pZNC->GetModules().GetAvailableMods(ssGlobalMods, - CModInfo::GlobalModule); - pZNC->GetModules().GetAvailableMods(ssUserMods, CModInfo::UserModule); - pZNC->GetModules().GetAvailableMods(ssNetworkMods, - CModInfo::NetworkModule); - if (ssGlobalMods.empty() && ssUserMods.empty() && - ssNetworkMods.empty()) { - CUtils::PrintStatus(false, ""); - CUtils::PrintError( - "No modules found. Perhaps you didn't install ZNC properly?"); - CUtils::PrintError( - "Read http://wiki.znc.in/Installation for instructions."); - if (!CUtils::GetBoolInput( - "Do you really want to run ZNC without any modules?", - false)) { - CZNC::DestroyInstance(); - return 1; - } - } - CUtils::PrintStatus(true, ""); - } + { + set ssGlobalMods; + set ssUserMods; + set ssNetworkMods; + CUtils::PrintAction("Checking for list of available modules"); + pZNC->GetModules().GetAvailableMods(ssGlobalMods, + CModInfo::GlobalModule); + pZNC->GetModules().GetAvailableMods(ssUserMods, CModInfo::UserModule); + pZNC->GetModules().GetAvailableMods(ssNetworkMods, + CModInfo::NetworkModule); + if (ssGlobalMods.empty() && ssUserMods.empty() && + ssNetworkMods.empty()) { + CUtils::PrintStatus(false, ""); + CUtils::PrintError( + "No modules found. Perhaps you didn't install ZNC properly?"); + CUtils::PrintError( + "Read http://wiki.znc.in/Installation for instructions."); + if (!CUtils::GetBoolInput( + "Do you really want to run ZNC without any modules?", + false)) { + CZNC::DestroyInstance(); + return 1; + } + } + CUtils::PrintStatus(true, ""); + } - if (isRoot()) { - CUtils::PrintError( - "You are running ZNC as root! Don't do that! There are not many " - "valid"); - CUtils::PrintError( - "reasons for this and it can, in theory, cause great damage!"); - if (!bAllowRoot) { - CZNC::DestroyInstance(); - return 1; - } - CUtils::PrintError("You have been warned."); - CUtils::PrintError( - "Hit CTRL+C now if you don't want to run ZNC as root."); - CUtils::PrintError("ZNC will start in 30 seconds."); - sleep(30); - } + if (isRoot()) { + CUtils::PrintError( + "You are running ZNC as root! Don't do that! There are not many " + "valid"); + CUtils::PrintError( + "reasons for this and it can, in theory, cause great damage!"); + if (!bAllowRoot) { + CZNC::DestroyInstance(); + return 1; + } + CUtils::PrintError("You have been warned."); + CUtils::PrintError( + "Hit CTRL+C now if you don't want to run ZNC as root."); + CUtils::PrintError("ZNC will start in 30 seconds."); + sleep(30); + } - if (bMakeConf) { - if (!pZNC->WriteNewConfig(sConfig)) { - CZNC::DestroyInstance(); - return 0; - } - /* Fall through to normal bootup */ - } + if (bMakeConf) { + if (!pZNC->WriteNewConfig(sConfig)) { + CZNC::DestroyInstance(); + return 0; + } + /* Fall through to normal bootup */ + } - CString sConfigError; - if (!pZNC->ParseConfig(sConfig, sConfigError)) { - CUtils::PrintError("Unrecoverable config error."); - CZNC::DestroyInstance(); - return 1; - } + CString sConfigError; + if (!pZNC->ParseConfig(sConfig, sConfigError)) { + CUtils::PrintError("Unrecoverable config error."); + CZNC::DestroyInstance(); + return 1; + } - if (!pZNC->OnBoot()) { - CUtils::PrintError("Exiting due to module boot errors."); - CZNC::DestroyInstance(); - return 1; - } + if (!pZNC->OnBoot()) { + CUtils::PrintError("Exiting due to module boot errors."); + CZNC::DestroyInstance(); + return 1; + } - if (bForeground) { - int iPid = getpid(); - CUtils::PrintMessage("Staying open for debugging [pid: " + - CString(iPid) + "]"); + if (bForeground) { + int iPid = getpid(); + CUtils::PrintMessage("Staying open for debugging [pid: " + + CString(iPid) + "]"); - pZNC->WritePidFile(iPid); - CUtils::PrintMessage(CZNC::GetTag()); - } else { - CUtils::PrintAction("Forking into the background"); + pZNC->WritePidFile(iPid); + CUtils::PrintMessage(CZNC::GetTag()); + } else { + CUtils::PrintAction("Forking into the background"); - int iPid = fork(); + int iPid = fork(); - if (iPid == -1) { - CUtils::PrintStatus(false, strerror(errno)); - CZNC::DestroyInstance(); - return 1; - } + if (iPid == -1) { + CUtils::PrintStatus(false, strerror(errno)); + CZNC::DestroyInstance(); + return 1; + } - if (iPid > 0) { - // We are the parent. We are done and will go to bed. - CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]"); + if (iPid > 0) { + // We are the parent. We are done and will go to bed. + CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]"); - pZNC->WritePidFile(iPid); - CUtils::PrintMessage(CZNC::GetTag()); - /* Don't destroy pZNC here or it will delete the pid file. */ - return 0; - } + pZNC->WritePidFile(iPid); + CUtils::PrintMessage(CZNC::GetTag()); + /* Don't destroy pZNC here or it will delete the pid file. */ + return 0; + } - /* fcntl() locks don't necessarily propagate to forked() - * children. Reacquire the lock here. Use the blocking - * call to avoid race condition with parent exiting. - */ - if (!pZNC->WaitForChildLock()) { - CUtils::PrintError( - "Child was unable to obtain lock on config file."); - CZNC::DestroyInstance(); - return 1; - } + /* fcntl() locks don't necessarily propagate to forked() + * children. Reacquire the lock here. Use the blocking + * call to avoid race condition with parent exiting. + */ + if (!pZNC->WaitForChildLock()) { + CUtils::PrintError( + "Child was unable to obtain lock on config file."); + CZNC::DestroyInstance(); + return 1; + } - // Redirect std in/out/err to /dev/null - close(0); - open("/dev/null", O_RDONLY); - close(1); - open("/dev/null", O_WRONLY); - close(2); - open("/dev/null", O_WRONLY); + // Redirect std in/out/err to /dev/null + close(0); + open("/dev/null", O_RDONLY); + close(1); + open("/dev/null", O_WRONLY); + close(2); + open("/dev/null", O_WRONLY); - CDebug::SetStdoutIsTTY(false); + CDebug::SetStdoutIsTTY(false); - // We are the child. There is no way we can be a process group - // leader, thus setsid() must succeed. - setsid(); - // Now we are in our own process group and session (no - // controlling terminal). We are independent! - } + // We are the child. There is no way we can be a process group + // leader, thus setsid() must succeed. + setsid(); + // Now we are in our own process group and session (no + // controlling terminal). We are independent! + } - // Handle all signals in separate thread - std::unique_ptr SignalHandler(new CSignalHandler(pZNC)); + // Handle all signals in separate thread + std::unique_ptr SignalHandler(new CSignalHandler(pZNC)); - int iRet = 0; + int iRet = 0; - try { - pZNC->Loop(); - } catch (const CException& e) { - switch (e.GetType()) { - case CException::EX_Shutdown: - iRet = 0; - break; - case CException::EX_Restart: { - // strdup() because GCC is stupid - char* args[] = { - strdup(argv[0]), strdup("--datadir"), - strdup(pZNC->GetZNCPath().c_str()), nullptr, - nullptr, nullptr, - nullptr}; - int pos = 3; - if (CDebug::Debug()) - args[pos++] = strdup("--debug"); - else if (bForeground) - args[pos++] = strdup("--foreground"); - if (!CDebug::StdoutIsTTY()) args[pos++] = strdup("--no-color"); - if (bAllowRoot) args[pos++] = strdup("--allow-root"); - // The above code adds 3 entries to args tops - // which means the array should be big enough + try { + pZNC->Loop(); + } catch (const CException& e) { + switch (e.GetType()) { + case CException::EX_Shutdown: + iRet = 0; + break; + case CException::EX_Restart: { + // strdup() because GCC is stupid + char* args[] = { + strdup(argv[0]), strdup("--datadir"), + strdup(pZNC->GetZNCPath().c_str()), nullptr, + nullptr, nullptr, + nullptr}; + int pos = 3; + if (CDebug::Debug()) + args[pos++] = strdup("--debug"); + else if (bForeground) + args[pos++] = strdup("--foreground"); + if (!CDebug::StdoutIsTTY()) args[pos++] = strdup("--no-color"); + if (bAllowRoot) args[pos++] = strdup("--allow-root"); + // The above code adds 3 entries to args tops + // which means the array should be big enough - SignalHandler.reset(); - CZNC::DestroyInstance(); - execvp(args[0], args); - CUtils::PrintError("Unable to restart ZNC [" + - CString(strerror(errno)) + "]"); - } /* Fall through */ - default: - iRet = 1; - } - } + SignalHandler.reset(); + CZNC::DestroyInstance(); + execvp(args[0], args); + CUtils::PrintError("Unable to restart ZNC [" + + CString(strerror(errno)) + "]"); + } /* Fall through */ + default: + iRet = 1; + } + } - SignalHandler.reset(); - CZNC::DestroyInstance(); + SignalHandler.reset(); + CZNC::DestroyInstance(); - CUtils::PrintMessage("Exiting"); + CUtils::PrintMessage("Exiting"); - return iRet; + return iRet; } diff --git a/src/znc.cpp b/src/znc.cpp index 82702996..755f6783 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -35,9 +35,9 @@ using std::tuple; using std::make_tuple; static inline CString FormatBindError() { - CString sError = (errno == 0 ? CString("unknown error, check the host name") - : CString(strerror(errno))); - return "Unable to bind [" + sError + "]"; + CString sError = (errno == 0 ? CString("unknown error, check the host name") + : CString(strerror(errno))); + return "Unable to bind [" + sError + "]"; } CZNC::CZNC() @@ -75,2015 +75,2015 @@ CZNC::CZNC() m_sConnectThrottle(), m_bProtectWebSessions(true), m_bHideVersion(false) { - if (!InitCsocket()) { - CUtils::PrintError("Could not initialize Csocket!"); - exit(-1); - } - m_sConnectThrottle.SetTTL(30000); + if (!InitCsocket()) { + CUtils::PrintError("Could not initialize Csocket!"); + exit(-1); + } + m_sConnectThrottle.SetTTL(30000); } CZNC::~CZNC() { - m_pModules->UnloadAll(); + m_pModules->UnloadAll(); - for (const auto& it : m_msUsers) { - it.second->GetModules().UnloadAll(); + for (const auto& it : m_msUsers) { + it.second->GetModules().UnloadAll(); - const vector& networks = it.second->GetNetworks(); - for (CIRCNetwork* pNetwork : networks) { - pNetwork->GetModules().UnloadAll(); - } - } + const vector& networks = it.second->GetNetworks(); + for (CIRCNetwork* pNetwork : networks) { + pNetwork->GetModules().UnloadAll(); + } + } - for (CListener* pListener : m_vpListeners) { - delete pListener; - } + for (CListener* pListener : m_vpListeners) { + delete pListener; + } - for (const auto& it : m_msUsers) { - it.second->SetBeingDeleted(true); - } + for (const auto& it : m_msUsers) { + it.second->SetBeingDeleted(true); + } - m_pConnectQueueTimer = nullptr; - // This deletes m_pConnectQueueTimer - m_Manager.Cleanup(); - DeleteUsers(); + m_pConnectQueueTimer = nullptr; + // This deletes m_pConnectQueueTimer + m_Manager.Cleanup(); + DeleteUsers(); - delete m_pModules; - delete m_pLockFile; + delete m_pModules; + delete m_pLockFile; - ShutdownCsocket(); - DeletePidFile(); + ShutdownCsocket(); + DeletePidFile(); } CString CZNC::GetVersion() { - return CString(VERSION_STR) + CString(ZNC_VERSION_EXTRA); + return CString(VERSION_STR) + CString(ZNC_VERSION_EXTRA); } CString CZNC::GetTag(bool bIncludeVersion, bool bHTML) { - if (!Get().m_bHideVersion) { - bIncludeVersion = true; - } - CString sAddress = - bHTML ? "http://znc.in" : "http://znc.in"; + if (!Get().m_bHideVersion) { + bIncludeVersion = true; + } + CString sAddress = + bHTML ? "http://znc.in" : "http://znc.in"; - if (!bIncludeVersion) { - return "ZNC - " + sAddress; - } + if (!bIncludeVersion) { + return "ZNC - " + sAddress; + } - CString sVersion = GetVersion(); + CString sVersion = GetVersion(); - return "ZNC " + sVersion + " - " + sAddress; + return "ZNC " + sVersion + " - " + sAddress; } CString CZNC::GetCompileOptionsString() { - return "IPv6: " + return "IPv6: " #ifdef HAVE_IPV6 - "yes" + "yes" #else - "no" + "no" #endif - ", SSL: " + ", SSL: " #ifdef HAVE_LIBSSL - "yes" + "yes" #else - "no" + "no" #endif - ", DNS: " + ", DNS: " #ifdef HAVE_THREADED_DNS - "threads" + "threads" #else - "blocking" + "blocking" #endif - ", charset: " + ", charset: " #ifdef HAVE_ICU - "yes" + "yes" #else - "no" + "no" #endif - ; + ; } CString CZNC::GetUptime() const { - time_t now = time(nullptr); - return CString::ToTimeStr(now - TimeStarted()); + time_t now = time(nullptr); + return CString::ToTimeStr(now - TimeStarted()); } bool CZNC::OnBoot() { - bool bFail = false; - ALLMODULECALL(OnBoot(), &bFail); - if (bFail) return false; + bool bFail = false; + ALLMODULECALL(OnBoot(), &bFail); + if (bFail) return false; - return true; + return true; } bool CZNC::HandleUserDeletion() { - if (m_msDelUsers.empty()) return false; + if (m_msDelUsers.empty()) return false; - for (const auto& it : m_msDelUsers) { - CUser* pUser = it.second; - pUser->SetBeingDeleted(true); + for (const auto& it : m_msDelUsers) { + CUser* pUser = it.second; + pUser->SetBeingDeleted(true); - if (GetModules().OnDeleteUser(*pUser)) { - pUser->SetBeingDeleted(false); - continue; - } - m_msUsers.erase(pUser->GetUserName()); - CWebSock::FinishUserSessions(*pUser); - delete pUser; - } + if (GetModules().OnDeleteUser(*pUser)) { + pUser->SetBeingDeleted(false); + continue; + } + m_msUsers.erase(pUser->GetUserName()); + CWebSock::FinishUserSessions(*pUser); + delete pUser; + } - m_msDelUsers.clear(); + m_msDelUsers.clear(); - return true; + return true; } void CZNC::Loop() { - while (true) { - CString sError; + while (true) { + CString sError; - ConfigState eState = GetConfigState(); - switch (eState) { - case ECONFIG_NEED_REHASH: - SetConfigState(ECONFIG_NOTHING); + ConfigState eState = GetConfigState(); + switch (eState) { + case ECONFIG_NEED_REHASH: + SetConfigState(ECONFIG_NOTHING); - if (RehashConfig(sError)) { - Broadcast("Rehashing succeeded", true); - } else { - Broadcast("Rehashing failed: " + sError, true); - Broadcast("ZNC is in some possibly inconsistent state!", - true); - } - break; - case ECONFIG_NEED_WRITE: - case ECONFIG_NEED_VERBOSE_WRITE: - SetConfigState(ECONFIG_NOTHING); + if (RehashConfig(sError)) { + Broadcast("Rehashing succeeded", true); + } else { + Broadcast("Rehashing failed: " + sError, true); + Broadcast("ZNC is in some possibly inconsistent state!", + true); + } + break; + case ECONFIG_NEED_WRITE: + case ECONFIG_NEED_VERBOSE_WRITE: + SetConfigState(ECONFIG_NOTHING); - if (!WriteConfig()) { - Broadcast("Writing the config file failed", true); - } else if (eState == ECONFIG_NEED_VERBOSE_WRITE) { - Broadcast("Writing the config succeeded", true); - } - break; - case ECONFIG_NOTHING: - break; - case ECONFIG_NEED_QUIT: - return; - } + if (!WriteConfig()) { + Broadcast("Writing the config file failed", true); + } else if (eState == ECONFIG_NEED_VERBOSE_WRITE) { + Broadcast("Writing the config succeeded", true); + } + break; + case ECONFIG_NOTHING: + break; + case ECONFIG_NEED_QUIT: + return; + } - // Check for users that need to be deleted - if (HandleUserDeletion()) { - // Also remove those user(s) from the config file - WriteConfig(); - } + // Check for users that need to be deleted + if (HandleUserDeletion()) { + // Also remove those user(s) from the config file + WriteConfig(); + } - // Csocket wants micro seconds - // 100 msec to 5 sec - m_Manager.DynamicSelectLoop(100 * 1000, 5 * 1000 * 1000); - } + // Csocket wants micro seconds + // 100 msec to 5 sec + m_Manager.DynamicSelectLoop(100 * 1000, 5 * 1000 * 1000); + } } CFile* CZNC::InitPidFile() { - if (!m_sPidFile.empty()) { - CString sFile; + if (!m_sPidFile.empty()) { + CString sFile; - // absolute path or relative to the data dir? - if (m_sPidFile[0] != '/') - sFile = GetZNCPath() + "/" + m_sPidFile; - else - sFile = m_sPidFile; + // absolute path or relative to the data dir? + if (m_sPidFile[0] != '/') + sFile = GetZNCPath() + "/" + m_sPidFile; + else + sFile = m_sPidFile; - return new CFile(sFile); - } + return new CFile(sFile); + } - return nullptr; + return nullptr; } bool CZNC::WritePidFile(int iPid) { - CFile* File = InitPidFile(); - if (File == nullptr) return false; + CFile* File = InitPidFile(); + if (File == nullptr) return false; - CUtils::PrintAction("Writing pid file [" + File->GetLongName() + "]"); + CUtils::PrintAction("Writing pid file [" + File->GetLongName() + "]"); - bool bRet = false; - if (File->Open(O_WRONLY | O_TRUNC | O_CREAT)) { - File->Write(CString(iPid) + "\n"); - File->Close(); - bRet = true; - } + bool bRet = false; + if (File->Open(O_WRONLY | O_TRUNC | O_CREAT)) { + File->Write(CString(iPid) + "\n"); + File->Close(); + bRet = true; + } - delete File; - CUtils::PrintStatus(bRet); - return bRet; + delete File; + CUtils::PrintStatus(bRet); + return bRet; } bool CZNC::DeletePidFile() { - CFile* File = InitPidFile(); - if (File == nullptr) return false; + CFile* File = InitPidFile(); + if (File == nullptr) return false; - CUtils::PrintAction("Deleting pid file [" + File->GetLongName() + "]"); + CUtils::PrintAction("Deleting pid file [" + File->GetLongName() + "]"); - bool bRet = File->Delete(); + bool bRet = File->Delete(); - delete File; - CUtils::PrintStatus(bRet); - return bRet; + delete File; + CUtils::PrintStatus(bRet); + return bRet; } bool CZNC::WritePemFile() { #ifndef HAVE_LIBSSL - CUtils::PrintError("ZNC was not compiled with ssl support."); - return false; + CUtils::PrintError("ZNC was not compiled with ssl support."); + return false; #else - CString sPemFile = GetPemLocation(); + CString sPemFile = GetPemLocation(); - CUtils::PrintAction("Writing Pem file [" + sPemFile + "]"); + CUtils::PrintAction("Writing Pem file [" + sPemFile + "]"); #ifndef _WIN32 - int fd = creat(sPemFile.c_str(), 0600); - if (fd == -1) { - CUtils::PrintStatus(false, "Unable to open"); - return false; - } - FILE* f = fdopen(fd, "w"); + int fd = creat(sPemFile.c_str(), 0600); + if (fd == -1) { + CUtils::PrintStatus(false, "Unable to open"); + return false; + } + FILE* f = fdopen(fd, "w"); #else - FILE* f = fopen(sPemFile.c_str(), "w"); + FILE* f = fopen(sPemFile.c_str(), "w"); #endif - if (!f) { - CUtils::PrintStatus(false, "Unable to open"); - return false; - } + if (!f) { + CUtils::PrintStatus(false, "Unable to open"); + return false; + } - CUtils::GenerateCert(f, ""); - fclose(f); + CUtils::GenerateCert(f, ""); + fclose(f); - CUtils::PrintStatus(true); - return true; + CUtils::PrintStatus(true); + return true; #endif } void CZNC::DeleteUsers() { - for (const auto& it : m_msUsers) { - it.second->SetBeingDeleted(true); - delete it.second; - } + for (const auto& it : m_msUsers) { + it.second->SetBeingDeleted(true); + delete it.second; + } - m_msUsers.clear(); - DisableConnectQueue(); + m_msUsers.clear(); + DisableConnectQueue(); } bool CZNC::IsHostAllowed(const CString& sHostMask) const { - for (const auto& it : m_msUsers) { - if (it.second->IsHostAllowed(sHostMask)) { - return true; - } - } + for (const auto& it : m_msUsers) { + if (it.second->IsHostAllowed(sHostMask)) { + return true; + } + } - return false; + return false; } bool CZNC::AllowConnectionFrom(const CString& sIP) const { - if (m_uiAnonIPLimit == 0) return true; - return (GetManager().GetAnonConnectionCount(sIP) < m_uiAnonIPLimit); + if (m_uiAnonIPLimit == 0) return true; + return (GetManager().GetAnonConnectionCount(sIP) < m_uiAnonIPLimit); } void CZNC::InitDirs(const CString& sArgvPath, const CString& sDataDir) { - // If the bin was not ran from the current directory, we need to add that - // dir onto our cwd - CString::size_type uPos = sArgvPath.rfind('/'); - if (uPos == CString::npos) - m_sCurPath = "./"; - else - m_sCurPath = CDir::ChangeDir("./", sArgvPath.Left(uPos), ""); + // If the bin was not ran from the current directory, we need to add that + // dir onto our cwd + CString::size_type uPos = sArgvPath.rfind('/'); + if (uPos == CString::npos) + m_sCurPath = "./"; + else + m_sCurPath = CDir::ChangeDir("./", sArgvPath.Left(uPos), ""); - // Try to set the user's home dir, default to binpath on failure - CFile::InitHomePath(m_sCurPath); + // Try to set the user's home dir, default to binpath on failure + CFile::InitHomePath(m_sCurPath); - if (sDataDir.empty()) { - m_sZNCPath = CFile::GetHomePath() + "/.znc"; - } else { - m_sZNCPath = sDataDir; - } + if (sDataDir.empty()) { + m_sZNCPath = CFile::GetHomePath() + "/.znc"; + } else { + m_sZNCPath = sDataDir; + } - m_sSSLCertFile = m_sSSLKeyFile = m_sSSLDHParamFile = - m_sZNCPath + "/znc.pem"; + m_sSSLCertFile = m_sSSLKeyFile = m_sSSLDHParamFile = + m_sZNCPath + "/znc.pem"; } CString CZNC::GetConfPath(bool bAllowMkDir) const { - CString sConfPath = m_sZNCPath + "/configs"; - if (bAllowMkDir && !CFile::Exists(sConfPath)) { - CDir::MakeDir(sConfPath); - } + CString sConfPath = m_sZNCPath + "/configs"; + if (bAllowMkDir && !CFile::Exists(sConfPath)) { + CDir::MakeDir(sConfPath); + } - return sConfPath; + return sConfPath; } CString CZNC::GetUserPath() const { - CString sUserPath = m_sZNCPath + "/users"; - if (!CFile::Exists(sUserPath)) { - CDir::MakeDir(sUserPath); - } + CString sUserPath = m_sZNCPath + "/users"; + if (!CFile::Exists(sUserPath)) { + CDir::MakeDir(sUserPath); + } - return sUserPath; + return sUserPath; } CString CZNC::GetModPath() const { - CString sModPath = m_sZNCPath + "/modules"; + CString sModPath = m_sZNCPath + "/modules"; - return sModPath; + return sModPath; } const CString& CZNC::GetCurPath() const { - if (!CFile::Exists(m_sCurPath)) { - CDir::MakeDir(m_sCurPath); - } - return m_sCurPath; + if (!CFile::Exists(m_sCurPath)) { + CDir::MakeDir(m_sCurPath); + } + return m_sCurPath; } const CString& CZNC::GetHomePath() const { return CFile::GetHomePath(); } const CString& CZNC::GetZNCPath() const { - if (!CFile::Exists(m_sZNCPath)) { - CDir::MakeDir(m_sZNCPath); - } - return m_sZNCPath; + if (!CFile::Exists(m_sZNCPath)) { + CDir::MakeDir(m_sZNCPath); + } + return m_sZNCPath; } CString CZNC::GetPemLocation() const { - return CDir::ChangeDir("", m_sSSLCertFile); + return CDir::ChangeDir("", m_sSSLCertFile); } CString CZNC::GetKeyLocation() const { - return CDir::ChangeDir("", m_sSSLKeyFile); + return CDir::ChangeDir("", m_sSSLKeyFile); } CString CZNC::GetDHParamLocation() const { - return CDir::ChangeDir("", m_sSSLDHParamFile); + return CDir::ChangeDir("", m_sSSLDHParamFile); } CString CZNC::ExpandConfigPath(const CString& sConfigFile, bool bAllowMkDir) { - CString sRetPath; + CString sRetPath; - if (sConfigFile.empty()) { - sRetPath = GetConfPath(bAllowMkDir) + "/znc.conf"; - } else { - if (sConfigFile.StartsWith("./") || sConfigFile.StartsWith("../")) { - sRetPath = GetCurPath() + "/" + sConfigFile; - } else if (!sConfigFile.StartsWith("/")) { - sRetPath = GetConfPath(bAllowMkDir) + "/" + sConfigFile; - } else { - sRetPath = sConfigFile; - } - } + if (sConfigFile.empty()) { + sRetPath = GetConfPath(bAllowMkDir) + "/znc.conf"; + } else { + if (sConfigFile.StartsWith("./") || sConfigFile.StartsWith("../")) { + sRetPath = GetCurPath() + "/" + sConfigFile; + } else if (!sConfigFile.StartsWith("/")) { + sRetPath = GetConfPath(bAllowMkDir) + "/" + sConfigFile; + } else { + sRetPath = sConfigFile; + } + } - return sRetPath; + return sRetPath; } bool CZNC::WriteConfig() { - if (GetConfigFile().empty()) { - DEBUG("Config file name is empty?!"); - return false; - } + if (GetConfigFile().empty()) { + DEBUG("Config file name is empty?!"); + return false; + } - // We first write to a temporary file and then move it to the right place - CFile* pFile = new CFile(GetConfigFile() + "~"); + // We first write to a temporary file and then move it to the right place + CFile* pFile = new CFile(GetConfigFile() + "~"); - if (!pFile->Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { - DEBUG("Could not write config to " + GetConfigFile() + "~: " + - CString(strerror(errno))); - delete pFile; - return false; - } + if (!pFile->Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { + DEBUG("Could not write config to " + GetConfigFile() + "~: " + + CString(strerror(errno))); + delete pFile; + return false; + } - // We have to "transfer" our lock on the config to the new file. - // The old file (= inode) is going away and thus a lock on it would be - // useless. These lock should always succeed (races, anyone?). - if (!pFile->TryExLock()) { - DEBUG("Error while locking the new config file, errno says: " + - CString(strerror(errno))); - pFile->Delete(); - delete pFile; - return false; - } + // We have to "transfer" our lock on the config to the new file. + // The old file (= inode) is going away and thus a lock on it would be + // useless. These lock should always succeed (races, anyone?). + if (!pFile->TryExLock()) { + DEBUG("Error while locking the new config file, errno says: " + + CString(strerror(errno))); + pFile->Delete(); + delete pFile; + return false; + } - pFile->Write(MakeConfigHeader() + "\n"); + pFile->Write(MakeConfigHeader() + "\n"); - CConfig config; - config.AddKeyValuePair("AnonIPLimit", CString(m_uiAnonIPLimit)); - config.AddKeyValuePair("MaxBufferSize", CString(m_uiMaxBufferSize)); - config.AddKeyValuePair("SSLCertFile", CString(m_sSSLCertFile)); - config.AddKeyValuePair("SSLKeyFile", CString(m_sSSLKeyFile)); - config.AddKeyValuePair("SSLDHParamFile", CString(m_sSSLDHParamFile)); - config.AddKeyValuePair("ProtectWebSessions", - CString(m_bProtectWebSessions)); - config.AddKeyValuePair("HideVersion", CString(m_bHideVersion)); - config.AddKeyValuePair("Version", CString(VERSION_STR)); + CConfig config; + config.AddKeyValuePair("AnonIPLimit", CString(m_uiAnonIPLimit)); + config.AddKeyValuePair("MaxBufferSize", CString(m_uiMaxBufferSize)); + config.AddKeyValuePair("SSLCertFile", CString(m_sSSLCertFile)); + config.AddKeyValuePair("SSLKeyFile", CString(m_sSSLKeyFile)); + config.AddKeyValuePair("SSLDHParamFile", CString(m_sSSLDHParamFile)); + config.AddKeyValuePair("ProtectWebSessions", + CString(m_bProtectWebSessions)); + config.AddKeyValuePair("HideVersion", CString(m_bHideVersion)); + config.AddKeyValuePair("Version", CString(VERSION_STR)); - unsigned int l = 0; - for (CListener* pListener : m_vpListeners) { - CConfig listenerConfig; + unsigned int l = 0; + for (CListener* pListener : m_vpListeners) { + CConfig listenerConfig; - listenerConfig.AddKeyValuePair("Host", pListener->GetBindHost()); - listenerConfig.AddKeyValuePair("URIPrefix", - pListener->GetURIPrefix() + "/"); - listenerConfig.AddKeyValuePair("Port", CString(pListener->GetPort())); + listenerConfig.AddKeyValuePair("Host", pListener->GetBindHost()); + listenerConfig.AddKeyValuePair("URIPrefix", + pListener->GetURIPrefix() + "/"); + listenerConfig.AddKeyValuePair("Port", CString(pListener->GetPort())); - listenerConfig.AddKeyValuePair( - "IPv4", CString(pListener->GetAddrType() != ADDR_IPV6ONLY)); - listenerConfig.AddKeyValuePair( - "IPv6", CString(pListener->GetAddrType() != ADDR_IPV4ONLY)); + listenerConfig.AddKeyValuePair( + "IPv4", CString(pListener->GetAddrType() != ADDR_IPV6ONLY)); + listenerConfig.AddKeyValuePair( + "IPv6", CString(pListener->GetAddrType() != ADDR_IPV4ONLY)); - listenerConfig.AddKeyValuePair("SSL", CString(pListener->IsSSL())); + listenerConfig.AddKeyValuePair("SSL", CString(pListener->IsSSL())); - listenerConfig.AddKeyValuePair( - "AllowIRC", - CString(pListener->GetAcceptType() != CListener::ACCEPT_HTTP)); - listenerConfig.AddKeyValuePair( - "AllowWeb", - CString(pListener->GetAcceptType() != CListener::ACCEPT_IRC)); + listenerConfig.AddKeyValuePair( + "AllowIRC", + CString(pListener->GetAcceptType() != CListener::ACCEPT_HTTP)); + listenerConfig.AddKeyValuePair( + "AllowWeb", + CString(pListener->GetAcceptType() != CListener::ACCEPT_IRC)); - config.AddSubConfig("Listener", "listener" + CString(l++), - listenerConfig); - } + config.AddSubConfig("Listener", "listener" + CString(l++), + listenerConfig); + } - config.AddKeyValuePair("ConnectDelay", CString(m_uiConnectDelay)); - config.AddKeyValuePair("ServerThrottle", - CString(m_sConnectThrottle.GetTTL() / 1000)); + config.AddKeyValuePair("ConnectDelay", CString(m_uiConnectDelay)); + config.AddKeyValuePair("ServerThrottle", + CString(m_sConnectThrottle.GetTTL() / 1000)); - if (!m_sPidFile.empty()) { - config.AddKeyValuePair("PidFile", m_sPidFile.FirstLine()); - } + if (!m_sPidFile.empty()) { + config.AddKeyValuePair("PidFile", m_sPidFile.FirstLine()); + } - if (!m_sSkinName.empty()) { - config.AddKeyValuePair("Skin", m_sSkinName.FirstLine()); - } + if (!m_sSkinName.empty()) { + config.AddKeyValuePair("Skin", m_sSkinName.FirstLine()); + } - if (!m_sStatusPrefix.empty()) { - config.AddKeyValuePair("StatusPrefix", m_sStatusPrefix.FirstLine()); - } + if (!m_sStatusPrefix.empty()) { + config.AddKeyValuePair("StatusPrefix", m_sStatusPrefix.FirstLine()); + } - if (!m_sSSLCiphers.empty()) { - config.AddKeyValuePair("SSLCiphers", CString(m_sSSLCiphers)); - } + if (!m_sSSLCiphers.empty()) { + config.AddKeyValuePair("SSLCiphers", CString(m_sSSLCiphers)); + } - if (!m_sSSLProtocols.empty()) { - config.AddKeyValuePair("SSLProtocols", m_sSSLProtocols); - } + if (!m_sSSLProtocols.empty()) { + config.AddKeyValuePair("SSLProtocols", m_sSSLProtocols); + } - for (const CString& sLine : m_vsMotd) { - config.AddKeyValuePair("Motd", sLine.FirstLine()); - } + for (const CString& sLine : m_vsMotd) { + config.AddKeyValuePair("Motd", sLine.FirstLine()); + } - for (const CString& sProxy : m_vsTrustedProxies) { - config.AddKeyValuePair("TrustedProxy", sProxy.FirstLine()); - } + for (const CString& sProxy : m_vsTrustedProxies) { + config.AddKeyValuePair("TrustedProxy", sProxy.FirstLine()); + } - CModules& Mods = GetModules(); + CModules& Mods = GetModules(); - for (const CModule* pMod : Mods) { - CString sName = pMod->GetModName(); - CString sArgs = pMod->GetArgs(); + for (const CModule* pMod : Mods) { + CString sName = pMod->GetModName(); + CString sArgs = pMod->GetArgs(); - if (!sArgs.empty()) { - sArgs = " " + sArgs.FirstLine(); - } + if (!sArgs.empty()) { + sArgs = " " + sArgs.FirstLine(); + } - config.AddKeyValuePair("LoadModule", sName.FirstLine() + sArgs); - } + config.AddKeyValuePair("LoadModule", sName.FirstLine() + sArgs); + } - for (const auto& it : m_msUsers) { - CString sErr; + for (const auto& it : m_msUsers) { + CString sErr; - if (!it.second->IsValid(sErr)) { - DEBUG("** Error writing config for user [" << it.first << "] [" - << sErr << "]"); - continue; - } + if (!it.second->IsValid(sErr)) { + DEBUG("** Error writing config for user [" << it.first << "] [" + << sErr << "]"); + continue; + } - config.AddSubConfig("User", it.second->GetUserName(), - it.second->ToConfig()); - } + config.AddSubConfig("User", it.second->GetUserName(), + it.second->ToConfig()); + } - config.Write(*pFile); + config.Write(*pFile); - // If Sync() fails... well, let's hope nothing important breaks.. - pFile->Sync(); + // If Sync() fails... well, let's hope nothing important breaks.. + pFile->Sync(); - if (pFile->HadError()) { - DEBUG("Error while writing the config, errno says: " + - CString(strerror(errno))); - pFile->Delete(); - delete pFile; - return false; - } + if (pFile->HadError()) { + DEBUG("Error while writing the config, errno says: " + + CString(strerror(errno))); + pFile->Delete(); + delete pFile; + return false; + } - // We wrote to a temporary name, move it to the right place - if (!pFile->Move(GetConfigFile(), true)) { - DEBUG( - "Error while replacing the config file with a new version, errno " - "says " - << strerror(errno)); - pFile->Delete(); - delete pFile; - return false; - } + // We wrote to a temporary name, move it to the right place + if (!pFile->Move(GetConfigFile(), true)) { + DEBUG( + "Error while replacing the config file with a new version, errno " + "says " + << strerror(errno)); + pFile->Delete(); + delete pFile; + return false; + } - // Everything went fine, just need to update the saved path. - pFile->SetFileName(GetConfigFile()); + // Everything went fine, just need to update the saved path. + pFile->SetFileName(GetConfigFile()); - // Make sure the lock is kept alive as long as we need it. - delete m_pLockFile; - m_pLockFile = pFile; + // Make sure the lock is kept alive as long as we need it. + delete m_pLockFile; + m_pLockFile = pFile; - return true; + return true; } CString CZNC::MakeConfigHeader() { - return "// WARNING\n" - "//\n" - "// Do NOT edit this file while ZNC is running!\n" - "// Use webadmin or *controlpanel instead.\n" - "//\n" - "// Altering this file by hand will forfeit all support.\n" - "//\n" - "// But if you feel risky, you might want to read help on /znc " - "saveconfig and /znc rehash.\n" - "// Also check http://en.znc.in/wiki/Configuration\n"; + return "// WARNING\n" + "//\n" + "// Do NOT edit this file while ZNC is running!\n" + "// Use webadmin or *controlpanel instead.\n" + "//\n" + "// Altering this file by hand will forfeit all support.\n" + "//\n" + "// But if you feel risky, you might want to read help on /znc " + "saveconfig and /znc rehash.\n" + "// Also check http://en.znc.in/wiki/Configuration\n"; } bool CZNC::WriteNewConfig(const CString& sConfigFile) { - CString sAnswer, sUser, sNetwork; - VCString vsLines; + CString sAnswer, sUser, sNetwork; + VCString vsLines; - vsLines.push_back(MakeConfigHeader()); - vsLines.push_back("Version = " + CString(VERSION_STR)); + vsLines.push_back(MakeConfigHeader()); + vsLines.push_back("Version = " + CString(VERSION_STR)); - m_sConfigFile = ExpandConfigPath(sConfigFile); + m_sConfigFile = ExpandConfigPath(sConfigFile); - if (CFile::Exists(m_sConfigFile)) { - CUtils::PrintStatus( - false, "WARNING: config [" + m_sConfigFile + "] already exists."); - } + if (CFile::Exists(m_sConfigFile)) { + CUtils::PrintStatus( + false, "WARNING: config [" + m_sConfigFile + "] already exists."); + } - CUtils::PrintMessage(""); - CUtils::PrintMessage("-- Global settings --"); - CUtils::PrintMessage(""); + CUtils::PrintMessage(""); + CUtils::PrintMessage("-- Global settings --"); + CUtils::PrintMessage(""); // Listen #ifdef HAVE_IPV6 - bool b6 = true; + bool b6 = true; #else - bool b6 = false; + bool b6 = false; #endif - CString sListenHost; - CString sURIPrefix; - bool bListenSSL = false; - unsigned int uListenPort = 0; - bool bSuccess; + CString sListenHost; + CString sURIPrefix; + bool bListenSSL = false; + unsigned int uListenPort = 0; + bool bSuccess; - do { - bSuccess = true; - while (true) { - if (!CUtils::GetNumInput("Listen on port", uListenPort, 1025, - 65534)) { - continue; - } - if (uListenPort == 6667) { - CUtils::PrintStatus(false, - "WARNING: Some web browsers reject port " - "6667. If you intend to"); - CUtils::PrintStatus(false, - "use ZNC's web interface, you might want " - "to use another port."); - if (!CUtils::GetBoolInput("Proceed with port 6667 anyway?", - true)) { - continue; - } - } - break; - } + do { + bSuccess = true; + while (true) { + if (!CUtils::GetNumInput("Listen on port", uListenPort, 1025, + 65534)) { + continue; + } + if (uListenPort == 6667) { + CUtils::PrintStatus(false, + "WARNING: Some web browsers reject port " + "6667. If you intend to"); + CUtils::PrintStatus(false, + "use ZNC's web interface, you might want " + "to use another port."); + if (!CUtils::GetBoolInput("Proceed with port 6667 anyway?", + true)) { + continue; + } + } + break; + } #ifdef HAVE_LIBSSL - bListenSSL = CUtils::GetBoolInput("Listen using SSL", bListenSSL); + bListenSSL = CUtils::GetBoolInput("Listen using SSL", bListenSSL); #endif #ifdef HAVE_IPV6 - b6 = CUtils::GetBoolInput("Listen using both IPv4 and IPv6", b6); + b6 = CUtils::GetBoolInput("Listen using both IPv4 and IPv6", b6); #endif - // Don't ask for listen host, it may be configured later if needed. + // Don't ask for listen host, it may be configured later if needed. - CUtils::PrintAction("Verifying the listener"); - CListener* pListener = new CListener( - (unsigned short int)uListenPort, sListenHost, sURIPrefix, - bListenSSL, b6 ? ADDR_ALL : ADDR_IPV4ONLY, CListener::ACCEPT_ALL); - if (!pListener->Listen()) { - CUtils::PrintStatus(false, FormatBindError()); - bSuccess = false; - } else - CUtils::PrintStatus(true); - delete pListener; - } while (!bSuccess); + CUtils::PrintAction("Verifying the listener"); + CListener* pListener = new CListener( + (unsigned short int)uListenPort, sListenHost, sURIPrefix, + bListenSSL, b6 ? ADDR_ALL : ADDR_IPV4ONLY, CListener::ACCEPT_ALL); + if (!pListener->Listen()) { + CUtils::PrintStatus(false, FormatBindError()); + bSuccess = false; + } else + CUtils::PrintStatus(true); + delete pListener; + } while (!bSuccess); #ifdef HAVE_LIBSSL - CString sPemFile = GetPemLocation(); - if (!CFile::Exists(sPemFile)) { - CUtils::PrintMessage("Unable to locate pem file: [" + sPemFile + - "], creating it"); - WritePemFile(); - } + CString sPemFile = GetPemLocation(); + if (!CFile::Exists(sPemFile)) { + CUtils::PrintMessage("Unable to locate pem file: [" + sPemFile + + "], creating it"); + WritePemFile(); + } #endif - vsLines.push_back(""); - vsLines.push_back("\tPort = " + CString(uListenPort)); - vsLines.push_back("\tIPv4 = true"); - vsLines.push_back("\tIPv6 = " + CString(b6)); - vsLines.push_back("\tSSL = " + CString(bListenSSL)); - if (!sListenHost.empty()) { - vsLines.push_back("\tHost = " + sListenHost); - } - vsLines.push_back(""); - // !Listen + vsLines.push_back(""); + vsLines.push_back("\tPort = " + CString(uListenPort)); + vsLines.push_back("\tIPv4 = true"); + vsLines.push_back("\tIPv6 = " + CString(b6)); + vsLines.push_back("\tSSL = " + CString(bListenSSL)); + if (!sListenHost.empty()) { + vsLines.push_back("\tHost = " + sListenHost); + } + vsLines.push_back(""); + // !Listen - set ssGlobalMods; - GetModules().GetDefaultMods(ssGlobalMods, CModInfo::GlobalModule); - vector vsGlobalModNames; - for (const CModInfo& Info : ssGlobalMods) { - vsGlobalModNames.push_back(Info.GetName()); - vsLines.push_back("LoadModule = " + Info.GetName()); - } - CUtils::PrintMessage( - "Enabled global modules [" + - CString(", ").Join(vsGlobalModNames.begin(), vsGlobalModNames.end()) + - "]"); + set ssGlobalMods; + GetModules().GetDefaultMods(ssGlobalMods, CModInfo::GlobalModule); + vector vsGlobalModNames; + for (const CModInfo& Info : ssGlobalMods) { + vsGlobalModNames.push_back(Info.GetName()); + vsLines.push_back("LoadModule = " + Info.GetName()); + } + CUtils::PrintMessage( + "Enabled global modules [" + + CString(", ").Join(vsGlobalModNames.begin(), vsGlobalModNames.end()) + + "]"); - // User - CUtils::PrintMessage(""); - CUtils::PrintMessage("-- Admin user settings --"); - CUtils::PrintMessage(""); + // User + CUtils::PrintMessage(""); + CUtils::PrintMessage("-- Admin user settings --"); + CUtils::PrintMessage(""); - vsLines.push_back(""); - CString sNick; - do { - CUtils::GetInput("Username", sUser, "", "alphanumeric"); - } while (!CUser::IsValidUserName(sUser)); + vsLines.push_back(""); + CString sNick; + do { + CUtils::GetInput("Username", sUser, "", "alphanumeric"); + } while (!CUser::IsValidUserName(sUser)); - vsLines.push_back(""); - CString sSalt; - sAnswer = CUtils::GetSaltedHashPass(sSalt); - vsLines.push_back("\tPass = " + CUtils::sDefaultHash + "#" + sAnswer + - "#" + sSalt + "#"); + vsLines.push_back(""); + CString sSalt; + sAnswer = CUtils::GetSaltedHashPass(sSalt); + vsLines.push_back("\tPass = " + CUtils::sDefaultHash + "#" + sAnswer + + "#" + sSalt + "#"); - vsLines.push_back("\tAdmin = true"); + vsLines.push_back("\tAdmin = true"); - CUtils::GetInput("Nick", sNick, CUser::MakeCleanUserName(sUser)); - vsLines.push_back("\tNick = " + sNick); - CUtils::GetInput("Alternate nick", sAnswer, sNick + "_"); - if (!sAnswer.empty()) { - vsLines.push_back("\tAltNick = " + sAnswer); - } - CUtils::GetInput("Ident", sAnswer, sUser); - vsLines.push_back("\tIdent = " + sAnswer); - CUtils::GetInput("Real name", sAnswer, "", "optional"); - if (!sAnswer.empty()) { - vsLines.push_back("\tRealName = " + sAnswer); - } - CUtils::GetInput("Bind host", sAnswer, "", "optional"); - if (!sAnswer.empty()) { - vsLines.push_back("\tBindHost = " + sAnswer); - } + CUtils::GetInput("Nick", sNick, CUser::MakeCleanUserName(sUser)); + vsLines.push_back("\tNick = " + sNick); + CUtils::GetInput("Alternate nick", sAnswer, sNick + "_"); + if (!sAnswer.empty()) { + vsLines.push_back("\tAltNick = " + sAnswer); + } + CUtils::GetInput("Ident", sAnswer, sUser); + vsLines.push_back("\tIdent = " + sAnswer); + CUtils::GetInput("Real name", sAnswer, "", "optional"); + if (!sAnswer.empty()) { + vsLines.push_back("\tRealName = " + sAnswer); + } + CUtils::GetInput("Bind host", sAnswer, "", "optional"); + if (!sAnswer.empty()) { + vsLines.push_back("\tBindHost = " + sAnswer); + } - set ssUserMods; - GetModules().GetDefaultMods(ssUserMods, CModInfo::UserModule); - vector vsUserModNames; - for (const CModInfo& Info : ssUserMods) { - vsUserModNames.push_back(Info.GetName()); - vsLines.push_back("\tLoadModule = " + Info.GetName()); - } - CUtils::PrintMessage( - "Enabled user modules [" + - CString(", ").Join(vsUserModNames.begin(), vsUserModNames.end()) + "]"); + set ssUserMods; + GetModules().GetDefaultMods(ssUserMods, CModInfo::UserModule); + vector vsUserModNames; + for (const CModInfo& Info : ssUserMods) { + vsUserModNames.push_back(Info.GetName()); + vsLines.push_back("\tLoadModule = " + Info.GetName()); + } + CUtils::PrintMessage( + "Enabled user modules [" + + CString(", ").Join(vsUserModNames.begin(), vsUserModNames.end()) + "]"); - CUtils::PrintMessage(""); - if (CUtils::GetBoolInput("Set up a network?", true)) { - vsLines.push_back(""); + CUtils::PrintMessage(""); + if (CUtils::GetBoolInput("Set up a network?", true)) { + vsLines.push_back(""); - CUtils::PrintMessage(""); - CUtils::PrintMessage("-- Network settings --"); - CUtils::PrintMessage(""); + CUtils::PrintMessage(""); + CUtils::PrintMessage("-- Network settings --"); + CUtils::PrintMessage(""); - do { - CUtils::GetInput("Name", sNetwork, "freenode"); - } while (!CIRCNetwork::IsValidNetwork(sNetwork)); + do { + CUtils::GetInput("Name", sNetwork, "freenode"); + } while (!CIRCNetwork::IsValidNetwork(sNetwork)); - vsLines.push_back("\t"); + vsLines.push_back("\t"); - set ssNetworkMods; - GetModules().GetDefaultMods(ssNetworkMods, CModInfo::NetworkModule); - vector vsNetworkModNames; - for (const CModInfo& Info : ssNetworkMods) { - vsNetworkModNames.push_back(Info.GetName()); - vsLines.push_back("\t\tLoadModule = " + Info.GetName()); - } + set ssNetworkMods; + GetModules().GetDefaultMods(ssNetworkMods, CModInfo::NetworkModule); + vector vsNetworkModNames; + for (const CModInfo& Info : ssNetworkMods) { + vsNetworkModNames.push_back(Info.GetName()); + vsLines.push_back("\t\tLoadModule = " + Info.GetName()); + } - CString sHost, sPass, sHint; - bool bSSL = false; - unsigned int uServerPort = 0; + CString sHost, sPass, sHint; + bool bSSL = false; + unsigned int uServerPort = 0; - if (sNetwork.Equals("freenode")) { - sHost = "chat.freenode.net"; + if (sNetwork.Equals("freenode")) { + sHost = "chat.freenode.net"; #ifdef HAVE_LIBSSL - bSSL = true; + bSSL = true; #endif - } else { - sHint = "host only"; - } + } else { + sHint = "host only"; + } - while (!CUtils::GetInput("Server host", sHost, sHost, sHint) || - !CServer::IsValidHostName(sHost)) - ; + while (!CUtils::GetInput("Server host", sHost, sHost, sHint) || + !CServer::IsValidHostName(sHost)) + ; #ifdef HAVE_LIBSSL - bSSL = CUtils::GetBoolInput("Server uses SSL?", bSSL); + bSSL = CUtils::GetBoolInput("Server uses SSL?", bSSL); #endif - while (!CUtils::GetNumInput("Server port", uServerPort, 1, 65535, - bSSL ? 6697 : 6667)) - ; - CUtils::GetInput("Server password (probably empty)", sPass); + while (!CUtils::GetNumInput("Server port", uServerPort, 1, 65535, + bSSL ? 6697 : 6667)) + ; + CUtils::GetInput("Server password (probably empty)", sPass); - vsLines.push_back("\t\tServer = " + sHost + ((bSSL) ? " +" : " ") + - CString(uServerPort) + " " + sPass); + vsLines.push_back("\t\tServer = " + sHost + ((bSSL) ? " +" : " ") + + CString(uServerPort) + " " + sPass); - CString sChans; - if (CUtils::GetInput("Initial channels", sChans)) { - vsLines.push_back(""); - VCString vsChans; - sChans.Replace(",", " "); - sChans.Replace(";", " "); - sChans.Split(" ", vsChans, false, "", "", true, true); - for (const CString& sChan : vsChans) { - vsLines.push_back("\t\t"); - vsLines.push_back("\t\t"); - } - } + CString sChans; + if (CUtils::GetInput("Initial channels", sChans)) { + vsLines.push_back(""); + VCString vsChans; + sChans.Replace(",", " "); + sChans.Replace(";", " "); + sChans.Split(" ", vsChans, false, "", "", true, true); + for (const CString& sChan : vsChans) { + vsLines.push_back("\t\t"); + vsLines.push_back("\t\t"); + } + } - CUtils::PrintMessage("Enabled network modules [" + - CString(", ").Join(vsNetworkModNames.begin(), - vsNetworkModNames.end()) + - "]"); + CUtils::PrintMessage("Enabled network modules [" + + CString(", ").Join(vsNetworkModNames.begin(), + vsNetworkModNames.end()) + + "]"); - vsLines.push_back("\t"); - } + vsLines.push_back("\t"); + } - vsLines.push_back(""); + vsLines.push_back(""); - CUtils::PrintMessage(""); - // !User + CUtils::PrintMessage(""); + // !User - CFile File; - bool bFileOK, bFileOpen = false; - do { - CUtils::PrintAction("Writing config [" + m_sConfigFile + "]"); + CFile File; + bool bFileOK, bFileOpen = false; + do { + CUtils::PrintAction("Writing config [" + m_sConfigFile + "]"); - bFileOK = true; - if (CFile::Exists(m_sConfigFile)) { - if (!File.TryExLock(m_sConfigFile)) { - CUtils::PrintStatus(false, - "ZNC is currently running on this config."); - bFileOK = false; - } else { - File.Close(); - CUtils::PrintStatus(false, "This config already exists."); - if (CUtils::GetBoolInput( - "Are you sure you want to overwrite it?", false)) - CUtils::PrintAction("Overwriting config [" + m_sConfigFile + - "]"); - else - bFileOK = false; - } - } + bFileOK = true; + if (CFile::Exists(m_sConfigFile)) { + if (!File.TryExLock(m_sConfigFile)) { + CUtils::PrintStatus(false, + "ZNC is currently running on this config."); + bFileOK = false; + } else { + File.Close(); + CUtils::PrintStatus(false, "This config already exists."); + if (CUtils::GetBoolInput( + "Are you sure you want to overwrite it?", false)) + CUtils::PrintAction("Overwriting config [" + m_sConfigFile + + "]"); + else + bFileOK = false; + } + } - if (bFileOK) { - File.SetFileName(m_sConfigFile); - if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { - bFileOpen = true; - } else { - CUtils::PrintStatus(false, "Unable to open file"); - bFileOK = false; - } - } - if (!bFileOK) { - while (!CUtils::GetInput("Please specify an alternate location", - m_sConfigFile, "", - "or \"stdout\" for displaying the config")) - ; - if (m_sConfigFile.Equals("stdout")) - bFileOK = true; - else - m_sConfigFile = ExpandConfigPath(m_sConfigFile); - } - } while (!bFileOK); + if (bFileOK) { + File.SetFileName(m_sConfigFile); + if (File.Open(O_WRONLY | O_CREAT | O_TRUNC, 0600)) { + bFileOpen = true; + } else { + CUtils::PrintStatus(false, "Unable to open file"); + bFileOK = false; + } + } + if (!bFileOK) { + while (!CUtils::GetInput("Please specify an alternate location", + m_sConfigFile, "", + "or \"stdout\" for displaying the config")) + ; + if (m_sConfigFile.Equals("stdout")) + bFileOK = true; + else + m_sConfigFile = ExpandConfigPath(m_sConfigFile); + } + } while (!bFileOK); - if (!bFileOpen) { - CUtils::PrintMessage(""); - CUtils::PrintMessage("Printing the new config to stdout:"); - CUtils::PrintMessage(""); - cout << endl << "------------------------------------------------------" - "----------------------" << endl << endl; - } + if (!bFileOpen) { + CUtils::PrintMessage(""); + CUtils::PrintMessage("Printing the new config to stdout:"); + CUtils::PrintMessage(""); + cout << endl << "------------------------------------------------------" + "----------------------" << endl << endl; + } - for (const CString& sLine : vsLines) { - if (bFileOpen) { - File.Write(sLine + "\n"); - } else { - cout << sLine << endl; - } - } + for (const CString& sLine : vsLines) { + if (bFileOpen) { + File.Write(sLine + "\n"); + } else { + cout << sLine << endl; + } + } - if (bFileOpen) { - File.Close(); - if (File.HadError()) - CUtils::PrintStatus(false, - "There was an error while writing the config"); - else - CUtils::PrintStatus(true); - } else { - cout << endl << "------------------------------------------------------" - "----------------------" << endl << endl; - } + if (bFileOpen) { + File.Close(); + if (File.HadError()) + CUtils::PrintStatus(false, + "There was an error while writing the config"); + else + CUtils::PrintStatus(true); + } else { + cout << endl << "------------------------------------------------------" + "----------------------" << endl << endl; + } - if (File.HadError()) { - bFileOpen = false; - CUtils::PrintMessage("Printing the new config to stdout instead:"); - cout << endl << "------------------------------------------------------" - "----------------------" << endl << endl; - for (const CString& sLine : vsLines) { - cout << sLine << endl; - } - cout << endl << "------------------------------------------------------" - "----------------------" << endl << endl; - } + if (File.HadError()) { + bFileOpen = false; + CUtils::PrintMessage("Printing the new config to stdout instead:"); + cout << endl << "------------------------------------------------------" + "----------------------" << endl << endl; + for (const CString& sLine : vsLines) { + cout << sLine << endl; + } + cout << endl << "------------------------------------------------------" + "----------------------" << endl << endl; + } - const CString sProtocol(bListenSSL ? "https" : "http"); - const CString sSSL(bListenSSL ? "+" : ""); - CUtils::PrintMessage(""); - CUtils::PrintMessage( - "To connect to this ZNC you need to connect to it as your IRC server", - true); - CUtils::PrintMessage( - "using the port that you supplied. You have to supply your login info", - true); - CUtils::PrintMessage( - "as the IRC server password like this: user/network:pass.", true); - CUtils::PrintMessage(""); - CUtils::PrintMessage("Try something like this in your IRC client...", true); - CUtils::PrintMessage("/server " + sSSL + - CString(uListenPort) + " " + sUser + ":", - true); - CUtils::PrintMessage(""); - CUtils::PrintMessage( - "To manage settings, users and networks, point your web browser to", - true); - CUtils::PrintMessage( - sProtocol + "://:" + CString(uListenPort) + "/", true); - CUtils::PrintMessage(""); + const CString sProtocol(bListenSSL ? "https" : "http"); + const CString sSSL(bListenSSL ? "+" : ""); + CUtils::PrintMessage(""); + CUtils::PrintMessage( + "To connect to this ZNC you need to connect to it as your IRC server", + true); + CUtils::PrintMessage( + "using the port that you supplied. You have to supply your login info", + true); + CUtils::PrintMessage( + "as the IRC server password like this: user/network:pass.", true); + CUtils::PrintMessage(""); + CUtils::PrintMessage("Try something like this in your IRC client...", true); + CUtils::PrintMessage("/server " + sSSL + + CString(uListenPort) + " " + sUser + ":", + true); + CUtils::PrintMessage(""); + CUtils::PrintMessage( + "To manage settings, users and networks, point your web browser to", + true); + CUtils::PrintMessage( + sProtocol + "://:" + CString(uListenPort) + "/", true); + CUtils::PrintMessage(""); - File.UnLock(); + File.UnLock(); - bool bWantLaunch = bFileOpen; - if (bWantLaunch) { - // "export ZNC_NO_LAUNCH_AFTER_MAKECONF=1" would cause znc --makeconf to - // not offer immediate launch. - // Useful for distros which want to create config when znc package is - // installed. - // See https://github.com/znc/znc/pull/257 - char* szNoLaunch = getenv("ZNC_NO_LAUNCH_AFTER_MAKECONF"); - if (szNoLaunch && *szNoLaunch == '1') { - bWantLaunch = false; - } - } - if (bWantLaunch) { - bWantLaunch = CUtils::GetBoolInput("Launch ZNC now?", true); - } - return bWantLaunch; + bool bWantLaunch = bFileOpen; + if (bWantLaunch) { + // "export ZNC_NO_LAUNCH_AFTER_MAKECONF=1" would cause znc --makeconf to + // not offer immediate launch. + // Useful for distros which want to create config when znc package is + // installed. + // See https://github.com/znc/znc/pull/257 + char* szNoLaunch = getenv("ZNC_NO_LAUNCH_AFTER_MAKECONF"); + if (szNoLaunch && *szNoLaunch == '1') { + bWantLaunch = false; + } + } + if (bWantLaunch) { + bWantLaunch = CUtils::GetBoolInput("Launch ZNC now?", true); + } + return bWantLaunch; } void CZNC::BackupConfigOnce(const CString& sSuffix) { - static bool didBackup = false; - if (didBackup) return; - didBackup = true; + static bool didBackup = false; + if (didBackup) return; + didBackup = true; - CUtils::PrintAction("Creating a config backup"); + CUtils::PrintAction("Creating a config backup"); - CString sBackup = CDir::ChangeDir(m_sConfigFile, "../znc.conf." + sSuffix); - if (CFile::Copy(m_sConfigFile, sBackup)) - CUtils::PrintStatus(true, sBackup); - else - CUtils::PrintStatus(false, strerror(errno)); + CString sBackup = CDir::ChangeDir(m_sConfigFile, "../znc.conf." + sSuffix); + if (CFile::Copy(m_sConfigFile, sBackup)) + CUtils::PrintStatus(true, sBackup); + else + CUtils::PrintStatus(false, strerror(errno)); } bool CZNC::ParseConfig(const CString& sConfig, CString& sError) { - m_sConfigFile = ExpandConfigPath(sConfig, false); + m_sConfigFile = ExpandConfigPath(sConfig, false); - CConfig config; - if (!ReadConfig(config, sError)) return false; + CConfig config; + if (!ReadConfig(config, sError)) return false; - if (!LoadGlobal(config, sError)) return false; + if (!LoadGlobal(config, sError)) return false; - if (!LoadUsers(config, sError)) return false; + if (!LoadUsers(config, sError)) return false; - return true; + return true; } bool CZNC::ReadConfig(CConfig& config, CString& sError) { - sError.clear(); + sError.clear(); - CUtils::PrintAction("Opening config [" + m_sConfigFile + "]"); + CUtils::PrintAction("Opening config [" + m_sConfigFile + "]"); - if (!CFile::Exists(m_sConfigFile)) { - sError = "No such file"; - CUtils::PrintStatus(false, sError); - CUtils::PrintMessage( - "Restart ZNC with the --makeconf option if you wish to create this " - "config."); - return false; - } + if (!CFile::Exists(m_sConfigFile)) { + sError = "No such file"; + CUtils::PrintStatus(false, sError); + CUtils::PrintMessage( + "Restart ZNC with the --makeconf option if you wish to create this " + "config."); + return false; + } - if (!CFile::IsReg(m_sConfigFile)) { - sError = "Not a file"; - CUtils::PrintStatus(false, sError); - return false; - } + if (!CFile::IsReg(m_sConfigFile)) { + sError = "Not a file"; + CUtils::PrintStatus(false, sError); + return false; + } - CFile* pFile = new CFile(m_sConfigFile); + CFile* pFile = new CFile(m_sConfigFile); - // need to open the config file Read/Write for fcntl() - // exclusive locking to work properly! - if (!pFile->Open(m_sConfigFile, O_RDWR)) { - sError = "Can not open config file"; - CUtils::PrintStatus(false, sError); - delete pFile; - return false; - } + // need to open the config file Read/Write for fcntl() + // exclusive locking to work properly! + if (!pFile->Open(m_sConfigFile, O_RDWR)) { + sError = "Can not open config file"; + CUtils::PrintStatus(false, sError); + delete pFile; + return false; + } - if (!pFile->TryExLock()) { - sError = "ZNC is already running on this config."; - CUtils::PrintStatus(false, sError); - delete pFile; - return false; - } + if (!pFile->TryExLock()) { + sError = "ZNC is already running on this config."; + CUtils::PrintStatus(false, sError); + delete pFile; + return false; + } - // (re)open the config file - delete m_pLockFile; - m_pLockFile = pFile; - CFile& File = *pFile; + // (re)open the config file + delete m_pLockFile; + m_pLockFile = pFile; + CFile& File = *pFile; - if (!config.Parse(File, sError)) { - CUtils::PrintStatus(false, sError); - return false; - } - CUtils::PrintStatus(true); + if (!config.Parse(File, sError)) { + CUtils::PrintStatus(false, sError); + return false; + } + CUtils::PrintStatus(true); - // check if config is from old ZNC version and - // create a backup file if neccessary - CString sSavedVersion; - config.FindStringEntry("version", sSavedVersion); - if (sSavedVersion.empty()) { - CUtils::PrintError( - "Config does not contain a version identifier. It may be be too " - "old or corrupt."); - return false; - } + // check if config is from old ZNC version and + // create a backup file if neccessary + CString sSavedVersion; + config.FindStringEntry("version", sSavedVersion); + if (sSavedVersion.empty()) { + CUtils::PrintError( + "Config does not contain a version identifier. It may be be too " + "old or corrupt."); + return false; + } - tuple tSavedVersion = - make_tuple(sSavedVersion.Token(0, false, ".").ToUInt(), - sSavedVersion.Token(1, false, ".").ToUInt()); - tuple tCurrentVersion = - make_tuple(VERSION_MAJOR, VERSION_MINOR); - if (tSavedVersion < tCurrentVersion) { - CUtils::PrintMessage("Found old config from ZNC " + sSavedVersion + - ". Saving a backup of it."); - BackupConfigOnce("pre-" + CString(VERSION_STR)); - } else if (tSavedVersion > tCurrentVersion) { - CUtils::PrintError("Config was saved from ZNC " + sSavedVersion + - ". It may or may not work with current ZNC " + - GetVersion()); - } + tuple tSavedVersion = + make_tuple(sSavedVersion.Token(0, false, ".").ToUInt(), + sSavedVersion.Token(1, false, ".").ToUInt()); + tuple tCurrentVersion = + make_tuple(VERSION_MAJOR, VERSION_MINOR); + if (tSavedVersion < tCurrentVersion) { + CUtils::PrintMessage("Found old config from ZNC " + sSavedVersion + + ". Saving a backup of it."); + BackupConfigOnce("pre-" + CString(VERSION_STR)); + } else if (tSavedVersion > tCurrentVersion) { + CUtils::PrintError("Config was saved from ZNC " + sSavedVersion + + ". It may or may not work with current ZNC " + + GetVersion()); + } - return true; + return true; } bool CZNC::RehashConfig(CString& sError) { - ALLMODULECALL(OnPreRehash(), NOTHING); + ALLMODULECALL(OnPreRehash(), NOTHING); - CConfig config; - if (!ReadConfig(config, sError)) return false; + CConfig config; + if (!ReadConfig(config, sError)) return false; - if (!LoadGlobal(config, sError)) return false; + if (!LoadGlobal(config, sError)) return false; - // do not reload users - it's dangerous! + // do not reload users - it's dangerous! - ALLMODULECALL(OnPostRehash(), NOTHING); - return true; + ALLMODULECALL(OnPostRehash(), NOTHING); + return true; } bool CZNC::LoadGlobal(CConfig& config, CString& sError) { - sError.clear(); + sError.clear(); - MCString msModules; // Modules are queued for later loading + MCString msModules; // Modules are queued for later loading - VCString vsList; - config.FindStringVector("loadmodule", vsList); - for (const CString& sModLine : vsList) { - CString sModName = sModLine.Token(0); - CString sArgs = sModLine.Token(1, true); + VCString vsList; + config.FindStringVector("loadmodule", vsList); + for (const CString& sModLine : vsList) { + CString sModName = sModLine.Token(0); + CString sArgs = sModLine.Token(1, true); - // compatibility for pre-1.0 configs - CString sSavedVersion; - config.FindStringEntry("version", sSavedVersion); - tuple tSavedVersion = - make_tuple(sSavedVersion.Token(0, false, ".").ToUInt(), - sSavedVersion.Token(1, false, ".").ToUInt()); - if (sModName == "saslauth" && tSavedVersion < make_tuple(0, 207)) { - CUtils::PrintMessage( - "saslauth module was renamed to cyrusauth. Loading cyrusauth " - "instead."); - sModName = "cyrusauth"; - } - // end-compatibility for pre-1.0 configs + // compatibility for pre-1.0 configs + CString sSavedVersion; + config.FindStringEntry("version", sSavedVersion); + tuple tSavedVersion = + make_tuple(sSavedVersion.Token(0, false, ".").ToUInt(), + sSavedVersion.Token(1, false, ".").ToUInt()); + if (sModName == "saslauth" && tSavedVersion < make_tuple(0, 207)) { + CUtils::PrintMessage( + "saslauth module was renamed to cyrusauth. Loading cyrusauth " + "instead."); + sModName = "cyrusauth"; + } + // end-compatibility for pre-1.0 configs - if (msModules.find(sModName) != msModules.end()) { - sError = "Module [" + sModName + "] already loaded"; - CUtils::PrintError(sError); - return false; - } - CString sModRet; - CModule* pOldMod; + if (msModules.find(sModName) != msModules.end()) { + sError = "Module [" + sModName + "] already loaded"; + CUtils::PrintError(sError); + return false; + } + CString sModRet; + CModule* pOldMod; - pOldMod = GetModules().FindModule(sModName); - if (!pOldMod) { - CUtils::PrintAction("Loading global module [" + sModName + "]"); + pOldMod = GetModules().FindModule(sModName); + if (!pOldMod) { + CUtils::PrintAction("Loading global module [" + sModName + "]"); - bool bModRet = - GetModules().LoadModule(sModName, sArgs, CModInfo::GlobalModule, - nullptr, nullptr, sModRet); + bool bModRet = + GetModules().LoadModule(sModName, sArgs, CModInfo::GlobalModule, + nullptr, nullptr, sModRet); - CUtils::PrintStatus(bModRet, bModRet ? "" : sModRet); - if (!bModRet) { - sError = sModRet; - return false; - } - } else if (pOldMod->GetArgs() != sArgs) { - CUtils::PrintAction("Reloading global module [" + sModName + "]"); + CUtils::PrintStatus(bModRet, bModRet ? "" : sModRet); + if (!bModRet) { + sError = sModRet; + return false; + } + } else if (pOldMod->GetArgs() != sArgs) { + CUtils::PrintAction("Reloading global module [" + sModName + "]"); - bool bModRet = GetModules().ReloadModule(sModName, sArgs, nullptr, - nullptr, sModRet); + bool bModRet = GetModules().ReloadModule(sModName, sArgs, nullptr, + nullptr, sModRet); - CUtils::PrintStatus(bModRet, sModRet); - if (!bModRet) { - sError = sModRet; - return false; - } - } else - CUtils::PrintMessage("Module [" + sModName + "] already loaded."); + CUtils::PrintStatus(bModRet, sModRet); + if (!bModRet) { + sError = sModRet; + return false; + } + } else + CUtils::PrintMessage("Module [" + sModName + "] already loaded."); - msModules[sModName] = sArgs; - } + msModules[sModName] = sArgs; + } - m_vsMotd.clear(); - config.FindStringVector("motd", vsList); - for (const CString& sMotd : vsList) { - AddMotd(sMotd); - } + m_vsMotd.clear(); + config.FindStringVector("motd", vsList); + for (const CString& sMotd : vsList) { + AddMotd(sMotd); + } - if (config.FindStringVector("bindhost", vsList)) { - CUtils::PrintStatus(false, - "WARNING: the global BindHost list is deprecated. " - "Ignoring the following lines:"); - for (const CString& sHost : vsList) { - CUtils::PrintStatus(false, "BindHost = " + sHost); - } - } - if (config.FindStringVector("vhost", vsList)) { - CUtils::PrintStatus(false, - "WARNING: the global vHost list is deprecated. " - "Ignoring the following lines:"); - for (const CString& sHost : vsList) { - CUtils::PrintStatus(false, "vHost = " + sHost); - } - } + if (config.FindStringVector("bindhost", vsList)) { + CUtils::PrintStatus(false, + "WARNING: the global BindHost list is deprecated. " + "Ignoring the following lines:"); + for (const CString& sHost : vsList) { + CUtils::PrintStatus(false, "BindHost = " + sHost); + } + } + if (config.FindStringVector("vhost", vsList)) { + CUtils::PrintStatus(false, + "WARNING: the global vHost list is deprecated. " + "Ignoring the following lines:"); + for (const CString& sHost : vsList) { + CUtils::PrintStatus(false, "vHost = " + sHost); + } + } - m_vsTrustedProxies.clear(); - config.FindStringVector("trustedproxy", vsList); - for (const CString& sProxy : vsList) { - AddTrustedProxy(sProxy); - } + m_vsTrustedProxies.clear(); + config.FindStringVector("trustedproxy", vsList); + for (const CString& sProxy : vsList) { + AddTrustedProxy(sProxy); + } - CString sVal; - if (config.FindStringEntry("pidfile", sVal)) m_sPidFile = sVal; - if (config.FindStringEntry("statusprefix", sVal)) m_sStatusPrefix = sVal; - if (config.FindStringEntry("sslcertfile", sVal)) m_sSSLCertFile = sVal; - if (config.FindStringEntry("sslkeyfile", sVal)) m_sSSLKeyFile = sVal; - if (config.FindStringEntry("ssldhparamfile", sVal)) - m_sSSLDHParamFile = sVal; - if (config.FindStringEntry("sslciphers", sVal)) m_sSSLCiphers = sVal; - if (config.FindStringEntry("skin", sVal)) SetSkinName(sVal); - if (config.FindStringEntry("connectdelay", sVal)) - SetConnectDelay(sVal.ToUInt()); - if (config.FindStringEntry("serverthrottle", sVal)) - m_sConnectThrottle.SetTTL(sVal.ToUInt() * 1000); - if (config.FindStringEntry("anoniplimit", sVal)) - m_uiAnonIPLimit = sVal.ToUInt(); - if (config.FindStringEntry("maxbuffersize", sVal)) - m_uiMaxBufferSize = sVal.ToUInt(); - if (config.FindStringEntry("protectwebsessions", sVal)) - m_bProtectWebSessions = sVal.ToBool(); - if (config.FindStringEntry("hideversion", sVal)) - m_bHideVersion = sVal.ToBool(); - if (config.FindStringEntry("sslprotocols", sVal)) { - if (!SetSSLProtocols(sVal)) { - VCString vsProtocols = GetAvailableSSLProtocols(); - CUtils::PrintError("Invalid SSLProtocols value [" + sVal + "]"); - CUtils::PrintError( - "The syntax is [SSLProtocols = [+|-] ...]"); - CUtils::PrintError( - "Available protocols are [" + - CString(", ").Join(vsProtocols.begin(), vsProtocols.end()) + - "]"); - return false; - } - } + CString sVal; + if (config.FindStringEntry("pidfile", sVal)) m_sPidFile = sVal; + if (config.FindStringEntry("statusprefix", sVal)) m_sStatusPrefix = sVal; + if (config.FindStringEntry("sslcertfile", sVal)) m_sSSLCertFile = sVal; + if (config.FindStringEntry("sslkeyfile", sVal)) m_sSSLKeyFile = sVal; + if (config.FindStringEntry("ssldhparamfile", sVal)) + m_sSSLDHParamFile = sVal; + if (config.FindStringEntry("sslciphers", sVal)) m_sSSLCiphers = sVal; + if (config.FindStringEntry("skin", sVal)) SetSkinName(sVal); + if (config.FindStringEntry("connectdelay", sVal)) + SetConnectDelay(sVal.ToUInt()); + if (config.FindStringEntry("serverthrottle", sVal)) + m_sConnectThrottle.SetTTL(sVal.ToUInt() * 1000); + if (config.FindStringEntry("anoniplimit", sVal)) + m_uiAnonIPLimit = sVal.ToUInt(); + if (config.FindStringEntry("maxbuffersize", sVal)) + m_uiMaxBufferSize = sVal.ToUInt(); + if (config.FindStringEntry("protectwebsessions", sVal)) + m_bProtectWebSessions = sVal.ToBool(); + if (config.FindStringEntry("hideversion", sVal)) + m_bHideVersion = sVal.ToBool(); + if (config.FindStringEntry("sslprotocols", sVal)) { + if (!SetSSLProtocols(sVal)) { + VCString vsProtocols = GetAvailableSSLProtocols(); + CUtils::PrintError("Invalid SSLProtocols value [" + sVal + "]"); + CUtils::PrintError( + "The syntax is [SSLProtocols = [+|-] ...]"); + CUtils::PrintError( + "Available protocols are [" + + CString(", ").Join(vsProtocols.begin(), vsProtocols.end()) + + "]"); + return false; + } + } - UnloadRemovedModules(msModules); + UnloadRemovedModules(msModules); - if (!LoadListeners(config, sError)) return false; + if (!LoadListeners(config, sError)) return false; - return true; + return true; } bool CZNC::LoadUsers(CConfig& config, CString& sError) { - sError.clear(); + sError.clear(); - m_msUsers.clear(); + m_msUsers.clear(); - CConfig::SubConfig subConf; - config.FindSubConfig("user", subConf); + CConfig::SubConfig subConf; + config.FindSubConfig("user", subConf); - for (const auto& subIt : subConf) { - const CString& sUserName = subIt.first; - CConfig* pSubConf = subIt.second.m_pSubConfig; + for (const auto& subIt : subConf) { + const CString& sUserName = subIt.first; + CConfig* pSubConf = subIt.second.m_pSubConfig; - CUtils::PrintMessage("Loading user [" + sUserName + "]"); + CUtils::PrintMessage("Loading user [" + sUserName + "]"); - CUser* pUser = new CUser(sUserName); + CUser* pUser = new CUser(sUserName); - if (!m_sStatusPrefix.empty()) { - if (!pUser->SetStatusPrefix(m_sStatusPrefix)) { - sError = "Invalid StatusPrefix [" + m_sStatusPrefix + - "] Must be 1-5 chars, no spaces."; - CUtils::PrintError(sError); - return false; - } - } + if (!m_sStatusPrefix.empty()) { + if (!pUser->SetStatusPrefix(m_sStatusPrefix)) { + sError = "Invalid StatusPrefix [" + m_sStatusPrefix + + "] Must be 1-5 chars, no spaces."; + CUtils::PrintError(sError); + return false; + } + } - if (!pUser->ParseConfig(pSubConf, sError)) { - CUtils::PrintError(sError); - delete pUser; - pUser = nullptr; - return false; - } + if (!pUser->ParseConfig(pSubConf, sError)) { + CUtils::PrintError(sError); + delete pUser; + pUser = nullptr; + return false; + } - if (!pSubConf->empty()) { - sError = "Unhandled lines in config for User [" + sUserName + "]!"; - CUtils::PrintError(sError); + if (!pSubConf->empty()) { + sError = "Unhandled lines in config for User [" + sUserName + "]!"; + CUtils::PrintError(sError); - DumpConfig(pSubConf); - return false; - } + DumpConfig(pSubConf); + return false; + } - CString sErr; - if (!AddUser(pUser, sErr, true)) { - sError = "Invalid user [" + pUser->GetUserName() + "] " + sErr; - } + CString sErr; + if (!AddUser(pUser, sErr, true)) { + sError = "Invalid user [" + pUser->GetUserName() + "] " + sErr; + } - if (!sError.empty()) { - CUtils::PrintError(sError); - if (pUser) { - pUser->SetBeingDeleted(true); - delete pUser; - pUser = nullptr; - } - return false; - } + if (!sError.empty()) { + CUtils::PrintError(sError); + if (pUser) { + pUser->SetBeingDeleted(true); + delete pUser; + pUser = nullptr; + } + return false; + } - pUser = nullptr; - } + pUser = nullptr; + } - if (m_msUsers.empty()) { - sError = "You must define at least one user in your config."; - CUtils::PrintError(sError); - return false; - } + if (m_msUsers.empty()) { + sError = "You must define at least one user in your config."; + CUtils::PrintError(sError); + return false; + } - return true; + return true; } bool CZNC::LoadListeners(CConfig& config, CString& sError) { - sError.clear(); + sError.clear(); - // Delete all listeners - while (!m_vpListeners.empty()) { - delete m_vpListeners[0]; - m_vpListeners.erase(m_vpListeners.begin()); - } + // Delete all listeners + while (!m_vpListeners.empty()) { + delete m_vpListeners[0]; + m_vpListeners.erase(m_vpListeners.begin()); + } - // compatibility for pre-1.0 configs - const char* szListenerEntries[] = {"listen", "listen6", "listen4", - "listener", "listener6", "listener4"}; + // compatibility for pre-1.0 configs + const char* szListenerEntries[] = {"listen", "listen6", "listen4", + "listener", "listener6", "listener4"}; - VCString vsList; - config.FindStringVector("loadmodule", vsList); + VCString vsList; + config.FindStringVector("loadmodule", vsList); - // This has to be after SSLCertFile is handled since it uses that value - for (const char* szEntry : szListenerEntries) { - config.FindStringVector(szEntry, vsList); - for (const CString& sListener : vsList) { - if (!AddListener(szEntry + CString(" ") + sListener, sError)) - return false; - } - } - // end-compatibility for pre-1.0 configs + // This has to be after SSLCertFile is handled since it uses that value + for (const char* szEntry : szListenerEntries) { + config.FindStringVector(szEntry, vsList); + for (const CString& sListener : vsList) { + if (!AddListener(szEntry + CString(" ") + sListener, sError)) + return false; + } + } + // end-compatibility for pre-1.0 configs - CConfig::SubConfig subConf; - config.FindSubConfig("listener", subConf); + CConfig::SubConfig subConf; + config.FindSubConfig("listener", subConf); - for (const auto& subIt : subConf) { - CConfig* pSubConf = subIt.second.m_pSubConfig; - if (!AddListener(pSubConf, sError)) return false; - if (!pSubConf->empty()) { - sError = "Unhandled lines in Listener config!"; - CUtils::PrintError(sError); + for (const auto& subIt : subConf) { + CConfig* pSubConf = subIt.second.m_pSubConfig; + if (!AddListener(pSubConf, sError)) return false; + if (!pSubConf->empty()) { + sError = "Unhandled lines in Listener config!"; + CUtils::PrintError(sError); - CZNC::DumpConfig(pSubConf); - return false; - } - } + CZNC::DumpConfig(pSubConf); + return false; + } + } - if (m_vpListeners.empty()) { - sError = "You must supply at least one Listener in your config."; - CUtils::PrintError(sError); - return false; - } + if (m_vpListeners.empty()) { + sError = "You must supply at least one Listener in your config."; + CUtils::PrintError(sError); + return false; + } - return true; + return true; } void CZNC::UnloadRemovedModules(const MCString& msModules) { - // unload modules which are no longer in the config + // unload modules which are no longer in the config - set ssUnload; - for (CModule* pCurMod : GetModules()) { - if (msModules.find(pCurMod->GetModName()) == msModules.end()) - ssUnload.insert(pCurMod->GetModName()); - } + set ssUnload; + for (CModule* pCurMod : GetModules()) { + if (msModules.find(pCurMod->GetModName()) == msModules.end()) + ssUnload.insert(pCurMod->GetModName()); + } - for (const CString& sMod : ssUnload) { - if (GetModules().UnloadModule(sMod)) - CUtils::PrintMessage("Unloaded global module [" + sMod + "]"); - else - CUtils::PrintMessage("Could not unload [" + sMod + "]"); - } + for (const CString& sMod : ssUnload) { + if (GetModules().UnloadModule(sMod)) + CUtils::PrintMessage("Unloaded global module [" + sMod + "]"); + else + CUtils::PrintMessage("Could not unload [" + sMod + "]"); + } } void CZNC::DumpConfig(const CConfig* pConfig) { - CConfig::EntryMapIterator eit = pConfig->BeginEntries(); - for (; eit != pConfig->EndEntries(); ++eit) { - const CString& sKey = eit->first; - const VCString& vsList = eit->second; - VCString::const_iterator it = vsList.begin(); - for (; it != vsList.end(); ++it) { - CUtils::PrintError(sKey + " = " + *it); - } - } + CConfig::EntryMapIterator eit = pConfig->BeginEntries(); + for (; eit != pConfig->EndEntries(); ++eit) { + const CString& sKey = eit->first; + const VCString& vsList = eit->second; + VCString::const_iterator it = vsList.begin(); + for (; it != vsList.end(); ++it) { + CUtils::PrintError(sKey + " = " + *it); + } + } - CConfig::SubConfigMapIterator sit = pConfig->BeginSubConfigs(); - for (; sit != pConfig->EndSubConfigs(); ++sit) { - const CString& sKey = sit->first; - const CConfig::SubConfig& sSub = sit->second; - CConfig::SubConfig::const_iterator it = sSub.begin(); + CConfig::SubConfigMapIterator sit = pConfig->BeginSubConfigs(); + for (; sit != pConfig->EndSubConfigs(); ++sit) { + const CString& sKey = sit->first; + const CConfig::SubConfig& sSub = sit->second; + CConfig::SubConfig::const_iterator it = sSub.begin(); - for (; it != sSub.end(); ++it) { - CUtils::PrintError("SubConfig [" + sKey + " " + it->first + "]:"); - DumpConfig(it->second.m_pSubConfig); - } - } + for (; it != sSub.end(); ++it) { + CUtils::PrintError("SubConfig [" + sKey + " " + it->first + "]:"); + DumpConfig(it->second.m_pSubConfig); + } + } } void CZNC::ClearTrustedProxies() { m_vsTrustedProxies.clear(); } bool CZNC::AddTrustedProxy(const CString& sHost) { - if (sHost.empty()) { - return false; - } + if (sHost.empty()) { + return false; + } - for (const CString& sTrustedProxy : m_vsTrustedProxies) { - if (sTrustedProxy.Equals(sHost)) { - return false; - } - } + for (const CString& sTrustedProxy : m_vsTrustedProxies) { + if (sTrustedProxy.Equals(sHost)) { + return false; + } + } - m_vsTrustedProxies.push_back(sHost); - return true; + m_vsTrustedProxies.push_back(sHost); + return true; } bool CZNC::RemTrustedProxy(const CString& sHost) { - VCString::iterator it; - for (it = m_vsTrustedProxies.begin(); it != m_vsTrustedProxies.end(); - ++it) { - if (sHost.Equals(*it)) { - m_vsTrustedProxies.erase(it); - return true; - } - } + VCString::iterator it; + for (it = m_vsTrustedProxies.begin(); it != m_vsTrustedProxies.end(); + ++it) { + if (sHost.Equals(*it)) { + m_vsTrustedProxies.erase(it); + return true; + } + } - return false; + return false; } void CZNC::Broadcast(const CString& sMessage, bool bAdminOnly, CUser* pSkipUser, CClient* pSkipClient) { - for (const auto& it : m_msUsers) { - if (bAdminOnly && !it.second->IsAdmin()) continue; + for (const auto& it : m_msUsers) { + if (bAdminOnly && !it.second->IsAdmin()) continue; - if (it.second != pSkipUser) { - CString sMsg = sMessage; + if (it.second != pSkipUser) { + CString sMsg = sMessage; - bool bContinue = false; - USERMODULECALL(OnBroadcast(sMsg), it.second, nullptr, &bContinue); - if (bContinue) continue; + bool bContinue = false; + USERMODULECALL(OnBroadcast(sMsg), it.second, nullptr, &bContinue); + if (bContinue) continue; - it.second->PutStatusNotice("*** " + sMsg, nullptr, pSkipClient); - } - } + it.second->PutStatusNotice("*** " + sMsg, nullptr, pSkipClient); + } + } } CModule* CZNC::FindModule(const CString& sModName, const CString& sUsername) { - if (sUsername.empty()) { - return CZNC::Get().GetModules().FindModule(sModName); - } + if (sUsername.empty()) { + return CZNC::Get().GetModules().FindModule(sModName); + } - CUser* pUser = FindUser(sUsername); + CUser* pUser = FindUser(sUsername); - return (!pUser) ? nullptr : pUser->GetModules().FindModule(sModName); + return (!pUser) ? nullptr : pUser->GetModules().FindModule(sModName); } CModule* CZNC::FindModule(const CString& sModName, CUser* pUser) { - if (pUser) { - return pUser->GetModules().FindModule(sModName); - } + if (pUser) { + return pUser->GetModules().FindModule(sModName); + } - return CZNC::Get().GetModules().FindModule(sModName); + return CZNC::Get().GetModules().FindModule(sModName); } bool CZNC::UpdateModule(const CString& sModule) { - CModule* pModule; + CModule* pModule; - map musLoaded; - map mnsLoaded; + map musLoaded; + map mnsLoaded; - // Unload the module for every user and network - for (const auto& it : m_msUsers) { - CUser* pUser = it.second; + // Unload the module for every user and network + for (const auto& it : m_msUsers) { + CUser* pUser = it.second; - pModule = pUser->GetModules().FindModule(sModule); - if (pModule) { - musLoaded[pUser] = pModule->GetArgs(); - pUser->GetModules().UnloadModule(sModule); - } + pModule = pUser->GetModules().FindModule(sModule); + if (pModule) { + musLoaded[pUser] = pModule->GetArgs(); + pUser->GetModules().UnloadModule(sModule); + } - // See if the user has this module loaded to a network - vector vNetworks = pUser->GetNetworks(); - for (CIRCNetwork* pNetwork : vNetworks) { - pModule = pNetwork->GetModules().FindModule(sModule); - if (pModule) { - mnsLoaded[pNetwork] = pModule->GetArgs(); - pNetwork->GetModules().UnloadModule(sModule); - } - } - } + // See if the user has this module loaded to a network + vector vNetworks = pUser->GetNetworks(); + for (CIRCNetwork* pNetwork : vNetworks) { + pModule = pNetwork->GetModules().FindModule(sModule); + if (pModule) { + mnsLoaded[pNetwork] = pModule->GetArgs(); + pNetwork->GetModules().UnloadModule(sModule); + } + } + } - // Unload the global module - bool bGlobal = false; - CString sGlobalArgs; + // Unload the global module + bool bGlobal = false; + CString sGlobalArgs; - pModule = GetModules().FindModule(sModule); - if (pModule) { - bGlobal = true; - sGlobalArgs = pModule->GetArgs(); - GetModules().UnloadModule(sModule); - } + pModule = GetModules().FindModule(sModule); + if (pModule) { + bGlobal = true; + sGlobalArgs = pModule->GetArgs(); + GetModules().UnloadModule(sModule); + } - // Lets reload everything - bool bError = false; - CString sErr; + // Lets reload everything + bool bError = false; + CString sErr; - // Reload the global module - if (bGlobal) { - if (!GetModules().LoadModule(sModule, sGlobalArgs, - CModInfo::GlobalModule, nullptr, nullptr, - sErr)) { - DEBUG("Failed to reload [" << sModule << "] globally [" << sErr - << "]"); - bError = true; - } - } + // Reload the global module + if (bGlobal) { + if (!GetModules().LoadModule(sModule, sGlobalArgs, + CModInfo::GlobalModule, nullptr, nullptr, + sErr)) { + DEBUG("Failed to reload [" << sModule << "] globally [" << sErr + << "]"); + bError = true; + } + } - // Reload the module for all users - for (const auto& it : musLoaded) { - CUser* pUser = it.first; - const CString& sArgs = it.second; + // Reload the module for all users + for (const auto& it : musLoaded) { + CUser* pUser = it.first; + const CString& sArgs = it.second; - if (!pUser->GetModules().LoadModule( - sModule, sArgs, CModInfo::UserModule, pUser, nullptr, sErr)) { - DEBUG("Failed to reload [" << sModule << "] for [" - << pUser->GetUserName() << "] [" << sErr - << "]"); - bError = true; - } - } + if (!pUser->GetModules().LoadModule( + sModule, sArgs, CModInfo::UserModule, pUser, nullptr, sErr)) { + DEBUG("Failed to reload [" << sModule << "] for [" + << pUser->GetUserName() << "] [" << sErr + << "]"); + bError = true; + } + } - // Reload the module for all networks - for (const auto& it : mnsLoaded) { - CIRCNetwork* pNetwork = it.first; - const CString& sArgs = it.second; + // Reload the module for all networks + for (const auto& it : mnsLoaded) { + CIRCNetwork* pNetwork = it.first; + const CString& sArgs = it.second; - if (!pNetwork->GetModules().LoadModule( - sModule, sArgs, CModInfo::NetworkModule, pNetwork->GetUser(), - pNetwork, sErr)) { - DEBUG("Failed to reload [" - << sModule << "] for [" << pNetwork->GetUser()->GetUserName() - << "/" << pNetwork->GetName() << "] [" << sErr << "]"); - bError = true; - } - } + if (!pNetwork->GetModules().LoadModule( + sModule, sArgs, CModInfo::NetworkModule, pNetwork->GetUser(), + pNetwork, sErr)) { + DEBUG("Failed to reload [" + << sModule << "] for [" << pNetwork->GetUser()->GetUserName() + << "/" << pNetwork->GetName() << "] [" << sErr << "]"); + bError = true; + } + } - return !bError; + return !bError; } CUser* CZNC::FindUser(const CString& sUsername) { - map::iterator it = m_msUsers.find(sUsername); + map::iterator it = m_msUsers.find(sUsername); - if (it != m_msUsers.end()) { - return it->second; - } + if (it != m_msUsers.end()) { + return it->second; + } - return nullptr; + return nullptr; } bool CZNC::DeleteUser(const CString& sUsername) { - CUser* pUser = FindUser(sUsername); + CUser* pUser = FindUser(sUsername); - if (!pUser) { - return false; - } + if (!pUser) { + return false; + } - m_msDelUsers[pUser->GetUserName()] = pUser; - return true; + m_msDelUsers[pUser->GetUserName()] = pUser; + return true; } bool CZNC::AddUser(CUser* pUser, CString& sErrorRet, bool bStartup) { - if (FindUser(pUser->GetUserName()) != nullptr) { - sErrorRet = "User already exists"; - DEBUG("User [" << pUser->GetUserName() << "] - already exists"); - return false; - } - if (!pUser->IsValid(sErrorRet)) { - DEBUG("Invalid user [" << pUser->GetUserName() << "] - [" << sErrorRet - << "]"); - return false; - } - bool bFailed = false; + if (FindUser(pUser->GetUserName()) != nullptr) { + sErrorRet = "User already exists"; + DEBUG("User [" << pUser->GetUserName() << "] - already exists"); + return false; + } + if (!pUser->IsValid(sErrorRet)) { + DEBUG("Invalid user [" << pUser->GetUserName() << "] - [" << sErrorRet + << "]"); + return false; + } + bool bFailed = false; - // do not call OnAddUser hook during ZNC startup - if (!bStartup) { - GLOBALMODULECALL(OnAddUser(*pUser, sErrorRet), &bFailed); - } + // do not call OnAddUser hook during ZNC startup + if (!bStartup) { + GLOBALMODULECALL(OnAddUser(*pUser, sErrorRet), &bFailed); + } - if (bFailed) { - DEBUG("AddUser [" << pUser->GetUserName() << "] aborted by a module [" - << sErrorRet << "]"); - return false; - } - m_msUsers[pUser->GetUserName()] = pUser; - return true; + if (bFailed) { + DEBUG("AddUser [" << pUser->GetUserName() << "] aborted by a module [" + << sErrorRet << "]"); + return false; + } + m_msUsers[pUser->GetUserName()] = pUser; + return true; } CListener* CZNC::FindListener(u_short uPort, const CString& sBindHost, EAddrType eAddr) { - for (CListener* pListener : m_vpListeners) { - if (pListener->GetPort() != uPort) continue; - if (pListener->GetBindHost() != sBindHost) continue; - if (pListener->GetAddrType() != eAddr) continue; - return pListener; - } - return nullptr; + for (CListener* pListener : m_vpListeners) { + if (pListener->GetPort() != uPort) continue; + if (pListener->GetBindHost() != sBindHost) continue; + if (pListener->GetAddrType() != eAddr) continue; + return pListener; + } + return nullptr; } bool CZNC::AddListener(const CString& sLine, CString& sError) { - CString sName = sLine.Token(0); - CString sValue = sLine.Token(1, true); + CString sName = sLine.Token(0); + CString sValue = sLine.Token(1, true); - EAddrType eAddr = ADDR_ALL; - if (sName.Equals("Listen4") || sName.Equals("Listen") || - sName.Equals("Listener4")) { - eAddr = ADDR_IPV4ONLY; - } - if (sName.Equals("Listener6")) { - eAddr = ADDR_IPV6ONLY; - } + EAddrType eAddr = ADDR_ALL; + if (sName.Equals("Listen4") || sName.Equals("Listen") || + sName.Equals("Listener4")) { + eAddr = ADDR_IPV4ONLY; + } + if (sName.Equals("Listener6")) { + eAddr = ADDR_IPV6ONLY; + } - CListener::EAcceptType eAccept = CListener::ACCEPT_ALL; - if (sValue.TrimPrefix("irc_only ")) - eAccept = CListener::ACCEPT_IRC; - else if (sValue.TrimPrefix("web_only ")) - eAccept = CListener::ACCEPT_HTTP; + CListener::EAcceptType eAccept = CListener::ACCEPT_ALL; + if (sValue.TrimPrefix("irc_only ")) + eAccept = CListener::ACCEPT_IRC; + else if (sValue.TrimPrefix("web_only ")) + eAccept = CListener::ACCEPT_HTTP; - bool bSSL = false; - CString sPort; - CString sBindHost; + bool bSSL = false; + CString sPort; + CString sBindHost; - if (ADDR_IPV4ONLY == eAddr) { - sValue.Replace(":", " "); - } + if (ADDR_IPV4ONLY == eAddr) { + sValue.Replace(":", " "); + } - if (sValue.Contains(" ")) { - sBindHost = sValue.Token(0, false, " "); - sPort = sValue.Token(1, true, " "); - } else { - sPort = sValue; - } + if (sValue.Contains(" ")) { + sBindHost = sValue.Token(0, false, " "); + sPort = sValue.Token(1, true, " "); + } else { + sPort = sValue; + } - if (sPort.TrimPrefix("+")) { - bSSL = true; - } + if (sPort.TrimPrefix("+")) { + bSSL = true; + } - // No support for URIPrefix for old-style configs. - CString sURIPrefix; - unsigned short uPort = sPort.ToUShort(); - return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, - sError); + // No support for URIPrefix for old-style configs. + CString sURIPrefix; + unsigned short uPort = sPort.ToUShort(); + return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, + sError); } bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost, const CString& sURIPrefixRaw, bool bSSL, EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError) { - CString sHostComment; + CString sHostComment; - if (!sBindHost.empty()) { - sHostComment = " on host [" + sBindHost + "]"; - } + if (!sBindHost.empty()) { + sHostComment = " on host [" + sBindHost + "]"; + } - CString sIPV6Comment; + CString sIPV6Comment; - switch (eAddr) { - case ADDR_ALL: - sIPV6Comment = ""; - break; - case ADDR_IPV4ONLY: - sIPV6Comment = " using ipv4"; - break; - case ADDR_IPV6ONLY: - sIPV6Comment = " using ipv6"; - } + switch (eAddr) { + case ADDR_ALL: + sIPV6Comment = ""; + break; + case ADDR_IPV4ONLY: + sIPV6Comment = " using ipv4"; + break; + case ADDR_IPV6ONLY: + sIPV6Comment = " using ipv6"; + } - CUtils::PrintAction("Binding to port [" + CString((bSSL) ? "+" : "") + - CString(uPort) + "]" + sHostComment + sIPV6Comment); + CUtils::PrintAction("Binding to port [" + CString((bSSL) ? "+" : "") + + CString(uPort) + "]" + sHostComment + sIPV6Comment); #ifndef HAVE_IPV6 - if (ADDR_IPV6ONLY == eAddr) { - sError = "IPV6 is not enabled"; - CUtils::PrintStatus(false, sError); - return false; - } + if (ADDR_IPV6ONLY == eAddr) { + sError = "IPV6 is not enabled"; + CUtils::PrintStatus(false, sError); + return false; + } #endif #ifndef HAVE_LIBSSL - if (bSSL) { - sError = "SSL is not enabled"; - CUtils::PrintStatus(false, sError); - return false; - } + if (bSSL) { + sError = "SSL is not enabled"; + CUtils::PrintStatus(false, sError); + return false; + } #else - CString sPemFile = GetPemLocation(); + CString sPemFile = GetPemLocation(); - if (bSSL && !CFile::Exists(sPemFile)) { - sError = "Unable to locate pem file: [" + sPemFile + "]"; - CUtils::PrintStatus(false, sError); + if (bSSL && !CFile::Exists(sPemFile)) { + sError = "Unable to locate pem file: [" + sPemFile + "]"; + CUtils::PrintStatus(false, sError); - // If stdin is e.g. /dev/null and we call GetBoolInput(), - // we are stuck in an endless loop! - if (isatty(0) && - CUtils::GetBoolInput("Would you like to create a new pem file?", - true)) { - sError.clear(); - WritePemFile(); - } else { - return false; - } + // If stdin is e.g. /dev/null and we call GetBoolInput(), + // we are stuck in an endless loop! + if (isatty(0) && + CUtils::GetBoolInput("Would you like to create a new pem file?", + true)) { + sError.clear(); + WritePemFile(); + } else { + return false; + } - CUtils::PrintAction("Binding to port [+" + CString(uPort) + "]" + - sHostComment + sIPV6Comment); - } + CUtils::PrintAction("Binding to port [+" + CString(uPort) + "]" + + sHostComment + sIPV6Comment); + } #endif - if (!uPort) { - sError = "Invalid port"; - CUtils::PrintStatus(false, sError); - return false; - } + if (!uPort) { + sError = "Invalid port"; + CUtils::PrintStatus(false, sError); + return false; + } - // URIPrefix must start with a slash and end without one. - CString sURIPrefix = CString(sURIPrefixRaw); - if (!sURIPrefix.empty()) { - if (!sURIPrefix.StartsWith("/")) { - sURIPrefix = "/" + sURIPrefix; - } - if (sURIPrefix.EndsWith("/")) { - sURIPrefix.TrimRight("/"); - } - } + // URIPrefix must start with a slash and end without one. + CString sURIPrefix = CString(sURIPrefixRaw); + if (!sURIPrefix.empty()) { + if (!sURIPrefix.StartsWith("/")) { + sURIPrefix = "/" + sURIPrefix; + } + if (sURIPrefix.EndsWith("/")) { + sURIPrefix.TrimRight("/"); + } + } - CListener* pListener = - new CListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept); + CListener* pListener = + new CListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept); - if (!pListener->Listen()) { - sError = FormatBindError(); - CUtils::PrintStatus(false, sError); - delete pListener; - return false; - } + if (!pListener->Listen()) { + sError = FormatBindError(); + CUtils::PrintStatus(false, sError); + delete pListener; + return false; + } - m_vpListeners.push_back(pListener); - CUtils::PrintStatus(true); + m_vpListeners.push_back(pListener); + CUtils::PrintStatus(true); - return true; + return true; } bool CZNC::AddListener(CConfig* pConfig, CString& sError) { - CString sBindHost; - CString sURIPrefix; - bool bSSL; - bool b4; + CString sBindHost; + CString sURIPrefix; + bool bSSL; + bool b4; #ifdef HAVE_IPV6 - bool b6 = true; + bool b6 = true; #else - bool b6 = false; + bool b6 = false; #endif - bool bIRC; - bool bWeb; - unsigned short uPort; - if (!pConfig->FindUShortEntry("port", uPort)) { - sError = "No port given"; - CUtils::PrintError(sError); - return false; - } - pConfig->FindStringEntry("host", sBindHost); - pConfig->FindBoolEntry("ssl", bSSL, false); - pConfig->FindBoolEntry("ipv4", b4, true); - pConfig->FindBoolEntry("ipv6", b6, b6); - pConfig->FindBoolEntry("allowirc", bIRC, true); - pConfig->FindBoolEntry("allowweb", bWeb, true); - pConfig->FindStringEntry("uriprefix", sURIPrefix); + bool bIRC; + bool bWeb; + unsigned short uPort; + if (!pConfig->FindUShortEntry("port", uPort)) { + sError = "No port given"; + CUtils::PrintError(sError); + return false; + } + pConfig->FindStringEntry("host", sBindHost); + pConfig->FindBoolEntry("ssl", bSSL, false); + pConfig->FindBoolEntry("ipv4", b4, true); + pConfig->FindBoolEntry("ipv6", b6, b6); + pConfig->FindBoolEntry("allowirc", bIRC, true); + pConfig->FindBoolEntry("allowweb", bWeb, true); + pConfig->FindStringEntry("uriprefix", sURIPrefix); - EAddrType eAddr; - if (b4 && b6) { - eAddr = ADDR_ALL; - } else if (b4 && !b6) { - eAddr = ADDR_IPV4ONLY; - } else if (!b4 && b6) { - eAddr = ADDR_IPV6ONLY; - } else { - sError = "No address family given"; - CUtils::PrintError(sError); - return false; - } + EAddrType eAddr; + if (b4 && b6) { + eAddr = ADDR_ALL; + } else if (b4 && !b6) { + eAddr = ADDR_IPV4ONLY; + } else if (!b4 && b6) { + eAddr = ADDR_IPV6ONLY; + } else { + sError = "No address family given"; + CUtils::PrintError(sError); + return false; + } - CListener::EAcceptType eAccept; - if (bIRC && bWeb) { - eAccept = CListener::ACCEPT_ALL; - } else if (bIRC && !bWeb) { - eAccept = CListener::ACCEPT_IRC; - } else if (!bIRC && bWeb) { - eAccept = CListener::ACCEPT_HTTP; - } else { - sError = "Either Web or IRC or both should be selected"; - CUtils::PrintError(sError); - return false; - } + CListener::EAcceptType eAccept; + if (bIRC && bWeb) { + eAccept = CListener::ACCEPT_ALL; + } else if (bIRC && !bWeb) { + eAccept = CListener::ACCEPT_IRC; + } else if (!bIRC && bWeb) { + eAccept = CListener::ACCEPT_HTTP; + } else { + sError = "Either Web or IRC or both should be selected"; + CUtils::PrintError(sError); + return false; + } - return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, - sError); + return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, + sError); } bool CZNC::AddListener(CListener* pListener) { - if (!pListener->GetRealListener()) { - // Listener doesnt actually listen - delete pListener; - return false; - } + if (!pListener->GetRealListener()) { + // Listener doesnt actually listen + delete pListener; + return false; + } - // We don't check if there is an identical listener already listening - // since one can't listen on e.g. the same port multiple times + // We don't check if there is an identical listener already listening + // since one can't listen on e.g. the same port multiple times - m_vpListeners.push_back(pListener); - return true; + m_vpListeners.push_back(pListener); + return true; } bool CZNC::DelListener(CListener* pListener) { - auto it = std::find(m_vpListeners.begin(), m_vpListeners.end(), pListener); - if (it != m_vpListeners.end()) { - m_vpListeners.erase(it); - delete pListener; - return true; - } + auto it = std::find(m_vpListeners.begin(), m_vpListeners.end(), pListener); + if (it != m_vpListeners.end()) { + m_vpListeners.erase(it); + delete pListener; + return true; + } - return false; + return false; } static CZNC* s_pZNC = nullptr; void CZNC::CreateInstance() { - if (s_pZNC) abort(); + if (s_pZNC) abort(); - s_pZNC = new CZNC(); + s_pZNC = new CZNC(); } CZNC& CZNC::Get() { return *s_pZNC; } void CZNC::DestroyInstance() { - delete s_pZNC; - s_pZNC = nullptr; + delete s_pZNC; + s_pZNC = nullptr; } CZNC::TrafficStatsMap CZNC::GetTrafficStats(TrafficStatsPair& Users, TrafficStatsPair& ZNC, TrafficStatsPair& Total) { - TrafficStatsMap ret; - unsigned long long uiUsers_in, uiUsers_out, uiZNC_in, uiZNC_out; - const map& msUsers = CZNC::Get().GetUserMap(); + TrafficStatsMap ret; + unsigned long long uiUsers_in, uiUsers_out, uiZNC_in, uiZNC_out; + const map& msUsers = CZNC::Get().GetUserMap(); - uiUsers_in = uiUsers_out = 0; - uiZNC_in = BytesRead(); - uiZNC_out = BytesWritten(); + uiUsers_in = uiUsers_out = 0; + uiZNC_in = BytesRead(); + uiZNC_out = BytesWritten(); - for (const auto& it : msUsers) { - ret[it.first] = - TrafficStatsPair(it.second->BytesRead(), it.second->BytesWritten()); - uiUsers_in += it.second->BytesRead(); - uiUsers_out += it.second->BytesWritten(); - } + for (const auto& it : msUsers) { + ret[it.first] = + TrafficStatsPair(it.second->BytesRead(), it.second->BytesWritten()); + uiUsers_in += it.second->BytesRead(); + uiUsers_out += it.second->BytesWritten(); + } - for (Csock* pSock : m_Manager) { - CUser* pUser = nullptr; - if (pSock->GetSockName().StartsWith("IRC::")) { - pUser = ((CIRCSock*)pSock)->GetNetwork()->GetUser(); - } else if (pSock->GetSockName().StartsWith("USR::")) { - pUser = ((CClient*)pSock)->GetUser(); - } + for (Csock* pSock : m_Manager) { + CUser* pUser = nullptr; + if (pSock->GetSockName().StartsWith("IRC::")) { + pUser = ((CIRCSock*)pSock)->GetNetwork()->GetUser(); + } else if (pSock->GetSockName().StartsWith("USR::")) { + pUser = ((CClient*)pSock)->GetUser(); + } - if (pUser) { - ret[pUser->GetUserName()].first += pSock->GetBytesRead(); - ret[pUser->GetUserName()].second += pSock->GetBytesWritten(); - uiUsers_in += pSock->GetBytesRead(); - uiUsers_out += pSock->GetBytesWritten(); - } else { - uiZNC_in += pSock->GetBytesRead(); - uiZNC_out += pSock->GetBytesWritten(); - } - } + if (pUser) { + ret[pUser->GetUserName()].first += pSock->GetBytesRead(); + ret[pUser->GetUserName()].second += pSock->GetBytesWritten(); + uiUsers_in += pSock->GetBytesRead(); + uiUsers_out += pSock->GetBytesWritten(); + } else { + uiZNC_in += pSock->GetBytesRead(); + uiZNC_out += pSock->GetBytesWritten(); + } + } - Users = TrafficStatsPair(uiUsers_in, uiUsers_out); - ZNC = TrafficStatsPair(uiZNC_in, uiZNC_out); - Total = TrafficStatsPair(uiUsers_in + uiZNC_in, uiUsers_out + uiZNC_out); + Users = TrafficStatsPair(uiUsers_in, uiUsers_out); + ZNC = TrafficStatsPair(uiZNC_in, uiZNC_out); + Total = TrafficStatsPair(uiUsers_in + uiZNC_in, uiUsers_out + uiZNC_out); - return ret; + return ret; } CZNC::TrafficStatsMap CZNC::GetNetworkTrafficStats(const CString& sUsername, TrafficStatsPair& Total) { - TrafficStatsMap Networks; + TrafficStatsMap Networks; - CUser* pUser = FindUser(sUsername); - if (pUser) { - for (const CIRCNetwork* pNetwork : pUser->GetNetworks()) { - Networks[pNetwork->GetName()].first = pNetwork->BytesRead(); - Networks[pNetwork->GetName()].second = pNetwork->BytesWritten(); - Total.first += pNetwork->BytesRead(); - Total.second += pNetwork->BytesWritten(); - } + CUser* pUser = FindUser(sUsername); + if (pUser) { + for (const CIRCNetwork* pNetwork : pUser->GetNetworks()) { + Networks[pNetwork->GetName()].first = pNetwork->BytesRead(); + Networks[pNetwork->GetName()].second = pNetwork->BytesWritten(); + Total.first += pNetwork->BytesRead(); + Total.second += pNetwork->BytesWritten(); + } - for (Csock* pSock : m_Manager) { - CIRCNetwork* pNetwork = nullptr; - if (pSock->GetSockName().StartsWith("IRC::")) { - pNetwork = ((CIRCSock*)pSock)->GetNetwork(); - } else if (pSock->GetSockName().StartsWith("USR::")) { - pNetwork = ((CClient*)pSock)->GetNetwork(); - } + for (Csock* pSock : m_Manager) { + CIRCNetwork* pNetwork = nullptr; + if (pSock->GetSockName().StartsWith("IRC::")) { + pNetwork = ((CIRCSock*)pSock)->GetNetwork(); + } else if (pSock->GetSockName().StartsWith("USR::")) { + pNetwork = ((CClient*)pSock)->GetNetwork(); + } - if (pNetwork && pNetwork->GetUser() == pUser) { - Networks[pNetwork->GetName()].first = pSock->GetBytesRead(); - Networks[pNetwork->GetName()].second = pSock->GetBytesWritten(); - Total.first += pSock->GetBytesRead(); - Total.second += pSock->GetBytesWritten(); - } - } - } + if (pNetwork && pNetwork->GetUser() == pUser) { + Networks[pNetwork->GetName()].first = pSock->GetBytesRead(); + Networks[pNetwork->GetName()].second = pSock->GetBytesWritten(); + Total.first += pSock->GetBytesRead(); + Total.second += pSock->GetBytesWritten(); + } + } + } - return Networks; + return Networks; } void CZNC::AuthUser(std::shared_ptr AuthClass) { - // TODO unless the auth module calls it, CUser::IsHostAllowed() is not - // honoured - bool bReturn = false; - GLOBALMODULECALL(OnLoginAttempt(AuthClass), &bReturn); - if (bReturn) return; + // TODO unless the auth module calls it, CUser::IsHostAllowed() is not + // honoured + bool bReturn = false; + GLOBALMODULECALL(OnLoginAttempt(AuthClass), &bReturn); + if (bReturn) return; - CUser* pUser = FindUser(AuthClass->GetUsername()); + CUser* pUser = FindUser(AuthClass->GetUsername()); - if (!pUser || !pUser->CheckPass(AuthClass->GetPassword())) { - AuthClass->RefuseLogin("Invalid Password"); - return; - } + if (!pUser || !pUser->CheckPass(AuthClass->GetPassword())) { + AuthClass->RefuseLogin("Invalid Password"); + return; + } - CString sHost = AuthClass->GetRemoteIP(); + CString sHost = AuthClass->GetRemoteIP(); - if (!pUser->IsHostAllowed(sHost)) { - AuthClass->RefuseLogin("Your host [" + sHost + "] is not allowed"); - return; - } + if (!pUser->IsHostAllowed(sHost)) { + AuthClass->RefuseLogin("Your host [" + sHost + "] is not allowed"); + return; + } - AuthClass->AcceptLogin(*pUser); + AuthClass->AcceptLogin(*pUser); } class CConnectQueueTimer : public CCron { public: - CConnectQueueTimer(int iSecs) : CCron() { - SetName("Connect users"); - Start(iSecs); - // Don't wait iSecs seconds for first timer run - m_bRunOnNextCall = true; - } - virtual ~CConnectQueueTimer() { - // This is only needed when ZNC shuts down: - // CZNC::~CZNC() sets its CConnectQueueTimer pointer to nullptr and - // calls the manager's Cleanup() which destroys all sockets and - // timers. If something calls CZNC::EnableConnectQueue() here - // (e.g. because a CIRCSock is destroyed), the socket manager - // deletes that timer almost immediately, but CZNC now got a - // dangling pointer to this timer which can crash later on. - // - // Unlikely but possible ;) - CZNC::Get().LeakConnectQueueTimer(this); - } + CConnectQueueTimer(int iSecs) : CCron() { + SetName("Connect users"); + Start(iSecs); + // Don't wait iSecs seconds for first timer run + m_bRunOnNextCall = true; + } + virtual ~CConnectQueueTimer() { + // This is only needed when ZNC shuts down: + // CZNC::~CZNC() sets its CConnectQueueTimer pointer to nullptr and + // calls the manager's Cleanup() which destroys all sockets and + // timers. If something calls CZNC::EnableConnectQueue() here + // (e.g. because a CIRCSock is destroyed), the socket manager + // deletes that timer almost immediately, but CZNC now got a + // dangling pointer to this timer which can crash later on. + // + // Unlikely but possible ;) + CZNC::Get().LeakConnectQueueTimer(this); + } protected: - void RunJob() override { - list ConnectionQueue; - list& RealConnectionQueue = - CZNC::Get().GetConnectionQueue(); + void RunJob() override { + list ConnectionQueue; + list& RealConnectionQueue = + CZNC::Get().GetConnectionQueue(); - // Problem: If a network can't connect right now because e.g. it - // is throttled, it will re-insert itself into the connection - // queue. However, we must only give each network a single - // chance during this timer run. - // - // Solution: We move the connection queue to our local list at - // the beginning and work from that. - ConnectionQueue.swap(RealConnectionQueue); + // Problem: If a network can't connect right now because e.g. it + // is throttled, it will re-insert itself into the connection + // queue. However, we must only give each network a single + // chance during this timer run. + // + // Solution: We move the connection queue to our local list at + // the beginning and work from that. + ConnectionQueue.swap(RealConnectionQueue); - while (!ConnectionQueue.empty()) { - CIRCNetwork* pNetwork = ConnectionQueue.front(); - ConnectionQueue.pop_front(); + while (!ConnectionQueue.empty()) { + CIRCNetwork* pNetwork = ConnectionQueue.front(); + ConnectionQueue.pop_front(); - if (pNetwork->Connect()) { - break; - } - } + if (pNetwork->Connect()) { + break; + } + } - /* Now re-insert anything that is left in our local list into - * the real connection queue. - */ - RealConnectionQueue.splice(RealConnectionQueue.begin(), - ConnectionQueue); + /* Now re-insert anything that is left in our local list into + * the real connection queue. + */ + RealConnectionQueue.splice(RealConnectionQueue.begin(), + ConnectionQueue); - if (RealConnectionQueue.empty()) { - DEBUG("ConnectQueueTimer done"); - CZNC::Get().DisableConnectQueue(); - } - } + if (RealConnectionQueue.empty()) { + DEBUG("ConnectQueueTimer done"); + CZNC::Get().DisableConnectQueue(); + } + } }; void CZNC::SetConnectDelay(unsigned int i) { - if (i < 1) { - // Don't hammer server with our failed connects - i = 1; - } - if (m_uiConnectDelay != i && m_pConnectQueueTimer != nullptr) { - m_pConnectQueueTimer->Start(i); - } - m_uiConnectDelay = i; + if (i < 1) { + // Don't hammer server with our failed connects + i = 1; + } + if (m_uiConnectDelay != i && m_pConnectQueueTimer != nullptr) { + m_pConnectQueueTimer->Start(i); + } + m_uiConnectDelay = i; } VCString CZNC::GetAvailableSSLProtocols() { - // NOTE: keep in sync with SetSSLProtocols() - return {"SSLv2", "SSLv3", "TLSv1", "TLSV1.1", "TLSv1.2"}; + // NOTE: keep in sync with SetSSLProtocols() + return {"SSLv2", "SSLv3", "TLSv1", "TLSV1.1", "TLSv1.2"}; } bool CZNC::SetSSLProtocols(const CString& sProtocols) { - VCString vsProtocols; - sProtocols.Split(" ", vsProtocols, false, "", "", true, true); + VCString vsProtocols; + sProtocols.Split(" ", vsProtocols, false, "", "", true, true); - unsigned int uDisabledProtocols = Csock::EDP_SSL; - for (CString& sProtocol : vsProtocols) { - unsigned int uFlag = 0; - bool bEnable = sProtocol.TrimPrefix("+"); - bool bDisable = sProtocol.TrimPrefix("-"); + unsigned int uDisabledProtocols = Csock::EDP_SSL; + for (CString& sProtocol : vsProtocols) { + unsigned int uFlag = 0; + bool bEnable = sProtocol.TrimPrefix("+"); + bool bDisable = sProtocol.TrimPrefix("-"); - // NOTE: keep in sync with GetAvailableSSLProtocols() - if (sProtocol.Equals("All")) { - uFlag = ~0; - } else if (sProtocol.Equals("SSLv2")) { - uFlag = Csock::EDP_SSLv2; - } else if (sProtocol.Equals("SSLv3")) { - uFlag = Csock::EDP_SSLv3; - } else if (sProtocol.Equals("TLSv1")) { - uFlag = Csock::EDP_TLSv1; - } else if (sProtocol.Equals("TLSv1.1")) { - uFlag = Csock::EDP_TLSv1_1; - } else if (sProtocol.Equals("TLSv1.2")) { - uFlag = Csock::EDP_TLSv1_2; - } else { - return false; - } + // NOTE: keep in sync with GetAvailableSSLProtocols() + if (sProtocol.Equals("All")) { + uFlag = ~0; + } else if (sProtocol.Equals("SSLv2")) { + uFlag = Csock::EDP_SSLv2; + } else if (sProtocol.Equals("SSLv3")) { + uFlag = Csock::EDP_SSLv3; + } else if (sProtocol.Equals("TLSv1")) { + uFlag = Csock::EDP_TLSv1; + } else if (sProtocol.Equals("TLSv1.1")) { + uFlag = Csock::EDP_TLSv1_1; + } else if (sProtocol.Equals("TLSv1.2")) { + uFlag = Csock::EDP_TLSv1_2; + } else { + return false; + } - if (bEnable) { - uDisabledProtocols &= ~uFlag; - } else if (bDisable) { - uDisabledProtocols |= uFlag; - } else { - uDisabledProtocols = ~uFlag; - } - } + if (bEnable) { + uDisabledProtocols &= ~uFlag; + } else if (bDisable) { + uDisabledProtocols |= uFlag; + } else { + uDisabledProtocols = ~uFlag; + } + } - m_sSSLProtocols = sProtocols; - m_uDisabledSSLProtocols = uDisabledProtocols; - return true; + m_sSSLProtocols = sProtocols; + m_uDisabledSSLProtocols = uDisabledProtocols; + return true; } void CZNC::EnableConnectQueue() { - if (!m_pConnectQueueTimer && !m_uiConnectPaused && - !m_lpConnectQueue.empty()) { - m_pConnectQueueTimer = new CConnectQueueTimer(m_uiConnectDelay); - GetManager().AddCron(m_pConnectQueueTimer); - } + if (!m_pConnectQueueTimer && !m_uiConnectPaused && + !m_lpConnectQueue.empty()) { + m_pConnectQueueTimer = new CConnectQueueTimer(m_uiConnectDelay); + GetManager().AddCron(m_pConnectQueueTimer); + } } void CZNC::DisableConnectQueue() { - if (m_pConnectQueueTimer) { - // This will kill the cron - m_pConnectQueueTimer->Stop(); - m_pConnectQueueTimer = nullptr; - } + if (m_pConnectQueueTimer) { + // This will kill the cron + m_pConnectQueueTimer->Stop(); + m_pConnectQueueTimer = nullptr; + } } void CZNC::PauseConnectQueue() { - DEBUG("Connection queue paused"); - m_uiConnectPaused++; + DEBUG("Connection queue paused"); + m_uiConnectPaused++; - if (m_pConnectQueueTimer) { - m_pConnectQueueTimer->Pause(); - } + if (m_pConnectQueueTimer) { + m_pConnectQueueTimer->Pause(); + } } void CZNC::ResumeConnectQueue() { - DEBUG("Connection queue resumed"); - m_uiConnectPaused--; + DEBUG("Connection queue resumed"); + m_uiConnectPaused--; - EnableConnectQueue(); - if (m_pConnectQueueTimer) { - m_pConnectQueueTimer->UnPause(); - } + EnableConnectQueue(); + if (m_pConnectQueueTimer) { + m_pConnectQueueTimer->UnPause(); + } } void CZNC::AddNetworkToQueue(CIRCNetwork* pNetwork) { - // Make sure we are not already in the queue - if (std::find(m_lpConnectQueue.begin(), m_lpConnectQueue.end(), pNetwork) != - m_lpConnectQueue.end()) { - return; - } + // Make sure we are not already in the queue + if (std::find(m_lpConnectQueue.begin(), m_lpConnectQueue.end(), pNetwork) != + m_lpConnectQueue.end()) { + return; + } - m_lpConnectQueue.push_back(pNetwork); - EnableConnectQueue(); + m_lpConnectQueue.push_back(pNetwork); + EnableConnectQueue(); } void CZNC::LeakConnectQueueTimer(CConnectQueueTimer* pTimer) { - if (m_pConnectQueueTimer == pTimer) m_pConnectQueueTimer = nullptr; + if (m_pConnectQueueTimer == pTimer) m_pConnectQueueTimer = nullptr; } bool CZNC::WaitForChildLock() { return m_pLockFile && m_pLockFile->ExLock(); } diff --git a/test/BufferTest.cpp b/test/BufferTest.cpp index e292b462..266f1a44 100644 --- a/test/BufferTest.cpp +++ b/test/BufferTest.cpp @@ -24,112 +24,112 @@ using ::testing::ContainerEq; class BufferTest : public ::testing::Test { protected: - void SetUp() { CZNC::CreateInstance(); } - void TearDown() { CZNC::DestroyInstance(); } + void SetUp() { CZNC::CreateInstance(); } + void TearDown() { CZNC::DestroyInstance(); } }; TEST_F(BufferTest, BufLine) { - CBuffer buffer(1); - buffer.AddLine(CMessage("@key=value :nick PRIVMSG {target} {text}"), - "hello there"); - const CBufLine& line = buffer.GetBufLine(0); - EXPECT_THAT(line.GetTags(), ContainerEq(MCString{{"key", "value"}})); - EXPECT_EQ(":nick PRIVMSG {target} {text}", line.GetFormat()); - EXPECT_EQ("hello there", line.GetText()); - EXPECT_EQ("PRIVMSG", line.GetCommand()); + CBuffer buffer(1); + buffer.AddLine(CMessage("@key=value :nick PRIVMSG {target} {text}"), + "hello there"); + const CBufLine& line = buffer.GetBufLine(0); + EXPECT_THAT(line.GetTags(), ContainerEq(MCString{{"key", "value"}})); + EXPECT_EQ(":nick PRIVMSG {target} {text}", line.GetFormat()); + EXPECT_EQ("hello there", line.GetText()); + EXPECT_EQ("PRIVMSG", line.GetCommand()); } TEST_F(BufferTest, LineCount) { - CBuffer buffer(123); - EXPECT_EQ(123u, buffer.GetLineCount()); + CBuffer buffer(123); + EXPECT_EQ(123u, buffer.GetLineCount()); - EXPECT_EQ(500u, CZNC::Get().GetMaxBufferSize()); - EXPECT_FALSE(buffer.SetLineCount(1000, false)); - EXPECT_EQ(123u, buffer.GetLineCount()); - EXPECT_TRUE(buffer.SetLineCount(500, false)); - EXPECT_EQ(500u, buffer.GetLineCount()); - EXPECT_TRUE(buffer.SetLineCount(1000, true)); - EXPECT_EQ(1000u, buffer.GetLineCount()); + EXPECT_EQ(500u, CZNC::Get().GetMaxBufferSize()); + EXPECT_FALSE(buffer.SetLineCount(1000, false)); + EXPECT_EQ(123u, buffer.GetLineCount()); + EXPECT_TRUE(buffer.SetLineCount(500, false)); + EXPECT_EQ(500u, buffer.GetLineCount()); + EXPECT_TRUE(buffer.SetLineCount(1000, true)); + EXPECT_EQ(1000u, buffer.GetLineCount()); } TEST_F(BufferTest, AddLine) { - CBuffer buffer(2); - EXPECT_TRUE(buffer.IsEmpty()); - EXPECT_EQ(0u, buffer.Size()); + CBuffer buffer(2); + EXPECT_TRUE(buffer.IsEmpty()); + EXPECT_EQ(0u, buffer.Size()); - EXPECT_EQ(1u, buffer.AddLine(CMessage("PRIVMSG nick :msg1"))); - EXPECT_FALSE(buffer.IsEmpty()); - EXPECT_EQ(1u, buffer.Size()); - EXPECT_EQ("PRIVMSG nick :msg1", buffer.GetBufLine(0).GetFormat()); + EXPECT_EQ(1u, buffer.AddLine(CMessage("PRIVMSG nick :msg1"))); + EXPECT_FALSE(buffer.IsEmpty()); + EXPECT_EQ(1u, buffer.Size()); + EXPECT_EQ("PRIVMSG nick :msg1", buffer.GetBufLine(0).GetFormat()); - EXPECT_EQ(2u, buffer.AddLine(CMessage("PRIVMSG nick :msg2"))); - EXPECT_FALSE(buffer.IsEmpty()); - EXPECT_EQ(2u, buffer.Size()); - EXPECT_EQ("PRIVMSG nick :msg1", buffer.GetBufLine(0).GetFormat()); - EXPECT_EQ("PRIVMSG nick :msg2", buffer.GetBufLine(1).GetFormat()); + EXPECT_EQ(2u, buffer.AddLine(CMessage("PRIVMSG nick :msg2"))); + EXPECT_FALSE(buffer.IsEmpty()); + EXPECT_EQ(2u, buffer.Size()); + EXPECT_EQ("PRIVMSG nick :msg1", buffer.GetBufLine(0).GetFormat()); + EXPECT_EQ("PRIVMSG nick :msg2", buffer.GetBufLine(1).GetFormat()); - EXPECT_EQ(2u, buffer.AddLine(CMessage("PRIVMSG nick :msg3"))); - EXPECT_FALSE(buffer.IsEmpty()); - EXPECT_EQ(2u, buffer.Size()); - EXPECT_EQ("PRIVMSG nick :msg2", buffer.GetBufLine(0).GetFormat()); - EXPECT_EQ("PRIVMSG nick :msg3", buffer.GetBufLine(1).GetFormat()); + EXPECT_EQ(2u, buffer.AddLine(CMessage("PRIVMSG nick :msg3"))); + EXPECT_FALSE(buffer.IsEmpty()); + EXPECT_EQ(2u, buffer.Size()); + EXPECT_EQ("PRIVMSG nick :msg2", buffer.GetBufLine(0).GetFormat()); + EXPECT_EQ("PRIVMSG nick :msg3", buffer.GetBufLine(1).GetFormat()); - buffer.SetLineCount(1); - EXPECT_FALSE(buffer.IsEmpty()); - EXPECT_EQ(1u, buffer.Size()); - EXPECT_EQ("PRIVMSG nick :msg3", buffer.GetBufLine(0).GetFormat()); + buffer.SetLineCount(1); + EXPECT_FALSE(buffer.IsEmpty()); + EXPECT_EQ(1u, buffer.Size()); + EXPECT_EQ("PRIVMSG nick :msg3", buffer.GetBufLine(0).GetFormat()); - buffer.Clear(); - EXPECT_TRUE(buffer.IsEmpty()); - EXPECT_EQ(0u, buffer.Size()); + buffer.Clear(); + EXPECT_TRUE(buffer.IsEmpty()); + EXPECT_EQ(0u, buffer.Size()); - buffer.SetLineCount(0); - buffer.AddLine(CMessage("TEST")); - EXPECT_TRUE(buffer.IsEmpty()); - EXPECT_EQ(0u, buffer.Size()); + buffer.SetLineCount(0); + buffer.AddLine(CMessage("TEST")); + EXPECT_TRUE(buffer.IsEmpty()); + EXPECT_EQ(0u, buffer.Size()); } TEST_F(BufferTest, UpdateLine) { - // clang-format off - CBuffer buffer(50); + // clang-format off + CBuffer buffer(50); - VCString lines = { - ":irc.server.com 001 nick :Welcome to the fake Internet Relay Chat Network nick", - ":irc.server.com 002 nick :Your host is irc.server.com[12.34.56.78/6697], running version ircd-fake-1.2.3", - ":irc.server.com 003 nick :This server was created Mon Jul 6 2015 at 16:53:49 UTC", - ":irc.server.com 004 nick irc.server.com ircd-fake-1.2.3 DOQRSZaghilopswz CFILMPQSbcefgijklmnopqrstvz bkloveqjfI", - ":irc.server.com 005 nick CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstz CHANLIMIT=#:120 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=fake KNOCK STATUSMSG=@+ CALLERID=g :are supported by this server", - ":irc.server.com 005 nick CASEMAPPING=rfc1459 CHARSET=ascii NICKLEN=16 CHANNELLEN=50 TOPICLEN=390 ETRACE CPRIVMSG CNOTICE DEAF=D MONITOR=100 FNC TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: :are supported by this server", - ":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server", - ":irc.server.com 251 nick :There are 160 users and 92457 invisible on 26 servers", - ":irc.server.com 252 nick 25 :IRC Operators online", - ":irc.server.com 253 nick 10 :unknown connection(s)", - ":irc.server.com 254 nick 63434 :channels formed", - ":irc.server.com 255 nick :I have 9455 clients and 1 servers", - ":irc.server.com 265 nick 9455 9682 :Current local users 9455, max 9682", - ":irc.server.com 266 nick 92617 96692 :Current global users 92617, max 96692", - ":irc.server.com 250 nick :Highest connection count: 9683 (9682 clients) (854623 connections received)" - }; - EXPECT_THAT(lines, SizeIs(15)); + VCString lines = { + ":irc.server.com 001 nick :Welcome to the fake Internet Relay Chat Network nick", + ":irc.server.com 002 nick :Your host is irc.server.com[12.34.56.78/6697], running version ircd-fake-1.2.3", + ":irc.server.com 003 nick :This server was created Mon Jul 6 2015 at 16:53:49 UTC", + ":irc.server.com 004 nick irc.server.com ircd-fake-1.2.3 DOQRSZaghilopswz CFILMPQSbcefgijklmnopqrstvz bkloveqjfI", + ":irc.server.com 005 nick CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstz CHANLIMIT=#:120 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=fake KNOCK STATUSMSG=@+ CALLERID=g :are supported by this server", + ":irc.server.com 005 nick CASEMAPPING=rfc1459 CHARSET=ascii NICKLEN=16 CHANNELLEN=50 TOPICLEN=390 ETRACE CPRIVMSG CNOTICE DEAF=D MONITOR=100 FNC TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: :are supported by this server", + ":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server", + ":irc.server.com 251 nick :There are 160 users and 92457 invisible on 26 servers", + ":irc.server.com 252 nick 25 :IRC Operators online", + ":irc.server.com 253 nick 10 :unknown connection(s)", + ":irc.server.com 254 nick 63434 :channels formed", + ":irc.server.com 255 nick :I have 9455 clients and 1 servers", + ":irc.server.com 265 nick 9455 9682 :Current local users 9455, max 9682", + ":irc.server.com 266 nick 92617 96692 :Current global users 92617, max 96692", + ":irc.server.com 250 nick :Highest connection count: 9683 (9682 clients) (854623 connections received)" + }; + EXPECT_THAT(lines, SizeIs(15)); - for (const CString& line : lines) { - buffer.AddLine(line); - } - EXPECT_EQ(15u, buffer.Size()); + for (const CString& line : lines) { + buffer.AddLine(line); + } + EXPECT_EQ(15u, buffer.Size()); - EXPECT_EQ(15u, buffer.UpdateLine("002", CMessage(":irc.server.net 002 nick :Your host is irc.server.net[11.22.33.44/6697], running version ircd-fake-3.2.1"))); - EXPECT_EQ(":irc.server.net 002 nick :Your host is irc.server.net[11.22.33.44/6697], running version ircd-fake-3.2.1", buffer.GetBufLine(1).GetFormat()); + EXPECT_EQ(15u, buffer.UpdateLine("002", CMessage(":irc.server.net 002 nick :Your host is irc.server.net[11.22.33.44/6697], running version ircd-fake-3.2.1"))); + EXPECT_EQ(":irc.server.net 002 nick :Your host is irc.server.net[11.22.33.44/6697], running version ircd-fake-3.2.1", buffer.GetBufLine(1).GetFormat()); - EXPECT_EQ(15u, buffer.UpdateLine("252", CMessage(":irc.server.com 252 nick 100 :IRC Operators online"))); - EXPECT_EQ(":irc.server.com 252 nick 100 :IRC Operators online", buffer.GetBufLine(8).GetFormat()); + EXPECT_EQ(15u, buffer.UpdateLine("252", CMessage(":irc.server.com 252 nick 100 :IRC Operators online"))); + EXPECT_EQ(":irc.server.com 252 nick 100 :IRC Operators online", buffer.GetBufLine(8).GetFormat()); - EXPECT_EQ(16u, buffer.UpdateLine("123", CMessage(":irc.server.com 123 nick foo bar"))); - EXPECT_EQ(":irc.server.com 123 nick foo bar", buffer.GetBufLine(15).GetFormat()); + EXPECT_EQ(16u, buffer.UpdateLine("123", CMessage(":irc.server.com 123 nick foo bar"))); + EXPECT_EQ(":irc.server.com 123 nick foo bar", buffer.GetBufLine(15).GetFormat()); - EXPECT_EQ(16u, buffer.UpdateExactLine(CMessage(":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server"))); - EXPECT_EQ(":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server", buffer.GetBufLine(6).GetFormat()); + EXPECT_EQ(16u, buffer.UpdateExactLine(CMessage(":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server"))); + EXPECT_EQ(":irc.server.com 005 nick EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server", buffer.GetBufLine(6).GetFormat()); - EXPECT_EQ(17u, buffer.UpdateExactLine(CMessage(":irc.server.com 005 nick FOO=bar :are supported by this server"))); - EXPECT_EQ(":irc.server.com 005 nick FOO=bar :are supported by this server", buffer.GetBufLine(16).GetFormat()); - // clang-format on + EXPECT_EQ(17u, buffer.UpdateExactLine(CMessage(":irc.server.com 005 nick FOO=bar :are supported by this server"))); + EXPECT_EQ(":irc.server.com 005 nick FOO=bar :are supported by this server", buffer.GetBufLine(16).GetFormat()); + // clang-format on } diff --git a/test/ClientTest.cpp b/test/ClientTest.cpp index 2a4f3295..cf97eba4 100644 --- a/test/ClientTest.cpp +++ b/test/ClientTest.cpp @@ -23,323 +23,323 @@ using ::testing::ElementsAre; class ClientTest : public IRCTest { protected: - void testPass(const CString& sInput, const CString& sUser, - const CString& sIdentifier, const CString& sNetwork, - const CString& sPass) const { - CClient client; - client.ParsePass(sInput); - EXPECT_EQ(sUser, client.m_sUser); - EXPECT_EQ(sIdentifier, client.m_sIdentifier); - EXPECT_EQ(sNetwork, client.m_sNetwork); - EXPECT_EQ(sPass, client.m_sPass); - } + void testPass(const CString& sInput, const CString& sUser, + const CString& sIdentifier, const CString& sNetwork, + const CString& sPass) const { + CClient client; + client.ParsePass(sInput); + EXPECT_EQ(sUser, client.m_sUser); + EXPECT_EQ(sIdentifier, client.m_sIdentifier); + EXPECT_EQ(sNetwork, client.m_sNetwork); + EXPECT_EQ(sPass, client.m_sPass); + } - void testUser(const CString& sInput, const CString& sUser, - const CString& sIdentifier, const CString& sNetwork) const { - CClient client; - client.ParseUser(sInput); - EXPECT_EQ(sUser, client.m_sUser); - EXPECT_EQ(sIdentifier, client.m_sIdentifier); - EXPECT_EQ(sNetwork, client.m_sNetwork); - } + void testUser(const CString& sInput, const CString& sUser, + const CString& sIdentifier, const CString& sNetwork) const { + CClient client; + client.ParseUser(sInput); + EXPECT_EQ(sUser, client.m_sUser); + EXPECT_EQ(sIdentifier, client.m_sIdentifier); + EXPECT_EQ(sNetwork, client.m_sNetwork); + } }; TEST_F(ClientTest, Pass) { - // clang-format off - testPass("p@ss#w0rd", "", "", "", "p@ss#w0rd"); - testPass("user:p@ss#w0rd", "user", "", "", "p@ss#w0rd"); - testPass("user/net-work:p@ss#w0rd", "user", "", "net-work", "p@ss#w0rd"); - testPass("user@identifier:p@ss#w0rd", "user", "identifier", "", "p@ss#w0rd"); - testPass("user@identifier/net-work:p@ss#w0rd", "user", "identifier", "net-work", "p@ss#w0rd"); + // clang-format off + testPass("p@ss#w0rd", "", "", "", "p@ss#w0rd"); + testPass("user:p@ss#w0rd", "user", "", "", "p@ss#w0rd"); + testPass("user/net-work:p@ss#w0rd", "user", "", "net-work", "p@ss#w0rd"); + testPass("user@identifier:p@ss#w0rd", "user", "identifier", "", "p@ss#w0rd"); + testPass("user@identifier/net-work:p@ss#w0rd", "user", "identifier", "net-work", "p@ss#w0rd"); - testPass("user@znc.in:p@ss#w0rd", "user@znc.in", "", "", "p@ss#w0rd"); - testPass("user@znc.in/net-work:p@ss#w0rd", "user@znc.in", "", "net-work", "p@ss#w0rd"); - testPass("user@znc.in@identifier:p@ss#w0rd", "user@znc.in", "identifier", "", "p@ss#w0rd"); - testPass("user@znc.in@identifier/net-work:p@ss#w0rd", "user@znc.in", "identifier", "net-work", "p@ss#w0rd"); - // clang-format on + testPass("user@znc.in:p@ss#w0rd", "user@znc.in", "", "", "p@ss#w0rd"); + testPass("user@znc.in/net-work:p@ss#w0rd", "user@znc.in", "", "net-work", "p@ss#w0rd"); + testPass("user@znc.in@identifier:p@ss#w0rd", "user@znc.in", "identifier", "", "p@ss#w0rd"); + testPass("user@znc.in@identifier/net-work:p@ss#w0rd", "user@znc.in", "identifier", "net-work", "p@ss#w0rd"); + // clang-format on } TEST_F(ClientTest, User) { - // clang-format off - testUser("user/net-work", "user", "", "net-work"); - testUser("user@identifier", "user", "identifier", ""); - testUser("user@identifier/net-work", "user", "identifier", "net-work"); + // clang-format off + testUser("user/net-work", "user", "", "net-work"); + testUser("user@identifier", "user", "identifier", ""); + testUser("user@identifier/net-work", "user", "identifier", "net-work"); - testUser("user@znc.in/net-work", "user@znc.in", "", "net-work"); - testUser("user@znc.in@identifier", "user@znc.in", "identifier", ""); - testUser("user@znc.in@identifier/net-work", "user@znc.in", "identifier", "net-work"); - // clang-format on + testUser("user@znc.in/net-work", "user@znc.in", "", "net-work"); + testUser("user@znc.in@identifier", "user@znc.in", "identifier", ""); + testUser("user@znc.in@identifier/net-work", "user@znc.in", "identifier", "net-work"); + // clang-format on } TEST_F(ClientTest, AccountNotify) { - CMessage msg(":nick!user@host ACCOUNT accountname"); - EXPECT_FALSE(m_pTestClient->HasAccountNotify()); - m_pTestClient->PutClient(msg); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - m_pTestClient->SetAccountNotify(true); - EXPECT_TRUE(m_pTestClient->HasAccountNotify()); - m_pTestClient->PutClient(msg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + CMessage msg(":nick!user@host ACCOUNT accountname"); + EXPECT_FALSE(m_pTestClient->HasAccountNotify()); + m_pTestClient->PutClient(msg); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + m_pTestClient->SetAccountNotify(true); + EXPECT_TRUE(m_pTestClient->HasAccountNotify()); + m_pTestClient->PutClient(msg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, AwayNotify) { - CMessage msg(":nick!user@host AWAY :message"); - EXPECT_FALSE(m_pTestClient->HasAwayNotify()); - m_pTestClient->PutClient(msg); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - m_pTestClient->SetAwayNotify(true); - EXPECT_TRUE(m_pTestClient->HasAwayNotify()); - m_pTestClient->PutClient(msg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + CMessage msg(":nick!user@host AWAY :message"); + EXPECT_FALSE(m_pTestClient->HasAwayNotify()); + m_pTestClient->PutClient(msg); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + m_pTestClient->SetAwayNotify(true); + EXPECT_TRUE(m_pTestClient->HasAwayNotify()); + m_pTestClient->PutClient(msg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, MultiPrefixWho) { // aka NAMESX - m_pTestSock->ReadLine( - ":server 005 guest PREFIX=(qaohv)~&@%+ NAMESX :are supported by this " - "server"); - m_pTestClient->Reset(); + m_pTestSock->ReadLine( + ":server 005 guest PREFIX=(qaohv)~&@%+ NAMESX :are supported by this " + "server"); + m_pTestClient->Reset(); - CMessage msg( - ":kenny.chatspike.net 352 guest #test grawity broken.symlink " - "*.chatspike.net grawity H@%+ :0 Mantas M."); - CMessage extmsg( - ":kenny.chatspike.net 352 guest #test grawity broken.symlink " - "*.chatspike.net grawity H@%+ :0 Mantas M."); - EXPECT_FALSE(m_pTestClient->HasNamesx()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->SetNamesx(true); - EXPECT_TRUE(m_pTestClient->HasNamesx()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, - ElementsAre(msg.ToString(), extmsg.ToString())); + CMessage msg( + ":kenny.chatspike.net 352 guest #test grawity broken.symlink " + "*.chatspike.net grawity H@%+ :0 Mantas M."); + CMessage extmsg( + ":kenny.chatspike.net 352 guest #test grawity broken.symlink " + "*.chatspike.net grawity H@%+ :0 Mantas M."); + EXPECT_FALSE(m_pTestClient->HasNamesx()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + m_pTestClient->SetNamesx(true); + EXPECT_TRUE(m_pTestClient->HasNamesx()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, + ElementsAre(msg.ToString(), extmsg.ToString())); } TEST_F(ClientTest, MultiPrefixNames) { // aka NAMESX - m_pTestSock->ReadLine( - ":server 005 guest PREFIX=(qaohv)~&@%+ NAMESX :are supported by this " - "server"); - m_pTestClient->Reset(); + m_pTestSock->ReadLine( + ":server 005 guest PREFIX=(qaohv)~&@%+ NAMESX :are supported by this " + "server"); + m_pTestClient->Reset(); - CMessage msg( - ":hades.arpa 353 guest = #tethys :~aji &Attila @alyx +KindOne Argure"); - CMessage extmsg( - ":hades.arpa 353 guest = #tethys :~&@%+aji &@Attila @+alyx +KindOne " - "Argure"); - EXPECT_FALSE(m_pTestClient->HasNamesx()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->SetNamesx(true); - EXPECT_TRUE(m_pTestClient->HasNamesx()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, - ElementsAre(msg.ToString(), extmsg.ToString())); + CMessage msg( + ":hades.arpa 353 guest = #tethys :~aji &Attila @alyx +KindOne Argure"); + CMessage extmsg( + ":hades.arpa 353 guest = #tethys :~&@%+aji &@Attila @+alyx +KindOne " + "Argure"); + EXPECT_FALSE(m_pTestClient->HasNamesx()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + m_pTestClient->SetNamesx(true); + EXPECT_TRUE(m_pTestClient->HasNamesx()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, + ElementsAre(msg.ToString(), extmsg.ToString())); } TEST_F(ClientTest, UserhostInNames) { // aka UHNAMES - m_pTestSock->ReadLine( - ":server 005 guest UHNAMES :are supported by this server"); - m_pTestClient->Reset(); + m_pTestSock->ReadLine( + ":server 005 guest UHNAMES :are supported by this server"); + m_pTestClient->Reset(); - CMessage msg(":irc.bnc.im 353 guest = #atheme :Rylee somasonic"); - CMessage extmsg( - ":irc.bnc.im 353 guest = #atheme :Rylee!rylai@localhost " - "somasonic!andrew@somasonic.org"); - EXPECT_FALSE(m_pTestClient->HasUHNames()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->SetUHNames(true); - EXPECT_TRUE(m_pTestClient->HasUHNames()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, - ElementsAre(msg.ToString(), extmsg.ToString())); + CMessage msg(":irc.bnc.im 353 guest = #atheme :Rylee somasonic"); + CMessage extmsg( + ":irc.bnc.im 353 guest = #atheme :Rylee!rylai@localhost " + "somasonic!andrew@somasonic.org"); + EXPECT_FALSE(m_pTestClient->HasUHNames()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + m_pTestClient->SetUHNames(true); + EXPECT_TRUE(m_pTestClient->HasUHNames()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, + ElementsAre(msg.ToString(), extmsg.ToString())); } TEST_F(ClientTest, ExtendedJoin) { - m_pTestSock->ReadLine(":server CAP * ACK :extended-join"); - m_pTestClient->Reset(); + m_pTestSock->ReadLine(":server CAP * ACK :extended-join"); + m_pTestClient->Reset(); - CMessage msg(":nick!user@host JOIN #channel"); - CMessage extmsg(":nick!user@host JOIN #channel account :Real Name"); - EXPECT_FALSE(m_pTestClient->HasExtendedJoin()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->SetExtendedJoin(true); - EXPECT_TRUE(m_pTestClient->HasExtendedJoin()); - m_pTestClient->PutClient(extmsg); - EXPECT_THAT(m_pTestClient->vsLines, - ElementsAre(msg.ToString(), extmsg.ToString())); + CMessage msg(":nick!user@host JOIN #channel"); + CMessage extmsg(":nick!user@host JOIN #channel account :Real Name"); + EXPECT_FALSE(m_pTestClient->HasExtendedJoin()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + m_pTestClient->SetExtendedJoin(true); + EXPECT_TRUE(m_pTestClient->HasExtendedJoin()); + m_pTestClient->PutClient(extmsg); + EXPECT_THAT(m_pTestClient->vsLines, + ElementsAre(msg.ToString(), extmsg.ToString())); } TEST_F(ClientTest, StatusMsg) { - m_pTestSock->ReadLine( - ":irc.znc.in 001 me :Welcome to the Internet Relay Network me"); - m_pTestSock->ReadLine( - ":irc.znc.in 005 me CHANTYPES=# PREFIX=(ov)@+ STATUSMSG=@+ :are " - "supported by this server"); + m_pTestSock->ReadLine( + ":irc.znc.in 001 me :Welcome to the Internet Relay Network me"); + m_pTestSock->ReadLine( + ":irc.znc.in 005 me CHANTYPES=# PREFIX=(ov)@+ STATUSMSG=@+ :are " + "supported by this server"); - m_pTestUser->SetAutoClearChanBuffer(false); - m_pTestClient->ReadLine("PRIVMSG @#chan :hello ops"); + m_pTestUser->SetAutoClearChanBuffer(false); + m_pTestClient->ReadLine("PRIVMSG @#chan :hello ops"); - EXPECT_EQ(1u, m_pTestChan->GetBuffer().Size()); + EXPECT_EQ(1u, m_pTestChan->GetBuffer().Size()); - m_pTestUser->SetTimestampPrepend(false); - EXPECT_EQ(":me PRIVMSG @#chan :hello ops", - m_pTestChan->GetBuffer().GetLine(0, *m_pTestClient)); + m_pTestUser->SetTimestampPrepend(false); + EXPECT_EQ(":me PRIVMSG @#chan :hello ops", + m_pTestChan->GetBuffer().GetLine(0, *m_pTestClient)); } TEST_F(ClientTest, OnUserCTCPReplyMessage) { - CMessage msg("NOTICE someone :\001VERSION 123\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("NOTICE someone :\001VERSION 123\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - CString sReply = - "NOTICE someone :\x01VERSION 123 via " + CZNC::GetTag(false) + "\x01"; + CString sReply = + "NOTICE someone :\x01VERSION 123 via " + CZNC::GetTag(false) + "\x01"; - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserCTCPReplyMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(sReply)); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserCTCPReplyMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(sReply)); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(sReply)); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(sReply)); } TEST_F(ClientTest, OnUserCTCPMessage) { - CMessage msg("PRIVMSG someone :\001VERSION\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("PRIVMSG someone :\001VERSION\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserCTCPMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserCTCPMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserActionMessage) { - CMessage msg("PRIVMSG #chan :\001ACTION acts\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("PRIVMSG #chan :\001ACTION acts\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserActionMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserActionMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserTextMessage) { - CMessage msg("PRIVMSG #chan :text"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("PRIVMSG #chan :text"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserTextMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserTextMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserNoticeMessage) { - CMessage msg("NOTICE #chan :text"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("NOTICE #chan :text"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserNoticeMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserNoticeMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserJoinMessage) { - CMessage msg("JOIN #chan key"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("JOIN #chan key"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserJoinMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserJoinMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserPartMessage) { - CMessage msg("PART #znc"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("PART #znc"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserPartMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserPartMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserTopicMessage) { - CMessage msg("TOPIC #chan :topic"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("TOPIC #chan :topic"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserTopicMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserTopicMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString())); } TEST_F(ClientTest, OnUserQuitMessage) { - CMessage msg("QUIT :reason"); - m_pTestModule->eAction = CModule::HALT; - m_pTestClient->ReadLine(msg.ToString()); + CMessage msg("QUIT :reason"); + m_pTestModule->eAction = CModule::HALT; + m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserQuitMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnUserQuitMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestClient->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // quit is never forwarded + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestClient->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // quit is never forwarded } diff --git a/test/ConfigTest.cpp b/test/ConfigTest.cpp index 4023a0bb..a5c6a527 100644 --- a/test/ConfigTest.cpp +++ b/test/ConfigTest.cpp @@ -20,86 +20,86 @@ class CConfigTest : public ::testing::Test { public: - virtual ~CConfigTest() { m_File.Delete(); } + virtual ~CConfigTest() { m_File.Delete(); } protected: - CFile& WriteFile(const CString& sConfig) { - char sName[] = "./temp-XXXXXX"; - int fd = mkstemp(sName); - m_File.Open(sName, O_RDWR); - close(fd); + CFile& WriteFile(const CString& sConfig) { + char sName[] = "./temp-XXXXXX"; + int fd = mkstemp(sName); + m_File.Open(sName, O_RDWR); + close(fd); - m_File.Write(sConfig); + m_File.Write(sConfig); - return m_File; - } + return m_File; + } private: - CFile m_File; + CFile m_File; }; class CConfigErrorTest : public CConfigTest { public: - void TEST_ERROR(const CString& sConfig, const CString& sExpectError) { - CFile& File = WriteFile(sConfig); + void TEST_ERROR(const CString& sConfig, const CString& sExpectError) { + CFile& File = WriteFile(sConfig); - CConfig conf; - CString sError; - EXPECT_FALSE(conf.Parse(File, sError)); + CConfig conf; + CString sError; + EXPECT_FALSE(conf.Parse(File, sError)); - EXPECT_EQ(sExpectError, sError); - } + EXPECT_EQ(sExpectError, sError); + } }; class CConfigSuccessTest : public CConfigTest { public: - void TEST_SUCCESS(const CString& sConfig, const CString& sExpectedOutput) { - CFile& File = WriteFile(sConfig); - // Verify that Parse() rewinds the file - File.Seek(12); + void TEST_SUCCESS(const CString& sConfig, const CString& sExpectedOutput) { + CFile& File = WriteFile(sConfig); + // Verify that Parse() rewinds the file + File.Seek(12); - CConfig conf; - CString sError; - EXPECT_TRUE(conf.Parse(File, sError)) << sError; - EXPECT_TRUE(sError.empty()) << "Non-empty error string!"; + CConfig conf; + CString sError; + EXPECT_TRUE(conf.Parse(File, sError)) << sError; + EXPECT_TRUE(sError.empty()) << "Non-empty error string!"; - CString sOutput; - ToString(sOutput, conf); + CString sOutput; + ToString(sOutput, conf); - EXPECT_EQ(sExpectedOutput, sOutput); - } + EXPECT_EQ(sExpectedOutput, sOutput); + } - void ToString(CString& sRes, CConfig& conf) { - CConfig::EntryMapIterator it = conf.BeginEntries(); - while (it != conf.EndEntries()) { - const CString& sKey = it->first; - const VCString& vsEntries = it->second; - VCString::const_iterator i = vsEntries.begin(); - if (i == vsEntries.end()) - sRes += sKey + " <- Error, empty list!\n"; - else - while (i != vsEntries.end()) { - sRes += sKey + "=" + *i + "\n"; - ++i; - } - ++it; - } + void ToString(CString& sRes, CConfig& conf) { + CConfig::EntryMapIterator it = conf.BeginEntries(); + while (it != conf.EndEntries()) { + const CString& sKey = it->first; + const VCString& vsEntries = it->second; + VCString::const_iterator i = vsEntries.begin(); + if (i == vsEntries.end()) + sRes += sKey + " <- Error, empty list!\n"; + else + while (i != vsEntries.end()) { + sRes += sKey + "=" + *i + "\n"; + ++i; + } + ++it; + } - CConfig::SubConfigMapIterator it2 = conf.BeginSubConfigs(); - while (it2 != conf.EndSubConfigs()) { - std::map::const_iterator it3 = - it2->second.begin(); + CConfig::SubConfigMapIterator it2 = conf.BeginSubConfigs(); + while (it2 != conf.EndSubConfigs()) { + std::map::const_iterator it3 = + it2->second.begin(); - while (it3 != it2->second.end()) { - sRes += "->" + it2->first + "/" + it3->first + "\n"; - ToString(sRes, *it3->second.m_pSubConfig); - sRes += "<-\n"; - ++it3; - } + while (it3 != it2->second.end()) { + sRes += "->" + it2->first + "/" + it3->first + "\n"; + ToString(sRes, *it3->second.m_pSubConfig); + sRes += "<-\n"; + ++it3; + } - ++it2; - } - } + ++it2; + } + } private: }; @@ -108,58 +108,58 @@ TEST_F(CConfigSuccessTest, Empty) { TEST_SUCCESS("", ""); } /* duplicate entries */ TEST_F(CConfigSuccessTest, Duble1) { - TEST_SUCCESS("Foo = bar\nFoo = baz\n", "foo=bar\nfoo=baz\n"); + TEST_SUCCESS("Foo = bar\nFoo = baz\n", "foo=bar\nfoo=baz\n"); } TEST_F(CConfigSuccessTest, Duble2) { - TEST_SUCCESS("Foo = baz\nFoo = bar\n", "foo=baz\nfoo=bar\n"); + TEST_SUCCESS("Foo = baz\nFoo = bar\n", "foo=baz\nfoo=bar\n"); } /* sub configs */ TEST_F(CConfigErrorTest, SubConf1) { - TEST_ERROR("", - "Error on line 1: Closing tag \"foo\" which is not open."); + TEST_ERROR("", + "Error on line 1: Closing tag \"foo\" which is not open."); } TEST_F(CConfigErrorTest, SubConf2) { - TEST_ERROR("\n\n", - "Error on line 2: Closing tag \"bar\" which is not open."); + TEST_ERROR("\n\n", + "Error on line 2: Closing tag \"bar\" which is not open."); } TEST_F(CConfigErrorTest, SubConf3) { - TEST_ERROR("", - "Error on line 1: Not all tags are closed at the end of the " - "file. Inner-most open tag is \"foo\"."); + TEST_ERROR("", + "Error on line 1: Not all tags are closed at the end of the " + "file. Inner-most open tag is \"foo\"."); } TEST_F(CConfigErrorTest, SubConf4) { - TEST_ERROR("\n", - "Error on line 1: Empty block name at begin of block."); + TEST_ERROR("\n", + "Error on line 1: Empty block name at begin of block."); } TEST_F(CConfigErrorTest, SubConf5) { - TEST_ERROR("\n\n\n", - "Error on line 4: Duplicate entry for tag \"foo\" name \"1\"."); + TEST_ERROR("\n\n\n", + "Error on line 4: Duplicate entry for tag \"foo\" name \"1\"."); } TEST_F(CConfigSuccessTest, SubConf6) { - TEST_SUCCESS("\n", "->foo/a\n<-\n"); + TEST_SUCCESS("\n", "->foo/a\n<-\n"); } TEST_F(CConfigSuccessTest, SubConf7) { - TEST_SUCCESS("\n \n \n", "->a/b\n->c/d\n<-\n<-\n"); + TEST_SUCCESS("\n \n \n", "->a/b\n->c/d\n<-\n<-\n"); } TEST_F(CConfigSuccessTest, SubConf8) { - TEST_SUCCESS(" \t \nfoo = bar\n\tFooO = bar\n", - "->a/B\nfoo=bar\nfooo=bar\n<-\n"); + TEST_SUCCESS(" \t \nfoo = bar\n\tFooO = bar\n", + "->a/B\nfoo=bar\nfooo=bar\n<-\n"); } /* comments */ TEST_F(CConfigSuccessTest, Comment1) { - TEST_SUCCESS("Foo = bar // baz\n// Bar = baz", "foo=bar // baz\n"); + TEST_SUCCESS("Foo = bar // baz\n// Bar = baz", "foo=bar // baz\n"); } TEST_F(CConfigSuccessTest, Comment2) { - TEST_SUCCESS( - "Foo = bar /* baz */\n/*** Foo = baz ***/\n /**** asdsdfdf \n Some " - "quite invalid stuff ***/\n", - "foo=bar /* baz */\n"); + TEST_SUCCESS( + "Foo = bar /* baz */\n/*** Foo = baz ***/\n /**** asdsdfdf \n Some " + "quite invalid stuff ***/\n", + "foo=bar /* baz */\n"); } TEST_F(CConfigErrorTest, Comment3) { - TEST_ERROR("\n/* Just a comment\n", - "Error on line 3: Comment not closed at end of file."); + TEST_ERROR("\n/* Just a comment\n", + "Error on line 3: Comment not closed at end of file."); } TEST_F(CConfigSuccessTest, Comment4) { TEST_SUCCESS("/* Foo\n/* Bar */", ""); } TEST_F(CConfigSuccessTest, Comment5) { TEST_SUCCESS("/* Foo\n// */", ""); } diff --git a/test/IRCSockTest.cpp b/test/IRCSockTest.cpp index cb0dc1a4..e630eb2f 100644 --- a/test/IRCSockTest.cpp +++ b/test/IRCSockTest.cpp @@ -33,481 +33,481 @@ class IRCSockTest : public IRCTest { }; TEST_F(IRCSockTest, OnAccountMessage) { - CMessage msg(":nick!user@host ACCOUNT accountname"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick!user@host ACCOUNT accountname"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnAccountMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // account-notify disabled + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnAccountMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // account-notify disabled } TEST_F(IRCSockTest, OnActionMessage) { - // 2 callbacks are called in row: OnCTCP, OnAction. - // If OnCTCP returns HALT, OnAction isn't called. - struct ActionModule : TestModule { - ActionModule() { Reset(); } - void Reset() { - Mock::VerifyAndClear(this); - EXPECT_CALL(*this, OnPrivCTCPMessage(_)).Times(0); - EXPECT_CALL(*this, OnChanCTCPMessage(_)).Times(0); - EXPECT_CALL(*this, OnPrivActionMessage(_)).Times(0); - EXPECT_CALL(*this, OnChanActionMessage(_)).Times(0); - TestModule::Reset(); - } - MOCK_METHOD1(OnPrivCTCPMessage, EModRet(CCTCPMessage&)); - MOCK_METHOD1(OnChanCTCPMessage, EModRet(CCTCPMessage&)); - MOCK_METHOD1(OnPrivActionMessage, EModRet(CActionMessage&)); - MOCK_METHOD1(OnChanActionMessage, EModRet(CActionMessage&)); - }; - ActionModule testModule; - CZNC::Get().GetModules().push_back(&testModule); - CChan* pExpectedChan = m_pTestChan; + // 2 callbacks are called in row: OnCTCP, OnAction. + // If OnCTCP returns HALT, OnAction isn't called. + struct ActionModule : TestModule { + ActionModule() { Reset(); } + void Reset() { + Mock::VerifyAndClear(this); + EXPECT_CALL(*this, OnPrivCTCPMessage(_)).Times(0); + EXPECT_CALL(*this, OnChanCTCPMessage(_)).Times(0); + EXPECT_CALL(*this, OnPrivActionMessage(_)).Times(0); + EXPECT_CALL(*this, OnChanActionMessage(_)).Times(0); + TestModule::Reset(); + } + MOCK_METHOD1(OnPrivCTCPMessage, EModRet(CCTCPMessage&)); + MOCK_METHOD1(OnChanCTCPMessage, EModRet(CCTCPMessage&)); + MOCK_METHOD1(OnPrivActionMessage, EModRet(CActionMessage&)); + MOCK_METHOD1(OnChanActionMessage, EModRet(CActionMessage&)); + }; + ActionModule testModule; + CZNC::Get().GetModules().push_back(&testModule); + CChan* pExpectedChan = m_pTestChan; - CMessage msg(":nick PRIVMSG #chan :\001ACTION hello\001"); - auto CON = Invoke([&](CMessage& m) { - EXPECT_EQ(msg.ToString(), m.ToString()); - EXPECT_EQ(m_pTestNetwork, m.GetNetwork()); - EXPECT_EQ(pExpectedChan, m.GetChan()); - return CModule::CONTINUE; - }); - auto HAL = Invoke([&](CMessage& m) { - EXPECT_EQ(msg.ToString(), m.ToString()); - EXPECT_EQ(m_pTestNetwork, m.GetNetwork()); - EXPECT_EQ(pExpectedChan, m.GetChan()); - return CModule::HALT; - }); - auto Reset = [&]() { - testModule.Reset(); - m_pTestClient->Reset(); - }; + CMessage msg(":nick PRIVMSG #chan :\001ACTION hello\001"); + auto CON = Invoke([&](CMessage& m) { + EXPECT_EQ(msg.ToString(), m.ToString()); + EXPECT_EQ(m_pTestNetwork, m.GetNetwork()); + EXPECT_EQ(pExpectedChan, m.GetChan()); + return CModule::CONTINUE; + }); + auto HAL = Invoke([&](CMessage& m) { + EXPECT_EQ(msg.ToString(), m.ToString()); + EXPECT_EQ(m_pTestNetwork, m.GetNetwork()); + EXPECT_EQ(pExpectedChan, m.GetChan()); + return CModule::HALT; + }); + auto Reset = [&]() { + testModule.Reset(); + m_pTestClient->Reset(); + }; - Reset(); - { - InSequence seq; - EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(CON); - EXPECT_CALL(testModule, OnChanActionMessage(_)).WillOnce(CON); - } - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + Reset(); + { + InSequence seq; + EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(CON); + EXPECT_CALL(testModule, OnChanActionMessage(_)).WillOnce(CON); + } + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - Reset(); - { - InSequence seq; - EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(CON); - EXPECT_CALL(testModule, OnChanActionMessage(_)).WillOnce(HAL); - } - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + Reset(); + { + InSequence seq; + EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(CON); + EXPECT_CALL(testModule, OnChanActionMessage(_)).WillOnce(HAL); + } + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - Reset(); - EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(HAL); - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + Reset(); + EXPECT_CALL(testModule, OnChanCTCPMessage(_)).WillOnce(HAL); + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - msg.Parse(":nick PRIVMSG me :\001ACTION hello\001"); - pExpectedChan = nullptr; + msg.Parse(":nick PRIVMSG me :\001ACTION hello\001"); + pExpectedChan = nullptr; - Reset(); - { - InSequence seq; - EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(CON); - EXPECT_CALL(testModule, OnPrivActionMessage(_)).WillOnce(CON); - } - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + Reset(); + { + InSequence seq; + EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(CON); + EXPECT_CALL(testModule, OnPrivActionMessage(_)).WillOnce(CON); + } + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - Reset(); - { - InSequence seq; - EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(CON); - EXPECT_CALL(testModule, OnPrivActionMessage(_)).WillOnce(HAL); - } - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + Reset(); + { + InSequence seq; + EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(CON); + EXPECT_CALL(testModule, OnPrivActionMessage(_)).WillOnce(HAL); + } + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - Reset(); - EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(HAL); - m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + Reset(); + EXPECT_CALL(testModule, OnPrivCTCPMessage(_)).WillOnce(HAL); + m_pTestSock->ReadLine(msg.ToString()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); } TEST_F(IRCSockTest, OnAwayMessage) { - CMessage msg(":nick!user@host AWAY :reason"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick!user@host AWAY :reason"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnAwayMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // away-notify disabled + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnAwayMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // away-notify disabled } TEST_F(IRCSockTest, OnCapabilityMessage) { - CMessage msg(":server CAP * LS :multi-prefix sasl"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":server CAP * LS :multi-prefix sasl"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnCapabilityMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnCapabilityMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); } TEST_F(IRCSockTest, OnCTCPMessage) { - CMessage msg(":nick PRIVMSG #chan :\001VERSION\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick PRIVMSG #chan :\001VERSION\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanCTCPMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanCTCPMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->Reset(); - m_pTestModule->Reset(); + m_pTestClient->Reset(); + m_pTestModule->Reset(); - msg.Parse(":nick PRIVMSG me :\001VERSION\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick PRIVMSG me :\001VERSION\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivCTCPMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivCTCPMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->Reset(); - m_pTestModule->Reset(); + m_pTestClient->Reset(); + m_pTestModule->Reset(); - msg.Parse(":nick NOTICE me :\001VERSION ZNC 0.0\001"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick NOTICE me :\001VERSION ZNC 0.0\001"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnCTCPReplyMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnCTCPReplyMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnErrorMessage) { - CMessage msg(":server ERROR :foo bar"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":server ERROR :foo bar"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnErrorMessage() hook (yet?) - EXPECT_THAT( - m_pTestClient->vsLines, - ElementsAre( - ":*status!znc@znc.in PRIVMSG me :Error from Server [foo bar]")); + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnErrorMessage() hook (yet?) + EXPECT_THAT( + m_pTestClient->vsLines, + ElementsAre( + ":*status!znc@znc.in PRIVMSG me :Error from Server [foo bar]")); } TEST_F(IRCSockTest, OnInviteMessage) { - CMessage msg(":nick INVITE me #znc"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick INVITE me #znc"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnInviteMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnInviteMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnJoinMessage) { - CMessage msg(":somebody JOIN #chan"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":somebody JOIN #chan"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnJoinMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnJoinMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); } TEST_F(IRCSockTest, OnKickMessage) { - CMessage msg(":nick KICK #chan person :reason"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick KICK #chan person :reason"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnKickMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnKickMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); } TEST_F(IRCSockTest, OnModeMessage) { - CMessage msg(":nick MODE #chan +k key"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick MODE #chan +k key"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnModeMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnModeMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnNickMessage) { - CMessage msg(":nobody NICK nick"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nobody NICK nick"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnNickMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnNickMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); - msg.Parse(":nick NICK somebody"); - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick NICK somebody"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnNoticeMessage) { - CMessage msg(":nick NOTICE #chan :hello"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick NOTICE #chan :hello"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanNoticeMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanNoticeMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->Reset(); - m_pTestModule->Reset(); + m_pTestClient->Reset(); + m_pTestModule->Reset(); - msg.Parse(":nick NOTICE me :hello"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick NOTICE me :hello"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivNoticeMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivNoticeMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnNumericMessage) { - CMessage msg(":irc.server.com 372 nick :motd"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":irc.server.com 372 nick :motd"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnNumericMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnNumericMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnPartMessage) { - CMessage msg(":nick PART #chan :reason"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick PART #chan :reason"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPartMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPartMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); } TEST_F(IRCSockTest, OnPingMessage) { - CMessage msg(":server PING :arg"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":server PING :arg"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, IsEmpty()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + EXPECT_THAT(m_pTestModule->vsHooks, IsEmpty()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); } TEST_F(IRCSockTest, OnPongMessage) { - CMessage msg(":server PONG :arg"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":server PONG :arg"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, IsEmpty()); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); + EXPECT_THAT(m_pTestModule->vsHooks, IsEmpty()); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); } TEST_F(IRCSockTest, OnQuitMessage) { - CMessage msg(":nobody QUIT :bye"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nobody QUIT :bye"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnQuitMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnQuitMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - msg.Parse(":nick QUIT :bye"); - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick QUIT :bye"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnTextMessage) { - CMessage msg(":nick PRIVMSG #chan :hello"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick PRIVMSG #chan :hello"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnChanMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); - m_pTestClient->Reset(); - m_pTestModule->Reset(); + m_pTestClient->Reset(); + m_pTestModule->Reset(); - msg.Parse(":nick PRIVMSG me :hello"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + msg.Parse(":nick PRIVMSG me :hello"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnPrivMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnTopicMessage) { - CMessage msg(":nick TOPIC #chan :topic"); - m_pTestModule->eAction = CModule::HALT; - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":nick TOPIC #chan :topic"); + m_pTestModule->eAction = CModule::HALT; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnTopicMessage")); - EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); - EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); - EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); - EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt + EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnTopicMessage")); + EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork)); + EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(m_pTestChan)); + EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt - m_pTestModule->eAction = CModule::CONTINUE; - m_pTestSock->ReadLine(msg.ToString()); + m_pTestModule->eAction = CModule::CONTINUE; + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, OnWallopsMessage) { - CMessage msg(":blub!dummy@rox-8DBEFE92 WALLOPS :this is a test"); - m_pTestSock->ReadLine(msg.ToString()); + CMessage msg(":blub!dummy@rox-8DBEFE92 WALLOPS :this is a test"); + m_pTestSock->ReadLine(msg.ToString()); - EXPECT_THAT(m_pTestModule->vsHooks, - IsEmpty()); // no OnWallopsMessage() hook (yet?) - EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); + EXPECT_THAT(m_pTestModule->vsHooks, + IsEmpty()); // no OnWallopsMessage() hook (yet?) + EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString())); } TEST_F(IRCSockTest, ISupport) { - MCString m1 = { - {"CHANTYPES", "#"}, {"EXCEPTS", ""}, - {"INVEX", ""}, {"CHANMODES", "eIbq,k,flj,CFLMPQScgimnprstz"}, - {"CHANLIMIT", "#:120"}, {"PREFIX", "(ov)@+"}, - {"MAXLIST", "bqeI:100"}, {"MODES", "4"}, - {"NETWORK", "znc"}, {"KNOCK", ""}, - {"STATUSMSG", "@+"}, {"CALLERID", "g"}, - }; + MCString m1 = { + {"CHANTYPES", "#"}, {"EXCEPTS", ""}, + {"INVEX", ""}, {"CHANMODES", "eIbq,k,flj,CFLMPQScgimnprstz"}, + {"CHANLIMIT", "#:120"}, {"PREFIX", "(ov)@+"}, + {"MAXLIST", "bqeI:100"}, {"MODES", "4"}, + {"NETWORK", "znc"}, {"KNOCK", ""}, + {"STATUSMSG", "@+"}, {"CALLERID", "g"}, + }; - m_pTestSock->ReadLine( - ":irc.znc.in 005 user CHANTYPES=# EXCEPTS INVEX " - "CHANMODES=eIbq,k,flj,CFLMPQScgimnprstz CHANLIMIT=#:120 PREFIX=(ov)@+ " - "MAXLIST=bqeI:100 MODES=4 NETWORK=znc KNOCK STATUSMSG=@+ CALLERID=g " - ":are supported by this server"); - EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m1)); - for (const auto& it : m1) { - EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); - } + m_pTestSock->ReadLine( + ":irc.znc.in 005 user CHANTYPES=# EXCEPTS INVEX " + "CHANMODES=eIbq,k,flj,CFLMPQScgimnprstz CHANLIMIT=#:120 PREFIX=(ov)@+ " + "MAXLIST=bqeI:100 MODES=4 NETWORK=znc KNOCK STATUSMSG=@+ CALLERID=g " + ":are supported by this server"); + EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m1)); + for (const auto& it : m1) { + EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); + } - MCString m2 = { - {"CASEMAPPING", "rfc1459"}, - {"CHARSET", "ascii"}, - {"NICKLEN", "16"}, - {"CHANNELLEN", "50"}, - {"TOPICLEN", "390"}, - {"ETRACE", ""}, - {"CPRIVMSG", ""}, - {"CNOTICE", ""}, - {"DEAF", "D"}, - {"MONITOR", "100"}, - {"FNC", ""}, - {"TARGMAX", - "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR:"}, - }; + MCString m2 = { + {"CASEMAPPING", "rfc1459"}, + {"CHARSET", "ascii"}, + {"NICKLEN", "16"}, + {"CHANNELLEN", "50"}, + {"TOPICLEN", "390"}, + {"ETRACE", ""}, + {"CPRIVMSG", ""}, + {"CNOTICE", ""}, + {"DEAF", "D"}, + {"MONITOR", "100"}, + {"FNC", ""}, + {"TARGMAX", + "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR:"}, + }; - MCString m12; - std::merge(m1.begin(), m1.end(), m2.begin(), m2.end(), - std::inserter(m12, m12.begin())); + MCString m12; + std::merge(m1.begin(), m1.end(), m2.begin(), m2.end(), + std::inserter(m12, m12.begin())); - m_pTestSock->ReadLine( - ":server 005 user CASEMAPPING=rfc1459 CHARSET=ascii NICKLEN=16 " - "CHANNELLEN=50 TOPICLEN=390 ETRACE CPRIVMSG CNOTICE DEAF=D MONITOR=100 " - "FNC " - "TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:," - "MONITOR: :are supported by this server"); - EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m12)); - for (const auto& it : m2) { - EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); - } + m_pTestSock->ReadLine( + ":server 005 user CASEMAPPING=rfc1459 CHARSET=ascii NICKLEN=16 " + "CHANNELLEN=50 TOPICLEN=390 ETRACE CPRIVMSG CNOTICE DEAF=D MONITOR=100 " + "FNC " + "TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:," + "MONITOR: :are supported by this server"); + EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m12)); + for (const auto& it : m2) { + EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); + } - MCString m3 = { - {"EXTBAN", "$,ajrxz"}, {"WHOX", ""}, {"CLIENTVER", "3.0"}, - {"SAFELIST", ""}, {"ELIST", "CTU"}, - }; + MCString m3 = { + {"EXTBAN", "$,ajrxz"}, {"WHOX", ""}, {"CLIENTVER", "3.0"}, + {"SAFELIST", ""}, {"ELIST", "CTU"}, + }; - MCString m123; - std::merge(m12.begin(), m12.end(), m3.begin(), m3.end(), - std::inserter(m123, m123.begin())); + MCString m123; + std::merge(m12.begin(), m12.end(), m3.begin(), m3.end(), + std::inserter(m123, m123.begin())); - m_pTestSock->ReadLine( - ":server 005 zzzzzz EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST " - "ELIST=CTU :are supported by this server"); - EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m123)); - for (const auto& it : m3) { - EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); - } + m_pTestSock->ReadLine( + ":server 005 zzzzzz EXTBAN=$,ajrxz WHOX CLIENTVER=3.0 SAFELIST " + "ELIST=CTU :are supported by this server"); + EXPECT_THAT(m_pTestSock->GetISupport(), ContainerEq(m123)); + for (const auto& it : m3) { + EXPECT_EQ(it.second, m_pTestSock->GetISupport(it.first)); + } - EXPECT_EQ("default", m_pTestSock->GetISupport("FOOBAR", "default")); - EXPECT_EQ("3.0", m_pTestSock->GetISupport("CLIENTVER", "default")); - EXPECT_EQ("", m_pTestSock->GetISupport("SAFELIST", "default")); + EXPECT_EQ("default", m_pTestSock->GetISupport("FOOBAR", "default")); + EXPECT_EQ("3.0", m_pTestSock->GetISupport("CLIENTVER", "default")); + EXPECT_EQ("", m_pTestSock->GetISupport("SAFELIST", "default")); } TEST_F(IRCSockTest, StatusMsg) { - m_pTestSock->ReadLine( - ":irc.znc.in 001 me :Welcome to the Internet Relay Network me"); - m_pTestSock->ReadLine( - ":irc.znc.in 005 me CHANTYPES=# PREFIX=(ov)@+ STATUSMSG=@+ :are " - "supported by this server"); + m_pTestSock->ReadLine( + ":irc.znc.in 001 me :Welcome to the Internet Relay Network me"); + m_pTestSock->ReadLine( + ":irc.znc.in 005 me CHANTYPES=# PREFIX=(ov)@+ STATUSMSG=@+ :are " + "supported by this server"); - m_pTestUser->SetAutoClearChanBuffer(false); - m_pTestSock->ReadLine(":someone PRIVMSG @#chan :hello ops"); + m_pTestUser->SetAutoClearChanBuffer(false); + m_pTestSock->ReadLine(":someone PRIVMSG @#chan :hello ops"); - EXPECT_EQ(1u, m_pTestChan->GetBuffer().Size()); + EXPECT_EQ(1u, m_pTestChan->GetBuffer().Size()); - m_pTestUser->SetTimestampPrepend(false); - EXPECT_EQ(":someone PRIVMSG @#chan :hello ops", - m_pTestChan->GetBuffer().GetLine(0, *m_pTestClient)); + m_pTestUser->SetTimestampPrepend(false); + EXPECT_EQ(":someone PRIVMSG @#chan :hello ops", + m_pTestChan->GetBuffer().GetLine(0, *m_pTestClient)); } diff --git a/test/IRCTest.h b/test/IRCTest.h index 1c078cfc..7937f8a8 100644 --- a/test/IRCTest.h +++ b/test/IRCTest.h @@ -29,210 +29,210 @@ class TestClient : public CClient { public: - TestClient() { SetNick("me"); } - bool Write(const CString& sData) override { - vsLines.push_back(sData.TrimSuffix_n("\r\n")); - return true; - } - void Reset() { vsLines.clear(); } - void SetAccountNotify(bool bEnabled) { m_bAccountNotify = bEnabled; } - void SetAwayNotify(bool bEnabled) { m_bAwayNotify = bEnabled; } - void SetExtendedJoin(bool bEnabled) { m_bExtendedJoin = bEnabled; } - void SetNamesx(bool bEnabled) { m_bNamesx = bEnabled; } - void SetUHNames(bool bEnabled) { m_bUHNames = bEnabled; } - VCString vsLines; + TestClient() { SetNick("me"); } + bool Write(const CString& sData) override { + vsLines.push_back(sData.TrimSuffix_n("\r\n")); + return true; + } + void Reset() { vsLines.clear(); } + void SetAccountNotify(bool bEnabled) { m_bAccountNotify = bEnabled; } + void SetAwayNotify(bool bEnabled) { m_bAwayNotify = bEnabled; } + void SetExtendedJoin(bool bEnabled) { m_bExtendedJoin = bEnabled; } + void SetNamesx(bool bEnabled) { m_bNamesx = bEnabled; } + void SetUHNames(bool bEnabled) { m_bUHNames = bEnabled; } + VCString vsLines; }; class TestIRCSock : public CIRCSock { public: - TestIRCSock(CIRCNetwork* pNetwork) : CIRCSock(pNetwork) { - m_Nick.SetNick("me"); - } - bool Write(const CString& sData) override { - vsLines.push_back(sData.TrimSuffix_n("\r\n")); - return true; - } - void Reset() { vsLines.clear(); } - VCString vsLines; + TestIRCSock(CIRCNetwork* pNetwork) : CIRCSock(pNetwork) { + m_Nick.SetNick("me"); + } + bool Write(const CString& sData) override { + vsLines.push_back(sData.TrimSuffix_n("\r\n")); + return true; + } + void Reset() { vsLines.clear(); } + VCString vsLines; }; class TestModule : public CModule { public: - TestModule() - : CModule(nullptr, nullptr, nullptr, "testmod", "", - CModInfo::NetworkModule) {} + TestModule() + : CModule(nullptr, nullptr, nullptr, "testmod", "", + CModInfo::NetworkModule) {} - EModRet OnCTCPReplyMessage(CCTCPMessage& msg) override { - vsHooks.push_back("OnCTCPReplyMessage"); - return OnMessage(msg); - } - EModRet OnPrivCTCPMessage(CCTCPMessage& msg) override { - vsHooks.push_back("OnPrivCTCPMessage"); - return OnMessage(msg); - } - EModRet OnChanCTCPMessage(CCTCPMessage& msg) override { - vsHooks.push_back("OnChanCTCPMessage"); - return OnMessage(msg); - } - EModRet OnPrivActionMessage(CActionMessage& msg) override { - vsHooks.push_back("OnPrivActionMessage"); - return OnMessage(msg); - } - EModRet OnChanActionMessage(CActionMessage& msg) override { - vsHooks.push_back("OnChanActionMessage"); - return OnMessage(msg); - } - EModRet OnPrivMessage(CTextMessage& msg) override { - vsHooks.push_back("OnPrivMessage"); - return OnMessage(msg); - } - EModRet OnChanMessage(CTextMessage& msg) override { - vsHooks.push_back("OnChanMessage"); - return OnMessage(msg); - } - EModRet OnPrivNoticeMessage(CNoticeMessage& msg) override { - vsHooks.push_back("OnPrivNoticeMessage"); - return OnMessage(msg); - } - EModRet OnChanNoticeMessage(CNoticeMessage& msg) override { - vsHooks.push_back("OnChanNoticeMessage"); - return OnMessage(msg); - } - EModRet OnTopicMessage(CTopicMessage& msg) override { - vsHooks.push_back("OnTopicMessage"); - return OnMessage(msg); - } - EModRet OnNumericMessage(CNumericMessage& msg) override { - vsHooks.push_back("OnNumericMessage"); - return OnMessage(msg); - } - void OnJoinMessage(CJoinMessage& msg) override { - vsHooks.push_back("OnJoinMessage"); - OnMessage(msg); - } - void OnKickMessage(CKickMessage& msg) override { - vsHooks.push_back("OnKickMessage"); - OnMessage(msg); - } - void OnNickMessage(CNickMessage& msg, - const std::vector& vChans) override { - vsHooks.push_back("OnNickMessage"); - OnMessage(msg); - } - void OnPartMessage(CPartMessage& msg) override { - vsHooks.push_back("OnPartMessage"); - OnMessage(msg); - } - void OnQuitMessage(CQuitMessage& msg, - const std::vector& vChans) override { - vsHooks.push_back("OnQuitMessage"); - OnMessage(msg); - } + EModRet OnCTCPReplyMessage(CCTCPMessage& msg) override { + vsHooks.push_back("OnCTCPReplyMessage"); + return OnMessage(msg); + } + EModRet OnPrivCTCPMessage(CCTCPMessage& msg) override { + vsHooks.push_back("OnPrivCTCPMessage"); + return OnMessage(msg); + } + EModRet OnChanCTCPMessage(CCTCPMessage& msg) override { + vsHooks.push_back("OnChanCTCPMessage"); + return OnMessage(msg); + } + EModRet OnPrivActionMessage(CActionMessage& msg) override { + vsHooks.push_back("OnPrivActionMessage"); + return OnMessage(msg); + } + EModRet OnChanActionMessage(CActionMessage& msg) override { + vsHooks.push_back("OnChanActionMessage"); + return OnMessage(msg); + } + EModRet OnPrivMessage(CTextMessage& msg) override { + vsHooks.push_back("OnPrivMessage"); + return OnMessage(msg); + } + EModRet OnChanMessage(CTextMessage& msg) override { + vsHooks.push_back("OnChanMessage"); + return OnMessage(msg); + } + EModRet OnPrivNoticeMessage(CNoticeMessage& msg) override { + vsHooks.push_back("OnPrivNoticeMessage"); + return OnMessage(msg); + } + EModRet OnChanNoticeMessage(CNoticeMessage& msg) override { + vsHooks.push_back("OnChanNoticeMessage"); + return OnMessage(msg); + } + EModRet OnTopicMessage(CTopicMessage& msg) override { + vsHooks.push_back("OnTopicMessage"); + return OnMessage(msg); + } + EModRet OnNumericMessage(CNumericMessage& msg) override { + vsHooks.push_back("OnNumericMessage"); + return OnMessage(msg); + } + void OnJoinMessage(CJoinMessage& msg) override { + vsHooks.push_back("OnJoinMessage"); + OnMessage(msg); + } + void OnKickMessage(CKickMessage& msg) override { + vsHooks.push_back("OnKickMessage"); + OnMessage(msg); + } + void OnNickMessage(CNickMessage& msg, + const std::vector& vChans) override { + vsHooks.push_back("OnNickMessage"); + OnMessage(msg); + } + void OnPartMessage(CPartMessage& msg) override { + vsHooks.push_back("OnPartMessage"); + OnMessage(msg); + } + void OnQuitMessage(CQuitMessage& msg, + const std::vector& vChans) override { + vsHooks.push_back("OnQuitMessage"); + OnMessage(msg); + } - EModRet OnUserCTCPReplyMessage(CCTCPMessage& msg) override { - vsHooks.push_back("OnUserCTCPReplyMessage"); - return OnMessage(msg); - } - EModRet OnUserCTCPMessage(CCTCPMessage& msg) override { - vsHooks.push_back("OnUserCTCPMessage"); - return OnMessage(msg); - } - EModRet OnUserActionMessage(CActionMessage& msg) override { - vsHooks.push_back("OnUserActionMessage"); - return OnMessage(msg); - } - EModRet OnUserTextMessage(CTextMessage& msg) override { - vsHooks.push_back("OnUserTextMessage"); - return OnMessage(msg); - } - EModRet OnUserNoticeMessage(CNoticeMessage& msg) override { - vsHooks.push_back("OnUserNoticeMessage"); - return OnMessage(msg); - } - EModRet OnUserJoinMessage(CJoinMessage& msg) override { - vsHooks.push_back("OnUserJoinMessage"); - return OnMessage(msg); - } - EModRet OnUserPartMessage(CPartMessage& msg) override { - vsHooks.push_back("OnUserPartMessage"); - return OnMessage(msg); - } - EModRet OnUserTopicMessage(CTopicMessage& msg) override { - vsHooks.push_back("OnUserTopicMessage"); - return OnMessage(msg); - } - EModRet OnUserQuitMessage(CQuitMessage& msg) override { - vsHooks.push_back("OnUserQuitMessage"); - return OnMessage(msg); - } + EModRet OnUserCTCPReplyMessage(CCTCPMessage& msg) override { + vsHooks.push_back("OnUserCTCPReplyMessage"); + return OnMessage(msg); + } + EModRet OnUserCTCPMessage(CCTCPMessage& msg) override { + vsHooks.push_back("OnUserCTCPMessage"); + return OnMessage(msg); + } + EModRet OnUserActionMessage(CActionMessage& msg) override { + vsHooks.push_back("OnUserActionMessage"); + return OnMessage(msg); + } + EModRet OnUserTextMessage(CTextMessage& msg) override { + vsHooks.push_back("OnUserTextMessage"); + return OnMessage(msg); + } + EModRet OnUserNoticeMessage(CNoticeMessage& msg) override { + vsHooks.push_back("OnUserNoticeMessage"); + return OnMessage(msg); + } + EModRet OnUserJoinMessage(CJoinMessage& msg) override { + vsHooks.push_back("OnUserJoinMessage"); + return OnMessage(msg); + } + EModRet OnUserPartMessage(CPartMessage& msg) override { + vsHooks.push_back("OnUserPartMessage"); + return OnMessage(msg); + } + EModRet OnUserTopicMessage(CTopicMessage& msg) override { + vsHooks.push_back("OnUserTopicMessage"); + return OnMessage(msg); + } + EModRet OnUserQuitMessage(CQuitMessage& msg) override { + vsHooks.push_back("OnUserQuitMessage"); + return OnMessage(msg); + } - EModRet OnMessage(const CMessage& msg) { - vsMessages.push_back(msg.ToString()); - vNetworks.push_back(msg.GetNetwork()); - vClients.push_back(msg.GetClient()); - vChannels.push_back(msg.GetChan()); - return eAction; - } + EModRet OnMessage(const CMessage& msg) { + vsMessages.push_back(msg.ToString()); + vNetworks.push_back(msg.GetNetwork()); + vClients.push_back(msg.GetClient()); + vChannels.push_back(msg.GetChan()); + return eAction; + } - void Reset() { - vsHooks.clear(); - vsMessages.clear(); - vNetworks.clear(); - vClients.clear(); - vChannels.clear(); - } + void Reset() { + vsHooks.clear(); + vsMessages.clear(); + vNetworks.clear(); + vClients.clear(); + vChannels.clear(); + } - VCString vsHooks; - VCString vsMessages; - std::vector vNetworks; - std::vector vClients; - std::vector vChannels; - EModRet eAction = CONTINUE; + VCString vsHooks; + VCString vsMessages; + std::vector vNetworks; + std::vector vClients; + std::vector vChannels; + EModRet eAction = CONTINUE; }; class IRCTest : public ::testing::Test { protected: - IRCTest() { - CDebug::SetDebug(false); - CZNC::CreateInstance(); - } - ~IRCTest() { CZNC::DestroyInstance(); } + IRCTest() { + CDebug::SetDebug(false); + CZNC::CreateInstance(); + } + ~IRCTest() { CZNC::DestroyInstance(); } - void SetUp() { - m_pTestUser = new CUser("user"); - m_pTestNetwork = new CIRCNetwork(m_pTestUser, "network"); - m_pTestChan = new CChan("#chan", m_pTestNetwork, false); - m_pTestSock = new TestIRCSock(m_pTestNetwork); - m_pTestClient = new TestClient; - m_pTestModule = new TestModule; + void SetUp() { + m_pTestUser = new CUser("user"); + m_pTestNetwork = new CIRCNetwork(m_pTestUser, "network"); + m_pTestChan = new CChan("#chan", m_pTestNetwork, false); + m_pTestSock = new TestIRCSock(m_pTestNetwork); + m_pTestClient = new TestClient; + m_pTestModule = new TestModule; - m_pTestUser->AddNetwork(m_pTestNetwork); - m_pTestNetwork->AddChan(m_pTestChan); - m_pTestChan->AddNick("nick"); - m_pTestClient->AcceptLogin(*m_pTestUser); - m_pTestClient->vsLines - .clear(); // :irc.znc.in 001 me :- Welcome to ZNC - - CZNC::Get().GetModules().push_back(m_pTestModule); - } + m_pTestUser->AddNetwork(m_pTestNetwork); + m_pTestNetwork->AddChan(m_pTestChan); + m_pTestChan->AddNick("nick"); + m_pTestClient->AcceptLogin(*m_pTestUser); + m_pTestClient->vsLines + .clear(); // :irc.znc.in 001 me :- Welcome to ZNC - + CZNC::Get().GetModules().push_back(m_pTestModule); + } - void TearDown() { - m_pTestUser->RemoveNetwork(m_pTestNetwork); - m_pTestNetwork->ClientDisconnected(m_pTestClient); - CZNC::Get().GetModules().clear(); + void TearDown() { + m_pTestUser->RemoveNetwork(m_pTestNetwork); + m_pTestNetwork->ClientDisconnected(m_pTestClient); + CZNC::Get().GetModules().clear(); - delete m_pTestClient; - delete m_pTestSock; - delete m_pTestNetwork; - delete m_pTestUser; - delete m_pTestModule; - } + delete m_pTestClient; + delete m_pTestSock; + delete m_pTestNetwork; + delete m_pTestUser; + delete m_pTestModule; + } - CUser* m_pTestUser; - CIRCNetwork* m_pTestNetwork; - CChan* m_pTestChan; - TestIRCSock* m_pTestSock; - TestClient* m_pTestClient; - TestModule* m_pTestModule; + CUser* m_pTestUser; + CIRCNetwork* m_pTestNetwork; + CChan* m_pTestChan; + TestIRCSock* m_pTestSock; + TestClient* m_pTestClient; + TestModule* m_pTestModule; }; #endif // IRCTEST_H diff --git a/test/Integration.cpp b/test/Integration.cpp index 025deacd..fc64abbc 100644 --- a/test/Integration.cpp +++ b/test/Integration.cpp @@ -34,12 +34,12 @@ #include #define Z \ - do { \ - if (::testing::Test::HasFatalFailure()) { \ - std::cerr << "At: " << __FILE__ << ":" << __LINE__ << std::endl; \ - return; \ - } \ - } while (0) + do { \ + if (::testing::Test::HasFatalFailure()) { \ + std::cerr << "At: " << __FILE__ << ":" << __LINE__ << std::endl; \ + return; \ + } \ + } while (0) using testing::HasSubstr; @@ -48,1668 +48,1668 @@ namespace { template class IO { public: - IO(Device* device, bool verbose = false) - : m_device(device), m_verbose(verbose) {} - virtual ~IO() {} - void ReadUntil(QByteArray pattern) { - auto deadline = QDateTime::currentDateTime().addSecs(30); - while (true) { - int search = m_readed.indexOf(pattern); - if (search != -1) { - m_readed.remove(0, search + pattern.length()); - return; - } - if (m_readed.length() > pattern.length()) { - m_readed = m_readed.right(pattern.length()); - } - const int timeout_ms = - QDateTime::currentDateTime().msecsTo(deadline); - ASSERT_GT(timeout_ms, 0) << "Wanted:" << pattern.toStdString(); - ASSERT_TRUE(m_device->waitForReadyRead(timeout_ms)) - << "Wanted: " << pattern.toStdString(); - QByteArray chunk = m_device->readAll(); - if (m_verbose) { - std::cout << chunk.toStdString() << std::flush; - } - m_readed += chunk; - } - } - void Write(QString s = "", bool new_line = true) { - if (!m_device) return; - if (m_verbose) { - std::cout << s.toStdString() << std::flush; - if (new_line) { - std::cout << std::endl; - } - } - s += "\n"; - { - QTextStream str(m_device); - str << s; - } - FlushIfCan(m_device); - } - void Close() { + IO(Device* device, bool verbose = false) + : m_device(device), m_verbose(verbose) {} + virtual ~IO() {} + void ReadUntil(QByteArray pattern) { + auto deadline = QDateTime::currentDateTime().addSecs(30); + while (true) { + int search = m_readed.indexOf(pattern); + if (search != -1) { + m_readed.remove(0, search + pattern.length()); + return; + } + if (m_readed.length() > pattern.length()) { + m_readed = m_readed.right(pattern.length()); + } + const int timeout_ms = + QDateTime::currentDateTime().msecsTo(deadline); + ASSERT_GT(timeout_ms, 0) << "Wanted:" << pattern.toStdString(); + ASSERT_TRUE(m_device->waitForReadyRead(timeout_ms)) + << "Wanted: " << pattern.toStdString(); + QByteArray chunk = m_device->readAll(); + if (m_verbose) { + std::cout << chunk.toStdString() << std::flush; + } + m_readed += chunk; + } + } + void Write(QString s = "", bool new_line = true) { + if (!m_device) return; + if (m_verbose) { + std::cout << s.toStdString() << std::flush; + if (new_line) { + std::cout << std::endl; + } + } + s += "\n"; + { + QTextStream str(m_device); + str << s; + } + FlushIfCan(m_device); + } + void Close() { #ifdef __CYGWIN__ #ifdef __x86_64__ - // Qt on cygwin64 silently doesn't send the rest of buffer from socket - // without this line - sleep(1); + // Qt on cygwin64 silently doesn't send the rest of buffer from socket + // without this line + sleep(1); #endif #endif - m_device->disconnectFromHost(); - } + m_device->disconnectFromHost(); + } private: - // QTextStream doesn't flush QTcpSocket, and QIODevice doesn't have flush() - // at all... - static void FlushIfCan(QIODevice*) {} - static void FlushIfCan(QTcpSocket* sock) { sock->flush(); } + // QTextStream doesn't flush QTcpSocket, and QIODevice doesn't have flush() + // at all... + static void FlushIfCan(QIODevice*) {} + static void FlushIfCan(QTcpSocket* sock) { sock->flush(); } - Device* m_device; - bool m_verbose; - QByteArray m_readed; + Device* m_device; + bool m_verbose; + QByteArray m_readed; }; template IO WrapIO(Device* d) { - return IO(d); + return IO(d); } using Socket = IO; class Process : public IO { public: - Process(QString cmd, QStringList args, bool interactive) - : IO(&m_proc, true) { - if (!interactive) { - m_proc.setProcessChannelMode(QProcess::ForwardedChannels); - } - auto env = QProcessEnvironment::systemEnvironment(); - // Default exit codes of sanitizers upon error: - // ASAN - 1 - // LSAN - 23 (part of ASAN, but uses a different value) - // TSAN - 66 - // - // ZNC uses 1 too to report startup failure. - // But we don't want to confuse expected starup failure with ASAN error. - env.insert("ASAN_OPTIONS", "exitcode=57"); - m_proc.setProcessEnvironment(env); - m_proc.start(cmd, args); - } - ~Process() { - if (m_kill) m_proc.terminate(); - [this]() { - ASSERT_TRUE(m_proc.waitForFinished()); - if (!m_allowDie) { - ASSERT_EQ(QProcess::NormalExit, m_proc.exitStatus()); - ASSERT_EQ(m_exit, m_proc.exitCode()); - } - }(); - } - void ShouldFinishItself(int code = 0) { - m_kill = false; - m_exit = code; - } - void CanDie() { m_allowDie = true; } + Process(QString cmd, QStringList args, bool interactive) + : IO(&m_proc, true) { + if (!interactive) { + m_proc.setProcessChannelMode(QProcess::ForwardedChannels); + } + auto env = QProcessEnvironment::systemEnvironment(); + // Default exit codes of sanitizers upon error: + // ASAN - 1 + // LSAN - 23 (part of ASAN, but uses a different value) + // TSAN - 66 + // + // ZNC uses 1 too to report startup failure. + // But we don't want to confuse expected starup failure with ASAN error. + env.insert("ASAN_OPTIONS", "exitcode=57"); + m_proc.setProcessEnvironment(env); + m_proc.start(cmd, args); + } + ~Process() { + if (m_kill) m_proc.terminate(); + [this]() { + ASSERT_TRUE(m_proc.waitForFinished()); + if (!m_allowDie) { + ASSERT_EQ(QProcess::NormalExit, m_proc.exitStatus()); + ASSERT_EQ(m_exit, m_proc.exitCode()); + } + }(); + } + void ShouldFinishItself(int code = 0) { + m_kill = false; + m_exit = code; + } + void CanDie() { m_allowDie = true; } private: - bool m_kill = true; - int m_exit = 0; - bool m_allowDie = false; - QProcess m_proc; + bool m_kill = true; + int m_exit = 0; + bool m_allowDie = false; + QProcess m_proc; }; void WriteConfig(QString path) { - // clang-format off - Process p("./znc", QStringList() << "--debug" << "--datadir" << path << "--makeconf", true); - p.ReadUntil("Listen on port");Z; p.Write("12345"); - p.ReadUntil("Listen using SSL");Z; p.Write(); - p.ReadUntil("IPv6");Z; p.Write(); - p.ReadUntil("Username");Z; p.Write("user"); - p.ReadUntil("password");Z; p.Write("hunter2", false); - p.ReadUntil("Confirm");Z; p.Write("hunter2", false); - p.ReadUntil("Nick [user]");Z; p.Write(); - p.ReadUntil("Alternate nick [user_]");Z; p.Write(); - p.ReadUntil("Ident [user]");Z; p.Write(); - p.ReadUntil("Real name");Z; p.Write(); - p.ReadUntil("Bind host");Z; p.Write(); - p.ReadUntil("Set up a network?");Z; p.Write(); - p.ReadUntil("Name [freenode]");Z; p.Write("test"); - p.ReadUntil("Server host (host only)");Z; p.Write("127.0.0.1"); - p.ReadUntil("Server uses SSL?");Z; p.Write(); - p.ReadUntil("6667");Z; p.Write(); - p.ReadUntil("password");Z; p.Write(); - p.ReadUntil("channels");Z; p.Write(); - p.ReadUntil("Launch ZNC now?");Z; p.Write("no"); - p.ShouldFinishItself(); - // clang-format on + // clang-format off + Process p("./znc", QStringList() << "--debug" << "--datadir" << path << "--makeconf", true); + p.ReadUntil("Listen on port");Z; p.Write("12345"); + p.ReadUntil("Listen using SSL");Z; p.Write(); + p.ReadUntil("IPv6");Z; p.Write(); + p.ReadUntil("Username");Z; p.Write("user"); + p.ReadUntil("password");Z; p.Write("hunter2", false); + p.ReadUntil("Confirm");Z; p.Write("hunter2", false); + p.ReadUntil("Nick [user]");Z; p.Write(); + p.ReadUntil("Alternate nick [user_]");Z; p.Write(); + p.ReadUntil("Ident [user]");Z; p.Write(); + p.ReadUntil("Real name");Z; p.Write(); + p.ReadUntil("Bind host");Z; p.Write(); + p.ReadUntil("Set up a network?");Z; p.Write(); + p.ReadUntil("Name [freenode]");Z; p.Write("test"); + p.ReadUntil("Server host (host only)");Z; p.Write("127.0.0.1"); + p.ReadUntil("Server uses SSL?");Z; p.Write(); + p.ReadUntil("6667");Z; p.Write(); + p.ReadUntil("password");Z; p.Write(); + p.ReadUntil("channels");Z; p.Write(); + p.ReadUntil("Launch ZNC now?");Z; p.Write("no"); + p.ShouldFinishItself(); + // clang-format on } TEST(Config, AlreadyExists) { - QTemporaryDir dir; - WriteConfig(dir.path()); - Z; - Process p("./znc", QStringList() << "--debug" - << "--datadir" << dir.path() - << "--makeconf", - true); - p.ReadUntil("already exists"); - Z; - p.CanDie(); + QTemporaryDir dir; + WriteConfig(dir.path()); + Z; + Process p("./znc", QStringList() << "--debug" + << "--datadir" << dir.path() + << "--makeconf", + true); + p.ReadUntil("already exists"); + Z; + p.CanDie(); } // Can't use QEventLoop without existing QCoreApplication class App { public: - App() : m_argv(new char{}), m_app(m_argc, &m_argv) {} - ~App() { delete m_argv; } + App() : m_argv(new char{}), m_app(m_argc, &m_argv) {} + ~App() { delete m_argv; } private: - int m_argc = 1; - char* m_argv; - QCoreApplication m_app; + int m_argc = 1; + char* m_argv; + QCoreApplication m_app; }; class ZNCTest : public testing::Test { protected: - void SetUp() override { - WriteConfig(m_dir.path()); - Z; - ASSERT_TRUE(m_server.listen(QHostAddress::LocalHost, 6667)) - << m_server.errorString().toStdString(); - Z; - } + void SetUp() override { + WriteConfig(m_dir.path()); + Z; + ASSERT_TRUE(m_server.listen(QHostAddress::LocalHost, 6667)) + << m_server.errorString().toStdString(); + Z; + } - Socket ConnectIRCd() { - [this] { - ASSERT_TRUE(m_server.waitForNewConnection(30000 /* msec */)); - }(); - return WrapIO(m_server.nextPendingConnection()); - } + Socket ConnectIRCd() { + [this] { + ASSERT_TRUE(m_server.waitForNewConnection(30000 /* msec */)); + }(); + return WrapIO(m_server.nextPendingConnection()); + } - Socket ConnectClient() { - m_clients.emplace_back(); - QTcpSocket& sock = m_clients.back(); - sock.connectToHost("127.0.0.1", 12345); - [&] { - ASSERT_TRUE(sock.waitForConnected()) - << sock.errorString().toStdString(); - }(); - return WrapIO(&sock); - } + Socket ConnectClient() { + m_clients.emplace_back(); + QTcpSocket& sock = m_clients.back(); + sock.connectToHost("127.0.0.1", 12345); + [&] { + ASSERT_TRUE(sock.waitForConnected()) + << sock.errorString().toStdString(); + }(); + return WrapIO(&sock); + } - std::unique_ptr Run() { - return std::unique_ptr( - new Process("./znc", QStringList() << "--debug" - << "--datadir" << m_dir.path(), - false)); - } + std::unique_ptr Run() { + return std::unique_ptr( + new Process("./znc", QStringList() << "--debug" + << "--datadir" << m_dir.path(), + false)); + } - Socket LoginClient() { - auto client = ConnectClient(); - client.Write("PASS :hunter2"); - client.Write("NICK nick"); - client.Write("USER user/test x x :x"); - return client; - } + Socket LoginClient() { + auto client = ConnectClient(); + client.Write("PASS :hunter2"); + client.Write("NICK nick"); + client.Write("USER user/test x x :x"); + return client; + } - std::unique_ptr HttpGet(QNetworkRequest request) { - return HandleHttp(m_network.get(request)); - } - std::unique_ptr HttpPost( - QNetworkRequest request, QList> data) { - request.setHeader(QNetworkRequest::ContentTypeHeader, - "application/x-www-form-urlencoded"); - QUrlQuery q; - q.setQueryItems(data); - return HandleHttp(m_network.post(request, q.toString().toUtf8())); - } - std::unique_ptr HandleHttp(QNetworkReply* reply) { - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, - [&]() { loop.quit(); }); - QObject::connect( - reply, - static_cast( - &QNetworkReply::error), - [&](QNetworkReply::NetworkError e) { - ADD_FAILURE() << reply->errorString().toStdString(); - }); - QTimer::singleShot(30000 /* msec */, &loop, [&]() { - ADD_FAILURE() << "connection timeout"; - loop.quit(); - }); - loop.exec(); - return std::unique_ptr(reply); - } + std::unique_ptr HttpGet(QNetworkRequest request) { + return HandleHttp(m_network.get(request)); + } + std::unique_ptr HttpPost( + QNetworkRequest request, QList> data) { + request.setHeader(QNetworkRequest::ContentTypeHeader, + "application/x-www-form-urlencoded"); + QUrlQuery q; + q.setQueryItems(data); + return HandleHttp(m_network.post(request, q.toString().toUtf8())); + } + std::unique_ptr HandleHttp(QNetworkReply* reply) { + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, + [&]() { loop.quit(); }); + QObject::connect( + reply, + static_cast( + &QNetworkReply::error), + [&](QNetworkReply::NetworkError e) { + ADD_FAILURE() << reply->errorString().toStdString(); + }); + QTimer::singleShot(30000 /* msec */, &loop, [&]() { + ADD_FAILURE() << "connection timeout"; + loop.quit(); + }); + loop.exec(); + return std::unique_ptr(reply); + } - App m_app; - QNetworkAccessManager m_network; - QTemporaryDir m_dir; - QTcpServer m_server; - std::list m_clients; + App m_app; + QNetworkAccessManager m_network; + QTemporaryDir m_dir; + QTcpServer m_server; + std::list m_clients; }; TEST_F(ZNCTest, Connect) { - auto znc = Run(); - Z; + auto znc = Run(); + Z; - auto ircd = ConnectIRCd(); - Z; - ircd.ReadUntil("CAP LS"); - Z; + auto ircd = ConnectIRCd(); + Z; + ircd.ReadUntil("CAP LS"); + Z; - auto client = ConnectClient(); - Z; - client.Write("PASS :hunter2"); - client.Write("NICK nick"); - client.Write("USER user/test x x :x"); - client.ReadUntil("Welcome"); - Z; - client.Close(); + auto client = ConnectClient(); + Z; + client.Write("PASS :hunter2"); + client.Write("NICK nick"); + client.Write("USER user/test x x :x"); + client.ReadUntil("Welcome"); + Z; + client.Close(); - client = ConnectClient(); - Z; - client.Write("PASS :user:hunter2"); - client.Write("NICK nick"); - client.Write("USER u x x x"); - client.ReadUntil("Welcome"); - Z; - client.Close(); + client = ConnectClient(); + Z; + client.Write("PASS :user:hunter2"); + client.Write("NICK nick"); + client.Write("USER u x x x"); + client.ReadUntil("Welcome"); + Z; + client.Close(); - client = ConnectClient(); - Z; - client.Write("NICK nick"); - client.Write("USER user x x x"); - client.ReadUntil("Configure your client to send a server password"); - client.Close(); + client = ConnectClient(); + Z; + client.Write("NICK nick"); + client.Write("USER user x x x"); + client.ReadUntil("Configure your client to send a server password"); + client.Close(); - ircd.Write(":server 001 nick :Hello"); - ircd.ReadUntil("WHO"); - Z; + ircd.Write(":server 001 nick :Hello"); + ircd.ReadUntil("WHO"); + Z; } TEST_F(ZNCTest, Channel) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; - auto client = LoginClient(); - Z; - client.ReadUntil("Welcome"); - Z; - client.Write("JOIN #znc"); - client.Close(); + auto client = LoginClient(); + Z; + client.ReadUntil("Welcome"); + Z; + client.Write("JOIN #znc"); + client.Close(); - ircd.Write(":server 001 nick :Hello"); - ircd.ReadUntil("JOIN #znc"); - Z; - ircd.Write(":nick JOIN :#znc"); - ircd.Write(":server 353 nick #znc :nick"); - ircd.Write(":server 366 nick #znc :End of /NAMES list"); - ircd.Write(":server PING :1"); - ircd.ReadUntil("PONG 1"); + ircd.Write(":server 001 nick :Hello"); + ircd.ReadUntil("JOIN #znc"); + Z; + ircd.Write(":nick JOIN :#znc"); + ircd.Write(":server 353 nick #znc :nick"); + ircd.Write(":server 366 nick #znc :End of /NAMES list"); + ircd.Write(":server PING :1"); + ircd.ReadUntil("PONG 1"); - client = LoginClient(); - Z; - client.ReadUntil(":nick JOIN :#znc"); - Z; + client = LoginClient(); + Z; + client.ReadUntil(":nick JOIN :#znc"); + Z; } TEST_F(ZNCTest, HTTP) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - auto reply = HttpGet(QNetworkRequest(QUrl("http://127.0.0.1:12345/"))); - Z; - EXPECT_THAT(reply->rawHeader("Server").toStdString(), HasSubstr("ZNC")); + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto reply = HttpGet(QNetworkRequest(QUrl("http://127.0.0.1:12345/"))); + Z; + EXPECT_THAT(reply->rawHeader("Server").toStdString(), HasSubstr("ZNC")); } TEST_F(ZNCTest, FixCVE20149403) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - ircd.Write(":server 001 nick :Hello"); - ircd.Write(":server 005 nick CHANTYPES=# :supports"); - ircd.Write(":server PING :1"); - ircd.ReadUntil("PONG 1"); - Z; + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + ircd.Write(":server 001 nick :Hello"); + ircd.Write(":server 005 nick CHANTYPES=# :supports"); + ircd.Write(":server PING :1"); + ircd.ReadUntil("PONG 1"); + Z; - QNetworkRequest request; - request.setRawHeader("Authorization", - "Basic " + QByteArray("user:hunter2").toBase64()); - request.setUrl(QUrl("http://127.0.0.1:12345/mods/global/webadmin/addchan")); - HttpPost(request, { - {"user", "user"}, - {"network", "test"}, - {"submitted", "1"}, - {"name", "znc"}, - }); - ircd.ReadUntil("JOIN #znc"); - Z; - EXPECT_THAT(HttpPost(request, - { - {"user", "user"}, - {"network", "test"}, - {"submitted", "1"}, - {"name", "znc"}, - }) - ->readAll() - .toStdString(), - HasSubstr("Channel [#znc] already exists")); + QNetworkRequest request; + request.setRawHeader("Authorization", + "Basic " + QByteArray("user:hunter2").toBase64()); + request.setUrl(QUrl("http://127.0.0.1:12345/mods/global/webadmin/addchan")); + HttpPost(request, { + {"user", "user"}, + {"network", "test"}, + {"submitted", "1"}, + {"name", "znc"}, + }); + ircd.ReadUntil("JOIN #znc"); + Z; + EXPECT_THAT(HttpPost(request, + { + {"user", "user"}, + {"network", "test"}, + {"submitted", "1"}, + {"name", "znc"}, + }) + ->readAll() + .toStdString(), + HasSubstr("Channel [#znc] already exists")); } TEST_F(ZNCTest, FixFixOfCVE20149403) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - ircd.Write(":server 001 nick :Hello"); - ircd.Write(":nick JOIN @#znc"); - ircd.ReadUntil("MODE @#znc"); - Z; - ircd.Write(":server 005 nick STATUSMSG=@ :supports"); - ircd.Write(":server PING :12345"); - ircd.ReadUntil("PONG 12345"); - Z; + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + ircd.Write(":server 001 nick :Hello"); + ircd.Write(":nick JOIN @#znc"); + ircd.ReadUntil("MODE @#znc"); + Z; + ircd.Write(":server 005 nick STATUSMSG=@ :supports"); + ircd.Write(":server PING :12345"); + ircd.ReadUntil("PONG 12345"); + Z; - QNetworkRequest request; - request.setRawHeader("Authorization", - "Basic " + QByteArray("user:hunter2").toBase64()); - request.setUrl(QUrl("http://127.0.0.1:12345/mods/global/webadmin/addchan")); - auto reply = HttpPost(request, { - {"user", "user"}, - {"network", "test"}, - {"submitted", "1"}, - {"name", "@#znc"}, - }); - EXPECT_THAT(reply->readAll().toStdString(), - HasSubstr("Could not add channel [@#znc]")); + QNetworkRequest request; + request.setRawHeader("Authorization", + "Basic " + QByteArray("user:hunter2").toBase64()); + request.setUrl(QUrl("http://127.0.0.1:12345/mods/global/webadmin/addchan")); + auto reply = HttpPost(request, { + {"user", "user"}, + {"network", "test"}, + {"submitted", "1"}, + {"name", "@#znc"}, + }); + EXPECT_THAT(reply->readAll().toStdString(), + HasSubstr("Could not add channel [@#znc]")); } TEST_F(ZNCTest, InvalidConfigInChan) { - QFile conf(m_dir.path() + "/configs/znc.conf"); - ASSERT_TRUE(conf.open(QIODevice::Append | QIODevice::Text)); - QTextStream out(&conf); - out << R"( - - - - Invalid = Line - - - - )"; - out.flush(); - auto znc = Run(); - Z; - znc->ShouldFinishItself(1); + QFile conf(m_dir.path() + "/configs/znc.conf"); + ASSERT_TRUE(conf.open(QIODevice::Append | QIODevice::Text)); + QTextStream out(&conf); + out << R"( + + + + Invalid = Line + + + + )"; + out.flush(); + auto znc = Run(); + Z; + znc->ShouldFinishItself(1); } TEST_F(ZNCTest, ControlpanelModule) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - auto client = LoginClient(); - Z; - - const QString request = "PRIVMSG *controlpanel :"; - const QByteArray response = ":*controlpanel!znc@znc.in PRIVMSG nick :"; - - // TODO: Figure out how to check for "HAVE_ICU" to test encoding. - // TODO: Test the CTCP VERSION. - - // 1. Test everything on "user". - // 2. Test everything on another user "KindOne" from "user". - // 3. Test one thing on "foobar" as the user does not exist from "user". - - // Add myself so I can test other things along with "user". - client.Write(request + "AddUser KindOne hunter2"); - client.ReadUntil(response + "User [KindOne] added!"); - Z; - - client.Write(request + "AddUser KindOne hunter2"); - client.ReadUntil(response + "Error: User [KindOne] already exists!"); - Z; - - client.Write(request + "AddCTCP user VERSION Test"); - client.ReadUntil(response + "Added!"); - Z; - - client.Write(request + "AddNetwork user freenode"); - client.ReadUntil(response + "Network [freenode] added for user [user]."); - Z; - - client.Write(request + "AddServer user freenode 127.0.0.1 6667"); - client.ReadUntil(response + - "Added IRC Server [127.0.0.1 6667] for network [freenode] " - "for user [user]."); - Z; - - client.Write(request + "AddChan user freenode #znc"); - client.ReadUntil(response + "Channel [#znc] for user [user] added."); - Z; - - client.Write(request + "AddChan user freenode #znc"); - client.ReadUntil(response + - "Error: [user] already has a channel named [#znc]."); - Z; - - client.Write(request + "AddUser user hunter2"); - client.ReadUntil(response + "Error: User [user] already exists!"); - Z; - - client.Write(request + "CloneUser user user_clone"); - client.ReadUntil(response + "User [user_clone] added!"); - Z; - - client.Write(request + "CloneUser user user_clone"); - client.ReadUntil(response + "Error: User not added! [User already exists]"); - Z; - - client.Write(request + "DelCTCP user VERSION"); - client.ReadUntil(response + - "Successfully removed [VERSION] for user [user]."); - Z; - - client.Write(request + "DelCTCP user VERSION"); - client.ReadUntil(response + "Error: [VERSION] not found for user [user]!"); - Z; - - client.Write(request + "DelChan user freenode #znc"); - client.ReadUntil(response + "Channel(s) [#znc] for user [user] deleted."); - Z; - - client.Write(request + "DelChan user freenode #znc"); - client.ReadUntil( - response + - "Error: User [user] does not have any channel matching [#znc]."); - Z; - - client.Write(request + "DelNetwork freenode"); - client.ReadUntil(response + "Network [freenode] deleted on user [user]."); - Z; - - client.Write(request + "DelNetwork freenode"); - client.ReadUntil(response + - "Error: [user] does not have a network named [freenode]."); - Z; - - client.Write(request + "AddNetwork user freenode"); - client.ReadUntil(response + "Network [freenode] added for user [user]."); - Z; - - client.Write(request + "AddChan user freenode #znc"); - client.ReadUntil(response + "Channel [#znc] for user [user] added."); - Z; - - client.Write(request + "DelUser user_clone"); - client.ReadUntil(response + "User [user_clone] deleted!"); - Z; - - client.Write(request + "DelUser user_clone"); - client.ReadUntil(response + "Error: User [user_clone] does not exist!"); - Z; - - client.Write(request + "Disconnect user freenode"); - client.ReadUntil( - response + - "Closed IRC connection for network [freenode] on user [user]."); - Z; - - client.Write(request + "Disconnect user EFnet"); - client.ReadUntil(response + - "Error: [user] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Get Nick"); - client.ReadUntil(response + "Nick = user"); - Z; - - client.Write(request + "Get Altnick"); - client.ReadUntil(response + "AltNick = user_"); - Z; - - client.Write(request + "Get Ident"); - client.ReadUntil(response + "Ident = user"); - Z; - - client.Write(request + "Get RealName"); - client.ReadUntil(response + "RealName = ZNC"); - Z; - - client.Write(request + "Get BindHost"); - client.ReadUntil(response + "BindHost = "); - Z; - - client.Write(request + "Get DefaultChanModes"); - client.ReadUntil(response + "DefaultChanModes = "); - Z; - - client.Write(request + "Get QuitMsg"); - client.ReadUntil(response + "QuitMsg = "); - Z; - - client.Write(request + "Get Password"); - client.ReadUntil(response + "Error: Unknown variable"); - Z; - - client.Write(request + "Get Timezone"); - client.ReadUntil(response + "Timezone = "); - Z; - - client.Write(request + "Get TimestampFormat"); - client.ReadUntil(response + "TimestampFormat = "); - Z; - - client.Write(request + "Get DCCBindHost"); - client.ReadUntil(response + "DCCBindHost = "); - Z; - - client.Write(request + "Get StatusPrefix"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "Get BufferCount"); - client.ReadUntil(response + "BufferCount = 50"); - Z; - - client.Write(request + "Get JoinTries"); - client.ReadUntil(response + "JoinTries = "); - Z; - - client.Write(request + "Get MaxJoins"); - client.ReadUntil(response + "MaxJoins = "); - Z; - - client.Write(request + "Get MaxNetworks"); - client.ReadUntil(response + "MaxNetworks = "); - Z; + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto client = LoginClient(); + Z; + + const QString request = "PRIVMSG *controlpanel :"; + const QByteArray response = ":*controlpanel!znc@znc.in PRIVMSG nick :"; + + // TODO: Figure out how to check for "HAVE_ICU" to test encoding. + // TODO: Test the CTCP VERSION. + + // 1. Test everything on "user". + // 2. Test everything on another user "KindOne" from "user". + // 3. Test one thing on "foobar" as the user does not exist from "user". + + // Add myself so I can test other things along with "user". + client.Write(request + "AddUser KindOne hunter2"); + client.ReadUntil(response + "User [KindOne] added!"); + Z; + + client.Write(request + "AddUser KindOne hunter2"); + client.ReadUntil(response + "Error: User [KindOne] already exists!"); + Z; + + client.Write(request + "AddCTCP user VERSION Test"); + client.ReadUntil(response + "Added!"); + Z; + + client.Write(request + "AddNetwork user freenode"); + client.ReadUntil(response + "Network [freenode] added for user [user]."); + Z; + + client.Write(request + "AddServer user freenode 127.0.0.1 6667"); + client.ReadUntil(response + + "Added IRC Server [127.0.0.1 6667] for network [freenode] " + "for user [user]."); + Z; + + client.Write(request + "AddChan user freenode #znc"); + client.ReadUntil(response + "Channel [#znc] for user [user] added."); + Z; + + client.Write(request + "AddChan user freenode #znc"); + client.ReadUntil(response + + "Error: [user] already has a channel named [#znc]."); + Z; + + client.Write(request + "AddUser user hunter2"); + client.ReadUntil(response + "Error: User [user] already exists!"); + Z; + + client.Write(request + "CloneUser user user_clone"); + client.ReadUntil(response + "User [user_clone] added!"); + Z; + + client.Write(request + "CloneUser user user_clone"); + client.ReadUntil(response + "Error: User not added! [User already exists]"); + Z; + + client.Write(request + "DelCTCP user VERSION"); + client.ReadUntil(response + + "Successfully removed [VERSION] for user [user]."); + Z; + + client.Write(request + "DelCTCP user VERSION"); + client.ReadUntil(response + "Error: [VERSION] not found for user [user]!"); + Z; + + client.Write(request + "DelChan user freenode #znc"); + client.ReadUntil(response + "Channel(s) [#znc] for user [user] deleted."); + Z; + + client.Write(request + "DelChan user freenode #znc"); + client.ReadUntil( + response + + "Error: User [user] does not have any channel matching [#znc]."); + Z; + + client.Write(request + "DelNetwork freenode"); + client.ReadUntil(response + "Network [freenode] deleted on user [user]."); + Z; + + client.Write(request + "DelNetwork freenode"); + client.ReadUntil(response + + "Error: [user] does not have a network named [freenode]."); + Z; + + client.Write(request + "AddNetwork user freenode"); + client.ReadUntil(response + "Network [freenode] added for user [user]."); + Z; + + client.Write(request + "AddChan user freenode #znc"); + client.ReadUntil(response + "Channel [#znc] for user [user] added."); + Z; + + client.Write(request + "DelUser user_clone"); + client.ReadUntil(response + "User [user_clone] deleted!"); + Z; + + client.Write(request + "DelUser user_clone"); + client.ReadUntil(response + "Error: User [user_clone] does not exist!"); + Z; + + client.Write(request + "Disconnect user freenode"); + client.ReadUntil( + response + + "Closed IRC connection for network [freenode] on user [user]."); + Z; + + client.Write(request + "Disconnect user EFnet"); + client.ReadUntil(response + + "Error: [user] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Get Nick"); + client.ReadUntil(response + "Nick = user"); + Z; + + client.Write(request + "Get Altnick"); + client.ReadUntil(response + "AltNick = user_"); + Z; + + client.Write(request + "Get Ident"); + client.ReadUntil(response + "Ident = user"); + Z; + + client.Write(request + "Get RealName"); + client.ReadUntil(response + "RealName = ZNC"); + Z; + + client.Write(request + "Get BindHost"); + client.ReadUntil(response + "BindHost = "); + Z; + + client.Write(request + "Get DefaultChanModes"); + client.ReadUntil(response + "DefaultChanModes = "); + Z; + + client.Write(request + "Get QuitMsg"); + client.ReadUntil(response + "QuitMsg = "); + Z; + + client.Write(request + "Get Password"); + client.ReadUntil(response + "Error: Unknown variable"); + Z; + + client.Write(request + "Get Timezone"); + client.ReadUntil(response + "Timezone = "); + Z; + + client.Write(request + "Get TimestampFormat"); + client.ReadUntil(response + "TimestampFormat = "); + Z; + + client.Write(request + "Get DCCBindHost"); + client.ReadUntil(response + "DCCBindHost = "); + Z; + + client.Write(request + "Get StatusPrefix"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "Get BufferCount"); + client.ReadUntil(response + "BufferCount = 50"); + Z; + + client.Write(request + "Get JoinTries"); + client.ReadUntil(response + "JoinTries = "); + Z; + + client.Write(request + "Get MaxJoins"); + client.ReadUntil(response + "MaxJoins = "); + Z; + + client.Write(request + "Get MaxNetworks"); + client.ReadUntil(response + "MaxNetworks = "); + Z; - client.Write(request + "Get MaxQueryBuffers"); - client.ReadUntil(response + "MaxQueryBuffers = "); - Z; + client.Write(request + "Get MaxQueryBuffers"); + client.ReadUntil(response + "MaxQueryBuffers = "); + Z; - client.Write(request + "Get Admin"); - client.ReadUntil(response + "Admin = true"); - Z; + client.Write(request + "Get Admin"); + client.ReadUntil(response + "Admin = true"); + Z; - client.Write(request + "Get AppendTimestamp"); - client.ReadUntil(response + "AppendTimestamp = false"); - Z; + client.Write(request + "Get AppendTimestamp"); + client.ReadUntil(response + "AppendTimestamp = false"); + Z; - client.Write(request + "Get AutoClearChanBuffer"); - client.ReadUntil(response + "AutoClearChanBuffer = true"); - Z; + client.Write(request + "Get AutoClearChanBuffer"); + client.ReadUntil(response + "AutoClearChanBuffer = true"); + Z; - client.Write(request + "Get AutoClearQueryBuffer"); - client.ReadUntil(response + "AutoClearQueryBuffer = true"); - Z; - - client.Write(request + "Get DenyLoadMod"); - client.ReadUntil(response + "DenyLoadMod = false"); - Z; - - client.Write(request + "Get DenySetBindHost"); - client.ReadUntil(response + "DenySetBindHost = false"); - Z; - - client.Write(request + "Get MultiClients"); - client.ReadUntil(response + "MultiClients = true"); - Z; - - client.Write(request + "Get PrependTimestamp"); - client.ReadUntil(response + "PrependTimestamp = true"); - Z; + client.Write(request + "Get AutoClearQueryBuffer"); + client.ReadUntil(response + "AutoClearQueryBuffer = true"); + Z; + + client.Write(request + "Get DenyLoadMod"); + client.ReadUntil(response + "DenyLoadMod = false"); + Z; + + client.Write(request + "Get DenySetBindHost"); + client.ReadUntil(response + "DenySetBindHost = false"); + Z; + + client.Write(request + "Get MultiClients"); + client.ReadUntil(response + "MultiClients = true"); + Z; + + client.Write(request + "Get PrependTimestamp"); + client.ReadUntil(response + "PrependTimestamp = true"); + Z; - client.Write(request + "GetChan DefModes user freenode #znc"); - client.ReadUntil(response + "#znc: DefModes = "); - Z; - - client.Write(request + "GetChan Key user freenode #znc"); - client.ReadUntil(response + "#znc: Key = "); - Z; - - client.Write(request + "GetChan BufferSize user freenode #znc"); - client.ReadUntil(response + "#znc: BufferSize = 50 (default)"); - Z; - - client.Write(request + "GetChan InConfig user freenode #znc"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; - - client.Write(request + "GetChan AutoClearChanBuffer user freenode #znc"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = true (default)"); - Z; - - client.Write(request + "GetChan Detached user freenode #znc"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; - - client.Write(request + "GetNetwork Nick user freenode"); - client.ReadUntil(response + "Nick = user"); - Z; - - client.Write(request + "GetNetwork Altnick user freenode"); - client.ReadUntil(response + "AltNick = user_"); - Z; - - client.Write(request + "GetNetwork Ident user freenode"); - client.ReadUntil(response + "Ident = user"); - Z; - - client.Write(request + "GetNetwork BindHost user freenode"); - client.ReadUntil(response + "BindHost = "); - Z; - - client.Write(request + "GetNetwork FloodRate user freenode"); - client.ReadUntil(response + "FloodRate = 1.00"); - Z; - - client.Write(request + "GetNetwork FloodBurst user freenode"); - client.ReadUntil(response + "FloodBurst = 4"); - Z; - - client.Write(request + "GetNetwork JoinDelay user freenode"); - client.ReadUntil(response + "JoinDelay = 0"); - Z; - - client.Write(request + "GetNetwork QuitMsg user freenode"); - client.ReadUntil(response + "QuitMsg = "); - Z; - - client.Write(request + "AddCTCP user VERSION Test"); - client.ReadUntil(response + "Added!"); - Z; - - client.Write(request + "ListCTCPs"); - client.ReadUntil(response + "Request: VERSION"); - Z; - - client.Write(request + "ListMods"); - client.ReadUntil(response + "Usage: ListMods "); - Z; - - client.Write(request + "ListNetMods"); - client.ReadUntil(response + "Usage: ListNetMods "); - Z; - - client.Write(request + "ListNetworks"); - client.ReadUntil(response + "Network: test"); - Z; - - client.Write(request + "ListUsers"); - client.ReadUntil(response + "Username: user"); - Z; - - client.Write(request + "LoadModule"); - client.ReadUntil(response + - "Usage: LoadModule [args]"); - Z; - - client.Write(request + "LoadModule user"); - client.ReadUntil(response + - "Usage: LoadModule [args]"); - Z; - - client.Write(request + "LoadModule user log"); - client.ReadUntil(response + "Loaded module [log]"); - Z; - - client.Write(request + "LoadModule user log"); - client.ReadUntil( - response + "Unable to load module [log] because it is already loaded"); - Z; - - client.Write(request + "LoadModule user autoop"); - client.ReadUntil(response + - "Unable to load module [autoop] [Module [autoop] does not " - "support module type [User]."); - Z; - - client.Write(request + "LoadNetModule user freenode log"); - client.ReadUntil(response + "Loaded module [log]"); - Z; - - client.Write(request + "LoadNetModule user freenode log"); - client.ReadUntil( - response + "Unable to load module [log] because it is already loaded"); - Z; - - client.Write(request + "LoadNetModule user EFnet log"); - client.ReadUntil(response + - "Error: [user] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Reconnect user freenode"); - client.ReadUntil( - response + - "Queued network [freenode] for user [user] for a reconnect."); - Z; - - client.Write(request + "Reconnect user EFnet"); - client.ReadUntil(response + - "Error: [user] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Set Nick user user1"); - client.ReadUntil(response + "Nick = user1"); - Z; - - client.Write(request + "Set Altnick user user_1"); - client.ReadUntil(response + "AltNick = user_1"); - Z; - - client.Write(request + "Set Ident user user1"); - client.ReadUntil(response + "Ident = user1"); - Z; - - client.Write(request + "Set RealName user lol"); - client.ReadUntil(response + "RealName = lol"); - Z; - - client.Write(request + "Set BindHost user 0.0.0.0"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; - - client.Write(request + "Set BindHost user 0.0.0.0"); - client.ReadUntil(response + "This bind host is already set!"); - Z; - - // Need to clear the bindhost for testing in the 'setnetwork'. - client.Write("PRIVMSG *status :ClearUserBindHost"); - client.ReadUntil( - ":*status!znc@znc.in PRIVMSG nick :Bind host cleared for your user."); - Z; - - client.Write(request + "Set DefaultChanModes user +znst"); - client.ReadUntil(response + "DefaultChanModes = +znst"); - Z; - - client.Write(request + "Set QuitMsg user Writing this took forever."); - client.ReadUntil(response + "QuitMsg = Writing this took forever"); - Z; - - client.Write(request + "Set Password user hunter2"); - client.ReadUntil(response + "Password has been changed!"); - Z; - - client.Write(request + "Set Timezone user America/New_York"); - client.ReadUntil(response + "Timezone = America/New_York"); - Z; - - client.Write(request + "Set TimestampFormat user [%H:%M]"); - client.ReadUntil(response + "TimestampFormat = [%H:%M]"); - Z; - - client.Write(request + "Set DCCBindHost user 0.0.0.0"); - client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); - Z; - - client.Write(request + "Set StatusPrefix user &"); - client.ReadUntil( - ":&controlpanel!znc@znc.in PRIVMSG nick :StatusPrefix = &"); - Z; - - client.Write("PRIVMSG &controlpanel :Set StatusPrefix user *"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "SetChan DefModes user freenode #znc ms"); - client.ReadUntil(response + "#znc: DefModes = ms"); - Z; - - client.Write(request + "SetChan Key user freenode #znc KindOneRules"); - client.ReadUntil(response + "#znc: Key = KindOneRules"); - Z; - - client.Write(request + "SetChan BufferSize user freenode #znc 9001"); - client.ReadUntil(response + "#znc: BufferSize = 9001"); - Z; - - client.Write(request + "SetChan InConfig user freenode #znc true"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; - - client.Write(request + - "SetChan AutoClearChanBuffer user freenode #znc false"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); - Z; - - client.Write(request + "SetChan Detached user freenode #znc false"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; - - client.Write(request + "SetNetwork Nick user freenode NotUser"); - client.ReadUntil(response + "Nick = NotUser"); - Z; - - client.Write(request + "SetNetwork Altnick user freenode NotUser_"); - client.ReadUntil(response + "AltNick = NotUser_"); - Z; - - client.Write(request + "SetNetwork Ident user freenode identd"); - client.ReadUntil(response + "Ident = identd"); - Z; + client.Write(request + "GetChan DefModes user freenode #znc"); + client.ReadUntil(response + "#znc: DefModes = "); + Z; + + client.Write(request + "GetChan Key user freenode #znc"); + client.ReadUntil(response + "#znc: Key = "); + Z; + + client.Write(request + "GetChan BufferSize user freenode #znc"); + client.ReadUntil(response + "#znc: BufferSize = 50 (default)"); + Z; + + client.Write(request + "GetChan InConfig user freenode #znc"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; + + client.Write(request + "GetChan AutoClearChanBuffer user freenode #znc"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = true (default)"); + Z; + + client.Write(request + "GetChan Detached user freenode #znc"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; + + client.Write(request + "GetNetwork Nick user freenode"); + client.ReadUntil(response + "Nick = user"); + Z; + + client.Write(request + "GetNetwork Altnick user freenode"); + client.ReadUntil(response + "AltNick = user_"); + Z; + + client.Write(request + "GetNetwork Ident user freenode"); + client.ReadUntil(response + "Ident = user"); + Z; + + client.Write(request + "GetNetwork BindHost user freenode"); + client.ReadUntil(response + "BindHost = "); + Z; + + client.Write(request + "GetNetwork FloodRate user freenode"); + client.ReadUntil(response + "FloodRate = 1.00"); + Z; + + client.Write(request + "GetNetwork FloodBurst user freenode"); + client.ReadUntil(response + "FloodBurst = 4"); + Z; + + client.Write(request + "GetNetwork JoinDelay user freenode"); + client.ReadUntil(response + "JoinDelay = 0"); + Z; + + client.Write(request + "GetNetwork QuitMsg user freenode"); + client.ReadUntil(response + "QuitMsg = "); + Z; + + client.Write(request + "AddCTCP user VERSION Test"); + client.ReadUntil(response + "Added!"); + Z; + + client.Write(request + "ListCTCPs"); + client.ReadUntil(response + "Request: VERSION"); + Z; + + client.Write(request + "ListMods"); + client.ReadUntil(response + "Usage: ListMods "); + Z; + + client.Write(request + "ListNetMods"); + client.ReadUntil(response + "Usage: ListNetMods "); + Z; + + client.Write(request + "ListNetworks"); + client.ReadUntil(response + "Network: test"); + Z; + + client.Write(request + "ListUsers"); + client.ReadUntil(response + "Username: user"); + Z; + + client.Write(request + "LoadModule"); + client.ReadUntil(response + + "Usage: LoadModule [args]"); + Z; + + client.Write(request + "LoadModule user"); + client.ReadUntil(response + + "Usage: LoadModule [args]"); + Z; + + client.Write(request + "LoadModule user log"); + client.ReadUntil(response + "Loaded module [log]"); + Z; + + client.Write(request + "LoadModule user log"); + client.ReadUntil( + response + "Unable to load module [log] because it is already loaded"); + Z; + + client.Write(request + "LoadModule user autoop"); + client.ReadUntil(response + + "Unable to load module [autoop] [Module [autoop] does not " + "support module type [User]."); + Z; + + client.Write(request + "LoadNetModule user freenode log"); + client.ReadUntil(response + "Loaded module [log]"); + Z; + + client.Write(request + "LoadNetModule user freenode log"); + client.ReadUntil( + response + "Unable to load module [log] because it is already loaded"); + Z; + + client.Write(request + "LoadNetModule user EFnet log"); + client.ReadUntil(response + + "Error: [user] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Reconnect user freenode"); + client.ReadUntil( + response + + "Queued network [freenode] for user [user] for a reconnect."); + Z; + + client.Write(request + "Reconnect user EFnet"); + client.ReadUntil(response + + "Error: [user] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Set Nick user user1"); + client.ReadUntil(response + "Nick = user1"); + Z; + + client.Write(request + "Set Altnick user user_1"); + client.ReadUntil(response + "AltNick = user_1"); + Z; + + client.Write(request + "Set Ident user user1"); + client.ReadUntil(response + "Ident = user1"); + Z; + + client.Write(request + "Set RealName user lol"); + client.ReadUntil(response + "RealName = lol"); + Z; + + client.Write(request + "Set BindHost user 0.0.0.0"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; + + client.Write(request + "Set BindHost user 0.0.0.0"); + client.ReadUntil(response + "This bind host is already set!"); + Z; + + // Need to clear the bindhost for testing in the 'setnetwork'. + client.Write("PRIVMSG *status :ClearUserBindHost"); + client.ReadUntil( + ":*status!znc@znc.in PRIVMSG nick :Bind host cleared for your user."); + Z; + + client.Write(request + "Set DefaultChanModes user +znst"); + client.ReadUntil(response + "DefaultChanModes = +znst"); + Z; + + client.Write(request + "Set QuitMsg user Writing this took forever."); + client.ReadUntil(response + "QuitMsg = Writing this took forever"); + Z; + + client.Write(request + "Set Password user hunter2"); + client.ReadUntil(response + "Password has been changed!"); + Z; + + client.Write(request + "Set Timezone user America/New_York"); + client.ReadUntil(response + "Timezone = America/New_York"); + Z; + + client.Write(request + "Set TimestampFormat user [%H:%M]"); + client.ReadUntil(response + "TimestampFormat = [%H:%M]"); + Z; + + client.Write(request + "Set DCCBindHost user 0.0.0.0"); + client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); + Z; + + client.Write(request + "Set StatusPrefix user &"); + client.ReadUntil( + ":&controlpanel!znc@znc.in PRIVMSG nick :StatusPrefix = &"); + Z; + + client.Write("PRIVMSG &controlpanel :Set StatusPrefix user *"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "SetChan DefModes user freenode #znc ms"); + client.ReadUntil(response + "#znc: DefModes = ms"); + Z; + + client.Write(request + "SetChan Key user freenode #znc KindOneRules"); + client.ReadUntil(response + "#znc: Key = KindOneRules"); + Z; + + client.Write(request + "SetChan BufferSize user freenode #znc 9001"); + client.ReadUntil(response + "#znc: BufferSize = 9001"); + Z; + + client.Write(request + "SetChan InConfig user freenode #znc true"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; + + client.Write(request + + "SetChan AutoClearChanBuffer user freenode #znc false"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); + Z; + + client.Write(request + "SetChan Detached user freenode #znc false"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; + + client.Write(request + "SetNetwork Nick user freenode NotUser"); + client.ReadUntil(response + "Nick = NotUser"); + Z; + + client.Write(request + "SetNetwork Altnick user freenode NotUser_"); + client.ReadUntil(response + "AltNick = NotUser_"); + Z; + + client.Write(request + "SetNetwork Ident user freenode identd"); + client.ReadUntil(response + "Ident = identd"); + Z; - client.Write(request + "SetNetwork BindHost user freenode 0.0.0.0"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; + client.Write(request + "SetNetwork BindHost user freenode 0.0.0.0"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; - client.Write(request + "SetNetwork FloodRate user freenode 66.00"); - client.ReadUntil(response + "FloodRate = 66.00"); - Z; + client.Write(request + "SetNetwork FloodRate user freenode 66.00"); + client.ReadUntil(response + "FloodRate = 66.00"); + Z; - client.Write(request + "SetNetwork FloodBurst user freenode 55"); - client.ReadUntil(response + "FloodBurst = 55"); - Z; + client.Write(request + "SetNetwork FloodBurst user freenode 55"); + client.ReadUntil(response + "FloodBurst = 55"); + Z; - client.Write(request + "SetNetwork JoinDelay user freenode 22"); - client.ReadUntil(response + "JoinDelay = 22"); - Z; + client.Write(request + "SetNetwork JoinDelay user freenode 22"); + client.ReadUntil(response + "JoinDelay = 22"); + Z; - client.Write(request + "SetNetwork QuitMsg user freenode telnet"); - client.ReadUntil(response + "QuitMsg = telnet"); - Z; + client.Write(request + "SetNetwork QuitMsg user freenode telnet"); + client.ReadUntil(response + "QuitMsg = telnet"); + Z; - client.Write(request + "Get Nick user"); - client.ReadUntil(response + "Nick = user1"); - Z; + client.Write(request + "Get Nick user"); + client.ReadUntil(response + "Nick = user1"); + Z; - client.Write(request + "Get Altnick user"); - client.ReadUntil(response + "AltNick = user_1"); - Z; + client.Write(request + "Get Altnick user"); + client.ReadUntil(response + "AltNick = user_1"); + Z; - client.Write(request + "Get Ident user"); - client.ReadUntil(response + "Ident = user1"); - Z; + client.Write(request + "Get Ident user"); + client.ReadUntil(response + "Ident = user1"); + Z; - client.Write(request + "Get RealName user"); - client.ReadUntil(response + "RealName = lol"); - Z; - - client.Write(request + "Get BindHost user"); - client.ReadUntil(response + "BindHost = "); - Z; - - client.Write(request + "Get DefaultChanModes user"); - client.ReadUntil(response + "DefaultChanModes = +znst"); - Z; - - client.Write(request + "Get QuitMsg user"); - client.ReadUntil(response + "QuitMsg = Writing this took forever"); - Z; - - client.Write(request + "Get Password user"); - client.ReadUntil(response + "Error: Unknown variable"); - Z; - - client.Write(request + "Get Timezone user"); - client.ReadUntil(response + "Timezone = America/New_York"); - Z; - - client.Write(request + "Get TimestampFormat user"); - client.ReadUntil(response + "TimestampFormat = [%H:%M]"); - Z; - - client.Write(request + "Get DCCBindHost user"); - client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); - Z; - - client.Write(request + "Get StatusPrefix user"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "GetChan DefModes user freenode #znc"); - client.ReadUntil(response + "#znc: DefModes = ms"); - Z; - - client.Write(request + "GetChan Key user freenode #znc"); - client.ReadUntil(response + "#znc: Key = KindOneRules"); - Z; - - client.Write(request + "GetChan BufferSize user freenode #znc"); - client.ReadUntil(response + "#znc: BufferSize = 9001"); - Z; - - client.Write(request + "GetChan InConfig user freenode #znc"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; - - client.Write(request + "GetChan AutoClearChanBuffer user freenode #znc"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); - Z; - - client.Write(request + "GetChan Detached user freenode #znc"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; - - client.Write(request + "GetNetwork Nick user freenode"); - client.ReadUntil(response + "Nick = NotUser"); - Z; - - client.Write(request + "GetNetwork Altnick user freenode"); - client.ReadUntil(response + "AltNick = NotUser_"); - Z; - - client.Write(request + "GetNetwork Ident user freenode"); - client.ReadUntil(response + "Ident = identd"); - Z; - - client.Write(request + "GetNetwork BindHost user freenode"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; - - client.Write(request + "GetNetwork FloodRate user freenode"); - client.ReadUntil(response + "FloodRate = 66.00"); - Z; - - client.Write(request + "GetNetwork FloodBurst user freenode 55"); - client.ReadUntil(response + "FloodBurst = 55"); - Z; - - client.Write(request + "GetNetwork JoinDelay user freenode 22"); - client.ReadUntil(response + "JoinDelay = 22"); - Z; - - client.Write(request + "GetNetwork QuitMsg user freenode"); - client.ReadUntil(response + "QuitMsg = telnet"); - Z; - - client.Write(request + "UnLoadModule"); - client.ReadUntil(response + "Usage: UnloadModule "); - Z; - - client.Write(request + "UnLoadModule user"); - client.ReadUntil(response + "Usage: UnloadModule "); - Z; - - // https://github.com/znc/znc/issues/194 - client.Write(request + "UnloadModule user controlpanel"); - client.ReadUntil(response + "Please use /znc unloadmod controlpanel"); - Z; - - client.Write(request + "UnLoadModule user log"); - client.ReadUntil(response + "Unloaded module [log]"); - Z; - - client.Write(request + "UnLoadModule user log"); - client.ReadUntil( - response + "Unable to unload module [log] [Module [log] not loaded.]"); - Z; - - client.Write(request + "UnLoadNetModule user freenode log"); - client.ReadUntil(response + "Unloaded module [log]"); - Z; - - client.Write(request + "UnLoadNetModule user freenode log"); - client.ReadUntil( - response + "Unable to unload module [log] [Module [log] not loaded.]"); - Z; - - client.Write(request + "UnLoadNetModule user EFnet log"); - client.ReadUntil(response + - "Error: [user] does not have a network named [EFnet]."); - Z; - - // Test on second user "KindOne" from "user". - - client.Write(request + "AddCTCP KindOne VERSION Test"); - client.ReadUntil(response + "Added!"); - Z; - - // Added at the very beginning. - client.Write(request + "AddNetwork KindOne freenode"); - client.ReadUntil(response + "Network [freenode] added for user [KindOne]."); - Z; - - client.Write(request + "AddServer KindOne freenode 127.0.0.1 6667"); - client.ReadUntil(response + - "Added IRC Server [127.0.0.1 6667] for network [freenode] " - "for user [KindOne]."); - Z; - - client.Write(request + "AddChan KindOne freenode #znc"); - client.ReadUntil(response + "Channel [#znc] for user [KindOne] added."); - Z; - - client.Write(request + "AddChan KindOne freenode #znc"); - client.ReadUntil(response + - "Error: [KindOne] already has a channel named [#znc]."); - Z; - - client.Write(request + "AddUser KindOne hunter2"); - client.ReadUntil(response + "Error: User [KindOne] already exists!"); - Z; - - client.Write(request + "CloneUser KindOne KindOne_clone"); - client.ReadUntil(response + "User [KindOne_clone] added!"); - Z; - - client.Write(request + "CloneUser KindOne KindOne_clone"); - client.ReadUntil(response + "Error: User not added! [User already exists]"); - Z; - - client.Write(request + "DelCTCP KindOne VERSION"); - client.ReadUntil(response + - "Successfully removed [VERSION] for user [KindOne]."); - Z; - - client.Write(request + "DelCTCP KindOne VERSION"); - client.ReadUntil(response + - "Error: [VERSION] not found for user [KindOne]!"); - Z; - - client.Write(request + "DelChan KindOne freenode #znc"); - client.ReadUntil(response + - "Channel(s) [#znc] for user [KindOne] deleted."); - Z; - - client.Write(request + "DelChan KindOne freenode #znc"); - client.ReadUntil( - response + - "Error: User [KindOne] does not have any channel matching [#znc]."); - Z; - - client.Write(request + "DelNetwork KindOne freenode"); - client.ReadUntil(response + - "Network [freenode] deleted on user [KindOne]."); - Z; - - client.Write(request + "DelNetwork KindOne freenode"); - client.ReadUntil( - response + - "Error: [KindOne] does not have a network named [freenode]."); - Z; - - client.Write(request + "AddNetwork KindOne freenode"); - client.ReadUntil(response + "Network [freenode] added for user [KindOne]."); - Z; - - client.Write(request + "AddChan KindOne freenode #znc"); - client.ReadUntil(response + "Channel [#znc] for user [KindOne] added."); - Z; - - client.Write(request + "DelUser KindOne_clone"); - client.ReadUntil(response + "User [KindOne_clone] deleted!"); - Z; - - client.Write(request + "DelUser KindOne_clone"); - client.ReadUntil(response + "Error: User [KindOne_clone] does not exist!"); - Z; - - client.Write(request + "Disconnect KindOne freenode"); - client.ReadUntil( - response + - "Closed IRC connection for network [freenode] on user [KindOne]."); - Z; - - client.Write(request + "Disconnect KindOne EFnet"); - client.ReadUntil(response + - "Error: [KindOne] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Get Nick KindOne"); - client.ReadUntil(response + "Nick = KindOne"); - Z; - - client.Write(request + "Get AltNick KindOne"); - client.ReadUntil(response + "AltNick = KindOne"); - Z; - - client.Write(request + "Get Ident KindOne"); - client.ReadUntil(response + "Ident = KindOne"); - Z; - - client.Write(request + "Get RealName KindOne"); - client.ReadUntil(response + "RealName = "); - Z; - - client.Write(request + "Get BindHost KindOne"); - client.ReadUntil(response + "BindHost = "); - Z; - - client.Write(request + "Get DefaultChanModes KindOne"); - client.ReadUntil(response + "DefaultChanModes = "); - Z; - - client.Write(request + "Get QuitMsg KindOne"); - client.ReadUntil(response + "QuitMsg = "); - Z; - - client.Write(request + "Get Password KindOne"); - client.ReadUntil(response + "Error: Unknown variable"); - Z; - - client.Write(request + "Get Timezone KindOne"); - client.ReadUntil(response + "Timezone = "); - Z; - - client.Write(request + "Get TimestampFormat KindOne"); - client.ReadUntil(response + "TimestampFormat = "); - Z; - - client.Write(request + "Get DCCBindHost KindOne"); - client.ReadUntil(response + "DCCBindHost = "); - Z; - - client.Write(request + "Get StatusPrefix KindOne"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "Get BufferCount KindOne"); - client.ReadUntil(response + "BufferCount = 50"); - Z; - - client.Write(request + "Get JoinTries KindOne"); - client.ReadUntil(response + "JoinTries = "); - Z; - - client.Write(request + "Get MaxJoins KindOne"); - client.ReadUntil(response + "MaxJoins = "); - Z; - - client.Write(request + "Get MaxNetworks KindOne"); - client.ReadUntil(response + "MaxNetworks = "); - Z; - - client.Write(request + "Get MaxQueryBuffers KindOne"); - client.ReadUntil(response + "MaxQueryBuffers = "); - Z; - - client.Write(request + "Get Admin KindOne"); - client.ReadUntil(response + "Admin = false"); - Z; - - client.Write(request + "Get AppendTimestamp KindOne"); - client.ReadUntil(response + "AppendTimestamp = false"); - Z; - - client.Write(request + "Get AutoClearChanBuffer KindOne"); - client.ReadUntil(response + "AutoClearChanBuffer = true"); - Z; - - client.Write(request + "Get AutoClearQueryBuffer KindOne"); - client.ReadUntil(response + "AutoClearQueryBuffer = true"); - Z; - - client.Write(request + "Get DenyLoadMod KindOne"); - client.ReadUntil(response + "DenyLoadMod = false"); - Z; - - client.Write(request + "Get DenySetBindHost KindOne"); - client.ReadUntil(response + "DenySetBindHost = false"); - Z; - - client.Write(request + "Get MultiClients KindOne"); - client.ReadUntil(response + "MultiClients = true"); - Z; - - client.Write(request + "Get PrependTimestamp KindOne"); - client.ReadUntil(response + "PrependTimestamp = true"); - Z; + client.Write(request + "Get RealName user"); + client.ReadUntil(response + "RealName = lol"); + Z; + + client.Write(request + "Get BindHost user"); + client.ReadUntil(response + "BindHost = "); + Z; + + client.Write(request + "Get DefaultChanModes user"); + client.ReadUntil(response + "DefaultChanModes = +znst"); + Z; + + client.Write(request + "Get QuitMsg user"); + client.ReadUntil(response + "QuitMsg = Writing this took forever"); + Z; + + client.Write(request + "Get Password user"); + client.ReadUntil(response + "Error: Unknown variable"); + Z; + + client.Write(request + "Get Timezone user"); + client.ReadUntil(response + "Timezone = America/New_York"); + Z; + + client.Write(request + "Get TimestampFormat user"); + client.ReadUntil(response + "TimestampFormat = [%H:%M]"); + Z; + + client.Write(request + "Get DCCBindHost user"); + client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); + Z; + + client.Write(request + "Get StatusPrefix user"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "GetChan DefModes user freenode #znc"); + client.ReadUntil(response + "#znc: DefModes = ms"); + Z; + + client.Write(request + "GetChan Key user freenode #znc"); + client.ReadUntil(response + "#znc: Key = KindOneRules"); + Z; + + client.Write(request + "GetChan BufferSize user freenode #znc"); + client.ReadUntil(response + "#znc: BufferSize = 9001"); + Z; + + client.Write(request + "GetChan InConfig user freenode #znc"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; + + client.Write(request + "GetChan AutoClearChanBuffer user freenode #znc"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); + Z; + + client.Write(request + "GetChan Detached user freenode #znc"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; + + client.Write(request + "GetNetwork Nick user freenode"); + client.ReadUntil(response + "Nick = NotUser"); + Z; + + client.Write(request + "GetNetwork Altnick user freenode"); + client.ReadUntil(response + "AltNick = NotUser_"); + Z; + + client.Write(request + "GetNetwork Ident user freenode"); + client.ReadUntil(response + "Ident = identd"); + Z; + + client.Write(request + "GetNetwork BindHost user freenode"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; + + client.Write(request + "GetNetwork FloodRate user freenode"); + client.ReadUntil(response + "FloodRate = 66.00"); + Z; + + client.Write(request + "GetNetwork FloodBurst user freenode 55"); + client.ReadUntil(response + "FloodBurst = 55"); + Z; + + client.Write(request + "GetNetwork JoinDelay user freenode 22"); + client.ReadUntil(response + "JoinDelay = 22"); + Z; + + client.Write(request + "GetNetwork QuitMsg user freenode"); + client.ReadUntil(response + "QuitMsg = telnet"); + Z; + + client.Write(request + "UnLoadModule"); + client.ReadUntil(response + "Usage: UnloadModule "); + Z; + + client.Write(request + "UnLoadModule user"); + client.ReadUntil(response + "Usage: UnloadModule "); + Z; + + // https://github.com/znc/znc/issues/194 + client.Write(request + "UnloadModule user controlpanel"); + client.ReadUntil(response + "Please use /znc unloadmod controlpanel"); + Z; + + client.Write(request + "UnLoadModule user log"); + client.ReadUntil(response + "Unloaded module [log]"); + Z; + + client.Write(request + "UnLoadModule user log"); + client.ReadUntil( + response + "Unable to unload module [log] [Module [log] not loaded.]"); + Z; + + client.Write(request + "UnLoadNetModule user freenode log"); + client.ReadUntil(response + "Unloaded module [log]"); + Z; + + client.Write(request + "UnLoadNetModule user freenode log"); + client.ReadUntil( + response + "Unable to unload module [log] [Module [log] not loaded.]"); + Z; + + client.Write(request + "UnLoadNetModule user EFnet log"); + client.ReadUntil(response + + "Error: [user] does not have a network named [EFnet]."); + Z; + + // Test on second user "KindOne" from "user". + + client.Write(request + "AddCTCP KindOne VERSION Test"); + client.ReadUntil(response + "Added!"); + Z; + + // Added at the very beginning. + client.Write(request + "AddNetwork KindOne freenode"); + client.ReadUntil(response + "Network [freenode] added for user [KindOne]."); + Z; + + client.Write(request + "AddServer KindOne freenode 127.0.0.1 6667"); + client.ReadUntil(response + + "Added IRC Server [127.0.0.1 6667] for network [freenode] " + "for user [KindOne]."); + Z; + + client.Write(request + "AddChan KindOne freenode #znc"); + client.ReadUntil(response + "Channel [#znc] for user [KindOne] added."); + Z; + + client.Write(request + "AddChan KindOne freenode #znc"); + client.ReadUntil(response + + "Error: [KindOne] already has a channel named [#znc]."); + Z; + + client.Write(request + "AddUser KindOne hunter2"); + client.ReadUntil(response + "Error: User [KindOne] already exists!"); + Z; + + client.Write(request + "CloneUser KindOne KindOne_clone"); + client.ReadUntil(response + "User [KindOne_clone] added!"); + Z; + + client.Write(request + "CloneUser KindOne KindOne_clone"); + client.ReadUntil(response + "Error: User not added! [User already exists]"); + Z; + + client.Write(request + "DelCTCP KindOne VERSION"); + client.ReadUntil(response + + "Successfully removed [VERSION] for user [KindOne]."); + Z; + + client.Write(request + "DelCTCP KindOne VERSION"); + client.ReadUntil(response + + "Error: [VERSION] not found for user [KindOne]!"); + Z; + + client.Write(request + "DelChan KindOne freenode #znc"); + client.ReadUntil(response + + "Channel(s) [#znc] for user [KindOne] deleted."); + Z; + + client.Write(request + "DelChan KindOne freenode #znc"); + client.ReadUntil( + response + + "Error: User [KindOne] does not have any channel matching [#znc]."); + Z; + + client.Write(request + "DelNetwork KindOne freenode"); + client.ReadUntil(response + + "Network [freenode] deleted on user [KindOne]."); + Z; + + client.Write(request + "DelNetwork KindOne freenode"); + client.ReadUntil( + response + + "Error: [KindOne] does not have a network named [freenode]."); + Z; + + client.Write(request + "AddNetwork KindOne freenode"); + client.ReadUntil(response + "Network [freenode] added for user [KindOne]."); + Z; + + client.Write(request + "AddChan KindOne freenode #znc"); + client.ReadUntil(response + "Channel [#znc] for user [KindOne] added."); + Z; + + client.Write(request + "DelUser KindOne_clone"); + client.ReadUntil(response + "User [KindOne_clone] deleted!"); + Z; + + client.Write(request + "DelUser KindOne_clone"); + client.ReadUntil(response + "Error: User [KindOne_clone] does not exist!"); + Z; + + client.Write(request + "Disconnect KindOne freenode"); + client.ReadUntil( + response + + "Closed IRC connection for network [freenode] on user [KindOne]."); + Z; + + client.Write(request + "Disconnect KindOne EFnet"); + client.ReadUntil(response + + "Error: [KindOne] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Get Nick KindOne"); + client.ReadUntil(response + "Nick = KindOne"); + Z; + + client.Write(request + "Get AltNick KindOne"); + client.ReadUntil(response + "AltNick = KindOne"); + Z; + + client.Write(request + "Get Ident KindOne"); + client.ReadUntil(response + "Ident = KindOne"); + Z; + + client.Write(request + "Get RealName KindOne"); + client.ReadUntil(response + "RealName = "); + Z; + + client.Write(request + "Get BindHost KindOne"); + client.ReadUntil(response + "BindHost = "); + Z; + + client.Write(request + "Get DefaultChanModes KindOne"); + client.ReadUntil(response + "DefaultChanModes = "); + Z; + + client.Write(request + "Get QuitMsg KindOne"); + client.ReadUntil(response + "QuitMsg = "); + Z; + + client.Write(request + "Get Password KindOne"); + client.ReadUntil(response + "Error: Unknown variable"); + Z; + + client.Write(request + "Get Timezone KindOne"); + client.ReadUntil(response + "Timezone = "); + Z; + + client.Write(request + "Get TimestampFormat KindOne"); + client.ReadUntil(response + "TimestampFormat = "); + Z; + + client.Write(request + "Get DCCBindHost KindOne"); + client.ReadUntil(response + "DCCBindHost = "); + Z; + + client.Write(request + "Get StatusPrefix KindOne"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "Get BufferCount KindOne"); + client.ReadUntil(response + "BufferCount = 50"); + Z; + + client.Write(request + "Get JoinTries KindOne"); + client.ReadUntil(response + "JoinTries = "); + Z; + + client.Write(request + "Get MaxJoins KindOne"); + client.ReadUntil(response + "MaxJoins = "); + Z; + + client.Write(request + "Get MaxNetworks KindOne"); + client.ReadUntil(response + "MaxNetworks = "); + Z; + + client.Write(request + "Get MaxQueryBuffers KindOne"); + client.ReadUntil(response + "MaxQueryBuffers = "); + Z; + + client.Write(request + "Get Admin KindOne"); + client.ReadUntil(response + "Admin = false"); + Z; + + client.Write(request + "Get AppendTimestamp KindOne"); + client.ReadUntil(response + "AppendTimestamp = false"); + Z; + + client.Write(request + "Get AutoClearChanBuffer KindOne"); + client.ReadUntil(response + "AutoClearChanBuffer = true"); + Z; + + client.Write(request + "Get AutoClearQueryBuffer KindOne"); + client.ReadUntil(response + "AutoClearQueryBuffer = true"); + Z; + + client.Write(request + "Get DenyLoadMod KindOne"); + client.ReadUntil(response + "DenyLoadMod = false"); + Z; + + client.Write(request + "Get DenySetBindHost KindOne"); + client.ReadUntil(response + "DenySetBindHost = false"); + Z; + + client.Write(request + "Get MultiClients KindOne"); + client.ReadUntil(response + "MultiClients = true"); + Z; + + client.Write(request + "Get PrependTimestamp KindOne"); + client.ReadUntil(response + "PrependTimestamp = true"); + Z; - client.Write(request + "GetChan DefModes KindOne freenode #znc"); - client.ReadUntil(response + "#znc: DefModes = "); - Z; + client.Write(request + "GetChan DefModes KindOne freenode #znc"); + client.ReadUntil(response + "#znc: DefModes = "); + Z; - client.Write(request + "GetChan Key KindOne freenode #znc"); - client.ReadUntil(response + "#znc: Key = "); - Z; + client.Write(request + "GetChan Key KindOne freenode #znc"); + client.ReadUntil(response + "#znc: Key = "); + Z; - client.Write(request + "GetChan BufferSize KindOne freenode #znc"); - client.ReadUntil(response + "#znc: BufferSize = 50 (default)"); - Z; - - client.Write(request + "GetChan InConfig KindOne freenode #znc"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; - - client.Write(request + "GetChan AutoClearChanBuffer KindOne freenode #znc"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = true (default)"); - Z; - - client.Write(request + "GetChan Detached KindOne freenode #znc"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; - - client.Write(request + "GetNetwork Nick KindOne freenode"); - client.ReadUntil(response + "Nick = KindOne"); - Z; - - client.Write(request + "GetNetwork Altnick KindOne freenode"); - client.ReadUntil(response + "AltNick = KindOne"); - Z; - - client.Write(request + "GetNetwork Ident KindOne freenode"); - client.ReadUntil(response + "Ident = KindOne"); - Z; - - client.Write(request + "GetNetwork BindHost KindOne freenode"); - client.ReadUntil(response + "BindHost = "); - Z; - - client.Write(request + "GetNetwork FloodRate KindOne freenode"); - client.ReadUntil(response + "FloodRate = 1.00"); - Z; - - client.Write(request + "GetNetwork FloodBurst KindOne freenode"); - client.ReadUntil(response + "FloodBurst = 4"); - Z; - - client.Write(request + "GetNetwork JoinDelay KindOne freenode"); - client.ReadUntil(response + "JoinDelay = 0"); - Z; - - client.Write(request + "GetNetwork QuitMsg KindOne freenode"); - client.ReadUntil(response + "QuitMsg = "); - Z; - - client.Write(request + "AddCTCP KindOne VERSION Test"); - client.ReadUntil(response + "Added!"); - Z; - - client.Write(request + "ListCTCPs KindOne"); - client.ReadUntil(response + "Request: VERSION"); - Z; - - client.Write(request + "ListMods KindOne"); - client.ReadUntil(response + "User [KindOne] has no modules loaded."); - Z; - - client.Write(request + "LoadModule KindOne autoop"); - client.ReadUntil(response + - "Unable to load module [autoop] [Module [autoop] does not " - "support module type [User].]"); - Z; - - client.Write(request + "LoadModule KindOne perform"); - client.ReadUntil(response + "Loaded module [perform]"); - Z; - - client.Write(request + "ListMods KindOne"); - client.ReadUntil(response + "Name: perform"); - Z; - - client.Write(request + "ListNetMods KindOne"); - client.ReadUntil(response + "Usage: ListNetMods "); - Z; - - client.Write(request + "ListNetworks KindOne"); - client.ReadUntil(response + "Network: freenode"); - Z; - - client.Write(request + "ListUsers"); - client.ReadUntil(response + "Username: user"); - Z; - - client.Write(request + "LoadModule"); - client.ReadUntil(response + - "Usage: LoadModule [args]"); - Z; - - client.Write(request + "LoadModule KindOne"); - client.ReadUntil(response + - "Usage: LoadModule [args]"); - Z; - - client.Write(request + "LoadModule KindOne log"); - client.ReadUntil(response + "Loaded module [log]"); - Z; - - client.Write(request + "LoadModule KindOne log"); - client.ReadUntil( - response + "Unable to load module [log] because it is already loaded"); - Z; - - client.Write(request + "LoadNetModule KindOne freenode log"); - client.ReadUntil(response + "Loaded module [log]"); - Z; - - client.Write(request + "LoadNetModule KindOne freenode log"); - client.ReadUntil( - response + "Unable to load module [log] because it is already loaded"); - Z; - - client.Write(request + "LoadNetModule KindOne EFnet log"); - client.ReadUntil(response + - "Error: [KindOne] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Reconnect KindOne freenode"); - client.ReadUntil( - response + - "Queued network [freenode] for user [KindOne] for a reconnect."); - Z; - - client.Write(request + "Reconnect KindOne EFnet"); - client.ReadUntil(response + - "Error: [KindOne] does not have a network named [EFnet]."); - Z; - - client.Write(request + "Set Nick KindOne KindTwo"); - client.ReadUntil(response + "Nick = KindTwo"); - Z; - - client.Write(request + "Set Altnick KindOne KindTwo_"); - client.ReadUntil(response + "AltNick = KindTwo_"); - Z; - - client.Write(request + "Set Ident KindOne znc"); - client.ReadUntil(response + "Ident = znc"); - Z; - - client.Write(request + "Set RealName KindOne real_name"); - client.ReadUntil(response + "RealName = real_name"); - Z; - - client.Write(request + "Set BindHost KindOne 0.0.0.0"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; - - client.Write(request + "Set DefaultChanModes KindOne +inst"); - client.ReadUntil(response + "DefaultChanModes = +inst"); - Z; - - client.Write(request + "Set QuitMsg KindOne Writing this took forever."); - client.ReadUntil(response + "QuitMsg = Writing this took forever"); - Z; - - client.Write(request + "Set Password KindOne hunter2"); - client.ReadUntil(response + "Password has been changed!"); - Z; - - client.Write(request + "Set Timezone KindOne America/New_York"); - client.ReadUntil(response + "Timezone = America/New_York"); - Z; - - client.Write(request + "Set TimestampFormat KindOne [%H:%M]"); - client.ReadUntil(response + "TimestampFormat = [%H:%M]"); - Z; - - client.Write(request + "Set DCCBindHost KindOne 0.0.0.0"); - client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); - Z; - - client.Write(request + "Set StatusPrefix KindOne &"); - client.ReadUntil(response + "StatusPrefix = &"); - Z; - - client.Write(request + "Set StatusPrefix KindOne *"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "SetChan DefModes KindOne freenode #znc is"); - client.ReadUntil(response + "#znc: DefModes = is"); - Z; - - client.Write(request + "SetChan Key KindOne freenode #znc KindOneRules"); - client.ReadUntil(response + "#znc: Key = KindOneRules"); - Z; - - client.Write(request + "SetChan BufferSize KindOne freenode #znc 9001"); - client.ReadUntil(response + "#znc: BufferSize = 9001"); - Z; - - client.Write(request + "SetChan InConfig KindOne freenode #znc true"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; - - client.Write(request + - "SetChan AutoClearChanBuffer KindOne freenode #znc false"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); - Z; - - client.Write(request + "SetChan Detached KindOne freenode #znc false"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; - - client.Write(request + "SetNetwork Nick KindOne freenode KindTwo"); - client.ReadUntil(response + "Nick = KindTwo"); - Z; - - client.Write(request + "SetNetwork Altnick KindOne freenode KindTwo_"); - client.ReadUntil(response + "AltNick = KindTwo_"); - Z; - - client.Write(request + "SetNetwork Ident KindOne freenode znc"); - client.ReadUntil(response + "Ident = znc"); - Z; + client.Write(request + "GetChan BufferSize KindOne freenode #znc"); + client.ReadUntil(response + "#znc: BufferSize = 50 (default)"); + Z; + + client.Write(request + "GetChan InConfig KindOne freenode #znc"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; + + client.Write(request + "GetChan AutoClearChanBuffer KindOne freenode #znc"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = true (default)"); + Z; + + client.Write(request + "GetChan Detached KindOne freenode #znc"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; + + client.Write(request + "GetNetwork Nick KindOne freenode"); + client.ReadUntil(response + "Nick = KindOne"); + Z; + + client.Write(request + "GetNetwork Altnick KindOne freenode"); + client.ReadUntil(response + "AltNick = KindOne"); + Z; + + client.Write(request + "GetNetwork Ident KindOne freenode"); + client.ReadUntil(response + "Ident = KindOne"); + Z; + + client.Write(request + "GetNetwork BindHost KindOne freenode"); + client.ReadUntil(response + "BindHost = "); + Z; + + client.Write(request + "GetNetwork FloodRate KindOne freenode"); + client.ReadUntil(response + "FloodRate = 1.00"); + Z; + + client.Write(request + "GetNetwork FloodBurst KindOne freenode"); + client.ReadUntil(response + "FloodBurst = 4"); + Z; + + client.Write(request + "GetNetwork JoinDelay KindOne freenode"); + client.ReadUntil(response + "JoinDelay = 0"); + Z; + + client.Write(request + "GetNetwork QuitMsg KindOne freenode"); + client.ReadUntil(response + "QuitMsg = "); + Z; + + client.Write(request + "AddCTCP KindOne VERSION Test"); + client.ReadUntil(response + "Added!"); + Z; + + client.Write(request + "ListCTCPs KindOne"); + client.ReadUntil(response + "Request: VERSION"); + Z; + + client.Write(request + "ListMods KindOne"); + client.ReadUntil(response + "User [KindOne] has no modules loaded."); + Z; + + client.Write(request + "LoadModule KindOne autoop"); + client.ReadUntil(response + + "Unable to load module [autoop] [Module [autoop] does not " + "support module type [User].]"); + Z; + + client.Write(request + "LoadModule KindOne perform"); + client.ReadUntil(response + "Loaded module [perform]"); + Z; + + client.Write(request + "ListMods KindOne"); + client.ReadUntil(response + "Name: perform"); + Z; + + client.Write(request + "ListNetMods KindOne"); + client.ReadUntil(response + "Usage: ListNetMods "); + Z; + + client.Write(request + "ListNetworks KindOne"); + client.ReadUntil(response + "Network: freenode"); + Z; + + client.Write(request + "ListUsers"); + client.ReadUntil(response + "Username: user"); + Z; + + client.Write(request + "LoadModule"); + client.ReadUntil(response + + "Usage: LoadModule [args]"); + Z; + + client.Write(request + "LoadModule KindOne"); + client.ReadUntil(response + + "Usage: LoadModule [args]"); + Z; + + client.Write(request + "LoadModule KindOne log"); + client.ReadUntil(response + "Loaded module [log]"); + Z; + + client.Write(request + "LoadModule KindOne log"); + client.ReadUntil( + response + "Unable to load module [log] because it is already loaded"); + Z; + + client.Write(request + "LoadNetModule KindOne freenode log"); + client.ReadUntil(response + "Loaded module [log]"); + Z; + + client.Write(request + "LoadNetModule KindOne freenode log"); + client.ReadUntil( + response + "Unable to load module [log] because it is already loaded"); + Z; + + client.Write(request + "LoadNetModule KindOne EFnet log"); + client.ReadUntil(response + + "Error: [KindOne] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Reconnect KindOne freenode"); + client.ReadUntil( + response + + "Queued network [freenode] for user [KindOne] for a reconnect."); + Z; + + client.Write(request + "Reconnect KindOne EFnet"); + client.ReadUntil(response + + "Error: [KindOne] does not have a network named [EFnet]."); + Z; + + client.Write(request + "Set Nick KindOne KindTwo"); + client.ReadUntil(response + "Nick = KindTwo"); + Z; + + client.Write(request + "Set Altnick KindOne KindTwo_"); + client.ReadUntil(response + "AltNick = KindTwo_"); + Z; + + client.Write(request + "Set Ident KindOne znc"); + client.ReadUntil(response + "Ident = znc"); + Z; + + client.Write(request + "Set RealName KindOne real_name"); + client.ReadUntil(response + "RealName = real_name"); + Z; + + client.Write(request + "Set BindHost KindOne 0.0.0.0"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; + + client.Write(request + "Set DefaultChanModes KindOne +inst"); + client.ReadUntil(response + "DefaultChanModes = +inst"); + Z; + + client.Write(request + "Set QuitMsg KindOne Writing this took forever."); + client.ReadUntil(response + "QuitMsg = Writing this took forever"); + Z; + + client.Write(request + "Set Password KindOne hunter2"); + client.ReadUntil(response + "Password has been changed!"); + Z; + + client.Write(request + "Set Timezone KindOne America/New_York"); + client.ReadUntil(response + "Timezone = America/New_York"); + Z; + + client.Write(request + "Set TimestampFormat KindOne [%H:%M]"); + client.ReadUntil(response + "TimestampFormat = [%H:%M]"); + Z; + + client.Write(request + "Set DCCBindHost KindOne 0.0.0.0"); + client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); + Z; + + client.Write(request + "Set StatusPrefix KindOne &"); + client.ReadUntil(response + "StatusPrefix = &"); + Z; + + client.Write(request + "Set StatusPrefix KindOne *"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "SetChan DefModes KindOne freenode #znc is"); + client.ReadUntil(response + "#znc: DefModes = is"); + Z; + + client.Write(request + "SetChan Key KindOne freenode #znc KindOneRules"); + client.ReadUntil(response + "#znc: Key = KindOneRules"); + Z; + + client.Write(request + "SetChan BufferSize KindOne freenode #znc 9001"); + client.ReadUntil(response + "#znc: BufferSize = 9001"); + Z; + + client.Write(request + "SetChan InConfig KindOne freenode #znc true"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; + + client.Write(request + + "SetChan AutoClearChanBuffer KindOne freenode #znc false"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); + Z; + + client.Write(request + "SetChan Detached KindOne freenode #znc false"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; + + client.Write(request + "SetNetwork Nick KindOne freenode KindTwo"); + client.ReadUntil(response + "Nick = KindTwo"); + Z; + + client.Write(request + "SetNetwork Altnick KindOne freenode KindTwo_"); + client.ReadUntil(response + "AltNick = KindTwo_"); + Z; + + client.Write(request + "SetNetwork Ident KindOne freenode znc"); + client.ReadUntil(response + "Ident = znc"); + Z; - client.Write(request + "SetNetwork BindHost KindOne freenode 0.0.0.0"); - client.ReadUntil(response + "This bind host is already set!"); - Z; + client.Write(request + "SetNetwork BindHost KindOne freenode 0.0.0.0"); + client.ReadUntil(response + "This bind host is already set!"); + Z; - client.Write(request + "SetNetwork FloodRate KindOne freenode 42.00"); - client.ReadUntil(response + "FloodRate = 42.00"); - Z; + client.Write(request + "SetNetwork FloodRate KindOne freenode 42.00"); + client.ReadUntil(response + "FloodRate = 42.00"); + Z; - client.Write(request + "SetNetwork FloodBurst KindOne freenode 20"); - client.ReadUntil(response + "FloodBurst = 20"); - Z; + client.Write(request + "SetNetwork FloodBurst KindOne freenode 20"); + client.ReadUntil(response + "FloodBurst = 20"); + Z; - client.Write(request + "SetNetwork JoinDelay KindOne freenode 5"); - client.ReadUntil(response + "JoinDelay = 5"); - Z; + client.Write(request + "SetNetwork JoinDelay KindOne freenode 5"); + client.ReadUntil(response + "JoinDelay = 5"); + Z; - client.Write(request + "SetNetwork QuitMsg KindOne freenode telnet"); - client.ReadUntil(response + "QuitMsg = telnet"); - Z; + client.Write(request + "SetNetwork QuitMsg KindOne freenode telnet"); + client.ReadUntil(response + "QuitMsg = telnet"); + Z; - client.Write(request + "Get Nick KindOne"); - client.ReadUntil(response + "Nick = KindTwo"); - Z; + client.Write(request + "Get Nick KindOne"); + client.ReadUntil(response + "Nick = KindTwo"); + Z; - client.Write(request + "Get Altnick KindOne"); - client.ReadUntil(response + "AltNick = KindTwo_"); - Z; + client.Write(request + "Get Altnick KindOne"); + client.ReadUntil(response + "AltNick = KindTwo_"); + Z; - client.Write(request + "Get Ident KindOne"); - client.ReadUntil(response + "Ident = znc"); - Z; + client.Write(request + "Get Ident KindOne"); + client.ReadUntil(response + "Ident = znc"); + Z; - client.Write(request + "Get RealName KindOne"); - client.ReadUntil(response + "RealName = real_name"); - Z; + client.Write(request + "Get RealName KindOne"); + client.ReadUntil(response + "RealName = real_name"); + Z; - client.Write(request + "Get BindHost KindOne"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; - - client.Write(request + "Get DefaultChanModes KindOne"); - client.ReadUntil(response + "DefaultChanModes = +inst"); - Z; - - client.Write(request + "Get QuitMsg KindOne"); - client.ReadUntil(response + "QuitMsg = Writing this took forever"); - Z; - - client.Write(request + "Get Password KindOne"); - client.ReadUntil(response + "Error: Unknown variable"); - Z; - - client.Write(request + "Get Timezone KindOne"); - client.ReadUntil(response + "Timezone = America/New_York"); - Z; - - client.Write(request + "Get TimestampFormat KindOne"); - client.ReadUntil(response + "TimestampFormat = [%H:%M]"); - Z; - - client.Write(request + "Get DCCBindHost KindOne"); - client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); - Z; - - client.Write(request + "Get StatusPrefix KindOne"); - client.ReadUntil(response + "StatusPrefix = *"); - Z; - - client.Write(request + "GetChan DefModes KindOne freenode #znc"); - client.ReadUntil(response + "#znc: DefModes = is"); - Z; - - client.Write(request + "GetChan Key KindOne freenode #znc"); - client.ReadUntil(response + "#znc: Key = KindOneRules"); - Z; - - client.Write(request + "GetChan BufferSize KindOne freenode #znc"); - client.ReadUntil(response + "#znc: BufferSize = 9001"); - Z; - - client.Write(request + "GetChan InConfig KindOne freenode #znc"); - client.ReadUntil(response + "#znc: InConfig = true"); - Z; + client.Write(request + "Get BindHost KindOne"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; + + client.Write(request + "Get DefaultChanModes KindOne"); + client.ReadUntil(response + "DefaultChanModes = +inst"); + Z; + + client.Write(request + "Get QuitMsg KindOne"); + client.ReadUntil(response + "QuitMsg = Writing this took forever"); + Z; + + client.Write(request + "Get Password KindOne"); + client.ReadUntil(response + "Error: Unknown variable"); + Z; + + client.Write(request + "Get Timezone KindOne"); + client.ReadUntil(response + "Timezone = America/New_York"); + Z; + + client.Write(request + "Get TimestampFormat KindOne"); + client.ReadUntil(response + "TimestampFormat = [%H:%M]"); + Z; + + client.Write(request + "Get DCCBindHost KindOne"); + client.ReadUntil(response + "DCCBindHost = 0.0.0.0"); + Z; + + client.Write(request + "Get StatusPrefix KindOne"); + client.ReadUntil(response + "StatusPrefix = *"); + Z; + + client.Write(request + "GetChan DefModes KindOne freenode #znc"); + client.ReadUntil(response + "#znc: DefModes = is"); + Z; + + client.Write(request + "GetChan Key KindOne freenode #znc"); + client.ReadUntil(response + "#znc: Key = KindOneRules"); + Z; + + client.Write(request + "GetChan BufferSize KindOne freenode #znc"); + client.ReadUntil(response + "#znc: BufferSize = 9001"); + Z; + + client.Write(request + "GetChan InConfig KindOne freenode #znc"); + client.ReadUntil(response + "#znc: InConfig = true"); + Z; - client.Write(request + "GetChan AutoClearChanBuffer KindOne freenode #znc"); - client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); - Z; + client.Write(request + "GetChan AutoClearChanBuffer KindOne freenode #znc"); + client.ReadUntil(response + "#znc: AutoClearChanBuffer = false"); + Z; - client.Write(request + "GetChan Detached KindOne freenode #znc"); - client.ReadUntil(response + "#znc: Detached = false"); - Z; + client.Write(request + "GetChan Detached KindOne freenode #znc"); + client.ReadUntil(response + "#znc: Detached = false"); + Z; - client.Write(request + "GetNetwork Nick KindOne freenode"); - client.ReadUntil(response + "Nick = KindTwo"); - Z; + client.Write(request + "GetNetwork Nick KindOne freenode"); + client.ReadUntil(response + "Nick = KindTwo"); + Z; - client.Write(request + "GetNetwork Altnick KindOne freenode"); - client.ReadUntil(response + "AltNick = KindTwo_"); - Z; + client.Write(request + "GetNetwork Altnick KindOne freenode"); + client.ReadUntil(response + "AltNick = KindTwo_"); + Z; - client.Write(request + "GetNetwork Ident KindOne freenode"); - client.ReadUntil(response + "Ident = znc"); - Z; + client.Write(request + "GetNetwork Ident KindOne freenode"); + client.ReadUntil(response + "Ident = znc"); + Z; - client.Write(request + "GetNetwork BindHost KindOne freenode"); - client.ReadUntil(response + "BindHost = 0.0.0.0"); - Z; + client.Write(request + "GetNetwork BindHost KindOne freenode"); + client.ReadUntil(response + "BindHost = 0.0.0.0"); + Z; - client.Write(request + "GetNetwork FloodRate KindOne freenode"); - client.ReadUntil(response + "FloodRate = 42.00"); - Z; + client.Write(request + "GetNetwork FloodRate KindOne freenode"); + client.ReadUntil(response + "FloodRate = 42.00"); + Z; - client.Write(request + "GetNetwork FloodBurst KindOne freenode"); - client.ReadUntil(response + "FloodBurst = 20"); - Z; + client.Write(request + "GetNetwork FloodBurst KindOne freenode"); + client.ReadUntil(response + "FloodBurst = 20"); + Z; - client.Write(request + "GetNetwork JoinDelay KindOne freenode"); - client.ReadUntil(response + "JoinDelay = 5"); - Z; + client.Write(request + "GetNetwork JoinDelay KindOne freenode"); + client.ReadUntil(response + "JoinDelay = 5"); + Z; - client.Write(request + "GetNetwork QuitMsg KindOne freenode"); - client.ReadUntil(response + "QuitMsg = telnet"); - Z; + client.Write(request + "GetNetwork QuitMsg KindOne freenode"); + client.ReadUntil(response + "QuitMsg = telnet"); + Z; - client.Write(request + "UnLoadModule"); - client.ReadUntil(response + "Usage: UnloadModule "); - Z; + client.Write(request + "UnLoadModule"); + client.ReadUntil(response + "Usage: UnloadModule "); + Z; - client.Write(request + "UnLoadModule KindOne"); - client.ReadUntil(response + "Usage: UnloadModule "); - Z; + client.Write(request + "UnLoadModule KindOne"); + client.ReadUntil(response + "Usage: UnloadModule "); + Z; - client.Write(request + "UnLoadModule KindOne log"); - client.ReadUntil(response + "Unloaded module [log]"); - Z; + client.Write(request + "UnLoadModule KindOne log"); + client.ReadUntil(response + "Unloaded module [log]"); + Z; - client.Write(request + "UnLoadModule KindOne log"); - client.ReadUntil( - response + "Unable to unload module [log] [Module [log] not loaded.]"); - Z; - - client.Write(request + "UnLoadNetModule KindOne freenode log"); - client.ReadUntil(response + "Unloaded module [log]"); - Z; - - client.Write(request + "UnLoadNetModule KindOne freenode log"); - client.ReadUntil( - response + "Unable to unload module [log] [Module [log] not loaded.]"); - Z; + client.Write(request + "UnLoadModule KindOne log"); + client.ReadUntil( + response + "Unable to unload module [log] [Module [log] not loaded.]"); + Z; + + client.Write(request + "UnLoadNetModule KindOne freenode log"); + client.ReadUntil(response + "Unloaded module [log]"); + Z; + + client.Write(request + "UnLoadNetModule KindOne freenode log"); + client.ReadUntil( + response + "Unable to unload module [log] [Module [log] not loaded.]"); + Z; - client.Write(request + "UnLoadNetModule KindOne EFnet log"); - client.ReadUntil(response + - "Error: [KindOne] does not have a network named [EFnet]."); - Z; + client.Write(request + "UnLoadNetModule KindOne EFnet log"); + client.ReadUntil(response + + "Error: [KindOne] does not have a network named [EFnet]."); + Z; - // Test on "foobar", a user that does not exist. - - client.Write(request + "AddCTCP foobar VERSION Test"); - client.ReadUntil(response + "Error: User [foobar] not found."); - Z; + // Test on "foobar", a user that does not exist. + + client.Write(request + "AddCTCP foobar VERSION Test"); + client.ReadUntil(response + "Error: User [foobar] not found."); + Z; } TEST_F(ZNCTest, ShellModule) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - auto client = LoginClient(); - Z; - client.Write("znc loadmod shell"); - client.Write("PRIVMSG *shell :echo blahblah"); - client.ReadUntil("PRIVMSG nick :blahblah"); - client.ReadUntil("PRIVMSG nick :znc$"); + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto client = LoginClient(); + Z; + client.Write("znc loadmod shell"); + client.Write("PRIVMSG *shell :echo blahblah"); + client.ReadUntil("PRIVMSG nick :blahblah"); + client.ReadUntil("PRIVMSG nick :znc$"); } TEST_F(ZNCTest, NotifyConnectModule) { - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - auto client = LoginClient(); - Z; - client.Write("znc loadmod notify_connect"); + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto client = LoginClient(); + Z; + client.Write("znc loadmod notify_connect"); - auto client2 = ConnectClient(); - client2.Write("PASS :hunter2"); - client2.Write("NICK nick"); - client2.Write("USER user/test x x :x"); - client.ReadUntil("NOTICE nick :*** user attached (from 127.0.0.1)"); - Z; + auto client2 = ConnectClient(); + client2.Write("PASS :hunter2"); + client2.Write("NICK nick"); + client2.Write("USER user/test x x :x"); + client.ReadUntil("NOTICE nick :*** user attached (from 127.0.0.1)"); + Z; - auto client3 = ConnectClient(); - client3.Write("PASS :hunter2"); - client3.Write("NICK nick"); - client3.Write("USER user@identifier/test x x :x"); - client.ReadUntil( - "NOTICE nick :*** user@identifier attached (from 127.0.0.1)"); - Z; - client2.ReadUntil( - "NOTICE nick :*** user@identifier attached (from 127.0.0.1)"); - Z; + auto client3 = ConnectClient(); + client3.Write("PASS :hunter2"); + client3.Write("NICK nick"); + client3.Write("USER user@identifier/test x x :x"); + client.ReadUntil( + "NOTICE nick :*** user@identifier attached (from 127.0.0.1)"); + Z; + client2.ReadUntil( + "NOTICE nick :*** user@identifier attached (from 127.0.0.1)"); + Z; - client2.Write("QUIT"); - client.ReadUntil("NOTICE nick :*** user detached (from 127.0.0.1)"); - Z; + client2.Write("QUIT"); + client.ReadUntil("NOTICE nick :*** user detached (from 127.0.0.1)"); + Z; - client3.Close(); - client.ReadUntil( - "NOTICE nick :*** user@identifier detached (from 127.0.0.1)"); - Z; + client3.Close(); + client.ReadUntil( + "NOTICE nick :*** user@identifier detached (from 127.0.0.1)"); + Z; } TEST_F(ZNCTest, WatchModule) { - // TODO test other messages - // TODO test options - auto znc = Run(); - Z; - auto ircd = ConnectIRCd(); - Z; - auto client = LoginClient(); - Z; - client.Write("znc loadmod watch"); - client.Write("PRIVMSG *watch :add *"); - client.ReadUntil("Adding entry:"); - ircd.Write(":server 001 nick :Hello"); - ircd.Write(":nick JOIN :#znc"); - ircd.Write(":n!i@h PRIVMSG #znc :\001ACTION foo\001"); - client.ReadUntil( - ":$*!watch@znc.in PRIVMSG nick :* CTCP: n [ACTION foo] to [#znc]"); + // TODO test other messages + // TODO test options + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto client = LoginClient(); + Z; + client.Write("znc loadmod watch"); + client.Write("PRIVMSG *watch :add *"); + client.ReadUntil("Adding entry:"); + ircd.Write(":server 001 nick :Hello"); + ircd.Write(":nick JOIN :#znc"); + ircd.Write(":n!i@h PRIVMSG #znc :\001ACTION foo\001"); + client.ReadUntil( + ":$*!watch@znc.in PRIVMSG nick :* CTCP: n [ACTION foo] to [#znc]"); } } // namespace diff --git a/test/MessageTest.cpp b/test/MessageTest.cpp index af3030d9..8a079e40 100644 --- a/test/MessageTest.cpp +++ b/test/MessageTest.cpp @@ -23,460 +23,460 @@ using ::testing::IsEmpty; using ::testing::ContainerEq; TEST(MessageTest, SetParam) { - CMessage msg; + CMessage msg; - msg.SetParam(1, "bar"); - EXPECT_THAT(msg.GetParams(), ContainerEq(VCString{"", "bar"})); + msg.SetParam(1, "bar"); + EXPECT_THAT(msg.GetParams(), ContainerEq(VCString{"", "bar"})); - msg.SetParam(0, "foo"); - EXPECT_THAT(msg.GetParams(), ContainerEq(VCString{"foo", "bar"})); + msg.SetParam(0, "foo"); + EXPECT_THAT(msg.GetParams(), ContainerEq(VCString{"foo", "bar"})); - msg.SetParam(3, "baz"); - EXPECT_THAT(msg.GetParams(), - ContainerEq(VCString{"foo", "bar", "", "baz"})); + msg.SetParam(3, "baz"); + EXPECT_THAT(msg.GetParams(), + ContainerEq(VCString{"foo", "bar", "", "baz"})); } TEST(MessageTest, GetParams) { - EXPECT_EQ("", CMessage("CMD").GetParams(0)); - EXPECT_EQ("", CMessage("CMD").GetParams(1)); - EXPECT_EQ("", CMessage("CMD").GetParams(-1)); + EXPECT_EQ("", CMessage("CMD").GetParams(0)); + EXPECT_EQ("", CMessage("CMD").GetParams(1)); + EXPECT_EQ("", CMessage("CMD").GetParams(-1)); - EXPECT_EQ("", CMessage("CMD").GetParams(0, 0)); - EXPECT_EQ("", CMessage("CMD").GetParams(1, 0)); - EXPECT_EQ("", CMessage("CMD").GetParams(-1, 0)); + EXPECT_EQ("", CMessage("CMD").GetParams(0, 0)); + EXPECT_EQ("", CMessage("CMD").GetParams(1, 0)); + EXPECT_EQ("", CMessage("CMD").GetParams(-1, 0)); - EXPECT_EQ("", CMessage("CMD").GetParams(0, 1)); - EXPECT_EQ("", CMessage("CMD").GetParams(1, 1)); - EXPECT_EQ("", CMessage("CMD").GetParams(-1, 1)); + EXPECT_EQ("", CMessage("CMD").GetParams(0, 1)); + EXPECT_EQ("", CMessage("CMD").GetParams(1, 1)); + EXPECT_EQ("", CMessage("CMD").GetParams(-1, 1)); - EXPECT_EQ("", CMessage("CMD").GetParams(0, 10)); - EXPECT_EQ("", CMessage("CMD").GetParams(1, 10)); - EXPECT_EQ("", CMessage("CMD").GetParams(-1, 10)); + EXPECT_EQ("", CMessage("CMD").GetParams(0, 10)); + EXPECT_EQ("", CMessage("CMD").GetParams(1, 10)); + EXPECT_EQ("", CMessage("CMD").GetParams(-1, 10)); - EXPECT_EQ("p1 :p2 p3", CMessage("CMD p1 :p2 p3").GetParams(0)); - EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1)); + EXPECT_EQ("p1 :p2 p3", CMessage("CMD p1 :p2 p3").GetParams(0)); + EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(0, 0)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(1, 0)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 0)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(0, 0)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(1, 0)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 0)); - EXPECT_EQ("p1", CMessage("CMD p1 :p2 p3").GetParams(0, 1)); - EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1, 1)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 1)); + EXPECT_EQ("p1", CMessage("CMD p1 :p2 p3").GetParams(0, 1)); + EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1, 1)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 1)); - EXPECT_EQ("p1 :p2 p3", CMessage("CMD p1 :p2 p3").GetParams(0, 10)); - EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1, 10)); - EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 10)); + EXPECT_EQ("p1 :p2 p3", CMessage("CMD p1 :p2 p3").GetParams(0, 10)); + EXPECT_EQ(":p2 p3", CMessage("CMD p1 :p2 p3").GetParams(1, 10)); + EXPECT_EQ("", CMessage("CMD p1 :p2 p3").GetParams(-1, 10)); } TEST(MessageTest, ToString) { - EXPECT_EQ("CMD", CMessage("CMD").ToString()); - EXPECT_EQ("CMD p1", CMessage("CMD p1").ToString()); - EXPECT_EQ("CMD p1 p2", CMessage("CMD p1 p2").ToString()); - EXPECT_EQ("CMD :p p p", CMessage("CMD :p p p").ToString()); - EXPECT_EQ(":irc.znc.in", CMessage(":irc.znc.in").ToString()); - EXPECT_EQ(":irc.znc.in CMD", CMessage(":irc.znc.in CMD").ToString()); - EXPECT_EQ(":irc.znc.in CMD p1", CMessage(":irc.znc.in CMD p1").ToString()); - EXPECT_EQ(":irc.znc.in CMD p1 p2", - CMessage(":irc.znc.in CMD p1 p2").ToString()); - EXPECT_EQ(":irc.znc.in CMD :p p p", - CMessage(":irc.znc.in CMD :p p p").ToString()); - EXPECT_EQ(":irc.znc.in CMD :", CMessage(":irc.znc.in CMD :").ToString()); + EXPECT_EQ("CMD", CMessage("CMD").ToString()); + EXPECT_EQ("CMD p1", CMessage("CMD p1").ToString()); + EXPECT_EQ("CMD p1 p2", CMessage("CMD p1 p2").ToString()); + EXPECT_EQ("CMD :p p p", CMessage("CMD :p p p").ToString()); + EXPECT_EQ(":irc.znc.in", CMessage(":irc.znc.in").ToString()); + EXPECT_EQ(":irc.znc.in CMD", CMessage(":irc.znc.in CMD").ToString()); + EXPECT_EQ(":irc.znc.in CMD p1", CMessage(":irc.znc.in CMD p1").ToString()); + EXPECT_EQ(":irc.znc.in CMD p1 p2", + CMessage(":irc.znc.in CMD p1 p2").ToString()); + EXPECT_EQ(":irc.znc.in CMD :p p p", + CMessage(":irc.znc.in CMD :p p p").ToString()); + EXPECT_EQ(":irc.znc.in CMD :", CMessage(":irc.znc.in CMD :").ToString()); - EXPECT_EQ("CMD", CMessage(CNick(), "CMD").ToString()); - EXPECT_EQ("CMD p1", CMessage(CNick(), "CMD", {"p1"}).ToString()); - EXPECT_EQ("CMD p1 p2", CMessage(CNick(), "CMD", {"p1", "p2"}).ToString()); - EXPECT_EQ("CMD :p p p", CMessage(CNick(), "CMD", {"p p p"}).ToString()); - EXPECT_EQ(":irc.znc.in", CMessage(CNick(":irc.znc.in"), "").ToString()); - EXPECT_EQ(":irc.znc.in CMD", - CMessage(CNick(":irc.znc.in"), "CMD").ToString()); - EXPECT_EQ(":irc.znc.in CMD p1", - CMessage(CNick(":irc.znc.in"), "CMD", {"p1"}).ToString()); - EXPECT_EQ(":irc.znc.in CMD p1 p2", - CMessage(CNick(":irc.znc.in"), "CMD", {"p1", "p2"}).ToString()); - EXPECT_EQ(":irc.znc.in CMD :p p p", - CMessage(CNick(":irc.znc.in"), "CMD", {"p p p"}).ToString()); - EXPECT_EQ(":irc.znc.in CMD :", - CMessage(CNick(":irc.znc.in"), "CMD", {""}).ToString()); + EXPECT_EQ("CMD", CMessage(CNick(), "CMD").ToString()); + EXPECT_EQ("CMD p1", CMessage(CNick(), "CMD", {"p1"}).ToString()); + EXPECT_EQ("CMD p1 p2", CMessage(CNick(), "CMD", {"p1", "p2"}).ToString()); + EXPECT_EQ("CMD :p p p", CMessage(CNick(), "CMD", {"p p p"}).ToString()); + EXPECT_EQ(":irc.znc.in", CMessage(CNick(":irc.znc.in"), "").ToString()); + EXPECT_EQ(":irc.znc.in CMD", + CMessage(CNick(":irc.znc.in"), "CMD").ToString()); + EXPECT_EQ(":irc.znc.in CMD p1", + CMessage(CNick(":irc.znc.in"), "CMD", {"p1"}).ToString()); + EXPECT_EQ(":irc.znc.in CMD p1 p2", + CMessage(CNick(":irc.znc.in"), "CMD", {"p1", "p2"}).ToString()); + EXPECT_EQ(":irc.znc.in CMD :p p p", + CMessage(CNick(":irc.znc.in"), "CMD", {"p p p"}).ToString()); + EXPECT_EQ(":irc.znc.in CMD :", + CMessage(CNick(":irc.znc.in"), "CMD", {""}).ToString()); - // #1045 - retain the colon if it was there - EXPECT_EQ(":services. 328 user #chan http://znc.in", - CMessage(":services. 328 user #chan http://znc.in").ToString()); - EXPECT_EQ(":services. 328 user #chan :http://znc.in", - CMessage(":services. 328 user #chan :http://znc.in").ToString()); + // #1045 - retain the colon if it was there + EXPECT_EQ(":services. 328 user #chan http://znc.in", + CMessage(":services. 328 user #chan http://znc.in").ToString()); + EXPECT_EQ(":services. 328 user #chan :http://znc.in", + CMessage(":services. 328 user #chan :http://znc.in").ToString()); } TEST(MessageTest, Tags) { - EXPECT_THAT(CMessage("").GetTags(), IsEmpty()); - EXPECT_THAT( - CMessage(":nick!ident@host PRIVMSG #chan :hello world").GetTags(), - IsEmpty()); + EXPECT_THAT(CMessage("").GetTags(), IsEmpty()); + EXPECT_THAT( + CMessage(":nick!ident@host PRIVMSG #chan :hello world").GetTags(), + IsEmpty()); - EXPECT_THAT(CMessage("@a=b").GetTags(), ContainerEq(MCString{{"a", "b"}})); - EXPECT_THAT( - CMessage("@a=b :nick!ident@host PRIVMSG #chan :hello world").GetTags(), - ContainerEq(MCString{{"a", "b"}})); - EXPECT_THAT(CMessage("@a=b :rest").GetTags(), - ContainerEq(MCString{{"a", "b"}})); + EXPECT_THAT(CMessage("@a=b").GetTags(), ContainerEq(MCString{{"a", "b"}})); + EXPECT_THAT( + CMessage("@a=b :nick!ident@host PRIVMSG #chan :hello world").GetTags(), + ContainerEq(MCString{{"a", "b"}})); + EXPECT_THAT(CMessage("@a=b :rest").GetTags(), + ContainerEq(MCString{{"a", "b"}})); - EXPECT_THAT( - CMessage("@ab=cdef;znc.in/gh-ij=klmn,op :rest").GetTags(), - ContainerEq(MCString{{"ab", "cdef"}, {"znc.in/gh-ij", "klmn,op"}})); - EXPECT_THAT(CMessage("@a===b== :rest").GetTags(), - ContainerEq(MCString{{"a", "==b=="}})); + EXPECT_THAT( + CMessage("@ab=cdef;znc.in/gh-ij=klmn,op :rest").GetTags(), + ContainerEq(MCString{{"ab", "cdef"}, {"znc.in/gh-ij", "klmn,op"}})); + EXPECT_THAT(CMessage("@a===b== :rest").GetTags(), + ContainerEq(MCString{{"a", "==b=="}})); - EXPECT_THAT(CMessage("@a;b=c;d :rest").GetTags(), - ContainerEq(MCString{{"a", ""}, {"b", "c"}, {"d", ""}})); + EXPECT_THAT(CMessage("@a;b=c;d :rest").GetTags(), + ContainerEq(MCString{{"a", ""}, {"b", "c"}, {"d", ""}})); - EXPECT_THAT( - CMessage( - R"(@semi-colon=\:;space=\s;NUL=\0;backslash=\\;CR=\r;LF=\n :rest)") - .GetTags(), - ContainerEq(MCString{{"semi-colon", ";"}, - {"space", " "}, - {"NUL", {'\0'}}, - {"backslash", "\\"}, - {"CR", {'\r'}}, - {"LF", {'\n'}}})); + EXPECT_THAT( + CMessage( + R"(@semi-colon=\:;space=\s;NUL=\0;backslash=\\;CR=\r;LF=\n :rest)") + .GetTags(), + ContainerEq(MCString{{"semi-colon", ";"}, + {"space", " "}, + {"NUL", {'\0'}}, + {"backslash", "\\"}, + {"CR", {'\r'}}, + {"LF", {'\n'}}})); - EXPECT_THAT(CMessage(R"(@a=\:\s\\\r\n :rest)").GetTags(), - ContainerEq(MCString{{"a", "; \\\r\n"}})); + EXPECT_THAT(CMessage(R"(@a=\:\s\\\r\n :rest)").GetTags(), + ContainerEq(MCString{{"a", "; \\\r\n"}})); - CMessage msg(":rest"); - msg.SetTags({{"a", "b"}}); - EXPECT_EQ("@a=b :rest", msg.ToString()); + CMessage msg(":rest"); + msg.SetTags({{"a", "b"}}); + EXPECT_EQ("@a=b :rest", msg.ToString()); - msg.SetTags({{"a", "b"}, {"c", "d"}}); - EXPECT_EQ("@a=b;c=d :rest", msg.ToString()); + msg.SetTags({{"a", "b"}, {"c", "d"}}); + EXPECT_EQ("@a=b;c=d :rest", msg.ToString()); - msg.SetTags({{"a", "b"}, {"c", "d"}, {"e", ""}}); - EXPECT_EQ("@a=b;c=d;e :rest", msg.ToString()); + msg.SetTags({{"a", "b"}, {"c", "d"}, {"e", ""}}); + EXPECT_EQ("@a=b;c=d;e :rest", msg.ToString()); - msg.SetTags({{"semi-colon", ";"}, - {"space", " "}, - {"NUL", {'\0'}}, - {"backslash", "\\"}, - {"CR", {'\r'}}, - {"LF", {'\n'}}}); - EXPECT_EQ( - R"(@CR=\r;LF=\n;NUL=\0;backslash=\\;semi-colon=\:;space=\s :rest)", - msg.ToString()); + msg.SetTags({{"semi-colon", ";"}, + {"space", " "}, + {"NUL", {'\0'}}, + {"backslash", "\\"}, + {"CR", {'\r'}}, + {"LF", {'\n'}}}); + EXPECT_EQ( + R"(@CR=\r;LF=\n;NUL=\0;backslash=\\;semi-colon=\:;space=\s :rest)", + msg.ToString()); - msg.SetTags({{"a", "; \\\r\n"}}); - EXPECT_EQ(R"(@a=\:\s\\\r\n :rest)", msg.ToString()); + msg.SetTags({{"a", "; \\\r\n"}}); + EXPECT_EQ(R"(@a=\:\s\\\r\n :rest)", msg.ToString()); } TEST(MessageTest, FormatFlags) { - const CString line = "@foo=bar :irc.example.com COMMAND param"; + const CString line = "@foo=bar :irc.example.com COMMAND param"; - CMessage msg(line); - EXPECT_EQ(line, msg.ToString()); - EXPECT_EQ(":irc.example.com COMMAND param", - msg.ToString(CMessage::ExcludeTags)); - EXPECT_EQ("@foo=bar COMMAND param", msg.ToString(CMessage::ExcludePrefix)); - EXPECT_EQ("COMMAND param", - msg.ToString(CMessage::ExcludePrefix | CMessage::ExcludeTags)); + CMessage msg(line); + EXPECT_EQ(line, msg.ToString()); + EXPECT_EQ(":irc.example.com COMMAND param", + msg.ToString(CMessage::ExcludeTags)); + EXPECT_EQ("@foo=bar COMMAND param", msg.ToString(CMessage::ExcludePrefix)); + EXPECT_EQ("COMMAND param", + msg.ToString(CMessage::ExcludePrefix | CMessage::ExcludeTags)); } TEST(MessageTest, Equals) { - EXPECT_TRUE(CMessage("JOIN #chan").Equals(CMessage("JOIN #chan"))); - EXPECT_FALSE(CMessage("JOIN #chan").Equals(CMessage("JOIN #znc"))); + EXPECT_TRUE(CMessage("JOIN #chan").Equals(CMessage("JOIN #chan"))); + EXPECT_FALSE(CMessage("JOIN #chan").Equals(CMessage("JOIN #znc"))); - EXPECT_TRUE( - CMessage(":nick JOIN #chan").Equals(CMessage(":nick JOIN #chan"))); - EXPECT_FALSE( - CMessage(":nick JOIN #chan").Equals(CMessage(":nick JOIN #znc"))); - EXPECT_FALSE( - CMessage(":nick JOIN #chan").Equals(CMessage(":someone JOIN #chan"))); + EXPECT_TRUE( + CMessage(":nick JOIN #chan").Equals(CMessage(":nick JOIN #chan"))); + EXPECT_FALSE( + CMessage(":nick JOIN #chan").Equals(CMessage(":nick JOIN #znc"))); + EXPECT_FALSE( + CMessage(":nick JOIN #chan").Equals(CMessage(":someone JOIN #chan"))); - EXPECT_TRUE( - CMessage("PRIVMSG nick :hi").Equals(CMessage("PRIVMSG nick :hi"))); - EXPECT_TRUE( - CMessage("PRIVMSG nick hi").Equals(CMessage("PRIVMSG nick :hi"))); - EXPECT_TRUE( - CMessage("PRIVMSG nick :hi").Equals(CMessage("PRIVMSG nick hi"))); - EXPECT_TRUE( - CMessage("PRIVMSG nick hi").Equals(CMessage("PRIVMSG nick hi"))); + EXPECT_TRUE( + CMessage("PRIVMSG nick :hi").Equals(CMessage("PRIVMSG nick :hi"))); + EXPECT_TRUE( + CMessage("PRIVMSG nick hi").Equals(CMessage("PRIVMSG nick :hi"))); + EXPECT_TRUE( + CMessage("PRIVMSG nick :hi").Equals(CMessage("PRIVMSG nick hi"))); + EXPECT_TRUE( + CMessage("PRIVMSG nick hi").Equals(CMessage("PRIVMSG nick hi"))); - EXPECT_TRUE(CMessage("CMD nick p1 p2").Equals(CMessage("CMD nick p1 p2"))); - EXPECT_TRUE( - CMessage("CMD nick :p1 p2").Equals(CMessage("CMD nick :p1 p2"))); - EXPECT_TRUE(CMessage("CMD nick p1 :p2").Equals(CMessage("CMD nick p1 p2"))); - EXPECT_FALSE( - CMessage("CMD nick :p1 p2").Equals(CMessage("CMD nick p1 p2"))); + EXPECT_TRUE(CMessage("CMD nick p1 p2").Equals(CMessage("CMD nick p1 p2"))); + EXPECT_TRUE( + CMessage("CMD nick :p1 p2").Equals(CMessage("CMD nick :p1 p2"))); + EXPECT_TRUE(CMessage("CMD nick p1 :p2").Equals(CMessage("CMD nick p1 p2"))); + EXPECT_FALSE( + CMessage("CMD nick :p1 p2").Equals(CMessage("CMD nick p1 p2"))); - EXPECT_TRUE(CMessage("@t=now :sender CMD p") - .Equals(CMessage("@t=then :sender CMD p"))); + EXPECT_TRUE(CMessage("@t=now :sender CMD p") + .Equals(CMessage("@t=then :sender CMD p"))); } TEST(MessageTest, Type) { - EXPECT_EQ(CMessage::Type::Unknown, CMessage("FOO").GetType()); - EXPECT_EQ(CMessage::Type::Account, CMessage("ACCOUNT").GetType()); - EXPECT_EQ(CMessage::Type::Away, CMessage("AWAY").GetType()); - EXPECT_EQ(CMessage::Type::Capability, CMessage("CAP").GetType()); - EXPECT_EQ(CMessage::Type::Error, CMessage("ERROR").GetType()); - EXPECT_EQ(CMessage::Type::Invite, CMessage("INVITE").GetType()); - EXPECT_EQ(CMessage::Type::Join, CMessage("JOIN").GetType()); - EXPECT_EQ(CMessage::Type::Kick, CMessage("KICK").GetType()); - EXPECT_EQ(CMessage::Type::Mode, CMessage("MODE").GetType()); - EXPECT_EQ(CMessage::Type::Nick, CMessage("NICK").GetType()); - EXPECT_EQ(CMessage::Type::Notice, CMessage("NOTICE").GetType()); - EXPECT_EQ(CMessage::Type::Numeric, CMessage("123").GetType()); - EXPECT_EQ(CMessage::Type::Part, CMessage("PART").GetType()); - EXPECT_EQ(CMessage::Type::Ping, CMessage("PING").GetType()); - EXPECT_EQ(CMessage::Type::Pong, CMessage("PONG").GetType()); - EXPECT_EQ(CMessage::Type::Quit, CMessage("QUIT").GetType()); - EXPECT_EQ(CMessage::Type::Text, CMessage("PRIVMSG").GetType()); - EXPECT_EQ(CMessage::Type::Topic, CMessage("TOPIC").GetType()); - EXPECT_EQ(CMessage::Type::Wallops, CMessage("WALLOPS").GetType()); + EXPECT_EQ(CMessage::Type::Unknown, CMessage("FOO").GetType()); + EXPECT_EQ(CMessage::Type::Account, CMessage("ACCOUNT").GetType()); + EXPECT_EQ(CMessage::Type::Away, CMessage("AWAY").GetType()); + EXPECT_EQ(CMessage::Type::Capability, CMessage("CAP").GetType()); + EXPECT_EQ(CMessage::Type::Error, CMessage("ERROR").GetType()); + EXPECT_EQ(CMessage::Type::Invite, CMessage("INVITE").GetType()); + EXPECT_EQ(CMessage::Type::Join, CMessage("JOIN").GetType()); + EXPECT_EQ(CMessage::Type::Kick, CMessage("KICK").GetType()); + EXPECT_EQ(CMessage::Type::Mode, CMessage("MODE").GetType()); + EXPECT_EQ(CMessage::Type::Nick, CMessage("NICK").GetType()); + EXPECT_EQ(CMessage::Type::Notice, CMessage("NOTICE").GetType()); + EXPECT_EQ(CMessage::Type::Numeric, CMessage("123").GetType()); + EXPECT_EQ(CMessage::Type::Part, CMessage("PART").GetType()); + EXPECT_EQ(CMessage::Type::Ping, CMessage("PING").GetType()); + EXPECT_EQ(CMessage::Type::Pong, CMessage("PONG").GetType()); + EXPECT_EQ(CMessage::Type::Quit, CMessage("QUIT").GetType()); + EXPECT_EQ(CMessage::Type::Text, CMessage("PRIVMSG").GetType()); + EXPECT_EQ(CMessage::Type::Topic, CMessage("TOPIC").GetType()); + EXPECT_EQ(CMessage::Type::Wallops, CMessage("WALLOPS").GetType()); - CMessage msg; - EXPECT_EQ(CMessage::Type::Unknown, msg.GetType()); + CMessage msg; + EXPECT_EQ(CMessage::Type::Unknown, msg.GetType()); - msg.SetCommand("PRIVMSG"); - EXPECT_EQ(CMessage::Type::Text, msg.GetType()); + msg.SetCommand("PRIVMSG"); + EXPECT_EQ(CMessage::Type::Text, msg.GetType()); - msg.SetParams({"target", "\001ACTION foo\001"}); - EXPECT_EQ(CMessage::Type::Action, msg.GetType()); + msg.SetParams({"target", "\001ACTION foo\001"}); + EXPECT_EQ(CMessage::Type::Action, msg.GetType()); - msg.SetParam(1, "\001foo\001"); - EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); + msg.SetParam(1, "\001foo\001"); + EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); - msg.SetCommand("NOTICE"); - EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); + msg.SetCommand("NOTICE"); + EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); - msg.SetParam(1, "foo"); - EXPECT_EQ(CMessage::Type::Notice, msg.GetType()); + msg.SetParam(1, "foo"); + EXPECT_EQ(CMessage::Type::Notice, msg.GetType()); } TEST(MessageTest, Target) { - CTargetMessage msg; - msg.Parse(":sender PRIVMSG #chan :foo bar"); - EXPECT_EQ("#chan", msg.GetTarget()); - msg.SetTarget("#znc"); - EXPECT_EQ("#znc", msg.GetTarget()); - EXPECT_EQ(":sender PRIVMSG #znc :foo bar", msg.ToString()); + CTargetMessage msg; + msg.Parse(":sender PRIVMSG #chan :foo bar"); + EXPECT_EQ("#chan", msg.GetTarget()); + msg.SetTarget("#znc"); + EXPECT_EQ("#znc", msg.GetTarget()); + EXPECT_EQ(":sender PRIVMSG #znc :foo bar", msg.ToString()); } TEST(MessageTest, ChanAction) { - CActionMessage msg; - msg.Parse(":sender PRIVMSG #chan :\001ACTION ACTS\001"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("ACTS", msg.GetText()); - EXPECT_EQ(CMessage::Type::Action, msg.GetType()); + CActionMessage msg; + msg.Parse(":sender PRIVMSG #chan :\001ACTION ACTS\001"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("ACTS", msg.GetText()); + EXPECT_EQ(CMessage::Type::Action, msg.GetType()); - msg.SetText("foo bar"); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG #chan :\001ACTION foo bar\001", msg.ToString()); + msg.SetText("foo bar"); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG #chan :\001ACTION foo bar\001", msg.ToString()); } TEST(MessageTest, ChanCTCP) { - CCTCPMessage msg; - msg.Parse(":sender PRIVMSG #chan :\001text\001"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("text", msg.GetText()); - EXPECT_FALSE(msg.IsReply()); - EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); + CCTCPMessage msg; + msg.Parse(":sender PRIVMSG #chan :\001text\001"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("text", msg.GetText()); + EXPECT_FALSE(msg.IsReply()); + EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); - msg.SetText("foo bar"); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG #chan :\001foo bar\001", msg.ToString()); + msg.SetText("foo bar"); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG #chan :\001foo bar\001", msg.ToString()); } TEST(MessageTest, ChanMsg) { - CTextMessage msg; - msg.Parse(":sender PRIVMSG #chan :text"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("text", msg.GetText()); - EXPECT_EQ(CMessage::Type::Text, msg.GetType()); + CTextMessage msg; + msg.Parse(":sender PRIVMSG #chan :text"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("text", msg.GetText()); + EXPECT_EQ(CMessage::Type::Text, msg.GetType()); - msg.SetText("foo bar"); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG #chan :foo bar", msg.ToString()); + msg.SetText("foo bar"); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG #chan :foo bar", msg.ToString()); } TEST(MessageTest, CTCPReply) { - CCTCPMessage msg; - msg.Parse(":sender NOTICE nick :\001FOO bar\001"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("NOTICE", msg.GetCommand()); - EXPECT_EQ("nick", msg.GetTarget()); - EXPECT_EQ("FOO bar", msg.GetText()); - EXPECT_TRUE(msg.IsReply()); - EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); + CCTCPMessage msg; + msg.Parse(":sender NOTICE nick :\001FOO bar\001"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("NOTICE", msg.GetCommand()); + EXPECT_EQ("nick", msg.GetTarget()); + EXPECT_EQ("FOO bar", msg.GetText()); + EXPECT_TRUE(msg.IsReply()); + EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); - msg.SetText("BAR foo"); - EXPECT_EQ("BAR foo", msg.GetText()); - EXPECT_EQ(":sender NOTICE nick :\001BAR foo\001", msg.ToString()); + msg.SetText("BAR foo"); + EXPECT_EQ("BAR foo", msg.GetText()); + EXPECT_EQ(":sender NOTICE nick :\001BAR foo\001", msg.ToString()); } TEST(MessageTest, Kick) { - CKickMessage msg; - msg.Parse(":nick KICK #chan person :reason"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("KICK", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("person", msg.GetKickedNick()); - EXPECT_EQ("reason", msg.GetReason()); - EXPECT_EQ(CMessage::Type::Kick, msg.GetType()); + CKickMessage msg; + msg.Parse(":nick KICK #chan person :reason"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("KICK", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("person", msg.GetKickedNick()); + EXPECT_EQ("reason", msg.GetReason()); + EXPECT_EQ(CMessage::Type::Kick, msg.GetType()); - msg.SetKickedNick("noone"); - EXPECT_EQ("noone", msg.GetKickedNick()); - msg.SetReason("test"); - EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick KICK #chan noone :test", msg.ToString()); + msg.SetKickedNick("noone"); + EXPECT_EQ("noone", msg.GetKickedNick()); + msg.SetReason("test"); + EXPECT_EQ("test", msg.GetReason()); + EXPECT_EQ(":nick KICK #chan noone :test", msg.ToString()); } TEST(MessageTest, Join) { - CJoinMessage msg; - msg.Parse(":nick JOIN #chan"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("JOIN", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ(CMessage::Type::Join, msg.GetType()); + CJoinMessage msg; + msg.Parse(":nick JOIN #chan"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("JOIN", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ(CMessage::Type::Join, msg.GetType()); - EXPECT_EQ(":nick JOIN #chan", msg.ToString()); + EXPECT_EQ(":nick JOIN #chan", msg.ToString()); } TEST(MessageTest, Mode) { - CModeMessage msg; - msg.Parse(":nick MODE #chan +k foo"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("MODE", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("+k foo", msg.GetModes()); + CModeMessage msg; + msg.Parse(":nick MODE #chan +k foo"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("MODE", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("+k foo", msg.GetModes()); - EXPECT_EQ(":nick MODE #chan +k foo", msg.ToString()); + EXPECT_EQ(":nick MODE #chan +k foo", msg.ToString()); - msg.Parse(":nick MODE nick :+i"); - EXPECT_EQ("+i", msg.GetModes()); + msg.Parse(":nick MODE nick :+i"); + EXPECT_EQ("+i", msg.GetModes()); - EXPECT_EQ(":nick MODE nick :+i", msg.ToString()); + EXPECT_EQ(":nick MODE nick :+i", msg.ToString()); } TEST(MessageTest, Nick) { - CNickMessage msg; - msg.Parse(":nick NICK person"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("NICK", msg.GetCommand()); - EXPECT_EQ("nick", msg.GetOldNick()); - EXPECT_EQ("person", msg.GetNewNick()); - EXPECT_EQ(CMessage::Type::Nick, msg.GetType()); + CNickMessage msg; + msg.Parse(":nick NICK person"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("NICK", msg.GetCommand()); + EXPECT_EQ("nick", msg.GetOldNick()); + EXPECT_EQ("person", msg.GetNewNick()); + EXPECT_EQ(CMessage::Type::Nick, msg.GetType()); - msg.SetNewNick("test"); - EXPECT_EQ("test", msg.GetNewNick()); - EXPECT_EQ(":nick NICK test", msg.ToString()); + msg.SetNewNick("test"); + EXPECT_EQ("test", msg.GetNewNick()); + EXPECT_EQ(":nick NICK test", msg.ToString()); } TEST(MessageTest, Numeric) { - CNumericMessage msg; - msg.Parse(":server 123 user :foo bar"); - EXPECT_EQ("server", msg.GetNick().GetNick()); - EXPECT_EQ("123", msg.GetCommand()); - EXPECT_EQ(123u, msg.GetCode()); - EXPECT_EQ(CMessage::Type::Numeric, msg.GetType()); + CNumericMessage msg; + msg.Parse(":server 123 user :foo bar"); + EXPECT_EQ("server", msg.GetNick().GetNick()); + EXPECT_EQ("123", msg.GetCommand()); + EXPECT_EQ(123u, msg.GetCode()); + EXPECT_EQ(CMessage::Type::Numeric, msg.GetType()); - EXPECT_EQ(":server 123 user :foo bar", msg.ToString()); + EXPECT_EQ(":server 123 user :foo bar", msg.ToString()); } TEST(MessageTest, Part) { - CPartMessage msg; - msg.Parse(":nick PART #chan :reason"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("PART", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("reason", msg.GetReason()); - EXPECT_EQ(CMessage::Type::Part, msg.GetType()); + CPartMessage msg; + msg.Parse(":nick PART #chan :reason"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("PART", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("reason", msg.GetReason()); + EXPECT_EQ(CMessage::Type::Part, msg.GetType()); - msg.SetReason("test"); - EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick PART #chan :test", msg.ToString()); + msg.SetReason("test"); + EXPECT_EQ("test", msg.GetReason()); + EXPECT_EQ(":nick PART #chan :test", msg.ToString()); } TEST(MessageTest, PrivAction) { - CActionMessage msg; - msg.Parse(":sender PRIVMSG receiver :\001ACTION ACTS\001"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("receiver", msg.GetTarget()); - EXPECT_EQ("ACTS", msg.GetText()); - EXPECT_EQ(CMessage::Type::Action, msg.GetType()); + CActionMessage msg; + msg.Parse(":sender PRIVMSG receiver :\001ACTION ACTS\001"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("receiver", msg.GetTarget()); + EXPECT_EQ("ACTS", msg.GetText()); + EXPECT_EQ(CMessage::Type::Action, msg.GetType()); - msg.SetText("foo bar"); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG receiver :\001ACTION foo bar\001", - msg.ToString()); + msg.SetText("foo bar"); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG receiver :\001ACTION foo bar\001", + msg.ToString()); } TEST(MessageTest, PrivCTCP) { - CCTCPMessage msg; - msg.Parse(":sender PRIVMSG receiver :\001text\001"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("receiver", msg.GetTarget()); - EXPECT_EQ("text", msg.GetText()); - EXPECT_FALSE(msg.IsReply()); - EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); + CCTCPMessage msg; + msg.Parse(":sender PRIVMSG receiver :\001text\001"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("receiver", msg.GetTarget()); + EXPECT_EQ("text", msg.GetText()); + EXPECT_FALSE(msg.IsReply()); + EXPECT_EQ(CMessage::Type::CTCP, msg.GetType()); - msg.SetText("foo bar"); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG receiver :\001foo bar\001", msg.ToString()); + msg.SetText("foo bar"); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG receiver :\001foo bar\001", msg.ToString()); } TEST(MessageTest, PrivMsg) { - CTextMessage msg; - msg.Parse(":sender PRIVMSG receiver :foo bar"); - EXPECT_EQ("sender", msg.GetNick().GetNick()); - EXPECT_EQ("PRIVMSG", msg.GetCommand()); - EXPECT_EQ("receiver", msg.GetTarget()); - EXPECT_EQ("foo bar", msg.GetText()); - EXPECT_EQ(CMessage::Type::Text, msg.GetType()); + CTextMessage msg; + msg.Parse(":sender PRIVMSG receiver :foo bar"); + EXPECT_EQ("sender", msg.GetNick().GetNick()); + EXPECT_EQ("PRIVMSG", msg.GetCommand()); + EXPECT_EQ("receiver", msg.GetTarget()); + EXPECT_EQ("foo bar", msg.GetText()); + EXPECT_EQ(CMessage::Type::Text, msg.GetType()); - msg.SetText(":)"); - EXPECT_EQ(":)", msg.GetText()); - EXPECT_EQ(":sender PRIVMSG receiver ::)", msg.ToString()); + msg.SetText(":)"); + EXPECT_EQ(":)", msg.GetText()); + EXPECT_EQ(":sender PRIVMSG receiver ::)", msg.ToString()); } TEST(MessageTest, Quit) { - CQuitMessage msg; - msg.Parse(":nick QUIT :reason"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("QUIT", msg.GetCommand()); - EXPECT_EQ("reason", msg.GetReason()); - EXPECT_EQ(CMessage::Type::Quit, msg.GetType()); + CQuitMessage msg; + msg.Parse(":nick QUIT :reason"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("QUIT", msg.GetCommand()); + EXPECT_EQ("reason", msg.GetReason()); + EXPECT_EQ(CMessage::Type::Quit, msg.GetType()); - msg.SetReason("test"); - EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick QUIT :test", msg.ToString()); + msg.SetReason("test"); + EXPECT_EQ("test", msg.GetReason()); + EXPECT_EQ(":nick QUIT :test", msg.ToString()); } TEST(MessageTest, Topic) { - CTopicMessage msg; - msg.Parse(":nick TOPIC #chan :topic"); - EXPECT_EQ("nick", msg.GetNick().GetNick()); - EXPECT_EQ("TOPIC", msg.GetCommand()); - EXPECT_EQ("#chan", msg.GetTarget()); - EXPECT_EQ("topic", msg.GetTopic()); - EXPECT_EQ(CMessage::Type::Topic, msg.GetType()); + CTopicMessage msg; + msg.Parse(":nick TOPIC #chan :topic"); + EXPECT_EQ("nick", msg.GetNick().GetNick()); + EXPECT_EQ("TOPIC", msg.GetCommand()); + EXPECT_EQ("#chan", msg.GetTarget()); + EXPECT_EQ("topic", msg.GetTopic()); + EXPECT_EQ(CMessage::Type::Topic, msg.GetType()); - msg.SetTopic("test"); - EXPECT_EQ("test", msg.GetTopic()); - EXPECT_EQ(":nick TOPIC #chan :test", msg.ToString()); + msg.SetTopic("test"); + EXPECT_EQ("test", msg.GetTopic()); + EXPECT_EQ(":nick TOPIC #chan :test", msg.ToString()); } TEST(MessageTest, Parse) { - CMessage msg; + CMessage msg; - // #1037 - msg.Parse(":irc.znc.in PRIVMSG ::)"); - EXPECT_EQ(":)", msg.GetParam(0)); + // #1037 + msg.Parse(":irc.znc.in PRIVMSG ::)"); + EXPECT_EQ(":)", msg.GetParam(0)); } // The test data for MessageTest.Parse originates from @@ -506,62 +506,62 @@ TEST(MessageTest, Parse) { // when checking a valid message with tags and a source TEST(MessageTest, ParseWithTags) { - const CString line = - "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 :irc.example.com " - "COMMAND param1 param2 :param3 param3"; + const CString line = + "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 :irc.example.com " + "COMMAND param1 param2 :param3 param3"; - CMessage msg(line); - EXPECT_EQ(line, msg.ToString()); - EXPECT_THAT(msg.GetTags(), ContainerEq(MCString{{"tag1", "value1"}, - {"tag2", ""}, - {"vendor1/tag3", "value2"}, - {"vendor2/tag4", ""}})); - EXPECT_EQ("irc.example.com", msg.GetNick().GetNick()); - EXPECT_EQ("COMMAND", msg.GetCommand()); - EXPECT_THAT(msg.GetParams(), - ContainerEq(VCString{"param1", "param2", "param3 param3"})); + CMessage msg(line); + EXPECT_EQ(line, msg.ToString()); + EXPECT_THAT(msg.GetTags(), ContainerEq(MCString{{"tag1", "value1"}, + {"tag2", ""}, + {"vendor1/tag3", "value2"}, + {"vendor2/tag4", ""}})); + EXPECT_EQ("irc.example.com", msg.GetNick().GetNick()); + EXPECT_EQ("COMMAND", msg.GetCommand()); + EXPECT_THAT(msg.GetParams(), + ContainerEq(VCString{"param1", "param2", "param3 param3"})); } // when checking a valid message with a source but no tags TEST(MessageTest, ParseWithoutTags) { - const CString line = - ":irc.example.com COMMAND param1 param2 :param3 param3"; + const CString line = + ":irc.example.com COMMAND param1 param2 :param3 param3"; - CMessage msg(line); - EXPECT_EQ(line, msg.ToString()); - EXPECT_EQ(MCString(), msg.GetTags()); - EXPECT_EQ("irc.example.com", msg.GetNick().GetNick()); - EXPECT_EQ("COMMAND", msg.GetCommand()); - EXPECT_THAT(msg.GetParams(), - ContainerEq(VCString{"param1", "param2", "param3 param3"})); + CMessage msg(line); + EXPECT_EQ(line, msg.ToString()); + EXPECT_EQ(MCString(), msg.GetTags()); + EXPECT_EQ("irc.example.com", msg.GetNick().GetNick()); + EXPECT_EQ("COMMAND", msg.GetCommand()); + EXPECT_THAT(msg.GetParams(), + ContainerEq(VCString{"param1", "param2", "param3 param3"})); } // when checking a valid message with tags but no source TEST(MessageTest, ParseWithoutSource) { - const CString line = - "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 " - "param2 :param3 param3"; + const CString line = + "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 " + "param2 :param3 param3"; - CMessage msg(line); - EXPECT_EQ(line, msg.ToString()); - EXPECT_THAT(msg.GetTags(), ContainerEq(MCString{{"tag1", "value1"}, - {"tag2", ""}, - {"vendor1/tag3", "value2"}, - {"vendor2/tag4", ""}})); - EXPECT_EQ("", msg.GetNick().GetNick()); - EXPECT_EQ("COMMAND", msg.GetCommand()); - EXPECT_THAT(msg.GetParams(), - ContainerEq(VCString{"param1", "param2", "param3 param3"})); + CMessage msg(line); + EXPECT_EQ(line, msg.ToString()); + EXPECT_THAT(msg.GetTags(), ContainerEq(MCString{{"tag1", "value1"}, + {"tag2", ""}, + {"vendor1/tag3", "value2"}, + {"vendor2/tag4", ""}})); + EXPECT_EQ("", msg.GetNick().GetNick()); + EXPECT_EQ("COMMAND", msg.GetCommand()); + EXPECT_THAT(msg.GetParams(), + ContainerEq(VCString{"param1", "param2", "param3 param3"})); } // when checking a valid message with no tags, source or parameters TEST(MessageTest, ParseWithoutSourceAndTags) { - const CString line = "COMMAND"; + const CString line = "COMMAND"; - CMessage msg(line); - EXPECT_EQ(line, msg.ToString()); - EXPECT_EQ(MCString(), msg.GetTags()); - EXPECT_EQ("", msg.GetNick().GetNick()); - EXPECT_EQ("COMMAND", msg.GetCommand()); - EXPECT_EQ(VCString(), msg.GetParams()); + CMessage msg(line); + EXPECT_EQ(line, msg.ToString()); + EXPECT_EQ(MCString(), msg.GetTags()); + EXPECT_EQ("", msg.GetNick().GetNick()); + EXPECT_EQ("COMMAND", msg.GetCommand()); + EXPECT_EQ(VCString(), msg.GetParams()); } diff --git a/test/ModulesTest.cpp b/test/ModulesTest.cpp index f6cd3b79..2b880130 100644 --- a/test/ModulesTest.cpp +++ b/test/ModulesTest.cpp @@ -20,430 +20,430 @@ class ModulesTest : public ::testing::Test { protected: - void SetUp() { CZNC::CreateInstance(); } - void TearDown() { CZNC::DestroyInstance(); } + void SetUp() { CZNC::CreateInstance(); } + void TearDown() { CZNC::DestroyInstance(); } }; class CLegacyModule : public CModule { public: - CLegacyModule() - : CModule(nullptr, nullptr, nullptr, "legacy", "", - CModInfo::NetworkModule) {} + CLegacyModule() + : CModule(nullptr, nullptr, nullptr, "legacy", "", + CModInfo::NetworkModule) {} - EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { - sTarget = "#legacy"; - sMessage = "CLegacyModule::OnUserCTCPReply"; - return eAction; - } - EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { - sTarget = "#legacy"; - sMessage = "CLegacyModule::OnUserCTCP"; - return eAction; - } - EModRet OnUserAction(CString& sTarget, CString& sMessage) override { - sTarget = "#legacy"; - sMessage = "CLegacyModule::OnUserAction"; - return eAction; - } - EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { - sTarget = "#legacy"; - sMessage = "CLegacyModule::OnUserMsg"; - return eAction; - } - EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { - sTarget = "#legacy"; - sMessage = "CLegacyModule::OnUserNotice"; - return eAction; - } - EModRet OnUserJoin(CString& sChannel, CString& sKey) override { - sChannel = "#legacy"; - sKey = "CLegacyModule::OnUserJoin"; - return eAction; - } - EModRet OnUserPart(CString& sChannel, CString& sMessage) override { - sChannel = "#legacy"; - sMessage = "CLegacyModule::OnUserPart"; - return eAction; - } - EModRet OnUserTopic(CString& sChannel, CString& sTopic) override { - sChannel = "#legacy"; - sTopic = "CLegacyModule::OnUserTopic"; - return eAction; - } - EModRet OnUserQuit(CString& sMessage) override { - sMessage = "CLegacyModule::OnUserQuit"; - return eAction; - } + EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage) override { + sTarget = "#legacy"; + sMessage = "CLegacyModule::OnUserCTCPReply"; + return eAction; + } + EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override { + sTarget = "#legacy"; + sMessage = "CLegacyModule::OnUserCTCP"; + return eAction; + } + EModRet OnUserAction(CString& sTarget, CString& sMessage) override { + sTarget = "#legacy"; + sMessage = "CLegacyModule::OnUserAction"; + return eAction; + } + EModRet OnUserMsg(CString& sTarget, CString& sMessage) override { + sTarget = "#legacy"; + sMessage = "CLegacyModule::OnUserMsg"; + return eAction; + } + EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { + sTarget = "#legacy"; + sMessage = "CLegacyModule::OnUserNotice"; + return eAction; + } + EModRet OnUserJoin(CString& sChannel, CString& sKey) override { + sChannel = "#legacy"; + sKey = "CLegacyModule::OnUserJoin"; + return eAction; + } + EModRet OnUserPart(CString& sChannel, CString& sMessage) override { + sChannel = "#legacy"; + sMessage = "CLegacyModule::OnUserPart"; + return eAction; + } + EModRet OnUserTopic(CString& sChannel, CString& sTopic) override { + sChannel = "#legacy"; + sTopic = "CLegacyModule::OnUserTopic"; + return eAction; + } + EModRet OnUserQuit(CString& sMessage) override { + sMessage = "CLegacyModule::OnUserQuit"; + return eAction; + } - EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnCTCPReply"; - return eAction; - } - EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnPrivCTCP"; - return eAction; - } - EModRet OnChanCTCP(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnChanCTCP"; - return eAction; - } - EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnPrivAction"; - return eAction; - } - EModRet OnChanAction(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnChanAction"; - return eAction; - } - EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnPrivMsg"; - return eAction; - } - EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnChanMsg"; - return eAction; - } - EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnPrivNotice"; - return eAction; - } - EModRet OnChanNotice(CNick& Nick, CChan& Channel, - CString& sMessage) override { - Nick.Parse("legacy!znc@znc.in"); - sMessage = "CLegacyModule::OnChanNotice"; - return eAction; - } - EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { - Nick.Parse("legacy!znc@znc.in"); - sTopic = "CLegacyModule::OnTopic"; - return eAction; - } + EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnCTCPReply"; + return eAction; + } + EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnPrivCTCP"; + return eAction; + } + EModRet OnChanCTCP(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnChanCTCP"; + return eAction; + } + EModRet OnPrivAction(CNick& Nick, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnPrivAction"; + return eAction; + } + EModRet OnChanAction(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnChanAction"; + return eAction; + } + EModRet OnPrivMsg(CNick& Nick, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnPrivMsg"; + return eAction; + } + EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnChanMsg"; + return eAction; + } + EModRet OnPrivNotice(CNick& Nick, CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnPrivNotice"; + return eAction; + } + EModRet OnChanNotice(CNick& Nick, CChan& Channel, + CString& sMessage) override { + Nick.Parse("legacy!znc@znc.in"); + sMessage = "CLegacyModule::OnChanNotice"; + return eAction; + } + EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) override { + Nick.Parse("legacy!znc@znc.in"); + sTopic = "CLegacyModule::OnTopic"; + return eAction; + } - EModRet eAction = CONTINUE; + EModRet eAction = CONTINUE; }; class CMessageModule : public CModule { public: - CMessageModule() - : CModule(nullptr, nullptr, nullptr, "CMessage", "", - CModInfo::NetworkModule) {} + CMessageModule() + : CModule(nullptr, nullptr, nullptr, "CMessage", "", + CModInfo::NetworkModule) {} - EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override { - Message.SetTarget("#target"); - Message.SetText("CMessageModule::OnUserCTCPReplyMessage"); - return eAction; - } - EModRet OnUserCTCPMessage(CCTCPMessage& Message) override { - Message.SetTarget("#target"); - Message.SetText("CMessageModule::OnUserCTCPMessage"); - return eAction; - } - EModRet OnUserActionMessage(CActionMessage& Message) override { - Message.SetTarget("#target"); - Message.SetText("CMessageModule::OnUserActionMessage"); - return eAction; - } - EModRet OnUserTextMessage(CTextMessage& Message) override { - Message.SetTarget("#target"); - Message.SetText("CMessageModule::OnUserTextMessage"); - return eAction; - } - EModRet OnUserNoticeMessage(CNoticeMessage& Message) override { - Message.SetTarget("#target"); - Message.SetText("CMessageModule::OnUserNoticeMessage"); - return eAction; - } - EModRet OnUserJoinMessage(CJoinMessage& Message) override { - Message.SetTarget("#target"); - Message.SetKey("CMessageModule::OnUserJoinMessage"); - return eAction; - } - EModRet OnUserPartMessage(CPartMessage& Message) override { - Message.SetTarget("#target"); - Message.SetReason("CMessageModule::OnUserPartMessage"); - return eAction; - } - EModRet OnUserTopicMessage(CTopicMessage& Message) override { - Message.SetTarget("#target"); - Message.SetTopic("CMessageModule::OnUserTopicMessage"); - return eAction; - } - EModRet OnUserQuitMessage(CQuitMessage& Message) override { - Message.SetReason("CMessageModule::OnUserQuitMessage"); - return eAction; - } + EModRet OnUserCTCPReplyMessage(CCTCPMessage& Message) override { + Message.SetTarget("#target"); + Message.SetText("CMessageModule::OnUserCTCPReplyMessage"); + return eAction; + } + EModRet OnUserCTCPMessage(CCTCPMessage& Message) override { + Message.SetTarget("#target"); + Message.SetText("CMessageModule::OnUserCTCPMessage"); + return eAction; + } + EModRet OnUserActionMessage(CActionMessage& Message) override { + Message.SetTarget("#target"); + Message.SetText("CMessageModule::OnUserActionMessage"); + return eAction; + } + EModRet OnUserTextMessage(CTextMessage& Message) override { + Message.SetTarget("#target"); + Message.SetText("CMessageModule::OnUserTextMessage"); + return eAction; + } + EModRet OnUserNoticeMessage(CNoticeMessage& Message) override { + Message.SetTarget("#target"); + Message.SetText("CMessageModule::OnUserNoticeMessage"); + return eAction; + } + EModRet OnUserJoinMessage(CJoinMessage& Message) override { + Message.SetTarget("#target"); + Message.SetKey("CMessageModule::OnUserJoinMessage"); + return eAction; + } + EModRet OnUserPartMessage(CPartMessage& Message) override { + Message.SetTarget("#target"); + Message.SetReason("CMessageModule::OnUserPartMessage"); + return eAction; + } + EModRet OnUserTopicMessage(CTopicMessage& Message) override { + Message.SetTarget("#target"); + Message.SetTopic("CMessageModule::OnUserTopicMessage"); + return eAction; + } + EModRet OnUserQuitMessage(CQuitMessage& Message) override { + Message.SetReason("CMessageModule::OnUserQuitMessage"); + return eAction; + } - EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnCTCPReplyMessage"); - return eAction; - } - EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnPrivCTCPMessage"); - return eAction; - } - EModRet OnChanCTCPMessage(CCTCPMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnChanCTCPMessage"); - return eAction; - } - EModRet OnPrivActionMessage(CActionMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnPrivActionMessage"); - return eAction; - } - EModRet OnChanActionMessage(CActionMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnChanActionMessage"); - return eAction; - } - EModRet OnPrivMessage(CTextMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnPrivMessage"); - return eAction; - } - EModRet OnChanMessage(CTextMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnChanMessage"); - return eAction; - } - EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnPrivNoticeMessage"); - return eAction; - } - EModRet OnChanNoticeMessage(CNoticeMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetText("CMessageModule::OnChanNoticeMessage"); - return eAction; - } - EModRet OnTopicMessage(CTopicMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetTopic("CMessageModule::OnTopicMessage"); - return eAction; - } - EModRet OnNumericMessage(CNumericMessage& Message) override { - Message.GetNick().SetNick("nick"); - Message.SetCommand("123"); - return eAction; - } + EModRet OnCTCPReplyMessage(CCTCPMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnCTCPReplyMessage"); + return eAction; + } + EModRet OnPrivCTCPMessage(CCTCPMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnPrivCTCPMessage"); + return eAction; + } + EModRet OnChanCTCPMessage(CCTCPMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnChanCTCPMessage"); + return eAction; + } + EModRet OnPrivActionMessage(CActionMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnPrivActionMessage"); + return eAction; + } + EModRet OnChanActionMessage(CActionMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnChanActionMessage"); + return eAction; + } + EModRet OnPrivMessage(CTextMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnPrivMessage"); + return eAction; + } + EModRet OnChanMessage(CTextMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnChanMessage"); + return eAction; + } + EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnPrivNoticeMessage"); + return eAction; + } + EModRet OnChanNoticeMessage(CNoticeMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetText("CMessageModule::OnChanNoticeMessage"); + return eAction; + } + EModRet OnTopicMessage(CTopicMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetTopic("CMessageModule::OnTopicMessage"); + return eAction; + } + EModRet OnNumericMessage(CNumericMessage& Message) override { + Message.GetNick().SetNick("nick"); + Message.SetCommand("123"); + return eAction; + } - EModRet eAction = CONTINUE; + EModRet eAction = CONTINUE; }; TEST_F(ModulesTest, Hooks) { - CModules& Modules = CZNC::Get().GetModules(); + CModules& Modules = CZNC::Get().GetModules(); - CLegacyModule LegacyMod; - Modules.push_back(&LegacyMod); + CLegacyModule LegacyMod; + Modules.push_back(&LegacyMod); - CMessageModule MessageMod; - Modules.push_back(&MessageMod); + CMessageModule MessageMod; + Modules.push_back(&MessageMod); - CCTCPMessage UserCTCPReply; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserCTCPReplyMessage(UserCTCPReply); - EXPECT_EQ("#legacy", UserCTCPReply.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserCTCPReply", UserCTCPReply.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserCTCPReplyMessage(UserCTCPReply); - EXPECT_EQ("#target", UserCTCPReply.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserCTCPReplyMessage", - UserCTCPReply.GetText()); + CCTCPMessage UserCTCPReply; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserCTCPReplyMessage(UserCTCPReply); + EXPECT_EQ("#legacy", UserCTCPReply.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserCTCPReply", UserCTCPReply.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserCTCPReplyMessage(UserCTCPReply); + EXPECT_EQ("#target", UserCTCPReply.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserCTCPReplyMessage", + UserCTCPReply.GetText()); - CCTCPMessage UserCTCPMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserCTCPMessage(UserCTCPMsg); - EXPECT_EQ("#legacy", UserCTCPMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserCTCP", UserCTCPMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserCTCPMessage(UserCTCPMsg); - EXPECT_EQ("#target", UserCTCPMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserCTCPMessage", UserCTCPMsg.GetText()); + CCTCPMessage UserCTCPMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserCTCPMessage(UserCTCPMsg); + EXPECT_EQ("#legacy", UserCTCPMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserCTCP", UserCTCPMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserCTCPMessage(UserCTCPMsg); + EXPECT_EQ("#target", UserCTCPMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserCTCPMessage", UserCTCPMsg.GetText()); - CActionMessage UserActionMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserActionMessage(UserActionMsg); - EXPECT_EQ("#legacy", UserActionMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserAction", UserActionMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserActionMessage(UserActionMsg); - EXPECT_EQ("#target", UserActionMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserActionMessage", UserActionMsg.GetText()); + CActionMessage UserActionMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserActionMessage(UserActionMsg); + EXPECT_EQ("#legacy", UserActionMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserAction", UserActionMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserActionMessage(UserActionMsg); + EXPECT_EQ("#target", UserActionMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserActionMessage", UserActionMsg.GetText()); - CTextMessage UserTextMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserTextMessage(UserTextMsg); - EXPECT_EQ("#legacy", UserTextMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserMsg", UserTextMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserTextMessage(UserTextMsg); - EXPECT_EQ("#target", UserTextMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserTextMessage", UserTextMsg.GetText()); + CTextMessage UserTextMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserTextMessage(UserTextMsg); + EXPECT_EQ("#legacy", UserTextMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserMsg", UserTextMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserTextMessage(UserTextMsg); + EXPECT_EQ("#target", UserTextMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserTextMessage", UserTextMsg.GetText()); - CNoticeMessage UserNoticeMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserNoticeMessage(UserNoticeMsg); - EXPECT_EQ("#legacy", UserNoticeMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserNotice", UserNoticeMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserNoticeMessage(UserNoticeMsg); - EXPECT_EQ("#target", UserNoticeMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserNoticeMessage", UserNoticeMsg.GetText()); + CNoticeMessage UserNoticeMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserNoticeMessage(UserNoticeMsg); + EXPECT_EQ("#legacy", UserNoticeMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserNotice", UserNoticeMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserNoticeMessage(UserNoticeMsg); + EXPECT_EQ("#target", UserNoticeMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserNoticeMessage", UserNoticeMsg.GetText()); - CJoinMessage UserJoinMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserJoinMessage(UserJoinMsg); - EXPECT_EQ("#legacy", UserJoinMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserJoin", UserJoinMsg.GetKey()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserJoinMessage(UserJoinMsg); - EXPECT_EQ("#target", UserJoinMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserJoinMessage", UserJoinMsg.GetKey()); + CJoinMessage UserJoinMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserJoinMessage(UserJoinMsg); + EXPECT_EQ("#legacy", UserJoinMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserJoin", UserJoinMsg.GetKey()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserJoinMessage(UserJoinMsg); + EXPECT_EQ("#target", UserJoinMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserJoinMessage", UserJoinMsg.GetKey()); - CPartMessage UserPartMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserPartMessage(UserPartMsg); - EXPECT_EQ("#legacy", UserPartMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserPart", UserPartMsg.GetReason()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserPartMessage(UserPartMsg); - EXPECT_EQ("#target", UserPartMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserPartMessage", UserPartMsg.GetReason()); + CPartMessage UserPartMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserPartMessage(UserPartMsg); + EXPECT_EQ("#legacy", UserPartMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserPart", UserPartMsg.GetReason()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserPartMessage(UserPartMsg); + EXPECT_EQ("#target", UserPartMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserPartMessage", UserPartMsg.GetReason()); - CTopicMessage UserTopicMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserTopicMessage(UserTopicMsg); - EXPECT_EQ("#legacy", UserTopicMsg.GetTarget()); - EXPECT_EQ("CLegacyModule::OnUserTopic", UserTopicMsg.GetTopic()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserTopicMessage(UserTopicMsg); - EXPECT_EQ("#target", UserTopicMsg.GetTarget()); - EXPECT_EQ("CMessageModule::OnUserTopicMessage", UserTopicMsg.GetTopic()); + CTopicMessage UserTopicMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserTopicMessage(UserTopicMsg); + EXPECT_EQ("#legacy", UserTopicMsg.GetTarget()); + EXPECT_EQ("CLegacyModule::OnUserTopic", UserTopicMsg.GetTopic()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserTopicMessage(UserTopicMsg); + EXPECT_EQ("#target", UserTopicMsg.GetTarget()); + EXPECT_EQ("CMessageModule::OnUserTopicMessage", UserTopicMsg.GetTopic()); - CQuitMessage UserQuitMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnUserQuitMessage(UserQuitMsg); - EXPECT_EQ("CLegacyModule::OnUserQuit", UserQuitMsg.GetReason()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnUserQuitMessage(UserQuitMsg); - EXPECT_EQ("CMessageModule::OnUserQuitMessage", UserQuitMsg.GetReason()); + CQuitMessage UserQuitMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnUserQuitMessage(UserQuitMsg); + EXPECT_EQ("CLegacyModule::OnUserQuit", UserQuitMsg.GetReason()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnUserQuitMessage(UserQuitMsg); + EXPECT_EQ("CMessageModule::OnUserQuitMessage", UserQuitMsg.GetReason()); - CCTCPMessage CTCPReply; - LegacyMod.eAction = CModule::HALT; - Modules.OnCTCPReplyMessage(CTCPReply); - EXPECT_EQ("legacy", CTCPReply.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnCTCPReply", CTCPReply.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnCTCPReplyMessage(CTCPReply); - EXPECT_EQ("nick", CTCPReply.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnCTCPReplyMessage", CTCPReply.GetText()); + CCTCPMessage CTCPReply; + LegacyMod.eAction = CModule::HALT; + Modules.OnCTCPReplyMessage(CTCPReply); + EXPECT_EQ("legacy", CTCPReply.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnCTCPReply", CTCPReply.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnCTCPReplyMessage(CTCPReply); + EXPECT_EQ("nick", CTCPReply.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnCTCPReplyMessage", CTCPReply.GetText()); - CCTCPMessage PrivCTCP; - LegacyMod.eAction = CModule::HALT; - Modules.OnPrivCTCPMessage(PrivCTCP); - EXPECT_EQ("legacy", PrivCTCP.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnPrivCTCP", PrivCTCP.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnPrivCTCPMessage(PrivCTCP); - EXPECT_EQ("nick", PrivCTCP.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnPrivCTCPMessage", PrivCTCP.GetText()); + CCTCPMessage PrivCTCP; + LegacyMod.eAction = CModule::HALT; + Modules.OnPrivCTCPMessage(PrivCTCP); + EXPECT_EQ("legacy", PrivCTCP.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnPrivCTCP", PrivCTCP.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnPrivCTCPMessage(PrivCTCP); + EXPECT_EQ("nick", PrivCTCP.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnPrivCTCPMessage", PrivCTCP.GetText()); - CCTCPMessage ChanCTCP; - LegacyMod.eAction = CModule::HALT; - Modules.OnChanCTCPMessage(ChanCTCP); - EXPECT_EQ("legacy", ChanCTCP.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnChanCTCP", ChanCTCP.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnChanCTCPMessage(ChanCTCP); - EXPECT_EQ("nick", ChanCTCP.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnChanCTCPMessage", ChanCTCP.GetText()); + CCTCPMessage ChanCTCP; + LegacyMod.eAction = CModule::HALT; + Modules.OnChanCTCPMessage(ChanCTCP); + EXPECT_EQ("legacy", ChanCTCP.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnChanCTCP", ChanCTCP.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnChanCTCPMessage(ChanCTCP); + EXPECT_EQ("nick", ChanCTCP.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnChanCTCPMessage", ChanCTCP.GetText()); - CActionMessage PrivAction; - LegacyMod.eAction = CModule::HALT; - Modules.OnPrivActionMessage(PrivAction); - EXPECT_EQ("legacy", PrivAction.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnPrivAction", PrivAction.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnPrivActionMessage(PrivAction); - EXPECT_EQ("nick", PrivAction.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnPrivActionMessage", PrivAction.GetText()); + CActionMessage PrivAction; + LegacyMod.eAction = CModule::HALT; + Modules.OnPrivActionMessage(PrivAction); + EXPECT_EQ("legacy", PrivAction.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnPrivAction", PrivAction.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnPrivActionMessage(PrivAction); + EXPECT_EQ("nick", PrivAction.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnPrivActionMessage", PrivAction.GetText()); - CActionMessage ChanAction; - LegacyMod.eAction = CModule::HALT; - Modules.OnChanActionMessage(ChanAction); - EXPECT_EQ("legacy", ChanAction.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnChanAction", ChanAction.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnChanActionMessage(ChanAction); - EXPECT_EQ("nick", ChanAction.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnChanActionMessage", ChanAction.GetText()); + CActionMessage ChanAction; + LegacyMod.eAction = CModule::HALT; + Modules.OnChanActionMessage(ChanAction); + EXPECT_EQ("legacy", ChanAction.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnChanAction", ChanAction.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnChanActionMessage(ChanAction); + EXPECT_EQ("nick", ChanAction.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnChanActionMessage", ChanAction.GetText()); - CTextMessage PrivMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnPrivMessage(PrivMsg); - EXPECT_EQ("legacy", PrivMsg.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnPrivMsg", PrivMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnPrivMessage(PrivMsg); - EXPECT_EQ("nick", PrivMsg.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnPrivMessage", PrivMsg.GetText()); + CTextMessage PrivMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnPrivMessage(PrivMsg); + EXPECT_EQ("legacy", PrivMsg.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnPrivMsg", PrivMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnPrivMessage(PrivMsg); + EXPECT_EQ("nick", PrivMsg.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnPrivMessage", PrivMsg.GetText()); - CTextMessage ChanMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnChanMessage(ChanMsg); - EXPECT_EQ("legacy", ChanMsg.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnChanMsg", ChanMsg.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnChanMessage(ChanMsg); - EXPECT_EQ("nick", ChanMsg.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnChanMessage", ChanMsg.GetText()); + CTextMessage ChanMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnChanMessage(ChanMsg); + EXPECT_EQ("legacy", ChanMsg.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnChanMsg", ChanMsg.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnChanMessage(ChanMsg); + EXPECT_EQ("nick", ChanMsg.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnChanMessage", ChanMsg.GetText()); - CNoticeMessage PrivNotice; - LegacyMod.eAction = CModule::HALT; - Modules.OnPrivNoticeMessage(PrivNotice); - EXPECT_EQ("legacy", PrivNotice.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnPrivNotice", PrivNotice.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnPrivNoticeMessage(PrivNotice); - EXPECT_EQ("nick", PrivNotice.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnPrivNoticeMessage", PrivNotice.GetText()); + CNoticeMessage PrivNotice; + LegacyMod.eAction = CModule::HALT; + Modules.OnPrivNoticeMessage(PrivNotice); + EXPECT_EQ("legacy", PrivNotice.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnPrivNotice", PrivNotice.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnPrivNoticeMessage(PrivNotice); + EXPECT_EQ("nick", PrivNotice.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnPrivNoticeMessage", PrivNotice.GetText()); - CNoticeMessage ChanNotice; - LegacyMod.eAction = CModule::HALT; - Modules.OnChanNoticeMessage(ChanNotice); - EXPECT_EQ("legacy", ChanNotice.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnChanNotice", ChanNotice.GetText()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnChanNoticeMessage(ChanNotice); - EXPECT_EQ("nick", ChanNotice.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnChanNoticeMessage", ChanNotice.GetText()); + CNoticeMessage ChanNotice; + LegacyMod.eAction = CModule::HALT; + Modules.OnChanNoticeMessage(ChanNotice); + EXPECT_EQ("legacy", ChanNotice.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnChanNotice", ChanNotice.GetText()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnChanNoticeMessage(ChanNotice); + EXPECT_EQ("nick", ChanNotice.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnChanNoticeMessage", ChanNotice.GetText()); - CTopicMessage TopicMsg; - LegacyMod.eAction = CModule::HALT; - Modules.OnTopicMessage(TopicMsg); - EXPECT_EQ("legacy", TopicMsg.GetNick().GetNick()); - EXPECT_EQ("CLegacyModule::OnTopic", TopicMsg.GetTopic()); - LegacyMod.eAction = CModule::CONTINUE; - Modules.OnTopicMessage(TopicMsg); - EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); - EXPECT_EQ("CMessageModule::OnTopicMessage", TopicMsg.GetTopic()); + CTopicMessage TopicMsg; + LegacyMod.eAction = CModule::HALT; + Modules.OnTopicMessage(TopicMsg); + EXPECT_EQ("legacy", TopicMsg.GetNick().GetNick()); + EXPECT_EQ("CLegacyModule::OnTopic", TopicMsg.GetTopic()); + LegacyMod.eAction = CModule::CONTINUE; + Modules.OnTopicMessage(TopicMsg); + EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); + EXPECT_EQ("CMessageModule::OnTopicMessage", TopicMsg.GetTopic()); - CNumericMessage NumericMsg; - Modules.OnNumericMessage(NumericMsg); - EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); - EXPECT_EQ(123u, NumericMsg.GetCode()); + CNumericMessage NumericMsg; + Modules.OnNumericMessage(NumericMsg); + EXPECT_EQ("nick", TopicMsg.GetNick().GetNick()); + EXPECT_EQ(123u, NumericMsg.GetCode()); - Modules.clear(); + Modules.clear(); } diff --git a/test/NetworkTest.cpp b/test/NetworkTest.cpp index ef222128..b3186b66 100644 --- a/test/NetworkTest.cpp +++ b/test/NetworkTest.cpp @@ -21,76 +21,76 @@ class NetworkTest : public ::testing::Test { protected: - void SetUp() { CZNC::CreateInstance(); } - void TearDown() { CZNC::DestroyInstance(); } + void SetUp() { CZNC::CreateInstance(); } + void TearDown() { CZNC::DestroyInstance(); } }; TEST_F(NetworkTest, FindChan) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - EXPECT_TRUE(network.AddChan("#foo", false)); - EXPECT_TRUE(network.AddChan("#Bar", false)); - EXPECT_TRUE(network.AddChan("#BAZ", false)); + EXPECT_TRUE(network.AddChan("#foo", false)); + EXPECT_TRUE(network.AddChan("#Bar", false)); + EXPECT_TRUE(network.AddChan("#BAZ", false)); - EXPECT_TRUE(network.FindChan("#foo")); - EXPECT_TRUE(network.FindChan("#Bar")); - EXPECT_TRUE(network.FindChan("#BAZ")); + EXPECT_TRUE(network.FindChan("#foo")); + EXPECT_TRUE(network.FindChan("#Bar")); + EXPECT_TRUE(network.FindChan("#BAZ")); - EXPECT_TRUE(network.FindChan("#Foo")); - EXPECT_TRUE(network.FindChan("#BAR")); - EXPECT_TRUE(network.FindChan("#baz")); + EXPECT_TRUE(network.FindChan("#Foo")); + EXPECT_TRUE(network.FindChan("#BAR")); + EXPECT_TRUE(network.FindChan("#baz")); - EXPECT_FALSE(network.FindChan("#f")); - EXPECT_FALSE(network.FindChan("&foo")); - EXPECT_FALSE(network.FindChan("##foo")); + EXPECT_FALSE(network.FindChan("#f")); + EXPECT_FALSE(network.FindChan("&foo")); + EXPECT_FALSE(network.FindChan("##foo")); } TEST_F(NetworkTest, FindChans) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - EXPECT_TRUE(network.AddChan("#foo", false)); - EXPECT_TRUE(network.AddChan("#Bar", false)); - EXPECT_TRUE(network.AddChan("#BAZ", false)); + EXPECT_TRUE(network.AddChan("#foo", false)); + EXPECT_TRUE(network.AddChan("#Bar", false)); + EXPECT_TRUE(network.AddChan("#BAZ", false)); - EXPECT_EQ(1u, network.FindChans("#f*").size()); - EXPECT_EQ(2u, network.FindChans("#b*").size()); - EXPECT_EQ(2u, network.FindChans("#?A*").size()); - EXPECT_EQ(1u, network.FindChans("*z").size()); + EXPECT_EQ(1u, network.FindChans("#f*").size()); + EXPECT_EQ(2u, network.FindChans("#b*").size()); + EXPECT_EQ(2u, network.FindChans("#?A*").size()); + EXPECT_EQ(1u, network.FindChans("*z").size()); } TEST_F(NetworkTest, FindQuery) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - EXPECT_TRUE(network.AddQuery("foo")); - EXPECT_TRUE(network.AddQuery("Bar")); - EXPECT_TRUE(network.AddQuery("BAZ")); + EXPECT_TRUE(network.AddQuery("foo")); + EXPECT_TRUE(network.AddQuery("Bar")); + EXPECT_TRUE(network.AddQuery("BAZ")); - EXPECT_TRUE(network.FindQuery("foo")); - EXPECT_TRUE(network.FindQuery("Bar")); - EXPECT_TRUE(network.FindQuery("BAZ")); + EXPECT_TRUE(network.FindQuery("foo")); + EXPECT_TRUE(network.FindQuery("Bar")); + EXPECT_TRUE(network.FindQuery("BAZ")); - EXPECT_TRUE(network.FindQuery("Foo")); - EXPECT_TRUE(network.FindQuery("BAR")); - EXPECT_TRUE(network.FindQuery("baz")); + EXPECT_TRUE(network.FindQuery("Foo")); + EXPECT_TRUE(network.FindQuery("BAR")); + EXPECT_TRUE(network.FindQuery("baz")); - EXPECT_FALSE(network.FindQuery("f")); - EXPECT_FALSE(network.FindQuery("fo")); - EXPECT_FALSE(network.FindQuery("FF")); + EXPECT_FALSE(network.FindQuery("f")); + EXPECT_FALSE(network.FindQuery("fo")); + EXPECT_FALSE(network.FindQuery("FF")); } TEST_F(NetworkTest, FindQueries) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - EXPECT_TRUE(network.AddQuery("foo")); - EXPECT_TRUE(network.AddQuery("Bar")); - EXPECT_TRUE(network.AddQuery("BAZ")); + EXPECT_TRUE(network.AddQuery("foo")); + EXPECT_TRUE(network.AddQuery("Bar")); + EXPECT_TRUE(network.AddQuery("BAZ")); - EXPECT_EQ(1u, network.FindQueries("f*").size()); - EXPECT_EQ(2u, network.FindQueries("b*").size()); - EXPECT_EQ(2u, network.FindQueries("?A*").size()); - EXPECT_EQ(1u, network.FindQueries("*z").size()); + EXPECT_EQ(1u, network.FindQueries("f*").size()); + EXPECT_EQ(2u, network.FindQueries("b*").size()); + EXPECT_EQ(2u, network.FindQueries("?A*").size()); + EXPECT_EQ(1u, network.FindQueries("*z").size()); } diff --git a/test/NickTest.cpp b/test/NickTest.cpp index 7ed4aa6b..248f4ee1 100644 --- a/test/NickTest.cpp +++ b/test/NickTest.cpp @@ -18,19 +18,19 @@ #include TEST(NickTest, Parse) { - CNick Nick1("nick!~ident@host"); - EXPECT_EQ("nick", Nick1.GetNick()); - EXPECT_EQ("~ident", Nick1.GetIdent()); - EXPECT_EQ("host", Nick1.GetHost()); - EXPECT_EQ("nick!~ident@host", Nick1.GetNickMask()); - EXPECT_EQ("nick!~ident@host", Nick1.GetHostMask()); - EXPECT_TRUE(Nick1.NickEquals("nick")); + CNick Nick1("nick!~ident@host"); + EXPECT_EQ("nick", Nick1.GetNick()); + EXPECT_EQ("~ident", Nick1.GetIdent()); + EXPECT_EQ("host", Nick1.GetHost()); + EXPECT_EQ("nick!~ident@host", Nick1.GetNickMask()); + EXPECT_EQ("nick!~ident@host", Nick1.GetHostMask()); + EXPECT_TRUE(Nick1.NickEquals("nick")); - CNick Nick2(":nick!~ident@host"); - EXPECT_EQ("nick", Nick2.GetNick()); - EXPECT_EQ("~ident", Nick2.GetIdent()); - EXPECT_EQ("host", Nick2.GetHost()); - EXPECT_EQ("nick!~ident@host", Nick2.GetNickMask()); - EXPECT_EQ("nick!~ident@host", Nick2.GetHostMask()); - EXPECT_TRUE(Nick2.NickEquals("nick")); + CNick Nick2(":nick!~ident@host"); + EXPECT_EQ("nick", Nick2.GetNick()); + EXPECT_EQ("~ident", Nick2.GetIdent()); + EXPECT_EQ("host", Nick2.GetHost()); + EXPECT_EQ("nick!~ident@host", Nick2.GetNickMask()); + EXPECT_EQ("nick!~ident@host", Nick2.GetHostMask()); + EXPECT_TRUE(Nick2.NickEquals("nick")); } diff --git a/test/QueryTest.cpp b/test/QueryTest.cpp index 4552ee44..01b27c42 100644 --- a/test/QueryTest.cpp +++ b/test/QueryTest.cpp @@ -25,88 +25,88 @@ using ::testing::MatchesRegex; class QueryTest : public ::testing::Test { protected: - void SetUp() { CZNC::CreateInstance(); } - void TearDown() { CZNC::DestroyInstance(); } + void SetUp() { CZNC::CreateInstance(); } + void TearDown() { CZNC::DestroyInstance(); } }; TEST_F(QueryTest, Name) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - CQuery query("query", &network); - EXPECT_EQ("query", query.GetName()); + CQuery query("query", &network); + EXPECT_EQ("query", query.GetName()); } TEST_F(QueryTest, AddClearBuffer) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - CQuery query("query", &network); - EXPECT_TRUE(query.GetBuffer().IsEmpty()); - query.AddBuffer("foo"); - EXPECT_EQ(1u, query.GetBuffer().Size()); - query.AddBuffer("bar"); - EXPECT_EQ(2u, query.GetBuffer().Size()); - query.ClearBuffer(); - EXPECT_TRUE(query.GetBuffer().IsEmpty()); + CQuery query("query", &network); + EXPECT_TRUE(query.GetBuffer().IsEmpty()); + query.AddBuffer("foo"); + EXPECT_EQ(1u, query.GetBuffer().Size()); + query.AddBuffer("bar"); + EXPECT_EQ(2u, query.GetBuffer().Size()); + query.ClearBuffer(); + EXPECT_TRUE(query.GetBuffer().IsEmpty()); } TEST_F(QueryTest, BufferSize) { - CUser user("user"); - CIRCNetwork network(&user, "network"); + CUser user("user"); + CIRCNetwork network(&user, "network"); - CQuery query("query", &network); - EXPECT_EQ(50u, user.GetQueryBufferSize()); - EXPECT_EQ(50u, query.GetBufferCount()); + CQuery query("query", &network); + EXPECT_EQ(50u, user.GetQueryBufferSize()); + EXPECT_EQ(50u, query.GetBufferCount()); - EXPECT_EQ(500u, CZNC::Get().GetMaxBufferSize()); - EXPECT_FALSE(query.SetBufferCount(1000, false)); - EXPECT_EQ(50u, query.GetBufferCount()); - EXPECT_TRUE(query.SetBufferCount(500, false)); - EXPECT_EQ(500u, query.GetBufferCount()); - EXPECT_TRUE(query.SetBufferCount(1000, true)); - EXPECT_EQ(1000u, query.GetBufferCount()); + EXPECT_EQ(500u, CZNC::Get().GetMaxBufferSize()); + EXPECT_FALSE(query.SetBufferCount(1000, false)); + EXPECT_EQ(50u, query.GetBufferCount()); + EXPECT_TRUE(query.SetBufferCount(500, false)); + EXPECT_EQ(500u, query.GetBufferCount()); + EXPECT_TRUE(query.SetBufferCount(1000, true)); + EXPECT_EQ(1000u, query.GetBufferCount()); } TEST_F(QueryTest, SendBuffer) { - CUser user("user"); - CIRCNetwork network(&user, "network"); - CDebug::SetDebug(false); + CUser user("user"); + CIRCNetwork network(&user, "network"); + CDebug::SetDebug(false); - TestClient client; - client.SetNick("me"); - client.AcceptLogin(user); - client.Reset(); + TestClient client; + client.SetNick("me"); + client.AcceptLogin(user); + client.Reset(); - CQuery query("query", &network); - query.AddBuffer(":sender PRIVMSG {target} :{text}", "a message"); - query.AddBuffer(":me PRIVMSG someone :{text}", "a self-message"); - query.AddBuffer(":sender NOTICE #znc :{text}", "a notice"); + CQuery query("query", &network); + query.AddBuffer(":sender PRIVMSG {target} :{text}", "a message"); + query.AddBuffer(":me PRIVMSG someone :{text}", "a self-message"); + query.AddBuffer(":sender NOTICE #znc :{text}", "a notice"); - client.Reset(); - query.SendBuffer(&client); - EXPECT_THAT( - client.vsLines, - ElementsAre( - MatchesRegex(R"(:sender PRIVMSG me :\[\d\d:\d\d:\d\d\] a message)"), - MatchesRegex( - R"(:sender NOTICE #znc :\[\d\d:\d\d:\d\d\] a notice)"))); + client.Reset(); + query.SendBuffer(&client); + EXPECT_THAT( + client.vsLines, + ElementsAre( + MatchesRegex(R"(:sender PRIVMSG me :\[\d\d:\d\d:\d\d\] a message)"), + MatchesRegex( + R"(:sender NOTICE #znc :\[\d\d:\d\d:\d\d\] a notice)"))); - client.Reset(); - user.SetTimestampPrepend(false); - query.SendBuffer(&client); - EXPECT_THAT(client.vsLines, ElementsAre(":sender PRIVMSG me :a message", - ":sender NOTICE #znc :a notice")); + client.Reset(); + user.SetTimestampPrepend(false); + query.SendBuffer(&client); + EXPECT_THAT(client.vsLines, ElementsAre(":sender PRIVMSG me :a message", + ":sender NOTICE #znc :a notice")); - client.Reset(); - user.SetTimestampAppend(true); - query.SendBuffer(&client); - EXPECT_THAT( - client.vsLines, - ElementsAre( - MatchesRegex(R"(:sender PRIVMSG me :a message \[\d\d:\d\d:\d\d\])"), - MatchesRegex( - R"(:sender NOTICE #znc :a notice \[\d\d:\d\d:\d\d\])"))); + client.Reset(); + user.SetTimestampAppend(true); + query.SendBuffer(&client); + EXPECT_THAT( + client.vsLines, + ElementsAre( + MatchesRegex(R"(:sender PRIVMSG me :a message \[\d\d:\d\d:\d\d\])"), + MatchesRegex( + R"(:sender NOTICE #znc :a notice \[\d\d:\d\d:\d\d\])"))); - network.ClientDisconnected(&client); + network.ClientDisconnected(&client); } diff --git a/test/StringTest.cpp b/test/StringTest.cpp index 045e5359..6ee6e084 100644 --- a/test/StringTest.cpp +++ b/test/StringTest.cpp @@ -19,247 +19,247 @@ // GTest uses this function to output objects static void PrintTo(const CString& s, std::ostream* o) { - *o << '"' << s.Escape_n(CString::EASCII, CString::EDEBUG) << '"'; + *o << '"' << s.Escape_n(CString::EASCII, CString::EDEBUG) << '"'; } class EscapeTest : public ::testing::Test { protected: - void testEncode(const CString& in, const CString& expectedOut, - const CString& sformat) { - CString::EEscape format = CString::ToEscape(sformat); - CString out; + void testEncode(const CString& in, const CString& expectedOut, + const CString& sformat) { + CString::EEscape format = CString::ToEscape(sformat); + CString out; - SCOPED_TRACE("Format: " + sformat); + SCOPED_TRACE("Format: " + sformat); - // Encode, then decode again and check we still got the same string - out = in.Escape_n(CString::EASCII, format); - EXPECT_EQ(expectedOut, out); - out = out.Escape_n(format, CString::EASCII); - EXPECT_EQ(in, out); - } + // Encode, then decode again and check we still got the same string + out = in.Escape_n(CString::EASCII, format); + EXPECT_EQ(expectedOut, out); + out = out.Escape_n(format, CString::EASCII); + EXPECT_EQ(in, out); + } - void testString(const CString& in, const CString& url, const CString& html, - const CString& sql, const CString& tag) { - SCOPED_TRACE("String: " + in); + void testString(const CString& in, const CString& url, const CString& html, + const CString& sql, const CString& tag) { + SCOPED_TRACE("String: " + in); - testEncode(in, url, "URL"); - testEncode(in, html, "HTML"); - testEncode(in, sql, "SQL"); - testEncode(in, tag, "MSGTAG"); - } + testEncode(in, url, "URL"); + testEncode(in, html, "HTML"); + testEncode(in, sql, "SQL"); + testEncode(in, tag, "MSGTAG"); + } }; TEST_F(EscapeTest, Test) { - // clang-format off - // input url html sql msgtag - testString("abcdefg","abcdefg", "abcdefg", "abcdefg", "abcdefg"); - testString("\n\t\r", "%0A%09%0D", "\n\t\r", "\\n\\t\\r", "\\n\t\\r"); - testString("'\"", "%27%22", "'"", "\\'\\\"", "'\""); - testString("&<>", "%26%3C%3E", "&<>", "&<>", "&<>"); - testString(" ;", "+%3B", " ;", " ;", "\\s\\:"); - // clang-format on + // clang-format off + // input url html sql msgtag + testString("abcdefg","abcdefg", "abcdefg", "abcdefg", "abcdefg"); + testString("\n\t\r", "%0A%09%0D", "\n\t\r", "\\n\\t\\r", "\\n\t\\r"); + testString("'\"", "%27%22", "'"", "\\'\\\"", "'\""); + testString("&<>", "%26%3C%3E", "&<>", "&<>", "&<>"); + testString(" ;", "+%3B", " ;", " ;", "\\s\\:"); + // clang-format on } TEST(StringTest, Bool) { - EXPECT_TRUE(CString(true).ToBool()); - EXPECT_FALSE(CString(false).ToBool()); + EXPECT_TRUE(CString(true).ToBool()); + EXPECT_FALSE(CString(false).ToBool()); } #define CS(s) (CString((s), sizeof(s) - 1)) TEST(StringTest, Cmp) { - CString s = "Bbb"; + CString s = "Bbb"; - EXPECT_EQ(CString("Bbb"), s); - EXPECT_LT(CString("Aaa"), s); - EXPECT_GT(CString("Ccc"), s); - EXPECT_EQ(0, s.StrCmp("Bbb")); - EXPECT_GT(0, s.StrCmp("bbb")); - EXPECT_LT(0, s.StrCmp("Aaa")); - EXPECT_GT(0, s.StrCmp("Ccc")); - EXPECT_EQ(0, s.CaseCmp("Bbb")); - EXPECT_EQ(0, s.CaseCmp("bbb")); - EXPECT_LT(0, s.CaseCmp("Aaa")); - EXPECT_GT(0, s.CaseCmp("Ccc")); + EXPECT_EQ(CString("Bbb"), s); + EXPECT_LT(CString("Aaa"), s); + EXPECT_GT(CString("Ccc"), s); + EXPECT_EQ(0, s.StrCmp("Bbb")); + EXPECT_GT(0, s.StrCmp("bbb")); + EXPECT_LT(0, s.StrCmp("Aaa")); + EXPECT_GT(0, s.StrCmp("Ccc")); + EXPECT_EQ(0, s.CaseCmp("Bbb")); + EXPECT_EQ(0, s.CaseCmp("bbb")); + EXPECT_LT(0, s.CaseCmp("Aaa")); + EXPECT_GT(0, s.CaseCmp("Ccc")); - EXPECT_TRUE(s.Equals("bbb")); - EXPECT_FALSE(s.Equals("bbb", true)); - EXPECT_FALSE(s.Equals("bb")); + EXPECT_TRUE(s.Equals("bbb")); + EXPECT_FALSE(s.Equals("bbb", true)); + EXPECT_FALSE(s.Equals("bb")); } TEST(StringTest, Wild) { - EXPECT_TRUE(CString::WildCmp("", "", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("", "", CString::CaseInsensitive)); + EXPECT_TRUE(CString::WildCmp("", "", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("", "", CString::CaseInsensitive)); - EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseSensitive)); - EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseInsensitive)); + EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseSensitive)); + EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseInsensitive)); - EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", - CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", - CString::CaseInsensitive)); + EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", + CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", + CString::CaseInsensitive)); - EXPECT_FALSE(CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", - CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", - CString::CaseInsensitive)); + EXPECT_FALSE(CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", + CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", + CString::CaseInsensitive)); - EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseInsensitive)); + EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseInsensitive)); - EXPECT_FALSE(CString::WildCmp("*A*b*c*", "abc", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*A*b*c*", "abc", CString::CaseInsensitive)); + EXPECT_FALSE(CString::WildCmp("*A*b*c*", "abc", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*A*b*c*", "abc", CString::CaseInsensitive)); - EXPECT_FALSE(CString::WildCmp("*a*b*c*", "Abc", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*a*b*c*", "Abc", CString::CaseInsensitive)); + EXPECT_FALSE(CString::WildCmp("*a*b*c*", "Abc", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*a*b*c*", "Abc", CString::CaseInsensitive)); - EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseInsensitive)); + EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseInsensitive)); - EXPECT_FALSE(CString::WildCmp("*a*B*c*", "AxByC", CString::CaseSensitive)); - EXPECT_TRUE(CString::WildCmp("*a*B*c*", "AxByC", CString::CaseInsensitive)); + EXPECT_FALSE(CString::WildCmp("*a*B*c*", "AxByC", CString::CaseSensitive)); + EXPECT_TRUE(CString::WildCmp("*a*B*c*", "AxByC", CString::CaseInsensitive)); } TEST(StringTest, Case) { - CString x = CS("xx"); - CString X = CS("XX"); - EXPECT_EQ(X, x.AsUpper()); - EXPECT_EQ(x, X.AsLower()); + CString x = CS("xx"); + CString X = CS("XX"); + EXPECT_EQ(X, x.AsUpper()); + EXPECT_EQ(x, X.AsLower()); } TEST(StringTest, Replace) { - EXPECT_EQ("(b()b)", CString("(a()a)").Replace_n("a", "b")); - EXPECT_EQ("(a()b)", CString("(a()a)").Replace_n("a", "b", "(", ")")); - EXPECT_EQ("a(b)", CString("(a()a)").Replace_n("a", "b", "(", ")", true)); + EXPECT_EQ("(b()b)", CString("(a()a)").Replace_n("a", "b")); + EXPECT_EQ("(a()b)", CString("(a()a)").Replace_n("a", "b", "(", ")")); + EXPECT_EQ("a(b)", CString("(a()a)").Replace_n("a", "b", "(", ")", true)); } TEST(StringTest, Misc) { - EXPECT_EQ("Hello,...", CString("Hello, I'm Bob").Ellipsize(9)); - EXPECT_EQ("Hello, I'm Bob", CString("Hello, I'm Bob").Ellipsize(90)); - EXPECT_EQ("..", CString("Hello, I'm Bob").Ellipsize(2)); + EXPECT_EQ("Hello,...", CString("Hello, I'm Bob").Ellipsize(9)); + EXPECT_EQ("Hello, I'm Bob", CString("Hello, I'm Bob").Ellipsize(90)); + EXPECT_EQ("..", CString("Hello, I'm Bob").Ellipsize(2)); - EXPECT_EQ("Xy", CS("Xyz").Left(2)); - EXPECT_EQ("Xyz", CS("Xyz").Left(20)); + EXPECT_EQ("Xy", CS("Xyz").Left(2)); + EXPECT_EQ("Xyz", CS("Xyz").Left(20)); - EXPECT_EQ("yz", CS("Xyz").Right(2)); - EXPECT_EQ("Xyz", CS("Xyz").Right(20)); + EXPECT_EQ("yz", CS("Xyz").Right(2)); + EXPECT_EQ("Xyz", CS("Xyz").Right(20)); } TEST(StringTest, Split) { - EXPECT_EQ("a", CS("a b c").Token(0)); - EXPECT_EQ("b", CS("a b c").Token(1)); - EXPECT_EQ("", CS("a b c").Token(100)); - EXPECT_EQ("b c", CS("a b c").Token(1, true)); - EXPECT_EQ("c", CS("a c").Token(1)); - EXPECT_EQ("", CS("a c").Token(1, false, " ", true)); - EXPECT_EQ("c", CS("a c").Token(1, false, " ")); - EXPECT_EQ(" c", CS("a c").Token(1, false, " ")); - EXPECT_EQ("c", CS("a c").Token(1, false, " ")); - EXPECT_EQ("b c", CS("a (b c) d").Token(1, false, " ", false, "(", ")")); - EXPECT_EQ("(b c)", - CS("a (b c) d").Token(1, false, " ", false, "(", ")", false)); - EXPECT_EQ("d", - CS("a (b c) d").Token(2, false, " ", false, "(", ")", false)); + EXPECT_EQ("a", CS("a b c").Token(0)); + EXPECT_EQ("b", CS("a b c").Token(1)); + EXPECT_EQ("", CS("a b c").Token(100)); + EXPECT_EQ("b c", CS("a b c").Token(1, true)); + EXPECT_EQ("c", CS("a c").Token(1)); + EXPECT_EQ("", CS("a c").Token(1, false, " ", true)); + EXPECT_EQ("c", CS("a c").Token(1, false, " ")); + EXPECT_EQ(" c", CS("a c").Token(1, false, " ")); + EXPECT_EQ("c", CS("a c").Token(1, false, " ")); + EXPECT_EQ("b c", CS("a (b c) d").Token(1, false, " ", false, "(", ")")); + EXPECT_EQ("(b c)", + CS("a (b c) d").Token(1, false, " ", false, "(", ")", false)); + EXPECT_EQ("d", + CS("a (b c) d").Token(2, false, " ", false, "(", ")", false)); - VCString vexpected; - VCString vresult; + VCString vexpected; + VCString vresult; - vexpected.push_back("a"); - vexpected.push_back("b"); - vexpected.push_back("c"); - CS("a b c").Split(" ", vresult); - EXPECT_EQ(vexpected, vresult); + vexpected.push_back("a"); + vexpected.push_back("b"); + vexpected.push_back("c"); + CS("a b c").Split(" ", vresult); + EXPECT_EQ(vexpected, vresult); - MCString mexpected = {{"a", "b"}, {"c", "d"}}; - MCString mresult; + MCString mexpected = {{"a", "b"}, {"c", "d"}}; + MCString mresult; - CS("a=x&c=d&a=b").URLSplit(mresult); - EXPECT_EQ(mexpected, mresult) << "URLSplit"; + CS("a=x&c=d&a=b").URLSplit(mresult); + EXPECT_EQ(mexpected, mresult) << "URLSplit"; } TEST(StringTest, NamedFormat) { - MCString m = {{"a", "b"}}; - EXPECT_EQ("{xbyb", CString::NamedFormat(CS("\\{x{a}y{a}"), m)); + MCString m = {{"a", "b"}}; + EXPECT_EQ("{xbyb", CString::NamedFormat(CS("\\{x{a}y{a}"), m)); } TEST(StringTest, Hash) { - EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", CS("").MD5()); - EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661", CS("a").MD5()); + EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", CS("").MD5()); + EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661", CS("a").MD5()); - EXPECT_EQ( - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - CS("").SHA256()); - EXPECT_EQ( - "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", - CS("a").SHA256()); + EXPECT_EQ( + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + CS("").SHA256()); + EXPECT_EQ( + "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + CS("a").SHA256()); } TEST(StringTest, Equals) { - EXPECT_TRUE(CS("ABC").Equals("abc")); - EXPECT_TRUE(CS("ABC").Equals("abc", CString::CaseInsensitive)); - EXPECT_FALSE(CS("ABC").Equals("abc", CString::CaseSensitive)); - EXPECT_TRUE(CS("ABC").Equals("abc", false)); // deprecated - EXPECT_FALSE(CS("ABC").Equals("abc", true)); // deprecated + EXPECT_TRUE(CS("ABC").Equals("abc")); + EXPECT_TRUE(CS("ABC").Equals("abc", CString::CaseInsensitive)); + EXPECT_FALSE(CS("ABC").Equals("abc", CString::CaseSensitive)); + EXPECT_TRUE(CS("ABC").Equals("abc", false)); // deprecated + EXPECT_FALSE(CS("ABC").Equals("abc", true)); // deprecated } TEST(StringTest, Find) { - EXPECT_EQ(0u, CString("Hello, I'm Bob").Find("Hello")); - EXPECT_EQ( - 0u, CString("Hello, I'm Bob").Find("Hello", CString::CaseInsensitive)); - EXPECT_EQ(0u, - CString("Hello, I'm Bob").Find("Hello", CString::CaseSensitive)); + EXPECT_EQ(0u, CString("Hello, I'm Bob").Find("Hello")); + EXPECT_EQ( + 0u, CString("Hello, I'm Bob").Find("Hello", CString::CaseInsensitive)); + EXPECT_EQ(0u, + CString("Hello, I'm Bob").Find("Hello", CString::CaseSensitive)); - EXPECT_EQ(7u, CString("Hello, I'm Bob").Find("i'm")); - EXPECT_EQ(7u, - CString("Hello, I'm Bob").Find("i'm", CString::CaseInsensitive)); - EXPECT_EQ(CString::npos, - CString("Hello, I'm Bob").Find("i'm", CString::CaseSensitive)); + EXPECT_EQ(7u, CString("Hello, I'm Bob").Find("i'm")); + EXPECT_EQ(7u, + CString("Hello, I'm Bob").Find("i'm", CString::CaseInsensitive)); + EXPECT_EQ(CString::npos, + CString("Hello, I'm Bob").Find("i'm", CString::CaseSensitive)); } TEST(StringTest, StartsWith) { - EXPECT_TRUE(CString("Hello, I'm Bob").StartsWith("Hello")); - EXPECT_TRUE(CString("Hello, I'm Bob") - .StartsWith("Hello", CString::CaseInsensitive)); - EXPECT_TRUE( - CString("Hello, I'm Bob").StartsWith("Hello", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").StartsWith("Hello")); + EXPECT_TRUE(CString("Hello, I'm Bob") + .StartsWith("Hello", CString::CaseInsensitive)); + EXPECT_TRUE( + CString("Hello, I'm Bob").StartsWith("Hello", CString::CaseSensitive)); - EXPECT_TRUE(CString("Hello, I'm Bob").StartsWith("hello")); - EXPECT_TRUE(CString("Hello, I'm Bob") - .StartsWith("hello", CString::CaseInsensitive)); - EXPECT_FALSE( - CString("Hello, I'm Bob").StartsWith("hello", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").StartsWith("hello")); + EXPECT_TRUE(CString("Hello, I'm Bob") + .StartsWith("hello", CString::CaseInsensitive)); + EXPECT_FALSE( + CString("Hello, I'm Bob").StartsWith("hello", CString::CaseSensitive)); } TEST(StringTest, EndsWith) { - EXPECT_TRUE(CString("Hello, I'm Bob").EndsWith("Bob")); - EXPECT_TRUE( - CString("Hello, I'm Bob").EndsWith("Bob", CString::CaseInsensitive)); - EXPECT_TRUE( - CString("Hello, I'm Bob").EndsWith("Bob", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").EndsWith("Bob")); + EXPECT_TRUE( + CString("Hello, I'm Bob").EndsWith("Bob", CString::CaseInsensitive)); + EXPECT_TRUE( + CString("Hello, I'm Bob").EndsWith("Bob", CString::CaseSensitive)); - EXPECT_TRUE(CString("Hello, I'm Bob").EndsWith("bob")); - EXPECT_TRUE( - CString("Hello, I'm Bob").EndsWith("bob", CString::CaseInsensitive)); - EXPECT_FALSE( - CString("Hello, I'm Bob").EndsWith("bob", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").EndsWith("bob")); + EXPECT_TRUE( + CString("Hello, I'm Bob").EndsWith("bob", CString::CaseInsensitive)); + EXPECT_FALSE( + CString("Hello, I'm Bob").EndsWith("bob", CString::CaseSensitive)); } TEST(StringTest, Contains) { - EXPECT_TRUE(CString("Hello, I'm Bob").Contains("Hello")); - EXPECT_TRUE( - CString("Hello, I'm Bob").Contains("Hello", CString::CaseInsensitive)); - EXPECT_TRUE( - CString("Hello, I'm Bob").Contains("Hello", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").Contains("Hello")); + EXPECT_TRUE( + CString("Hello, I'm Bob").Contains("Hello", CString::CaseInsensitive)); + EXPECT_TRUE( + CString("Hello, I'm Bob").Contains("Hello", CString::CaseSensitive)); - EXPECT_TRUE(CString("Hello, I'm Bob").Contains("i'm")); - EXPECT_TRUE( - CString("Hello, I'm Bob").Contains("i'm", CString::CaseInsensitive)); - EXPECT_FALSE( - CString("Hello, I'm Bob").Contains("i'm", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").Contains("i'm")); + EXPECT_TRUE( + CString("Hello, I'm Bob").Contains("i'm", CString::CaseInsensitive)); + EXPECT_FALSE( + CString("Hello, I'm Bob").Contains("i'm", CString::CaseSensitive)); - EXPECT_TRUE(CString("Hello, I'm Bob").Contains("i'm bob")); - EXPECT_TRUE(CString("Hello, I'm Bob") - .Contains("i'm bob", CString::CaseInsensitive)); - EXPECT_FALSE( - CString("Hello, I'm Bob").Contains("i'm bob", CString::CaseSensitive)); + EXPECT_TRUE(CString("Hello, I'm Bob").Contains("i'm bob")); + EXPECT_TRUE(CString("Hello, I'm Bob") + .Contains("i'm bob", CString::CaseInsensitive)); + EXPECT_FALSE( + CString("Hello, I'm Bob").Contains("i'm bob", CString::CaseSensitive)); } diff --git a/test/ThreadTest.cpp b/test/ThreadTest.cpp index d7229aad..c896f6c2 100644 --- a/test/ThreadTest.cpp +++ b/test/ThreadTest.cpp @@ -20,166 +20,166 @@ class CWaitingJob : public CJob { public: - CWaitingJob(bool& destroyed) - : m_bDestroyed(destroyed), - m_Mutex(), - m_CV(), - m_bThreadReady(false), - m_bThreadDone(false){}; + CWaitingJob(bool& destroyed) + : m_bDestroyed(destroyed), + m_Mutex(), + m_CV(), + m_bThreadReady(false), + m_bThreadDone(false){}; - ~CWaitingJob() { - EXPECT_TRUE(m_bThreadReady); - EXPECT_TRUE(m_bThreadDone); - EXPECT_FALSE(wasCancelled()); - m_bDestroyed = true; - } + ~CWaitingJob() { + EXPECT_TRUE(m_bThreadReady); + EXPECT_TRUE(m_bThreadDone); + EXPECT_FALSE(wasCancelled()); + m_bDestroyed = true; + } - void signal() { - CMutexLocker locker(m_Mutex); - // Wait for the thread to run - while (!m_bThreadReady) m_CV.wait(m_Mutex); + void signal() { + CMutexLocker locker(m_Mutex); + // Wait for the thread to run + while (!m_bThreadReady) m_CV.wait(m_Mutex); - // and signal it to exit - m_bThreadDone = true; - m_CV.notify_all(); - } + // and signal it to exit + m_bThreadDone = true; + m_CV.notify_all(); + } - virtual void runThread() { - CMutexLocker locker(m_Mutex); - // We are running - m_bThreadReady = true; - m_CV.notify_all(); + virtual void runThread() { + CMutexLocker locker(m_Mutex); + // We are running + m_bThreadReady = true; + m_CV.notify_all(); - // wait for our exit signal - while (!m_bThreadDone) m_CV.wait(m_Mutex); - } + // wait for our exit signal + while (!m_bThreadDone) m_CV.wait(m_Mutex); + } - virtual void runMain() {} + virtual void runMain() {} private: - bool& m_bDestroyed; - CMutex m_Mutex; - CConditionVariable m_CV; - bool m_bThreadReady; - bool m_bThreadDone; + bool& m_bDestroyed; + CMutex m_Mutex; + CConditionVariable m_CV; + bool m_bThreadReady; + bool m_bThreadDone; }; TEST(Thread, RunJob) { - bool destroyed = false; - CWaitingJob* pJob = new CWaitingJob(destroyed); + bool destroyed = false; + CWaitingJob* pJob = new CWaitingJob(destroyed); - CThreadPool::Get().addJob(pJob); - pJob->signal(); + CThreadPool::Get().addJob(pJob); + pJob->signal(); - while (!destroyed) CThreadPool::Get().handlePipeReadable(); + while (!destroyed) CThreadPool::Get().handlePipeReadable(); } class CCancelJob : public CJob { public: - CCancelJob(bool& destroyed) - : m_bDestroyed(destroyed), - m_Mutex(), - m_CVThreadReady(), - m_bThreadReady(false) {} + CCancelJob(bool& destroyed) + : m_bDestroyed(destroyed), + m_Mutex(), + m_CVThreadReady(), + m_bThreadReady(false) {} - ~CCancelJob() { - EXPECT_TRUE(wasCancelled()); - m_bDestroyed = true; - } + ~CCancelJob() { + EXPECT_TRUE(wasCancelled()); + m_bDestroyed = true; + } - void wait() { - CMutexLocker locker(m_Mutex); - // Wait for the thread to run - while (!m_bThreadReady) m_CVThreadReady.wait(m_Mutex); - } + void wait() { + CMutexLocker locker(m_Mutex); + // Wait for the thread to run + while (!m_bThreadReady) m_CVThreadReady.wait(m_Mutex); + } - virtual void runThread() { - m_Mutex.lock(); - // We are running, tell the main thread - m_bThreadReady = true; - m_CVThreadReady.notify_all(); - // Have to unlock here so that wait() can get the mutex - m_Mutex.unlock(); + virtual void runThread() { + m_Mutex.lock(); + // We are running, tell the main thread + m_bThreadReady = true; + m_CVThreadReady.notify_all(); + // Have to unlock here so that wait() can get the mutex + m_Mutex.unlock(); - while (!wasCancelled()) { - // We can't do much besides busy-looping here. If the - // job really gets cancelled while it is already - // running, the main thread is stuck in cancelJob(), so - // it cannot signal us in any way. And signaling us - // before calling cancelJob() effictively is the same - // thing as busy looping anyway. So busy looping it is. - // (Yes, CJob shouldn't be used for anything that - // requires synchronisation between threads!) - } - } + while (!wasCancelled()) { + // We can't do much besides busy-looping here. If the + // job really gets cancelled while it is already + // running, the main thread is stuck in cancelJob(), so + // it cannot signal us in any way. And signaling us + // before calling cancelJob() effictively is the same + // thing as busy looping anyway. So busy looping it is. + // (Yes, CJob shouldn't be used for anything that + // requires synchronisation between threads!) + } + } - virtual void runMain() {} + virtual void runMain() {} private: - bool& m_bDestroyed; - CMutex m_Mutex; - CConditionVariable m_CVThreadReady; - bool m_bThreadReady; + bool& m_bDestroyed; + CMutex m_Mutex; + CConditionVariable m_CVThreadReady; + bool m_bThreadReady; }; TEST(Thread, CancelJobEarly) { - bool destroyed = false; - CCancelJob* pJob = new CCancelJob(destroyed); + bool destroyed = false; + CCancelJob* pJob = new CCancelJob(destroyed); - CThreadPool::Get().addJob(pJob); - // Don't wait for the job to run. The idea here is that we are calling - // cancelJob() before pJob->runThread() runs, but this is a race. - CThreadPool::Get().cancelJob(pJob); + CThreadPool::Get().addJob(pJob); + // Don't wait for the job to run. The idea here is that we are calling + // cancelJob() before pJob->runThread() runs, but this is a race. + CThreadPool::Get().cancelJob(pJob); - // cancelJob() should only return after successful cancellation - EXPECT_TRUE(destroyed); + // cancelJob() should only return after successful cancellation + EXPECT_TRUE(destroyed); } TEST(Thread, CancelJobWhileRunning) { - bool destroyed = false; - CCancelJob* pJob = new CCancelJob(destroyed); + bool destroyed = false; + CCancelJob* pJob = new CCancelJob(destroyed); - CThreadPool::Get().addJob(pJob); - // Wait for the job to run - pJob->wait(); - CThreadPool::Get().cancelJob(pJob); + CThreadPool::Get().addJob(pJob); + // Wait for the job to run + pJob->wait(); + CThreadPool::Get().cancelJob(pJob); - // cancelJob() should only return after successful cancellation - EXPECT_TRUE(destroyed); + // cancelJob() should only return after successful cancellation + EXPECT_TRUE(destroyed); } class CEmptyJob : public CJob { public: - CEmptyJob(bool& destroyed) : m_bDestroyed(destroyed) {} + CEmptyJob(bool& destroyed) : m_bDestroyed(destroyed) {} - ~CEmptyJob() { - EXPECT_TRUE(wasCancelled()); - m_bDestroyed = true; - } + ~CEmptyJob() { + EXPECT_TRUE(wasCancelled()); + m_bDestroyed = true; + } - virtual void runThread() {} - virtual void runMain() {} + virtual void runThread() {} + virtual void runMain() {} private: - bool& m_bDestroyed; + bool& m_bDestroyed; }; TEST(Thread, CancelJobWhenDone) { - bool destroyed = false; - CEmptyJob* pJob = new CEmptyJob(destroyed); + bool destroyed = false; + CEmptyJob* pJob = new CEmptyJob(destroyed); - CThreadPool::Get().addJob(pJob); + CThreadPool::Get().addJob(pJob); - // Wait for the job to finish - fd_set fds; - FD_ZERO(&fds); - FD_SET(CThreadPool::Get().getReadFD(), &fds); - EXPECT_EQ(1, select(1 + CThreadPool::Get().getReadFD(), &fds, nullptr, - nullptr, nullptr)); + // Wait for the job to finish + fd_set fds; + FD_ZERO(&fds); + FD_SET(CThreadPool::Get().getReadFD(), &fds); + EXPECT_EQ(1, select(1 + CThreadPool::Get().getReadFD(), &fds, nullptr, + nullptr, nullptr)); - // And only cancel it afterwards - CThreadPool::Get().cancelJob(pJob); + // And only cancel it afterwards + CThreadPool::Get().cancelJob(pJob); - // cancelJob() should only return after successful cancellation - EXPECT_TRUE(destroyed); + // cancelJob() should only return after successful cancellation + EXPECT_TRUE(destroyed); } diff --git a/test/UtilsTest.cpp b/test/UtilsTest.cpp index 42e3da25..09d9571b 100644 --- a/test/UtilsTest.cpp +++ b/test/UtilsTest.cpp @@ -19,102 +19,102 @@ #include TEST(IRC32, GetMessageTags) { - EXPECT_EQ(MCString(), CUtils::GetMessageTags("")); - EXPECT_EQ(MCString(), CUtils::GetMessageTags( - ":nick!ident@host PRIVMSG #chan :hello world")); + EXPECT_EQ(MCString(), CUtils::GetMessageTags("")); + EXPECT_EQ(MCString(), CUtils::GetMessageTags( + ":nick!ident@host PRIVMSG #chan :hello world")); - MCString exp = {{"a", "b"}}; - EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b")); - EXPECT_EQ(exp, CUtils::GetMessageTags( - "@a=b :nick!ident@host PRIVMSG #chan :hello world")); - EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b :rest")); - exp.clear(); + MCString exp = {{"a", "b"}}; + EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b")); + EXPECT_EQ(exp, CUtils::GetMessageTags( + "@a=b :nick!ident@host PRIVMSG #chan :hello world")); + EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b :rest")); + exp.clear(); - exp = {{"ab", "cdef"}, {"znc.in/gh-ij", "klmn,op"}}; - EXPECT_EQ(exp, - CUtils::GetMessageTags("@ab=cdef;znc.in/gh-ij=klmn,op :rest")); + exp = {{"ab", "cdef"}, {"znc.in/gh-ij", "klmn,op"}}; + EXPECT_EQ(exp, + CUtils::GetMessageTags("@ab=cdef;znc.in/gh-ij=klmn,op :rest")); - exp = {{"a", "==b=="}}; - EXPECT_EQ(exp, CUtils::GetMessageTags("@a===b== :rest")); - exp.clear(); + exp = {{"a", "==b=="}}; + EXPECT_EQ(exp, CUtils::GetMessageTags("@a===b== :rest")); + exp.clear(); - exp = {{"a", ""}, {"b", "c"}, {"d", ""}}; - EXPECT_EQ(exp, CUtils::GetMessageTags("@a;b=c;d :rest")); + exp = {{"a", ""}, {"b", "c"}, {"d", ""}}; + EXPECT_EQ(exp, CUtils::GetMessageTags("@a;b=c;d :rest")); - exp = {{"semi-colon", ";"}, {"space", " "}, {"NUL", {'\0'}}, - {"backslash", "\\"}, {"CR", {'\r'}}, {"LF", {'\n'}}}; - EXPECT_EQ( - exp, - CUtils::GetMessageTags( - R"(@semi-colon=\:;space=\s;NUL=\0;backslash=\\;CR=\r;LF=\n :rest)")); - exp.clear(); + exp = {{"semi-colon", ";"}, {"space", " "}, {"NUL", {'\0'}}, + {"backslash", "\\"}, {"CR", {'\r'}}, {"LF", {'\n'}}}; + EXPECT_EQ( + exp, + CUtils::GetMessageTags( + R"(@semi-colon=\:;space=\s;NUL=\0;backslash=\\;CR=\r;LF=\n :rest)")); + exp.clear(); - exp = {{"a", "; \\\r\n"}}; - EXPECT_EQ(exp, CUtils::GetMessageTags(R"(@a=\:\s\\\r\n :rest)")); - exp.clear(); + exp = {{"a", "; \\\r\n"}}; + EXPECT_EQ(exp, CUtils::GetMessageTags(R"(@a=\:\s\\\r\n :rest)")); + exp.clear(); } TEST(IRC32, SetMessageTags) { - CString sLine; + CString sLine; - sLine = ":rest"; - CUtils::SetMessageTags(sLine, MCString()); - EXPECT_EQ(":rest", sLine); + sLine = ":rest"; + CUtils::SetMessageTags(sLine, MCString()); + EXPECT_EQ(":rest", sLine); - MCString tags = {{"a", "b"}}; - CUtils::SetMessageTags(sLine, tags); - EXPECT_EQ("@a=b :rest", sLine); + MCString tags = {{"a", "b"}}; + CUtils::SetMessageTags(sLine, tags); + EXPECT_EQ("@a=b :rest", sLine); - tags = {{"a", "b"}, {"c", "d"}}; - CUtils::SetMessageTags(sLine, tags); - EXPECT_EQ("@a=b;c=d :rest", sLine); + tags = {{"a", "b"}, {"c", "d"}}; + CUtils::SetMessageTags(sLine, tags); + EXPECT_EQ("@a=b;c=d :rest", sLine); - tags = {{"a", "b"}, {"c", "d"}, {"e", ""}}; - CUtils::SetMessageTags(sLine, tags); - EXPECT_EQ("@a=b;c=d;e :rest", sLine); + tags = {{"a", "b"}, {"c", "d"}, {"e", ""}}; + CUtils::SetMessageTags(sLine, tags); + EXPECT_EQ("@a=b;c=d;e :rest", sLine); - tags = {{"semi-colon", ";"}, {"space", " "}, {"NUL", {'\0'}}, - {"backslash", "\\"}, {"CR", {'\r'}}, {"LF", {'\n'}}}; - CUtils::SetMessageTags(sLine, tags); - EXPECT_EQ( - R"(@CR=\r;LF=\n;NUL=\0;backslash=\\;semi-colon=\:;space=\s :rest)", - sLine); + tags = {{"semi-colon", ";"}, {"space", " "}, {"NUL", {'\0'}}, + {"backslash", "\\"}, {"CR", {'\r'}}, {"LF", {'\n'}}}; + CUtils::SetMessageTags(sLine, tags); + EXPECT_EQ( + R"(@CR=\r;LF=\n;NUL=\0;backslash=\\;semi-colon=\:;space=\s :rest)", + sLine); - tags = {{"a", "; \\\r\n"}}; - CUtils::SetMessageTags(sLine, tags); - EXPECT_EQ(R"(@a=\:\s\\\r\n :rest)", sLine); + tags = {{"a", "; \\\r\n"}}; + CUtils::SetMessageTags(sLine, tags); + EXPECT_EQ(R"(@a=\:\s\\\r\n :rest)", sLine); } TEST(UtilsTest, ServerTime) { - char* oldTZ = getenv("TZ"); - if (oldTZ) oldTZ = strdup(oldTZ); - setenv("TZ", "UTC", 1); - tzset(); + char* oldTZ = getenv("TZ"); + if (oldTZ) oldTZ = strdup(oldTZ); + setenv("TZ", "UTC", 1); + tzset(); - timeval tv1 = CUtils::ParseServerTime("2011-10-19T16:40:51.620Z"); - CString str1 = CUtils::FormatServerTime(tv1); - EXPECT_EQ("2011-10-19T16:40:51.620Z", str1); + timeval tv1 = CUtils::ParseServerTime("2011-10-19T16:40:51.620Z"); + CString str1 = CUtils::FormatServerTime(tv1); + EXPECT_EQ("2011-10-19T16:40:51.620Z", str1); - timeval now; - if (!gettimeofday(&now, nullptr)) { - now.tv_sec = time(nullptr); - now.tv_usec = 0; - } + timeval now; + if (!gettimeofday(&now, nullptr)) { + now.tv_sec = time(nullptr); + now.tv_usec = 0; + } - CString str2 = CUtils::FormatServerTime(now); - timeval tv2 = CUtils::ParseServerTime(str2); - EXPECT_EQ(now.tv_sec, tv2.tv_sec); - EXPECT_EQ(now.tv_usec, tv2.tv_usec); + CString str2 = CUtils::FormatServerTime(now); + timeval tv2 = CUtils::ParseServerTime(str2); + EXPECT_EQ(now.tv_sec, tv2.tv_sec); + EXPECT_EQ(now.tv_usec, tv2.tv_usec); - timeval tv3 = CUtils::ParseServerTime("invalid"); - CString str3 = CUtils::FormatServerTime(tv3); - EXPECT_EQ("1970-01-01T00:00:00.000Z", str3); + timeval tv3 = CUtils::ParseServerTime("invalid"); + CString str3 = CUtils::FormatServerTime(tv3); + EXPECT_EQ("1970-01-01T00:00:00.000Z", str3); - if (oldTZ) { - setenv("TZ", oldTZ, 1); - free(oldTZ); - } else { - unsetenv("TZ"); - } - tzset(); + if (oldTZ) { + setenv("TZ", oldTZ, 1); + free(oldTZ); + } else { + unsetenv("TZ"); + } + tzset(); }