diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 5936f0fb..4062064f 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -49,10 +49,17 @@ ignorable_error(const int err) namespace fs { + /* + Attempts to clone a path. + The directories which already exist are left alone. + The new directories have metadata set to match the original if + possible. Optionally ignore errors on metadata copies. + */ int clonepath(const string &fromsrc, const string &tosrc, - const char *relative) + const char *relative, + const bool return_metadata_errors) { int rv; struct stat st; @@ -83,29 +90,28 @@ namespace fs rv = fs::mkdir(topath,st.st_mode); if(rv == -1) { - if(errno != EEXIST) - return -1; - - rv = fs::chmod_check_on_error(topath,st.st_mode); - if(rv == -1) + if(errno == EEXIST) + return 0; + else return -1; } - // It may not support it... it's fine... + // it may not support it... it's fine... rv = fs::attr::copy(frompath,topath); - if((rv == -1) && !ignorable_error(errno)) + if(return_metadata_errors && (rv == -1) && !ignorable_error(errno)) return -1; + // it may not support it... it's fine... rv = fs::xattr::copy(frompath,topath); - if((rv == -1) && !ignorable_error(errno)) + if(return_metadata_errors && (rv == -1) && !ignorable_error(errno)) return -1; rv = fs::lchown_check_on_error(topath,st); - if(rv == -1) + if(return_metadata_errors && (rv == -1)) return -1; rv = fs::utime(topath,st); - if(rv == -1) + if(return_metadata_errors && (rv == -1)) return -1; return 0; @@ -114,15 +120,17 @@ namespace fs int clonepath(const std::string &from, const std::string &to, - const std::string &relative) + const std::string &relative, + const bool return_metadata_errors) { - return fs::clonepath(from,to,relative.c_str()); + return fs::clonepath(from,to,relative.c_str(),return_metadata_errors); } int clonepath_as_root(const string &from, const string &to, - const char *relative) + const char *relative, + const bool return_metadata_errors) { if((relative == NULL) || (relative[0] == '\0')) return 0; @@ -132,15 +140,16 @@ namespace fs { const ugid::SetRootGuard ugidGuard; - return fs::clonepath(from,to,relative); + return fs::clonepath(from,to,relative,return_metadata_errors); } } int clonepath_as_root(const std::string &from, const std::string &to, - const std::string &relative) + const std::string &relative, + const bool return_metadata_errors) { - return fs::clonepath_as_root(from,to,relative.c_str()); + return fs::clonepath_as_root(from,to,relative.c_str(),return_metadata_errors); } } diff --git a/src/fs_clonepath.hpp b/src/fs_clonepath.hpp index e98e7316..34904d0c 100644 --- a/src/fs_clonepath.hpp +++ b/src/fs_clonepath.hpp @@ -22,15 +22,19 @@ namespace fs { int clonepath(const std::string &from, const std::string &to, - const char *relative); + const char *relative, + const bool return_metadata_errors = false); int clonepath(const std::string &from, const std::string &to, - const std::string &relative); + const std::string &relative, + const bool return_metadata_errors = false); int clonepath_as_root(const std::string &from, const std::string &to, - const char *relative); + const char *relative, + const bool return_metadata_errors = false); int clonepath_as_root(const std::string &from, const std::string &to, - const std::string &relative); + const std::string &relative, + const bool return_metadata_errors = false); }