X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Ffile_utils.cc;h=7c3dffe71ffeee1195cc3ec3a9728dd9bfbf46ac;hb=f6b9572bfd86537422b7cb033e83ae1651f30816;hp=af2c67b40c0b13e04e071cc3d6da64832af2b982;hpb=b5af3bb8e313e13166cc54c60a14e5492e674065;p=ardour.git diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc index af2c67b40c..7c3dffe71f 100644 --- a/libs/pbd/file_utils.cc +++ b/libs/pbd/file_utils.cc @@ -19,24 +19,34 @@ #include +#include +#include + #include +#include #include -#include -#include +#include + +#include "pbd/compose.h" +#include "pbd/file_utils.h" +#include "pbd/error.h" +#include "pbd/pathscanner.h" -#include +#include "i18n.h" + +using namespace std; namespace PBD { void -get_files_in_directory (const sys::path& directory_path, vector& result) +get_files_in_directory (const std::string& directory_path, vector& result) { - if (!is_directory(directory_path)) return; + if (!Glib::file_test (directory_path, Glib::FILE_TEST_IS_DIR)) return; try { - Glib::Dir dir(directory_path.to_string()); + Glib::Dir dir(directory_path); std::copy(dir.begin(), dir.end(), std::back_inserter(result)); } catch (Glib::FileError& err) @@ -46,13 +56,14 @@ get_files_in_directory (const sys::path& directory_path, vector& result) } void -find_matching_files_in_directory (const sys::path& directory, +find_matching_files_in_directory (const std::string& directory, const Glib::PatternSpec& pattern, - vector& result) + vector& result) { vector tmp_files; get_files_in_directory (directory, tmp_files); + result.reserve(tmp_files.size()); for (vector::iterator file_iter = tmp_files.begin(); file_iter != tmp_files.end(); @@ -60,19 +71,19 @@ find_matching_files_in_directory (const sys::path& directory, { if (!pattern.match(*file_iter)) continue; - sys::path full_path(directory); - full_path /= *file_iter; + std::string full_path(directory); + full_path = Glib::build_filename (full_path, *file_iter); result.push_back(full_path); } } void -find_matching_files_in_directories (const vector& paths, +find_matching_files_in_directories (const vector& paths, const Glib::PatternSpec& pattern, - vector& result) + vector& result) { - for (vector::const_iterator path_iter = paths.begin(); + for (vector::const_iterator path_iter = paths.begin(); path_iter != paths.end(); ++path_iter) { @@ -83,33 +94,23 @@ find_matching_files_in_directories (const vector& paths, void find_matching_files_in_search_path (const SearchPath& search_path, const Glib::PatternSpec& pattern, - vector& result) + vector& result) { - vector dirs; - std::copy(search_path.begin(), search_path.end(), std::back_inserter(dirs)); - find_matching_files_in_directories (dirs, pattern, result); + find_matching_files_in_directories (search_path, pattern, result); } bool find_file_in_search_path(const SearchPath& search_path, const string& filename, - sys::path& result) + std::string& result) { - vector tmp; + vector tmp; Glib::PatternSpec tmp_pattern(filename); find_matching_files_in_search_path (search_path, tmp_pattern, tmp); if (tmp.size() == 0) { - info << string_compose - ( - "Found no file named %1 in search path %2", - filename, - search_path.get_string () - ) - << endmsg; - return false; } @@ -120,7 +121,7 @@ find_file_in_search_path(const SearchPath& search_path, ( "Found more than one file matching %1 in search path %2", filename, - search_path.get_string () + search_path () ) << endmsg; } @@ -131,4 +132,109 @@ find_file_in_search_path(const SearchPath& search_path, return true; } +bool +copy_file(const std::string & from_path, const std::string & to_path) +{ + if (!Glib::file_test (from_path, Glib::FILE_TEST_EXISTS)) return false; + + Glib::RefPtr from_file = Gio::File::create_for_path(from_path); + Glib::RefPtr to_file = Gio::File::create_for_path(to_path); + + try + { + from_file->copy (to_file, Gio::FILE_COPY_OVERWRITE); + } + catch(const Glib::Exception& ex) + { + error << string_compose (_("Unable to Copy file %1 to %2 (%3)"), + from_path, to_path, ex.what()) + << endmsg; + return false; + } + return true; +} + +static +bool accept_all_files (string const &, void *) +{ + return true; +} + +void +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); + } +} + +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) +{ + struct stat bA; + int const rA = g_stat (a.c_str(), &bA); + struct stat 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. + */ + + struct stat 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