mirror of
https://github.com/znc/znc.git
synced 2026-06-28 05:51:50 +02:00
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
This commit is contained in:
+247
@@ -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; }
|
||||
+339
@@ -0,0 +1,339 @@
|
||||
#ifndef _FILEUTILS_H
|
||||
#define _FILEUTILS_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
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<CFile*> {
|
||||
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<CFile>);
|
||||
}*/
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user