Make sure the generator doesn't try to send a negative checksum count to

the sender (which would cause it to die with a cryptic error).  Instead,
warn the user when the file's size is too large for checksum processing.
This commit is contained in:
Wayne Davison committed 2008-05-31 10:13:28 -07:00
1 parent a64f19e24b
commit cc911409d6
2 files changed
+24 -7

No files matched your search

+6
View File
@@ -19,6 +19,8 @@ Changes since 3.0.2:
- Fixed several places in the code that were not returning the right
errno when a function failed.
- Fixed the backing up of a device or special file into a backup dir.
- Moved the setting of the socket options prior to the connect().
- If rsync exits in the middle of a --progress output, it now outputs a
@@ -27,6 +29,10 @@ Changes since 3.0.2:
- Fixed a problem with how a destination path with a trailing slash was
compared against the daemon excludes.
- If a file's length is so huge that we overflow a checksum buffer count
(i.e. several hundred TB), warn the user and avoid sending an invalid
checksum struct over the wire.
- Use the overflow_exit() function for overflows, not out_of_memory().
ENHANCEMENTS:
+18 -7
View File
@@ -753,6 +753,7 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
{
int32 blength;
int s2length;
int64 l;
if (block_size)
blength = block_size;
@@ -760,7 +761,6 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
blength = BLOCK_SIZE;
else {
int32 c;
int64 l;
int cnt;
for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
@@ -783,7 +783,6 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
s2length = SUM_LENGTH;
} else {
int32 c;
int64 l;
int b = BLOCKSUM_BIAS;
for (l = len; l >>= 1; b += 2) {}
for (c = blength; (c >>= 1) && b; b--) {}
@@ -797,7 +796,10 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
sum->blength = blength;
sum->s2length = s2length;
sum->remainder = (int32)(len % blength);
sum->count = (int32)(len / blength) + (sum->remainder != 0);
sum->count = (int32)(l = (len / blength) + (sum->remainder != 0));
if ((int64)sum->count != l)
sum->count = -1;
if (sum->count && verbose > 2) {
rprintf(FINFO,
@@ -813,7 +815,7 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
*
* Generate approximately one checksum every block_len bytes.
*/
static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
{
int32 i;
struct map_struct *mapbuf;
@@ -821,10 +823,12 @@ static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
OFF_T offset = 0;
sum_sizes_sqroot(&sum, len);
if (sum.count < 0)
return -1;
write_sum_head(f_out, &sum);
if (append_mode > 0 && f_copy < 0)
return;
return 0;
if (len > 0)
mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
@@ -861,6 +865,8 @@ static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
if (mapbuf)
unmap_file(mapbuf);
return 0;
}
@@ -1938,10 +1944,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
if (read_batch)
goto cleanup;
if (statret != 0 || whole_file)
if (statret != 0 || whole_file || sx.st.st_size <= 0)
write_sum_head(f_out, NULL);
else {
generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy);
if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {
rprintf(FWARNING,
"WARNING: file is too large for checksum sending: %s\n",
fnamecmp);
write_sum_head(f_out, NULL);
}
close(fd);
}