X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a7c1fa0049d2fbee5fde35b4cb2fbea4bd7545db..b3bf9b9df95137a3a43248be9599d919b04877af:/compat.c diff --git a/compat.c b/compat.c index 1717a3fa..6e000724 100644 --- a/compat.c +++ b/compat.c @@ -3,7 +3,7 @@ * * Copyright (C) Andrew Tridgell 1996 * Copyright (C) Paul Mackerras 1996 - * Copyright (C) 2004-2007 Wayne Davison + * Copyright (C) 2004-2009 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,6 @@ int remote_protocol = 0; int file_extra_cnt = 0; /* count of file-list extras that everyone gets */ int inc_recurse = 0; -extern int verbose; extern int am_server; extern int am_sender; extern int local_server; @@ -48,7 +47,7 @@ extern int preserve_acls; extern int preserve_xattrs; extern int need_messages_from_generator; extern int delete_mode, delete_before, delete_during, delete_after; -extern char *shell_cmd; /* contains VER.SUB string if client is a pre-release */ +extern char *shell_cmd; extern char *partial_dir; extern char *dest_option; extern char *files_from; @@ -57,15 +56,25 @@ extern struct filter_list_struct filter_list; extern int need_unsorted_flist; #ifdef ICONV_OPTION extern iconv_t ic_send, ic_recv; +extern char *iconv_opt; #endif /* These index values are for the file-list's extra-attribute array. */ int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx; +int receiver_symlink_times = 0; /* receiver can set the time on a symlink */ +int sender_symlink_iconv = 0; /* sender should convert symlink content */ + #ifdef ICONV_OPTION int filesfrom_convert = 0; #endif +#define CF_INC_RECURSE (1<<0) +#define CF_SYMLINK_TIMES (1<<1) +#define CF_SYMLINK_ICONV (1<<2) + +static const char *client_info; + /* The server makes sure that if either side only supports a pre-release * version of a protocol, that both sides must speak a compatible version * of that protocol for it to be advertised as available. */ @@ -79,8 +88,9 @@ static void check_sub_protocol(void) int our_sub = 0; #endif - if (!shell_cmd || !(dot = strchr(shell_cmd, '.')) - || !(their_protocol = atoi(shell_cmd)) + /* client_info starts with VER.SUB string if client is a pre-release. */ + if (!(their_protocol = atoi(client_info)) + || !(dot = strchr(client_info, '.')) || !(their_sub = atoi(dot+1))) { #if SUBPROTOCOL_VERSION != 0 if (our_sub) @@ -103,6 +113,8 @@ static void check_sub_protocol(void) void set_allow_inc_recurse(void) { + client_info = shell_cmd ? shell_cmd : ""; + if (!recurse || use_qsort) allow_inc_recurse = 0; else if (!am_sender @@ -110,7 +122,7 @@ void set_allow_inc_recurse(void) || delay_updates || prune_empty_dirs)) allow_inc_recurse = 0; else if (am_server && !local_server - && (!shell_cmd || strchr(shell_cmd, 'i') == NULL)) + && (strchr(client_info, 'i') == NULL)) allow_inc_recurse = 0; } @@ -147,7 +159,7 @@ void setup_protocol(int f_out,int f_in) exit_cleanup(RERR_PROTOCOL); } - if (verbose > 3) { + if (DEBUG_GTE(PROTO, 1)) { rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n", am_server? "Server" : "Client", remote_protocol, protocol_version); } @@ -233,12 +245,34 @@ void setup_protocol(int f_out,int f_in) exit_cleanup(RERR_PROTOCOL); } } else if (protocol_version >= 30) { - /* The inc_recurse var MUST be set to 0 or 1. */ + int compat_flags; if (am_server) { - inc_recurse = allow_inc_recurse ? 1 : 0; - write_byte(f_out, inc_recurse); + compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0; +#if defined HAVE_LUTIMES && defined HAVE_UTIMES + compat_flags |= CF_SYMLINK_TIMES; +#endif +#ifdef ICONV_OPTION + compat_flags |= CF_SYMLINK_ICONV; +#endif + write_byte(f_out, compat_flags); } else - inc_recurse = read_byte(f_in) ? 1 : 0; + compat_flags = read_byte(f_in); + /* The inc_recurse var MUST be set to 0 or 1. */ + inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0; + if (am_sender) { + receiver_symlink_times = am_server + ? strchr(client_info, 'L') != NULL + : !!(compat_flags & CF_SYMLINK_TIMES); + } +#if defined HAVE_LUTIMES && defined HAVE_UTIMES + else + receiver_symlink_times = 1; +#endif +#ifdef ICONV_OPTION + sender_symlink_iconv = iconv_opt && (am_server + ? strchr(client_info, 's') != NULL + : !!(compat_flags & CF_SYMLINK_ICONV)); +#endif if (inc_recurse && !allow_inc_recurse) { /* This should only be able to happen in a batch. */ fprintf(stderr, @@ -247,6 +281,10 @@ void setup_protocol(int f_out,int f_in) exit_cleanup(RERR_SYNTAX); } need_messages_from_generator = 1; +#if defined HAVE_LUTIMES && defined HAVE_UTIMES + } else if (!am_sender) { + receiver_symlink_times = 1; +#endif } if (need_unsorted_flist && (!am_sender || inc_recurse))