Adding group-auth patch; updating patches.
authorWayne Davison <wayned@samba.org>
Wed, 21 Oct 2009 03:00:07 +0000 (20:00 -0700)
committerWayne Davison <wayned@samba.org>
Wed, 21 Oct 2009 03:00:07 +0000 (20:00 -0700)
41 files changed:
acls.diff
adaptec_acl_mods.diff
atimes.diff
backup-dir-dels.diff
catch_crash_signals.diff
checksum-reading.diff
checksum-updating.diff
checksum-xattr.diff
copy-devices.diff
crtimes.diff
cvs-entries.diff
daemon-forward-lookup.diff
date-only.diff
db.diff
detect-renamed-lax.diff
detect-renamed.diff
downdate.diff
drop-cache.diff
fileflags.diff
filter-attribute-mods.diff
fsync.diff
group-auth.diff [new file with mode: 0644]
ignore-case.diff
link-by-hash.diff
nameconverter.diff
netgroup-auth.diff
omit-dir-changes.diff
openssl-support.diff
osx-xattr-nodev.diff
preallocate.diff
slow-down.diff
slp.diff
soften-links.diff
source-backup.diff
source-filter_dest-filter.diff
sparse-block.diff
stdout.diff
time-limit.diff
transliterate.diff
tru64.diff
xattrs.diff

index cafbf86..e59a344 100644 (file)
--- a/acls.diff
+++ b/acls.diff
@@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/acls.c b/acls.c
 --- a/acls.c
 +++ b/acls.c
@@ -40,7 +40,7 @@ diff --git a/acls.c b/acls.c
  static int calc_sacl_entries(const rsync_acl *racl)
  {
        /* A System ACL always gets user/group/other permission entries. */
-@@ -558,6 +571,96 @@ int get_acl(const char *fname, stat_x *sxp)
+@@ -555,6 +568,96 @@ int get_acl(const char *fname, stat_x *sxp)
        return 0;
  }
  
@@ -137,9 +137,9 @@ diff --git a/acls.c b/acls.c
  /* === Send functions === */
  
  /* Send the ida list over the file descriptor. */
-@@ -633,6 +736,11 @@ static void send_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type,
+@@ -630,6 +733,11 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB_ACL_TYPE_T type,
   * This also frees the ACL data. */
- void send_acl(stat_x *sxp, int f)
+ void send_acl(int f, stat_x *sxp)
  {
 +      if (protocol_version < 30) {
 +              old_send_acl(sxp, f);
@@ -149,7 +149,7 @@ diff --git a/acls.c b/acls.c
        if (!sxp->acc_acl) {
                sxp->acc_acl = create_racl();
                rsync_acl_fake_perms(sxp->acc_acl, sxp->st.st_mode);
-@@ -650,6 +758,160 @@ void send_acl(stat_x *sxp, int f)
+@@ -647,6 +755,160 @@ void send_acl(int f, stat_x *sxp)
        }
  }
  
@@ -309,23 +309,23 @@ diff --git a/acls.c b/acls.c
 +
  /* === Receive functions === */
  
- static uint32 recv_acl_access(uchar *name_follows_ptr, int f)
-@@ -765,6 +1027,11 @@ static int recv_rsync_acl(item_list *racl_list, SMB_ACL_TYPE_T type, int f)
+ static uint32 recv_acl_access(int f, uchar *name_follows_ptr)
+@@ -768,6 +1030,11 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode
  /* Receive the ACL info the sender has included for this file-list entry. */
- void receive_acl(struct file_struct *file, int f)
+ void receive_acl(int f, struct file_struct *file)
  {
 +      if (protocol_version < 30) {
 +              old_recv_acl(file, f);
 +              return;
 +      }
 +
-       F_ACL(file) = recv_rsync_acl(&access_acl_list, SMB_ACL_TYPE_ACCESS, f);
+       F_ACL(file) = recv_rsync_acl(f, &access_acl_list, SMB_ACL_TYPE_ACCESS, file->mode);
  
        if (S_ISDIR(file->mode))
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -189,13 +189,6 @@ void setup_protocol(int f_out,int f_in)
+@@ -192,13 +192,6 @@ void setup_protocol(int f_out,int f_in)
        if (protocol_version < 30) {
                if (append_mode == 1)
                        append_mode = 2;
index 008399e..fca8569 100644 (file)
@@ -24,7 +24,7 @@ Todo:
 Fix a bug that could lose some bits when stripping some (supposedly)
 superfluous ACL info.
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/lib/sysacls.c b/lib/sysacls.c
 --- a/lib/sysacls.c
 +++ b/lib/sysacls.c
index 4bc51f5..2157fd9 100644 (file)
@@ -4,11 +4,11 @@ To use this patch, run these commands for a successful build:
     ./configure                      (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -43,6 +43,7 @@ extern int protocol_version;
+@@ -45,6 +45,7 @@ extern int protocol_version;
  extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
@@ -16,7 +16,7 @@ diff --git a/compat.c b/compat.c
  extern int preserve_acls;
  extern int preserve_xattrs;
  extern int need_messages_from_generator;
-@@ -60,7 +61,7 @@ extern char *iconv_opt;
+@@ -62,7 +63,7 @@ extern char *iconv_opt;
  #endif
  
  /* These index values are for the file-list's extra-attribute array. */
@@ -25,7 +25,7 @@ diff --git a/compat.c b/compat.c
  
  int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
  int sender_symlink_iconv = 0; /* sender should convert symlink content */
-@@ -136,6 +137,8 @@ void setup_protocol(int f_out,int f_in)
+@@ -139,6 +140,8 @@ void setup_protocol(int f_out,int f_in)
                uid_ndx = ++file_extra_cnt;
        if (preserve_gid)
                gid_ndx = ++file_extra_cnt;
@@ -45,7 +45,7 @@ diff --git a/flist.c b/flist.c
  extern int relative_paths;
  extern int implied_dirs;
  extern int file_extra_cnt;
-@@ -396,7 +397,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -405,7 +406,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
  #endif
                            int ndx, int first_ndx)
  {
@@ -54,10 +54,10 @@ diff --git a/flist.c b/flist.c
        static mode_t mode;
  #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
-@@ -494,6 +495,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-               xflags |= XMIT_SAME_TIME;
-       else
+@@ -505,6 +506,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                modtime = file->modtime;
+       if (NSEC_BUMP(file) && protocol_version >= 31)
+               xflags |= XMIT_MOD_NSEC;
 +      if (atimes_ndx && !S_ISDIR(mode)) {
 +              time_t file_atime = f_atime(file);
 +              if (file_atime == atime)
@@ -68,8 +68,8 @@ diff --git a/flist.c b/flist.c
  
  #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,
-       }
+@@ -591,6 +599,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+               write_varint(f, F_MOD_NSEC(file));
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
 +      if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME))
@@ -77,17 +77,17 @@ diff --git a/flist.c b/flist.c
        if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
                if (protocol_version < 30)
                        write_int(f, uid);
-@@ -664,7 +674,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)
+@@ -676,7 +686,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, atime;
        static mode_t mode;
  #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
-@@ -802,6 +812,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
-       }
+@@ -820,6 +830,16 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
+               modtime_nsec = 0;
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
 +      if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME)) {
@@ -103,7 +103,7 @@ diff --git a/flist.c b/flist.c
  
        if (chmod_modes && !S_ISLNK(mode) && mode)
                mode = tweak_mode(mode, chmod_modes);
-@@ -952,6 +972,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -980,6 +1000,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
@@ -112,7 +112,7 @@ diff --git a/flist.c b/flist.c
        if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
  
-@@ -1337,6 +1359,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1375,6 +1397,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;
@@ -124,7 +124,7 @@ diff --git a/flist.c b/flist.c
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
-@@ -455,6 +455,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -456,6 +456,9 @@ 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;
@@ -134,7 +134,7 @@ diff --git a/generator.c b/generator.c
  #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
                if (S_ISLNK(file->mode)) {
                        ;
-@@ -825,6 +828,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -826,6 +829,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;
@@ -143,7 +143,7 @@ diff --git a/generator.c b/generator.c
                        if (preserve_hard_links && F_IS_HLINKED(file))
                                finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
                        if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
-@@ -1010,6 +1015,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1018,6 +1023,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];
@@ -151,7 +151,7 @@ diff --git a/generator.c b/generator.c
        int64 len;
        int colwidth = human_readable ? 14 : 11;
  
-@@ -1025,10 +1031,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1033,10 +1039,11 @@ static void list_file_entry(struct file_struct *f)
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
@@ -166,7 +166,7 @@ diff --git a/generator.c b/generator.c
        } else
  #endif
        if (missing_args == 2 && f->mode == 0) {
-@@ -1036,9 +1043,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1044,9 +1051,11 @@ static void list_file_entry(struct file_struct *f)
                        colwidth + 31, "*missing",
                        f_name(f, NULL));
        } else {
@@ -180,12 +180,12 @@ diff --git a/generator.c b/generator.c
        }
  }
  
-@@ -1870,7 +1879,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1923,7 +1932,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                        STRUCT_STAT st;
                        if (link_stat(fname, &st, 0) == 0
                         && cmp_time(st.st_mtime, file->modtime) != 0)
--                              set_modtime(fname, file->modtime, file->mode);
-+                              set_times(fname, file->modtime, file->modtime, file->mode);
+-                              set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode);
++                              set_times(fname, file->modtime, F_MOD_NSEC(file), file->modtime, file->mode);
                }
                if (counter >= loopchk_limit) {
                        if (allowed_lull)
@@ -245,7 +245,7 @@ diff --git a/options.c b/options.c
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -698,6 +699,7 @@ void usage(enum logcode F)
+@@ -699,6 +700,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");
@@ -253,7 +253,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
  #ifdef SUPPORT_XATTRS
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
-@@ -845,6 +847,9 @@ static struct poptOption long_options[] = {
+@@ -846,6 +848,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 },
@@ -263,7 +263,7 @@ diff --git a/options.c b/options.c
    {"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 },
-@@ -2306,6 +2311,8 @@ void server_options(char **args, int *argc_p)
+@@ -2307,6 +2312,8 @@ void server_options(char **args, int *argc_p)
                argstr[x++] = 'D';
        if (preserve_times)
                argstr[x++] = 't';
@@ -275,7 +275,7 @@ diff --git a/options.c b/options.c
 diff --git a/rsync.c b/rsync.c
 --- a/rsync.c
 +++ b/rsync.c
-@@ -384,6 +384,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -434,6 +434,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
        int updated = 0;
        stat_x sx2;
        int change_uid, change_gid;
@@ -283,7 +283,7 @@ diff --git a/rsync.c b/rsync.c
        mode_t new_mode = file->mode;
        int inherit;
  
-@@ -422,20 +423,38 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -472,20 +473,38 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                set_xattr(fname, file, fnamecmp, sxp);
  #endif
  
@@ -295,7 +295,7 @@ diff --git a/rsync.c b/rsync.c
 +              flags |= ATTRS_SKIP_ATIME;
        if (!(flags & ATTRS_SKIP_MTIME)
            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
--              int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
+-              int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
 +              mtime = file->modtime;
 +              updated = 1;
 +      } else
@@ -310,7 +310,7 @@ diff --git a/rsync.c b/rsync.c
 +      } else
 +              atime = sxp->st.st_atime;
 +      if (updated) {
-+              int ret = set_times(fname, mtime, atime, sxp->st.st_mode);
++              int ret = set_times(fname, mtime, F_MOD_NSEC(file), atime, sxp->st.st_mode);
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
@@ -326,7 +326,7 @@ diff --git a/rsync.c b/rsync.c
        }
  
        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
-@@ -570,7 +589,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -622,7 +641,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,
@@ -335,7 +335,7 @@ diff --git a/rsync.c b/rsync.c
  
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
-@@ -597,7 +616,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -649,7 +668,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
  
    do_set_file_attrs:
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
@@ -347,15 +347,15 @@ diff --git a/rsync.c b/rsync.c
 diff --git 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,6 +62,7 @@
  #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_SAME_ATIME (1<<13)               /* protocols ?? - now */
+ #define XMIT_MOD_NSEC (1<<13)         /* protocols 31 - now */
++#define XMIT_SAME_ATIME (1<<14)               /* protocols ?? - now */
  
  /* These flags are used in the live flist data. */
  
-@@ -155,6 +156,7 @@
+@@ -158,6 +159,7 @@
  
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
@@ -363,7 +363,7 @@ diff --git a/rsync.h b/rsync.h
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -656,12 +658,14 @@ extern int file_extra_cnt;
+@@ -660,12 +662,14 @@ extern int file_extra_cnt;
  extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
@@ -402,7 +402,7 @@ diff --git a/rsync.yo b/rsync.yo
  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
-@@ -1907,7 +1914,10 @@ quote(itemization(
+@@ -1930,7 +1937,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).
@@ -468,7 +468,7 @@ diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
 diff --git 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
  
@@ -477,25 +477,33 @@ diff --git a/tls.c b/tls.c
  static void failed(char const *what, char const *where)
  {
        fprintf(stderr, PROGRAM ": %s %s: %s\n",
-@@ -115,12 +117,29 @@ static void failed(char const *what, char const *where)
+@@ -125,12 +127,37 @@ static void failed(char const *what, char const *where)
        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) {
++              int len;
 +              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);
-+      } 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)
@@ -509,14 +517,16 @@ diff --git a/tls.c b/tls.c
        char linkbuf[4096];
  
        if (do_lstat(fname, &buf) < 0)
-@@ -159,19 +178,11 @@ static void list_file(const char *fname)
+@@ -168,30 +195,17 @@ static void list_file(const char *fname)
+       }
  
        permstring(permbuf, buf.st_mode);
+-
 -      if (buf.st_mtime) {
+-              int len;
 -              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,
@@ -524,17 +534,30 @@ diff --git a/tls.c b/tls.c
 -                      (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);
+-              }
++      if (nsec_times)
++              nsecs = (int)buf.ST_MTIME_NSEC
++      else
+ #endif
+-      } else {
+-              int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1);
+-              memset(datebuf, ' ', len);
+-              datebuf[len] = '\0';
+-      }
++              nsecs = -1;
++      storetime(mtimebuf, sizeof mtimebuf, buf.st_mtime, nsecs);
 +      if (display_atimes)
-+              storetime(atimebuf, S_ISDIR(buf.st_mode) ? 0 : buf.st_atime, sizeof atimebuf);
++              storetime(atimebuf, sizeof atimebuf, S_ISDIR(buf.st_mode) ? 0 : buf.st_atime, -1);
 +      else
 +              atimebuf[0] = '\0';
  
        /* TODO: Perhaps escape special characters in fname? */
  
-@@ -182,13 +193,14 @@ static void list_file(const char *fname)
+@@ -202,13 +216,14 @@ static void list_file(const char *fname)
                    (long)minor(buf.st_rdev));
        } else
                printf("%15s", do_big_num(buf.st_size, 1, NULL));
@@ -551,7 +574,7 @@ diff --git a/tls.c b/tls.c
    {"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 +216,7 @@ static void tls_usage(int ret)
+@@ -227,6 +242,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");
@@ -566,12 +589,12 @@ diff --git a/util.c b/util.c
        exit_cleanup(RERR_MALLOC);
  }
  
--int set_modtime(const char *fname, time_t modtime, mode_t mode)
-+int set_times(const char *fname, time_t modtime, time_t atime, mode_t mode)
+-int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
++int set_times(const char *fname, time_t modtime, uint32 mod_nsec, time_t atime, mode_t mode)
  {
- #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
+ #ifndef CAN_SET_SYMLINK_TIMES
        if (S_ISLNK(mode))
-@@ -131,9 +131,13 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
+@@ -131,9 +131,13 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
  #endif
  
        if (DEBUG_GTE(TIME, 1)) {
@@ -587,17 +610,28 @@ diff --git a/util.c b/util.c
        }
  
        if (dry_run)
-@@ -142,7 +146,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
+@@ -142,8 +146,8 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
        {
- #ifdef HAVE_UTIMES
+ #ifdef HAVE_UTIMENSAT
+               struct timespec t[2];
+-              t[0].tv_sec = 0;
+-              t[0].tv_nsec = UTIME_NOW;
++              t[0].tv_sec = atime;
++              t[0].tv_nsec = 0;
+               t[1].tv_sec = modtime;
+               t[1].tv_nsec = mod_nsec;
+               if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0)
+@@ -151,7 +155,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
+               return 0;
+ #elif defined HAVE_UTIMES || defined HAVE_LUTIMES
                struct timeval t[2];
 -              t[0].tv_sec = time(NULL);
 +              t[0].tv_sec = atime;
                t[0].tv_usec = 0;
                t[1].tv_sec = modtime;
-               t[1].tv_usec = 0;
-@@ -156,12 +160,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
-               return utimes(fname, t);
+               t[1].tv_usec = mod_nsec / 1000;
+@@ -164,12 +168,12 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
+ # endif
  #elif defined HAVE_STRUCT_UTIMBUF
                struct utimbuf tbuf;
 -              tbuf.actime = time(NULL);
index dd54b47..6927985 100644 (file)
@@ -19,7 +19,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                 (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/backup.c b/backup.c
 --- a/backup.c
 +++ b/backup.c
@@ -211,7 +211,7 @@ diff --git a/options.c b/options.c
  char *sockopts = NULL;
  char *usermap = NULL;
  char *groupmap = NULL;
-@@ -669,6 +675,8 @@ void usage(enum logcode F)
+@@ -670,6 +676,8 @@ void usage(enum logcode F)
    rprintf(F," -b, --backup                make backups (see --suffix & --backup-dir)\n");
    rprintf(F,"     --backup-dir=DIR        make backups into hierarchy based in DIR\n");
    rprintf(F,"     --suffix=SUFFIX         set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
@@ -220,7 +220,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -u, --update                skip files that are newer on the receiver\n");
    rprintf(F,"     --inplace               update destination files in-place (SEE MAN PAGE)\n");
    rprintf(F,"     --append                append data onto shorter files\n");
-@@ -968,7 +976,9 @@ static struct poptOption long_options[] = {
+@@ -969,7 +977,9 @@ static struct poptOption long_options[] = {
    {"backup",          'b', POPT_ARG_VAL,    &make_backups, 1, 0, 0 },
    {"no-backup",        0,  POPT_ARG_VAL,    &make_backups, 0, 0, 0 },
    {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
@@ -230,7 +230,7 @@ diff --git a/options.c b/options.c
    {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
    {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
    {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
-@@ -1971,6 +1981,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1972,6 +1982,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, SP_DEFAULT);
                if (backup_dir)
                        backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, SP_DEFAULT);
@@ -239,7 +239,7 @@ diff --git a/options.c b/options.c
        }
        if (daemon_filter_list.head && !am_sender) {
                filter_rule_list *elp = &daemon_filter_list;
-@@ -1992,6 +2004,14 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1993,6 +2005,14 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        if (check_filter(elp, FLOG, dir, 1) < 0)
                                goto options_rejected;
                }
@@ -254,7 +254,7 @@ diff --git a/options.c b/options.c
        }
  
        if (!backup_suffix)
-@@ -2003,6 +2023,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2004,6 +2024,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        backup_suffix);
                return 0;
        }
@@ -275,7 +275,7 @@ diff --git a/options.c b/options.c
        if (backup_dir) {
                while (*backup_dir == '.' && backup_dir[1] == '/')
                        backup_dir += 2;
-@@ -2036,6 +2070,34 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2037,6 +2071,34 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        "P *%s", backup_suffix);
                parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
        }
@@ -310,7 +310,7 @@ diff --git a/options.c b/options.c
  
        if (make_backups && !backup_dir) {
                omit_dir_times = 0; /* Implied, so avoid -O to sender. */
-@@ -2449,6 +2511,10 @@ void server_options(char **args, int *argc_p)
+@@ -2450,6 +2512,10 @@ void server_options(char **args, int *argc_p)
                args[ac++] = "--backup-dir";
                args[ac++] = backup_dir;
        }
@@ -321,7 +321,7 @@ diff --git a/options.c b/options.c
  
        /* Only send --suffix if it specifies a non-default value. */
        if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
-@@ -2457,7 +2523,14 @@ void server_options(char **args, int *argc_p)
+@@ -2458,7 +2524,14 @@ void server_options(char **args, int *argc_p)
                        goto oom;
                args[ac++] = arg;
        }
index 02fc67c..63a611f 100644 (file)
@@ -25,7 +25,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                  (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/errcode.h b/errcode.h
 --- a/errcode.h
 +++ b/errcode.h
@@ -52,7 +52,7 @@ diff --git a/log.c b/log.c
 diff --git a/main.c b/main.c
 --- a/main.c
 +++ b/main.c
-@@ -169,8 +169,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
+@@ -175,8 +175,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
                        *exit_code_ptr = RERR_TERMINATED;
                else
                        *exit_code_ptr = RERR_WAITCHILD;
@@ -65,7 +65,7 @@ diff --git a/main.c b/main.c
  }
  
  void write_del_stats(int f)
-@@ -1401,6 +1404,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
+@@ -1407,6 +1410,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
                                break;
                        }
                }
@@ -80,7 +80,7 @@ diff --git a/main.c b/main.c
        }
  #endif
  #ifndef HAVE_SIGACTION
-@@ -1459,6 +1470,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
+@@ -1465,6 +1476,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
  }
  #endif
  
@@ -93,7 +93,7 @@ diff --git a/main.c b/main.c
  
  int main(int argc,char *argv[])
  {
-@@ -1481,6 +1498,11 @@ int main(int argc,char *argv[])
+@@ -1487,6 +1504,11 @@ int main(int argc,char *argv[])
        SIGACTMASK(SIGFPE, rsync_panic_handler);
        SIGACTMASK(SIGABRT, rsync_panic_handler);
        SIGACTMASK(SIGBUS, rsync_panic_handler);
index 4fa0844..3e8748d 100644 (file)
@@ -16,7 +16,7 @@ To use this patch, run these commands for a successful build:
     ./configure                               (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/checksum.c b/checksum.c
 --- a/checksum.c
 +++ b/checksum.c
@@ -41,7 +41,7 @@ diff --git a/clientserver.c b/clientserver.c
  extern int io_timeout;
  extern int no_detach;
  extern int write_batch;
-@@ -862,6 +864,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -871,6 +873,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        } else if (am_root < 0) /* Treat --fake-super from client as --super. */
                am_root = 2;
  
@@ -86,8 +86,8 @@ diff --git a/flist.c b/flist.c
  extern struct stats stats;
  extern char *filesfrom_host;
  extern char *usermap, *groupmap;
-@@ -87,6 +91,12 @@ extern int filesfrom_convert;
- extern iconv_t ic_send, ic_recv;
+@@ -95,6 +99,12 @@ extern iconv_t ic_send, ic_recv;
+ #endif
  #endif
  
 +#define RSYNCSUMS_FILE ".rsyncsums"
@@ -99,7 +99,7 @@ diff --git a/flist.c b/flist.c
  #define PTR_SIZE (sizeof (struct file_struct *))
  
  int io_error;
-@@ -127,7 +137,11 @@ static char tmp_sum[MAX_DIGEST_LEN];
+@@ -136,7 +146,11 @@ static char tmp_sum[MAX_DIGEST_LEN];
  static char empty_sum[MAX_DIGEST_LEN];
  static int flist_count_offset; /* for --delete --progress */
  
@@ -112,7 +112,7 @@ diff --git a/flist.c b/flist.c
  static void output_flist(struct file_list *flist);
  
  void init_flist(void)
-@@ -342,6 +356,238 @@ static void flist_done_allocating(struct file_list *flist)
+@@ -351,6 +365,238 @@ static void flist_done_allocating(struct file_list *flist)
                flist->pool_boundary = ptr;
  }
  
@@ -351,7 +351,7 @@ diff --git a/flist.c b/flist.c
  /* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
   * F_PATHNAME(), or (2) "NULL, dir, dirlen" to chdir() to the supplied dir,
   * with dir == NULL taken to be the starting directory, and dirlen < 0
-@@ -1114,7 +1360,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1142,7 +1388,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                              STRUCT_STAT *stp, int flags, int filter_level)
  {
        static char *lastdir;
@@ -360,7 +360,7 @@ diff --git a/flist.c b/flist.c
        struct file_struct *file;
        char thisname[MAXPATHLEN];
        char linkname[MAXPATHLEN];
-@@ -1260,9 +1506,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1288,9 +1534,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                        memcpy(lastdir, thisname, len);
                        lastdir[len] = '\0';
                        lastdir_len = len;
@@ -378,7 +378,7 @@ diff --git a/flist.c b/flist.c
        basename_len = strlen(basename) + 1; /* count the '\0' */
  
  #ifdef SUPPORT_LINKS
-@@ -1276,11 +1529,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1308,11 +1561,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                extra_len += EXTRA_LEN;
  #endif
  
@@ -392,7 +392,7 @@ diff --git a/flist.c b/flist.c
  
  #if EXTRA_ROUNDING > 0
        if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
-@@ -1357,8 +1607,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1395,8 +1645,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                return NULL;
        }
  
@@ -409,8 +409,8 @@ diff --git a/flist.c b/flist.c
  
        if (unsort_ndx)
                F_NDX(file) = stats.num_dirs;
-@@ -2472,7 +2728,7 @@ struct file_list *recv_file_list(int f)
-               flist_eof = 1;
+@@ -2518,7 +2774,7 @@ struct file_list *recv_file_list(int f)
+                       rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
        }
  
 -      flist_sort_and_clean(flist, relative_paths);
@@ -418,7 +418,7 @@ diff --git a/flist.c b/flist.c
  
        if (protocol_version < 30) {
                /* Recv the io_error flag */
-@@ -2693,7 +2949,7 @@ void flist_free(struct file_list *flist)
+@@ -2741,7 +2997,7 @@ void flist_free(struct file_list *flist)
  
  /* This routine ensures we don't have any duplicate names in our file list.
   * duplicate names can cause corruption because of the pipelining. */
@@ -427,7 +427,7 @@ diff --git a/flist.c b/flist.c
  {
        char fbuf[MAXPATHLEN];
        int i, prev_i;
-@@ -2744,7 +3000,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2792,7 +3048,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
                        /* If one is a dir and the other is not, we want to
                         * keep the dir because it might have contents in the
                         * list.  Otherwise keep the first one. */
@@ -436,7 +436,7 @@ diff --git a/flist.c b/flist.c
                                struct file_struct *fp = flist->sorted[j];
                                if (!S_ISDIR(fp->mode))
                                        keep = i, drop = j;
-@@ -2760,8 +3016,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2808,8 +3064,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
                        } else
                                keep = j, drop = i;
  
@@ -447,7 +447,7 @@ diff --git a/flist.c b/flist.c
                                        rprintf(FINFO,
                                            "removing duplicate name %s from file list (%d)\n",
                                            f_name(file, fbuf), drop + flist->ndx_start);
-@@ -2783,7 +3039,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2831,7 +3087,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
        }
        flist->high = prev_i;
  
@@ -467,7 +467,7 @@ diff --git a/generator.c b/generator.c
  extern int remove_source_files;
  extern int delay_updates;
  extern int update_only;
-@@ -522,7 +523,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -523,7 +524,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
  
  
  /* Perform our quick-check heuristic for determining if a file is unchanged. */
@@ -476,7 +476,7 @@ diff --git a/generator.c b/generator.c
  {
        if (st->st_size != F_LENGTH(file))
                return 0;
-@@ -531,7 +532,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -532,7 +533,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
           of the file time to determine whether to sync */
        if (always_checksum > 0 && S_ISREG(st->st_mode)) {
                char sum[MAX_DIGEST_LEN];
@@ -488,7 +488,7 @@ diff --git a/generator.c b/generator.c
                return memcmp(sum, F_SUM(file), checksum_len) == 0;
        }
  
-@@ -795,7 +799,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -796,7 +800,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                        match_level = 1;
                        /* FALL THROUGH */
                case 1:
@@ -497,7 +497,7 @@ diff --git a/generator.c b/generator.c
                                continue;
                        best_match = j;
                        match_level = 2;
-@@ -1074,7 +1078,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1082,7 +1086,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
         * --ignore-non-existing, daemon exclude, or mkdir failure. */
        static struct file_struct *skip_dir = NULL;
        static struct file_list *fuzzy_dirlist = NULL;
@@ -506,7 +506,7 @@ diff --git a/generator.c b/generator.c
        struct file_struct *fuzzy_file = NULL;
        int fd = -1, f_copy = -1;
        stat_x sx, real_sx;
-@@ -1158,8 +1162,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1166,8 +1170,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                flist_free(fuzzy_dirlist);
                                fuzzy_dirlist = NULL;
                        }
@@ -517,7 +517,7 @@ diff --git a/generator.c b/generator.c
  #ifdef SUPPORT_ACLS
                        if (!preserve_perms)
                                dflt_perms = default_perms_for_dir(dn);
-@@ -1167,10 +1171,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1175,10 +1179,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                }
                parent_dirname = dn;
  
@@ -537,7 +537,7 @@ diff --git a/generator.c b/generator.c
                }
  
                statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
-@@ -1616,7 +1625,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1601,7 +1610,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                ;
        else if (fnamecmp_type == FNAMECMP_FUZZY)
                ;
@@ -549,7 +549,7 @@ diff --git a/generator.c b/generator.c
 diff --git a/hlink.c b/hlink.c
 --- a/hlink.c
 +++ b/hlink.c
-@@ -413,7 +413,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
+@@ -410,7 +410,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
                                }
                                break;
                        }
@@ -577,7 +577,7 @@ diff --git a/itypes.h b/itypes.h
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -132,6 +132,7 @@ typedef struct {
+@@ -133,6 +133,7 @@ typedef struct {
  /* NOTE: update this macro if the last char* variable changes! */
  #define LOCAL_STRING_COUNT() (offsetof(local_vars, uid) / sizeof (char*) + 1)
  
@@ -585,7 +585,7 @@ diff --git a/loadparm.c b/loadparm.c
        int max_connections;
        int max_verbosity;
        int syslog_facility;
-@@ -204,6 +205,7 @@ static const all_vars Defaults = {
+@@ -205,6 +206,7 @@ static const all_vars Defaults = {
   /* temp_dir; */              NULL,
   /* uid; */                   NULL,
  
@@ -593,7 +593,7 @@ diff --git a/loadparm.c b/loadparm.c
   /* max_connections; */               0,
   /* max_verbosity; */         1,
   /* syslog_facility; */               LOG_DAEMON,
-@@ -305,6 +307,13 @@ static struct enum_list enum_facilities[] = {
+@@ -306,6 +308,13 @@ static struct enum_list enum_facilities[] = {
        { -1, NULL }
  };
  
@@ -607,7 +607,7 @@ diff --git a/loadparm.c b/loadparm.c
  static struct parm_struct parm_table[] =
  {
   {"address",           P_STRING, P_GLOBAL,&Vars.g.bind_address,        NULL,0},
-@@ -315,6 +324,7 @@ static struct parm_struct parm_table[] =
+@@ -316,6 +325,7 @@ static struct parm_struct parm_table[] =
  
   {"auth users",        P_STRING, P_LOCAL, &Vars.l.auth_users,          NULL,0},
   {"charset",           P_STRING, P_LOCAL, &Vars.l.charset,             NULL,0},
@@ -615,7 +615,7 @@ diff --git a/loadparm.c b/loadparm.c
   {"comment",           P_STRING, P_LOCAL, &Vars.l.comment,             NULL,0},
   {"dont compress",     P_STRING, P_LOCAL, &Vars.l.dont_compress,       NULL,0},
   {"exclude from",      P_STRING, P_LOCAL, &Vars.l.exclude_from,        NULL,0},
-@@ -419,6 +429,7 @@ FN_LOCAL_STRING(lp_secrets_file, secrets_file)
+@@ -470,6 +480,7 @@ FN_LOCAL_STRING(lp_secrets_file, secrets_file)
  FN_LOCAL_STRING(lp_temp_dir, temp_dir)
  FN_LOCAL_STRING(lp_uid, uid)
  
@@ -634,7 +634,7 @@ diff --git a/options.c b/options.c
  int max_delete = INT_MIN;
  OFF_T max_size = 0;
  OFF_T min_size = 0;
-@@ -661,6 +662,7 @@ void usage(enum logcode F)
+@@ -662,6 +663,7 @@ void usage(enum logcode F)
    rprintf(F," -q, --quiet                 suppress non-error messages\n");
    rprintf(F,"     --no-motd               suppress daemon-mode MOTD (see manpage caveat)\n");
    rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
@@ -642,7 +642,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)\n");
    rprintf(F,"     --no-OPTION             turn off an implied OPTION (e.g. --no-D)\n");
    rprintf(F," -r, --recursive             recurse into directories\n");
-@@ -798,7 +800,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -799,7 +801,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
        OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
        OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG,
@@ -651,7 +651,7 @@ diff --git a/options.c b/options.c
        OPT_SERVER, OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -933,6 +935,7 @@ static struct poptOption long_options[] = {
+@@ -934,6 +936,7 @@ static struct poptOption long_options[] = {
    {"checksum",        'c', POPT_ARG_VAL,    &always_checksum, 1, 0, 0 },
    {"no-checksum",      0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
    {"no-c",             0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
@@ -659,7 +659,7 @@ diff --git a/options.c b/options.c
    {"block-size",      'B', POPT_ARG_LONG,   &block_size, 0, 0, 0 },
    {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
    {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
-@@ -1631,6 +1634,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1632,6 +1635,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        }
                        break;
  
@@ -683,7 +683,7 @@ diff --git a/options.c b/options.c
                case OPT_INFO:
                        arg = poptGetOptArg(pc);
                        parse_output_words(info_words, info_levels, arg, USER_PRIORITY);
-@@ -1831,6 +1851,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1832,6 +1852,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
        }
  #endif
  
@@ -696,8 +696,8 @@ diff --git a/options.c b/options.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -716,6 +716,10 @@ extern int xattrs_ndx;
- #define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
+@@ -723,6 +723,10 @@ extern int xattrs_ndx;
+ #define F_SUM(f) ((char*)OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) \
                                    + SUM_EXTRA_CNT - 1))
  
 +/* These are only valid on an entry read from a checksum file. */
@@ -707,7 +707,7 @@ diff --git a/rsync.h b/rsync.h
  /* Some utility defines: */
  #define F_IS_ACTIVE(f) (f)->basename[0]
  #define F_IS_HLINKED(f) ((f)->flags & FLAG_HLINKED)
-@@ -903,6 +907,13 @@ typedef struct {
+@@ -911,6 +915,13 @@ typedef struct {
        char fname[1]; /* has variable size */
  } relnamecache;
  
@@ -794,7 +794,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -292,6 +292,17 @@ locking on this file to ensure that the max connections limit is not
+@@ -312,6 +312,17 @@ locking on this file to ensure that the max connections limit is not
  exceeded for the modules sharing the lock file.
  The default is tt(/var/run/rsyncd.lock).
  
index 9de9e96..22bf310 100644 (file)
@@ -29,7 +29,7 @@ diff --git a/flist.c b/flist.c
  extern int am_root;
  extern int am_server;
  extern int am_daemon;
-@@ -99,6 +100,9 @@ extern iconv_t ic_send, ic_recv;
+@@ -107,6 +108,9 @@ extern iconv_t ic_send, ic_recv;
  
  #define PTR_SIZE (sizeof (struct file_struct *))
  
@@ -39,7 +39,7 @@ diff --git a/flist.c b/flist.c
  int io_error;
  int checksum_len;
  dev_t filesystem_dev; /* used to implement -x */
-@@ -137,8 +141,13 @@ static char tmp_sum[MAX_DIGEST_LEN];
+@@ -146,8 +150,13 @@ static char tmp_sum[MAX_DIGEST_LEN];
  static char empty_sum[MAX_DIGEST_LEN];
  static int flist_count_offset; /* for --delete --progress */
  
@@ -53,7 +53,7 @@ diff --git a/flist.c b/flist.c
  } *csum_cache = NULL;
  
  static void flist_sort_and_clean(struct file_list *flist, int flags);
-@@ -356,7 +365,79 @@ static void flist_done_allocating(struct file_list *flist)
+@@ -365,7 +374,79 @@ static void flist_done_allocating(struct file_list *flist)
                flist->pool_boundary = ptr;
  }
  
@@ -134,7 +134,7 @@ diff --git a/flist.c b/flist.c
  {
        int slot, slots = am_sender ? 1 : basis_dir_cnt + 1;
  
-@@ -370,6 +451,9 @@ void reset_checksum_cache()
+@@ -379,6 +460,9 @@ void reset_checksum_cache()
                struct file_list *flist = csum_cache[slot].flist;
  
                if (flist) {
@@ -144,7 +144,7 @@ diff --git a/flist.c b/flist.c
                        /* Reset the pool memory and empty the file-list array. */
                        pool_free_old(flist->file_pool,
                                      pool_boundary(flist->file_pool, 0));
-@@ -380,6 +464,10 @@ void reset_checksum_cache()
+@@ -389,6 +473,10 @@ void reset_checksum_cache()
                flist->low = 0;
                flist->high = -1;
                flist->next = NULL;
@@ -155,7 +155,7 @@ diff --git a/flist.c b/flist.c
        }
  }
  
-@@ -387,7 +475,7 @@ void reset_checksum_cache()
+@@ -396,7 +484,7 @@ void reset_checksum_cache()
  static int add_checksum(struct file_list *flist, const char *dirname,
                        const char *basename, int basename_len, OFF_T file_length,
                        time_t mtime, uint32 ctime, uint32 inode,
@@ -164,7 +164,7 @@ diff --git a/flist.c b/flist.c
  {
        struct file_struct *file;
        int alloc_len, extra_len;
-@@ -404,7 +492,7 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -413,7 +501,7 @@ static int add_checksum(struct file_list *flist, const char *dirname,
        if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
                extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
  #endif
@@ -173,7 +173,7 @@ diff --git a/flist.c b/flist.c
        bp = pool_alloc(flist->file_pool, alloc_len, "add_checksum");
  
        memset(bp, 0, extra_len + FILE_STRUCT_LEN);
-@@ -413,7 +501,14 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -422,7 +510,14 @@ static int add_checksum(struct file_list *flist, const char *dirname,
        bp += FILE_STRUCT_LEN;
  
        memcpy(bp, basename, basename_len);
@@ -188,7 +188,7 @@ diff --git a/flist.c b/flist.c
        file->mode = S_IFREG;
        file->modtime = mtime;
        file->len32 = (uint32)file_length;
-@@ -442,10 +537,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -451,10 +546,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
        char line[MAXPATHLEN+1024], fbuf[MAXPATHLEN], sum[MAX_DIGEST_LEN];
        FILE *fp;
        char *cp;
@@ -201,7 +201,7 @@ diff --git a/flist.c b/flist.c
        int dlen = dirname ? strlcpy(fbuf, dirname, sizeof fbuf) : 0;
  
        if (dlen >= (int)(sizeof fbuf - 1 - RSYNCSUMS_LEN))
-@@ -466,7 +562,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -475,7 +571,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
        while (fgets(line, sizeof line, fp)) {
                cp = line;
                if (protocol_version >= 30) {
@@ -210,7 +210,7 @@ diff --git a/flist.c b/flist.c
                        if (*cp == '=')
                                while (*++cp == '=') {}
                        else
-@@ -477,7 +573,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -486,7 +582,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
                }
  
                if (*cp == '=') {
@@ -226,7 +226,7 @@ diff --git a/flist.c b/flist.c
                } else {
                        for (i = 0; i < checksum_len*2; i++, cp++) {
                                int x;
-@@ -495,13 +598,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -504,13 +607,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
                                else
                                        sum[i/2] = x << 4;
                        }
@@ -242,7 +242,7 @@ diff --git a/flist.c b/flist.c
                        if (*cp == '=')
                                while (*++cp == '=') {}
                        else
-@@ -551,24 +655,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -560,24 +664,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
                        continue;
  
                strlcpy(fbuf+dlen, cp, sizeof fbuf - dlen);
@@ -357,7 +357,7 @@ diff --git a/flist.c b/flist.c
                read_checksums(slot, flist, file->dirname);
        }
  
-@@ -580,12 +772,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file,
+@@ -589,12 +781,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file,
                 && (checksum_files & CSF_LAX
                  || (F_CTIME(fp) == (uint32)stp->st_ctime
                   && F_INODE(fp) == (uint32)stp->st_ino))) {
@@ -390,7 +390,7 @@ diff --git a/flist.c b/flist.c
  }
  
  /* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
-@@ -1461,6 +1672,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1489,6 +1700,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
                if (ignore_perishable)
                        non_perishable_cnt++;
@@ -399,7 +399,7 @@ diff --git a/flist.c b/flist.c
                return NULL;
        }
  
-@@ -1507,13 +1720,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1535,13 +1748,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                        lastdir[len] = '\0';
                        lastdir_len = len;
                        if (checksum_files && am_sender && flist)
@@ -415,7 +415,7 @@ diff --git a/flist.c b/flist.c
                }
        }
        basename_len = strlen(basename) + 1; /* count the '\0' */
-@@ -1609,7 +1822,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1647,7 +1860,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
  
        if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
                if (flist && checksum_files)
@@ -424,7 +424,7 @@ diff --git a/flist.c b/flist.c
                else
                        file_checksum(thisname, st.st_size, tmp_sum);
                if (sender_keeps_checksum)
-@@ -1981,6 +2194,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -2020,6 +2233,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
  
        closedir(d);
  
@@ -434,9 +434,9 @@ diff --git a/flist.c b/flist.c
        if (f >= 0 && recurse && !divert_dirs) {
                int i, end = flist->used - 1;
                /* send_if_directory() bumps flist->used, so use "end". */
-@@ -2599,6 +2815,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
-       } else
-               flist_eof = 1;
+@@ -2643,6 +2859,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+                       rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
+       }
  
 +      if (checksum_files & CSF_UPDATE && flist_eof)
 +              reset_checksum_cache(0); /* writes any last updates */
@@ -447,7 +447,7 @@ diff --git a/flist.c b/flist.c
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
-@@ -111,6 +111,7 @@ static int dir_tweaking;
+@@ -112,6 +112,7 @@ static int dir_tweaking;
  static int symlink_timeset_failed_flags;
  static int need_retouch_dir_times;
  static int need_retouch_dir_perms;
@@ -455,7 +455,7 @@ diff --git a/generator.c b/generator.c
  static const char *solo_file = NULL;
  
  enum nonregtype {
-@@ -533,7 +534,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
+@@ -534,7 +535,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
        if (always_checksum > 0 && S_ISREG(st->st_mode)) {
                char sum[MAX_DIGEST_LEN];
                if (checksum_files && slot >= 0)
@@ -464,7 +464,7 @@ diff --git a/generator.c b/generator.c
                else
                        file_checksum(fn, st->st_size, sum);
                return memcmp(sum, F_SUM(file), checksum_len) == 0;
-@@ -1177,7 +1178,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1185,7 +1186,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
                        }
                        if (checksum_files) {
@@ -474,7 +474,7 @@ diff --git a/generator.c b/generator.c
                        }
                        need_new_dirscan = 0;
                }
-@@ -1335,6 +1337,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1343,6 +1345,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        else
                                change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
                }
@@ -482,7 +482,7 @@ diff --git a/generator.c b/generator.c
                goto cleanup;
        }
  
-@@ -1631,6 +1634,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1616,6 +1619,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        handle_partial_dir(partialptr, PDIR_DELETE);
                }
                set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
@@ -491,7 +491,7 @@ diff --git a/generator.c b/generator.c
                if (itemizing)
                        itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
  #ifdef SUPPORT_HARD_LINKS
-@@ -2063,6 +2068,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2120,6 +2125,7 @@ void generate_files(int f_out, const char *local_name)
                                } else
                                        change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
                        }
@@ -499,7 +499,7 @@ diff --git a/generator.c b/generator.c
                }
                for (i = cur_flist->low; i <= cur_flist->high; i++) {
                        struct file_struct *file = cur_flist->sorted[i];
-@@ -2157,6 +2163,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2214,6 +2220,9 @@ void generate_files(int f_out, const char *local_name)
                        wait_for_receiver();
        }
  
@@ -512,7 +512,7 @@ diff --git a/generator.c b/generator.c
 diff --git a/io.c b/io.c
 --- a/io.c
 +++ b/io.c
-@@ -49,6 +49,7 @@ extern int list_only;
+@@ -52,6 +52,7 @@ extern int list_only;
  extern int read_batch;
  extern int protect_args;
  extern int checksum_seed;
@@ -520,7 +520,7 @@ diff --git a/io.c b/io.c
  extern int protocol_version;
  extern int remove_source_files;
  extern int preserve_hard_links;
-@@ -161,6 +162,9 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
+@@ -875,6 +876,9 @@ static void got_flist_entry_status(enum festatus status, int ndx)
                                flist_ndx_push(&hlink_list, ndx);
                                flist->in_progress++;
                        }
@@ -533,7 +533,7 @@ diff --git a/io.c b/io.c
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -311,6 +311,10 @@ static struct enum_list enum_csum_modes[] = {
+@@ -312,6 +312,10 @@ static struct enum_list enum_csum_modes[] = {
        { CSF_IGNORE_FILES, "none" },
        { CSF_LAX_MODE, "lax" },
        { CSF_STRICT_MODE, "strict" },
@@ -547,7 +547,7 @@ diff --git a/loadparm.c b/loadparm.c
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
-@@ -1636,7 +1636,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1637,7 +1637,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
  
                case OPT_SUMFILES:
                        arg = poptGetOptArg(pc);
@@ -575,7 +575,7 @@ diff --git a/receiver.c b/receiver.c
  extern int inplace;
  extern int delay_updates;
  extern mode_t orig_umask;
-@@ -344,7 +345,7 @@ static void handle_delayed_updates(char *local_name)
+@@ -376,7 +377,7 @@ static void handle_delayed_updates(char *local_name)
                                        "rename failed for %s (from %s)",
                                        full_fname(fname), partialptr);
                        } else {
@@ -584,7 +584,7 @@ diff --git a/receiver.c b/receiver.c
                                 || (preserve_hard_links && F_IS_HLINKED(file)))
                                        send_msg_int(MSG_SUCCESS, ndx);
                                handle_partial_dir(partialptr, PDIR_DELETE);
-@@ -794,7 +795,7 @@ int recv_files(int f_in, char *local_name)
+@@ -829,7 +830,7 @@ int recv_files(int f_in, int f_out, char *local_name)
                case 2:
                        break;
                case 1:
@@ -596,7 +596,7 @@ diff --git a/receiver.c b/receiver.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -909,6 +909,8 @@ typedef struct {
+@@ -917,6 +917,8 @@ typedef struct {
  
  #define CSF_ENABLE (1<<1)
  #define CSF_LAX (1<<2)
@@ -628,7 +628,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -295,13 +295,15 @@ The default is tt(/var/run/rsyncd.lock).
+@@ -315,13 +315,15 @@ The default is tt(/var/run/rsyncd.lock).
  dit(bf(checksum files)) This parameter tells rsync to make use of any cached
  checksum information it finds in per-directory .rsyncsums files when the
  current transfer is using the bf(--checksum) option.  The value can be set
index 7de37d7..23febb9 100644 (file)
@@ -8,11 +8,11 @@ To use this patch, run these commands for a successful build:
     ./configure                               (optional if already run)
     make
 
-based-on: 06886d36cfdcfb94f0d67f8964d22ee7c7872018
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/flist.c b/flist.c
 --- a/flist.c
 +++ b/flist.c
-@@ -1277,7 +1277,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1309,7 +1309,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
  #endif
  
        if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
@@ -25,7 +25,7 @@ diff --git a/flist.c b/flist.c
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
-@@ -531,7 +531,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -532,7 +532,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
           of the file time to determine whether to sync */
        if (always_checksum > 0 && S_ISREG(st->st_mode)) {
                char sum[MAX_DIGEST_LEN];
@@ -278,7 +278,7 @@ diff --git a/xattrs.c b/xattrs.c
                                continue;
                }
  
-@@ -914,6 +922,39 @@ int del_def_xattr_acl(const char *fname)
+@@ -947,6 +955,39 @@ int del_def_xattr_acl(const char *fname)
  }
  #endif
  
index b44198a..891ecc1 100644 (file)
@@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build:
     ./configure                      (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -20,7 +20,7 @@ diff --git a/generator.c b/generator.c
  extern int preserve_specials;
  extern int preserve_hard_links;
  extern int preserve_executability;
-@@ -1511,7 +1512,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1496,7 +1497,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
  
@@ -40,7 +40,7 @@ diff --git a/options.c b/options.c
  int preserve_links = 0;
  int preserve_hard_links = 0;
  int preserve_acls = 0;
-@@ -694,6 +695,7 @@ void usage(enum logcode F)
+@@ -695,6 +696,7 @@ void usage(enum logcode F)
    rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
    rprintf(F," -g, --group                 preserve group\n");
    rprintf(F,"     --devices               preserve device files (super-user only)\n");
@@ -48,7 +48,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --specials              preserve special files\n");
    rprintf(F," -D                          same as --devices --specials\n");
    rprintf(F," -t, --times                 preserve modification times\n");
-@@ -862,6 +864,7 @@ static struct poptOption long_options[] = {
+@@ -863,6 +865,7 @@ static struct poptOption long_options[] = {
    {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
    {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
    {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
@@ -56,7 +56,7 @@ diff --git a/options.c b/options.c
    {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
    {"no-specials",      0,  POPT_ARG_VAL,    &preserve_specials, 0, 0, 0 },
    {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
-@@ -2626,6 +2629,9 @@ void server_options(char **args, int *argc_p)
+@@ -2627,6 +2630,9 @@ void server_options(char **args, int *argc_p)
        else if (remove_source_files)
                args[ac++] = "--remove-sent-files";
  
@@ -77,7 +77,7 @@ diff --git a/rsync.c b/rsync.c
  extern int am_root;
  extern int am_server;
  extern int am_sender;
-@@ -330,7 +331,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
+@@ -380,7 +381,8 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
  
        if (iflags & ITEM_TRANSFER) {
                int i = ndx - cur_flist->ndx_start;
@@ -90,7 +90,7 @@ diff --git a/rsync.c b/rsync.c
 diff --git a/sender.c b/sender.c
 --- a/sender.c
 +++ b/sender.c
-@@ -328,6 +328,20 @@ void send_files(int f_in, int f_out)
+@@ -336,6 +336,20 @@ void send_files(int f_in, int f_out)
                        exit_cleanup(RERR_PROTOCOL);
                }
  
index 6134ce7..fb0116c 100644 (file)
@@ -12,7 +12,7 @@ based-on: patch/fileflags
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -44,6 +44,7 @@ extern int force_change;
+@@ -46,6 +46,7 @@ extern int force_change;
  extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
@@ -20,7 +20,7 @@ diff --git a/compat.c b/compat.c
  extern int preserve_fileflags;
  extern int preserve_acls;
  extern int preserve_xattrs;
-@@ -62,7 +63,7 @@ extern char *iconv_opt;
+@@ -64,7 +65,7 @@ extern char *iconv_opt;
  #endif
  
  /* These index values are for the file-list's extra-attribute array. */
@@ -29,7 +29,7 @@ diff --git a/compat.c b/compat.c
  
  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)
+@@ -141,6 +142,8 @@ void setup_protocol(int f_out,int f_in)
                uid_ndx = ++file_extra_cnt;
        if (preserve_gid)
                gid_ndx = ++file_extra_cnt;
@@ -49,7 +49,7 @@ diff --git a/flist.c b/flist.c
  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,
+@@ -406,7 +407,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
  #endif
                            int ndx, int first_ndx)
  {
@@ -58,10 +58,10 @@ diff --git a/flist.c b/flist.c
        static mode_t mode;
  #ifdef SUPPORT_FILEFLAGS
        static uint32 fileflags;
-@@ -506,6 +507,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-               xflags |= XMIT_SAME_TIME;
-       else
+@@ -517,6 +518,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                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)
@@ -72,28 +72,28 @@ diff --git a/flist.c b/flist.c
  
  #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != 0) {
-@@ -588,6 +596,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-               else
-                       write_int(f, modtime);
+@@ -601,6 +609,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
-@@ -680,7 +690,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)
+@@ -692,7 +702,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;
-@@ -819,6 +829,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
-               } else
-                       modtime = read_int(f);
-       }
+@@ -837,6 +847,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);
@@ -110,7 +110,7 @@ diff --git a/flist.c b/flist.c
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
  
-@@ -979,6 +1002,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -1007,6 +1030,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                F_GROUP(file) = gid;
                file->flags |= gid_flags;
        }
@@ -119,7 +119,7 @@ diff --git a/flist.c b/flist.c
        if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
  
-@@ -1368,6 +1393,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1406,6 +1431,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;
@@ -139,7 +139,7 @@ diff --git a/generator.c b/generator.c
  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)
+@@ -420,6 +421,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;
  
@@ -153,7 +153,7 @@ diff --git a/generator.c b/generator.c
  #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
+@@ -463,6 +471,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;
@@ -166,7 +166,7 @@ diff --git a/generator.c b/generator.c
  #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,
+@@ -1030,6 +1044,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];
@@ -174,7 +174,7 @@ diff --git a/generator.c b/generator.c
        int64 len;
        int colwidth = human_readable ? 14 : 11;
  
-@@ -1037,10 +1052,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1045,10 +1060,11 @@ static void list_file_entry(struct file_struct *f)
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
@@ -189,7 +189,7 @@ diff --git a/generator.c b/generator.c
        } else
  #endif
        if (missing_args == 2 && f->mode == 0) {
-@@ -1048,9 +1064,11 @@ static void list_file_entry(struct file_struct *f)
+@@ -1056,9 +1072,11 @@ static void list_file_entry(struct file_struct *f)
                        colwidth + 31, "*missing",
                        f_name(f, NULL));
        } else {
@@ -203,7 +203,7 @@ diff --git a/generator.c b/generator.c
        }
  }
  
-@@ -1141,6 +1159,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1149,6 +1167,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        return;
                }
        }
@@ -267,7 +267,7 @@ diff --git a/options.c b/options.c
  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");
@@ -275,7 +275,7 @@ diff --git a/options.c b/options.c
    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 },
@@ -285,7 +285,7 @@ diff --git a/options.c b/options.c
    {"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 },
-@@ -2332,6 +2337,8 @@ void server_options(char **args, int *argc_p)
+@@ -2333,6 +2338,8 @@ void server_options(char **args, int *argc_p)
                argstr[x++] = 'D';
        if (preserve_times)
                argstr[x++] = 't';
@@ -297,7 +297,7 @@ diff --git a/options.c b/options.c
 diff --git 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,
+@@ -521,6 +521,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                else
                        file->flags |= FLAG_TIME_FAILED;
        }
@@ -312,7 +312,7 @@ diff --git a/rsync.c b/rsync.c
  
        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,
+@@ -671,7 +679,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
@@ -321,7 +321,7 @@ diff --git a/rsync.c b/rsync.c
  
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
-@@ -650,7 +658,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -702,7 +710,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
  
    do_set_file_attrs:
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
@@ -333,15 +333,17 @@ diff --git a/rsync.c b/rsync.c
 diff --git 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_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. */
-@@ -157,6 +158,7 @@
+@@ -160,6 +161,7 @@
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
  #define ATTRS_DELAY_IMMUTABLE (1<<2)
@@ -349,7 +351,7 @@ diff --git a/rsync.h b/rsync.h
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -173,7 +175,7 @@
+@@ -176,7 +178,7 @@
  #define FNAMECMP_FUZZY                0x83
  
  /* For use by the itemize_changes code */
@@ -358,7 +360,7 @@ diff --git a/rsync.h b/rsync.h
  #define ITEM_REPORT_CHANGE (1<<1)
  #define ITEM_REPORT_SIZE (1<<2)     /* regular files only */
  #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */
-@@ -681,6 +683,7 @@ extern int file_extra_cnt;
+@@ -685,6 +687,7 @@ extern int file_extra_cnt;
  extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
@@ -366,7 +368,7 @@ diff --git a/rsync.h b/rsync.h
  extern int fileflags_ndx;
  extern int acls_ndx;
  extern int xattrs_ndx;
-@@ -688,6 +691,7 @@ extern int xattrs_ndx;
+@@ -692,6 +695,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)
@@ -374,7 +376,7 @@ diff --git a/rsync.h b/rsync.h
  #define DEV_EXTRA_CNT 2
  #define DIRNODE_EXTRA_CNT 3
  #define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
-@@ -955,6 +959,7 @@ typedef struct {
+@@ -963,6 +967,7 @@ typedef struct {
  
  typedef struct {
      STRUCT_STAT st;
@@ -403,7 +405,7 @@ diff --git a/rsync.yo b/rsync.yo
  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
-@@ -1880,7 +1884,7 @@ with older versions of rsync, but that also turns on the output of other
+@@ -1903,7 +1907,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
@@ -412,7 +414,7 @@ diff --git a/rsync.yo b/rsync.yo
  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.
-@@ -1939,6 +1943,8 @@ quote(itemization(
+@@ -1962,6 +1966,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.
@@ -424,7 +426,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/syscall.c b/syscall.c
 --- a/syscall.c
 +++ b/syscall.c
-@@ -37,6 +37,11 @@ extern int force_change;
+@@ -38,6 +38,11 @@ extern int force_change;
  extern int preserve_perms;
  extern int preserve_executability;
  
@@ -436,7 +438,7 @@ diff --git a/syscall.c b/syscall.c
  #define RETURN_ERROR_IF(x,e) \
        do { \
                if (x) { \
-@@ -394,3 +399,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
+@@ -437,3 +442,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
        return lseek(fd, offset, whence);
  #endif
  }
@@ -518,7 +520,7 @@ diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
 diff --git 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
  
@@ -527,25 +529,33 @@ diff --git a/tls.c b/tls.c
  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);
  }
  
-+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) {
++              int len;
 +              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);
-+      } 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)
@@ -566,14 +576,15 @@ diff --git a/tls.c b/tls.c
  #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) {
+-              int len;
 -              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,
@@ -581,17 +592,26 @@ diff --git a/tls.c b/tls.c
 -                      (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)
-+              storetime(crtimebuf, crtime, sizeof crtimebuf);
++              storetime(crtimebuf, sizeof crtimebuf, crtime, -1);
 +      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));
@@ -608,7 +628,7 @@ diff --git a/tls.c b/tls.c
    {"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");
index bfe357d..74db784 100644 (file)
@@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                 (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/exclude.c b/exclude.c
 --- a/exclude.c
 +++ b/exclude.c
@@ -88,7 +88,7 @@ diff --git a/exclude.c b/exclude.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -152,6 +152,7 @@
+@@ -155,6 +155,7 @@
  #define XFLG_ANCHORED2ABS     (1<<2) /* leading slash indicates absolute */
  #define XFLG_ABS_IF_SLASH     (1<<3) /* leading or interior slash is absolute */
  #define XFLG_DIR2WILD3                (1<<4) /* dir/ match gets trailing *** added */
index b49fcce..b0e4ded 100644 (file)
@@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/access.c b/access.c
 --- a/access.c
 +++ b/access.c
index c58d21d..863d073 100644 (file)
@@ -14,7 +14,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                 (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -26,7 +26,7 @@ diff --git a/generator.c b/generator.c
  extern int size_only;
  extern OFF_T max_size;
  extern OFF_T min_size;
-@@ -524,6 +525,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -525,6 +526,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
  /* Perform our quick-check heuristic for determining if a file is unchanged. */
  int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
  {
@@ -47,7 +47,7 @@ diff --git a/options.c b/options.c
  int daemon_bwlimit = 0;
  int bwlimit = 0;
  int fuzzy_basis = 0;
-@@ -739,6 +740,7 @@ void usage(enum logcode F)
+@@ -740,6 +741,7 @@ void usage(enum logcode F)
    rprintf(F," -I, --ignore-times          don't skip files that match in size and mod-time\n");
    rprintf(F," -M, --remote-option=OPTION  send OPTION to the remote side only\n");
    rprintf(F,"     --size-only             skip files that match in size\n");
@@ -55,7 +55,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --modify-window=NUM     compare mod-times with reduced accuracy\n");
    rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
-@@ -887,6 +889,7 @@ static struct poptOption long_options[] = {
+@@ -888,6 +890,7 @@ static struct poptOption long_options[] = {
    {"chmod",            0,  POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
    {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
    {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
@@ -63,7 +63,7 @@ diff --git a/options.c b/options.c
    {"one-file-system", 'x', POPT_ARG_NONE,   0, 'x', 0, 0 },
    {"no-one-file-system",'x',POPT_ARG_VAL,   &one_file_system, 0, 0, 0 },
    {"no-x",            'x', POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
-@@ -2510,6 +2513,9 @@ void server_options(char **args, int *argc_p)
+@@ -2511,6 +2514,9 @@ void server_options(char **args, int *argc_p)
        else if (missing_args == 1 && !am_sender)
                args[ac++] = "--ignore-missing-args";
  
diff --git a/db.diff b/db.diff
index 4cf967e..7b5b19b 100644 (file)
--- a/db.diff
+++ b/db.diff
@@ -23,7 +23,7 @@ To use this patch, run these commands for a successful build:
     ./configure                               (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/Makefile.in b/Makefile.in
 --- a/Makefile.in
 +++ b/Makefile.in
@@ -123,7 +123,7 @@ diff --git a/clientserver.c b/clientserver.c
  extern char *bind_address;
  extern char *config_file;
  extern char *logfile_format;
-@@ -642,6 +645,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -668,6 +671,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
  
        log_init(1);
  
@@ -132,8 +132,8 @@ diff --git a/clientserver.c b/clientserver.c
 +
  #ifdef HAVE_PUTENV
        if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
-               char *modname, *modpath, *hostaddr, *hostname, *username;
-@@ -850,6 +856,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+               int status;
+@@ -859,6 +865,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
  
        am_server = 1; /* Don't let someone try to be tricky. */
        quiet = 0;
@@ -147,7 +147,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -312,7 +312,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
+@@ -322,7 +322,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
      sys/un.h sys/attr.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
      netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
      sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h \
@@ -156,7 +156,7 @@ diff --git a/configure.in b/configure.in
  AC_HEADER_MAJOR
  
  AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
-@@ -977,6 +977,29 @@ if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"
+@@ -1004,6 +1004,29 @@ if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"
      fi
  fi
  
@@ -190,7 +190,7 @@ diff --git a/db.c b/db.c
 new file mode 100644
 --- /dev/null
 +++ b/db.c
-@@ -0,0 +1,566 @@
+@@ -0,0 +1,567 @@
 +/*
 + * Routines to access extended file info via DB.
 + *
@@ -212,6 +212,7 @@ new file mode 100644
 +
 +#include "rsync.h"
 +#include "ifuncs.h"
++#include "itypes.h"
 +
 +#if defined HAVE_MYSQL_MYSQL_H && defined HAVE_LIBMYSQLCLIENT
 +#define USE_MYSQL
@@ -768,7 +769,7 @@ diff --git a/flist.c b/flist.c
  extern int eol_nulls;
  extern int relative_paths;
  extern int implied_dirs;
-@@ -1276,11 +1277,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1308,11 +1309,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                extra_len += EXTRA_LEN;
  #endif
  
@@ -782,7 +783,7 @@ diff --git a/flist.c b/flist.c
  
  #if EXTRA_ROUNDING > 0
        if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
-@@ -1357,8 +1355,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1395,8 +1393,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                return NULL;
        }
  
@@ -797,7 +798,7 @@ diff --git a/flist.c b/flist.c
  
        if (unsort_ndx)
                F_NDX(file) = stats.num_dirs;
-@@ -2020,6 +2022,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2061,6 +2063,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                     | (eol_nulls || reading_remotely ? RL_EOL_NULLS : 0);
        int implied_dot_dir = 0;
  
@@ -818,7 +819,7 @@ diff --git a/generator.c b/generator.c
  extern int append_mode;
  extern int make_backups;
  extern int csum_length;
-@@ -531,7 +532,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -532,7 +533,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
           of the file time to determine whether to sync */
        if (always_checksum > 0 && S_ISREG(st->st_mode)) {
                char sum[MAX_DIGEST_LEN];
@@ -828,7 +829,7 @@ diff --git a/generator.c b/generator.c
                return memcmp(sum, F_SUM(file), checksum_len) == 0;
        }
  
-@@ -2017,6 +2019,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2074,6 +2076,9 @@ void generate_files(int f_out, const char *local_name)
                        : "enabled");
        }
  
@@ -841,7 +842,7 @@ diff --git a/generator.c b/generator.c
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -107,6 +107,7 @@ typedef struct {
+@@ -108,6 +108,7 @@ typedef struct {
        char *auth_users;
        char *charset;
        char *comment;
@@ -849,7 +850,7 @@ diff --git a/loadparm.c b/loadparm.c
        char *dont_compress;
        char *exclude;
        char *exclude_from;
-@@ -181,6 +182,7 @@ static const all_vars Defaults = {
+@@ -182,6 +183,7 @@ static const all_vars Defaults = {
   /* auth_users; */            NULL,
   /* charset; */               NULL,
   /* comment; */               NULL,
@@ -857,7 +858,7 @@ diff --git a/loadparm.c b/loadparm.c
   /* dont_compress; */         DEFAULT_DONT_COMPRESS,
   /* exclude; */                       NULL,
   /* exclude_from; */          NULL,
-@@ -316,6 +318,7 @@ static struct parm_struct parm_table[] =
+@@ -317,6 +319,7 @@ static struct parm_struct parm_table[] =
   {"auth users",        P_STRING, P_LOCAL, &Vars.l.auth_users,          NULL,0},
   {"charset",           P_STRING, P_LOCAL, &Vars.l.charset,             NULL,0},
   {"comment",           P_STRING, P_LOCAL, &Vars.l.comment,             NULL,0},
@@ -865,7 +866,7 @@ diff --git a/loadparm.c b/loadparm.c
   {"dont compress",     P_STRING, P_LOCAL, &Vars.l.dont_compress,       NULL,0},
   {"exclude from",      P_STRING, P_LOCAL, &Vars.l.exclude_from,        NULL,0},
   {"exclude",           P_STRING, P_LOCAL, &Vars.l.exclude,             NULL,0},
-@@ -396,6 +399,7 @@ FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port)
+@@ -447,6 +450,7 @@ FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port)
  FN_LOCAL_STRING(lp_auth_users, auth_users)
  FN_LOCAL_STRING(lp_charset, charset)
  FN_LOCAL_STRING(lp_comment, comment)
@@ -876,7 +877,7 @@ diff --git a/loadparm.c b/loadparm.c
 diff --git a/main.c b/main.c
 --- a/main.c
 +++ b/main.c
-@@ -49,6 +49,7 @@ extern int copy_unsafe_links;
+@@ -50,6 +50,7 @@ extern int copy_unsafe_links;
  extern int keep_dirlinks;
  extern int preserve_hard_links;
  extern int protocol_version;
@@ -884,7 +885,7 @@ diff --git a/main.c b/main.c
  extern int file_total;
  extern int recurse;
  extern int xfer_dirs;
-@@ -74,6 +75,7 @@ extern char *filesfrom_host;
+@@ -79,6 +80,7 @@ extern char *filesfrom_host;
  extern char *partial_dir;
  extern char *dest_option;
  extern char *rsync_path;
@@ -892,7 +893,7 @@ diff --git a/main.c b/main.c
  extern char *shell_cmd;
  extern char *batch_name;
  extern char *password_file;
-@@ -1577,6 +1579,9 @@ int main(int argc,char *argv[])
+@@ -1584,6 +1586,9 @@ int main(int argc,char *argv[])
                exit_cleanup(RERR_SYNTAX);
        }
  
@@ -913,7 +914,7 @@ diff --git a/options.c b/options.c
  int eol_nulls = 0;
  int protect_args = 0;
  int human_readable = 1;
-@@ -566,6 +567,7 @@ static void print_rsync_version(enum logcode f)
+@@ -567,6 +568,7 @@ static void print_rsync_version(enum logcode f)
        char const *links = "no ";
        char const *iconv = "no ";
        char const *ipv6 = "no ";
@@ -921,8 +922,8 @@ diff --git a/options.c b/options.c
        STRUCT_STAT *dumstat;
  
  #if SUBPROTOCOL_VERSION != 0
-@@ -599,6 +601,11 @@ static void print_rsync_version(enum logcode f)
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+@@ -600,6 +602,11 @@ static void print_rsync_version(enum logcode f)
+ #ifdef CAN_SET_SYMLINK_TIMES
        symtimes = "";
  #endif
 +#if defined HAVE_MYSQL_MYSQL_H && defined HAVE_LIBMYSQLCLIENT
@@ -933,7 +934,7 @@ diff --git a/options.c b/options.c
  
        rprintf(f, "%s  version %s  protocol version %d%s\n",
                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -612,8 +619,8 @@ static void print_rsync_version(enum logcode f)
+@@ -613,8 +620,8 @@ static void print_rsync_version(enum logcode f)
                (int)(sizeof (int64) * 8));
        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
                got_socketpair, hardlinks, links, ipv6, have_inplace);
@@ -944,7 +945,7 @@ diff --git a/options.c b/options.c
  
  #ifdef MAINTAINER_MODE
        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -661,6 +668,7 @@ void usage(enum logcode F)
+@@ -662,6 +669,7 @@ void usage(enum logcode F)
    rprintf(F," -q, --quiet                 suppress non-error messages\n");
    rprintf(F,"     --no-motd               suppress daemon-mode MOTD (see manpage caveat)\n");
    rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
@@ -952,7 +953,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)\n");
    rprintf(F,"     --no-OPTION             turn off an implied OPTION (e.g. --no-D)\n");
    rprintf(F," -r, --recursive             recurse into directories\n");
-@@ -933,6 +941,7 @@ static struct poptOption long_options[] = {
+@@ -934,6 +942,7 @@ static struct poptOption long_options[] = {
    {"checksum",        'c', POPT_ARG_VAL,    &always_checksum, 1, 0, 0 },
    {"no-checksum",      0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
    {"no-c",             0,  POPT_ARG_VAL,    &always_checksum, 0, 0, 0 },
@@ -1054,7 +1055,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -281,6 +281,18 @@ is daemon.  This setting has no effect if the "log file" setting is a
+@@ -301,6 +301,18 @@ is daemon.  This setting has no effect if the "log file" setting is a
  non-empty string (either set in the per-modules settings, or inherited
  from the global settings).
  
index 0e1e9cb..7b2b4c1 100644 (file)
@@ -24,7 +24,7 @@ based-on: patch/detect-renamed
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
-@@ -469,7 +469,9 @@ static int fattr_find(struct file_struct *f, char *fname)
+@@ -470,7 +470,9 @@ static int fattr_find(struct file_struct *f, char *fname)
                                continue;
                        }
                }
@@ -35,7 +35,7 @@ diff --git a/generator.c b/generator.c
                diff = u_strcmp(fmid->basename, f->basename);
                if (diff == 0) {
                        good_match = mid;
-@@ -1800,6 +1802,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1785,6 +1787,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                fnamecmp = partialptr;
                fnamecmp_type = FNAMECMP_PARTIAL_DIR;
                statret = 0;
@@ -60,7 +60,7 @@ diff --git a/generator.c b/generator.c
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
-@@ -744,6 +744,8 @@ void usage(enum logcode F)
+@@ -745,6 +745,8 @@ void usage(enum logcode F)
    rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
    rprintf(F,"     --detect-renamed        try to find renamed files to speed up the transfer\n");
@@ -69,7 +69,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
    rprintf(F,"     --copy-dest=DIR         ... and include copies of unchanged files\n");
    rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
-@@ -939,7 +941,9 @@ static struct poptOption long_options[] = {
+@@ -940,7 +942,9 @@ static struct poptOption long_options[] = {
    {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
    {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
    {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
@@ -80,7 +80,7 @@ diff --git a/options.c b/options.c
    {"fuzzy",           'y', POPT_ARG_VAL,    &fuzzy_basis, 1, 0, 0 },
    {"no-fuzzy",         0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
    {"no-y",             0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
-@@ -2497,8 +2501,14 @@ void server_options(char **args, int *argc_p)
+@@ -2498,8 +2502,14 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = "--super";
                if (size_only)
                        args[ac++] = "--size-only";
@@ -109,7 +109,7 @@ diff --git a/rsync.yo b/rsync.yo
       --compare-dest=DIR      also compare received files relative to DIR
       --copy-dest=DIR         ... and include copies of unchanged files
       --link-dest=DIR         hardlink to files in DIR when unchanged
-@@ -1640,6 +1642,17 @@ the bf(--partial-dir) option, that directory will be used instead.  These
+@@ -1641,6 +1643,17 @@ the bf(--partial-dir) option, that directory will be used instead.  These
  potential alternate-basis files will be removed as the transfer progresses.
  This option conflicts with bf(--inplace) and bf(--append).
  
index 819ca2b..f881083 100644 (file)
@@ -32,11 +32,11 @@ TODO:
   a file that can't use it, while missing out on giving it to a file
   that could use it.
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -40,6 +40,7 @@ extern int checksum_seed;
+@@ -42,6 +42,7 @@ extern int checksum_seed;
  extern int basis_dir_cnt;
  extern int prune_empty_dirs;
  extern int protocol_version;
@@ -44,7 +44,7 @@ diff --git a/compat.c b/compat.c
  extern int protect_args;
  extern int preserve_uid;
  extern int preserve_gid;
-@@ -119,6 +120,7 @@ void set_allow_inc_recurse(void)
+@@ -122,6 +123,7 @@ void set_allow_inc_recurse(void)
                allow_inc_recurse = 0;
        else if (!am_sender
         && (delete_before || delete_after
@@ -112,7 +112,7 @@ diff --git a/flist.c b/flist.c
  extern int protocol_version;
  extern int sanitize_paths;
  extern int munge_symlinks;
-@@ -124,6 +125,8 @@ static int64 tmp_dev, tmp_ino;
+@@ -133,6 +134,8 @@ static int64 tmp_dev, tmp_ino;
  #endif
  static char tmp_sum[MAX_DIGEST_LEN];
  
@@ -121,7 +121,7 @@ diff --git a/flist.c b/flist.c
  static char empty_sum[MAX_DIGEST_LEN];
  static int flist_count_offset; /* for --delete --progress */
  
-@@ -291,6 +294,45 @@ static int is_excluded(const char *fname, int is_dir, int filter_level)
+@@ -300,6 +303,45 @@ static int is_excluded(const char *fname, int is_dir, int filter_level)
        return 0;
  }
  
@@ -167,7 +167,7 @@ diff --git a/flist.c b/flist.c
  static void send_directory(int f, struct file_list *flist,
                           char *fbuf, int len, int flags);
  
-@@ -2474,6 +2516,25 @@ struct file_list *recv_file_list(int f)
+@@ -2520,6 +2562,25 @@ struct file_list *recv_file_list(int f)
  
        flist_sort_and_clean(flist, relative_paths);
  
@@ -204,7 +204,7 @@ diff --git a/generator.c b/generator.c
  extern int whole_file;
  extern int list_only;
  extern int read_batch;
-@@ -98,10 +99,12 @@ extern uid_t our_uid;
+@@ -99,10 +100,12 @@ extern char *tmpdir;
  extern char *basis_dir[MAX_BASIS_DIRS+1];
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  extern filter_rule_list filter_list, daemon_filter_list;
@@ -217,7 +217,7 @@ diff --git a/generator.c b/generator.c
  static int deldelay_size = 0, deldelay_cnt = 0;
  static char *deldelay_buf = NULL;
  static int deldelay_fd = -1;
-@@ -181,6 +184,8 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
+@@ -182,6 +185,8 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
                if (!flush_delete_delay())
                        return 0;
        }
@@ -226,7 +226,7 @@ diff --git a/generator.c b/generator.c
  
        return 1;
  }
-@@ -272,13 +277,18 @@ static void do_delayed_deletions(char *delbuf)
+@@ -273,13 +278,18 @@ static void do_delayed_deletions(char *delbuf)
   * all the --delete-WHEN options.  Note that the fbuf pointer must point to a
   * MAXPATHLEN buffer with the name of the directory in it (the functions we
   * call will append names onto the end, but the old dir value will be restored
@@ -249,7 +249,7 @@ diff --git a/generator.c b/generator.c
        int save_uid_ndx = uid_ndx;
  
        if (!fbuf) {
-@@ -293,17 +303,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -294,17 +304,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                maybe_send_keepalive();
  
        if (io_error && !ignore_errors) {
@@ -277,7 +277,7 @@ diff --git a/generator.c b/generator.c
        if (one_file_system) {
                if (file->flags & FLAG_TOP_DIR)
                        filesystem_dev = *fs_dev;
-@@ -316,6 +331,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -317,6 +332,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
  
        dirlist = get_dirlist(fbuf, dlen, 0);
  
@@ -292,7 +292,7 @@ diff --git a/generator.c b/generator.c
        /* If an item in dirlist is not found in flist, delete it
         * from the filesystem. */
        for (i = dirlist->used; i--; ) {
-@@ -328,6 +351,10 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -329,6 +352,10 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                                        f_name(fp, NULL));
                        continue;
                }
@@ -303,7 +303,7 @@ diff --git a/generator.c b/generator.c
                /* Here we want to match regardless of file type.  Replacement
                 * of a file with one of another type is handled separately by
                 * a delete_item call with a DEL_MAKE_ROOM flag. */
-@@ -336,14 +363,19 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -337,14 +364,19 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                        if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
                                flags |= DEL_NO_UID_WRITE;
                        f_name(fp, delbuf);
@@ -327,7 +327,7 @@ diff --git a/generator.c b/generator.c
        flist_free(dirlist);
  
        if (!save_uid_ndx) {
-@@ -381,14 +413,122 @@ static void do_delete_pass(void)
+@@ -382,14 +414,122 @@ static void do_delete_pass(void)
                 || !S_ISDIR(st.st_mode))
                        continue;
  
@@ -451,8 +451,8 @@ diff --git a/generator.c b/generator.c
 +
  int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
  {
- #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
-@@ -1042,6 +1182,7 @@ static void list_file_entry(struct file_struct *f)
+ #ifndef CAN_SET_SYMLINK_TIMES
+@@ -1050,6 +1190,7 @@ static void list_file_entry(struct file_struct *f)
        }
  }
  
@@ -460,7 +460,7 @@ diff --git a/generator.c b/generator.c
  static int phase = 0;
  static int dflt_perms;
  
-@@ -1321,9 +1462,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1329,9 +1470,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                }
                else if (delete_during && f_out != -1 && !phase
                    && !(file->flags & FLAG_MISSING_DIR)) {
@@ -476,7 +476,7 @@ diff --git a/generator.c b/generator.c
                                change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
                }
                goto cleanup;
-@@ -1605,8 +1749,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1590,8 +1734,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        goto cleanup;
                }
  #endif
@@ -492,7 +492,7 @@ diff --git a/generator.c b/generator.c
                rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
                        full_fname(fname));
                goto cleanup;
-@@ -1998,6 +2148,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -2055,6 +2205,12 @@ void generate_files(int f_out, const char *local_name)
        if (DEBUG_GTE(GENR, 1))
                rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
  
@@ -505,7 +505,7 @@ diff --git a/generator.c b/generator.c
        if (delete_before && !solo_file && cur_flist->used > 0)
                do_delete_pass();
        if (delete_during == 2) {
-@@ -2008,7 +2164,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2065,7 +2221,7 @@ void generate_files(int f_out, const char *local_name)
        }
        info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;
  
@@ -514,7 +514,7 @@ diff --git a/generator.c b/generator.c
                whole_file = 0;
        if (DEBUG_GTE(FLIST, 1)) {
                rprintf(FINFO, "delta-transmission %s\n",
-@@ -2050,7 +2206,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2107,7 +2263,7 @@ void generate_files(int f_out, const char *local_name)
                                                dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
                                        } else
                                                dirdev = MAKEDEV(0, 0);
@@ -523,7 +523,7 @@ diff --git a/generator.c b/generator.c
                                } else
                                        change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
                        }
-@@ -2097,7 +2253,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2154,7 +2310,21 @@ void generate_files(int f_out, const char *local_name)
        } while ((cur_flist = cur_flist->next) != NULL);
  
        if (delete_during)
@@ -557,7 +557,7 @@ diff --git a/options.c b/options.c
  int implied_dirs = 1;
  int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
  int numeric_ids = 0;
-@@ -742,6 +743,7 @@ void usage(enum logcode F)
+@@ -743,6 +744,7 @@ void usage(enum logcode F)
    rprintf(F,"     --modify-window=NUM     compare mod-times with reduced accuracy\n");
    rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
@@ -565,7 +565,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
    rprintf(F,"     --copy-dest=DIR         ... and include copies of unchanged files\n");
    rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
-@@ -937,6 +939,7 @@ static struct poptOption long_options[] = {
+@@ -938,6 +940,7 @@ static struct poptOption long_options[] = {
    {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
    {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
    {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
@@ -573,7 +573,7 @@ diff --git a/options.c b/options.c
    {"fuzzy",           'y', POPT_ARG_VAL,    &fuzzy_basis, 1, 0, 0 },
    {"no-fuzzy",         0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
    {"no-y",             0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
-@@ -2122,7 +2125,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2123,7 +2126,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                inplace = 1;
        }
  
@@ -582,7 +582,7 @@ diff --git a/options.c b/options.c
                partial_dir = tmp_partialdir;
  
        if (inplace) {
-@@ -2131,6 +2134,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2132,6 +2135,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        snprintf(err_buf, sizeof err_buf,
                                 "--%s cannot be used with --%s\n",
                                 append_mode ? "append" : "inplace",
@@ -590,7 +590,7 @@ diff --git a/options.c b/options.c
                                 delay_updates ? "delay-updates" : "partial-dir");
                        return 0;
                }
-@@ -2493,6 +2497,8 @@ void server_options(char **args, int *argc_p)
+@@ -2494,6 +2498,8 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = "--super";
                if (size_only)
                        args[ac++] = "--size-only";
@@ -603,7 +603,7 @@ diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
 @@ -242,7 +242,7 @@ enum msgcode {
- #define NDX_DEL_STATS -2
+ #define NDX_DEL_STATS -3
  #define NDX_FLIST_OFFSET -101
  
 -/* For calling delete_item() and delete_dir_contents(). */
@@ -630,7 +630,7 @@ diff --git a/rsync.yo b/rsync.yo
       --compare-dest=DIR      also compare received files relative to DIR
       --copy-dest=DIR         ... and include copies of unchanged files
       --link-dest=DIR         hardlink to files in DIR when unchanged
-@@ -1624,6 +1625,21 @@ Note that the use of the bf(--delete) option might get rid of any potential
+@@ -1625,6 +1626,21 @@ Note that the use of the bf(--delete) option might get rid of any potential
  fuzzy-match files, so either use bf(--delete-after) or specify some
  filename exclusions if you need to prevent this.
  
@@ -655,7 +655,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/util.c b/util.c
 --- a/util.c
 +++ b/util.c
-@@ -1112,6 +1112,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
+@@ -1088,6 +1088,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
        return path;
  }
  
index 753ad16..bf3cce5 100644 (file)
@@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                 (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -19,7 +19,7 @@ diff --git a/generator.c b/generator.c
  extern int human_readable;
  extern int ignore_existing;
  extern int ignore_non_existing;
-@@ -1546,6 +1547,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1531,6 +1532,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
  
@@ -33,7 +33,7 @@ diff --git a/generator.c b/generator.c
        fnamecmp = fname;
        fnamecmp_type = FNAMECMP_FNAME;
  
-@@ -1908,6 +1916,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1961,6 +1969,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
                        ignore_existing = -ignore_existing;
                        ignore_non_existing = -ignore_non_existing;
                        update_only = -update_only;
@@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c
                        always_checksum = -always_checksum;
                        size_only = -size_only;
                        append_mode = -append_mode;
-@@ -1933,6 +1942,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1986,6 +1995,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
                        ignore_existing = -ignore_existing;
                        ignore_non_existing = -ignore_non_existing;
                        update_only = -update_only;
@@ -60,7 +60,7 @@ diff --git a/options.c b/options.c
  int cvs_exclude = 0;
  int dry_run = 0;
  int do_xfers = 1;
-@@ -670,6 +671,7 @@ void usage(enum logcode F)
+@@ -671,6 +672,7 @@ void usage(enum logcode F)
    rprintf(F,"     --backup-dir=DIR        make backups into hierarchy based in DIR\n");
    rprintf(F,"     --suffix=SUFFIX         set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
    rprintf(F," -u, --update                skip files that are newer on the receiver\n");
@@ -68,7 +68,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --inplace               update destination files in-place (SEE MAN PAGE)\n");
    rprintf(F,"     --append                append data onto shorter files\n");
    rprintf(F,"     --append-verify         like --append, but with old data in file checksum\n");
-@@ -891,6 +893,7 @@ static struct poptOption long_options[] = {
+@@ -892,6 +894,7 @@ static struct poptOption long_options[] = {
    {"no-one-file-system",'x',POPT_ARG_VAL,   &one_file_system, 0, 0, 0 },
    {"no-x",            'x', POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
    {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
index e4639e2..b7028da 100644 (file)
@@ -69,7 +69,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/checksum.c b/checksum.c
 --- a/checksum.c
 +++ b/checksum.c
@@ -104,12 +104,12 @@ diff --git a/cleanup.c b/cleanup.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -553,7 +553,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
+@@ -574,7 +574,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
      setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
      strerror putenv iconv_open locale_charset nl_langinfo getxattr \
      extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
--    initgroups)
-+    initgroups posix_fadvise64)
+-    initgroups utimensat)
++    initgroups utimensat posix_fadvise64)
  
  dnl cygwin iconv.h defines iconv_open as libiconv_open
  if test x"$ac_cv_func_iconv_open" != x"yes"; then
@@ -132,7 +132,7 @@ diff --git a/fileio.c b/fileio.c
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
-@@ -112,6 +112,10 @@ static int need_retouch_dir_times;
+@@ -113,6 +113,10 @@ static int need_retouch_dir_times;
  static int need_retouch_dir_perms;
  static const char *solo_file = NULL;
  
@@ -154,7 +154,7 @@ diff --git a/options.c b/options.c
  int cvs_exclude = 0;
  int dry_run = 0;
  int do_xfers = 1;
-@@ -670,6 +671,9 @@ void usage(enum logcode F)
+@@ -671,6 +672,9 @@ void usage(enum logcode F)
    rprintf(F,"     --backup-dir=DIR        make backups into hierarchy based in DIR\n");
    rprintf(F,"     --suffix=SUFFIX         set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
    rprintf(F," -u, --update                skip files that are newer on the receiver\n");
@@ -164,7 +164,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --inplace               update destination files in-place (SEE MAN PAGE)\n");
    rprintf(F,"     --append                append data onto shorter files\n");
    rprintf(F,"     --append-verify         like --append, but with old data in file checksum\n");
-@@ -891,6 +895,9 @@ static struct poptOption long_options[] = {
+@@ -892,6 +896,9 @@ static struct poptOption long_options[] = {
    {"no-one-file-system",'x',POPT_ARG_VAL,   &one_file_system, 0, 0, 0 },
    {"no-x",            'x', POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
    {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
@@ -174,7 +174,7 @@ diff --git a/options.c b/options.c
    {"existing",         0,  POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
    {"ignore-non-existing",0,POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
    {"ignore-existing",  0,  POPT_ARG_NONE,   &ignore_existing, 0, 0, 0 },
-@@ -2252,6 +2259,11 @@ void server_options(char **args, int *argc_p)
+@@ -2253,6 +2260,11 @@ void server_options(char **args, int *argc_p)
        if (!am_sender)
                args[ac++] = "--sender";
  
@@ -197,9 +197,9 @@ diff --git a/receiver.c b/receiver.c
 +#define close(fd) fadv_close(fd)
 +#endif
 +
- /*
-  * get_tmpname() - create a tmp filename for a given filename
-  *
+ #define TMPNAME_SUFFIX ".XXXXXX"
+ #define TMPNAME_SUFFIX_LEN ((int)sizeof TMPNAME_SUFFIX - 1)
+ #define MAX_UNIQUE_NUMBER 999999
 diff --git a/rsync.yo b/rsync.yo
 --- a/rsync.yo
 +++ b/rsync.yo
@@ -212,8 +212,8 @@ diff --git a/rsync.yo b/rsync.yo
   -W, --whole-file            copy files whole (w/o delta-xfer algorithm)
   -x, --one-file-system       don't cross filesystem boundaries
 @@ -1127,6 +1128,10 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
- filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
+ filesystem. It seems to have problems seeking over null regions,
+ and ends up corrupting the files.
  
 +dit(bf(--drop-cache)) Tell the OS to drop the caching of the file data.  This
 +prevents rsync from filling up the filesystem cache.  This can sometimes help
@@ -225,9 +225,9 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/sender.c b/sender.c
 --- a/sender.c
 +++ b/sender.c
-@@ -44,6 +44,10 @@ extern int write_batch;
- extern struct stats stats;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
+@@ -47,6 +47,10 @@ extern struct file_list *cur_flist, *first_flist, *dir_flist;
BOOL extra_flist_sending_enabled;
  
 +#ifdef HAVE_POSIX_FADVISE64
 +#define close(fd) fadv_close(fd)
@@ -239,8 +239,8 @@ diff --git a/sender.c b/sender.c
 diff --git a/t_unsafe.c b/t_unsafe.c
 --- a/t_unsafe.c
 +++ b/t_unsafe.c
-@@ -27,6 +27,7 @@ int dry_run = 0;
- int am_root = 0;
+@@ -28,6 +28,7 @@ int am_root = 0;
+ int am_sender = 1;
  int read_only = 0;
  int list_only = 0;
 +int drop_cache = 0;
index 561e17e..6f60dca 100644 (file)
@@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build:
     ./configure
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/Makefile.in b/Makefile.in
 --- a/Makefile.in
 +++ b/Makefile.in
@@ -33,7 +33,7 @@ diff --git a/Makefile.in b/Makefile.in
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -40,9 +40,11 @@ extern int checksum_seed;
+@@ -42,9 +42,11 @@ extern int checksum_seed;
  extern int basis_dir_cnt;
  extern int prune_empty_dirs;
  extern int protocol_version;
@@ -45,7 +45,7 @@ diff --git a/compat.c b/compat.c
  extern int preserve_acls;
  extern int preserve_xattrs;
  extern int need_messages_from_generator;
-@@ -60,7 +62,7 @@ extern char *iconv_opt;
+@@ -62,7 +64,7 @@ extern char *iconv_opt;
  #endif
  
  /* These index values are for the file-list's extra-attribute array. */
@@ -54,7 +54,7 @@ diff --git a/compat.c b/compat.c
  
  int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
  int sender_symlink_iconv = 0; /* sender should convert symlink content */
-@@ -136,6 +138,8 @@ void setup_protocol(int f_out,int f_in)
+@@ -139,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;
@@ -66,12 +66,12 @@ diff --git a/compat.c b/compat.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -553,7 +553,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
+@@ -574,7 +574,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
      setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
      strerror putenv iconv_open locale_charset nl_langinfo getxattr \
      extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
--    initgroups)
-+    initgroups chflags)
+-    initgroups utimensat)
++    initgroups utimensat chflags)
  
  dnl cygwin iconv.h defines iconv_open as libiconv_open
  if test x"$ac_cv_func_iconv_open" != x"yes"; then
@@ -134,7 +134,7 @@ diff --git a/flist.c b/flist.c
  extern int missing_args;
  extern int uid_ndx;
  extern int gid_ndx;
-@@ -398,6 +399,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -407,6 +408,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
  {
        static time_t modtime;
        static mode_t mode;
@@ -144,7 +144,7 @@ diff --git a/flist.c b/flist.c
  #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
  #endif
-@@ -441,6 +445,14 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -450,6 +454,14 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                xflags |= XMIT_SAME_MODE;
        else
                mode = file->mode;
@@ -159,8 +159,8 @@ diff --git a/flist.c b/flist.c
  
        if (preserve_devices && IS_DEVICE(mode)) {
                if (protocol_version < 28) {
-@@ -578,6 +590,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
-       }
+@@ -591,6 +603,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+               write_varint(f, F_MOD_NSEC(file));
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
 +#ifdef SUPPORT_FILEFLAGS
@@ -170,7 +170,7 @@ diff --git a/flist.c b/flist.c
        if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
                if (protocol_version < 30)
                        write_int(f, uid);
-@@ -666,6 +682,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -678,6 +694,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
  {
        static int64 modtime;
        static mode_t mode;
@@ -180,7 +180,7 @@ diff --git a/flist.c b/flist.c
  #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
  #endif
-@@ -805,6 +824,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -823,6 +842,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
  
        if (chmod_modes && !S_ISLNK(mode) && mode)
                mode = tweak_mode(mode, chmod_modes);
@@ -191,7 +191,7 @@ diff --git a/flist.c b/flist.c
  
        if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
                if (protocol_version < 30)
-@@ -946,6 +969,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -974,6 +997,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        }
  #endif
        file->mode = mode;
@@ -202,7 +202,7 @@ diff --git a/flist.c b/flist.c
        if (preserve_uid)
                F_OWNER(file) = uid;
        if (preserve_gid) {
-@@ -1333,6 +1360,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1371,6 +1398,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        }
  #endif
        file->mode = st.st_mode;
@@ -213,14 +213,6 @@ diff --git a/flist.c b/flist.c
        if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
                F_OWNER(file) = st.st_uid;
        if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
-@@ -1476,6 +1507,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
- #endif
- #ifdef SUPPORT_XATTRS
-               if (preserve_xattrs) {
-+                      sx.st.st_mode = file->mode;
-                       if (get_xattr(fname, &sx) < 0) {
-                               io_error |= IOERR_GENERAL;
-                               return NULL;
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -235,7 +227,7 @@ diff --git a/generator.c b/generator.c
  extern int uid_ndx;
  extern int gid_ndx;
  extern int delete_mode;
-@@ -406,6 +408,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -407,6 +409,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
         && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
                return 0;
  
@@ -247,7 +239,7 @@ diff --git a/generator.c b/generator.c
        if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
                return 0;
  
-@@ -471,6 +478,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -472,6 +479,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
                    && sxp->st.st_gid != (gid_t)F_GROUP(file))
                        iflags |= ITEM_REPORT_GROUP;
@@ -259,7 +251,7 @@ diff --git a/generator.c b/generator.c
  #ifdef SUPPORT_ACLS
                if (preserve_acls && !S_ISLNK(file->mode)) {
                        if (!ACL_READY(*sxp))
-@@ -1258,6 +1270,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1266,6 +1278,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        file->mode = dest_mode(file->mode, sx.st.st_mode,
                                               dflt_perms, statret == 0);
                }
@@ -270,7 +262,7 @@ diff --git a/generator.c b/generator.c
                if (statret != 0 && basis_dir[0] != NULL) {
                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
                                              itemizing, code);
-@@ -1298,10 +1314,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1306,10 +1322,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                /* We need to ensure that the dirs in the transfer have writable
                 * permissions during the time we are putting files within them.
                 * This is then fixed after the transfer is done. */
@@ -287,7 +279,7 @@ diff --git a/generator.c b/generator.c
                                rsyserr(FERROR_XFER, errno,
                                        "failed to modify permissions on %s",
                                        full_fname(fname));
-@@ -1336,6 +1357,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1344,6 +1365,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms,
                                       exists);
        }
@@ -298,7 +290,7 @@ diff --git a/generator.c b/generator.c
  
  #ifdef SUPPORT_HARD_LINKS
        if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
-@@ -1865,13 +1890,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1918,13 +1943,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                        continue;
                fname = f_name(file, NULL);
                if (!(file->mode & S_IWUSR))
@@ -308,8 +300,8 @@ diff --git a/generator.c b/generator.c
                        STRUCT_STAT st;
                        if (link_stat(fname, &st, 0) == 0
                         && cmp_time(st.st_mtime, file->modtime) != 0)
--                              set_modtime(fname, file->modtime, file->mode);
-+                              set_modtime(fname, file->modtime, file->mode, 0);
+-                              set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode);
++                              set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode, 0);
                }
 +#ifdef SUPPORT_FORCE_CHANGE
 +              if (force_change && F_FFLAGS(file) & force_change)
@@ -349,7 +341,7 @@ diff --git a/options.c b/options.c
  int io_timeout = 0;
  int prune_empty_dirs = 0;
  int use_qsort = 0;
-@@ -566,6 +568,7 @@ static void print_rsync_version(enum logcode f)
+@@ -567,6 +569,7 @@ static void print_rsync_version(enum logcode f)
        char const *links = "no ";
        char const *iconv = "no ";
        char const *ipv6 = "no ";
@@ -357,8 +349,8 @@ diff --git a/options.c b/options.c
        STRUCT_STAT *dumstat;
  
  #if SUBPROTOCOL_VERSION != 0
-@@ -599,6 +602,9 @@ static void print_rsync_version(enum logcode f)
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+@@ -600,6 +603,9 @@ static void print_rsync_version(enum logcode f)
+ #ifdef CAN_SET_SYMLINK_TIMES
        symtimes = "";
  #endif
 +#ifdef SUPPORT_FILEFLAGS
@@ -367,7 +359,7 @@ diff --git a/options.c b/options.c
  
        rprintf(f, "%s  version %s  protocol version %d%s\n",
                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -612,8 +618,8 @@ static void print_rsync_version(enum logcode f)
+@@ -613,8 +619,8 @@ static void print_rsync_version(enum logcode f)
                (int)(sizeof (int64) * 8));
        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
                got_socketpair, hardlinks, links, ipv6, have_inplace);
@@ -378,7 +370,7 @@ diff --git a/options.c b/options.c
  
  #ifdef MAINTAINER_MODE
        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -683,6 +689,9 @@ void usage(enum logcode F)
+@@ -684,6 +690,9 @@ void usage(enum logcode F)
    rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
    rprintf(F," -H, --hard-links            preserve hard links\n");
    rprintf(F," -p, --perms                 preserve permissions\n");
@@ -388,7 +380,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -E, --executability         preserve the file's executability\n");
    rprintf(F,"     --chmod=CHMOD           affect file and/or directory permissions\n");
  #ifdef SUPPORT_ACLS
-@@ -722,7 +731,12 @@ void usage(enum logcode F)
+@@ -723,7 +732,12 @@ void usage(enum logcode F)
    rprintf(F,"     --ignore-missing-args   ignore missing source args without error\n");
    rprintf(F,"     --delete-missing-args   delete missing source args from destination\n");
    rprintf(F,"     --ignore-errors         delete even if there are I/O errors\n");
@@ -402,7 +394,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
    rprintf(F,"     --max-size=SIZE         don't transfer any file larger than SIZE\n");
    rprintf(F,"     --min-size=SIZE         don't transfer any file smaller than SIZE\n");
-@@ -835,6 +849,10 @@ static struct poptOption long_options[] = {
+@@ -836,6 +850,10 @@ static struct poptOption long_options[] = {
    {"perms",           'p', POPT_ARG_VAL,    &preserve_perms, 1, 0, 0 },
    {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
    {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
@@ -413,7 +405,7 @@ diff --git a/options.c b/options.c
    {"executability",   'E', POPT_ARG_NONE,   &preserve_executability, 0, 0, 0 },
    {"acls",            'A', POPT_ARG_NONE,   0, 'A', 0, 0 },
    {"no-acls",          0,  POPT_ARG_VAL,    &preserve_acls, 0, 0, 0 },
-@@ -917,6 +935,14 @@ static struct poptOption long_options[] = {
+@@ -918,6 +936,14 @@ static struct poptOption long_options[] = {
    {"remove-source-files",0,POPT_ARG_VAL,    &remove_source_files, 1, 0, 0 },
    {"force",            0,  POPT_ARG_VAL,    &force_delete, 1, 0, 0 },
    {"no-force",         0,  POPT_ARG_VAL,    &force_delete, 0, 0, 0 },
@@ -428,7 +420,7 @@ diff --git a/options.c b/options.c
    {"ignore-errors",    0,  POPT_ARG_VAL,    &ignore_errors, 1, 0, 0 },
    {"no-ignore-errors", 0,  POPT_ARG_VAL,    &ignore_errors, 0, 0, 0 },
    {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
-@@ -2400,6 +2426,9 @@ void server_options(char **args, int *argc_p)
+@@ -2401,6 +2427,9 @@ void server_options(char **args, int *argc_p)
        if (xfer_dirs && !recurse && delete_mode && am_sender)
                args[ac++] = "--no-r";
  
@@ -438,7 +430,7 @@ diff --git a/options.c b/options.c
        if (do_compression && def_compress_level != Z_DEFAULT_COMPRESSION) {
                if (asprintf(&arg, "--compress-level=%d", def_compress_level) < 0)
                        goto oom;
-@@ -2487,6 +2516,16 @@ void server_options(char **args, int *argc_p)
+@@ -2488,6 +2517,16 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = "--delete-excluded";
                if (force_delete)
                        args[ac++] = "--force";
@@ -466,7 +458,7 @@ diff --git a/rsync.c b/rsync.c
  extern int preserve_executability;
  extern int preserve_times;
  extern int am_root;
-@@ -378,6 +379,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
+@@ -428,6 +429,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
        return new_mode;
  }
  
@@ -506,16 +498,16 @@ diff --git a/rsync.c b/rsync.c
  int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                   const char *fnamecmp, int flags)
  {
-@@ -426,7 +460,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -476,7 +510,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                flags |= ATTRS_SKIP_MTIME;
        if (!(flags & ATTRS_SKIP_MTIME)
            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
--              int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
-+              int ret = set_modtime(fname, file->modtime, sxp->st.st_mode, ST_FLAGS(sxp->st));
+-              int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
++              int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode, ST_FLAGS(sxp->st));
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
-@@ -462,7 +496,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -512,7 +546,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                if (am_root >= 0) {
                        if (do_lchown(fname,
                            change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid,
@@ -525,7 +517,7 @@ diff --git a/rsync.c b/rsync.c
                                /* We shouldn't have attempted to change uid
                                 * or gid unless have the privilege. */
                                rsyserr(FERROR_XFER, errno, "%s %s failed",
-@@ -494,7 +529,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -546,7 +581,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
  
  #ifdef HAVE_CHMOD
        if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
@@ -534,7 +526,7 @@ diff --git a/rsync.c b/rsync.c
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno,
                                "failed to set permissions on %s",
-@@ -506,6 +541,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -558,6 +593,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
        }
  #endif
  
@@ -554,7 +546,7 @@ diff --git a/rsync.c b/rsync.c
        if (INFO_GTE(NAME, 2) && flags & ATTRS_REPORT) {
                if (updated)
                        rprintf(FCLIENT, "%s\n", fname);
-@@ -570,7 +618,8 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -622,7 +670,8 @@ int finish_transfer(const char *fname, const char *fnametmp,
  
        /* Change permissions before putting the file into place. */
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
@@ -564,7 +556,7 @@ diff --git a/rsync.c b/rsync.c
  
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
-@@ -589,6 +638,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -641,6 +690,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
        }
        if (ret == 0) {
                /* The file was moved into place (not copied), so it's done. */
@@ -578,15 +570,15 @@ diff --git a/rsync.c b/rsync.c
 diff --git 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,6 +62,7 @@
  #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_MOD_NSEC (1<<13)         /* protocols 31 - now */
 +#define XMIT_SAME_FLAGS (1<<14)               /* protocols ?? - now */
  
  /* These flags are used in the live flist data. */
  
-@@ -155,6 +156,7 @@
+@@ -158,6 +159,7 @@
  
  #define ATTRS_REPORT          (1<<0)
  #define ATTRS_SKIP_MTIME      (1<<1)
@@ -594,7 +586,7 @@ diff --git a/rsync.h b/rsync.h
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -181,6 +183,7 @@
+@@ -184,6 +186,7 @@
  #define ITEM_REPORT_GROUP (1<<6)
  #define ITEM_REPORT_ACL (1<<7)
  #define ITEM_REPORT_XATTR (1<<8)
@@ -602,7 +594,7 @@ diff --git a/rsync.h b/rsync.h
  #define ITEM_BASIS_TYPE_FOLLOWS (1<<11)
  #define ITEM_XNAME_FOLLOWS (1<<12)
  #define ITEM_IS_NEW (1<<13)
-@@ -486,6 +489,28 @@ typedef unsigned int size_t;
+@@ -490,6 +493,28 @@ typedef unsigned int size_t;
  #endif
  #endif
  
@@ -631,7 +623,7 @@ diff --git a/rsync.h b/rsync.h
  /* Find a variable that is either exactly 32-bits or longer.
   * If some code depends on 32-bit truncation, it will need to
   * take special action in a "#if SIZEOF_INT32 > 4" section. */
-@@ -656,6 +681,7 @@ extern int file_extra_cnt;
+@@ -660,6 +685,7 @@ extern int file_extra_cnt;
  extern int inc_recurse;
  extern int uid_ndx;
  extern int gid_ndx;
@@ -639,7 +631,7 @@ diff --git a/rsync.h b/rsync.h
  extern int acls_ndx;
  extern int xattrs_ndx;
  
-@@ -693,6 +719,11 @@ extern int xattrs_ndx;
+@@ -701,6 +727,11 @@ 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
@@ -722,8 +714,8 @@ diff --git a/rsync.yo b/rsync.yo
 +
  dit(bf(--chmod)) This option tells rsync to apply one or more
  comma-separated "chmod" strings to the permission of the files in the
- transfer.  The resulting value is treated as though it was the permissions
-@@ -1300,12 +1328,13 @@ display as a "*missing" entry in the bf(--list-only) output.
+ transfer.  The resulting value is treated as though it were the permissions
+@@ -1301,12 +1329,13 @@ display as a "*missing" entry in the bf(--list-only) output.
  dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files
  even when there are I/O errors.
  
@@ -740,7 +732,7 @@ diff --git a/rsync.yo b/rsync.yo
  bf(--recursive) option was also enabled.
  
  dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
-@@ -1851,7 +1880,7 @@ with older versions of rsync, but that also turns on the output of other
+@@ -1874,7 +1903,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
@@ -749,7 +741,7 @@ diff --git a/rsync.yo b/rsync.yo
  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.
-@@ -1907,7 +1936,7 @@ quote(itemization(
+@@ -1930,7 +1959,7 @@ 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).
@@ -761,15 +753,15 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/syscall.c b/syscall.c
 --- a/syscall.c
 +++ b/syscall.c
-@@ -33,6 +33,7 @@ extern int dry_run;
- extern int am_root;
+@@ -34,6 +34,7 @@ extern int am_root;
+ extern int am_sender;
  extern int read_only;
  extern int list_only;
 +extern int force_change;
  extern int preserve_perms;
  extern int preserve_executability;
  
-@@ -50,7 +51,23 @@ int do_unlink(const char *fname)
+@@ -51,7 +52,23 @@ int do_unlink(const char *fname)
  {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
@@ -793,8 +785,8 @@ diff --git a/syscall.c b/syscall.c
 +      return -1;
  }
  
- int do_symlink(const char *fname1, const char *fname2)
-@@ -69,14 +86,37 @@ int do_link(const char *fname1, const char *fname2)
+ #ifdef SUPPORT_LINKS
+@@ -112,14 +129,37 @@ int do_link(const char *fname1, const char *fname2)
  }
  #endif
  
@@ -834,7 +826,7 @@ diff --git a/syscall.c b/syscall.c
  }
  
  int do_mknod(const char *pathname, mode_t mode, dev_t dev)
-@@ -116,7 +156,7 @@ int do_mknod(const char *pathname, mode_t mode, dev_t dev)
+@@ -159,7 +199,7 @@ int do_mknod(const char *pathname, mode_t mode, dev_t dev)
                        return -1;
                close(sock);
  #ifdef HAVE_CHMOD
@@ -843,7 +835,7 @@ diff --git a/syscall.c b/syscall.c
  #else
                return 0;
  #endif
-@@ -133,7 +173,22 @@ int do_rmdir(const char *pathname)
+@@ -176,7 +216,22 @@ int do_rmdir(const char *pathname)
  {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
@@ -867,7 +859,7 @@ diff --git a/syscall.c b/syscall.c
  }
  
  int do_open(const char *pathname, int flags, mode_t mode)
-@@ -147,7 +202,7 @@ int do_open(const char *pathname, int flags, mode_t mode)
+@@ -190,7 +245,7 @@ int do_open(const char *pathname, int flags, mode_t mode)
  }
  
  #ifdef HAVE_CHMOD
@@ -876,7 +868,7 @@ diff --git a/syscall.c b/syscall.c
  {
        int code;
        if (dry_run) return 0;
-@@ -168,17 +223,74 @@ int do_chmod(const char *path, mode_t mode)
+@@ -211,17 +266,74 @@ int do_chmod(const char *path, mode_t mode)
  #endif
        } else
                code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
@@ -1002,25 +994,41 @@ diff --git a/util.c b/util.c
        exit_cleanup(RERR_MALLOC);
  }
  
--int set_modtime(const char *fname, time_t modtime, mode_t mode)
-+int set_modtime(const char *fname, time_t modtime, mode_t mode, uint32 fileflags)
+-int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
++int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags)
  {
- #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
+ #ifndef CAN_SET_SYMLINK_TIMES
        if (S_ISLNK(mode))
-@@ -140,6 +141,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
+@@ -140,15 +141,14 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
                return 0;
  
        {
 +              int ret;
- #ifdef HAVE_UTIMES
+ #ifdef HAVE_UTIMENSAT
+               struct timespec t[2];
+               t[0].tv_sec = 0;
+               t[0].tv_nsec = UTIME_NOW;
+               t[1].tv_sec = modtime;
+               t[1].tv_nsec = mod_nsec;
+-              if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0)
+-                      return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
+-              return 0;
++#define SET_THE_TIME(fn) utimensat(AT_FDCWD, fn, t, AT_SYMLINK_NOFOLLOW)
+ #elif defined HAVE_UTIMES || defined HAVE_LUTIMES
                struct timeval t[2];
                t[0].tv_sec = time(NULL);
-@@ -153,20 +155,39 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
-                       return 0;
-               }
- # endif
+@@ -156,25 +156,44 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
+               t[1].tv_sec = modtime;
+               t[1].tv_usec = mod_nsec / 1000;
+ # ifdef HAVE_LUTIMES
+-              if (lutimes(fname, t) < 0)
+-                      return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
+-              return 0;
++#define SET_THE_TIME(fn) lutimes(fn, t)
+ # else
 -              return utimes(fname, t);
 +#define SET_THE_TIME(fn) utimes(fn, t)
+ # endif
  #elif defined HAVE_STRUCT_UTIMBUF
                struct utimbuf tbuf;
                tbuf.actime = time(NULL);
@@ -1037,6 +1045,8 @@ diff --git a/util.c b/util.c
  #error No file-time-modification routine found!
  #endif
 +              ret = SET_THE_TIME(fname);
++              if (ret != 0 && S_ISLNK(mode) && errno == ENOSYS)
++                      return 1;
 +#ifdef SUPPORT_FORCE_CHANGE
 +              if (ret != 0 && force_change && errno == EPERM) {
 +                      if (fileflags == NO_FFLAGS) {
@@ -1061,30 +1071,7 @@ diff --git a/util.c b/util.c
 diff --git a/xattrs.c b/xattrs.c
 --- a/xattrs.c
 +++ b/xattrs.c
-@@ -284,6 +284,10 @@ int get_xattr(const char *fname, stat_x *sxp)
- {
-       sxp->xattr = new(item_list);
-       *sxp->xattr = empty_xattr;
-+
-+      if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode))
-+              return 0;
-+
-       if (rsync_xal_get(fname, sxp->xattr) < 0) {
-               free_xattr(sxp);
-               return -1;
-@@ -884,6 +888,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
-               return -1;
-       }
-+      if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) {
-+              errno = ENOTSUP;
-+              return -1;
-+      }
-+
-       ndx = F_XATTR(file);
-       return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp);
- }
-@@ -1000,7 +1009,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
+@@ -1033,7 +1033,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
        mode = (fst.st_mode & _S_IFMT) | (fmode & ACCESSPERMS)
             | (S_ISDIR(fst.st_mode) ? 0700 : 0600);
        if (fst.st_mode != mode)
index ffd2aeb..47a968f 100644 (file)
@@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/exclude.c b/exclude.c
 --- a/exclude.c
 +++ b/exclude.c
@@ -246,7 +246,7 @@ diff --git a/flist.c b/flist.c
  
  #ifdef ICONV_OPTION
  extern int filesfrom_convert;
-@@ -274,7 +275,8 @@ static inline int path_is_daemon_excluded(char *path, int ignore_filename)
+@@ -283,7 +284,8 @@ static inline int path_is_daemon_excluded(char *path, int ignore_filename)
  
  /* This function is used to check if a file should be included/excluded
   * from the list of files based on its name and type etc.  The value of
@@ -256,7 +256,7 @@ diff --git a/flist.c b/flist.c
  static int is_excluded(const char *fname, int is_dir, int filter_level)
  {
  #if 0 /* This currently never happens, so avoid a useless compare. */
-@@ -283,6 +285,8 @@ static int is_excluded(const char *fname, int is_dir, int filter_level)
+@@ -292,6 +294,8 @@ static int is_excluded(const char *fname, int is_dir, int filter_level)
  #endif
        if (is_daemon_excluded(fname, is_dir))
                return 1;
@@ -265,7 +265,7 @@ diff --git a/flist.c b/flist.c
        if (filter_level != ALL_FILTERS)
                return 0;
        if (filter_list.head
-@@ -1142,7 +1146,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1170,7 +1174,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        } else if (readlink_stat(thisname, &st, linkname) != 0) {
                int save_errno = errno;
                /* See if file is excluded before reporting an error. */
@@ -274,7 +274,7 @@ diff --git a/flist.c b/flist.c
                 && (is_excluded(thisname, 0, filter_level)
                  || is_excluded(thisname, 1, filter_level))) {
                        if (ignore_perishable && save_errno != ENOENT)
-@@ -1187,6 +1191,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1215,6 +1219,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
  
        if (filter_level == NO_FILTERS)
                goto skip_filters;
@@ -287,7 +287,7 @@ diff --git a/flist.c b/flist.c
  
        if (S_ISDIR(st.st_mode)) {
                if (!xfer_dirs) {
-@@ -1377,12 +1387,23 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
+@@ -1415,12 +1425,23 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
                                          int flags, int filter_level)
  {
        struct file_struct *file;
@@ -312,7 +312,7 @@ diff --git a/flist.c b/flist.c
                file->mode = tweak_mode(file->mode, chmod_modes);
  
        if (f >= 0) {
-@@ -2239,7 +2260,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2280,7 +2301,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                        struct file_struct *file;
                        file = send_file_name(f, flist, fbuf, &st,
                                              FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
@@ -321,7 +321,7 @@ diff --git a/flist.c b/flist.c
                        if (!file)
                                continue;
                        if (inc_recurse) {
-@@ -2253,7 +2274,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2294,7 +2315,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                        } else
                                send_if_directory(f, flist, file, fbuf, len, flags);
                } else
@@ -333,7 +333,7 @@ diff --git a/flist.c b/flist.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -146,6 +146,9 @@
+@@ -149,6 +149,9 @@
  #define NO_FILTERS    0
  #define SERVER_FILTERS        1
  #define ALL_FILTERS   2
@@ -343,7 +343,7 @@ diff --git a/rsync.h b/rsync.h
  
  #define XFLG_FATAL_ERRORS     (1<<0)
  #define XFLG_OLD_PREFIXES     (1<<1)
-@@ -798,6 +801,8 @@ struct map_struct {
+@@ -805,6 +808,8 @@ struct map_struct {
        int status;             /* first errno from read errors         */
  };
  
@@ -352,7 +352,7 @@ diff --git a/rsync.h b/rsync.h
  #define FILTRULE_WILD         (1<<0) /* pattern has '*', '[', and/or '?' */
  #define FILTRULE_WILD2                (1<<1) /* pattern has '**' */
  #define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
-@@ -818,8 +823,18 @@ struct map_struct {
+@@ -825,8 +830,18 @@ struct map_struct {
  #define FILTRULE_RECEIVER_SIDE        (1<<17)/* rule applies to the receiving side */
  #define FILTRULE_CLEAR_LIST   (1<<18)/* this item is the "!" token */
  #define FILTRULE_PERISHABLE   (1<<19)/* perishable if parent dir goes away */
@@ -371,7 +371,7 @@ diff --git a/rsync.h b/rsync.h
  
  typedef struct filter_struct {
        struct filter_struct *next;
-@@ -829,6 +844,11 @@ typedef struct filter_struct {
+@@ -836,6 +851,11 @@ typedef struct filter_struct {
                int slash_cnt;
                struct filter_list_struct *mergelist;
        } u;
@@ -395,7 +395,7 @@ diff --git a/rsync.yo b/rsync.yo
  
  See the bf(--perms) and bf(--executability) options for how the resulting
  permission value can be applied to the files in the transfer.
-@@ -1808,6 +1810,10 @@ be omitted, but if USER is empty, a leading colon must be supplied.
+@@ -1831,6 +1833,10 @@ be omitted, but if USER is empty, a leading colon must be supplied.
  If you specify "--chown=foo:bar, this is exactly the same as specifying
  "--usermap=*:foo --groupmap=*:bar", only easier.
  
@@ -406,7 +406,7 @@ diff --git a/rsync.yo b/rsync.yo
  dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum I/O
  timeout in seconds. If no data is transferred for the specified time
  then rsync will exit. The default is 0, which means no timeout.
-@@ -2620,6 +2626,15 @@ itemization(
+@@ -2643,6 +2649,15 @@ itemization(
    option's default rules that exclude things like "CVS" and "*.o" are
    marked as perishable, and will not prevent a directory that was removed
    on the source from being deleted on the destination.
@@ -422,7 +422,7 @@ diff --git a/rsync.yo b/rsync.yo
  )
  
  manpagesection(MERGE-FILE FILTER RULES)
-@@ -2681,6 +2696,12 @@ itemization(
+@@ -2704,6 +2719,12 @@ itemization(
    a rule prefix such as bf(hide)).
  )
  
@@ -438,7 +438,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/util.c b/util.c
 --- a/util.c
 +++ b/util.c
-@@ -840,6 +840,25 @@ size_t stringjoin(char *dest, size_t destsize, ...)
+@@ -816,6 +816,25 @@ size_t stringjoin(char *dest, size_t destsize, ...)
        return ret;
  }
  
index bb73276..f684b7f 100644 (file)
@@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
@@ -19,7 +19,7 @@ diff --git a/options.c b/options.c
  int preserve_links = 0;
  int preserve_hard_links = 0;
  int preserve_acls = 0;
-@@ -730,6 +731,7 @@ void usage(enum logcode F)
+@@ -731,6 +732,7 @@ void usage(enum logcode F)
    rprintf(F,"     --partial-dir=DIR       put a partially transferred file into DIR\n");
    rprintf(F,"     --delay-updates         put all updated files into place at transfer's end\n");
    rprintf(F," -m, --prune-empty-dirs      prune empty directory chains from the file-list\n");
@@ -27,7 +27,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
    rprintf(F,"     --usermap=STRING        custom username mapping\n");
    rprintf(F,"     --groupmap=STRING       custom groupname mapping\n");
-@@ -988,6 +990,7 @@ static struct poptOption long_options[] = {
+@@ -989,6 +991,7 @@ static struct poptOption long_options[] = {
    {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
    {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
    {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
@@ -35,7 +35,7 @@ diff --git a/options.c b/options.c
    {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
    {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -2572,6 +2575,9 @@ void server_options(char **args, int *argc_p)
+@@ -2573,6 +2576,9 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = tmpdir;
                }
  
@@ -56,7 +56,7 @@ diff --git a/receiver.c b/receiver.c
  extern int basis_dir_cnt;
  extern int make_backups;
  extern int cleanup_got_literal;
-@@ -305,6 +306,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -337,6 +338,12 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        if (sum_end(file_sum1) != checksum_len)
                overflow_exit("checksum_len"); /* Impossible... */
  
@@ -91,7 +91,7 @@ diff --git a/util.c b/util.c
  extern int modify_window;
  extern int relative_paths;
  extern int preserve_xattrs;
-@@ -374,6 +375,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
+@@ -382,6 +383,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
                        full_fname(source));
        }
  
diff --git a/group-auth.diff b/group-auth.diff
new file mode 100644 (file)
index 0000000..f1bac4f
--- /dev/null
@@ -0,0 +1,416 @@
+This patch adds the ability to do group authentications to the "auth users"
+line via the @group idiom and to specify a group password via an @group entry
+in the secrets file (though the latter is not required if you wish to have
+per-user passwords).  It also allows you to override a module's read-only or
+read-write setting on a per auth-entry basis by adding a :ro or :rw suffix to a
+username or a @groupname.
+
+To use this patch, run these commands for a successful build:
+
+    patch -p1 <patches/group-auth.diff
+    ./configure                         (optional if already run)
+    make
+
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
+diff --git a/authenticate.c b/authenticate.c
+--- a/authenticate.c
++++ b/authenticate.c
+@@ -19,7 +19,9 @@
+  */
+ #include "rsync.h"
++#include "itypes.h"
++extern int read_only;
+ extern char *password_file;
+ /***************************************************************************
+@@ -76,25 +78,40 @@ static void gen_challenge(const char *addr, char *challenge)
+       base64_encode(digest, len, challenge, 0);
+ }
++/* Generate an MD4 hash created from the combination of the password
++ * and the challenge string and return it base64-encoded. */
++static void generate_hash(const char *in, const char *challenge, char *out)
++{
++      char buf[MAX_DIGEST_LEN];
++      int len;
++
++      sum_init(0);
++      sum_update(in, strlen(in));
++      sum_update(challenge, strlen(challenge));
++      len = sum_end(buf);
++
++      base64_encode(buf, len, out, 0);
++}
+ /* Return the secret for a user from the secret file, null terminated.
+  * Maximum length is len (not counting the null). */
+-static int get_secret(int module, const char *user, char *secret, int len)
++static const char *check_secret(int module, const char *user, const char *group,
++                              const char *challenge, const char *pass)
+ {
++      char line[1024];
++      char pass2[MAX_DIGEST_LEN*2];
+       const char *fname = lp_secrets_file(module);
+       STRUCT_STAT st;
+       int fd, ok = 1;
+-      const char *p;
+-      char ch, *s;
++      int user_len = strlen(user);
++      int group_len = group ? strlen(group) : 0;
++      char *err;
+-      if (!fname || !*fname)
+-              return 0;
++      if (!fname || !*fname || (fd = open(fname, O_RDONLY)) < 0)
++              return "no secrets file";
+-      if ((fd = open(fname, O_RDONLY)) < 0)
+-              return 0;
+-
+-      if (do_stat(fname, &st) == -1) {
+-              rsyserr(FLOG, errno, "stat(%s)", fname);
++      if (do_fstat(fd, &st) == -1) {
++              rsyserr(FLOG, errno, "fstat(%s)", fname);
+               ok = 0;
+       } else if (lp_strict_modes(module)) {
+               if ((st.st_mode & 06) != 0) {
+@@ -106,50 +123,47 @@ static int get_secret(int module, const char *user, char *secret, int len)
+               }
+       }
+       if (!ok) {
+-              rprintf(FLOG, "continuing without secrets file\n");
+               close(fd);
+-              return 0;
++              return "ignoring secrets file";
+       }
+       if (*user == '#') {
+               /* Reject attempt to match a comment. */
+               close(fd);
+-              return 0;
++              return "invalid username";
+       }
+-      /* Try to find a line that starts with the user name and a ':'. */
+-      p = user;
+-      while (1) {
+-              if (read(fd, &ch, 1) != 1) {
+-                      close(fd);
+-                      return 0;
++      /* Try to find a line that starts with the user (or @group) name and a ':'. */
++      err = "secret not found";
++      while ((user || group) && read_line_old(fd, line, sizeof line)) {
++              const char **ptr, *s;
++              int len;
++              if (*line == '@') {
++                      ptr = &group;
++                      len = group_len;
++                      s = line+1;
++              } else {
++                      ptr = &user;
++                      len = user_len;
++                      s = line;
+               }
+-              if (ch == '\n')
+-                      p = user;
+-              else if (p) {
+-                      if (*p == ch)
+-                              p++;
+-                      else if (!*p && ch == ':')
+-                              break;
+-                      else
+-                              p = NULL;
++              if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
++                      continue;
++              generate_hash(s+len+1, challenge, pass2);
++              if (strcmp(pass, pass2) == 0) {
++                      err = NULL;
++                      break;
+               }
++              err = "password mismatch";
++              *ptr = NULL; /* Don't look for name again. */
+       }
+-      /* Slurp the secret into the "secret" buffer. */
+-      s = secret;
+-      while (len > 0) {
+-              if (read(fd, s, 1) != 1 || *s == '\n')
+-                      break;
+-              if (*s == '\r')
+-                      continue;
+-              s++;
+-              len--;
+-      }
+-      *s = '\0';
+       close(fd);
+-      return 1;
++      memset(line, 0, sizeof line);
++      memset(pass2, 0, sizeof pass2);
++
++      return err;
+ }
+ static const char *getpassf(const char *filename)
+@@ -199,21 +213,6 @@ static const char *getpassf(const char *filename)
+       return NULL;
+ }
+-/* Generate an MD4 hash created from the combination of the password
+- * and the challenge string and return it base64-encoded. */
+-static void generate_hash(const char *in, const char *challenge, char *out)
+-{
+-      char buf[MAX_DIGEST_LEN];
+-      int len;
+-
+-      sum_init(0);
+-      sum_update(in, strlen(in));
+-      sum_update(challenge, strlen(challenge));
+-      len = sum_end(buf);
+-
+-      base64_encode(buf, len, out, 0);
+-}
+-
+ /* Possibly negotiate authentication with the client.  Use "leader" to
+  * start off the auth if necessary.
+  *
+@@ -226,9 +225,12 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
+       char *users = lp_auth_users(module);
+       char challenge[MAX_DIGEST_LEN*2];
+       char line[BIGPATHBUFLEN];
+-      char secret[512];
+-      char pass2[MAX_DIGEST_LEN*2];
++      char **auth_uid_groups = NULL;
++      int auth_uid_groups_cnt = -1;
++      const char *err = NULL;
++      int group_match = -1;
+       char *tok, *pass;
++      char opt_ch = '\0';
+       /* if no auth list then allow anyone in! */
+       if (!users || !*users)
+@@ -251,37 +253,92 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
+               out_of_memory("auth_server");
+       for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
+-              if (wildmatch(tok, line))
+-                      break;
++              char *opts;
++              /* See if the user appended :deny, :ro, or :rw. */
++              if ((opts = strchr(tok, ':')) != NULL) {
++                      *opts++ = '\0';
++                      opt_ch = isUpper(opts) ? toLower(opts) : *opts;
++                      if (opt_ch == 'r') { /* handle ro and rw */
++                              opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1];
++                              if (opt_ch == 'o')
++                                      opt_ch = 'r';
++                              else if (opt_ch != 'w')
++                                      opt_ch = '\0';
++                      } else if (opt_ch != 'd') /* if it's not deny, ignore it */
++                              opt_ch = '\0';
++              } else
++                      opt_ch = '\0';
++              if (*tok != '@') {
++                      /* Match the username */
++                      if (wildmatch(tok, line))
++                              break;
++              } else {
++#ifdef HAVE_GETGROUPLIST
++                      int j;
++                      /* See if authorizing user is a real user, and if so, see
++                       * if it is in a group that matches tok+1 wildmat. */
++                      if (auth_uid_groups_cnt < 0) {
++                              gid_t gid_list[64];
++                              uid_t auth_uid;
++                              auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
++                              if (!user_to_uid(line, &auth_uid, False)
++                               || getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
++                                      auth_uid_groups_cnt = 0;
++                              else {
++                                      if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
++                                              out_of_memory("auth_server");
++                                      for (j = 0; j < auth_uid_groups_cnt; j++)
++                                              auth_uid_groups[j] = gid_to_group(gid_list[j]);
++                              }
++                      }
++                      for (j = 0; j < auth_uid_groups_cnt; j++) {
++                              if (auth_uid_groups[j] && wildmatch(tok+1, auth_uid_groups[j])) {
++                                      group_match = j;
++                                      break;
++                              }
++                      }
++                      if (group_match >= 0)
++                              break;
++#else
++                      rprintf(FLOG, "your computer doesn't support getgrouplist(), so no @group authorization is possible.\n");
++#endif
++              }
+       }
++
+       free(users);
+-      if (!tok) {
+-              rprintf(FLOG, "auth failed on module %s from %s (%s): "
+-                      "unauthorized user\n",
+-                      lp_name(module), host, addr);
+-              return NULL;
++      if (!tok)
++              err = "no matching rule";
++      else if (opt_ch == 'd')
++              err = "denied by rule";
++      else {
++              char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
++              err = check_secret(module, line, group, challenge, pass);
+       }
+-      memset(secret, 0, sizeof secret);
+-      if (!get_secret(module, line, secret, sizeof secret - 1)) {
+-              memset(secret, 0, sizeof secret);
+-              rprintf(FLOG, "auth failed on module %s from %s (%s): "
+-                      "missing secret for user \"%s\"\n",
+-                      lp_name(module), host, addr, line);
+-              return NULL;
+-      }
++      memset(challenge, 0, sizeof challenge);
++      memset(pass, 0, strlen(pass));
+-      generate_hash(secret, challenge, pass2);
+-      memset(secret, 0, sizeof secret);
++      if (auth_uid_groups) {
++              int j;
++              for (j = 0; j < auth_uid_groups_cnt; j++) {
++                      if (auth_uid_groups[j])
++                              free(auth_uid_groups[j]);
++              }
++              free(auth_uid_groups);
++      }
+-      if (strcmp(pass, pass2) != 0) {
+-              rprintf(FLOG, "auth failed on module %s from %s (%s): "
+-                      "password mismatch\n",
+-                      lp_name(module), host, addr);
++      if (err) {
++              rprintf(FLOG, "auth failed on module %s from %s (%s) for %s: %s\n",
++                      lp_name(module), host, addr, line, err);
+               return NULL;
+       }
++      if (opt_ch == 'r')
++              read_only = 1;
++      else if (opt_ch == 'w')
++              read_only = 0;
++
+       return strdup(line);
+ }
+diff --git a/clientserver.c b/clientserver.c
+--- a/clientserver.c
++++ b/clientserver.c
+@@ -546,6 +546,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+               return -1;
+       }
++      read_only = lp_read_only(i); /* may also be overridden by auth_server() */
+       auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
+       if (!auth_user) {
+@@ -556,9 +557,6 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+       module_id = i;
+-      if (lp_read_only(i))
+-              read_only = 1;
+-
+       if (lp_transfer_logging(i) && !logfile_format)
+               logfile_format = lp_log_format(i);
+       if (log_format_has(logfile_format, 'i'))
+diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
+--- a/rsyncd.conf.yo
++++ b/rsyncd.conf.yo
+@@ -318,6 +318,8 @@ attempted uploads will fail. If "read only" is false then uploads will
+ be possible if file permissions on the daemon side allow them. The default
+ is for all modules to be read only.
++Note that "auth users" can override this setting on a per-user basis.
++
+ dit(bf(write only)) This parameter determines whether clients
+ will be able to download files or not. If "write only" is true then any
+ attempted downloads will fail. If "write only" is false then downloads
+@@ -430,10 +432,12 @@ be on to the clients.
+ See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
+ manpage for information on the format of this string.
+-dit(bf(auth users)) This parameter specifies a comma and
+-space-separated list of usernames that will be allowed to connect to
++dit(bf(auth users)) This parameter specifies a comma and/or space-separated
++list of authorization rules.  In its simplest form, you list the usernames
++that will be allowed to connect to
+ this module. The usernames do not need to exist on the local
+-system. The usernames may also contain shell wildcard characters. If
++system. The rules may contain shell wildcard characters that will be matched
++against the username provided by the client for authentication. If
+ "auth users" is set then the client will be challenged to supply a
+ username and password to connect to the module. A challenge response
+ authentication protocol is used for this exchange. The plain text
+@@ -441,20 +445,50 @@ usernames and passwords are stored in the file specified by the
+ "secrets file" parameter. The default is for all users to be able to
+ connect without a password (this is called "anonymous rsync").
++In addition to username matching, you can specify groupname matching via a '@'
++prefix.  When using groupname matching, the authenticating username must be a
++real user on the system, or it will be assumed to be a member of no groups.
++For example, specifying "@rsync" will match the authenticating user if the
++named user is a member of the rsync group.
++
++Finally, options may be specified after a colon (:).  The options allow you to
++"deny" a user or a group, set the access to "ro" (read-only), or set the access
++to "rw" (read/write).  Setting an auth-rule-specific ro/rw setting overrides
++the module's default "read only" setting.
++
++Be sure to put the rules in the order you want them to be matched, because the
++checking stops at the first match.  For example:
++
++verb(  auth users = joe:deny @guest:deny admin:rw @rsync:ro susan )
++
++In the above rule, user joe will be denied access no matter what.  Any user
++that is in the group "guest" is also denied access.  The user "admin" gets
++access in read/write mode, even if the admin user is in group rsync (because
++the admin user-matching rule is before the rsync group-matching rule).
++Finally, user susan gets the default ro/rw setting of the module, but only
++if susan's user didn't match an earlier group-matching rule.
++
++See the description of the secrets file for how you can have per-user passwords
++as well as per-group passwords (either or both).
++
+ See also the section entitled "USING RSYNC-DAEMON FEATURES VIA A REMOTE
+ SHELL CONNECTION" in bf(rsync)(1) for information on how handle an
+ rsyncd.conf-level username that differs from the remote-shell-level
+ username when using a remote shell to connect to an rsync daemon.
+-dit(bf(secrets file)) This parameter specifies the name of
+-a file that contains the username:password pairs used for
+-authenticating this module. This file is only consulted if the "auth
+-users" parameter is specified. The file is line based and contains
+-username:password pairs separated by a single colon. Any line starting
+-with a hash (#) is considered a comment and is skipped. The passwords
+-can contain any characters but be warned that many operating systems
+-limit the length of passwords that can be typed at the client end, so
+-you may find that passwords longer than 8 characters don't work.
++dit(bf(secrets file)) This parameter specifies the name of a file that contains
++the username:password and/or @group:password pairs used for authenticating this
++module. This file is only consulted if the "auth users" parameter is specified.
++The file is line-based and contains one name:password pair per line.  Any line
++has a hash (#) as the very first character on the line is considered a comment
++and is skipped.  The passwords can contain any characters but be warned that
++many operating systems limit the length of passwords that can be typed at the
++client end, so you may find that passwords longer than 8 characters don't work.
++
++The use of group-specific lines are only relevant when the module was
++authorized using a matching "@group" rule.  When that happens, the user can be
++authorized via either their "username:password" line or the "@group:password"
++line for the group that triggered the authentication.
+ There is no default for the "secrets file" parameter, you must choose a name
+ (such as tt(/etc/rsyncd.secrets)).  The file must normally not be readable
index 7b6b29a..abedb9e 100644 (file)
@@ -12,7 +12,7 @@ TODO:
  - Make this code handle multibyte character encodings, and honor the
    --iconv setting when converting case.
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/exclude.c b/exclude.c
 --- a/exclude.c
 +++ b/exclude.c
@@ -56,7 +56,7 @@ diff --git a/flist.c b/flist.c
  extern int ignore_errors;
  extern int numeric_ids;
  extern int recurse;
-@@ -2934,6 +2935,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -2982,6 +2983,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
  {
        int dif;
        const uchar *c1, *c2;
@@ -64,7 +64,7 @@ diff --git a/flist.c b/flist.c
        enum fnc_state state1, state2;
        enum fnc_type type1, type2;
        enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM;
-@@ -3044,7 +3046,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -3092,7 +3094,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
                        if (type1 != type2)
                                return type1 == t_PATH ? 1 : -1;
                }
@@ -220,7 +220,7 @@ diff --git a/options.c b/options.c
  int blocking_io = -1;
  int checksum_seed = 0;
  int inplace = 0;
-@@ -759,6 +760,7 @@ void usage(enum logcode F)
+@@ -760,6 +761,7 @@ void usage(enum logcode F)
    rprintf(F,"     --files-from=FILE       read list of source-file names from FILE\n");
    rprintf(F," -0, --from0                 all *-from/filter files are delimited by 0s\n");
    rprintf(F," -s, --protect-args          no space-splitting; only wildcard special-chars\n");
@@ -228,7 +228,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --address=ADDRESS       bind address for outgoing socket to daemon\n");
    rprintf(F,"     --port=PORT             specify double-colon alternate port number\n");
    rprintf(F,"     --sockopts=OPTIONS      specify custom TCP options\n");
-@@ -973,6 +975,8 @@ static struct poptOption long_options[] = {
+@@ -974,6 +976,8 @@ static struct poptOption long_options[] = {
    {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
    {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
    {"only-write-batch", 0,  POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
@@ -237,7 +237,7 @@ diff --git a/options.c b/options.c
    {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
    {"from0",           '0', POPT_ARG_VAL,    &eol_nulls, 1, 0, 0},
    {"no-from0",         0,  POPT_ARG_VAL,    &eol_nulls, 0, 0, 0},
-@@ -2522,6 +2526,9 @@ void server_options(char **args, int *argc_p)
+@@ -2523,6 +2527,9 @@ void server_options(char **args, int *argc_p)
                args[ac++] = arg;
        }
  
@@ -258,7 +258,7 @@ diff --git a/rsync.yo b/rsync.yo
       --address=ADDRESS       bind address for outgoing socket to daemon
       --port=PORT             specify double-colon alternate port number
       --sockopts=OPTIONS      specify custom TCP options
-@@ -1582,6 +1583,10 @@ If you use this option with bf(--iconv), the args will also be translated
+@@ -1583,6 +1584,10 @@ If you use this option with bf(--iconv), the args will also be translated
  from the local to the remote character-set.  The translation happens before
  wild-cards are expanded.  See also the bf(--files-from) option.
  
index 1415923..f697067 100644 (file)
@@ -12,7 +12,7 @@ To use this patch, run these commands for a successful build:
     ./configure
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/Makefile.in b/Makefile.in
 --- a/Makefile.in
 +++ b/Makefile.in
@@ -36,7 +36,7 @@ diff --git a/flist.c b/flist.c
  extern char *usermap, *groupmap;
  
  extern char curr_dir[MAXPATHLEN];
-@@ -891,7 +892,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -909,7 +910,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                extra_len += EXTRA_LEN;
  #endif
  
@@ -400,7 +400,7 @@ diff --git a/options.c b/options.c
  char *config_file = NULL;
  char *shell_cmd = NULL;
  char *logfile_name = NULL;
-@@ -745,6 +746,7 @@ void usage(enum logcode F)
+@@ -746,6 +747,7 @@ void usage(enum logcode F)
    rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
    rprintf(F,"     --copy-dest=DIR         ... and include copies of unchanged files\n");
    rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
@@ -408,7 +408,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -z, --compress              compress file data during the transfer\n");
    rprintf(F,"     --compress-level=NUM    explicitly set compression level\n");
    rprintf(F,"     --skip-compress=LIST    skip compressing files with a suffix in LIST\n");
-@@ -798,7 +800,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -799,7 +801,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
        OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
        OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG,
@@ -417,7 +417,7 @@ diff --git a/options.c b/options.c
        OPT_SERVER, OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -937,6 +939,7 @@ static struct poptOption long_options[] = {
+@@ -938,6 +940,7 @@ static struct poptOption long_options[] = {
    {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
    {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
    {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
@@ -425,7 +425,7 @@ diff --git a/options.c b/options.c
    {"fuzzy",           'y', POPT_ARG_VAL,    &fuzzy_basis, 1, 0, 0 },
    {"no-fuzzy",         0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
    {"no-y",             0,  POPT_ARG_VAL,    &fuzzy_basis, 0, 0, 0 },
-@@ -1743,6 +1746,21 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1744,6 +1747,21 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        return 0;
  #endif
  
@@ -447,7 +447,7 @@ diff --git a/options.c b/options.c
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off. */
-@@ -2601,6 +2619,11 @@ void server_options(char **args, int *argc_p)
+@@ -2602,6 +2620,11 @@ void server_options(char **args, int *argc_p)
        } else if (inplace)
                args[ac++] = "--inplace";
  
@@ -462,7 +462,7 @@ diff --git a/options.c b/options.c
 diff --git a/receiver.c b/receiver.c
 --- a/receiver.c
 +++ b/receiver.c
-@@ -164,11 +164,13 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
+@@ -196,11 +196,13 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
  }
  
  static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
@@ -477,7 +477,7 @@ diff --git a/receiver.c b/receiver.c
        int32 len;
        OFF_T offset = 0;
        OFF_T offset2;
-@@ -188,6 +190,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -220,6 +222,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        } else
                mapbuf = NULL;
  
@@ -487,7 +487,7 @@ diff --git a/receiver.c b/receiver.c
        sum_init(checksum_seed);
  
        if (append_mode > 0) {
-@@ -232,6 +237,8 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -264,6 +269,8 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
                        cleanup_got_literal = 1;
  
                        sum_update(data, i);
@@ -496,7 +496,7 @@ diff --git a/receiver.c b/receiver.c
  
                        if (fd != -1 && write_file(fd,data,i) != i)
                                goto report_write_error;
-@@ -258,6 +265,8 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -290,6 +297,8 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
  
                        see_token(map, len);
                        sum_update(map, len);
@@ -505,7 +505,7 @@ diff --git a/receiver.c b/receiver.c
                }
  
                if (updating_basis_or_equiv) {
-@@ -305,6 +314,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -337,6 +346,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        if (sum_end(file_sum1) != checksum_len)
                overflow_exit("checksum_len"); /* Impossible... */
  
@@ -515,7 +515,7 @@ diff --git a/receiver.c b/receiver.c
        if (mapbuf)
                unmap_file(mapbuf);
  
-@@ -319,7 +331,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -351,7 +363,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
  
  static void discard_receive_data(int f_in, OFF_T length)
  {
@@ -524,7 +524,7 @@ diff --git a/receiver.c b/receiver.c
  }
  
  static void handle_delayed_updates(char *local_name)
-@@ -744,7 +756,7 @@ int recv_files(int f_in, char *local_name)
+@@ -779,7 +791,7 @@ int recv_files(int f_in, int f_out, char *local_name)
  
                /* recv file data */
                recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
@@ -536,7 +536,7 @@ diff --git a/receiver.c b/receiver.c
 diff --git a/rsync.c b/rsync.c
 --- a/rsync.c
 +++ b/rsync.c
-@@ -48,6 +48,7 @@ extern int flist_eof;
+@@ -49,6 +49,7 @@ extern int file_old_total;
  extern int msgs2stderr;
  extern int keep_dirlinks;
  extern int make_backups;
@@ -544,7 +544,7 @@ diff --git a/rsync.c b/rsync.c
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  extern struct chmod_mode_struct *daemon_chmod_modes;
  #ifdef ICONV_OPTION
-@@ -575,8 +576,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -627,8 +628,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
        /* move tmp file over real file */
        if (DEBUG_GTE(RECV, 1))
                rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
@@ -565,7 +565,7 @@ diff --git a/rsync.c b/rsync.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -854,6 +854,14 @@ struct stats {
+@@ -861,6 +861,14 @@ struct stats {
        int xferred_files;
  };
  
index ffe43c0..73b2cf0 100644 (file)
@@ -20,7 +20,7 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/clientserver.c b/clientserver.c
 --- a/clientserver.c
 +++ b/clientserver.c
@@ -40,16 +40,16 @@ diff --git a/clientserver.c b/clientserver.c
  
  #ifdef HAVE_SIGACTION
  static struct sigaction sigact;
-@@ -643,7 +645,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -669,7 +671,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        log_init(1);
  
  #ifdef HAVE_PUTENV
 -      if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
 +      if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i) || *lp_name_converter(i)) {
-               char *modname, *modpath, *hostaddr, *hostname, *username;
                int status;
  
-@@ -732,6 +734,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+               umask(orig_umask);
+@@ -741,6 +743,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
                        set_blocking(fds[1]);
                        pre_exec_fd = fds[1];
                }
@@ -94,7 +94,7 @@ diff --git a/clientserver.c b/clientserver.c
                umask(0);
        }
  #endif
-@@ -959,6 +999,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -968,6 +1008,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        return 0;
  }
  
@@ -142,7 +142,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -121,6 +121,7 @@ typedef struct {
+@@ -122,6 +122,7 @@ typedef struct {
        char *log_file;
        char *log_format;
        char *name;
@@ -150,7 +150,7 @@ diff --git a/loadparm.c b/loadparm.c
        char *outgoing_chmod;
        char *path;
        char *postxfer_exec;
-@@ -195,6 +196,7 @@ static const all_vars Defaults = {
+@@ -196,6 +197,7 @@ static const all_vars Defaults = {
   /* log_file; */              NULL,
   /* log_format; */            "%o %h [%a] %m (%u) %f %l",
   /* name; */                  NULL,
@@ -158,7 +158,7 @@ diff --git a/loadparm.c b/loadparm.c
   /* outgoing_chmod; */                NULL,
   /* path; */                  NULL,
   /* postxfer_exec; */         NULL,
-@@ -337,6 +339,7 @@ static struct parm_struct parm_table[] =
+@@ -338,6 +340,7 @@ static struct parm_struct parm_table[] =
   {"max verbosity",     P_INTEGER,P_LOCAL, &Vars.l.max_verbosity,       NULL,0},
   {"munge symlinks",    P_BOOL,   P_LOCAL, &Vars.l.munge_symlinks,      NULL,0},
   {"name",              P_STRING, P_LOCAL, &Vars.l.name,                NULL,0},
@@ -166,7 +166,7 @@ diff --git a/loadparm.c b/loadparm.c
   {"numeric ids",       P_BOOL,   P_LOCAL, &Vars.l.numeric_ids,         NULL,0},
   {"outgoing chmod",    P_STRING, P_LOCAL, &Vars.l.outgoing_chmod,      NULL,0},
   {"path",              P_PATH,   P_LOCAL, &Vars.l.path,                NULL,0},
-@@ -414,6 +417,7 @@ FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
+@@ -465,6 +468,7 @@ FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
  FN_LOCAL_STRING(lp_path, path)
  FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
  FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
@@ -177,7 +177,7 @@ diff --git a/loadparm.c b/loadparm.c
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -163,10 +163,11 @@ if the module is not read-only).
+@@ -183,10 +183,11 @@ if the module is not read-only).
  
  When this parameter is enabled, rsync will not attempt to map users and groups
  by name (by default), but instead copy IDs as though bf(--numeric-ids) had
@@ -191,7 +191,7 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
  process in the chroot hierarchy will need to have access to the resources
  used by these library functions (traditionally /etc/passwd and
  /etc/group, but perhaps additional dynamic libraries as well).
-@@ -232,6 +233,27 @@ path elements that rsync believes will allow a symlink to escape the module's
+@@ -252,6 +253,27 @@ path elements that rsync believes will allow a symlink to escape the module's
  hierarchy.  There are tricky ways to work around this, though, so you had
  better trust your users if you choose this combination of parameters.
  
@@ -297,12 +297,12 @@ diff --git a/uidlist.c b/uidlist.c
  extern int preserve_acls;
  extern int numeric_ids;
 +extern pid_t namecvt_pid;
+ extern gid_t our_gid;
  extern char *usermap;
  extern char *groupmap;
-@@ -75,8 +76,12 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, const char *nam
+@@ -76,8 +77,12 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, const char *nam
  /* turn a uid into a user name */
static const char *uid_to_name(uid_t uid)
char *uid_to_user(uid_t uid)
  {
 -      struct passwd *pass = getpwuid(uid);
 -      if (pass)
@@ -315,9 +315,9 @@ diff --git a/uidlist.c b/uidlist.c
                return strdup(pass->pw_name);
        return NULL;
  }
-@@ -84,8 +89,12 @@ static const char *uid_to_name(uid_t uid)
+@@ -85,8 +90,12 @@ char *uid_to_user(uid_t uid)
  /* turn a gid into a group name */
static const char *gid_to_name(gid_t gid)
char *gid_to_group(gid_t gid)
  {
 -      struct group *grp = getgrgid(gid);
 -      if (grp)
@@ -330,22 +330,7 @@ diff --git a/uidlist.c b/uidlist.c
                return strdup(grp->gr_name);
        return NULL;
  }
-diff --git a/util.c b/util.c
---- a/util.c
-+++ b/util.c
-@@ -31,9 +31,10 @@ extern int modify_window;
- extern int relative_paths;
- extern int preserve_xattrs;
- extern char *module_dir;
--extern unsigned int module_dirlen;
- extern mode_t orig_umask;
- extern char *partial_dir;
-+extern pid_t namecvt_pid;
-+extern unsigned int module_dirlen;
- extern filter_rule_list daemon_filter_list;
- int sanitize_paths = 0;
-@@ -537,32 +538,54 @@ void kill_all(int sig)
+@@ -94,32 +103,54 @@ char *gid_to_group(gid_t gid)
  /* Parse a user name or (optionally) a number into a uid */
  int user_to_uid(const char *name, uid_t *uid_p, BOOL num_ok)
  {
@@ -408,3 +393,18 @@ diff --git a/util.c b/util.c
        return 1;
  }
  
+diff --git a/util.c b/util.c
+--- a/util.c
++++ b/util.c
+@@ -31,9 +31,10 @@ extern int modify_window;
+ extern int relative_paths;
+ extern int preserve_xattrs;
+ extern char *module_dir;
+-extern unsigned int module_dirlen;
+ extern mode_t orig_umask;
+ extern char *partial_dir;
++extern pid_t namecvt_pid;
++extern unsigned int module_dirlen;
+ extern filter_rule_list daemon_filter_list;
+ int sanitize_paths = 0;
index d6e311f..18ebb53 100644 (file)
@@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build:
     ./configure                           (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/access.c b/access.c
 --- a/access.c
 +++ b/access.c
index 058fe3e..2533782 100644 (file)
@@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build:
     ./configure                              (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -19,15 +19,15 @@ diff --git a/generator.c b/generator.c
  extern int uid_ndx;
  extern int gid_ndx;
  extern int delete_mode;
-@@ -437,6 +438,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -438,6 +439,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
             const char *xname)
  {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
 +              int omit_changes = omit_dir_changes && S_ISDIR(sxp->st.st_mode);
                int keep_time = !preserve_times ? 0
                    : S_ISDIR(file->mode) ? preserve_times > 1 :
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
-@@ -466,10 +468,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+ #ifdef CAN_SET_SYMLINK_TIMES
+@@ -467,10 +469,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                } else if (preserve_executability
                 && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
                        iflags |= ITEM_REPORT_PERMS;
@@ -42,7 +42,7 @@ diff --git a/generator.c b/generator.c
                        iflags |= ITEM_REPORT_GROUP;
  #ifdef SUPPORT_ACLS
                if (preserve_acls && !S_ISLNK(file->mode)) {
-@@ -1254,7 +1257,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1262,7 +1265,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                real_sx = sx;
                if (file->flags & FLAG_DIR_CREATED)
                        statret = -1;
@@ -62,7 +62,7 @@ diff --git a/options.c b/options.c
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -698,6 +699,7 @@ void usage(enum logcode F)
+@@ -699,6 +700,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");
@@ -70,7 +70,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
  #ifdef SUPPORT_XATTRS
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
-@@ -848,6 +850,7 @@ static struct poptOption long_options[] = {
+@@ -849,6 +851,7 @@ static struct poptOption long_options[] = {
    {"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 },
@@ -78,7 +78,7 @@ diff --git a/options.c b/options.c
    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
    {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
    {"no-super",         0,  POPT_ARG_VAL,    &am_root, 0, 0, 0 },
-@@ -2037,6 +2040,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2038,6 +2041,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
        }
  
@@ -87,7 +87,7 @@ diff --git a/options.c b/options.c
        if (make_backups && !backup_dir) {
                omit_dir_times = 0; /* Implied, so avoid -O to sender. */
                if (preserve_times > 1)
-@@ -2280,6 +2285,8 @@ void server_options(char **args, int *argc_p)
+@@ -2281,6 +2286,8 @@ void server_options(char **args, int *argc_p)
                        argstr[x++] = 'm';
                if (omit_dir_times)
                        argstr[x++] = 'O';
@@ -107,7 +107,7 @@ diff --git a/rsync.c b/rsync.c
  extern int am_root;
  extern int am_server;
  extern int am_sender;
-@@ -438,9 +439,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -488,9 +489,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                        file->flags |= FLAG_TIME_FAILED;
        }
  
index 7c17739..a86af0b 100644 (file)
@@ -35,7 +35,7 @@ To use this patch, run these commands for a successful build:
     ./configure
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/Makefile.in b/Makefile.in
 --- a/Makefile.in
 +++ b/Makefile.in
@@ -164,7 +164,7 @@ diff --git a/clientserver.c b/clientserver.c
                        return -1;
                }
  
-@@ -1016,6 +1063,9 @@ int start_daemon(int f_in, int f_out)
+@@ -1025,6 +1072,9 @@ int start_daemon(int f_in, int f_out)
        if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0)
                return -1;
  
@@ -174,7 +174,7 @@ diff --git a/clientserver.c b/clientserver.c
        line[0] = 0;
        if (!read_line_old(f_in, line, sizeof line))
                return -1;
-@@ -1027,6 +1077,20 @@ int start_daemon(int f_in, int f_out)
+@@ -1036,6 +1086,20 @@ int start_daemon(int f_in, int f_out)
                return -1;
        }
  
@@ -198,7 +198,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -293,6 +293,21 @@ if test x"$enable_locale" != x"no"; then
+@@ -303,6 +303,21 @@ if test x"$enable_locale" != x"no"; then
        AC_DEFINE(CONFIG_LOCALE)
  fi
  
@@ -238,7 +238,7 @@ diff --git a/options.c b/options.c
  #define MAX_BATCH_NAME_LEN 256        /* Must be less than MAXPATHLEN-13 */
  char *batch_name = NULL;
  
-@@ -566,6 +574,7 @@ static void print_rsync_version(enum logcode f)
+@@ -567,6 +575,7 @@ static void print_rsync_version(enum logcode f)
        char const *links = "no ";
        char const *iconv = "no ";
        char const *ipv6 = "no ";
@@ -246,8 +246,8 @@ diff --git a/options.c b/options.c
        STRUCT_STAT *dumstat;
  
  #if SUBPROTOCOL_VERSION != 0
-@@ -599,6 +608,9 @@ static void print_rsync_version(enum logcode f)
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+@@ -600,6 +609,9 @@ static void print_rsync_version(enum logcode f)
+ #ifdef CAN_SET_SYMLINK_TIMES
        symtimes = "";
  #endif
 +#ifdef HAVE_OPENSSL
@@ -256,7 +256,7 @@ diff --git a/options.c b/options.c
  
        rprintf(f, "%s  version %s  protocol version %d%s\n",
                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -612,8 +624,8 @@ static void print_rsync_version(enum logcode f)
+@@ -613,8 +625,8 @@ static void print_rsync_version(enum logcode f)
                (int)(sizeof (int64) * 8));
        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
                got_socketpair, hardlinks, links, ipv6, have_inplace);
@@ -267,7 +267,7 @@ diff --git a/options.c b/options.c
  
  #ifdef MAINTAINER_MODE
        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -784,6 +796,13 @@ void usage(enum logcode F)
+@@ -785,6 +797,13 @@ void usage(enum logcode F)
  #endif
    rprintf(F," -4, --ipv4                  prefer IPv4\n");
    rprintf(F," -6, --ipv6                  prefer IPv6\n");
@@ -281,7 +281,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --version               print version number\n");
    rprintf(F,"(-h) --help                  show this help (-h works with no other options)\n");
  
-@@ -798,7 +817,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -799,7 +818,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
        OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
        OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG,
@@ -290,7 +290,7 @@ diff --git a/options.c b/options.c
        OPT_SERVER, OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -1012,6 +1031,13 @@ static struct poptOption long_options[] = {
+@@ -1013,6 +1032,13 @@ static struct poptOption long_options[] = {
    {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
    {"server",           0,  POPT_ARG_NONE,   0, OPT_SERVER, 0, 0 },
    {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
@@ -304,7 +304,7 @@ diff --git a/options.c b/options.c
    /* All the following options switch us into daemon-mode option-parsing. */
    {"config",           0,  POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
    {"daemon",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
-@@ -1039,6 +1065,13 @@ static void daemon_usage(enum logcode F)
+@@ -1040,6 +1066,13 @@ static void daemon_usage(enum logcode F)
    rprintf(F," -v, --verbose               increase verbosity\n");
    rprintf(F," -4, --ipv4                  prefer IPv4\n");
    rprintf(F," -6, --ipv6                  prefer IPv6\n");
@@ -318,7 +318,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --help                  show this help screen\n");
  
    rprintf(F,"\n");
-@@ -1064,6 +1097,13 @@ static struct poptOption long_daemon_options[] = {
+@@ -1065,6 +1098,13 @@ static struct poptOption long_daemon_options[] = {
    {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
    {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
@@ -332,7 +332,7 @@ diff --git a/options.c b/options.c
    {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
    {"no-verbose",       0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
    {"no-v",             0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
-@@ -1358,6 +1398,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1359,6 +1399,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                                        verbose++;
                                        break;
  
@@ -345,7 +345,7 @@ diff --git a/options.c b/options.c
                                default:
                                        rprintf(FERROR,
                                            "rsync: %s: %s (in daemon mode)\n",
-@@ -1384,6 +1430,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1385,6 +1431,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                                exit_cleanup(RERR_SYNTAX);
                        }
  
@@ -363,7 +363,7 @@ diff --git a/options.c b/options.c
                        *argv_p = argv = poptGetArgs(pc);
                        *argc_p = argc = count_args(argv);
                        am_starting_up = 0;
-@@ -1743,6 +1800,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1744,6 +1801,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        return 0;
  #endif
  
@@ -376,7 +376,7 @@ diff --git a/options.c b/options.c
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off. */
-@@ -2125,6 +2188,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2126,6 +2189,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
        if (delay_updates && !partial_dir)
                partial_dir = tmp_partialdir;
  
@@ -394,7 +394,7 @@ diff --git a/options.c b/options.c
        if (inplace) {
  #ifdef HAVE_FTRUNCATE
                if (partial_dir) {
-@@ -2715,9 +2789,18 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
+@@ -2716,9 +2790,18 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
  {
        char *path;
  
@@ -427,7 +427,7 @@ diff --git a/rsync.h b/rsync.h
  
  #define SYMLINK_PREFIX "/rsyncd-munged/"  /* This MUST have a trailing slash! */
  #define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1)
-@@ -573,6 +574,11 @@ typedef unsigned int size_t;
+@@ -577,6 +578,11 @@ typedef unsigned int size_t;
  # define SIZEOF_INT64 SIZEOF_OFF_T
  #endif
  
index 08db30c..eb60cd7 100644 (file)
@@ -8,41 +8,4 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
-diff --git a/flist.c b/flist.c
---- a/flist.c
-+++ b/flist.c
-@@ -1476,6 +1476,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
- #endif
- #ifdef SUPPORT_XATTRS
-               if (preserve_xattrs) {
-+                      sx.st.st_mode = file->mode;
-                       if (get_xattr(fname, &sx) < 0) {
-                               io_error |= IOERR_GENERAL;
-                               return NULL;
-diff --git a/xattrs.c b/xattrs.c
---- a/xattrs.c
-+++ b/xattrs.c
-@@ -284,6 +284,10 @@ int get_xattr(const char *fname, stat_x *sxp)
- {
-       sxp->xattr = new(item_list);
-       *sxp->xattr = empty_xattr;
-+
-+      if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode))
-+              return 0;
-+
-       if (rsync_xal_get(fname, sxp->xattr) < 0) {
-               free_xattr(sxp);
-               return -1;
-@@ -884,6 +888,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
-               return -1;
-       }
-+      if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) {
-+              errno = ENOTSUP;
-+              return -1;
-+      }
-+
-       ndx = F_XATTR(file);
-       return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp);
- }
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
index 2ffb7f1..e2429ad 100644 (file)
@@ -9,11 +9,11 @@ To use this patch, run these commands for a successful build:
     ./configure
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -32,6 +32,7 @@ extern int inplace;
+@@ -34,6 +34,7 @@ extern int inplace;
  extern int recurse;
  extern int use_qsort;
  extern int allow_inc_recurse;
@@ -21,7 +21,7 @@ diff --git a/compat.c b/compat.c
  extern int append_mode;
  extern int fuzzy_basis;
  extern int read_batch;
-@@ -186,6 +187,15 @@ void setup_protocol(int f_out,int f_in)
+@@ -189,6 +190,15 @@ void setup_protocol(int f_out,int f_in)
        if (read_batch)
                check_batch_flags();
  
@@ -40,12 +40,12 @@ diff --git a/compat.c b/compat.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -553,13 +553,40 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
+@@ -574,13 +574,40 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
      setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
      strerror putenv iconv_open locale_charset nl_langinfo getxattr \
      extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
--    initgroups)
-+    initgroups fallocate posix_fallocate)
+-    initgroups utimensat)
++    initgroups utimensat fallocate posix_fallocate)
  
  dnl cygwin iconv.h defines iconv_open as libiconv_open
  if test x"$ac_cv_func_iconv_open" != x"yes"; then
@@ -93,7 +93,7 @@ diff --git a/options.c b/options.c
  int do_compression = 0;
  int def_compress_level = Z_DEFAULT_COMPRESSION;
  int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
-@@ -566,6 +567,7 @@ static void print_rsync_version(enum logcode f)
+@@ -567,6 +568,7 @@ static void print_rsync_version(enum logcode f)
        char const *links = "no ";
        char const *iconv = "no ";
        char const *ipv6 = "no ";
@@ -101,8 +101,8 @@ diff --git a/options.c b/options.c
        STRUCT_STAT *dumstat;
  
  #if SUBPROTOCOL_VERSION != 0
-@@ -599,6 +601,9 @@ static void print_rsync_version(enum logcode f)
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+@@ -600,6 +602,9 @@ static void print_rsync_version(enum logcode f)
+ #ifdef CAN_SET_SYMLINK_TIMES
        symtimes = "";
  #endif
 +#ifdef SUPPORT_PREALLOCATION
@@ -111,7 +111,7 @@ diff --git a/options.c b/options.c
  
        rprintf(f, "%s  version %s  protocol version %d%s\n",
                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -612,8 +617,8 @@ static void print_rsync_version(enum logcode f)
+@@ -613,8 +618,8 @@ static void print_rsync_version(enum logcode f)
                (int)(sizeof (int64) * 8));
        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
                got_socketpair, hardlinks, links, ipv6, have_inplace);
@@ -122,7 +122,7 @@ diff --git a/options.c b/options.c
  
  #ifdef MAINTAINER_MODE
        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -703,6 +708,9 @@ void usage(enum logcode F)
+@@ -704,6 +709,9 @@ void usage(enum logcode F)
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
  #endif
    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
@@ -132,7 +132,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -n, --dry-run               perform a trial run with no changes made\n");
    rprintf(F," -W, --whole-file            copy files whole (without delta-xfer algorithm)\n");
    rprintf(F," -x, --one-file-system       don't cross filesystem boundaries\n");
-@@ -899,6 +907,7 @@ static struct poptOption long_options[] = {
+@@ -900,6 +908,7 @@ static struct poptOption long_options[] = {
    {"sparse",          'S', POPT_ARG_VAL,    &sparse_files, 1, 0, 0 },
    {"no-sparse",        0,  POPT_ARG_VAL,    &sparse_files, 0, 0, 0 },
    {"no-S",             0,  POPT_ARG_VAL,    &sparse_files, 0, 0, 0 },
@@ -140,7 +140,7 @@ diff --git a/options.c b/options.c
    {"inplace",          0,  POPT_ARG_VAL,    &inplace, 1, 0, 0 },
    {"no-inplace",       0,  POPT_ARG_VAL,    &inplace, 0, 0, 0 },
    {"append",           0,  POPT_ARG_NONE,   0, OPT_APPEND, 0, 0 },
-@@ -2626,6 +2635,9 @@ void server_options(char **args, int *argc_p)
+@@ -2627,6 +2636,9 @@ void server_options(char **args, int *argc_p)
        else if (remove_source_files)
                args[ac++] = "--remove-sent-files";
  
@@ -161,7 +161,7 @@ diff --git a/receiver.c b/receiver.c
  extern int keep_partial;
  extern int checksum_len;
  extern int checksum_seed;
-@@ -175,6 +176,18 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -207,6 +208,18 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        char *data;
        int32 i;
        char *map = NULL;
@@ -180,7 +180,7 @@ diff --git a/receiver.c b/receiver.c
  
        read_sum_head(f_in, &sum);
  
-@@ -285,8 +298,14 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
+@@ -317,8 +330,14 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
                goto report_write_error;
  
  #ifdef HAVE_FTRUNCATE
@@ -200,7 +200,7 @@ diff --git a/receiver.c b/receiver.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -638,6 +638,13 @@ struct ht_int64_node {
+@@ -642,6 +642,13 @@ struct ht_int64_node {
  #define ACLS_NEED_MASK 1
  #endif
  
@@ -226,8 +226,8 @@ diff --git a/rsync.yo b/rsync.yo
   -W, --whole-file            copy files whole (w/o delta-xfer algorithm)
   -x, --one-file-system       don't cross filesystem boundaries
 @@ -1127,6 +1128,18 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
- filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
+ filesystem. It seems to have problems seeking over null regions,
+ and ends up corrupting the files.
  
 +dit(bf(--preallocate)) This tells the receiver to allocate each destination
 +file to its eventual size before writing data to the file.  Rsync will only use
@@ -257,8 +257,8 @@ diff --git a/syscall.c b/syscall.c
 +
  extern int dry_run;
  extern int am_root;
- extern int read_only;
-@@ -282,3 +286,21 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
+ extern int am_sender;
+@@ -325,3 +329,21 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
        return lseek(fd, offset, whence);
  #endif
  }
@@ -302,7 +302,7 @@ diff --git a/util.c b/util.c
  extern int module_id;
  extern int modify_window;
  extern int relative_paths;
-@@ -324,6 +325,10 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
+@@ -332,6 +333,10 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
        int ifd;
        char buf[1024 * 8];
        int len;   /* Number of bytes read into `buf'. */
@@ -313,7 +313,7 @@ diff --git a/util.c b/util.c
  
        if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
                int save_errno = errno;
-@@ -349,7 +354,27 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
+@@ -357,7 +362,27 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
                }
        }
  
@@ -341,7 +341,7 @@ diff --git a/util.c b/util.c
                if (full_write(ofd, buf, len) < 0) {
                        int save_errno = errno;
                        rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
-@@ -374,6 +399,16 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
+@@ -382,6 +407,16 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
                        full_fname(source));
        }
  
index c315470..6c0236a 100644 (file)
@@ -14,7 +14,7 @@ To use this patch, run these commands for a successful build:
     ./configure                           (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/flist.c b/flist.c
 --- a/flist.c
 +++ b/flist.c
@@ -26,7 +26,7 @@ diff --git a/flist.c b/flist.c
  extern struct stats stats;
  extern char *filesfrom_host;
  extern char *usermap, *groupmap;
-@@ -1714,6 +1715,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1753,6 +1754,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
                }
  
                send_file_name(f, flist, fbuf, NULL, flags, filter_level);
@@ -47,7 +47,7 @@ diff --git a/options.c b/options.c
  size_t bwlimit_writemax = 0;
  int ignore_existing = 0;
  int ignore_non_existing = 0;
-@@ -775,6 +776,7 @@ void usage(enum logcode F)
+@@ -776,6 +777,7 @@ void usage(enum logcode F)
    rprintf(F,"     --password-file=FILE    read daemon-access password from FILE\n");
    rprintf(F,"     --list-only             list the files instead of copying them\n");
    rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
@@ -55,7 +55,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
    rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
    rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
-@@ -963,6 +965,7 @@ static struct poptOption long_options[] = {
+@@ -964,6 +966,7 @@ static struct poptOption long_options[] = {
    {"itemize-changes", 'i', POPT_ARG_NONE,   0, 'i', 0, 0 },
    {"no-itemize-changes",0, POPT_ARG_VAL,    &itemize_changes, 0, 0, 0 },
    {"no-i",             0,  POPT_ARG_VAL,    &itemize_changes, 0, 0, 0 },
index 7437d50..4d6baa9 100644 (file)
--- a/slp.diff
+++ b/slp.diff
@@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build:
 TODO: the configure changes should abort if the user requests --enable-slp
 and we can't honor that request.
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/Makefile.in b/Makefile.in
 --- a/Makefile.in
 +++ b/Makefile.in
@@ -44,7 +44,7 @@ diff --git a/Makefile.in b/Makefile.in
 diff --git a/clientserver.c b/clientserver.c
 --- a/clientserver.c
 +++ b/clientserver.c
-@@ -1147,6 +1147,13 @@ int daemon_main(void)
+@@ -1156,6 +1156,13 @@ int daemon_main(void)
         * address too.  In fact, why not just do inet_ntop on the
         * local address??? */
  
@@ -61,7 +61,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -647,6 +647,29 @@ if test $rsync_cv_can_hardlink_special = yes; then
+@@ -668,6 +668,29 @@ if test $rsync_cv_can_hardlink_special = yes; then
      AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.])
  fi
  
@@ -94,7 +94,7 @@ diff --git a/configure.in b/configure.in
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -97,6 +97,9 @@ typedef struct {
+@@ -98,6 +98,9 @@ typedef struct {
        char *socket_options;
  
        int rsync_port;
@@ -104,7 +104,7 @@ diff --git a/loadparm.c b/loadparm.c
  } global_vars;
  
  /* This structure describes a single section.  Their order must match the
-@@ -311,6 +314,9 @@ static struct parm_struct parm_table[] =
+@@ -312,6 +315,9 @@ static struct parm_struct parm_table[] =
   {"motd file",         P_STRING, P_GLOBAL,&Vars.g.motd_file,           NULL,0},
   {"pid file",          P_STRING, P_GLOBAL,&Vars.g.pid_file,            NULL,0},
   {"port",              P_INTEGER,P_GLOBAL,&Vars.g.rsync_port,          NULL,0},
@@ -114,7 +114,7 @@ diff --git a/loadparm.c b/loadparm.c
   {"socket options",    P_STRING, P_GLOBAL,&Vars.g.socket_options,      NULL,0},
  
   {"auth users",        P_STRING, P_LOCAL, &Vars.l.auth_users,          NULL,0},
-@@ -392,6 +398,9 @@ FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file)
+@@ -443,6 +449,9 @@ FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file)
  FN_GLOBAL_STRING(lp_socket_options, &Vars.g.socket_options)
  
  FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port)
@@ -127,7 +127,7 @@ diff --git a/loadparm.c b/loadparm.c
 diff --git a/main.c b/main.c
 --- a/main.c
 +++ b/main.c
-@@ -1207,6 +1207,18 @@ static int start_client(int argc, char *argv[])
+@@ -1213,6 +1213,18 @@ static int start_client(int argc, char *argv[])
  
        if (!read_batch) { /* for read_batch, NO source is specified */
                char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
@@ -149,7 +149,7 @@ diff --git a/main.c b/main.c
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
-@@ -566,6 +566,7 @@ static void print_rsync_version(enum logcode f)
+@@ -567,6 +567,7 @@ static void print_rsync_version(enum logcode f)
        char const *links = "no ";
        char const *iconv = "no ";
        char const *ipv6 = "no ";
@@ -157,8 +157,8 @@ diff --git a/options.c b/options.c
        STRUCT_STAT *dumstat;
  
  #if SUBPROTOCOL_VERSION != 0
-@@ -599,6 +600,9 @@ static void print_rsync_version(enum logcode f)
- #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+@@ -600,6 +601,9 @@ static void print_rsync_version(enum logcode f)
+ #ifdef CAN_SET_SYMLINK_TIMES
        symtimes = "";
  #endif
 +#if HAVE_LIBSLP
@@ -167,7 +167,7 @@ diff --git a/options.c b/options.c
  
        rprintf(f, "%s  version %s  protocol version %d%s\n",
                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -612,8 +616,8 @@ static void print_rsync_version(enum logcode f)
+@@ -613,8 +617,8 @@ static void print_rsync_version(enum logcode f)
                (int)(sizeof (int64) * 8));
        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
                got_socketpair, hardlinks, links, ipv6, have_inplace);
@@ -181,7 +181,7 @@ diff --git a/options.c b/options.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -194,6 +194,10 @@
+@@ -197,6 +197,10 @@
  #define SIGNIFICANT_ITEM_FLAGS (~(\
        ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE))
  
@@ -220,7 +220,7 @@ new file mode 100644
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -108,6 +108,15 @@ details on some of the options you may be able to set. By default no
+@@ -120,6 +120,15 @@ details on some of the options you may be able to set. By default no
  special socket options are set.  These settings can also be specified
  via the bf(--sockopts) command-line option.
  
@@ -236,7 +236,7 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
  enddit()
  
  manpagesection(MODULE PARAMETERS)
-@@ -739,6 +748,7 @@ use chroot = yes
+@@ -766,6 +775,7 @@ use chroot = yes
  max connections = 4
  syslog facility = local5
  pid file = /var/run/rsyncd.pid
index 1589c45..124d983 100644 (file)
@@ -10,11 +10,11 @@ To use this patch, run these commands for a successful build:
     ./configure                           (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/syscall.c b/syscall.c
 --- a/syscall.c
 +++ b/syscall.c
-@@ -63,9 +63,14 @@ int do_symlink(const char *fname1, const char *fname2)
+@@ -106,9 +106,14 @@ ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
  #ifdef HAVE_LINK
  int do_link(const char *fname1, const char *fname2)
  {
index e2fee5d..436aa12 100644 (file)
@@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build:
 
 -- Matt McCutchen <hashproduct@gmail.com>
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
@@ -21,7 +21,7 @@ diff --git a/options.c b/options.c
  
  /**
   * If 1, send the whole file as literal data rather than trying to
-@@ -712,6 +713,7 @@ void usage(enum logcode F)
+@@ -713,6 +714,7 @@ void usage(enum logcode F)
    rprintf(F,"     --existing              skip creating new files on receiver\n");
    rprintf(F,"     --ignore-existing       skip updating files that already exist on receiver\n");
    rprintf(F,"     --remove-source-files   sender removes synchronized files (non-dirs)\n");
@@ -29,7 +29,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --del                   an alias for --delete-during\n");
    rprintf(F,"     --delete                delete extraneous files from destination dirs\n");
    rprintf(F,"     --delete-before         receiver deletes before transfer, not during\n");
-@@ -966,6 +968,7 @@ static struct poptOption long_options[] = {
+@@ -967,6 +969,7 @@ static struct poptOption long_options[] = {
    {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
    {"no-bwlimit",       0,  POPT_ARG_VAL,    &bwlimit, 0, 0, 0 },
    {"backup",          'b', POPT_ARG_VAL,    &make_backups, 1, 0, 0 },
@@ -37,7 +37,7 @@ diff --git a/options.c b/options.c
    {"no-backup",        0,  POPT_ARG_VAL,    &make_backups, 0, 0, 0 },
    {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
    {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
-@@ -2501,6 +2504,8 @@ void server_options(char **args, int *argc_p)
+@@ -2502,6 +2505,8 @@ void server_options(char **args, int *argc_p)
                                goto oom;
                        args[ac++] = arg;
                }
@@ -57,7 +57,7 @@ diff --git a/rsync.yo b/rsync.yo
       --del                   an alias for --delete-during
       --delete                delete extraneous files from dest dirs
       --delete-before         receiver deletes before xfer, not during
-@@ -1197,6 +1198,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
+@@ -1198,6 +1199,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
  side the files (meaning non-directories) that are a part of the transfer
  and have been successfully duplicated on the receiving side.
  
@@ -75,7 +75,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/sender.c b/sender.c
 --- a/sender.c
 +++ b/sender.c
-@@ -38,6 +38,7 @@ extern int protocol_version;
+@@ -39,6 +39,7 @@ extern int protocol_version;
  extern int remove_source_files;
  extern int updating_basis_file;
  extern int make_backups;
@@ -83,7 +83,7 @@ diff --git a/sender.c b/sender.c
  extern int inplace;
  extern int batch_fd;
  extern int write_batch;
-@@ -121,6 +122,7 @@ void successful_send(int ndx)
+@@ -124,6 +125,7 @@ void successful_send(int ndx)
        char fname[MAXPATHLEN];
        struct file_struct *file;
        struct file_list *flist;
@@ -91,7 +91,7 @@ diff --git a/sender.c b/sender.c
  
        if (!remove_source_files)
                return;
-@@ -131,7 +133,11 @@ void successful_send(int ndx)
+@@ -134,7 +136,11 @@ void successful_send(int ndx)
                return;
        f_name(file, fname);
  
index 53b75cb..acbe698 100644 (file)
@@ -30,7 +30,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/generator.c b/generator.c
 --- a/generator.c
 +++ b/generator.c
@@ -42,7 +42,7 @@ diff --git a/generator.c b/generator.c
  extern int size_only;
  extern OFF_T max_size;
  extern OFF_T min_size;
-@@ -524,7 +525,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -525,7 +526,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
  /* Perform our quick-check heuristic for determining if a file is unchanged. */
  int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
  {
@@ -54,7 +54,7 @@ diff --git a/generator.c b/generator.c
 diff --git a/main.c b/main.c
 --- a/main.c
 +++ b/main.c
-@@ -142,7 +142,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
+@@ -148,7 +148,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
  }
  
  /* Wait for a process to exit, calling io_flush while waiting. */
@@ -83,7 +83,7 @@ diff --git a/options.c b/options.c
  char *rsync_path = RSYNC_PATH;
  char *backup_dir = NULL;
  char backup_dir_buf[MAXPATHLEN];
-@@ -739,6 +742,7 @@ void usage(enum logcode F)
+@@ -740,6 +743,7 @@ void usage(enum logcode F)
    rprintf(F," -I, --ignore-times          don't skip files that match in size and mod-time\n");
    rprintf(F," -M, --remote-option=OPTION  send OPTION to the remote side only\n");
    rprintf(F,"     --size-only             skip files that match in size\n");
@@ -91,7 +91,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --modify-window=NUM     compare mod-times with reduced accuracy\n");
    rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
-@@ -778,6 +782,8 @@ void usage(enum logcode F)
+@@ -779,6 +783,8 @@ void usage(enum logcode F)
    rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
    rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
    rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
@@ -100,7 +100,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --protocol=NUM          force an older protocol version to be used\n");
  #ifdef ICONV_OPTION
    rprintf(F,"     --iconv=CONVERT_SPEC    request charset conversion of filenames\n");
-@@ -887,6 +893,7 @@ static struct poptOption long_options[] = {
+@@ -888,6 +894,7 @@ static struct poptOption long_options[] = {
    {"chmod",            0,  POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
    {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
    {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
@@ -108,7 +108,7 @@ diff --git a/options.c b/options.c
    {"one-file-system", 'x', POPT_ARG_NONE,   0, 'x', 0, 0 },
    {"no-one-file-system",'x',POPT_ARG_VAL,   &one_file_system, 0, 0, 0 },
    {"no-x",            'x', POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
-@@ -1007,6 +1014,8 @@ static struct poptOption long_options[] = {
+@@ -1008,6 +1015,8 @@ static struct poptOption long_options[] = {
    {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
    {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
    {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
@@ -117,7 +117,7 @@ diff --git a/options.c b/options.c
    {"remote-option",   'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
    {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
    {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
-@@ -2166,6 +2175,16 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2167,6 +2176,16 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                }
        }
  
@@ -134,7 +134,7 @@ diff --git a/options.c b/options.c
        if (files_from) {
                char *h, *p;
                int q;
-@@ -2510,6 +2529,25 @@ void server_options(char **args, int *argc_p)
+@@ -2511,6 +2530,25 @@ void server_options(char **args, int *argc_p)
        else if (missing_args == 1 && !am_sender)
                args[ac++] = "--ignore-missing-args";
  
@@ -252,7 +252,7 @@ diff --git a/receiver.c b/receiver.c
  extern char *partial_dir;
  extern char *basis_dir[MAX_BASIS_DIRS+1];
  extern char sender_file_sum[MAX_DIGEST_LEN];
-@@ -441,6 +442,8 @@ int recv_files(int f_in, char *local_name)
+@@ -476,6 +477,8 @@ int recv_files(int f_in, int f_out, char *local_name)
        const char *parent_dirname = "";
  #endif
        int ndx, recv_ok;
@@ -261,7 +261,7 @@ diff --git a/receiver.c b/receiver.c
  
        if (DEBUG_GTE(RECV, 1))
                rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);
-@@ -448,6 +451,23 @@ int recv_files(int f_in, char *local_name)
+@@ -483,6 +486,23 @@ int recv_files(int f_in, int f_out, char *local_name)
        if (delay_updates)
                delayed_bits = bitbag_create(cur_flist->used + 1);
  
@@ -285,7 +285,7 @@ diff --git a/receiver.c b/receiver.c
        while (1) {
                cleanup_disable();
  
-@@ -742,6 +762,9 @@ int recv_files(int f_in, char *local_name)
+@@ -777,6 +797,9 @@ int recv_files(int f_in, int f_out, char *local_name)
                else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
                        rprintf(FINFO, "%s\n", fname);
  
@@ -295,7 +295,7 @@ diff --git a/receiver.c b/receiver.c
                /* recv file data */
                recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
                                       fname, fd2, F_LENGTH(file));
-@@ -756,6 +779,16 @@ int recv_files(int f_in, char *local_name)
+@@ -791,6 +814,16 @@ int recv_files(int f_in, int f_out, char *local_name)
                        exit_cleanup(RERR_FILEIO);
                }
  
@@ -315,7 +315,7 @@ diff --git a/receiver.c b/receiver.c
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
-@@ -138,6 +138,7 @@
+@@ -141,6 +141,7 @@
  #define IOERR_DEL_LIMIT (1<<2)
  
  #define MAX_ARGS 1000
@@ -343,7 +343,7 @@ diff --git a/rsync.yo b/rsync.yo
       --protocol=NUM          force an older protocol version to be used
       --iconv=CONVERT_SPEC    request charset conversion of filenames
       --checksum-seed=NUM     set block/file checksum seed (advanced)
-@@ -2283,6 +2286,33 @@ file previously generated by bf(--write-batch).
+@@ -2306,6 +2309,33 @@ file previously generated by bf(--write-batch).
  If em(FILE) is bf(-), the batch data will be read from standard input.
  See the "BATCH MODE" section for details.
  
@@ -380,7 +380,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/sender.c b/sender.c
 --- a/sender.c
 +++ b/sender.c
-@@ -41,6 +41,7 @@ extern int make_backups;
+@@ -42,6 +42,7 @@ extern int make_backups;
  extern int inplace;
  extern int batch_fd;
  extern int write_batch;
@@ -388,9 +388,9 @@ diff --git a/sender.c b/sender.c
  extern struct stats stats;
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  
-@@ -173,6 +174,26 @@ void send_files(int f_in, int f_out)
-       enum logcode log_code = log_before_transfer ? FLOG : FINFO;
+@@ -177,6 +178,26 @@ void send_files(int f_in, int f_out)
        int f_xfer = write_batch < 0 ? batch_fd : f_out;
+       int save_io_error = io_error;
        int ndx, j;
 +      char *filter_argv[MAX_FILTER_ARGS + 1];
 +      char *tmp = 0;
@@ -415,7 +415,7 @@ diff --git a/sender.c b/sender.c
  
        if (DEBUG_GTE(SEND, 1))
                rprintf(FINFO, "send_files starting\n");
-@@ -298,6 +319,7 @@ void send_files(int f_in, int f_out)
+@@ -306,6 +327,7 @@ void send_files(int f_in, int f_out)
                        exit_cleanup(RERR_PROTOCOL);
                }
  
@@ -423,7 +423,7 @@ diff --git a/sender.c b/sender.c
                fd = do_open(fname, O_RDONLY, 0);
                if (fd == -1) {
                        if (errno == ENOENT) {
-@@ -319,6 +341,33 @@ void send_files(int f_in, int f_out)
+@@ -327,6 +349,33 @@ void send_files(int f_in, int f_out)
                        continue;
                }
  
@@ -457,7 +457,7 @@ diff --git a/sender.c b/sender.c
                /* map the local file */
                if (do_fstat(fd, &st) != 0) {
                        io_error |= IOERR_GENERAL;
-@@ -369,6 +418,8 @@ void send_files(int f_in, int f_out)
+@@ -377,6 +426,8 @@ void send_files(int f_in, int f_out)
                        }
                }
                close(fd);
index 021534c..f188f1f 100644 (file)
@@ -18,7 +18,7 @@ To use this patch, run these commands for a successful build:
     ./configure                               (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/fileio.c b/fileio.c
 --- a/fileio.c
 +++ b/fileio.c
@@ -50,7 +50,7 @@ diff --git a/options.c b/options.c
  int do_compression = 0;
  int def_compress_level = Z_DEFAULT_COMPRESSION;
  int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
-@@ -703,6 +704,7 @@ void usage(enum logcode F)
+@@ -704,6 +705,7 @@ void usage(enum logcode F)
    rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
  #endif
    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
@@ -58,7 +58,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -n, --dry-run               perform a trial run with no changes made\n");
    rprintf(F," -W, --whole-file            copy files whole (without delta-xfer algorithm)\n");
    rprintf(F," -x, --one-file-system       don't cross filesystem boundaries\n");
-@@ -899,6 +901,7 @@ static struct poptOption long_options[] = {
+@@ -900,6 +902,7 @@ static struct poptOption long_options[] = {
    {"sparse",          'S', POPT_ARG_VAL,    &sparse_files, 1, 0, 0 },
    {"no-sparse",        0,  POPT_ARG_VAL,    &sparse_files, 0, 0, 0 },
    {"no-S",             0,  POPT_ARG_VAL,    &sparse_files, 0, 0, 0 },
@@ -66,7 +66,7 @@ diff --git a/options.c b/options.c
    {"inplace",          0,  POPT_ARG_VAL,    &inplace, 1, 0, 0 },
    {"no-inplace",       0,  POPT_ARG_VAL,    &inplace, 0, 0, 0 },
    {"append",           0,  POPT_ARG_NONE,   0, OPT_APPEND, 0, 0 },
-@@ -2433,6 +2436,12 @@ void server_options(char **args, int *argc_p)
+@@ -2434,6 +2437,12 @@ void server_options(char **args, int *argc_p)
                args[ac++] = arg;
        }
  
@@ -91,8 +91,8 @@ diff --git a/rsync.yo b/rsync.yo
   -W, --whole-file            copy files whole (w/o delta-xfer algorithm)
   -x, --one-file-system       don't cross filesystem boundaries
 @@ -1127,6 +1128,15 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
- filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
+ filesystem. It seems to have problems seeking over null regions,
+ and ends up corrupting the files.
  
 +dit(bf(--sparse-block=SIZE)) Change the block size used to handle sparse files
 +to SIZE bytes.  This option only has an effect if the bf(--sparse) (bf(-S))
index e3e483c..3d62b9a 100644 (file)
@@ -7,11 +7,11 @@ To use this patch, run these commands for a successful build:
     ./configure                            (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
-@@ -300,6 +300,7 @@ static int refused_partial, refused_progress, refused_delete_before;
+@@ -301,6 +301,7 @@ static int refused_partial, refused_progress, refused_delete_before;
  static int refused_delete_during;
  static int refused_inplace, refused_no_iconv;
  static BOOL usermap_via_chown, groupmap_via_chown;
@@ -19,7 +19,7 @@ diff --git a/options.c b/options.c
  static char *max_size_arg, *min_size_arg;
  static char tmp_partialdir[] = ".~tmp~";
  
-@@ -775,6 +776,7 @@ void usage(enum logcode F)
+@@ -776,6 +777,7 @@ void usage(enum logcode F)
    rprintf(F,"     --password-file=FILE    read daemon-access password from FILE\n");
    rprintf(F,"     --list-only             list the files instead of copying them\n");
    rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
@@ -27,7 +27,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
    rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
    rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
-@@ -1007,6 +1009,7 @@ static struct poptOption long_options[] = {
+@@ -1008,6 +1010,7 @@ static struct poptOption long_options[] = {
    {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
    {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
    {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
@@ -35,7 +35,7 @@ diff --git a/options.c b/options.c
    {"remote-option",   'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
    {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
    {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
-@@ -1758,6 +1761,13 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1759,6 +1762,13 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                }
        }
  
index 5f13f19..161e734 100644 (file)
@@ -9,19 +9,19 @@ To use this patch, run these commands for a successful build:
     ./configure                              (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/io.c b/io.c
 --- a/io.c
 +++ b/io.c
-@@ -53,6 +53,7 @@ extern int protocol_version;
- extern int remove_source_files;
+@@ -57,6 +57,7 @@ extern int remove_source_files;
  extern int preserve_hard_links;
+ extern BOOL extra_flist_sending_enabled;
  extern struct stats stats;
 +extern time_t stop_at_utime;
  extern struct file_list *cur_flist;
  #ifdef ICONV_OPTION
  extern int filesfrom_convert;
-@@ -182,16 +183,24 @@ static void check_timeout(void)
+@@ -137,16 +138,24 @@ static void check_timeout(void)
  {
        time_t t;
  
@@ -60,7 +60,7 @@ diff --git a/options.c b/options.c
  int max_delete = INT_MIN;
  OFF_T max_size = 0;
  OFF_T min_size = 0;
-@@ -775,6 +776,8 @@ void usage(enum logcode F)
+@@ -776,6 +777,8 @@ void usage(enum logcode F)
    rprintf(F,"     --password-file=FILE    read daemon-access password from FILE\n");
    rprintf(F,"     --list-only             list the files instead of copying them\n");
    rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
@@ -69,7 +69,7 @@ diff --git a/options.c b/options.c
    rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
    rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
    rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
-@@ -798,7 +801,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -799,7 +802,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
        OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
        OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG,
@@ -78,7 +78,7 @@ diff --git a/options.c b/options.c
        OPT_SERVER, OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -988,6 +991,8 @@ static struct poptOption long_options[] = {
+@@ -989,6 +992,8 @@ static struct poptOption long_options[] = {
    {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
    {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
    {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
@@ -87,7 +87,7 @@ diff --git a/options.c b/options.c
    {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
    {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -1743,6 +1748,36 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1744,6 +1749,36 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        return 0;
  #endif
  
@@ -124,7 +124,7 @@ diff --git a/options.c b/options.c
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off. */
-@@ -2445,6 +2480,15 @@ void server_options(char **args, int *argc_p)
+@@ -2446,6 +2481,15 @@ void server_options(char **args, int *argc_p)
                args[ac++] = arg;
        }
  
@@ -152,7 +152,7 @@ diff --git a/rsync.yo b/rsync.yo
       --write-batch=FILE      write a batched update to FILE
       --only-write-batch=FILE like --write-batch but w/o updating dest
       --read-batch=FILE       read a batched update from FILE
-@@ -2257,6 +2259,19 @@ transfer was too fast, it will wait before sending the next data block. The
+@@ -2280,6 +2282,19 @@ transfer was too fast, it will wait before sending the next data block. The
  result is an average transfer rate equaling the specified limit. A value
  of zero specifies no limit.
  
@@ -306,6 +306,6 @@ diff --git a/util.c b/util.c
 +      return val;
 +}
 +
- int set_modtime(const char *fname, time_t modtime, mode_t mode)
+ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
  {
- #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
+ #ifndef CAN_SET_SYMLINK_TIMES
index e812840..05ef8e1 100644 (file)
@@ -13,7 +13,7 @@ To use this patch, run these commands for a successful build:
     ./configure                                 (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/flist.c b/flist.c
 --- a/flist.c
 +++ b/flist.c
@@ -24,10 +24,10 @@ diff --git a/flist.c b/flist.c
 +extern char *tr_opt, *tr_left, *tr_right;
 +extern int tr_right_len;
 +
- #define PTR_SIZE (sizeof (struct file_struct *))
- int io_error;
-@@ -661,6 +664,24 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+ #ifdef HAVE_UTIMENSAT
+ #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ #define ST_MTIME_NSEC st_mtim.tv_nsec
+@@ -674,6 +677,24 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                stats.total_size += F_LENGTH(file);
  }
  
@@ -49,10 +49,10 @@ diff --git a/flist.c b/flist.c
 +      *p2 = '\0';
 +}
 +
- 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)
  {
-@@ -729,6 +750,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+       static int64 modtime;
+@@ -742,6 +763,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        }
  #endif
  
@@ -74,7 +74,7 @@ diff --git a/options.c b/options.c
  
  #define MAX_BATCH_NAME_LEN 256        /* Must be less than MAXPATHLEN-13 */
  char *batch_name = NULL;
-@@ -782,6 +784,7 @@ void usage(enum logcode F)
+@@ -783,6 +785,7 @@ void usage(enum logcode F)
  #ifdef ICONV_OPTION
    rprintf(F,"     --iconv=CONVERT_SPEC    request charset conversion of filenames\n");
  #endif
@@ -82,7 +82,7 @@ diff --git a/options.c b/options.c
    rprintf(F," -4, --ipv4                  prefer IPv4\n");
    rprintf(F," -6, --ipv6                  prefer IPv6\n");
    rprintf(F,"     --version               print version number\n");
-@@ -995,6 +998,7 @@ static struct poptOption long_options[] = {
+@@ -996,6 +999,7 @@ static struct poptOption long_options[] = {
    {"iconv",            0,  POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
    {"no-iconv",         0,  POPT_ARG_NONE,   0, OPT_NO_ICONV, 0, 0 },
  #endif
@@ -90,7 +90,7 @@ diff --git a/options.c b/options.c
    {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
    {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
    {"8-bit-output",    '8', POPT_ARG_VAL,    &allow_8bit_chars, 1, 0, 0 },
-@@ -2212,6 +2216,31 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2213,6 +2217,31 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                }
        }
  
@@ -122,7 +122,7 @@ diff --git a/options.c b/options.c
        am_starting_up = 0;
  
        return 1;
-@@ -2626,6 +2655,12 @@ void server_options(char **args, int *argc_p)
+@@ -2627,6 +2656,12 @@ void server_options(char **args, int *argc_p)
        else if (remove_source_files)
                args[ac++] = "--remove-sent-files";
  
@@ -146,7 +146,7 @@ diff --git a/rsync.yo b/rsync.yo
       --checksum-seed=NUM     set block/file checksum seed (advanced)
   -4, --ipv4                  prefer IPv4
   -6, --ipv6                  prefer IPv6
-@@ -2321,6 +2322,22 @@ daemon uses the charset specified in its "charset" configuration parameter
+@@ -2344,6 +2345,22 @@ daemon uses the charset specified in its "charset" configuration parameter
  regardless of the remote charset you actually pass.  Thus, you may feel free to
  specify just the local charset for a daemon transfer (e.g. bf(--iconv=utf8)).
  
index ebaaab5..53e3791 100644 (file)
@@ -6,7 +6,7 @@ To use this patch, run these commands for a successful build:
     ./configure                          (optional if already run)
     make
 
-based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/syscall.c b/syscall.c
 --- a/syscall.c
 +++ b/syscall.c
index 4ece1ba..80c283a 100644 (file)
@@ -14,7 +14,7 @@ based-on: patch/acls
 diff --git a/compat.c b/compat.c
 --- a/compat.c
 +++ b/compat.c
-@@ -189,13 +189,6 @@ void setup_protocol(int f_out,int f_in)
+@@ -192,13 +192,6 @@ void setup_protocol(int f_out,int f_in)
        if (protocol_version < 30) {
                if (append_mode == 1)
                        append_mode = 2;
@@ -56,7 +56,7 @@ diff --git a/xattrs.c b/xattrs.c
                        /* For large datums, we store a flag and a checksum. */
                        name_offset = 1 + MAX_DIGEST_LEN;
                        sum_init(checksum_seed);
-@@ -351,7 +353,7 @@ static int find_matching_xattr(item_list *xalp)
+@@ -365,7 +367,7 @@ static int find_matching_xattr(item_list *xalp)
                         || rxas1[j].datum_len != rxas2[j].datum_len
                         || strcmp(rxas1[j].name, rxas2[j].name))
                                break;
@@ -65,7 +65,7 @@ diff --git a/xattrs.c b/xattrs.c
                                if (memcmp(rxas1[j].datum + 1,
                                           rxas2[j].datum + 1,
                                           MAX_DIGEST_LEN) != 0)
-@@ -388,13 +390,22 @@ int send_xattr(stat_x *sxp, int f)
+@@ -402,13 +404,22 @@ int send_xattr(int f, stat_x *sxp)
  {
        int ndx = find_matching_xattr(sxp->xattr);
  
@@ -91,7 +91,7 @@ diff --git a/xattrs.c b/xattrs.c
                for (rxa = sxp->xattr->items; count--; rxa++) {
                        size_t name_len = rxa->name_len;
                        const char *name = rxa->name;
-@@ -413,8 +424,8 @@ int send_xattr(stat_x *sxp, int f)
+@@ -427,8 +438,8 @@ int send_xattr(int f, stat_x *sxp)
                                name_len += UPRE_LEN;
                        }
  #endif
@@ -102,7 +102,7 @@ diff --git a/xattrs.c b/xattrs.c
  #ifndef HAVE_LINUX_XATTRS
                        if (name_len > rxa->name_len) {
                                write_buf(f, USER_PREFIX, UPRE_LEN);
-@@ -422,7 +433,7 @@ int send_xattr(stat_x *sxp, int f)
+@@ -436,7 +447,7 @@ int send_xattr(int f, stat_x *sxp)
                        }
  #endif
                        write_buf(f, name, name_len);
@@ -111,7 +111,7 @@ diff --git a/xattrs.c b/xattrs.c
                                write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
                        else
                                write_buf(f, rxa->datum, rxa->datum_len);
-@@ -472,7 +483,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
+@@ -486,7 +497,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
                cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
                if (cmp > 0)
                        same = 0;
@@ -120,7 +120,7 @@ diff --git a/xattrs.c b/xattrs.c
                        same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
                            && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
                                      MAX_DIGEST_LEN) == 0;
-@@ -517,6 +528,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
+@@ -531,6 +542,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
        int cnt, prior_req = 0;
        rsync_xa *rxa;
  
@@ -130,7 +130,7 @@ diff --git a/xattrs.c b/xattrs.c
        lst += F_XATTR(file);
        for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
                if (rxa->datum_len <= MAX_FULL_DATUM)
-@@ -573,6 +587,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
+@@ -587,6 +601,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
        rsync_xa *rxa;
        int rel_pos, cnt, num, got_xattr_data = 0;
  
@@ -140,7 +140,7 @@ diff --git a/xattrs.c b/xattrs.c
        if (F_XATTR(file) < 0) {
                rprintf(FERROR, "recv_xattr_request: internal data error!\n");
                exit_cleanup(RERR_STREAMIO);
-@@ -635,7 +652,22 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -649,7 +666,22 @@ void receive_xattr(int f, struct file_struct *file)
  #else
        int need_sort = 1;
  #endif
@@ -164,7 +164,7 @@ diff --git a/xattrs.c b/xattrs.c
  
        if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
                rprintf(FERROR, "receive_xattr: xa index %d out of"
-@@ -648,7 +680,7 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -662,7 +694,7 @@ void receive_xattr(int f, struct file_struct *file)
                return;
        }
        
@@ -173,7 +173,7 @@ diff --git a/xattrs.c b/xattrs.c
                (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
                temp_xattr.count = 0;
        }
-@@ -656,9 +688,10 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -670,9 +702,10 @@ void receive_xattr(int f, struct file_struct *file)
        for (num = 1; num <= count; num++) {
                char *ptr, *name;
                rsync_xa *rxa;