X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ce827c3e50cd168027a555ec961b6636e5b63e59..1b502f3ec234bf1045c6bb146f64734d09e81956:/flist.c diff --git a/flist.c b/flist.c index 6eb02c7b..a167c3b9 100644 --- a/flist.c +++ b/flist.c @@ -87,6 +87,14 @@ extern int filesfrom_convert; extern iconv_t ic_send, ic_recv; #endif +#ifdef HAVE_UTIMENSAT +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC +#define ST_MTIME_NSEC st_mtim.tv_nsec +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) +#define ST_MTIME_NSEC st_mtimensec +#endif +#endif + #define PTR_SIZE (sizeof (struct file_struct *)) int io_error; @@ -196,7 +204,7 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf) if (link_stat(path, stp, copy_dirlinks) < 0) return -1; if (S_ISLNK(stp->st_mode)) { - int llen = readlink(path, linkbuf, MAXPATHLEN - 1); + int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1); if (llen < 0) return -1; linkbuf[llen] = '\0'; @@ -495,6 +503,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, xflags |= XMIT_SAME_TIME; else modtime = file->modtime; + if (NSEC_BUMP(file) && protocol_version >= 31) + xflags |= XMIT_MOD_NSEC; #ifdef SUPPORT_HARD_LINKS if (tmp_dev != 0) { @@ -577,6 +587,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, else write_int(f, modtime); } + if (xflags & XMIT_MOD_NSEC) + write_varint(f, F_MOD_NSEC(file)); if (!(xflags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); if (preserve_uid && !(xflags & XMIT_SAME_UID)) { @@ -662,8 +674,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, stats.total_size += F_LENGTH(file); } -static struct file_struct *recv_file_entry(struct file_list *flist, - int xflags, int f) +static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags) { static int64 modtime; static mode_t mode; @@ -685,6 +696,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, int extra_len = file_extra_cnt * EXTRA_LEN; int first_hlink_ndx = -1; int64 file_length; + uint32 modtime_nsec; const char *basename; struct file_struct *file; alloc_pool_t *pool; @@ -768,6 +780,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start]; file_length = F_LENGTH(first); modtime = first->modtime; + modtime_nsec = F_MOD_NSEC(first); mode = first->mode; if (preserve_uid) uid = F_OWNER(first); @@ -801,6 +814,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } else modtime = read_int(f); } + if (xflags & XMIT_MOD_NSEC) + modtime_nsec = read_varint(f); + else + modtime_nsec = 0; if (!(xflags & XMIT_SAME_MODE)) mode = from_wire_mode(read_int(f)); @@ -898,6 +915,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, #if SIZEOF_INT64 >= 8 if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) extra_len += EXTRA_LEN; +#endif +#ifdef HAVE_UTIMENSAT + if (modtime_nsec) + extra_len += EXTRA_LEN; #endif if (file_length < 0) { rprintf(FERROR, "Offset underflow: file-length is negative\n"); @@ -934,6 +955,12 @@ static struct file_struct *recv_file_entry(struct file_list *flist, file->flags |= FLAG_HLINKED; #endif file->modtime = (time_t)modtime; +#ifdef HAVE_UTIMENSAT + if (modtime_nsec) { + file->flags |= FLAG_MOD_NSEC; + OPT_EXTRA(file, 0)->unum = modtime_nsec; + } +#endif file->len32 = (uint32)file_length; #if SIZEOF_INT64 >= 8 if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) { @@ -942,7 +969,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, exit_cleanup(RERR_UNSUPPORTED); #else file->flags |= FLAG_LENGTH64; - OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32); + OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(file_length >> 32); #endif } #endif @@ -1088,11 +1115,11 @@ static struct file_struct *recv_file_entry(struct file_list *flist, #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(mode)) - receive_acl(file, f); + receive_acl(f, file); #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) - receive_xattr(file, f ); + receive_xattr(f, file); #endif if (S_ISREG(mode) || S_ISLNK(mode)) @@ -1272,6 +1299,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, linkname_len = 0; #endif +#ifdef ST_MTIME_NSEC + if (st.ST_MTIME_NSEC && protocol_version >= 31) + extra_len += EXTRA_LEN; +#endif #if SIZEOF_CAPITAL_OFF_T >= 8 if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) extra_len += EXTRA_LEN; @@ -1326,11 +1357,17 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, file->flags = flags; file->modtime = st.st_mtime; +#ifdef ST_MTIME_NSEC + if (st.ST_MTIME_NSEC && protocol_version >= 31) { + file->flags |= FLAG_MOD_NSEC; + OPT_EXTRA(file, 0)->unum = st.ST_MTIME_NSEC; + } +#endif file->len32 = (uint32)st.st_size; #if SIZEOF_CAPITAL_OFF_T >= 8 if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) { file->flags |= FLAG_LENGTH64; - OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32); + OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(st.st_size >> 32); } #endif file->mode = st.st_mode; @@ -1493,13 +1530,13 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { - send_acl(&sx, f); + send_acl(f, &sx); free_acl(&sx); } #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) { - F_XATTR(file) = send_xattr(&sx, f); + F_XATTR(file) = send_xattr(f, &sx); free_xattr(&sx); } #endif @@ -2403,7 +2440,7 @@ struct file_list *recv_file_list(int f) } flist_expand(flist, 1); - file = recv_file_entry(flist, flags, f); + file = recv_file_entry(f, flist, flags); if (S_ISREG(file->mode)) { /* Already counted */