%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