]> git.ipfire.org Git - thirdparty/rsync.git/blobdiff - compat.c
Some indentation fixes.
[thirdparty/rsync.git] / compat.c
index c555732c33c92dc4c390d69a38724613256afa9c..855eae9824c05eeac3964be69a92d581e9041e2d 100644 (file)
--- a/compat.c
+++ b/compat.c
@@ -47,16 +47,14 @@ extern int preserve_xattrs;
 extern int xfer_flags_as_varint;
 extern int need_messages_from_generator;
 extern int delete_mode, delete_before, delete_during, delete_after;
-extern int xfersum_type;
-extern int checksum_type;
 extern int do_compression;
+extern int do_compression_level;
 extern char *shell_cmd;
 extern char *partial_dir;
-extern char *dest_option;
 extern char *files_from;
 extern char *filesfrom_host;
-extern char *checksum_choice;
-extern char *compress_choice;
+extern const char *checksum_choice;
+extern const char *compress_choice;
 extern filter_rule_list filter_list;
 extern int need_unsorted_flist;
 #ifdef ICONV_OPTION
@@ -89,6 +87,12 @@ int filesfrom_convert = 0;
 
 struct name_num_obj valid_compressions = {
        "compress", NULL, NULL, 0, 0, {
+#ifdef SUPPORT_ZSTD
+               { CPRES_ZSTD, "zstd", NULL },
+#endif
+#ifdef SUPPORT_LZ4
+               { CPRES_LZ4, "lz4", NULL },
+#endif
                { CPRES_ZLIBX, "zlibx", NULL },
                { CPRES_ZLIB, "zlib", NULL },
                { CPRES_NONE, "none", NULL },
@@ -174,17 +178,26 @@ void parse_compress_choice(int final_call)
        else
                do_compression = CPRES_NONE;
 
+       if (do_compression != CPRES_NONE && final_call)
+               init_compression_level(); /* There's a chance this might turn compression off! */
+
        if (do_compression == CPRES_NONE)
                compress_choice = NULL;
 
-       if (final_call && DEBUG_GTE(NSTR, am_server ? 2 : 1)) {
-               const char *c_s = am_server ? "Server" : "Client";
-               if (valid_compressions.negotiated_name)
-                       rprintf(FINFO, "%s negotiated compress: %s\n", c_s, valid_compressions.negotiated_name);
-               else {
-                       struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression);
-                       rprintf(FINFO, "%s compress: %s\n", c_s, nni ? nni->name : "UNKNOWN");
-               }
+       /* Snag the compression name for both write_batch's option output & the following debug output. */
+       if (valid_compressions.negotiated_name)
+               compress_choice = valid_compressions.negotiated_name;
+       else if (compress_choice == NULL) {
+               struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression);
+               compress_choice = nni ? nni->name : "UNKNOWN";
+       }
+
+       if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)
+        && (do_compression != CPRES_NONE || do_compression_level != CLVL_NOT_SPECIFIED)) {
+               rprintf(FINFO, "%s%s compress: %s (level %d)\n",
+                       am_server ? "Server" : "Client",
+                       valid_compressions.negotiated_name ? " negotiated" : "",
+                       compress_choice, do_compression_level);
        }
 }
 
@@ -256,7 +269,7 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
                                struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
                                if (nni && !nno->saw[nni->num]) {
                                        nno->saw[nni->num] = ++cnt;
-                                       if (nni->main_name && *nni->main_name) {
+                                       if (nni->main_name) {
                                                to = tok + strlcpy(tok, nni->main_name, tobuf_len - (tok - tobuf));
                                                if (to - tobuf >= tobuf_len) {
                                                        to = tok - 1;
@@ -294,7 +307,7 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
        if (len < 0)
                len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN);
 
-       if (DEBUG_GTE(NSTR, am_server ? 4 : 2)) {
+       if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
                if (am_server)
                        rprintf(FINFO, "Client %s list (on server): %s\n", nno->type, tmpbuf);
                else
@@ -329,10 +342,53 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
        exit_cleanup(RERR_UNSUPPORTED);
 }
 
+/* The saw buffer is initialized and used to store ordinal values from 1 to N
+ * for the order of the args in the array.  If dup_markup == '\0', duplicates
+ * are removed otherwise the char is prefixed to the duplicate term and, if it
+ * is an opening paren/bracket/brace, the matching closing char is suffixed. */
+int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len, char dup_markup)
+{
+       struct name_num_item *nni;
+       int len = 0, cnt = 0;
+       char delim = '\0', post_delim;
+
+       switch (dup_markup) {
+       case '(': post_delim = ')'; break;
+       case '[': post_delim = ']'; break;
+       case '{': post_delim = '}'; break;
+       default: post_delim = '\0'; break;
+       }
+
+       init_nno_saw(nno, 0);
+
+       for (nni = nno->list, len = 0; nni->name; nni++) {
+               if (nni->main_name) {
+                       if (!dup_markup)
+                               continue;
+                       delim = dup_markup;
+               }
+               if (len)
+                       to_buf[len++]= ' ';
+               if (delim) {
+                       to_buf[len++]= delim;
+                       delim = post_delim;
+               }
+               len += strlcpy(to_buf+len, nni->name, to_buf_len - len);
+               if (len >= to_buf_len - 3)
+                       exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE... */
+               if (delim) {
+                       to_buf[len++]= delim;
+                       delim = '\0';
+               }
+               nno->saw[nni->num] = ++cnt;
+       }
+
+       return len;
+}
+
 static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *env_name)
 {
        char tmpbuf[MAX_NSTR_STRLEN];
-       struct name_num_item *nni;
        const char *list_str = getenv(env_name);
        int len, fail_if_empty = list_str && strstr(list_str, "FAIL");
 
@@ -344,9 +400,8 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
                return;
        }
 
-       init_nno_saw(nno, 0);
-
        if (list_str && *list_str && (!am_server || local_server)) {
+               init_nno_saw(nno, 0);
                len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
                if (fail_if_empty && !len)
                        len = strlcpy(tmpbuf, "FAIL", MAX_NSTR_STRLEN);
@@ -354,21 +409,10 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
        } else
                list_str = NULL;
 
-       if (!list_str || !*list_str) {
-               int cnt = 0;
-               for (nni = nno->list, len = 0; nni->name; nni++) {
-                       if (nni->main_name)
-                               continue;
-                       if (len)
-                               tmpbuf[len++]= ' ';
-                       len += strlcpy(tmpbuf+len, nni->name, MAX_NSTR_STRLEN - len);
-                       if (len >= (int)MAX_NSTR_STRLEN - 1)
-                               exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE... */
-                       nno->saw[nni->num] = ++cnt;
-               }
-       }
+       if (!list_str || !*list_str)
+               len = get_default_nno_list(nno, tmpbuf, MAX_NSTR_STRLEN, '\0');
 
-       if (DEBUG_GTE(NSTR, am_server ? 4 : 2)) {
+       if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
                if (am_server)
                        rprintf(FINFO, "Server %s list (on server): %s\n", nno->type, tmpbuf);
                else
@@ -378,8 +422,7 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
        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. */
-               if (!read_batch)
-                       recv_negotiate_str(-1, nno, tmpbuf, len);
+               recv_negotiate_str(-1, nno, tmpbuf, len);
        } else {
                /* 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. */
@@ -401,17 +444,11 @@ static void negotiate_the_strings(int f_in, int f_out)
                char tmpbuf[MAX_NSTR_STRLEN];
                recv_negotiate_str(f_in, &valid_checksums, tmpbuf, -1);
        }
-       if (valid_checksums.negotiated_name)
-               xfersum_type = checksum_type = valid_checksums.negotiated_num;
 
        if (valid_compressions.saw) {
                char tmpbuf[MAX_NSTR_STRLEN];
                recv_negotiate_str(f_in, &valid_compressions, tmpbuf, -1);
        }
-#if 0
-       if (valid_compressions.negotiated_name)
-               compress_type = valid_checksums.negotiated_num;
-#endif
 }
 
 void setup_protocol(int f_out,int f_in)
@@ -494,16 +531,16 @@ void setup_protocol(int f_out,int f_in)
                        append_mode = 2;
                if (preserve_acls && !local_server) {
                        rprintf(FERROR,
-                           "--acls requires protocol 30 or higher"
-                           " (negotiated %d).\n",
-                           protocol_version);
+                               "--acls requires protocol 30 or higher"
+                               " (negotiated %d).\n",
+                               protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
                if (preserve_xattrs && !local_server) {
                        rprintf(FERROR,
-                           "--xattrs requires protocol 30 or higher"
-                           " (negotiated %d).\n",
-                           protocol_version);
+                               "--xattrs requires protocol 30 or higher"
+                               " (negotiated %d).\n",
+                               protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
        }
@@ -518,33 +555,33 @@ void setup_protocol(int f_out,int f_in)
        if (protocol_version < 29) {
                if (fuzzy_basis) {
                        rprintf(FERROR,
-                           "--fuzzy requires protocol 29 or higher"
-                           " (negotiated %d).\n",
-                           protocol_version);
+                               "--fuzzy requires protocol 29 or higher"
+                               " (negotiated %d).\n",
+                               protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (basis_dir_cnt && inplace) {
                        rprintf(FERROR,
-                           "%s with --inplace requires protocol 29 or higher"
-                           " (negotiated %d).\n",
-                           dest_option, protocol_version);
+                               "%s with --inplace requires protocol 29 or higher"
+                               " (negotiated %d).\n",
+                               alt_dest_opt(0), protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (basis_dir_cnt > 1) {
                        rprintf(FERROR,
-                           "Using more than one %s option requires protocol"
-                           " 29 or higher (negotiated %d).\n",
-                           dest_option, protocol_version);
+                               "Using more than one %s option requires protocol"
+                               " 29 or higher (negotiated %d).\n",
+                               alt_dest_opt(0), protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (prune_empty_dirs) {
                        rprintf(FERROR,
-                           "--prune-empty-dirs requires protocol 29 or higher"
-                           " (negotiated %d).\n",
-                           protocol_version);
+                               "--prune-empty-dirs requires protocol 29 or higher"
+                               " (negotiated %d).\n",
+                               protocol_version);
                        exit_cleanup(RERR_PROTOCOL);
                }
        } else if (protocol_version >= 30) {
@@ -603,8 +640,8 @@ void setup_protocol(int f_out,int f_in)
                if (inc_recurse && !allow_inc_recurse) {
                        /* This should only be able to happen in a batch. */
                        fprintf(stderr,
-                           "Incompatible options specified for inc-recursive %s.\n",
-                           read_batch ? "batch file" : "connection");
+                               "Incompatible options specified for inc-recursive %s.\n",
+                               read_batch ? "batch file" : "connection");
                        exit_cleanup(RERR_SYNTAX);
                }
                use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
@@ -647,14 +684,11 @@ void setup_protocol(int f_out,int f_in)
                checksum_seed = read_int(f_in);
        }
 
-       init_flist();
-}
+       parse_checksum_choice(1); /* Sets checksum_type & xfersum_type */
+       parse_compress_choice(1); /* Sets do_compression */
 
-void maybe_write_negotiated_strings(int batch_fd)
-{
-       if (valid_checksums.negotiated_name)
-               write_vstring(batch_fd, valid_checksums.negotiated_name, strlen(valid_checksums.negotiated_name));
+       if (write_batch && !am_server)
+               write_batch_shell_file();
 
-       if (valid_compressions.negotiated_name)
-               write_vstring(batch_fd, valid_compressions.negotiated_name, strlen(valid_compressions.negotiated_name));
+       init_flist();
 }