summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2022-05-11 05:23:22 +0200
committerSven Gothel <[email protected]>2022-05-11 05:23:22 +0200
commit7ead351b6691d36dc74e2450aebe64b567a348b5 (patch)
tree3cadb097bddf7432323e63b4a192db7628c689da
parent9b86252797269dac0763fe1da8e37b7573205020 (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.hpp206
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;
}
}