<commit_before>#include "main.h"
#include "User.h"
#include "Nick.h"
#include "Modules.h"
#include "Chan.h"
#include "znc.h"
#include "HTTPSock.h"
#include "Server.h"
#include "Template.h"

class CWebAdminMod;

class CWebAdminSock : public CHTTPSock {
public:
	CWebAdminSock(CWebAdminMod* pModule);
	CWebAdminSock(CWebAdminMod* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60);
	virtual ~CWebAdminSock();

	virtual bool OnPageRequest(const CString& sURI, CString& sPageRet);
	virtual bool OnLogin(const CString& sUser, const CString& sPass);

	CString GetSkinDir();
	void PrintPage(CString& sPageRet, const CString& sTmplName);

	void GetErrorPage(CString& sPageRet, const CString& sError) {
		m_Template["Title"] = "Error";
		m_Template["Error"] = sError;

		PrintPage(sPageRet, "Error.tmpl");
	}

	void ListUsersPage(CString& sPageRet);
	bool SettingsPage(CString& sPageRet);
	bool ChanPage(CString& sPageRet, CChan* = NULL);
	bool DelChan(CString& sPageRet);
	bool UserPage(CString& sPageRet, CUser* pUser = NULL);
	CUser* GetNewUser(CString& sPageRet, CUser* pUser);

	CString GetModArgs(const CString& sModName, bool bGlobal = false) {
		if (!bGlobal && !m_pUser) {
			return "";
		}

		CModules& Modules = (bGlobal) ? CZNC::Get().GetModules() : m_pUser->GetModules();

		for (unsigned int a = 0; a < Modules.size(); a++) {
			CModule* pModule = Modules[a];

			if (pModule->GetModName() == sModName) {
				return pModule->GetArgs();
			}
		}

		return "";
	}

	virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
	bool IsAdmin(bool bAllowUserAdmin = true) const { return m_bAdmin; }

private:
protected:
	CWebAdminMod*	m_pModule;
	CUser*			m_pUser;
	bool			m_bAdmin;
	CTemplate		m_Template;
};

class CWebAdminMod : public CGlobalModule {
public:
	CWebAdminMod(void *pDLL, const CString& sModName) : CGlobalModule(pDLL, sModName) {
		m_uPort = 8080;
		m_sSkinName = GetNV("SkinName");
	}

	virtual ~CWebAdminMod() {
		while (m_spSocks.size()) {							// Loop through the sockets that we have created
			m_pManager->DelSockByAddr(*m_spSocks.begin());	// Delete each one which will call SockDestroyed() and erase it from the set
		}													// This way we don't want to erase it ourselves, that's why we're using the funky while loop

		m_spSocks.clear();
	}

	virtual bool OnBoot() {
		return true;
	}

	virtual bool OnLoad(const CString& sArgs) {
		bool bSSL = false;
		CString sPort = sArgs.Token(0);

		if (sPort.Left(1) == "+") {
#ifdef HAVE_LIBSSL
			sPort.TrimLeft("+");
			bSSL = true;
#else
			return false;
#endif
		}

		if (!sPort.empty()) {
			m_uPort = sPort.ToUInt();
		}

		CWebAdminSock* pListenSock = new CWebAdminSock(this);
#ifdef HAVE_LIBSSL
		if (bSSL) {
			pListenSock->SetPemLocation(CZNC::Get().GetPemLocation());
		}
#endif

		return m_pManager->ListenHost(m_uPort, "WebAdmin::Listener", CZNC::Get().GetListenHost(), bSSL, SOMAXCONN, pListenSock);
	}

	void AddSock(CWebAdminSock* pSock) {
		m_spSocks.insert(pSock);
	}

	void SockDestroyed(CWebAdminSock* pSock) {
		m_spSocks.erase(pSock);
	}

	void SetSkinName(const CString& s) {
		m_sSkinName = s;
		SetNV("SkinName", m_sSkinName);
	}

	CString GetSkinName() const { return (m_sSkinName.empty()) ? CString("default") : m_sSkinName; }

private:
	unsigned int		m_uPort;
	CString				m_sSkinName;
	set<CWebAdminSock*>	m_spSocks;
};
 
CString CWebAdminSock::GetSkinDir() {
	CString sModPath = CZNC::Get().FindModPath(m_pModule->GetModName());	// @todo store the path to the module at load time and store it in a member var which can be used here

	while (!sModPath.empty() && sModPath.Right(1) != "/") {
		sModPath.RightChomp();<commit_msg>Added listen host support<commit_after>#include "main.h"
#include "User.h"
#include "Nick.h"
#include "Modules.h"
#include "Chan.h"
#include "znc.h"
#include "HTTPSock.h"
#include "Server.h"
#include "Template.h"

class CWebAdminMod;

class CWebAdminSock : public CHTTPSock {
public:
	CWebAdminSock(CWebAdminMod* pModule);
	CWebAdminSock(CWebAdminMod* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60);
	virtual ~CWebAdminSock();

	virtual bool OnPageRequest(const CString& sURI, CString& sPageRet);
	virtual bool OnLogin(const CString& sUser, const CString& sPass);

	CString GetSkinDir();
	void PrintPage(CString& sPageRet, const CString& sTmplName);

	void GetErrorPage(CString& sPageRet, const CString& sError) {
		m_Template["Title"] = "Error";
		m_Template["Error"] = sError;

		PrintPage(sPageRet, "Error.tmpl");
	}

	void ListUsersPage(CString& sPageRet);
	bool SettingsPage(CString& sPageRet);
	bool ChanPage(CString& sPageRet, CChan* = NULL);
	bool DelChan(CString& sPageRet);
	bool UserPage(CString& sPageRet, CUser* pUser = NULL);
	CUser* GetNewUser(CString& sPageRet, CUser* pUser);

	CString GetModArgs(const CString& sModName, bool bGlobal = false) {
		if (!bGlobal && !m_pUser) {
			return "";
		}

		CModules& Modules = (bGlobal) ? CZNC::Get().GetModules() : m_pUser->GetModules();

		for (unsigned int a = 0; a < Modules.size(); a++) {
			CModule* pModule = Modules[a];

			if (pModule->GetModName() == sModName) {
				return pModule->GetArgs();
			}
		}

		return "";
	}

	virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
	bool IsAdmin(bool bAllowUserAdmin = true) const { return m_bAdmin; }

private:
protected:
	CWebAdminMod*	m_pModule;
	CUser*			m_pUser;
	bool			m_bAdmin;
	CTemplate		m_Template;
};

class CWebAdminMod : public CGlobalModule {
public:
	CWebAdminMod(void *pDLL, const CString& sModName) : CGlobalModule(pDLL, sModName) {
		m_uPort = 8080;
		m_sSkinName = GetNV("SkinName");
	}

	virtual ~CWebAdminMod() {
		while (m_spSocks.size()) {							// Loop through the sockets that we have created
			m_pManager->DelSockByAddr(*m_spSocks.begin());	// Delete each one which will call SockDestroyed() and erase it from the set
		}													// This way we don't want to erase it ourselves, that's why we're using the funky while loop

		m_spSocks.clear();
	}

	virtual bool OnBoot() {
		return true;
	}

	virtual bool OnLoad(const CString& sArgs) {
		bool bSSL = false;
		CString sPort;

		if (sArgs.find(" ") != CString::npos) {
			m_sListenHost = sArgs.Token(0);
			sPort = sArgs.Token(1);
		} else {
			sPort = sArgs.Token(0);
		}

		if (sPort.Left(1) == "+") {
#ifdef HAVE_LIBSSL
			sPort.TrimLeft("+");
			bSSL = true;
#else
			return false;
#endif
		}

		if (!sPort.empty()) {
			m_uPort = sPort.ToUInt();
		}

		CWebAdminSock* pListenSock = new CWebAdminSock(this);
#ifdef HAVE_LIBSSL
		if (bSSL) {
			pListenSock->SetPemLocation(CZNC::Get().GetPemLocation());
		}
#endif

		return m_pManager->ListenHost(m_uPort, "WebAdmin::Listener", m_sListenHost, bSSL, SOMAXCONN, pListenSock);
	}

	void AddSock(CWebAdminSock* pSock) {
		m_spSocks.insert(pSock);
	}

	void SockDestroyed(CWebAdminSock* pSock) {
		m_spSocks.erase(pSock);
	}

	void SetSkinName(const CString& s) {
		m_sSkinName = s;
		SetNV("SkinName", m_sSkinName);
	}

	CString GetSkinName() const { return (m_sSkinName.empty()) ? CString("default") : m_sSkinName; }

private:
	unsigned int		m_uPort;
	CString				m_sSkinName;
	set<CWebAdminSock*>	m_spSocks;
	CString				m_sListenHost;
};
 
CString CWebAdminSock::GetSkinDir() {
	CString sModPath = CZNC::Get().FindModPath(m_pModule->GetModName());	// @todo store the path to the module at load time and store it in a member var which can be used here

	while (!sModPath.empty() && sModPath.Right(1) != "/") {
		sModPath.RightChomp();
{'fraction_non_alphanumeric': 0.13402749966626618, 'fraction_numerical': 0.002936857562408223, 'mean_word_length': 4.57855547282204, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7208060', 'n_tokens_mistral': 3116, 'n_tokens_neox': 2837, 'n_words': 669}