} *csum_cache = NULL;
static void flist_sort_and_clean(struct file_list *flist, int flags);
-@@ -363,7 +372,79 @@ static void flist_done_allocating(struct file_list *flist)
+@@ -351,7 +360,79 @@ static void flist_done_allocating(struct file_list *flist)
flist->pool_boundary = ptr;
}
{
int slot, slots = am_sender ? 1 : basis_dir_cnt + 1;
-@@ -377,6 +458,9 @@ void reset_checksum_cache()
+@@ -365,6 +446,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));
-@@ -387,6 +471,10 @@ void reset_checksum_cache()
+@@ -375,6 +459,10 @@ void reset_checksum_cache()
flist->low = 0;
flist->high = -1;
flist->next = NULL;
}
}
-@@ -394,7 +482,7 @@ void reset_checksum_cache()
+@@ -382,7 +470,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;
-@@ -411,7 +499,7 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -399,7 +487,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);
-@@ -420,7 +508,14 @@ static int add_checksum(struct file_list *flist, const char *dirname,
+@@ -408,7 +496,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;
-@@ -449,10 +544,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -437,10 +532,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))
-@@ -473,7 +569,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -461,7 +557,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
while (fgets(line, sizeof line, fp)) {
cp = line;
if (protocol_version >= 30) {
if (*cp == '=')
while (*++cp == '=') {}
else
-@@ -484,7 +580,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -472,7 +568,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
}
if (*cp == '=') {
} else {
for (i = 0; i < checksum_len*2; i++, cp++) {
int x;
-@@ -502,13 +605,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -490,13 +593,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
-@@ -558,24 +662,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam
+@@ -546,24 +650,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);
}
-@@ -587,12 +779,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file,
+@@ -575,12 +767,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))) {
+ }
}
- int push_pathname(const char *dir, int len)
-@@ -1378,6 +1589,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+ /* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
+@@ -1371,6 +1582,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;
}
-@@ -1424,13 +1637,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1417,13 +1630,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' */
-@@ -1512,7 +1725,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1509,7 +1722,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);
}
-@@ -1804,6 +2017,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1839,6 +2052,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". */
-@@ -2389,6 +2605,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2435,6 +2651,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
}
} else
flist_eof = 1;
static const char *solo_file = NULL;
/* For calling delete_item() and delete_dir_contents(). */
-@@ -717,7 +718,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
+@@ -723,7 +724,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->st_size, sum);
return memcmp(sum, F_SUM(file), checksum_len) == 0;
-@@ -1350,7 +1351,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1366,7 +1367,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
}
if (checksum_files) {
}
need_new_dirscan = 0;
}
-@@ -1488,9 +1490,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
- DEV_MINOR(devp) = minor(real_sx.st.st_dev);
- }
+@@ -1516,6 +1518,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+ else
+ change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
}
-- else if (delete_during && f_out != -1 && !phase
-- && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR))
-- delete_in_dir(fname, file, &real_sx.st.st_dev);
-+ else if (file->flags & FLAG_CONTENT_DIR && f_out != -1) {
-+ if (delete_during && !phase && !(file->flags & FLAG_MISSING_DIR))
-+ delete_in_dir(fname, file, &real_sx.st.st_dev);
-+ upcoming_whole_dir = 1;
-+ } else
-+ upcoming_whole_dir = 0;
++ upcoming_whole_dir = file->flags & FLAG_CONTENT_DIR && f_out != -1 ? 1 : 0;
goto cleanup;
}
-@@ -1783,6 +1788,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1808,6 +1811,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
-@@ -2195,6 +2202,7 @@ void generate_files(int f_out, const char *local_name)
- delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
- }
+@@ -2247,6 +2252,7 @@ void generate_files(int f_out, const char *local_name)
+ } else
+ change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
+ upcoming_whole_dir = fp->flags & FLAG_CONTENT_DIR ? 1 : 0;
}
for (i = cur_flist->low; i <= cur_flist->high; i++) {
struct file_struct *file = cur_flist->sorted[i];
-@@ -2275,6 +2283,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2327,6 +2333,9 @@ void generate_files(int f_out, const char *local_name)
wait_for_receiver();
}
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -866,6 +866,8 @@ typedef struct {
+@@ -874,6 +874,8 @@ typedef struct {
#define CSF_ENABLE (1<<1)
#define CSF_LAX (1<<2)
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -284,13 +284,15 @@ The default is tt(/var/run/rsyncd.lock).
- dit(bf(checksum files)) This option tells rsync to make use of any cached
+ dit(bf(checksum files)) This parameter tells rsync to make use of any cached
checksum information it finds in per-directory .rsyncsums files when the
current transfer is using the bf(--checksum) option. The value can be set
-to either "lax", "strict", or "none" -- see the client's bf(--sumfiles)
+the bf(exclude) directive for a way to hide the .rsyncsums files from the
+user.
- dit(bf(read only)) The "read only" option determines whether clients
+ dit(bf(read only)) This parameter determines whether clients
will be able to upload files or not. If "read only" is true then any