The patches for 3.0.0pre6.
[rsync/rsync-patches.git] / atimes.diff
index 00b933a..353a9e3 100644 (file)
@@ -7,26 +7,27 @@ To use this patch, run these commands for a successful build:
 
 TODO:  need to fix this to handle 64-bit time_t values!
 
 
 TODO:  need to fix this to handle 64-bit time_t values!
 
---- old/compat.c
-+++ new/compat.c
-@@ -44,6 +44,7 @@ extern int prune_empty_dirs;
- extern int protocol_version;
+diff --git a/compat.c b/compat.c
+--- a/compat.c
++++ b/compat.c
+@@ -44,6 +44,7 @@ extern int protocol_version;
+ extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
 +extern int preserve_atimes;
  extern int preserve_acls;
  extern int preserve_xattrs;
  extern int preserve_uid;
  extern int preserve_gid;
 +extern int preserve_atimes;
  extern int preserve_acls;
  extern int preserve_xattrs;
- extern int preserve_hard_links;
-@@ -58,7 +59,7 @@ extern char *dest_option;
- extern struct filter_list_struct filter_list;
+ extern int need_messages_from_generator;
+@@ -60,7 +61,7 @@ extern iconv_t ic_send, ic_recv;
+ #endif
  
  /* These index values are for the file-list's extra-attribute array. */
  
  /* These index values are for the file-list's extra-attribute array. */
--int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx;
-+int uid_ndx, gid_ndx, atimes_ndx, acls_ndx, xattrs_ndx;
+-int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
++int uid_ndx, gid_ndx, atimes_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
  
  
- /* The server makes sure that if either side only supports a pre-release
-  * version of a protocol, that both sides must speak a compatible version
-@@ -99,6 +100,8 @@ void setup_protocol(int f_out,int f_in)
+ #ifdef ICONV_OPTION
+ int filesfrom_convert = 0;
+@@ -124,6 +125,8 @@ void setup_protocol(int f_out,int f_in)
                uid_ndx = ++file_extra_cnt;
        if (preserve_gid)
                gid_ndx = ++file_extra_cnt;
                uid_ndx = ++file_extra_cnt;
        if (preserve_gid)
                gid_ndx = ++file_extra_cnt;
@@ -35,52 +36,26 @@ TODO:  need to fix this to handle 64-bit time_t values!
        if (preserve_acls && !am_sender)
                acls_ndx = ++file_extra_cnt;
        if (preserve_xattrs)
        if (preserve_acls && !am_sender)
                acls_ndx = ++file_extra_cnt;
        if (preserve_xattrs)
---- old/flist.c
-+++ new/flist.c
-@@ -52,6 +52,7 @@ extern int preserve_devices;
- extern int preserve_specials;
+diff --git a/flist.c b/flist.c
+--- a/flist.c
++++ b/flist.c
+@@ -53,6 +53,7 @@ extern int preserve_specials;
  extern int uid_ndx;
  extern int gid_ndx;
  extern int uid_ndx;
  extern int gid_ndx;
+ extern int eol_nulls;
 +extern int atimes_ndx;
  extern int relative_paths;
  extern int implied_dirs;
  extern int file_extra_cnt;
 +extern int atimes_ndx;
  extern int relative_paths;
  extern int implied_dirs;
  extern int file_extra_cnt;
-@@ -158,6 +159,7 @@ void show_flist_stats(void)
- static void list_file_entry(struct file_struct *f)
- {
-       char permbuf[PERMSTRING_SIZE];
-+      time_t atime = atimes_ndx ? F_ATIME(f) : 0;
-       double len;
-       if (!F_IS_ACTIVE(f)) {
-@@ -172,14 +174,16 @@ static void list_file_entry(struct file_
- #ifdef SUPPORT_LINKS
-       if (preserve_links && S_ISLNK(f->mode)) {
--              rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-+              rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
-                       permbuf, len, timestring(f->modtime),
-+                      atimes_ndx ? timestring(atime) : "",
-                       f_name(f, NULL), F_SYMLINK(f));
-       } else
- #endif
-       {
--              rprintf(FINFO, "%s %11.0f %s %s\n",
-+              rprintf(FINFO, "%s %11.0f %s %s %s\n",
-                       permbuf, len, timestring(f->modtime),
-+                      atimes_ndx ? timestring(atime) : "",
-                       f_name(f, NULL));
-       }
- }
-@@ -347,6 +351,7 @@ int push_pathname(const char *dir, int l
- static void send_file_entry(int f, struct file_struct *file, int ndx)
+@@ -344,6 +345,7 @@ int push_pathname(const char *dir, int len)
+ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ndx)
  {
        static time_t modtime;
 +      static time_t atime;
        static mode_t mode;
  {
        static time_t modtime;
 +      static time_t atime;
        static mode_t mode;
+ #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
        static int64 dev;
-       static dev_t rdev;
-@@ -446,6 +451,13 @@ static void send_file_entry(int f, struc
+@@ -450,6 +452,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
                xflags |= XMIT_SAME_TIME;
        else
                modtime = file->modtime;
                xflags |= XMIT_SAME_TIME;
        else
                modtime = file->modtime;
@@ -94,7 +69,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  
  #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != 0) {
  
  #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != 0) {
-@@ -517,6 +529,8 @@ static void send_file_entry(int f, struc
+@@ -523,6 +532,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
        }
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
        }
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
@@ -103,16 +78,16 @@ TODO:  need to fix this to handle 64-bit time_t values!
        if (uid_ndx && !(xflags & XMIT_SAME_UID)) {
                if (protocol_version < 30)
                        write_int(f, uid);
        if (uid_ndx && !(xflags & XMIT_SAME_UID)) {
                if (protocol_version < 30)
                        write_int(f, uid);
-@@ -603,7 +617,7 @@ static void send_file_entry(int f, struc
+@@ -609,7 +620,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
  static struct file_struct *recv_file_entry(struct file_list *flist,
                                           int xflags, int f)
  {
 -      static int64 modtime;
 +      static int64 modtime, atime;
        static mode_t mode;
  static struct file_struct *recv_file_entry(struct file_list *flist,
                                           int xflags, int f)
  {
 -      static int64 modtime;
 +      static int64 modtime, atime;
        static mode_t mode;
+ #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
        static int64 dev;
-       static dev_t rdev;
-@@ -739,6 +753,16 @@ static struct file_struct *recv_file_ent
+@@ -742,6 +753,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
        }
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
        }
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
@@ -120,7 +95,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
 +              atime = read_varlong(f, 4);
 +#if SIZEOF_TIME_T < SIZEOF_INT64
 +              if ((atime > INT_MAX || atime < INT_MIN) && !am_generator) {
 +              atime = read_varlong(f, 4);
 +#if SIZEOF_TIME_T < SIZEOF_INT64
 +              if ((atime > INT_MAX || atime < INT_MIN) && !am_generator) {
-+                      rprintf(FERROR,
++                      rprintf(FERROR_XFER,
 +                              "Access time value of %s truncated on receiver.\n",
 +                              lastname);
 +              }
 +                              "Access time value of %s truncated on receiver.\n",
 +                              lastname);
 +              }
@@ -129,54 +104,82 @@ TODO:  need to fix this to handle 64-bit time_t values!
  
        if (chmod_modes && !S_ISLNK(mode))
                mode = tweak_mode(mode, chmod_modes);
  
        if (chmod_modes && !S_ISLNK(mode))
                mode = tweak_mode(mode, chmod_modes);
-@@ -867,6 +891,8 @@ static struct file_struct *recv_file_ent
+@@ -872,6 +893,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
 +      if (atimes_ndx)
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
 +      if (atimes_ndx)
-+              F_ATIME(file) = (time_t)atime;
- #ifdef ICONV_OPTION
-       if (ic_ndx)
++              F_ATIME(file) = (uint32)atime;
+       if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
                F_NDX(file) = flist->used + flist->ndx_start;
-@@ -1191,6 +1217,8 @@ struct file_struct *make_file(const char
+@@ -1200,6 +1223,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                F_OWNER(file) = st.st_uid;
        if (gid_ndx)
                F_GROUP(file) = st.st_gid;
 +      if (atimes_ndx)
                F_OWNER(file) = st.st_uid;
        if (gid_ndx)
                F_GROUP(file) = st.st_gid;
 +      if (atimes_ndx)
-+              F_ATIME(file) = st.st_atime;
++              F_ATIME(file) = (uint32)st.st_atime;
  
        if (basename != thisname)
                file->dirname = lastdir;
  
        if (basename != thisname)
                file->dirname = lastdir;
---- old/generator.c
-+++ new/generator.c
+diff --git a/generator.c b/generator.c
+--- a/generator.c
++++ b/generator.c
 @@ -43,6 +43,7 @@ extern int preserve_specials;
  extern int preserve_hard_links;
  extern int preserve_perms;
  extern int preserve_times;
 +extern int preserve_atimes;
 @@ -43,6 +43,7 @@ extern int preserve_specials;
  extern int preserve_hard_links;
  extern int preserve_perms;
  extern int preserve_times;
 +extern int preserve_atimes;
- extern int omit_dir_times;
  extern int uid_ndx;
  extern int gid_ndx;
  extern int uid_ndx;
  extern int gid_ndx;
-@@ -564,6 +565,9 @@ void itemize(const char *fnamecmp, struc
+ extern int delete_mode;
+@@ -568,6 +569,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
                 || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
                        iflags |= ITEM_REPORT_TIME;
 +              if (preserve_atimes && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
 +               && cmp_time(F_ATIME(file), sxp->st.st_atime) != 0)
 +                      iflags |= ITEM_REPORT_ATIME;
                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
                 || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
                        iflags |= ITEM_REPORT_TIME;
 +              if (preserve_atimes && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
 +               && cmp_time(F_ATIME(file), sxp->st.st_atime) != 0)
 +                      iflags |= ITEM_REPORT_ATIME;
-               if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
-                       iflags |= ITEM_REPORT_PERMS;
-               if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
-@@ -881,6 +885,8 @@ static int try_dests_reg(struct file_str
+ #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
+               if (S_ISLNK(file->mode)) {
+                       ;
+@@ -923,6 +927,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                if (link_dest) {
                        if (!hard_link_one(file, fname, cmpbuf, 1))
                                goto try_a_copy;
 +                      if (preserve_atimes)
 +                              set_file_attrs(fname, file, sxp, NULL, 0);
                        if (preserve_hard_links && F_IS_HLINKED(file))
                if (link_dest) {
                        if (!hard_link_one(file, fname, cmpbuf, 1))
                                goto try_a_copy;
 +                      if (preserve_atimes)
 +                              set_file_attrs(fname, file, sxp, NULL, 0);
                        if (preserve_hard_links && F_IS_HLINKED(file))
-                               finish_hard_link(file, fname, &sxp->st, itemizing, code, j);
+                               finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
                        if (itemizing && (verbose > 1 || stdout_format_has_i > 1)) {
                        if (itemizing && (verbose > 1 || stdout_format_has_i > 1)) {
-@@ -1775,7 +1781,7 @@ static void touch_up_dirs(struct file_li
+@@ -1113,6 +1119,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+ static void list_file_entry(struct file_struct *f)
+ {
+       char permbuf[PERMSTRING_SIZE];
++      time_t atime = atimes_ndx ? F_ATIME(f) : 0;
+       double len;
+       if (!F_IS_ACTIVE(f)) {
+@@ -1127,14 +1134,16 @@ static void list_file_entry(struct file_struct *f)
+ #ifdef SUPPORT_LINKS
+       if (preserve_links && S_ISLNK(f->mode)) {
+-              rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
++              rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
+                       permbuf, len, timestring(f->modtime),
++                      atimes_ndx ? timestring(atime) : "",
+                       f_name(f, NULL), F_SYMLINK(f));
+       } else
+ #endif
+       {
+-              rprintf(FINFO, "%s %11.0f %s %s\n",
++              rprintf(FINFO, "%s %11.0f %s %s %s\n",
+                       permbuf, len, timestring(f->modtime),
++                      atimes_ndx ? timestring(atime) : "",
+                       f_name(f, NULL));
+       }
+ }
+@@ -1884,7 +1893,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                if (!(file->mode & S_IWUSR))
                        do_chmod(fname, file->mode);
                if (need_retouch_dir_times)
                if (!(file->mode & S_IWUSR))
                        do_chmod(fname, file->mode);
                if (need_retouch_dir_times)
@@ -185,9 +188,10 @@ TODO:  need to fix this to handle 64-bit time_t values!
                if (allowed_lull && !(counter % lull_mod))
                        maybe_send_keepalive();
                else if (!(counter & 0xFF))
                if (allowed_lull && !(counter % lull_mod))
                        maybe_send_keepalive();
                else if (!(counter & 0xFF))
---- old/log.c
-+++ new/log.c
-@@ -631,7 +631,8 @@ static void log_formatted(enum logcode c
+diff --git a/log.c b/log.c
+--- a/log.c
++++ b/log.c
+@@ -642,7 +642,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
                        c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
                        c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
                        c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
                        c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
@@ -197,17 +201,18 @@ TODO:  need to fix this to handle 64-bit time_t values!
                        c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
                        c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
                        c[11] = '\0';
                        c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
                        c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
                        c[11] = '\0';
---- old/options.c
-+++ new/options.c
-@@ -57,6 +57,7 @@ int preserve_uid = 0;
+diff --git a/options.c b/options.c
+--- a/options.c
++++ b/options.c
+@@ -57,6 +57,7 @@ int preserve_specials = 0;
+ int preserve_uid = 0;
  int preserve_gid = 0;
  int preserve_times = 0;
  int preserve_gid = 0;
  int preserve_times = 0;
- int omit_dir_times = 0;
 +int preserve_atimes = 0;
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
 +int preserve_atimes = 0;
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -338,6 +339,7 @@ void usage(enum logcode F)
+@@ -347,6 +348,7 @@ void usage(enum logcode F)
    rprintf(F," -D                          same as --devices --specials\n");
    rprintf(F," -t, --times                 preserve modification times\n");
    rprintf(F," -O, --omit-dir-times        omit directories from --times\n");
    rprintf(F," -D                          same as --devices --specials\n");
    rprintf(F," -t, --times                 preserve modification times\n");
    rprintf(F," -O, --omit-dir-times        omit directories from --times\n");
@@ -215,17 +220,17 @@ TODO:  need to fix this to handle 64-bit time_t values!
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
  #ifdef SUPPORT_XATTRS
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
  #ifdef SUPPORT_XATTRS
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
-@@ -473,6 +475,9 @@ static struct poptOption long_options[] 
-   {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
+@@ -482,6 +484,9 @@ static struct poptOption long_options[] = {
+   {"times",           't', POPT_ARG_VAL,    &preserve_times, 2, 0, 0 },
    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
 +  {"atimes",          'U', POPT_ARG_VAL,    &preserve_atimes, 1, 0, 0 },
 +  {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
 +  {"no-U",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
 +  {"atimes",          'U', POPT_ARG_VAL,    &preserve_atimes, 1, 0, 0 },
 +  {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
 +  {"no-U",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
-   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
-   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
-   {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
-@@ -1675,6 +1680,8 @@ void server_options(char **args,int *arg
+   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 1, 0, 0 },
+   {"no-omit-dir-times",0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 },
+   {"no-O",             0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 },
+@@ -1716,6 +1721,8 @@ void server_options(char **args, int *argc_p)
                argstr[x++] = 'D';
        if (preserve_times)
                argstr[x++] = 't';
                argstr[x++] = 'D';
        if (preserve_times)
                argstr[x++] = 't';
@@ -234,31 +239,32 @@ TODO:  need to fix this to handle 64-bit time_t values!
        if (preserve_perms)
                argstr[x++] = 'p';
        else if (preserve_executability && am_sender)
        if (preserve_perms)
                argstr[x++] = 'p';
        else if (preserve_executability && am_sender)
---- old/rsync.c
-+++ new/rsync.c
-@@ -32,6 +32,7 @@ extern int preserve_acls;
+diff --git a/rsync.c b/rsync.c
+--- a/rsync.c
++++ b/rsync.c
+@@ -33,6 +33,7 @@ extern int preserve_acls;
  extern int preserve_xattrs;
  extern int preserve_perms;
  extern int preserve_executability;
 +extern int preserve_atimes;
  extern int preserve_times;
  extern int preserve_xattrs;
  extern int preserve_perms;
  extern int preserve_executability;
 +extern int preserve_atimes;
  extern int preserve_times;
- extern int omit_dir_times;
  extern int am_root;
  extern int am_root;
-@@ -274,6 +275,7 @@ int set_file_attrs(const char *fname, st
+ extern int am_server;
+@@ -343,6 +344,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
        int updated = 0;
        int updated = 0;
-       statx sx2;
+       stat_x sx2;
        int change_uid, change_gid;
 +      time_t atime, mtime;
        mode_t new_mode = file->mode;
        int change_uid, change_gid;
 +      time_t atime, mtime;
        mode_t new_mode = file->mode;
+       int inherit;
  
  
-       if (!sxp) {
-@@ -311,18 +313,36 @@ int set_file_attrs(const char *fname, st
-               set_stat_xattr(fname, file);
+@@ -386,18 +388,36 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+               set_xattr(fname, file, fnamecmp, sxp);
  #endif
  
 +      /* This code must be the first update in the function due to
 +       * how it uses the "updated" variable. */
  #endif
  
 +      /* This code must be the first update in the function due to
 +       * how it uses the "updated" variable. */
-       if (!preserve_times || (S_ISDIR(sxp->st.st_mode) && omit_dir_times))
+       if (!preserve_times || (S_ISDIR(sxp->st.st_mode) && preserve_times == 1))
                flags |= ATTRS_SKIP_MTIME;
 +      if (!preserve_atimes || S_ISDIR(sxp->st.st_mode))
 +              flags |= ATTRS_SKIP_ATIME;
                flags |= ATTRS_SKIP_MTIME;
 +      if (!preserve_atimes || S_ISDIR(sxp->st.st_mode))
 +              flags |= ATTRS_SKIP_ATIME;
@@ -281,7 +287,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
 +      if (updated) {
 +              int ret = set_times(fname, mtime, atime, sxp->st.st_mode);
                if (ret < 0) {
 +      if (updated) {
 +              int ret = set_times(fname, mtime, atime, sxp->st.st_mode);
                if (ret < 0) {
-                       rsyserr(FERROR, errno, "failed to set times on %s",
+                       rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
                        goto cleanup;
                }
                                full_fname(fname));
                        goto cleanup;
                }
@@ -292,17 +298,18 @@ TODO:  need to fix this to handle 64-bit time_t values!
        }
  
        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
        }
  
        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
---- old/rsync.h
-+++ new/rsync.h
-@@ -57,6 +57,7 @@
+diff --git a/rsync.h b/rsync.h
+--- a/rsync.h
++++ b/rsync.h
+@@ -60,6 +60,7 @@
  #define XMIT_RDEV_MINOR_8_pre30 (1<<11)       /* protocols 28 - 29  */
  #define XMIT_RDEV_MINOR_8_pre30 (1<<11)       /* protocols 28 - 29  */
- #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - NOW */
- #define XMIT_HLINK_FIRST (1<<12)      /* protocols 30 - NOW (HLINKED files only) */
-+#define XMIT_SAME_ATIME (1<<13)               /* protocols ?? - NOW */
+ #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
+ #define XMIT_HLINK_FIRST (1<<12)      /* protocols 30 - now (HLINKED files only) */
++#define XMIT_SAME_ATIME (1<<13)               /* protocols ?? - now */
  
  /* These flags are used in the live flist data. */
  
  
  /* These flags are used in the live flist data. */
  
-@@ -144,6 +145,7 @@
+@@ -148,6 +149,7 @@
  
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
  
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
@@ -310,25 +317,26 @@ TODO:  need to fix this to handle 64-bit time_t values!
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -583,6 +585,7 @@ struct file_struct {
- extern int file_extra_cnt;
+@@ -618,6 +620,7 @@ extern int file_extra_cnt;
+ extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
 +extern int atimes_ndx;
  extern int acls_ndx;
  extern int xattrs_ndx;
  
  extern int uid_ndx;
  extern int gid_ndx;
 +extern int atimes_ndx;
  extern int acls_ndx;
  extern int xattrs_ndx;
  
-@@ -620,6 +623,7 @@ extern int xattrs_ndx;
+@@ -655,6 +658,7 @@ extern int xattrs_ndx;
  /* When the associated option is on, all entries will have these present: */
  #define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum
  #define F_GROUP(f) REQ_EXTRA(f, gid_ndx)->unum
 +#define F_ATIME(f) REQ_EXTRA(f, atimes_ndx)->unum
  #define F_ACL(f) REQ_EXTRA(f, acls_ndx)->num
  #define F_XATTR(f) REQ_EXTRA(f, xattrs_ndx)->num
  /* When the associated option is on, all entries will have these present: */
  #define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum
  #define F_GROUP(f) REQ_EXTRA(f, gid_ndx)->unum
 +#define F_ATIME(f) REQ_EXTRA(f, atimes_ndx)->unum
  #define F_ACL(f) REQ_EXTRA(f, acls_ndx)->num
  #define F_XATTR(f) REQ_EXTRA(f, xattrs_ndx)->num
- #define F_NDX(f) REQ_EXTRA(f, ic_ndx)->num
---- old/rsync.yo
-+++ new/rsync.yo
-@@ -353,6 +353,7 @@ to the detailed description below for a 
+ #define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
+diff --git a/rsync.yo b/rsync.yo
+--- a/rsync.yo
++++ b/rsync.yo
+@@ -349,6 +349,7 @@ to the detailed description below for a complete description.  verb(
   -D                          same as --devices --specials
   -t, --times                 preserve modification times
   -O, --omit-dir-times        omit directories from --times
   -D                          same as --devices --specials
   -t, --times                 preserve modification times
   -O, --omit-dir-times        omit directories from --times
@@ -336,7 +344,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
       --super                 receiver attempts super-user activities
       --fake-super            store/recover privileged attrs using xattrs
   -S, --sparse                handle sparse files efficiently
       --super                 receiver attempts super-user activities
       --fake-super            store/recover privileged attrs using xattrs
   -S, --sparse                handle sparse files efficiently
-@@ -930,6 +931,12 @@ it is preserving modification times (see
+@@ -974,6 +975,12 @@ it is preserving modification times (see bf(--times)).  If NFS is sharing
  the directories on the receiving side, it is a good idea to use bf(-O).
  This option is inferred if you use bf(--backup) without bf(--backup-dir).
  
  the directories on the receiving side, it is a good idea to use bf(-O).
  This option is inferred if you use bf(--backup) without bf(--backup-dir).
  
@@ -349,7 +357,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  dit(bf(--super)) This tells the receiving side to attempt super-user
  activities even if the receiving rsync wasn't run by the super-user.  These
  activities include: preserving users via the bf(--owner) option, preserving
  dit(bf(--super)) This tells the receiving side to attempt super-user
  activities even if the receiving rsync wasn't run by the super-user.  These
  activities include: preserving users via the bf(--owner) option, preserving
-@@ -1592,8 +1599,10 @@ quote(itemization(
+@@ -1671,8 +1678,10 @@ quote(itemization(
    sender's value (requires bf(--owner) and super-user privileges).
    it() A bf(g) means the group is different and is being updated to the
    sender's value (requires bf(--group) and the authority to set the group).
    sender's value (requires bf(--owner) and super-user privileges).
    it() A bf(g) means the group is different and is being updated to the
    sender's value (requires bf(--group) and the authority to set the group).
@@ -362,8 +370,9 @@ TODO:  need to fix this to handle 64-bit time_t values!
    it() The bf(a) means that the ACL information changed.
    it() The bf(x) slot is reserved for reporting extended attribute changes
    (a feature that is not yet released).
    it() The bf(a) means that the ACL information changed.
    it() The bf(x) slot is reserved for reporting extended attribute changes
    (a feature that is not yet released).
---- old/sender.c
-+++ new/sender.c
+diff --git a/sender.c b/sender.c
+--- a/sender.c
++++ b/sender.c
 @@ -43,6 +43,7 @@ extern int do_progress;
  extern int inplace;
  extern int batch_fd;
 @@ -43,6 +43,7 @@ extern int do_progress;
  extern int inplace;
  extern int batch_fd;
@@ -372,8 +381,10 @@ TODO:  need to fix this to handle 64-bit time_t values!
  extern struct stats stats;
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  
  extern struct stats stats;
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  
---- old/testsuite/atimes.test
-+++ new/testsuite/atimes.test
+diff --git a/testsuite/atimes.test b/testsuite/atimes.test
+new file mode 100644
+--- /dev/null
++++ b/testsuite/atimes.test
 @@ -0,0 +1,19 @@
 +#! /bin/sh
 +
 @@ -0,0 +1,19 @@
 +#! /bin/sh
 +
@@ -394,9 +405,10 @@ TODO:  need to fix this to handle 64-bit time_t values!
 +
 +# The script would have aborted on error, so getting here means we've won.
 +exit 0
 +
 +# The script would have aborted on error, so getting here means we've won.
 +exit 0
---- old/testsuite/rsync.fns
-+++ new/testsuite/rsync.fns
-@@ -186,6 +186,10 @@ checkit() {
+diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
+--- a/testsuite/rsync.fns
++++ b/testsuite/rsync.fns
+@@ -187,6 +187,10 @@ checkit() {
      # We can just write everything to stdout/stderr, because the
      # wrapper hides it unless there is a problem.
  
      # We can just write everything to stdout/stderr, because the
      # wrapper hides it unless there is a problem.
  
@@ -407,7 +419,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
      echo "Running: \"$1\""  
      eval "$1" 
      status=$?
      echo "Running: \"$1\""  
      eval "$1" 
      status=$?
-@@ -193,10 +197,13 @@ checkit() {
+@@ -194,10 +198,13 @@ checkit() {
        failed="YES";
      fi
  
        failed="YES";
      fi
  
@@ -422,9 +434,10 @@ TODO:  need to fix this to handle 64-bit time_t values!
      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
  
      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
  
---- old/tls.c
-+++ new/tls.c
-@@ -99,6 +99,8 @@ static int stat_xattr(const char *fname,
+diff --git a/tls.c b/tls.c
+--- a/tls.c
++++ b/tls.c
+@@ -104,6 +104,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
  
  #endif
  
  
  #endif
  
@@ -433,7 +446,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  static void failed(char const *what, char const *where)
  {
        fprintf(stderr, PROGRAM ": %s %s: %s\n",
  static void failed(char const *what, char const *where)
  {
        fprintf(stderr, PROGRAM ": %s %s: %s\n",
-@@ -106,12 +108,29 @@ static void failed(char const *what, cha
+@@ -111,12 +113,29 @@ static void failed(char const *what, char const *where)
        exit(1);
  }
  
        exit(1);
  }
  
@@ -465,7 +478,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
        char linkbuf[4096];
  
        if (do_lstat(fname, &buf) < 0)
        char linkbuf[4096];
  
        if (do_lstat(fname, &buf) < 0)
-@@ -148,19 +167,8 @@ static void list_file(const char *fname)
+@@ -153,19 +172,8 @@ static void list_file(const char *fname)
  
        permstring(permbuf, buf.st_mode);
  
  
        permstring(permbuf, buf.st_mode);
  
@@ -487,7 +500,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  
        /* TODO: Perhaps escape special characters in fname? */
  
  
        /* TODO: Perhaps escape special characters in fname? */
  
-@@ -171,13 +179,15 @@ static void list_file(const char *fname)
+@@ -176,13 +184,15 @@ static void list_file(const char *fname)
                    (long)minor(buf.st_rdev));
        } else /* NB: use double for size since it might not fit in a long. */
                printf("%12.0f", (double)buf.st_size);
                    (long)minor(buf.st_rdev));
        } else /* NB: use double for size since it might not fit in a long. */
                printf("%12.0f", (double)buf.st_size);
@@ -495,7 +508,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
 +      printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
               (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
 -             datebuf, fname, linkbuf);
 +      printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
               (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
 -             datebuf, fname, linkbuf);
-+             mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
++             mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
 +             fname, linkbuf);
  }
  
 +             fname, linkbuf);
  }
  
@@ -505,7 +518,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  #ifdef SUPPORT_XATTRS
    {"fake-super",      'f', POPT_ARG_VAL,    &am_root, -1, 0, 0 },
  #endif
  #ifdef SUPPORT_XATTRS
    {"fake-super",      'f', POPT_ARG_VAL,    &am_root, -1, 0, 0 },
  #endif
-@@ -191,6 +201,7 @@ static void tls_usage(int ret)
+@@ -196,6 +206,7 @@ static void tls_usage(int ret)
    fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n");
    fprintf(F,"Trivial file listing program for portably checking rsync\n");
    fprintf(F,"\nOptions:\n");
    fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n");
    fprintf(F,"Trivial file listing program for portably checking rsync\n");
    fprintf(F,"\nOptions:\n");
@@ -513,9 +526,10 @@ TODO:  need to fix this to handle 64-bit time_t values!
  #ifdef SUPPORT_XATTRS
    fprintf(F," -f, --fake-super            display attributes including fake-super xattrs\n");
  #endif
  #ifdef SUPPORT_XATTRS
    fprintf(F," -f, --fake-super            display attributes including fake-super xattrs\n");
  #endif
---- old/util.c
-+++ new/util.c
-@@ -121,7 +121,7 @@ NORETURN void overflow_exit(const char *
+diff --git a/util.c b/util.c
+--- a/util.c
++++ b/util.c
+@@ -122,7 +122,7 @@ NORETURN void overflow_exit(const char *str)
        exit_cleanup(RERR_MALLOC);
  }
  
        exit_cleanup(RERR_MALLOC);
  }
  
@@ -524,7 +538,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
  {
  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
        if (S_ISLNK(mode))
  {
  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
        if (S_ISLNK(mode))
-@@ -129,9 +129,13 @@ int set_modtime(const char *fname, time_
+@@ -130,9 +130,13 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
  #endif
  
        if (verbose > 2) {
  #endif
  
        if (verbose > 2) {
@@ -540,7 +554,7 @@ TODO:  need to fix this to handle 64-bit time_t values!
        }
  
        if (dry_run)
        }
  
        if (dry_run)
-@@ -140,7 +144,7 @@ int set_modtime(const char *fname, time_
+@@ -141,7 +145,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
        {
  #ifdef HAVE_UTIMES
                struct timeval t[2];
        {
  #ifdef HAVE_UTIMES
                struct timeval t[2];
@@ -549,9 +563,9 @@ TODO:  need to fix this to handle 64-bit time_t values!
                t[0].tv_usec = 0;
                t[1].tv_sec = modtime;
                t[1].tv_usec = 0;
                t[0].tv_usec = 0;
                t[1].tv_sec = modtime;
                t[1].tv_usec = 0;
-@@ -153,12 +157,12 @@ int set_modtime(const char *fname, time_
+@@ -154,12 +158,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
                return utimes(fname, t);
                return utimes(fname, t);
- #elif defined HAVE_UTIMBUF
+ #elif defined HAVE_STRUCT_UTIMBUF
                struct utimbuf tbuf;
 -              tbuf.actime = time(NULL);
 +              tbuf.actime = atime;
                struct utimbuf tbuf;
 -              tbuf.actime = time(NULL);
 +              tbuf.actime = atime;