*** 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