|
a/src/utils/fstreewalk.cpp |
|
b/src/utils/fstreewalk.cpp |
|
... |
|
... |
37 |
#ifndef NO_NAMESPACES
|
37 |
#ifndef NO_NAMESPACES
|
38 |
using namespace std;
|
38 |
using namespace std;
|
39 |
#endif /* NO_NAMESPACES */
|
39 |
#endif /* NO_NAMESPACES */
|
40 |
|
40 |
|
41 |
class FsTreeWalker::Internal {
|
41 |
class FsTreeWalker::Internal {
|
42 |
Options options;
|
42 |
int options;
|
43 |
stringstream reason;
|
43 |
stringstream reason;
|
44 |
list<string> skippedNames;
|
44 |
list<string> skippedNames;
|
45 |
list<string> skippedPaths;
|
45 |
list<string> skippedPaths;
|
46 |
int errors;
|
46 |
int errors;
|
47 |
void logsyserr(const char *call, const string ¶m)
|
47 |
void logsyserr(const char *call, const string ¶m)
|
|
... |
|
... |
51 |
strerror(errno) << endl;
|
51 |
strerror(errno) << endl;
|
52 |
}
|
52 |
}
|
53 |
friend class FsTreeWalker;
|
53 |
friend class FsTreeWalker;
|
54 |
};
|
54 |
};
|
55 |
|
55 |
|
56 |
FsTreeWalker::FsTreeWalker(Options opts)
|
56 |
FsTreeWalker::FsTreeWalker(int opts)
|
57 |
{
|
57 |
{
|
58 |
data = new Internal;
|
58 |
data = new Internal;
|
59 |
if (data) {
|
59 |
if (data) {
|
60 |
data->options = opts;
|
60 |
data->options = opts;
|
61 |
data->errors = 0;
|
61 |
data->errors = 0;
|
|
... |
|
... |
110 |
return false;
|
110 |
return false;
|
111 |
}
|
111 |
}
|
112 |
|
112 |
|
113 |
bool FsTreeWalker::addSkippedPath(const string& ipath)
|
113 |
bool FsTreeWalker::addSkippedPath(const string& ipath)
|
114 |
{
|
114 |
{
|
115 |
string path = path_canon(ipath);
|
115 |
string path = (data->options & FtwNoCanon) ? ipath : path_canon(ipath);
|
116 |
if (find(data->skippedPaths.begin(),
|
116 |
if (find(data->skippedPaths.begin(),
|
117 |
data->skippedPaths.end(), path) == data->skippedPaths.end())
|
117 |
data->skippedPaths.end(), path) == data->skippedPaths.end())
|
118 |
data->skippedPaths.push_back(path);
|
118 |
data->skippedPaths.push_back(path);
|
119 |
return true;
|
119 |
return true;
|
120 |
}
|
120 |
}
|
121 |
bool FsTreeWalker::setSkippedPaths(const list<string> &paths)
|
121 |
bool FsTreeWalker::setSkippedPaths(const list<string> &paths)
|
122 |
{
|
122 |
{
|
123 |
data->skippedPaths = paths;
|
123 |
data->skippedPaths = paths;
|
124 |
for (list<string>::iterator it = data->skippedPaths.begin();
|
124 |
for (list<string>::iterator it = data->skippedPaths.begin();
|
125 |
it != data->skippedPaths.end(); it++)
|
125 |
it != data->skippedPaths.end(); it++)
|
|
|
126 |
if (!(data->options & FtwNoCanon))
|
126 |
*it = path_canon(*it);
|
127 |
*it = path_canon(*it);
|
127 |
data->skippedPaths.sort();
|
128 |
data->skippedPaths.sort();
|
128 |
data->skippedPaths.unique();
|
129 |
data->skippedPaths.unique();
|
129 |
return true;
|
130 |
return true;
|
130 |
}
|
131 |
}
|
131 |
bool FsTreeWalker::inSkippedPaths(const string& path)
|
132 |
bool FsTreeWalker::inSkippedPaths(const string& path)
|
|
... |
|
... |
140 |
}
|
141 |
}
|
141 |
|
142 |
|
142 |
FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
143 |
FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
143 |
FsTreeWalkerCB& cb)
|
144 |
FsTreeWalkerCB& cb)
|
144 |
{
|
145 |
{
|
145 |
string top = path_canon(_top);
|
146 |
string top = (data->options & FtwNoCanon) ? _top : path_canon(_top);
|
146 |
|
147 |
|
147 |
struct stat st;
|
148 |
struct stat st;
|
148 |
int statret;
|
149 |
int statret;
|
149 |
// We always follow symlinks at this point. Makes more sense.
|
150 |
// We always follow symlinks at this point. Makes more sense.
|
150 |
statret = stat(top.c_str(), &st);
|
151 |
statret = stat(top.c_str(), &st);
|
|
... |
|
... |
223 |
} else {
|
224 |
} else {
|
224 |
status = iwalk(fn, &st, cb);
|
225 |
status = iwalk(fn, &st, cb);
|
225 |
}
|
226 |
}
|
226 |
if (status & (FtwStop|FtwError))
|
227 |
if (status & (FtwStop|FtwError))
|
227 |
goto out;
|
228 |
goto out;
|
|
|
229 |
|
|
|
230 |
// No DirReturn call when not recursing
|
|
|
231 |
if (!(data->options & FtwNoRecurse))
|
228 |
if ((status = cb.processone(top, &st, FtwDirReturn))
|
232 |
if ((status = cb.processone(top, &st, FtwDirReturn))
|
229 |
& (FtwStop|FtwError))
|
233 |
& (FtwStop|FtwError))
|
230 |
goto out;
|
234 |
goto out;
|
231 |
} else if (S_ISREG(st.st_mode)) {
|
235 |
} else if (S_ISREG(st.st_mode)) {
|
232 |
if ((status = cb.processone(fn, &st, FtwRegular)) &
|
236 |
if ((status = cb.processone(fn, &st, FtwRegular)) &
|
233 |
(FtwStop|FtwError)) {
|
237 |
(FtwStop|FtwError)) {
|
234 |
goto out;
|
238 |
goto out;
|
235 |
}
|
239 |
}
|
|
... |
|
... |
254 |
|
258 |
|
255 |
#include "fstreewalk.h"
|
259 |
#include "fstreewalk.h"
|
256 |
|
260 |
|
257 |
using namespace std;
|
261 |
using namespace std;
|
258 |
|
262 |
|
|
|
263 |
static int op_flags;
|
|
|
264 |
#define OPT_MOINS 0x1
|
|
|
265 |
#define OPT_p 0x2
|
|
|
266 |
#define OPT_P 0x4
|
|
|
267 |
#define OPT_r 0x8
|
|
|
268 |
#define OPT_c 0x10
|
|
|
269 |
|
259 |
class myCB : public FsTreeWalkerCB {
|
270 |
class myCB : public FsTreeWalkerCB {
|
260 |
public:
|
271 |
public:
|
261 |
FsTreeWalker::Status processone(const string &path,
|
272 |
FsTreeWalker::Status processone(const string &path,
|
262 |
const struct stat *st,
|
273 |
const struct stat *st,
|
263 |
FsTreeWalker::CbFlag flg)
|
274 |
FsTreeWalker::CbFlag flg)
|
264 |
{
|
275 |
{
|
265 |
if (flg == FsTreeWalker::FtwDirEnter) {
|
276 |
if (flg == FsTreeWalker::FtwDirEnter) {
|
|
|
277 |
if (op_flags & OPT_r)
|
|
|
278 |
cout << path << endl;
|
|
|
279 |
else
|
266 |
cout << "[Entering " << path << "]" << endl;
|
280 |
cout << "[Entering " << path << "]" << endl;
|
267 |
} else if (flg == FsTreeWalker::FtwDirReturn) {
|
281 |
} else if (flg == FsTreeWalker::FtwDirReturn) {
|
268 |
cout << "[Returning to " << path << "]" << endl;
|
282 |
cout << "[Returning to " << path << "]" << endl;
|
269 |
} else if (flg == FsTreeWalker::FtwRegular) {
|
283 |
} else if (flg == FsTreeWalker::FtwRegular) {
|
270 |
cout << path << endl;
|
284 |
cout << path << endl;
|
271 |
}
|
285 |
}
|
|
... |
|
... |
274 |
};
|
288 |
};
|
275 |
|
289 |
|
276 |
static const char *thisprog;
|
290 |
static const char *thisprog;
|
277 |
|
291 |
|
278 |
static char usage [] =
|
292 |
static char usage [] =
|
279 |
"trfstreewalk [-p pattern] [-P ignpath] topdir\n\n"
|
293 |
"trfstreewalk [-p pattern] [-P ignpath] [-r] [-c] topdir\n"
|
|
|
294 |
" -r : norecurse\n"
|
|
|
295 |
" -c : no path canonification\n"
|
280 |
;
|
296 |
;
|
281 |
static void
|
297 |
static void
|
282 |
Usage(void)
|
298 |
Usage(void)
|
283 |
{
|
299 |
{
|
284 |
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
300 |
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
285 |
exit(1);
|
301 |
exit(1);
|
286 |
}
|
302 |
}
|
287 |
|
|
|
288 |
static int op_flags;
|
|
|
289 |
#define OPT_MOINS 0x1
|
|
|
290 |
#define OPT_p 0x2
|
|
|
291 |
#define OPT_P 0x4
|
|
|
292 |
|
303 |
|
293 |
int main(int argc, const char **argv)
|
304 |
int main(int argc, const char **argv)
|
294 |
{
|
305 |
{
|
295 |
list<string> patterns;
|
306 |
list<string> patterns;
|
296 |
list<string> paths;
|
307 |
list<string> paths;
|
|
... |
|
... |
302 |
if (!(**argv))
|
313 |
if (!(**argv))
|
303 |
/* Cas du "adb - core" */
|
314 |
/* Cas du "adb - core" */
|
304 |
Usage();
|
315 |
Usage();
|
305 |
while (**argv)
|
316 |
while (**argv)
|
306 |
switch (*(*argv)++) {
|
317 |
switch (*(*argv)++) {
|
|
|
318 |
case 'r': op_flags |= OPT_r; break;
|
|
|
319 |
case 'c': op_flags |= OPT_c; break;
|
307 |
case 'p': op_flags |= OPT_p; if (argc < 2) Usage();
|
320 |
case 'p': op_flags |= OPT_p; if (argc < 2) Usage();
|
308 |
patterns.push_back(*(++argv));
|
321 |
patterns.push_back(*(++argv));
|
309 |
argc--;
|
322 |
argc--;
|
310 |
goto b1;
|
323 |
goto b1;
|
311 |
case 'P': op_flags |= OPT_P; if (argc < 2) Usage();
|
324 |
case 'P': op_flags |= OPT_P; if (argc < 2) Usage();
|
|
... |
|
... |
319 |
|
332 |
|
320 |
if (argc != 1)
|
333 |
if (argc != 1)
|
321 |
Usage();
|
334 |
Usage();
|
322 |
string topdir = *argv++;argc--;
|
335 |
string topdir = *argv++;argc--;
|
323 |
|
336 |
|
|
|
337 |
int opt = 0;
|
|
|
338 |
if (op_flags & OPT_r)
|
|
|
339 |
opt |= FsTreeWalker::FtwNoRecurse;
|
|
|
340 |
if (op_flags & OPT_c)
|
|
|
341 |
opt |= FsTreeWalker::FtwNoCanon;
|
324 |
FsTreeWalker walker;
|
342 |
FsTreeWalker walker(opt);
|
325 |
walker.setSkippedNames(patterns);
|
343 |
walker.setSkippedNames(patterns);
|
326 |
walker.setSkippedPaths(paths);
|
344 |
walker.setSkippedPaths(paths);
|
327 |
myCB cb;
|
345 |
myCB cb;
|
328 |
walker.walk(topdir, cb);
|
346 |
walker.walk(topdir, cb);
|
329 |
if (walker.getErrCnt() > 0)
|
347 |
if (walker.getErrCnt() > 0)
|