Fix alignment issue on 64-bit. Solution from Steve Ortiz.
[rsync/rsync-patches.git] / crtimes.diff
index 6c5148b..5766c91 100644 (file)
@@ -8,11 +8,11 @@ To use this patch, run these commands for a successful build:
     ./configure                      (optional if already run)
     make
 
     ./configure                      (optional if already run)
     make
 
+based-on: patch/master/fileflags
 diff --git a/compat.c b/compat.c
 diff --git a/compat.c b/compat.c
-index ef1882d..132ff90 100644
 --- a/compat.c
 +++ b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -44,6 +44,7 @@ extern int force_change;
+@@ -45,6 +45,7 @@ extern int force_change;
  extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
  extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
@@ -20,7 +20,7 @@ index ef1882d..132ff90 100644
  extern int preserve_fileflags;
  extern int preserve_acls;
  extern int preserve_xattrs;
  extern int preserve_fileflags;
  extern int preserve_acls;
  extern int preserve_xattrs;
-@@ -62,7 +63,7 @@ extern char *iconv_opt;
+@@ -63,7 +64,7 @@ extern char *iconv_opt;
  #endif
  
  /* These index values are for the file-list's extra-attribute array. */
  #endif
  
  /* These index values are for the file-list's extra-attribute array. */
@@ -29,7 +29,7 @@ index ef1882d..132ff90 100644
  
  int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
  int sender_symlink_iconv = 0; /* sender should convert symlink content */
  
  int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
  int sender_symlink_iconv = 0; /* sender should convert symlink content */
-@@ -138,6 +139,8 @@ void setup_protocol(int f_out,int f_in)
+@@ -140,6 +141,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;
@@ -39,7 +39,6 @@ index ef1882d..132ff90 100644
                fileflags_ndx = ++file_extra_cnt;
        if (preserve_acls && !am_sender)
 diff --git a/flist.c b/flist.c
                fileflags_ndx = ++file_extra_cnt;
        if (preserve_acls && !am_sender)
 diff --git a/flist.c b/flist.c
-index e1d01be..3287447 100644
 --- a/flist.c
 +++ b/flist.c
 @@ -56,6 +56,7 @@ extern int missing_args;
 --- a/flist.c
 +++ b/flist.c
 @@ -56,6 +56,7 @@ extern int missing_args;
@@ -50,7 +49,7 @@ index e1d01be..3287447 100644
  extern int relative_paths;
  extern int implied_dirs;
  extern int file_extra_cnt;
  extern int relative_paths;
  extern int implied_dirs;
  extern int file_extra_cnt;
-@@ -397,7 +398,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -407,7 +408,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
  #endif
                            int ndx, int first_ndx)
  {
  #endif
                            int ndx, int first_ndx)
  {
@@ -59,10 +58,10 @@ index e1d01be..3287447 100644
        static mode_t mode;
  #ifdef SUPPORT_FILEFLAGS
        static uint32 fileflags;
        static mode_t mode;
  #ifdef SUPPORT_FILEFLAGS
        static uint32 fileflags;
-@@ -496,6 +497,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-               xflags |= XMIT_SAME_TIME;
-       else
+@@ -518,6 +519,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                modtime = file->modtime;
                modtime = file->modtime;
+       if (NSEC_BUMP(file) && protocol_version >= 31)
+               xflags |= XMIT_MOD_NSEC;
 +      if (crtimes_ndx) {
 +              time_t file_crtime = f_crtime(file);
 +              if (file_crtime == modtime)
 +      if (crtimes_ndx) {
 +              time_t file_crtime = f_crtime(file);
 +              if (file_crtime == modtime)
@@ -73,28 +72,28 @@ index e1d01be..3287447 100644
  
  #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != 0) {
  
  #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != 0) {
-@@ -578,6 +586,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-               else
-                       write_int(f, modtime);
+@@ -602,6 +610,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
        }
        }
+       if (xflags & XMIT_MOD_NSEC)
+               write_varint(f, F_MOD_NSEC(file));
 +      if (crtimes_ndx && !(xflags & XMIT_CRTIME_EQ_MTIME))
 +              write_varlong(f, crtime, 4);
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
  #ifdef SUPPORT_FILEFLAGS
 +      if (crtimes_ndx && !(xflags & XMIT_CRTIME_EQ_MTIME))
 +              write_varlong(f, crtime, 4);
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
  #ifdef SUPPORT_FILEFLAGS
-@@ -670,7 +680,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
- static struct file_struct *recv_file_entry(struct file_list *flist,
                                         int xflags, int f)
+@@ -693,7 +703,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags)
  {
 -      static int64 modtime;
 +      static int64 modtime, crtime;
        static mode_t mode;
  #ifdef SUPPORT_FILEFLAGS
        static uint32 fileflags;
  {
 -      static int64 modtime;
 +      static int64 modtime, crtime;
        static mode_t mode;
  #ifdef SUPPORT_FILEFLAGS
        static uint32 fileflags;
-@@ -810,6 +820,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
-               } else
-                       modtime = read_int(f);
-       }
+@@ -838,6 +848,19 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
+               modtime_nsec = read_varint(f);
+       else
+               modtime_nsec = 0;
 +      if (crtimes_ndx) {
 +              if (!(xflags & XMIT_CRTIME_EQ_MTIME)) {
 +                      crtime = read_varlong(f, 4);
 +      if (crtimes_ndx) {
 +              if (!(xflags & XMIT_CRTIME_EQ_MTIME)) {
 +                      crtime = read_varlong(f, 4);
@@ -111,7 +110,7 @@ index e1d01be..3287447 100644
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
  
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
  
-@@ -969,6 +992,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -1008,6 +1031,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
@@ -120,7 +119,7 @@ index e1d01be..3287447 100644
        if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
  
        if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
  
-@@ -1358,6 +1383,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1407,6 +1432,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                F_OWNER(file) = st.st_uid;
        if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
                F_GROUP(file) = st.st_gid;
                F_OWNER(file) = st.st_uid;
        if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
                F_GROUP(file) = st.st_gid;
@@ -130,7 +129,6 @@ index e1d01be..3287447 100644
        if (basename != thisname)
                file->dirname = lastdir;
 diff --git a/generator.c b/generator.c
        if (basename != thisname)
                file->dirname = lastdir;
 diff --git a/generator.c b/generator.c
-index eee42e8..932f81c 100644
 --- a/generator.c
 +++ b/generator.c
 @@ -40,6 +40,7 @@ extern int preserve_xattrs;
 --- a/generator.c
 +++ b/generator.c
 @@ -40,6 +40,7 @@ extern int preserve_xattrs;
@@ -141,7 +139,7 @@ index eee42e8..932f81c 100644
  extern int preserve_hard_links;
  extern int preserve_executability;
  extern int preserve_fileflags;
  extern int preserve_hard_links;
  extern int preserve_executability;
  extern int preserve_fileflags;
-@@ -419,6 +420,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -418,6 +419,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
        if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
                return 0;
  
        if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
                return 0;
  
@@ -155,7 +153,7 @@ index eee42e8..932f81c 100644
  #ifdef SUPPORT_ACLS
        if (preserve_acls && !S_ISLNK(file->mode)) {
                if (!ACL_READY(*sxp))
  #ifdef SUPPORT_ACLS
        if (preserve_acls && !S_ISLNK(file->mode)) {
                if (!ACL_READY(*sxp))
-@@ -462,6 +470,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -461,6 +469,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                 : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
                        iflags |= ITEM_REPORT_TIME;
                 : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
                        iflags |= ITEM_REPORT_TIME;
@@ -168,7 +166,7 @@ index eee42e8..932f81c 100644
  #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
                if (S_ISLNK(file->mode)) {
                        ;
  #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
                if (S_ISLNK(file->mode)) {
                        ;
-@@ -1022,6 +1036,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1028,6 +1042,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];
  static void list_file_entry(struct file_struct *f)
  {
        char permbuf[PERMSTRING_SIZE];
@@ -176,7 +174,7 @@ index eee42e8..932f81c 100644
        int64 len;
        int colwidth = human_readable ? 14 : 11;
  
        int64 len;
        int colwidth = human_readable ? 14 : 11;
  
-@@ -1037,10 +1052,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1043,10 +1058,11 @@ static void list_file_entry(struct file_struct *f)
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
@@ -191,7 +189,7 @@ index eee42e8..932f81c 100644
        } else
  #endif
        if (missing_args == 2 && f->mode == 0) {
        } else
  #endif
        if (missing_args == 2 && f->mode == 0) {
-@@ -1048,9 +1064,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1054,9 +1070,11 @@ static void list_file_entry(struct file_struct *f)
                        colwidth + 31, "*missing",
                        f_name(f, NULL));
        } else {
                        colwidth + 31, "*missing",
                        f_name(f, NULL));
        } else {
@@ -205,7 +203,7 @@ index eee42e8..932f81c 100644
        }
  }
  
        }
  }
  
-@@ -1141,6 +1159,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1147,6 +1165,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        return;
                }
        }
                        return;
                }
        }
@@ -214,11 +212,10 @@ index eee42e8..932f81c 100644
        init_stat_x(&sx);
        if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
 diff --git a/ifuncs.h b/ifuncs.h
        init_stat_x(&sx);
        if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
 diff --git a/ifuncs.h b/ifuncs.h
-index 8c128d5..4254dfb 100644
 --- a/ifuncs.h
 +++ b/ifuncs.h
 --- a/ifuncs.h
 +++ b/ifuncs.h
-@@ -35,6 +35,28 @@ realloc_xbuf(xbuf *xb, size_t sz)
-       xb->size = sz;
+@@ -43,6 +43,28 @@ free_xbuf(xbuf *xb)
+       memset(xb, 0, sizeof (xbuf));
  }
  
 +static inline time_t
  }
  
 +static inline time_t
@@ -247,10 +244,9 @@ index 8c128d5..4254dfb 100644
  to_wire_mode(mode_t mode)
  {
 diff --git a/log.c b/log.c
  to_wire_mode(mode_t mode)
  {
 diff --git a/log.c b/log.c
-index 83948b1..7a1d9ce 100644
 --- a/log.c
 +++ b/log.c
 --- a/log.c
 +++ b/log.c
-@@ -718,7 +718,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
+@@ -736,7 +736,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                        c[8] = !(iflags & ITEM_REPORT_FFLAGS) ? '.' : 'f';
                        c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
                        c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
                        c[8] = !(iflags & ITEM_REPORT_FFLAGS) ? '.' : 'f';
                        c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
                        c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
@@ -261,7 +257,6 @@ index 83948b1..7a1d9ce 100644
                        if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
                                char ch = iflags & ITEM_IS_NEW ? '+' : '?';
 diff --git a/options.c b/options.c
                        if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
                                char ch = iflags & ITEM_IS_NEW ? '+' : '?';
 diff --git a/options.c b/options.c
-index ae3d2d0..bb3bad3 100644
 --- a/options.c
 +++ b/options.c
 @@ -60,6 +60,7 @@ int preserve_specials = 0;
 --- a/options.c
 +++ b/options.c
 @@ -60,6 +60,7 @@ int preserve_specials = 0;
@@ -272,7 +267,7 @@ index ae3d2d0..bb3bad3 100644
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -707,6 +708,7 @@ void usage(enum logcode F)
+@@ -708,6 +709,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");
@@ -280,7 +275,7 @@ index ae3d2d0..bb3bad3 100644
    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");
-@@ -863,6 +865,9 @@ static struct poptOption long_options[] = {
+@@ -864,6 +866,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 },
    {"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 },
@@ -290,7 +285,7 @@ index ae3d2d0..bb3bad3 100644
    {"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 },
    {"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 },
-@@ -2315,6 +2320,8 @@ void server_options(char **args, int *argc_p)
+@@ -2367,6 +2372,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';
@@ -300,10 +295,9 @@ index ae3d2d0..bb3bad3 100644
                argstr[x++] = 'p';
        else if (preserve_executability && am_sender)
 diff --git a/rsync.c b/rsync.c
                argstr[x++] = 'p';
        else if (preserve_executability && am_sender)
 diff --git a/rsync.c b/rsync.c
-index 3188535..ab4f8e4 100644
 --- a/rsync.c
 +++ b/rsync.c
 --- a/rsync.c
 +++ b/rsync.c
-@@ -471,6 +471,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -538,6 +538,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                else
                        file->flags |= FLAG_TIME_FAILED;
        }
                else
                        file->flags |= FLAG_TIME_FAILED;
        }
@@ -318,7 +312,7 @@ index 3188535..ab4f8e4 100644
  
        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
        change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
  
        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
        change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
-@@ -619,7 +627,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -688,7 +696,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
        /* Change permissions before putting the file into place. */
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
                       ATTRS_DELAY_IMMUTABLE
        /* Change permissions before putting the file into place. */
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
                       ATTRS_DELAY_IMMUTABLE
@@ -327,7 +321,7 @@ index 3188535..ab4f8e4 100644
  
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
  
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
-@@ -650,7 +658,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -719,7 +727,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
  
    do_set_file_attrs:
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
  
    do_set_file_attrs:
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
@@ -337,18 +331,19 @@ index 3188535..ab4f8e4 100644
        if (temp_copy_name) {
                if (do_rename(fnametmp, fname) < 0) {
 diff --git a/rsync.h b/rsync.h
        if (temp_copy_name) {
                if (do_rename(fnametmp, fname) < 0) {
 diff --git a/rsync.h b/rsync.h
-index 16820fd..b3973c8 100644
 --- a/rsync.h
 +++ b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -61,6 +61,7 @@
- #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
+@@ -62,7 +62,8 @@
  #define XMIT_HLINK_FIRST (1<<12)      /* protocols 30 - now (HLINKED files only) */
  #define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31 - now (w/XMIT_EXTENDED_FLAGS) */
  #define XMIT_HLINK_FIRST (1<<12)      /* protocols 30 - now (HLINKED files only) */
  #define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31 - now (w/XMIT_EXTENDED_FLAGS) */
-+#define XMIT_CRTIME_EQ_MTIME (1<<13)  /* protocols ?? - now */
- #define XMIT_SAME_FLAGS (1<<14)               /* protocols ?? - now */
+ #define XMIT_MOD_NSEC (1<<13)         /* protocols 31 - now */
+-#define XMIT_SAME_FLAGS (1<<14)               /* protocols ?? - now */
++#define XMIT_CRTIME_EQ_MTIME (1<<14)  /* protocols ?? - now */
++#define XMIT_SAME_FLAGS (1<<15)               /* protocols ?? - now */
  
  /* These flags are used in the live flist data. */
  
  /* These flags are used in the live flist data. */
-@@ -157,6 +158,7 @@
+@@ -162,6 +163,7 @@
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
  #define ATTRS_DELAY_IMMUTABLE (1<<2)
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
  #define ATTRS_DELAY_IMMUTABLE (1<<2)
@@ -356,7 +351,7 @@ index 16820fd..b3973c8 100644
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -173,7 +175,7 @@
+@@ -178,7 +180,7 @@
  #define FNAMECMP_FUZZY                0x83
  
  /* For use by the itemize_changes code */
  #define FNAMECMP_FUZZY                0x83
  
  /* For use by the itemize_changes code */
@@ -365,7 +360,7 @@ index 16820fd..b3973c8 100644
  #define ITEM_REPORT_CHANGE (1<<1)
  #define ITEM_REPORT_SIZE (1<<2)     /* regular files only */
  #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */
  #define ITEM_REPORT_CHANGE (1<<1)
  #define ITEM_REPORT_SIZE (1<<2)     /* regular files only */
  #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */
-@@ -677,6 +679,7 @@ extern int file_extra_cnt;
+@@ -693,6 +695,7 @@ extern int file_extra_cnt;
  extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
  extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
@@ -373,7 +368,7 @@ index 16820fd..b3973c8 100644
  extern int fileflags_ndx;
  extern int acls_ndx;
  extern int xattrs_ndx;
  extern int fileflags_ndx;
  extern int acls_ndx;
  extern int xattrs_ndx;
-@@ -684,6 +687,7 @@ extern int xattrs_ndx;
+@@ -700,6 +703,7 @@ extern int xattrs_ndx;
  #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
  #define EXTRA_LEN (sizeof (union file_extras))
  #define PTR_EXTRA_CNT ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
  #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
  #define EXTRA_LEN (sizeof (union file_extras))
  #define PTR_EXTRA_CNT ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
@@ -381,7 +376,7 @@ index 16820fd..b3973c8 100644
  #define DEV_EXTRA_CNT 2
  #define DIRNODE_EXTRA_CNT 3
  #define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
  #define DEV_EXTRA_CNT 2
  #define DIRNODE_EXTRA_CNT 3
  #define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
-@@ -954,6 +958,7 @@ typedef struct {
+@@ -979,6 +983,7 @@ typedef struct {
  
  typedef struct {
      STRUCT_STAT st;
  
  typedef struct {
      STRUCT_STAT st;
@@ -390,7 +385,6 @@ index 16820fd..b3973c8 100644
      struct rsync_acl *acc_acl; /* access ACL */
      struct rsync_acl *def_acl; /* default ACL */
 diff --git a/rsync.yo b/rsync.yo
      struct rsync_acl *acc_acl; /* access ACL */
      struct rsync_acl *def_acl; /* default ACL */
 diff --git a/rsync.yo b/rsync.yo
-index 7b41d5f..5670c46 100644
 --- a/rsync.yo
 +++ b/rsync.yo
 @@ -357,6 +357,7 @@ to the detailed description below for a complete description.  verb(
 --- a/rsync.yo
 +++ b/rsync.yo
 @@ -357,6 +357,7 @@ to the detailed description below for a complete description.  verb(
@@ -401,7 +395,7 @@ index 7b41d5f..5670c46 100644
       --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
-@@ -1099,6 +1100,9 @@ it is preserving modification times (see bf(--times)).  If NFS is sharing
+@@ -1110,6 +1111,9 @@ 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).
  
@@ -411,7 +405,7 @@ index 7b41d5f..5670c46 100644
  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
-@@ -1861,7 +1865,7 @@ with older versions of rsync, but that also turns on the output of other
+@@ -1922,7 +1926,7 @@ with older versions of rsync, but that also turns on the output of other
  verbose messages).
  
  The "%i" escape has a cryptic output that is 11 letters long.  The general
  verbose messages).
  
  The "%i" escape has a cryptic output that is 11 letters long.  The general
@@ -420,7 +414,7 @@ index 7b41d5f..5670c46 100644
  type of update being done, bf(X) is replaced by the file-type, and the
  other letters represent attributes that may be output if they are being
  modified.
  type of update being done, bf(X) is replaced by the file-type, and the
  other letters represent attributes that may be output if they are being
  modified.
-@@ -1920,6 +1924,8 @@ quote(itemization(
+@@ -1981,6 +1985,8 @@ quote(itemization(
    it() The bf(f) means that the fileflags information changed.
    it() The bf(a) means that the ACL information changed.
    it() The bf(x) means that the extended attribute information changed.
    it() The bf(f) means that the fileflags information changed.
    it() The bf(a) means that the ACL information changed.
    it() The bf(x) means that the extended attribute information changed.
@@ -430,22 +424,24 @@ index 7b41d5f..5670c46 100644
  
  One other output is possible:  when deleting files, the "%i" will output
 diff --git a/syscall.c b/syscall.c
  
  One other output is possible:  when deleting files, the "%i" will output
 diff --git a/syscall.c b/syscall.c
-index 45604b1..c463997 100644
 --- a/syscall.c
 +++ b/syscall.c
 --- a/syscall.c
 +++ b/syscall.c
-@@ -37,6 +37,11 @@ extern int force_change;
+@@ -38,6 +38,14 @@ extern int force_change;
  extern int preserve_perms;
  extern int preserve_executability;
  
  extern int preserve_perms;
  extern int preserve_executability;
  
++#pragma pack(push)
++#pragma pack(4)
 +struct create_time {
 +struct create_time {
-+      unsigned long length;
++      uint32 length;
 +      struct timespec crtime;
 +};
 +      struct timespec crtime;
 +};
++#pragma pack(pop)
 +
  #define RETURN_ERROR_IF(x,e) \
        do { \
                if (x) { \
 +
  #define RETURN_ERROR_IF(x,e) \
        do { \
                if (x) { \
-@@ -394,3 +399,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
+@@ -439,3 +447,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
        return lseek(fd, offset, whence);
  #endif
  }
        return lseek(fd, offset, whence);
  #endif
  }
@@ -481,7 +477,6 @@ index 45604b1..c463997 100644
 +}
 diff --git a/testsuite/crtimes.test b/testsuite/crtimes.test
 new file mode 100644
 +}
 diff --git a/testsuite/crtimes.test b/testsuite/crtimes.test
 new file mode 100644
-index 0000000..b904e16
 --- /dev/null
 +++ b/testsuite/crtimes.test
 @@ -0,0 +1,24 @@
 --- /dev/null
 +++ b/testsuite/crtimes.test
 @@ -0,0 +1,24 @@
@@ -510,10 +505,9 @@ index 0000000..b904e16
 +# The script would have aborted on error, so getting here means we've won.
 +exit 0
 diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
 +# The script would have aborted on error, so getting here means we've won.
 +exit 0
 diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
-index b26aee3..4faaf93 100644
 --- a/testsuite/rsync.fns
 +++ b/testsuite/rsync.fns
 --- a/testsuite/rsync.fns
 +++ b/testsuite/rsync.fns
-@@ -24,9 +24,9 @@ todir="$tmpdir/to"
+@@ -23,9 +23,9 @@ todir="$tmpdir/to"
  chkdir="$tmpdir/chk"
  
  # For itemized output:
  chkdir="$tmpdir/chk"
  
  # For itemized output:
@@ -527,10 +521,9 @@ index b26aee3..4faaf93 100644
  # Berkley's nice.
  PATH="$PATH:/usr/ucb"
 diff --git a/tls.c b/tls.c
  # Berkley's nice.
  PATH="$PATH:/usr/ucb"
 diff --git a/tls.c b/tls.c
-index 8cc5748..6da4df9 100644
 --- a/tls.c
 +++ b/tls.c
 --- a/tls.c
 +++ b/tls.c
-@@ -108,6 +108,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
+@@ -118,6 +118,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
  
  #endif
  
  
  #endif
  
@@ -539,25 +532,33 @@ index 8cc5748..6da4df9 100644
  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",
-@@ -115,16 +117,36 @@ static void failed(char const *what, char const *where)
+@@ -125,16 +127,44 @@ static void failed(char const *what, char const *where)
        exit(1);
  }
  
        exit(1);
  }
  
-+static void storetime(char *dest, time_t t, size_t destsize)
++static void storetime(char *dest, size_t destsize, time_t t, int nsecs)
 +{
 +      if (t) {
 +{
 +      if (t) {
++              int len;
 +              struct tm *mt = gmtime(&t);
 +
 +              struct tm *mt = gmtime(&t);
 +
-+              snprintf(dest, destsize,
-+                      "%04d-%02d-%02d %02d:%02d:%02d ",
++              len = snprintf(dest, destsize,
++                      "%04d-%02d-%02d %02d:%02d:%02d",
 +                      (int)mt->tm_year + 1900,
 +                      (int)mt->tm_mon + 1,
 +                      (int)mt->tm_mday,
 +                      (int)mt->tm_hour,
 +                      (int)mt->tm_min,
 +                      (int)mt->tm_sec);
 +                      (int)mt->tm_year + 1900,
 +                      (int)mt->tm_mon + 1,
 +                      (int)mt->tm_mday,
 +                      (int)mt->tm_hour,
 +                      (int)mt->tm_min,
 +                      (int)mt->tm_sec);
-+      } else
-+              strlcpy(dest, "                    ", destsize);
++              if (nsecs >= 0) {
++                      snprintf(datebuf + len, sizeof datebuf - len, ".%09d", nsecs);
++              }
++      } else {
++              int has_nsecs = nsecs >= 0 ? 1 : 0;
++              int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1);
++              memset(datebuf, ' ', len);
++              datebuf[len] = '\0';
++      }
 +}
 +
  static void list_file(const char *fname)
 +}
 +
  static void list_file(const char *fname)
@@ -578,14 +579,15 @@ index 8cc5748..6da4df9 100644
  #ifdef SUPPORT_XATTRS
        if (am_root < 0)
                stat_xattr(fname, &buf);
  #ifdef SUPPORT_XATTRS
        if (am_root < 0)
                stat_xattr(fname, &buf);
-@@ -159,19 +181,11 @@ static void list_file(const char *fname)
+@@ -169,29 +199,11 @@ static void list_file(const char *fname)
  
        permstring(permbuf, buf.st_mode);
  
 -      if (buf.st_mtime) {
  
        permstring(permbuf, buf.st_mode);
  
 -      if (buf.st_mtime) {
+-              int len;
 -              mt = gmtime(&buf.st_mtime);
 -
 -              mt = gmtime(&buf.st_mtime);
 -
--              snprintf(datebuf, sizeof datebuf,
+-              len = snprintf(datebuf, sizeof datebuf,
 -                      "%04d-%02d-%02d %02d:%02d:%02d",
 -                      (int)mt->tm_year + 1900,
 -                      (int)mt->tm_mon + 1,
 -                      "%04d-%02d-%02d %02d:%02d:%02d",
 -                      (int)mt->tm_year + 1900,
 -                      (int)mt->tm_mon + 1,
@@ -593,17 +595,26 @@ index 8cc5748..6da4df9 100644
 -                      (int)mt->tm_hour,
 -                      (int)mt->tm_min,
 -                      (int)mt->tm_sec);
 -                      (int)mt->tm_hour,
 -                      (int)mt->tm_min,
 -                      (int)mt->tm_sec);
--      } else
--              strlcpy(datebuf, "                   ", sizeof datebuf);
-+      storetime(mtimebuf, buf.st_mtime, sizeof mtimebuf);
+-#ifdef ST_MTIME_NSEC
+-              if (nsec_times) {
+-                      snprintf(datebuf + len, sizeof datebuf - len,
+-                              ".%09d", (int)buf.ST_MTIME_NSEC);
+-              }
+-#endif
+-      } else {
+-              int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1);
+-              memset(datebuf, ' ', len);
+-              datebuf[len] = '\0';
+-      }
++      storetime(mtimebuf, sizeof mtimebuf, buf.st_mtime, nsecs);
 +      if (display_crtimes)
 +      if (display_crtimes)
-+              storetime(crtimebuf, crtime, sizeof crtimebuf);
++              storetime(crtimebuf, sizeof crtimebuf, crtime, -1);
 +      else
 +              crtimebuf[0] = '\0';
  
        /* TODO: Perhaps escape special characters in fname? */
  
 +      else
 +              crtimebuf[0] = '\0';
  
        /* TODO: Perhaps escape special characters in fname? */
  
-@@ -182,13 +196,14 @@ static void list_file(const char *fname)
+@@ -202,13 +214,14 @@ static void list_file(const char *fname)
                    (long)minor(buf.st_rdev));
        } else
                printf("%15s", do_big_num(buf.st_size, 1, NULL));
                    (long)minor(buf.st_rdev));
        } else
                printf("%15s", do_big_num(buf.st_size, 1, NULL));
@@ -620,7 +631,7 @@ index 8cc5748..6da4df9 100644
    {"link-times",      'l', POPT_ARG_NONE,   &link_times, 0, 0, 0 },
    {"link-owner",      'L', POPT_ARG_NONE,   &link_owner, 0, 0, 0 },
  #ifdef SUPPORT_XATTRS
    {"link-times",      'l', POPT_ARG_NONE,   &link_times, 0, 0, 0 },
    {"link-owner",      'L', POPT_ARG_NONE,   &link_owner, 0, 0, 0 },
  #ifdef SUPPORT_XATTRS
-@@ -204,6 +219,7 @@ static void tls_usage(int ret)
+@@ -227,6 +240,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");