Document the new --specials option and how -D and --devices now work.
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index 61a6360..87a2ba7 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -69,10 +69,11 @@ extern struct filter_list_struct server_filter_list;
 
 int io_error;
 int checksum_len;
+dev_t filesystem_dev; /* used to implement -x */
+unsigned int file_struct_len;
 
 static char empty_sum[MD4_SUM_LENGTH];
 static int flist_count_offset;
-static unsigned int file_struct_len;
 
 static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
 static void output_flist(struct file_list *flist);
@@ -618,7 +619,6 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
        memset(bp, 0, file_struct_len);
        bp += file_struct_len;
 
-       file->flags = 0;
        file->modtime = modtime;
        file->length = file_length;
        file->mode = mode;
@@ -646,13 +646,14 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
                        in_del_hier = recurse;
                        del_hier_name_len = file->dir.depth == 0 ? 0 : l1 + l2;
                        if (relative_paths && del_hier_name_len > 2
-                           && basename_len == 1+1 && *basename == '.')
+                           && lastname[del_hier_name_len-1] == '.'
+                           && lastname[del_hier_name_len-2] == '/')
                                del_hier_name_len -= 2;
                        file->flags |= FLAG_TOP_DIR | FLAG_DEL_HERE;
                } else if (in_del_hier) {
                        if (!relative_paths || !del_hier_name_len
                         || (l1 >= del_hier_name_len
-                         && thisname[del_hier_name_len] == '/'))
+                         && lastname[del_hier_name_len] == '/'))
                                file->flags |= FLAG_DEL_HERE;
                        else
                                in_del_hier = 0;
@@ -807,24 +808,16 @@ struct file_struct *make_file(char *fname, struct file_list *flist,
        /* We only care about directories because we need to avoid recursing
         * into a mount-point directory, not to avoid copying a symlinked
         * file if -L (or similar) was specified. */
-       if (one_file_system && S_ISDIR(st.st_mode) && !(flags & FLAG_TOP_DIR)) {
-               STRUCT_STAT st2;
-               unsigned int len = strlcat(thisname, "/..", sizeof thisname);
-               /* If the directory's .. dir is on a different filesystem,
-                * either mark this dir as a mount-point or skip it. */
-               if (len < sizeof thisname && do_stat(thisname, &st2) == 0
-                && (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino)) {
-                       if (one_file_system > 1) {
-                               if (verbose > 2) {
-                                       rprintf(FINFO,
-                                           "skipping mount-point dir %s\n",
-                                           thisname);
-                               }
-                               return NULL;
+       if (one_file_system && st.st_dev != filesystem_dev
+        && S_ISDIR(st.st_mode)) {
+               if (one_file_system > 1) {
+                       if (verbose > 2) {
+                               rprintf(FINFO, "skipping mount-point dir %s\n",
+                                       thisname);
                        }
-                       flags |= FLAG_MOUNT_POINT;
+                       return NULL;
                }
-               thisname[len-3] = '\0';
+               flags |= FLAG_MOUNT_POINT;
        }
 
        if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level))
@@ -1281,6 +1274,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                        }
                }
 
+               if (one_file_system)
+                       filesystem_dev = st.st_dev;
+
                if (recurse || (xfer_dirs && is_dot_dir)) {
                        struct file_struct *file;
                        file = send_file_name(f, flist, fbuf, &st, FLAG_TOP_DIR);
@@ -1327,8 +1323,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
         * without causing a compatibility problem with older versions. */
        clean_flist(flist, 0, 0);
 
-       /* Now send the uid/gid list. This was introduced in
-        * protocol version 15 */
        send_uid_list(f);
 
        /* send the io_error flag */
@@ -1398,8 +1392,6 @@ struct file_list *recv_file_list(int f)
        clean_flist(flist, relative_paths, 1);
 
        if (f >= 0) {
-               /* Now send the uid/gid list. This was introduced in
-                * protocol version 15 */
                recv_uid_list(f, flist);
 
                /* Recv the io_error flag */