extern int copy_unsafe_links;
extern int protocol_version;
extern int sanitize_paths;
+extern int munge_symlinks;
+extern int need_unsorted_flist;
+extern int unsort_ndx;
extern struct stats stats;
extern char *filesfrom_host;
extern struct filter_list_struct server_filter_list;
#ifdef ICONV_OPTION
-extern int ic_ndx;
extern int filesfrom_convert;
-extern int need_unsorted_flist;
extern iconv_t ic_send, ic_recv;
#endif
}
return x_stat(path, stp, NULL);
}
+ if (munge_symlinks && am_sender && llen > SYMLINK_PREFIX_LEN
+ && strncmp(linkbuf, SYMLINK_PREFIX, SYMLINK_PREFIX_LEN) == 0) {
+ memmove(linkbuf, linkbuf + SYMLINK_PREFIX_LEN,
+ llen - SYMLINK_PREFIX_LEN + 1);
+ }
}
return 0;
#else
clean_fname(thisname, 0);
if (sanitize_paths)
- sanitize_path(thisname, thisname, "", 0, NULL);
+ sanitize_path(thisname, thisname, "", 0);
if ((basename = strrchr(thisname, '/')) != NULL) {
int len = basename++ - thisname;
modtime = read_varlong(f, 4);
#if SIZEOF_TIME_T < SIZEOF_INT64
if ((modtime > INT_MAX || modtime < INT_MIN) && !am_generator) {
- rprintf(FERROR,
+ rprintf(FERROR_XFER,
"Time value of %s truncated on receiver.\n",
lastname);
}
linkname_len - 1);
overflow_exit("recv_file_entry");
}
+ if (munge_symlinks)
+ linkname_len += SYMLINK_PREFIX_LEN;
}
else
#endif
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
-#ifdef ICONV_OPTION
- if (ic_ndx)
+ if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
-#endif
if (basename != thisname) {
file->dirname = lastdir;
if (first_hlink_ndx >= flist->ndx_start) {
struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
memcpy(bp, F_SYMLINK(first), linkname_len);
- } else
+ } else if (munge_symlinks) {
+ strlcpy(bp, SYMLINK_PREFIX, linkname_len);
+ bp += SYMLINK_PREFIX_LEN;
+ linkname_len -= SYMLINK_PREFIX_LEN;
read_sbuf(f, bp, linkname_len - 1);
- if (sanitize_paths)
- sanitize_path(bp, bp, "", lastdir_depth, NULL);
+ } else {
+ read_sbuf(f, bp, linkname_len - 1);
+ if (sanitize_paths)
+ sanitize_path(bp, bp, "", lastdir_depth);
+ }
}
#endif
}
clean_fname(thisname, 0);
if (sanitize_paths)
- sanitize_path(thisname, thisname, "", 0, NULL);
+ sanitize_path(thisname, thisname, "", 0);
if (stp && S_ISDIR(stp->st_mode)) {
st = *stp; /* Needed for "symlink/." with --relative. */
if (copy_links && x_lstat(thisname, &st, NULL) == 0
&& S_ISLNK(st.st_mode)) {
io_error |= IOERR_GENERAL;
- rprintf(FERROR, "symlink has no referent: %s\n",
+ rprintf(FERROR_XFER, "symlink has no referent: %s\n",
full_fname(thisname));
} else
#endif
{
enum logcode c = am_daemon && protocol_version < 28
- ? FERROR : FINFO;
+ ? FERROR : FWARNING;
io_error |= IOERR_VANISHED;
rprintf(c, "file has vanished: %s\n",
full_fname(thisname));
}
} else {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, save_errno, "readlink %s failed",
+ rsyserr(FERROR_XFER, save_errno, "readlink %s failed",
full_fname(thisname));
}
return NULL;
if (basename_len == 0+1)
return NULL;
-#ifdef ICONV_OPTION
- if (ic_ndx)
+ if (unsort_ndx)
F_NDX(file) = dir_count - 1;
-#endif
return file;
}
fbuf[--len] = '\0';
if (len >= MAXPATHLEN - 1) {
io_error |= IOERR_GENERAL;
- rprintf(FERROR, "skipping long-named directory: %s\n",
+ rprintf(FERROR_XFER, "skipping long-named directory: %s\n",
full_fname(fbuf));
return;
}
if (!(d = opendir(fbuf))) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "opendir %s failed", full_fname(fbuf));
+ rsyserr(FERROR_XFER, errno, "opendir %s failed", full_fname(fbuf));
return;
}
if (errno) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "readdir(%s)", full_fname(fbuf));
+ rsyserr(FERROR_XFER, errno, "readdir(%s)", full_fname(fbuf));
}
closedir(d);
STRUCT_STAT st;
if (link_stat(fbuf, &st, copy_dirlinks) != 0) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "link_stat %s failed",
+ rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
return;
}
STRUCT_STAT st;
if (link_stat(fbuf, &st, 1) != 0) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "link_stat %s failed",
+ rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
}
struct file_list *flist;
int64 start_write;
uint16 prev_flags;
- int future_cnt, save_io_error = io_error;
+ int old_cnt, save_io_error = io_error;
if (flist_eof)
return;
/* Keep sending data until we have the requested number of
* files in the upcoming file-lists. */
- if (cur_flist->next) {
- flist = first_flist->prev; /* the newest flist */
- future_cnt = flist->ndx_end - cur_flist->next->ndx_start + 1;
- } else
- future_cnt = 0;
- while (future_cnt < at_least) {
+ old_cnt = cur_flist->used;
+ for (flist = first_flist; flist != cur_flist; flist = flist->next)
+ 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;
const char *pathname = F_PATHNAME(file);
flist = flist_new(0, "send_extra_file_list");
start_write = stats.total_written;
-#ifdef ICONV_OPTION
- if (ic_ndx)
+ if (unsort_ndx)
dir_ndx = F_NDX(file);
else
-#endif
dir_ndx = send_dir_ndx;
write_ndx(f, NDX_FLIST_OFFSET - dir_ndx);
flist->parent_ndx = dir_ndx;
write_byte(f, 0);
-#ifdef ICONV_OPTION
if (need_unsorted_flist) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
out_of_memory("send_extra_file_list");
memcpy(flist->sorted, flist->files,
flist->used * sizeof (struct file_struct*));
} else
-#endif
flist->sorted = flist->files;
clean_flist(flist, 0);
- flist->ndx_end = flist->ndx_start + flist->used - 1
- - (dir_count - dstart);
+ flist->ndx_end = flist->ndx_start + flist->used - 1;
+ if (!need_unsorted_flist)
+ flist->ndx_end -= (dir_count - dstart);
add_dirs_to_tree(send_dir_ndx, flist, dir_count - dstart);
flist_done_allocating(flist);
file_total += flist->used;
- future_cnt += flist->used;
stats.flist_size += stats.total_written - start_write;
stats.num_files += flist->used;
if (verbose > 3)
disable_buffering = io_start_buffering_out(f);
if (filesfrom_fd >= 0) {
if (argv[0] && !push_dir(argv[0], 0)) {
- rsyserr(FERROR, errno, "push_dir %s failed in %s",
+ rsyserr(FERROR_XFER, errno, "push_dir %s failed in %s",
full_fname(argv[0]), curr_dir);
exit_cleanup(RERR_FILESELECT);
}
if (use_ff_fd) {
if (read_line(filesfrom_fd, fbuf, sizeof fbuf, rl_flags) == 0)
break;
- sanitize_path(fbuf, fbuf, "", 0, NULL);
+ sanitize_path(fbuf, fbuf, "", 0);
} else {
if (argc-- == 0)
break;
strlcpy(fbuf, *argv++, MAXPATHLEN);
if (sanitize_paths)
- sanitize_path(fbuf, fbuf, "", 0, NULL);
+ sanitize_path(fbuf, fbuf, "", 0);
}
len = strlen(fbuf);
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "link_stat %s failed",
+ rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
}
* receiving side to ask for whatever name it kept. For incremental
* recursion mode, the sender marks duplicate dirs so that it can
* send them together in a single file-list. */
-#ifdef ICONV_OPTION
if (need_unsorted_flist) {
if (inc_recurse) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
flist->low = 0;
flist->high = flist->used - 1;
}
- } else
-#endif
- {
+ } else {
flist->sorted = flist->files;
clean_flist(flist, 0);
}
file_total += flist->used;
flist->ndx_end = flist->ndx_start + flist->used - 1;
- if (inc_recurse && flist->ndx_start > 1)
+ if (inc_recurse && !need_unsorted_flist && flist->ndx_start > 1)
flist->ndx_end -= dir_flist->used - dstart;
if (verbose > 2)
if (show_filelist_p())
finish_filelist_progress(flist);
-#ifdef ICONV_OPTION
if (need_unsorted_flist) {
/* Create an extra array of index pointers that we can sort for
* the generator's use (for wading through the files in sorted
(dir_flist->used - dstart) * sizeof (struct file_struct*));
fsort(dir_flist->sorted + dstart, dir_flist->used - dstart);
}
- } else
-#endif
- {
+ } else {
flist->sorted = flist->files;
if (inc_recurse && dir_flist->used > dstart) {
dir_flist->sorted = dir_flist->files;
rprintf(FINFO, "[%s] flist start=%d, end=%d, used=%d, low=%d, high=%d\n",
who, flist->ndx_start, flist->ndx_end, flist->used, flist->low, flist->high);
for (i = 0; i < flist->used; i++) {
- file = flist->sorted[i];
+ file = flist->files[i];
if ((am_root || am_sender) && uid_ndx) {
snprintf(uidbuf, sizeof uidbuf, " uid=%u",
F_OWNER(file));