X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ebec5eb689e9b01509b6507d23478548cbc117e8..5e58e3f9cf3db5c3958fe6505eb59a2f814887fb:/flist.c diff --git a/flist.c b/flist.c index 61a6360d..277750c0 100644 --- 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); @@ -361,14 +362,14 @@ static void send_file_entry(struct file_struct *file, int f) flags |= XMIT_RDEV_MINOR_IS_SMALL; } } - if (file->uid == uid) + if (file->ids->uid == uid) flags |= XMIT_SAME_UID; else - uid = file->uid; - if (file->gid == gid) + uid = file->ids->uid; + if (file->ids->gid == gid) flags |= XMIT_SAME_GID; else - gid = file->gid; + gid = file->ids->gid; if (file->modtime == modtime) flags |= XMIT_SAME_TIME; else @@ -618,12 +619,10 @@ 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; - file->uid = uid; - file->gid = gid; + file->ids = id_pair(uid, gid); if (dirname_len) { file->dirname = lastdir = bp; @@ -646,13 +645,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 +807,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)) @@ -886,8 +878,7 @@ struct file_struct *make_file(char *fname, struct file_list *flist, file->modtime = st.st_mtime; file->length = st.st_size; file->mode = st.st_mode; - file->uid = st.st_uid; - file->gid = st.st_gid; + file->ids = id_pair(st.st_uid, st.st_gid); #ifdef SUPPORT_HARD_LINKS if (flist && flist->hlink_pool) { @@ -954,8 +945,7 @@ struct file_struct *make_file(char *fname, struct file_list *flist, file->modtime = st2.st_mtime; file->length = st2.st_size; file->mode = st2.st_mode; - file->uid = st2.st_uid; - file->gid = st2.st_gid; + file->ids = id_pair(st2.st_uid, st2.st_gid); file->u.link = NULL; } else file->mode = save_mode; @@ -1281,6 +1271,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 +1320,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,9 +1389,7 @@ 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_uid_list(f); /* Recv the io_error flag */ if (lp_ignore_errors(module_id) || ignore_errors) @@ -1627,11 +1616,11 @@ static void output_flist(struct file_list *flist) for (i = 0; i < flist->count; i++) { file = flist->files[i]; if ((am_root || am_sender) && preserve_uid) - sprintf(uidbuf, " uid=%ld", (long)file->uid); + sprintf(uidbuf, " uid=%ld", (long)file->ids->uid); else *uidbuf = '\0'; - if (preserve_gid && file->gid != GID_NONE) - sprintf(gidbuf, " gid=%ld", (long)file->gid); + if (preserve_gid && file->ids->gid != GID_NONE) + sprintf(gidbuf, " gid=%ld", (long)file->ids->gid); else *gidbuf = '\0'; if (!am_sender)