#include "rsync.h"
#include "itypes.h"
+#include "ifuncs.h"
extern int am_server;
extern int am_sender;
void set_allow_inc_recurse(void)
{
- client_info = shell_cmd ? shell_cmd : "";
+ if (!local_server)
+ client_info = shell_cmd ? shell_cmd : "";
+ else if (am_server) {
+ char buf[64];
+ maybe_add_e_option(buf, sizeof buf);
+ client_info = *buf ? strdup(buf+1) : ""; /* The +1 skips the leading "e". */
+ }
if (!recurse || use_qsort)
allow_inc_recurse = 0;
&& (delete_before || delete_after
|| delay_updates || prune_empty_dirs))
allow_inc_recurse = 0;
- else if (am_server && !local_server
- && (strchr(client_info, 'i') == NULL))
+ else if (am_server && strchr(client_info, 'i') == NULL)
allow_inc_recurse = 0;
}
atimes_ndx = (file_extra_cnt += EXTRA64_CNT);
if (preserve_crtimes)
crtimes_ndx = (file_extra_cnt += EXTRA64_CNT);
- if (am_sender) /* This is most likely in the in64 union as well. */
+ if (am_sender) /* This is most likely in the file_extras64 union as well. */
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
else
depth_ndx = ++file_extra_cnt;
#ifdef ICONV_OPTION
compat_flags |= CF_SYMLINK_ICONV;
#endif
- if (local_server || strchr(client_info, 'f') != NULL)
+ if (strchr(client_info, 'f') != NULL)
compat_flags |= CF_SAFE_FLIST;
- if (local_server || strchr(client_info, 'x') != NULL)
+ if (strchr(client_info, 'x') != NULL)
compat_flags |= CF_AVOID_XATTR_OPTIM;
- if (local_server || strchr(client_info, 'C') != NULL)
+ if (strchr(client_info, 'C') != NULL)
compat_flags |= CF_CHKSUM_SEED_FIX;
- if (local_server || strchr(client_info, 'I') != NULL)
+ if (strchr(client_info, 'I') != NULL)
compat_flags |= CF_INPLACE_PARTIAL_DIR;
- if (local_server || strchr(client_info, 'u') != NULL)
+ if (strchr(client_info, 'u') != NULL)
compat_flags |= CF_ID0_NAMES;
- if (local_server || strchr(client_info, 'v') != NULL) {
+ if (strchr(client_info, 'v') != NULL) {
do_negotiated_strings = 1;
compat_flags |= CF_VARINT_FLIST_FLAGS;
}
#endif
#ifdef ICONV_OPTION
sender_symlink_iconv = iconv_opt && (am_server
- ? local_server || strchr(client_info, 's') != NULL
+ ? strchr(client_info, 's') != NULL
: !!(compat_flags & CF_SYMLINK_ICONV));
#endif
if (inc_recurse && !allow_inc_recurse) {
set_allow_inc_recurse();
- /* We don't really know the actual protocol_version at this point,
- * but checking the pre-negotiated value allows the user to use a
- * --protocol=29 override to avoid the use of this -eFLAGS opt. */
- if (protocol_version >= 30) {
- /* Use "eFlags" alias so that cull_options doesn't think that these are no-arg option letters. */
-#define eFlags argstr
- /* We make use of the -e option to let the server know about
- * any pre-release protocol version && some behavior flags. */
- eFlags[x++] = 'e';
-#if SUBPROTOCOL_VERSION != 0
- if (protocol_version == PROTOCOL_VERSION) {
- x += snprintf(argstr+x, sizeof argstr - x,
- "%d.%d",
- PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
- } else
-#endif
- eFlags[x++] = '.';
- if (allow_inc_recurse)
- eFlags[x++] = 'i';
-#ifdef CAN_SET_SYMLINK_TIMES
- eFlags[x++] = 'L'; /* symlink time-setting support */
-#endif
-#ifdef ICONV_OPTION
- eFlags[x++] = 's'; /* symlink iconv translation support */
-#endif
- eFlags[x++] = 'f'; /* flist I/O-error safety support */
- eFlags[x++] = 'x'; /* xattr hardlink optimization not desired */
- eFlags[x++] = 'C'; /* support checksum seed order fix */
- eFlags[x++] = 'I'; /* support inplace_partial behavior */
- eFlags[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
- eFlags[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
- /* NOTE: Avoid using 'V' -- it was the high bit of a write_byte() that became write_varint(). */
-#undef eFlags
- }
-
- if (x >= (int)sizeof argstr) { /* Not possible... */
- rprintf(FERROR, "argstr overflow in server_options().\n");
- exit_cleanup(RERR_MALLOC);
- }
-
- argstr[x] = '\0';
+ /* This '\0'-terminates argstr and makes sure it didn't overflow. */
+ x += maybe_add_e_option(argstr + x, (int)sizeof argstr - x);
if (x > 1)
args[ac++] = argstr;
out_of_memory("server_options");
}
+int maybe_add_e_option(char *buf, int buf_len)
+{
+ int x = 0;
+
+ /* We don't really know the actual protocol_version at this point,
+ * but checking the pre-negotiated value allows the user to use a
+ * --protocol=29 override to avoid the use of this -eFLAGS opt. */
+ if (protocol_version >= 30 && buf_len > 0) {
+ /* We make use of the -e option to let the server know about
+ * any pre-release protocol version && some behavior flags. */
+ buf[x++] = 'e';
+
+#if SUBPROTOCOL_VERSION != 0
+ if (protocol_version == PROTOCOL_VERSION)
+ x += snprintf(buf + x, buf_len - x, "%d.%d", PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
+ else
+#endif
+ buf[x++] = '.';
+ if (allow_inc_recurse)
+ buf[x++] = 'i';
+#ifdef CAN_SET_SYMLINK_TIMES
+ buf[x++] = 'L'; /* symlink time-setting support */
+#endif
+#ifdef ICONV_OPTION
+ buf[x++] = 's'; /* symlink iconv translation support */
+#endif
+ buf[x++] = 'f'; /* flist I/O-error safety support */
+ buf[x++] = 'x'; /* xattr hardlink optimization not desired */
+ buf[x++] = 'C'; /* support checksum seed order fix */
+ buf[x++] = 'I'; /* support inplace_partial behavior */
+ buf[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
+ buf[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
+
+ /* NOTE: Avoid using 'V' -- it was represented with the high bit of a write_byte() that became a write_varint(). */
+ }
+
+ if (x >= buf_len) { /* Not possible... */
+ rprintf(FERROR, "overflow in add_e_flags().\n");
+ exit_cleanup(RERR_MALLOC);
+ }
+
+ buf[x] = '\0';
+
+ return x;
+}
+
/* If str points to a valid hostspec, return allocated memory containing the
* [USER@]HOST part of the string, and set the path_start_ptr to the part of
* the string after the host part. Otherwise, return NULL. If port_ptr is