New Ticket     Tickets     Wiki     Browse Source     Timeline     Roadmap     Ticket Reports     Search

Changeset 80017


Ignore:
Timestamp:
07/01/11 21:52:41 (4 years ago)
Author:
blair@…
Message:

rsync: update to 3.0.8.

Location:
trunk/dports/net/rsync
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/dports/net/rsync/Portfile

    r75561 r80017  
    44 
    55name                rsync 
    6 version             3.0.7 
    7 revision            1 
     6version             3.0.8 
    87categories          net 
    98platforms           darwin freebsd sunos 
     
    2322                    http://rsync.samba.org/ftp/rsync/src/ 
    2423 
    25 checksums           md5     b53525900817cf1ba7ad3a516ab5bfe9 \ 
    26                     sha1    63426a1bc71991d93159cd522521fbacdafb7a61 \ 
    27                     rmd160  aa3bdec0d7692ac1de52f2efc925e9a34bbd917b 
     24checksums           md5     0ee8346ce16bdfe4c88a236e94c752b4 \ 
     25                    sha1    10e80173c7e9ed8b8a4dc9e8fdab08402da5f08d \ 
     26                    rmd160  f00c5ba42e33a1745976c9af5e770c220a6fa4a6 
    2827 
    2928depends_lib         port:popt port:libiconv 
    3029 
    31 # these come from http://rsync.samba.org/ftp/rsync/rsync-patches-3.0.7.tar.gz 
     30# these come from http://rsync.samba.org/ftp/rsync/rsync-patches-3.0.8.tar.gz 
    3231# and need to be updated with each release 
    3332patchfiles          patch-fileflags.diff \ 
  • trunk/dports/net/rsync/files/patch-crtimes.diff

    r75561 r80017  
    66    patch -p1 <patches/fileflags.diff 
    77    patch -p1 <patches/crtimes.diff 
    8     ./configure                      (optional if already run) 
     8    ./prepare-source 
     9    ./configure 
    910    make 
    1011 
     
    1314--- a/compat.c 
    1415+++ b/compat.c 
    15 @@ -46,6 +46,7 @@ extern int force_change; 
     16@@ -47,6 +47,7 @@ extern int force_change; 
    1617 extern int protect_args; 
    1718 extern int preserve_uid; 
     
    2122 extern int preserve_acls; 
    2223 extern int preserve_xattrs; 
    23 @@ -64,7 +65,7 @@ extern char *iconv_opt; 
     24@@ -65,7 +66,7 @@ extern char *iconv_opt; 
    2425 #endif 
    2526  
     
    3031 int receiver_symlink_times = 0; /* receiver can set the time on a symlink */ 
    3132 int sender_symlink_iconv = 0;  /* sender should convert symlink content */ 
    32 @@ -141,6 +142,8 @@ void setup_protocol(int f_out,int f_in) 
     33@@ -142,6 +143,8 @@ void setup_protocol(int f_out,int f_in) 
    3334                uid_ndx = ++file_extra_cnt; 
    3435        if (preserve_gid) 
     
    4243--- a/flist.c 
    4344+++ b/flist.c 
    44 @@ -56,6 +56,7 @@ extern int delete_during; 
    45  extern int uid_ndx; 
    46  extern int gid_ndx; 
     45@@ -54,6 +54,7 @@ extern int preserve_specials; 
     46 extern int preserve_fileflags; 
     47 extern int delete_during; 
    4748 extern int eol_nulls; 
    4849+extern int crtimes_ndx; 
    4950 extern int relative_paths; 
    5051 extern int implied_dirs; 
    51  extern int file_extra_cnt; 
    52 @@ -395,7 +396,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     52 extern int ignore_perishable; 
     53@@ -393,7 +394,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    5354 #endif 
    5455                            int ndx, int first_ndx) 
     
    5960 #ifdef SUPPORT_FILEFLAGS 
    6061        static uint32 fileflags; 
    61 @@ -490,6 +491,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     62@@ -488,6 +489,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    6263                xflags |= XMIT_SAME_TIME; 
    6364        else 
     
    7273  
    7374 #ifdef SUPPORT_HARD_LINKS 
    74         if (tmp_dev != 0) { 
    75 @@ -559,6 +567,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     75        if (tmp_dev != -1) { 
     76@@ -557,6 +565,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    7677                else 
    7778                        write_int(f, modtime); 
     
    8283                write_int(f, to_wire_mode(mode)); 
    8384 #ifdef SUPPORT_FILEFLAGS 
    84 @@ -649,7 +659,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    85  static struct file_struct *recv_file_entry(struct file_list *flist, 
    86                                            int xflags, int f) 
     85@@ -648,7 +658,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     86  
     87 static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags) 
    8788 { 
    8889-       static int64 modtime; 
     
    9192 #ifdef SUPPORT_FILEFLAGS 
    9293        static uint32 fileflags; 
    93 @@ -755,6 +765,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     94@@ -758,6 +768,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    9495                                uid = F_OWNER(first); 
    9596                        if (preserve_gid) 
     
    100101                                uint32 *devp = F_RDEV_P(first); 
    101102                                rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); 
    102 @@ -783,6 +795,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     103@@ -786,6 +798,19 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    103104                } else 
    104105                        modtime = read_int(f); 
     
    120121                mode = from_wire_mode(read_int(f)); 
    121122  
    122 @@ -943,6 +968,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     123@@ -946,6 +971,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    123124                F_GROUP(file) = gid; 
    124125                file->flags |= gid_flags; 
     
    129130                F_NDX(file) = flist->used + flist->ndx_start; 
    130131  
    131 @@ -1319,6 +1346,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, 
    132                 F_OWNER(file) = st.st_uid; 
    133         if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */ 
     132@@ -1324,6 +1351,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, 
    134133                F_GROUP(file) = st.st_gid; 
     134        if (am_generator && st.st_uid == our_uid) 
     135                file->flags |= FLAG_OWNED_BY_US; 
    135136+       if (crtimes_ndx) 
    136137+               f_crtime_set(file, get_create_time(fname)); 
     
    149150 extern int verbose; 
    150151 extern int dry_run; 
    151 @@ -40,6 +41,7 @@ extern int preserve_xattrs; 
     152@@ -41,6 +42,7 @@ extern int preserve_xattrs; 
    152153 extern int preserve_links; 
    153154 extern int preserve_devices; 
     
    157158 extern int preserve_executability; 
    158159 extern int preserve_fileflags; 
    159 @@ -623,6 +625,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) 
    160         if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) 
    161                 return 0; 
    162   
     160@@ -576,8 +578,15 @@ static void do_delete_pass(void) 
     161                rprintf(FINFO, "                    \r"); 
     162 } 
     163  
     164-static inline int time_differs(struct file_struct *file, stat_x *sxp) 
     165+static inline int time_differs(struct file_struct *file, stat_x *sxp, const char *fname) 
     166 { 
    163167+       if (crtimes_ndx) { 
    164168+               if (sxp->crtime == 0) 
    165169+                       sxp->crtime = get_create_time(fname); 
    166170+               if (cmp_time(sxp->crtime, f_crtime(file)) != 0) 
    167 +                       return 0; 
     171+                       return 1; 
    168172+       } 
    169173+ 
    170  #ifdef SUPPORT_ACLS 
    171         if (preserve_acls && !S_ISLNK(file->mode)) { 
    172                 if (!ACL_READY(*sxp)) 
    173 @@ -666,6 +675,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre 
     174        return cmp_time(sxp->st.st_mtime, file->modtime); 
     175 } 
     176  
     177@@ -635,7 +644,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) 
     178 { 
     179        if (S_ISLNK(file->mode)) { 
     180 #ifdef CAN_SET_SYMLINK_TIMES 
     181-               if (preserve_times & PRESERVE_LINK_TIMES && time_differs(file, sxp)) 
     182+               if (preserve_times & PRESERVE_LINK_TIMES && time_differs(file, sxp, fname)) 
     183                        return 0; 
     184 #endif 
     185 #ifdef CAN_CHMOD_SYMLINK 
     186@@ -655,7 +664,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) 
     187                        return 0; 
     188 #endif 
     189        } else { 
     190-               if (preserve_times && time_differs(file, sxp)) 
     191+               if (preserve_times && time_differs(file, sxp, fname)) 
     192                        return 0; 
     193                if (perms_differ(file, sxp)) 
     194                        return 0; 
     195@@ -698,6 +707,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre 
    174196                 : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) 
    175197                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) 
     
    184206                if (S_ISLNK(file->mode)) { 
    185207                        ; 
    186 @@ -1225,7 +1240,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, 
     208@@ -1263,7 +1278,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, 
    187209  
    188210 static void list_file_entry(struct file_struct *f) 
     
    193215  
    194216        if (!F_IS_ACTIVE(f)) { 
    195 @@ -1236,19 +1251,24 @@ static void list_file_entry(struct file_struct *f) 
     217@@ -1274,19 +1289,24 @@ static void list_file_entry(struct file_struct *f) 
    196218        permstring(permbuf, f->mode); 
    197219        len = F_LENGTH(f); 
     
    222244 } 
    223245  
    224 @@ -1339,6 +1359,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
     246@@ -1383,6 +1403,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
    225247                        return; 
    226248                } 
     
    228250+       sx.crtime = 0; 
    229251  
    230  #ifdef SUPPORT_ACLS 
    231         sx.acc_acl = sx.def_acl = NULL; 
     252        if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) { 
     253          parent_is_dry_missing: 
    232254diff --git a/hlink.c b/hlink.c 
    233255--- a/hlink.c 
    234256+++ b/hlink.c 
    235 @@ -370,6 +370,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname, 
     257@@ -371,6 +371,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname, 
    236258                char cmpbuf[MAXPATHLEN]; 
    237259                stat_x alt_sx; 
     
    241263                alt_sx.acc_acl = alt_sx.def_acl = NULL; 
    242264 #endif 
    243 @@ -498,6 +499,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx, 
     265@@ -499,6 +500,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx, 
    244266        } else 
    245267                our_name = fname; 
     
    284306--- a/log.c 
    285307+++ b/log.c 
    286 @@ -663,7 +663,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, 
     308@@ -661,7 +661,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, 
    287309                        c[8] = !(iflags & ITEM_REPORT_FFLAGS) ? '.' : 'f'; 
    288310                        c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a'; 
     
    305327 int cvs_exclude = 0; 
    306328 int dry_run = 0; 
    307 @@ -362,6 +363,7 @@ void usage(enum logcode F) 
     329@@ -361,6 +362,7 @@ void usage(enum logcode F) 
    308330   rprintf(F," -D                          same as --devices --specials\n"); 
    309331   rprintf(F," -t, --times                 preserve modification times\n"); 
     
    313335 #ifdef SUPPORT_XATTRS 
    314336   rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n"); 
    315 @@ -508,6 +510,9 @@ static struct poptOption long_options[] = { 
    316    {"times",           't', POPT_ARG_VAL,    &preserve_times, 2, 0, 0 }, 
     337@@ -507,6 +509,9 @@ static struct poptOption long_options[] = { 
     338   {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 }, 
    317339   {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 }, 
    318340   {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 }, 
     
    323345   {"no-omit-dir-times",0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 }, 
    324346   {"no-O",             0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 }, 
    325 @@ -1805,6 +1810,8 @@ void server_options(char **args, int *argc_p) 
     347@@ -1810,6 +1815,8 @@ void server_options(char **args, int *argc_p) 
    326348                argstr[x++] = 'D'; 
    327349        if (preserve_times) 
     
    335357--- a/rsync.c 
    336358+++ b/rsync.c 
    337 @@ -427,6 +427,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     359@@ -464,6 +464,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    338360                                full_fname(fname)); 
    339361                        return 0; 
     
    343365                sx2.acc_acl = sx2.def_acl = NULL; 
    344366 #endif 
    345 @@ -474,6 +475,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     367@@ -505,6 +506,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     368         || (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode)) 
     369         || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode))) 
     370                flags |= ATTRS_SKIP_MTIME; 
     371+       /* Don't set the creation date on the root folder of an HFS+ volume. */ 
     372+       if (sxp->st.st_ino == 2 && S_ISDIR(sxp->st.st_mode)) 
     373+               flags |= ATTRS_SKIP_CRTIME; 
     374        if (!(flags & ATTRS_SKIP_MTIME) 
     375            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) { 
     376                int ret = set_modtime(fname, file->modtime, sxp->st.st_mode, ST_FLAGS(sxp->st)); 
     377@@ -518,6 +522,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    346378                else 
    347379                        file->flags |= FLAG_TIME_FAILED; 
     
    358390        change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); 
    359391        change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP) 
    360 @@ -621,7 +630,7 @@ int finish_transfer(const char *fname, const char *fnametmp, 
     392@@ -675,7 +687,7 @@ int finish_transfer(const char *fname, const char *fnametmp, 
    361393        /* Change permissions before putting the file into place. */ 
    362394        set_file_attrs(fnametmp, file, NULL, fnamecmp, 
     
    367399        /* move tmp file over real file */ 
    368400        if (verbose > 2) 
    369 @@ -652,7 +661,7 @@ int finish_transfer(const char *fname, const char *fnametmp, 
     401@@ -706,7 +718,7 @@ int finish_transfer(const char *fname, const char *fnametmp, 
    370402  
    371403   do_set_file_attrs: 
     
    387419  
    388420 /* These flags are used in the live flist data. */ 
    389 @@ -157,6 +158,7 @@ 
     421@@ -162,6 +163,7 @@ 
    390422 #define ATTRS_REPORT           (1<<0) 
    391423 #define ATTRS_SKIP_MTIME       (1<<1) 
     
    395427 #define FULL_FLUSH     1 
    396428 #define NORMAL_FLUSH   0 
    397 @@ -173,7 +175,7 @@ 
     429@@ -178,7 +180,7 @@ 
    398430 #define FNAMECMP_FUZZY         0x83 
    399431  
     
    404436 #define ITEM_REPORT_SIZE (1<<2)     /* regular files only */ 
    405437 #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */ 
    406 @@ -658,6 +660,7 @@ extern int file_extra_cnt; 
     438@@ -677,6 +679,7 @@ extern int file_extra_cnt; 
    407439 extern int inc_recurse; 
    408440 extern int uid_ndx; 
     
    412444 extern int acls_ndx; 
    413445 extern int xattrs_ndx; 
    414 @@ -665,6 +668,7 @@ extern int xattrs_ndx; 
     446@@ -684,6 +687,7 @@ extern int xattrs_ndx; 
    415447 #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename)) 
    416448 #define EXTRA_LEN (sizeof (union file_extras)) 
     
    420452 #define DIRNODE_EXTRA_CNT 3 
    421453 #define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN) 
    422 @@ -932,6 +936,7 @@ typedef struct { 
     454@@ -951,6 +955,7 @@ typedef struct { 
    423455  
    424456 typedef struct { 
     
    439471      --fake-super            store/recover privileged attrs using xattrs 
    440472  -S, --sparse                handle sparse files efficiently 
    441 @@ -1039,6 +1040,9 @@ it is preserving modification times (see bf(--times)).  If NFS is sharing 
     473@@ -1086,6 +1087,9 @@ it is preserving modification times (see bf(--times)).  If NFS is sharing 
    442474 the directories on the receiving side, it is a good idea to use bf(-O). 
    443475 This option is inferred if you use bf(--backup) without bf(--backup-dir). 
     
    449481 activities even if the receiving rsync wasn't run by the super-user.  These 
    450482 activities include: preserving users via the bf(--owner) option, preserving 
    451 @@ -1717,7 +1721,7 @@ with older versions of rsync, but that also turns on the output of other 
     483@@ -1782,7 +1786,7 @@ with older versions of rsync, but that also turns on the output of other 
    452484 verbose messages). 
    453485  
     
    458490 other letters represent attributes that may be output if they are being 
    459491 modified. 
    460 @@ -1776,6 +1780,8 @@ quote(itemization( 
     492@@ -1841,6 +1845,8 @@ quote(itemization( 
    461493   it() The bf(f) means that the fileflags information changed. 
    462494   it() The bf(a) means that the ACL information changed. 
     
    470502--- a/syscall.c 
    471503+++ b/syscall.c 
    472 @@ -37,6 +37,14 @@ extern int force_change; 
     504@@ -37,6 +37,13 @@ extern int force_change; 
    473505 extern int preserve_perms; 
    474506 extern int preserve_executability; 
    475507  
    476 +#pragma pack(push) 
    477 +#pragma pack(4) 
     508+#pragma pack(push, 4) 
    478509+struct create_time { 
    479510+       uint32 length; 
     
    485516        do { \ 
    486517                if (x) { \ 
    487 @@ -394,3 +399,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) 
    488         return lseek(fd, offset, whence); 
     518@@ -529,6 +536,36 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) 
    489519 #endif 
    490520 } 
    491 + 
     521  
    492522+time_t get_create_time(const char *path) 
    493523+{ 
     
    519549+       return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW); 
    520550+} 
     551+ 
     552 #ifdef HAVE_UTIMENSAT 
     553 int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags) 
     554 { 
    521555diff --git a/testsuite/crtimes.test b/testsuite/crtimes.test 
    522556new file mode 100644 
     
    561595+allspace='          ' 
    562596+dots='......' # trailing dots after changes 
     597 tab_ch='       ' # a single tab character 
    563598  
    564599 # Berkley's nice. 
    565  PATH="$PATH:/usr/ucb" 
    566600diff --git a/tls.c b/tls.c 
    567601--- a/tls.c 
     
    668702--- a/proto.h 
    669703+++ b/proto.h 
    670 @@ -314,6 +314,8 @@ int do_stat(const char *fname, STRUCT_ST 
     704@@ -315,6 +315,8 @@ int do_stat(const char *fname, STRUCT_ST 
    671705 int do_lstat(const char *fname, STRUCT_STAT *st); 
    672706 int do_fstat(int fd, STRUCT_STAT *st); 
     
    674708+time_t get_create_time(const char *path); 
    675709+int set_create_time(const char *path, time_t crtime); 
    676  void set_compression(const char *fname); 
    677  void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset, 
    678                 int32 n, int32 toklen); 
     710 int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
     711 int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
     712 int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
    679713diff -up a/rsync.1 b/rsync.1 
    680714--- a/rsync.1 
    681715+++ b/rsync.1 
    682 @@ -429,6 +429,7 @@ to the detailed description below for a  
     716@@ -429,6 +429,7 @@ to the detailed description below for a 
    683717  \-D                          same as \-\-devices \-\-specials 
    684718  \-t, \-\-times                 preserve modification times 
    685719  \-O, \-\-omit\-dir\-times        omit directories from \-\-times 
    686720+ \-N, \-\-crtimes               preserve create times (newness) 
    687       \-\-super                 receiver attempts super-user activities 
     721      \-\-super                 receiver attempts super\-user activities 
    688722      \-\-fake\-super            store/recover privileged attrs using xattrs 
    689723  \-S, \-\-sparse                handle sparse files efficiently 
    690 @@ -1194,6 +1195,10 @@ it is preserving modification times (see 
     724@@ -1253,6 +1254,10 @@ it is preserving modification times (see 
    691725 the directories on the receiving side, it is a good idea to use \fB\-O\fP. 
    692726 This option is inferred if you use \fB\-\-backup\fP without \fB\-\-backup\-dir\fP. 
     
    697731+.IP  
    698732 .IP "\fB\-\-super\fP" 
    699  This tells the receiving side to attempt super-user 
    700  activities even if the receiving rsync wasn\(cq\&t run by the super-user.  These 
    701 @@ -1963,7 +1968,7 @@ with older versions of rsync, but that a 
     733 This tells the receiving side to attempt super\-user 
     734 activities even if the receiving rsync wasn\(cq\&t run by the super\-user.  These 
     735@@ -2037,7 +2042,7 @@ with older versions of rsync, but that a 
    702736 verbose messages). 
    703737 .IP  
     
    705739-format is like the string \fBYXcstpogfax\fP, where \fBY\fP is replaced by the 
    706740+format is like the string \fBYXcstpogfaxn\fP, where \fBY\fP is replaced by the 
    707  type of update being done, \fBX\fP is replaced by the file-type, and the 
     741 type of update being done, \fBX\fP is replaced by the file\-type, and the 
    708742 other letters represent attributes that may be output if they are being 
    709743 modified. 
    710 @@ -2038,6 +2043,9 @@ The \fBf\fP means that the fileflags inf 
     744@@ -2112,6 +2117,9 @@ The \fBf\fP means that the fileflags inf 
    711745 The \fBa\fP means that the ACL information changed. 
    712746 .IP o  
  • trunk/dports/net/rsync/files/patch-fileflags.diff

    r62301 r80017  
    99    make 
    1010 
    11 based-on: 54f00c3f89fc147f2f9cba89d26a5bb1d20e783b 
     11based-on: 1ddcdaf3f6808ba53aef9e19f630a18808de22ac 
    1212diff --git a/Makefile.in b/Makefile.in 
    1313--- a/Makefile.in 
     
    3434--- a/compat.c 
    3535+++ b/compat.c 
    36 @@ -42,9 +42,11 @@ extern int checksum_seed; 
     36@@ -43,9 +43,11 @@ extern int checksum_seed; 
    3737 extern int basis_dir_cnt; 
    3838 extern int prune_empty_dirs; 
     
    4646 extern int preserve_xattrs; 
    4747 extern int need_messages_from_generator; 
    48 @@ -62,7 +64,7 @@ extern char *iconv_opt; 
     48@@ -63,7 +65,7 @@ extern char *iconv_opt; 
    4949 #endif 
    5050  
     
    5555 int receiver_symlink_times = 0; /* receiver can set the time on a symlink */ 
    5656 int sender_symlink_iconv = 0;  /* sender should convert symlink content */ 
    57 @@ -139,6 +141,8 @@ void setup_protocol(int f_out,int f_in) 
     57@@ -140,6 +142,8 @@ void setup_protocol(int f_out,int f_in) 
    5858                uid_ndx = ++file_extra_cnt; 
    5959        if (preserve_gid) 
     
    6464                acls_ndx = ++file_extra_cnt; 
    6565        if (preserve_xattrs) 
    66 diff --git a/configure.in b/configure.in 
    67 --- a/configure.in 
    68 +++ b/configure.in 
    69 @@ -567,6 +567,7 @@ AC_FUNC_UTIME_NULL 
     66diff --git a/configure.ac b/configure.ac 
     67--- a/configure.ac 
     68+++ b/configure.ac 
     69@@ -569,6 +569,7 @@ AC_FUNC_UTIME_NULL 
    7070 AC_FUNC_ALLOCA 
    7171 AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ 
     
    8484+extern int preserve_fileflags; 
    8585 extern int delete_during; 
    86  extern int uid_ndx; 
    87  extern int gid_ndx; 
    88 @@ -396,6 +397,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     86 extern int eol_nulls; 
     87 extern int relative_paths; 
     88@@ -394,6 +395,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    8989 { 
    9090        static time_t modtime; 
     
    9696        static int64 dev; 
    9797 #endif 
    98 @@ -425,6 +429,14 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     98@@ -423,6 +427,14 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    9999                xflags |= XMIT_SAME_MODE; 
    100100        else 
     
    111111        if (preserve_devices && IS_DEVICE(mode)) { 
    112112                if (protocol_version < 28) { 
    113 @@ -549,6 +561,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
     113@@ -547,6 +559,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, 
    114114        } 
    115115        if (!(xflags & XMIT_SAME_MODE)) 
     
    122122                if (protocol_version < 30) 
    123123                        write_int(f, uid); 
    124 @@ -635,6 +651,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     124@@ -634,6 +650,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    125125 { 
    126126        static int64 modtime; 
     
    132132        static int64 dev; 
    133133 #endif 
    134 @@ -769,6 +788,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     134@@ -731,6 +750,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
     135                        file_length = F_LENGTH(first); 
     136                        modtime = first->modtime; 
     137                        mode = first->mode; 
     138+#ifdef SUPPORT_FILEFLAGS 
     139+                       if (preserve_fileflags) 
     140+                               fileflags = F_FFLAGS(first); 
     141+#endif 
     142                        if (preserve_uid) 
     143                                uid = F_OWNER(first); 
     144                        if (preserve_gid) 
     145@@ -768,6 +791,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    135146  
    136147        if (chmod_modes && !S_ISLNK(mode)) 
     
    143154        if (preserve_uid && !(xflags & XMIT_SAME_UID)) { 
    144155                if (protocol_version < 30) 
    145 @@ -910,6 +933,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 
     156@@ -909,6 +936,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x 
    146157        } 
    147158 #endif 
    148159        file->mode = mode; 
    149160+#ifdef SUPPORT_FILEFLAGS 
    150 +       if (preserve_fileflags) 
     161+       if (fileflags_ndx) /* check the ndx for force_change w/o preserve_fileflags */ 
    151162+               F_FFLAGS(file) = fileflags; 
    152163+#endif 
     
    154165                F_OWNER(file) = uid; 
    155166        if (preserve_gid) { 
    156 @@ -1284,6 +1311,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, 
     167@@ -1283,6 +1314,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, 
    157168        } 
    158169 #endif 
     
    162173+               F_FFLAGS(file) = st.st_flags; 
    163174+#endif 
    164         if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */ 
     175        if (preserve_uid) 
    165176                F_OWNER(file) = st.st_uid; 
    166         if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */ 
    167 @@ -1427,6 +1458,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, 
    168  #endif 
     177        if (preserve_gid) 
     178@@ -1429,6 +1464,9 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, 
    169179 #ifdef SUPPORT_XATTRS 
    170180                if (preserve_xattrs) { 
    171 +                       sx.st.st_mode = file->mode; 
     181                        sx.st.st_mode = file->mode; 
     182+#ifdef SUPPORT_FILEFLAGS 
     183+                       sx.st.st_flags = preserve_fileflags ? F_FFLAGS(file) : 0; 
     184+#endif 
    172185                        sx.xattr = NULL; 
    173186                        if (get_xattr(fname, &sx) < 0) { 
     
    176189--- a/generator.c 
    177190+++ b/generator.c 
    178 @@ -42,8 +42,10 @@ extern int preserve_devices; 
     191@@ -35,6 +35,7 @@ extern int do_progress; 
     192 extern int relative_paths; 
     193 extern int implied_dirs; 
     194 extern int keep_dirlinks; 
     195+extern int force_change; 
     196 extern int preserve_acls; 
     197 extern int preserve_xattrs; 
     198 extern int preserve_links; 
     199@@ -42,6 +43,7 @@ extern int preserve_devices; 
    179200 extern int preserve_specials; 
    180201 extern int preserve_hard_links; 
     
    183204 extern int preserve_perms; 
    184205 extern int preserve_times; 
    185 +extern int force_change; 
    186  extern int uid_ndx; 
    187  extern int gid_ndx; 
    188206 extern int delete_mode; 
    189 @@ -166,7 +168,7 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) 
     207@@ -164,11 +166,15 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) 
    190208        } 
    191209  
     
    195213  
    196214        if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) { 
    197                 int save_uid_ndx = uid_ndx; 
    198 @@ -174,6 +176,13 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) 
     215                /* This only happens on the first call to delete_item() since 
    199216                 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */ 
    200                 if (!uid_ndx) 
    201                         uid_ndx = ++file_extra_cnt; 
    202 +#ifdef SUPPORT_FORCE_CHANGE 
    203 +               if (force_change) { 
    204 +                       STRUCT_STAT st; 
    205 +                       if (x_lstat(fbuf, &st, NULL) == 0) 
    206 +                               make_mutable(fbuf, st.st_mode, st.st_flags, force_change); 
    207 +               } 
     217+#ifdef SUPPORT_FORCE_CHANGE 
     218+               if (force_change) 
     219+                       make_mutable(fbuf, NULL, NO_FFLAGS, force_change); 
    208220+#endif 
    209221                ignore_perishable = 1; 
    210222                /* If DEL_RECURSE is not set, this just reports emptiness. */ 
    211223                ret = delete_dir_contents(fbuf, flags); 
    212 @@ -294,8 +303,12 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) 
     224@@ -285,8 +291,14 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) 
    213225                } 
    214226  
    215227                strlcpy(p, fp->basename, remainder); 
    216228+#ifdef SUPPORT_FORCE_CHANGE 
    217 +               if (force_change) 
    218 +                       make_mutable(fname, fp->mode, F_FFLAGS(fp), force_change); 
    219 +#endif 
    220                 if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid) 
     229+               if (force_change) { 
     230+                       mode_t mode = fp->mode; 
     231+                       make_mutable(fname, &mode, F_FFLAGS(fp), force_change); 
     232+               } 
     233+#endif 
     234                if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) 
    221235-                       do_chmod(fname, fp->mode | S_IWUSR); 
    222236+                       do_chmod(fname, fp->mode | S_IWUSR, NO_FFLAGS); 
     
    224238                if (S_ISDIR(fp->mode)) { 
    225239                        if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) 
    226 @@ -599,6 +612,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) 
    227          && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) 
    228                 return 0; 
    229   
     240@@ -647,6 +659,10 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) 
     241                        return 0; 
     242                if (perms_differ(file, sxp)) 
     243                        return 0; 
    230244+#ifdef SUPPORT_FILEFLAGS 
    231 +       if (preserve_fileflags && !S_ISLNK(file->mode) && sxp->st.st_flags != F_FFLAGS(file)) 
    232 +               return 0; 
    233 +#endif 
    234 + 
    235         if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file)) 
    236                 return 0; 
    237   
    238 @@ -664,6 +682,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre 
     245+               if (preserve_fileflags && sxp->st.st_flags != F_FFLAGS(file)) 
     246+                       return 0; 
     247+#endif 
     248                if (ownership_differs(file, sxp)) 
     249                        return 0; 
     250 #ifdef SUPPORT_ACLS 
     251@@ -698,6 +714,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre 
    239252                if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) 
    240253                    && sxp->st.st_gid != (gid_t)F_GROUP(file)) 
     
    248261                if (preserve_acls && !S_ISLNK(file->mode)) { 
    249262                        if (!ACL_READY(*sxp)) 
    250 @@ -1442,6 +1465,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
     263@@ -1491,6 +1512,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
    251264                        file->mode = dest_mode(file->mode, sx.st.st_mode, 
    252265                                               dflt_perms, statret == 0); 
     
    259272                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, 
    260273                                              itemizing, code); 
    261 @@ -1482,10 +1509,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
     274@@ -1526,10 +1551,17 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
    262275                /* We need to ensure that the dirs in the transfer have writable 
    263276                 * permissions during the time we are putting files within them. 
    264277                 * This is then fixed after the transfer is done. */ 
    265278+#ifdef SUPPORT_FORCE_CHANGE 
    266 +               if (force_change && F_FFLAGS(file) & force_change 
    267 +                && make_mutable(fname, file->mode, F_FFLAGS(file), force_change)) 
    268 +                       need_retouch_dir_perms = 1; 
     279+               if (force_change && F_FFLAGS(file) & force_change) { 
     280+                       mode_t mode = file->mode; 
     281+                       if (make_mutable(fname, &mode, F_FFLAGS(file), force_change)) 
     282+                               need_retouch_dir_perms = 1; 
     283+               } 
    269284+#endif 
    270285 #ifdef HAVE_CHMOD 
     
    276291                                        "failed to modify permissions on %s", 
    277292                                        full_fname(fname)); 
    278 @@ -1520,6 +1552,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
     293@@ -1572,6 +1604,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 
    279294                file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, 
    280295                                       exists); 
     
    287302 #ifdef SUPPORT_HARD_LINKS 
    288303        if (preserve_hard_links && F_HLINK_NOT_FIRST(file) 
    289 @@ -2061,13 +2097,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx) 
     304@@ -2115,13 +2151,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx) 
    290305                        continue; 
    291306                fname = f_name(file, NULL); 
     
    310325--- a/log.c 
    311326+++ b/log.c 
    312 @@ -660,7 +660,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op, 
     327@@ -658,7 +658,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op, 
    313328                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p'; 
    314329                        c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o'; 
     
    319334                        c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x'; 
    320335                        c[11] = '\0'; 
     336diff --git a/main.c b/main.c 
     337--- a/main.c 
     338+++ b/main.c 
     339@@ -26,6 +26,9 @@ 
     340 #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H 
     341 #include <locale.h> 
     342 #endif 
     343+#ifdef SUPPORT_FORCE_CHANGE 
     344+#include <sys/sysctl.h> 
     345+#endif 
     346  
     347 extern int verbose; 
     348 extern int dry_run; 
     349@@ -51,6 +54,7 @@ extern int protocol_version; 
     350 extern int file_total; 
     351 extern int recurse; 
     352 extern int xfer_dirs; 
     353+extern int force_change; 
     354 extern int protect_args; 
     355 extern int relative_paths; 
     356 extern int sanitize_paths; 
     357@@ -753,6 +757,22 @@ static int do_recv(int f_in, int f_out, char *local_name) 
     358         * points to an identical file won't be replaced by the referent. */ 
     359        copy_links = copy_dirlinks = copy_unsafe_links = 0; 
     360  
     361+#ifdef SUPPORT_FORCE_CHANGE 
     362+       if (force_change & SYS_IMMUTABLE) { 
     363+               /* Determine whether we'll be able to unlock a system immutable item. */ 
     364+               int mib[2]; 
     365+               int securityLevel = 0; 
     366+               size_t len = sizeof securityLevel; 
     367+ 
     368+               mib[0] = CTL_KERN; 
     369+               mib[1] = KERN_SECURELVL; 
     370+               if (sysctl(mib, 2, &securityLevel, &len, NULL, 0) == 0 && securityLevel > 0) { 
     371+                       rprintf(FERROR, "System security level is too high to force mutability on system immutable files and directories.\n"); 
     372+                       exit_cleanup(RERR_UNSUPPORTED); 
     373+               } 
     374+       } 
     375+#endif 
     376+ 
     377 #ifdef SUPPORT_HARD_LINKS 
     378        if (preserve_hard_links && !inc_recurse) 
     379                match_hard_links(first_flist); 
    321380diff --git a/options.c b/options.c 
    322381--- a/options.c 
     
    336395+int force_change = 0; 
    337396 int io_timeout = 0; 
    338  int allowed_lull = 0; 
    339397 int prune_empty_dirs = 0; 
    340 @@ -224,6 +226,7 @@ static void print_rsync_version(enum logcode f) 
     398 int use_qsort = 0; 
     399@@ -223,6 +225,7 @@ static void print_rsync_version(enum logcode f) 
    341400        char const *links = "no "; 
    342401        char const *iconv = "no "; 
     
    346405  
    347406 #if SUBPROTOCOL_VERSION != 0 
    348 @@ -257,6 +260,9 @@ static void print_rsync_version(enum logcode f) 
    349  #if defined HAVE_LUTIMES && defined HAVE_UTIMES 
     407@@ -256,6 +259,9 @@ static void print_rsync_version(enum logcode f) 
     408 #ifdef CAN_SET_SYMLINK_TIMES 
    350409        symtimes = ""; 
    351410 #endif 
     
    356415        rprintf(f, "%s  version %s  protocol version %d%s\n", 
    357416                RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); 
    358 @@ -270,8 +276,8 @@ static void print_rsync_version(enum logcode f) 
     417@@ -269,8 +275,8 @@ static void print_rsync_version(enum logcode f) 
    359418                (int)(sizeof (int64) * 8)); 
    360419        rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n", 
     
    367426 #ifdef MAINTAINER_MODE 
    368427        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); 
    369 @@ -338,6 +344,9 @@ void usage(enum logcode F) 
     428@@ -337,6 +343,9 @@ void usage(enum logcode F) 
    370429   rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n"); 
    371430   rprintf(F," -H, --hard-links            preserve hard links\n"); 
     
    377436   rprintf(F,"     --chmod=CHMOD           affect file and/or directory permissions\n"); 
    378437 #ifdef SUPPORT_ACLS 
    379 @@ -375,7 +384,12 @@ void usage(enum logcode F) 
     438@@ -374,7 +383,12 @@ void usage(enum logcode F) 
    380439   rprintf(F,"     --delete-after          receiver deletes after transfer, not during\n"); 
    381440   rprintf(F,"     --delete-excluded       also delete excluded files from destination dirs\n"); 
     
    391450   rprintf(F,"     --max-size=SIZE         don't transfer any file larger than SIZE\n"); 
    392451   rprintf(F,"     --min-size=SIZE         don't transfer any file smaller than SIZE\n"); 
    393 @@ -480,6 +494,10 @@ static struct poptOption long_options[] = { 
     452@@ -479,6 +493,10 @@ static struct poptOption long_options[] = { 
    394453   {"perms",           'p', POPT_ARG_VAL,    &preserve_perms, 1, 0, 0 }, 
    395454   {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 }, 
     
    402461   {"acls",            'A', POPT_ARG_NONE,   0, 'A', 0, 0 }, 
    403462   {"no-acls",          0,  POPT_ARG_VAL,    &preserve_acls, 0, 0, 0 }, 
    404 @@ -558,6 +576,14 @@ static struct poptOption long_options[] = { 
     463@@ -557,6 +575,14 @@ static struct poptOption long_options[] = { 
    405464   {"remove-source-files",0,POPT_ARG_VAL,    &remove_source_files, 1, 0, 0 }, 
    406465   {"force",            0,  POPT_ARG_VAL,    &force_delete, 1, 0, 0 }, 
     
    417476   {"no-ignore-errors", 0,  POPT_ARG_VAL,    &ignore_errors, 0, 0, 0 }, 
    418477   {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 }, 
    419 @@ -1874,6 +1900,9 @@ void server_options(char **args, int *argc_p) 
     478@@ -1879,6 +1905,9 @@ void server_options(char **args, int *argc_p) 
    420479        if (xfer_dirs && !recurse && delete_mode && am_sender) 
    421480                args[ac++] = "--no-r"; 
     
    427486                if (asprintf(&arg, "--compress-level=%d", def_compress_level) < 0) 
    428487                        goto oom; 
    429 @@ -1961,6 +1990,16 @@ void server_options(char **args, int *argc_p) 
     488@@ -1966,6 +1995,16 @@ void server_options(char **args, int *argc_p) 
    430489                        args[ac++] = "--delete-excluded"; 
    431490                if (force_delete) 
     
    447506--- a/rsync.c 
    448507+++ b/rsync.c 
    449 @@ -32,6 +32,7 @@ extern int dry_run; 
     508@@ -29,9 +29,11 @@ 
     509  
     510 extern int verbose; 
     511 extern int dry_run; 
     512+extern int force_change; 
    450513 extern int preserve_acls; 
    451514 extern int preserve_xattrs; 
     
    455518 extern int preserve_times; 
    456519 extern int am_root; 
    457 @@ -376,6 +377,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms, 
     520@@ -374,6 +376,74 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms, 
    458521        return new_mode; 
    459522 } 
     
    465528+       if (do_chflags(fname, fileflags) != 0) { 
    466529+               rsyserr(FERROR_XFER, errno, 
    467 +                       "failed to set file flags on %s", 
    468 +                       full_fname(fname)); 
     530+                       "failed to set fileflags (%x) on %s", 
     531+                       fileflags, full_fname(fname)); 
    469532+               return 0; 
    470533+       } 
     
    473536+} 
    474537+ 
    475 +/* Remove immutable flags from an object, so it can be altered/removed. */ 
    476 +int make_mutable(const char *fname, mode_t mode, uint32 fileflags, uint32 iflags) 
     538+/* Remove immutable flags from an object, so it can be altered/removed. 
     539+ * Returns the fileflags if flags were removed, otherwise 0.  If the 
     540+ * fileflags value is NO_FFLAGS, we will stat the fname to figure out 
     541+ * what the flags are, and return the mode via *mode_ptr (if non-NULL). */ 
     542+uint32 make_mutable(const char *fname, mode_t *mode_ptr, uint32 fileflags, uint32 iflags) 
    477543+{ 
    478 +       if (S_ISLNK(mode) || !(fileflags & iflags)) 
     544+       if (fileflags == NO_FFLAGS) { 
     545+               STRUCT_STAT st; 
     546+               if (x_lstat(fname, &st, NULL) < 0) 
     547+                       return 0; 
     548+               fileflags = st.st_flags; 
     549+               if (mode_ptr) 
     550+                       *mode_ptr = st.st_mode; 
     551+               else 
     552+                       mode_ptr = &st.st_mode; 
     553+       } 
     554+ 
     555+       if ((mode_ptr && S_ISLNK(*mode_ptr)) || !(fileflags & iflags)) 
    479556+               return 0; 
     557+ 
    480558+       if (!set_fileflags(fname, fileflags & ~iflags)) 
    481 +               return -1; 
    482 +       return 1; 
     559+               return 0; 
     560+ 
     561+       return fileflags; 
    483562+} 
    484563+ 
     
    486565+int undo_make_mutable(const char *fname, uint32 fileflags) 
    487566+{ 
    488 +       if (!set_fileflags(fname, fileflags)) 
     567+       if (!set_fileflags(fname, fileflags)) { 
     568+               rsyserr(FINFO, errno, "failed to relock %s", full_fname(fname)); 
    489569+               return -1; 
     570+       } 
    490571+       return 1; 
     572+} 
     573+ 
     574+/* This returns the st_flags value if the parent directory was made mutable, otherwise 0. 
     575+ * It stores the parent directory path into parent_dirbuf. */ 
     576+int make_parentdir_mutable(const char *fname, uint32 iflags, char *parent_dirbuf, int parent_dirbuf_size) 
     577+{ 
     578+       char *slash = strrchr(fname, '/'); 
     579+ 
     580+       if (slash) { 
     581+               int len = slash - fname; 
     582+               if (len >= parent_dirbuf_size) 
     583+                       return 0; 
     584+               strlcpy(parent_dirbuf, fname, len+1); 
     585+       } else 
     586+               strlcpy(parent_dirbuf, ".", parent_dirbuf_size); 
     587+ 
     588+       return make_mutable(parent_dirbuf, NULL, NO_FFLAGS, iflags); 
    491589+} 
    492590+#endif 
     
    495593                   const char *fnamecmp, int flags) 
    496594 { 
    497 @@ -429,7 +463,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     595@@ -382,6 +452,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     596        int change_uid, change_gid; 
     597        mode_t new_mode = file->mode; 
     598        int inherit; 
     599+#ifdef SUPPORT_FORCE_CHANGE 
     600+       int became_mutable = 0; 
     601+#endif 
     602  
     603        if (!sxp) { 
     604                if (dry_run) 
     605@@ -411,6 +484,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     606        if (daemon_chmod_modes && !S_ISLNK(new_mode)) 
     607                new_mode = tweak_mode(new_mode, daemon_chmod_modes); 
     608  
     609+#ifdef SUPPORT_FORCE_CHANGE 
     610+       if (force_change) 
     611+               became_mutable = make_mutable(fname, &sxp->st.st_mode, sxp->st.st_flags, force_change); 
     612+#endif 
     613+ 
     614 #ifdef SUPPORT_ACLS 
     615        if (preserve_acls && !S_ISLNK(file->mode) && !ACL_READY(*sxp)) 
     616                get_acl(fname, sxp); 
     617@@ -429,7 +507,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    498618                flags |= ATTRS_SKIP_MTIME; 
    499619        if (!(flags & ATTRS_SKIP_MTIME) 
     
    504624                        rsyserr(FERROR_XFER, errno, "failed to set times on %s", 
    505625                                full_fname(fname)); 
    506 @@ -465,7 +499,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     626@@ -465,7 +543,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    507627                if (am_root >= 0) { 
    508                         if (do_lchown(fname, 
    509                             change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid, 
    510 -                           change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid) != 0) { 
    511 +                           change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid, 
    512 +                           sxp->st.st_mode, ST_FLAGS(sxp->st)) != 0) { 
     628                        uid_t uid = change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid; 
     629                        gid_t gid = change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid; 
     630-                       if (do_lchown(fname, uid, gid) != 0) { 
     631+                       if (do_lchown(fname, uid, gid, sxp->st.st_mode, ST_FLAGS(sxp->st)) != 0) { 
    513632                                /* We shouldn't have attempted to change uid 
    514633                                 * or gid unless have the privilege. */ 
    515634                                rsyserr(FERROR_XFER, errno, "%s %s failed", 
    516 @@ -497,7 +532,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     635@@ -503,7 +581,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    517636  
    518637 #ifdef HAVE_CHMOD 
     
    523642                        rsyserr(FERROR_XFER, errno, 
    524643                                "failed to set permissions on %s", 
    525 @@ -509,6 +544,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
     644@@ -515,6 +593,24 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    526645        } 
    527646 #endif 
    528647  
     648+#ifdef SUPPORT_FORCE_CHANGE 
     649+       if (became_mutable) 
     650+               undo_make_mutable(fname, sxp->st.st_flags); 
     651+#endif 
     652+ 
    529653+#ifdef SUPPORT_FILEFLAGS 
    530654+       if (preserve_fileflags && !S_ISLNK(sxp->st.st_mode) 
     
    543667                if (updated) 
    544668                        rprintf(FCLIENT, "%s\n", fname); 
    545 @@ -572,7 +620,8 @@ int finish_transfer(const char *fname, const char *fnametmp, 
     669@@ -578,7 +674,8 @@ int finish_transfer(const char *fname, const char *fnametmp, 
    546670  
    547671        /* Change permissions before putting the file into place. */ 
     
    553677        /* move tmp file over real file */ 
    554678        if (verbose > 2) 
    555 @@ -591,6 +640,10 @@ int finish_transfer(const char *fname, const char *fnametmp, 
     679@@ -597,6 +694,10 @@ int finish_transfer(const char *fname, const char *fnametmp, 
    556680        } 
    557681        if (ret == 0) { 
     
    575699 /* These flags are used in the live flist data. */ 
    576700  
    577 @@ -155,6 +156,7 @@ 
     701@@ -160,6 +161,7 @@ 
    578702  
    579703 #define ATTRS_REPORT           (1<<0) 
     
    583707 #define FULL_FLUSH     1 
    584708 #define NORMAL_FLUSH   0 
    585 @@ -181,6 +183,7 @@ 
     709@@ -186,6 +188,7 @@ 
    586710 #define ITEM_REPORT_GROUP (1<<6) 
    587711 #define ITEM_REPORT_ACL (1<<7) 
     
    591715 #define ITEM_XNAME_FOLLOWS (1<<12) 
    592716 #define ITEM_IS_NEW (1<<13) 
    593 @@ -463,6 +466,28 @@ typedef unsigned int size_t; 
     717@@ -482,6 +485,28 @@ typedef unsigned int size_t; 
    594718 #endif 
    595719 #endif 
     
    620744  * If some code depends on 32-bit truncation, it will need to 
    621745  * take special action in a "#if SIZEOF_INT32 > 4" section. */ 
    622 @@ -633,6 +658,7 @@ extern int file_extra_cnt; 
     746@@ -652,6 +677,7 @@ extern int file_extra_cnt; 
    623747 extern int inc_recurse; 
    624748 extern int uid_ndx; 
     
    628752 extern int xattrs_ndx; 
    629753  
    630 @@ -670,6 +696,11 @@ extern int xattrs_ndx; 
     754@@ -689,6 +715,11 @@ extern int xattrs_ndx; 
    631755 /* When the associated option is on, all entries will have these present: */ 
    632756 #define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum 
     
    673797 dit(--no-OPTION) You may turn off one or more implied options by prefixing 
    674798 the option name with "no-".  Not all options may be prefixed with a "no-": 
    675 @@ -809,7 +814,7 @@ they would be using bf(--copy-links). 
     799@@ -827,7 +832,7 @@ they would be using bf(--copy-links). 
    676800 Without this option, if the sending side has replaced a directory with a 
    677801 symlink to a directory, the receiving side will delete anything that is in 
     
    682806 See also bf(--keep-dirlinks) for an analogous option for the receiving 
    683807 side. 
    684 @@ -946,6 +951,29 @@ super-user copies all namespaces except system.*.  A normal user only copies 
    685  the user.* namespace.  To be able to backup and restore non-user namespaces as 
    686  a normal user, see the bf(--fake-super) option. 
     808@@ -990,6 +995,29 @@ Note that this option does not copy rsyncs special xattr values (e.g. those 
     809 used by bf(--fake-super)) unless you repeat the option (e.g. -XX).  This 
     810 "copy all xattrs" mode cannot be used with bf(--fake-super). 
    687811  
    688812+dit(bf(--fileflags)) This option causes rsync to update the file-flags to be 
     
    712836 comma-separated "chmod" strings to the permission of the files in the 
    713837 transfer.  The resulting value is treated as though it were the permissions 
    714 @@ -1217,12 +1245,13 @@ See bf(--delete) (which is implied) for more details on file-deletion. 
     838@@ -1260,12 +1288,13 @@ See bf(--delete) (which is implied) for more details on file-deletion. 
    715839 dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files 
    716840 even when there are I/O errors. 
     
    729853  
    730854 dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM 
    731 @@ -1688,7 +1717,7 @@ with older versions of rsync, but that also turns on the output of other 
     855@@ -1753,7 +1782,7 @@ with older versions of rsync, but that also turns on the output of other 
    732856 verbose messages). 
    733857  
     
    738862 other letters represent attributes that may be output if they are being 
    739863 modified. 
    740 @@ -1744,7 +1773,7 @@ quote(itemization( 
     864@@ -1809,7 +1838,7 @@ quote(itemization( 
    741865   sender's value (requires bf(--owner) and super-user privileges). 
    742866   it() A bf(g) means the group is different and is being updated to the 
     
    758882 extern int preserve_executability; 
    759883  
    760 @@ -50,7 +51,23 @@ int do_unlink(const char *fname) 
     884@@ -50,14 +51,56 @@ int do_unlink(const char *fname) 
    761885 { 
    762886        if (dry_run) return 0; 
     
    765889+       if (unlink(fname) == 0) 
    766890+               return 0; 
    767 +#ifdef SUPPORT_FORCE_CHANGE 
    768 +       if (force_change && errno == EPERM) { 
    769 +               STRUCT_STAT st; 
    770 + 
    771 +               if (x_lstat(fname, &st, NULL) == 0 
    772 +                && make_mutable(fname, st.st_mode, st.st_flags, force_change) > 0) { 
    773 +                       if (unlink(fname) == 0) 
     891+ 
     892+#ifdef SUPPORT_FORCE_CHANGE 
     893+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     894+               char parent[MAXPATHLEN]; 
     895+               int parent_flags; 
     896+               int saved_errno = errno; 
     897+               int file_flags = make_mutable(fname, NULL, NO_FFLAGS, force_change); 
     898+               if (file_flags && unlink(fname) == 0) 
     899+                       return 0; 
     900+               parent_flags = make_parentdir_mutable(fname, force_change, parent, sizeof parent); 
     901+               if (parent_flags) { 
     902+                       int ret = unlink(fname); 
     903+                       undo_make_mutable(parent, parent_flags); 
     904+                       if (ret == 0) 
    774905+                               return 0; 
    775 +                       undo_make_mutable(fname, st.st_flags); 
    776906+               } 
    777 +               /* TODO: handle immutable directories */ 
    778 +               errno = EPERM; 
    779 +       } 
    780 +#endif 
     907+               if (file_flags) 
     908+                       undo_make_mutable(fname, file_flags); 
     909+               errno = saved_errno; 
     910+       } 
     911+#endif 
     912+ 
    781913+       return -1; 
    782914 } 
    783915  
    784916 int do_symlink(const char *fname1, const char *fname2) 
    785 @@ -69,14 +86,37 @@ int do_link(const char *fname1, const char *fname2) 
     917 { 
     918        if (dry_run) return 0; 
     919        RETURN_ERROR_IF_RO_OR_LO; 
     920-       return symlink(fname1, fname2); 
     921+       if (symlink(fname1, fname2) == 0) 
     922+               return 0; 
     923+ 
     924+#ifdef SUPPORT_FORCE_CHANGE 
     925+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     926+               char parent[MAXPATHLEN]; 
     927+               int saved_errno = errno; 
     928+               int parent_flags = make_parentdir_mutable(fname2, force_change, parent, sizeof parent); 
     929+               if (parent_flags) { 
     930+                       int ret = symlink(fname1, fname2); 
     931+                       undo_make_mutable(parent, parent_flags); 
     932+                       if (ret == 0) 
     933+                               return 0; 
     934+               } 
     935+               errno = saved_errno; 
     936+       } 
     937+#endif 
     938+ 
     939+       return -1; 
     940 } 
     941  
     942 #ifdef HAVE_LINK 
     943@@ -65,18 +108,55 @@ int do_link(const char *fname1, const char *fname2) 
     944 { 
     945        if (dry_run) return 0; 
     946        RETURN_ERROR_IF_RO_OR_LO; 
     947-       return link(fname1, fname2); 
     948+       if (link(fname1, fname2) == 0) 
     949+               return 0; 
     950+ 
     951+#ifdef SUPPORT_FORCE_CHANGE 
     952+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     953+               char parent[MAXPATHLEN]; 
     954+               int saved_errno = errno; 
     955+               int parent_flags = make_parentdir_mutable(fname2, force_change, parent, sizeof parent); 
     956+               if (parent_flags) { 
     957+                       int ret = link(fname1, fname2); 
     958+                       undo_make_mutable(parent, parent_flags); 
     959+                       if (ret == 0) 
     960+                               return 0; 
     961+               } 
     962+               errno = saved_errno; 
     963+       } 
     964+#endif 
     965+ 
     966+       return -1; 
    786967 } 
    787968 #endif 
     
    798979+       if (lchown(path, owner, group) == 0) 
    799980+               return 0; 
    800 +#ifdef SUPPORT_FORCE_CHANGE 
    801 +       if (force_change && errno == EPERM) { 
    802 +               if (fileflags == NO_FFLAGS) { 
    803 +                       STRUCT_STAT st; 
    804 +                       if (x_lstat(path, &st, NULL) == 0) { 
    805 +                               mode = st.st_mode; 
    806 +                               fileflags = st.st_flags; 
    807 +                       } 
    808 +               } 
    809 +               if (fileflags != NO_FFLAGS 
    810 +                && make_mutable(path, mode, fileflags, force_change) > 0) { 
     981+ 
     982+#ifdef SUPPORT_FORCE_CHANGE 
     983+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     984+               int saved_errno = errno; 
     985+               fileflags = make_mutable(path, &mode, fileflags, force_change); 
     986+               if (fileflags) { 
    811987+                       int ret = lchown(path, owner, group); 
    812988+                       undo_make_mutable(path, fileflags); 
     
    814990+                               return 0; 
    815991+               } 
    816 +               errno = EPERM; 
     992+               errno = saved_errno; 
    817993+       } 
    818994+#else 
    819995+       mode = fileflags = 0; /* avoid compiler warning */ 
    820996+#endif 
     997+ 
    821998+       return -1; 
    822999 } 
    8231000  
    8241001 int do_mknod(const char *pathname, mode_t mode, dev_t dev) 
    825 @@ -116,7 +156,7 @@ int do_mknod(const char *pathname, mode_t mode, dev_t dev) 
     1002@@ -116,7 +196,7 @@ int do_mknod(const char *pathname, mode_t mode, dev_t dev) 
    8261003                        return -1; 
    8271004                close(sock); 
     
    8321009                return 0; 
    8331010 #endif 
    834 @@ -133,7 +173,22 @@ int do_rmdir(const char *pathname) 
     1011@@ -133,21 +213,63 @@ int do_rmdir(const char *pathname) 
    8351012 { 
    8361013        if (dry_run) return 0; 
     
    8391016+       if (rmdir(pathname) == 0) 
    8401017+               return 0; 
    841 +#ifdef SUPPORT_FORCE_CHANGE 
    842 +       if (force_change && errno == EPERM) { 
    843 +               STRUCT_STAT st; 
    844 + 
    845 +               if (x_lstat(pathname, &st, NULL) == 0 
    846 +                && make_mutable(pathname, st.st_mode, st.st_flags, force_change) > 0) { 
    847 +                       if (rmdir(pathname) == 0) 
     1018+ 
     1019+#ifdef SUPPORT_FORCE_CHANGE 
     1020+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     1021+               char parent[MAXPATHLEN]; 
     1022+               int parent_flags; 
     1023+               int saved_errno = errno; 
     1024+               int file_flags = make_mutable(pathname, NULL, NO_FFLAGS, force_change); 
     1025+               if (file_flags && rmdir(pathname) == 0) 
     1026+                       return 0; 
     1027+               parent_flags = make_parentdir_mutable(pathname, force_change, parent, sizeof parent); 
     1028+               if (parent_flags) { 
     1029+                       int ret = rmdir(pathname); 
     1030+                       undo_make_mutable(parent, parent_flags); 
     1031+                       if (ret == 0) 
    8481032+                               return 0; 
    849 +                       undo_make_mutable(pathname, st.st_flags); 
    8501033+               } 
    851 +               errno = EPERM; 
    852 +       } 
    853 +#endif 
     1034+               if (file_flags) 
     1035+                       undo_make_mutable(pathname, file_flags); 
     1036+               errno = saved_errno; 
     1037+       } 
     1038+#endif 
     1039+ 
    8541040+       return -1; 
    8551041 } 
    8561042  
    8571043 int do_open(const char *pathname, int flags, mode_t mode) 
    858 @@ -147,7 +202,7 @@ int do_open(const char *pathname, int flags, mode_t mode) 
     1044 { 
     1045+       int fd; 
     1046        if (flags != O_RDONLY) { 
     1047                RETURN_ERROR_IF(dry_run, 0); 
     1048                RETURN_ERROR_IF_RO_OR_LO; 
     1049        } 
     1050+       if ((fd = open(pathname, flags | O_BINARY, mode)) >= 0) 
     1051+               return fd; 
     1052+ 
     1053+#ifdef SUPPORT_FORCE_CHANGE 
     1054+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     1055+               char parent[MAXPATHLEN]; 
     1056+               int saved_errno = errno; 
     1057+               int parent_flags = make_parentdir_mutable(pathname, force_change, parent, sizeof parent); 
     1058+               if (parent_flags) { 
     1059+                       fd = open(pathname, flags | O_BINARY, mode); 
     1060+                       undo_make_mutable(parent, parent_flags); 
     1061+                       if (fd >= 0) 
     1062+                               return fd; 
     1063+               } 
     1064+               errno = saved_errno; 
     1065+       } 
     1066+#endif 
     1067  
     1068-       return open(pathname, flags | O_BINARY, mode); 
     1069+       return -1; 
    8591070 } 
    8601071  
     
    8651076        int code; 
    8661077        if (dry_run) return 0; 
    867 @@ -168,17 +223,74 @@ int do_chmod(const char *path, mode_t mode) 
    868  #endif 
     1078@@ -170,17 +292,93 @@ int do_chmod(const char *path, mode_t mode) 
    8691079        } else 
    8701080                code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */ 
    871 +#ifdef SUPPORT_FORCE_CHANGE 
    872 +       if (code < 0 && force_change && errno == EPERM && !S_ISLNK(mode)) { 
    873 +               if (fileflags == NO_FFLAGS) { 
    874 +                       STRUCT_STAT st; 
    875 +                       if (x_lstat(path, &st, NULL) == 0) 
    876 +                               fileflags = st.st_flags; 
    877 +               } 
    878 +               if (fileflags != NO_FFLAGS 
    879 +                && make_mutable(path, mode, fileflags, force_change) > 0) { 
     1081 #endif /* !HAVE_LCHMOD */ 
     1082+#ifdef SUPPORT_FORCE_CHANGE 
     1083+       if (code < 0 && force_change && (errno == EPERM || errno == EACCES) && !S_ISLNK(mode)) { 
     1084+               int saved_errno = errno; 
     1085+               fileflags = make_mutable(path, &mode, fileflags, force_change); 
     1086+               if (fileflags) { 
     1087+#ifdef HAVE_LCHMOD 
     1088+                       code = lchmod(path, mode & CHMOD_BITS); 
     1089+#else 
    8801090+                       code = chmod(path, mode & CHMOD_BITS); 
     1091+#endif 
    8811092+                       undo_make_mutable(path, fileflags); 
    8821093+                       if (code == 0) 
    8831094+                               return 0; 
    8841095+               } 
    885 +               errno = EPERM; 
     1096+               errno = saved_errno; 
    8861097+       } 
    8871098+#else 
     
    9101121+       if (rename(fname1, fname2) == 0) 
    9111122+               return 0; 
    912 +#ifdef SUPPORT_FORCE_CHANGE 
    913 +       if (force_change && errno == EPERM) { 
    914 +               STRUCT_STAT st1, st2; 
    915 +               int became_mutable; 
    916 + 
    917 +               if (x_lstat(fname1, &st1, NULL) != 0) 
    918 +                       goto failed; 
    919 +               became_mutable = make_mutable(fname1, st1.st_mode, st1.st_flags, force_change) > 0; 
    920 +               if (became_mutable && rename(fname1, fname2) == 0) 
    921 +                       goto success; 
    922 +               if (x_lstat(fname2, &st2, NULL) == 0 
    923 +                && make_mutable(fname2, st2.st_mode, st2.st_flags, force_change) > 0) { 
    924 +                       if (rename(fname1, fname2) == 0) { 
    925 +                         success: 
    926 +                               if (became_mutable) /* Yes, use fname2 and st1! */ 
    927 +                                       undo_make_mutable(fname2, st1.st_flags); 
    928 +                               return 0; 
     1123+ 
     1124+#ifdef SUPPORT_FORCE_CHANGE 
     1125+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     1126+               int saved_errno = errno; 
     1127+               int ret = -1, file2_flags = 0; 
     1128+               int file1_flags = make_mutable(fname1, NULL, NO_FFLAGS, force_change); 
     1129+               if (file1_flags && rename(fname1, fname2) == 0) 
     1130+                       ret = 0; 
     1131+               else { 
     1132+                       file2_flags = make_mutable(fname2, NULL, NO_FFLAGS, force_change); 
     1133+                       if (file2_flags && rename(fname1, fname2) == 0) 
     1134+                               ret = 0; 
     1135+                       else { 
     1136+                               char parent1[MAXPATHLEN]; 
     1137+                               int parent1_flags = make_parentdir_mutable(fname1, force_change, 
     1138+                                                       parent1, sizeof parent1); 
     1139+                               if (parent1_flags && rename(fname1, fname2) == 0) 
     1140+                                       ret = 0; 
     1141+                               else { 
     1142+                                       char parent2[MAXPATHLEN]; 
     1143+                                       int parent2_flags = make_parentdir_mutable(fname2, force_change, 
     1144+                                                               parent2, sizeof parent2); 
     1145+                                       if (parent2_flags) { 
     1146+                                               if (rename(fname1, fname2) == 0) 
     1147+                                                       ret = 0; 
     1148+                                               undo_make_mutable(parent2, parent2_flags); 
     1149+                                       } 
     1150+                               } 
     1151+                               if (parent1_flags) 
     1152+                                       undo_make_mutable(parent1, parent1_flags); 
    9291153+                       } 
    930 +                       undo_make_mutable(fname2, st2.st_flags); 
    9311154+               } 
    932 +               /* TODO: handle immutable directories */ 
    933 +               if (became_mutable) 
    934 +                       undo_make_mutable(fname1, st1.st_flags); 
    935 +         failed: 
    936 +               errno = EPERM; 
    937 +       } 
    938 +#endif 
     1155+ 
     1156+               if (ret == 0) 
     1157+                       file2_flags = file1_flags; /* file1 is now file2 */ 
     1158+               else if (file1_flags) 
     1159+                       undo_make_mutable(fname1, file1_flags); 
     1160+               if (file2_flags) 
     1161+                       undo_make_mutable(fname2, file2_flags); 
     1162+               if (ret == 0) 
     1163+                       return 0; 
     1164+ 
     1165+               errno = saved_errno; 
     1166+       } 
     1167+#endif 
     1168+ 
    9391169+       return -1; 
    9401170 } 
    9411171  
    942  void trim_trailing_slashes(char *name) 
     1172 #ifdef HAVE_FTRUNCATE 
     1173@@ -222,7 +420,25 @@ int do_mkdir(char *fname, mode_t mode) 
     1174        if (dry_run) return 0; 
     1175        RETURN_ERROR_IF_RO_OR_LO; 
     1176        trim_trailing_slashes(fname); 
     1177-       return mkdir(fname, mode); 
     1178+       if (mkdir(fname, mode) == 0) 
     1179+               return 0; 
     1180+ 
     1181+#ifdef SUPPORT_FORCE_CHANGE 
     1182+       if (force_change && (errno == EPERM || errno == EACCES)) { 
     1183+               char parent[MAXPATHLEN]; 
     1184+               int saved_errno = errno; 
     1185+               int parent_flags = make_parentdir_mutable(fname, force_change, parent, sizeof parent); 
     1186+               if (parent_flags) { 
     1187+                       int ret = mkdir(fname, mode); 
     1188+                       undo_make_mutable(parent, parent_flags); 
     1189+                       if (ret == 0) 
     1190+                               return 0; 
     1191+               } 
     1192+               errno = saved_errno; 
     1193+       } 
     1194+#endif 
     1195+ 
     1196+       return -1; 
     1197 } 
     1198  
     1199 /* like mkstemp but forces permissions */ 
     1200@@ -235,7 +451,19 @@ int do_mkstemp(char *template, mode_t perms) 
     1201 #if defined HAVE_SECURE_MKSTEMP && defined HAVE_FCHMOD && (!defined HAVE_OPEN64 || defined HAVE_MKSTEMP64) 
     1202        { 
     1203                int fd = mkstemp(template); 
     1204-               if (fd == -1) 
     1205+#ifdef SUPPORT_FORCE_CHANGE 
     1206+               if (fd < 0 && force_change) { 
     1207+                       char parent[MAXPATHLEN]; 
     1208+                       int saved_errno = errno; 
     1209+                       int parent_flags = make_parentdir_mutable(template, force_change, parent, sizeof parent); 
     1210+                       if (parent_flags) { 
     1211+                               fd = mkstemp(template); 
     1212+                               undo_make_mutable(parent, parent_flags); 
     1213+                       } 
     1214+                       errno = saved_errno; 
     1215+               } 
     1216+#endif 
     1217+               if (fd < 0) 
     1218                        return -1; 
     1219                if (fchmod(fd, perms) != 0 && preserve_perms) { 
     1220                        int errno_save = errno; 
     1221@@ -302,7 +530,7 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) 
     1222 } 
     1223  
     1224 #ifdef HAVE_UTIMENSAT 
     1225-int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec) 
     1226+int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags) 
     1227 { 
     1228        struct timespec t[2]; 
     1229  
     1230@@ -313,12 +541,26 @@ int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec) 
     1231        t[0].tv_nsec = UTIME_NOW; 
     1232        t[1].tv_sec = modtime; 
     1233        t[1].tv_nsec = mod_nsec; 
     1234-       return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW); 
     1235+       if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) == 0) 
     1236+               return 0; 
     1237+ 
     1238+#ifdef SUPPORT_FORCE_CHANGE 
     1239+       fileflags = make_mutable(fname, &mode, fileflags, force_change); 
     1240+       if (fileflags) { 
     1241+               if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) == 0) 
     1242+                       return 0; 
     1243+               undo_make_mutable(fname, fileflags); 
     1244+       } 
     1245+#else 
     1246+       mode = fileflags; /* avoid compiler warning */ 
     1247+#endif 
     1248+ 
     1249+       return -1; 
     1250 } 
     1251 #endif 
     1252  
     1253 #ifdef HAVE_LUTIMES 
     1254-int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec) 
     1255+int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags) 
     1256 { 
     1257        struct timeval t[2]; 
     1258  
     1259@@ -329,12 +571,26 @@ int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec) 
     1260        t[0].tv_usec = 0; 
     1261        t[1].tv_sec = modtime; 
     1262        t[1].tv_usec = mod_nsec / 1000; 
     1263-       return lutimes(fname, t); 
     1264+       if (lutimes(fname, t) == 0) 
     1265+               return 0; 
     1266+ 
     1267+#ifdef SUPPORT_FORCE_CHANGE 
     1268+       fileflags = make_mutable(fname, &mode, fileflags, force_change); 
     1269+       if (fileflags) { 
     1270+               if (lutimes(fname, t) == 0) 
     1271+                       return 0; 
     1272+               undo_make_mutable(fname, fileflags); 
     1273+       } 
     1274+#else 
     1275+       mode = fileflags; /* avoid compiler warning */ 
     1276+#endif 
     1277+ 
     1278+       return -1; 
     1279 } 
     1280 #endif 
     1281  
     1282 #ifdef HAVE_UTIMES 
     1283-int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec) 
     1284+int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags) 
     1285 { 
     1286        struct timeval t[2]; 
     1287  
     1288@@ -345,14 +601,28 @@ int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec) 
     1289        t[0].tv_usec = 0; 
     1290        t[1].tv_sec = modtime; 
     1291        t[1].tv_usec = mod_nsec / 1000; 
     1292-       return utimes(fname, t); 
     1293+       if (utimes(fname, t) == 0) 
     1294+               return 0; 
     1295+ 
     1296+#ifdef SUPPORT_FORCE_CHANGE 
     1297+       fileflags = make_mutable(fname, &mode, fileflags, force_change); 
     1298+       if (fileflags) { 
     1299+               if (utimes(fname, t) == 0) 
     1300+                       return 0; 
     1301+               undo_make_mutable(fname, fileflags); 
     1302+       } 
     1303+#else 
     1304+       mode = fileflags; /* avoid compiler warning */ 
     1305+#endif 
     1306+ 
     1307+       return -1; 
     1308 } 
     1309  
     1310 #elif defined HAVE_UTIME 
     1311-int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec)) 
     1312+int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec), mode_t mode, uint32 fileflags) 
     1313 { 
     1314 #ifdef HAVE_STRUCT_UTIMBUF 
     1315-       struct utimbuf tbuf; 
     1316+       struct utimbuf tbuf, *t = &tbuf; 
     1317 #else 
     1318        time_t t[2]; 
     1319 #endif 
     1320@@ -360,15 +630,28 @@ int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec)) 
     1321        if (dry_run) return 0; 
     1322        RETURN_ERROR_IF_RO_OR_LO; 
     1323  
     1324-# ifdef HAVE_STRUCT_UTIMBUF 
     1325+#ifdef HAVE_STRUCT_UTIMBUF 
     1326        tbuf.actime = time(NULL); 
     1327        tbuf.modtime = modtime; 
     1328-       return utime(fname, &tbuf); 
     1329-# else 
     1330+#else 
     1331        t[0] = time(NULL); 
     1332        t[1] = modtime; 
     1333-       return utime(fname, t); 
     1334-# endif 
     1335+#endif 
     1336+       if (utime(fname, t) == 0) 
     1337+               return 0; 
     1338+ 
     1339+#ifdef SUPPORT_FORCE_CHANGE 
     1340+       fileflags = make_mutable(fname, &mode, fileflags, force_change); 
     1341+       if (fileflags) { 
     1342+               if (utime(fname, t) == 0) 
     1343+                       return 0; 
     1344+               undo_make_mutable(fname, fileflags); 
     1345+       } 
     1346+#else 
     1347+       mode = fileflags; /* avoid compiler warning */ 
     1348+#endif 
     1349+ 
     1350+       return -1; 
     1351 } 
     1352  
     1353 #else 
    9431354diff --git a/t_stub.c b/t_stub.c 
    9441355--- a/t_stub.c 
     
    9491360 int module_dirlen = 0; 
    9501361+int force_change = 0; 
     1362 int preserve_times = 0; 
    9511363 int preserve_xattrs = 0; 
    9521364 mode_t orig_umask = 002; 
    953  char *partial_dir; 
    954 @@ -89,3 +90,23 @@ struct filter_list_struct daemon_filter_list; 
     1365@@ -90,3 +91,27 @@ struct filter_list_struct daemon_filter_list; 
    9551366 { 
    9561367        return "tester"; 
     
    9581369+ 
    9591370+#if defined SUPPORT_FILEFLAGS || defined SUPPORT_FORCE_CHANGE 
    960 + int make_mutable(UNUSED(const char *fname), UNUSED(mode_t mode), UNUSED(uint32 fileflags), UNUSED(uint32 iflags)) 
     1371+ uint32 make_mutable(UNUSED(const char *fname), UNUSED(mode_t *mode), UNUSED(uint32 fileflags), UNUSED(uint32 iflags)) 
    9611372+{ 
    9621373+       return 0; 
    9631374+} 
    9641375+ 
    965 +/* Undo a prior make_mutable() call that returned a 1. */ 
    9661376+ int undo_make_mutable(UNUSED(const char *fname), UNUSED(uint32 fileflags)) 
     1377+{ 
     1378+       return 0; 
     1379+} 
     1380+ 
     1381+ int make_parentdir_mutable(UNUSED(const char *fname), UNUSED(uint32 iflags), UNUSED(char *parent_dirbuf), UNUSED(int parent_dirbuf_size)) 
    9671382+{ 
    9681383+       return 0; 
     
    9791394--- a/util.c 
    9801395+++ b/util.c 
    981 @@ -29,6 +29,7 @@ extern int module_id; 
    982  extern int modify_window; 
    983  extern int relative_paths; 
    984  extern int human_readable; 
    985 +extern int force_change; 
    986  extern int preserve_xattrs; 
    987  extern char *module_dir; 
    988  extern unsigned int module_dirlen; 
    989 @@ -123,7 +124,7 @@ NORETURN void overflow_exit(const char *str) 
    990         exit_cleanup(RERR_MALLOC); 
    991  } 
    992   
     1396@@ -125,7 +125,7 @@ NORETURN void overflow_exit(const char *str) 
     1397  
     1398 /* This returns 0 for success, 1 for a symlink if symlink time-setting 
     1399  * is not possible, or -1 for any other error. */ 
    9931400-int set_modtime(const char *fname, time_t modtime, mode_t mode) 
    9941401+int set_modtime(const char *fname, time_t modtime, mode_t mode, uint32 fileflags) 
    9951402 { 
    996  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES 
    997         if (S_ISLNK(mode)) 
    998 @@ -140,6 +141,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 
    999                 return 0; 
    1000   
    1001         { 
    1002 +               int ret; 
     1403        static int switch_step = 0; 
     1404  
     1405@@ -138,7 +138,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 
     1406        switch (switch_step) { 
     1407 #ifdef HAVE_UTIMENSAT 
     1408 #include "case_N.h" 
     1409-               if (do_utimensat(fname, modtime, 0) == 0) 
     1410+               if (do_utimensat(fname, modtime, 0, mode, fileflags) == 0) 
     1411                        break; 
     1412                if (errno != ENOSYS) 
     1413                        return -1; 
     1414@@ -148,7 +148,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 
     1415  
     1416 #ifdef HAVE_LUTIMES 
     1417 #include "case_N.h" 
     1418-               if (do_lutimes(fname, modtime, 0) == 0) 
     1419+               if (do_lutimes(fname, modtime, 0, mode, fileflags) == 0) 
     1420                        break; 
     1421                if (errno != ENOSYS) 
     1422                        return -1; 
     1423@@ -167,10 +167,10 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 
     1424  
     1425 #include "case_N.h" 
    10031426 #ifdef HAVE_UTIMES 
    1004                 struct timeval t[2]; 
    1005                 t[0].tv_sec = time(NULL); 
    1006 @@ -153,20 +155,39 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) 
    1007                         return 0; 
    1008                 } 
    1009  # endif 
    1010 -               return utimes(fname, t); 
    1011 +#define SET_THE_TIME(fn) utimes(fn, t) 
    1012  #elif defined HAVE_STRUCT_UTIMBUF 
    1013                 struct utimbuf tbuf; 
    1014                 tbuf.actime = time(NULL); 
    1015                 tbuf.modtime = modtime; 
    1016 -               return utime(fname,&tbuf); 
    1017 +#define SET_THE_TIME(fn) utime(fn, &tbuf) 
    1018  #elif defined HAVE_UTIME 
    1019                 time_t t[2]; 
    1020                 t[0] = time(NULL); 
    1021                 t[1] = modtime; 
    1022 -               return utime(fname,t); 
    1023 +#define SET_THE_TIME(fn) utime(fn, t) 
     1427-               if (do_utimes(fname, modtime, 0) == 0) 
     1428+               if (do_utimes(fname, modtime, 0, mode, fileflags) == 0) 
     1429                        break; 
    10241430 #else 
    1025  #error No file-time-modification routine found! 
    1026  #endif 
    1027 +               ret = SET_THE_TIME(fname); 
    1028 +#ifdef SUPPORT_FORCE_CHANGE 
    1029 +               if (ret != 0 && force_change && errno == EPERM) { 
    1030 +                       if (fileflags == NO_FFLAGS) { 
    1031 +                               STRUCT_STAT st; 
    1032 +                               if (x_lstat(fname, &st, NULL) == 0) 
    1033 +                                       fileflags = st.st_flags; 
    1034 +                       } 
    1035 +                       if (fileflags != NO_FFLAGS 
    1036 +                        && make_mutable(fname, mode, fileflags, force_change) > 0) { 
    1037 +                               ret = SET_THE_TIME(fname); 
    1038 +                               undo_make_mutable(fname, fileflags); 
    1039 +                       } 
    1040 +                       errno = EPERM; 
    1041 +               } 
    1042 +#else 
    1043 +               fileflags = 0; /* avoid compiler warning */ 
    1044 +#endif 
    1045 +               return ret; 
    1046         } 
    1047  } 
     1431-               if (do_utime(fname, modtime, 0) == 0) 
     1432+               if (do_utime(fname, modtime, 0, mode, fileflags) == 0) 
     1433                        break; 
     1434 #endif 
    10481435  
    10491436diff --git a/xattrs.c b/xattrs.c 
    10501437--- a/xattrs.c 
    10511438+++ b/xattrs.c 
    1052 @@ -283,6 +283,10 @@ int get_xattr(const char *fname, stat_x *sxp) 
    1053  { 
    1054         sxp->xattr = new(item_list); 
    1055         *sxp->xattr = empty_xattr; 
    1056 + 
    1057 +       if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) 
    1058 +               return 0; 
    1059 + 
    1060         if (rsync_xal_get(fname, sxp->xattr) < 0) { 
    1061                 free_xattr(sxp); 
    1062                 return -1; 
    1063 @@ -883,6 +887,11 @@ int set_xattr(const char *fname, const struct file_struct *file, 
    1064                 return -1; 
    1065         } 
    1066   
    1067 +       if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) { 
    1068 +               errno = ENOTSUP; 
    1069 +               return -1; 
    1070 +       } 
    1071 + 
    1072         ndx = F_XATTR(file); 
    1073         return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp); 
    1074  } 
    1075 @@ -999,7 +1008,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) 
     1439@@ -1041,7 +1041,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) 
    10761440        mode = (fst.st_mode & _S_IFMT) | (fmode & ACCESSPERMS) 
    10771441             | (S_ISDIR(fst.st_mode) ? 0700 : 0600); 
     
    10981462--- a/configure.sh 
    10991463+++ b/configure.sh 
    1100 @@ -7351,6 +7351,7 @@ fi 
     1464@@ -7425,6 +7425,7 @@ fi 
    11011465  
    11021466 for ac_func in waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ 
     
    11091473--- a/proto.h 
    11101474+++ b/proto.h 
    1111 @@ -274,6 +274,8 @@ int read_ndx_and_attrs(int f_in, int *if 
     1475@@ -274,6 +274,9 @@ int read_ndx_and_attrs(int f_in, int *if 
    11121476 void free_sums(struct sum_struct *s); 
    11131477 mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms, 
    11141478                 int exists); 
    1115 +int make_mutable(const char *fname, mode_t mode, uint32 fileflags, uint32 iflags); 
     1479+uint32 make_mutable(const char *fname, mode_t *mode_ptr, uint32 fileflags, uint32 iflags); 
    11161480+int undo_make_mutable(const char *fname, uint32 fileflags); 
     1481+int make_parentdir_mutable(const char *fname, uint32 iflags, char *parent_dirbuf, int parent_dirbuf_size); 
    11171482 int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 
    11181483                   const char *fnamecmp, int flags); 
    11191484 RETSIGTYPE sig_int(UNUSED(int val)); 
    1120 @@ -298,11 +300,12 @@ int sock_exec(const char *prog); 
     1485@@ -297,11 +300,12 @@ void set_socket_options(int fd, char *op 
    11211486 int do_unlink(const char *fname); 
    11221487 int do_symlink(const char *fname1, const char *fname2); 
     
    11311496+int do_chflags(const char *path, uint32 fileflags); 
    11321497 int do_rename(const char *fname1, const char *fname2); 
     1498 int do_ftruncate(int fd, OFF_T size); 
    11331499 void trim_trailing_slashes(char *name); 
    1134  int do_mkdir(char *fname, mode_t mode); 
    1135 @@ -330,7 +333,7 @@ int fd_pair(int fd[2]); 
     1500@@ -311,10 +315,10 @@ int do_stat(const char *fname, STRUCT_ST 
     1501 int do_lstat(const char *fname, STRUCT_STAT *st); 
     1502 int do_fstat(int fd, STRUCT_STAT *st); 
     1503 OFF_T do_lseek(int fd, OFF_T offset, int whence); 
     1504-int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec); 
     1505-int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec); 
     1506-int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec); 
     1507-int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec)); 
     1508+int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
     1509+int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
     1510+int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode, uint32 fileflags); 
     1511+int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec), mode_t mode, uint32 fileflags); 
     1512 void set_compression(const char *fname); 
     1513 void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset, 
     1514                int32 n, int32 toklen); 
     1515@@ -334,7 +338,7 @@ int fd_pair(int fd[2]); 
    11361516 void print_child_argv(const char *prefix, char **cmd); 
    11371517 NORETURN void out_of_memory(const char *str); 
     
    11451525--- a/rsync.1 
    11461526+++ b/rsync.1 
    1147 @@ -417,6 +417,7 @@ to the detailed description below for a  
     1527@@ -417,6 +417,7 @@ to the detailed description below for a 
    11481528  \-K, \-\-keep\-dirlinks         treat symlinked dir on receiver as dir 
    11491529  \-H, \-\-hard\-links            preserve hard links 
    11501530  \-p, \-\-perms                 preserve permissions 
    1151 +     \-\-fileflags             preserve file-flags (aka chflags) 
     1531+     \-\-fileflags             preserve file\-flags (aka chflags) 
    11521532  \-E, \-\-executability         preserve executability 
    11531533      \-\-chmod=CHMOD           affect file and/or directory permissions 
    11541534  \-A, \-\-acls                  preserve ACLs (implies \-p) 
    1155 @@ -448,7 +449,10 @@ to the detailed description below for a  
     1535@@ -448,7 +449,10 @@ to the detailed description below for a 
    11561536      \-\-delete\-after          receiver deletes after transfer, not before 
    11571537      \-\-delete\-excluded       also delete excluded files from dest dirs 
     
    11601540+     \-\-force\-delete          force deletion of dirs even if not empty 
    11611541+     \-\-force\-change          affect user/system immutable files/dirs 
    1162 +     \-\-force\-uchange         affect user-immutable files/dirs 
    1163 +     \-\-force\-schange         affect system-immutable files/dirs 
     1542+     \-\-force\-uchange         affect user\-immutable files/dirs 
     1543+     \-\-force\-schange         affect system\-immutable files/dirs 
    11641544      \-\-max\-delete=NUM        don'\&t delete more than NUM files 
    11651545      \-\-max\-size=SIZE         don'\&t transfer any file larger than SIZE 
     
    11681548 .IP  
    11691549 Note that \fB\-a\fP \fBdoes not preserve hardlinks\fP, because 
    1170  finding multiply-linked files is expensive.  You must separately 
     1550 finding multiply\-linked files is expensive.  You must separately 
    11711551-specify \fB\-H\fP. 
    11721552+specify \fB\-H\fP.  Note also that for backward compatibility, \fB\-a\fP 
     
    11751555 .IP "\-\-no\-OPTION" 
    11761556 You may turn off one or more implied options by prefixing 
    1177 @@ -931,7 +936,7 @@ they would be using \fB\-\-copy\-links\f 
     1557@@ -955,7 +960,7 @@ they would be using \fB\-\-copy\-links\f 
    11781558 Without this option, if the sending side has replaced a directory with a 
    11791559 symlink to a directory, the receiving side will delete anything that is in 
     
    11841564 See also \fB\-\-keep\-dirlinks\fP for an analogous option for the receiving 
    11851565 side. 
    1186 @@ -1086,6 +1091,33 @@ super-user copies all namespaces except  
    1187  the user.* namespace.  To be able to backup and restore non-user namespaces as 
    1188  a normal user, see the \fB\-\-fake\-super\fP option. 
     1566@@ -1142,6 +1147,33 @@ Note that this option does not copy rsyn 
     1567 used by \fB\-\-fake\-super\fP) unless you repeat the option (e.g. \-XX).  This 
     1568 \(dq\&copy all xattrs\(dq\& mode cannot be used with \fB\-\-fake\-super\fP. 
    11891569 .IP  
    11901570+.IP "\fB\-\-fileflags\fP" 
    1191 +This option causes rsync to update the file-flags to be 
     1571+This option causes rsync to update the file\-flags to be 
    11921572+the same as the source files and directories (if your OS supports the 
    1193 +\fBchflags\fP(2) system call).   Some flags can only be altered by the super-user 
    1194 +and some might only be unset below a certain secure-level (usually single-user 
     1573+\fBchflags\fP(2) system call).   Some flags can only be altered by the super\-user 
     1574+and some might only be unset below a certain secure\-level (usually single\-user 
    11951575+mode). It will not make files alterable that are set to immutable on the 
    11961576+receiver.  To do that, see \fB\-\-force\-change\fP, \fB\-\-force\-uchange\fP, and 
     
    11981578+.IP  
    11991579+.IP "\fB\-\-force\-change\fP" 
    1200 +This option causes rsync to disable both user-immutable 
    1201 +and system-immutable flags on files and directories that are being updated or 
     1580+This option causes rsync to disable both user\-immutable 
     1581+and system\-immutable flags on files and directories that are being updated or 
    12021582+deleted on the receiving side.  This option overrides \fB\-\-force\-uchange\fP and 
    12031583+\fB\-\-force\-schange\fP. 
    12041584+.IP  
    12051585+.IP "\fB\-\-force\-uchange\fP" 
    1206 +This option causes rsync to disable user-immutable 
     1586+This option causes rsync to disable user\-immutable 
    12071587+flags on files and directories that are being updated or deleted on the 
    12081588+receiving side.  It does not try to affect system flags.  This option overrides 
     
    12101590+.IP  
    12111591+.IP "\fB\-\-force\-schange\fP" 
    1212 +This option causes rsync to disable system-immutable 
     1592+This option causes rsync to disable system\-immutable 
    12131593+flags on files and directories that are being updated or deleted on the 
    12141594+receiving side.  It does not try to affect user flags.  This option overrides 
     
    12171597 .IP "\fB\-\-chmod\fP" 
    12181598 This option tells rsync to apply one or more 
    1219  comma-separated \(dq\&chmod\(dq\& strings to the permission of the files in the 
    1220 @@ -1387,13 +1419,14 @@ See \fB\-\-delete\fP (which is implied)  
     1599 comma\-separated \(dq\&chmod\(dq\& strings to the permission of the files in the 
     1600@@ -1442,13 +1474,14 @@ See \fB\-\-delete\fP (which is implied) 
    12211601 Tells \fB\-\-delete\fP to go ahead and delete files 
    12221602 even when there are I/O errors. 
     
    12241604-.IP "\fB\-\-force\fP" 
    12251605+.IP "\fB\-\-force\-delete\fP" 
    1226  This option tells rsync to delete a non-empty directory 
    1227  when it is to be replaced by a non-directory.  This is only relevant if 
     1606 This option tells rsync to delete a non\-empty directory 
     1607 when it is to be replaced by a non\-directory.  This is only relevant if 
    12281608 deletions are not active (see \fB\-\-delete\fP for details). 
    12291609 .IP  
    12301610-Note for older rsync versions: \fB\-\-force\fP used to still be required when 
    1231 -using \fB\-\-delete\-after\fP, and it used to be non-functional unless the 
     1611-using \fB\-\-delete\-after\fP, and it used to be non\-functional unless the 
    12321612+This option can be abbreviated \fB\-\-force\fP for backward compatibility. 
    12331613+Note that some older rsync versions used to still require \fB\-\-force\fP 
    1234 +when using \fB\-\-delete\-after\fP, and it used to be non-functional unless the 
     1614+when using \fB\-\-delete\-after\fP, and it used to be non\-functional unless the 
    12351615 \fB\-\-recursive\fP option was also enabled. 
    12361616 .IP  
    12371617 .IP "\fB\-\-max\-delete=NUM\fP" 
    1238 @@ -1930,7 +1963,7 @@ with older versions of rsync, but that a 
     1618@@ -2004,7 +2037,7 @@ with older versions of rsync, but that a 
    12391619 verbose messages). 
    12401620 .IP  
     
    12421622-format is like the string \fBYXcstpoguax\fP, where \fBY\fP is replaced by the 
    12431623+format is like the string \fBYXcstpogfax\fP, where \fBY\fP is replaced by the 
    1244  type of update being done, \fBX\fP is replaced by the file-type, and the 
     1624 type of update being done, \fBX\fP is replaced by the file\-type, and the 
    12451625 other letters represent attributes that may be output if they are being 
    12461626 modified. 
    1247 @@ -2000,7 +2033,7 @@ sender\(cq\&s value (requires \fB\-\-own 
     1627@@ -2074,7 +2107,7 @@ sender\(cq\&s value (requires \fB\-\-own 
    12481628 A \fBg\fP means the group is different and is being updated to the 
    12491629 sender\(cq\&s value (requires \fB\-\-group\fP and the authority to set the group). 
Note: See TracChangeset for help on using the changeset viewer.