X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/057f649fc9048ba7851027001ce746ee079922d9..16edf86595a5a990a942fa045dfb523dae1fe6cb:/flist.c diff --git a/flist.c b/flist.c index 33b37b01..23def370 100644 --- a/flist.c +++ b/flist.c @@ -43,6 +43,7 @@ extern int one_file_system; extern int copy_dirlinks; extern int keep_dirlinks; extern int preserve_acls; +extern int preserve_xattrs; extern int preserve_links; extern int preserve_hard_links; extern int preserve_devices; @@ -85,9 +86,9 @@ static dev_t tmp_rdev; #ifdef SUPPORT_HARD_LINKS static int64 tmp_dev, tmp_ino; #endif -static char tmp_sum[MD4_SUM_LENGTH]; +static char tmp_sum[MAX_DIGEST_LEN]; -static char empty_sum[MD4_SUM_LENGTH]; +static char empty_sum[MAX_DIGEST_LEN]; static int flist_count_offset; /* for --delete --progress */ static void clean_flist(struct file_list *flist, int strip_root, int no_dups); @@ -99,7 +100,9 @@ void init_flist(void) rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n", (int)FILE_STRUCT_LEN, (int)EXTRA_LEN); } - checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH; + checksum_len = protocol_version < 21 ? 2 + : protocol_version < 30 ? MD4_DIGEST_LEN + : MD5_DIGEST_LEN; } static int show_filelist_p(void) @@ -335,8 +338,8 @@ int push_flist_dir(const char *dir, int len) if (dir && !push_dir(dir, 0)) { io_error |= IOERR_GENERAL; - rsyserr(FERROR, errno, "push_dir %s failed", - full_fname(dir)); + rsyserr(FERROR, errno, "push_dir %s failed in %s", + full_fname(dir), curr_dir); return 0; } @@ -383,8 +386,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx) flags |= XMIT_SAME_RDEV_MAJOR; else rdev_major = major(rdev); - if ((uint32)minor(rdev) <= 0xFFu) - flags |= XMIT_RDEV_MINOR_IS_SMALL; + if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu) + flags |= XMIT_RDEV_MINOR_8_pre30; } } else if (protocol_version < 28) rdev = MAKEDEV(0, 0); @@ -484,19 +487,27 @@ static void send_file_entry(int f, struct file_struct *file, int ndx) if (!(flags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); if (preserve_uid && !(flags & XMIT_SAME_UID)) { - write_abbrevint30(f, uid); - if (flags & XMIT_USER_NAME_FOLLOWS) { - int len = strlen(user_name); - write_byte(f, len); - write_buf(f, user_name, len); + if (protocol_version < 30) + write_int(f, uid); + else { + write_abbrevint(f, uid); + if (flags & XMIT_USER_NAME_FOLLOWS) { + int len = strlen(user_name); + write_byte(f, len); + write_buf(f, user_name, len); + } } } if (preserve_gid && !(flags & XMIT_SAME_GID)) { - write_abbrevint30(f, gid); - if (flags & XMIT_GROUP_NAME_FOLLOWS) { - int len = strlen(group_name); - write_byte(f, len); - write_buf(f, group_name, len); + if (protocol_version < 30) + write_int(f, gid); + else { + write_abbrevint(f, gid); + if (flags & XMIT_GROUP_NAME_FOLLOWS) { + int len = strlen(group_name); + write_byte(f, len); + write_buf(f, group_name, len); + } } } if ((preserve_devices && IS_DEVICE(mode)) @@ -506,8 +517,10 @@ static void send_file_entry(int f, struct file_struct *file, int ndx) write_int(f, (int)rdev); } else { if (!(flags & XMIT_SAME_RDEV_MAJOR)) - write_int(f, major(rdev)); - if (flags & XMIT_RDEV_MINOR_IS_SMALL) + write_abbrevint30(f, major(rdev)); + if (protocol_version >= 30) + write_abbrevint(f, minor(rdev)); + else if (flags & XMIT_RDEV_MINOR_8_pre30) write_byte(f, minor(rdev)); else write_int(f, minor(rdev)); @@ -662,18 +675,26 @@ static struct file_struct *recv_file_entry(struct file_list *flist, mode = tweak_mode(mode, chmod_modes); if (preserve_uid && !(flags & XMIT_SAME_UID)) { - uid = (uid_t)read_abbrevint30(f); - if (flags & XMIT_USER_NAME_FOLLOWS) - uid = recv_user_name(f, uid); - else if (inc_recurse && am_root && !numeric_ids) - uid = match_uid(uid); + if (protocol_version < 30) + uid = (uid_t)read_int(f); + else { + uid = (uid_t)read_abbrevint(f); + if (flags & XMIT_USER_NAME_FOLLOWS) + uid = recv_user_name(f, uid); + else if (inc_recurse && am_root && !numeric_ids) + uid = match_uid(uid); + } } if (preserve_gid && !(flags & XMIT_SAME_GID)) { - gid = (gid_t)read_abbrevint30(f); - if (flags & XMIT_GROUP_NAME_FOLLOWS) - gid = recv_group_name(f, gid); - else if (inc_recurse && (!am_root || !numeric_ids)) - gid = match_gid(gid); + if (protocol_version < 30) + gid = (gid_t)read_int(f); + else { + gid = (gid_t)read_abbrevint(f); + if (flags & XMIT_GROUP_NAME_FOLLOWS) + gid = recv_group_name(f, gid); + else if (inc_recurse && (!am_root || !numeric_ids)) + gid = match_gid(gid); + } } if ((preserve_devices && IS_DEVICE(mode)) @@ -684,8 +705,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } else { uint32 rdev_minor; if (!(flags & XMIT_SAME_RDEV_MAJOR)) - rdev_major = read_int(f); - if (flags & XMIT_RDEV_MINOR_IS_SMALL) + rdev_major = read_abbrevint30(f); + if (protocol_version >= 30) + rdev_minor = read_abbrevint(f); + else if (flags & XMIT_RDEV_MINOR_8_pre30) rdev_minor = read_byte(f); else rdev_minor = read_int(f); @@ -866,6 +889,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, if (preserve_acls && !S_ISLNK(mode)) receive_acl(file, f); #endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) + receive_xattr(file, f ); +#endif if (S_ISREG(mode) || S_ISLNK(mode)) stats.total_size += file_length; @@ -1138,7 +1165,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, int flags, int filter_flags) { struct file_struct *file; -#ifdef SUPPORT_ACLS +#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS statx sx; #endif @@ -1157,6 +1184,13 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, return NULL; } #endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs && f >= 0) { + sx.xattr = NULL; + if (get_xattr(fname, &sx) < 0) + return NULL; + } +#endif maybe_emit_filelist_progress(flist->count + flist_count_offset); @@ -1169,6 +1203,12 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, send_acl(&sx, f); free_acl(&sx); } +#endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) { + F_XATTR(file) = send_xattr(&sx, f); + free_xattr(&sx); + } #endif } return file; @@ -1314,7 +1354,7 @@ void send_extra_file_list(int f, int at_least) int64 start_write; int future_cnt, save_io_error = io_error; - if (send_dir_ndx < 0) + if (flist_eof) return; /* Keep sending data until we have the requested number of @@ -1417,8 +1457,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) disable_buffering = io_start_buffering_out(f); if (filesfrom_fd >= 0) { if (argv[0] && !push_dir(argv[0], 0)) { - rsyserr(FERROR, errno, "push_dir %s failed", - full_fname(argv[0])); + rsyserr(FERROR, errno, "push_dir %s failed in %s", + full_fname(argv[0]), curr_dir); exit_cleanup(RERR_FILESELECT); } use_ff_fd = 1; @@ -1469,18 +1509,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) && (len == 1 || fbuf[len-2] == '/'); } - if (link_stat(fbuf, &st, copy_dirlinks) != 0) { - io_error |= IOERR_GENERAL; - rsyserr(FERROR, errno, "link_stat %s failed", - full_fname(fbuf)); - continue; - } - - if (S_ISDIR(st.st_mode) && !xfer_dirs) { - rprintf(FINFO, "skipping directory %s\n", fbuf); - continue; - } - dir = NULL; if (!relative_paths) { @@ -1558,8 +1586,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) } else if (!push_flist_dir(lastdir, lastdir_len)) { push_error: io_error |= IOERR_GENERAL; - rsyserr(FERROR, errno, "push_dir %s failed", - full_fname(dir)); + rsyserr(FERROR, errno, "push_dir %s failed in %s", + full_fname(dir), curr_dir); continue; } } @@ -1567,6 +1595,18 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (fn != fbuf) memmove(fbuf, fn, len + 1); + if (link_stat(fbuf, &st, copy_dirlinks) != 0) { + io_error |= IOERR_GENERAL; + rsyserr(FERROR, errno, "link_stat %s failed", + full_fname(fbuf)); + continue; + } + + if (S_ISDIR(st.st_mode) && !xfer_dirs) { + rprintf(FINFO, "skipping directory %s\n", fbuf); + continue; + } + if (implied_dirs && (p=strrchr(fbuf,'/')) && p != fbuf) { /* Send the implied directories at the start of the * source spec, so we get their permissions right. */ @@ -1667,14 +1707,15 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (inc_recurse) { add_dirs_to_tree(-1, 0, dir_flist->count - 1); - if (file_total == 1) { + if (send_dir_ndx < 0) { + write_ndx(f, NDX_FLIST_EOF); + flist_eof = 1; + } + else if (file_total == 1) { /* If we're creating incremental file-lists and there * was just 1 item in the first file-list, send 1 more * file-list to check if this is a 1-file xfer. */ - if (send_dir_ndx < 0) - write_ndx(f, NDX_DONE); - else - send_extra_file_list(f, 1); + send_extra_file_list(f, 1); } } @@ -1783,7 +1824,7 @@ void recv_additional_file_list(int f) { struct file_list *flist; int ndx = read_ndx(f); - if (ndx == NDX_DONE) { + if (ndx == NDX_FLIST_EOF) { flist_eof = 1; change_local_filter_dir(NULL, 0, 0); } else {