follow top (entry) symlinks even if nofollow is set

This commit is contained in:
dockes 2007-08-28 08:08:39 +00:00
parent 77cfa7948e
commit f231470f51
2 changed files with 27 additions and 20 deletions

View File

@ -1,5 +1,5 @@
#ifndef lint #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 #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -130,38 +130,44 @@ bool FsTreeWalker::inSkippedPaths(const string& path)
return false; return false;
} }
FsTreeWalker::Status FsTreeWalker::walk(const string &top, FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
FsTreeWalkerCB& cb) 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; struct stat st;
int statret; int statret;
// We always follow symlinks at this point. Makes more sense.
// Handle the top entry statret = stat(top.c_str(), &st);
statret = (data->options & FtwFollow) ? stat(top.c_str(), &st) :
lstat(top.c_str(), &st);
if (statret == -1) { if (statret == -1) {
data->logsyserr("stat", top); data->logsyserr("stat", top);
return FtwError; return FtwError;
} }
if (S_ISDIR(st.st_mode)) { return iwalk(top, &st, cb);
if ((status = cb.processone(top, &st, FtwDirEnter)) & }
// 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)) { (FtwStop|FtwError)) {
return status; return status;
} }
} else if (S_ISREG(st.st_mode)) { } else if (S_ISREG(stp->st_mode)) {
return cb.processone(top, &st, FtwRegular); return cb.processone(top, stp, FtwRegular);
} else { } else {
return status; return status;
} }
// Handle directory entries // This is a directory, read it and process entries:
DIR *d = opendir(top.c_str()); DIR *d = opendir(top.c_str());
if (d == 0) { if (d == 0) {
data->logsyserr("opendir", top); data->logsyserr("opendir", top);
@ -206,7 +212,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
if (data->options & FtwNoRecurse) { if (data->options & FtwNoRecurse) {
status = cb.processone(fn, &st, FtwDirEnter); status = cb.processone(fn, &st, FtwDirEnter);
} else { } else {
status = iwalk(fn, cb); status = iwalk(fn, &st, cb);
} }
if (status & (FtwStop|FtwError)) if (status & (FtwStop|FtwError))
goto out; goto out;

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _FSTREEWALK_H_INCLUDED_ #ifndef _FSTREEWALK_H_INCLUDED_
#define _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 <string>
#include <list> #include <list>
@ -27,6 +27,7 @@ using std::list;
#endif #endif
class FsTreeWalkerCB; class FsTreeWalkerCB;
struct stat;
/** /**
* Class implementing a unix directory recursive walk. * Class implementing a unix directory recursive walk.
@ -74,7 +75,7 @@ class FsTreeWalker {
bool inSkippedPaths(const string& path); bool inSkippedPaths(const string& path);
bool inSkippedNames(const string& name); bool inSkippedNames(const string& name);
private: private:
Status iwalk(const string &dir, FsTreeWalkerCB& cb); Status iwalk(const string &dir, struct stat *stp, FsTreeWalkerCB& cb);
class Internal; class Internal;
Internal *data; Internal *data;
}; };