* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
extern int one_file_system;
extern int copy_dirlinks;
extern int keep_dirlinks;
extern int one_file_system;
extern int copy_dirlinks;
extern int keep_dirlinks;
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
if (tmp_dev != 0) {
if (protocol_version >= 30) {
struct idev_node *np = idev_node(tmp_dev, tmp_ino);
if (tmp_dev != 0) {
if (protocol_version >= 30) {
struct idev_node *np = idev_node(tmp_dev, tmp_ino);
else
write_byte(f, l2);
write_buf(f, fname + l1, l2);
if (first_hlink_ndx >= 0) {
else
write_byte(f, l2);
write_buf(f, fname + l1, l2);
if (first_hlink_ndx >= 0) {
if (!(flags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
if (!(flags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
- write_int(f, uid);
- if (flags & XMIT_USER_NAME_FOLLOWS) {
- int len = strlen(user_name);
- write_byte(f, len);
- write_buf(f, user_name, len);
+ if (protocol_version < 30)
+ write_int(f, uid);
+ else {
+ write_abbrevint(f, uid);
+ if (flags & XMIT_USER_NAME_FOLLOWS) {
+ int len = strlen(user_name);
+ write_byte(f, len);
+ write_buf(f, user_name, len);
+ }
- write_int(f, gid);
- if (flags & XMIT_GROUP_NAME_FOLLOWS) {
- int len = strlen(group_name);
- write_byte(f, len);
- write_buf(f, group_name, len);
+ if (protocol_version < 30)
+ write_int(f, gid);
+ else {
+ write_abbrevint(f, gid);
+ if (flags & XMIT_GROUP_NAME_FOLLOWS) {
+ int len = strlen(group_name);
+ write_byte(f, len);
+ write_buf(f, group_name, len);
+ }
- write_int(f, major(rdev));
- if (flags & XMIT_RDEV_MINOR_IS_SMALL)
+ write_abbrevint30(f, major(rdev));
+ if (protocol_version >= 30)
+ write_abbrevint(f, minor(rdev));
+ else if (flags & XMIT_RDEV_MINOR_8_pre30)
write_byte(f, minor(rdev));
else
write_int(f, minor(rdev));
write_byte(f, minor(rdev));
else
write_int(f, minor(rdev));
if (protocol_version >= 30
&& BITS_SETnUNSET(flags, XMIT_HLINKED, XMIT_HLINK_FIRST)) {
struct file_struct *first;
if (protocol_version >= 30
&& BITS_SETnUNSET(flags, XMIT_HLINKED, XMIT_HLINK_FIRST)) {
struct file_struct *first;
if (first_hlink_ndx < 0 || first_hlink_ndx >= flist->count) {
rprintf(FERROR,
"hard-link reference out of range: %d (%d)\n",
if (first_hlink_ndx < 0 || first_hlink_ndx >= flist->count) {
rprintf(FERROR,
"hard-link reference out of range: %d (%d)\n",
|| (preserve_specials && IS_SPECIAL(mode))) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
|| (preserve_specials && IS_SPECIAL(mode))) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
- uid = (uid_t)read_int(f);
- if (flags & XMIT_USER_NAME_FOLLOWS)
- uid = recv_user_name(f, uid);
- else if (incremental && am_root && !numeric_ids)
- uid = match_uid(uid);
+ if (protocol_version < 30)
+ uid = (uid_t)read_int(f);
+ else {
+ uid = (uid_t)read_abbrevint(f);
+ if (flags & XMIT_USER_NAME_FOLLOWS)
+ uid = recv_user_name(f, uid);
+ else if (inc_recurse && am_root && !numeric_ids)
+ uid = match_uid(uid);
+ }
- gid = (gid_t)read_int(f);
- if (flags & XMIT_GROUP_NAME_FOLLOWS)
- gid = recv_group_name(f, gid);
- else if (incremental && (!am_root || !numeric_ids))
- gid = match_gid(gid);
+ if (protocol_version < 30)
+ gid = (gid_t)read_int(f);
+ else {
+ gid = (gid_t)read_abbrevint(f);
+ if (flags & XMIT_GROUP_NAME_FOLLOWS)
+ gid = recv_group_name(f, gid);
+ else if (inc_recurse && (!am_root || !numeric_ids))
+ gid = match_gid(gid);
+ }
- rdev_major = read_int(f);
- if (flags & XMIT_RDEV_MINOR_IS_SMALL)
+ rdev_major = read_abbrevint30(f);
+ if (protocol_version >= 30)
+ rdev_minor = read_abbrevint(f);
+ else if (flags & XMIT_RDEV_MINOR_8_pre30)
if (linkname_len <= 0 || linkname_len > MAXPATHLEN) {
rprintf(FERROR, "overflow: linkname_len=%d\n",
linkname_len - 1);
if (linkname_len <= 0 || linkname_len > MAXPATHLEN) {
rprintf(FERROR, "overflow: linkname_len=%d\n",
linkname_len - 1);
int flags, int filter_flags)
{
struct file_struct *file;
int flags, int filter_flags)
{
struct file_struct *file;
file = make_file(fname, flist, stp, flags, filter_flags);
if (!file)
file = make_file(fname, flist, stp, flags, filter_flags);
if (!file)
if (chmod_modes && !S_ISLNK(file->mode))
file->mode = tweak_mode(file->mode, chmod_modes);
if (chmod_modes && !S_ISLNK(file->mode))
file->mode = tweak_mode(file->mode, chmod_modes);
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && !S_ISLNK(file->mode) && f >= 0) {
+ sx.st.st_mode = file->mode;
+ sx.acc_acl = sx.def_acl = NULL;
+ if (get_acl(fname, &sx) < 0)
+ return NULL;
+ }
+#endif
+
maybe_emit_filelist_progress(flist->count + flist_count_offset);
flist_expand(flist);
flist->files[flist->count++] = file;
maybe_emit_filelist_progress(flist->count + flist_count_offset);
flist_expand(flist);
flist->files[flist->count++] = file;
- past_and_present = cur_flist->ndx_start - first_flist->ndx_start
- + cur_flist->count;
- while (file_total - past_and_present < at_least) {
+ if (cur_flist->next) {
+ flist = first_flist->prev; /* the newest flist */
+ future_cnt = flist->count
+ + flist->ndx_start - cur_flist->next->ndx_start;
+ } else
+ future_cnt = 0;
+ while (future_cnt < at_least) {
flist = flist_new(0, "send_extra_file_list");
start_write = stats.total_written;
flist = flist_new(0, "send_extra_file_list");
start_write = stats.total_written;
change_local_filter_dir(fbuf, dlen, send_dir_depth);
send_directory(f, flist, send_dir_ndx, fbuf, dlen, FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
write_byte(f, 0);
clean_flist(flist, 0, 0);
file_total += flist->count;
change_local_filter_dir(fbuf, dlen, send_dir_depth);
send_directory(f, flist, send_dir_ndx, fbuf, dlen, FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
write_byte(f, 0);
clean_flist(flist, 0, 0);
file_total += flist->count;
rprintf(FLOG, "building file list\n");
if (show_filelist_p())
start_filelist_progress("building file list");
rprintf(FLOG, "building file list\n");
if (show_filelist_p())
start_filelist_progress("building file list");
rprintf(FCLIENT, "sending incremental file list\n");
start_write = stats.total_written;
rprintf(FCLIENT, "sending incremental file list\n");
start_write = stats.total_written;
dir_flist = flist_new(FLIST_TEMP, "send_file_list");
flags = FLAG_DIVERT_DIRS;
} else {
dir_flist = flist_new(FLIST_TEMP, "send_file_list");
flags = FLAG_DIVERT_DIRS;
} else {
if (fn != p || (*lp && *lp != '/')) {
int save_copy_links = copy_links;
int save_xfer_dirs = xfer_dirs;
if (fn != p || (*lp && *lp != '/')) {
int save_copy_links = copy_links;
int save_xfer_dirs = xfer_dirs;
copy_links |= copy_unsafe_links;
xfer_dirs = 1;
while ((slash = strchr(slash+1, '/')) != 0) {
copy_links |= copy_unsafe_links;
xfer_dirs = 1;
while ((slash = strchr(slash+1, '/')) != 0) {
struct file_struct *file;
int top_flags = FLAG_TOP_DIR | FLAG_XFER_DIR
| (is_dot_dir ? 0 : flags)
struct file_struct *file;
int top_flags = FLAG_TOP_DIR | FLAG_XFER_DIR
| (is_dot_dir ? 0 : flags)
file = send_file_name(f, flist, fbuf, &st,
top_flags, ALL_FILTERS);
file = send_file_name(f, flist, fbuf, &st,
top_flags, ALL_FILTERS);
send_if_directory(f, flist, file, fbuf, len, flags);
} else
send_file_name(f, flist, fbuf, &st, flags, ALL_FILTERS);
send_if_directory(f, flist, file, fbuf, len, flags);
} else
send_file_name(f, flist, fbuf, &st, flags, ALL_FILTERS);
write_byte(f, 0); /* Indicate end of file list */
#ifdef SUPPORT_HARD_LINKS
write_byte(f, 0); /* Indicate end of file list */
#ifdef SUPPORT_HARD_LINKS
* kept. For incremental mode, the sender also removes duplicates
* in this initial file-list so that it avoids re-sending duplicated
* directories. */
* kept. For incremental mode, the sender also removes duplicates
* in this initial file-list so that it avoids re-sending duplicated
* directories. */
add_dirs_to_tree(-1, 0, dir_flist->count - 1);
if (file_total == 1) {
/* If we're creating incremental file-lists and there
* was just 1 item in the first file-list, send 1 more
* file-list to check if this is a 1-file xfer. */
if (send_dir_ndx < 0)
add_dirs_to_tree(-1, 0, dir_flist->count - 1);
if (file_total == 1) {
/* If we're creating incremental file-lists and there
* was just 1 item in the first file-list, send 1 more
* file-list to check if this is a 1-file xfer. */
if (send_dir_ndx < 0)
rprintf(FLOG, "receiving file list\n");
if (show_filelist_p())
start_filelist_progress("receiving file list");
rprintf(FLOG, "receiving file list\n");
if (show_filelist_p())
start_filelist_progress("receiving file list");
rprintf(FCLIENT, "receiving incremental file list\n");
start_read = stats.total_read;
rprintf(FCLIENT, "receiving incremental file list\n");
start_read = stats.total_read;
if (flist->ndx_start == 0)
dir_flist = flist_new(FLIST_TEMP, "recv_file_list");
dstart = dir_flist->count;
if (flist->ndx_start == 0)
dir_flist = flist_new(FLIST_TEMP, "recv_file_list");
dstart = dir_flist->count;
flags |= read_byte(f) << 8;
file = recv_file_entry(flist, flags, f);
flags |= read_byte(f) << 8;
file = recv_file_entry(flist, flags, f);
qsort(dir_flist->files + dstart, dir_flist->count - dstart,
sizeof dir_flist->files[0], (int (*)())file_compare);
} else if (f >= 0)
qsort(dir_flist->files + dstart, dir_flist->count - dstart,
sizeof dir_flist->files[0], (int (*)())file_compare);
} else if (f >= 0)