*** empty log message ***

This commit is contained in:
dockes 2004-12-10 18:13:14 +00:00
parent 8520b2edcd
commit 597c930cd1
4 changed files with 283 additions and 0 deletions

168
src/utils/fstreewalk.cpp Normal file
View 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 &param)
{
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
View 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
View 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
View 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_ */