./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/acls.c b/acls.c
-index 6e0f601..3a613c5 100644
--- a/acls.c
+++ b/acls.c
@@ -31,6 +31,7 @@ extern int list_only;
/* Flags used to indicate what items are being transmitted for an entry. */
#define XMIT_USER_OBJ (1<<0)
-@@ -107,6 +108,18 @@ static const char *str_acl_type(SMB_ACL_TYPE_T type)
+@@ -110,6 +111,18 @@ static const char *str_acl_type(SMB_ACL_TYPE_T type)
return "unknown ACL type!";
}
static int calc_sacl_entries(const rsync_acl *racl)
{
/* A System ACL always gets user/group/other permission entries. */
-@@ -554,6 +567,96 @@ int get_acl(const char *fname, stat_x *sxp)
+@@ -558,6 +571,96 @@ int get_acl(const char *fname, stat_x *sxp)
return 0;
}
/* === Send functions === */
/* Send the ida list over the file descriptor. */
-@@ -629,6 +732,11 @@ static void send_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type,
+@@ -633,6 +736,11 @@ static void send_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type,
* This also frees the ACL data. */
void send_acl(stat_x *sxp, int f)
{
if (!sxp->acc_acl) {
sxp->acc_acl = create_racl();
rsync_acl_fake_perms(sxp->acc_acl, sxp->st.st_mode);
-@@ -646,6 +754,160 @@ void send_acl(stat_x *sxp, int f)
+@@ -650,6 +758,160 @@ void send_acl(stat_x *sxp, int f)
}
}
/* === Receive functions === */
static uint32 recv_acl_access(uchar *name_follows_ptr, int f)
-@@ -768,6 +1030,11 @@ static int recv_rsync_acl(item_list *racl_list, SMB_ACL_TYPE_T type, int f)
+@@ -765,6 +1027,11 @@ static int recv_rsync_acl(item_list *racl_list, SMB_ACL_TYPE_T type, int f)
/* Receive the ACL info the sender has included for this file-list entry. */
void receive_acl(struct file_struct *file, int f)
{
if (S_ISDIR(file->mode))
diff --git a/compat.c b/compat.c
-index 6e00072..1b66069 100644
--- a/compat.c
+++ b/compat.c
@@ -189,13 +189,6 @@ void setup_protocol(int f_out,int f_in)
Fix a bug that could lose some bits when stripping some (supposedly)
superfluous ACL info.
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/lib/sysacls.c b/lib/sysacls.c
-index 7334fd4..1bacc75 100644
--- a/lib/sysacls.c
+++ b/lib/sysacls.c
@@ -31,6 +31,18 @@
acl_add_perm(permset, ACL_READ);
if (bits & 2)
diff --git a/lib/sysacls.h b/lib/sysacls.h
-index fd75bb6..5bd64de 100644
--- a/lib/sysacls.h
+++ b/lib/sysacls.h
@@ -59,8 +59,8 @@
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/compat.c b/compat.c
-index 6e00072..795e6bd 100644
--- a/compat.c
+++ b/compat.c
@@ -43,6 +43,7 @@ extern int protocol_version;
acls_ndx = ++file_extra_cnt;
if (preserve_xattrs)
diff --git a/flist.c b/flist.c
-index 09b4fc5..169e918 100644
--- a/flist.c
+++ b/flist.c
@@ -55,6 +55,7 @@ extern int missing_args;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
-@@ -484,6 +485,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -494,6 +495,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_TIME;
else
modtime = file->modtime;
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != 0) {
-@@ -568,6 +576,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -578,6 +586,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
write_int(f, uid);
-@@ -654,7 +664,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -664,7 +674,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
-@@ -793,6 +803,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -802,6 +812,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
if (chmod_modes && !S_ISLNK(mode) && mode)
mode = tweak_mode(mode, chmod_modes);
-@@ -942,6 +962,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -952,6 +972,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
-@@ -1327,6 +1349,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1337,6 +1359,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_OWNER(file) = st.st_uid;
if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
F_GROUP(file) = st.st_gid;
if (basename != thisname)
file->dirname = lastdir;
diff --git a/generator.c b/generator.c
-index 12007a1..7d15744 100644
--- a/generator.c
+++ b/generator.c
@@ -455,6 +455,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
}
}
-@@ -1875,7 +1884,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1870,7 +1879,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
STRUCT_STAT st;
if (link_stat(fname, &st, 0) == 0
&& cmp_time(st.st_mtime, file->modtime) != 0)
if (counter >= loopchk_limit) {
if (allowed_lull)
diff --git a/ifuncs.h b/ifuncs.h
-index 8c128d5..7834d3a 100644
--- a/ifuncs.h
+++ b/ifuncs.h
@@ -35,6 +35,28 @@ realloc_xbuf(xbuf *xb, size_t sz)
to_wire_mode(mode_t mode)
{
diff --git a/log.c b/log.c
-index a687375..0f714ad 100644
--- a/log.c
+++ b/log.c
@@ -715,7 +715,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
c[11] = '\0';
diff --git a/options.c b/options.c
-index e7c6c61..01ccf5a 100644
--- a/options.c
+++ b/options.c
@@ -59,6 +59,7 @@ int preserve_specials = 0;
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
-@@ -2289,6 +2294,8 @@ void server_options(char **args, int *argc_p)
+@@ -2306,6 +2311,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
argstr[x++] = 'p';
else if (preserve_executability && am_sender)
diff --git a/rsync.c b/rsync.c
-index 2c026a2..95a6ebe 100644
--- a/rsync.c
+++ b/rsync.c
@@ -384,6 +384,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
if (temp_copy_name) {
if (do_rename(fnametmp, fname) < 0) {
diff --git a/rsync.h b/rsync.h
-index be7cf8a..2f85dee 100644
--- a/rsync.h
+++ b/rsync.h
@@ -61,6 +61,7 @@
#define FULL_FLUSH 1
#define NORMAL_FLUSH 0
-@@ -652,12 +654,14 @@ extern int file_extra_cnt;
+@@ -656,12 +658,14 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
#define DIRNODE_EXTRA_CNT 3
#define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..ec98c6e 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -356,6 +356,7 @@ to the detailed description below for a complete description. verb(
--super receiver attempts super-user activities
--fake-super store/recover privileged attrs using xattrs
-S, --sparse handle sparse files efficiently
-@@ -1071,6 +1072,12 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
+@@ -1078,6 +1079,12 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
the directories on the receiving side, it is a good idea to use bf(-O).
This option is inferred if you use bf(--backup) without bf(--backup-dir).
dit(bf(--super)) This tells the receiving side to attempt super-user
activities even if the receiving rsync wasn't run by the super-user. These
activities include: preserving users via the bf(--owner) option, preserving
-@@ -1888,7 +1895,10 @@ quote(itemization(
+@@ -1907,7 +1914,10 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
))
diff --git a/testsuite/atimes.test b/testsuite/atimes.test
new file mode 100644
-index 0000000..bd3f292
--- /dev/null
+++ b/testsuite/atimes.test
@@ -0,0 +1,17 @@
+# The script would have aborted on error, so getting here means we've won.
+exit 0
diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
-index b26aee3..0c1c7d8 100644
--- a/testsuite/rsync.fns
+++ b/testsuite/rsync.fns
@@ -215,6 +215,10 @@ checkit() {
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
diff --git a/tls.c b/tls.c
-index 8cc5748..c27c97f 100644
--- a/tls.c
+++ b/tls.c
@@ -108,6 +108,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
fprintf(F," -L, --link-owner display the owner+group on a symlink\n");
#ifdef SUPPORT_XATTRS
diff --git a/util.c b/util.c
-index 0cafed6..05f6d72 100644
--- a/util.c
+++ b/util.c
@@ -123,7 +123,7 @@ NORETURN void overflow_exit(const char *str)
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/backup.c b/backup.c
-index 0da6b33..ff77078 100644
--- a/backup.c
+++ b/backup.c
-@@ -29,10 +29,17 @@ extern int preserve_specials;
+@@ -29,29 +29,36 @@ extern int preserve_specials;
extern int preserve_links;
extern int safe_symlinks;
extern int backup_dir_len;
+
+static BOOL deleting;
- /* make a complete pathname for backup file */
- char *get_backup_name(const char *fname)
-@@ -51,6 +58,22 @@ char *get_backup_name(const char *fname)
- return NULL;
- }
-
-+static char *get_delete_name(const char *fname)
-+{
-+ if (backup_dir_dels) {
-+ if (stringjoin(backup_dir_dels_buf + backup_dir_dels_len, backup_dir_dels_remainder,
-+ fname, backup_suffix_dels, NULL) < backup_dir_dels_remainder)
-+ return backup_dir_dels_buf;
-+ } else {
-+ if (stringjoin(backup_dir_dels_buf, MAXPATHLEN,
-+ fname, backup_suffix_dels, NULL) < MAXPATHLEN)
-+ return backup_dir_dels_buf;
-+ }
-+
-+ rprintf(FERROR, "delete filename too long\n");
-+ return NULL;
-+}
-+
- /****************************************************************************
- Create a directory given an absolute path, perms based upon another directory
- path
-@@ -59,7 +82,7 @@ int make_bak_dir(const char *fullpath)
+ /* Create a backup path from the given fname, putting the result into
+ * backup_dir_buf. Any new directories (compared to the prior backup
+ * path) are ensured to exist as directories, replacing anything else
+ * that may be in the way (e.g. a symlink). */
+-static BOOL copy_valid_path(const char *fname)
++static BOOL copy_valid_path(const char *fname, char *buf, int prefix_len, unsigned int remainder, const char *suffix)
{
- char fbuf[MAXPATHLEN], *rel, *end, *p;
- struct file_struct *file;
-- int len = backup_dir_len;
-+ int len = deleting ? backup_dir_dels_len : backup_dir_len;
+ const char *f;
+ int flags;
+ BOOL ret = True;
stat_x sx;
+- char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;
++ char *b, *rel = buf + prefix_len, *name = rel;
- while (*fullpath == '.' && fullpath[1] == '/') {
-@@ -179,7 +202,7 @@ int make_backup(const char *fname, BOOL prefer_rename)
- stat_x sx;
- struct file_struct *file;
- int save_preserve_xattrs;
-- char *buf = get_backup_name(fname);
-+ char *buf = deleting ? get_delete_name(fname) : get_backup_name(fname);
- int ret = 0;
+ for (f = fname, b = rel; *f && *f == *b; f++, b++) {
+ if (*b == '/')
+ name = b + 1;
+ }
- if (!buf)
-@@ -341,3 +364,13 @@ int make_backup(const char *fname, BOOL prefer_rename)
+- if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {
++ if (stringjoin(rel, remainder, fname, suffix, NULL) >= remainder) {
+ rprintf(FERROR, "backup filename too long\n");
+ *name = '\0';
+ return False;
+@@ -62,16 +69,16 @@ static BOOL copy_valid_path(const char *fname)
+ return True;
+ *b = '\0';
+
+- if (do_lstat(backup_dir_buf, &sx.st) < 0) {
++ if (do_lstat(buf, &sx.st) < 0) {
+ if (errno == ENOENT)
+ break;
+- rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
++ rsyserr(FERROR, errno, "backup lstat %s failed", buf);
+ *name = '\0';
+ return False;
+ }
+ if (!S_ISDIR(sx.st.st_mode)) {
+ flags = get_del_for_flag(sx.st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
+- if (delete_item(backup_dir_buf, sx.st.st_mode, flags) == 0)
++ if (delete_item(buf, sx.st.st_mode, flags) == 0)
+ break;
+ *name = '\0';
+ return False;
+@@ -85,8 +92,8 @@ static BOOL copy_valid_path(const char *fname)
+ for ( ; b; name = b + 1, b = strchr(name, '/')) {
+ *b = '\0';
+
+- if (mkdir_defmode(backup_dir_buf) < 0) {
+- rsyserr(FERROR, errno, "backup mkdir %s failed", backup_dir_buf);
++ if (mkdir_defmode(buf) < 0) {
++ rsyserr(FERROR, errno, "backup mkdir %s failed", buf);
+ *name = '\0';
+ ret = False;
+ break;
+@@ -114,7 +121,7 @@ static BOOL copy_valid_path(const char *fname)
+ free_xattr(&sx);
+ }
+ #endif
+- set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);
++ set_file_attrs(buf, file, NULL, NULL, 0);
+ unmake_file(file);
+ }
+
+@@ -134,15 +141,20 @@ static BOOL copy_valid_path(const char *fname)
+ /* Make a complete pathname for backup file and verify any new path elements. */
+ char *get_backup_name(const char *fname)
+ {
++ char *buf = deleting ? backup_dir_dels_buf : backup_dir_buf;
++ char *suffix = deleting ? backup_suffix_dels : backup_suffix;
++
+ if (backup_dir) {
++ int prefix_len = deleting ? backup_dir_dels_len : backup_dir_len;
++ unsigned int remainder = deleting ? backup_dir_dels_remainder : backup_dir_remainder;
+ /* copy fname into backup_dir_buf while validating the dirs. */
+- if (copy_valid_path(fname))
+- return backup_dir_buf;
++ if (copy_valid_path(fname, buf, prefix_len, remainder, suffix))
++ return buf;
+ return NULL;
+ } else {
+ if (stringjoin(backup_dir_buf, MAXPATHLEN,
+- fname, backup_suffix, NULL) < MAXPATHLEN)
+- return backup_dir_buf;
++ fname, suffix, NULL) < MAXPATHLEN)
++ return buf;
}
+
+ rprintf(FERROR, "backup filename too long\n");
+@@ -317,3 +329,13 @@ int make_backup(const char *fname, BOOL prefer_rename)
+ rprintf(FINFO, "backed up %s to %s\n", fname, buf);
return ret;
}
+
+ return ret;
+}
diff --git a/delete.c b/delete.c
-index 33fdd0e..31228d0 100644
--- a/delete.c
+++ b/delete.c
@@ -28,6 +28,9 @@ extern int max_delete;
what = "rmdir";
ok = do_rmdir(fbuf) == 0;
} else {
-- if (make_backups > 0 && (backup_dir || !is_backup_file(fbuf))) {
-+ if (make_backups > 0 && (backup_dir_dels || !is_backup_file(fbuf))) {
+- if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
++ if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir_dels || !is_backup_file(fbuf))) {
what = "make_backup";
- ok = make_backup(fbuf, True);
+ ok = safe_delete(fbuf);
what = "unlink";
ok = robust_unlink(fbuf) == 0;
diff --git a/options.c b/options.c
-index e7c6c61..37e4086 100644
--- a/options.c
+++ b/options.c
@@ -151,10 +151,14 @@ int no_detach
{"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
{"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
{"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
-@@ -1964,6 +1974,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1971,6 +1981,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, SP_DEFAULT);
if (backup_dir)
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, SP_DEFAULT);
+ backup_dir_dels = sanitize_path(NULL, backup_dir_dels, NULL, 0, SP_DEFAULT);
}
if (daemon_filter_list.head && !am_sender) {
- struct filter_list_struct *elp = &daemon_filter_list;
-@@ -1985,6 +1997,14 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+ filter_rule_list *elp = &daemon_filter_list;
+@@ -1992,6 +2004,14 @@ int parse_arguments(int *argc_p, const char ***argv_p)
if (check_filter(elp, FLOG, dir, 1) < 0)
goto options_rejected;
}
}
if (!backup_suffix)
-@@ -1996,6 +2016,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2003,6 +2023,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
backup_suffix);
return 0;
}
+ return 0;
+ }
if (backup_dir) {
- backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
- backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
-@@ -2019,6 +2053,34 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+ while (*backup_dir == '.' && backup_dir[1] == '/')
+ backup_dir += 2;
+@@ -2036,6 +2070,34 @@ int parse_arguments(int *argc_p, const char ***argv_p)
"P *%s", backup_suffix);
- parse_rule(&filter_list, backup_dir_buf, 0, 0);
+ parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
}
+ if (backup_dir_dels) {
+ backup_dir_dels_len = strlcpy(backup_dir_dels_buf, backup_dir_dels, sizeof backup_dir_dels_buf);
if (make_backups && !backup_dir) {
omit_dir_times = 0; /* Implied, so avoid -O to sender. */
-@@ -2432,6 +2494,10 @@ void server_options(char **args, int *argc_p)
+@@ -2449,6 +2511,10 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--backup-dir";
args[ac++] = backup_dir;
}
/* Only send --suffix if it specifies a non-default value. */
if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
-@@ -2440,7 +2506,14 @@ void server_options(char **args, int *argc_p)
+@@ -2457,7 +2523,14 @@ void server_options(char **args, int *argc_p)
goto oom;
args[ac++] = arg;
}
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/errcode.h b/errcode.h
-index 41c5543..e9c5a28 100644
--- a/errcode.h
+++ b/errcode.h
@@ -47,6 +47,8 @@
* ssh and the shell seem to return these values:
*
diff --git a/log.c b/log.c
-index a687375..8e46712 100644
--- a/log.c
+++ b/log.c
@@ -88,6 +88,7 @@ struct {
{ RERR_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
diff --git a/main.c b/main.c
-index 2ef2f47..45159d3 100644
--- a/main.c
+++ b/main.c
-@@ -167,8 +167,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
+@@ -169,8 +169,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
*exit_code_ptr = RERR_TERMINATED;
else
*exit_code_ptr = RERR_WAITCHILD;
}
void write_del_stats(int f)
-@@ -1389,6 +1392,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
+@@ -1401,6 +1404,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
break;
}
}
}
#endif
#ifndef HAVE_SIGACTION
-@@ -1447,6 +1458,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
+@@ -1459,6 +1470,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
}
#endif
int main(int argc,char *argv[])
{
-@@ -1469,6 +1486,11 @@ int main(int argc,char *argv[])
+@@ -1481,6 +1498,11 @@ int main(int argc,char *argv[])
SIGACTMASK(SIGFPE, rsync_panic_handler);
SIGACTMASK(SIGABRT, rsync_panic_handler);
SIGACTMASK(SIGBUS, rsync_panic_handler);
starttime = time(NULL);
diff --git a/socket.c b/socket.c
-index 5df3a50..3423e18 100644
--- a/socket.c
+++ b/socket.c
@@ -518,7 +518,17 @@ int is_a_socket(int fd)
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/checksum.c b/checksum.c
-index 811b5b6..f418dc2 100644
--- a/checksum.c
+++ b/checksum.c
@@ -98,7 +98,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
struct map_struct *buf;
OFF_T i, len = size;
diff --git a/clientserver.c b/clientserver.c
-index b6afe00..2681f33 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -42,6 +42,8 @@ extern int numeric_ids;
extern int io_timeout;
extern int no_detach;
extern int write_batch;
-@@ -868,6 +870,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -862,6 +864,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
} else if (am_root < 0) /* Treat --fake-super from client as --super. */
am_root = 2;
filesfrom_fd = f_in;
diff --git a/flist.c b/flist.c
-index 09b4fc5..8a42d80 100644
--- a/flist.c
+++ b/flist.c
@@ -22,6 +22,7 @@
/* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
* F_PATHNAME(), or (2) "NULL, dir, dirlen" to chdir() to the supplied dir,
* with dir == NULL taken to be the starting directory, and dirlen < 0
-@@ -1105,7 +1351,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1114,7 +1360,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
STRUCT_STAT *stp, int flags, int filter_level)
{
static char *lastdir;
struct file_struct *file;
char thisname[MAXPATHLEN];
char linkname[MAXPATHLEN];
-@@ -1251,9 +1497,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1260,9 +1506,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
memcpy(lastdir, thisname, len);
lastdir[len] = '\0';
lastdir_len = len;
basename_len = strlen(basename) + 1; /* count the '\0' */
#ifdef SUPPORT_LINKS
-@@ -1267,11 +1520,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1276,11 +1529,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
extra_len += EXTRA_LEN;
#endif
#if EXTRA_ROUNDING > 0
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
-@@ -1347,8 +1597,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1357,8 +1607,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
return NULL;
}
if (unsort_ndx)
F_NDX(file) = stats.num_dirs;
-@@ -2462,7 +2718,7 @@ struct file_list *recv_file_list(int f)
+@@ -2472,7 +2728,7 @@ struct file_list *recv_file_list(int f)
flist_eof = 1;
}
if (protocol_version < 30) {
/* Recv the io_error flag */
-@@ -2683,7 +2939,7 @@ void flist_free(struct file_list *flist)
+@@ -2693,7 +2949,7 @@ void flist_free(struct file_list *flist)
/* This routine ensures we don't have any duplicate names in our file list.
* duplicate names can cause corruption because of the pipelining. */
{
char fbuf[MAXPATHLEN];
int i, prev_i;
-@@ -2734,7 +2990,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2744,7 +3000,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
/* If one is a dir and the other is not, we want to
* keep the dir because it might have contents in the
* list. Otherwise keep the first one. */
struct file_struct *fp = flist->sorted[j];
if (!S_ISDIR(fp->mode))
keep = i, drop = j;
-@@ -2750,8 +3006,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2760,8 +3016,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
} else
keep = j, drop = i;
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",
f_name(file, fbuf), drop + flist->ndx_start);
-@@ -2773,7 +3029,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2783,7 +3039,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
}
flist->high = prev_i;
* paths, but this must be done _after_ the sorting phase. */
for (i = flist->low; i <= flist->high; i++) {
diff --git a/generator.c b/generator.c
-index 12007a1..48a5062 100644
--- a/generator.c
+++ b/generator.c
@@ -53,6 +53,7 @@ extern int delete_after;
}
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
-@@ -1612,7 +1621,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1616,7 +1625,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
;
else if (fnamecmp_type == FNAMECMP_FUZZY)
;
do_unlink(partialptr);
handle_partial_dir(partialptr, PDIR_DELETE);
diff --git a/hlink.c b/hlink.c
-index c9eb33a..6109266 100644
--- a/hlink.c
+++ b/hlink.c
@@ -413,7 +413,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
statret = 1;
if (unchanged_attrs(cmpbuf, file, &alt_sx))
diff --git a/itypes.h b/itypes.h
-index df34140..1bdf506 100644
--- a/itypes.h
+++ b/itypes.h
@@ -23,6 +23,12 @@ isDigit(const char *ptr)
{
return isprint(*(unsigned char *)ptr);
diff --git a/loadparm.c b/loadparm.c
-index 8e48e6d..899d2b5 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -132,6 +132,7 @@ typedef struct {
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
diff --git a/options.c b/options.c
-index e7c6c61..2e110f3 100644
--- a/options.c
+++ b/options.c
@@ -112,6 +112,7 @@ size_t bwlimit_writemax = 0;
{"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
-@@ -1630,6 +1633,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1631,6 +1634,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
break;
case OPT_INFO:
arg = poptGetOptArg(pc);
parse_output_words(info_words, info_levels, arg, USER_PRIORITY);
-@@ -1830,6 +1850,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1831,6 +1851,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
#endif
snprintf(err_buf, sizeof err_buf,
"--write-batch and --read-batch can not be used together\n");
diff --git a/rsync.h b/rsync.h
-index be7cf8a..ba8f3db 100644
--- a/rsync.h
+++ b/rsync.h
-@@ -712,6 +712,10 @@ extern int xattrs_ndx;
+@@ -716,6 +716,10 @@ extern int xattrs_ndx;
#define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
+ SUM_EXTRA_CNT - 1))
/* Some utility defines: */
#define F_IS_ACTIVE(f) (f)->basename[0]
#define F_IS_HLINKED(f) ((f)->flags & FLAG_HLINKED)
-@@ -902,6 +906,13 @@ typedef struct {
+@@ -903,6 +907,13 @@ typedef struct {
char fname[1]; /* has variable size */
} relnamecache;
#include "lib/mdigest.h"
#include "lib/wildmatch.h"
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..7aa62cf 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -323,6 +323,7 @@ to the detailed description below for a complete description. verb(
-r, --recursive recurse into directories
@@ -568,9 +569,9 @@ uses a "quick check" that (by default) checks if each file's size and time
of last modification match between the sender and receiver. This option
- changes this to compare a 128-bit MD4 checksum for each file that has a
+ changes this to compare a 128-bit checksum for each file that has a
matching size. Generating the checksums means that both sides will expend
-a lot of disk I/O reading all the data in the files in the transfer (and
-this is prior to any reading that will be done to transfer changed files),
The sending side generates its checksums while it is doing the file-system
scan that builds the list of the available files. The receiver generates
-@@ -578,12 +579,44 @@ its checksums when it is scanning for changed files, and will checksum any
+@@ -578,6 +579,8 @@ its checksums when it is scanning for changed files, and will checksum any
file that has the same size as the corresponding sender's file: files with
either a changed size or a changed checksum are selected for transfer.
Note that rsync always verifies that each em(transferred) file was
correctly reconstructed on the receiving side by checking a whole-file
checksum that is generated as the file is transferred, but that
- automatic after-the-transfer verification has nothing to do with this
- option's before-the-transfer "Does this file need to be updated?" check.
+@@ -587,6 +590,36 @@ option's before-the-transfer "Does this file need to be updated?" check.
+ For protocol 30 and beyond (first supported in 3.0.0), the checksum used is
+ MD5. For older protocols, the checksum used is MD4.
+dit(bf(--sumfiles=MODE)) This option tells rsync to make use of any cached
+checksum information it finds in per-directory .rsyncsums files when the
way of saying you want recursion and want to preserve almost
everything (with -H being a notable omission).
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
-index d4978cd..0fc98fd 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -292,6 +292,17 @@ locking on this file to ensure that the max connections limit is not
attempted uploads will fail. If "read only" is false then uploads will
diff --git a/support/rsyncsums b/support/rsyncsums
new file mode 100755
-index 0000000..ce03c80
--- /dev/null
+++ b/support/rsyncsums
@@ -0,0 +1,201 @@
- Fix the code that removes .rsyncsums files when a dir becomes empty.
+based-on: patch/checksum-reading
diff --git a/flist.c b/flist.c
-index 8a42d80..d65c475 100644
--- a/flist.c
+++ b/flist.c
@@ -27,6 +27,7 @@
}
/* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
-@@ -1452,6 +1663,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1461,6 +1672,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
if (ignore_perishable)
non_perishable_cnt++;
return NULL;
}
-@@ -1498,13 +1711,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1507,13 +1720,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
lastdir[len] = '\0';
lastdir_len = len;
if (checksum_files && am_sender && flist)
}
}
basename_len = strlen(basename) + 1; /* count the '\0' */
-@@ -1599,7 +1812,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1609,7 +1822,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
if (flist && checksum_files)
else
file_checksum(thisname, st.st_size, tmp_sum);
if (sender_keeps_checksum)
-@@ -1971,6 +2184,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1981,6 +2194,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
closedir(d);
if (f >= 0 && recurse && !divert_dirs) {
int i, end = flist->used - 1;
/* send_if_directory() bumps flist->used, so use "end". */
-@@ -2589,6 +2805,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2599,6 +2815,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
} else
flist_eof = 1;
}
diff --git a/generator.c b/generator.c
-index 48a5062..8717ab7 100644
--- a/generator.c
+++ b/generator.c
@@ -111,6 +111,7 @@ static int dir_tweaking;
goto cleanup;
}
-@@ -1627,6 +1630,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1631,6 +1634,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
handle_partial_dir(partialptr, PDIR_DELETE);
}
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
#ifdef SUPPORT_HARD_LINKS
-@@ -2068,6 +2073,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2063,6 +2068,7 @@ void generate_files(int f_out, const char *local_name)
} else
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
}
for (i = cur_flist->low; i <= cur_flist->high; i++) {
struct file_struct *file = cur_flist->sorted[i];
-@@ -2162,6 +2168,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2157,6 +2163,9 @@ void generate_files(int f_out, const char *local_name)
wait_for_receiver();
}
info_levels[INFO_PROGRESS] = save_info_progress;
diff --git a/io.c b/io.c
-index 6a89c8f..50e73b1 100644
--- a/io.c
+++ b/io.c
@@ -49,6 +49,7 @@ extern int list_only;
break;
case FES_REDO:
diff --git a/loadparm.c b/loadparm.c
-index 899d2b5..3123c93 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -311,6 +311,10 @@ static struct enum_list enum_csum_modes[] = {
};
diff --git a/options.c b/options.c
-index 2e110f3..26d5561 100644
--- a/options.c
+++ b/options.c
-@@ -1635,7 +1635,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1636,7 +1636,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
case OPT_SUMFILES:
arg = poptGetOptArg(pc);
checksum_files |= CSF_LAX_MODE;
else if (strcmp(arg, "strict") == 0)
diff --git a/receiver.c b/receiver.c
-index 4325e30..2cea8fe 100644
--- a/receiver.c
+++ b/receiver.c
@@ -47,6 +47,7 @@ extern int sparse_files;
send_msg_int(MSG_SUCCESS, ndx);
break;
diff --git a/rsync.h b/rsync.h
-index ba8f3db..89c47bd 100644
--- a/rsync.h
+++ b/rsync.h
-@@ -908,6 +908,8 @@ typedef struct {
+@@ -909,6 +909,8 @@ typedef struct {
#define CSF_ENABLE (1<<1)
#define CSF_LAX (1<<2)
#define CSF_IGNORE_FILES 0
#define CSF_LAX_MODE (CSF_ENABLE|CSF_LAX)
diff --git a/rsync.yo b/rsync.yo
-index 7aa62cf..a119ed7 100644
--- a/rsync.yo
+++ b/rsync.yo
-@@ -596,9 +596,13 @@ computed just as it would be if bf(--sumfiles) was not specified.
+@@ -599,9 +599,13 @@ computed just as it would be if bf(--sumfiles) was not specified.
The MODE value is either "lax", for relaxed checking (which compares size
and mtime), "strict" (which also compares ctime and inode), or "none" to
This option has no effect unless bf(--checksum, -c) was also specified. It
also only affects the current side of the transfer, so if you want the
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
-index 0fc98fd..3024842 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -295,13 +295,15 @@ The default is tt(/var/run/rsyncd.lock).
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/flist.c b/flist.c
-index 09b4fc5..3295724 100644
--- a/flist.c
+++ b/flist.c
-@@ -1268,7 +1268,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1277,7 +1277,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
#endif
if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
}
diff --git a/generator.c b/generator.c
-index 12007a1..2587bc9 100644
--- a/generator.c
+++ b/generator.c
@@ -531,7 +531,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
diff --git a/support/xsums b/support/xsums
new file mode 100644
-index 0000000..31d2537
--- /dev/null
+++ b/support/xsums
@@ -0,0 +1,118 @@
+EOT
+}
diff --git a/xattrs.c b/xattrs.c
-index 2d0e050..f364a2a 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -34,6 +34,8 @@ extern int read_only;
typedef struct {
char *datum, *name;
-@@ -239,7 +245,9 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
+@@ -241,7 +247,9 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
|| (am_root < 0
&& (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0
|| strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0
continue;
}
-@@ -895,6 +903,39 @@ int del_def_xattr_acl(const char *fname)
+@@ -914,6 +922,39 @@ int del_def_xattr_acl(const char *fname)
}
#endif
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/generator.c b/generator.c
-index 12007a1..a2875fd 100644
--- a/generator.c
+++ b/generator.c
@@ -39,6 +39,7 @@ extern int preserve_acls;
extern int preserve_specials;
extern int preserve_hard_links;
extern int preserve_executability;
-@@ -1507,7 +1508,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1511,7 +1512,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
fname = f_name(file, NULL);
rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
diff --git a/options.c b/options.c
-index e7c6c61..b0806e8 100644
--- a/options.c
+++ b/options.c
@@ -48,6 +48,7 @@ int append_mode = 0;
{"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 },
{"no-specials", 0, POPT_ARG_VAL, &preserve_specials, 0, 0, 0 },
{"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 },
-@@ -2609,6 +2612,9 @@ void server_options(char **args, int *argc_p)
+@@ -2626,6 +2629,9 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
rprintf(FERROR, "argc overflow in server_options().\n");
exit_cleanup(RERR_MALLOC);
diff --git a/rsync.c b/rsync.c
-index 2c026a2..cfc6ffa 100644
--- a/rsync.c
+++ b/rsync.c
@@ -33,6 +33,7 @@ extern int preserve_xattrs;
"received request to transfer non-regular file: %d [%s]\n",
ndx, who_am_i());
diff --git a/sender.c b/sender.c
-index bf8221d..f115457 100644
--- a/sender.c
+++ b/sender.c
-@@ -329,6 +329,20 @@ void send_files(int f_in, int f_out)
+@@ -328,6 +328,20 @@ void send_files(int f_in, int f_out)
exit_cleanup(RERR_PROTOCOL);
}
./configure (optional if already run)
make
+based-on: patch/fileflags
diff --git a/compat.c b/compat.c
-index ef1882d..132ff90 100644
--- a/compat.c
+++ b/compat.c
@@ -44,6 +44,7 @@ extern int force_change;
fileflags_ndx = ++file_extra_cnt;
if (preserve_acls && !am_sender)
diff --git a/flist.c b/flist.c
-index e1d01be..3287447 100644
--- a/flist.c
+++ b/flist.c
@@ -56,6 +56,7 @@ extern int missing_args;
static mode_t mode;
#ifdef SUPPORT_FILEFLAGS
static uint32 fileflags;
-@@ -496,6 +497,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -506,6 +507,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_TIME;
else
modtime = file->modtime;
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != 0) {
-@@ -578,6 +586,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -588,6 +596,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
write_int(f, modtime);
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
#ifdef SUPPORT_FILEFLAGS
-@@ -670,7 +680,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -680,7 +690,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
static mode_t mode;
#ifdef SUPPORT_FILEFLAGS
static uint32 fileflags;
-@@ -810,6 +820,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -819,6 +829,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
} else
modtime = read_int(f);
}
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
-@@ -969,6 +992,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -979,6 +1002,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
-@@ -1358,6 +1383,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1368,6 +1393,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_OWNER(file) = st.st_uid;
if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
F_GROUP(file) = st.st_gid;
if (basename != thisname)
file->dirname = lastdir;
diff --git a/generator.c b/generator.c
-index eee42e8..932f81c 100644
--- a/generator.c
+++ b/generator.c
@@ -40,6 +40,7 @@ extern int preserve_xattrs;
init_stat_x(&sx);
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
diff --git a/ifuncs.h b/ifuncs.h
-index 8c128d5..4254dfb 100644
--- a/ifuncs.h
+++ b/ifuncs.h
@@ -35,6 +35,28 @@ realloc_xbuf(xbuf *xb, size_t sz)
to_wire_mode(mode_t mode)
{
diff --git a/log.c b/log.c
-index 83948b1..7a1d9ce 100644
--- a/log.c
+++ b/log.c
@@ -718,7 +718,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
char ch = iflags & ITEM_IS_NEW ? '+' : '?';
diff --git a/options.c b/options.c
-index ae3d2d0..bb3bad3 100644
--- a/options.c
+++ b/options.c
@@ -60,6 +60,7 @@ int preserve_specials = 0;
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
-@@ -2315,6 +2320,8 @@ void server_options(char **args, int *argc_p)
+@@ -2332,6 +2337,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
argstr[x++] = 'p';
else if (preserve_executability && am_sender)
diff --git a/rsync.c b/rsync.c
-index 3188535..ab4f8e4 100644
--- a/rsync.c
+++ b/rsync.c
@@ -471,6 +471,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
if (temp_copy_name) {
if (do_rename(fnametmp, fname) < 0) {
diff --git a/rsync.h b/rsync.h
-index 16820fd..b3973c8 100644
--- a/rsync.h
+++ b/rsync.h
@@ -61,6 +61,7 @@
#define ITEM_REPORT_CHANGE (1<<1)
#define ITEM_REPORT_SIZE (1<<2) /* regular files only */
#define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */
-@@ -677,6 +679,7 @@ extern int file_extra_cnt;
+@@ -681,6 +683,7 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
extern int fileflags_ndx;
extern int acls_ndx;
extern int xattrs_ndx;
-@@ -684,6 +687,7 @@ extern int xattrs_ndx;
+@@ -688,6 +691,7 @@ extern int xattrs_ndx;
#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
#define EXTRA_LEN (sizeof (union file_extras))
#define PTR_EXTRA_CNT ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
#define DEV_EXTRA_CNT 2
#define DIRNODE_EXTRA_CNT 3
#define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
-@@ -954,6 +958,7 @@ typedef struct {
+@@ -955,6 +959,7 @@ typedef struct {
typedef struct {
STRUCT_STAT st;
struct rsync_acl *acc_acl; /* access ACL */
struct rsync_acl *def_acl; /* default ACL */
diff --git a/rsync.yo b/rsync.yo
-index 7b41d5f..5670c46 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -357,6 +357,7 @@ to the detailed description below for a complete description. verb(
--super receiver attempts super-user activities
--fake-super store/recover privileged attrs using xattrs
-S, --sparse handle sparse files efficiently
-@@ -1099,6 +1100,9 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
+@@ -1106,6 +1107,9 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
the directories on the receiving side, it is a good idea to use bf(-O).
This option is inferred if you use bf(--backup) without bf(--backup-dir).
dit(bf(--super)) This tells the receiving side to attempt super-user
activities even if the receiving rsync wasn't run by the super-user. These
activities include: preserving users via the bf(--owner) option, preserving
-@@ -1861,7 +1865,7 @@ with older versions of rsync, but that also turns on the output of other
+@@ -1880,7 +1884,7 @@ with older versions of rsync, but that also turns on the output of other
verbose messages).
The "%i" escape has a cryptic output that is 11 letters long. The general
type of update being done, bf(X) is replaced by the file-type, and the
other letters represent attributes that may be output if they are being
modified.
-@@ -1920,6 +1924,8 @@ quote(itemization(
+@@ -1939,6 +1943,8 @@ quote(itemization(
it() The bf(f) means that the fileflags information changed.
it() The bf(a) means that the ACL information changed.
it() The bf(x) means that the extended attribute information changed.
One other output is possible: when deleting files, the "%i" will output
diff --git a/syscall.c b/syscall.c
-index 45604b1..c463997 100644
--- a/syscall.c
+++ b/syscall.c
@@ -37,6 +37,11 @@ extern int force_change;
+}
diff --git a/testsuite/crtimes.test b/testsuite/crtimes.test
new file mode 100644
-index 0000000..b904e16
--- /dev/null
+++ b/testsuite/crtimes.test
@@ -0,0 +1,24 @@
+# The script would have aborted on error, so getting here means we've won.
+exit 0
diff --git a/testsuite/rsync.fns b/testsuite/rsync.fns
-index b26aee3..4faaf93 100644
--- a/testsuite/rsync.fns
+++ b/testsuite/rsync.fns
@@ -24,9 +24,9 @@ todir="$tmpdir/to"
# Berkley's nice.
PATH="$PATH:/usr/ucb"
diff --git a/tls.c b/tls.c
-index 8cc5748..6da4df9 100644
--- a/tls.c
+++ b/tls.c
@@ -108,6 +108,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/exclude.c b/exclude.c
-index 5fa6e00..60e557d 100644
--- a/exclude.c
+++ b/exclude.c
-@@ -275,6 +275,8 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
- if (!(lp = new_array(struct filter_list_struct, 1)))
+@@ -267,6 +267,8 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
+ if (!(lp = new_array(filter_rule_list, 1)))
out_of_memory("add_rule");
lp->head = lp->tail = lp->parent_dirscan_head = NULL;
+ if (mflags & MATCHFLG_CVS_IGNORE)
+ cp = "CVS";
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
out_of_memory("add_rule");
- ret->u.mergelist = lp;
-@@ -536,6 +538,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
+ rule->u.mergelist = lp;
+@@ -526,6 +528,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
set_filter_dir(dir, dirlen);
}
+ }
if (strlcpy(dirbuf + dirbuf_len, ex->pattern,
MAXPATHLEN - dirbuf_len) < MAXPATHLEN - dirbuf_len) {
- parse_filter_file(lp, dirbuf, ex->match_flags,
-@@ -1122,6 +1132,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+ parse_filter_file(lp, dirbuf, ex,
+@@ -1151,6 +1161,7 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
char line[BIGPATHBUFLEN];
char *eob = line + sizeof line - 1;
- int word_split = mflags & MATCHFLG_WORD_SPLIT;
+ BOOL word_split = (template->rflags & FILTRULE_WORD_SPLIT) != 0;
+ int slash_parse = xflags & XFLG_CVS_ENTRIES ? 1 : 0;
if (!fname || !*fname)
return;
-@@ -1168,6 +1179,24 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+@@ -1197,6 +1208,24 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
}
break;
}
if (word_split && isspace(ch))
break;
if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))
-@@ -1177,13 +1206,15 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+@@ -1206,13 +1235,14 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
else
overflow = 1;
}
*s = '\0';
/* Skip an empty token and (when line parsing) comments. */
- if (*line && (word_split || (*line != ';' && *line != '#')))
-+ if (*line && (word_split || slash_parse
-+ || (*line != ';' && *line != '#')))
- parse_rule(listp, line, mflags, xflags);
++ if (*line && (word_split || slash_parse || (*line != ';' && *line != '#')))
+ parse_filter_str(listp, line, template, xflags);
if (ch == EOF)
break;
diff --git a/rsync.h b/rsync.h
-index be7cf8a..6605092 100644
--- a/rsync.h
+++ b/rsync.h
@@ -152,6 +152,7 @@
#define ATTRS_REPORT (1<<0)
#define ATTRS_SKIP_MTIME (1<<1)
diff --git a/testsuite/exclude.test b/testsuite/exclude.test
-index 099344f..993edcc 100644
--- a/testsuite/exclude.test
+++ b/testsuite/exclude.test
@@ -19,6 +19,7 @@ export CVSIGNORE
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/access.c b/access.c
-index 9a023de..ad1cdb1 100644
--- a/access.c
+++ b/access.c
@@ -210,6 +210,38 @@ static int match_address(const char *addr, const char *tok)
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/generator.c b/generator.c
-index 12007a1..a2519e6 100644
--- a/generator.c
+++ b/generator.c
@@ -64,6 +64,7 @@ extern int append_mode;
return 0;
diff --git a/options.c b/options.c
-index e7c6c61..b317903 100644
--- a/options.c
+++ b/options.c
@@ -105,6 +105,7 @@ int safe_symlinks = 0;
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
{"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
{"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
-@@ -2493,6 +2496,9 @@ void server_options(char **args, int *argc_p)
+@@ -2510,6 +2513,9 @@ void server_options(char **args, int *argc_p)
else if (missing_args == 1 && !am_sender)
args[ac++] = "--ignore-missing-args";
if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
goto oom;
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..710b32d 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -394,6 +394,7 @@ to the detailed description below for a complete description. verb(
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/Makefile.in b/Makefile.in
-index feacb90..f9da8eb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -36,7 +36,7 @@ ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
diff --git a/checksum.c b/checksum.c
-index 811b5b6..a7617af 100644
--- a/checksum.c
+++ b/checksum.c
@@ -23,6 +23,7 @@
unmap_file(buf);
}
diff --git a/cleanup.c b/cleanup.c
-index 19ef072..ca46868 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -25,6 +25,7 @@
int status;
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
diff --git a/clientserver.c b/clientserver.c
-index b6afe00..37cad54 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -42,13 +42,16 @@ extern int numeric_ids;
extern char *bind_address;
extern char *config_file;
extern char *logfile_format;
-@@ -648,6 +651,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -642,6 +645,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
log_init(1);
#ifdef HAVE_PUTENV
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
char *modname, *modpath, *hostaddr, *hostname, *username;
-@@ -856,6 +862,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -850,6 +856,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
am_server = 1; /* Don't let someone try to be tricky. */
quiet = 0;
ignore_errors = 1;
if (write_batch < 0)
diff --git a/configure.in b/configure.in
-index bc7d4a7..43d51ff 100644
--- a/configure.in
+++ b/configure.in
@@ -312,7 +312,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
AC_DEFINE(FORCE_FD_ZERO_MEMSET, 1, [Used to make "checker" understand that FD_ZERO() clears memory.])
diff --git a/db.c b/db.c
new file mode 100644
-index 0000000..6855488
--- /dev/null
+++ b/db.c
@@ -0,0 +1,566 @@
+ return 0;
+}
diff --git a/flist.c b/flist.c
-index 09b4fc5..8d280e9 100644
--- a/flist.c
+++ b/flist.c
@@ -54,6 +54,7 @@ extern int preserve_specials;
extern int eol_nulls;
extern int relative_paths;
extern int implied_dirs;
-@@ -1267,11 +1268,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1276,11 +1277,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
extra_len += EXTRA_LEN;
#endif
#if EXTRA_ROUNDING > 0
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
-@@ -1347,8 +1345,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1357,8 +1355,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
return NULL;
}
if (unsort_ndx)
F_NDX(file) = stats.num_dirs;
-@@ -2010,6 +2012,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2020,6 +2022,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
| (eol_nulls || reading_remotely ? RL_EOL_NULLS : 0);
int implied_dot_dir = 0;
if (show_filelist_p())
start_filelist_progress("building file list");
diff --git a/generator.c b/generator.c
-index 12007a1..315463f 100644
--- a/generator.c
+++ b/generator.c
@@ -60,6 +60,7 @@ extern int human_readable;
return memcmp(sum, F_SUM(file), checksum_len) == 0;
}
-@@ -2022,6 +2024,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2017,6 +2019,9 @@ void generate_files(int f_out, const char *local_name)
: "enabled");
}
* waiting for the other 2 processes to do their thing, we don't want
* to exit on a timeout. If the data stops flowing, the receiver will
diff --git a/loadparm.c b/loadparm.c
-index 8e48e6d..e6eaec8 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -107,6 +107,7 @@ typedef struct {
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
diff --git a/main.c b/main.c
-index 2ef2f47..ac88e12 100644
--- a/main.c
+++ b/main.c
@@ -49,6 +49,7 @@ extern int copy_unsafe_links;
extern char *shell_cmd;
extern char *batch_name;
extern char *password_file;
-@@ -1565,6 +1567,9 @@ int main(int argc,char *argv[])
+@@ -1577,6 +1579,9 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
set_nonblocking(STDIN_FILENO);
set_nonblocking(STDOUT_FILENO);
diff --git a/options.c b/options.c
-index e7c6c61..d47cb7c 100644
--- a/options.c
+++ b/options.c
@@ -92,6 +92,7 @@ int use_qsort = 0;
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
diff --git a/pipe.c b/pipe.c
-index a33117c..2f6aa21 100644
--- a/pipe.c
+++ b/pipe.c
@@ -27,6 +27,9 @@ extern int am_server;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..1b81189 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -323,6 +323,7 @@ to the detailed description below for a complete description. verb(
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
--no-OPTION turn off an implied OPTION (e.g. --no-D)
-r, --recursive recurse into directories
-@@ -584,6 +585,47 @@ checksum that is generated as the file is transferred, but that
- automatic after-the-transfer verification has nothing to do with this
- option's before-the-transfer "Does this file need to be updated?" check.
+@@ -587,6 +588,47 @@ option's before-the-transfer "Does this file need to be updated?" check.
+ For protocol 30 and beyond (first supported in 3.0.0), the checksum used is
+ MD5. For older protocols, the checksum used is MD4.
+dit(bf(--db=CONFIG_FILE)) This option specifies a CONFIG_FILE to read
+that holds connection details for a database of checksum information.
way of saying you want recursion and want to preserve almost
everything (with -H being a notable omission).
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
-index d4978cd..68c588c 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -281,6 +281,18 @@ is daemon. This setting has no effect if the "log file" setting is a
generate (since the information goes into the log file). The default is 1,
diff --git a/support/rsyncdb b/support/rsyncdb
new file mode 100755
-index 0000000..801068c
--- /dev/null
+++ b/support/rsyncdb
@@ -0,0 +1,331 @@
-- Matt McCutchen <hashproduct+rsync@gmail.com>
+based-on: patch/detect-renamed
diff --git a/generator.c b/generator.c
-index 35ba203..ac844ac 100644
--- a/generator.c
+++ b/generator.c
@@ -469,7 +469,9 @@ static int fattr_find(struct file_struct *f, char *fname)
diff = u_strcmp(fmid->basename, f->basename);
if (diff == 0) {
good_match = mid;
-@@ -1796,6 +1798,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1800,6 +1802,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
if (!do_xfers)
diff --git a/options.c b/options.c
-index 7e454b3..1da38cb 100644
--- a/options.c
+++ b/options.c
@@ -744,6 +744,8 @@ void usage(enum logcode F)
{"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 },
{"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
-@@ -2480,8 +2484,14 @@ void server_options(char **args, int *argc_p)
+@@ -2497,8 +2501,14 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--super";
if (size_only)
args[ac++] = "--size-only";
args[ac++] = "--stats";
} else {
diff --git a/rsync.yo b/rsync.yo
-index 4df39b0..e254152 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -398,6 +398,8 @@ to the detailed description below for a complete description. verb(
--compare-dest=DIR also compare received files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
-@@ -1621,6 +1623,17 @@ the bf(--partial-dir) option, that directory will be used instead. These
+@@ -1640,6 +1642,17 @@ the bf(--partial-dir) option, that directory will be used instead. These
potential alternate-basis files will be removed as the transfer progresses.
This option conflicts with bf(--inplace) and bf(--append).
a file that can't use it, while missing out on giving it to a file
that could use it.
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/compat.c b/compat.c
-index 6e00072..5fc9e37 100644
--- a/compat.c
+++ b/compat.c
@@ -40,6 +40,7 @@ extern int checksum_seed;
allow_inc_recurse = 0;
else if (am_server && !local_server
diff --git a/delete.c b/delete.c
-index 33fdd0e..6130a4c 100644
--- a/delete.c
+++ b/delete.c
@@ -25,6 +25,7 @@
enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
{
diff --git a/flist.c b/flist.c
-index 09b4fc5..929aa85 100644
--- a/flist.c
+++ b/flist.c
@@ -63,6 +63,7 @@ extern int non_perishable_cnt;
static void send_directory(int f, struct file_list *flist,
char *fbuf, int len, int flags);
-@@ -2464,6 +2506,25 @@ struct file_list *recv_file_list(int f)
+@@ -2474,6 +2516,25 @@ struct file_list *recv_file_list(int f)
flist_sort_and_clean(flist, relative_paths);
/* Recv the io_error flag */
int err = read_int(f);
diff --git a/generator.c b/generator.c
-index 12007a1..35ba203 100644
--- a/generator.c
+++ b/generator.c
@@ -81,6 +81,7 @@ extern char *partial_dir;
@@ -98,10 +99,12 @@ extern uid_t our_uid;
extern char *basis_dir[MAX_BASIS_DIRS+1];
extern struct file_list *cur_flist, *first_flist, *dir_flist;
- extern struct filter_list_struct filter_list, daemon_filter_list;
+ extern filter_rule_list filter_list, daemon_filter_list;
+extern struct file_list the_fattr_list;
int maybe_ATTRS_REPORT = 0;
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
}
goto cleanup;
-@@ -1601,8 +1745,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1605,8 +1749,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
#endif
rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
full_fname(fname));
goto cleanup;
-@@ -2003,6 +2153,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -1998,6 +2148,12 @@ void generate_files(int f_out, const char *local_name)
if (DEBUG_GTE(GENR, 1))
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
if (delete_before && !solo_file && cur_flist->used > 0)
do_delete_pass();
if (delete_during == 2) {
-@@ -2013,7 +2169,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2008,7 +2164,7 @@ void generate_files(int f_out, const char *local_name)
}
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;
whole_file = 0;
if (DEBUG_GTE(FLIST, 1)) {
rprintf(FINFO, "delta-transmission %s\n",
-@@ -2055,7 +2211,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2050,7 +2206,7 @@ void generate_files(int f_out, const char *local_name)
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
dirdev = MAKEDEV(0, 0);
} else
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
-@@ -2102,7 +2258,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2097,7 +2253,21 @@ void generate_files(int f_out, const char *local_name)
} while ((cur_flist = cur_flist->next) != NULL);
if (delete_during)
if (DEBUG_GTE(GENR, 1))
rprintf(FINFO, "generate_files phase=%d\n", phase);
diff --git a/options.c b/options.c
-index e7c6c61..7e454b3 100644
--- a/options.c
+++ b/options.c
@@ -80,6 +80,7 @@ int am_server = 0;
{"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 },
{"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
-@@ -2105,7 +2108,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2122,7 +2125,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
inplace = 1;
}
partial_dir = tmp_partialdir;
if (inplace) {
-@@ -2114,6 +2117,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2131,6 +2134,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
snprintf(err_buf, sizeof err_buf,
"--%s cannot be used with --%s\n",
append_mode ? "append" : "inplace",
delay_updates ? "delay-updates" : "partial-dir");
return 0;
}
-@@ -2476,6 +2480,8 @@ void server_options(char **args, int *argc_p)
+@@ -2493,6 +2497,8 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--super";
if (size_only)
args[ac++] = "--size-only";
args[ac++] = "--stats";
} else {
diff --git a/rsync.h b/rsync.h
-index be7cf8a..278e282 100644
--- a/rsync.h
+++ b/rsync.h
@@ -242,7 +242,7 @@ enum msgcode {
#define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL)
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..4df39b0 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -397,6 +397,7 @@ to the detailed description below for a complete description. verb(
--compare-dest=DIR also compare received files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
-@@ -1605,6 +1606,21 @@ Note that the use of the bf(--delete) option might get rid of any potential
+@@ -1624,6 +1625,21 @@ Note that the use of the bf(--delete) option might get rid of any potential
fuzzy-match files, so either use bf(--delete-after) or specify some
filename exclusions if you need to prevent this.
the destination machine as an additional hierarchy to compare destination
files against doing transfers (if the files are missing in the destination
diff --git a/util.c b/util.c
-index 0cafed6..7e5c71f 100644
--- a/util.c
+++ b/util.c
-@@ -1064,6 +1064,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
+@@ -1112,6 +1112,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
return path;
}
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/generator.c b/generator.c
-index 12007a1..f326030 100644
--- a/generator.c
+++ b/generator.c
@@ -56,6 +56,7 @@ extern int ignore_errors;
extern int human_readable;
extern int ignore_existing;
extern int ignore_non_existing;
-@@ -1542,6 +1543,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1546,6 +1547,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
-@@ -1913,6 +1921,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1908,6 +1916,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
ignore_existing = -ignore_existing;
ignore_non_existing = -ignore_non_existing;
update_only = -update_only;
always_checksum = -always_checksum;
size_only = -size_only;
append_mode = -append_mode;
-@@ -1938,6 +1947,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1933,6 +1942,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
ignore_existing = -ignore_existing;
ignore_non_existing = -ignore_non_existing;
update_only = -update_only;
size_only = -size_only;
append_mode = -append_mode;
diff --git a/options.c b/options.c
-index e7c6c61..371d72f 100644
--- a/options.c
+++ b/options.c
@@ -60,6 +60,7 @@ int preserve_uid = 0;
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/checksum.c b/checksum.c
-index 811b5b6..f1f51cb 100644
--- a/checksum.c
+++ b/checksum.c
@@ -24,6 +24,10 @@
a simple 32 bit checksum that can be upadted from either end
(inspired by Mark Adler's Adler-32 checksum)
diff --git a/cleanup.c b/cleanup.c
-index 19ef072..84a6cf3 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -47,7 +47,13 @@ void close_all(void)
for (fd = max_fd; fd >= 0; fd--) {
if ((ret = do_fstat(fd, &st)) == 0) {
diff --git a/configure.in b/configure.in
-index bc7d4a7..e9ff45a 100644
--- a/configure.in
+++ b/configure.in
@@ -553,7 +553,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
dnl cygwin iconv.h defines iconv_open as libiconv_open
if test x"$ac_cv_func_iconv_open" != x"yes"; then
diff --git a/fileio.c b/fileio.c
-index 0faa619..0326fe8 100644
--- a/fileio.c
+++ b/fileio.c
@@ -31,6 +31,12 @@ extern int sparse_files;
{
int ret;
diff --git a/generator.c b/generator.c
-index 12007a1..f0c7a91 100644
--- a/generator.c
+++ b/generator.c
@@ -112,6 +112,10 @@ static int need_retouch_dir_times;
TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK
};
diff --git a/options.c b/options.c
-index e7c6c61..ce55d8e 100644
--- a/options.c
+++ b/options.c
@@ -60,6 +60,7 @@ int preserve_uid = 0;
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
-@@ -2235,6 +2242,11 @@ void server_options(char **args, int *argc_p)
+@@ -2252,6 +2259,11 @@ void server_options(char **args, int *argc_p)
if (!am_sender)
args[ac++] = "--sender";
argstr[0] = '-';
diff --git a/receiver.c b/receiver.c
-index 4325e30..a3da64e 100644
--- a/receiver.c
+++ b/receiver.c
@@ -64,6 +64,10 @@ static flist_ndx_list batch_redo_list;
* get_tmpname() - create a tmp filename for a given filename
*
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..512aa6b 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -359,6 +359,7 @@ to the detailed description below for a complete description. verb(
-n, --dry-run perform a trial run with no changes made
-W, --whole-file copy files whole (w/o delta-xfer algorithm)
-x, --one-file-system don't cross filesystem boundaries
-@@ -1120,6 +1121,10 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
+@@ -1127,6 +1128,10 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
make any changes (and produces mostly the same output as a real run). It
is most commonly used in combination with the bf(-v, --verbose) and/or
diff --git a/sender.c b/sender.c
-index bf8221d..9e23dbb 100644
--- a/sender.c
+++ b/sender.c
-@@ -45,6 +45,10 @@ extern int write_batch;
+@@ -44,6 +44,10 @@ extern int write_batch;
extern struct stats stats;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
* @file
*
diff --git a/t_unsafe.c b/t_unsafe.c
-index 9ba0aaa..3cb55e9 100644
--- a/t_unsafe.c
+++ b/t_unsafe.c
@@ -27,6 +27,7 @@ int dry_run = 0;
int preserve_perms = 0;
int preserve_executability = 0;
diff --git a/util.c b/util.c
-index 0cafed6..06d8770 100644
--- a/util.c
+++ b/util.c
@@ -27,6 +27,7 @@
./configure
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/Makefile.in b/Makefile.in
-index feacb90..cd4cf2d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,7 +43,7 @@ popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
diff --git a/compat.c b/compat.c
-index 6e00072..ef1882d 100644
--- a/compat.c
+++ b/compat.c
@@ -40,9 +40,11 @@ extern int checksum_seed;
acls_ndx = ++file_extra_cnt;
if (preserve_xattrs)
diff --git a/configure.in b/configure.in
-index bc7d4a7..8709fa4 100644
--- a/configure.in
+++ b/configure.in
@@ -553,7 +553,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
dnl cygwin iconv.h defines iconv_open as libiconv_open
if test x"$ac_cv_func_iconv_open" != x"yes"; then
diff --git a/delete.c b/delete.c
-index 33fdd0e..1c0df57 100644
--- a/delete.c
+++ b/delete.c
@@ -25,6 +25,7 @@
/* If DEL_RECURSE is not set, this just reports emptiness. */
ret = delete_dir_contents(fbuf, flags);
diff --git a/flist.c b/flist.c
-index 09b4fc5..e1d01be 100644
--- a/flist.c
+++ b/flist.c
@@ -51,6 +51,7 @@ extern int preserve_links;
+ }
+#endif
- if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
-@@ -568,6 +580,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+ if (preserve_devices && IS_DEVICE(mode)) {
+ if (protocol_version < 28) {
+@@ -578,6 +590,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
write_int(f, uid);
-@@ -656,6 +672,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -666,6 +682,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
{
static int64 modtime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
#endif
-@@ -796,6 +815,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -805,6 +824,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
if (chmod_modes && !S_ISLNK(mode) && mode)
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
-@@ -936,6 +959,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -946,6 +969,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
#endif
file->mode = mode;
if (preserve_uid)
F_OWNER(file) = uid;
if (preserve_gid) {
-@@ -1323,6 +1350,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1333,6 +1360,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
}
#endif
file->mode = st.st_mode;
if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
F_OWNER(file) = st.st_uid;
if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
-@@ -1466,6 +1497,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
+@@ -1476,6 +1507,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
io_error |= IOERR_GENERAL;
return NULL;
diff --git a/generator.c b/generator.c
-index 12007a1..eee42e8 100644
--- a/generator.c
+++ b/generator.c
@@ -42,8 +42,10 @@ extern int preserve_devices;
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
-@@ -1870,13 +1895,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1865,13 +1890,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
continue;
fname = f_name(file, NULL);
if (!(file->mode & S_IWUSR))
if (allowed_lull)
maybe_send_keepalive();
diff --git a/log.c b/log.c
-index a687375..83948b1 100644
--- a/log.c
+++ b/log.c
@@ -715,7 +715,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
c[11] = '\0';
diff --git a/options.c b/options.c
-index e7c6c61..ae3d2d0 100644
--- a/options.c
+++ b/options.c
@@ -53,6 +53,7 @@ int preserve_hard_links = 0;
{"ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 1, 0, 0 },
{"no-ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 0, 0, 0 },
{"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
-@@ -2383,6 +2409,9 @@ void server_options(char **args, int *argc_p)
+@@ -2400,6 +2426,9 @@ void server_options(char **args, int *argc_p)
if (xfer_dirs && !recurse && delete_mode && am_sender)
args[ac++] = "--no-r";
if (do_compression && def_compress_level != Z_DEFAULT_COMPRESSION) {
if (asprintf(&arg, "--compress-level=%d", def_compress_level) < 0)
goto oom;
-@@ -2470,6 +2499,16 @@ void server_options(char **args, int *argc_p)
+@@ -2487,6 +2516,16 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--delete-excluded";
if (force_delete)
args[ac++] = "--force";
args[ac++] = "--only-write-batch=X";
if (am_root > 1)
diff --git a/rsync.c b/rsync.c
-index 2c026a2..3188535 100644
--- a/rsync.c
+++ b/rsync.c
@@ -31,6 +31,7 @@ extern int dry_run;
}
/* The file was copied, so tweak the perms of the copied file. If it
diff --git a/rsync.h b/rsync.h
-index be7cf8a..16820fd 100644
--- a/rsync.h
+++ b/rsync.h
@@ -61,6 +61,7 @@
#define ITEM_BASIS_TYPE_FOLLOWS (1<<11)
#define ITEM_XNAME_FOLLOWS (1<<12)
#define ITEM_IS_NEW (1<<13)
-@@ -482,6 +485,28 @@ typedef unsigned int size_t;
+@@ -486,6 +489,28 @@ typedef unsigned int size_t;
#endif
#endif
/* Find a variable that is either exactly 32-bits or longer.
* If some code depends on 32-bit truncation, it will need to
* take special action in a "#if SIZEOF_INT32 > 4" section. */
-@@ -652,6 +677,7 @@ extern int file_extra_cnt;
+@@ -656,6 +681,7 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
extern int acls_ndx;
extern int xattrs_ndx;
-@@ -689,6 +715,11 @@ extern int xattrs_ndx;
+@@ -693,6 +719,11 @@ extern int xattrs_ndx;
/* When the associated option is on, all entries will have these present: */
#define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum
#define F_GROUP(f) REQ_EXTRA(f, gid_ndx)->unum
#define F_XATTR(f) REQ_EXTRA(f, xattrs_ndx)->num
#define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..7b41d5f 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -345,6 +345,7 @@ to the detailed description below for a complete description. verb(
--max-delete=NUM don't delete more than NUM files
--max-size=SIZE don't transfer any file larger than SIZE
--min-size=SIZE don't transfer any file smaller than SIZE
-@@ -592,7 +596,8 @@ specified, in which case bf(-r) is not implied.
+@@ -595,7 +599,8 @@ specified, in which case bf(-r) is not implied.
Note that bf(-a) bf(does not preserve hardlinks), because
finding multiply-linked files is expensive. You must separately
dit(--no-OPTION) You may turn off one or more implied options by prefixing
the option name with "no-". Not all options may be prefixed with a "no-":
-@@ -869,7 +874,7 @@ they would be using bf(--copy-links).
+@@ -876,7 +881,7 @@ they would be using bf(--copy-links).
Without this option, if the sending side has replaced a directory with a
symlink to a directory, the receiving side will delete anything that is in
the way of the new symlink, including a directory hierarchy (as long as
See also bf(--keep-dirlinks) for an analogous option for the receiving
side.
-@@ -1006,6 +1011,29 @@ super-user copies all namespaces except system.*. A normal user only copies
+@@ -1013,6 +1018,29 @@ super-user copies all namespaces except system.*. A normal user only copies
the user.* namespace. To be able to backup and restore non-user namespaces as
a normal user, see the bf(--fake-super) option.
dit(bf(--chmod)) This option tells rsync to apply one or more
comma-separated "chmod" strings to the permission of the files in the
transfer. The resulting value is treated as though it was the permissions
-@@ -1285,12 +1313,13 @@ display as a "*missing" entry in the bf(--list-only) output.
+@@ -1300,12 +1328,13 @@ display as a "*missing" entry in the bf(--list-only) output.
dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files
even when there are I/O errors.
bf(--recursive) option was also enabled.
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
-@@ -1832,7 +1861,7 @@ with older versions of rsync, but that also turns on the output of other
+@@ -1851,7 +1880,7 @@ with older versions of rsync, but that also turns on the output of other
verbose messages).
The "%i" escape has a cryptic output that is 11 letters long. The general
type of update being done, bf(X) is replaced by the file-type, and the
other letters represent attributes that may be output if they are being
modified.
-@@ -1888,7 +1917,7 @@ quote(itemization(
+@@ -1907,7 +1936,7 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
it() The bf(x) means that the extended attribute information changed.
))
diff --git a/syscall.c b/syscall.c
-index cfabc3e..45604b1 100644
--- a/syscall.c
+++ b/syscall.c
@@ -33,6 +33,7 @@ extern int dry_run;
void trim_trailing_slashes(char *name)
diff --git a/t_stub.c b/t_stub.c
-index 02cfa69..9228d0c 100644
--- a/t_stub.c
+++ b/t_stub.c
@@ -25,6 +25,7 @@ int modify_window = 0;
int preserve_xattrs = 0;
mode_t orig_umask = 002;
char number_separator = ',';
-@@ -89,3 +90,23 @@ struct filter_list_struct daemon_filter_list;
+@@ -84,3 +85,23 @@ filter_rule_list daemon_filter_list;
{
return "tester";
}
+}
+#endif
diff --git a/util.c b/util.c
-index 0cafed6..ed26a05 100644
--- a/util.c
+++ b/util.c
@@ -30,6 +30,7 @@ extern int module_id;
}
diff --git a/xattrs.c b/xattrs.c
-index 2d0e050..5d04599 100644
--- a/xattrs.c
+++ b/xattrs.c
-@@ -282,6 +282,10 @@ int get_xattr(const char *fname, stat_x *sxp)
+@@ -284,6 +284,10 @@ int get_xattr(const char *fname, stat_x *sxp)
{
sxp->xattr = new(item_list);
*sxp->xattr = empty_xattr;
if (rsync_xal_get(fname, sxp->xattr) < 0) {
free_xattr(sxp);
return -1;
-@@ -865,6 +869,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
+@@ -884,6 +888,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
return -1;
}
ndx = F_XATTR(file);
return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp);
}
-@@ -981,7 +990,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
+@@ -1000,7 +1009,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
mode = (fst.st_mode & _S_IFMT) | (fmode & ACCESSPERMS)
| (S_ISDIR(fst.st_mode) ? 0700 : 0600);
if (fst.st_mode != mode)
- do_chmod(fname, mode);
+ do_chmod(fname, mode, ST_FLAGS(fst));
- if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode))
+ if (!IS_DEVICE(fst.st_mode))
fst.st_rdev = 0; /* just in case */
--- /dev/null
+From: Matt McCutchen <matt@mattmccutchen.net>
+
+Implement the "m", "o", "g" include modifiers to tweak the permissions,
+owner, or group of matching files.
+
+To use this patch, run these commands for a successful build:
+
+ patch -p1 <patches/filter-attribute-mods.diff
+ ./configure (optional if already run)
+ make
+
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
+diff --git a/exclude.c b/exclude.c
+--- a/exclude.c
++++ b/exclude.c
+@@ -44,8 +44,11 @@ filter_rule_list filter_list = { .debug_type = "" };
+ filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" };
+ filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" };
+
+-/* Need room enough for ":MODS " prefix plus some room to grow. */
+-#define MAX_RULE_PREFIX (16)
++filter_rule *last_hit_filter_rule;
++
++/* Need room enough for ":MODS " prefix, which can now include
++ * chmod/user/group values. */
++#define MAX_RULE_PREFIX (256)
+
+ #define SLASH_WILD3_SUFFIX "/***"
+
+@@ -118,8 +121,27 @@ static void teardown_mergelist(filter_rule *ex)
+ mergelist_cnt--;
+ }
+
++static struct filter_chmod_struct *ref_filter_chmod(struct filter_chmod_struct *chmod)
++{
++ chmod->ref_cnt++;
++ assert(chmod->ref_cnt != 0); /* Catch overflow. */
++ return chmod;
++}
++
++static void unref_filter_chmod(struct filter_chmod_struct *chmod)
++{
++ chmod->ref_cnt--;
++ if (chmod->ref_cnt == 0) {
++ free(chmod->modestr);
++ free_chmod_mode(chmod->modes);
++ free(chmod);
++ }
++}
++
+ static void free_filter(filter_rule *ex)
+ {
++ if (ex->rflags & FILTRULE_CHMOD)
++ unref_filter_chmod(ex->chmod);
+ free(ex->pattern);
+ free(ex);
+ }
+@@ -722,7 +744,8 @@ static void report_filter_result(enum logcode code, char const *name,
+ }
+
+ /* Return -1 if file "name" is defined to be excluded by the specified
+- * exclude list, 1 if it is included, and 0 if it was not matched. */
++ * exclude list, 1 if it is included, and 0 if it was not matched.
++ * Sets last_hit_filter_rule to the filter that was hit, or NULL if none. */
+ int check_filter(filter_rule_list *listp, enum logcode code,
+ const char *name, int name_is_dir)
+ {
+@@ -748,10 +771,12 @@ int check_filter(filter_rule_list *listp, enum logcode code,
+ if (rule_matches(name, ent, name_is_dir)) {
+ report_filter_result(code, name, ent, name_is_dir,
+ listp->debug_type);
++ last_hit_filter_rule = ent;
+ return ent->rflags & FILTRULE_INCLUDE ? 1 : -1;
+ }
+ }
+
++ last_hit_filter_rule = NULL;
+ return 0;
+ }
+
+@@ -768,9 +793,46 @@ static const uchar *rule_strcmp(const uchar *str, const char *rule, int rule_len
+ return NULL;
+ }
+
++static char *grab_paren_value(const uchar **s_ptr)
++{
++ const uchar *start, *end;
++ int val_sz;
++ char *val;
++
++ if ((*s_ptr)[1] != '(')
++ return NULL;
++ start = (*s_ptr) + 2;
++
++ for (end = start; *end != ')'; end++)
++ if (!*end || *end == ' ' || *end == '_')
++ return NULL;
++
++ val_sz = end - start + 1;
++ val = new_array(char, val_sz);
++ strlcpy(val, (const char *)start, val_sz);
++ *s_ptr = end; /* remember ++s in parse_rule_tok */
++ return val;
++}
++
++static struct filter_chmod_struct *make_chmod_struct(char *modestr)
++{
++ struct filter_chmod_struct *chmod;
++ struct chmod_mode_struct *modes = NULL;
++
++ if (!parse_chmod(modestr, &modes))
++ return NULL;
++
++ if (!(chmod = new(struct filter_chmod_struct)))
++ out_of_memory("make_chmod_struct");
++ chmod->ref_cnt = 1;
++ chmod->modestr = modestr;
++ chmod->modes = modes;
++ return chmod;
++}
++
+ #define FILTRULES_FROM_CONTAINER (FILTRULE_ABS_PATH | FILTRULE_INCLUDE \
+ | FILTRULE_DIRECTORY | FILTRULE_NEGATE \
+- | FILTRULE_PERISHABLE)
++ | FILTRULE_PERISHABLE | FILTRULES_ATTRS)
+
+ /* Gets the next include/exclude rule from *rulestr_ptr and advances
+ * *rulestr_ptr to point beyond it. Stores the pattern's start (within
+@@ -785,6 +847,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
+ const char **pat_ptr, unsigned int *pat_len_ptr)
+ {
+ const uchar *s = (const uchar *)*rulestr_ptr;
++ char *val;
+ filter_rule *rule;
+ unsigned int len;
+
+@@ -804,6 +867,12 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
+ /* Inherit from the template. Don't inherit FILTRULES_SIDES; we check
+ * that later. */
+ rule->rflags = template->rflags & FILTRULES_FROM_CONTAINER;
++ if (template->rflags & FILTRULE_CHMOD)
++ rule->chmod = ref_filter_chmod(template->chmod);
++ if (template->rflags & FILTRULE_FORCE_OWNER)
++ rule->force_uid = template->force_uid;
++ if (template->rflags & FILTRULE_FORCE_GROUP)
++ rule->force_gid = template->force_gid;
+
+ /* Figure out what kind of a filter rule "s" is pointing at. Note
+ * that if FILTRULE_NO_PREFIXES is set, the rule is either an include
+@@ -949,11 +1018,63 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
+ goto invalid;
+ rule->rflags |= FILTRULE_EXCLUDE_SELF;
+ break;
++ case 'g': {
++ gid_t gid;
++
++ if (!(val = grab_paren_value(&s)))
++ goto invalid;
++ if (group_to_gid(val, &gid, True)) {
++ rule->rflags |= FILTRULE_FORCE_GROUP;
++ rule->force_gid = gid;
++ } else {
++ rprintf(FERROR,
++ "unknown group '%s' in filter rule: %s\n",
++ val, *rulestr_ptr);
++ exit_cleanup(RERR_SYNTAX);
++ }
++ free(val);
++ break;
++ }
++ case 'm': {
++ struct filter_chmod_struct *chmod;
++
++ if (!(val = grab_paren_value(&s)))
++ goto invalid;
++ if ((chmod = make_chmod_struct(val))) {
++ if (rule->rflags & FILTRULE_CHMOD)
++ unref_filter_chmod(rule->chmod);
++ rule->rflags |= FILTRULE_CHMOD;
++ rule->chmod = chmod;
++ } else {
++ rprintf(FERROR,
++ "unparseable chmod string '%s' in filter rule: %s\n",
++ val, *rulestr_ptr);
++ exit_cleanup(RERR_SYNTAX);
++ }
++ break;
++ }
+ case 'n':
+ if (!(rule->rflags & FILTRULE_MERGE_FILE))
+ goto invalid;
+ rule->rflags |= FILTRULE_NO_INHERIT;
+ break;
++ case 'o': {
++ uid_t uid;
++
++ if (!(val = grab_paren_value(&s)))
++ goto invalid;
++ if (user_to_uid(val, &uid, True)) {
++ rule->rflags |= FILTRULE_FORCE_OWNER;
++ rule->force_uid = uid;
++ } else {
++ rprintf(FERROR,
++ "unknown user '%s' in filter rule: %s\n",
++ val, *rulestr_ptr);
++ exit_cleanup(RERR_SYNTAX);
++ }
++ free(val);
++ break;
++ }
+ case 'p':
+ rule->rflags |= FILTRULE_PERISHABLE;
+ break;
+@@ -1275,6 +1396,23 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
+ else if (am_sender)
+ return NULL;
+ }
++ if (rule->rflags & FILTRULES_ATTRS) {
++ if (!for_xfer || protocol_version >= 31) {
++ if (rule->rflags & FILTRULE_CHMOD)
++ if (!snappendf(&op, (buf + sizeof buf) - op,
++ "m(%s)", rule->chmod->modestr))
++ return NULL;
++ if (rule->rflags & FILTRULE_FORCE_OWNER)
++ if (!snappendf(&op, (buf + sizeof buf) - op,
++ "o(%u)", (unsigned)rule->force_uid))
++ return NULL;
++ if (rule->rflags & FILTRULE_FORCE_GROUP)
++ if (!snappendf(&op, (buf + sizeof buf) - op,
++ "g(%u)", (unsigned)rule->force_gid))
++ return NULL;
++ } else if (!am_sender)
++ return NULL;
++ }
+ if (op - buf > legal_len)
+ return NULL;
+ if (legal_len)
+diff --git a/flist.c b/flist.c
+--- a/flist.c
++++ b/flist.c
+@@ -81,6 +81,7 @@ extern struct chmod_mode_struct *chmod_modes;
+
+ extern filter_rule_list filter_list;
+ extern filter_rule_list daemon_filter_list;
++extern filter_rule *last_hit_filter_rule;
+
+ #ifdef ICONV_OPTION
+ extern int filesfrom_convert;
+@@ -274,7 +275,8 @@ static inline int path_is_daemon_excluded(char *path, int ignore_filename)
+
+ /* This function is used to check if a file should be included/excluded
+ * from the list of files based on its name and type etc. The value of
+- * filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
++ * filter_level is set to either SERVER_FILTERS or ALL_FILTERS.
++ * "last_hit_filter_rule" will be set to the operative filter, or NULL if none. */
+ static int is_excluded(const char *fname, int is_dir, int filter_level)
+ {
+ #if 0 /* This currently never happens, so avoid a useless compare. */
+@@ -283,6 +285,8 @@ static int is_excluded(const char *fname, int is_dir, int filter_level)
+ #endif
+ if (is_daemon_excluded(fname, is_dir))
+ return 1;
++ /* Don't leave a daemon include in last_hit_filter_rule. */
++ last_hit_filter_rule = NULL;
+ if (filter_level != ALL_FILTERS)
+ return 0;
+ if (filter_list.head
+@@ -1142,7 +1146,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+ } else if (readlink_stat(thisname, &st, linkname) != 0) {
+ int save_errno = errno;
+ /* See if file is excluded before reporting an error. */
+- if (filter_level != NO_FILTERS
++ if (filter_level != NO_FILTERS && filter_level != ALL_FILTERS_NO_EXCLUDE
+ && (is_excluded(thisname, 0, filter_level)
+ || is_excluded(thisname, 1, filter_level))) {
+ if (ignore_perishable && save_errno != ENOENT)
+@@ -1187,6 +1191,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+
+ if (filter_level == NO_FILTERS)
+ goto skip_filters;
++ if (filter_level == ALL_FILTERS_NO_EXCLUDE) {
++ /* Call only for the side effect of setting last_hit_filter_rule to
++ * any operative include filter, which might affect attributes. */
++ is_excluded(thisname, S_ISDIR(st.st_mode) != 0, ALL_FILTERS);
++ goto skip_filters;
++ }
+
+ if (S_ISDIR(st.st_mode)) {
+ if (!xfer_dirs) {
+@@ -1377,12 +1387,23 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
+ int flags, int filter_level)
+ {
+ struct file_struct *file;
++ BOOL can_tweak_mode;
+
+ file = make_file(fname, flist, stp, flags, filter_level);
+ if (!file)
+ return NULL;
+
+- if (chmod_modes && !S_ISLNK(file->mode) && file->mode)
++ can_tweak_mode = !S_ISLNK(file->mode) && file->mode;
++ if ((filter_level == ALL_FILTERS || filter_level == ALL_FILTERS_NO_EXCLUDE)
++ && last_hit_filter_rule) {
++ if ((last_hit_filter_rule->rflags & FILTRULE_CHMOD) && can_tweak_mode)
++ file->mode = tweak_mode(file->mode, last_hit_filter_rule->chmod->modes);
++ if ((last_hit_filter_rule->rflags & FILTRULE_FORCE_OWNER) && uid_ndx)
++ F_OWNER(file) = last_hit_filter_rule->force_uid;
++ if ((last_hit_filter_rule->rflags & FILTRULE_FORCE_GROUP) && gid_ndx)
++ F_GROUP(file) = last_hit_filter_rule->force_gid;
++ }
++ if (chmod_modes && can_tweak_mode)
+ file->mode = tweak_mode(file->mode, chmod_modes);
+
+ if (f >= 0) {
+@@ -2239,7 +2260,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+ struct file_struct *file;
+ file = send_file_name(f, flist, fbuf, &st,
+ FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
+- NO_FILTERS);
++ ALL_FILTERS_NO_EXCLUDE);
+ if (!file)
+ continue;
+ if (inc_recurse) {
+@@ -2253,7 +2274,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+ } else
+ send_if_directory(f, flist, file, fbuf, len, flags);
+ } else
+- send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
++ send_file_name(f, flist, fbuf, &st, flags, ALL_FILTERS_NO_EXCLUDE);
+ }
+
+ gettimeofday(&end_tv, NULL);
+diff --git a/rsync.h b/rsync.h
+--- a/rsync.h
++++ b/rsync.h
+@@ -146,6 +146,9 @@
+ #define NO_FILTERS 0
+ #define SERVER_FILTERS 1
+ #define ALL_FILTERS 2
++/* Don't let the file be excluded, but check for a filter that might affect
++ * its attributes via FILTRULES_ATTRS. */
++#define ALL_FILTERS_NO_EXCLUDE 3
+
+ #define XFLG_FATAL_ERRORS (1<<0)
+ #define XFLG_OLD_PREFIXES (1<<1)
+@@ -798,6 +801,8 @@ struct map_struct {
+ int status; /* first errno from read errors */
+ };
+
++struct chmod_mode_struct;
++
+ #define FILTRULE_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
+ #define FILTRULE_WILD2 (1<<1) /* pattern has '**' */
+ #define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
+@@ -818,8 +823,18 @@ struct map_struct {
+ #define FILTRULE_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
+ #define FILTRULE_CLEAR_LIST (1<<18)/* this item is the "!" token */
+ #define FILTRULE_PERISHABLE (1<<19)/* perishable if parent dir goes away */
++#define FILTRULE_CHMOD (1<<20)/* chmod-tweak matching files */
++#define FILTRULE_FORCE_OWNER (1<<21)/* force owner of matching files */
++#define FILTRULE_FORCE_GROUP (1<<22)/* force group of matching files */
+
+ #define FILTRULES_SIDES (FILTRULE_SENDER_SIDE | FILTRULE_RECEIVER_SIDE)
++#define FILTRULES_ATTRS (FILTRULE_CHMOD | FILTRULE_FORCE_OWNER | FILTRULE_FORCE_GROUP)
++
++struct filter_chmod_struct {
++ unsigned int ref_cnt;
++ char *modestr;
++ struct chmod_mode_struct *modes;
++};
+
+ typedef struct filter_struct {
+ struct filter_struct *next;
+@@ -829,6 +844,11 @@ typedef struct filter_struct {
+ int slash_cnt;
+ struct filter_list_struct *mergelist;
+ } u;
++ /* TODO: Use an "extras" mechanism to avoid
++ * allocating this memory when we don't need it. */
++ struct filter_chmod_struct *chmod;
++ uid_t force_uid;
++ gid_t force_gid;
+ } filter_rule;
+
+ typedef struct filter_list_struct {
+diff --git a/rsync.yo b/rsync.yo
+--- a/rsync.yo
++++ b/rsync.yo
+@@ -1028,6 +1028,8 @@ quote(--chmod=Dg+s,ug+w,Fo-w,+X)
+
+ It is also legal to specify multiple bf(--chmod) options, as each
+ additional option is just appended to the list of changes to make.
++To change permissions of files matching a pattern, use an include filter with
++the bf(m) modifier, which takes effect before any bf(--chmod) options.
+
+ See the bf(--perms) and bf(--executability) options for how the resulting
+ permission value can be applied to the files in the transfer.
+@@ -1808,6 +1810,10 @@ be omitted, but if USER is empty, a leading colon must be supplied.
+ If you specify "--chown=foo:bar, this is exactly the same as specifying
+ "--usermap=*:foo --groupmap=*:bar", only easier.
+
++To change ownership of files matching a pattern, use an include filter with
++the bf(o) and bf(g) modifiers, which take effect before uid/gid mapping and
++therefore em(can) be mixed with bf(--usermap) and bf(--groupmap).
++
+ dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum I/O
+ timeout in seconds. If no data is transferred for the specified time
+ then rsync will exit. The default is 0, which means no timeout.
+@@ -2620,6 +2626,15 @@ itemization(
+ option's default rules that exclude things like "CVS" and "*.o" are
+ marked as perishable, and will not prevent a directory that was removed
+ on the source from being deleted on the destination.
++ it() An bf(m+nop()(CHMOD)) on an include rule tweaks the permissions of matching
++ source files in the same way as bf(--chmod). This happens before any
++ tweaks requested via bf(--chmod) options.
++ it() An bf(o+nop()(USER)) on an include rule pretends that matching source files
++ are owned by bf(USER) (a name or numeric uid). This happens before any uid
++ mapping by name or bf(--usermap).
++ it() A bf(g+nop()(GROUP)) on an include rule pretends that matching source files
++ are owned by bf(GROUP) (a name or numeric gid). This happens before any gid
++ mapping by name or bf(--groupmap).
+ )
+
+ manpagesection(MERGE-FILE FILTER RULES)
+@@ -2681,6 +2696,12 @@ itemization(
+ a rule prefix such as bf(hide)).
+ )
+
++The attribute-affecting modifiers bf(m), bf(o), and bf(g) work only in client
++filters (not in daemon filters), and only the modifiers of the first matching
++rule are applied. As an example, assuming bf(--super) is enabled, the
++rule "+o+nop()(root)g+nop()(root)m+nop()(go=) *~" would ensure that all "backup" files belong to
++root and are not accessible to anyone else.
++
+ Per-directory rules are inherited in all subdirectories of the directory
+ where the merge-file was found unless the 'n' modifier was used. Each
+ subdirectory's rules are prefixed to the inherited per-directory rules
+diff --git a/util.c b/util.c
+--- a/util.c
++++ b/util.c
+@@ -840,6 +840,25 @@ size_t stringjoin(char *dest, size_t destsize, ...)
+ return ret;
+ }
+
++/* Append formatted text at *dest_ptr up to a maximum of sz (like snprintf).
++ * On success, advance *dest_ptr and return True; on overflow, return False. */
++BOOL snappendf(char **dest_ptr, size_t sz, const char *format, ...)
++{
++ va_list ap;
++ size_t len;
++
++ va_start(ap, format);
++ len = vsnprintf(*dest_ptr, sz, format, ap);
++ va_end(ap);
++
++ if (len >= sz)
++ return False;
++ else {
++ *dest_ptr += len;
++ return True;
++ }
++}
++
+ int count_dir_elements(const char *p)
+ {
+ int cnt = 0, new_component = 1;
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/options.c b/options.c
-index e7c6c61..44ad60e 100644
--- a/options.c
+++ b/options.c
@@ -48,6 +48,7 @@ int append_mode = 0;
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -2555,6 +2558,9 @@ void server_options(char **args, int *argc_p)
+@@ -2572,6 +2575,9 @@ void server_options(char **args, int *argc_p)
args[ac++] = tmpdir;
}
/* the server only needs this option if it is not the sender,
* and it may be an older version that doesn't know this
diff --git a/receiver.c b/receiver.c
-index 4325e30..1523977 100644
--- a/receiver.c
+++ b/receiver.c
@@ -38,6 +38,7 @@ extern int relative_paths;
unmap_file(mapbuf);
diff --git a/t_stub.c b/t_stub.c
-index 02cfa69..fb61480 100644
--- a/t_stub.c
+++ b/t_stub.c
@@ -21,6 +21,7 @@
int module_id = -1;
int relative_paths = 0;
diff --git a/util.c b/util.c
-index 0cafed6..88b3521 100644
--- a/util.c
+++ b/util.c
@@ -27,6 +27,7 @@
extern int modify_window;
extern int relative_paths;
extern int preserve_xattrs;
-@@ -334,6 +335,13 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -374,6 +375,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
full_fname(source));
}
- Make this code handle multibyte character encodings, and honor the
--iconv setting when converting case.
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/exclude.c b/exclude.c
-index 5fa6e00..5b3b135 100644
--- a/exclude.c
+++ b/exclude.c
@@ -21,6 +21,7 @@
extern int am_server;
extern int am_sender;
-@@ -697,16 +698,15 @@ static int rule_matches(const char *fname, struct filter_struct *ex, int name_is
+@@ -687,16 +688,15 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_is_dir)
if (litmatch_array(pattern, strings, slash_handling))
return ret_match;
} else if (anchored_match) {
return !ret_match;
diff --git a/flist.c b/flist.c
-index 09b4fc5..ae70300 100644
--- a/flist.c
+++ b/flist.c
@@ -34,6 +34,7 @@ extern int am_generator;
extern int ignore_errors;
extern int numeric_ids;
extern int recurse;
-@@ -2924,6 +2925,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -2934,6 +2935,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
{
int dif;
const uchar *c1, *c2;
enum fnc_state state1, state2;
enum fnc_type type1, type2;
enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM;
-@@ -3034,7 +3036,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -3044,7 +3046,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
if (type1 != type2)
return type1 == t_PATH ? 1 : -1;
}
return dif;
}
diff --git a/ifuncs.h b/ifuncs.h
-index 8c128d5..a4cfd3d 100644
--- a/ifuncs.h
+++ b/ifuncs.h
@@ -77,3 +77,38 @@ init_stat_x(stat_x *sx_p)
+#define ic_strNE(s1,s2) (!ic_strEQ(s1,s2))
+#define ic_strnNE(s1,s2) (!ic_strnEQ(s1,s2,n))
diff --git a/lib/wildmatch.c b/lib/wildmatch.c
-index f3a1731..72660ca 100644
--- a/lib/wildmatch.c
+++ b/lib/wildmatch.c
@@ -53,6 +53,8 @@
}
diff --git a/options.c b/options.c
-index e7c6c61..6e73e9c 100644
--- a/options.c
+++ b/options.c
@@ -117,6 +117,7 @@ OFF_T max_size = 0;
{"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
{"from0", '0', POPT_ARG_VAL, &eol_nulls, 1, 0, 0},
{"no-from0", 0, POPT_ARG_VAL, &eol_nulls, 0, 0, 0},
-@@ -2505,6 +2509,9 @@ void server_options(char **args, int *argc_p)
+@@ -2522,6 +2526,9 @@ void server_options(char **args, int *argc_p)
args[ac++] = arg;
}
if (partial_dir != tmp_partialdir) {
args[ac++] = "--partial-dir";
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..339aca8 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -414,6 +414,7 @@ to the detailed description below for a complete description. verb(
--address=ADDRESS bind address for outgoing socket to daemon
--port=PORT specify double-colon alternate port number
--sockopts=OPTIONS specify custom TCP options
-@@ -1563,6 +1564,10 @@ If you use this option with bf(--iconv), the args will also be translated
+@@ -1582,6 +1583,10 @@ If you use this option with bf(--iconv), the args will also be translated
from the local to the remote character-set. The translation happens before
wild-cards are expanded. See also the bf(--files-from) option.
scratch directory when creating temporary copies of the files transferred
on the receiving side. The default behavior is to create each temporary
diff --git a/wildtest.c b/wildtest.c
-index 07351a1..c899eb8 100644
--- a/wildtest.c
+++ b/wildtest.c
@@ -30,6 +30,7 @@
./configure
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/Makefile.in b/Makefile.in
-index feacb90..b27b1e7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,7 +37,7 @@ OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
diff --git a/flist.c b/flist.c
-index 09b4fc5..570bcee 100644
--- a/flist.c
+++ b/flist.c
@@ -73,6 +73,7 @@ extern int sender_keeps_checksum;
extern char *usermap, *groupmap;
extern char curr_dir[MAXPATHLEN];
-@@ -881,7 +882,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -891,7 +892,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
extra_len += EXTRA_LEN;
#endif
#if SIZEOF_INT64 >= 8
diff --git a/hashlink.c b/hashlink.c
new file mode 100644
-index 0000000..15e2a73
--- /dev/null
+++ b/hashlink.c
@@ -0,0 +1,339 @@
+}
+#endif
diff --git a/options.c b/options.c
-index e7c6c61..73b1aa4 100644
--- a/options.c
+++ b/options.c
@@ -158,6 +158,7 @@ char *backup_suffix = NULL;
{"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 },
{"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
-@@ -1742,6 +1745,21 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1743,6 +1746,21 @@ int parse_arguments(int *argc_p, const char ***argv_p)
return 0;
#endif
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -2584,6 +2602,11 @@ void server_options(char **args, int *argc_p)
+@@ -2601,6 +2619,11 @@ void server_options(char **args, int *argc_p)
} else if (inplace)
args[ac++] = "--inplace";
if (filesfrom_host) {
args[ac++] = "--files-from";
diff --git a/receiver.c b/receiver.c
-index 4325e30..2709d5e 100644
--- a/receiver.c
+++ b/receiver.c
@@ -164,11 +164,13 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
log_item(log_code, file, &initial_stats, iflags, NULL);
diff --git a/rsync.c b/rsync.c
-index 2c026a2..87f6d54 100644
--- a/rsync.c
+++ b/rsync.c
@@ -48,6 +48,7 @@ extern int flist_eof;
rsyserr(FERROR_XFER, errno, "%s %s -> \"%s\"",
ret == -2 ? "copy" : "rename",
diff --git a/rsync.h b/rsync.h
-index be7cf8a..d4e2aca 100644
--- a/rsync.h
+++ b/rsync.h
-@@ -853,6 +853,14 @@ struct stats {
+@@ -854,6 +854,14 @@ struct stats {
int xferred_files;
};
struct flist_ndx_item {
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..568b481 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -400,6 +400,7 @@ to the detailed description below for a complete description. verb(
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/clientserver.c b/clientserver.c
-index b6afe00..568a121 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -67,6 +67,7 @@ extern iconv_t ic_send, ic_recv;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
-@@ -649,7 +651,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -643,7 +645,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
log_init(1);
#ifdef HAVE_PUTENV
char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
-@@ -738,6 +740,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -732,6 +734,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
set_blocking(fds[1]);
pre_exec_fd = fds[1];
}
umask(0);
}
#endif
-@@ -965,6 +1005,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -959,6 +999,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
return 0;
}
with "list = False". */
static void send_listing(int fd)
diff --git a/loadparm.c b/loadparm.c
-index 8e48e6d..c623689 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -121,6 +121,7 @@ typedef struct {
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
-index d4978cd..fd0f7d9 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -163,10 +163,11 @@ if the module is not read-only).
the daemon will use the value of the "charset" parameter regardless of the
diff --git a/support/nameconvert b/support/nameconvert
new file mode 100755
-index 0000000..d01f593
--- /dev/null
+++ b/support/nameconvert
@@ -0,0 +1,42 @@
+ print $ans, $eol;
+}
diff --git a/t_stub.c b/t_stub.c
-index 02cfa69..eaaf8a9 100644
--- a/t_stub.c
+++ b/t_stub.c
@@ -30,6 +30,7 @@ mode_t orig_umask = 002;
char *partial_dir;
char *module_dir;
+pid_t namecvt_pid;
- struct filter_list_struct daemon_filter_list;
+ filter_rule_list daemon_filter_list;
void rprintf(UNUSED(enum logcode code), const char *format, ...)
-@@ -75,6 +76,11 @@ struct filter_list_struct daemon_filter_list;
+@@ -70,6 +71,11 @@ filter_rule_list daemon_filter_list;
return -1;
}
{
return NULL;
diff --git a/uidlist.c b/uidlist.c
-index 7e8cbd7..472aeb9 100644
--- a/uidlist.c
+++ b/uidlist.c
@@ -33,6 +33,7 @@ extern int preserve_uid;
return NULL;
}
diff --git a/util.c b/util.c
-index 0cafed6..dc1647b 100644
--- a/util.c
+++ b/util.c
@@ -31,9 +31,10 @@ extern int modify_window;
extern char *partial_dir;
+extern pid_t namecvt_pid;
+extern unsigned int module_dirlen;
- extern struct filter_list_struct daemon_filter_list;
+ extern filter_rule_list daemon_filter_list;
int sanitize_paths = 0;
-@@ -497,24 +498,44 @@ void kill_all(int sig)
- /** Turn a user name into a uid */
- int name_to_uid(const char *name, uid_t *uid_p)
+@@ -537,32 +538,54 @@ void kill_all(int sig)
+ /* Parse a user name or (optionally) a number into a uid */
+ int user_to_uid(const char *name, uid_t *uid_p, BOOL num_ok)
{
- struct passwd *pass;
+ uid_t uid;
+
if (!name || !*name)
return 0;
++
+ if (num_ok && name[strspn(name, "0123456789")] == '\0') {
+ *uid_p = atol(name);
+ return 1;
+ }
- if (!(pass = getpwnam(name)))
- return 0;
- *uid_p = pass->pw_uid;
return 1;
}
- /** Turn a group name into a gid */
- int name_to_gid(const char *name, gid_t *gid_p)
+ /* Parse a group name or (optionally) a number into a gid */
+ int group_to_gid(const char *name, gid_t *gid_p, BOOL num_ok)
{
- struct group *grp;
+ gid_t gid;
+
if (!name || !*name)
return 0;
++
+ if (num_ok && name[strspn(name, "0123456789")] == '\0') {
+ *gid_p = atol(name);
+ return 1;
+ }
- if (!(grp = getgrnam(name)))
- return 0;
- *gid_p = grp->gr_gid;
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/access.c b/access.c
-index 9a023de..c6d9f3c 100644
--- a/access.c
+++ b/access.c
@@ -19,11 +19,14 @@
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/generator.c b/generator.c
-index 12007a1..29c9297 100644
--- a/generator.c
+++ b/generator.c
@@ -44,6 +44,7 @@ extern int preserve_hard_links;
dflt_perms, statret == 0);
}
diff --git a/options.c b/options.c
-index e7c6c61..03588fd 100644
--- a/options.c
+++ b/options.c
@@ -59,6 +59,7 @@ int preserve_specials = 0;
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
{"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 },
{"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 },
-@@ -2020,6 +2023,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
- parse_rule(&filter_list, backup_dir_buf, 0, 0);
+@@ -2037,6 +2040,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+ parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
}
+ if (omit_dir_changes)
if (make_backups && !backup_dir) {
omit_dir_times = 0; /* Implied, so avoid -O to sender. */
if (preserve_times > 1)
-@@ -2263,6 +2268,8 @@ void server_options(char **args, int *argc_p)
+@@ -2280,6 +2285,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'm';
if (omit_dir_times)
argstr[x++] = 'O';
if (copy_links)
argstr[x++] = 'L';
diff --git a/rsync.c b/rsync.c
-index 2c026a2..caf3204 100644
--- a/rsync.c
+++ b/rsync.c
@@ -33,6 +33,7 @@ extern int preserve_xattrs;
if (S_ISLNK(sxp->st.st_mode)) {
;
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..9aef20a 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -356,6 +356,7 @@ to the detailed description below for a complete description. verb(
--super receiver attempts super-user activities
--fake-super store/recover privileged attrs using xattrs
-S, --sparse handle sparse files efficiently
-@@ -1071,6 +1072,10 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
+@@ -1078,6 +1079,10 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
the directories on the receiving side, it is a good idea to use bf(-O).
This option is inferred if you use bf(--backup) without bf(--backup-dir).
./configure
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/Makefile.in b/Makefile.in
-index feacb90..3016643 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -41,7 +41,7 @@ OBJS3=progress.o pipe.o
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
diff --git a/cleanup.c b/cleanup.c
-index 19ef072..506f575 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -25,6 +25,9 @@
#include "case_N.h"
diff --git a/clientserver.c b/clientserver.c
-index b6afe00..5467c72 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -30,6 +30,9 @@ extern int am_sender;
return -1;
}
-@@ -1022,6 +1069,9 @@ int start_daemon(int f_in, int f_out)
+@@ -1016,6 +1063,9 @@ int start_daemon(int f_in, int f_out)
if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0)
return -1;
line[0] = 0;
if (!read_line_old(f_in, line, sizeof line))
return -1;
-@@ -1033,6 +1083,20 @@ int start_daemon(int f_in, int f_out)
+@@ -1027,6 +1077,20 @@ int start_daemon(int f_in, int f_out)
return -1;
}
/* it's some sort of command that I don't understand */
io_printf(f_out, "@ERROR: Unknown command '%s'\n", line);
diff --git a/configure.in b/configure.in
-index bc7d4a7..73ca6c5 100644
--- a/configure.in
+++ b/configure.in
@@ -293,6 +293,21 @@ if test x"$enable_locale" != x"no"; then
case $host_os in
*cygwin* ) AC_MSG_RESULT(yes)
diff --git a/options.c b/options.c
-index e7c6c61..634b89e 100644
--- a/options.c
+++ b/options.c
@@ -191,6 +191,14 @@ int logfile_format_has_o_or_i = 0;
*argv_p = argv = poptGetArgs(pc);
*argc_p = argc = count_args(argv);
am_starting_up = 0;
-@@ -1742,6 +1799,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1743,6 +1800,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
return 0;
#endif
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -2108,6 +2171,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2125,6 +2188,17 @@ int parse_arguments(int *argc_p, const char ***argv_p)
if (delay_updates && !partial_dir)
partial_dir = tmp_partialdir;
if (inplace) {
#ifdef HAVE_FTRUNCATE
if (partial_dir) {
-@@ -2698,9 +2772,18 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
+@@ -2715,9 +2789,18 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
{
char *path;
*port_ptr = RSYNC_PORT;
return path;
diff --git a/rsync.h b/rsync.h
-index be7cf8a..7b7cc88 100644
--- a/rsync.h
+++ b/rsync.h
@@ -31,6 +31,7 @@
#define SYMLINK_PREFIX "/rsyncd-munged/" /* This MUST have a trailing slash! */
#define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1)
-@@ -569,6 +570,11 @@ typedef unsigned int size_t;
+@@ -573,6 +574,11 @@ typedef unsigned int size_t;
# define SIZEOF_INT64 SIZEOF_OFF_T
#endif
int32 size, entries;
diff --git a/ssl.c b/ssl.c
new file mode 100644
-index 0000000..f0d4d9f
--- /dev/null
+++ b/ssl.c
@@ -0,0 +1,369 @@
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/flist.c b/flist.c
-index 09b4fc5..a948194 100644
--- a/flist.c
+++ b/flist.c
-@@ -1466,6 +1466,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
+@@ -1476,6 +1476,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
io_error |= IOERR_GENERAL;
return NULL;
diff --git a/xattrs.c b/xattrs.c
-index 2d0e050..3c70d8a 100644
--- a/xattrs.c
+++ b/xattrs.c
-@@ -282,6 +282,10 @@ int get_xattr(const char *fname, stat_x *sxp)
+@@ -284,6 +284,10 @@ int get_xattr(const char *fname, stat_x *sxp)
{
sxp->xattr = new(item_list);
*sxp->xattr = empty_xattr;
if (rsync_xal_get(fname, sxp->xattr) < 0) {
free_xattr(sxp);
return -1;
-@@ -865,6 +869,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
+@@ -884,6 +888,11 @@ int set_xattr(const char *fname, const struct file_struct *file,
return -1;
}
./configure
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/compat.c b/compat.c
-index 6e00072..c9590cc 100644
--- a/compat.c
+++ b/compat.c
@@ -32,6 +32,7 @@ extern int inplace;
if (append_mode == 1)
append_mode = 2;
diff --git a/configure.in b/configure.in
-index bc7d4a7..61f9b05 100644
--- a/configure.in
+++ b/configure.in
@@ -553,13 +553,40 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
if test $ac_cv_func_getpgrp = yes; then
AC_FUNC_GETPGRP
diff --git a/options.c b/options.c
-index e7c6c61..6f848f1 100644
--- a/options.c
+++ b/options.c
@@ -73,6 +73,7 @@ int remove_source_files = 0;
{"inplace", 0, POPT_ARG_VAL, &inplace, 1, 0, 0 },
{"no-inplace", 0, POPT_ARG_VAL, &inplace, 0, 0, 0 },
{"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 },
-@@ -2609,6 +2618,9 @@ void server_options(char **args, int *argc_p)
+@@ -2626,6 +2635,9 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
rprintf(FERROR, "argc overflow in server_options().\n");
exit_cleanup(RERR_MALLOC);
diff --git a/receiver.c b/receiver.c
-index 4325e30..739a0ba 100644
--- a/receiver.c
+++ b/receiver.c
@@ -44,6 +44,7 @@ extern int cleanup_got_literal;
full_fname(fname));
}
diff --git a/rsync.h b/rsync.h
-index be7cf8a..0ad3075 100644
--- a/rsync.h
+++ b/rsync.h
-@@ -634,6 +634,13 @@ struct ht_int64_node {
+@@ -638,6 +638,13 @@ struct ht_int64_node {
#define ACLS_NEED_MASK 1
#endif
int32 num;
uint32 unum;
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..36a2077 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -359,6 +359,7 @@ to the detailed description below for a complete description. verb(
-n, --dry-run perform a trial run with no changes made
-W, --whole-file copy files whole (w/o delta-xfer algorithm)
-x, --one-file-system don't cross filesystem boundaries
-@@ -1120,6 +1121,18 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
+@@ -1127,6 +1128,18 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
make any changes (and produces mostly the same output as a real run). It
is most commonly used in combination with the bf(-v, --verbose) and/or
diff --git a/syscall.c b/syscall.c
-index cfabc3e..81fb957 100644
--- a/syscall.c
+++ b/syscall.c
@@ -29,6 +29,10 @@
+}
+#endif
diff --git a/t_stub.c b/t_stub.c
-index 02cfa69..52a7f02 100644
--- a/t_stub.c
+++ b/t_stub.c
@@ -22,6 +22,7 @@
int relative_paths = 0;
int module_dirlen = 0;
diff --git a/util.c b/util.c
-index 0cafed6..20dd0d3 100644
--- a/util.c
+++ b/util.c
@@ -26,6 +26,7 @@
extern int module_id;
extern int modify_window;
extern int relative_paths;
-@@ -276,6 +277,10 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -324,6 +325,10 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
int ifd;
char buf[1024 * 8];
int len; /* Number of bytes read into `buf'. */
if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
int save_errno = errno;
-@@ -309,7 +314,27 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -349,7 +354,27 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
}
}
if (full_write(ofd, buf, len) < 0) {
int save_errno = errno;
rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
-@@ -334,6 +359,16 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -374,6 +399,16 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
full_fname(source));
}
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/flist.c b/flist.c
-index 09b4fc5..a8847a2 100644
--- a/flist.c
+++ b/flist.c
@@ -71,6 +71,7 @@ extern int sender_symlink_iconv;
extern struct stats stats;
extern char *filesfrom_host;
extern char *usermap, *groupmap;
-@@ -1704,6 +1705,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1714,6 +1715,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
}
send_file_name(f, flist, fbuf, NULL, flags, filter_level);
fbuf[len] = '\0';
diff --git a/options.c b/options.c
-index e7c6c61..762a167 100644
--- a/options.c
+++ b/options.c
@@ -108,6 +108,7 @@ int size_only = 0;
TODO: the configure changes should abort if the user requests --enable-slp
and we can't honor that request.
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/Makefile.in b/Makefile.in
-index feacb90..09e1547 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -13,6 +13,8 @@ CFLAGS=@CFLAGS@
$(OBJS): $(HEADERS)
$(CHECK_OBJS): $(HEADERS)
diff --git a/clientserver.c b/clientserver.c
-index b6afe00..a242809 100644
--- a/clientserver.c
+++ b/clientserver.c
-@@ -1153,6 +1153,13 @@ int daemon_main(void)
+@@ -1147,6 +1147,13 @@ int daemon_main(void)
* address too. In fact, why not just do inet_ntop on the
* local address??? */
return -1;
}
diff --git a/configure.in b/configure.in
-index bc7d4a7..f8dc177 100644
--- a/configure.in
+++ b/configure.in
@@ -647,6 +647,29 @@ if test $rsync_cv_can_hardlink_special = yes; then
AC_TRY_RUN([
#include <sys/types.h>
diff --git a/loadparm.c b/loadparm.c
-index 8e48e6d..a833006 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -97,6 +97,9 @@ typedef struct {
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_charset, charset)
diff --git a/main.c b/main.c
-index 2ef2f47..3535264 100644
--- a/main.c
+++ b/main.c
-@@ -1195,6 +1195,18 @@ static int start_client(int argc, char *argv[])
+@@ -1207,6 +1207,18 @@ static int start_client(int argc, char *argv[])
if (!read_batch) { /* for read_batch, NO source is specified */
char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
char *dummy_host;
int dummy_port = 0;
diff --git a/options.c b/options.c
-index e7c6c61..dae5716 100644
--- a/options.c
+++ b/options.c
@@ -566,6 +566,7 @@ static void print_rsync_version(enum logcode f)
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
diff --git a/rsync.h b/rsync.h
-index be7cf8a..8353124 100644
--- a/rsync.h
+++ b/rsync.h
@@ -194,6 +194,10 @@
#define CFN_KEEP_TRAILING_SLASH (1<<1)
#define CFN_DROP_TRAILING_DOT_DIR (1<<2)
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..1518b3f 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -148,7 +148,12 @@ particular rsync daemon by leaving off the module name:
diff --git a/rsyncd.conf b/rsyncd.conf
new file mode 100644
-index 0000000..971723f
--- /dev/null
+++ b/rsyncd.conf
@@ -0,0 +1,3 @@
+slp refresh = 300
+
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
-index d4978cd..318f0ec 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -108,6 +108,15 @@ details on some of the options you may be able to set. By default no
[ftp]
path = /var/ftp/./pub
diff --git a/socket.c b/socket.c
-index 5df3a50..a4a2b0a 100644
--- a/socket.c
+++ b/socket.c
@@ -530,6 +530,16 @@ void start_accept_loop(int port, int (*fn)(int, int))
for (i = 0, fd = -1; sp[i] >= 0; i++) {
diff --git a/srvloc.c b/srvloc.c
new file mode 100644
-index 0000000..99eea16
--- /dev/null
+++ b/srvloc.c
@@ -0,0 +1,103 @@
+}
diff --git a/srvreg.c b/srvreg.c
new file mode 100644
-index 0000000..04afe60
--- /dev/null
+++ b/srvreg.c
@@ -0,0 +1,128 @@
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/syscall.c b/syscall.c
-index cfabc3e..fbbd79e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -63,9 +63,14 @@ int do_symlink(const char *fname1, const char *fname2)
-- Matt McCutchen <hashproduct@gmail.com>
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/options.c b/options.c
-index e7c6c61..77fb180 100644
--- a/options.c
+++ b/options.c
-@@ -33,6 +33,7 @@ extern struct filter_list_struct filter_list;
- extern struct filter_list_struct daemon_filter_list;
+@@ -33,6 +33,7 @@ extern filter_rule_list filter_list;
+ extern filter_rule_list daemon_filter_list;
int make_backups = 0;
+int make_source_backups = 0;
{"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 },
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
{"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
-@@ -2484,6 +2487,8 @@ void server_options(char **args, int *argc_p)
+@@ -2501,6 +2504,8 @@ void server_options(char **args, int *argc_p)
goto oom;
args[ac++] = arg;
}
/* --delete-missing-args needs the cooperation of both sides, but
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..4080af2 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -368,6 +368,7 @@ to the detailed description below for a complete description. verb(
--del an alias for --delete-during
--delete delete extraneous files from dest dirs
--delete-before receiver deletes before xfer, not during
-@@ -1182,6 +1183,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
+@@ -1197,6 +1198,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
side the files (meaning non-directories) that are a part of the transfer
and have been successfully duplicated on the receiving side.
receiving side (ones that aren't on the sending side), but only for the
directories that are being synchronized. You must have asked rsync to
diff --git a/sender.c b/sender.c
-index bf8221d..102540c 100644
--- a/sender.c
+++ b/sender.c
-@@ -39,6 +39,7 @@ extern int protocol_version;
+@@ -38,6 +38,7 @@ extern int protocol_version;
extern int remove_source_files;
extern int updating_basis_file;
extern int make_backups;
extern int inplace;
extern int batch_fd;
extern int write_batch;
-@@ -122,6 +123,7 @@ void successful_send(int ndx)
+@@ -121,6 +122,7 @@ void successful_send(int ndx)
char fname[MAXPATHLEN];
struct file_struct *file;
struct file_list *flist;
if (!remove_source_files)
return;
-@@ -132,7 +134,11 @@ void successful_send(int ndx)
+@@ -131,7 +133,11 @@ void successful_send(int ndx)
return;
f_name(file, fname);
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/generator.c b/generator.c
-index 12007a1..88bd5e7 100644
--- a/generator.c
+++ b/generator.c
@@ -64,6 +64,7 @@ extern int append_mode;
/* if always checksum is set then we use the checksum instead
diff --git a/main.c b/main.c
-index 2ef2f47..e7b4a05 100644
--- a/main.c
+++ b/main.c
-@@ -140,7 +140,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
+@@ -142,7 +142,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
}
/* Wait for a process to exit, calling io_flush while waiting. */
pid_t waited_pid;
int status;
diff --git a/options.c b/options.c
-index e7c6c61..059bcbf 100644
--- a/options.c
+++ b/options.c
@@ -105,6 +105,7 @@ int safe_symlinks = 0;
{"remote-option", 'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
-@@ -2149,6 +2158,16 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2166,6 +2175,16 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
}
if (files_from) {
char *h, *p;
int q;
-@@ -2493,6 +2512,25 @@ void server_options(char **args, int *argc_p)
+@@ -2510,6 +2529,25 @@ void server_options(char **args, int *argc_p)
else if (missing_args == 1 && !am_sender)
args[ac++] = "--ignore-missing-args";
if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
goto oom;
diff --git a/pipe.c b/pipe.c
-index a33117c..43eea31 100644
--- a/pipe.c
+++ b/pipe.c
@@ -180,3 +180,77 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
+ return pid;
+}
diff --git a/receiver.c b/receiver.c
-index 4325e30..e5ede73 100644
--- a/receiver.c
+++ b/receiver.c
@@ -52,6 +52,7 @@ extern int delay_updates;
if (partialptr == fname)
partialptr = NULL;
diff --git a/rsync.h b/rsync.h
-index be7cf8a..8d78818 100644
--- a/rsync.h
+++ b/rsync.h
@@ -138,6 +138,7 @@
#define MAX_SERVER_ARGS (MAX_BASIS_DIRS*2 + 100)
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..edfad5e 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -394,6 +394,7 @@ to the detailed description below for a complete description. verb(
--protocol=NUM force an older protocol version to be used
--iconv=CONVERT_SPEC request charset conversion of filenames
--checksum-seed=NUM set block/file checksum seed (advanced)
-@@ -2256,6 +2259,33 @@ file previously generated by bf(--write-batch).
+@@ -2283,6 +2286,33 @@ file previously generated by bf(--write-batch).
If em(FILE) is bf(-), the batch data will be read from standard input.
See the "BATCH MODE" section for details.
is useful for creating a batch file that is compatible with an older
version of rsync. For instance, if rsync 2.6.4 is being used with the
diff --git a/sender.c b/sender.c
-index bf8221d..f315f80 100644
--- a/sender.c
+++ b/sender.c
-@@ -42,6 +42,7 @@ extern int make_backups;
+@@ -41,6 +41,7 @@ extern int make_backups;
extern int inplace;
extern int batch_fd;
extern int write_batch;
extern struct stats stats;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
-@@ -174,6 +175,26 @@ void send_files(int f_in, int f_out)
+@@ -173,6 +174,26 @@ void send_files(int f_in, int f_out)
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int ndx, j;
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "send_files starting\n");
-@@ -299,6 +320,7 @@ void send_files(int f_in, int f_out)
+@@ -298,6 +319,7 @@ void send_files(int f_in, int f_out)
exit_cleanup(RERR_PROTOCOL);
}
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
if (errno == ENOENT) {
-@@ -320,6 +342,33 @@ void send_files(int f_in, int f_out)
+@@ -319,6 +341,33 @@ void send_files(int f_in, int f_out)
continue;
}
/* map the local file */
if (do_fstat(fd, &st) != 0) {
io_error |= IOERR_GENERAL;
-@@ -370,6 +419,8 @@ void send_files(int f_in, int f_out)
+@@ -369,6 +418,8 @@ void send_files(int f_in, int f_out)
}
}
close(fd);
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/fileio.c b/fileio.c
-index 0faa619..b76dc02 100644
--- a/fileio.c
+++ b/fileio.c
@@ -27,6 +27,7 @@
} else {
if (!wf_writeBuf) {
diff --git a/options.c b/options.c
-index e7c6c61..a0fb2e7 100644
--- a/options.c
+++ b/options.c
@@ -73,6 +73,7 @@ int remove_source_files = 0;
{"inplace", 0, POPT_ARG_VAL, &inplace, 1, 0, 0 },
{"no-inplace", 0, POPT_ARG_VAL, &inplace, 0, 0, 0 },
{"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 },
-@@ -2416,6 +2419,12 @@ void server_options(char **args, int *argc_p)
+@@ -2433,6 +2436,12 @@ void server_options(char **args, int *argc_p)
args[ac++] = arg;
}
if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
goto oom;
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..5fa8396 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -359,6 +359,7 @@ to the detailed description below for a complete description. verb(
-n, --dry-run perform a trial run with no changes made
-W, --whole-file copy files whole (w/o delta-xfer algorithm)
-x, --one-file-system don't cross filesystem boundaries
-@@ -1120,6 +1121,15 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
+@@ -1127,6 +1128,15 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/options.c b/options.c
-index e7c6c61..e0e0cda 100644
--- a/options.c
+++ b/options.c
@@ -300,6 +300,7 @@ static int refused_partial, refused_progress, refused_delete_before;
{"remote-option", 'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
-@@ -1757,6 +1760,13 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1758,6 +1761,13 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
}
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/io.c b/io.c
-index 6a89c8f..d248f0f 100644
--- a/io.c
+++ b/io.c
@@ -53,6 +53,7 @@ extern int protocol_version;
if (!am_server && !am_daemon) {
rprintf(FERROR, "io timeout after %d seconds -- exiting\n",
diff --git a/options.c b/options.c
-index e7c6c61..6e72c02 100644
--- a/options.c
+++ b/options.c
@@ -112,6 +112,7 @@ size_t bwlimit_writemax = 0;
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -1742,6 +1747,36 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1743,6 +1748,36 @@ int parse_arguments(int *argc_p, const char ***argv_p)
return 0;
#endif
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -2428,6 +2463,15 @@ void server_options(char **args, int *argc_p)
+@@ -2445,6 +2480,15 @@ void server_options(char **args, int *argc_p)
args[ac++] = arg;
}
args[ac++] = "--backup-dir";
args[ac++] = backup_dir;
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..6945d06 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -431,6 +431,8 @@ to the detailed description below for a complete description. verb(
--write-batch=FILE write a batched update to FILE
--only-write-batch=FILE like --write-batch but w/o updating dest
--read-batch=FILE read a batched update from FILE
-@@ -2230,6 +2232,19 @@ transfer was too fast, it will wait before sending the next data block. The
+@@ -2257,6 +2259,19 @@ transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equaling the specified limit. A value
of zero specifies no limit.
another identical destination with bf(--read-batch). See the "BATCH MODE"
section for details, and also the bf(--only-write-batch) option.
diff --git a/util.c b/util.c
-index 0cafed6..f3e2669 100644
--- a/util.c
+++ b/util.c
@@ -123,6 +123,133 @@ NORETURN void overflow_exit(const char *str)
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/flist.c b/flist.c
-index 09b4fc5..f69167e 100644
--- a/flist.c
+++ b/flist.c
@@ -87,6 +87,9 @@ extern int filesfrom_convert;
#define PTR_SIZE (sizeof (struct file_struct *))
int io_error;
-@@ -651,6 +654,24 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
+@@ -661,6 +664,24 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
stats.total_size += F_LENGTH(file);
}
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
-@@ -719,6 +740,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -729,6 +750,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
#endif
clean_fname(thisname, 0);
diff --git a/options.c b/options.c
-index e7c6c61..cd0891c 100644
--- a/options.c
+++ b/options.c
@@ -190,6 +190,8 @@ int logfile_format_has_i = 0;
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
{"8-bit-output", '8', POPT_ARG_VAL, &allow_8bit_chars, 1, 0, 0 },
-@@ -2195,6 +2199,31 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2212,6 +2216,31 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
}
am_starting_up = 0;
return 1;
-@@ -2609,6 +2638,12 @@ void server_options(char **args, int *argc_p)
+@@ -2626,6 +2655,12 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
rprintf(FERROR, "argc overflow in server_options().\n");
exit_cleanup(RERR_MALLOC);
diff --git a/rsync.yo b/rsync.yo
-index 941f7a5..dda8608 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -436,6 +436,7 @@ to the detailed description below for a complete description. verb(
--checksum-seed=NUM set block/file checksum seed (advanced)
-4, --ipv4 prefer IPv4
-6, --ipv6 prefer IPv6
-@@ -2294,6 +2295,22 @@ daemon uses the charset specified in its "charset" configuration parameter
+@@ -2321,6 +2322,22 @@ daemon uses the charset specified in its "charset" configuration parameter
regardless of the remote charset you actually pass. Thus, you may feel free to
specify just the local charset for a daemon transfer (e.g. bf(--iconv=utf8)).
./configure (optional if already run)
make
+based-on: 181c9faf928faad08ef095f4667afe460ec3bef6
diff --git a/syscall.c b/syscall.c
-index cfabc3e..c6deb7e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -23,6 +23,7 @@
./configure (optional if already run)
make
+based-on: patch/acls
diff --git a/compat.c b/compat.c
-index 1b66069..fb46fa5 100644
--- a/compat.c
+++ b/compat.c
@@ -189,13 +189,6 @@ void setup_protocol(int f_out,int f_in)
if (delete_mode && !(delete_before+delete_during+delete_after)) {
diff --git a/xattrs.c b/xattrs.c
-index 2d0e050..b2017ed 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -22,6 +22,7 @@
#define RSYNC_XAL_INITIAL 5
#define RSYNC_XAL_LIST_INITIAL 100
-@@ -247,7 +249,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
+@@ -249,7 +251,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
return -1;
/* For large datums, we store a flag and a checksum. */
name_offset = 1 + MAX_DIGEST_LEN;
sum_init(checksum_seed);
-@@ -349,7 +351,7 @@ static int find_matching_xattr(item_list *xalp)
+@@ -351,7 +353,7 @@ static int find_matching_xattr(item_list *xalp)
|| rxas1[j].datum_len != rxas2[j].datum_len
|| strcmp(rxas1[j].name, rxas2[j].name))
break;
if (memcmp(rxas1[j].datum + 1,
rxas2[j].datum + 1,
MAX_DIGEST_LEN) != 0)
-@@ -386,13 +388,22 @@ int send_xattr(stat_x *sxp, int f)
+@@ -388,13 +390,22 @@ int send_xattr(stat_x *sxp, int f)
{
int ndx = find_matching_xattr(sxp->xattr);
for (rxa = sxp->xattr->items; count--; rxa++) {
size_t name_len = rxa->name_len;
const char *name = rxa->name;
-@@ -411,8 +422,8 @@ int send_xattr(stat_x *sxp, int f)
+@@ -413,8 +424,8 @@ int send_xattr(stat_x *sxp, int f)
name_len += UPRE_LEN;
}
#endif
#ifndef HAVE_LINUX_XATTRS
if (name_len > rxa->name_len) {
write_buf(f, USER_PREFIX, UPRE_LEN);
-@@ -420,7 +431,7 @@ int send_xattr(stat_x *sxp, int f)
+@@ -422,7 +433,7 @@ int send_xattr(stat_x *sxp, int f)
}
#endif
write_buf(f, name, name_len);
write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
else
write_buf(f, rxa->datum, rxa->datum_len);
-@@ -470,7 +481,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
+@@ -472,7 +483,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
if (cmp > 0)
same = 0;
same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
&& memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
MAX_DIGEST_LEN) == 0;
-@@ -515,6 +526,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
+@@ -517,6 +528,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
int cnt, prior_req = 0;
rsync_xa *rxa;
lst += F_XATTR(file);
for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
if (rxa->datum_len <= MAX_FULL_DATUM)
-@@ -571,6 +585,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
+@@ -573,6 +587,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
rsync_xa *rxa;
int rel_pos, cnt, num, got_xattr_data = 0;
if (F_XATTR(file) < 0) {
rprintf(FERROR, "recv_xattr_request: internal data error!\n");
exit_cleanup(RERR_STREAMIO);
-@@ -633,7 +650,22 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -635,7 +652,22 @@ void receive_xattr(struct file_struct *file, int f)
#else
int need_sort = 1;
#endif
if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
rprintf(FERROR, "receive_xattr: xa index %d out of"
-@@ -646,7 +678,7 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -648,7 +680,7 @@ void receive_xattr(struct file_struct *file, int f)
return;
}
(void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
temp_xattr.count = 0;
}
-@@ -654,9 +686,10 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -656,9 +688,10 @@ void receive_xattr(struct file_struct *file, int f)
for (num = 1; num <= count; num++) {
char *ptr, *name;
rsync_xa *rxa;