diff --git a/Client.cpp b/Client.cpp index 9ec2ab2d..850ec7b5 100644 --- a/Client.cpp +++ b/Client.cpp @@ -1020,7 +1020,7 @@ void CClient::UserCommand(const CString& sLine) { return; } - sAbsolutePath = CUtils::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath()); + sAbsolutePath = CDir::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath()); if (sAbsolutePath.Left(sAllowedPath.length()) != sAllowedPath) { PutStatus("Illegal path."); @@ -1040,7 +1040,7 @@ void CClient::UserCommand(const CString& sLine) { return; } - sAbsolutePath = CUtils::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath()); + sAbsolutePath = CDir::ChangeDir(m_pUser->GetDLPath(), sFile, CZNC::Get().GetHomePath()); if (sAbsolutePath.Left(sAllowedPath.length()) != sAllowedPath) { PutStatus("Illegal path."); diff --git a/FileUtils.cpp b/FileUtils.cpp index 4b379d12..364458e5 100644 --- a/FileUtils.cpp +++ b/FileUtils.cpp @@ -357,6 +357,104 @@ CString CFile::GetDir() const { void CFile::SetFD(int iFD) { m_iFD = iFD; } +CString CDir::ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir) { + 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; +} + +int CDir::MakeDir(const CString& sPath, mode_t iMode) { + CString sDir = sPath; + CString::size_type iFind = sDir.find("/"); + + if (iFind == CString::npos) { + return mkdir(sDir.c_str(), iMode); + } + iFind++; + + while ((iFind < sDir.length()) && (sDir[iFind] == '/')) { + iFind++; // eat up extra /'s + } + + if (iFind >= sDir.length()) { + return mkdir(sDir.c_str(), iMode); + } + + CString sWorkDir = sDir.substr(0, iFind); // include the trailing slash + CString sNewDir = sDir.erase(0, iFind); + + struct stat st; + + if (sWorkDir.length() > 1) { + sWorkDir = sWorkDir.erase(sWorkDir.length() - 1, 1); // trim off the trailing slash + } + + if (stat(sWorkDir.c_str(), &st) == 0) { + int iChdir = chdir(sWorkDir.c_str()); + if (iChdir != 0) { + return iChdir; // could not change to dir + } + + // go ahead and call the next step + return MakeDir(sNewDir.c_str(), iMode); + } + + switch(errno) { + case ENOENT: { + // ok, file doesn't exists, lets create it and cd into it + int iMkdir = mkdir(sWorkDir.c_str(), iMode); + if (iMkdir != 0) { + return iMkdir; // could not create dir + } + + int iChdir = chdir(sWorkDir.c_str()); + if (iChdir != 0) { + return iChdir; // could not change to dir + } + + return MakeDir(sNewDir.c_str(), iMode); + } + default: + break; + } + + return -1; +} + int CExecSock::popen2(int & iReadFD, int & iWriteFD, const CString & sCommand) { int rpipes[2] = { -1, -1 }; int wpipes[2] = { -1, -1 }; diff --git a/FileUtils.h b/FileUtils.h index 7b3f4f86..0f3f60b6 100644 --- a/FileUtils.h +++ b/FileUtils.h @@ -266,6 +266,9 @@ public: CFile::EFileAttr GetSortAttr() { return m_eSortAttr; } bool IsDescending() { return m_bDesc; } + static CString ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir); + static int MakeDir(const CString& sPath, mode_t iMode = 0700); + static CString GetCWD() { CString sRet; char * pszCurDir = getcwd(NULL, 0); diff --git a/HTTPSock.cpp b/HTTPSock.cpp index ccc372ad..91bfdcb3 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -116,7 +116,7 @@ bool CHTTPSock::PrintFile(const CString& sFileName, CString sContentType) { sFilePath.LeftChomp(1); } - sFilePath = CUtils::ChangeDir(m_sDocRoot, sFilePath, m_sDocRoot); + sFilePath = CDir::ChangeDir(m_sDocRoot, sFilePath, m_sDocRoot); if (sFilePath.Left(m_sDocRoot.size()) != m_sDocRoot) { PrintErrorPage(403, "Forbidden", "You don't have permission to access that file on this server."); diff --git a/Modules.h b/Modules.h index f03c5821..27203649 100644 --- a/Modules.h +++ b/Modules.h @@ -316,7 +316,7 @@ public: MCString::iterator BeginNV() { return m_mssRegistry.begin(); } void DelNV(MCString::iterator it) { m_mssRegistry.erase(it); } - const CString& GetSavePath() const { if (!CFile::Exists(m_sSavePath)) { CUtils::MakeDir(m_sSavePath); } return m_sSavePath; } + const CString& GetSavePath() const { if (!CFile::Exists(m_sSavePath)) { CDir::MakeDir(m_sSavePath); } return m_sSavePath; } // Setters void SetFake(bool b) { m_bFake = b; } diff --git a/User.cpp b/User.cpp index 3ebf29a5..1f596da6 100644 --- a/User.cpp +++ b/User.cpp @@ -914,7 +914,7 @@ bool CUser::ResumeFile(const CString& sRemoteNick, unsigned short uPort, unsigne } bool CUser::SendFile(const CString& sRemoteNick, const CString& sFileName, const CString& sModuleName) { - CString sFullPath = CUtils::ChangeDir(GetDLPath(), sFileName, CZNC::Get().GetHomePath()); + CString sFullPath = CDir::ChangeDir(GetDLPath(), sFileName, CZNC::Get().GetHomePath()); CDCCSock* pSock = new CDCCSock(this, sRemoteNick, sFullPath, sModuleName); CFile* pFile = pSock->OpenFile(false); diff --git a/User.h b/User.h index 7094920f..2803d170 100644 --- a/User.h +++ b/User.h @@ -168,8 +168,8 @@ public: const CString& GetChanPrefixes() const { return m_sChanPrefixes; } bool IsChan(const CString& sChan) const; - const CString& GetUserPath() const { if (!CFile::Exists(m_sUserPath)) { CUtils::MakeDir(m_sUserPath); } return m_sUserPath; } - const CString& GetDLPath() const { if (!CFile::Exists(m_sDLPath)) { CUtils::MakeDir(m_sDLPath); } return m_sDLPath; } + const CString& GetUserPath() const { if (!CFile::Exists(m_sUserPath)) { CDir::MakeDir(m_sUserPath); } return m_sUserPath; } + const CString& GetDLPath() const { if (!CFile::Exists(m_sDLPath)) { CDir::MakeDir(m_sDLPath); } return m_sDLPath; } bool UseClientIP() const; bool GetKeepNick() const; diff --git a/Utils.cpp b/Utils.cpp index 89eb878e..451d7547 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -159,104 +159,6 @@ unsigned long CUtils::GetLongIP(const CString& sIP) { return (unsigned long) ((atoi(ip[0]) << 24) + (atoi(ip[1]) << 16) + (atoi(ip[2]) << 8) + atoi(ip[3])); } -CString CUtils::ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir) { - 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; -} - -int CUtils::MakeDir(const CString& sPath, mode_t iMode) { - CString sDir = sPath; - CString::size_type iFind = sDir.find("/"); - - if (iFind == CString::npos) { - return mkdir(sDir.c_str(), iMode); - } - iFind++; - - while ((iFind < sDir.length()) && (sDir[iFind] == '/')) { - iFind++; // eat up extra /'s - } - - if (iFind >= sDir.length()) { - return mkdir(sDir.c_str(), iMode); - } - - CString sWorkDir = sDir.substr(0, iFind); // include the trailing slash - CString sNewDir = sDir.erase(0, iFind); - - struct stat st; - - if (sWorkDir.length() > 1) { - sWorkDir = sWorkDir.erase(sWorkDir.length() - 1, 1); // trim off the trailing slash - } - - if (stat(sWorkDir.c_str(), &st) == 0) { - int iChdir = chdir(sWorkDir.c_str()); - if (iChdir != 0) { - return iChdir; // could not change to dir - } - - // go ahead and call the next step - return MakeDir(sNewDir.c_str(), iMode); - } - - switch(errno) { - case ENOENT: { - // ok, file doesn't exists, lets create it and cd into it - int iMkdir = mkdir(sWorkDir.c_str(), iMode); - if (iMkdir != 0) { - return iMkdir; // could not create dir - } - - int iChdir = chdir(sWorkDir.c_str()); - if (iChdir != 0) { - return iChdir; // could not change to dir - } - - return MakeDir(sNewDir.c_str(), iMode); - } - default: - break; - } - - return -1; -} - CString CUtils::GetHashPass() { while (true) { char* pass = CUtils::GetPass("Enter Password"); diff --git a/Utils.h b/Utils.h index 114ea1f3..0cbaa8e6 100644 --- a/Utils.h +++ b/Utils.h @@ -44,8 +44,6 @@ public: static CString GetIP(unsigned long addr); static unsigned long GetLongIP(const CString& sIP); - static CString ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir); - static int MakeDir(const CString& sPath, mode_t iMode = 0700); static void SetStdoutIsTTY(bool b) { stdoutIsTTY = b; } static void PrintError(const CString& sMessage); diff --git a/modules/shell.cpp b/modules/shell.cpp index a6178479..e9dabcad 100644 --- a/modules/shell.cpp +++ b/modules/shell.cpp @@ -57,7 +57,7 @@ public: virtual void OnModCommand(const CString& sCommand) { if ((strcasecmp(sCommand.c_str(), "cd") == 0) || (strncasecmp(sCommand.c_str(), "cd ", 3) == 0)) { - CString sPath = CUtils::ChangeDir(m_sPath, ((sCommand.length() == 2) ? CString(CZNC::Get().GetHomePath()) : CString(sCommand.substr(3))), CZNC::Get().GetHomePath()); + CString sPath = CDir::ChangeDir(m_sPath, ((sCommand.length() == 2) ? CString(CZNC::Get().GetHomePath()) : CString(sCommand.substr(3))), CZNC::Get().GetHomePath()); CFile Dir(sPath); if (Dir.IsDir()) { @@ -76,7 +76,7 @@ public: if ((sToNick.empty()) || (sFile.empty())) { PutShell("usage: Send "); } else { - sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); + sFile = CDir::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); if (!CFile::Exists(sFile)) { PutShell("get: no such file [" + sFile + "]"); @@ -92,7 +92,7 @@ public: if (sFile.empty()) { PutShell("usage: Get "); } else { - sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); + sFile = CDir::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); if (!CFile::Exists(sFile)) { PutShell("get: no such file [" + sFile + "]"); @@ -118,7 +118,7 @@ public: virtual EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize) { if (strcasecmp(RemoteNick.GetNick().c_str(), CString(GetModNick()).c_str()) == 0) { - CString sLocalFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); + CString sLocalFile = CDir::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath()); m_pUser->GetFile(m_pUser->GetCurNick(), CUtils::GetIP(uLongIP), uPort, sLocalFile, uFileSize, GetModName()); diff --git a/znc.cpp b/znc.cpp index 04886824..98fc7288 100644 --- a/znc.cpp +++ b/znc.cpp @@ -397,7 +397,7 @@ 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('/'); - m_sCurPath = (uPos == CString::npos) ? CString(buf) : CUtils::ChangeDir(buf, sArgvPath.substr(0, uPos), ""); + m_sCurPath = (uPos == CString::npos) ? CString(buf) : CDir::ChangeDir(buf, sArgvPath.substr(0, uPos), ""); // Try to set the user's home dir, default to binpath on failure home = getenv("HOME"); diff --git a/znc.h b/znc.h index 8f4f86a1..9850f787 100644 --- a/znc.h +++ b/znc.h @@ -137,12 +137,12 @@ public: CGlobalModules& GetModules() { return *m_pModules; } #endif const CString& GetStatusPrefix() const { return m_sStatusPrefix; } - const CString& GetCurPath() const { if (!CFile::Exists(m_sCurPath)) { CUtils::MakeDir(m_sCurPath); } return m_sCurPath; } - const CString& GetModPath() const { if (!CFile::Exists(m_sModPath)) { CUtils::MakeDir(m_sModPath); } return m_sModPath; } - const CString& GetHomePath() const { if (!CFile::Exists(m_sHomePath)) { CUtils::MakeDir(m_sHomePath); } return m_sHomePath; } - const CString& GetZNCPath() const { if (!CFile::Exists(m_sZNCPath)) { CUtils::MakeDir(m_sZNCPath); } return m_sZNCPath; } - const CString& GetConfPath() const { if (!CFile::Exists(m_sConfPath)) { CUtils::MakeDir(m_sConfPath); } return m_sConfPath; } - const CString& GetUserPath() const { if (!CFile::Exists(m_sUserPath)) { CUtils::MakeDir(m_sUserPath); } return m_sUserPath; } + const CString& GetCurPath() const { if (!CFile::Exists(m_sCurPath)) { CDir::MakeDir(m_sCurPath); } return m_sCurPath; } + const CString& GetModPath() const { if (!CFile::Exists(m_sModPath)) { CDir::MakeDir(m_sModPath); } return m_sModPath; } + const CString& GetHomePath() const { if (!CFile::Exists(m_sHomePath)) { CDir::MakeDir(m_sHomePath); } return m_sHomePath; } + const CString& GetZNCPath() const { if (!CFile::Exists(m_sZNCPath)) { CDir::MakeDir(m_sZNCPath); } return m_sZNCPath; } + const CString& GetConfPath() const { if (!CFile::Exists(m_sConfPath)) { CDir::MakeDir(m_sConfPath); } return m_sConfPath; } + const CString& GetUserPath() const { if (!CFile::Exists(m_sUserPath)) { CDir::MakeDir(m_sUserPath); } return m_sUserPath; } CString GetPemLocation() const { return GetZNCPath() + "/znc.pem"; } const CString& GetConfigFile() const { return m_sConfigFile; } bool WritePemFile(bool bEncPem = false);