diff options
author | Sven Gothel <[email protected]> | 2022-05-11 05:23:22 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2022-05-11 05:23:22 +0200 |
commit | 7ead351b6691d36dc74e2450aebe64b567a348b5 (patch) | |
tree | 3cadb097bddf7432323e63b4a192db7628c689da | |
parent | 9b86252797269dac0763fe1da8e37b7573205020 (diff) |
C++ Trial: Complete file_stats and file_utils in dbt_utils.hpp (namely mkdir and remove)
-rw-r--r-- | trial/direct_bt/dbt_utils.hpp | 206 |
1 files changed, 110 insertions, 96 deletions
diff --git a/trial/direct_bt/dbt_utils.hpp b/trial/direct_bt/dbt_utils.hpp index 8db548bc..47e6c7db 100644 --- a/trial/direct_bt/dbt_utils.hpp +++ b/trial/direct_bt/dbt_utils.hpp @@ -37,75 +37,86 @@ #include <sys/types.h> #include <dirent.h> - -class DBTUtils { +class file_stats { private: - static int get_stat_mode(const std::string& name, bool& no_access, bool& not_existing, bool& is_file, bool& is_dir) { - no_access = false; - not_existing = false; - is_file = false; - is_dir = false; + std::string fname_; + bool access_, exists_, is_link_, is_file_, is_dir_; + int errno_res_; + public: + file_stats(const std::string& fname, const bool use_lstat=true) noexcept + : fname_(fname), access_(true), exists_(true), + is_link_(false), is_file_(false), is_dir_(false), + errno_res_(0) + { struct stat s; - if( 0 != stat(name.c_str(), &s) ) { + int stat_res; + if( use_lstat ) { + stat_res = ::lstat(fname.c_str(), &s); + } else { + stat_res = ::stat(fname.c_str(), &s); + } + if( 0 != stat_res ) { switch( errno ) { case EACCES: - no_access = true; + access_ = false; break; case ENOENT: - not_existing = true; + exists_ = false; break; default: break; } - jau::fprintf_td(stderr, "****** PATH '%s': stat errno: %d %s\n", - name.c_str(), errno, strerror(errno)); - return errno; + if( access_ && exists_ ) { + errno_res_ = errno; + } + } else { + is_link_ = S_ISLNK( s.st_mode ); + is_file_ = S_ISREG( s.st_mode ); + is_dir_ = S_ISDIR( s.st_mode ); } - is_file = S_ISREG( s.st_mode ); - is_dir = S_ISDIR( s.st_mode ); - return 0; } - public: - static bool is_existing(const std::string& name) { - bool no_access, not_existing, is_file, is_dir; - const bool res0 = 0 == get_stat_mode(name, no_access, not_existing, is_file, is_dir); - return res0 && !not_existing; - } + int errno_res() const noexcept { return errno_res_; } + bool ok() const noexcept { return 0 == errno_res_; } - static bool is_dir(const std::string& name) { - bool no_access, not_existing, is_file, is_dir; - const bool res0 = 0 == get_stat_mode(name, no_access, not_existing, is_file, is_dir); - return res0 && is_dir; - } + bool has_access() const noexcept { return access_; } + bool exists() const noexcept { return exists_; } + + bool is_link() const noexcept { return is_link_; } + bool is_file() const noexcept { return is_file_; } + bool is_dir() const noexcept { return is_dir_; } - static bool is_file(const std::string& name) { - bool no_access, not_existing, is_file, is_dir; - const bool res0 = 0 == get_stat_mode(name, no_access, not_existing, is_file, is_dir); - return res0 && is_file; + std::string to_string() const noexcept { + const std::string e = 0 != errno_res_ ? ", "+std::string(::strerror(errno_res_)) : ""; + return "stat['"+fname_+"', access "+std::to_string(access_)+", exists "+std::to_string(exists_)+ + ", link "+std::to_string(is_link_)+", file "+std::to_string(is_file_)+ + ", dir "+std::to_string(is_dir_)+", errno "+std::to_string(errno_res_)+e+"]"; } +}; +class file_utils { + public: static bool mkdir(const std::string& name) { - bool no_access, not_existing, is_file, is_dir; - const int errno_res = get_stat_mode(name, no_access, not_existing, is_file, is_dir); - if( 0 != errno_res && !not_existing) { - jau::fprintf_td(stderr, "****** PATH '%s': stat failed: %d %s\n", name.c_str(), errno_res, strerror(errno_res)); + file_stats fstats(name); + + if( !fstats.ok() ) { + jau::fprintf_td(stderr, "mkdir stat failed: %s\n", fstats.to_string().c_str()); return false; } - if( !not_existing && is_dir ) { - jau::fprintf_td(stderr, "****** PATH '%s': dir already exists\n", name.c_str()); + if( fstats.is_dir() ) { + jau::fprintf_td(stderr, "mkdir failed: %s, dir already exists\n", fstats.to_string().c_str()); return true; - } else if( not_existing ) { + } else if( !fstats.exists() ) { const int dir_err = ::mkdir(name.c_str(), S_IRWXU | S_IRWXG ); // excluding others if ( 0 != dir_err ) { - jau::fprintf_td(stderr, "****** PATH '%s': mkdir failed: %d %s\n", name.c_str(), errno, strerror(errno)); + jau::fprintf_td(stderr, "mkdir failed: %s, errno %d (%s)\n", fstats.to_string().c_str(), errno, strerror(errno)); return false; } else { return true; } } else { - jau::fprintf_td(stderr, "****** PATH '%s': entity exists but is no dir\n", name.c_str()); + jau::fprintf_td(stderr, "mkdir failed: %s, exists but is no dir\n", fstats.to_string().c_str()); return false; } } @@ -117,25 +128,18 @@ class DBTUtils { if( ( dir = ::opendir( dname.c_str() ) ) != nullptr ) { while ( ( ent = ::readdir( dir ) ) != NULL ) { std::string fname( ent->d_name ); - if( 0 == fname.find("bd_") ) { // prefix checl - const jau::nsize_t suffix_pos = fname.size() - 4; - if( suffix_pos == fname.find(".key", suffix_pos) ) { // suffix check - res.push_back( dname + "/" + fname ); // full path - } + if( "." != fname && ".." != fname ) { // avoid '.' and '..' + res.push_back( dname + "/" + fname ); // full path } } ::closedir (dir); - } // else: could not open directory - return res; - } - - static bool mkdirKeyFolder() { - if( mkdir( DBTConstants::CLIENT_KEY_PATH ) ) { - if( mkdir( DBTConstants::SERVER_KEY_PATH ) ) { - return true; - } + } else { + // could not open directory + file_stats fstats(dname); + jau::fprintf_td(stderr, "get_file_list failed: %s, errno %d (%s)\n", + fstats.to_string().c_str(), errno, strerror(errno)); } - return false; + return res; } /** @@ -145,58 +149,68 @@ class DBTUtils { * @return true only if the file or the directory with content has been deleted, otherwise false */ static bool remove(const std::string& file, const bool recursive) { - (void) recursive; - if( 0 != ::remove( file.c_str() ) ) { - if( ENOENT == errno ) { - // not existing - jau::fprintf_td(stderr, "****** PATH '%s': remove OK, not existing\n", file.c_str()); - return true; - } else { - jau::fprintf_td(stderr, "****** PATH '%s': remove failed: %d %s\n", file.c_str(), errno, strerror(errno)); - return false; - } - } else { - jau::fprintf_td(stderr, "****** PATH '%s': remove OK, removed\n", file.c_str()); - return true; - } -#if 0 + file_stats fstats_parent(file); bool rm_parent = true; - std::vector<std::string> contents = get_file_list(file); - if ( contents.size() > 0 ) { - for (const std::string& f : contents) { - bool no_access, not_existing, is_file, is_dir; - const int errno_res = get_stat_mode(f, no_access, not_existing, is_file, is_dir); - if( 0 != errno_res && !not_existing) { - jau::fprintf_td(stderr, "****** PATH '%s': stat failed: %d %s\n", f.c_str(), errno_res, strerror(errno_res)); - return false; - } - if( not_existing ) { - jau::fprintf_td(stderr, "****** PATH '%s': listed entity not existing: %d %s\n", f.c_str(), errno_res, strerror(errno_res)); - // try to continue .. - } else if( is_dir ) { - if( recursive ) { - rm_parent = remove(f, true) && rm_parent; - } else { - // can't empty contents -> can't rm 'file' - rm_parent = false; + if( fstats_parent.is_dir() ) { + std::vector<std::string> contents = get_file_list(file); + if ( contents.size() > 0 ) { + for (const std::string& f : contents) { + file_stats fstats(f); + if( !fstats.ok() ) { + jau::fprintf_td(stderr, "remove: stat failed: %s\n", fstats.to_string().c_str()); + return false; + } + if( !fstats.exists() ) { + jau::fprintf_td(stderr, "remove: listed entity not existing: %s\n", fstats.to_string().c_str()); + // try to continue .. + } else if( fstats.is_link() ) { + jau::fprintf_td(stderr, "remove: listed entity is link (drop): %s\n", fstats.to_string().c_str()); + } else if( fstats.is_dir() ) { + if( recursive ) { + rm_parent = remove(f, true) && rm_parent; + } else { + // can't empty contents -> can't rm 'file' + rm_parent = false; + } + } else if( fstats.is_file() ) { + const int res = ::remove( f.c_str() ); + rm_parent = 0 == res && rm_parent; + if( 0 != res ) { + jau::fprintf_td(stderr, "remove.1 failed: %s, res %d, errno %d (%s)\n", + fstats.to_string().c_str(), res, errno, strerror(errno)); + } } - } else /* assume is_file or link .. */ { - rm_parent = f.delete() && rm_parent; } } } if( rm_parent ) { - try { - return file.delete(); - } catch( final Exception e ) { e.printStackTrace(); } + const int res = ::remove( file.c_str() ); + if( 0 != res ) { + jau::fprintf_td(stderr, "remove.2 failed: %s, res %d, errno %d (%s)\n", + fstats_parent.to_string().c_str(), res, errno, strerror(errno)); + } + return 0 == res; + } + return false; + } +}; + +class DBTUtils { + public: + + static bool mkdirKeyFolder() { + if( file_utils::mkdir( DBTConstants::CLIENT_KEY_PATH ) ) { + if( file_utils::mkdir( DBTConstants::SERVER_KEY_PATH ) ) { + return true; + } } return false; -#endif } + static bool rmKeyFolder() { - if( remove( DBTConstants::CLIENT_KEY_PATH, true ) ) { - if( remove( DBTConstants::SERVER_KEY_PATH, true ) ) { + if( file_utils::remove( DBTConstants::CLIENT_KEY_PATH, true ) ) { + if( file_utils::remove( DBTConstants::SERVER_KEY_PATH, true ) ) { return true; } } |