mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db5bfe67a5 | ||
|
|
5447d038c6 | ||
|
|
711773631b | ||
|
|
bf3e49b453 | ||
|
|
034d5e8770 | ||
|
|
ad8917437a | ||
|
|
1b664d30e4 | ||
|
|
ea38f34d02 | ||
|
|
44d4727664 | ||
|
|
1f2f413167 | ||
|
|
0a09df2c5e | ||
|
|
cc861cf8c0 | ||
|
|
5183c0d6f0 | ||
|
|
706bff9176 | ||
|
|
2c1204032b | ||
|
|
8adc2240e0 | ||
|
|
84ad83525b | ||
|
|
9a3449a398 | ||
|
|
3258534e99 | ||
|
|
b94bba4036 | ||
|
|
a182507bef | ||
|
|
2895b65f53 | ||
|
|
def595c559 | ||
|
|
68b1ce1dc3 | ||
|
|
5a4116e553 | ||
|
|
024bf1d831 | ||
|
|
db4f919ebe | ||
|
|
6ac2c7b682 |
56
NEWS.md
56
NEWS.md
@@ -1,3 +1,54 @@
|
||||
# NEWS for rsync 3.2.6 (9 Sep 2022)
|
||||
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
- More path-cleaning improvements in the file-list validation code to avoid
|
||||
rejecting of valid args.
|
||||
|
||||
- A file-list validation fix for a [`--files-from`](rsync.1#opt) file that ends
|
||||
without a line-terminating character.
|
||||
|
||||
- Added a safety check that prevents the sender from removing destination files
|
||||
when a local copy using [`--remove-source-files`](rsync.1#opt) has some files
|
||||
that are shared between the sending & receiving hierarchies, including the
|
||||
case where the source dir & destination dir are identical.
|
||||
|
||||
- Fixed a bug in the internal MD4 checksum code that could cause the digest
|
||||
to be sporadically incorrect (the openssl version was/is fine).
|
||||
|
||||
- A minor tweak to rrsync added "copy-devices" to the list of known args, but
|
||||
left it disabled by default.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
- Rename `--protect-args` to [`--secluded-args`](rsync.1#opt) to make it
|
||||
clearer how it differs from the default backslash-escaped arg-protecting
|
||||
behavior of rsync. The old option names are still accepted. The
|
||||
environment-variable override did not change its name.
|
||||
|
||||
### PACKAGING RELATED:
|
||||
|
||||
- The configure option `--with-protected-args` was renamed to
|
||||
`--with-secluded-args`. This option makes `--secluded-args` the default
|
||||
rsync behavior instead of using backslash escaping for protecting args.
|
||||
|
||||
- The mkgitver script now makes sure that a `.git` dir/file is in the top-level
|
||||
source dir before calling `git describe`. It also runs a basic check on the
|
||||
version value. This should avoid using an unrelated git description for
|
||||
rsync's version.
|
||||
|
||||
### DEVELOPER RELATED:
|
||||
|
||||
- The configure script no longer sets the -pedantic-errors CFLAG (which it
|
||||
used to try to do only for gcc).
|
||||
|
||||
- The name_num_obj struct was modified to allow its dynamic name_num_item list
|
||||
to be initialized in a better way.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
# NEWS for rsync 3.2.5 (14 Aug 2022)
|
||||
|
||||
## Changes in this version:
|
||||
@@ -64,7 +115,7 @@
|
||||
### BEHAVIOR CHANGES:
|
||||
|
||||
- A new form of arg protection was added that works similarly to the older
|
||||
[`--protect-args`](rsync.1#opt) (`-s`) option but in a way that avoids
|
||||
`--protect-args` ([`-s`](rsync.1#opt)) option but in a way that avoids
|
||||
breaking things like rrsync (the restricted rsync script): rsync now uses
|
||||
backslash escaping for sending "shell-active" characters to the remote
|
||||
shell. This includes spaces, so fetching a remote file via a simple quoted
|
||||
@@ -168,7 +219,7 @@
|
||||
|
||||
- Fixed a potential issue in git-set-file-times when handling commits with
|
||||
high-bit characters in the description & when handling a description that
|
||||
might mimick the git raw-commit deliniators. (See the support dir.)
|
||||
might mimic the git raw-commit deliniators. (See the support dir.)
|
||||
|
||||
- The bundled systemd/rsync.service file now includes `Restart=on-failure`.
|
||||
|
||||
@@ -4541,6 +4592,7 @@
|
||||
|
||||
| RELEASE DATE | VER. | DATE OF COMMIT\* | PROTOCOL |
|
||||
|--------------|--------|------------------|-------------|
|
||||
| 09 Sep 2022 | 3.2.6 | | 31 |
|
||||
| 14 Aug 2022 | 3.2.5 | | 31 |
|
||||
| 15 Apr 2022 | 3.2.4 | | 31 |
|
||||
| 06 Aug 2020 | 3.2.3 | | 31 |
|
||||
|
||||
28
checksum.c
28
checksum.c
@@ -42,21 +42,23 @@ extern int protocol_version;
|
||||
extern int proper_seed_order;
|
||||
extern const char *checksum_choice;
|
||||
|
||||
struct name_num_obj valid_checksums = {
|
||||
"checksum", NULL, 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, "xxh128", NULL },
|
||||
{ CSUM_XXH3_64, "xxh3", NULL },
|
||||
#endif
|
||||
#ifdef SUPPORT_XXHASH
|
||||
{ CSUM_XXH64, "xxh64", NULL },
|
||||
{ CSUM_XXH64, "xxhash", NULL },
|
||||
{ CSUM_XXH64, "xxh64", NULL },
|
||||
{ CSUM_XXH64, "xxhash", NULL },
|
||||
#endif
|
||||
{ CSUM_MD5, "md5", NULL },
|
||||
{ CSUM_MD4, "md4", NULL },
|
||||
{ CSUM_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
}
|
||||
{ CSUM_MD5, "md5", NULL },
|
||||
{ CSUM_MD4, "md4", NULL },
|
||||
{ CSUM_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
struct name_num_obj valid_checksums = {
|
||||
"checksum", NULL, NULL, 0, 0, valid_checksums_items
|
||||
};
|
||||
|
||||
int xfersum_type = 0; /* used for the file transfer checksums */
|
||||
@@ -418,8 +420,8 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
|
||||
|
||||
mdfour_begin(&m);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK), CSUM_CHUNK);
|
||||
|
||||
/* Prior to version 27 an incorrect MD4 checksum was computed
|
||||
* by failing to call mdfour_tail() for block sizes that
|
||||
|
||||
@@ -381,7 +381,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
|
||||
if (rl_nulls) {
|
||||
for (i = 0; i < sargc; i++) {
|
||||
if (!sargs[i]) /* stop at --protect-args NULL */
|
||||
if (!sargs[i]) /* stop at --secluded-args NULL */
|
||||
break;
|
||||
write_sbuf(f_out, sargs[i]);
|
||||
write_byte(f_out, 0);
|
||||
|
||||
20
compat.c
20
compat.c
@@ -91,19 +91,21 @@ int filesfrom_convert = 0;
|
||||
|
||||
#define MAX_NSTR_STRLEN 256
|
||||
|
||||
struct name_num_obj valid_compressions = {
|
||||
"compress", NULL, NULL, 0, 0, {
|
||||
struct name_num_item valid_compressions_items[] = {
|
||||
#ifdef SUPPORT_ZSTD
|
||||
{ CPRES_ZSTD, "zstd", NULL },
|
||||
{ CPRES_ZSTD, "zstd", NULL },
|
||||
#endif
|
||||
#ifdef SUPPORT_LZ4
|
||||
{ CPRES_LZ4, "lz4", NULL },
|
||||
{ CPRES_LZ4, "lz4", NULL },
|
||||
#endif
|
||||
{ CPRES_ZLIBX, "zlibx", NULL },
|
||||
{ CPRES_ZLIB, "zlib", NULL },
|
||||
{ CPRES_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
}
|
||||
{ CPRES_ZLIBX, "zlibx", NULL },
|
||||
{ CPRES_ZLIB, "zlib", NULL },
|
||||
{ CPRES_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
struct name_num_obj valid_compressions = {
|
||||
"compress", NULL, NULL, 0, 0, valid_compressions_items
|
||||
};
|
||||
|
||||
#define CF_INC_RECURSE (1<<0)
|
||||
|
||||
23
configure.ac
23
configure.ac
@@ -153,10 +153,10 @@ AC_ARG_WITH(included-popt,
|
||||
AC_ARG_WITH(included-zlib,
|
||||
AS_HELP_STRING([--with-included-zlib],[use bundled zlib library, not from system]))
|
||||
|
||||
AC_ARG_WITH(protected-args,
|
||||
AS_HELP_STRING([--with-protected-args],[make --protected-args option the default]))
|
||||
if test x"$with_protected_args" = x"yes"; then
|
||||
AC_DEFINE_UNQUOTED(RSYNC_USE_PROTECTED_ARGS, 1, [Define to 1 if --protected-args should be the default])
|
||||
AC_ARG_WITH(secluded-args,
|
||||
AS_HELP_STRING([--with-secluded-args],[make --secluded-args option the default]))
|
||||
if test x"$with_secluded_args" = x"yes"; then
|
||||
AC_DEFINE_UNQUOTED(RSYNC_USE_SECLUDED_ARGS, 1, [Define to 1 if --secluded-args should be the default])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(rsync-path,
|
||||
@@ -1071,21 +1071,6 @@ elif test x"$ac_cv_header_popt_h" != x"yes"; then
|
||||
with_included_popt=yes
|
||||
fi
|
||||
|
||||
if test x"$GCC" = x"yes"; then
|
||||
if test x"$with_included_popt" != x"yes"; then
|
||||
# Turn pedantic warnings into errors to ensure an array-init overflow is an error.
|
||||
CFLAGS="$CFLAGS -pedantic-errors"
|
||||
else
|
||||
# Our internal popt code cannot be compiled with pedantic warnings as errors, so try to
|
||||
# turn off pedantic warnings (which will not lose the error for array-init overflow).
|
||||
# Older gcc versions don't understand -Wno-pedantic, so check if --help=warnings lists
|
||||
# -Wpedantic and use that as a flag.
|
||||
case `$CC --help=warnings 2>/dev/null | grep Wpedantic` in
|
||||
*-Wpedantic*) CFLAGS="$CFLAGS -pedantic-errors -Wno-pedantic" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to use included libpopt])
|
||||
if test x"$with_included_popt" = x"yes"; then
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
|
||||
140
exclude.c
140
exclude.c
@@ -361,6 +361,8 @@ void implied_include_partial_string(const char *s_start, const char *s_end)
|
||||
void free_implied_include_partial_string()
|
||||
{
|
||||
if (partial_string_buf) {
|
||||
if (partial_string_len)
|
||||
add_implied_include("", 0);
|
||||
free(partial_string_buf);
|
||||
partial_string_buf = NULL;
|
||||
}
|
||||
@@ -371,9 +373,8 @@ void free_implied_include_partial_string()
|
||||
* that the receiver uses to validate the file list from the sender. */
|
||||
void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
{
|
||||
filter_rule *rule;
|
||||
int arg_len, saw_wild = 0, saw_live_open_brkt = 0, backslash_cnt = 0;
|
||||
int slash_cnt = 1; /* We know we're adding a leading slash. */
|
||||
int slash_cnt = 0;
|
||||
const char *cp;
|
||||
char *p;
|
||||
if (trust_sender_args)
|
||||
@@ -404,6 +405,7 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
arg++;
|
||||
arg_len = strlen(arg);
|
||||
if (arg_len) {
|
||||
char *new_pat;
|
||||
if (strpbrk(arg, "*[?")) {
|
||||
/* We need to add room to escape backslashes if wildcard chars are present. */
|
||||
for (cp = arg; (cp = strchr(cp, '\\')) != NULL; cp++)
|
||||
@@ -411,16 +413,9 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
saw_wild = 1;
|
||||
}
|
||||
arg_len++; /* Leave room for the prefixed slash */
|
||||
rule = new0(filter_rule);
|
||||
if (!implied_filter_list.head)
|
||||
implied_filter_list.head = implied_filter_list.tail = rule;
|
||||
else {
|
||||
rule->next = implied_filter_list.head;
|
||||
implied_filter_list.head = rule;
|
||||
}
|
||||
rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
|
||||
p = rule->pattern = new_array(char, arg_len + 1);
|
||||
p = new_pat = new_array(char, arg_len + 1);
|
||||
*p++ = '/';
|
||||
slash_cnt++;
|
||||
for (cp = arg; *cp; ) {
|
||||
switch (*cp) {
|
||||
case '\\':
|
||||
@@ -436,39 +431,33 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
break;
|
||||
case '/':
|
||||
if (p[-1] == '/') { /* This is safe because of the initial slash. */
|
||||
if (*++cp == '\0') {
|
||||
slash_cnt--;
|
||||
p--;
|
||||
}
|
||||
} else if (cp[1] == '\0') {
|
||||
cp++;
|
||||
break;
|
||||
} else {
|
||||
slash_cnt++;
|
||||
*p++ = *cp++;
|
||||
}
|
||||
if (relative_paths) {
|
||||
filter_rule const *ent;
|
||||
int found = 0;
|
||||
*p = '\0';
|
||||
for (ent = implied_filter_list.head; ent; ent = ent->next) {
|
||||
if (ent != rule && strcmp(ent->pattern, rule->pattern) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
break;
|
||||
case '.':
|
||||
if (p[-1] == '/') {
|
||||
if (cp[1] == '/') {
|
||||
cp += 2;
|
||||
if (!*cp) {
|
||||
slash_cnt--;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
filter_rule *R_rule = new0(filter_rule);
|
||||
R_rule->rflags = FILTRULE_INCLUDE | FILTRULE_DIRECTORY;
|
||||
/* Check if our sub-path has wildcards or escaped backslashes */
|
||||
if (saw_wild && strpbrk(rule->pattern, "*[?\\"))
|
||||
R_rule->rflags |= FILTRULE_WILD;
|
||||
R_rule->pattern = strdup(rule->pattern);
|
||||
R_rule->u.slash_cnt = slash_cnt;
|
||||
R_rule->next = implied_filter_list.head;
|
||||
implied_filter_list.head = R_rule;
|
||||
if (DEBUG_GTE(FILTER, 3)) {
|
||||
rprintf(FINFO, "[%s] add_implied_include(%s/)\n",
|
||||
who_am_i(), R_rule->pattern);
|
||||
}
|
||||
if (saw_live_open_brkt)
|
||||
maybe_add_literal_brackets_rule(R_rule, -1);
|
||||
}
|
||||
}
|
||||
slash_cnt++;
|
||||
*p++ = *cp++;
|
||||
} else if (cp[1] == '\0') {
|
||||
cp++;
|
||||
slash_cnt--;
|
||||
p--;
|
||||
} else
|
||||
*p++ = *cp++;
|
||||
} else
|
||||
*p++ = *cp++;
|
||||
break;
|
||||
case '[':
|
||||
saw_live_open_brkt = 1;
|
||||
@@ -480,18 +469,63 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
rule->u.slash_cnt = slash_cnt;
|
||||
arg = rule->pattern;
|
||||
arg_len = p - arg; /* We recompute it due to backslash weirdness. */
|
||||
if (DEBUG_GTE(FILTER, 3))
|
||||
rprintf(FINFO, "[%s] add_implied_include(%s)\n", who_am_i(), rule->pattern);
|
||||
if (saw_live_open_brkt)
|
||||
maybe_add_literal_brackets_rule(rule, arg_len);
|
||||
arg_len = p - new_pat;
|
||||
if (!arg_len)
|
||||
free(new_pat);
|
||||
else {
|
||||
filter_rule *rule = new0(filter_rule);
|
||||
rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
|
||||
rule->u.slash_cnt = slash_cnt;
|
||||
arg = rule->pattern = new_pat;
|
||||
if (!implied_filter_list.head)
|
||||
implied_filter_list.head = implied_filter_list.tail = rule;
|
||||
else {
|
||||
rule->next = implied_filter_list.head;
|
||||
implied_filter_list.head = rule;
|
||||
}
|
||||
if (DEBUG_GTE(FILTER, 3))
|
||||
rprintf(FINFO, "[%s] add_implied_include(%s)\n", who_am_i(), arg);
|
||||
if (saw_live_open_brkt)
|
||||
maybe_add_literal_brackets_rule(rule, arg_len);
|
||||
if (relative_paths && slash_cnt) {
|
||||
filter_rule const *ent;
|
||||
int found = 0;
|
||||
slash_cnt = 1;
|
||||
for (p = new_pat + 1; (p = strchr(p, '/')) != NULL; p++) {
|
||||
*p = '\0';
|
||||
for (ent = implied_filter_list.head; ent; ent = ent->next) {
|
||||
if (ent != rule && strcmp(ent->pattern, new_pat) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
filter_rule *R_rule = new0(filter_rule);
|
||||
R_rule->rflags = FILTRULE_INCLUDE | FILTRULE_DIRECTORY;
|
||||
/* Check if our sub-path has wildcards or escaped backslashes */
|
||||
if (saw_wild && strpbrk(rule->pattern, "*[?\\"))
|
||||
R_rule->rflags |= FILTRULE_WILD;
|
||||
R_rule->pattern = strdup(new_pat);
|
||||
R_rule->u.slash_cnt = slash_cnt;
|
||||
R_rule->next = implied_filter_list.head;
|
||||
implied_filter_list.head = R_rule;
|
||||
if (DEBUG_GTE(FILTER, 3)) {
|
||||
rprintf(FINFO, "[%s] add_implied_include(%s/)\n",
|
||||
who_am_i(), R_rule->pattern);
|
||||
}
|
||||
if (saw_live_open_brkt)
|
||||
maybe_add_literal_brackets_rule(R_rule, -1);
|
||||
}
|
||||
*p = '/';
|
||||
slash_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse || xfer_dirs) {
|
||||
/* Now create a rule with an added "/" & "**" or "*" at the end */
|
||||
rule = new0(filter_rule);
|
||||
filter_rule *rule = new0(filter_rule);
|
||||
rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD;
|
||||
if (recurse)
|
||||
rule->rflags |= FILTRULE_WILD2;
|
||||
@@ -499,7 +533,7 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
if (!saw_wild && backslash_cnt) {
|
||||
/* We are appending a wildcard, so now the backslashes need to be escaped. */
|
||||
p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1);
|
||||
for (cp = arg; *cp; ) {
|
||||
for (cp = arg; *cp; ) { /* Note that arg_len != 0 because backslash_cnt > 0 */
|
||||
if (*cp == '\\')
|
||||
*p++ = '\\';
|
||||
*p++ = *cp++;
|
||||
@@ -511,13 +545,15 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
||||
p += arg_len;
|
||||
}
|
||||
}
|
||||
if (p[-1] != '/')
|
||||
if (p[-1] != '/') {
|
||||
*p++ = '/';
|
||||
slash_cnt++;
|
||||
}
|
||||
*p++ = '*';
|
||||
if (recurse)
|
||||
*p++ = '*';
|
||||
*p = '\0';
|
||||
rule->u.slash_cnt = slash_cnt + 1;
|
||||
rule->u.slash_cnt = slash_cnt;
|
||||
rule->next = implied_filter_list.head;
|
||||
implied_filter_list.head = rule;
|
||||
if (DEBUG_GTE(FILTER, 3))
|
||||
|
||||
@@ -1819,7 +1819,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
goto cleanup;
|
||||
return_with_success:
|
||||
if (!dry_run)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
send_msg_success(fname, ndx);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
6
hlink.c
6
hlink.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2020 Wayne Davison
|
||||
* Copyright (C) 2004-2022 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -446,7 +446,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
return -1;
|
||||
|
||||
if (remove_source_files == 1 && do_xfers)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
send_msg_success(fname, ndx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -519,7 +519,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
if (val < 0)
|
||||
continue;
|
||||
if (remove_source_files == 1 && do_xfers)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
send_msg_success(fname, ndx);
|
||||
}
|
||||
|
||||
if (inc_recurse) {
|
||||
|
||||
34
io.c
34
io.c
@@ -41,6 +41,7 @@ extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int am_receiver;
|
||||
extern int am_generator;
|
||||
extern int local_server;
|
||||
extern int msgs2stderr;
|
||||
extern int inc_recurse;
|
||||
extern int io_error;
|
||||
@@ -84,6 +85,8 @@ int sock_f_out = -1;
|
||||
int64 total_data_read = 0;
|
||||
int64 total_data_written = 0;
|
||||
|
||||
char num_dev_ino_buf[4 + 8 + 8];
|
||||
|
||||
static struct {
|
||||
xbuf in, out, msg;
|
||||
int in_fd;
|
||||
@@ -1064,6 +1067,24 @@ void send_msg_int(enum msgcode code, int num)
|
||||
send_msg(code, numbuf, 4, -1);
|
||||
}
|
||||
|
||||
void send_msg_success(const char *fname, int num)
|
||||
{
|
||||
if (local_server) {
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (DEBUG_GTE(IO, 1))
|
||||
rprintf(FINFO, "[%s] send_msg_success(%d)\n", who_am_i(), num);
|
||||
|
||||
if (stat(fname, &st) < 0)
|
||||
memset(&st, 0, sizeof (STRUCT_STAT));
|
||||
SIVAL(num_dev_ino_buf, 0, num);
|
||||
SIVAL64(num_dev_ino_buf, 4, st.st_dev);
|
||||
SIVAL64(num_dev_ino_buf, 4+8, st.st_ino);
|
||||
send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
|
||||
} else
|
||||
send_msg_int(MSG_SUCCESS, num);
|
||||
}
|
||||
|
||||
static void got_flist_entry_status(enum festatus status, int ndx)
|
||||
{
|
||||
struct file_list *flist = flist_for_ndx(ndx, "got_flist_entry_status");
|
||||
@@ -1078,8 +1099,12 @@ static void got_flist_entry_status(enum festatus status, int ndx)
|
||||
|
||||
switch (status) {
|
||||
case FES_SUCCESS:
|
||||
if (remove_source_files)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
if (remove_source_files) {
|
||||
if (local_server)
|
||||
send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
|
||||
else
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case FES_NO_SEND:
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
@@ -1574,14 +1599,15 @@ static void read_a_msg(void)
|
||||
}
|
||||
break;
|
||||
case MSG_SUCCESS:
|
||||
if (msg_bytes != 4) {
|
||||
if (msg_bytes != (local_server ? 4+8+8 : 4)) {
|
||||
invalid_msg:
|
||||
rprintf(FERROR, "invalid multi-message %d:%lu [%s%s]\n",
|
||||
tag, (unsigned long)msg_bytes, who_am_i(),
|
||||
inc_recurse ? "/inc" : "");
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
val = raw_read_int();
|
||||
raw_read_buf(num_dev_ino_buf, msg_bytes);
|
||||
val = IVAL(num_dev_ino_buf, 0);
|
||||
iobuf.in_multiplexed = 1;
|
||||
if (am_generator)
|
||||
got_flist_entry_status(FES_SUCCESS, val);
|
||||
|
||||
@@ -389,7 +389,7 @@ class TransformHtml(HTMLParser):
|
||||
if val.startswith(('https://', 'http://', 'mailto:', 'ftp:')):
|
||||
pass # nothing to check
|
||||
elif '#' in val:
|
||||
pg, tgt = val.split('#', 2)
|
||||
pg, tgt = val.split('#', 1)
|
||||
if pg and pg not in VALID_PAGES or '#' in tgt:
|
||||
st.bad_hashtags.add(val)
|
||||
elif tgt in ('', 'opt', 'dopt'):
|
||||
@@ -478,7 +478,7 @@ class TransformHtml(HTMLParser):
|
||||
find = 'href="' + st.a_href + '"'
|
||||
for j in range(len(st.html_out)-1, 0, -1):
|
||||
if find in st.html_out[j]:
|
||||
pg, tgt = st.a_href.split('#', 2)
|
||||
pg, tgt = st.a_href.split('#', 1)
|
||||
derived = txt2target(atxt, tgt)
|
||||
if pg == '':
|
||||
if derived in st.latest_targets:
|
||||
|
||||
10
mkgitver
10
mkgitver
@@ -1,14 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
gitver=`git describe --abbrev=8 2>/dev/null`
|
||||
|
||||
if [ ! -f git-version.h ]; then
|
||||
touch git-version.h
|
||||
fi
|
||||
|
||||
case "$gitver" in
|
||||
*.*)
|
||||
if [ -e "$srcdir/.git" ]; then
|
||||
gitver=`git describe --abbrev=8 2>/dev/null | sed -n '/^v3\.[0-9][0-9]*\.[0-9][0-9]*\(-\|$\)/p'`
|
||||
if [ -n "$gitver" ]; then
|
||||
echo "#define RSYNC_GITVER \"$gitver\"" >git-version.h.new
|
||||
if ! diff git-version.h.new git-version.h >/dev/null; then
|
||||
echo "Updating git-version.h"
|
||||
@@ -16,5 +16,5 @@ case "$gitver" in
|
||||
else
|
||||
rm git-version.h.new
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
14
options.c
14
options.c
@@ -788,7 +788,9 @@ static struct poptOption long_options[] = {
|
||||
{"no-from0", 0, POPT_ARG_VAL, &eol_nulls, 0, 0, 0},
|
||||
{"old-args", 0, POPT_ARG_NONE, 0, OPT_OLD_ARGS, 0, 0},
|
||||
{"no-old-args", 0, POPT_ARG_VAL, &old_style_args, 0, 0, 0},
|
||||
{"protect-args", 's', POPT_ARG_VAL, &protect_args, 1, 0, 0},
|
||||
{"secluded-args", 's', POPT_ARG_VAL, &protect_args, 1, 0, 0},
|
||||
{"no-secluded-args", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
|
||||
{"protect-args", 0, POPT_ARG_VAL, &protect_args, 1, 0, 0},
|
||||
{"no-protect-args", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
|
||||
{"no-s", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
|
||||
{"trust-sender", 0, POPT_ARG_VAL, &trust_sender, 1, 0, 0},
|
||||
@@ -950,7 +952,7 @@ static void set_refuse_options(void)
|
||||
if (!am_daemon
|
||||
|| op->shortName == 'e' /* Required for compatibility flags */
|
||||
|| op->shortName == '0' /* --from0 just modifies --files-from, so refuse that instead (or not) */
|
||||
|| op->shortName == 's' /* --protect-args is always OK */
|
||||
|| op->shortName == 's' /* --secluded-args is always OK */
|
||||
|| op->shortName == 'n' /* --dry-run is always OK */
|
||||
|| strcmp("iconv", longName) == 0
|
||||
|| strcmp("no-iconv", longName) == 0
|
||||
@@ -1949,7 +1951,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
} else if (old_style_args) {
|
||||
if (protect_args > 0) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--protect-args conflicts with --old-args.\n");
|
||||
"--secluded-args conflicts with --old-args.\n");
|
||||
return 0;
|
||||
}
|
||||
protect_args = 0;
|
||||
@@ -1961,7 +1963,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
else if ((arg = getenv("RSYNC_PROTECT_ARGS")) != NULL && *arg)
|
||||
protect_args = atoi(arg) ? 1 : 0;
|
||||
else {
|
||||
#ifdef RSYNC_USE_PROTECTED_ARGS
|
||||
#ifdef RSYNC_USE_SECLUDED_ARGS
|
||||
protect_args = 1;
|
||||
#else
|
||||
protect_args = 0;
|
||||
@@ -2508,7 +2510,9 @@ char *safe_arg(const char *opt, const char *arg)
|
||||
char *ret;
|
||||
if (!protect_args && old_style_args < 2 && (!old_style_args || (!is_filename_arg && opt != SPLIT_ARG_WHEN_OLD))) {
|
||||
const char *f;
|
||||
if (!trust_sender_args && *arg == '~' && (relative_paths || !strchr(arg, '/'))) {
|
||||
if (!trust_sender_args && *arg == '~'
|
||||
&& ((relative_paths && !strstr(arg, "/./"))
|
||||
|| !strchr(arg, '/'))) {
|
||||
extras++;
|
||||
escape_leading_tilde = 1;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ long_opts = { # These include some extra long-args that BackupPC uses:
|
||||
'recursive': 0,
|
||||
'stderr': 1,
|
||||
'times': 0,
|
||||
'copy-devices': -1,
|
||||
'write-devices': -1,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 3.2.5
|
||||
Version: 3.2.6
|
||||
%define fullversion %{version}
|
||||
Release: 1
|
||||
%define srcdir src
|
||||
@@ -79,8 +79,8 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%dir /etc/rsync-ssl/certs
|
||||
|
||||
%changelog
|
||||
* Sun Aug 14 2022 Wayne Davison <wayne@opencoder.net>
|
||||
Released 3.2.5.
|
||||
* Fri Sep 09 2022 Wayne Davison <wayne@opencoder.net>
|
||||
Released 3.2.6.
|
||||
|
||||
* Fri Mar 21 2008 Wayne Davison <wayne@opencoder.net>
|
||||
Added installation of /etc/xinetd.d/rsync file and some commented-out
|
||||
|
||||
@@ -32,7 +32,7 @@ def _tweak_opts(cmd, opts, **maybe_set_args):
|
||||
opts = opts.copy()
|
||||
_maybe_set(opts, **maybe_set_args)
|
||||
|
||||
if type(cmd) == str:
|
||||
if isinstance(cmd, str):
|
||||
_maybe_set(opts, shell=True)
|
||||
|
||||
want_raw = opts.pop('raw', False)
|
||||
|
||||
@@ -232,7 +232,7 @@ About to:
|
||||
cmd_chk(['packaging/year-tweak'])
|
||||
|
||||
print(dash_line)
|
||||
cmd_run("git diff")
|
||||
cmd_run("git diff".split())
|
||||
|
||||
srctar_name = f"{rsync_ver}.tar.gz"
|
||||
pattar_name = f"rsync-patches-{version}.tar.gz"
|
||||
@@ -247,7 +247,7 @@ About to:
|
||||
|
||||
About to:
|
||||
- git commit all changes
|
||||
- generate the manpages
|
||||
- run a full build, ensuring that the manpages & configure.sh are up-to-date
|
||||
- merge the {args.master_branch} branch into the patch/{args.master_branch}/* branches
|
||||
- update the files in the "patches" dir and OPTIONALLY (if you type 'y') to
|
||||
run patch-update with the --make option (which opens a shell on error)
|
||||
@@ -258,9 +258,9 @@ About to:
|
||||
if s.returncode:
|
||||
die('Aborting')
|
||||
|
||||
cmd_chk('make gen')
|
||||
cmd_chk('touch configure.ac && packaging/smart-make && make gen')
|
||||
|
||||
print(f'Creating any missing patch branches.')
|
||||
print('Creating any missing patch branches.')
|
||||
s = cmd_run(f'packaging/branch-from-patch --branch={args.master_branch} --add-missing')
|
||||
if s.returncode:
|
||||
die('Aborting')
|
||||
|
||||
12
receiver.c
12
receiver.c
@@ -439,9 +439,8 @@ static void handle_delayed_updates(char *local_name)
|
||||
"rename failed for %s (from %s)",
|
||||
full_fname(fname), partialptr);
|
||||
} else {
|
||||
if (remove_source_files
|
||||
|| (preserve_hard_links && F_IS_HLINKED(file)))
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
if (remove_source_files || (preserve_hard_links && F_IS_HLINKED(file)))
|
||||
send_msg_success(fname, ndx);
|
||||
handle_partial_dir(partialptr, PDIR_DELETE);
|
||||
}
|
||||
}
|
||||
@@ -698,7 +697,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
if (!am_server)
|
||||
discard_receive_data(f_in, file);
|
||||
if (inc_recurse)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
send_msg_success(fname, ndx);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -926,9 +925,8 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
if (remove_source_files || inc_recurse
|
||||
|| (preserve_hard_links && F_IS_HLINKED(file)))
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
if (remove_source_files || inc_recurse || (preserve_hard_links && F_IS_HLINKED(file)))
|
||||
send_msg_success(fname, ndx);
|
||||
break;
|
||||
case 0: {
|
||||
enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
|
||||
|
||||
123
rsync.1.md
123
rsync.1.md
@@ -195,6 +195,24 @@ Dedicate a "host1-files" dir to the remote content:
|
||||
|
||||
See the [`--trust-sender`](#opt) option for additional details.
|
||||
|
||||
CAUTION: it is not particularly safe to use rsync to copy files from a
|
||||
case-preserving filesystem to a case-ignoring filesystem. If you must perform
|
||||
such a copy, you should either disable symlinks via `--no-links` or enable the
|
||||
munging of symlinks via [`--munge-links`](#opt) (and make sure you use the
|
||||
right local or remote option). This will prevent rsync from doing potentially
|
||||
dangerous things if a symlink name overlaps with a file or directory. It does
|
||||
not, however, ensure that you get a full copy of all the files (since that may
|
||||
not be possible when the names overlap). A potentially better solution is to
|
||||
list all the source files and create a safe list of filenames that you pass to
|
||||
the [`--files-from`](#opt) option. Any files that conflict in name would need
|
||||
to be copied to different destination directories using more than one copy.
|
||||
|
||||
While a copy of a case-ignoring filesystem to a case-ignoring filesystem can
|
||||
work out fairly well, if no `--delete-during` or `--delete-before` option is
|
||||
active, rsync can potentially update an existing file on the receiveing side
|
||||
without noticing that the upper-/lower-case of the filename should be changed
|
||||
to match the sender.
|
||||
|
||||
## ADVANCED USAGE
|
||||
|
||||
The syntax for requesting multiple files from a remote host is done by
|
||||
@@ -203,7 +221,12 @@ the hostname omitted. For instance, all these work:
|
||||
|
||||
> rsync -aiv host:file1 :file2 host:file{3,4} /dest/
|
||||
> rsync -aiv host::modname/file{1,2} host::modname/extra /dest/
|
||||
> rsync -aiv host::modname/first ::modname/extra{1,2} /dest/
|
||||
> rsync -aiv host::modname/first ::extra-file{1,2} /dest/
|
||||
|
||||
Note that a daemon connection only supports accessing one module per copy
|
||||
command, so if the start of a follow-up path doesn't begin with the
|
||||
modname of the first path, it is assumed to be a path in the module (such as
|
||||
the extra-file1 & extra-file2 that are grabbed above).
|
||||
|
||||
Really old versions of rsync (2.6.9 and before) only allowed specifying one
|
||||
remote-source arg, so some people have instead relied on the remote-shell
|
||||
@@ -235,17 +258,19 @@ section below for information on that.)
|
||||
Using rsync in this way is the same as using it with a remote shell except
|
||||
that:
|
||||
|
||||
- you either use a double colon :: instead of a single colon to separate the
|
||||
hostname from the path, or you use an rsync:// URL.
|
||||
- the first word of the "path" is actually a module name.
|
||||
- the remote daemon may print a message of the day when you connect.
|
||||
- if you specify no path name on the remote daemon then the list of accessible
|
||||
paths on the daemon will be shown.
|
||||
- if you specify no local destination then a listing of the specified files on
|
||||
the remote daemon is provided.
|
||||
- you must not specify the [`--rsh`](#opt) (`-e`) option (since that overrides
|
||||
the daemon connection to use ssh -- see [USING RSYNC-DAEMON FEATURES VIA A
|
||||
REMOTE-SHELL CONNECTION](#) below).
|
||||
- Use either double-colon syntax or rsync:// URL syntax instead of the
|
||||
single-colon (remote shell) syntax.
|
||||
- The first element of the "path" is actually a module name.
|
||||
- Additional remote source args can use an abbreviated syntax that omits the
|
||||
hostname and/or the module name, as discussed in [ADVANCED USAGE](#).
|
||||
- The remote daemon may print a "message of the day" when you connect.
|
||||
- If you specify only the host (with no module or path) then a list of
|
||||
accessible modules on the daemon is output.
|
||||
- If you specify a remote source path but no destination, a listing of the
|
||||
matching files on the remote daemon is output.
|
||||
- The [`--rsh`](#opt) (`-e`) option must be omitted to avoid changing the
|
||||
connection style from using a socket connection to [USING RSYNC-DAEMON
|
||||
FEATURES VIA A REMOTE-SHELL CONNECTION](#).
|
||||
|
||||
An example that copies all the files in a remote module named "src":
|
||||
|
||||
@@ -464,7 +489,7 @@ has its own detailed description later in this manpage.
|
||||
--files-from=FILE read list of source-file names from FILE
|
||||
--from0, -0 all *-from/filter files are delimited by 0s
|
||||
--old-args disable the modern arg-protection idiom
|
||||
--protect-args, -s no space-splitting; wildcard chars only
|
||||
--secluded-args, -s use the protocol to safely send the args
|
||||
--trust-sender trust the remote sender's file list
|
||||
--copy-as=USER[:GROUP] specify user & optional group for the copy
|
||||
--address=ADDRESS bind address for outgoing socket to daemon
|
||||
@@ -1808,6 +1833,10 @@ expand it.
|
||||
Starting with 3.1.0, rsync will skip the sender-side removal (and output an
|
||||
error) if the file's size or modify time has not stayed unchanged.
|
||||
|
||||
Starting with 3.2.6, a local rsync copy will ensure that the sender does
|
||||
not remove a file the receiver just verified, such as when the user
|
||||
accidentally makes the source and destination directory the same path.
|
||||
|
||||
0. `--delete`
|
||||
|
||||
This tells rsync to delete extraneous files from the receiving side (ones
|
||||
@@ -1904,13 +1933,13 @@ expand it.
|
||||
|
||||
By default, an exclude or include has both a server-side effect (to "hide"
|
||||
and "show" files when building the server's file list) and a receiver-side
|
||||
effect (to "protect" and "risk" files when deletions are occuring). Any
|
||||
effect (to "protect" and "risk" files when deletions are occurring). Any
|
||||
rule that has no modifier to specify what sides it is executed on will be
|
||||
instead treated as if it were a server-side rule only, avoiding any
|
||||
"protect" effects of the rules.
|
||||
|
||||
A rule can still apply to both sides even with this option specified if the
|
||||
rule is given both the sender & receiver modifer letters (e.g., `-f'-sr
|
||||
rule is given both the sender & receiver modifier letters (e.g., `-f'-sr
|
||||
foo'`). Receiver-side protect/risk rules can also be explicitly specified
|
||||
to limit the deletions. This saves you from having to edit a bunch of
|
||||
`-f'- foo'` rules into `-f'-s foo'` (aka `-f'H foo'`) rules (not to mention
|
||||
@@ -2330,7 +2359,7 @@ expand it.
|
||||
This would copy all the files specified in the /path/file-list file that
|
||||
was located on the remote "src" host.
|
||||
|
||||
If the [`--iconv`](#opt) and [`--protect-args`](#opt) options are specified
|
||||
If the [`--iconv`](#opt) and [`--secluded-args`](#opt) options are specified
|
||||
and the `--files-from` filenames are being sent from one host to another,
|
||||
the filenames will be translated from the sending host's charset to the
|
||||
receiving host's charset.
|
||||
@@ -2379,38 +2408,46 @@ expand it.
|
||||
because we can't know for sure what names to expect when the remote shell
|
||||
is interpreting the args.
|
||||
|
||||
This option conflicts with the [`--protect-args`](#opt) option.
|
||||
This option conflicts with the [`--secluded-args`](#opt) option.
|
||||
|
||||
0. `--protect-args`, `-s`
|
||||
0. `--secluded-args`, `-s`
|
||||
|
||||
This option sends all filenames and most options to the remote rsync
|
||||
without allowing the remote shell to interpret them. Wildcards are
|
||||
expanded on the remote host by rsync instead of the shell doing it.
|
||||
This option sends all filenames and most options to the remote rsync via
|
||||
the protocol (not the remote shell command line) which avoids letting the
|
||||
remote shell modify them. Wildcards are expanded on the remote host by
|
||||
rsync instead of a shell.
|
||||
|
||||
This is similar to the new-style backslash-escaping of args that was added
|
||||
in 3.2.4, but supports some extra features and doesn't rely on backslash
|
||||
escaping in the remote shell.
|
||||
This is similar to the default backslash-escaping of args that was added
|
||||
in 3.2.4 (see [`--old-args`](#opt)) in that it prevents things like space
|
||||
splitting and unwanted special-character side-effects. However, it has the
|
||||
drawbacks of being incompatible with older rsync versions (prior to 3.0.0)
|
||||
and of being refused by restricted shells that want to be able to inspect
|
||||
all the option values for safety.
|
||||
|
||||
If you use this option with [`--iconv`](#opt), the args related to the
|
||||
remote side will also be translated from the local to the remote
|
||||
character-set. The translation happens before wild-cards are expanded.
|
||||
See also the [`--files-from`](#opt) option.
|
||||
This option is useful for those times that you need the argument's
|
||||
character set to be converted for the remote host, if the remote shell is
|
||||
incompatible with the default backslash-escpaing method, or there is some
|
||||
other reason that you want the majority of the options and arguments to
|
||||
bypass the command-line of the remote shell.
|
||||
|
||||
If you combine this option with [`--iconv`](#opt), the args related to the
|
||||
remote side will be translated from the local to the remote character-set.
|
||||
The translation happens before wild-cards are expanded. See also the
|
||||
[`--files-from`](#opt) option.
|
||||
|
||||
You may also control this setting via the [`RSYNC_PROTECT_ARGS`](#)
|
||||
environment variable. If it has a non-zero value, this setting will be
|
||||
enabled by default, otherwise it will be disabled by default. Either state
|
||||
is overridden by a manually specified positive or negative version of this
|
||||
option (note that `--no-s` and `--no-protect-args` are the negative
|
||||
option (note that `--no-s` and `--no-secluded-args` are the negative
|
||||
versions). This environment variable is also superseded by a non-zero
|
||||
[`RSYNC_OLD_ARGS`](#) export.
|
||||
|
||||
You may need to disable this option when interacting with an older rsync
|
||||
(one prior to 3.0.0).
|
||||
|
||||
This option conflicts with the [`--old-args`](#opt) option.
|
||||
|
||||
Note that this option is incompatible with the use of the restricted rsync
|
||||
script (`rrsync`) since it hides options from the script's inspection.
|
||||
This option used to be called `--protect-args` (before 3.2.6) and that
|
||||
older name can still be used (though specifying it as `-s` is always the
|
||||
easiest and most compatible choice).
|
||||
|
||||
0. `--trust-sender`
|
||||
|
||||
@@ -2918,9 +2955,8 @@ expand it.
|
||||
[`--group`](#opt) (`-g`) option (since rsync needs to have those options
|
||||
enabled for the mapping options to work).
|
||||
|
||||
An older rsync client may need to use [`--protect-args`](#opt) (`-s`) to
|
||||
avoid a complaint about wildcard characters, but a modern rsync handles
|
||||
this automatically.
|
||||
An older rsync client may need to use [`-s`](#opt) to avoid a complaint
|
||||
about wildcard characters, but a modern rsync handles this automatically.
|
||||
|
||||
0. `--chown=USER:GROUP`
|
||||
|
||||
@@ -2935,9 +2971,8 @@ expand it.
|
||||
"`--usermap=*:foo --groupmap=*:bar`", only easier (and with the same
|
||||
implied [`--owner`](#opt) and/or [`--group`](#opt) options).
|
||||
|
||||
An older rsync client may need to use [`--protect-args`](#opt) (`-s`) to
|
||||
avoid a complaint about wildcard characters, but a modern rsync handles
|
||||
this automatically.
|
||||
An older rsync client may need to use [`-s`](#opt) to avoid a complaint
|
||||
about wildcard characters, but a modern rsync handles this automatically.
|
||||
|
||||
0. `--timeout=SECONDS`
|
||||
|
||||
@@ -3641,7 +3676,7 @@ expand it.
|
||||
For a list of what charset names your local iconv library supports, you can
|
||||
run "`iconv --list`".
|
||||
|
||||
If you specify the [`--protect-args`](#opt) (`-s`) option, rsync will
|
||||
If you specify the [`--secluded-args`](#opt) (`-s`) option, rsync will
|
||||
translate the filenames you specify on the command-line that are being sent
|
||||
to the remote host. See also the [`--files-from`](#opt) option.
|
||||
|
||||
@@ -4589,17 +4624,17 @@ file is included or excluded.
|
||||
supersedes the [`RSYNC_PROTECT_ARGS`](#) variable.
|
||||
|
||||
This variable is ignored if [`--old-args`](#opt), `--no-old-args`, or
|
||||
[`--protect-args`](#opt) is specified on the command line.
|
||||
[`--secluded-args`](#opt) is specified on the command line.
|
||||
|
||||
First supported in 3.2.4.
|
||||
|
||||
0. `RSYNC_PROTECT_ARGS`
|
||||
|
||||
Specify a non-zero numeric value if you want the [`--protect-args`](#opt)
|
||||
Specify a non-zero numeric value if you want the [`--secluded-args`](#opt)
|
||||
option to be enabled by default, or a zero value to make sure that it is
|
||||
disabled by default.
|
||||
|
||||
This variable is ignored if [`--protect-args`](#opt), `--no-protect-args`,
|
||||
This variable is ignored if [`--secluded-args`](#opt), `--no-secluded-args`,
|
||||
or [`--old-args`](#opt) is specified on the command line.
|
||||
|
||||
First supported in 3.1.0. Starting in 3.2.4, this variable is ignored if
|
||||
|
||||
2
rsync.h
2
rsync.h
@@ -1172,7 +1172,7 @@ struct name_num_obj {
|
||||
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;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_ZLIB
|
||||
|
||||
@@ -894,7 +894,7 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
> refuse options = * !a !v !compress*
|
||||
|
||||
Don't worry that the "`*`" will refuse certain vital options such as
|
||||
`--dry-run`, `--server`, `--no-iconv`, `--protect-args`, etc. These
|
||||
`--dry-run`, `--server`, `--no-iconv`, `--seclude-args`, etc. These
|
||||
important options are not matched by wild-card, so they must be overridden
|
||||
by their exact name. For instance, if you're forcing iconv transfers you
|
||||
could use something like this:
|
||||
@@ -948,7 +948,7 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
`--log-file-format`.
|
||||
- `--sender`: Use "[write only](#)" parameter instead of refusing this.
|
||||
- `--dry-run`, `-n`: Who would want to disable this?
|
||||
- `--protect-args`, `-s`: This actually makes transfers safer.
|
||||
- `--seclude-args`, `-s`: Is the oldest arg-protection method.
|
||||
- `--from0`, `-0`: Makes it easier to accept/refuse `--files-from` without
|
||||
affecting this helpful modifier.
|
||||
- `--iconv`: This is auto-disabled based on "[charset](#)" parameter.
|
||||
|
||||
9
sender.c
9
sender.c
@@ -25,6 +25,7 @@
|
||||
extern int do_xfers;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int local_server;
|
||||
extern int inc_recurse;
|
||||
extern int log_before_transfer;
|
||||
extern int stdout_format_has_i;
|
||||
@@ -51,6 +52,7 @@ extern int file_old_total;
|
||||
extern BOOL want_progress_now;
|
||||
extern struct stats stats;
|
||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||
extern char num_dev_ino_buf[4 + 8 + 8];
|
||||
|
||||
BOOL extra_flist_sending_enabled;
|
||||
|
||||
@@ -144,6 +146,13 @@ void successful_send(int ndx)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (local_server
|
||||
&& (int64)st.st_dev == IVAL64(num_dev_ino_buf, 4)
|
||||
&& (int64)st.st_ino == IVAL64(num_dev_ino_buf, 4 + 8)) {
|
||||
rprintf(FERROR_XFER, "ERROR: Skipping sender remove of destination file: %s\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime
|
||||
#ifdef ST_MTIME_NSEC
|
||||
|| (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file))
|
||||
|
||||
@@ -47,6 +47,7 @@ long_opts = {
|
||||
'compress-choice': 1,
|
||||
'compress-level': 1,
|
||||
'copy-dest': 2,
|
||||
'copy-devices': -1,
|
||||
'copy-unsafe-links': 0,
|
||||
'daemon': -1,
|
||||
'debug': 1,
|
||||
|
||||
@@ -22,6 +22,10 @@ transfer in one of two easy ways:
|
||||
* forcing the running of the rrsync script
|
||||
* forcing the running of an rsync daemon-over-ssh command.
|
||||
|
||||
Both of these setups use a feature of ssh that allows a command to be forced to
|
||||
run instead of an interactive shell. However, if the user's home shell is bash,
|
||||
please see [BASH SECURITY ISSUE](#) for a potential issue.
|
||||
|
||||
To use the rrsync script, edit the user's `~/.ssh/authorized_keys` file and add
|
||||
a prefix like one of the following (followed by a space) in front of each
|
||||
ssh-key line that should be restricted:
|
||||
@@ -107,6 +111,26 @@ overrides.
|
||||
The script (or a copy of it) can be manually edited if you want it to customize
|
||||
the option handling.
|
||||
|
||||
## BASH SECURITY ISSUE
|
||||
|
||||
If your users have bash set as their home shell, bash may try to be overly
|
||||
helpful and ensure that the user's login bashrc files are run prior to
|
||||
executing the forced command. This can be a problem if the user can somehow
|
||||
update their home bashrc files, perhaps via the restricted copy, a shared home
|
||||
directory, or something similar.
|
||||
|
||||
One simple way to avoid the issue is to switch the user to a simpler shell,
|
||||
such as dash. When choosing the new home shell, make sure that you're not
|
||||
choosing bash in disguise, as it is unclear if it avoids the security issue.
|
||||
|
||||
Another potential fix is to ensure that the user's home directory is not a
|
||||
shared mount and that they have no means of copying files outside of their
|
||||
restricted directories. This may require you to force the enabling of symlink
|
||||
munging on the server side.
|
||||
|
||||
A future version of openssh may have a change to the handling of forced
|
||||
commands that allows it to avoid using the user's home shell.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
The `~/.ssh/authorized_keys` file might have lines in it like this:
|
||||
|
||||
1
t_stub.c
1
t_stub.c
@@ -29,7 +29,6 @@ int protect_args = 0;
|
||||
int module_id = -1;
|
||||
int relative_paths = 0;
|
||||
int module_dirlen = 0;
|
||||
int preserve_mtimes = 0;
|
||||
int preserve_xattrs = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_executability = 0;
|
||||
|
||||
4
usage.c
4
usage.c
@@ -110,12 +110,12 @@ static void print_info_flags(enum logcode f)
|
||||
#endif
|
||||
"xattrs",
|
||||
|
||||
#ifdef RSYNC_USE_PROTECTED_ARGS
|
||||
#ifdef RSYNC_USE_SECLUDED_ARGS
|
||||
"default "
|
||||
#else
|
||||
"optional "
|
||||
#endif
|
||||
"protect-args",
|
||||
"secluded-args",
|
||||
|
||||
#ifndef ICONV_OPTION
|
||||
"no "
|
||||
|
||||
1
util1.c
1
util1.c
@@ -31,7 +31,6 @@ extern int do_fsync;
|
||||
extern int protect_args;
|
||||
extern int modify_window;
|
||||
extern int relative_paths;
|
||||
extern int preserve_mtimes;
|
||||
extern int preserve_xattrs;
|
||||
extern int omit_link_times;
|
||||
extern int preallocate_files;
|
||||
|
||||
Reference in New Issue
Block a user