*** empty log message ***
This commit is contained in:
parent
8520b2edcd
commit
597c930cd1
168
src/utils/fstreewalk.cpp
Normal file
168
src/utils/fstreewalk.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#ifndef lint
|
||||||
|
static char rcsid[] = "@(#$Id: fstreewalk.cpp,v 1.1 2004-12-10 18:13:13 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TEST_FSTREEWALK
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "debuglog.h"
|
||||||
|
#include "pathut.h"
|
||||||
|
#include "fstreewalk.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class FsTreeWalker::Internal {
|
||||||
|
Options options;
|
||||||
|
stringstream reason;
|
||||||
|
int errors;
|
||||||
|
void logsyserr(const char *call, const string ¶m)
|
||||||
|
{
|
||||||
|
errors++;
|
||||||
|
reason << call << "(" << param << ") : " << errno << " : " <<
|
||||||
|
strerror(errno) << endl;
|
||||||
|
}
|
||||||
|
friend class FsTreeWalker;
|
||||||
|
};
|
||||||
|
|
||||||
|
FsTreeWalker::FsTreeWalker(Options opts)
|
||||||
|
{
|
||||||
|
data = new Internal;
|
||||||
|
if (data) {
|
||||||
|
data->options = opts;
|
||||||
|
data->errors = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FsTreeWalker::~FsTreeWalker()
|
||||||
|
{
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
string FsTreeWalker::getReason()
|
||||||
|
{
|
||||||
|
return data->reason.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FsTreeWalker::getErrCnt()
|
||||||
|
{
|
||||||
|
return data->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
FsTreeWalker::Status FsTreeWalker::walk(const string &top, CbType fun,
|
||||||
|
void *cdata)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
if (statret == -1) {
|
||||||
|
data->logsyserr("stat", top);
|
||||||
|
return FtwError;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
if ((status = fun(cdata, top, &st, FtwDirEnter)) &
|
||||||
|
(FtwStop|FtwError)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
return fun(cdata, top, &st, FtwRegular);
|
||||||
|
} else {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle directory entries
|
||||||
|
DIR *d = opendir(top.c_str());
|
||||||
|
if (d == 0) {
|
||||||
|
data->logsyserr("opendir", top);
|
||||||
|
switch (errno) {
|
||||||
|
case EPERM:
|
||||||
|
case EACCES:
|
||||||
|
goto out;
|
||||||
|
default:
|
||||||
|
status = FtwError;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *ent;
|
||||||
|
while ((ent = readdir(d)) != 0) {
|
||||||
|
// We do process hidden files for now
|
||||||
|
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string fn = top;
|
||||||
|
path_cat(fn, ent->d_name);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
int statret = (data->options & FtwFollow) ? stat(fn.c_str(), &st) :
|
||||||
|
lstat(fn.c_str(), &st);
|
||||||
|
if (statret == -1) {
|
||||||
|
data->logsyserr("stat", fn);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
if (data->options & FtwNoRecurse) {
|
||||||
|
status = fun(cdata, fn, &st, FtwDirEnter);
|
||||||
|
} else {
|
||||||
|
status=walk(fn, fun, cdata);
|
||||||
|
}
|
||||||
|
if (status & (FtwStop|FtwError)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
if ((status = fun(cdata, fn, &st, FtwRegular)) &
|
||||||
|
(FtwStop|FtwError)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We skip other file types (devices etc...)
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (d)
|
||||||
|
closedir(d);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // TEST_FSTREEWALK
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "fstreewalk.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
FsTreeWalker::Status walkfunc(void *, const string &path,
|
||||||
|
const struct stat *st,
|
||||||
|
FsTreeWalker::CbFlag flg)
|
||||||
|
{
|
||||||
|
if (flg == FsTreeWalker::FtwDirEnter) {
|
||||||
|
cout << "[Entering " << path << "]" << endl;
|
||||||
|
} else if (flg == FsTreeWalker::FtwRegular) {
|
||||||
|
cout << path << endl;
|
||||||
|
}
|
||||||
|
return FsTreeWalker::FtwOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
cerr << "Usage: fstreewalk <topdir>" << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
FsTreeWalker walker;
|
||||||
|
walker.walk(argv[1], walkfunc, 0);
|
||||||
|
if (walker.getErrCnt() > 0)
|
||||||
|
cout << walker.getReason();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_FSTREEWALK
|
||||||
28
src/utils/fstreewalk.h
Normal file
28
src/utils/fstreewalk.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _FSTREEWALK_H_INCLUDED_
|
||||||
|
#define _FSTREEWALK_H_INCLUDED_
|
||||||
|
/* @(#$Id: fstreewalk.h,v 1.1 2004-12-10 18:13:13 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class FsTreeWalker {
|
||||||
|
public:
|
||||||
|
enum CbFlag {FtwRegular, FtwDirEnter, FtwDirReturn};
|
||||||
|
enum Status {FtwOk=0, FtwError=1, FtwStop=2,
|
||||||
|
FtwStatAll = FtwError|FtwStop};
|
||||||
|
enum Options {FtwOptNone = 0, FtwNoRecurse = 1, FtwFollow = 2};
|
||||||
|
|
||||||
|
typedef Status (*CbType)(void *cdata,
|
||||||
|
const std::string &, const struct stat *, CbFlag);
|
||||||
|
|
||||||
|
FsTreeWalker(Options opts = FtwOptNone);
|
||||||
|
~FsTreeWalker();
|
||||||
|
Status walk(const std::string &dir, CbType fun, void *cdata);
|
||||||
|
std::string getReason();
|
||||||
|
int getErrCnt();
|
||||||
|
private:
|
||||||
|
class Internal;
|
||||||
|
Internal *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _FSTREEWALK_H_INCLUDED_ */
|
||||||
68
src/utils/pathut.cpp
Normal file
68
src/utils/pathut.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#ifndef lint
|
||||||
|
static char rcsid[] = "@(#$Id: pathut.cpp,v 1.1 2004-12-10 18:13:14 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TEST_PATHUT
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#include "pathut.h"
|
||||||
|
|
||||||
|
std::string path_getfather(const std::string &s) {
|
||||||
|
std::string father = s;
|
||||||
|
|
||||||
|
// ??
|
||||||
|
if (father.empty())
|
||||||
|
return "./";
|
||||||
|
|
||||||
|
if (father[father.length() - 1] == '/') {
|
||||||
|
// Input ends with /. Strip it, handle special case for root
|
||||||
|
if (father.length() == 1)
|
||||||
|
return father;
|
||||||
|
father.erase(father.length()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::size_type slp = father.rfind('/');
|
||||||
|
if (slp == std::string::npos)
|
||||||
|
return "./";
|
||||||
|
|
||||||
|
father.erase(slp);
|
||||||
|
path_catslash(father);
|
||||||
|
return father;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_home()
|
||||||
|
{
|
||||||
|
uid_t uid = getuid();
|
||||||
|
|
||||||
|
struct passwd *entry = getpwuid(uid);
|
||||||
|
if (entry == 0)
|
||||||
|
return "/";
|
||||||
|
|
||||||
|
std::string homedir = entry->pw_dir;
|
||||||
|
path_catslash(homedir);
|
||||||
|
return homedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // TEST_PATHUT
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "pathut.h"
|
||||||
|
|
||||||
|
const char *tstvec[] = {"", "/", "/dir", "/dir/", "/dir1/dir2",
|
||||||
|
"/dir1/dir2",
|
||||||
|
"./dir", "./dir1/", "dir", "../dir"};
|
||||||
|
|
||||||
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0;i < sizeof(tstvec) / sizeof(char *); i++) {
|
||||||
|
cout << tstvec[i] << " -> " << path_getfather(tstvec[i]) << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_PATHUT
|
||||||
|
|
||||||
19
src/utils/pathut.h
Normal file
19
src/utils/pathut.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _PATHUT_H_INCLUDED_
|
||||||
|
#define _PATHUT_H_INCLUDED_
|
||||||
|
/* @(#$Id: pathut.h,v 1.1 2004-12-10 18:13:14 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
inline void path_catslash(std::string &s) {
|
||||||
|
if (s.empty() || s[s.length() - 1] != '/')
|
||||||
|
s += '/';
|
||||||
|
}
|
||||||
|
inline void path_cat(std::string &s1, const std::string &s2) {
|
||||||
|
path_catslash(s1);
|
||||||
|
s1 += s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern std::string path_getfather(const std::string &s);
|
||||||
|
extern std::string path_home();
|
||||||
|
|
||||||
|
#endif /* _PATHUT_H_INCLUDED_ */
|
||||||
Loading…
x
Reference in New Issue
Block a user