String GetHomeDirectory() { String r; INTERLOCKED_(sHlock) { String& s = sHomeDir(); if(s.IsEmpty()) { s = Nvl(GetEnv("HOME"), "/root"); } r = s; } return r; }
CString CDir::ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHome) { CString sHomeDir(sHome); if (sHomeDir.empty()) { sHomeDir = CFile::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; }
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 }