void DelChans(const CString& sChans) { VCString vsChans; sChans.Split(" ", vsChans); for (unsigned int a = 0; a < vsChans.size(); a++) { m_ssChans.erase(vsChans[a].AsLower()); } }
CString CLogMod::JoinRules(const CString& sSeparator) const { VCString vsRules; for (const CLogRule& Rule : m_vRules) { vsRules.push_back(Rule.ToString()); } return sSeparator.Join(vsRules.begin(), vsRules.end()); }
bool CClient::OnJoinMessage(CJoinMessage& Message) { CString sChans = Message.GetTarget(); CString sKeys = Message.GetKey(); VCString vsChans; sChans.Split(",", vsChans, false); sChans.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] : ""); if (m_pNetwork) { // May be nullptr. Message.SetChan(m_pNetwork->FindChan(vsChans[a])); } bool bContinue = false; NETWORKMODULECALL(OnUserJoinMessage(Message), m_pUser, m_pNetwork, this, &bContinue); if (bContinue) continue; CString sChannel = Message.GetTarget(); CString sKey = Message.GetKey(); if (m_pNetwork) { CChan* pChan = m_pNetwork->FindChan(sChannel); if (pChan) { if (pChan->IsDetached()) pChan->AttachUser(this); else pChan->JoinUser(sKey); continue; } else if (!sChannel.empty()) { pChan = new CChan(sChannel, m_pNetwork, false); if (m_pNetwork->AddChan(pChan)) { pChan->SetKey(sKey); } } } if (!sChannel.empty()) { sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); if (!vsKeys.empty()) { sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); } } } Message.SetTarget(sChans); Message.SetKey(sKeys); return sChans.empty(); }
void CHTTPSock::ReadLine(const CString& sData) { if (m_bGotHeader) { return; } CString sLine = sData; sLine.TrimRight("\r\n"); 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; sLine.Token(1, true).Split(";", vsNV, false, "", "", true, true); for (unsigned int a = 0; a < vsNV.size(); a++) { CString s(vsNV[a]); 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_bLoggedIn = OnLogin(m_sUser, m_sPass); } 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("If-None-Match:")) { // this is for proper client cache support (HTTP 304) on static files: m_sIfNoneMatch = sLine.Token(1, true); } else if (sLine.empty()) { m_bGotHeader = true; if (m_bPost) { m_sPostData = GetInternalReadBuffer(); CheckPost(); } else { GetPage(); } DisableReadLine(); } }
void CIRCSock::ParseISupport(const CMessage& Message) { 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, "="); if (0 < sName.length() && ':' == sName[0]) { break; } m_mISupport[sName] = sValue; 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 (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 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"); } } }
void CWebSock::SetPaths(CModule* pModule, bool bIsTemplate) { m_Template.ClearPaths(); VCString vsDirs = GetDirs(pModule, bIsTemplate); for (size_t i = 0; i < vsDirs.size(); ++i) { m_Template.AppendPath(vsDirs[i]); } m_bPathsSet = true; }
CString CWebSock::FindTmpl(CModule* pModule, const CString& sName) { VCString vsDirs = GetDirs(pModule, true); CString sFile = pModule->GetModName() + "_" + sName; for (size_t i = 0; i < vsDirs.size(); ++i) { if (CFile::Exists(CDir::ChangeDir(vsDirs[i], sFile))) { m_Template.AppendPath(vsDirs[i]); return sFile; } } return sName; }
void CLogMod::SetRulesCmd(const CString& sLine) { VCString vsRules = SplitRules(sLine.Token(1, true)); if (vsRules.empty()) { PutModule("Usage: SetRules <rules>"); PutModule("Wildcards are allowed"); } else { SetRules(vsRules); SetNV("rules", JoinRules(",")); ListRulesCmd(); } }
void CUrlBufferModule::CheckLineForLink(const CString& sMessage, const CString& sOrigin) { if(sOrigin != m_pUser->GetUserName() && GetNV("enable").ToBool() ) { VCString words; CString output; sMessage.Split(" ", words, false, "", "", true, true); for (size_t a = 0; a < words.size(); a++) { CString& word = words[a]; if(word.Left(4) == "http" || word.Left(4) == "www.") { //if you find an image download it, save it in the www directory and keep the new link in buffer VCString tokens; word.Split("/", tokens, false, "", "", true, true); CString name = tokens[tokens.size()-1]; word.Split(".", tokens, false, "", "", true, true); //if it's an image link download/upload it else just keep the link time_t curtime; time(&curtime); CString dir = GetNV("directory") + CUtils::FormatTime(curtime,"%Y-%m-%d", m_pUser->GetTimezone()) + "/"; CString nickname = (sOrigin.empty())? m_pUser->GetUserName() : sOrigin; if(!CFile::Exists(dir) && !CFile::IsDir(dir, false)) { CDir::MakeDir(dir, 0775); } if(isValidExtension( tokens[tokens.size()-1] )) { std::stringstream ss; if( GetNV("enablelocal").ToBool()) { ss << "wget -b -O " << dir.c_str() << name <<" -q " << word.c_str() << " 2>&1"; getStdoutFromCommand(ss.str()); } ss.str(""); if (!word.WildCmp("*imgur*") && GetNV("reupload").ToBool()) { ss << "curl -d \"image=" << word.c_str() << "\" -d \"key=5ce86e7f95d8e58b18931bf290f387be\" http://api.imgur.com/2/upload.xml | sed -n 's/.*<original>\\(.*\\)<\\/original>.*/\\1/p' 2>&1"; output = getStdoutFromCommand(ss.str()); lastUrls.push_back(output); } else { lastUrls.push_back(word); } } else if(GetNV("bufferalllinks").ToBool()){ lastUrls.push_back(word); //append nick:link to file CString filename = dir + "links.txt"; std::ofstream log(filename.c_str() , std::ios_base::app | std::ios_base::out); log << nickname << ": " << word << "\n"; } nicks.push_back( nickname ); } } } }
void CHTTPSock::ParseParams(const CString& sParams, map<CString, VCString> &msvsParams) { msvsParams.clear(); VCString vsPairs; sParams.Split("&", vsPairs, true); for (unsigned int a = 0; a < vsPairs.size(); a++) { const CString& sPair = vsPairs[a]; 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); } }
bool CDir::MakeDir(const CString& sPath, mode_t iMode) { #ifdef _WIN32 if (sPath.empty()) return false; CString sFixedPath = sPath; sFixedPath.Replace("/", "\\"); int iResult = SHCreateDirectoryEx(0, sFixedPath.c_str(), NULL); return (iResult == ERROR_SUCCESS || iResult == ERROR_FILE_EXISTS || iResult == ERROR_ALREADY_EXISTS); #else CString sDir; VCString dirs; VCString::iterator it; // Just in case someone tries this... if (sPath.empty()) return false; // If this is an absolute path, we need to handle this now! if (sPath.Left(1) == "/") 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; int i = mkdir(sDir.c_str(), iMode); 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; } sDir += "/"; } // All went well return true; #endif }
int CChan::AddNicks(const CString& sNicks) { int iRet = 0; VCString vsNicks; VCString::iterator it; sNicks.Split(" ", vsNicks, false); for (it = vsNicks.begin(); it != vsNicks.end(); ++it) { if (AddNick(*it)) { iRet++; } } return iRet; }
bool BootStrap(CChan *pChan) { CString sFile; if (DecryptChannel(pChan->GetName(), sFile)) { if (!pChan->GetBuffer().IsEmpty()) return(true); // reloaded a module probably in this case, so just verify we can decrypt the file VCString vsLines; VCString::iterator it; sFile.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(); CString sFormat = sLine.Token(1, true); CString sText(*++it); sText.Trim(); pChan->AddBuffer(sFormat, sText, &ts); } else { // Old format, escape the line and use as is. pChan->AddBuffer(_NAMEDFMT(sLine)); } } } else { m_sPassword = ""; CUtils::PrintError("[" + GetModName() + ".so] Failed to Decrypt [" + pChan->GetName() + "]"); return(false); } return(true); }
virtual bool OnLoad(const CString& sArgs, CString& sMessage) { VCString vsChans; sArgs.Split(" ", vsChans, false); for (VCString::const_iterator it = vsChans.begin(); it != vsChans.end(); ++it) { if (!Add(*it)) { PutModule("Unable to add [" + *it + "]"); } } // Load our saved settings, ignore errors MCString::iterator it; for (it = BeginNV(); it != EndNV(); ++it) { Add(it->first); } return true; }
size_t CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const map<CString, VCString>& msvsParams, const CString& sFilter) { vsRet.clear(); map<CString, VCString>::const_iterator it = msvsParams.find(sName); 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); } } return vsRet.size(); }
bool CStickyChan::OnLoad(const CString& sArgs, CString& sMessage) { VCString vsChans; VCString::iterator it; sArgs.Split(",", vsChans, false); for (it = vsChans.begin(); it != vsChans.end(); ++it) { CString sChan = it->Token(0); CString sKey = it->Token(1, true); SetNV(sChan, sKey); } // Since we now have these channels added, clear the argument list SetArgs(""); AddTimer(RunTimer, "StickyChanTimer", 15); return(true); }
virtual EModRet OnUserRaw(CString& sLine) { //Handle ISON if (sLine.Token(0).Equals("ison")) { VCString vsNicks; VCString::const_iterator it; // Get the list of nicks which are being asked for sLine.Token(1, true).TrimLeft_n(":").Split(" ", vsNicks, false); CString sBNCNicks; for (it = vsNicks.begin(); it != vsNicks.end(); ++it) { if (IsOnlineModNick(*it)) { sBNCNicks += " " + *it; } } // Remove the leading space sBNCNicks.LeftChomp(); if (!m_pNetwork->GetIRCSock()) { // if we are not connected to any IRC server, send // an empty or module-nick filled response. PutUser(":irc.znc.in 303 " + m_pClient->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); if (IsOnlineModNick(sNick)) { PutUser(":znc.in 311 " + m_pNetwork->GetCurNick() + " " + sNick + " " + sNick + " znc.in * :" + sNick); PutUser(":znc.in 312 " + m_pNetwork->GetCurNick() + " " + sNick + " *.znc.in :Bouncer"); PutUser(":znc.in 318 " + m_pNetwork->GetCurNick() + " " + sNick + " :End of /WHOIS list."); return HALT; } } return CONTINUE; }
void Replay(const CString & sChan) { CString sFile; PutUser(":***[email protected] PRIVMSG " + sChan + " :Buffer Playback..."); if (DecryptChannel(sChan, sFile)) { VCString vsLines; VCString::iterator it; sFile.Split("\n", vsLines); for (it = vsLines.begin(); it != vsLines.end(); ++it) { CString sLine(*it); sLine.Trim(); PutUser(sLine); } } PutUser(":***[email protected] PRIVMSG " + sChan + " :Playback Complete."); }
void SetMechanismCommand(const CString& sLine) { CString sMechanisms = sLine.Token(1, true).AsUpper(); if (!sMechanisms.empty()) { VCString vsMechanisms; sMechanisms.Split(" ", vsMechanisms); for (VCString::const_iterator it = vsMechanisms.begin(); it != vsMechanisms.end(); ++it) { if (!SupportsMechanism(*it)) { PutModule("Unsupported mechanism: " + *it); return; } } SetNV(NV_MECHANISMS, sMechanisms); } PutModule("Current mechanisms set: " + GetMechanismsString()); }
bool ConvertCharset(const VCString& vsFrom, const CString& sTo, CString& sData) { CString sDataCopy(sData); if(!m_bForce) { // check whether sData already is encoded with the right charset: iconv_t icTest = iconv_open(sTo.c_str(), sTo.c_str()); if(icTest != (iconv_t)-1) { size_t uTest = GetConversionLength(icTest, sData); iconv_close(icTest); if(uTest != (size_t)-1 && uTest != (size_t)-2) { DEBUG("charset: [" + sData.Escape_n(CString::EURL) + "] is valid [" + sTo + "] already."); return true; } } } bool bConverted = false; // try all possible source charsets: for(VCString::const_iterator itf = vsFrom.begin(); itf != vsFrom.end(); ++itf) { if(ConvertCharset(*itf, sTo, sDataCopy)) { // conversion successful! sData = sDataCopy; bConverted = true; break; } else { // reset string and try the next charset: sDataCopy = sData; } } return bConverted; }
CString CMessage::GetParamsColon(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()); }
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.Left(1).CaseCmp(".") == 0) sCmd = "Binds::ProcessDcc - - {" + sCmd + "}"; 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()); } }
virtual bool OnLoad(const CString& sArgs, CString& sMessage) { OnBoot(); MCString::iterator it; for (it = BeginNV(); it != EndNV(); it++) { VCString vsKeys; VCString::iterator it2; if (CZNC::Get().FindUser(it->first) == NULL) { DEBUG("Unknown user in saved data [" + it->first + "]"); continue; } it->second.Split(" ", vsKeys, false); for (it2 = vsKeys.begin(); it2 != vsKeys.end(); it2++) { m_PubKeys[it->first].insert(*it2); } } return true; }
virtual void OnModCommand(const CString& sCmdLine) { CString sCommand = sCmdLine.Token(0); CString sArgs = sCmdLine.Token(1, true); if (sCommand.Equals("setpass")) { PutModule("Password set to [" + sArgs + "]"); m_sPassword = CBlowfish::MD5(sArgs); } else if (sCommand.Equals("dumpbuff")) { CString sFile; if (DecryptChannel(sArgs, sFile)) { VCString vsLines; VCString::iterator it; sFile.Split("\n", vsLines); for (it = vsLines.begin(); it != vsLines.end(); ++it) { CString sLine(*it); sLine.Trim(); PutModule("[" + sLine + "]"); } } PutModule("//!-- EOF " + sArgs); } else if (sCommand.Equals("replay")) { Replay(sArgs); PutModule("Replayed " + sArgs); } else if (sCommand.Equals("save")) { SaveBufferToDisk(); PutModule("Done."); } else PutModule("Unknown command [" + sCommand + "]"); }
bool CDir::MakeDir(const CString& sPath, mode_t iMode) { CString sDir; VCString dirs; VCString::iterator it; // 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 = "/"; // 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); 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; } sDir += "/"; } // All went well return true; }
bool BootStrap() { CString sFile; if (DecryptMessages(sFile)) { VCString vsLines; VCString::iterator it; 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); } return(true); }
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); } // 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; } } return true; }
VCString CWebSock::GetDirs(CModule* pModule, bool bIsTemplate) { CString sHomeSkinsDir(CZNC::Get().GetZNCPath() + "/webskins/"); CString sSkinName(GetSkinName()); VCString vsResult; // Module specific paths if (pModule) { const CString& sModName(pModule->GetModName()); // 1. ~/.znc/webskins/<user_skin_setting>/mods/<mod_name>/ // if (!sSkinName.empty()) { vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + "/"); } // 2. ~/.znc/webskins/_default_/mods/<mod_name>/ // vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + "/"); // 3. ./modules/<mod_name>/tmpl/ // vsResult.push_back(pModule->GetModDataDir() + "/tmpl/"); // 4. ~/.znc/webskins/<user_skin_setting>/mods/<mod_name>/ // if (!sSkinName.empty()) { vsResult.push_back(GetSkinPath(sSkinName) + "/mods/" + sModName + "/"); } // 5. ~/.znc/webskins/_default_/mods/<mod_name>/ // vsResult.push_back(GetSkinPath("_default_") + "/mods/" + sModName + "/"); } // 6. ~/.znc/webskins/<user_skin_setting>/ // if (!sSkinName.empty()) { vsResult.push_back(GetSkinPath(sSkinName) + CString(bIsTemplate ? "/tmpl/" : "/")); } // 7. ~/.znc/webskins/_default_/ // vsResult.push_back(GetSkinPath("_default_") + CString(bIsTemplate ? "/tmpl/" : "/")); return vsResult; }
CMessage CBufLine::ToMessage(const CClient& Client, const MCString& mssParams) const { CMessage Line = m_Message; 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); } // 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; }
virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl) { if (sPageName != "index") { // only accept requests to /mods/perform/ return false; } if (WebSock.IsPost()) { VCString vsPerf; WebSock.GetRawParam("perform", true).Split("\n", vsPerf, false); m_vPerform.clear(); for (VCString::const_iterator it = vsPerf.begin(); it != vsPerf.end(); ++it) m_vPerform.push_back(ParsePerform(*it)); Save(); } for (VCString::const_iterator it = m_vPerform.begin(); it != m_vPerform.end(); ++it) { CTemplate& Row = Tmpl.AddRow("PerformLoop"); Row["Perform"] = *it; } return true; }