-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFileUtils.h
283 lines (237 loc) · 6.85 KB
/
FileUtils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
* Copyright (C) 2004-2011 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#ifndef _FILEUTILS_H
#define _FILEUTILS_H
#include "zncconfig.h"
#include "Socket.h"
#include "ZNCString.h"
#include <dirent.h>
#include <map>
#include <signal.h>
#include <vector>
using std::vector;
using std::map;
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);
int Read(char *pszBuffer, int iBytes);
bool ReadLine(CString & sData, const CString & sDelimiter = "\n");
bool ReadFile(CString& sData, size_t iMaxSize = 512 * 1024);
int Write(const char *pszBuffer, u_int iBytes);
int Write(const CString & sData);
void Close();
void ClearBuffer();
bool TryExLock(const CString& sLockFile, int iFlags = O_RDONLY | O_CREAT);
bool TryExLock();
bool ExLock();
bool UnLock();
bool IsOpen() const;
CString GetLongName() const;
CString GetShortName() const;
CString GetDir() const;
private:
// fcntl() locking wrapper
bool Lock(int iType, bool bBlocking);
CString m_sBuffer;
int m_iFD;
protected:
CString m_sLongName; //!< Absolute filename (m_sPath + "/" + m_sShortName)
CString m_sShortName; //!< Filename alone, without path
};
class CDir : public vector<CFile*> {
public:
CDir(const CString& sDir) {
m_bDesc = false;
m_eSortAttr = CFile::FA_Name;
Fill(sDir);
}
CDir() {
m_bDesc = false;
m_eSortAttr = CFile::FA_Name;
}
~CDir() {
CleanUp();
}
void CleanUp() {
for (unsigned int a = 0; a < size(); a++) {
delete (*this)[a];
}
clear();
}
int Fill(const CString& sDir) {
return FillByWildcard(sDir, "*");
}
int 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)) != 0) {
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 + "/" + 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() { return m_eSortAttr; }
bool IsDescending() { 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(NULL, 0);
if (pszCurDir) {
sRet = pszCurDir;
free(pszCurDir);
}
return sRet;
}
private:
protected:
CFile::EFileAttr m_eSortAttr;
bool m_bDesc;
};
//! @author [email protected]
class CExecSock : public CZNCSock {
public:
CExecSock() : CZNCSock() {
m_iPid = -1;
}
int Execute(const CString & sExec) {
int iReadFD, iWriteFD;
m_iPid = popen2(iReadFD, iWriteFD, sExec);
if (m_iPid != -1) {
ConnectFD(iReadFD, iWriteFD, "0.0.0.0:0");
}
return(m_iPid);
}
void Kill(int iSignal)
{
kill(m_iPid, iSignal);
Close();
}
virtual ~CExecSock() {
close2(m_iPid, GetRSock(), GetWSock());
SetRSock(-1);
SetWSock(-1);
}
int popen2(int & iReadFD, int & iWriteFD, const CString & sCommand);
void close2(int iPid, int iReadFD, int iWriteFD);
private:
int m_iPid;
};
#endif // !_FILEUTILS_H