Example #1
0
    void OnGetAvailableMods(set<CModInfo>& ssMods,
                            CModInfo::EModuleType eType) override {
        CDir Dir;
        CModules::ModDirList dirs = CModules::GetModDirs();

        while (!dirs.empty()) {
            set<CString> 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);

                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);
            }

            dirs.pop();
        }
    }
Example #2
0
	virtual void OnGetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eType) {

		unsigned int a = 0;
		CDir Dir;

		CModules::ModDirList dirs = CModules::GetModDirs();

		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)) {
					ssMods.insert(ModInfo);
				}
				PEND;
			}
		}
	}
Example #3
0
File: Modules.cpp Project: md-5/znc
void CModules::GetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eType) {
	ssMods.clear();

	unsigned int a = 0;
	CDir Dir;

	ModDirList dirs = GetModDirs();

	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);

			CString sIgnoreRetMsg;
			if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) {
				if (ModInfo.SupportsType(eType)) {
					ssMods.insert(ModInfo);
				}
			}
		}
	}

	GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NOTHING);
}
Example #4
0
File: User.cpp Project: johnfb/znc
bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
	TOption<const CString&> 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 },
	};
	size_t numStringOptions = sizeof(StringOptions) / sizeof(StringOptions[0]);
	TOption<unsigned int> UIntOptions[] = {
		{ "jointries", &CUser::SetJoinTries },
	};
	size_t numUIntOptions = sizeof(UIntOptions) / sizeof(UIntOptions[0]);
	TOption<bool> BoolOptions[] = {
		{ "keepbuffer", &CUser::SetKeepBuffer }, // XXX compatibility crap from pre-0.207
		{ "autoclearchanbuffer", &CUser::SetAutoClearChanBuffer },
		{ "multiclients", &CUser::SetMultiClients },
		{ "denyloadmod", &CUser::SetDenyLoadMod },
		{ "admin", &CUser::SetAdmin },
		{ "denysetbindhost", &CUser::SetDenySetBindHost },
		{ "denysetvhost", &CUser::SetDenySetBindHost },
		{ "appendtimestamp", &CUser::SetTimestampAppend },
		{ "prependtimestamp", &CUser::SetTimestampPrepend },
	};
	size_t numBoolOptions = sizeof(BoolOptions) / sizeof(BoolOptions[0]);

	for (size_t i = 0; i < numStringOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(StringOptions[i].name, sValue))
			(this->*StringOptions[i].pSetter)(sValue);
	}
	for (size_t i = 0; i < numUIntOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(UIntOptions[i].name, sValue))
			(this->*UIntOptions[i].pSetter)(sValue.ToUInt());
	}
	for (size_t i = 0; i < numBoolOptions; i++) {
		CString sValue;
		if (pConfig->FindStringEntry(BoolOptions[i].name, sValue))
			(this->*BoolOptions[i].pSetter)(sValue.ToBool());
	}

	VCString vsList;
	VCString::const_iterator vit;
	pConfig->FindStringVector("allow", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		AddAllowedHost(*vit);
	}
	pConfig->FindStringVector("ctcpreply", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		const CString& sValue = *vit;
		AddCTCPReply(sValue.Token(0), sValue.Token(1, true));
	}

	CString sValue;

	// MaxJoins has been removed
	pConfig->FindStringEntry("maxjoins", 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, NULL, sModRet);

			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("awaysuffix", sValue)) {
		CUtils::PrintMessage("WARNING: AwaySuffix has been depricated, 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 = <plain text>
	// Pass = <md5 hash> -
	// Pass = plain#<plain text>
	// Pass = <hash name>#<hash>
	// Pass = <hash name>#<salted hash>#<salt>#
	// 'Salted hash' means hash of 'password' + 'salt'
	// Possible hashes are md5 and sha256
	if (sValue.Right(1) == "-") {
		sValue.RightChomp();
		sValue.Trim();
		SetPass(sValue, 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;
		}

		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;
	}

	pConfig->FindSubConfig("network", subConf);
	for (subIt = subConf.begin(); subIt != subConf.end(); ++subIt) {
		const CString& sNetworkName = subIt->first;

		CIRCNetwork *pNetwork = FindNetwork(sNetworkName);

		if (!pNetwork) {
			pNetwork = new CIRCNetwork(this, sNetworkName);
		}

		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) {
			pNetwork = AddNetwork("default");
		}

		if (pNetwork) {
			CUtils::PrintMessage("NOTICE: Found deprecated config, upgrading to a network");

			if (!pNetwork->ParseConfig(pConfig, sError, true)) {
				return false;
			}
		}
	}

	pConfig->FindStringVector("loadmodule", vsList);
	for (vit = vsList.begin(); vit != vsList.end(); ++vit) {
		sValue = *vit;
		CString sModName = sValue.Token(0);

		// XXX Legacy crap, added in ZNC 0.089
		if (sModName == "discon_kick") {
			CUtils::PrintMessage("NOTICE: [discon_kick] was renamed, loading [disconkick] instead");
			sModName = "disconkick";
		}

		// XXX Legacy crap, added in ZNC 0.099
		if (sModName == "fixfreenode") {
			CUtils::PrintMessage("NOTICE: [fixfreenode] doesn't do anything useful anymore, ignoring it");
			continue;
		}

		CUtils::PrintAction("Loading Module [" + sModName + "]");
		CString sModRet;
		CString sArgs = sValue.Token(1, true);
		bool bModRet = true;

		CModInfo ModInfo;
		if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sModName, sModRet)) {
			sError = "Unable to find modinfo [" + sModName + "] [" + sModRet + "]";
			return false;
		}

		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");

			for (vector<CIRCNetwork*>::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
				if (fNVFile.Exists()) {
					CString sNetworkModPath = (*it)->GetNetworkPath() + "/moddata/" + sModName;
					if (!CFile::Exists(sNetworkModPath)) {
						CDir::MakeDir(sNetworkModPath);
					}

					fNVFile.Copy(sNetworkModPath + "/.registry");
				}

				bModRet = (*it)->GetModules().LoadModule(sModName, sArgs, CModInfo::NetworkModule, this, *it, sModRet);
				if (!bModRet) {
					break;
				}
			}
		} else {
			bModRet = GetModules().LoadModule(sModName, sArgs, CModInfo::UserModule, this, NULL, sModRet);
		}

		CUtils::PrintStatus(bModRet, sModRet);
		if (!bModRet) {
			sError = sModRet;
			return false;
		}
		continue;
	}

	// Move ircconnectenabled to the networks
	if (pConfig->FindStringEntry("ircconnectenabled", sValue)) {
		for (vector<CIRCNetwork*>::iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
			(*it)->SetIRCConnectEnabled(sValue.ToBool());
		}
	}

	return true;
}
CString CDir::ChangeDir(const CString& sPathIn, const CString& sAddIn, const CString& sHomeIn) {
	/* this function is pretty crappy but needed to fix ZNC's strange way of handling file paths */
	CString sResult;
	CString sPath(sPathIn);
	CString sAdd(sAddIn);
	CString sHomeDir(sHomeIn);

	if (sHomeDir.empty())
	{
		// use the default home dir, if no custom home dir has been passed in.
		sHomeDir = CZNC::Get().GetHomePath();
	}

	// we want to use backslashes for this function's inner workings.
	sHomeDir.Replace("/", "\\");
	sPath.Replace("/", "\\");
	sAdd.Replace("/", "\\");

	if (sAdd == "~")
	{
		// if the add dir is the home dir (why?!), use that as result...
		sResult = sHomeDir;
	}
	else
	{
		if(!PathIsRelative(sAdd.c_str()))
		{
			// if add already is an absolute path, use it for the result...
			// ... however, it can still contain ./ or ../ stuff,
			// which will be resolved later.
			sResult = sAdd;
		}
		else
		{
			// if the first part of the path (sPath) is relative,
			// make it absolute, starting from the znc.exe directory:
			if(PathIsRelative(sPath.c_str()))
			{
				char szLocalPath[1024] = {0};

				// get the full path to znc.exe and strip off "znc.exe" from the end:
				if(GetModuleFileName(NULL, szLocalPath, 1023) != 0 && szLocalPath[0])
				{
					PathRemoveFileSpec(szLocalPath);

					if(PathIsDirectory(szLocalPath))
					{
						// append the relative sPath to our znc.exe dir,
						// thereby making it absolute.
						char szAbsolutePathBuffer[1024] = {0};
						PathCombine(szAbsolutePathBuffer, szLocalPath, sPath.c_str());

						// PathCombine will also resolve any ./ or ../ parts in the path.

						// use the now-absolute path:
						sPath = szAbsolutePathBuffer;
					}
				}
			}

			// append the (relative) sAdd path to the (absolute) sPath path:
			char szAbsoluteResultBuffer[1024] = {0};
			PathCombine(szAbsoluteResultBuffer, sPath.c_str(), sAdd.c_str());

			sResult = szAbsoluteResultBuffer;
		}
	}

	char szResultBuffer[1024] = {0};
	
	// make sure no ./ or ../ stuff survives this function. never.
	if(!sResult.empty() && PathCanonicalize(szResultBuffer, sResult.c_str()))
	{
		if(sAdd.empty() || sAdd[sAdd.length() - 1] != '\\')
		{
			PathRemoveBackslash(szResultBuffer);
		}
		else
		{
			PathAddBackslash(szResultBuffer);
		}

		sResult = szResultBuffer;
		sResult.Replace("\\", "/");

		return sResult;
	}
	else
	{
		abort();
		return ""; // to shut up compiler warning
	}
#else
CString CDir::ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHome) {
	CString sHomeDir(sHome);

	if (sHomeDir.empty()) {
		sHomeDir = CZNC::Get().GetHomePath();
	}

	if (sAdd == "~") {
		return sHomeDir;
	}

	CString sAddDir(sAdd);

	if (sAddDir.Left(2) == "~/") {
		sAddDir.LeftChomp();
		sAddDir = sHomeDir + sAddDir;
	}

	CString sRet = ((sAddDir.size()) && (sAddDir[0] == '/')) ? "" : sPath;
	sAddDir += "/";
	CString sCurDir;

	if (sRet.Right(1) == "/") {
		sRet.RightChomp();
	}

	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;
		}
	}

	return (sRet.empty()) ? "/" : sRet;
#endif
}