./configure (optional if already run)
make
-based-on: 5eda68f11bf6efe782cca60a2415191f4532c3b5
+based-on: 0327a2526b8f3e6c050e4541805b8b702ba5d7ce
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -45,6 +45,8 @@ extern int numeric_ids;
+@@ -44,6 +44,8 @@ extern int numeric_ids;
extern int filesfrom_fd;
extern int remote_protocol;
extern int protocol_version;
extern int io_timeout;
extern int no_detach;
extern int write_batch;
-@@ -1038,6 +1040,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -1033,6 +1035,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;
extern int checksum_type;
extern int module_id;
extern int ignore_errors;
-@@ -61,6 +63,7 @@ extern int implied_dirs;
+@@ -62,6 +64,7 @@ extern int implied_dirs;
extern int ignore_perishable;
extern int non_perishable_cnt;
extern int prune_empty_dirs;
extern int copy_links;
extern int copy_unsafe_links;
extern int protocol_version;
-@@ -72,6 +75,7 @@ extern int sender_symlink_iconv;
+@@ -73,6 +76,7 @@ extern int sender_symlink_iconv;
extern int output_needs_newline;
extern int sender_keeps_checksum;
extern int unsort_ndx;
extern uid_t our_uid;
extern struct stats stats;
extern char *filesfrom_host;
-@@ -89,6 +93,20 @@ extern int filesfrom_convert;
+@@ -90,6 +94,20 @@ extern int filesfrom_convert;
extern iconv_t ic_send, ic_recv;
#endif
#define PTR_SIZE (sizeof (struct file_struct *))
int io_error;
-@@ -133,8 +151,12 @@ static char empty_sum[MAX_DIGEST_LEN];
+@@ -134,8 +152,12 @@ static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static int show_filelist_progress;
static void output_flist(struct file_list *flist);
void init_flist(void)
-@@ -323,6 +345,235 @@ static void flist_done_allocating(struct file_list *flist)
+@@ -324,6 +346,235 @@ static void flist_done_allocating(struct file_list *flist)
flist->pool_boundary = ptr;
}
/* 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
-@@ -1159,7 +1410,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1200,7 +1451,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];
-@@ -1305,9 +1556,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1346,9 +1597,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
-@@ -1325,11 +1583,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1366,11 +1624,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))
-@@ -1414,8 +1669,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1459,8 +1714,14 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
return NULL;
}
if (unsort_ndx)
F_NDX(file) = stats.num_dirs;
-@@ -2627,7 +2888,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
+@@ -2672,7 +2933,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
/* The --relative option sends paths with a leading slash, so we need
* to specify the strip_root option here. We rejected leading slashes
* for a non-relative transfer in recv_file_entry(). */
if (protocol_version < 30) {
/* Recv the io_error flag */
-@@ -2872,7 +3133,7 @@ void flist_free(struct file_list *flist)
+@@ -2917,7 +3178,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;
-@@ -2923,7 +3184,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2968,7 +3229,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;
-@@ -2939,8 +3200,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2984,8 +3245,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);
-@@ -2962,7 +3223,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -3007,7 +3268,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
}
flist->high = prev_i;
extern int remove_source_files;
extern int delay_updates;
extern int update_only;
-@@ -580,7 +581,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -601,7 +602,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
{
if (st->st_size != F_LENGTH(file))
return 0;
-@@ -589,7 +590,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -610,7 +611,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
of the file time to determine whether to sync */
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
return memcmp(sum, F_SUM(file), flist_csum_len) == 0;
}
-@@ -886,7 +890,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -907,7 +911,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
best_match = j;
match_level = 1;
}
continue;
if (match_level == 1) {
best_match = j;
-@@ -1197,7 +1201,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1220,7 +1224,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
* --ignore-non-existing, daemon exclude, or mkdir failure. */
static struct file_struct *skip_dir = NULL;
static struct file_list *fuzzy_dirlist[MAX_BASIS_DIRS+1];
struct file_struct *fuzzy_file = NULL;
int fd = -1, f_copy = -1;
stat_x sx, real_sx;
-@@ -1308,8 +1312,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1337,8 +1341,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fuzzy_dirlist[i] = NULL;
}
}
#ifdef SUPPORT_ACLS
if (!preserve_perms)
dflt_perms = default_perms_for_dir(dn);
-@@ -1317,6 +1322,24 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1346,6 +1351,24 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
parent_dirname = dn;
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
stat_errno = errno;
}
-@@ -1720,22 +1743,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1749,22 +1772,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
partialptr = NULL;
if (statret != 0 && fuzzy_basis) {
/* Sets fnamecmp_type to FNAMECMP_FUZZY or above. */
fuzzy_file = find_fuzzy(file, fuzzy_dirlist, &fnamecmp_type);
if (fuzzy_file) {
-@@ -1768,7 +1775,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1797,7 +1804,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
;
else if (fnamecmp_type >= FNAMECMP_FUZZY)
;
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -119,6 +119,7 @@ size_t bwlimit_writemax = 0;
+@@ -120,6 +120,7 @@ size_t bwlimit_writemax = 0;
int ignore_existing = 0;
int ignore_non_existing = 0;
int need_messages_from_generator = 0;
int max_delete = INT_MIN;
OFF_T max_size = -1;
OFF_T min_size = -1;
-@@ -783,7 +784,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -794,7 +795,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE,
-- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
-+ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_SUMFILES,
+- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR,
++ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_SUMFILES,
OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS,
OPT_STOP_AFTER, OPT_STOP_AT,
OPT_REFUSED_BASE = 9000};
-@@ -935,6 +936,7 @@ static struct poptOption long_options[] = {
+@@ -950,6 +951,7 @@ static struct poptOption long_options[] = {
{"no-c", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 },
{"checksum-choice", 0, POPT_ARG_STRING, &checksum_choice, 0, 0, 0 },
{"cc", 0, POPT_ARG_STRING, &checksum_choice, 0, 0, 0 },
{"block-size", 'B', POPT_ARG_STRING, 0, OPT_BLOCK_SIZE, 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 },
-@@ -1935,6 +1937,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1955,6 +1957,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);
-@@ -2247,6 +2266,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2285,6 +2304,9 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
#endif
--archive, -a archive mode; equals -rlptgoD (no -H,-A,-X)
--no-OPTION turn off an implied OPTION (e.g. --no-D)
--recursive, -r recurse into directories
-@@ -683,6 +684,8 @@ your home directory (remove the '=' for that).
+@@ -698,6 +699,8 @@ your home directory (remove the '=' for that).
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 _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
-@@ -693,6 +696,38 @@ your home directory (remove the '=' for that).
+@@ -708,6 +711,38 @@ your home directory (remove the '=' for that).
can be overridden using either the `--checksum-choice` (`--cc`) option or an
environment variable that is discussed in that option's section.
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -870,6 +870,10 @@ extern int xattrs_ndx;
+@@ -878,6 +878,10 @@ extern int xattrs_ndx;
#define F_SUM(f) ((char*)OPT_EXTRA(f, START_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)
-@@ -1082,6 +1086,13 @@ typedef struct {
+@@ -1090,6 +1094,13 @@ typedef struct {
#define RELNAMECACHE_LEN (offsetof(relnamecache, fname))
#endif
extern int am_root;
extern int am_server;
extern int am_daemon;
-@@ -109,6 +110,9 @@ extern iconv_t ic_send, ic_recv;
+@@ -110,6 +111,9 @@ extern iconv_t ic_send, ic_recv;
#define PTR_SIZE (sizeof (struct file_struct *))
int io_error;
int flist_csum_len;
dev_t filesystem_dev; /* used to implement -x */
-@@ -151,8 +155,13 @@ static char empty_sum[MAX_DIGEST_LEN];
+@@ -152,8 +156,13 @@ static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static int show_filelist_progress;
} *csum_cache = NULL;
static struct file_list *flist_new(int flags, const char *msg);
-@@ -345,7 +354,79 @@ static void flist_done_allocating(struct file_list *flist)
+@@ -346,7 +355,79 @@ static void flist_done_allocating(struct file_list *flist)
flist->pool_boundary = ptr;
}
{
int slot, slots = am_sender ? 1 : basis_dir_cnt + 1;
-@@ -356,6 +437,9 @@ void reset_checksum_cache()
+@@ -357,6 +438,9 @@ void reset_checksum_cache()
struct file_list *flist = csum_cache[slot].flist;
if (flist) {
/* Reset the pool memory and empty the file-list array. */
pool_free_old(flist->file_pool,
pool_boundary(flist->file_pool, 0));
-@@ -366,6 +450,10 @@ void reset_checksum_cache()
+@@ -367,6 +451,10 @@ void reset_checksum_cache()
flist->low = 0;
flist->high = -1;
flist->next = NULL;
}
}
-@@ -373,7 +461,7 @@ void reset_checksum_cache()
+@@ -374,7 +462,7 @@ void reset_checksum_cache()
static int add_checksum(struct file_list *flist, const char *dirname,
const char *basename, int basename_len, OFF_T file_length,
time_t mtime, uint32 ctime, uint32 inode,
{
struct file_struct *file;
int alloc_len, extra_len;
-@@ -390,7 +478,7 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -391,7 +479,7 @@ static int add_checksum(struct file_list *flist, const char *dirname,
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
#endif
bp = pool_alloc(flist->file_pool, alloc_len, "add_checksum");
memset(bp, 0, extra_len + FILE_STRUCT_LEN);
-@@ -399,7 +487,14 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -400,7 +488,14 @@ static int add_checksum(struct file_list *flist, const char *dirname,
bp += FILE_STRUCT_LEN;
memcpy(bp, basename, basename_len);
file->mode = S_IFREG;
file->modtime = mtime;
file->len32 = (uint32)file_length;
-@@ -428,10 +523,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -429,10 +524,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
char line[MAXPATHLEN+1024], fbuf[MAXPATHLEN], sum[MAX_DIGEST_LEN];
FILE *fp;
char *cp;
int dlen = dirname ? strlcpy(fbuf, dirname, sizeof fbuf) : 0;
if (dlen >= (int)(sizeof fbuf - 1 - RSYNCSUMS_LEN))
-@@ -452,7 +548,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -453,7 +549,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
while (fgets(line, sizeof line, fp)) {
cp = line;
if (checksum_type == 5) {
if (*cp == '=')
while (*++cp == '=') {}
else
-@@ -463,7 +559,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -464,7 +560,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
}
if (*cp == '=') {
} else {
for (i = 0; i < flist_csum_len*2; i++, cp++) {
int x;
-@@ -481,13 +584,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -482,13 +585,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
else
sum[i/2] = x << 4;
}
if (*cp == '=')
while (*++cp == '=') {}
else
-@@ -537,24 +641,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -538,24 +642,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
continue;
strlcpy(fbuf+dlen, cp, sizeof fbuf - dlen);
read_checksums(slot, flist, file->dirname);
}
-@@ -566,12 +758,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file,
+@@ -567,12 +759,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file,
&& (checksum_files & CSF_LAX
|| (F_CTIME(fp) == (uint32)stp->st_ctime
&& F_INODE(fp) == (uint32)stp->st_ino))) {
}
/* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
-@@ -1511,6 +1722,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1552,6 +1763,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;
}
-@@ -1557,13 +1770,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1598,13 +1811,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' */
-@@ -1671,7 +1884,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1716,7 +1929,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, tmp_sum);
if (sender_keeps_checksum)
-@@ -2063,6 +2276,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -2108,6 +2321,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". */
-@@ -2726,6 +2942,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2771,6 +2987,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
}
static const char *solo_file = NULL;
enum nonregtype {
-@@ -591,7 +592,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
+@@ -612,7 +613,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
if (checksum_files && slot >= 0)
else
file_checksum(fn, st, sum);
return memcmp(sum, F_SUM(file), flist_csum_len) == 0;
-@@ -1335,7 +1336,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1364,7 +1365,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
}
if (checksum_files) {
}
need_new_dirscan = 0;
}
-@@ -1506,6 +1508,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1535,6 +1537,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
else
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
}
prior_dir_file = file;
goto cleanup;
}
-@@ -1781,6 +1784,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1810,6 +1813,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 | maybe_ATTRS_ACCURATE_TIME);
if (itemizing)
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
#ifdef SUPPORT_HARD_LINKS
-@@ -2277,6 +2282,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2306,6 +2311,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];
-@@ -2371,6 +2377,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2400,6 +2406,9 @@ void generate_files(int f_out, const char *local_name)
wait_for_receiver();
}
extern int protect_args;
extern int checksum_seed;
+extern int checksum_files;
+ extern int daemon_connection;
extern int protocol_version;
extern int remove_source_files;
- extern int preserve_hard_links;
-@@ -1061,6 +1062,9 @@ static void got_flist_entry_status(enum festatus status, int ndx)
+@@ -1066,6 +1067,9 @@ static void got_flist_entry_status(enum festatus status, int ndx)
if (inc_recurse)
flist->in_progress++;
}
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -1939,7 +1939,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1959,7 +1959,15 @@ int parse_arguments(int *argc_p, const char ***argv_p)
case OPT_SUMFILES:
arg = poptGetOptArg(pc);
diff --git a/rsync.1.md b/rsync.1.md
--- a/rsync.1.md
+++ b/rsync.1.md
-@@ -707,9 +707,13 @@ your home directory (remove the '=' for that).
+@@ -722,9 +722,13 @@ your home directory (remove the '=' for that).
The MODE value is either "lax", for relaxed checking (which compares size
and mtime), "strict" (which also compares ctime and inode), or "none" to
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -1088,6 +1088,8 @@ typedef struct {
+@@ -1096,6 +1096,8 @@ typedef struct {
#define CSF_ENABLE (1<<1)
#define CSF_LAX (1<<2)
./configure (optional if already run)
make
-based-on: af531cf787995f6a3bc381cd1da1988192e7ef59
+based-on: 0327a2526b8f3e6c050e4541805b8b702ba5d7ce
diff --git a/Makefile.in b/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -892,7 +892,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -913,7 +913,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
best_match = j;
match_level = 2;
}
best_match = j;
match_level = 3;
break;
-@@ -932,7 +932,12 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -953,7 +953,12 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
}
} else
#endif
if (itemizing)
itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL);
}
-@@ -1088,7 +1093,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1109,7 +1114,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
if (match_level == 3) {
#ifdef SUPPORT_HARD_LINKS
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -783,7 +783,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -794,7 +794,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE,
-- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
-+ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_CLONE_DEST,
+- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR,
++ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_CLONE_DEST,
OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS,
OPT_STOP_AFTER, OPT_STOP_AT,
OPT_REFUSED_BASE = 9000};
-@@ -939,6 +939,7 @@ static struct poptOption long_options[] = {
+@@ -954,6 +954,7 @@ static struct poptOption long_options[] = {
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
{"fuzzy", 'y', POPT_ARG_NONE, 0, 'y', 0, 0 },
{"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
-@@ -1202,6 +1203,9 @@ static void set_refuse_options(void)
+@@ -1219,6 +1220,9 @@ static void set_refuse_options(void)
#ifndef SUPPORT_HARD_LINKS
parse_one_refuse_match(0, "link-dest", list_end);
#endif
#ifndef HAVE_MKTIME
parse_one_refuse_match(0, "stop-at", list_end);
#endif
-@@ -1528,6 +1532,8 @@ char *alt_dest_opt(int type)
+@@ -1548,6 +1552,8 @@ char *alt_dest_opt(int type)
return "--copy-dest";
case LINK_DEST:
return "--link-dest";
default:
NOISY_DEATH("Unknown alt_dest_opt type");
}
-@@ -1898,6 +1904,10 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -1918,6 +1924,10 @@ int parse_arguments(int *argc_p, const char ***argv_p)
want_dest_type = LINK_DEST;
goto set_dest_dir;
diff --git a/rsync.1.md b/rsync.1.md
--- a/rsync.1.md
+++ b/rsync.1.md
-@@ -422,6 +422,7 @@ detailed description below for a complete description.
+@@ -424,6 +424,7 @@ detailed description below for a complete description.
--compare-dest=DIR also compare destination files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
--compress, -z compress file data during the transfer
--compress-choice=STR choose the compression algorithm (aka --zc)
--compress-level=NUM explicitly set compression level (aka --zl)
-@@ -2290,6 +2291,17 @@ your home directory (remove the '=' for that).
+@@ -2330,6 +2331,17 @@ your home directory (remove the '=' for that).
specified (or implied by `-a`). You can work-around this bug by avoiding
the `-o` option when sending to an old rsync.
diff --git a/syscall.c b/syscall.c
--- a/syscall.c
+++ b/syscall.c
-@@ -129,6 +129,54 @@ int do_link(const char *old_path, const char *new_path)
+@@ -138,6 +138,54 @@ int do_link(const char *old_path, const char *new_path)
}
#endif
./configure
make
-based-on: c3cf174e5ed52e709ecdfd65c7d5da34c7574b96
+based-on: 0327a2526b8f3e6c050e4541805b8b702ba5d7ce
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -45,12 +45,15 @@ extern int numeric_ids;
+@@ -44,12 +44,15 @@ extern int numeric_ids;
extern int filesfrom_fd;
extern int remote_protocol;
extern int protocol_version;
extern char *bind_address;
extern char *config_file;
extern char *logfile_format;
-@@ -814,6 +817,11 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -809,6 +812,11 @@ 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_early_exec(module_id) || *lp_prexfer_exec(module_id)
|| *lp_postxfer_exec(module_id) || *lp_name_converter(module_id))
-@@ -1026,6 +1034,8 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -1021,6 +1029,8 @@ 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;
extern int io_error;
extern int batch_fd;
extern int eol_nulls;
-@@ -1487,6 +1489,32 @@ static void read_a_msg(void)
+@@ -1492,6 +1494,32 @@ static void read_a_msg(void)
if (am_sender)
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
break;
case MSG_DELETED:
if (msg_bytes >= sizeof data)
goto overflow;
-@@ -1638,6 +1666,7 @@ static void read_a_msg(void)
+@@ -1643,6 +1671,7 @@ static void read_a_msg(void)
* with a duplicate exit message. */
_exit_cleanup(val, __FILE__, 0 - __LINE__);
default:
extern char *shell_cmd;
extern char *password_file;
extern char *backup_dir;
-@@ -1219,6 +1222,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
+@@ -1223,6 +1226,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
if (am_daemon && io_timeout && protocol_version >= 31)
send_msg_int(MSG_IO_TIMEOUT, io_timeout);
if (am_sender) {
keep_dirlinks = 0; /* Must be disabled on the sender. */
if (need_messages_from_generator)
-@@ -1502,6 +1508,9 @@ static int start_client(int argc, char *argv[])
+@@ -1506,6 +1512,9 @@ static int start_client(int argc, char *argv[])
else
env_port = rsync_port;
+ if (db_config)
+ db_read_config(FERROR, db_config);
+
- if (daemon_over_rsh < 0)
+ if (daemon_connection < 0)
return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -87,6 +87,7 @@ int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
+@@ -86,6 +86,7 @@ int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
int am_server = 0;
int am_sender = 0;
int am_starting_up = 1;
int relative_paths = -1;
int implied_dirs = 1;
int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
-@@ -100,6 +101,7 @@ int use_qsort = 0;
+@@ -99,6 +100,7 @@ int use_qsort = 0;
char *files_from = NULL;
int filesfrom_fd = -1;
char *filesfrom_host = NULL;
int eol_nulls = 0;
int protect_args = -1;
int human_readable = 1;
-@@ -108,6 +110,9 @@ int mkpath_dest_arg = 0;
+@@ -107,6 +109,9 @@ int mkpath_dest_arg = 0;
int allow_inc_recurse = 1;
int xfer_dirs = -1;
int am_daemon = 0;
int connect_timeout = 0;
int keep_partial = 0;
int safe_symlinks = 0;
-@@ -290,6 +295,7 @@ static struct output_struct debug_words[COUNT_DEBUG+1] = {
+@@ -289,6 +294,7 @@ static struct output_struct debug_words[COUNT_DEBUG+1] = {
DEBUG_WORD(CHDIR, W_CLI|W_SRV, "Debug when the current directory changes"),
DEBUG_WORD(CONNECT, W_CLI, "Debug connection events (levels 1-2)"),
DEBUG_WORD(CMD, W_CLI, "Debug commands+options that are issued (levels 1-2)"),
DEBUG_WORD(DEL, W_REC, "Debug delete actions (levels 1-3)"),
DEBUG_WORD(DELTASUM, W_SND|W_REC, "Debug delta-transfer checksumming (levels 1-4)"),
DEBUG_WORD(DUP, W_REC, "Debug weeding of duplicate names"),
-@@ -682,6 +688,16 @@ static void print_info_flags(enum logcode f)
+@@ -681,6 +687,16 @@ static void print_info_flags(enum logcode f)
#endif
"crtimes",
"*Optimizations",
#ifndef HAVE_SIMD
-@@ -795,6 +811,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -794,6 +810,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE,
+ OPT_NO_DB, OPT_DBONLY,
- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
+ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR,
OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS,
OPT_STOP_AFTER, OPT_STOP_AT,
@@ -950,6 +967,10 @@ static struct poptOption long_options[] = {
./configure
make
-based-on: af531cf787995f6a3bc381cd1da1988192e7ef59
+based-on: 0327a2526b8f3e6c050e4541805b8b702ba5d7ce
diff --git a/Makefile.in b/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
extern char *logfile_format;
extern char *files_from;
extern char *tmpdir;
-@@ -666,6 +667,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
+@@ -665,6 +666,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
return -1;
}
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -166,6 +166,7 @@ char *backup_suffix = NULL;
+@@ -167,6 +167,7 @@ char *backup_suffix = NULL;
char *tmpdir = NULL;
char *partial_dir = NULL;
char *basis_dir[MAX_BASIS_DIRS+1];
char *config_file = NULL;
char *shell_cmd = NULL;
char *logfile_name = NULL;
-@@ -227,7 +228,7 @@ static const char *debug_verbosity[] = {
+@@ -228,7 +229,7 @@ static const char *debug_verbosity[] = {
/*2*/ "BIND,CMD,CONNECT,DEL,DELTASUM,DUP,FILTER,FLIST,ICONV",
/*3*/ "ACL,BACKUP,CONNECT2,DELTASUM2,DEL2,EXIT,FILTER2,FLIST2,FUZZY,GENR,OWN,RECV,SEND,TIME",
/*4*/ "CMD2,DELTASUM3,DEL3,EXIT2,FLIST3,ICONV2,OWN2,PROTO,TIME2",
};
#define MAX_VERBOSITY ((int)(sizeof debug_verbosity / sizeof debug_verbosity[0]) - 1)
-@@ -297,6 +298,7 @@ static struct output_struct debug_words[COUNT_DEBUG+1] = {
+@@ -298,6 +299,7 @@ static struct output_struct debug_words[COUNT_DEBUG+1] = {
DEBUG_WORD(FUZZY, W_REC, "Debug fuzzy scoring (levels 1-2)"),
DEBUG_WORD(GENR, W_REC, "Debug generator functions"),
DEBUG_WORD(HASH, W_SND|W_REC, "Debug hashtable code"),
DEBUG_WORD(HLINK, W_SND|W_REC, "Debug hard-link actions (levels 1-3)"),
DEBUG_WORD(ICONV, W_CLI|W_SRV, "Debug iconv character conversions (levels 1-2)"),
DEBUG_WORD(IO, W_CLI|W_SRV, "Debug I/O routines (levels 1-4)"),
-@@ -783,7 +785,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -794,7 +796,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE,
-- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
-+ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_LINK_BY_HASH,
+- OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR,
++ OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_LINK_BY_HASH,
OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS,
OPT_STOP_AFTER, OPT_STOP_AT,
OPT_REFUSED_BASE = 9000};
-@@ -939,6 +941,7 @@ static struct poptOption long_options[] = {
+@@ -954,6 +956,7 @@ static struct poptOption long_options[] = {
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
{"fuzzy", 'y', POPT_ARG_NONE, 0, 'y', 0, 0 },
{"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
{"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 },
-@@ -1188,6 +1191,9 @@ static void set_refuse_options(void)
+@@ -1205,6 +1208,9 @@ static void set_refuse_options(void)
ref = cp + 1;
}
if (am_daemon) {
#ifdef ICONV_OPTION
if (!*lp_charset(module_id))
-@@ -2047,6 +2053,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2067,6 +2073,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
return 0;
#endif
case OPT_STOP_AFTER: {
long val;
arg = poptGetOptArg(pc);
-@@ -2381,6 +2401,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+@@ -2419,6 +2439,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);
}
if (daemon_filter_list.head && !am_sender) {
filter_rule_list *elp = &daemon_filter_list;
-@@ -3063,6 +3085,12 @@ void server_options(char **args, int *argc_p)
+@@ -3103,6 +3125,12 @@ void server_options(char **args, int *argc_p)
} else if (inplace)
args[ac++] = "--inplace";
diff --git a/rsync.1.md b/rsync.1.md
--- a/rsync.1.md
+++ b/rsync.1.md
-@@ -422,6 +422,7 @@ detailed description below for a complete description.
+@@ -424,6 +424,7 @@ detailed description below for a complete description.
--compare-dest=DIR also compare destination files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
--compress, -z compress file data during the transfer
--compress-choice=STR choose the compression algorithm (aka --zc)
--compress-level=NUM explicitly set compression level (aka --zl)
-@@ -2290,6 +2291,50 @@ your home directory (remove the '=' for that).
+@@ -2330,6 +2331,50 @@ your home directory (remove the '=' for that).
specified (or implied by `-a`). You can work-around this bug by avoiding
the `-o` option when sending to an old rsync.
extern int sanitize_paths;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct chmod_mode_struct *daemon_chmod_modes;
-@@ -735,6 +736,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -748,6 +749,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
}
if (ret == 0) {
/* The file was moved into place (not copied), so it's done. */
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -1408,7 +1408,8 @@ extern short info_levels[], debug_levels[];
+@@ -1424,7 +1424,8 @@ extern short info_levels[], debug_levels[];
#define DEBUG_FUZZY (DEBUG_FLIST+1)
#define DEBUG_GENR (DEBUG_FUZZY+1)
#define DEBUG_HASH (DEBUG_GENR+1)
diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md
--- a/rsyncd.conf.5.md
+++ b/rsyncd.conf.5.md
-@@ -339,6 +339,23 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
+@@ -354,6 +354,23 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
is 0, which means no limit. A negative value disables the module. See
also the "lock file" parameter.