Commit de6ab501 authored by Wayne Davison's avatar Wayne Davison

Pass the 'f' compatibility flag to the server (via -e)

so that 3.0.7 knows we support the safer flist-xfer method.
parent 4286ea60
...@@ -30,10 +30,6 @@ Changes since 3.0.4: ...@@ -30,10 +30,6 @@ Changes since 3.0.4:
BUG FIXES: BUG FIXES:
- Fixed a bug in incremental recursion transfers where an I/O error might
not get noticed in time for the receiving side to disable deletions
(requires protocol 31).
- Changed the way --progress overwrites its prior output in order to make - Changed the way --progress overwrites its prior output in order to make
it nearly impossible for the progress to get overwritten by an error. it nearly impossible for the progress to get overwritten by an error.
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
int remote_protocol = 0; int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */ int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0; int inc_recurse = 0;
int use_safe_inc_flist = 0;
extern int am_server; extern int am_server;
extern int am_sender; extern int am_sender;
...@@ -72,6 +73,7 @@ int filesfrom_convert = 0; ...@@ -72,6 +73,7 @@ int filesfrom_convert = 0;
#define CF_INC_RECURSE (1<<0) #define CF_INC_RECURSE (1<<0)
#define CF_SYMLINK_TIMES (1<<1) #define CF_SYMLINK_TIMES (1<<1)
#define CF_SYMLINK_ICONV (1<<2) #define CF_SYMLINK_ICONV (1<<2)
#define CF_SAFE_FLIST (1<<3)
static const char *client_info; static const char *client_info;
...@@ -254,10 +256,11 @@ void setup_protocol(int f_out,int f_in) ...@@ -254,10 +256,11 @@ void setup_protocol(int f_out,int f_in)
#ifdef ICONV_OPTION #ifdef ICONV_OPTION
compat_flags |= CF_SYMLINK_ICONV; compat_flags |= CF_SYMLINK_ICONV;
#endif #endif
if (local_server || strchr(client_info, 'f') != NULL)
compat_flags |= CF_SAFE_FLIST;
write_byte(f_out, compat_flags); write_byte(f_out, compat_flags);
} else { } else
compat_flags = read_byte(f_in); compat_flags = read_byte(f_in);
}
/* The inc_recurse var MUST be set to 0 or 1. */ /* The inc_recurse var MUST be set to 0 or 1. */
inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0; inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
if (am_sender) { if (am_sender) {
...@@ -281,6 +284,7 @@ void setup_protocol(int f_out,int f_in) ...@@ -281,6 +284,7 @@ void setup_protocol(int f_out,int f_in)
read_batch ? "batch file" : "connection"); read_batch ? "batch file" : "connection");
exit_cleanup(RERR_SYNTAX); exit_cleanup(RERR_SYNTAX);
} }
use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
need_messages_from_generator = 1; need_messages_from_generator = 1;
#ifdef CAN_SET_SYMLINK_TIMES #ifdef CAN_SET_SYMLINK_TIMES
} else if (!am_sender) { } else if (!am_sender) {
......
...@@ -50,6 +50,7 @@ extern int preserve_links; ...@@ -50,6 +50,7 @@ extern int preserve_links;
extern int preserve_hard_links; extern int preserve_hard_links;
extern int preserve_devices; extern int preserve_devices;
extern int preserve_specials; extern int preserve_specials;
extern int delete_during;
extern int missing_args; extern int missing_args;
extern int uid_ndx; extern int uid_ndx;
extern int gid_ndx; extern int gid_ndx;
...@@ -65,6 +66,7 @@ extern int copy_unsafe_links; ...@@ -65,6 +66,7 @@ extern int copy_unsafe_links;
extern int protocol_version; extern int protocol_version;
extern int sanitize_paths; extern int sanitize_paths;
extern int munge_symlinks; extern int munge_symlinks;
extern int use_safe_inc_flist;
extern int need_unsorted_flist; extern int need_unsorted_flist;
extern int sender_symlink_iconv; extern int sender_symlink_iconv;
extern int output_needs_newline; extern int output_needs_newline;
...@@ -1872,6 +1874,15 @@ done: ...@@ -1872,6 +1874,15 @@ done:
filter_list = save_filter_list; filter_list = save_filter_list;
} }
static NORETURN void fatal_unsafe_io_error(void)
{
/* This (sadly) can only happen when pushing data because
* the sender does not know about what kind of delete
* is in effect on the receiving side when pulling. */
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-during issue with a pre-3.0.7 receiver.\n");
exit_cleanup(RERR_UNSUPPORTED);
}
static void send1extra(int f, struct file_struct *file, struct file_list *flist) static void send1extra(int f, struct file_struct *file, struct file_list *flist)
{ {
char fbuf[MAXPATHLEN]; char fbuf[MAXPATHLEN];
...@@ -1987,11 +1998,15 @@ void send_extra_file_list(int f, int at_least) ...@@ -1987,11 +1998,15 @@ void send_extra_file_list(int f, int at_least)
dp = F_DIR_NODE_P(file); dp = F_DIR_NODE_P(file);
} }
if (protocol_version < 31 || io_error == save_io_error || ignore_errors) if (io_error == save_io_error || ignore_errors)
write_byte(f, 0); write_byte(f, 0);
else { else if (use_safe_inc_flist) {
write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST); write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
write_varint(f, io_error); write_varint(f, io_error);
} else {
if (delete_during)
fatal_unsafe_io_error();
write_byte(f, 0);
} }
if (need_unsorted_flist) { if (need_unsorted_flist) {
...@@ -2313,11 +2328,15 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) ...@@ -2313,11 +2328,15 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
start_tv = end_tv; start_tv = end_tv;
/* Indicate end of file list */ /* Indicate end of file list */
if (protocol_version < 31 || io_error == 0 || ignore_errors) if (io_error == 0 || ignore_errors)
write_byte(f, 0); write_byte(f, 0);
else { else if (use_safe_inc_flist) {
write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST); write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
write_varint(f, io_error); write_varint(f, io_error);
} else {
if (delete_during && inc_recurse)
fatal_unsafe_io_error();
write_byte(f, 0);
} }
#ifdef SUPPORT_HARD_LINKS #ifdef SUPPORT_HARD_LINKS
...@@ -2357,7 +2376,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) ...@@ -2357,7 +2376,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
/* send the io_error flag */ /* send the io_error flag */
if (protocol_version < 30) if (protocol_version < 30)
write_int(f, ignore_errors ? 0 : io_error); write_int(f, ignore_errors ? 0 : io_error);
else if (io_error && protocol_version == 30 && !ignore_errors) else if (!use_safe_inc_flist && io_error && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error); send_msg_int(MSG_IO_ERROR, io_error);
if (disable_buffering) if (disable_buffering)
...@@ -2443,7 +2462,7 @@ struct file_list *recv_file_list(int f) ...@@ -2443,7 +2462,7 @@ struct file_list *recv_file_list(int f)
if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) { if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
int err; int err;
if (protocol_version < 31) { if (!use_safe_inc_flist) {
rprintf(FERROR, "Invalid flist flag: %x\n", flags); rprintf(FERROR, "Invalid flist flag: %x\n", flags);
exit_cleanup(RERR_PROTOCOL); exit_cleanup(RERR_PROTOCOL);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment