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:
prozacx
2005-05-02 22:34:11 +00:00
parent 503dc56a30
commit b58cb3c8b3
2 changed files with 586 additions and 0 deletions
+247
View File
@@ -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
View File
@@ -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