follow top (entry) symlinks even if nofollow is set
This commit is contained in:
parent
77cfa7948e
commit
f231470f51
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: fstreewalk.cpp,v 1.12 2007-07-12 10:53:07 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: fstreewalk.cpp,v 1.13 2007-08-28 08:08:38 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -130,38 +130,44 @@ bool FsTreeWalker::inSkippedPaths(const string& path)
|
||||
return false;
|
||||
}
|
||||
|
||||
FsTreeWalker::Status FsTreeWalker::walk(const string &top,
|
||||
FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
||||
FsTreeWalkerCB& cb)
|
||||
{
|
||||
return iwalk(path_canon(top), cb);
|
||||
}
|
||||
string top = path_canon(_top);
|
||||
|
||||
FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
|
||||
FsTreeWalkerCB& cb)
|
||||
{
|
||||
Status status = FtwOk;
|
||||
struct stat st;
|
||||
int statret;
|
||||
|
||||
// Handle the top entry
|
||||
statret = (data->options & FtwFollow) ? stat(top.c_str(), &st) :
|
||||
lstat(top.c_str(), &st);
|
||||
// We always follow symlinks at this point. Makes more sense.
|
||||
statret = stat(top.c_str(), &st);
|
||||
if (statret == -1) {
|
||||
data->logsyserr("stat", top);
|
||||
return FtwError;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if ((status = cb.processone(top, &st, FtwDirEnter)) &
|
||||
return iwalk(top, &st, cb);
|
||||
}
|
||||
|
||||
// Note that the 'norecurse' flag is handled as part of the directory read.
|
||||
// This means that we always go into the top 'walk()' parameter if it is a
|
||||
// directory, even if norecurse is set. Bug or Feature ?
|
||||
FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
|
||||
struct stat *stp,
|
||||
FsTreeWalkerCB& cb)
|
||||
{
|
||||
Status status = FtwOk;
|
||||
|
||||
// Handle the parameter
|
||||
if (S_ISDIR(stp->st_mode)) {
|
||||
if ((status = cb.processone(top, stp, FtwDirEnter)) &
|
||||
(FtwStop|FtwError)) {
|
||||
return status;
|
||||
}
|
||||
} else if (S_ISREG(st.st_mode)) {
|
||||
return cb.processone(top, &st, FtwRegular);
|
||||
} else if (S_ISREG(stp->st_mode)) {
|
||||
return cb.processone(top, stp, FtwRegular);
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Handle directory entries
|
||||
// This is a directory, read it and process entries:
|
||||
DIR *d = opendir(top.c_str());
|
||||
if (d == 0) {
|
||||
data->logsyserr("opendir", top);
|
||||
@ -206,7 +212,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
|
||||
if (data->options & FtwNoRecurse) {
|
||||
status = cb.processone(fn, &st, FtwDirEnter);
|
||||
} else {
|
||||
status = iwalk(fn, cb);
|
||||
status = iwalk(fn, &st, cb);
|
||||
}
|
||||
if (status & (FtwStop|FtwError))
|
||||
goto out;
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
#ifndef _FSTREEWALK_H_INCLUDED_
|
||||
#define _FSTREEWALK_H_INCLUDED_
|
||||
/* @(#$Id: fstreewalk.h,v 1.7 2007-07-12 10:53:07 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
/* @(#$Id: fstreewalk.h,v 1.8 2007-08-28 08:08:39 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
@ -27,6 +27,7 @@ using std::list;
|
||||
#endif
|
||||
|
||||
class FsTreeWalkerCB;
|
||||
struct stat;
|
||||
|
||||
/**
|
||||
* Class implementing a unix directory recursive walk.
|
||||
@ -74,7 +75,7 @@ class FsTreeWalker {
|
||||
bool inSkippedPaths(const string& path);
|
||||
bool inSkippedNames(const string& name);
|
||||
private:
|
||||
Status iwalk(const string &dir, FsTreeWalkerCB& cb);
|
||||
Status iwalk(const string &dir, struct stat *stp, FsTreeWalkerCB& cb);
|
||||
class Internal;
|
||||
Internal *data;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user