./configure (optional if already run)
make
-based-on: def595c55960504328b5bfa45c08c42a90382076
+based-on: 9a3449a3980421f84ac55498ba565bc112b20d6c
diff --git a/authenticate.c b/authenticate.c
--- a/authenticate.c
+++ b/authenticate.c
diff --git a/checksum.c b/checksum.c
--- a/checksum.c
+++ b/checksum.c
-@@ -42,48 +42,79 @@ extern int protocol_version;
+@@ -42,50 +42,83 @@ extern int protocol_version;
extern int proper_seed_order;
extern const char *checksum_choice;
+#define NNI_EVP (1<<1)
+#define NNI_EVP_OK (1<<2)
+
- struct name_num_obj valid_checksums = {
-- "checksum", NULL, NULL, 0, 0, {
-+ "checksum", NULL, 0, 0, {
+ struct name_num_item valid_checksums_items[] = {
#ifdef SUPPORT_XXH3
-- { CSUM_XXH3_128, "xxh128", NULL },
-- { CSUM_XXH3_64, "xxh3", NULL },
-+ { CSUM_XXH3_128, 0, "xxh128", NULL },
-+ { CSUM_XXH3_64, 0, "xxh3", NULL },
+- { CSUM_XXH3_128, "xxh128", NULL },
+- { CSUM_XXH3_64, "xxh3", NULL },
++ { CSUM_XXH3_128, 0, "xxh128", NULL },
++ { CSUM_XXH3_64, 0, "xxh3", NULL },
#endif
#ifdef SUPPORT_XXHASH
-- { CSUM_XXH64, "xxh64", NULL },
-- { CSUM_XXH64, "xxhash", NULL },
-+ { CSUM_XXH64, 0, "xxh64", NULL },
-+ { CSUM_XXH64, 0, "xxhash", NULL },
+- { CSUM_XXH64, "xxh64", NULL },
+- { CSUM_XXH64, "xxhash", NULL },
++ { CSUM_XXH64, 0, "xxh64", NULL },
++ { CSUM_XXH64, 0, "xxhash", NULL },
#endif
-- { CSUM_MD5, "md5", NULL },
-- { CSUM_MD4, "md4", NULL },
-- { CSUM_NONE, "none", NULL },
-- { 0, NULL, NULL }
-+ { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
-+ { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
-+ { CSUM_NONE, 0, "none", NULL },
-+ { 0, 0, NULL, NULL }
- }
+- { CSUM_MD5, "md5", NULL },
+- { CSUM_MD4, "md4", NULL },
+- { CSUM_NONE, "none", NULL },
+- { 0, NULL, NULL }
++ { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
++ { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
++ { CSUM_NONE, 0, "none", NULL },
++ { 0, 0, NULL, NULL }
+ };
+
+ struct name_num_obj valid_checksums = {
+- "checksum", NULL, NULL, 0, 0, valid_checksums_items
++ "checksum", NULL, 0, 0, valid_checksums_items
};
-int xfersum_type = 0; /* used for the file transfer checksums */
-int checksum_type = 0; /* used for the pre-transfer (--checksum) checksums */
++struct name_num_item valid_auth_checksums_items[] = {
++ { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
++ { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
++ { 0, 0, NULL, NULL }
++};
++
+struct name_num_obj valid_auth_checksums = {
-+ "daemon auth checksum", NULL, 0, 0, {
-+ { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
-+ { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
-+ { 0, 0, NULL, NULL }
-+ }
++ "daemon auth checksum", NULL, 0, 0, valid_auth_checksums_items
+};
+
+/* These cannot make use of openssl, so they're marked just as built-in */
+ { CSUM_MD4, NNI_BUILTIN, "md4", NULL };
+struct name_num_item implied_checksum_md5 =
+ { CSUM_MD5, NNI_BUILTIN, "md5", NULL };
-
++
+struct name_num_item *xfer_sum_nni; /* used for the transfer checksum2 computations */
+const EVP_MD *xfer_sum_evp_md;
+int xfer_sum_len;
+struct name_num_item *file_sum_nni; /* used for the pre-transfer --checksum computations */
+const EVP_MD *file_sum_evp_md;
+int file_sum_len;
-+
+
+#ifdef USE_OPENSSL
+EVP_MD_CTX *ctx_evp = NULL;
+#endif
nni = get_nni_by_name(&valid_checksums, name, len);
if (!nni) {
-@@ -91,44 +122,72 @@ int parse_csum_name(const char *name, int len)
+@@ -93,44 +126,72 @@ int parse_csum_name(const char *name, int len)
exit_cleanup(RERR_UNSUPPORTED);
}
checksum_choice);
}
}
-@@ -209,7 +268,24 @@ uint32 get_checksum1(char *buf1, int32 len)
+@@ -211,7 +272,24 @@ uint32 get_checksum1(char *buf1, int32 len)
void get_checksum2(char *buf, int32 len, char *sum)
{
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
-@@ -227,7 +303,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
+@@ -229,7 +307,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
}
#endif
case CSUM_MD5: {
uchar seedbuf[4];
md5_begin(&m5);
if (proper_seed_order) {
-@@ -247,20 +323,6 @@ void get_checksum2(char *buf, int32 len, char *sum)
+@@ -249,20 +327,6 @@ void get_checksum2(char *buf, int32 len, char *sum)
break;
}
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC: {
-@@ -293,7 +355,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
+@@ -295,7 +359,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
mdfour_update(&m, (uchar *)(buf1+i), len-i);
mdfour_result(&m, (uchar *)sum);
-@@ -311,15 +373,33 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -313,15 +377,33 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
int32 remainder;
int fd;
#ifdef SUPPORT_XXHASH
case CSUM_XXH64: {
static XXH64_state_t* state = NULL;
-@@ -379,7 +459,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -381,7 +463,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
}
#endif
case CSUM_MD5: {
md5_begin(&m5);
-@@ -394,23 +474,6 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -396,23 +478,6 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
break;
}
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC: {
-@@ -426,7 +489,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -428,7 +493,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
-@@ -434,7 +497,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -436,7 +501,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
}
default:
rprintf(FERROR, "Invalid checksum-choice for --checksum: %s (%d)\n",
exit_cleanup(RERR_UNSUPPORTED);
}
-@@ -443,30 +506,35 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -445,30 +510,35 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
}
static int32 sumresidue;
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
if (!xxh64_state && !(xxh64_state = XXH64_createState()))
-@@ -487,20 +555,16 @@ void sum_init(int csum_type, int seed)
+@@ -489,20 +559,16 @@ void sum_init(int csum_type, int seed)
break;
#endif
case CSUM_MD5:
sumresidue = 0;
SIVAL(s, 0, seed);
sum_update(s, 4);
-@@ -510,6 +574,8 @@ void sum_init(int csum_type, int seed)
+@@ -512,6 +578,8 @@ void sum_init(int csum_type, int seed)
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
}
/**
-@@ -522,7 +588,12 @@ void sum_init(int csum_type, int seed)
+@@ -524,7 +592,12 @@ void sum_init(int csum_type, int seed)
**/
void sum_update(const char *p, int32 len)
{
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
XXH64_update(xxh64_state, p, len);
-@@ -537,39 +608,35 @@ void sum_update(const char *p, int32 len)
+@@ -539,39 +612,35 @@ void sum_update(const char *p, int32 len)
break;
#endif
case CSUM_MD5:
break;
case CSUM_NONE:
break;
-@@ -578,13 +645,18 @@ void sum_update(const char *p, int32 len)
+@@ -580,13 +649,18 @@ void sum_update(const char *p, int32 len)
}
}
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64_digest(xxh64_state));
-@@ -602,22 +674,18 @@ int sum_end(char *sum)
+@@ -604,22 +678,18 @@ int sum_end(char *sum)
}
#endif
case CSUM_MD5:
break;
case CSUM_NONE:
*sum = '\0';
-@@ -625,33 +693,80 @@ int sum_end(char *sum)
+@@ -627,33 +697,85 @@ int sum_end(char *sum)
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
+ struct name_num_item *nni;
+#endif
+#ifdef USE_OPENSSL
-+ struct name_num_item *tmp_list[NNO_LIST_SIZE*2];
++ item_list tmp_list;
++ struct name_num_item **nni_list;
+ int pos, thru_pos;
+#endif
+
+ nni->num = CSUM_gone;
+ }
+ }
++ }
++#endif
++#ifdef USE_OPENSSL
++ memset(&tmp_list, 0, sizeof tmp_list);
++ for (nni = valid_checksums.list; nni->name; nni++) {
++ nni_list = EXPAND_ITEM_LIST(&tmp_list, struct name_num_item *, 20);
++ *nni_list = nni;
}
- sum_init(CSUM_XXH3_64, 0);
- sum_update(buf, 32816);
- continue;
- if (t != f)
- nni[t++] = nni[f];
-+#endif
-+#ifdef USE_OPENSSL
-+ pos = 0;
-+ for (nni = valid_checksums.list; nni->name; nni++)
-+ tmp_list[pos++] = nni;
-+ for (nni = valid_auth_checksums.list; nni->name; nni++)
-+ tmp_list[pos++] = nni;
-+ tmp_list[pos] = NULL;
++ for (nni = valid_auth_checksums.list; nni->name; nni++) {
++ nni_list = EXPAND_ITEM_LIST(&tmp_list, struct name_num_item *, 20);
++ *nni_list = nni;
++ }
+
-+ qsort(tmp_list, pos, sizeof (struct name_num_item*), nni_sorter);
++ nni_list = tmp_list.items;
++ qsort(tmp_list.items, tmp_list.count, sizeof (struct name_num_item*), nni_sorter);
+
-+ for (pos = 0; tmp_list[pos]; pos++) {
-+ nni = tmp_list[pos];
-+ for (thru_pos = pos; tmp_list[thru_pos+1]; thru_pos++) {
-+ const struct name_num_item *other = tmp_list[thru_pos+1];
++ for (pos = 0; (size_t)pos < tmp_list.count; pos++) {
++ nni = nni_list[pos];
++ for (thru_pos = pos; (size_t)thru_pos+1 < tmp_list.count; thru_pos++) {
++ const struct name_num_item *other = nni_list[thru_pos+1];
+ if (other->num != nni->num || other->flags != nni->flags)
+ break;
+ }
+ nni->num = CSUM_gone;
+ }
+ while (pos < thru_pos) {
-+ struct name_num_item *other = tmp_list[++pos];
++ struct name_num_item *other = nni_list[++pos];
+ other->num = nni->num;
+ other->flags = nni->flags;
}
/* These index values are for the file-list's extra-attribute array. */
int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
-@@ -92,17 +98,17 @@ int filesfrom_convert = 0;
- #define MAX_NSTR_STRLEN 256
+@@ -93,19 +99,19 @@ int filesfrom_convert = 0;
- struct name_num_obj valid_compressions = {
-- "compress", NULL, NULL, 0, 0, {
-+ "compress", NULL, 0, 0, {
+ struct name_num_item valid_compressions_items[] = {
#ifdef SUPPORT_ZSTD
-- { CPRES_ZSTD, "zstd", NULL },
-+ { CPRES_ZSTD, 0, "zstd", NULL },
+- { CPRES_ZSTD, "zstd", NULL },
++ { CPRES_ZSTD, 0, "zstd", NULL },
#endif
#ifdef SUPPORT_LZ4
-- { CPRES_LZ4, "lz4", NULL },
-+ { CPRES_LZ4, 0, "lz4", NULL },
+- { CPRES_LZ4, "lz4", NULL },
++ { CPRES_LZ4, 0, "lz4", NULL },
#endif
-- { CPRES_ZLIBX, "zlibx", NULL },
-- { CPRES_ZLIB, "zlib", NULL },
-- { CPRES_NONE, "none", NULL },
-- { 0, NULL, NULL }
-+ { CPRES_ZLIBX, 0, "zlibx", NULL },
-+ { CPRES_ZLIB, 0, "zlib", NULL },
-+ { CPRES_NONE, 0, "none", NULL },
-+ { 0, 0, NULL, NULL }
- }
+- { CPRES_ZLIBX, "zlibx", NULL },
+- { CPRES_ZLIB, "zlib", NULL },
+- { CPRES_NONE, "none", NULL },
+- { 0, NULL, NULL }
++ { CPRES_ZLIBX, 0, "zlibx", NULL },
++ { CPRES_ZLIB, 0, "zlib", NULL },
++ { CPRES_NONE, 0, "none", NULL },
++ { 0, 0, NULL, NULL }
+ };
+
+ struct name_num_obj valid_compressions = {
+- "compress", NULL, NULL, 0, 0, valid_compressions_items
++ "compress", NULL, 0, 0, valid_compressions_items
};
-@@ -125,11 +131,7 @@ static void check_sub_protocol(void)
+ #define CF_INC_RECURSE (1<<0)
+@@ -127,11 +133,7 @@ static void check_sub_protocol(void)
{
char *dot;
int their_protocol, their_sub;
/* client_info starts with VER.SUB string if client is a pre-release. */
if (!(their_protocol = atoi(client_info))
-@@ -176,8 +178,8 @@ void set_allow_inc_recurse(void)
+@@ -178,8 +180,8 @@ void set_allow_inc_recurse(void)
void parse_compress_choice(int final_call)
{
else if (compress_choice) {
struct name_num_item *nni = get_nni_by_name(&valid_compressions, compress_choice, -1);
if (!nni) {
-@@ -199,8 +201,8 @@ void parse_compress_choice(int final_call)
+@@ -201,8 +203,8 @@ void parse_compress_choice(int final_call)
compress_choice = NULL;
/* Snag the compression name for both write_batch's option output & the following debug output. */
else if (compress_choice == NULL) {
struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression);
compress_choice = nni ? nni->name : "UNKNOWN";
-@@ -210,7 +212,7 @@ void parse_compress_choice(int final_call)
+@@ -212,7 +214,7 @@ void parse_compress_choice(int final_call)
&& (do_compression != CPRES_NONE || do_compression_level != CLVL_NOT_SPECIFIED)) {
rprintf(FINFO, "%s%s compress: %s (level %d)\n",
am_server ? "Server" : "Client",
compress_choice, do_compression_level);
}
}
-@@ -223,6 +225,8 @@ struct name_num_item *get_nni_by_name(struct name_num_obj *nno, const char *name
+@@ -225,6 +227,8 @@ struct name_num_item *get_nni_by_name(struct name_num_obj *nno, const char *name
len = strlen(name);
for (nni = nno->list; nni->name; nni++) {
if (strncasecmp(name, nni->name, len) == 0 && nni->name[len] == '\0')
return nni;
}
-@@ -257,10 +261,12 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
+@@ -259,10 +263,12 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
if (!nno->saw) {
nno->saw = new_array0(uchar, nno->saw_len);
else
nno->saw[nni->num] = cnt;
}
-@@ -286,8 +292,8 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
+@@ -288,8 +294,8 @@ 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 (to - tobuf >= tobuf_len) {
to = tok - 1;
break;
-@@ -321,13 +327,44 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
+@@ -323,13 +329,44 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
return to - tobuf;
}
if (len < 0)
len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN);
-@@ -338,37 +375,8 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
+@@ -340,37 +377,8 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
rprintf(FINFO, "Server %s list (on client): %s\n", nno->type, tmpbuf);
}
if (!am_server || !do_negotiated_strings) {
char *cp = tmpbuf;
-@@ -464,8 +472,10 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
+@@ -466,8 +474,10 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
init_nno_saw(nno, 0);
for (nni = nno->list, len = 0; nni->name; nni++) {
continue;
delim = dup_markup;
}
-@@ -554,7 +564,7 @@ static void negotiate_the_strings(int f_in, int f_out)
+@@ -556,7 +566,7 @@ static void negotiate_the_strings(int f_in, int f_out)
/* If the other side is too old to negotiate, the above steps just made sure that
* the env didn't disallow the old algorithm. Mark things as non-negotiated. */
if (!do_negotiated_strings)
}
void setup_protocol(int f_out,int f_in)
-@@ -803,11 +813,73 @@ void setup_protocol(int f_out,int f_in)
+@@ -805,11 +815,73 @@ void setup_protocol(int f_out,int f_in)
checksum_seed = read_int(f_in);
}
#define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
#define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
-@@ -1162,17 +1163,19 @@ typedef struct {
+@@ -1162,16 +1163,16 @@ typedef struct {
#define NSTR_COMPRESS 1
struct name_num_item {
+ struct name_num_item *main_nni;
};
-+#define NNO_LIST_SIZE 10
-+
struct name_num_obj {
const char *type;
- const char *negotiated_name;
uchar *saw;
int saw_len;
- int negotiated_num;
-- struct name_num_item list[10]; /* we'll get a compile error/warning if this is ever too small */
-+ struct name_num_item list[NNO_LIST_SIZE]; /* we'll get a compile error/warning if this is ever too small */
+ struct name_num_item *list;
};
- #ifdef EXTERNAL_ZLIB
diff --git a/util2.c b/util2.c
--- a/util2.c
+++ b/util2.c