#include "rsync.h"
#include "ifuncs.h"
#include "rounding.h"
+#include "inums.h"
#include "io.h"
extern int am_root;
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
-static int dir_count = 0;
static void flist_sort_and_clean(struct file_list *flist, int strip_root);
static void output_flist(struct file_list *flist);
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
who_am_i(),
- big_num(sizeof flist->files[0] * flist->malloced, 0),
+ big_num(sizeof flist->files[0] * flist->malloced),
(new_ptr == flist->files) ? " not" : "");
}
int l1, l2;
int xflags;
- /* Initialize starting value of xflags. */
- if (protocol_version >= 30 && S_ISDIR(file->mode)) {
- dir_count++;
- if (file->flags & FLAG_CONTENT_DIR)
- xflags = file->flags & FLAG_TOP_DIR;
- else if (file->flags & FLAG_IMPLIED_DIR)
- xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
+ /* Initialize starting value of xflags and adjust counts. */
+ if (S_ISREG(file->mode))
+ xflags = 0;
+ else if (S_ISDIR(file->mode)) {
+ stats.num_dirs++;
+ if (protocol_version >= 30) {
+ if (file->flags & FLAG_CONTENT_DIR)
+ xflags = file->flags & FLAG_TOP_DIR;
+ else if (file->flags & FLAG_IMPLIED_DIR)
+ xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
+ else
+ xflags = XMIT_NO_CONTENT_DIR;
+ } else
+ xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
+ } else {
+ if (S_ISLNK(file->mode))
+ stats.num_symlinks++;
+ else if (IS_DEVICE(file->mode))
+ stats.num_devices++;
else
- xflags = XMIT_NO_CONTENT_DIR;
- } else
- xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
+ stats.num_specials++;
+ xflags = 0;
+ }
if (file->mode == mode)
xflags |= XMIT_SAME_MODE;
} else if (DEBUG_GTE(HLINK, 3)) {
rprintf(FINFO, "[%s] dev:inode for #%d is %s:%s\n",
who_am_i(), first_ndx + ndx,
- big_num(tmp_dev, 0), big_num(tmp_ino, 0));
+ big_num(tmp_dev), big_num(tmp_ino));
}
}
} else {
}
#ifdef ICONV_OPTION
/* We don't know how much extra room we need to convert
- * the as-yet-unread symlink data when converting it,
- * so let's hope that a double-size buffer is plenty. */
+ * the as-yet-unread symlink data, so let's hope that a
+ * double-size buffer is plenty. */
if (sender_symlink_iconv)
- linkname_len = linkname_len * 2 + 1;
+ linkname_len *= 2;
#endif
if (munge_symlinks)
linkname_len += SYMLINK_PREFIX_LEN;
xbuf outbuf, inbuf;
alloc_len = linkname_len;
- linkname_len /= 2; /* (linkname_len-1) / 2 for odd values. */
+ linkname_len /= 2;
/* Read the symlink data into the end of our double-sized
* buffer and then convert it into the right spot. */
}
} else {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR_XFER, save_errno, "readlink %s failed",
+ rsyserr(FERROR_XFER, save_errno, "readlink_stat(%s) failed",
full_fname(thisname));
}
return NULL;
memcpy(F_SUM(file), tmp_sum, checksum_len);
if (unsort_ndx)
- F_NDX(file) = dir_count;
+ F_NDX(file) = stats.num_dirs;
return file;
}
old_cnt += flist->used;
while (file_total - old_cnt < at_least) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
- int dir_ndx, dstart = dir_count;
+ int dir_ndx, dstart = stats.num_dirs;
const char *pathname = F_PATHNAME(file);
int32 *dp;
dp = F_DIR_NODE_P(file);
}
- write_byte(f, 0);
+ if (protocol_version < 31 || io_error == save_io_error || ignore_errors)
+ write_byte(f, 0);
+ else {
+ write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
+ write_int(f, io_error);
+ }
if (need_unsorted_flist) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
flist_sort_and_clean(flist, 0);
- add_dirs_to_tree(send_dir_ndx, flist, dir_count - dstart);
+ add_dirs_to_tree(send_dir_ndx, flist, stats.num_dirs - dstart);
flist_done_allocating(flist);
file_total += flist->used;
}
finish:
- if (io_error != save_io_error && !ignore_errors)
+ if (io_error != save_io_error && protocol_version == 30 && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error);
}
stats.flist_buildtime = 1;
start_tv = end_tv;
- write_byte(f, 0); /* Indicate end of file list */
+ /* Indicate end of file list */
+ if (protocol_version < 31 || io_error == 0 || ignore_errors)
+ write_byte(f, 0);
+ else {
+ write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
+ write_int(f, io_error);
+ }
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && protocol_version >= 30 && !inc_recurse)
/* send the io_error flag */
if (protocol_version < 30)
write_int(f, ignore_errors ? 0 : io_error);
- else if (io_error && !ignore_errors)
+ else if (io_error && protocol_version == 30 && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error);
if (disable_buffering)
if (inc_recurse) {
send_dir_depth = 1;
- add_dirs_to_tree(-1, flist, dir_count);
+ add_dirs_to_tree(-1, flist, stats.num_dirs);
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
flist->parent_ndx = -1;
flist_done_allocating(flist);
while ((flags = read_byte(f)) != 0) {
struct file_struct *file;
- flist_expand(flist, 1);
-
if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
flags |= read_byte(f) << 8;
- file = recv_file_entry(flist, flags, f);
- if (inc_recurse && S_ISDIR(file->mode)) {
- flist_expand(dir_flist, 1);
- dir_flist->files[dir_flist->used++] = file;
+ if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
+ int err;
+ if (protocol_version < 31) {
+ rprintf(FERROR, "Invalid flist flag: %x\n", flags);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ err = read_int(f);
+ if (!ignore_errors)
+ io_error |= err;
+ break;
}
+ flist_expand(flist, 1);
+ file = recv_file_entry(flist, flags, f);
+
+ if (S_ISREG(file->mode)) {
+ /* Already counted */
+ } else if (S_ISDIR(file->mode)) {
+ if (inc_recurse) {
+ flist_expand(dir_flist, 1);
+ dir_flist->files[dir_flist->used++] = file;
+ }
+ stats.num_dirs++;
+ } else if (S_ISLNK(file->mode))
+ stats.num_symlinks++;
+ else if (IS_DEVICE(file->mode))
+ stats.num_symlinks++;
+ else
+ stats.num_specials++;
+
flist->files[flist->used++] = file;
maybe_emit_filelist_progress(flist->used);
if (protocol_version < 30) {
/* Recv the io_error flag */
- if (ignore_errors)
- read_int(f);
- else
- io_error |= read_int(f);
+ int err = read_int(f);
+ if (!ignore_errors)
+ io_error |= err;
} else if (inc_recurse && flist->ndx_start == 1) {
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
flist->parent_ndx = -1;
"[%s] i=%d %s %s%s%s%s mode=0%o len=%s%s%s flags=%x\n",
who, i + flist->ndx_start,
root, dir, slash, name, trail,
- (int)file->mode, big_num(F_LENGTH(file), 0),
+ (int)file->mode, comma_num(F_LENGTH(file)),
uidbuf, gidbuf, file->flags);
}
}