File: FileUtils.h

package info (click to toggle)
znc 0.045-3%2Betch3
  • links: PTS
  • area: main
  • in suites: etch
  • size: 1,120 kB
  • ctags: 2,324
  • sloc: cpp: 17,406; sh: 2,380; perl: 448; makefile: 134
file content (355 lines) | stat: -rw-r--r-- 8,088 bytes parent folder | download
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#ifndef _FILEUTILS_H
#define _FILEUTILS_H

#include <unistd.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "String.h"
#include <vector>
#include <map>
using std::vector;
using std::map;

class CFile {
public:
	CFile();
	CFile(const CString& sLongName);
	virtual ~CFile();

	enum EOptions {
		F_Read		= O_RDONLY,
		F_Write		= O_WRONLY,
		F_Create	= O_CREAT,
		F_Truncate	= O_TRUNC
	};

	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;

	bool access(int mode);

	// 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;
	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 CString& sFile);

	static unsigned long long GetSize(const CString& sFile);
	static unsigned int GetATime(const CString& sFile);
	static unsigned int GetMTime(const CString& sFile);
	static unsigned int GetCTime(const CString& sFile);
	static int GetUID(const CString& sFile);
	static int GetGID(const CString& sFile);
	static int GetInfo(const CString& sFile, struct stat& st);

	//
	// Functions to manipulate the file on the filesystem
	//
	int Delete();
	int Move(const CString& sNewFileName, bool bOverwrite = false);
	int 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(unsigned long uPos);
	bool Open(const CString& sFileName, int iFlags, mode_t iMode = 0644);
	bool Open(int iFlags, mode_t iMode = 0644);
	int Read(char *pszBuffer, int iBytes);
	bool ReadLine(CString & sData);
	int Write(const char *pszBuffer, u_int iBytes);
	int Write(const CString & sData);
	void Close();
	void ClearBuffer();

	bool IsOpen() const;
	CString GetLongName() const;
	CString GetShortName() const;
	CString GetDir() const;
	void SetFD(int iFD);

private:
	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;
	}

	virtual ~CDir() {
		CleanUp();
	}

	virtual void CleanUp() {
		for (unsigned int a = 0; a < size(); a++) {
			delete (*this)[a];
		}

		clear();
	}

	int Fill(const CString& 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 CString& sDir) {
		CFile cFile(sDir);
		return (cFile.Exists()) && (cFile.IsDir());
	}

/*	static bool Create(const CString& sDir, mode_t mode = 0755) {
		VCCString vSubDirs = sDir.split("[/\\\\]+");
		CCString 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 CCString& sDir, const CCString& sRegex, const CCString& 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()) && (!CCString::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 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(mode_t mode, 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; }

/*	static bool MkDir(const CString & 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;
			}
		}


		VCCString vPath = sPath.TrimRight_n("/").split("/+");

		if (vPath.empty()) {
			return false;
		}

		if (sPath[0] == '/');
			vPath[0] = "/" + vPath[0];

		CCString 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 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;
};

#endif // !_FILEUTILS_H