1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2025-08-17 15:19:48 +00:00

First import

This commit is contained in:
King_DuckZ 2015-11-05 15:32:31 +01:00
commit 31a70945bb
7 changed files with 1071 additions and 0 deletions

156
src/filesearcher.cpp Normal file
View file

@ -0,0 +1,156 @@
/* Copyright 2015, Michele Santullo
* This file is part of "dindexer".
*
* "dindexer" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "dindexer" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
*/
#include "filesearcher.hpp"
#if !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE 500
#endif
#include <ftw.h>
#include <iostream>
#include <sys/types.h>
#include <cstring>
namespace fastf {
extern "C" int PrintName ( const char* parPath, const struct stat* parStat, int parType, FTW* parBuff );
namespace {
struct SearchOptions {
FileSearcher::CallbackType* callback;
const FileSearcher::ConstCharVecType* extensions;
const FileSearcher::ConstCharVecType* ignorePaths;
int search_flags;
};
__thread SearchOptions g_searchOptions;
bool print_def_callback (const char* parPath, int parLevel, bool parDir, bool parSymlink) {
std::cout << parPath;
if (parDir) {
std::cout << '/';
}
if (parSymlink) {
std::cout << " (symlink)";
}
std::cout << " (" << parLevel << ')';
std::cout << '\n';
return true;
}
int HandleDir (const char* parPath, const struct stat*, FTW* parBuff, bool parCanBeRead, bool parSymlink) {
if (not (*g_searchOptions.callback)(parPath, parBuff->level, true, parSymlink))
return FTW_STOP;
if (!parCanBeRead)
return FTW_SKIP_SUBTREE;
const FileSearcher::ConstCharVecType& ignorePaths = *g_searchOptions.ignorePaths;
for (int z = 0; z < static_cast<int>(ignorePaths.size()); ++z) {
if (std::strncmp(ignorePaths[z].str, parPath + parBuff->base, ignorePaths[z].len) == 0)
return FTW_SKIP_SUBTREE;
}
return FTW_CONTINUE;
}
int HandleFile (const char* parPath, const struct stat*, FTW* parBuff, bool parSymlink) {
const FileSearcher::ConstCharVecType& extensions = *g_searchOptions.extensions;
if (extensions.empty()) {
if (not (*g_searchOptions.callback)(parPath, parBuff->level, false, parSymlink)) {
return FTW_STOP;
}
}
else {
for (int z = 0; z < static_cast<int>(extensions.size()); ++z) {
const int& extLen = extensions[z].len;
const int pathLen = parBuff->base + std::strlen(parPath + parBuff->base);
if (std::strncmp(extensions[z].str, parPath + pathLen - extLen, extensions[z].len) == 0) {
if (not (*g_searchOptions.callback)(parPath, parBuff->level, false, parSymlink)) {
return FTW_STOP;
}
break;
}
}
}
return FTW_CONTINUE;
}
int HandleLink (const char* parPath, const struct stat* parStat, FTW* parBuff, bool parBroken) {
if (parBroken)
return FTW_CONTINUE;
else
return HandleFile(parPath, parStat, parBuff, true);
}
extern "C" int PrintName (const char* parPath, const struct stat* parStat, int parType, FTW* parBuff) {
struct stat st;
lstat(parPath, &st);
const bool is_symlink = S_ISLNK(st.st_mode);
switch (parType) {
//parPath is a directory which can't be read
case FTW_DNR:
//parPath is a directory
case FTW_D:
return HandleDir(parPath, parStat, parBuff, static_cast<bool>(FTW_DNR != parType), is_symlink);
//parPath is a regular file
case FTW_F:
return HandleFile(parPath, parStat, parBuff, is_symlink);
//The stat(2) call failed on parPath, which is not a symbolic link
case FTW_NS:
return FTW_CONTINUE;
//parPath is a symbolic link pointing to a nonexistent file (This occurs only if FTW_PHYS is not set)
case FTW_SLN:
//parPath is a symbolic link, and FTW_PHYS was set in flags
case FTW_SL:
return HandleLink(parPath, parStat, parBuff, static_cast<bool>(FTW_SLN == parType));
}
return FTW_CONTINUE;
}
} //unnamed namespace
FileSearcher::FileSearcher (const char* parBaseDir) :
callback_(&print_def_callback),
baseDir_(parBaseDir),
followSymlinks_(false),
remainInFilesystem_(true)
{
}
FileSearcher::~FileSearcher() noexcept {
}
void FileSearcher::Search (const ConstCharVecType& parExtensions, const ConstCharVecType& parIgnorePaths) {
g_searchOptions.search_flags = FTW_ACTIONRETVAL;
if (remainInFilesystem_)
g_searchOptions.search_flags |= FTW_MOUNT;
if (!followSymlinks_)
g_searchOptions.search_flags |= FTW_PHYS;
g_searchOptions.extensions = &parExtensions;
g_searchOptions.ignorePaths = &parIgnorePaths;
g_searchOptions.callback = &callback_;
nftw(baseDir_, &PrintName, 15, g_searchOptions.search_flags);
}
void FileSearcher::SetCallback (CallbackType parCallback) {
callback_ = parCallback;
}
} //namespace fastf

60
src/filesearcher.hpp Normal file
View file

@ -0,0 +1,60 @@
/* Copyright 2015, Michele Santullo
* This file is part of "dindexer".
*
* "dindexer" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "dindexer" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef idB6D385B7779240308449D6081CB790F1
#define idB6D385B7779240308449D6081CB790F1
#include <vector>
#include <functional>
namespace fastf {
struct StringWithLength {
StringWithLength ( const char* parStr, int parLen ) :
str(parStr),
len(parLen)
{
}
const char* const str;
const int len;
};
class FileSearcher {
public:
typedef std::vector<StringWithLength> ConstCharVecType;
typedef std::function<bool(const char*, int, bool, bool)> CallbackType;
explicit FileSearcher ( const char* parBaseDir );
~FileSearcher ( void ) noexcept;
void Search ( const ConstCharVecType& parExtensions, const ConstCharVecType& parIgnorePaths );
void SetFollowSymlinks ( bool parFollow ) noexcept { followSymlinks_ = parFollow; }
bool FollowSymlinks ( void ) const noexcept { return followSymlinks_; }
void SetRemainInFilesystem ( bool parRemain ) noexcept { remainInFilesystem_ = parRemain; }
bool RemainInFilesystem ( void ) const noexcept { return remainInFilesystem_; }
void SetCallback ( CallbackType parCallback );
private:
CallbackType callback_;
const char* const baseDir_;
bool followSymlinks_;
bool remainInFilesystem_;
};
} //namespace fastf
#endif

54
src/main.cpp Normal file
View file

@ -0,0 +1,54 @@
/* Copyright 2015, Michele Santullo
* This file is part of "dindexer".
*
* "dindexer" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "dindexer" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <ciso646>
#include "filesearcher.hpp"
#include "pathname.hpp"
bool my_callback (const char* parPath, int parLevel, bool parDir, bool parSymlink) {
if (parLevel > 0 and not parDir)
std::cout << parPath << '\n';
return true;
}
int main (int parArgc, char* parArgv[]) {
std::cout << "argc: " << parArgc << '\n';
for (int z = 0; z < parArgc; ++z) {
std::cout << "argv[" << z << "]: " << parArgv[z] << '\n';
}
std::cout << std::endl;
fastf::FileSearcher searcher("/home/duckz/dev/code/cpp/dindexer/test");
fastf::FileSearcher::ConstCharVecType ext, ignore;
searcher.SetFollowSymlinks(true);
searcher.SetCallback(fastf::FileSearcher::CallbackType(&my_callback));
//searcher.Search(ext, ignore);
din::PathName pn("/home/duckz/dev/code/cpp/dindexer/test");
din::PathName pn1("///home/duckz/dev/code/cpp/dindexer/test");
din::PathName pn2("home/duckz////dev/code/cpp/dindexer/test");
din::PathName pn3("/home/duckz/dev/code/cpp/dindexer/test/");
din::PathName pn4("/home/duckz/dev/code/cpp/dindexer/test////");
std::cout << pn.path() << '\n';
std::cout << pn1.path() << '\n';
std::cout << pn2.path() << '\n';
std::cout << pn3.path() << '\n';
std::cout << pn4.path() << '\n';
return 0;
}

77
src/pathname.cpp Normal file
View file

@ -0,0 +1,77 @@
/* Copyright 2015, Michele Santullo
* This file is part of "dindexer".
*
* "dindexer" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "dindexer" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
*/
#include "pathname.hpp"
#include <algorithm>
#include <cstring>
namespace din {
namespace {
void split_path (std::vector<std::string>* parOut, const char* parPath, std::size_t parLen) {
parOut->clear();
const char* from = parPath;
const char* next;
while (parPath + parLen != (next = std::find(from, parPath + parLen, '/'))) {
if (next != from) {
parOut->push_back(std::string(from, next));
from = next;
}
++from;
}
if (next != from) {
parOut->push_back(std::string(from, next));
}
}
} //unnamed namespace
PathName::PathName (const char* parPath) {
if (not parPath) {
m_absolute = false;
}
else {
m_absolute = ('/' == *parPath);
split_path(&m_atoms, parPath, std::strlen(parPath));
}
}
std::string PathName::path() const {
if (m_atoms.empty()) {
if (m_absolute) {
return std::string("/");
}
else {
return std::string("");
}
}
std::size_t reserve = (m_absolute ? 1 : 0);
for (const auto& itm : m_atoms) {
reserve += itm.size();
}
reserve += m_atoms.size() - 1;
std::string out;
out.reserve(reserve);
const char* slash = (m_absolute ? "/" : "");
for (const auto& itm : m_atoms) {
out += slash;
out += itm;
slash = "/";
}
return std::move(out);
}
} //namespace din

39
src/pathname.hpp Normal file
View file

@ -0,0 +1,39 @@
/* Copyright 2015, Michele Santullo
* This file is part of "dindexer".
*
* "dindexer" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "dindexer" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id279E04E31E2C4D98B8C902781A3CE018
#define id279E04E31E2C4D98B8C902781A3CE018
#include <vector>
#include <string>
namespace din {
class PathName {
public:
explicit PathName ( const char* parPath );
~PathName ( void ) noexcept = default;
bool is_absolute ( void ) const;
std::string path ( void ) const;
private:
std::vector<std::string> m_atoms;
bool m_absolute;
};
} //namespace din
#endif