[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Sat Jun 27 01:00:33 UTC 2020


The branch, master has been updated
       via  ab29ee9c Negotation env lists can specify "client & server"
       via  d07c2992 A few more simple changes & fixes.
      from  b1a8b09c Some man page changes.

https://git.samba.org/?p=rsync.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ab29ee9c44ef8d58bd2a2bf1cf0e911c71a92104
Author: Wayne Davison <wayne at opencoder.net>
Date:   Fri Jun 26 16:51:30 2020 -0700

    Negotation env lists can specify "client & server"

commit d07c2992d1b672ac8524e462fcb5f4bf223de768
Author: Wayne Davison <wayne at opencoder.net>
Date:   Fri Jun 26 13:10:10 2020 -0700

    A few more simple changes & fixes.

-----------------------------------------------------------------------

Summary of changes:
 NEWS.md    |  3 ++-
 batch.c    |  8 -------
 compat.c   | 76 ++++++++++++++++++++++++++++++++++++++++++--------------------
 ifuncs.h   |  2 +-
 options.c  |  2 +-
 rsync.1.md | 21 ++++++++++++-----
 rsync.h    | 12 +++++-----
 util2.c    |  4 ++--
 8 files changed, 80 insertions(+), 48 deletions(-)


Changeset truncated at 500 lines:

diff --git a/NEWS.md b/NEWS.md
index 2d81eb66..d579b955 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -17,7 +17,8 @@ Protocol: 31 (unchanged)
 ### ENHANCEMENTS:
 
  - Allow the server side to restrict checksum & compression choices via
-   the same environment variables the client uses.
+   the same environment variables the client uses.  Allow the env vars
+   to be divided into "client list & server list" by the "`&`" char.
 
  - Simplify how the negotiation environment variables apply to older rsync
    versions.
diff --git a/batch.c b/batch.c
index 805acc6f..582c8c16 100644
--- a/batch.c
+++ b/batch.c
@@ -269,14 +269,6 @@ void write_batch_shell_file(void)
 			err |= write_opt("--exclude-from", "-");
 	}
 
-	/* We need to make sure that any protocol-based or negotiated choices get accurately
-	 * reflected in the options we save AND that we avoid any need for --read-batch to
-	 * do a string-based negotiation (since we don't write them into the file). */
-	if (do_compression)
-		err |= write_opt("--compress-choice", compress_choice);
-	if (strchr(checksum_choice, ',') || xfersum_type != parse_csum_name(NULL, -1))
-		err |= write_opt("--checksum-choice", checksum_choice);
-
 	/* Elide the filename args from the option list, but scan for them in reverse. */
 	for (i = raw_argc-1, j = cooked_argc-1; i > 0 && j >= 0; i--) {
 		if (strcmp(raw_argv[i], cooked_argv[j]) == 0) {
diff --git a/compat.c b/compat.c
index ba14a8c5..bf0b4e6d 100644
--- a/compat.c
+++ b/compat.c
@@ -20,6 +20,7 @@
  */
 
 #include "rsync.h"
+#include "itypes.h"
 
 extern int am_server;
 extern int am_sender;
@@ -109,6 +110,9 @@ struct name_num_obj valid_compressions = {
 #define CF_INPLACE_PARTIAL_DIR (1<<6)
 #define CF_VARINT_FLIST_FLAGS (1<<7)
 
+#define ENV_CHECKSUM 0
+#define ENV_COMPRESS 1
+
 static const char *client_info;
 
 /* The server makes sure that if either side only supports a pre-release
@@ -262,10 +266,14 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
 static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf, int tobuf_len)
 {
 	char *to = tobuf, *tok = NULL;
-	int cnt = 0;
+	int saw_tok = 0, cnt = 0;
 
 	while (1) {
-		if (*from == ' ' || !*from) {
+		int at_space = isSpace(from);
+		char ch = *from++;
+		if (ch == '&')
+			ch = '\0';
+		if (!ch || at_space) {
 			if (tok) {
 				struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
 				if (nni && !nno->saw[nni->num]) {
@@ -279,9 +287,10 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
 					}
 				} else
 					to = tok - (tok != tobuf);
+				saw_tok = 1;
 				tok = NULL;
 			}
-			if (!*from++)
+			if (!ch)
 				break;
 			continue;
 		}
@@ -294,10 +303,13 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
 			to = tok - (tok != tobuf);
 			break;
 		}
-		*to++ = *from++;
+		*to++ = ch;
 	}
 	*to = '\0';
 
+	if (saw_tok && to == tobuf)
+		return strlcpy(tobuf, "INVALID", MAX_NSTR_STRLEN);
+
 	return to - tobuf;
 }
 
@@ -349,14 +361,36 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
 	exit_cleanup(RERR_UNSUPPORTED);
 }
 
+static const char *getenv_nstr(int etype)
+{
+	const char *env_str = getenv(etype == ENV_COMPRESS ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
+
+	/* When writing a batch file, we always negotiate an old-style choice. */
+	if (write_batch) 
+		env_str = etype == ENV_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
+
+	if (am_server && env_str) {
+		char *cp = strchr(env_str, '&');
+		if (cp)
+			env_str = cp + 1;
+	}
+
+	return env_str;
+}
+
 /* If num2 < 0 then the caller is checking compress values, otherwise checksum values. */
 void validate_choice_vs_env(int num1, int num2)
 {
 	struct name_num_obj *nno = num2 < 0 ? &valid_compressions : &valid_checksums;
-	const char *list_str = getenv(num2 < 0 ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
+	const char *list_str = getenv_nstr(num2 < 0 ? ENV_COMPRESS : ENV_CHECKSUM);
 	char tmpbuf[MAX_NSTR_STRLEN];
 
-	if (!list_str || !*list_str)
+	if (!list_str)
+		return;
+
+	while (isSpace(list_str)) list_str++;
+
+	if (!*list_str)
 		return;
 
 	init_nno_saw(nno, 0);
@@ -422,17 +456,15 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
 	return len;
 }
 
-static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *env_name)
+static void send_negotiate_str(int f_out, struct name_num_obj *nno, int etype)
 {
 	char tmpbuf[MAX_NSTR_STRLEN];
-	const char *list_str = getenv(env_name);
+	const char *list_str = getenv_nstr(etype);
 	int len;
 
 	if (list_str && *list_str) {
 		init_nno_saw(nno, 0);
 		len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
-		if (!len)
-			len = strlcpy(tmpbuf, "FAIL", MAX_NSTR_STRLEN);
 		list_str = tmpbuf;
 	} else
 		list_str = NULL;
@@ -447,15 +479,10 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
 			rprintf(FINFO, "Client %s list (on client): %s\n", nno->type, tmpbuf);
 	}
 
-	if (local_server) {
-		/* A local server doesn't bother to send/recv the strings, it just constructs
-		 * and parses the same string on both sides. */
-		recv_negotiate_str(-1, nno, tmpbuf, len);
-	} else if (do_negotiated_strings) {
-		/* Each side sends their list of valid names to the other side and then both sides
-		 * pick the first name in the client's list that is also in the server's list. */
+	/* Each side sends their list of valid names to the other side and then both sides
+	 * pick the first name in the client's list that is also in the server's list. */
+	if (do_negotiated_strings)
 		write_vstring(f_out, tmpbuf, len);
-	}
 }
 
 static void negotiate_the_strings(int f_in, int f_out)
@@ -463,10 +490,10 @@ static void negotiate_the_strings(int f_in, int f_out)
 	/* We send all the negotiation strings before we start to read them to help avoid a slow startup. */
 
 	if (!checksum_choice)
-		send_negotiate_str(f_out, &valid_checksums, "RSYNC_CHECKSUM_LIST");
+		send_negotiate_str(f_out, &valid_checksums, ENV_CHECKSUM);
 
 	if (do_compression && !compress_choice)
-		send_negotiate_str(f_out, &valid_compressions, "RSYNC_COMPRESS_LIST");
+		send_negotiate_str(f_out, &valid_compressions, ENV_COMPRESS);
 
 	if (valid_checksums.saw) {
 		char tmpbuf[MAX_NSTR_STRLEN];
@@ -645,10 +672,8 @@ void setup_protocol(int f_out,int f_in)
 			if (local_server || strchr(client_info, 'I') != NULL)
 				compat_flags |= CF_INPLACE_PARTIAL_DIR;
 			if (local_server || strchr(client_info, 'v') != NULL) {
-				if (!write_batch || protocol_version >= 30) {
-					do_negotiated_strings = 1;
-					compat_flags |= CF_VARINT_FLIST_FLAGS;
-				}
+				do_negotiated_strings = 1;
+				compat_flags |= CF_VARINT_FLIST_FLAGS;
 			}
 			if (strchr(client_info, 'V') != NULL) { /* Support a pre-release 'V' that got superseded */
 				if (!write_batch)
@@ -697,6 +722,9 @@ void setup_protocol(int f_out,int f_in)
 #endif
 	}
 
+	if (read_batch)
+		do_negotiated_strings = 0;
+
 	if (need_unsorted_flist && (!am_sender || inc_recurse))
 		unsort_ndx = ++file_extra_cnt;
 
diff --git a/ifuncs.h b/ifuncs.h
index 7f9bde09..099fd07d 100644
--- a/ifuncs.h
+++ b/ifuncs.h
@@ -105,7 +105,7 @@ free_stat_x(stat_x *sx_p)
 static inline char *my_strdup(const char *str, const char *file, int line)
 {
     int len = strlen(str)+1;
-    char *buf = _my_alloc(do_malloc, len, 1, file, line);
+    char *buf = my_alloc(do_malloc, len, 1, file, line);
     memcpy(buf, str, len);
     return buf;
 }
diff --git a/options.c b/options.c
index 141fa24f..0e2c0bb0 100644
--- a/options.c
+++ b/options.c
@@ -1301,7 +1301,7 @@ static ssize_t parse_size_arg(char *size_arg, char def_suf, const char *opt_name
 	while (reps--)
 		size *= mult;
 	size *= atof(size_arg);
-	if ((*arg == '+' || *arg == '-') && arg[1] == '1')
+	if ((*arg == '+' || *arg == '-') && arg[1] == '1' && arg != size_arg)
 		size += atoi(arg), arg += 2;
 	if (*arg)
 		goto failure;
diff --git a/rsync.1.md b/rsync.1.md
index e145efd0..3708e1e1 100644
--- a/rsync.1.md
+++ b/rsync.1.md
@@ -1506,7 +1506,10 @@ your home directory (remove the '=' for that).
     transfer checksum separately from the pre-transfer checksum, and it ignores
     "auto" and all unknown checksum names.  If the remote rsync is not new
     enough to handle a checksum negotiation list, its list is assumed to
-    consist of a single "md5" or "md4" item based on the protocol version.
+    consist of a single "md5" or "md4" item based on the protocol version.  If
+    the environment variable contains a "`&`" character, the string is
+    separated into the client list & server list, either one of which can be
+    empty (giving that side the default list).
 
     The use of the `--checksum-choice` option overrides this environment list.
 
@@ -1740,7 +1743,7 @@ your home directory (remove the '=' for that).
     multiples of 1024.  If you use a two-letter suffix that ends with a "B"
     (e.g. "kb") then you get units that are multiples of 1000.
 
-    Finally, if the value ends with either "+1" or "-1", it will be offset by
+    Finally, if the string ends with either "+1" or "-1", it will be offset by
     one byte in the indicated direction.  The largest possible value is
     `8192P-1`.
 
@@ -2295,11 +2298,14 @@ your home directory (remove the '=' for that).
 
     When both sides of the transfer are at least 3.2.0, rsync chooses the first
     algorithm in the client's list of choices that is also in the server's list
-    of choices.  Your default order can be customized by setting the environment
+    of choices.  The default order can be customized by setting the environment
     variable RSYNC_COMPRESS_LIST to a space-separated list of acceptable
     compression names.  If no common compress choice is found, the client exits
-    with an error.  If the remote rsync is too old to support checksum negotiation,
-    its list is assumed to be "zlib".
+    with an error.  If the remote rsync is too old to support checksum
+    negotiation, its list is assumed to be "zlib".  If the environment variable
+    contains a "`&`" character, the string is separated into the client list &
+    server list, either one of which can be empty (giving that side the default
+    list).
 
     There are some older rsync versions that were configured to reject a `-z`
     option and require the use of `-zz` because their compression library was
@@ -3104,6 +3110,11 @@ your home directory (remove the '=' for that).
     with `--read-batch`.  See the "BATCH MODE" section for details, and also
     the `--only-write-batch` option.
 
+    This option overrides the negotiated checksum & compress lists and always
+    negotiates a choice based on old-school md5/md4/zlib choices.  If you want
+    a more modern choice, use the `--checksum-choice` (`--cc`) and/or
+    `--compress-choice` (`--zc`) options.
+
 0.  `--only-write-batch=FILE`
 
     Works like `--write-batch`, except that no updates are made on the
diff --git a/rsync.h b/rsync.h
index ef2668d1..22a3a949 100644
--- a/rsync.h
+++ b/rsync.h
@@ -1265,13 +1265,13 @@ extern int errno;
 extern char *do_malloc;
 
 /* Convenient wrappers for malloc and realloc.  Use them. */
-#define new(type) ((type*)_my_alloc(do_malloc, 1, sizeof (type), __FILE__, __LINE__))
-#define new0(type) ((type*)_my_alloc(NULL, 1, sizeof (type), __FILE__, __LINE__))
-#define realloc_buf(ptr, num) _my_alloc((ptr), (num), 1, __FILE__, __LINE__)
+#define new(type) ((type*)my_alloc(do_malloc, sizeof (type), 1, __FILE__, __LINE__))
+#define new0(type) ((type*)my_alloc(NULL, sizeof (type), 1, __FILE__, __LINE__))
+#define realloc_buf(ptr, num) my_alloc((ptr), (num), 1, __FILE__, __LINE__)
 
-#define new_array(type, num) ((type*)_my_alloc(do_malloc, (num), sizeof (type), __FILE__, __LINE__))
-#define new_array0(type, num) ((type*)_my_alloc(NULL, (num), sizeof (type), __FILE__, __LINE__))
-#define realloc_array(ptr, type, num) ((type*)_my_alloc((ptr), (num), sizeof (type), __FILE__, __LINE__))
+#define new_array(type, num) ((type*)my_alloc(do_malloc, (num), sizeof (type), __FILE__, __LINE__))
+#define new_array0(type, num) ((type*)my_alloc(NULL, (num), sizeof (type), __FILE__, __LINE__))
+#define realloc_array(ptr, type, num) ((type*)my_alloc((ptr), (num), sizeof (type), __FILE__, __LINE__))
 
 #define strdup(s) my_strdup(s, __FILE__, __LINE__)
 
diff --git a/util2.c b/util2.c
index 10b7e4b6..181dbd7d 100644
--- a/util2.c
+++ b/util2.c
@@ -71,7 +71,7 @@ int msleep(int t)
 	return True;
 }
 
-/* We convert a num manually because need %lld precision, and that's not a portable sprintf() escape. */
+/* Convert a num manually because the needed %lld precision is not a portable sprintf() escape. */
 char *num_to_byte_string(ssize_t num)
 {
 	char buf[128], *s = buf + sizeof buf - 1;
@@ -84,7 +84,7 @@ char *num_to_byte_string(ssize_t num)
 	return strdup(s);
 }
 
-void *_my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
+void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
 {
 	if (num >= max_alloc/size) {
 		if (!file)


-- 
The rsync repository.



More information about the rsync-cvs mailing list