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 <wa...@opencoder.net> Date: Fri Jun 26 16:51:30 2020 -0700 Negotation env lists can specify "client & server" commit d07c2992d1b672ac8524e462fcb5f4bf223de768 Author: Wayne Davison <wa...@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. _______________________________________________ rsync-cvs mailing list rsync-cvs@lists.samba.org https://lists.samba.org/mailman/listinfo/rsync-cvs