--- old/Makefile.in
+++ new/Makefile.in
-@@ -31,7 +31,7 @@ LIBOBJ=lib/wildmatch.o lib/compat.o lib/
+@@ -32,7 +32,7 @@ LIBOBJ=lib/wildmatch.o lib/compat.o lib/
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
#ifdef HAVE_PUTENV
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
-@@ -628,6 +631,9 @@ static int rsync_module(int f_in, int f_
+@@ -629,6 +632,9 @@ static int rsync_module(int f_in, int f_
rprintf(FLOG, "rsync %s %s from %s@%s (%s)\n",
am_sender ? "on" : "to",
request, auth_user, host, addr);
am_sender ? "on" : "to",
--- old/configure.in
+++ new/configure.in
-@@ -577,6 +577,12 @@ if test x"$with_included_popt" != x"yes"
+@@ -610,6 +610,12 @@ if test x"$with_included_popt" != x"yes"
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
fi
FN_LOCAL_BOOL(lp_list, list)
--- old/log.c
+++ new/log.c
-@@ -92,7 +92,7 @@ struct {
+@@ -94,7 +94,7 @@ struct {
/*
* Map from rsync error code to name, or return NULL.
*/
for (i = 0; rerr_names[i].name; i++) {
--- old/receiver.c
+++ new/receiver.c
-@@ -109,6 +109,10 @@ static int get_tmpname(char *fnametmp, c
+@@ -111,6 +111,10 @@ static int get_tmpname(char *fnametmp, c
if (maxname < 1) {
rprintf(FERROR, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
}
-@@ -170,6 +174,10 @@ static int receive_data(int f_in, char *
+@@ -172,6 +176,10 @@ static int receive_data(int f_in, char *
if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f",
full_fname(fname), (double)j, (double)offset);
exit_cleanup(RERR_FILEIO);
}
}
-@@ -227,6 +235,11 @@ static int receive_data(int f_in, char *
+@@ -229,6 +237,11 @@ static int receive_data(int f_in, char *
"lseek of %s returned %.0f, not %.0f",
full_fname(fname),
(double)pos, (double)offset);
exit_cleanup(RERR_FILEIO);
}
continue;
-@@ -252,6 +265,9 @@ static int receive_data(int f_in, char *
+@@ -254,6 +267,9 @@ static int receive_data(int f_in, char *
report_write_error:
rsyserr(FERROR, errno, "write failed on %s",
full_fname(fname));
exit_cleanup(RERR_FILEIO);
}
-@@ -295,6 +311,12 @@ static void handle_delayed_updates(struc
+@@ -297,6 +313,12 @@ static void handle_delayed_updates(struc
rsyserr(FERROR, errno,
"rename failed for %s (from %s)",
full_fname(fname), partialptr);
+ partialptr);
+#endif
} else {
- if (remove_sent_files
+ if (remove_source_files
|| (preserve_hard_links
-@@ -417,6 +439,9 @@ int recv_files(int f_in, struct file_lis
+@@ -421,6 +443,9 @@ int recv_files(int f_in, struct file_lis
if (server_filter_list.head
&& check_filter(&server_filter_list, fname, 0) < 0) {
rprintf(FERROR, "attempt to hack rsync failed.\n");
exit_cleanup(RERR_PROTOCOL);
}
-@@ -471,6 +496,11 @@ int recv_files(int f_in, struct file_lis
+@@ -477,6 +502,11 @@ int recv_files(int f_in, struct file_lis
rprintf(FERROR,
"invalid basis_dir index: %d.\n",
fnamecmp_type);
exit_cleanup(RERR_PROTOCOL);
}
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
-@@ -516,6 +546,9 @@ int recv_files(int f_in, struct file_lis
+@@ -522,6 +552,9 @@ int recv_files(int f_in, struct file_lis
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
rsyserr(FERROR, errno, "fstat %s failed",
full_fname(fnamecmp));
discard_receive_data(f_in, file->length);
close(fd1);
continue;
-@@ -529,6 +562,9 @@ int recv_files(int f_in, struct file_lis
+@@ -535,6 +568,9 @@ int recv_files(int f_in, struct file_lis
*/
rprintf(FERROR,"recv_files: %s is a directory\n",
full_fname(fnamecmp));
discard_receive_data(f_in, file->length);
close(fd1);
continue;
-@@ -552,6 +588,9 @@ int recv_files(int f_in, struct file_lis
+@@ -558,6 +594,9 @@ int recv_files(int f_in, struct file_lis
if (fd2 == -1) {
rsyserr(FERROR, errno, "open %s failed",
full_fname(fname));
discard_receive_data(f_in, file->length);
if (fd1 != -1)
close(fd1);
-@@ -585,6 +624,10 @@ int recv_files(int f_in, struct file_lis
+@@ -591,6 +630,10 @@ int recv_files(int f_in, struct file_lis
if (fd2 == -1) {
rsyserr(FERROR, errno, "mkstemp %s failed",
full_fname(fnametmp));
discard_receive_data(f_in, file->length);
if (fd1 != -1)
close(fd1);
-@@ -605,12 +648,19 @@ int recv_files(int f_in, struct file_lis
+@@ -611,12 +654,19 @@ int recv_files(int f_in, struct file_lis
fname, fd2, file->length);
log_item(log_code, file, &initial_stats, iflags, NULL);
exit_cleanup(RERR_FILEIO);
}
-@@ -669,6 +719,12 @@ int recv_files(int f_in, struct file_lis
+@@ -675,6 +725,12 @@ int recv_files(int f_in, struct file_lis
rprintf(msgtype,
"%s: %s failed verification -- update %s%s.\n",
errstr, fname, keptstr, redostr);
SIVAL(numbuf, 0, i);
--- old/sender.c
+++ new/sender.c
-@@ -353,6 +353,9 @@ void send_files(struct file_list *flist,
+@@ -355,6 +355,9 @@ void send_files(struct file_list *flist,
end_progress(st.st_size);
log_item(log_code, file, &initial_stats, iflags, NULL);
char *dn = file->dirname ? file->dirname : ".";
if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
if (relative_paths && !implied_dirs
-- && safe_stat(dn, &st) < 0
-+ && safe_stat(dn, &sx.st) < 0
+- && do_stat(dn, &st) < 0
++ && do_stat(dn, &sx.st) < 0
&& create_directory_path(fname) < 0) {
rsyserr(FERROR, errno,
"recv_generator: mkdir %s failed",
char *tmpdir = NULL;
char *partial_dir = NULL;
char *basis_dir[MAX_BASIS_DIRS+1];
-@@ -151,7 +155,9 @@ char *log_format = NULL;
+@@ -153,7 +157,9 @@ char *stdout_format = NULL;
char *password_file = NULL;
char *rsync_path = RSYNC_PATH;
char *backup_dir = NULL;
char *sockopts = NULL;
int rsync_port = 0;
int compare_dest = 0;
-@@ -282,6 +288,8 @@ void usage(enum logcode F)
+@@ -290,6 +296,8 @@ void usage(enum logcode F)
rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
rprintf(F," -u, --update skip files that are newer on the receiver\n");
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," --append append data onto shorter files\n");
-@@ -499,7 +507,9 @@ static struct poptOption long_options[]
+@@ -514,7 +522,9 @@ static struct poptOption long_options[]
{"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
{"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
{"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 },
-@@ -1219,6 +1229,10 @@ int parse_arguments(int *argc, const cha
+@@ -1225,6 +1235,8 @@ int parse_arguments(int *argc, const cha
+ tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, NULL);
+ if (backup_dir)
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, NULL);
- die_on_unsafe_path(backup_dir, 0);
- }
-+ if (backup_dir_dels) {
++ if (backup_dir_dels)
+ backup_dir_dels = sanitize_path(NULL, backup_dir_dels, NULL, 0, NULL);
-+ die_on_unsafe_path(backup_dir_dels, 0);
-+ }
}
if (server_filter_list.head && !am_sender) {
struct filter_list_struct *elp = &server_filter_list;
-@@ -1240,6 +1254,14 @@ int parse_arguments(int *argc, const cha
+@@ -1246,6 +1258,14 @@ int parse_arguments(int *argc, const cha
return 0;
}
}
}
if (!backup_suffix)
-@@ -1251,6 +1273,16 @@ int parse_arguments(int *argc, const cha
+@@ -1257,6 +1277,16 @@ int parse_arguments(int *argc, const cha
backup_suffix);
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;
-@@ -1274,6 +1306,31 @@ int parse_arguments(int *argc, const cha
+@@ -1280,6 +1310,31 @@ int parse_arguments(int *argc, const cha
"P *%s", backup_suffix);
parse_rule(&filter_list, backup_dir_buf, 0, 0);
}
if (make_backups && !backup_dir)
omit_dir_times = 1;
-@@ -1618,6 +1675,10 @@ void server_options(char **args,int *arg
+@@ -1639,6 +1694,10 @@ void server_options(char **args,int *arg
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) {
-@@ -1626,7 +1687,13 @@ void server_options(char **args,int *arg
+@@ -1647,7 +1706,13 @@ void server_options(char **args,int *arg
goto oom;
args[ac++] = arg;
}
extern int module_id;
extern int ignore_errors;
extern int numeric_ids;
-@@ -691,6 +692,16 @@ static struct file_struct *receive_file_
+@@ -693,6 +694,16 @@ static struct file_struct *receive_file_
sum = empty_sum;
}
read_buf(f, sum, checksum_len);
extern int checksum_len;
extern char *partial_dir;
extern char *basis_dir[];
-@@ -375,7 +376,8 @@ void itemize(struct file_struct *file, i
+@@ -376,7 +377,8 @@ void itemize(struct file_struct *file, i
/* Perform our quick-check heuristic for determining if a file is unchanged. */
{
if (st->st_size != file->length)
return 0;
-@@ -384,6 +386,8 @@ int unchanged_file(char *fn, struct file
+@@ -385,6 +387,8 @@ int unchanged_file(char *fn, struct file
of the file time to determine whether to sync */
if (always_checksum && S_ISREG(st->st_mode)) {
char sum[MD4_SUM_LENGTH];
file_checksum(fn, sum, st->st_size);
return memcmp(sum, file->u.sum, checksum_len) == 0;
}
-@@ -626,7 +630,7 @@ static int try_dests_reg(struct file_str
+@@ -622,7 +626,7 @@ static int try_dests_reg(struct file_str
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 2;
-@@ -1201,7 +1205,7 @@ static void recv_generator(char *fname,
+@@ -1210,7 +1214,7 @@ static void recv_generator(char *fname,
;
else if (fnamecmp_type == FNAMECMP_FUZZY)
;
handle_partial_dir(partialptr, PDIR_DELETE);
--- old/hlink.c
+++ new/hlink.c
-@@ -212,7 +212,7 @@ int hard_link_check(struct file_struct *
+@@ -220,7 +220,7 @@ int hard_link_check(struct file_struct *
itemizing = code = 0;
break;
}
extern int recurse;
extern int relative_paths;
extern int sanitize_paths;
-@@ -69,6 +70,9 @@ extern char *shell_cmd;
- extern char *batch_name;
+@@ -71,6 +72,9 @@ extern char *batch_name;
+ extern char curr_dir[MAXPATHLEN];
extern struct filter_list_struct server_filter_list;
+extern char curr_dir[MAXPATHLEN];
+
+int pre_checksum = 0;
int local_server = 0;
+ int new_root_dir = 0;
mode_t orig_umask = 0;
- struct file_list *the_file_list;
-@@ -751,6 +755,7 @@ static void do_server_recv(int f_in, int
+@@ -784,6 +788,7 @@ static void do_server_recv(int f_in, int
struct file_list *flist;
char *local_name = NULL;
char *dir = NULL;
int save_verbose = verbose;
if (filesfrom_fd >= 0) {
-@@ -794,6 +799,10 @@ static void do_server_recv(int f_in, int
+@@ -827,6 +832,10 @@ static void do_server_recv(int f_in, int
filesfrom_fd = -1;
}
flist = recv_file_list(f_in);
verbose = save_verbose;
if (!flist) {
-@@ -802,6 +811,9 @@ static void do_server_recv(int f_in, int
+@@ -835,6 +844,9 @@ static void do_server_recv(int f_in, int
}
the_file_list = flist;
if (argc > 0)
local_name = get_local_name(flist,argv[0]);
-@@ -885,6 +897,7 @@ int client_run(int f_in, int f_out, pid_
+@@ -916,6 +928,7 @@ int client_run(int f_in, int f_out, pid_
{
struct file_list *flist = NULL;
int exit_code = 0, exit_code2 = 0;
char *local_name = NULL;
cleanup_child_pid = pid;
-@@ -959,11 +972,18 @@ int client_run(int f_in, int f_out, pid_
+@@ -990,11 +1003,18 @@ int client_run(int f_in, int f_out, pid_
filesfrom_fd = -1;
}
--- old/generator.c
+++ new/generator.c
-@@ -61,6 +61,7 @@ extern int append_mode;
+@@ -60,6 +60,7 @@ extern int append_mode;
extern int make_backups;
extern int csum_length;
extern int ignore_times;
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -376,7 +377,7 @@ void itemize(struct file_struct *file, i
+@@ -378,7 +379,7 @@ void itemize(struct file_struct *file, i
/* Perform our quick-check heuristic for determining if a file is unchanged. */
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
{
/* if always checksum is set then we use the checksum instead
--- old/main.c
+++ new/main.c
-@@ -119,7 +119,7 @@ pid_t wait_process(pid_t pid, int *statu
+@@ -122,7 +122,7 @@ pid_t wait_process(pid_t pid, int *statu
}
/* Wait for a process to exit, calling io_flush while waiting. */
char *rsync_path = RSYNC_PATH;
char *backup_dir = NULL;
char backup_dir_buf[MAXPATHLEN];
-@@ -337,6 +340,7 @@ void usage(enum logcode F)
+@@ -341,6 +344,7 @@ void usage(enum logcode F)
rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
rprintf(F," --size-only skip files that match in size\n");
rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
-@@ -374,6 +378,8 @@ void usage(enum logcode F)
+@@ -378,6 +382,8 @@ void usage(enum logcode F)
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
rprintf(F," --protocol=NUM force an older protocol version to be used\n");
#ifdef INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
-@@ -454,6 +460,7 @@ static struct poptOption long_options[]
+@@ -459,6 +465,7 @@ static struct poptOption long_options[]
{"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
{"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
{"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
-@@ -531,6 +538,8 @@ static struct poptOption long_options[]
+@@ -537,6 +544,8 @@ static struct poptOption long_options[]
{"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
{"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
{"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 },
-@@ -1409,6 +1418,16 @@ int parse_arguments(int *argc, const cha
+@@ -1403,6 +1412,16 @@ int parse_arguments(int *argc, const cha
}
}
if (files_from) {
char *h, *p;
int q;
-@@ -1675,6 +1694,25 @@ void server_options(char **args,int *arg
+@@ -1669,6 +1688,25 @@ void server_options(char **args,int *arg
args[ac++] = "--size-only";
}
extern char *stdout_format;
extern char *tmpdir;
extern char *partial_dir;
-@@ -348,6 +349,8 @@ int recv_files(int f_in, struct file_lis
+@@ -350,6 +351,8 @@ int recv_files(int f_in, struct file_lis
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int max_phase = protocol_version >= 29 ? 2 : 1;
int i, recv_ok;
if (verbose > 2)
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
-@@ -360,6 +363,23 @@ int recv_files(int f_in, struct file_lis
- if (delay_updates)
- delayed_bits = bitbag_create(flist->count);
+@@ -364,6 +367,23 @@ int recv_files(int f_in, struct file_lis
+
+ updating_basis = inplace;
+ if (dest_filter) {
+ char *p;
while (1) {
cleanup_disable();
-@@ -600,6 +620,9 @@ int recv_files(int f_in, struct file_lis
+@@ -606,6 +626,9 @@ int recv_files(int f_in, struct file_lis
else if (!am_server && verbose && do_progress)
rprintf(FINFO, "%s\n", fname);
/* recv file data */
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
fname, fd2, file->length);
-@@ -614,6 +637,16 @@ int recv_files(int f_in, struct file_lis
+@@ -620,6 +643,16 @@ int recv_files(int f_in, struct file_lis
exit_cleanup(RERR_FILEIO);
}
if (partialptr == fname)
--- old/rsync.h
+++ new/rsync.h
-@@ -103,6 +103,7 @@
+@@ -104,6 +104,7 @@
#define IOERR_DEL_LIMIT (1<<2)
#define MAX_ARGS 1000
--protocol=NUM force an older protocol version to be used
--checksum-seed=NUM set block/file checksum seed (advanced)
-4, --ipv4 prefer IPv4
-@@ -1733,6 +1736,33 @@ file previously generated by bf(--write-
+@@ -1753,6 +1756,33 @@ file previously generated by bf(--write-
If em(FILE) is bf(-), the batch data will be read from standard input.
See the "BATCH MODE" section for details.
extern char *stdout_format;
-@@ -222,6 +223,26 @@ void send_files(struct file_list *flist,
+@@ -224,6 +225,26 @@ void send_files(struct file_list *flist,
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int i, j;
if (verbose > 2)
rprintf(FINFO, "send_files starting\n");
-@@ -295,6 +316,7 @@ void send_files(struct file_list *flist,
+@@ -297,6 +318,7 @@ void send_files(struct file_list *flist,
return;
}
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
if (errno == ENOENT) {
-@@ -323,6 +345,33 @@ void send_files(struct file_list *flist,
+@@ -325,6 +347,33 @@ void send_files(struct file_list *flist,
return;
}
if (st.st_size) {
int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
mbuf = map_file(fd, st.st_size, read_size, s->blength);
-@@ -364,6 +413,8 @@ void send_files(struct file_list *flist,
+@@ -366,6 +415,8 @@ void send_files(struct file_list *flist,
}
}
close(fd);