when using -x to stop at filesystem boundaries, include the mount
authorAndrew Tridgell <tridge@samba.org>
Thu, 26 Mar 1998 00:11:50 +0000 (00:11 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 26 Mar 1998 00:11:50 +0000 (00:11 +0000)
points but not their contents.

I did this by calling stat() on the directory above the current
directory and checking to see if it has the correct st_dev. Hopefully
this will work for most systems.

Note that the permissions and ownership on the mount point cannot be
copied correctly as they are unavailable while the filesystem is
mounted. Instead rsync will set the permissions and ownership to those
of the root directory of the mounted filesystem (ie. the apparent
permissions/ownership of the directory)

flist.c

diff --git a/flist.c b/flist.c
index 0aa1eea..e67d4b2 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -316,6 +316,29 @@ void receive_file_entry(struct file_struct **fptr,
 }
 
 
+/* determine if a file in a different filesstem should be skipped
+   when one_file_system is set. We bascally only want to include
+   the mount points - but they can be hard to find! */
+static int skip_filesystem(char *fname, struct stat *st)
+{
+       struct stat st2;
+       char *p = strrchr(fname, '/');
+
+       /* skip all but directories */
+       if (!S_ISDIR(st->st_mode)) return 1;
+
+       /* if its not a subdirectory then allow */
+       if (!p) return 0;
+
+       *p = 0;
+       if (link_stat(fname, &st2)) {
+               *p = '/';
+               return 0;
+       }
+       *p = '/';
+       
+       return (st2.st_dev != filesystem_dev);
+}
 
 static struct file_struct *make_file(char *fname)
 {
@@ -343,8 +366,10 @@ static struct file_struct *make_file(char *fname)
                return NULL;
        }
        
-       if (one_file_system && st.st_dev != filesystem_dev)
-               return NULL;
+       if (one_file_system && st.st_dev != filesystem_dev) {
+               if (skip_filesystem(fname, &st))
+                       return NULL;
+       }
        
        if (!match_file_name(fname,&st))
                return NULL;