"Fossies" - the Fresh Open Source Software Archive 
Member "qdiff-0.9.1/tfiletools.h" (21 Oct 2008, 8422 Bytes) of package /linux/privat/old/qdiff-0.9.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*GPL*START*
2 *
3 * tfilesync.h - file and directory handling tolls header file
4 *
5 * Copyright (C) 2000 by Johannes Overmann <Johannes.Overmann@gmx.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * *GPL*END*/
21
22 #ifndef _ngw_tfiletools_h_
23 #define _ngw_tfiletools_h_
24
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <assert.h>
29 #include "tstring.h"
30 #include "texception.h"
31 #include "tmap.h"
32 #include "tvector.h"
33
34 // history:
35 // 2001:
36 // 25 Jun 2001: created (Dir and File taken from filesync.cc)
37
38 #ifdef __STRICT_ANSI__
39 #define S_ISVTX 01000
40 #define S_ISLNK(a) 0
41 #define S_ISSOCK(a) 0
42 #define S_IFMT 0170000
43 #endif
44
45
46 // own device type which is a simple 64 bit unsigned integer
47 typedef unsigned long long mydev_t;
48 inline mydev_t dev_t2mydev_t(const dev_t& dev) {
49 #ifdef __APPLE__
50 return *(reinterpret_cast<const unsigned int*>(&dev));
51 #else
52 return *(reinterpret_cast<const mydev_t*>(&dev));
53 #endif
54 }
55 inline dev_t mydev_t2dev_t(mydev_t dev) {
56 return *(reinterpret_cast<const dev_t*>(&dev));
57 }
58
59
60 // file instance information (needed for hardlink structure)
61 struct TFileInstance {
62 TFileInstance(mydev_t d = 0, ino_t i = 0): device(d), inode(i) {}
63 mydev_t device;
64 ino_t inode;
65 };
66 inline bool operator < (const TFileInstance& d1, const TFileInstance& d2) {
67 if(d1.device < d2.device) return true;
68 return d1.inode < d2.inode;
69 }
70 inline bool operator == (const TFileInstance& d1, const TFileInstance& d2) {
71 return (d1.inode == d2.inode) && (d1.device == d2.device);
72 }
73 inline bool operator != (const TFileInstance& d1, const TFileInstance& d2) {
74 return (d1.inode != d2.inode) || (d1.device != d2.device);
75 }
76
77 class TFile {
78 public:
79 // cons & des
80 TFile(const tstring& fname = tstring()): name_(fname), stated(false) {}
81 ~TFile() {}
82 void invalidateStat() const { const_cast<TFile*>(this)->stated = false; }
83
84 // read only interface
85
86 // file types
87 enum FileType { FT_UNKNOWN, FT_REGULAR, FT_DIR, FT_SYMLINK, FT_CHARDEV, FT_BLOCKDEV, FT_FIFO, FT_SOCKET };
88
89 // name
90 const tstring& name() const {if(name_.empty()) throw TNotInitializedException("TFile"); return name_;}
91 tstring filename() const {tstring r= name_; r.extractFilename(); return r;}
92 tstring pathname() const {tstring r= name_; r.extractPath(); return r;}
93
94 // stat fields
95 mydev_t device() const {getstat(); return dev_t2mydev_t(statbuf.st_dev);}
96 ino_t inode() const {getstat(); return statbuf.st_ino;}
97 nlink_t hardlinks() const {getstat(); return statbuf.st_nlink;}
98 uid_t userid() const {getstat(); return statbuf.st_uid;}
99 gid_t groupid() const {getstat(); return statbuf.st_gid;}
100 mydev_t devicetype() const {getstat(); return dev_t2mydev_t(statbuf.st_rdev);}
101 off_t size() const {getstat(); return statbuf.st_size;}
102 time_t atime() const {getstat(); return statbuf.st_atime;}
103 time_t mtime() const {getstat(); return statbuf.st_mtime;}
104 time_t ctime() const {getstat(); return statbuf.st_ctime;}
105 // mode fields
106 mode_t protection() const { getstat(); return statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); }
107 bool isdir() const { getstat(); return S_ISDIR(statbuf.st_mode); }
108 bool isregular() const { getstat(); return S_ISREG(statbuf.st_mode); }
109 bool issymlink() const { getstat(); return S_ISLNK(statbuf.st_mode); }
110 bool ischardev() const { getstat(); return S_ISCHR(statbuf.st_mode); }
111 bool isblockdev() const { getstat(); return S_ISBLK(statbuf.st_mode); }
112 bool isfifo() const { getstat(); return S_ISFIFO(statbuf.st_mode); }
113 bool issocket() const { getstat(); return S_ISSOCK(statbuf.st_mode); }
114 bool devicetypeApplies() const { return ischardev() || isblockdev(); }
115 mode_t filetypebits() const { return statbuf.st_mode & S_IFMT; }
116 TFileInstance instance() const { return TFileInstance(device(), inode()); }
117 FileType filetype() const;
118 tstring filetypeLongStr() const;
119 char filetypeChar() const;
120 tstring filetypeStr7() const;
121 static void followLinks(bool follow = true) { follow_links = follow; }
122 static size_t numStated() { return num_stated; }
123
124 private:
125 // private helpers
126 void getstat() const;
127
128 // private data
129 tstring name_;
130 struct stat statbuf;
131 bool stated;
132
133 // private static data
134 static bool follow_links;
135 static size_t num_stated;
136
137 // avoid implicit comparison
138 bool operator==(const TFile&);
139 };
140
141
142 class TDir;
143
144 class TSubTreeContext {
145 public:
146 TSubTreeContext(bool cross_filesystems, size_t max_depth = 0xffffffff): root(0), cross_filesystems(cross_filesystems), max_depth(max_depth) {}
147 TDir *root;
148 bool cross_filesystems;
149 size_t max_depth;
150 };
151
152
153 class TDir: public TFile {
154 public:
155 TDir(): TFile(), scanned(false), subTreeContext(0), depth(0) {}
156 TDir(const tstring& fname, TSubTreeContext& subTreeContext_, size_t depth = 0): TFile(fname), scanned(false), subTreeContext(&subTreeContext_), depth(depth) { init(); }
157 TDir(const TFile& file_, TSubTreeContext& subTreeContext_, size_t depth = 0): TFile(file_), scanned(false), subTreeContext(&subTreeContext_), depth(depth) { init(); }
158 ~TDir() {}
159
160 // read only interface
161 const TFile& file(const tstring& fname) const { scan(); if(name2fileid.contains(fname)) return files[name2fileid[fname]]; else throw TNotFoundException(); }
162 const TDir & dir (const tstring& fname) const { scan(); if(name2dirid .contains(fname)) return dirs [name2dirid [fname]]; else throw TNotFoundException(); }
163 const TFile& file(size_t index) const { scan(); if(index >= files.size()) throw TZeroBasedIndexOutOfRangeException(index, files.size()); return files[index];}
164 const TDir & dir (size_t index) const { scan(); if(index >= dirs .size()) throw TZeroBasedIndexOutOfRangeException(index, dirs .size()); return dirs [index];}
165 size_t numFiles() const { scan(); return files.size();}
166 size_t numDirs () const { scan(); return dirs .size();}
167 bool containsFile(const tstring& fname) const { scan(); return name2fileid.contains(fname); }
168 bool containsDir (const tstring& fname) const { scan(); return name2dirid .contains(fname); }
169 bool contains (const tstring& fname) const { return containsDir(fname) || containsFile(fname); }
170 bool isEmpty() const { return dirs.empty() && files.empty(); }
171 void invalidateContents() { freeMem(); }
172 size_t numRecursive(bool low_mem = true, const char *verbose = 0, bool count_files = true, bool count_dirs = true) const;
173 void freeMem() const { if(scanned) { TDir *t = const_cast<TDir*>(this); t->dirs.clear(); t->files.clear(); t->name2fileid.clear(); t->name2dirid.clear(); t->scanned = false; } }
174 static void resetVerboseNum() { old_verbose_num = verbose_num = 0; };
175 static void noLeafOptimize(bool no_opt) {
176 no_leaf_optimize = no_opt;
177 #ifdef WIN32
178 no_leaf_optimize = true;
179 #endif
180 }
181
182 private:
183 // private helpers
184 void scan() const;
185 void init() { assert(subTreeContext); if(subTreeContext->root == 0) subTreeContext->root = this; }
186
187 // private data
188 bool scanned;
189 tmap<tstring,int> name2fileid;
190 tmap<int,TFile> files;
191 tmap<tstring,int> name2dirid;
192 tmap<int,TDir> dirs;
193 TSubTreeContext *subTreeContext;
194 size_t depth;
195
196 // private static data
197 static size_t verbose_num;
198 static size_t old_verbose_num;
199 static bool no_leaf_optimize;
200
201 // forbid implicit comparison
202 bool operator==(const TDir&);
203 };
204
205 // global functions
206 tvector<tstring> findFilesRecursive(const TDir& dir);
207 tvector<tstring> filterExtensions(const tvector<tstring>& list, const tvector<tstring>& extensions, bool remove = false);
208 void makeDirectoriesIncludingParentsIfNecessary(const tstring& dirname, bool verbose = false, bool dummy = false);
209
210
211 #endif /* _ngw_tfiletools_h_ */
212