ZNC  trunk
FileUtils.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2024 ZNC, see the NOTICE file for details.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ZNC_FILEUTILS_H
18 #define ZNC_FILEUTILS_H
19 
20 #include <znc/zncconfig.h>
21 #include <znc/ZNCString.h>
22 #include <dirent.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <vector>
29 
30 class CFile {
31  public:
32  CFile();
33  CFile(const CString& sLongName);
34  ~CFile();
35 
36  enum EFileTypes {
43  FT_SOCK
44  };
45 
46  void SetFileName(const CString& sLongName);
47  static bool IsReg(const CString& sLongName, bool bUseLstat = false);
48  static bool IsDir(const CString& sLongName, bool bUseLstat = false);
49  static bool IsChr(const CString& sLongName, bool bUseLstat = false);
50  static bool IsBlk(const CString& sLongName, bool bUseLstat = false);
51  static bool IsFifo(const CString& sLongName, bool bUseLstat = false);
52  static bool IsLnk(const CString& sLongName, bool bUseLstat = true);
53  static bool IsSock(const CString& sLongName, bool bUseLstat = false);
54 
55  bool IsReg(bool bUseLstat = false) const;
56  bool IsDir(bool bUseLstat = false) const;
57  bool IsChr(bool bUseLstat = false) const;
58  bool IsBlk(bool bUseLstat = false) const;
59  bool IsFifo(bool bUseLstat = false) const;
60  bool IsLnk(bool bUseLstat = true) const;
61  bool IsSock(bool bUseLstat = false) const;
62 
63  // for gettin file types, using fstat instead
64  static bool FType(const CString& sFileName, EFileTypes eType,
65  bool bUseLstat = false);
66 
68 
69  //
70  // Functions to retrieve file information
71  //
72  bool Exists() const;
73  off_t GetSize() const;
74  time_t GetATime() const;
75  time_t GetMTime() const;
76  time_t GetCTime() const;
77  uid_t GetUID() const;
78  gid_t GetGID() const;
79  static bool Exists(const CString& sFile);
80 
81  static off_t GetSize(const CString& sFile);
82  static time_t GetATime(const CString& sFile);
83  static time_t GetMTime(const CString& sFile);
84  static time_t GetCTime(const CString& sFile);
85  static uid_t GetUID(const CString& sFile);
86  static gid_t GetGID(const CString& sFile);
87  static int GetInfo(const CString& sFile, struct stat& st);
88 
89  //
90  // Functions to manipulate the file on the filesystem
91  //
92  bool Delete();
93  bool Move(const CString& sNewFileName, bool bOverwrite = false);
94  bool Copy(const CString& sNewFileName, bool bOverwrite = false);
95 
96  static bool Delete(const CString& sFileName);
97  static bool Move(const CString& sOldFileName, const CString& sNewFileName,
98  bool bOverwrite = false);
99  static bool Copy(const CString& sOldFileName, const CString& sNewFileName,
100  bool bOverwrite = false);
101  bool Chmod(mode_t mode);
102  static bool Chmod(const CString& sFile, mode_t mode);
103  bool Seek(off_t uPos);
104  bool Truncate();
105  bool Sync();
106  bool Open(const CString& sFileName, int iFlags = O_RDONLY,
107  mode_t iMode = 0644);
108  bool Open(int iFlags = O_RDONLY, mode_t iMode = 0644);
109  ssize_t Read(char* pszBuffer, int iBytes);
110  bool ReadLine(CString& sData, const CString& sDelimiter = "\n");
111  bool ReadFile(CString& sData, size_t iMaxSize = 512 * 1024);
112  ssize_t Write(const char* pszBuffer, size_t iBytes);
113  ssize_t Write(const CString& sData);
114  void Close();
115  void ClearBuffer();
116 
117  bool TryExLock(const CString& sLockFile, int iFlags = O_RDWR | O_CREAT);
118  bool TryExLock();
119  bool ExLock();
120  bool UnLock();
121 
122  bool IsOpen() const;
125  CString GetDir() const;
126 
127  bool HadError() const { return m_bHadError; }
128  void ResetError() { m_bHadError = false; }
129 
130  static void InitHomePath(const CString& sFallback);
131  static const CString& GetHomePath() { return m_sHomePath; }
132 
133  private:
134  // fcntl() locking wrapper
135  bool Lock(short iType, bool bBlocking);
136 
137  CString m_sBuffer;
138  int m_iFD;
139  bool m_bHadError;
140 
141  static CString m_sHomePath;
142 
143  protected:
146 };
147 
148 class CDir : public std::vector<CFile*> {
149  public:
150  CDir(const CString& sDir) : m_eSortAttr(CFile::FA_Name), m_bDesc(false) {
151  Fill(sDir);
152  }
153 
154  CDir() : m_eSortAttr(CFile::FA_Name), m_bDesc(false) {}
155 
156  ~CDir() { CleanUp(); }
157 
158  void CleanUp() {
159  for (unsigned int a = 0; a < size(); a++) {
160  delete (*this)[a];
161  }
162 
163  clear();
164  }
165 
166  size_t Fill(const CString& sDir) { return FillByWildcard(sDir, "*"); }
167 
168  size_t FillByWildcard(const CString& sDir, const CString& sWildcard) {
169  CleanUp();
170  DIR* dir = opendir((sDir.empty()) ? "." : sDir.c_str());
171 
172  if (!dir) {
173  return 0;
174  }
175 
176  struct dirent* de;
177 
178  while ((de = readdir(dir)) != nullptr) {
179  if ((strcmp(de->d_name, ".") == 0) ||
180  (strcmp(de->d_name, "..") == 0)) {
181  continue;
182  }
183  if ((!sWildcard.empty()) &&
184  (!CString(de->d_name).WildCmp(sWildcard))) {
185  continue;
186  }
187 
188  CFile* file =
189  new CFile(sDir.TrimSuffix_n("/") + "/" +
190  de->d_name /*, this*/); // @todo need to pass pointer
191  // to 'this' if we want to do
192  // Sort()
193  push_back(file);
194  }
195 
196  closedir(dir);
197  return size();
198  }
199 
200  static unsigned int Chmod(mode_t mode, const CString& sWildcard,
201  const CString& sDir = ".") {
202  CDir cDir;
203  cDir.FillByWildcard(sDir, sWildcard);
204  return cDir.Chmod(mode);
205  }
206 
207  unsigned int Chmod(mode_t mode) {
208  unsigned int uRet = 0;
209  for (unsigned int a = 0; a < size(); a++) {
210  if ((*this)[a]->Chmod(mode)) {
211  uRet++;
212  }
213  }
214 
215  return uRet;
216  }
217 
218  static unsigned int Delete(const CString& sWildcard,
219  const CString& sDir = ".") {
220  CDir cDir;
221  cDir.FillByWildcard(sDir, sWildcard);
222  return cDir.Delete();
223  }
224 
225  unsigned int Delete() {
226  unsigned int uRet = 0;
227  for (unsigned int a = 0; a < size(); a++) {
228  if ((*this)[a]->Delete()) {
229  uRet++;
230  }
231  }
232 
233  return uRet;
234  }
235 
237  bool IsDescending() const { return m_bDesc; }
238 
239  // Check if sPath + "/" + sAdd (~/ is handled) is an absolute path which
240  // resides under sPath. Returns absolute path on success, else "".
241  static CString CheckPathPrefix(const CString& sPath, const CString& sAdd,
242  const CString& sHomeDir = "");
243  static CString ChangeDir(const CString& sPath, const CString& sAdd,
244  const CString& sHomeDir = "");
245  static bool MakeDir(const CString& sPath, mode_t iMode = 0700);
246 
247  static CString GetCWD() {
248  CString sRet;
249  char* pszCurDir = getcwd(nullptr, 0);
250  if (pszCurDir) {
251  sRet = pszCurDir;
252  free(pszCurDir);
253  }
254 
255  return sRet;
256  }
257 
258  private:
259  protected:
261  bool m_bDesc;
262 };
263 #endif // !ZNC_FILEUTILS_H
Definition: FileUtils.h:148
CFile::EFileAttr m_eSortAttr
Definition: FileUtils.h:260
static bool MakeDir(const CString &sPath, mode_t iMode=0700)
size_t Fill(const CString &sDir)
Definition: FileUtils.h:166
unsigned int Delete()
Definition: FileUtils.h:225
CDir(const CString &sDir)
Definition: FileUtils.h:150
~CDir()
Definition: FileUtils.h:156
static unsigned int Chmod(mode_t mode, const CString &sWildcard, const CString &sDir=".")
Definition: FileUtils.h:200
static unsigned int Delete(const CString &sWildcard, const CString &sDir=".")
Definition: FileUtils.h:218
static CString GetCWD()
Definition: FileUtils.h:247
bool m_bDesc
Definition: FileUtils.h:261
void CleanUp()
Definition: FileUtils.h:158
unsigned int Chmod(mode_t mode)
Definition: FileUtils.h:207
static CString CheckPathPrefix(const CString &sPath, const CString &sAdd, const CString &sHomeDir="")
CDir()
Definition: FileUtils.h:154
CFile::EFileAttr GetSortAttr() const
Definition: FileUtils.h:236
static CString ChangeDir(const CString &sPath, const CString &sAdd, const CString &sHomeDir="")
bool IsDescending() const
Definition: FileUtils.h:237
size_t FillByWildcard(const CString &sDir, const CString &sWildcard)
Definition: FileUtils.h:168
Definition: FileUtils.h:30
static bool IsLnk(const CString &sLongName, bool bUseLstat=true)
static bool Copy(const CString &sOldFileName, const CString &sNewFileName, bool bOverwrite=false)
static bool Move(const CString &sOldFileName, const CString &sNewFileName, bool bOverwrite=false)
static time_t GetMTime(const CString &sFile)
bool IsChr(bool bUseLstat=false) const
static gid_t GetGID(const CString &sFile)
static time_t GetCTime(const CString &sFile)
CString GetDir() const
void ClearBuffer()
static const CString & GetHomePath()
Definition: FileUtils.h:131
bool Move(const CString &sNewFileName, bool bOverwrite=false)
static int GetInfo(const CString &sFile, struct stat &st)
void SetFileName(const CString &sLongName)
EFileTypes
Definition: FileUtils.h:36
@ FT_BLOCK
Definition: FileUtils.h:40
@ FT_SOCK
Definition: FileUtils.h:43
@ FT_LINK
Definition: FileUtils.h:42
@ FT_FIFO
Definition: FileUtils.h:41
@ FT_CHARACTER
Definition: FileUtils.h:39
@ FT_REGULAR
Definition: FileUtils.h:37
@ FT_DIRECTORY
Definition: FileUtils.h:38
CFile(const CString &sLongName)
bool TryExLock()
bool Seek(off_t uPos)
static bool Exists(const CString &sFile)
bool IsOpen() const
static bool Delete(const CString &sFileName)
static bool IsBlk(const CString &sLongName, bool bUseLstat=false)
time_t GetCTime() const
static bool Chmod(const CString &sFile, mode_t mode)
CString m_sLongName
Absolute filename (m_sPath + "/" + m_sShortName)
Definition: FileUtils.h:144
bool HadError() const
Definition: FileUtils.h:127
CString GetLongName() const
bool IsFifo(bool bUseLstat=false) const
bool Truncate()
bool ExLock()
bool IsDir(bool bUseLstat=false) const
bool Delete()
bool Sync()
bool Open(int iFlags=O_RDONLY, mode_t iMode=0644)
bool TryExLock(const CString &sLockFile, int iFlags=O_RDWR|O_CREAT)
void ResetError()
Definition: FileUtils.h:128
bool Chmod(mode_t mode)
gid_t GetGID() const
bool ReadFile(CString &sData, size_t iMaxSize=512 *1024)
bool UnLock()
void Close()
bool ReadLine(CString &sData, const CString &sDelimiter="\n")
ssize_t Write(const CString &sData)
static bool IsSock(const CString &sLongName, bool bUseLstat=false)
time_t GetMTime() const
bool Open(const CString &sFileName, int iFlags=O_RDONLY, mode_t iMode=0644)
static off_t GetSize(const CString &sFile)
CString m_sShortName
Filename alone, without path.
Definition: FileUtils.h:145
off_t GetSize() const
bool IsBlk(bool bUseLstat=false) const
CString GetShortName() const
bool IsSock(bool bUseLstat=false) const
static bool IsChr(const CString &sLongName, bool bUseLstat=false)
static bool FType(const CString &sFileName, EFileTypes eType, bool bUseLstat=false)
static bool IsDir(const CString &sLongName, bool bUseLstat=false)
bool Exists() const
static void InitHomePath(const CString &sFallback)
time_t GetATime() const
bool IsReg(bool bUseLstat=false) const
bool IsLnk(bool bUseLstat=true) const
static bool IsReg(const CString &sLongName, bool bUseLstat=false)
static time_t GetATime(const CString &sFile)
static uid_t GetUID(const CString &sFile)
ssize_t Read(char *pszBuffer, int iBytes)
static bool IsFifo(const CString &sLongName, bool bUseLstat=false)
ssize_t Write(const char *pszBuffer, size_t iBytes)
uid_t GetUID() const
bool Copy(const CString &sNewFileName, bool bOverwrite=false)
EFileAttr
Definition: FileUtils.h:67
@ FA_Name
Definition: FileUtils.h:67
@ FA_UID
Definition: FileUtils.h:67
@ FA_ATime
Definition: FileUtils.h:67
@ FA_CTime
Definition: FileUtils.h:67
@ FA_MTime
Definition: FileUtils.h:67
@ FA_Size
Definition: FileUtils.h:67
String class that is used inside ZNC.
Definition: ZNCString.h:68
CString TrimSuffix_n(const CString &sSuffix) const
Trim a given suffix.
static bool WildCmp(const CString &sWild, const CString &sString, CaseSensitivity cs=CaseSensitive)
Do a wildcard comparison between two strings.