From b43d52da54e5545d4e863038370c6ab7104fb03a Mon Sep 17 00:00:00 2001 From: Denis Corbin Date: Sun, 19 May 2024 17:25:59 +0200 Subject: [PATCH] providing more details of the type of entry found by entrepot::read_dir_next_dirinfo() method --- src/dar_suite/line_tools.cpp | 10 +++--- src/libdar/entrepot.hpp | 7 ++-- src/libdar/entrepot_aux.hpp | 49 +++++++++++++++++++++++++++ src/libdar/entrepot_libcurl.cpp | 4 +-- src/libdar/entrepot_libcurl.hpp | 2 +- src/libdar/entrepot_local.cpp | 8 ++--- src/libdar/entrepot_local.hpp | 2 +- src/libdar/etage.cpp | 20 +++++++---- src/libdar/etage.hpp | 9 +++-- src/libdar/filesystem_backup.cpp | 4 +-- src/libdar/filesystem_tools.cpp | 6 ++-- src/libdar/i_entrepot_libcurl.cpp | 18 +++++----- src/libdar/i_entrepot_libcurl.hpp | 10 +++--- src/python/pybind11_libdar.cpp | 9 +++-- src/testing/test_entrepot_libcurl.cpp | 6 ++-- 15 files changed, 115 insertions(+), 49 deletions(-) create mode 100644 src/libdar/entrepot_aux.hpp diff --git a/src/dar_suite/line_tools.cpp b/src/dar_suite/line_tools.cpp index 3b5c0f15..a1104c9f 100644 --- a/src/dar_suite/line_tools.cpp +++ b/src/dar_suite/line_tools.cpp @@ -1538,13 +1538,13 @@ void line_tools_check_min_digits(user_interaction & dialog, const path & loc, co { bool found = false; string cur; - bool isdir; + inode_type tp; etage contents(dialog, loc.display().c_str(), datetime(0), datetime(0), false, false); regular_mask slice = regular_mask(base + "\\.0+[1-9][0-9]*\\." + extension + "$", true); - while(!found && contents.read(cur, isdir)) + while(!found && contents.read(cur, tp)) { found = slice.is_covered(cur); if(found) @@ -2027,7 +2027,7 @@ static bool is_a_slice_available(user_interaction & ui, const string & base, con try { string rest; - bool isdir; + inode_type tp; line_tools_split_path_basename(base.c_str(), chem, rest); @@ -2036,8 +2036,8 @@ static bool is_a_slice_available(user_interaction & ui, const string & base, con etage contents = etage(ui, chem->display().c_str(), datetime(0), datetime(0), false, false); // we don't care the dates here so we set them to zero regular_mask slice = regular_mask(rest + "\\.[0-9]+\\."+ extension, true); - while(!ret && contents.read(rest, isdir)) - ret = isdir ? false : slice.is_covered(rest); + while(!ret && contents.read(rest, tp)) + ret = (tp == inode_type::isdir) ? false : slice.is_covered(rest); } catch(Erange & e) { diff --git a/src/libdar/entrepot.hpp b/src/libdar/entrepot.hpp index c067a788..d53f7b7c 100644 --- a/src/libdar/entrepot.hpp +++ b/src/libdar/entrepot.hpp @@ -41,6 +41,7 @@ #include "path.hpp" #include "archive_aux.hpp" #include "gf_mode.hpp" +#include "entrepot_aux.hpp" namespace libdar { @@ -160,11 +161,11 @@ namespace libdar /// alternative to the method read_dir_next, should be implemented also /// \param[out] filename name of the next entry in the directory, (valid only if this method returned true) - /// \param[out] isdir true if filename is a directory (valid only if this method returned true) - /// \note a call to rea_dir_reset_dirinfo() should be done before the first call to this method + /// \param[out] tp gives the nature of the entry + /// \note a call to read_dir_reset_dirinfo() should be done before the first call to this method /// \note either use read_dir_reset() followed by read_dir_next() calls, or call /// read_dir_reset_dirinfo() followed by read_dir_next_dirinfo() calls - virtual bool read_dir_next_dirinfo(std::string & filename, bool & isdir) const = 0; + virtual bool read_dir_next_dirinfo(std::string & filename, inode_type & tp) const = 0; /// create a new directory in the current directory diff --git a/src/libdar/entrepot_aux.hpp b/src/libdar/entrepot_aux.hpp new file mode 100644 index 00000000..ae89d22f --- /dev/null +++ b/src/libdar/entrepot_aux.hpp @@ -0,0 +1,49 @@ +/*********************************************************************/ +// dar - disk archive - a backup/restoration program +// Copyright (C) 2002-2024 Denis Corbin +// +// This program 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 2 +// of the License, or (at your option) any later version. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// to contact the author, see the AUTHOR file +/*********************************************************************/ + + /// \file entrepot_aux.hpp + /// \brief set of datastructures used to interact with entrepot objects + /// \ingroup API + + +#ifndef ENTREPOT_AUX_HPP +#define ENTREPOT_AUX_HPP + +#include "../my_config.h" + +#include "integers.hpp" +#include + +namespace libdar +{ + + /// \addtogroup API + /// @{ + + /// type of inode + enum class inode_type { nondir, isdir, unknown }; + + + /// @} + +} // end of namespace + +#endif diff --git a/src/libdar/entrepot_libcurl.cpp b/src/libdar/entrepot_libcurl.cpp index d117e113..217a9446 100644 --- a/src/libdar/entrepot_libcurl.cpp +++ b/src/libdar/entrepot_libcurl.cpp @@ -254,7 +254,7 @@ namespace libdar #endif } - bool entrepot_libcurl::read_dir_next_dirinfo(std::string & filename, bool & isdir) const + bool entrepot_libcurl::read_dir_next_dirinfo(std::string & filename, inode_type & tp) const { #if defined ( LIBCURL_AVAILABLE ) && defined ( LIBTHREADAR_AVAILABLE ) bool ret; @@ -262,7 +262,7 @@ namespace libdar NLS_SWAP_IN; try { - ret = pimpl->read_dir_next_dirinfo(filename, isdir); + ret = pimpl->read_dir_next_dirinfo(filename, tp); } catch(...) { diff --git a/src/libdar/entrepot_libcurl.hpp b/src/libdar/entrepot_libcurl.hpp index 4dba7068..ed6df28a 100644 --- a/src/libdar/entrepot_libcurl.hpp +++ b/src/libdar/entrepot_libcurl.hpp @@ -85,7 +85,7 @@ namespace libdar virtual void read_dir_reset() const override; virtual bool read_dir_next(std::string & filename) const override; virtual void read_dir_reset_dirinfo() const override; - virtual bool read_dir_next_dirinfo(std::string & filename, bool & isdir) const override; + virtual bool read_dir_next_dirinfo(std::string & filename, inode_type & tp) const override; virtual void create_dir(const std::string & dirname, U_I permission) override; diff --git a/src/libdar/entrepot_local.cpp b/src/libdar/entrepot_local.cpp index 4e395ad1..69c9f6d1 100644 --- a/src/libdar/entrepot_local.cpp +++ b/src/libdar/entrepot_local.cpp @@ -104,11 +104,11 @@ namespace libdar bool entrepot_local::read_dir_next(string & filename) const { - bool isdir; - return read_dir_next_dirinfo(filename, isdir); + inode_type tp; + return read_dir_next_dirinfo(filename, tp); } - bool entrepot_local::read_dir_next_dirinfo(std::string & filename, bool & isdir) const + bool entrepot_local::read_dir_next_dirinfo(std::string & filename, inode_type & tp) const { entrepot_local *me = const_cast(this); @@ -116,7 +116,7 @@ namespace libdar throw SRC_BUG; if(contents == nullptr) return false; - if(!contents->read(filename, isdir)) + if(!contents->read(filename, tp)) { delete contents; me->contents = nullptr; diff --git a/src/libdar/entrepot_local.hpp b/src/libdar/entrepot_local.hpp index 84c1194a..d3fc8308 100644 --- a/src/libdar/entrepot_local.hpp +++ b/src/libdar/entrepot_local.hpp @@ -67,7 +67,7 @@ namespace libdar virtual void read_dir_reset() const override { read_dir_reset_dirinfo(); }; virtual bool read_dir_next(std::string & filename) const override; virtual void read_dir_reset_dirinfo() const override; - virtual bool read_dir_next_dirinfo(std::string & filename, bool & isdir) const override; + virtual bool read_dir_next_dirinfo(std::string & filename, inode_type & tp) const override; virtual void create_dir(const std::string & dirname, U_I permission) override; diff --git a/src/libdar/etage.cpp b/src/libdar/etage.cpp index afdf54f6..432db86f 100644 --- a/src/libdar/etage.cpp +++ b/src/libdar/etage.cpp @@ -155,10 +155,18 @@ namespace libdar if(cache_directory_tagging) is_cache_dir = cache_directory_tagging_check(dirname, ret->d_name); - fichier.push_back(cell(string(ret->d_name), - (ret->d_type == DT_DIR - || ret->d_type == DT_LNK - || ret->d_type == DT_UNKNOWN))); + switch(ret->d_type) + { + case DT_DIR: + fichier.push_back(cell(string(ret->d_name), inode_type::isdir)); + break; + case DT_LNK: + case DT_UNKNOWN: + fichier.push_back(cell(string(ret->d_name), inode_type::unknown)); + break; + default: + fichier.push_back(cell(string(ret->d_name), inode_type::nondir)); + } } } closedir(tmp); @@ -182,14 +190,14 @@ namespace libdar } } - bool etage::read(string & ref, bool & isdir) + bool etage::read(string & ref, inode_type & tp) { if(fichier.empty()) return false; else { ref = fichier.front().name; - isdir = fichier.front().isdir; + tp = fichier.front().type; fichier.pop_front(); return true; } diff --git a/src/libdar/etage.hpp b/src/libdar/etage.hpp index 32ae1309..6b6ca9a1 100644 --- a/src/libdar/etage.hpp +++ b/src/libdar/etage.hpp @@ -32,6 +32,7 @@ #include #include "datetime.hpp" #include "user_interaction.hpp" +#include "entrepot_aux.hpp" namespace libdar { @@ -62,18 +63,20 @@ namespace libdar etage & operator = (etage && ref) noexcept = default; ~etage() = default; - bool read(std::string & ref, bool & isdir); + bool read(std::string & ref, inode_type & tp); bool is_empty() const { return fichier.empty(); }; datetime get_last_mod() const { return last_mod; }; datetime get_last_acc() const { return last_acc; }; private: + struct cell { std::string name; - bool isdir; + inode_type type; + cell(const std::string & filename, - bool is_dir): name(filename), isdir(is_dir) {}; + inode_type tp): name(filename), type(tp) {}; }; std::deque fichier; ///< holds the list of entry in the directory diff --git a/src/libdar/filesystem_backup.cpp b/src/libdar/filesystem_backup.cpp index a18ed6a3..26ac82b9 100644 --- a/src/libdar/filesystem_backup.cpp +++ b/src/libdar/filesystem_backup.cpp @@ -245,9 +245,9 @@ namespace libdar { etage & inner = pile.back(); string name; - bool isdir; + inode_type tp; - if(!inner.read(name, isdir)) + if(!inner.read(name, tp)) { string tmp; diff --git a/src/libdar/filesystem_tools.cpp b/src/libdar/filesystem_tools.cpp index b03f4363..d48b1463 100644 --- a/src/libdar/filesystem_tools.cpp +++ b/src/libdar/filesystem_tools.cpp @@ -171,12 +171,12 @@ namespace libdar { etage fils = etage(ui, s, datetime(0), datetime(0), false, false); // we don't care the access and modification time because directory will be destroyed string tmp; - bool isdir; + inode_type tp; // first we destroy directory's children - while(fils.read(tmp, isdir)) + while(fils.read(tmp, tp)) { - if(isdir) + if(tp == inode_type::isdir) filesystem_tools_supprime(ui, (path(ref).append(tmp)).display()); else tools_unlink((path(ref).append(tmp)).display()); diff --git a/src/libdar/i_entrepot_libcurl.cpp b/src/libdar/i_entrepot_libcurl.cpp index 8b53fe84..e8dc2a20 100644 --- a/src/libdar/i_entrepot_libcurl.cpp +++ b/src/libdar/i_entrepot_libcurl.cpp @@ -98,18 +98,18 @@ namespace libdar bool entrepot_libcurl::i_entrepot_libcurl::read_dir_next(string & filename) const { - bool isdir; - return read_dir_next_dirinfo(filename, isdir); + inode_type tp; + return read_dir_next_dirinfo(filename, tp); } - bool entrepot_libcurl::i_entrepot_libcurl::read_dir_next_dirinfo(std::string & filename, bool & isdir) const + bool entrepot_libcurl::i_entrepot_libcurl::read_dir_next_dirinfo(std::string & filename, inode_type & tp) const { if(cur_dir_cursor == current_dir.end()) return false; else { filename = cur_dir_cursor->first; - isdir = cur_dir_cursor->second; + tp = cur_dir_cursor->second; ++cur_dir_cursor; return true; } @@ -390,7 +390,7 @@ namespace libdar void entrepot_libcurl::i_entrepot_libcurl::fill_temporary_list() const { - std::map::iterator it = current_dir.begin(); + std::map::iterator it = current_dir.begin(); temporary_list.clear(); while(it != current_dir.end()) @@ -505,7 +505,7 @@ namespace libdar // looking for best_entry in current_dir and updating its value - map::iterator found = current_dir.find(*best_entry); + map::iterator found = current_dir.find(*best_entry); if(found == current_dir.end()) throw SRC_BUG; // entry found in temporary_list but not in current_dir??? what was temporary_list filled with then??? @@ -518,7 +518,7 @@ namespace libdar // chdir on symlink pointing to nondir inode will fail, but at least this stay an // option, which would not be the case if we assume all symlinks not to point to // directories: chdir to them would then be forbidden by entrepot_libcurl... - found->second = (line[0] == 'd' || line[0] == 'l'); + found->second = (line[0] == 'd' || line[0] == 'l') ? inode_type::isdir : inode_type::nondir; // we now remove the best_entry from temporary_list to speed up future search @@ -583,7 +583,7 @@ namespace libdar if(!reading_dir_tmp.empty()) { if(!details) - current_dir[reading_dir_tmp] = false; // for now we assume it is not a directory + current_dir[reading_dir_tmp] = inode_type::unknown; reading_dir_tmp.clear(); } break; @@ -644,7 +644,7 @@ namespace libdar if(me->withdirinfo) me->update_current_dir_with_line(me->reading_dir_tmp); else - me->current_dir[me->reading_dir_tmp] = false; // for now assumed to be non directory entry + me->current_dir[me->reading_dir_tmp] = inode_type::unknown; me->reading_dir_tmp.clear(); break; case '\r': diff --git a/src/libdar/i_entrepot_libcurl.hpp b/src/libdar/i_entrepot_libcurl.hpp index fe0f493f..7c6d5dff 100644 --- a/src/libdar/i_entrepot_libcurl.hpp +++ b/src/libdar/i_entrepot_libcurl.hpp @@ -88,7 +88,7 @@ namespace libdar virtual void read_dir_reset() const override { set_current_dir(false); }; virtual bool read_dir_next(std::string & filename) const override; virtual void read_dir_reset_dirinfo() const override { set_current_dir(true); }; - virtual bool read_dir_next_dirinfo(std::string & filename, bool & isdir) const override; + virtual bool read_dir_next_dirinfo(std::string & filename, inode_type &tp) const override; virtual void create_dir(const std::string & dirname, U_I permission) override; @@ -113,10 +113,10 @@ namespace libdar mycurl_protocol x_proto; std::string base_URL; ///< URL of the repository with only minimum path (login/password is given outside the URL) mutable mycurl_easyhandle_sharing easyh; - mutable std::map current_dir; ///< map current directory entries to their property of being themselves a directory - mutable std::string reading_dir_tmp; ///< used by callback to split received byte flow, line per line - mutable std::deque temporary_list; ///< used only when looking for dir/nodir property - mutable std::map::const_iterator cur_dir_cursor; ///< next entry to be read from current_dir + mutable std::map current_dir; ///< map current directory entries to their property of being themselves a directory + mutable std::string reading_dir_tmp; ///< used by callback to split received byte flow, line per line + mutable std::deque temporary_list; ///< used only when looking for dir/nodir property + mutable std::map::const_iterator cur_dir_cursor; ///< next entry to be read from current_dir U_I wait_delay; bool verbosity; mutable bool withdirinfo; ///< used by callback function while reading directory content, to know whether to expect only a filename per line or whole entry information diff --git a/src/python/pybind11_libdar.cpp b/src/python/pybind11_libdar.cpp index e2fd7c2f..dee02401 100644 --- a/src/python/pybind11_libdar.cpp +++ b/src/python/pybind11_libdar.cpp @@ -972,6 +972,11 @@ PYBIND11_MODULE(libdar, mod) // entrepot_* classes // + pybind11::enum_(mod, "inode_type") + .value("nondir", libdar::inode_type::nondir) + .value("isdir", libdar::inode_type::isdir) + .value("unknown", libdar::inode_type::unknown); + class py_entrepot : public libdar::entrepot { public: @@ -1057,14 +1062,14 @@ PYBIND11_MODULE(libdar, mod) ); }; - virtual bool read_dir_next_dirinfo(std::string & filename, bool & isdir) const override + virtual bool read_dir_next_dirinfo(std::string & filename, libdar::inode_type & tp) const override { PYBIND11_OVERRIDE_PURE( bool, libdar::entrepot, read_dir_next, filename, - isdir); + tp); }; virtual void create_dir(const std::string & dirname, libdar::U_I permission) override diff --git a/src/testing/test_entrepot_libcurl.cpp b/src/testing/test_entrepot_libcurl.cpp index 34bd6e03..763a8bc7 100644 --- a/src/testing/test_entrepot_libcurl.cpp +++ b/src/testing/test_entrepot_libcurl.cpp @@ -142,13 +142,13 @@ void f1(int argc, char *argv[]) 3); string entry; - bool isdir; + inode_type tp; if(chemin != "") reposito.set_location(chemin); ui->printf("Directory content"); reposito.read_dir_reset_dirinfo(); - while(reposito.read_dir_next_dirinfo(entry, isdir)) - ui->printf("%s | %s", isdir? "DIR" : "xxx", entry.c_str()); + while(reposito.read_dir_next_dirinfo(entry, tp)) + ui->printf("%s | %s", tp == inode_type::isdir ? "DIR" : "xxx", entry.c_str()); fichier_local readme("/etc/fstab");