From b58cb3c8b30f778f009df4bfcc931d56d50308b1 Mon Sep 17 00:00:00 2001 From: prozacx Date: Mon, 2 May 2005 22:34:11 +0000 Subject: [PATCH] Added CDir and split CFile out from Utils.cpp/h git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@232 726aef4b-f618-498e-8847-2d620e286838 --- FileUtils.cpp | 247 ++++++++++++++++++++++++++++++++++++ FileUtils.h | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 586 insertions(+) create mode 100644 FileUtils.cpp create mode 100644 FileUtils.h diff --git a/FileUtils.cpp b/FileUtils.cpp new file mode 100644 index 00000000..d1c461c9 --- /dev/null +++ b/FileUtils.cpp @@ -0,0 +1,247 @@ +#include "FileUtils.h" + +CFile::CFile(const string& sLongName) { + m_sLongName = sLongName; + m_iFD = -1; + + m_sShortName = sLongName; + + // @todo shouldn't this be Right() and RightChomp() ?! + while (CUtils::Left(m_sShortName, 1) == "/") { + CUtils::LeftChomp(m_sShortName); + } + + string::size_type uPos = m_sShortName.rfind('/'); + if (uPos != string::npos) { + m_sShortName = m_sShortName.substr(uPos +1); + } +} + +CFile::~CFile() { + if (m_iFD != -1) { + Close(); + } +} + +bool CFile::IsReg(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_REGULAR, bUseLstat); } +bool CFile::IsDir(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_DIRECTORY, bUseLstat); } +bool CFile::IsChr(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_CHARACTER, bUseLstat); } +bool CFile::IsBlk(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_BLOCK, bUseLstat); } +bool CFile::IsFifo(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_FIFO, bUseLstat); } +bool CFile::IsLnk(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_LINK, bUseLstat); } +bool CFile::IsSock(const string& sLongName, bool bUseLstat) { return CFile::FType(sLongName, FT_SOCK, bUseLstat); } + +bool CFile::IsReg(bool bUseLstat) { return CFile::IsReg(m_sLongName, bUseLstat); } +bool CFile::IsDir(bool bUseLstat) { return CFile::IsDir(m_sLongName, bUseLstat); } +bool CFile::IsChr(bool bUseLstat) { return CFile::IsChr(m_sLongName, bUseLstat); } +bool CFile::IsBlk(bool bUseLstat) { return CFile::IsBlk(m_sLongName, bUseLstat); } +bool CFile::IsFifo(bool bUseLstat) { return CFile::IsFifo(m_sLongName, bUseLstat); } +bool CFile::IsLnk(bool bUseLstat) { return CFile::IsLnk(m_sLongName, bUseLstat); } +bool CFile::IsSock(bool bUseLstat) { return CFile::IsSock(m_sLongName, bUseLstat); } + +bool CFile::access(int mode) { return (::access(m_sLongName.c_str(), mode) == 0); } + +// for gettin file types, using fstat instead +bool CFile::FType(const string sFileName, EFileTypes eType, bool bUseLstat) { + struct stat st; + + if (!bUseLstat) { + if (stat(sFileName.c_str(), &st) != 0) { + return false; + } + } else { + if (lstat(sFileName.c_str(), &st) != 0) { + return false; + } + } + + switch (eType) { + case FT_REGULAR: + return S_ISREG(st.st_mode); + case FT_DIRECTORY: + return S_ISDIR(st.st_mode); + case FT_CHARACTER: + return S_ISCHR(st.st_mode); + case FT_BLOCK: + return S_ISBLK(st.st_mode); + case FT_FIFO: + return S_ISFIFO(st.st_mode); + case FT_LINK: + return S_ISLNK(st.st_mode); + case FT_SOCK: + return S_ISSOCK(st.st_mode); + default: + return false; + } + return false; +} + +// +// Functions to retrieve file information +// +bool CFile::Exists() const { return CFile::Exists(m_sLongName); } +unsigned long long CFile::GetSize() const { return CFile::GetSize(m_sLongName); } +unsigned int CFile::GetATime() const { return CFile::GetATime(m_sLongName); } +unsigned int CFile::GetMTime() const { return CFile::GetMTime(m_sLongName); } +unsigned int CFile::GetCTime() const { return CFile::GetCTime(m_sLongName); } +int CFile::GetUID() const { return CFile::GetUID(m_sLongName); } +int CFile::GetGID() const { return CFile::GetGID(m_sLongName); } +bool CFile::Exists(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) == 0); +} + +unsigned long long CFile::GetSize(const string& sFile) { + struct stat st; + if(stat(sFile.c_str(), &st) != 0) { + return 0; + } + + return (S_ISREG(st.st_mode)) ? st.st_size : 0; +} + +unsigned int CFile::GetATime(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_atime; +} + +unsigned int CFile::GetMTime(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_mtime; +} + +unsigned int CFile::GetCTime(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? 0 : st.st_ctime; +} + +int CFile::GetUID(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? -1 : (int) st.st_uid; +} + +int CFile::GetGID(const string& sFile) { + struct stat st; + return (stat(sFile.c_str(), &st) != 0) ? -1 : (int) st.st_gid; +} +int CFile::GetInfo(const string& sFile, struct stat& st) { + return stat(sFile.c_str(), &st); +} + +// +// Functions to manipulate the file on the filesystem +// +int CFile::Delete() { return CFile::Delete(m_sLongName); } +int CFile::Move(const string& sNewFileName, bool bOverwrite) { + return CFile::Move(m_sLongName, sNewFileName, bOverwrite); +} + +bool CFile::Delete(const string& sFileName) { + if(!CFile::Exists(sFileName)) { + return false; + } + + return (unlink(sFileName.c_str()) == 0) ? true : false; +} + +bool CFile::Move(const string& sOldFileName, const string& sNewFileName, bool bOverwrite) { + if((!bOverwrite) && (CFile::Exists(sNewFileName))) { + return false; + } + + //string sNewLongName = (sNewFileName[0] == '/') ? sNewFileName : m_sPath + "/" + sNewFileName; + return (rename(sOldFileName.c_str(), sNewFileName.c_str()) == 0) ? true : false; +} + +bool CFile::Chmod(mode_t mode) { + return CFile::Chmod(m_sLongName, mode); +} + +bool CFile::Chmod(const string& sFile, mode_t mode) { + return (chmod(sFile.c_str(), mode) == 0); +} + +bool CFile::Seek(unsigned long uPos) { + return (m_iFD == -1) ? false : ((unsigned int) lseek(m_iFD, uPos, SEEK_SET) == uPos); +} + +bool CFile::Open(int iFlags, mode_t iMode) { + if (m_iFD != -1) { + return false; + } + + m_iFD = open(m_sLongName.c_str(), iFlags, iMode); + return (m_iFD > -1); +} + +int CFile::Read(char *pszBuffer, int iBytes) { + if (m_iFD == -1) { + return -1; + } + + return read(m_iFD, pszBuffer, iBytes); +} + +bool CFile::ReadLine(string & sData) { + char buff[64]; + sData.clear(); + if (m_iFD == -1) { + return false; + } + + bool bEOF = false; + + while(true) { + string::size_type iFind = m_sBuffer.find("\n"); + if (iFind != string::npos) { + sData = m_sBuffer.substr(0, (iFind + 1)); + m_sBuffer.erase(0, (iFind + 1)); + break; + } + + memset((char *)buff, '\0', 64); + int iBytes = read(m_iFD, buff, 64); + switch(iBytes) { + case -1: { + bEOF = true; + break; + } + case 0: { + bEOF = true; + break; + } + default: { + m_sBuffer.append(buff, iBytes); + break; + } + } + + if (bEOF) { + break; + } + } + + string::size_type iFind = m_sBuffer.find("\n"); + if (iFind != string::npos) { + return true; + } + + return !bEOF; +} + +int CFile::Write(const char *pszBuffer, u_int iBytes) { + if (m_iFD == -1) { + return -1; + } + + return write(m_iFD, pszBuffer, iBytes); +} + +int CFile::Write(const string & sData) { + return Write(sData.data(), sData.size()); +} +void CFile::Close() { close(m_iFD); m_iFD = -1; } + +string CFile::GetLongName() const { return m_sLongName; } +string CFile::GetShortName() const { return m_sShortName; } +void CFile::SetFD(int iFD) { m_iFD = iFD; } diff --git a/FileUtils.h b/FileUtils.h new file mode 100644 index 00000000..f7c8bca4 --- /dev/null +++ b/FileUtils.h @@ -0,0 +1,339 @@ +#ifndef _FILEUTILS_H +#define _FILEUTILS_H + +#include +#include +#include +#include +#include +#include + +#include "Utils.h" + +#include +#include +#include +using std::string; +using std::vector; +using std::map; + +class CFile { +public: + CFile(const string& sLongName); + virtual ~CFile(); + + enum EFileTypes { + FT_REGULAR, + FT_DIRECTORY, + FT_CHARACTER, + FT_BLOCK, + FT_FIFO, + FT_LINK, + FT_SOCK + }; + + static bool IsReg(const string& sLongName, bool bUseLstat = false); + static bool IsDir(const string& sLongName, bool bUseLstat = false); + static bool IsChr(const string& sLongName, bool bUseLstat = false); + static bool IsBlk(const string& sLongName, bool bUseLstat = false); + static bool IsFifo(const string& sLongName, bool bUseLstat = false); + static bool IsLnk(const string& sLongName, bool bUseLstat = true); + static bool IsSock(const string& sLongName, bool bUseLstat = false); + + bool IsReg(bool bUseLstat = false); + bool IsDir(bool bUseLstat = false); + bool IsChr(bool bUseLstat = false); + bool IsBlk(bool bUseLstat = false); + bool IsFifo(bool bUseLstat = false); + bool IsLnk(bool bUseLstat = true); + bool IsSock(bool bUseLstat = false); + + bool access(int mode); + + // for gettin file types, using fstat instead + static bool FType(const string sFileName, EFileTypes eType, bool bUseLstat = false); + + enum EFileAttr { + FA_Name, + FA_Size, + FA_ATime, + FA_MTime, + FA_CTime, + FA_UID + }; + + // + // Functions to retrieve file information + // + bool Exists() const; + unsigned long long GetSize() const; + unsigned int GetATime() const; + unsigned int GetMTime() const; + unsigned int GetCTime() const; + int GetUID() const; + int GetGID() const; + static bool Exists(const string& sFile); + + static unsigned long long GetSize(const string& sFile); + static unsigned int GetATime(const string& sFile); + static unsigned int GetMTime(const string& sFile); + static unsigned int GetCTime(const string& sFile); + static int GetUID(const string& sFile); + static int GetGID(const string& sFile); + static int GetInfo(const string& sFile, struct stat& st); + + // + // Functions to manipulate the file on the filesystem + // + int Delete(); + int Move(const string& sNewFileName, bool bOverwrite = false); + + static bool Delete(const string& sFileName); + static bool Move(const string& sOldFileName, const string& sNewFileName, bool bOverwrite = false); + bool Chmod(mode_t mode); + static bool Chmod(const string& sFile, mode_t mode); + bool Seek(unsigned long uPos); + bool Open(int iFlags, mode_t iMode = 0644); + int Read(char *pszBuffer, int iBytes); + bool ReadLine(string & sData); + int Write(const char *pszBuffer, u_int iBytes); + int Write(const string & sData); + void Close(); + + string GetLongName() const; + string GetShortName() const; + void SetFD(int iFD); + +private: + string m_sBuffer; + int m_iFD; + +protected: + string m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName) + string m_sShortName; //!< Filename alone, without path +}; + +class CDir : public vector { +public: + + CDir(const string& sDir) { + m_bDesc = false; + m_eSortAttr = CFile::FA_Name; + Fill(sDir); + } + + CDir() { + m_bDesc = false; + m_eSortAttr = CFile::FA_Name; + } + + virtual ~CDir() { + CleanUp(); + } + + virtual void CleanUp() { + for (unsigned int a = 0; a < size(); a++) { + delete (*this)[a]; + } + + clear(); + } + + int Fill(const string& sDir) { + return FillByWildcard(sDir, "*"); + } + + /*void Sort(CFile::EFileAttr eSortAttr, bool bDesc = false) { + m_eSortAttr = eSortAttr; + m_bDesc = bDesc; + sort(begin(), end(), TPtrCmp); + }*/ + + static bool Exists(const string& sDir) { + CFile cFile(sDir); + return (cFile.Exists()) && (cFile.IsDir()); + } + +/* static bool Create(const string& sDir, mode_t mode = 0755) { + VCstring vSubDirs = sDir.split("[/\\\\]+"); + Cstring sCurDir; + + for (unsigned int a = 0; a < vSubDirs.size(); a++) { + sCurDir += vSubDirs[a] + "/"; + if ((!CDir::Exists(sCurDir)) && (mkdir(sCurDir.c_str(), mode) != 0)) { + return false; + } + } + + return true; + } + + int FillByRegex(const Cstring& sDir, const Cstring& sRegex, const Cstring& sFlags = "") { + CleanUp(); + DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str()); + + if (!dir) { + return 0; + } + + struct dirent * de; + + while ((de = readdir(dir)) != 0) { + if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) { + continue; + } + if ((!sRegex.empty()) && (!Cstring::search(de->d_name, sRegex, sFlags))) { + continue; + } + + CFile *file = new CFile(sDir, de->d_name, this); + push_back(file); + } + + closedir(dir); + return size(); + }*/ + + int FillByWildcard(const string& sDir, const string& sWildcard) { + CleanUp(); + DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str()); + + if (!dir) { + return 0; + } + + struct dirent * de; + + while ((de = readdir(dir)) != 0) { + if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) { + continue; + } + if ((!sWildcard.empty()) && (!CUtils::wildcmp(sWildcard.c_str(), de->d_name))) { + continue; + } + + CFile *file = new CFile(sDir + "/" + de->d_name/*, this*/); // @todo need to pass pointer to 'this' if we want to do Sort() + push_back(file); + } + + closedir(dir); + return size(); + } + + static unsigned int Chmod(mode_t mode, const string& sWildcard, const string& sDir = ".") { + CDir cDir; + cDir.FillByWildcard(sDir, sWildcard); + return cDir.Chmod(mode); + } + + unsigned int Chmod(mode_t mode) { + unsigned int uRet = 0; + for (unsigned int a = 0; a < size(); a++) { + if ((*this)[a]->Chmod(mode)) { + uRet++; + } + } + + return uRet; + } + + static unsigned int Delete(mode_t mode, const string& sWildcard, const string& sDir = ".") { + CDir cDir; + cDir.FillByWildcard(sDir, sWildcard); + return cDir.Delete(); + } + + unsigned int Delete() { + unsigned int uRet = 0; + for (unsigned int a = 0; a < size(); a++) { + if ((*this)[a]->Delete()) { + uRet++; + } + } + + return uRet; + } + + CFile::EFileAttr GetSortAttr() { return m_eSortAttr; } + bool IsDescending() { return m_bDesc; } + +/* static bool MkDir(const string & sPath, mode_t iMode, bool bBuildParents = false, bool bApplyModToParents = false) { + if (sPath.empty()) { + WARN("empty path!"); + return false; + } + + if (!bBuildParents) { // only building target + mode_t uMask = umask(0000); + int iRet = mkdir(sPath.c_str(), iMode); + umask(uMask); + + if (iRet != 0) { + return false; + } + } + + + VCstring vPath = sPath.TrimRight_n("/").split("/+"); + + if (vPath.empty()) { + return false; + } + + if (sPath[0] == '/'); + vPath[0] = "/" + vPath[0]; + + Cstring sCurDir = GetCWD(); + + mode_t uMask = 0000; + if (bApplyModToParents) { + uMask = umask(0000); + } + + for (unsigned int a = 0; a < (vPath.size() - 1); a++) { + if ((mkdir(vPath[a].c_str(), iMode) != 0) && (errno != EEXIST)) { + if (bApplyModToParents) { + umask(uMask); + } + + return false; + } + + if (chdir(vPath[a].c_str()) != 0) { + chdir(sCurDir.c_str()); + if (bApplyModToParents) { + umask(uMask); + } + + return false; + } + } + + if (!bApplyModToParents) { + uMask = umask(0000); + } + + int iRet = mkdir(vPath[vPath.size() - 1].c_str(), iMode); + umask(uMask); + chdir(sCurDir.c_str()); + return (iRet == 0); + }*/ + + static string GetCWD() { + string sRet; + char * pszCurDir = getcwd(NULL, 0); + if (pszCurDir) { + sRet = pszCurDir; + free(pszCurDir); + } + + return sRet; + } + +private: +protected: + CFile::EFileAttr m_eSortAttr; + bool m_bDesc; +}; + +#endif // !_FILEUTILS_H