X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Ffile_utils.cc;h=44254989c1bfbd227930aa9da8e206f1143ab6aa;hb=e3329000557015ce54691235769db8821e75666b;hp=f323ebcb69715d781f2b7a408f68c70a453d57d9;hpb=e66e9854d7dac2e76753b74f3fe0eb323ac35f4f;p=ardour.git diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc index f323ebcb69..44254989c1 100644 --- a/libs/pbd/file_utils.cc +++ b/libs/pbd/file_utils.cc @@ -18,6 +18,14 @@ */ #include +#include + +#include +#include + +#ifdef COMPILER_MINGW +#include // For W_OK +#endif #include #include @@ -27,8 +35,10 @@ #include "pbd/compose.h" #include "pbd/file_utils.h" +#include "pbd/debug.h" #include "pbd/error.h" #include "pbd/pathscanner.h" +#include "pbd/stl_delete.h" #include "i18n.h" @@ -71,6 +81,11 @@ find_matching_files_in_directory (const std::string& directory, std::string full_path(directory); full_path = Glib::build_filename (full_path, *file_iter); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1\n", full_path) + ); + result.push_back(full_path); } } @@ -89,7 +104,7 @@ find_matching_files_in_directories (const vector& paths, } void -find_matching_files_in_search_path (const SearchPath& search_path, +find_matching_files_in_search_path (const Searchpath& search_path, const Glib::PatternSpec& pattern, vector& result) { @@ -97,7 +112,7 @@ find_matching_files_in_search_path (const SearchPath& search_path, } bool -find_file_in_search_path(const SearchPath& search_path, +find_file_in_search_path(const Searchpath& search_path, const string& filename, std::string& result) { @@ -108,24 +123,28 @@ find_file_in_search_path(const SearchPath& search_path, if (tmp.size() == 0) { + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("No file matching %1 found in Path: %2\n", filename, search_path.to_string()) + ); return false; } -#if 0 if (tmp.size() != 1) { - info << string_compose - ( - "Found more than one file matching %1 in search path %2", - filename, - search_path () - ) - << endmsg; + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found more that one file matching %1 in Path: %2\n", filename, search_path.to_string()) + ); } -#endif result = tmp.front(); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1 in Path: %2\n", filename, search_path.to_string()) + ); + return true; } @@ -162,11 +181,80 @@ copy_files(const std::string & from_path, const std::string & to_dir) { PathScanner scanner; vector* files = scanner (from_path, accept_all_files, 0, true, false); - for (vector::iterator i = files->begin(); i != files->end(); ++i) { - std::string from = Glib::build_filename (from_path, **i); - std::string to = Glib::build_filename (to_dir, **i); - copy_file (from, to); + + if (files) { + for (vector::iterator i = files->begin(); i != files->end(); ++i) { + std::string from = Glib::build_filename (from_path, **i); + std::string to = Glib::build_filename (to_dir, **i); + copy_file (from, to); + } + vector_delete (files); + } +} + +std::string +get_absolute_path (const std::string & p) +{ + Glib::RefPtr f = Gio::File::create_for_path (p); + return f->get_path (); +} + +bool +equivalent_paths (const std::string& a, const std::string& b) +{ + GStatBuf bA; + int const rA = g_stat (a.c_str(), &bA); + GStatBuf bB; + int const rB = g_stat (b.c_str(), &bB); + + return (rA == 0 && rB == 0 && bA.st_dev == bB.st_dev && bA.st_ino == bB.st_ino); +} + +bool +path_is_within (std::string const & haystack, std::string needle) +{ + while (1) { + if (equivalent_paths (haystack, needle)) { + return true; + } + + needle = Glib::path_get_dirname (needle); + if (needle == "." || needle == "/") { + break; + } + } + + return false; +} + +bool +exists_and_writable (const std::string & p) +{ + /* writable() really reflects the whole folder, but if for any + reason the session state file can't be written to, still + make us unwritable. + */ + + GStatBuf statbuf; + + if (g_stat (p.c_str(), &statbuf) != 0) { + /* doesn't exist - not writable */ + return false; + } else { + if (!(statbuf.st_mode & S_IWUSR)) { + /* exists and is not writable */ + return false; + } + /* filesystem may be mounted read-only, so even though file + * permissions permit access, the mount status does not. + * access(2) seems like the best test for this. + */ + if (g_access (p.c_str(), W_OK) != 0) { + return false; + } } + + return true; } } // namespace PBD