Add path_is_within to decide if a path is within a given
authorCarl Hetherington <carl@carlh.net>
Mon, 28 May 2012 16:32:41 +0000 (16:32 +0000)
committerCarl Hetherington <carl@carlh.net>
Mon, 28 May 2012 16:32:41 +0000 (16:32 +0000)
directory, taking symlinks into account, and use it to
decide whether a file is within the session folder.  Should
fix #4552.

git-svn-id: svn://localhost/ardour2/branches/3.0@12468 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/utils.h
libs/ardour/file_source.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/utils.cc
libs/pbd/filesystem.cc
libs/pbd/pbd/filesystem.h
libs/pbd/wscript

index 7eba3fa18c010040ae72911c465d8a30c7e8b98d..5052f03bab8aee93d4794e8a045256bc158c63e6 100644 (file)
@@ -61,7 +61,6 @@ std::string path_expand (std::string);        /* single file path */
 std::string search_path_expand (std::string); /* colon-separated search path */
 std::string region_name_from_path (std::string path, bool strip_channels, bool add_channel_suffix = false, uint32_t total = 0, uint32_t this_one = 0);
 bool path_is_paired (std::string path, std::string& pair_base);
-bool inodes_same (const std::string &, const std::string &);
 
 void compute_equal_power_fades (ARDOUR::framecnt_t nframes, float* in, float* out);
 
index fd3e9ef142e071a25e0db60f55c7326c43800aa6..f4f3c40d9d6d6f76e64c93ef22b6ec942db2206f 100644 (file)
@@ -33,6 +33,7 @@
 #include "pbd/strsplit.h"
 #include "pbd/shortpath.h"
 #include "pbd/enumwriter.h"
+#include "pbd/filesystem.h"
 
 #include <glibmm/miscutils.h>
 #include <glibmm/fileutils.h>
@@ -277,7 +278,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
                        ++j;
                        
                        while (j != hits.end()) {
-                               if (inodes_same (*i, *j)) {
+                               if (PBD::sys::inodes_same (*i, *j)) {
                                        /* *i and *j are the same file; break out of the loop early */
                                        break;
                                }
index 37d4d2908f2a85b0c05ca99dca5f7a4e5df19b38..fdddb3b2c21a37b2f940ea4914484e5b0507de1f 100644 (file)
@@ -4478,7 +4478,7 @@ Session::ensure_search_path_includes (const string& path, DataType type)
                search_path = config.get_midi_search_path ();
                break;
        }
-       
+
        split (search_path, dirs, ':');
 
        for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
@@ -4488,7 +4488,7 @@ Session::ensure_search_path_includes (const string& path, DataType type)
 
                   On Windows, I think we could just do if (*i == path) here.
                */
-               if (inodes_same (*i, path)) {
+               if (PBD::sys::inodes_same (*i, path)) {
                        return;
                }
        }
index 4b40a80d80fc7ea2775f02d449e5e0c21147f191..e729a7b00d5f603138fcacfc5040043161739083 100644 (file)
@@ -428,7 +428,7 @@ bool
 Session::path_is_within_session (const std::string& path)
 {
        for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
-               if (path.find ((*i).path) == 0) {
+               if (PBD::sys::path_is_within (i->path, path)) {
                        return true;
                }
        }
index beb003e71377f05159b7b58fb682cbc3eff3d0c1..8ab20ecc6287dea60dafa80781abaf408538c053 100644 (file)
@@ -745,18 +745,6 @@ double slider_position_to_gain_with_max (double g, double max_gain)
        return slider_position_to_gain (g * max_gain/2.0);
 }
 
-/** @return true if files a and b have the same inode */
-bool
-inodes_same (const string& a, const string& b)
-{
-       struct stat bA;
-       int const rA = stat (a.c_str(), &bA);
-       struct stat bB;
-       int const rB = stat (b.c_str(), &bB);
-
-       return (rA == 0 && rB == 0 && bA.st_ino == bB.st_ino);
-}
-
 extern "C" {
        void c_stacktrace() { stacktrace (cerr); }
 }
index a4bf78180261428e5e5b5fd344394fbee17ee7fc..819a044a7bd6b233c14268519e48f1a71c8215f3 100644 (file)
@@ -254,6 +254,39 @@ get_absolute_path (const path & p)
        return f->get_path ();
 }
 
+/** @return true if a and b have the same inode */
+bool
+inodes_same (const path& a, const path& b)
+{
+       struct stat bA;
+       int const rA = stat (a.to_string().c_str(), &bA);
+       struct stat bB;
+       int const rB = stat (b.to_string().c_str(), &bB);
+
+       return (rA == 0 && rB == 0 && bA.st_ino == bB.st_ino);
+}
+
+/** Find out if `needle' is a file or directory within the
+ *  directory `haystack'.
+ *  @return true if it is.
+ */
+bool
+path_is_within (path const & haystack, path needle)
+{
+       while (1) {
+               if (inodes_same (haystack, needle)) {
+                       return true;
+               }
+
+               needle = needle.branch_path ();
+               if (needle.to_string().empty() || needle.to_string() == "/") {
+                       break;
+               }
+       }
+
+       return false;
+}
+
 } // namespace sys
 
 } // namespace PBD
index e8073adf0ed7ae59be8e6d2e317ab6648dc7b38d..1fb6fbc155a85ec7a3f21a8ed6debc29c0fc1d24 100644 (file)
@@ -205,6 +205,10 @@ std::string extension (const path& p);
 
 path get_absolute_path (const path &);
 
+bool path_is_within (const path &, path);      
+
+bool inodes_same (const path &, const path &);
+
 } // namespace sys
 
 } // namespace PBD
index 83a78f8ef03ac957b7d7fe8ae6646e2fee8faabf..da0f9c0dd104f8068dae62c57217eca88a90e778 100644 (file)
@@ -139,6 +139,7 @@ def build(bld):
                 test/scalar_properties.cc
                 test/signals_test.cc
                 test/convert_test.cc
+                test/filesystem_test.cc
         '''.split()
         testobj.target       = 'run-tests'
         testobj.includes     = obj.includes + ['test', '../pbd']