X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/6e5b682273436decb233e1ce83a923364c7eb25d..5dd14f0c3388f69932d521915e039e32b9e6d970:/flist.c diff --git a/flist.c b/flist.c index 5e5fe64e..766f1b37 100644 --- a/flist.c +++ b/flist.c @@ -23,6 +23,7 @@ #include "rsync.h" #include "ifuncs.h" #include "rounding.h" +#include "inums.h" #include "io.h" extern int am_root; @@ -65,6 +66,7 @@ extern int protocol_version; extern int sanitize_paths; extern int munge_symlinks; extern int need_unsorted_flist; +extern int sender_symlink_iconv; extern int output_needs_newline; extern int sender_keeps_checksum; extern int unsort_ndx; @@ -320,7 +322,7 @@ static void flist_expand(struct file_list *flist, int extra) 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" : ""); } @@ -487,7 +489,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, } 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 { @@ -695,7 +697,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) { io_error |= IOERR_GENERAL; - rprintf(FERROR_XFER, + rprintf(FERROR_UTF8, "[%s] cannot convert filename: %s (%s)\n", who_am_i(), lastname, strerror(errno)); outbuf.len = 0; @@ -838,10 +840,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } #ifdef ICONV_OPTION /* We don't know how much extra room we need to convert - * the as-yet-unread symlink name when converting it, - * so let's hope that a double-size buffer is plenty. */ - if (ic_recv != (iconv_t)-1) - linkname_len = linkname_len * 2 + 1; + * the as-yet-unread symlink data, so let's hope that a + * double-size buffer is plenty. */ + if (sender_symlink_iconv) + linkname_len *= 2; #endif if (munge_symlinks) linkname_len += SYMLINK_PREFIX_LEN; @@ -984,13 +986,13 @@ static struct file_struct *recv_file_entry(struct file_list *flist, linkname_len -= SYMLINK_PREFIX_LEN; } #ifdef ICONV_OPTION - if (ic_recv != (iconv_t)-1) { + if (sender_symlink_iconv) { xbuf outbuf, inbuf; alloc_len = linkname_len; - linkname_len /= 2; /* (linkname_len-1) / 2 for odd values. */ + linkname_len /= 2; - /* Read the symlink name into the end of our double-sized + /* Read the symlink data into the end of our double-sized * buffer and then convert it into the right spot. */ INIT_XBUF(inbuf, bp + alloc_len - linkname_len, linkname_len - 1, (size_t)-1); @@ -1000,7 +1002,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) { io_error |= IOERR_GENERAL; rprintf(FERROR_XFER, - "[%s] cannot convert symlink name for: %s (%s)\n", + "[%s] cannot convert symlink data for: %s (%s)\n", who_am_i(), full_fname(thisname), strerror(errno)); bp = (char*)file->basename; *bp++ = '\0'; @@ -1148,7 +1150,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, } } 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; @@ -1422,14 +1424,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, fbuf[outbuf.len] = '\0'; #ifdef SUPPORT_LINKS - if (symlink_len) { + if (symlink_len && sender_symlink_iconv) { INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1); INIT_CONST_XBUF(outbuf, symlink_buf); if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) { io_error |= IOERR_GENERAL; f_name(file, fbuf); rprintf(FERROR_XFER, - "[%s] cannot convert symlink name for: %s (%s)\n", + "[%s] cannot convert symlink data for: %s (%s)\n", who_am_i(), full_fname(fbuf), strerror(errno)); return NULL; } @@ -1915,7 +1917,12 @@ void send_extra_file_list(int f, int at_least) 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))) @@ -1956,7 +1963,7 @@ void send_extra_file_list(int f, int at_least) } 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); } @@ -2212,7 +2219,13 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) 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) @@ -2250,7 +2263,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) /* 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) @@ -2321,10 +2334,22 @@ struct file_list *recv_file_list(int f) 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; + + 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 (inc_recurse && S_ISDIR(file->mode)) { @@ -2388,10 +2413,9 @@ struct file_list *recv_file_list(int f) 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; @@ -2796,7 +2820,7 @@ static void output_flist(struct file_list *flist) "[%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); } }