%PDF- %PDF-
Direktori : /data/old/usr/local/include/znc/ |
Current File : //data/old/usr/local/include/znc/FileUtils.h |
/* * Copyright (C) 2004-2018 ZNC, see the NOTICE file for details. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ZNC_FILEUTILS_H #define ZNC_FILEUTILS_H #include <znc/zncconfig.h> #include <znc/ZNCString.h> #include <dirent.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <vector> class CFile { public: CFile(); CFile(const CString& sLongName); ~CFile(); enum EFileTypes { FT_REGULAR, FT_DIRECTORY, FT_CHARACTER, FT_BLOCK, FT_FIFO, FT_LINK, FT_SOCK }; void SetFileName(const CString& sLongName); static bool IsReg(const CString& sLongName, bool bUseLstat = false); static bool IsDir(const CString& sLongName, bool bUseLstat = false); static bool IsChr(const CString& sLongName, bool bUseLstat = false); static bool IsBlk(const CString& sLongName, bool bUseLstat = false); static bool IsFifo(const CString& sLongName, bool bUseLstat = false); static bool IsLnk(const CString& sLongName, bool bUseLstat = true); static bool IsSock(const CString& sLongName, bool bUseLstat = false); bool IsReg(bool bUseLstat = false) const; bool IsDir(bool bUseLstat = false) const; bool IsChr(bool bUseLstat = false) const; bool IsBlk(bool bUseLstat = false) const; bool IsFifo(bool bUseLstat = false) const; bool IsLnk(bool bUseLstat = true) const; bool IsSock(bool bUseLstat = false) const; // for gettin file types, using fstat instead static bool FType(const CString& 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; off_t GetSize() const; time_t GetATime() const; time_t GetMTime() const; time_t GetCTime() const; uid_t GetUID() const; gid_t GetGID() const; static bool Exists(const CString& sFile); static off_t GetSize(const CString& sFile); static time_t GetATime(const CString& sFile); static time_t GetMTime(const CString& sFile); static time_t GetCTime(const CString& sFile); static uid_t GetUID(const CString& sFile); static gid_t GetGID(const CString& sFile); static int GetInfo(const CString& sFile, struct stat& st); // // Functions to manipulate the file on the filesystem // bool Delete(); bool Move(const CString& sNewFileName, bool bOverwrite = false); bool Copy(const CString& sNewFileName, bool bOverwrite = false); static bool Delete(const CString& sFileName); static bool Move(const CString& sOldFileName, const CString& sNewFileName, bool bOverwrite = false); static bool Copy(const CString& sOldFileName, const CString& sNewFileName, bool bOverwrite = false); bool Chmod(mode_t mode); static bool Chmod(const CString& sFile, mode_t mode); bool Seek(off_t uPos); bool Truncate(); bool Sync(); bool Open(const CString& sFileName, int iFlags = O_RDONLY, mode_t iMode = 0644); bool Open(int iFlags = O_RDONLY, mode_t iMode = 0644); ssize_t Read(char* pszBuffer, int iBytes); bool ReadLine(CString& sData, const CString& sDelimiter = "\n"); bool ReadFile(CString& sData, size_t iMaxSize = 512 * 1024); ssize_t Write(const char* pszBuffer, size_t iBytes); ssize_t Write(const CString& sData); void Close(); void ClearBuffer(); bool TryExLock(const CString& sLockFile, int iFlags = O_RDWR | O_CREAT); bool TryExLock(); bool ExLock(); bool UnLock(); bool IsOpen() const; CString GetLongName() const; CString GetShortName() const; CString GetDir() const; bool HadError() const { return m_bHadError; } void ResetError() { m_bHadError = false; } static void InitHomePath(const CString& sFallback); static const CString& GetHomePath() { return m_sHomePath; } private: // fcntl() locking wrapper bool Lock(short iType, bool bBlocking); CString m_sBuffer; int m_iFD; bool m_bHadError; static CString m_sHomePath; protected: CString m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName) CString m_sShortName; //!< Filename alone, without path }; class CDir : public std::vector<CFile*> { public: CDir(const CString& sDir) : m_eSortAttr(CFile::FA_Name), m_bDesc(false) { Fill(sDir); } CDir() : m_eSortAttr(CFile::FA_Name), m_bDesc(false) {} ~CDir() { CleanUp(); } void CleanUp() { for (unsigned int a = 0; a < size(); a++) { delete (*this)[a]; } clear(); } size_t Fill(const CString& sDir) { return FillByWildcard(sDir, "*"); } size_t FillByWildcard(const CString& sDir, const CString& sWildcard) { CleanUp(); DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str()); if (!dir) { return 0; } struct dirent* de; while ((de = readdir(dir)) != nullptr) { if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) { continue; } if ((!sWildcard.empty()) && (!CString(de->d_name).WildCmp(sWildcard))) { continue; } CFile* file = new CFile(sDir.TrimSuffix_n("/") + "/" + 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 CString& sWildcard, const CString& 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(const CString& sWildcard, const CString& 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() const { return m_eSortAttr; } bool IsDescending() const { return m_bDesc; } // Check if sPath + "/" + sAdd (~/ is handled) is an absolute path which // resides under sPath. Returns absolute path on success, else "". static CString CheckPathPrefix(const CString& sPath, const CString& sAdd, const CString& sHomeDir = ""); static CString ChangeDir(const CString& sPath, const CString& sAdd, const CString& sHomeDir = ""); static bool MakeDir(const CString& sPath, mode_t iMode = 0700); static CString GetCWD() { CString sRet; char* pszCurDir = getcwd(nullptr, 0); if (pszCurDir) { sRet = pszCurDir; free(pszCurDir); } return sRet; } private: protected: CFile::EFileAttr m_eSortAttr; bool m_bDesc; }; #endif // !ZNC_FILEUTILS_H