Compare commits

...

1220 Commits

Author SHA1 Message Date
Andrew Tridgell
de3cc03b03 Preparing for release of 3.4.2 [buildall] 2026-04-28 14:29:48 +10:00
Andrew Tridgell
006ee327d6 packaging: new release script 2026-04-28 14:27:41 +10:00
Andrew Tridgell
9b6363fa10 update NEWS.md ready for 3.4.2 2026-04-28 12:55:38 +10:00
Andrew Tridgell
9e2f0fe9ae packaging: remove support for rsync-patches 2026-04-28 12:55:38 +10:00
Michal Ruprich
4f6e4ea64a Do not clean DISPLAY unconditionally 2026-04-22 13:05:35 +10:00
Andrew Tridgell
567c40935f call tzset() before chroot to cache timezone data
localtime/localtime_r need /etc/localtime for timezone info.
After chroot this file is inaccessible, causing log timestamps
to fall back to UTC. Calling tzset() before chroot ensures the
timezone data is cached by glibc for subsequent calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 13:02:10 +10:00
Michal Ruprich
8e11f0c169 Using a correct time in log file 2026-04-22 13:02:10 +10:00
Andrew Tridgell
e9dbc8d66d rsyncd.conf: document the temp dir parameter
The temp dir parameter was functional but undocumented in the man page.

Fixes: https://github.com/RsyncProject/rsync/issues/820

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 12:34:58 +10:00
Andrew Tridgell
bd2dbd2f32 runtests.py: preserve test-execution order in skipped list
The sorted() call reordered skipped test names alphabetically,
causing CI expected-skipped mismatches (e.g. acls,acls-default
instead of acls-default,acls). Sort by original test order instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 12:34:39 +10:00
Andrew Tridgell
350e295d1c runtests.py: add -j/--parallel option for parallel test execution
Add parallel test execution using concurrent.futures. With -j8 the
test suite completes in ~4s vs ~29s sequential (~7x speedup).

Also fix two issues that caused failures under parallel execution:
- rsync_ls_lR now prunes testtmp/ so parallel tests don't see each
  other's temp files when scanning the source tree
- clean-fname-underflow.test now uses $scratchdir instead of /tmp

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 12:34:39 +10:00
Andrew Tridgell
066156fcd9 replace runtests.sh with runtests.py
Rewrite the test runner in Python with proper command-line options
including --valgrind which directs valgrind output to per-process
log files so it doesn't interfere with test output comparisons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 12:34:39 +10:00
Holger Hoffstätte
a5bbe859db Fix glibc-2.43 constness warnings
Glibc 2.43 added C23 const-preserving overloads to various string functions,
which change the return type depending on the constness of the argument(s).
Currently this leads to warnings from calls to strtok() or strchr().
Fix this by properly declaring the respective variable types.

Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
2026-04-22 12:10:08 +10:00
Andrew Tridgell
d046525de3 zero all new memory from allocations
Change my_alloc() to use calloc instead of malloc so all fresh
allocations return zeroed memory. Also zero the expanded portion
in expand_item_list() after realloc, since it knows both old and
new sizes. This gives more predictable behaviour in case of bugs
where uninitialised or stale memory is accidentally accessed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 11:44:10 +10:00
Andrew Tridgell
bb0a8118c2 xattrs: fixed count in qsort
this fixes the count passed to the sort of the xattr list. This issue
was reported here:

https://www.openwall.com/lists/oss-security/2026/04/16/2

the bug is not exploitable due to the fork-per-connection design of
rsync, the attack is the equivalent of the user closing the socket
themselves.
2026-04-22 10:38:14 +10:00
Andrew Tridgell
d1df0aaf70 fix signed integer overflow in proxy protocol v2 header parsing
The len field in the proxy v2 header was declared as signed char,
allowing a negative size to bypass the validation check and cause
a stack buffer overflow when passed to read_buf() as size_t.

This bug was reported by John Walker from ZeroPath, many thanks for
the clear report!

With the current code this bug does not represent a security issue as
it only results in the exit of the forked process that is specific to
the attached client, so it is equivalent to the client closing the
socket, so no CVE for this, but it is good to fix it to prevent a
future issue.
2026-04-16 13:59:52 +10:00
Andrew Tridgell
15d8e49a64 zlib: convert K&R function definitions to ANSI style
The bundled zlib 1.2.8 used K&R-style function definitions which are
rejected by clang 16+ as hard errors. Convert all 90 functions across
9 files to ANSI-style prototypes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 13:49:30 +10:00
Andrew Tridgell
b905ab23af CI: add simd-checksum to expected-skipped on macOS and Cygwin
The new simd-checksum test is skipped on platforms where SIMD
instructions are unavailable (macOS ARM, Cygwin). Add it to the
RSYNC_EXPECT_SKIPPED lists so CI doesn't fail on the mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 09:52:01 +11:00
Andrew Tridgell
aa142f08ef fix uninitialized mul_one in AVX2 checksum and add SIMD checksum test
The AVX2 get_checksum1_avx2_64() read mul_one before initializing it,
which is undefined behavior. Replace the cmpeq/abs trick with
_mm256_set1_epi8(1) to match the SSSE3 and SSE2 versions.

Add a TEST_SIMD_CHECKSUM1 test mode that verifies all SIMD paths
(SSE2, SSSE3, AVX2, and the full dispatch chain) produce identical
results to the C reference, across multiple buffer sizes with both
aligned and unaligned buffers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 09:52:01 +11:00
Andrew Tridgell
236417cf35 acl: fixed ACL ID mapping for non-root
closes issue #618
2026-01-19 11:32:13 +11:00
Andrew Tridgell
2a97d81e99 CI: fixed MacOS test
fixed multiple MacOS issues
2025-12-31 11:37:27 +11:00
Andrew Tridgell
359e539a72 reject negative token values in compressed stream receivers
Validate that token numbers read from compressed streams are
non-negative. A negative token value would cause the return value
of recv_*_token() to become positive, which callers interpret as
literal data length, but no data pointer is set on this code path.

While this only causes the receiver to crash (which is process-isolated
and only affects the attacker's own connection), it's still undefined
behavior.

Reported-by: Will Sergeant <wlsergeant@gmail.com>
2025-12-31 09:31:52 +11:00
Andrew Tridgell
9e0898460d util: fixed issue in clean_fname()
fixes buffer underflow (not exploitable) in clean_fname
2025-12-30 17:49:35 +11:00
Andrew Tridgell
185520a141 testsuite: added clean-fname-underflow test 2025-12-30 17:49:35 +11:00
Andrew Tridgell
c98f9d1f68 fix uninitialized buf1 in get_checksum2() MD4 path
The static buf1 pointer was only allocated when len > len1, but on
first call with len == 0, this condition is false (0 > 0), leaving
buf1 NULL when passed to memcpy().

Fixes #673
2025-12-30 16:51:43 +11:00
Nebojša Cvetković
1f9ce2fcbe rsync: Add missing dirs long option 2025-12-30 16:48:34 +11:00
Andrew Tridgell
797e17fc4a fixed an invalid access to files array
this was found by Calum Hutton from Rapid7. It is a real bug, but
analysis shows it can't be leverged into an exploit. Worth fixing
though.

Many thanks to Calum and Rapid7 for finding and reporting this
2025-08-23 17:49:19 +10:00
Ronnie Sahlberg
c2db921890 options.c: Fix segv if poptGetContext returns NULL
If poptGetContext returns NULL, perhaps due to OOM,
a NULL pointer is passed into poptReadDefaultConfig()
which in turns SEGVs when trying to dereference it.

This was found using https://github.com/sahlberg/malloc-fail-tester.git
$ ./test_malloc_failure.sh rsync -Pav crash crosh

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-08-23 17:49:03 +10:00
Silent
77be09aaed syscall: fix a Y2038 bug by replacing Int32x32To64 with multiplication
Int32x32To64 macro internally truncates the arguments to int32,
while time_t is 64-bit on most/all modern platforms.
Therefore, usage of this macro creates a Year 2038 bug.
2025-08-23 17:32:11 +10:00
Jeremy Norris
0d0f615240 Ignore directory has vanished errors. 2025-08-23 17:31:52 +10:00
Max Kellermann
b6457bbc83 make lots of global variables const
This way, they can live in `.rodata` and the compiler is allowed to do
certain optimizations.
2025-08-23 17:31:40 +10:00
Peter Eriksson
1807ce485a Fix handling of objects with many xattrs on FreeBSD 2025-08-23 17:31:28 +10:00
Rahul Mehta
9c175ac9ef chore: gitignore MacOS debug symbols 2025-08-23 17:31:12 +10:00
Emily
a84b79ea58 Allow ls(1) to fail in test setup
This can happen when the tests are unable to `stat(2)` some files in
`/etc`, `/bin`, or `/`, due to Unix permissions or other sandboxing. We
still guard against serious errors, which use exit code 2.
2025-08-23 17:30:59 +10:00
fbuescher
d4c4f6754e fixed remove multiple leading slashes 2025-08-23 17:14:43 +10:00
Michal Ruprich
a4b926dcdc bool is a keyword in C23 2025-08-23 17:14:26 +10:00
Eli Schwartz
0973d0e380 configure.ac: check for xattr support both in libc and in -lattr
In 2015, the attr/xattr.h header was fully removed from upstream attr.

In 2020, rsync started preferring the standard header, if it exists:
https://github.com/RsyncProject/rsync/pull/22

But the fix was incomplete. We still looked for the getxattr function in
-lattr, and used it if -lattr exists. This was the case even if the
system libc was sufficient to provide the needed functions. Result:
overlinking to -lattr, if it happened to be installed for any other
reason.

```
checking whether to support extended attributes... Using Linux xattrs
checking for getxattr in -lattr... yes
```

Instead, use a different autoconf macro that first checks if the
function is available for use without any libraries (e.g. it is in
libc).

Result:

```
checking whether to support extended attributes... Using Linux xattrs
checking for library containing getxattr... none required
```

Signed-off-by: Eli Schwartz <eschwartz@gentoo.org>
2025-08-23 17:14:06 +10:00
Ethan Halsall
e405cfc073 feat: add compress threads to man page 2025-08-23 17:13:49 +10:00
Ethan Halsall
b78a841bb0 feat: validate compress threads option 2025-08-23 17:13:49 +10:00
Ethan Halsall
f7a2b8a3fa feat: add threads to zstd compression 2025-08-23 17:13:49 +10:00
Arnaud Rebillout
d941807915 Fix flaky hardlinks test
The test was added in dc34990, it turns out that it's flaky. It failed
once on the Debian build infra, cf. [1].

The problem is that the command `rsync -aH '$fromdir/sym' '$todir'`
updates the mod time of `$todir`, so there might be a diff between the
output of `rsync_ls_lR $fromdir` and `rsync_ls_lR $todir`, if ever rsync
runs 1 second (or more) after the directories were created.

To clarify: it's easy to make the test fails 100% of the times with this
change:

```
 makepath "$fromdir/sym" "$todir"
+sleep 5
 checkit "$RSYNC -aH '$fromdir/sym' '$todir'" "$fromdir" "$todir"
```

With the fix proposed here, we don't use `checkit` anymore, instead we
just run the rsync command, then a simple `diff` to compare the two
directories. This is exactly what the other `-H` test just above does.

In case there's some doubts, `diff` fails if `sym` is missing:

```
$ mkdir -p foo/sym bar
$ diff foo bar || echo KO!
Only in foo: sym
KO!
```

I tested that, after this commit, the test still catches the `-H`
regression in rsync 3.4.0.

Fixes: https://github.com/RsyncProject/rsync/issues/735

[1]: https://buildd.debian.org/status/fetch.php?pkg=rsync&arch=ppc64el&ver=3.4.1%2Bds1-1&stamp=1741147156&raw=0
2025-08-23 17:13:28 +10:00
Krzysztof Płocharz
992e10efaf Fix --open-noatime option not working on files
atime of source files could sometimes be overwritten
even though --open-noatime option was used.

To fix that, optional O_NOATIME flag was added
to do_open_nofollow which is also used to open regular
files since fix:
  "fixed symlink race condition in sender"
Previously optional O_NOATIME flag was only in do_open.
2025-08-23 17:13:09 +10:00
Chris Lamb
1c5ebdc4e5 Make the build reproducible
From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1093201:
Whilst working on the Reproducible Builds effort [0], we noticed that
rsync could not be built reproducibly.

This is because the date in the manual page can vary depending on
whether there is a .git directory and the modification time of version.h
and Mafile, which might get modified when patching via quilt.

A patch is attached that makes this use SOURCE_DATE_EPOCH, which
will always be reliable.
2025-08-23 16:40:34 +10:00
Wayne Davison
9994933c8c Test on ubuntu-latest. 2025-02-11 13:37:12 -08:00
Alan Coopersmith
23d9ead5af popt: remove obsolete findme.c & findme.h
popt 1.14 merged these into popt.c but the import into rsync
missed removing them.

Fixes: https://github.com/RsyncProject/rsync/issues/710

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2025-01-17 08:31:36 +11:00
Wayne Davison
fcfdd36054 Update MAINTAINER_TZ_OFFSET on release.
This also fixes a string with \s that wasn't a r'...' string.
2025-01-15 23:27:27 -08:00
Wayne Davison
89b847393f Fix python deprecation warning. 2025-01-15 22:36:29 -08:00
Wayne Davison
788ecbe5ea Don't edit copyright year values anymore. 2025-01-15 22:30:32 -08:00
Wayne Davison
353506bc51 Improve interior dashes in long options.
Improve the backslash-adding code in md-convert to affect dashes in the
interior of long options.  Perhaps fixes #686.
2025-01-15 22:23:30 -08:00
Wayne Davison
7cff121ec8 Start 3.4.2dev going. 2025-01-15 22:01:42 -08:00
Andrew Tridgell
14f33837dc fixed build error on ia64 NonStop
it treats missing prototype as an error, not warning
2025-01-16 15:27:21 +11:00
Andrew Tridgell
3305a7a063 Preparing for release of 3.4.1 [buildall] 2025-01-16 07:49:23 +11:00
Andrew Tridgell
494879b819 update NEWS.md for 3.4.1 2025-01-16 07:47:07 +11:00
Andrew Tridgell
8d6da040e5 popt: remove dependency on alloca 2025-01-16 07:27:46 +11:00
Natanael Copa
68e9add76a Fix build on ancient glibc without openat(AT_FDCWD
Fixes: https://github.com/RsyncProject/rsync/issues/701
2025-01-16 06:43:57 +11:00
Rodrigo OSORIO
dc34990b2e Test send a single directory with -H enabled
Ensure this still working after 3.4.0 breakage

https://github.com/RsyncProject/rsync/issues/702
2025-01-16 06:32:17 +11:00
Natanael Copa
81ead9e70c Fix use-after-free in generator
full_fname() will free the return value in the next call so we need to
duplicate it before passing it to rsyserr.

Fixes: https://github.com/RsyncProject/rsync/issues/704
2025-01-16 06:27:26 +11:00
Natanael Copa
996af4a79f Fix FLAG_GOT_DIR_FLIST collission with FLAG_HLINKED
fixes commit 688f5c379a (Refuse a duplicate dirlist.)

Fixes: https://github.com/RsyncProject/rsync/issues/702
Fixes: https://github.com/RsyncProject/rsync/issues/697
2025-01-16 06:21:54 +11:00
Andrew Tridgell
dacadd53a9 update maintainer address
use rsync.project@gmail.com
2025-01-15 12:13:41 +11:00
Wayne Davison
a6312e60c9 Force rsync group when uploading files. 2025-01-14 13:09:33 -08:00
Andrew Tridgell
e3ee0e7319 Preparing for release of 3.4.0 [buildall] 2025-01-15 05:53:23 +11:00
Andrew Tridgell
0fd29b6bcb packaging: adjust release script
remove auto-edit of NEWS.md
2025-01-15 05:50:22 +11:00
Andrew Tridgell
7f79682732 NEWS: update protocol version table 2025-01-15 05:50:05 +11:00
Andrew Tridgell
870b7d96dc update NEWS for 3.4.0 2025-01-15 05:30:32 +11:00
Andrew Tridgell
9dc31473ba change version to 3.4.0 2025-01-15 05:30:32 +11:00
Andrew Tridgell
536ae3f4ef raise protocol version to 32
make it easier to spot unpatched servers
2025-01-15 05:30:32 +11:00
Andrew Tridgell
0590b09d9a fixed symlink race condition in sender
when we open a file that we don't expect to be a symlink use
O_NOFOLLOW to prevent a race condition where an attacker could change
a file between being a normal file and a symlink
2025-01-15 05:30:32 +11:00
Andrew Tridgell
407c71c7ce make --safe-links stricter
when --safe-links is used also reject links where a '../' component is
included in the destination as other than the leading part of the
filename
2025-01-15 05:30:32 +11:00
Andrew Tridgell
344327385f range check dir_ndx before use 2025-01-15 05:30:32 +11:00
Wayne Davison
688f5c379a Refuse a duplicate dirlist. 2025-01-15 05:30:32 +11:00
Andrew Tridgell
9f86ddc965 disallow ../ elements in relpath for secure_relative_open 2025-01-15 05:30:32 +11:00
Andrew Tridgell
c35e28331f receiver: use secure_relative_open() for basis file
this prevents attacks where the basis file is manipulated by a
malicious sender to gain information about files outside the
destination tree
2025-01-15 05:30:32 +11:00
Andrew Tridgell
b4a27ca25d added secure_relative_open()
this is an open that enforces no symlink following for all path
components in a relative path
2025-01-15 05:30:32 +11:00
Andrew Tridgell
8ad4b5d912 refuse fuzzy options when fuzzy not selected
this prevents a malicious server providing a file to compare to when
the user has not given the fuzzy option
2025-01-15 05:30:32 +11:00
Andrew Tridgell
589b0691e5 prevent information leak off the stack
prevent leak of uninitialised stack data in hash_search
2025-01-15 05:30:32 +11:00
Charalampos Mitrodimas
36212021f0 hlink: Fix function pointer cast in qsort()
Replace unsafe generic function pointer cast with proper type cast for
qsort() comparison function. This fixes a potential type mismatch
warning without changing the behavior.

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
2024-12-18 08:56:27 +11:00
Andrew Tridgell
2b38542e0d added security email address to README.md 2024-12-18 08:55:45 +11:00
Frederic Grabowski
321dd78f8c fix typo in manual page 2024-11-19 21:45:50 -08:00
Romain Geissler
6f10f12577 When not using the builtin zlib, link it before linking libcrypto, as libcrypto depends on zlib.
This prevents "undefined symbol" errors which might arise from libcrypto.a if linking openssl statically.
2024-11-19 21:40:14 -08:00
Colin Watson
1a95869dfc Allow basic connectivity check via rrsync
rsbackup (https://github.com/ewxrjk/rsbackup) uses "ssh <host> true" to
check that the host in question is reachable.  I like to configure my
backed-up hosts to force the backup system to go via `rrsync`, but I
always have to add a local tweak to allow `SSH_ORIGINAL_COMMAND=true` to
work.  I think this would be safe enough to include in rrsync.
2024-11-19 21:35:49 -08:00
Rose
c9fe6ca304 Introduce PTR_SUB
This is more intuitive than adding a negative number.
2024-11-19 21:33:30 -08:00
Samuel Henrique
990fa5c1e1 rrsync: fix wrong parameter name in manpage SYNOPSIS
Replace ¨rw¨ with ¨ro¨.

Reported on Debian by Adriano Rafael Gomes <adrianorg@debian.org>
2024-11-19 21:32:18 -08:00
Holger Hoffstätte
07069880a2 Fix warning about conflicting lseek/lseek64 prototypes
Clang rightfully complains about conflicting prototypes, as both lseek() variants
are redefined:

  syscall.c:394:10: warning: a function declaration without a prototype is deprecated
  in all versions of C and is treated as a zero-parameter prototype in C2x, conflicting
  with a previous declaration [-Wdeprecated-non-prototype]
        off64_t lseek64();
                ^
/usr/include/unistd.h:350:18: note: conflicting prototype is here
extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence)
                 ^
1 warning generated.

The point of the #ifdef is to build for the configured OFF_T; there is
no reason to redefine lseek/lseek64, which should have been found
via configure.

Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
2024-11-19 21:28:39 -08:00
Holger Hoffstätte
e55b190f4a Fix warning about missing bomb(..) prototype
Clang rightfully complains about invoking bomb(..) without a proper prototype:
  lib/pool_alloc.c:171:16: warning: passing arguments to a function without a prototype
  is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype]
                (*pool->bomb)(bomb_msg, __FILE__, __LINE__);
                             ^
1 warning generated.

Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
2024-11-19 21:28:39 -08:00
Holger Hoffstätte
48d51a1370 Fix __m128i_u / __m256i_u alignment
Building with clang-16 complains with:
./simd-checksum-x86_64.cpp:204:25: warning: passing 1-byte aligned argument to
  16-byte aligned parameter 1 of '_mm_store_si128' may result in an unaligned pointer
  access [-Walign-mismatch]

Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
2024-11-19 21:28:39 -08:00
Wayne Davison
f654e47691 Mention latest NEWS. 2024-11-14 11:59:12 -08:00
Wayne Davison
83ad3533d4 Always check old==new, even for missing array size. 2024-11-14 11:53:40 -08:00
Wayne Davison
fa28c5d693 Improve packaging/var-checker.
Make var-checker compare the variable type of the extern vars to ensure
that they are all consistent. Fix the remaining issues.
2024-11-14 11:42:24 -08:00
Carlo Marcelo Arenas Belón
62bb9bba02 acls: correct type/size for orig_umask
Since 05278935 (- Call mkdir_defmode() instead of do_mkdir(). - Define
orig_umask in this file, not options.c. - Made orig_umask a mode_t, not an
int., 2006-02-24), the type for the global was changed, and therefore on
systems where sizeof(mode_t) != sizeof(int), writes or reads to them will
overflow to adjacent bytes.

Change the type to the one used everywhere else and avoid this problem.

While at it, silence again a warning that is being triggered by
Apple's clang 15.
2024-11-14 07:15:14 +11:00
Wayne Davison
6601510425 Mention more NEWS. 2024-11-09 11:05:16 -08:00
Wayne Davison
f7ac7ffd16 Some minor option/prompt tweaks. 2024-11-05 17:50:16 -08:00
Wayne Davison
4320c25fcc More helper script improvements. 2024-11-05 13:44:17 -08:00
Wayne Davison
4490fb8660 Add some info for making a release. 2024-11-05 13:03:04 -08:00
Wayne Davison
475ca7d43c Add helper script for updating samba files. 2024-11-05 12:42:42 -08:00
Wayne Davison
7c3c54b132 Don't force zsh use. 2024-11-05 11:20:28 -08:00
Wayne Davison
bcf0738f98 Indentation tweak. 2024-11-05 11:20:17 -08:00
Wayne Davison
8749ec6436 Update to newer artifact version. 2024-11-05 11:14:46 -08:00
Wayne Davison
42e2b56c4e Another cast when multiplying integers. 2024-11-05 11:01:03 -08:00
Wayne Davison
0902b52f66 Some checksum buffer fixes.
- Put sum2_array into sum_struct to hold an array of sum2 checksums
  that are each xfer_sum_len bytes.
- Remove sum2 buf from sum_buf.
- Add macro sum2_at() to access each sum2 array element.
- Throw an error if a sums header has an s2length larger than
  xfer_sum_len.
2024-10-29 23:06:34 -07:00
vincent sgherzi
9615a2492b added apple silicon path details 2024-05-29 11:19:19 +10:00
Wayne Davison
4592aa770d More tweaks for Actions.
- When a .github/workflows/*.yml file changes, skip running unaffected
  builds.
- We need git to be installed for git-version.h generation.
2024-04-10 13:24:09 -07:00
Wayne Davison
8bc363cc9f Separate the builds and make Cygwin always run. 2024-04-10 13:02:34 -07:00
Wayne Davison
a9a3155756 Work around pkg install issue.
The xxhash, lz4, and zstd libraries aren't getting installed on FreeBSD.
[buildall]
2024-04-10 12:45:26 -07:00
Wayne Davison
fcc79836b8 Get fetch-depth:0 right. 2024-04-10 12:30:05 -07:00
Wayne Davison
804411b7fd Get rid of gensend target & cached git version.
- Change the developer flow to not require updating the git-version repo
  that the builds used to download a git-version.h file. The Actions now
  do a full repo fetch so that the .h file can be generated via the git
  history.
- Get rid of the gensend Makefile target that was used for the above.
- Get rid of the pre-push git hook file that called "Make gensend".
- Change the FreeBSD build to save an artifact with its built binaries.

[buildall]
2024-04-10 12:23:58 -07:00
Wayne Davison
0b1b2a3ff4 Get the "dev" suffix right. 2024-04-10 11:53:17 -07:00
Wayne Davison
50bdf9685d Remove duplicate paragraph. 2024-04-10 11:51:59 -07:00
Charalampos Mitrodimas
3f2a38b011 CI: added Solaris build
Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
2024-04-09 07:34:26 +10:00
Wayne Davison
5510255f12 Tweak maintainer messaging. 2024-04-08 13:16:12 -07:00
Wayne Davison
56a039b04a Changes for 3.3.1dev. 2024-04-08 13:15:16 -07:00
Andrew Tridgell
7bc3be2b9e CI: fixed rules for when to trigger 2024-04-08 15:50:47 +10:00
Andrew Tridgell
411c4789df support: added install_deps_ubuntu.sh
convenient way to bootstrap quickly
2024-04-08 15:32:16 +10:00
Andrew Tridgell
231b239f30 check for stpcpy
needed for popt on macos
2024-04-08 15:31:36 +10:00
Andrew Tridgell
4c8683c875 update to popt 1.19 2024-04-08 15:31:36 +10:00
Rose
85c906f964 Silence unused var warning
recv_ida_entries still needs to be called regardless, so we cannot take that out. Let's just quiet the compiler instead.
2024-04-07 09:28:03 +10:00
Christian Hesse
35f5a21a16 hint that a proxy can handle plain and ssl stream at the same time 2024-04-07 09:25:46 +10:00
Andrew Tridgell
99673f937f CI: added FreeBSD build 2024-04-07 08:07:50 +10:00
Andrew Tridgell
9505ac5945 removed old cirrus CI 2024-04-07 08:07:50 +10:00
Ivan Babrou
0dd25d4752 configure.ac: fix failing IPv6 check due to missing return type
Fixing this warning escalated to an error, resuting in no IPv6 support:

```
configure.sh:7679: checking whether to enable ipv6
configure.sh:7718: clang -o conftest -g -O2 -DHAVE_CONFIG_H -Wall -W   conftest.c  >&5
conftest.c:73:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
main()
^
int
1 error generated.
configure.sh:7718: $? = 1
configure.sh: program exited with status 1
```
2024-04-07 07:46:47 +10:00
Wayne Davison
ae3e13ba99 Update github links. 2024-04-06 10:33:42 -07:00
Wayne Davison
6c8ca91c73 Preparing for release of 3.3.0 [buildall] 2024-04-06 09:30:21 -07:00
Wayne Davison
079e74a30f Some year updates. 2024-04-06 09:22:29 -07:00
Wayne Davison
abc3c74652 Mention latest changes in NEWS. 2024-04-06 09:22:29 -07:00
Jiri Slaby
99ab59464b exclude: fix crashes with fortified strlcpy()
Fortified (-D_FORTIFY_SOURCE=2 for gcc) builds make strlcpy() crash when
its third parameter (size) is larger than the buffer:
  $ rsync -FFXHav '--filter=merge global-rsync-filter' Align-37-43/ xxx
  sending incremental file list
  *** buffer overflow detected ***: terminated

It's in the exclude code in setup_merge_file():
  strlcpy(y, save, MAXPATHLEN);

Note the 'y' pointer was incremented, so it no longer points to memory
with MAXPATHLEN "owned" bytes.

Fix it by remembering the number of copied bytes into the 'save' buffer
and use that instead of MAXPATHLEN which is clearly incorrect.

Fixes #511.
2024-04-06 08:41:41 -07:00
Grant Gardner
a47ae6fad9 typo in rsyncd.conf.5.md 2024-04-06 09:53:47 +11:00
Wayne Davison
2f9b963aba Make --max-alloc=0 safer.
Always do size checking in my_alloc(), even for `--max-alloc=0`.
2023-06-27 09:01:25 -07:00
Wayne Davison
3476caea3e Convert mnt-excl into python. 2023-05-22 08:29:15 -07:00
Wayne Davison
6f3c5eccee Fix old stats bug that counted devices as symlinks. 2023-05-16 22:44:54 -07:00
Wayne Davison
79fda35342 A couple more NEWS improvements. 2023-05-08 08:15:42 -07:00
Wayne Davison
cd76993461 Mention updated config files. 2023-05-04 08:45:42 -07:00
zhangwenlong
05a683900f update config.guess config.sub (#478)
- curl -sL -o config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
- curl -sL -o config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'

Signed-off-by: Wenlong Zhang <zhangwenlong@loongson.cn>
2023-05-04 08:41:52 -07:00
Wayne Davison
86f41650fb A couple spelling tweaks; tweak order. 2023-04-30 17:28:50 -07:00
Wayne Davison
9a06b2edb0 Preparing for release of 3.3.0pre1 [buildall] 2023-04-29 09:01:43 -07:00
Wayne Davison
273dced284 Update the NEWS. 2023-04-29 09:01:09 -07:00
Wayne Davison
b6e2321973 Mention that --crtimes support is spotty. 2023-04-29 08:21:19 -07:00
Wayne Davison
fe95a9369a Fix issue with trailing --sparse --inplace blocks.
Fixes #450.
2023-04-29 07:56:27 -07:00
Wayne Davison
6ae7f4085a Add --force-link-text to md-convert. 2023-04-23 08:26:32 -07:00
Wayne Davison
0f599d3641 Fix overflow of sum2 buffer for sha1 rolling checksums.
Fixed #353.
2023-04-22 08:49:50 -07:00
Wayne Davison
c3d3b49d72 Make use of .UR & .UE for links. 2023-04-22 08:40:27 -07:00
Wayne Davison
c69dc7a5ab Tweak shell protection news to mention a few more characters. 2023-03-30 12:56:49 -07:00
dogvisor
2c82006b1f add rrsync option to enforce --ignore-existing (#461)
The `-no-overwrite` rrsync option disallows the updating of existing files for incoming rrsync copies.
2023-03-30 12:55:56 -07:00
Wayne Davison
0698ea9aeb Fix flist string comparison issue in tr_TR.utf-8 locale. 2023-02-05 19:46:45 -08:00
Wayne Davison
90df93e446 Don't call memcmp() on an empty lastdir. 2023-01-08 21:35:39 -08:00
Wayne Davison
5c93dedf45 Add backtick to SHELL_CHARS. 2023-01-04 21:52:48 -08:00
Wayne Davison
f1e3434b59 Trust the sender on a local transfer. 2022-12-01 20:24:17 -08:00
Wayne Davison
48252c3c2b A couple manpage links. 2022-11-23 07:59:12 -08:00
Wayne Davison
5b67ff2a86 Improve [global] module documentation. 2022-11-22 22:55:52 -08:00
Wayne Davison
8990ad96de Duplicate argv data before poptFreeContext(). 2022-11-22 22:21:15 -08:00
Wayne Davison
0f44e864d4 Another python conversion. 2022-11-20 09:38:12 -08:00
Wayne Davison
ab0d5021ed Convert a few more scripts to python3. 2022-11-16 00:10:09 -08:00
Wayne Davison
7402896523 Tweak an older NEWS item to be a bit clearer. 2022-11-09 16:04:02 -08:00
Wayne Davison
5374994089 Avoid quoting of tilde when it's a destination arg. 2022-11-05 09:22:10 -07:00
Wayne Davison
526366129a Upgrade verion of actions. 2022-11-02 23:54:41 -07:00
Wayne Davison
556a2c5bc2 Check for EVP_MD_CTX_copy in crypto lib instead of MD5_Init. 2022-10-25 21:55:53 -07:00
Wayne Davison
27feda0436 Call OpenSSL_add_all_algorithms() on older openssl versions. 2022-10-25 09:04:45 -07:00
Wayne Davison
bf96cd314c Init the checksum choices before the daemon auth. 2022-10-25 09:04:45 -07:00
Wayne Davison
1b2688807d Fix protocol <= 29 daemon auth if openssl is handling md4. 2022-10-24 08:38:00 -07:00
Wayne Davison
08ec80ac65 Cygwin needs stdout flushed. [buildall] 2022-10-22 12:04:32 -07:00
Wayne Davison
6b5ae825db Preparing for release of 3.2.7 [buildall] 2022-10-20 17:57:22 -07:00
Wayne Davison
3b719d1d6e Improve JSON output a bit more. 2022-10-20 17:50:06 -07:00
Wayne Davison
ebe1af749c Make use of -VV when checking rsync capabilities. 2022-10-20 09:09:26 -07:00
Wayne Davison
de6848ed97 Re-run the exclude test using lsh.sh pull.
The exclude.test file continues to run local copies (which are a special
kind of "push") while the exclude-lsh.test symlink runs a a "pull" using
the lsh.sh script as the "remote" shell.
2022-10-19 20:58:29 -07:00
Wayne Davison
42f8386823 Improve --mkpath a bit more. 2022-10-16 12:27:30 -07:00
Wayne Davison
ad6245f394 Include "buildall" flag in the release commit. 2022-10-16 12:14:46 -07:00
Wayne Davison
ca980b5863 Yet another manpage tweak. 2022-10-16 12:10:05 -07:00
Wayne Davison
677aa0dc91 Fix version verification when "\|" doesn't work in sed. 2022-10-16 11:14:15 -07:00
Wayne Davison
025596757c Silence autoconf warnings. 2022-10-16 10:28:58 -07:00
Wayne Davison
449d9bf950 Make the new manpage section better. 2022-10-16 10:26:39 -07:00
Wayne Davison
35ecec972a A few more manpage clarifications. 2022-10-15 17:02:18 -07:00
Alexponomarev7
d76cabe54f Fix autoconf help strings (#389) 2022-10-15 16:54:27 -07:00
Wayne Davison
b5544a95b1 Add info on single-file copying; tweak --mkpath. 2022-10-12 10:16:47 -07:00
Wayne Davison
11bd2a4fd6 Tweak NEWS. 2022-10-10 08:55:09 -07:00
Wayne Davison
6ba434de5c Change fgrep to grep. 2022-10-06 22:18:48 -07:00
Wayne Davison
3296351442 Fix validation of "preN" git tags for git-version.h. 2022-10-02 11:43:46 -07:00
Wayne Davison
0088a85aeb Mention smart-make in a comment. 2022-10-02 11:26:44 -07:00
Wayne Davison
4923c4dc0c Mention the --list-only output format. 2022-10-02 10:35:23 -07:00
Wayne Davison
76c4fa8b54 Mention latest changes. 2022-10-02 10:03:00 -07:00
Wayne Davison
25efa10802 Complain if the destination arg is empty. 2022-10-02 09:54:59 -07:00
Wayne Davison
fdf5e577f5 Read a 4-byte mtime as unsigned (old-protocol).
When conversing with a protocol 29 or earlier rsync, the modtime values
are arriving as 4-byte integers.  This change interprets these short
values as unsigned integers, allowing the time that can be conveyed to
range from 1-Jan-1970 to 7-Feb-2106 instead of the signed range of
13-Dec-1901 to 19-Jan-2038.  Given that we are fast approaching 2038,
any old-protocol transfers will be better served using the unsigned
range rather than the signed.

It is important to keep in mind that protocol 30 & 31 convey the full
8-byte mtime value (plus nanoseconds), allowing for a huge span of time
that is not affected by this change.
2022-10-02 09:54:54 -07:00
Wayne Davison
19bd0dd340 Use newer protocol to avoid mtime corruption. 2022-10-01 08:04:00 -07:00
Wayne Davison
ed4b3448be Preparing for release of 3.2.7pre1 2022-09-30 12:36:21 -07:00
Wayne Davison
4d44bf122d A few more doc tweaks & comment tweaks. 2022-09-30 12:34:58 -07:00
Wayne Davison
6af27a538e Explicitly ignore snprintf() return value. 2022-09-30 11:50:20 -07:00
Wayne Davison
f9e29dfb09 More NEWS updates. 2022-09-25 13:20:06 -07:00
Wayne Davison
591de7ce5c Fix compile w/o openssl; disable sha256 & sha512 for --checksum. 2022-09-25 12:42:09 -07:00
Wayne Davison
c8c627756a Avoid test -e. 2022-09-20 21:50:07 -07:00
Wayne Davison
46884e4ff6 Fix a link. 2022-09-20 00:12:49 -07:00
Wayne Davison
97e02bf21a Some "use chroot" improvements.
- The sanitize_paths variable was set too often. It only needs to be set
  when the "inner" path is not "/".  This change avoids sanitizing &
  munging things for a path=/ module just because chroot is off.
- The default for "use chroot" is now "unset" instead of "true".  When
  unset it checks if chrooting works, and if not, it proceeds with a
  sanitized copy instead of totally failing to work.  This makes it
  easier to setup a non-root rsync daemon, for instance.  It will have
  no effect on a typical Linux root-run daemon where the default will
  continue to use chroot (because chrooting works).  A config file can
  explicitly set "use chroot = true | false" to force the choice.
- Try to improve the "use chroot" manpage.
2022-09-20 00:08:16 -07:00
Wayne Davison
77d762ced8 Stop importing "re". 2022-09-19 22:36:49 -07:00
Wayne Davison
5b27d2e6f3 Pre-compute FILE_SUM_EXTRA_CNT. 2022-09-15 10:25:32 -07:00
Wayne Davison
7e634f5355 We always add a slash now that path is cleaned. 2022-09-15 10:13:20 -07:00
Kenneth Finnegan
8fe8cfd60a Use string length diff heuristic to skip Levenshtein Algo (#369)
When using the --fuzzy option to try and find close matches locally,
the edit distance algorithm used is O(N^2), which can get painful on
CPU constrained systems when working in folders with tens of thousands
of files in it.

The lower bound on the calculated Levenshtein distance is the difference
of the two strings being compared, so if that difference is larger than
the current best match, the calculation of the exact edit distance between
the two strings can be skipped.

Testing on the OpenSUSE package repo has shown a 50% reduction in the CPU time
required to plan the rsync transaction.
2022-09-15 10:12:02 -07:00
Wayne Davison
7a2dbf7177 Make the implied-arg adding for --relative more efficient. 2022-09-14 08:20:41 -07:00
Wayne Davison
8449539a0f More NEWS updates. 2022-09-14 07:57:44 -07:00
Wayne Davison
71c2b5d0e3 Fix exclusion of /. with --relative. 2022-09-14 07:14:13 -07:00
Wayne Davison
f3f5d8420f Tweak a define. 2022-09-14 07:13:24 -07:00
Wayne Davison
8b1b81e054 Use UNSUPPORTED instead of PROTOCOL for various validation checks. 2022-09-13 23:38:01 -07:00
Wayne Davison
e8161304f7 Use hashlittle2() for xattr hashing
- The non-zero key code is now in hashtable.c
- The hashtable_create() code already checks for OOM
2022-09-13 22:43:01 -07:00
Wayne Davison
b012cde1ed Add hashlittle2() and ensure the hash is never 0
It's probably time for a faster hash algorithm, but this gives us
the free 64-bit hashing that things like the xattr code can use.
2022-09-13 22:37:39 -07:00
Wayne Davison
464555ea92 Fix really silly bug with --relative rules. 2022-09-13 20:56:32 -07:00
Wayne Davison
df904f590e Improve var ref. 2022-09-13 20:55:58 -07:00
Wayne Davison
208d6ad1cd NEWS tweak. 2022-09-13 20:54:35 -07:00
Wayne Davison
51dae12c92 Update NEWS. 2022-09-12 22:04:33 -07:00
Wayne Davison
950730313d Fix bug with validing remote filter rules. 2022-09-12 22:02:00 -07:00
Wayne Davison
81c5c81381 Mention the filename when unpack_smb_acl() returns an error. 2022-09-11 10:04:26 -07:00
Wayne Davison
a6a0d2f77c Require a newer protocol to specify the digest list. 2022-09-10 22:12:24 -07:00
Wayne Davison
418e38a878 Talk about the new daemon greeting line. 2022-09-10 22:12:23 -07:00
Wayne Davison
b2dcabdbb9 Improve output of "N-bit" items in json data. 2022-09-10 21:10:10 -07:00
Wayne Davison
ad53a9b5a0 Also change dashes in the dict var names to make jq use easier. 2022-09-10 17:30:54 -07:00
Wayne Davison
1750288660 A few more tweaks. 2022-09-10 16:35:20 -07:00
Wayne Davison
087fffaa2b Unify older protect-args capability to secluded-args name. 2022-09-10 16:17:32 -07:00
Wayne Davison
5c1fa2a21d Use dict for capabilities & optimizations in json output. 2022-09-10 16:01:53 -07:00
Wayne Davison
0efa63f2e6 Use JSON output if --version (-V) is repeated (client side only). 2022-09-10 13:14:42 -07:00
Wayne Davison
ae16850dc5 Add support for various SHA checksum digests
The main purpose of the SHA checksums are to allow the daemon auth code
to pick a stonger digest method when negotiating the auth digest to use.
However, the SHA digests are also available for use in file checksums,
should someon really want to use one of them.

The new digests are listed from strongest to weakest at the start of the
daemon auth list, giving them the highest priority.

The new digests are listed from weakest to strongest near the end of the
checksum list, giving them the lowest priority of use for file
checksums.
2022-09-10 11:48:44 -07:00
Wayne Davison
7e2711bb2b Improve various things in the checksum code
- Size flist checksum data to hold the active size, not the max.
- Add a negotiated hash method to the daemon auth code.
- Use EVP for all openssl digests. This makes it easy to add more
  openssl digest methods and avoids deprecation warnings.
- Support a way to re-enable deprecated digests via openssl conf
  file and allow a default file to be configured.
- Supply a simple openssl-rsync.cnf file to enable legacy digests.
2022-09-10 11:39:37 -07:00
Wayne Davison
b8c2fde3a5 Try freebsd-13-1 to fix weird wget issue. 2022-09-09 13:16:27 -07:00
Wayne Davison
1f12b196fd When deleting a tag, del in the patches dir too. 2022-09-09 12:59:22 -07:00
Wayne Davison
bafe73dd5c Start 3.2.7dev going. 2022-09-09 12:59:17 -07:00
Wayne Davison
db5bfe67a5 Preparing for release of 3.2.6 2022-09-09 12:23:37 -07:00
Wayne Davison
5447d038c6 Mention a potential bash security issue with openssh forced commands. 2022-09-09 10:48:52 -07:00
Wayne Davison
711773631b A few more minor tweaks. 2022-09-01 22:07:54 -07:00
Wayne Davison
bf3e49b453 Improve the daemon info a bit. 2022-09-01 22:01:18 -07:00
Wayne Davison
034d5e8770 Tweak a couple links. 2022-08-23 21:12:26 -07:00
Wayne Davison
ad8917437a Mention that copying to a case-ignoring filesystem can be problematical. 2022-08-23 21:02:41 -07:00
Wayne Davison
1b664d30e4 Fix an unreleased bug handling a leading dot. 2022-08-23 19:38:41 -07:00
Wayne Davison
ea38f34d02 Another spelling fix. 2022-08-23 15:44:48 -07:00
Wayne Davison
44d4727664 Fix a link. 2022-08-23 15:30:37 -07:00
Wayne Davison
1f2f413167 Fix split limits. 2022-08-23 15:30:32 -07:00
Wayne Davison
0a09df2c5e Rename --protect-args to --secluded-args. 2022-08-23 14:56:23 -07:00
Wayne Davison
cc861cf8c0 More NEWS tweaks. 2022-08-22 08:15:35 -07:00
Wayne Davison
5183c0d6f0 Add safety check for local --remove-source-files.
A local_server copy now includes the dev+ino info from the destination
file so that the sender can make sure that it is not going to delete
the destination file.  Fixes mistakes such as:

  rsync -aiv --remove-source-files dir .
2022-08-21 10:19:23 -07:00
Wayne Davison
706bff9176 Mention the latest changes. 2022-08-20 08:30:22 -07:00
Wayne Davison
2c1204032b Make sure that the configure.sh script is up-to-date in a release. 2022-08-19 09:49:52 -07:00
Wayne Davison
8adc2240e0 Mention copy-devices. 2022-08-19 08:56:49 -07:00
Wayne Davison
84ad83525b Remove unneeded var. 2022-08-19 08:56:04 -07:00
Wayne Davison
9a3449a398 Stop enabling -pedantic-errors. 2022-08-18 17:33:54 -07:00
Wayne Davison
3258534e99 Change name_num_obj struct to use a name_num_item pointer. 2022-08-18 17:33:25 -07:00
Samuel Henrique
b94bba4036 Fix typos on manpage (#358) 2022-08-17 21:50:43 -07:00
Wayne Davison
a182507bef Fix issue when the files-from list isn't nl terminated. 2022-08-17 16:57:39 -07:00
Wayne Davison
2895b65f53 Another mkgitver tweak & mention it in NEWS. 2022-08-16 08:56:36 -07:00
Wayne Davison
def595c559 Remove useless comment. 2022-08-15 21:56:37 -07:00
Wayne Davison
68b1ce1dc3 Only run git describe if .git exists in the $srcdir. 2022-08-15 21:52:13 -07:00
Wayne Davison
5a4116e553 Start 3.2.6dev going. 2022-08-15 19:01:56 -07:00
Wayne Davison
024bf1d831 Do more path cleaning in add_implied_include(); make u.slash_cnt more accurate. 2022-08-15 18:55:54 -07:00
Wayne Davison
db4f919ebe Allow ~/remote/./path with -R if the path has /./ in it. 2022-08-15 18:55:05 -07:00
Wayne Davison
6ac2c7b682 We must use the CSUM_CHUNK size in the non-openssl MD4 code. 2022-08-14 14:03:02 -07:00
Wayne Davison
0e10163a9d Fix another dot-dir implied arg issue. 2022-08-14 12:27:25 -07:00
Wayne Davison
5fcf20ee9d Preparing for release of 3.2.5 2022-08-14 10:15:08 -07:00
Wayne Davison
fc72d2b771 Update the NEWS. 2022-08-14 10:12:06 -07:00
Wayne Davison
b7ea3fcd19 Ensure a dynamically linked xxhash lib is >= 0.8 for XX3. 2022-08-14 10:09:40 -07:00
Wayne Davison
9cb7529ba6 Remove some trailing whitespace. 2022-08-13 10:53:53 -07:00
Wayne Davison
55ad8757ec Make a --trust-sender a bit clearer. 2022-08-10 16:34:26 -07:00
Wayne Davison
3e4b01173a One more doc tweak. 2022-08-10 08:48:27 -07:00
Wayne Davison
2f1d1d5cac Add packaging note. 2022-08-10 08:42:22 -07:00
Wayne Davison
4c0a4067df Fix handling of a character class with an escaped closing bracket. 2022-08-09 17:55:03 -07:00
Wayne Davison
8550142804 Be a little paranoid. 2022-08-09 17:55:03 -07:00
Wayne Davison
97f40754ba A couple manpage tweaks. 2022-08-09 17:55:01 -07:00
Wayne Davison
cff8f04477 Add --trust-sender option. 2022-08-09 11:45:56 -07:00
Wayne Davison
db8034f12e Escape leading tilde char when "~" or with -R. 2022-08-09 11:42:32 -07:00
Wayne Davison
c86763dc38 Fix handling of daemon module names in file-list verification; convert some while loops to for loops. 2022-08-09 11:37:47 -07:00
Wayne Davison
5ce575b157 Preparing for release of 3.2.5pre2 2022-08-08 22:50:31 -07:00
Wayne Davison
fabef23bea Fix --relative when copying an absolute path. 2022-08-08 21:30:43 -07:00
Wayne Davison
685bf58046 Handle files-from args that span 2 buffers. 2022-08-08 21:18:10 -07:00
Wayne Davison
9e2921fce8 A fix for the zlib fix. 2022-08-08 20:05:10 -07:00
Wayne Davison
80d8f7c7cb Handle a "[foo]" arg matching the literal wildcards. 2022-08-08 19:57:28 -07:00
Wayne Davison
38e1b075b4 Fix some issues with backslashed wildcards in args. 2022-08-08 19:26:05 -07:00
Wayne Davison
d659610afc Handle a trailing "/." at the end of a source arg. 2022-08-08 17:36:36 -07:00
Wayne Davison
6cafc1f8bf Update the NEWS. 2022-08-07 09:59:43 -07:00
Wayne Davison
788f11ea6a Fix zlib bug with a large gzip header extra field
From zlib commit eff308af425b67093bab25f80f1ae950166bece1.
Fixes CVE-2022-37434.
2022-08-07 09:34:26 -07:00
Wayne Davison
b7fdc9ef0e Make sure that --read-batch doesn't try to check args. 2022-08-07 08:56:39 -07:00
Wayne Davison
0d8cc26044 Some md-convert doc tweaks. 2022-08-03 09:55:51 -07:00
Jakub Wilk
2955888468 Fix typos in NEWS (#339) 2022-08-02 11:31:04 -07:00
Wayne Davison
0773cecc1f Preparing for release of 3.2.5pre1 2022-08-01 18:51:07 -07:00
Wayne Davison
8e33586359 Tweaks to allow for a release. 2022-08-01 18:50:28 -07:00
Wayne Davison
da5c72da4b More NEWS. 2022-08-01 18:36:22 -07:00
Wayne Davison
2f7c583143 A few more minor tweaks. 2022-08-01 18:36:21 -07:00
Wayne Davison
51fd4993ba Avoid the getgroups program when cross-compiliing. 2022-08-01 09:00:34 -07:00
Wayne Davison
e37bfdb445 Make sure sign is consistend in 2 gid comparisons. 2022-08-01 08:29:15 -07:00
Wayne Davison
3d7015afa2 A few more minor changes. 2022-08-01 07:45:57 -07:00
Wayne Davison
7e5424b806 More improvements to file-list checking
- Avoid implied rules on generator and (with extra certainty) on server
- Add -R implied-directory path elements as directory includes
- Log about extra file-list checking using a new --debug=FILTER3 level
2022-08-01 07:00:51 -07:00
Wayne Davison
43f70b961e The latest NEWS. 2022-07-31 17:47:45 -07:00
Wayne Davison
b7231c7d02 Some extra file-list safety checks. 2022-07-31 17:46:34 -07:00
Wayne Davison
15c34f0a8c A few more minor doc tweaks. 2022-07-11 13:54:59 -07:00
Wayne Davison
d1e42ffa16 A few minor fixes. 2022-06-19 17:35:18 -07:00
Wayne Davison
36f489c211 Link to rsyncd.conf page server-setup details. 2022-06-19 16:55:18 -07:00
Wayne Davison
defe2287aa Improve the filter intro. 2022-06-19 16:45:43 -07:00
Wayne Davison
112bef11ad Improve filter discussion. 2022-06-19 16:28:45 -07:00
Wayne Davison
b38780f3fd Some proxy improvements (mainly). 2022-06-19 11:42:25 -07:00
Wayne Davison
5f33238f06 Some clarifications about transfer rules. 2022-06-19 11:42:24 -07:00
Wayne Davison
3592ac3c02 Include bsd/strings.h if it exists
Some systems apparently put strlcpy() into a separate bsd/strings.h file
without putting the function into a separate library. Thus, configure
finds that the function exists for linking but the build does not have
the declaration (which rsync only supplies if it is also supplying its
own version of the function).
2022-06-19 10:11:28 -07:00
Yuri Chornoivan
c897b16f32 Fix minor typos (#327) 2022-06-19 09:14:36 -07:00
Wayne Davison
4f741addbd Fix configure's "signed char" check
When pedantic errors are enabled, SIGNED_CHAR_OK was no longer
being set correctly. This would cause the checksum code to use
"char" instead of "signed char", and if the default for a "char"
was unsigned, the checksum code would fail to compute the right
hash values.  Fixes bug #317.
2022-06-18 10:23:32 -07:00
Wayne Davison
355b81d8bc Avoid -pedantic-errors on non-x86 for the moment. 2022-06-18 09:42:16 -07:00
Wayne Davison
6f35553372 Fix grabbing version value in configure. 2022-06-01 17:41:28 -07:00
Wayne Davison
71090b7e2c Improve discussion of old-args in advanced usage. 2022-05-14 16:41:44 -07:00
Wayne Davison
2ab2ee166e Make md-convert --test work again. 2022-05-06 19:37:40 -07:00
Wayne Davison
1e858e39e6 Manpage improvements. 2022-05-06 17:42:55 -07:00
Wayne Davison
664639e349 Use the maintainer's timezone for translating the manpage date. 2022-05-06 17:42:54 -07:00
Wayne Davison
517b9d91fc Setup for 3.2.5dev. 2022-05-06 17:24:54 -07:00
Wayne Davison
0ac7ebceef Preparing for release of 3.2.4 2022-04-15 13:31:16 -07:00
Wayne Davison
85c56b2603 The latest news. 2022-04-11 09:50:58 -07:00
Wayne Davison
10aeb75cea Add debugging comment about read_buf_(). 2022-04-11 09:50:31 -07:00
Simon Deziel
d41bb98c09 systemd: restart daemon on-failure (#302)
man 5 systemd.service:
> Setting this to on-failure is the recommended choice for long-running services

Partial fix for https://bugzilla.samba.org/show_bug.cgi?id=13463

Signed-off-by: Simon Deziel <simon@sdeziel.info>
2022-04-11 09:08:11 -07:00
Yoichi NAKAYAMA
2fda51692b Specify log format to avoid malfunctions and unexpected errors. (#305)
Solve the following problems:
* mishandling of commit message lines similar to committer lines
* UnicodeDecodeError with commit messages that cannot be interpreted
  as utf-8
2022-04-11 08:57:19 -07:00
Michal Ruprich
1de71e8a78 Fix for CVE-2018-25032 in zlib (#306) 2022-04-11 08:50:50 -07:00
Wayne Davison
60dd42be60 Handle linking with a zlib with external read_buf. 2022-04-11 08:29:54 -07:00
Wayne Davison
d821e4cbfb Preparing for release of 3.2.4pre4 2022-03-27 14:59:57 -07:00
Wayne Davison
8aa465117f Add new & improved --copy-devices option. 2022-03-27 14:04:59 -07:00
Wayne Davison
8977815f5d Some --write-device fixes. 2022-03-27 12:52:26 -07:00
Wayne Davison
a48c20c97c Combine some alt-dest tests. 2022-03-26 10:01:12 -07:00
Wayne Davison
601f47436f Rename compare-dest test. 2022-03-26 10:01:10 -07:00
Sam Mikes
ef76d6cfa5 Extract unlink_and_reopen from copy_file (#294)
* add tests to exercise copy_file

* Extract new function unlink_and_reopen from copy_file

The argument `ofd` to copy_file is always set to -1 unless
`open_tmpfile()` is called at generator.c:909

This change
 * removes assignment to a function argument
 * renames argument `ofd` to `tmpfilefd` in line with existing uses
 * extracts a new function `unlink_and_reopen` which is static to util1.c
 * rewrites header comments for copy_file
2022-03-26 09:14:10 -07:00
Wayne Davison
96ed4b47b9 Some word fixes. 2022-03-26 08:58:51 -07:00
Wayne Davison
13c4019e94 Also ignore a root-level rrsync file. 2022-03-13 10:45:09 -07:00
Wayne Davison
b7b387b1f7 Add FALLTHROUGH comment. 2022-03-13 09:31:44 -07:00
Wayne Davison
7569edfaef Use ac_includes_default in largefile support test. 2022-03-09 18:38:03 -08:00
Wayne Davison
55b2a06812 Test newer FreeBSD. 2022-03-03 17:26:47 -08:00
Wayne Davison
b81a509556 Make asm use more selectable
- Make the SIMD ASM code off by default. Use configure --enable-simd-asm
  to enable.
- Allow MD5 ASM code to be requested even when OpenSSL is handling MD4
  checksums. Use configure --enable-md5-asm to enable.
2022-03-03 17:00:57 -08:00
Wayne Davison
26f4dbe12c Change usage (--version) output to note when ASM isn't really being used. 2022-02-21 16:41:50 -08:00
Sam Mikes
b3f1970f18 Fix wording in RSYNC_PORT section (#293)
Fix wording from 'does is not read' -> 'is not read'
2022-02-21 14:00:45 -08:00
Wayne Davison
c51da9174f Build Cygwin on windows-2022 with newer python. [buildall] 2022-02-09 14:00:13 -08:00
Wayne Davison
81f71f6f29 Add a CAUTION message to --debug=FILTER for trailing whitespace. 2022-01-27 08:53:41 -08:00
Wayne Davison
48e7005554 Add a couple more --rsync-path opts to the test. [buildall] 2022-01-20 10:51:13 -08:00
Wayne Davison
2b3e68814b Specify the rsync that lsh.sh should run. [buildall] 2022-01-20 09:02:02 -08:00
Wayne Davison
cc83294316 Preparing for release of 3.2.4pre3 2022-01-18 23:47:45 -08:00
Wayne Davison
08c8375acb Tweak rrsync rules in the Makefile. 2022-01-18 23:13:22 -08:00
Wayne Davison
824a057935 Add some arg-escaping tests. 2022-01-18 22:47:05 -08:00
Wayne Davison
d91ddb97d1 Don't backslash-escape args for a local transfer. 2022-01-18 22:47:05 -08:00
Wayne Davison
5bb637ca04 Add missing ">". 2022-01-18 22:47:03 -08:00
Wayne Davison
142aba00d5 Silence some symlink mode-change failures. 2022-01-17 22:23:31 -08:00
Wayne Davison
8687e44d10 Fix a broken link & make a tweak. 2022-01-17 20:44:16 -08:00
Wayne Davison
0bd8e85185 Facilitate the next release. 2022-01-17 19:43:43 -08:00
Wayne Davison
00a5ab2364 Tweak some rrsync rules for cleanup & release. 2022-01-17 18:52:49 -08:00
Wayne Davison
f44e76b65c Handle html link targets in a better way. 2022-01-17 18:11:45 -08:00
Wayne Davison
1174d97072 Fix --old-args interaction with a daemon
Ensure that a remote rsync daemon will not split a filename arg unless
the user asked for `--old-args`.
2022-01-17 18:11:03 -08:00
Wayne Davison
d9eaffe564 Complain about --old-args with --protect-args. 2022-01-17 18:09:36 -08:00
Wayne Davison
6197385d1f More man & NEWS enhancements, including linking to env vars. 2022-01-17 18:09:34 -08:00
Wayne Davison
d07272d631 More man page and NEWS improvements.
- Add link targets for all option choices, not just the first one.
- Tweak cross-link arg format.
- Add more links, including some in the latest NEWS.
- Split out a few numbered lists.
2022-01-16 10:47:36 -08:00
Wayne Davison
e2a011d9d0 Fix some typos mentioned in the fossies report. 2022-01-16 10:33:22 -08:00
Wayne Davison
76dc7d0a76 It's OK to capitalize rsync at the start of a sentence. 2022-01-15 21:44:26 -08:00
Wayne Davison
7e94e52144 Some NEWS.html improvements.
- Improve NEWS heading's link targets using version info.
- Optimize regex compilation.
- Make sure every link target is unique.
- Allow link targets to start with a number.
2022-01-15 21:07:34 -08:00
Wayne Davison
5ef7e3c9c5 Remove <a name=...> tags. 2022-01-15 20:55:54 -08:00
Wayne Davison
d2cc1149b3 Get md-convert to output the release html files in the right dir. 2022-01-15 19:12:03 -08:00
Wayne Davison
c3b553a93f Preparing for release of 3.2.4pre2 2022-01-15 17:21:01 -08:00
Wayne Davison
eb0b41587c Use standard "git diff" for full diff highlighting support. 2022-01-15 17:20:11 -08:00
Wayne Davison
3c0bb7ff51 Even more man page improvements. 2022-01-15 17:13:31 -08:00
Wayne Davison
995ce7198b Man page improvments, including html cross-links. 2022-01-15 16:31:54 -08:00
Wayne Davison
38ffa522f6 A few more man page format tweaks. 2022-01-14 14:27:31 -08:00
Wayne Davison
8898aecb21 Make it easier to get section links. 2022-01-14 13:55:22 -08:00
Wayne Davison
f08505e92b Add more link targets to html man pages. 2022-01-13 23:44:30 -08:00
Wayne Davison
c1e8809a8f Tweak a caveat. 2022-01-13 23:31:43 -08:00
Wayne Davison
6130c4fa3c Display ??:??:?? when a time estimate gets too big. 2022-01-13 08:22:25 -08:00
Wayne Davison
8c4ceb3b86 Avoid a -8 in the progress output's remaining time
If the double "remain" value is so large that it overflows an int, make
the estimated seconds output as :00 instead of :-8.  Similar for the
estimated remaining minutes.  Support larger hours values.
2022-01-12 20:04:32 -08:00
Wayne Davison
30a5909544 Some symlink improvements to the man page. 2022-01-12 16:43:40 -08:00
Wayne Davison
e841944b47 Change manpage headings in html to use h2 tags with an id target. 2022-01-12 16:43:22 -08:00
Wayne Davison
635d8c0632 A repeated --old-args does more escape disabling. 2022-01-09 18:20:23 -08:00
Wayne Davison
6b8db0f644 Add an arg-protection idiom using backslash-escapes
The new default is to protect args and options from unintended shell
interpretation using backslash escapes.  See the new `--old-args` option
for a way to get the old-style splitting.  This idiom was chosen over
making `--protect-args` enabled by default because it is more backward
compatible (e.g. it works with rrsync). Fixes #272.
2022-01-09 17:47:24 -08:00
Wayne Davison
3b2804c815 Tweak a comment. 2022-01-09 14:03:31 -08:00
Wayne Davison
ff1792edf1 Improve --copy-links description. 2022-01-09 12:38:36 -08:00
Wayne Davison
b985123d2e Allow someone to specify scratchbase=FOO for runtests.sh. 2022-01-09 11:40:41 -08:00
Wayne Davison
c983279020 Improve rrsync usage and some more NEWS tweaks. 2022-01-03 00:47:19 -08:00
Wayne Davison
ee9199b542 More NEWS improvements. 2022-01-03 00:18:59 -08:00
Wayne Davison
f1a6998df2 Only send the --no-W kluge to a receiver. 2022-01-02 23:51:35 -08:00
Wayne Davison
3e44bbd313 Preparing for release of 3.2.4pre1 2022-01-02 15:13:19 -08:00
Wayne Davison
4adfdaaf12 Tweak stderr handling for older BackupPC versions
This makes the default for a protocol-28 server process be --stderr=client
instead of --stderr=errors.  See rsync's github issue #95.
2022-01-02 14:48:04 -08:00
Wayne Davison
4a7ba3cfaf A couple man page improvements. 2022-01-02 14:43:30 -08:00
Rodrigo Osorio
ffbca80ca2 Time-limit options are not being checked enough (#179)
The `--stop-at`, `--stop-after`, and `--time-limit`` options should have their
limit checked when receiving and sending data, not just when receiving.
Fixes #177.
2022-01-02 14:37:27 -08:00
Wayne Davison
c11467af36 Some compression improvements.
The compression level of the first file in the transfer no longer sets
the level for all files that follow it.  Document that per-file level
switching has no current effect (except for a global "dont compress = *"
rule in the daemon).
2021-12-31 12:21:13 -08:00
Wayne Davison
13cfe6406f Add error-code ignoring options to atomic-rsync. 2021-12-30 12:29:14 -08:00
Wayne Davison
8e77ece0ee Tweak the rrsync man page. 2021-12-30 12:29:09 -08:00
Marco Nenciarini
ffec7fe109 Fix rrsync directory normalization (#268)
Fix an off-by-one in the `args.dir_slash_len` variable that leads to base every absolute path on `/`
2021-12-30 08:59:17 -08:00
Wayne Davison
e07f8fb863 Add a default single-access lock. 2021-12-27 17:57:53 -08:00
Wayne Davison
8cf9dbb742 Change args to maybe-make-man. 2021-12-27 17:40:31 -08:00
Wayne Davison
3008e7c226 Include "rrsync" in "all" target when --with-rrsync was used. 2021-12-27 15:52:11 -08:00
Wayne Davison
a2b630c0bb Unify md parsing scripts & improve non-man html conversions. 2021-12-27 14:24:05 -08:00
Wayne Davison
5b1baa7a2e Rename md2man. 2021-12-27 13:42:19 -08:00
Wayne Davison
7f8cf771b7 Add more backticks. 2021-12-27 13:11:23 -08:00
Wayne Davison
b00e99c529 Ignore the built rrsync man-page files. 2021-12-27 12:10:31 -08:00
Wayne Davison
a76e32f949 Test --with-rrsync configure option & put rrsync into the artifacts. 2021-12-26 14:58:16 -08:00
Wayne Davison
512acd125e Use mallinfo2, when available, and use %zd for size_t values on C99.
An exhanced version of pull request #265.
2021-12-26 14:25:53 -08:00
Wayne Davison
72adf49ba8 rrsync improvements
- Convert rrsync to python.
- Enhance security of arg & option checking.
- Reject `-L` (`--copy-links`) by default.
- Add `-munge` and `-no-del` options.
- Tweak the logfile line format.
- Created an rrsync man page.
- Use `configure --with-rrsync` if you want `make install` to install
  rrsync and its man page.
- Give lsh more rrsync testing support.
2021-12-26 12:29:00 -08:00
Wayne Davison
73ceea6ad2 Convert atomic-rsync to python. 2021-12-20 17:36:33 -08:00
Wayne Davison
39c3ae0ea3 Convert munge-symlinks to python. 2021-12-20 16:41:16 -08:00
Wayne Davison
ed19ea05fe Make rrsync default to munged symlinks. 2021-12-20 15:16:30 -08:00
Wayne Davison
dc1b9febf1 Add options to assist in localhost rrsync testing. 2021-12-20 15:08:20 -08:00
Wayne Davison
d9015da151 Add --munge-links rsync option; convert to python. 2021-12-20 13:51:50 -08:00
Wayne Davison
1f0e62f139 Improve a couple support scripts:
- rsync-no-vanished now avoids joining stdout & stderr, avoids affecting
  a non-client run, and gets the rsync status code correctly.
- rsync-slash-strip now avoids affecting a non-client run.
2021-11-13 10:39:09 -08:00
Andrew Aladjev
7d830ff52f improved cross compilation detection (#252) 2021-11-07 11:45:49 -08:00
Issam Maghni
8f383e8987 shell: test -a|o is not POSIX (#250) 2021-11-07 10:23:01 -08:00
Wayne Davison
ca538965d8 Add closing backticks that Itzoke pointed out. 2021-11-07 10:11:12 -08:00
Wayne Davison
e4669b81ae Add the --info=NONREG setting. 2021-11-03 09:35:50 -07:00
Wayne Davison
1b9308b727 More NEWS changes. 2021-10-30 15:58:01 -07:00
Wayne Davison
80c64dc3b3 Fix the ability to read the user's numeric locale. 2021-10-29 20:06:06 -07:00
Wayne Davison
be3d6c0fbb Update the NEWS. 2021-10-19 21:10:59 -07:00
Wayne Davison
7956070f2b Make --chown|--usermap|--groupmap imply -o|-g (as appropriate). 2021-10-19 21:10:12 -07:00
Wayne Davison
d0f34b5a76 Allow a "%scope" suffix on the client's ipv6 addr.
Hopefully fixes bug #239.
2021-10-17 13:58:57 -07:00
Achim Leitner
84498104bf Linux: Handle protected_regular in inplace writes (#241)
The Linux fs.protected_regular sysctl setting could cause rsync to fail to write a file in-place with the O_CREAT flag set, so the code now tries an open without O_CREAT when it might help to avoid an EACCES error.  A testsuite script is included (and slightly improved by Wayne to ensure that it outputs a SKIP when fs.protected_regular is turned off).
2021-10-17 13:00:24 -07:00
Wayne Davison
378a0a634f Add more skipped verifications. [buildall] 2021-10-17 12:45:45 -07:00
Wayne Davison
ac08fa74f3 Tweak output about skipped tests. 2021-10-17 12:07:03 -07:00
Wayne Davison
d5d4ae51ee Change RSYNX_MAX_SKIPPED to RSYNC_EXPECT_SKIPPED. 2021-10-17 11:34:07 -07:00
Wayne Davison
0f87eafa2f A couple minor tweaks. 2021-10-13 10:39:44 -07:00
Wayne Davison
3af00277ee We need stat memcpy. 2021-10-10 14:01:59 -07:00
Wayne Davison
b774dbc1c0 Improve --omit-dir-times & --omit-link-times
The code now better handles skipping time setting on dirs and/or links
when --atimes and/or --crtimes is specified without --times.
2021-10-10 13:39:09 -07:00
Wayne Davison
296352ecb0 Tweak atime/crtime code a bit more. 2021-10-10 12:43:11 -07:00
Wayne Davison
11a9b62322 Avoid spurious warning about "code" var not being initialized. 2021-10-10 10:05:26 -07:00
Wayne Davison
452ef78517 Unify on "path" vs "fname" arg naming. 2021-10-10 09:53:35 -07:00
Wayne Davison
0d1b48893a Change do_lchmod() back to a swtich with some better ENOTSUP & ENOSYS logic. 2021-10-10 09:32:43 -07:00
Wayne Davison
ec8a05f653 Some packaging improvements. 2021-10-10 09:28:24 -07:00
Wayne Davison
78b5bc6629 Enable --atimes on macOS. 2021-10-02 15:23:30 -07:00
Wayne Davison
f41cdc75a1 Check ro in set_create_time() for Cygwin too. 2021-10-02 11:39:41 -07:00
Wayne Davison
c8e7c4b352 Avoid an issue where the size of st_dev != dev_t. 2021-10-01 14:21:26 -07:00
Wayne Davison
bff084c10a Always run mkgitver prior to a build
Some hosts were not running `mkgitver` when they should, so tweak the
script to only update the timestamp when the file's data changes and
then always run the script when performing a build.
2021-10-01 14:17:53 -07:00
Wayne Davison
16c8b05f11 Add more NEWS updates. 2021-10-01 13:40:07 -07:00
Wayne Davison
15dd2058fd Change do_chmod to always try lchmod() first (when possible). 2021-10-01 13:28:57 -07:00
Wayne Davison
c27180c044 Add a couple more options to rrsync. 2021-10-01 13:24:51 -07:00
Wayne Davison
050fdd4126 Allow the script to be run from inside the packaging dir. 2021-10-01 13:23:30 -07:00
Jindřich Makovička
ae1f002999 Reduce memory usage (#235)
In 2004, an allocation optimization has been added to the file
list handling code, that preallocates 32k of file_struct pointers
in a file_list. This optimization predates the incremental
recursion feature, for which it is not appropriate anymore. When
copying a tree containing a large number of small directories,
using the incremental recursion, rsync allocates many short
file_lists. Suddenly, the unused file_struct pointers can easily
take 90-95% of the memory allocated by rsync.
2021-10-01 12:04:59 -07:00
Wayne Davison
3911c23866 Tweak SIMD & ASM option defaults. 2021-09-27 11:09:43 -07:00
Wayne Davison
3814dbb0f4 Make cygwin's curl grab the gist file. [buildall] 2021-09-27 10:34:22 -07:00
Wayne Davison
82f023d7e3 Add --fsync option (promoted from patches). 2021-09-27 10:30:00 -07:00
Wayne Davison
ec57c57baf Help avoid a --sparse --inplace bug in older rsyncs. 2021-09-27 10:16:15 -07:00
Wayne Davison
354fa581c1 Fix typo. 2021-09-26 19:27:46 -07:00
Wayne Davison
d881814a35 Don't allow a broken samba host to cause gensend to fail. 2021-09-26 19:11:24 -07:00
Wayne Davison
ad048d78ac Allow $host_cpu to be amd64 in addition to x86_64. 2021-09-26 19:11:20 -07:00
Wayne Davison
109dbc0b75 Rename cmdormsg -> cmd-or-msg. 2021-09-26 18:55:46 -07:00
Wayne Davison
745ecf2825 Fix a couple variable typos. 2021-09-26 18:50:32 -07:00
Shark64
265785b7b9 x86-64 AVX2 assemby implemenation of get_checksum1() (#174) 2021-09-26 18:16:55 -07:00
Wayne Davison
97f4d48a07 configure improvements
- Make SIMD & ASM only default to enabled on linux for now (due to
  FreeBSD & MacOS issues).
- Improve the enable/disable help messages so that they don't look
  wrong when the opposite --enable-X/--disable-X arg is specified.
2021-09-26 18:11:06 -07:00
Wayne Davison
3cc7f0ba43 Tweak a comment. 2021-09-26 17:23:33 -07:00
a1346054
dde4695136 Minor cleanup (#214)
- use `grep -E` and `grep -F` (`egrep` and `fgrep` are non-standard)
- use same hashbang style for all test scripts
- use explicit comparisons in test scripts
- remove redundant ; from test scripts
- make test script not executable, just like all the other scripts
- unify codestyle across all test scripts
- make openssl license exception clearer by having it at the top
- use modern links in COPYING. The text now matches:
  https://www.gnu.org/licenses/gpl-3.0.txt
- fix typo
2021-09-26 16:57:55 -07:00
Fabian H
3337930292 add ssl/tls key option (#216)
Improves rsync-ssl configurability.
2021-09-26 16:44:00 -07:00
zgpmax
44cc148907 Fix spelling of nanosecond (#220)
Hyphenating the word just makes it harder to find when nanosecond support was added.
2021-09-26 16:42:02 -07:00
TomasKorbar
b2e16facd4 Eventually add write permission when setting extended attributes (#212)
* Eventually add write permission when setting extended attributes

When we need to set extended atributes of file which does not
allow write then temporarily add write permission and after
attributes are set, remove it again.

Resolves #208

Co-authored-by: Wayne Davison <wayne@opencoder.net>
2021-09-26 16:34:15 -07:00
Wayne Davison
4fd662fea9 Remove duplicate include. 2021-09-26 16:28:35 -07:00
Wayne Davison
12c058698b Add gist update logic to gensend target. 2021-09-26 14:57:22 -07:00
Wayne Davison
33095916ec Make use of a git gist instead of the samba website. 2021-09-26 12:09:17 -07:00
Wayne Davison
5818cf8596 Add missing INET6 check. 2021-09-26 11:25:18 -07:00
Jonathan Davies
1fa0bd1e87 configure.ac: Test IPv6 compatibility instead of relying on library probes (#206)
Legacy configure behaviour was to detect IPv6 support through known IPv6
capable version of common standard libraries. Now: it runs a POSIX test
to determine if IPv6 is usable (in case it has not been disabled).

Patch originally from Pierre-Olivier Mercier <nemunaire@nemunai.re>.

Signed-off-by: Jonathan Davies <jpds@protonmail.com>
2021-09-26 11:25:06 -07:00
Fabian H
592c6bc3e5 add missing - in certopt (#210)
otherwise openssl will give an error and not accept is as argument
2021-08-16 15:52:39 -07:00
Natanael Copa
efc81c93a9 Add test and fix regression for --delay-updates (#192) (#204)
Fixes regression introduced with commit 3a7bf54ad5 (A resumed
partial-dir file is transferred in-place.)
2021-07-28 09:10:55 -07:00
Wayne Davison
35d4f6737a Update the options in rrsync. 2021-07-09 11:58:27 -07:00
Wayne Davison
291a042b3e Support --crtimes on Cygwin. 2021-07-08 18:59:26 -07:00
Wayne Davison
9dad3721a9 Make whole-line comments clearer. 2021-07-04 12:42:51 -07:00
Wayne Davison
dbb1c2d10c Set whole_file = 0 when whole_file < 0. Fixes issue 114. 2021-07-04 12:15:16 -07:00
Wayne Davison
e8e34ed6fb Need to also check stdout_format_has_i in some INFO-NAME checks. 2021-06-27 11:34:57 -07:00
Wayne Davison
c529782a8d Fix compiling without ftruncate. 2021-06-27 09:45:41 -07:00
juleslagarde
2dfd48492e fix man page typo
Fix a copy/paste error that should be referring to deletions.
2021-06-16 22:39:45 -07:00
Wayne Davison
a6bdf313f2 Unset DISPLAY in environment.
Without a DISPLAY var, ssh won't try to forward X11 when making an
ssh connection.  This patch also makes use of setenv() and unsetenv()
if they are available.
2021-05-01 09:14:51 -07:00
Bart S
915685e01b Updated GLIBC check in configure.ac (#175)
The current GLIBC check does not consider we may see glibc 3.0 in the future.
2021-05-01 08:23:25 -07:00
Wayne Davison
05540220a9 Fix plural of --group option. 2021-04-03 21:09:14 -07:00
Wayne Davison
75158e1086 Fix git-set-file-times's handling of staged changed files. 2021-03-15 09:35:39 -07:00
Wayne Davison
676537cf29 Switch to using image_family for Cirrus CI. 2021-03-02 19:16:52 -08:00
Wayne Davison
d857fd42ac Install bash on FreeBSD CI. 2021-03-02 19:09:23 -08:00
Wayne Davison
5856b71eb7 Update FreeBSD CI to 12.2. 2021-03-02 19:02:08 -08:00
Wayne Davison
57adb2973a See if explicitly installing m4 gets FreeBSD CI a newer gm4 version. 2021-03-02 14:13:54 -08:00
Wayne Davison
ead44adcd3 Allow the generator's msg iobuf to get bigger too. 2021-02-25 12:28:18 -08:00
Wayne Davison
d3085f7add Rename util.c to util1.c
Fixes an issue where the Makefile's glob of *.c could sort util.c &
util2.c in an order that depends on the current collation setting.
2021-02-25 09:14:33 -08:00
Wayne Davison
1da64c37e8 A few Cygwin build tweaks. [buildall] 2021-02-10 08:07:03 -08:00
Wayne Davison
ef36b097bf Stop checking for gmake in build scripts
Since a non-cygwin gmake trips up the github cygwin action, let's just
require that the user put a good "make" early on their path (a simple
`ln -s `which gmake` ~/bin/make` with the right $PATH works fine).
2021-02-04 20:51:04 -08:00
Wayne Davison
ec3833c96e Add optional netgroup.h include for NetBSD hosts. 2021-02-01 16:31:28 -08:00
Wayne Davison
25dfc2c41d Some pip-releated tweaking. 2021-02-01 09:00:06 -08:00
Wayne Davison
d5b7889d40 Add a link to the man page to the README. 2021-02-01 08:47:44 -08:00
Wayne Davison
74561d70b5 Check for netinet/ip.h after including netinet/in.h. 2021-01-31 11:11:07 -08:00
Wayne Davison
83f7372369 A couple "make" tweaks. 2021-01-31 11:10:38 -08:00
Wayne Davison
8c3de35b0b Put 0 in parens to silence an Xcode warning. 2021-01-31 09:28:34 -08:00
Wayne Davison
ec1d5d564c Add --with-nobody-user=FOO configure option. 2021-01-15 07:38:49 -08:00
Wayne Davison
26befd9c6c Cygwin python3 is now 3.8 w/o commonmark lib. [buildall] 2021-01-01 10:02:49 -08:00
James Cook
a28c4558c5 Fix spelling error in man page. (#124)
trasnferred -> transferred
2020-12-10 09:43:04 -08:00
Wayne Davison
ed6a0dc7c2 Fix a typo. 2020-12-09 22:35:16 -08:00
Wayne Davison
9dd62525f3 Work around glibc's lchmod() issue a better way. 2020-11-29 09:40:03 -08:00
Wayne Davison
ada588a7a8 Include stdlib.h for exit() and consult HAVE_* macros more. 2020-11-29 09:13:09 -08:00
Wayne Davison
286e164ed6 Tweak cmd_txt routines in the packaging scripts. 2020-11-01 11:27:08 -08:00
Wayne Davison
85b8dc8aba Force HAVE_LCHMOD off for Linux (for now). 2020-10-30 16:37:52 -07:00
Wayne Davison
0748800118 Use the right powershell env syntax. [buildall] 2020-10-07 14:02:28 -07:00
edo
b7fab6f285 Allow cross-compilation with SIMD (x86_84) (#104)
Replace runtime SIMD check with a compile-only test in case of
cross-compilation.

You can still use '--enable-simd=no' to build x86_64 code without
SIMD instructions.
2020-10-06 22:33:57 -07:00
Wayne Davison
9fc7deab0d Update CI builds to new path-setting idiom. 2020-10-06 22:28:17 -07:00
Wayne Davison
b115bc8a5d Silence a few more warnings. 2020-09-29 16:05:29 -07:00
Wayne Davison
cd018c7a4c Use a better -Wno-pedantic heuristic. 2020-09-29 15:30:20 -07:00
Wayne Davison
9fce0eb5ab Avoid some pedantic errors & old warnings. 2020-09-29 14:51:45 -07:00
Wayne Davison
33e94849b1 Handle early gcc versions that don't understand -Wno-pedantic. 2020-09-29 14:27:59 -07:00
Wayne Davison
8f1511184a Make gcc die on init overflow of an array.
- Use -pedantic-errors with gcc to make an array-init fatal.
- Fix all the extra warnings that gcc outputs due to this option.
- Also add -Wno-pedantic to gcc if we're using the internal popt
  code (since it has lots of pedantic issues).
2020-09-29 13:18:28 -07:00
Wayne Davison
acca9d43d3 Expand the max name_num_item list size. 2020-09-29 12:57:32 -07:00
Wayne Davison
58f464f4da Change --info=skip2 messages & add info on attr changes. 2020-09-23 09:33:29 -07:00
Wayne Davison
7eb59a9152 Change from $build_cpu to $host_cpu as edo1 suggested. 2020-09-22 17:19:48 -07:00
Wayne Davison
740ed11aa8 Make the extra info on the "exists" messages optional. 2020-09-22 16:45:07 -07:00
Wayne Davison
d2a97a7ab4 Various file comparison improvements
- Rename unchanged_file() to quick_check_ok().
- Enhance quick_check_ok() to work with non-regular files.
- Add a get_file_type() function to the generator.
- Use the new functions in the generator code to make the logic simpler.
- Fix a bug where the `--alt-dest` functions were not checking if a
  special file fully matched the non-permission mode bits before
  deciding if we have found an alt-dest match.
- Enhance the `--info=skip --ignore-existing` output to include extra
  info on if the existing file differs in type or passes the standard
  quick-check logic.
- Add `--info=skip2` that authorizes rsync to perform a slow checksum
  "quick check" when ignoring existing files. This provides the uptodate
  and differs info even if we need to checksum a file to get it.
2020-09-22 12:48:02 -07:00
Wayne Davison
15bc7ded39 More NEWS updates. 2020-09-21 19:17:59 -07:00
Wayne Davison
f0810068a6 A couple whitespace tweaks. 2020-09-21 18:42:21 -07:00
Shark64
7aa2f36317 optimize avx2 code (#102)
Optimize avx2 code using only intrinsic functions supported by older gcc versions.
2020-09-21 15:11:27 -07:00
Wayne Davison
9cd85b8496 Skip an append if sender's file gets shorter.
Fixes bug #90.  Similar to a pull request by Tomas Korbar.
2020-09-21 14:57:45 -07:00
Wayne Davison
f8dcd7d452 Improve the docs for --archive.
A slightly tweaked version of a patch from Richard Michael.
2020-09-21 14:07:48 -07:00
Wayne Davison
69530b406e Avoid output variance in protocol 29. 2020-09-21 13:45:42 -07:00
Wayne Davison
122b0fdc4f Check status of tests that pipe rsync's output & simplify output diffing. 2020-09-21 13:32:41 -07:00
Wayne Davison
b990d97d35 Put CAN_HARDLINK_SYMLINK info into --version output. 2020-09-21 13:17:15 -07:00
Wayne Davison
fd6839b746 Avoid spurious "is newer" messages with --update. 2020-09-21 11:07:42 -07:00
Wayne Davison
a79d9b22b1 Update the NEWS. 2020-09-08 22:31:18 -07:00
Wayne Davison
2613c9d98a Handle a --mkpath failure
Fixes bug #96 where --mkpath makes rsync complain when a dest path
exists but the path contains an alt-dest name for the single file.
2020-09-08 10:58:47 -07:00
Wayne Davison
27aff880a9 Use new xxhash lib in cygwin build. [buildall] 2020-09-07 19:42:08 -07:00
Wayne Davison
7b53e67d64 Try using the Windows version of curl. [buildall] 2020-09-07 15:11:32 -07:00
Wayne Davison
da956469a1 Another cygwin build attempt. [buildall] 2020-09-07 14:46:27 -07:00
Wayne Davison
9c59632d8b Improve a sentence about --stderr=all. 2020-09-07 14:42:35 -07:00
Wayne Davison
d1f458d383 Try cygwin build again. [buildall] 2020-09-07 14:23:39 -07:00
Wayne Davison
a35a900ac0 Add git-version.h to "gen" target. 2020-09-06 23:36:08 -07:00
Wayne Davison
f4c3969b63 Leave git-version.h out of GENFILES so it doesn't go in a release tar. 2020-09-06 23:27:28 -07:00
Wayne Davison
ee75e51f2f Allow git-version.h to be provided for the build
For a non-git build or for a git build w/o adequate git history, we now
allow the git-version.h file to be provided before the build.  If the
file does not exist, we either create an empty file or put a define of
RSYNC_GITVER in it based on the output of git describe.  The github
builds now snag the git-version.h file that was generated for the last
commit so that they all get the same version string, even with a shallow
checkout.
2020-09-06 23:09:11 -07:00
Wayne Davison
9f9240b661 Set CXX_OK=no when cross compiling. 2020-09-03 10:07:36 -07:00
Wayne Davison
48885309c7 Create SECURITY.md 2020-09-02 14:49:20 -07:00
Wayne Davison
203b3d0143 Setup for 3.2.4dev. 2020-08-27 19:36:57 -07:00
Wayne Davison
25526eb3fe Simplify the compat logic for local_server
Change the logic in compat.c to construct the client_info string value
for a local copy so that the various checks of the string don't need to
make an exception for local_server.
2020-08-27 19:23:13 -07:00
Matt McCutchen
c3f7414c45 rsync-ssl: Verify the hostname in the certificate when using openssl. 2020-08-26 14:07:02 -07:00
Wayne Davison
4c4fce5107 Add some comments about protocol versions. 2020-08-07 16:25:12 -07:00
Wayne Davison
6816b31378 Simplify where version.h is included. 2020-08-06 21:10:46 -07:00
Wayne Davison
e94bad1c15 Preparing for release of 3.2.3 2020-08-06 20:57:26 -07:00
Wayne Davison
617d726a3d Tweak a comment. 2020-08-05 21:32:44 -07:00
Wayne Davison
020eda887f Change fetch depth. 2020-08-03 14:47:38 -07:00
Wayne Davison
b5f8021a12 Don't use --always to ensure a tag is in gitver. 2020-08-03 14:27:49 -07:00
Wayne Davison
7b6947576a Avoid a build fail when git isn't installed. 2020-08-03 14:20:08 -07:00
Wayne Davison
9375a8c4c2 Make my_alloc(NULL) use malloc instead of calloc. 2020-08-03 14:01:18 -07:00
Wayne Davison
7f5c4084c7 Use touch for proto.h-tstamp since one awk wasn't updating mtime. 2020-08-03 13:33:46 -07:00
Wayne Davison
6c89f00d1b Move SUPPORT_ATIMES to rsync.h. 2020-08-03 13:27:00 -07:00
Wayne Davison
dee0993286 Create usage.c for smaller awk-dep rebuilds. 2020-08-03 12:23:18 -07:00
Wayne Davison
47351c2b16 Use RSYNC_GITVER in more output 2020-08-03 10:46:31 -07:00
Wayne Davison
16b7670614 A couple more mkgitver tweaks
- Support git worktree checkouts (has non-dir .git)
- Use --always for someone who may be missing a tag.
2020-08-03 10:23:43 -07:00
Wayne Davison
72b2a81f90 Use --abbrev=8 instead of --tags. 2020-08-01 00:43:37 -07:00
Wayne Davison
d73c26d2b7 Put git version in a file for between-release versioning. 2020-08-01 00:15:06 -07:00
Wayne Davison
e83bbeb673 Don't make .PHONY the first target in a Makefile. 2020-07-30 18:58:34 -07:00
Wayne Davison
b6aa9c5cfe Make configure less annoying
- Improve configure's notifications around the new features.
- Improve the info about man page generation and fetching.
2020-07-30 18:33:58 -07:00
Wayne Davison
dfe3b77cb5 Some Makefile improvements.
- Improve distclean.
- Remove proto.h from GENFILES (we don't need to distribute it).
- Improve finddead target.
2020-07-29 11:51:55 -07:00
Wayne Davison
cbe3b2bfe5 Tweak a comment. 2020-07-29 11:51:52 -07:00
Wayne Davison
b1ae7fc941 INSTALL changes, including some Fedora packages. 2020-07-29 11:22:23 -07:00
Wayne Davison
8695bcc2b1 Preparing for release of 3.2.3pre1 2020-07-27 17:56:25 -07:00
Wayne Davison
4ae6f708b1 Need 3.2.3 line in table & tweak to release script. 2020-07-27 17:54:48 -07:00
Wayne Davison
14c4656fb8 A couple more NEWS updates. 2020-07-27 17:31:51 -07:00
Wayne Davison
13cec31f7f Set LANG to C to help with some remote build hosts. 2020-07-27 16:48:48 -07:00
Wayne Davison
5db7e4b1ee Use linkat() if available
Some OSes have a more capable linkat() function that can hard-link
syslinks, so use linkat() when it is available.
2020-07-27 16:36:55 -07:00
Wayne Davison
54693fa992 Add a few more skip-compress suffixes. 2020-07-27 15:56:48 -07:00
Wayne Davison
3f83bcb4af Make the --append* options have more warnings. 2020-07-27 15:21:50 -07:00
Wayne Davison
e1e546d67e Don't allow a completely empty source arg. 2020-07-27 14:49:51 -07:00
Wayne Davison
3714084f48 Mention an implied option. 2020-07-27 13:49:51 -07:00
Wayne Davison
eb2c3a5e18 Replace a couple calloc() calls with new_array0(). 2020-07-26 23:30:50 -07:00
Wayne Davison
f6967eca58 Complain about a missing/non-dir --temp-dir. 2020-07-26 02:01:30 -07:00
Wayne Davison
8455bf66c2 Don't include config.h in proto.h rule. 2020-07-26 01:40:55 -07:00
Wayne Davison
00e59e01e3 Mention awk/gawk/nawk dependency. 2020-07-26 01:40:43 -07:00
Wayne Davison
91eaffe13f Mention --protect-args in --chown info. 2020-07-26 01:02:07 -07:00
Wayne Davison
2066024981 Fix issue where rdev major could get out of sync
If the receiving side read a hard-linked device, it needs to set the
value of rdev_major to the value it snags from the hard-linked data
because the sender set their rdev_major value for that file entry.
2020-07-26 00:11:28 -07:00
Wayne Davison
d274b2096f Have release script use patch-update --make (not --shell) 2020-07-25 10:52:49 -07:00
Wayne Davison
0327a2526b Fix a grammar error. 2020-07-25 10:40:46 -07:00
Wayne Davison
f43412f1d5 More spelling fixes. 2020-07-25 10:34:26 -07:00
Wayne Davison
b9010ec617 Fix some spelling errors. 2020-07-25 10:21:50 -07:00
Wayne Davison
21ecc833ea Change new stderr options to --stderr=MODE. 2020-07-25 10:03:32 -07:00
Wayne Davison
f9bb8f76ee Change daemon variable & simplify some option code
- Rename daemon_over_rsh -> daemon_connection since it is also used to
  indicate if a non-rsh daemon connection is active.
- Move the daemon-over-rsh exception out of server_options() to the one
  caller that needs that behavior.
- Don't allow noop_io_until_death() to be short-circuited when talking
  to a daemon over a socket, because it can't send errors via stderr.
2020-07-25 09:36:42 -07:00
Wayne Davison
a5a9f268fe Tweak NEWS & src_file(). 2020-07-24 23:30:32 -07:00
Wayne Davison
0a255771f4 Add --errors2stderr & --msgs2protocol options. 2020-07-24 22:48:37 -07:00
Wayne Davison
e07d79ad50 Handle the first run of configure; prefer gmake. 2020-07-24 17:37:01 -07:00
Wayne Davison
2f74eb7584 Change smart-rebuild to smart-make. 2020-07-24 17:25:09 -07:00
Wayne Davison
39741c7d50 Fix the setting of $make. 2020-07-24 16:49:55 -07:00
Wayne Davison
3f016888fd Add helper script for a smart rebuild. 2020-07-24 14:19:19 -07:00
Wayne Davison
e5a012c959 Link to the git blob for source files. 2020-07-24 13:20:11 -07:00
Wayne Davison
c3cf174e5e More changes to NEWS, README, INSTALL, & configure.ac 2020-07-24 12:38:25 -07:00
Wayne Davison
a0a7c9f2e3 Enable xattrs on Cygwin.
- Tweak configure.ac to have Cygwin use linux xattrs.
- Change CI setup to install attr packages on Cygwin.

[buildall]
2020-07-24 11:38:14 -07:00
Wayne Davison
a8f61ba937 Add Cygwin package info into INSTALL.md. 2020-07-24 11:37:50 -07:00
Wayne Davison
842d6edfdc Fix devices-fake test if rsync can't link specials
- Add info about hardlinked specials to --version output.
- Use "no hardlink-special" info to ensure that the devices-fake
  test will not fail.
2020-07-24 11:33:21 -07:00
Wayne Davison
92a8855ff3 Install python3 for cygwin [buildall] 2020-07-24 10:10:26 -07:00
Wayne Davison
def96fd7c4 Install python36 for cygwin [buildall] 2020-07-24 09:57:41 -07:00
Wayne Davison
f624a73bbc Change the --mkpath message. 2020-07-24 09:46:53 -07:00
Wayne Davison
93a373f6ba Some INSTALL improvements. 2020-07-24 09:42:49 -07:00
Wayne Davison
01742c07e6 Add --mkpath option. Fixes bugzilla bug 4621. 2020-07-23 20:54:38 -07:00
Wayne Davison
e00662f263 Add packages to INSTALL.md; put INSTALL.md on ftp site 2020-07-23 17:29:13 -07:00
Wayne Davison
491ddb08a4 Simplify md_parser assignment. 2020-07-23 17:28:34 -07:00
Wayne Davison
918cb39fed Fix multi-line code blocks. 2020-07-23 16:22:12 -07:00
Wayne Davison
1369fe43e1 Tweak ubuntu configure args. 2020-07-23 12:32:41 -07:00
Wayne Davison
150f3416ac Setup commonmark on Cygwin. 2020-07-23 12:20:40 -07:00
Wayne Davison
d8941be8cb Simplify the msgs2stderr default logic. 2020-07-23 12:15:50 -07:00
Wayne Davison
592059c8fd Improve error output for local & remote-shell xfers 2020-07-23 11:23:47 -07:00
Wayne Davison
37f4a23f60 Drop a superfluous "+". 2020-07-22 21:42:24 -07:00
Wayne Davison
27be94c889 A few more build improvements
Includes Ben's RSYNC_MAX_SKIPPED=3 suggestion for FreeBSD and a fix for
the artifact file list for Cygwin.
2020-07-22 21:01:01 -07:00
Wayne Davison
974f49e22a Add --crtimes option. 2020-07-22 12:12:18 -07:00
Wayne Davison
9f7506ac1b Improve --itemize-changes doc. 2020-07-22 11:30:00 -07:00
Wayne Davison
8779d6c8bb Switch to RSYNC_MAX_SKIPPED test setting. 2020-07-22 11:00:26 -07:00
Wayne Davison
96be713fd2 Update NEWS. 2020-07-21 12:37:56 -07:00
Wayne Davison
13d8fc9542 Avoid some extraneous parent-dir warnings
Don't complain about an absent parent dir if the current file is marked
as missing and there is a marked-as-missing entry for the parent dir.
2020-07-21 11:54:54 -07:00
Wayne Davison
f74473b151 Don't create a path for a file marked as missing. 2020-07-21 11:54:48 -07:00
Wayne Davison
5eda68f11b Tweak include syntax. 2020-07-20 18:45:36 -07:00
Wayne Davison
f635207347 Save the build into an artifact. 2020-07-20 14:44:35 -07:00
Wayne Davison
64f7e893f3 Ignore *.exe files (for Cygwin builds). 2020-07-20 14:43:06 -07:00
Wayne Davison
31556ec7a8 Use just $(...) instead of a mix of that and ${...}. 2020-07-20 14:42:13 -07:00
Wayne Davison
9ad3f4385f Make the daily build happen a few hours later. 2020-07-18 23:17:25 -07:00
Wayne Davison
e9899dbdb4 Add strict (no-skipping) checks and use them. 2020-07-17 11:20:04 -07:00
Wayne Davison
18cffa8aa9 A couple minor changes. 2020-07-17 10:56:22 -07:00
Wayne Davison
7e07a32504 Add the name converter daemon parameter.
This is based on the long-standing patch but with the protocol changed
to just use newlines as delimiters instead of null chars (since names
should not contain a newline AND it makes it easier to write a helper
script).  Lots of other small improvements and a better default value
for "numeric ids" when using "use chroot" with "name converter".
2020-07-17 10:30:59 -07:00
Wayne Davison
be11a496bb Run a daily build. 2020-07-16 22:04:40 -07:00
Wayne Davison
c6f5f0b505 Let's try cygwin again. (#69)
Setup an optional cygwin build that is currently triggered when a [buildall] is in the commit message (the build is currently quite slow).
2020-07-15 14:30:22 -07:00
Wayne Davison
f553da1730 GitHub artifact test didn't work. 2020-07-15 13:53:40 -07:00
Wayne Davison
40753bcbf7 Tweak the save path. 2020-07-15 13:42:36 -07:00
Wayne Davison
33df361d52 Avoid normal build on cygwin-save change. 2020-07-15 13:20:40 -07:00
Wayne Davison
f4db970718 Try to get cygwin-save to run. 2020-07-15 13:16:36 -07:00
Wayne Davison
ab3928898f Try to save cygwin install in an artifact. 2020-07-15 12:31:38 -07:00
Ben RUBSON
13f274fd02 Force git line endings (#68) 2020-07-15 10:20:52 -07:00
Wayne Davison
b51fe50e7f Tweak the workflows filename. 2020-07-14 21:47:50 -07:00
Wayne Davison
1829a2ee0d Disable cygwin for now. 2020-07-14 21:47:11 -07:00
Wayne Davison
65370a0f56 Try a couple different way to fix the build. 2020-07-14 21:32:41 -07:00
Wayne Davison
23213099e9 Try Cygwin build in actions. 2020-07-14 21:18:52 -07:00
Wayne Davison
25e08110d5 Let's try a Cygwin build on Cirrus. 2020-07-14 20:41:44 -07:00
Wayne Davison
95f683039d Mention the auto-build-save setup. 2020-07-14 20:25:02 -07:00
Ben RUBSON
129d7195ff Enable FreeBSD CI ssl (#66) 2020-07-14 13:22:55 -07:00
Wayne Davison
044339d6b4 Reduce the installed pkg items since they are so slow. 2020-07-13 16:26:58 -07:00
Wayne Davison
4c4fc7462a A few more NEWS & man tweaks. 2020-07-13 16:14:27 -07:00
Wayne Davison
22cb57ee20 Try using cmarkgfm. 2020-07-13 15:44:43 -07:00
Wayne Davison
4c0be4da13 Avoid a failed test on Cygwin. 2020-07-13 15:33:07 -07:00
Wayne Davison
4549855126 Search for cmark. 2020-07-13 14:09:24 -07:00
Wayne Davison
284c28c773 Add new code to recv_group_name() too. 2020-07-13 13:43:17 -07:00
Wayne Davison
d2406ae372 Give up on commonmark. 2020-07-13 13:42:28 -07:00
Wayne Davison
1e9c34972a Avoid a crash if id-0 doesn't exist. 2020-07-13 13:18:38 -07:00
Wayne Davison
116bd19324 One more commonmark try. 2020-07-13 13:12:39 -07:00
Wayne Davison
883de22c29 Avoid a test failure if id didn't work. 2020-07-13 12:59:22 -07:00
Wayne Davison
18f500a7a4 Try another way to get commonmark working. 2020-07-13 12:59:07 -07:00
Wayne Davison
d14b0ca4db Install commonmark on FreeBSD. 2020-07-13 12:18:13 -07:00
Wayne Davison
4156e7d464 Tweak lsh's Usage message & opening comment. 2020-07-13 12:01:00 -07:00
Wayne Davison
9e48da65c1 Search for commonmark pkg. 2020-07-13 12:00:56 -07:00
Wayne Davison
2cdf9416ee Tweak brew run. 2020-07-13 10:41:26 -07:00
Wayne Davison
cd0c83e485 Setup a macOS CI. 2020-07-13 10:38:17 -07:00
Wayne Davison
0e814e956c A couple more NEWS items. 2020-07-12 23:45:55 -07:00
Wayne Davison
f47e5a7732 Mention file & line on OOM and overflow errors.
Also simplify output of src file paths in errors & warnings when
built in a alternate build dir.
2020-07-12 23:25:21 -07:00
Wayne Davison
91fff802b9 Check for overflow the right way. 2020-07-12 22:45:01 -07:00
Wayne Davison
3c8ac20d63 Fix a typo. 2020-07-12 20:51:21 -07:00
Wayne Davison
38a521defd More NEWS tweaks. 2020-07-12 20:49:01 -07:00
Wayne Davison
2f13049600 Add "@netgroup" names to host matching. 2020-07-12 19:16:57 -07:00
Wayne Davison
af531cf787 Add the --stop-after & --stop-at options. 2020-07-12 18:32:41 -07:00
Wayne Davison
d495e343c0 A few word tweaks. 2020-07-12 12:38:12 -07:00
Ben RUBSON
de7e4d00ab Improve FreeBSD tests (#61)
Improve FreeBSD tests & use a ZFS mount for the CI's testtmp.
2020-07-12 12:36:02 -07:00
Wayne Davison
374cc1be74 Get my yaml continuation line right. 2020-07-11 16:22:48 -07:00
Wayne Davison
8b25488fe9 More CI tweaks
- Add to ubuntu build: make install & rsync-ssl test run
- Don't fail a build if samba.org daemon list has an issue.
2020-07-11 16:08:22 -07:00
Wayne Davison
4f5742baa0 Make sure FreeBSD has bash installed. 2020-07-11 15:51:05 -07:00
Wayne Davison
2b416de4ca More FreeBSD script separation. 2020-07-11 15:37:51 -07:00
Wayne Davison
1f41b7dca1 Add a little more FreeBSD testing. 2020-07-11 15:32:51 -07:00
Wayne Davison
486e7852db Add FreeBSD test & re-enable linux build. 2020-07-11 15:03:31 -07:00
Wayne Davison
a68a92793c Just disable md2man on FreeBSD for now. 2020-07-11 12:28:05 -07:00
Wayne Davison
a84e8aced7 Add 2 more FreeBSD pkg installs. 2020-07-11 12:22:05 -07:00
Wayne Davison
3bc2d9aeaa Add some FreeBSD pkg installs and pause on linux. 2020-07-11 12:11:13 -07:00
benrubson
6214c26bd3 Add FreeBSD CI 2020-07-11 11:54:33 -07:00
Wayne Davison
da7a350667 Some number & string improvements
- Use strdup(do_big_num(...)) to replace num_to_byte_string(...).
- Allow a ',' for a decimal point in a SIZE option in some locales.
- Get rid of old (now unused) strdup() compatibility function.
- Try harder to include the newline in a single error message write.
2020-07-11 11:39:36 -07:00
Wayne Davison
66ca4fc97b Allow --block-size's size to have a suffix.
Change the block_size global to be an int32.
2020-07-10 13:00:42 -07:00
Wayne Davison
7d63f8b249 Add missing "M" in SIZE suffixes; mention bytes are the default. 2020-07-10 09:59:17 -07:00
Wayne Davison
bb1365dd77 Fix see_token zstd case. 2020-07-10 09:47:16 -07:00
Wayne Davison
bcc273d460 Clean more built .h files. 2020-07-09 15:18:11 -07:00
Wayne Davison
a6da3c67f8 Must read the nsec val even w/o CAN_SET_NSEC. 2020-07-08 14:17:01 -07:00
Wayne Davison
ab110fc8fb Warning fixes & impossible-failure improvements
- Silence a couple warnings for less-common builds.
- Use a better impossible-failure idiom than assert(0).
2020-07-08 12:26:19 -07:00
Wayne Davison
7265d96116 Avoid non-updating proto.h on Alpine. 2020-07-07 23:50:55 -07:00
Wayne Davison
560b63b051 Avoid a test failure on Alpine. 2020-07-07 23:05:41 -07:00
Wayne Davison
0eb82a7c90 Fix xattr issue with MIGHT_NEED_PRE.
Fixes bugzilla 13113.
2020-07-07 20:07:31 -07:00
Wayne Davison
f92a5182fc Tweak the NEWS. 2020-07-07 19:50:13 -07:00
Wayne Davison
fb6fabc116 Fix an xattr free of the wrong object.
In uncache_tmp_xattrs() the code used to find the value to unlink,
update the single-linked list, and then free the wrong pointer.
This fixes bug #50.
2020-07-07 14:25:58 -07:00
Wayne Davison
c3269275a8 Don't use UNUSED() when an arg is used sometimes. 2020-07-07 13:12:51 -07:00
Wayne Davison
7e47855d47 Update the NEWS. 2020-07-07 12:38:20 -07:00
Wayne Davison
d2d6ad481a Allow --max-alloc=0 for unlimited. 2020-07-07 11:56:23 -07:00
Wayne Davison
5dcb49c7dd Allow --bwlimit=0 again. 2020-07-07 11:43:33 -07:00
Wayne Davison
19d8550cf4 One more TANDEM include. 2020-07-06 09:41:31 -07:00
Wayne Davison
7610f76aea Remove another file_struct kluge. 2020-07-06 09:31:22 -07:00
Wayne Davison
59cb358fda More TANDEM changes
- Handle a non-0 root uid.
- Handle alternate major/minor/MAKEDEV funcs.
- Other misc compatibility tweaks.
2020-07-06 00:05:46 -07:00
Wayne Davison
bb16db1747 Send the uid/gid 0 name since not all systems use 0 for root. 2020-07-05 22:51:12 -07:00
Wayne Davison
d6f0342a34 Change name map funcs to return a const char*. 2020-07-05 22:17:09 -07:00
Wayne Davison
6f6e5b51cc Some TANDEM ACL support. 2020-07-05 20:09:16 -07:00
Wayne Davison
28de25a664 Some whitespace & paren cleanup. 2020-07-05 20:09:13 -07:00
Wayne Davison
052b34dceb A bit more configure tweaking. 2020-07-05 19:16:32 -07:00
Wayne Davison
748b5c5d53 Some configure tweaks for TANDEM. 2020-07-05 19:08:44 -07:00
Wayne Davison
e1e4ffe057 Some C99 flexible array changes
- Use C99 flexible arrays when possible, and fall back on the existing
  fname[1] kluges on older compilers.
- Avoid static initialization of a flexible array, which is not really
  in the C standard.
2020-07-05 17:25:53 -07:00
Wayne Davison
1b53b2ff4b Tweak a comment. 2020-07-05 14:42:36 -07:00
Wayne Davison
da45cecfc8 Tweak a couple var names. 2020-07-05 14:22:09 -07:00
Wayne Davison
87b5d233e9 Setup for 3.2.3dev. 2020-07-05 09:26:40 -07:00
Wayne Davison
194cee671d Preparing for release of 3.2.2 2020-07-04 23:12:59 -07:00
Wayne Davison
b7c5520add Handle tweaked NEWS headings & protocol change. 2020-07-04 23:11:46 -07:00
Wayne Davison
2bee307592 Get rid of some superfluous lz4 code. 2020-07-04 16:13:00 -07:00
Wayne Davison
85e62c330d Tweak indentation. 2020-07-04 16:10:37 -07:00
Wayne Davison
0add026a5d Initialize values string in a more consistent spot. 2020-07-04 14:21:15 -07:00
Wayne Davison
f4184849c4 Use module_id more consistently after it is set. 2020-07-04 10:28:39 -07:00
Wayne Davison
565cde84a7 Don't turn off the user's open-noatime unless the module is forcing the value. 2020-07-04 10:28:38 -07:00
Paul Slootman
f0e670b4c6 Add "open noatime" module option to rsyncd.conf 2020-07-04 09:30:35 -07:00
Wayne Davison
ef8951779d Fix issue in --compress-level doc. 2020-07-03 11:58:36 -07:00
Wayne Davison
e285f8f9d2 Some NEWS and man page tweaks. 2020-07-02 22:33:40 -07:00
Wayne Davison
cb383673f6 Tweak a var name. 2020-07-02 09:34:08 -07:00
Wayne Davison
0768d620a5 Another table tweak. 2020-07-01 14:20:14 -07:00
Wayne Davison
d640d78f91 Change how protocol changes are mentioned; fix table in html. 2020-07-01 14:14:24 -07:00
Wayne Davison
544b3d8b3b A few more systemd tweaks. 2020-07-01 12:10:14 -07:00
Wayne Davison
ce12142c45 Don't set systemd ProtectHome=on by default. 2020-07-01 10:41:13 -07:00
Wayne Davison
c83a81ca38 Move name exceptions into the txt file. 2020-07-01 09:05:21 -07:00
Wayne Davison
d88db22ae8 Add support for the remaining parser types. 2020-07-01 08:15:12 -07:00
Wayne Davison
a1cc50ba96 Preparing for release of 3.2.2pre3 2020-06-30 23:17:50 -07:00
Wayne Davison
feb2fff894 Put the optimizations into their own list. 2020-06-30 19:31:59 -07:00
Wayne Davison
7d30490ef4 Simplify the daemon parameter definitions
The code now derives all the struct defines, default value assignments,
parser-param defines, and lp_foo() accessor functions from a single list
of daemon parameters.
2020-06-30 19:30:28 -07:00
Wayne Davison
317beebef8 Avoid crash of transfer logging w/default log format. 2020-06-30 12:16:52 -07:00
Wayne Davison
7a413c9722 Avoid strdup redefinition warning. 2020-06-30 08:27:20 -07:00
Wayne Davison
5be7363297 Avoid bloating the src-dir scan. 2020-06-29 21:45:56 -07:00
Wayne Davison
646784f0e5 Move the new target after "all". 2020-06-29 20:04:54 -07:00
Wayne Davison
18ed3f0279 More patch-update improvements; configure.ac tweak; Makefile tweaks. 2020-06-29 19:53:05 -07:00
Wayne Davison
00dd50a00c Preparing for release of 3.2.2pre2 2020-06-28 19:54:38 -07:00
Wayne Davison
7039d14616 Improve the per-branch build dir support
The release script & the patch management script now require the use of
an auto-build-save dir that makes it much easier to keep the generated
files from melding together, and remembers the configure setup for each
patch branch.
2020-06-28 19:42:25 -07:00
Wayne Davison
ec3c9f2f5a Improve alternate build-dir support
We now put the configure.sh, config.h.in, and aclocal.m4 files in the
alternate build dir along with the other generated files.  This requires
that we create symlinks for configure.ac & m4 in the build dir, which is
handled on the first run of configure or prepare-source.  I also changed
the patch-branch handling away from the .gen-stash dir to an automatic
build/$PATCH subdir idiom that will keep each branch's configuration
separated.  These automatic build dirs are only used when there is a
.git dir, a build/master dir, and no top-dir Makefile.  You'll also
want to have package/make early on your path for optimal ease of use.
2020-06-28 15:12:10 -07:00
Wayne Davison
3b4f5fb891 Move the version string out of configure.ac. 2020-06-28 15:02:19 -07:00
Wayne Davison
76064b1bf2 Fix rebuilding configure.sh in an alternate build dir 2020-06-28 12:55:43 -07:00
Wayne Davison
8df766917e A bit more man page & NEWS tweaking. 2020-06-28 09:21:29 -07:00
Wayne Davison
299430a6c1 Lack of "saw" values now reported as "INVALID"; tweak a comment. 2020-06-27 23:14:35 -07:00
Wayne Davison
dcbe005a6a Preparing for release of 3.2.2pre1 2020-06-27 21:22:49 -07:00
Wayne Davison
af57b55bdb Some misc cleanup
Remove some extraneous vars, update some years, add an  rrsync opt, &
ensure some less options are set right when running release-rsync.
2020-06-27 21:19:52 -07:00
Wayne Davison
967e6426b9 Improve the NSTR differentiation idiom. 2020-06-27 20:43:38 -07:00
Wayne Davison
61971acbe1 Some more doc & NEWS improvements. 2020-06-27 20:43:34 -07:00
Wayne Davison
5bd0b6cf71 Change the CI name 2020-06-27 18:40:21 -07:00
Wayne Davison
0eec25f75b Some patch-update & vim ft improvements
- Stash off some gen files when switching patch branches.
- Set the filetype in "env -S" files that vim can't handle.
2020-06-27 17:59:04 -07:00
Wayne Davison
3a6f06003c Improve the output when a negotiation fails. 2020-06-27 10:51:29 -07:00
Wayne Davison
f805d1a7f7 More NEWS and man page changes. 2020-06-27 10:39:12 -07:00
Wayne Davison
ab29ee9c44 Negotation env lists can specify "client & server" 2020-06-26 17:56:57 -07:00
Wayne Davison
d07c2992d1 A few more simple changes & fixes. 2020-06-26 13:19:07 -07:00
Wayne Davison
b1a8b09c21 Some man page changes. 2020-06-26 11:27:27 -07:00
Wayne Davison
fe2ef556d9 A few more tweaks. 2020-06-25 22:30:02 -07:00
Wayne Davison
11eb67eec9 Some memory allocation improvements
- All the memory-allocation macros now auto-check for failure and exit
   with a failure message that incudes the caller's file and lineno
   info.  This includes strdup().

 - Added the `--max-alloc=SIZE` option to be able to override the memory
   allocator's sanity-check limit.  It defaults to 1G (as before).
   Fixes bugzilla bug 12769.
2020-06-25 20:54:21 -07:00
Christian Hesse
39a083b16b Add missing semicolon in man page
All nginx configuration directives end in semicolon.
2020-06-24 17:54:47 -07:00
Wayne Davison
202b7b18af Tweak alloc args to size_t w/proper realloc order. 2020-06-24 17:52:36 -07:00
Wayne Davison
20934382e3 Use normal C comment style. 2020-06-23 21:45:32 -07:00
Wayne Davison
1bdf68b905 Prepare for future release of XXH3 & XXH128. 2020-06-23 21:01:25 -07:00
Wayne Davison
89827e49bc Another NEWS update. 2020-06-23 19:32:44 -07:00
Wayne Davison
f157ff3b3a Avoid negotiating a "none" choice by default
The client does not pass "none" as a negotiation choice unless it's from
the user's environment list.  The server still passes the "none" value
to the client unless its environment var excludes it.
2020-06-23 19:20:01 -07:00
Wayne Davison
d15cfef935 Setup for 3.2.2dev. 2020-06-23 19:02:59 -07:00
Wayne Davison
28f9c960d5 The server side can enforce its negotiation limits 2020-06-23 18:53:23 -07:00
Wayne Davison
323c42d51e Improve how the env restricts negotiated strings
- The env on the server side now affects the negotiated strings
  that are sent to the client.
- A too-old remote rsync gets a default negotiated string value
  so that an env restriction now handles old clients the same way
  as new ones.
2020-06-23 17:33:16 -07:00
Wayne Davison
d1fdf9ff8d Avoid -U if --atimes is disabled. 2020-06-23 15:53:47 -07:00
Wayne Davison
e93f40d8b4 Apple needs a leading underscore. 2020-06-23 15:47:27 -07:00
Hiroshi Takekawa
4df1b1d4fe Makefile.in: Use srcdir for installing rsync-ssl
When building out of source tree, we can't find rsync-ssl in the current
directory and installation fails.  Fix it by using the srcdir variable for the
path to rsync-ssl.

Signed-off-by: Hiroshi Takekawa <sian.ht@gmail.com>
2020-06-23 09:02:33 -07:00
Wayne Davison
1af58f6b77 Improve the info about compression. 2020-06-22 20:37:52 -07:00
Wayne Davison
a8fc8fc2d2 Preparing for release of 3.2.1 2020-06-22 19:31:16 -07:00
Wayne Davison
b8b7f1f3d0 Fix a typo. 2020-06-22 19:30:07 -07:00
Wayne Davison
622a116917 A few more man page tweaks. 2020-06-22 19:21:32 -07:00
Wayne Davison
b51b0b3236 Get the NEWS heading idiom right. 2020-06-22 14:46:14 -07:00
Wayne Davison
8cb1c99563 A few more https changes. 2020-06-22 14:21:15 -07:00
Wayne Davison
597a751466 Update links to https. 2020-06-22 14:16:21 -07:00
Wayne Davison
5a9e4ae5e7 Improve the options info a bit more. 2020-06-22 14:12:27 -07:00
Wayne Davison
3094552311 Add --zl=N opt & improve its docs. 2020-06-22 13:41:42 -07:00
Samuel Henrique
e4c9ff5873 Make --backup be set when --backup-dir is used 2020-06-22 13:05:17 -07:00
Samuel Henrique
9b13bcf185 Add Documentation field to systemd unit 2020-06-22 13:01:02 -07:00
Wayne Davison
8f6d6bcb08 Tweak valid_ipaddr() check. 2020-06-22 11:17:56 -07:00
Wayne Davison
300fd3055a Even more NEWS changes. 2020-06-22 09:57:29 -07:00
Wayne Davison
f6df3708c2 A few more NEWS changes; change release script. 2020-06-22 09:09:51 -07:00
Wayne Davison
785cb938ec Even more NEWS improvements. 2020-06-21 23:30:00 -07:00
Wayne Davison
246d117df0 A bit more NEWS tweaking. 2020-06-21 23:07:16 -07:00
Wayne Davison
3f776f582b More talk of buggy clang++. 2020-06-21 22:53:33 -07:00
Wayne Davison
d8d2d71663 Get the g++ version to see if it is really clang. 2020-06-21 22:34:32 -07:00
Wayne Davison
6a9adabfbb Mention the early-input on stdin. 2020-06-21 20:25:51 -07:00
Wayne Davison
2564f25114 Put the date in the heading of a pre release too. 2020-06-21 19:46:28 -07:00
Wayne Davison
7fb08531e0 Preparing for release of 3.2.1pre1 2020-06-21 19:24:26 -07:00
Wayne Davison
9dba0bb7fb Improve the simd note. 2020-06-21 18:52:28 -07:00
Wayne Davison
87bca719c3 Merge OLDNEWS.md into NEWS.md 2020-06-21 18:42:53 -07:00
Wayne Davison
f3439944ea The proto files don't need perl, so change fetch rule. 2020-06-21 16:46:50 -07:00
Wayne Davison
a7c1690d62 One more >= tweak. 2020-06-21 15:30:34 -07:00
Wayne Davison
662fedd74b Get the early-input reading code right. 2020-06-21 15:23:13 -07:00
Wayne Davison
128139c66a Leave 3.2.0 news in the NEWS file for 3.2.1. 2020-06-21 15:20:43 -07:00
Wayne Davison
2b439c1fc8 Disable atimes on macOS. 2020-06-21 15:16:56 -07:00
Wayne Davison
e16b22751a Add --early-input=FILE option. 2020-06-21 14:32:00 -07:00
Wayne Davison
7587e20cf4 Output a helpful msg about configure only if the command fails. 2020-06-21 12:55:24 -07:00
Wayne Davison
2e1b46db39 Close STDIN for early exec script. 2020-06-21 11:17:09 -07:00
Wayne Davison
f4e6fe54c9 More NEWS changes. 2020-06-21 09:18:52 -07:00
Wayne Davison
f86ceb5539 Give more_testing() a default target. 2020-06-21 09:06:59 -07:00
Wayne Davison
dfa34b4792 Some more docs/news changes.
- Mention the -VV behavior.
- Mention how the protect-args default is presented in -V list.
2020-06-21 08:58:45 -07:00
Wayne Davison
e9e9fd0cca Use an ssse3 target instead of an inline declaration. 2020-06-21 08:28:49 -07:00
Wayne Davison
7e95ba8787 Add -fno-slp-vectorize to clang++. 2020-06-21 08:05:19 -07:00
Wayne Davison
66fd34ed84 Mention atimes & protected-args in capabilities. 2020-06-20 23:28:19 -07:00
Wayne Davison
f8c6f9f4f3 Tweak the NEWS. 2020-06-20 23:15:22 -07:00
Wayne Davison
e6cfebb578 We only need one capability marked with a "*". 2020-06-20 22:09:08 -07:00
Wayne Davison
5d2379d93f Mention "asm" instead of "ASM". 2020-06-20 21:59:51 -07:00
Wayne Davison
6884ccbd2f Mention openssl-crypto in -VV list. 2020-06-20 21:44:46 -07:00
Wayne Davison
bad97961dc Elide -g from CXXFLAGS before the c++ test. 2020-06-20 21:26:21 -07:00
Wayne Davison
b0ab07cdac Some README and man page tweaks. 2020-06-20 20:31:52 -07:00
Wayne Davison
68c4583693 Change repo to be 3.2.1dev. 2020-06-20 20:17:13 -07:00
Wayne Davison
6b237b0fe9 Require -VV to see SIMD & ASM in version output 2020-06-20 19:57:11 -07:00
Wayne Davison
b37a136314 Get rid of -g option in CXXFLAGS (at least for now). 2020-06-20 19:23:54 -07:00
Wayne Davison
c9c8c64506 Remove leftover case match. 2020-06-20 19:00:57 -07:00
Wayne Davison
c5d502dc5f When fetching gen files, make sure aclocal.m4 is older than configure files. 2020-06-20 18:46:16 -07:00
Wayne Davison
1629b803cb More asm improvements
- Only use the asm code if we're on x86_64.
- More changes to decouple asm from simd.
- Check if the -Wa,--noexecstack option works.
- Support --disable-asm configure option.
2020-06-20 18:40:47 -07:00
Wayne Davison
29c7a4558a Include more SIMD test code to weed out older compilers. 2020-06-20 17:48:56 -07:00
Wayne Davison
b7dc2ca25c Decouple the MD5 asm code from the simd enabling. 2020-06-20 17:01:25 -07:00
Wayne Davison
f525f2c818 Remove asm type & size. 2020-06-20 16:54:24 -07:00
Wayne Davison
1b5819efbd Use AC_RUN_IFELSE() to make sure we can run the cpp test program. 2020-06-20 14:47:55 -07:00
Wayne Davison
a56a0bc7d6 Mention how to turn off simd near the cpp compile. 2020-06-20 11:53:22 -07:00
Wayne Davison
bd7bd5ff0c Simplify some escaping. 2020-06-20 11:35:56 -07:00
Wayne Davison
f9aece899f Change SIMD test to use a compile check. 2020-06-20 11:13:06 -07:00
Wayne Davison
63508f1518 Handle hard-linking the top-level $VER-NEWS.html file on a final release. 2020-06-20 09:57:35 -07:00
Wayne Davison
9ac22062af The nightly dir is gone now. 2020-06-20 09:43:25 -07:00
Wayne Davison
73faaab26d Pass --noexecstack to assembler. 2020-06-20 09:23:56 -07:00
Wayne Davison
9467c1f9b9 Fix conditional directives in the asm file
- Switch .s -> .S to enable the preprocessor.
- Move some defines from mdigest.h to md-defines.h.
- Tweak the asm file to use md-defines.h.
- Add a couple missing .h dependencies in the Makefile.
2020-06-20 09:06:18 -07:00
Wayne Davison
04653dabc8 Exclude the asm code when it's not being used. 2020-06-20 08:05:53 -07:00
Wayne Davison
19617f7b4a Fix compiling in a separate dir. 2020-06-20 08:05:53 -07:00
Caleb Xu
b218de2702 lib/md5-asm-x86_64.s: fix build with Apple Clang
The Mach-O x86-64 model doesn't seem to support ".type" and
".size" directives in assembly. Add ifdefs that should allow for
the file to build without issues in Apple Clang.
2020-06-19 23:38:15 -07:00
Wayne Davison
d4764934c3 A slightly modified g++/clang++ check. 2020-06-19 23:29:31 -07:00
Wayne Davison
c225330aaf Preparing for release of 3.2.0 2020-06-19 14:11:01 -07:00
Wayne Davison
3c56896d21 Simplify a variable. 2020-06-19 11:07:02 -07:00
Wayne Davison
deb8353d2c Yes, we know we're discarding a return value. 2020-06-19 10:56:32 -07:00
Wayne Davison
73053f26bc Simple change to recv_token(). 2020-06-19 09:55:48 -07:00
Holger Hoffstätte
0c13e1b3f8 Prevent unnecessary xattr warning by reordering header inclusion. (#22)
xattr headers have been provided by glibc (at least on Linux/glibc)
for many years now. Reorder the inclusion of xattr headers to
attempt compatibility/legacy after the common case.
This prevents the warning without changing compatibility to
non-glibc systems.

* Add dependency on lib/sysxattrs.h header in Makefile

Co-authored-by: Wayne Davison <wayne@opencoder.net>
2020-06-19 08:22:54 -07:00
Wayne Davison
9da38f2f99 A few minor man page tweaks. 2020-06-19 00:26:43 -07:00
Wayne Davison
a93ffb1ae9 More non-breaking space/dash improvements
- In html, use css more for non-breakability.
- In nroff, mark more dashes as non-breaking in code->bold sections,
  and get rid of backslashed dashes in preformatted blocks.
2020-06-18 23:55:51 -07:00
Wayne Davison
e08f600378 Use -&#8288; instead of &#8209;
Using a non-breaking zero-width char after a dash makes the browser
avoiding breaking on that dash and also makes it match a dash in a
search.  This is better than a non-breaking dash char, which does not
match a dash in a search.
2020-06-18 22:58:11 -07:00
Wayne Davison
e406845542 Comment must be indented to avoid ending the list item. 2020-06-18 21:57:34 -07:00
Wayne Davison
a93eb4cf38 Handle a missing c++ too. 2020-06-18 17:02:46 -07:00
Wayne Davison
7fd24bef0f Make SIMD enabled by default again (for x86_64) 2020-06-18 16:28:28 -07:00
Wayne Davison
1a9a184145 Check extra rounding using an int64. 2020-06-18 15:45:39 -07:00
Wayne Davison
4965ccf283 We need to use nawk or gawk on Solaris, not their weird awk. 2020-06-18 14:53:55 -07:00
Wayne Davison
c6f89cbf9c Complain if we can't enable simd on non-x86_64. 2020-06-18 14:27:00 -07:00
Wayne Davison
2921779c1f Fix clang check. 2020-06-18 13:46:01 -07:00
Wayne Davison
cbed522ef4 Get rid of useless -e with sed. 2020-06-18 13:31:50 -07:00
Chainfire
4f539ccf21 x86-64 SIMD build fixes (#20)
* x86-64 SIMD build fixes

configure.ac was modified to detect g++ >=5 and clang++ >=7. Additionally
some script malfunctions on FreeBSD were corrected.

The get_checksum1() code has been modified to fix clang and g++ 10
compilation.

This version of the code and configure.ac has been tested on:

Ubuntu 16 - gcc 7.3.0, clang 6.0.0
Debian 10 - gcc 5.4.0, 6.4.0, 7.2.0, 8.4.0, 9.2.1, 10.0.1, clang 5.0.2,
6.0.1, 7.0.1, 8.0.0, 9.0.0, 10.0.0
ArchLinux 20200605 - gcc 10.1.0, clang 10.0.0
FreeBSD 12.1 - gcc 9.3.0, clang 8.0.1

It is unknown if it will work on gcc 5.0-5.3, but the script currently
allows it.
2020-06-18 13:20:44 -07:00
Wayne Davison
b5e539fc5a Use documentation to extract 2 more .h lists
- Change default_cvsignore char[] into a define.
- Make the DEFAULT_DONT_COMPRESS and DEFAULT_CVSIGNORE defines get set
  based on their info in rsync.1.md.
- Add a few more don't-compress suffixes from Simon Matter.
2020-06-18 11:20:57 -07:00
Wayne Davison
88c18ef648 Make the g++ check more lenient. 2020-06-18 09:31:47 -07:00
Wayne Davison
7dc9431f60 A few minor man page improvements. 2020-06-17 11:25:38 -07:00
Wayne Davison
07a3e1f939 Enhance compatibility with older python3 versions. 2020-06-17 10:52:02 -07:00
Wayne Davison
93223719c9 A couple more NEWS tweaks. 2020-06-17 10:30:32 -07:00
Wayne Davison
0b2d5fe494 Preparing for release of 3.2.0pre3 2020-06-17 10:12:09 -07:00
Wayne Davison
d3c7cfad22 Be a little more explicit with override info. 2020-06-17 09:31:48 -07:00
Christian Hesse
9ec777faf8 add a systemd socket unit for rsync 2020-06-17 09:19:12 -07:00
Christian Hesse
69f445fd09 update rsync systemd unit, add more security features 2020-06-17 09:19:12 -07:00
Wayne Davison
643b9d0183 Change SIMD back to disabled unless requested. 2020-06-16 23:00:01 -07:00
Wayne Davison
2c681b874e Some fixes after compiling on cygwin. 2020-06-16 22:58:24 -07:00
Wayne Davison
e44e79cedb Update config.guess & config.sub. 2020-06-16 21:24:23 -07:00
Wayne Davison
beaf19c3e7 Have --disable-md2man affect the Makefile. 2020-06-16 19:05:05 -07:00
Wayne Davison
0b2a394cbc Fix /usr/bin/env with script args. 2020-06-16 18:32:16 -07:00
Wayne Davison
27e88dec04 Use /usr/bin/env for increased portability. 2020-06-16 18:27:48 -07:00
Wayne Davison
929f136b3b A few more NEWS tweaks. 2020-06-16 15:48:23 -07:00
benrubson
6a22f4fee1 enh(configure) Promote OpenSSL crypto lib support 2020-06-16 15:05:36 -07:00
Wayne Davison
d90990d6ac A few more trivial tweaks. 2020-06-16 14:42:41 -07:00
Wayne Davison
111225a996 Fix md2man --test on a fresh checkout. 2020-06-16 14:03:16 -07:00
Wayne Davison
7dfcbf7df6 Add g++ failure info; add mention of SSL rsyncd examples. 2020-06-16 12:10:56 -07:00
Wayne Davison
38ecf188d9 Only complain about lack of g++ on linux for now. 2020-06-16 11:35:54 -07:00
Wayne Davison
29be5eddde Add configure check for md2man functioning; split long error lines. 2020-06-16 11:13:45 -07:00
Wayne Davison
54b1ddc45d Change configure to make new features more likely to get included in a build. 2020-06-16 09:59:00 -07:00
Wayne Davison
8cd9aa326c Fix bug in CXXFLAGS tweak. 2020-06-16 09:14:28 -07:00
Wayne Davison
cd50745e1c Remove the new $< use from the Makefile. 2020-06-16 08:46:44 -07:00
Wayne Davison
ae94e3db4b Tweak my email. 2020-06-16 07:55:42 -07:00
Wayne Davison
6efaa74dd3 More spelling fixes from Fossies
https://fossies.org/linux/test/rsync-master.tar.gz/codespell.html
2020-06-16 07:46:28 -07:00
Wayne Davison
5496eda5d1 Turn help-from-md into an awk script. 2020-06-15 18:32:00 -07:00
Wayne Davison
353dec1102 Avoid -e option to sed for BSD. 2020-06-15 15:08:42 -07:00
Wayne Davison
d80da9e674 A few small tweaks. 2020-06-15 15:04:08 -07:00
Wayne Davison
6f0c56304f Preparing for release of 3.2.0pre2 2020-06-15 11:53:19 -07:00
Wayne Davison
2452ad3663 Fixed setting of rsync_lastver var. 2020-06-15 11:52:54 -07:00
Wayne Davison
1fa38546a0 Document how to setup rsyncd behind a TLS proxy. 2020-06-15 11:36:24 -07:00
Wayne Davison
249e28c75a Rename "haproxy header" to "proxy protocol". 2020-06-15 11:33:23 -07:00
Wayne Davison
6273153c5f Add preliminary gnutls support. 2020-06-15 11:19:36 -07:00
Wayne Davison
628dcceb8d Choose openssl before stunnel. 2020-06-15 10:41:08 -07:00
Wayne Davison
00ec415a69 Tweak the stunnel4 Verify config; tweak the rsync-ssl docs/usage. 2020-06-15 09:36:13 -07:00
Wayne Davison
ec8035cef9 A minor NEWS tweak. 2020-06-15 09:21:26 -07:00
Wayne Davison
775f64f4b8 Add a warning header to the generated help-*.h files. 2020-06-14 18:49:38 -07:00
Wayne Davison
660274bfb7 A few more md -> html improvements 2020-06-14 18:28:30 -07:00
Wayne Davison
59cf9ff797 More NEWS improvements. 2020-06-14 18:00:18 -07:00
Wayne Davison
ff272503b0 Output who_am_i() info in all rsyserr() messages. 2020-06-14 15:54:42 -07:00
Wayne Davison
43a939e3f2 Improve some md files. 2020-06-14 15:29:45 -07:00
Wayne Davison
b65b6db304 Add handling of non-breaking space & double-dash. 2020-06-14 15:29:45 -07:00
Wayne Davison
7b1f8f57c3 Update rrsync & its opt-culling script. 2020-06-13 22:11:37 -07:00
Wayne Davison
c32012d199 Need to indent a code block in the README. 2020-06-13 21:31:26 -07:00
Wayne Davison
9ba6ce1b67 More release improvements. 2020-06-13 21:21:26 -07:00
Wayne Davison
ca9e247762 Mention renamed .md files. 2020-06-13 20:42:33 -07:00
Wayne Davison
f27a630e46 Don't use c++ comments. 2020-06-13 20:12:15 -07:00
Wayne Davison
243a9d9be0 A few more release script fixes. 2020-06-13 20:11:06 -07:00
Wayne Davison
c528f8d5c8 Preparing for release of 3.2.0pre1 2020-06-13 19:16:26 -07:00
Wayne Davison
1d1c0f14e1 Make -4 & -6 also able to affect an ssh remote shell. 2020-06-13 19:15:02 -07:00
Wayne Davison
e63ff70eae Some indentation fixes. 2020-06-13 19:15:02 -07:00
Wayne Davison
8a70f1420b Some fixes for the release script & other helpers. 2020-06-13 19:15:00 -07:00
Wayne Davison
cdf58a7aba Change alt_dest_name() to alt_dest_opt(). 2020-06-13 12:04:13 -07:00
Wayne Davison
1d6c9676f9 Change 3 alt-dest vars to just one + some defines. 2020-06-13 11:47:08 -07:00
Wayne Davison
3d29fa99ec Tweak a couple var names. 2020-06-13 11:47:04 -07:00
Wayne Davison
d167935874 Change a function name. 2020-06-13 03:03:33 -07:00
Wayne Davison
d326961290 Fix overzealous setting of mtime & tweak time comparisons
- Stop setting the mtime on a file we didn't transfer (or didn't verify
  the checksum) when the time diff is within the modify window.
- Stop computing a time difference (-1|0|1) when all we care about is
  time equality.
2020-06-13 02:41:30 -07:00
Wayne Davison
7dec4029ee Convert a couple files to UTF-8; more Copyright years. 2020-06-13 02:41:04 -07:00
Wayne Davison
ab0189c813 Make use of poptDupArgv(). 2020-06-12 23:28:27 -07:00
Wayne Davison
bb484a799e The unalias argv array needs room for a trailing NULL. 2020-06-12 23:19:14 -07:00
Wayne Davison
ad9f1571ce Add hashtable to delete_in_dir() to fix -x deletions 2020-06-12 17:42:56 -07:00
Wayne Davison
f800557824 Tweak the hashtable routines to be a little clearer and easier. 2020-06-12 17:42:41 -07:00
Wayne Davison
13f81f4aa7 Tweak a usage message. 2020-06-12 10:20:33 -07:00
Wayne Davison
d3ae752c53 Fix running prepare-source from a separate build dir. 2020-06-12 09:29:42 -07:00
Wayne Davison
e3437244b5 Improve how the help lines are harvested from the md file. 2020-06-12 08:50:51 -07:00
Wayne Davison
1efeb59166 Enable SIMD by default (if g++ is around). 2020-06-12 08:29:36 -07:00
Wayne Davison
d4fc18f375 Use the refused-option code to disable options that aren't compiled into the source. 2020-06-11 22:53:29 -07:00
Wayne Davison
58680edb12 Improve checkcsum/compress info that may differ between packaged versions. 2020-06-11 22:03:10 -07:00
Wayne Davison
34141954c7 Add packaging notes to NEWS. 2020-06-11 20:35:18 -07:00
Wayne Davison
cba00be622 Translate man page's option list into .h files for options.h to use. 2020-06-11 20:34:23 -07:00
Wayne Davison
de78dd685b Simplify the install of rsync-ssl by unifying 2 scripts. 2020-06-11 20:26:56 -07:00
Wayne Davison
88abb50229 Promote newer compressors to the start of the list. 2020-06-11 20:26:56 -07:00
Wayne Davison
6d6b8595df Remove generated doc files via make clean. 2020-06-11 20:26:45 -07:00
Wayne Davison
66bd4774a8 Allow maintainer to build with /usr/local prefix but document /usr. 2020-06-11 19:15:08 -07:00
Wayne Davison
c117fa4bf9 Create a get_device_size() helper function. 2020-06-11 16:09:36 -07:00
Wayne Davison
b040825b86 Improve the haproxy header docs. 2020-06-11 15:23:35 -07:00
Wayne Davison
3c793ef153 Use /dev/shm instead of requiring /dev/shm/tmp. 2020-06-11 14:33:25 -07:00
Wayne Davison
cff0764b7f Add haproxy header parameter to rsync daemon 2020-06-11 14:22:25 -07:00
Wayne Davison
a3377921eb Add early exec daemon parameter.
Inspired by Ciprian Dorin Craciun's `bootstrap exec` patch.
2020-06-10 21:38:37 -07:00
Wayne Davison
a61ffbafe5 Make sure the tmpdir2 dir is writable. 2020-06-10 13:59:02 -07:00
Wayne Davison
190b474610 Mention how to run a single test. 2020-06-10 13:59:02 -07:00
Wayne Davison
85e90b0f80 Update copyright year in runtests.sh too. 2020-06-10 13:59:02 -07:00
Wayne Davison
516ca6a442 Add support for /run/shm/tmp dir so the CI action doesn't skip a test. 2020-06-10 13:17:41 -07:00
Wayne Davison
fe993ca94d Have the CI actions run make check29 & check30. 2020-06-10 12:02:40 -07:00
Wayne Davison
f8683063fb Fix a couple batchfile issues. 2020-06-10 11:23:14 -07:00
Wayne Davison
7c83eb6e63 Improve gensend rule & list of PHONY targets. 2020-06-10 09:44:23 -07:00
Wayne Davison
58e8ecf48f Improvements for release process; a gensend hook. 2020-06-10 09:31:01 -07:00
Wayne Davison
c5e44330a5 Fix double-gen of manpages. 2020-06-10 00:39:30 -07:00
Wayne Davison
ae82762c31 Fix the output with -D; a few minor tweaks. 2020-06-10 00:26:29 -07:00
Wayne Davison
2ac7401b44 Mention the github rsync home. 2020-06-09 18:08:29 -07:00
Wayne Davison
44af79223e The samba rsync server now requires ssl. 2020-06-09 17:28:07 -07:00
Wayne Davison
03fc62ad2f More man processing improvements
- Support the commonmark library in addition to cmarkgfm.
- Remove github-flavor from the markup.
- A few more html style improvements.
2020-06-09 17:02:41 -07:00
Wayne Davison
68c865c9e6 A few more man page script improvements. 2020-06-09 09:17:37 -07:00
Wayne Davison
6dc94e39a7 Output the files at the end; fix a missing double-quote. 2020-06-09 00:58:07 -07:00
Wayne Davison
8146b04ffb Fix the html title. 2020-06-08 22:52:58 -07:00
Wayne Davison
5b19cf7875 A couple man page tweaks. 2020-06-08 22:48:14 -07:00
Wayne Davison
53fae55652 Change man page src format from yodl to markdown.
This removes the yodl dependency, which is sometimes hard to track down.
Instead, this uses a python3 script that leverages the cmarkgfm library
to turn the source file into html.  Then, the script parses the html in
order to turn the tag stream into a nroff stream using a simple state
machine. While it's doing that it also implements one added format rule
that turns an ordinal list that starts at 0 into a description list
(since markdown doesn't have an easy description list idiom).
2020-06-08 21:03:42 -07:00
Wayne Davison
bd66a92e7c Tweak the new heading 2020-06-07 19:46:22 -07:00
Sebastian Andrzej Siewior
165ef61de3 Add OpenSSL license exception also to COPYING
Add the OpenSSL license exception also to the COPYING file which
contains the license related information.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
2020-06-07 19:46:22 -07:00
Wayne Davison
7dbbde8c5e Use ZSTD_CLEVEL_DEFAULT define. 2020-06-07 19:30:24 -07:00
Wayne Davison
888f4f9503 Put the rsync-ssl-rsh helper script into a lib dir. 2020-06-07 19:25:18 -07:00
Wayne Davison
2c6f0581ac A couple minor fixes. 2020-06-04 22:54:38 -07:00
Wayne Davison
916faecb83 Only sender can output non-final stats on error
The receiving side's stats are split between 2 processes until the very end.
2020-06-04 21:40:43 -07:00
Wayne Davison
5d7b71b7a7 Make use of O_NOFOLLOW if it is defined. 2020-06-04 19:47:59 -07:00
Wayne Davison
0dde65a26b Mention more NEWS items. 2020-06-04 19:08:04 -07:00
Wayne Davison
b177311aee Use a lock to not fail on a left-over pid file. 2020-06-04 19:08:03 -07:00
Wayne Davison
778f0dff9b Use more switch statements. 2020-06-04 16:17:12 -07:00
Wayne Davison
342579aa6f Make -V the short opt for --version. 2020-06-04 15:52:38 -07:00
Wayne Davison
01b9bbb0f9 Avoid a deadlock due to huge amounts of verbose messages.
Allow the receiver to increase their iobuf.msg xbuf if it fills up. This
ensures that the receiver will never block trying to output a message,
and thus it will always drain the data from the sender and keep the
whole thing from clogging up.
2020-06-04 14:20:51 -07:00
Wayne Davison
852a0b29c3 Tweak --copy-as docs a bit more. 2020-06-04 13:07:50 -07:00
Wayne Davison
55290c8584 Add hostname "lh" as a --no-cd localhost. 2020-06-04 12:58:02 -07:00
Wayne Davison
e633091d23 Fix change_dir() leaving appended slash in curr_dir on failure. 2020-06-04 12:35:24 -07:00
Wayne Davison
4c9fdb9f74 Handle --skip-compress right for new compressors
Some compressors can't completely turn off, so minimize the level
when a file is being "skipped".
2020-06-02 18:06:09 -07:00
Wayne Davison
e0d30a22d7 Mention that rsync --version outputs checksum & compress lists. 2020-06-02 17:21:51 -07:00
Wayne Davison
42ec4e3090 Update ccpp.yml
Switch to ubuntu-20.04 and add a couple dev libs.
2020-06-02 17:20:22 -07:00
Wayne Davison
3735002751 Some improvements to the release mechanism
- Some manpage changes to make them more consistent and to add a section
  that the release script expects in rsync-ssl.
- Fixed some issues in release-rsync pertaining to various file changes,
  such as the .md file changes.
- Change the gpg handling to stop prompting for a passphrase since gpg
  now makes use of gpg-agent (and the old gpg script is apparently not
  passing through fd 2 that git needs to get status).
2020-06-02 16:54:07 -07:00
Wayne Davison
d47a80c05e Move the CSUM defines. 2020-06-01 18:49:15 -07:00
Wayne Davison
9dd9952138 A few style tweaks. 2020-06-01 18:38:06 -07:00
Jorrit Jongma
71c4ae2336 Move OpenSSL-related MD4/5 defines and imports to lib/mdigest.h
Works just as well, prevents having to repeat them across files
2020-06-01 17:57:38 -07:00
Wayne Davison
c0268d9217 Some improvements for --msgs2stderr and --daemon.
- Set am_daemon to -1 (from 1) when the daemon is run via rsh.
- Only disable --msgs2stderr for a normal (socket) daemon.
- Forward a -q to the server if --msgs2stderr was also specified.
- Added --no-msgs2stderr option to allow it to be overridden.
2020-05-31 16:02:46 -07:00
Wayne Davison
da448cdc99 Mention the latest NEWS items. 2020-05-30 05:54:09 -07:00
Wayne Davison
d619a87aa5 Avoid noop_io_until_death() if --msgs2stderr was specified. 2020-05-30 05:53:59 -07:00
benrubson
a931301bef Search for double-fuzzy files only when needed 2020-05-29 23:13:15 -07:00
Wayne Davison
265b0bc9bb Silence a strncpy() warning. 2020-05-29 17:35:56 -07:00
Wayne Davison
13f249a826 Silence some g++ warnings. 2020-05-29 17:24:15 -07:00
Wayne Davison
c66e08acb3 Give configure's snprintf() test a guaranteed short string at the start. 2020-05-29 17:24:05 -07:00
Wayne Davison
f5446552f3 Silence gcc7.1 warnings about snprintf(). 2020-05-29 14:18:08 -07:00
Wayne Davison
364d302bca Fix regex issue due to python 3.8 bug. 2020-05-28 20:48:24 -07:00
Wayne Davison
60e71c1b8b A few minor xxhash changes. 2020-05-28 20:40:23 -07:00
Wayne Davison
342921eb97 Merge pull request #5 from benrubson/daemonstats
Have daemon log data sent/received even when exiting with an error.
2020-05-28 13:42:47 -07:00
Wayne Davison
df0ed76a76 Add stub for canonical_checksum(). 2020-05-28 12:46:46 -07:00
Wayne Davison
d7521f5428 The xxh* checksums don't need to be reversed on output. 2020-05-28 12:33:36 -07:00
Wayne Davison
c7f10de442 Switch to using LZ4_compress_default(). 2020-05-28 11:40:52 -07:00
Wayne Davison
f60bd811e9 Use MSG_FLUSH in a couple more spots. 2020-05-28 00:41:39 -07:00
Wayne Davison
cd0637a953 Merge pull request #2 from benrubson/flush
Help final error messages get to the sender. Is particularly helpful when talking with an older rsync client. Adds a new flush type of MSG_FLUSH.
2020-05-27 23:35:25 -07:00
Wayne Davison
8809f65b13 A couple minor tweaks. 2020-05-26 22:36:56 -07:00
benrubson
c906619620 Log data sent/received even if error 2020-05-26 19:53:25 +02:00
Wayne Davison
5710d2fe2e Simplify the capabilities array. 2020-05-26 08:05:24 -07:00
benrubson
32fe5fbc11 Correctly send last error to sender 2020-05-26 16:24:30 +02:00
Wayne Davison
bcb0a24a8f Convert NEWS & OLDNEWS into .md files. 2020-05-26 02:24:33 -07:00
Wayne Davison
96ed96dabd Fix the parsing of the --version capabilities. 2020-05-25 23:42:51 -07:00
Wayne Davison
8ad2ca9ae2 Install yodl for the CI builds. 2020-05-25 23:42:51 -07:00
Wayne Davison
23a37ecac4 Get indent right. 2020-05-25 23:33:11 -07:00
Wayne Davison
47bae3abf6 Improve output of capabilities in --version list.
It now wraps better as the "no " prefixes change, and it makes it easier
to maintain patches that add items into the capabilities list.
2020-05-25 23:24:46 -07:00
Wayne Davison
dff9dd56a0 Remove xxhash from capabilities list.
It's now listed in the "Checksum list:" output.
2020-05-25 21:31:40 -07:00
Wayne Davison
7182508a75 Fix a couple deb names. 2020-05-25 21:21:58 -07:00
Wayne Davison
cb0fe9e195 Improve CI setup. 2020-05-25 21:17:51 -07:00
Wayne Davison
87f2984df0 Improve how negotiated info affects batch files. 2020-05-25 19:19:59 -07:00
Wayne Davison
24ce3e9d54 Tweak the --zz option to --zc (aka --compress-choice). 2020-05-25 16:57:47 -07:00
Wayne Davison
98cddfaf7a Rename a couple files to .md 2020-05-25 15:05:06 -07:00
Wayne Davison
d1fcb8ce9d Add some extra indent. 2020-05-25 14:59:51 -07:00
Wayne Davison
b4ace35304 Create ccpp.yml 2020-05-25 14:43:25 -07:00
Wayne Davison
888ce058d8 Two sparse fixes from Yuxuan Shui.
- Make "len" parameter of do_punch_hole an OFF_T.
- Clear sparse_past_write in sparse_end(), otherwise when write_sparse()
  is called for the next file, do_punch_hole() will be called with a pos
  that's not actually the current position in file, causing it to fail.
2020-05-25 14:01:52 -07:00
Wayne Davison
c394e86184 Include lz4 compression support.
Based on a patch that was emailed to me without a valid return address.
2020-05-25 13:45:56 -07:00
Wayne Davison
4aaadc2f29 Include zstd compression support.
Based on a patch by Sebastian A. Siewior. Fixes bug #14338.
2020-05-25 13:44:48 -07:00
Wayne Davison
abef92c037 Fix handling of a compressor that has no off_level. 2020-05-25 13:02:56 -07:00
Wayne Davison
87019d7721 Output the default checksum & compress lists in the --version output. 2020-05-25 13:02:12 -07:00
Wayne Davison
fc265c5a92 A couple minor configure.ac tweaks. 2020-05-25 11:50:44 -07:00
Wayne Davison
d999efe6e5 Make compression-level handling generic. 2020-05-25 11:18:51 -07:00
Wayne Davison
97e8c55ee8 Some minor tweaks & tidying up. 2020-05-24 22:50:51 -07:00
Wayne Davison
739fa96737 Change odd-ball map_ptr() to use remainder like the others. 2020-05-24 20:38:48 -07:00
Jorrit Jongma
d474f2986e Improve performance of file_checksum()
Previously files were hashed in blocks of CSUM_CHUNK (64) bytes. This
causes significant overhead. The CSUM_CHUNK define cannot be changed as
md5.c depends on it, but there is no obvious reason to use it in
file_checksum(). By using CHUNK_SIZE (32 kB) instead, in some test
cases throughput more than doubles.
2020-05-24 20:33:33 -07:00
Wayne Davison
a863c62cd1 More NEWS updates. 2020-05-24 20:19:15 -07:00
Wayne Davison
5ac353d845 Prefer zlibx compression consistently instead of having 2 possible default preference orders. 2020-05-24 19:52:08 -07:00
Wayne Davison
faecd066a6 Don't auto-foward debug options to the server side anymore. 2020-05-24 19:37:15 -07:00
Wayne Davison
6efc43cc0a Fix -z choice with older rsyncs. 2020-05-24 19:16:05 -07:00
Wayne Davison
4496e0e8e7 A few more compression tweaks. 2020-05-24 18:43:03 -07:00
Wayne Davison
64d5ea39c0 More compress changes
- Add the zlibx (external-code compatible) compression name.
- Re-enable zlib support with the external library so it can be
  tried as a fallback if zlibx isn't available.
- Add --compress-choice=STR (aka -zz=STR) option.
- Make --cc=STR an alias for --checksum-choice=STR.
- Hook up the new compression negotiation logic.
2020-05-24 17:24:42 -07:00
Wayne Davison
4af8403aa2 Fix negotiation of none & improve NSTR debug msgs. 2020-05-24 13:49:06 -07:00
Wayne Davison
2f84a6bd73 Add support for negotiated checksum names. 2020-05-24 13:22:19 -07:00
Wayne Davison
eda15d52a8 Make xxh64 the "main_name" for the current xxhash. 2020-05-24 02:10:05 -07:00
Wayne Davison
741d5f10c6 Fix some warnings. 2020-05-24 02:04:14 -07:00
Wayne Davison
4f92fd8ddd Some more checksum improvements
- Add/improve --debug=CSUM2 messages.
- Add an "xxh64" alias for "xxhash" name because we should be
  getting a few more xxhash variations in the future.
- Tweak the matching code to handle entries that have multiple
  names.
- Tweak some of the vars/defines.
2020-05-24 01:00:53 -07:00
Wayne Davison
7f2359a5cc Improve some early debug-message newlines.
Avoid a newline issue during the output of --DEBUG=CSUM info from
both the server and the client -- we need to output the full message
with its newline as much as possible.
2020-05-23 21:51:28 -07:00
Wayne Davison
6e942e5898 Avoid re-evaluating the args of SIVAL* w/CAREFUL_ALIGNMENT. 2020-05-23 21:43:53 -07:00
Wayne Davison
1c9bb168bb Unify the checksum context memory, since we only use one at a time. 2020-05-23 18:52:03 -07:00
Wayne Davison
799de21af6 Fixed the use of openssl MD4 for transfer checksums. 2020-05-23 16:22:36 -07:00
Wayne Davison
1cb1edeb68 Optional openssl support for MD4 pre-transfer checksums (but, sadly, not transfer checksums). 2020-05-23 12:30:58 -07:00
Wayne Davison
15c1162b24 Add optional use of the openssl crypto lib for MD5. 2020-05-23 10:06:59 -07:00
Wayne Davison
a7175ee029 Mention a few more news items. 2020-05-22 23:26:25 -07:00
Wayne Davison
68516f91be Add "input" handling for cmd_txt_*() pkglib.py. 2020-05-22 22:49:02 -07:00
Jorrit Jongma
531ffa8104 Optimized assembler version of md5_process() for x86-64
Originally created by Marc Bevand and placed in the public domain.
Enable/disabled via the same --enable-simd configure switch as
the rolling checksum optimizations.
2020-05-22 22:37:21 -07:00
Wayne Davison
d7212df0f1 A little more safety in negotiate_checksum(). 2020-05-22 19:29:05 -07:00
Wayne Davison
a28bc3ebf6 Promoting xxhash support. 2020-05-22 17:59:12 -07:00
Wayne Davison
55bb4dab7a Some checksum improvements
- Improve csum negotation logic.
- Define the csum names in a single structure.
- Add --debug=CSUM.
2020-05-22 17:59:12 -07:00
Jorrit Jongma
5fa4209ca0 AVX2 optimized version of get_checksum1() for x86-64
Additionally restructures build switches and defines from SSE2 to SIMD,
to allow potential reuse should patches become available with SIMD
instructions for other processor architectures.

(Some minor tweaks of Jorrit's patch to avoid requiring GNU make and to
avoid C++ comments in .c files.)
2020-05-22 11:31:31 -07:00
Wayne Davison
4f6c8c6652 Checksum negotiation & more bits for compat_flags
- Add checksum negotiation to the protocol so that we can easily add new
  checksum algorithms and each will be used when both sides support it.
- Increase the size of the compat_flags value in the protocol from a
  byte to an int.
2020-05-22 09:52:14 -07:00
Wayne Davison
a7303a3d3d Fix a bug in the writing of the batch.sh file
Fix the code that writes the options and the default destination path
into the batch.sh file to be able to handle options being specified
after source/dest args.
2020-05-22 08:27:07 -07:00
Jorrit Jongma
70c6b408dc SSE2/SSSE3 optimized version of get_checksum1() for x86-64
Requires compilation using GCC C++ front end, build scripts have been
modified accordingly. C++ is only used when the optimization is enabled
(g++ as compiler, x86-64 build target, --enable-sse2 is passed to
configure).

(Wayne made a few tweaks, including making it disabled by default.)
2020-05-21 14:41:55 -07:00
Wayne Davison
be7af36c51 Tweak the accept/refuse strings a bit. 2020-05-18 00:06:06 -07:00
Wayne Davison
3b36bde953 Add back a lost "*" and document the refusing of log-file* opts. 2020-05-17 23:28:35 -07:00
Wayne Davison
c3986d4c5a More manpage improvements for "refuse options". 2020-05-17 22:19:25 -07:00
Wayne Davison
b3a1a0ca9d Add the ability to negate matches for the daemon's "refuse options". 2020-05-17 21:29:11 -07:00
Wayne Davison
e448d31d63 Need to flush early errors before we exit. 2020-05-17 21:20:15 -07:00
Wayne Davison
37de48979e Some pkglib improvements. 2020-05-17 20:32:43 -07:00
Wayne Davison
08f955e17b A couple more manpage fixes. 2020-05-13 00:20:03 -07:00
Wayne Davison
3435ae9bd0 A bit more manpage tweaking. 2020-05-13 00:11:57 -07:00
Wayne Davison
7a9295778c Change r'\1%s\2' to r'\g<1>%s\2'. 2020-05-06 17:23:34 -07:00
Wayne Davison
f7746d0000 A couple extra function checks for future features. 2020-04-29 22:14:49 -07:00
Wayne Davison
96a6ea0f26 Convert another packaging script to python3. 2020-04-29 21:25:17 -07:00
Wayne Davison
6242786158 A few superficial tweaks. 2020-04-29 19:41:56 -07:00
Wayne Davison
b430ceec7a Use a varint to send the file-list flags
If both sides support the "V" compatibility flag, we send the file-list
flags as a varint instead of a 1-or-2 byte value.  This upgrades the
number of reserved flag bits from 1 to 17 with very few extra bytes in
typical file-list data.
2020-04-29 18:22:52 -07:00
Wayne Davison
3a7bf54ad5 A resumed partial-dir file is transferred in-place.
Fixed bug #13071.
2020-04-29 17:02:14 -07:00
Wayne Davison
c1cb307b4b Fix a couple issues with the atime file-list value. 2020-04-26 18:42:37 -07:00
Wayne Davison
af6118d98b Allow a missing parent dir when --delete-missing-args was specified. 2020-04-26 18:10:40 -07:00
Wayne Davison
ea3337a210 Add extensions to the default no-compress list.
Fixes bug #13749.
2020-04-26 17:07:58 -07:00
Wayne Davison
035a13f7e4 Add a few new opts to rrsync. 2020-04-26 14:54:45 -07:00
Wayne Davison
f14adfd75e Some var cleanup; move test-util vars into t_stub.c. 2020-04-26 14:54:43 -07:00
Wayne Davison
d218be3482 Update a few more copyright years. 2020-04-25 23:34:16 -07:00
Wayne Davison
f4c077e85e Change pending version to 3.2.0 (currently 3.2.0dev). 2020-04-25 23:30:42 -07:00
Wayne Davison
1c7785ab1e Change do_setattrlist_times() to use an stp arg. 2020-04-25 21:39:11 -07:00
Wayne Davison
87257f869c Change --set-notime to --open-noatime. 2020-04-23 14:32:26 -07:00
Wayne Davison
b936741032 Added --atimes and --set-noatime options. 2020-04-23 13:24:15 -07:00
Wayne Davison
2b2a3c87b6 Mention more changes in the NEWS. 2020-04-23 13:18:07 -07:00
Wayne Davison
6e962ac51e Eliminate .in for rsync-ssl. 2020-04-22 14:53:06 -07:00
Wayne Davison
991ab811cb Turn nightly-rsync into a python script. 2020-04-22 12:43:25 -07:00
Wayne Davison
3249824264 Some more rsync-ssl improvements:
- Make the rsync-ssl default behavior more user friendly.
- Install rsync-ssl & rsync-ssl-rsh in the regular install rules.
- Add a manpage for rsync-ssl (which is also installed).
- Get rid of the rsync-ssl-client package in our spec file.
2020-04-22 12:40:14 -07:00
Wayne Davison
1c465dc33a Change the name of the rsh-ssl-rsync script. 2020-04-22 10:52:01 -07:00
Wayne Davison
2a87d78f69 Change the rsync-ssl helper script
The new rsh-ssl-rsync helper script (replacing stunnel-rsync) supports
openssl in addition to stunnel.  The RSYNC_SSL_TYPE environment variable
can be set to specify which type of connection to use, and the first arg
to rsync-ssl can be --type=stunnel or --type=openssl to override the env
var or the default of "stunnel".  The helper script now looks for
stunnel4 or stunnel on the PATH at runtime instead of having configure
look for it at compile time.
2020-04-19 14:00:33 -07:00
Wayne Davison
3ba4db7030 Two more spelling fixes and some year updates. 2020-04-16 09:31:02 -07:00
Wayne Davison
d29702134a Spelling fixes from a Fossies run done by Jens. 2020-04-15 17:42:23 -07:00
Wayne Davison
1c82a1e1e5 A few file-data improvements. 2020-04-12 15:51:20 -07:00
Wayne Davison
2d0c7adba9 Change some packaging tools into python3 and make a few improvements. 2020-04-12 00:13:35 -07:00
Wayne Davison
0b4b31a960 Add a (pending) release line for 3.1.4. 2020-04-11 17:59:22 -07:00
Wayne Davison
8a21e5a8c6 Use the --quiet option. 2020-04-09 18:42:31 -07:00
Wayne Davison
fa9c8d04d4 Put the year-tweak script into packaging dir. 2020-04-09 15:17:09 -07:00
Wayne Davison
c5fabfb068 Set Copyright years and make them easier to update
I replaced git-set-file-times with an improved version that I wrote
recently (in python3). A new script uses it to figure out the
last-modified year for each *.[ch] file and updates its copyright.
It also puts the latest year into the latest-year.h file for the
output of --version.
2020-04-09 15:11:37 -07:00
Wayne Davison
e2aee6c4af Switch RSYNC_PORT to -1 in check_for_hostspec(). 2020-04-07 19:21:37 -07:00
Wayne Davison
2598ca668b Fix the default skip-compress list.
The default value of the skip-compress list actually comes from the
daemon's default lp_dont_compress() value, but a while back the vars
stopped getting default values in a non-daemon run. I added a call to
reset_daemon_vars() so that the "Vars" values get set from "Defaults".
2020-04-07 18:15:09 -07:00
Wayne Davison
cd7ad50bc8 Tweak the grep to look for sys/sysmacros.h. 2020-04-07 15:32:06 -07:00
Wayne Davison
5e4a1441cb Avoid the include warnings for major(). 2020-04-07 15:16:19 -07:00
Wayne Davison
9dea2ae87c Make use of the new RSYNC_PORT env var. 2020-04-07 13:36:01 -07:00
Ethan Sommer via rsync
795268bb7c Replace mkproto.pl with mkproto.awk
This replaces the build dependency on perl with one on awk which is
already used throughout the build system and is much more ubiquitous
than perl.
2020-04-07 13:08:05 -07:00
Wayne Davison
70cbc66b7f Set RSYNC_PORT in the env for a daemon-over-rsh connection.
Fixes bug #14163.
2020-04-05 19:34:27 -07:00
Wayne Davison
b63276e70f A quick fix for some perl patch-helper scripts. 2020-04-05 17:18:32 -07:00
Wayne Davison
b0c03e2be9 Another tweak for a change in git status. 2020-04-05 17:12:29 -07:00
Wayne Davison
8475e0e492 Tweak some indentation. 2020-04-05 17:03:15 -07:00
Wayne Davison
7f06cc7ed0 Don't throw an error if a potential fuzzy dir isn't a dir
Add a flag for calling get_dirlist() and for send_directory() that
indicates that the dirname is allowed to not be a directory.  Based
on a patch by Ben Rubson.  Fixes bug #13445.
2020-04-05 16:41:15 -07:00
Wayne Davison
10d40508e6 Use "exit 1" in atomic-rsync for error exit.
Fixes bug #15469.
2020-04-05 16:23:07 -07:00
Wayne Davison
daf8f7a669 Some configure improvements for strict C99 compilers (based on a patch by Florian Weimer). 2020-04-05 16:19:54 -07:00
Wayne Davison
15fa9ab06d Add progress output via SIGINFO and SIGVTALRM
On BSD-ish systems you can type Ctrl+T to see the current file and
the progress output (in --info=progress2 format).  On hosts w/o
SIGINFO, use something like "killall -VTALRM rsync" or a more
targetted "kill -VTALRM PID ..." call (as needed).
2020-04-05 15:07:31 -07:00
Wayne Davison
7e70e4842b No need to forward --write-devices to a remote sender. 2020-04-05 12:01:48 -07:00
Wayne Davison
9e9d33a2db Added the --write-devices option.
This is a fleshed out version of the old one in the patches repo with
documentation & proper handling of the implied --inplace option for a
daemon's option-rufusing considerations. I ommitted the -w short option
as I would hate for someone to turn this on accidentally.
2020-04-05 11:56:28 -07:00
Wayne Davison
b32aa4797d Make exit_cleanup() use _exit() if called from a signal handler.
Fixes bug #13982.
2020-04-05 10:26:40 -07:00
Wayne Davison
826ddc5403 Enhance the validation of --block-size for older protocols.
Fixes bug #13974.
2020-04-05 10:05:25 -07:00
Wayne Davison
3bd4e1e8cd Make the --copy-links caveat a little clearer. 2020-04-05 09:43:59 -07:00
Wayne Davison
51e23e0ab7 Use nanosleep if it is available.
Fixes bug #14328.
2020-04-05 09:22:00 -07:00
Wayne Davison
08650cb14c Add a --copy-as=USER[:GROUP] option
This can be used by a root-run rsync to try to make reading or writing
files safer in a situation where you can't run the whole rsync command
as a non-root user.
2020-03-29 13:18:20 -07:00
Wayne Davison
24c28cd715 Match the latest git "clean" text. 2019-03-19 09:35:59 -07:00
Wayne Davison
c0c6a97c35 Try to fix the iconv crash in bug 11338.
Applying Michal Ruprich's suggested patch for the rwrite() function that
should hopefully help with a bug that I couldn't reproduce.
2019-03-16 11:51:49 -07:00
Wayne Davison
d47d379216 Fix bug in try_dests_reg that Florian Zumbiehl pointed out.
If the alternate-destination code was scanning multiple alt dirs and it
found the right size/mtime/checksum info but not the right xattrs, it
would keep scanning the other dirs for a better xattr match, but it
would omit the unchanged-file check that needs to happen first.
2019-03-16 11:12:53 -07:00
Wayne Davison
eb1b138ec2 Clarify the cut-off point for --copy-safe-links. 2019-03-16 10:55:50 -07:00
Wayne Davison
13f596433b Some doc tweaks suggested by Clément Pit-Claudel. 2019-03-16 10:10:14 -07:00
Wayne Davison
3fe4469bfa Fix zlib CVE-2016-9843. 2019-03-16 09:56:11 -07:00
Wayne Davison
8eb50bce43 Fix zlib CVE-2016-9842. 2019-03-16 09:56:11 -07:00
Wayne Davison
fc10fafa25 Fix zlib CVE-2016-9841. 2019-03-16 09:56:11 -07:00
Wayne Davison
efcbec3df5 Fix zlib CVE-2016-9840. 2019-03-16 09:56:11 -07:00
Wayne Davison
3e2e4b5a33 Tweak the copyright year. 2019-03-16 09:15:49 -07:00
Wayne Davison
79332c0d66 Fix --remove-source-files sanity check w/--copy-links the right way.
Fixes bug #10494.
2019-03-16 09:09:09 -07:00
Wayne Davison
bdfc296faf Handle a run from down inside the checkout tree. 2019-03-15 12:20:55 -07:00
Wayne Davison
2ad1c4e800 Improve write-only --sender check & handle 2 new options. 2019-01-15 11:18:36 -08:00
Wayne Davison
0da7ba57b5 Update option culling to handle latest changes. 2019-01-15 11:16:50 -08:00
Wayne Davison
b3d12c5a3d Use a separate pass-by-value pointer for clarity. 2019-01-15 10:46:29 -08:00
Wayne Davison
bc7402aa3a Avoid warning about leaked mem (didn't affect rsync's pool use). 2019-01-15 10:46:29 -08:00
Wayne Davison
f233dffbd6 Avoid leaving a file open on error return. 2019-01-15 10:38:00 -08:00
Wayne Davison
c2da3809f7 Fix --prealloc to keep file-size 0 when possible. 2019-01-15 08:59:35 -08:00
Wayne Davison
48346c878f Reject --log-file when read-only. 2019-01-09 13:35:21 -08:00
Wayne Davison
a0274c08b5 Improve check for ".." and guard against dash args. 2019-01-09 13:35:21 -08:00
Wayne Davison
f627e27749 Save each expanded daemon-config string on first use to
avoid a new alloc on every use (one that was not freed).
2019-01-09 13:35:21 -08:00
Wayne Davison
0b6cae6792 No need to strdup each new section since we stopped using free(). 2019-01-08 20:30:58 -08:00
Wayne Davison
e5610f1877 Avoid a yodl macro warning. 2019-01-08 16:39:48 -08:00
Wayne Davison
c376170644 Make sure that some memory zeroing always happens. 2019-01-08 14:46:41 -08:00
Wayne Davison
48163179eb Avoid a yodl macro warning. 2019-01-08 13:38:19 -08:00
Wayne Davison
b4c1b27e03 Fix 2 spelling errors pointed out by bug 13734. 2019-01-08 13:34:32 -08:00
Wayne Davison
c90b87e021 Avoid a failed test if dirs report 1 hlink (e.g. WSL weirdness). 2019-01-04 21:43:50 -08:00
Wayne Davison
ad17b21889 Silence fall-through warnings. 2019-01-04 15:06:30 -08:00
Wayne Davison
a366868535 Avoid a potential out-of-bounds read in daemon mode if argc is 0. 2018-12-15 16:59:18 -08:00
Wayne Davison
f55d35c5a0 Try to be clearer that --append-verify isn't a general-purpose-copy option. 2018-11-20 14:17:32 -08:00
Wayne Davison
6af8e11450 Don't force cygwin to solaris ACLs anymore. 2018-11-20 14:11:42 -08:00
Wayne Davison
1a288c06d9 Document how a leading comma changes the gid parsing. 2018-11-20 13:44:09 -08:00
Wayne Davison
4aeb093206 Fix itemizing of wrong dir name on some --iconv transfers.
Fixes bug #13492.
2018-11-20 13:21:32 -08:00
Wayne Davison
1eb7a7061a Need to mark xattr rules in get_rule_prefix().
This fixes the bug of xattr filters getting sent as a normal filter rule
(since the 'x' was dropped in the prefix).
2018-06-14 15:22:53 -07:00
Wayne Davison
eec6ab7615 Avoid a compiler error/warning about shifting a negative value.
Fixes bug #13268.
2018-03-25 19:11:41 -07:00
Wayne Davison
5df9847f06 Allow some pre-/post-xfer exec shell restrictions.
Support both RSYNC_SHELL & RSYNC_NO_XFER_EXEC environment variables.
2018-03-25 11:02:50 -07:00
Wayne Davison
fb7a162f53 Prepare the repository for more development. 2018-03-25 10:04:29 -07:00
Wayne Davison
d73762eea3 Preparing for release of 3.1.3 2018-01-28 15:24:27 -08:00
Wayne Davison
d58405a353 Mention nanoseconds change. 2018-01-15 11:25:04 -08:00
Wayne Davison
0f8e9e2d86 Don't force nanoseconds if a file wasn't transferred or checksummed. 2018-01-15 10:58:31 -08:00
Wayne Davison
c4a3f55be3 Preparing for release of 3.1.3pre1 2018-01-14 21:34:42 -08:00
Wayne Davison
473108ae6e Tweak copyright date. 2018-01-14 19:55:07 -08:00
Wayne Davison
e401959b89 Mention more changes. 2018-01-14 19:51:25 -08:00
Jeriko One
7706303828 Ignore --protect-args when already sent by client
In parse_arguments when --protect-args is encountered the function exits
early. The caller is expected to check protect_args, and recall
parse_arguments setting protect_args to 2. This patch prevents the
client from resetting protect_args during the second pass of
parse_arguments. This prevents parse_arguments returning early the
second time before it's able to sanitize the arguments it received.
2018-01-09 17:51:30 -08:00
Wayne Davison
f5e8a17e09 Fix issue with earlier path-check (fixes "make check")
and make a BOOL more explicit.
2017-12-03 16:27:11 -08:00
Jeriko One
5509597dec Check daemon filter against fnamecmp in recv_files(). 2017-12-03 16:13:06 -08:00
Jeriko One
70aeb5fddd Sanitize xname in read_ndx_and_attrs. 2017-12-03 16:13:05 -08:00
Jeriko One
3e06d40029 Check fname in recv_files sooner. 2017-12-03 16:12:28 -08:00
Wayne Davison
416e719bea More archaic-checksum improvements. This makes the len vars clearer
and ensures that only the flist code gets the 2-byte digest len.
2017-11-07 14:01:13 -08:00
Wayne Davison
9f5dc9309d Use the right sum len. 2017-11-07 13:32:10 -08:00
Wayne Davison
b984e9dbd4 Replace startdit|enddit with description for newer yodl.
Fixes bug 13115.
2017-11-05 12:29:14 -08:00
Wayne Davison
c60d9fcab1 Add missing closing paren that Paul Slootman pointed out. 2017-11-05 11:56:52 -08:00
Wayne Davison
47a63d90e7 Enforce trailing \0 when receiving xattr name values.
Fixes bug 13112.
2017-11-05 11:46:09 -08:00
Wayne Davison
bc112b0e7f Use full MD4 len for archaic protocol auth. 2017-10-30 13:34:18 -07:00
Wayne Davison
8a82feeb7c Don't overflow an allocated dest buf when input path is empty.
Fixes bug 13105.
2017-10-29 15:53:28 -07:00
Wayne Davison
0350f95e7b Add an extra argc validation in do_server_sender().
Fixes bug 13104.
2017-10-29 15:52:56 -07:00
Wayne Davison
9a480deec4 Only allow a modern checksum method for passwords. 2017-10-24 20:44:37 -07:00
Wayne Davison
c252546cee Don't forget to tweak sum_update(). 2017-10-24 20:44:20 -07:00
Wayne Davison
7b8a4ecd6f Handle archaic checksums properly. 2017-10-24 15:42:43 -07:00
Wayne Davison
17b849c97a Set our_uid & our_gid values when changed by the daemon.
Fixes bug 10719.
2017-10-09 17:13:00 -07:00
Wayne Davison
276a9836bd Mention --link-dest limit. 2017-10-08 09:30:18 -07:00
Wayne Davison
c140b2e749 Mention refusing delete for write-only. 2017-10-08 09:18:10 -07:00
Wayne Davison
b547302943 Mention -O is forced, not just implied. 2017-10-08 08:52:33 -07:00
Wayne Davison
136c6c7734 Fix double-fuzzy + link-dest issue.
Fixes bug 11866.
2017-10-08 08:39:37 -07:00
Wayne Davison
3fb1634f21 Fix possible buffer overrun for some large name_len values.
Fixes bug 12568.
2017-10-07 17:54:05 -07:00
Wayne Davison
881addc9e1 Add "daemon chroot|uid|gid" parameters.
This allows the daemon to run chrooted as any uid+gid you like
(prior to the transfer possibly changing the chroot and/or the
uid+gid further). Based on the patch in #12817.
2017-09-04 14:20:16 -07:00
Wayne Davison
b7799aaefe Add nanosecond mtime support for Mac OS X.
Slightly tweaked the patch contributed by Heikki Lindholm.
2017-08-31 08:22:14 -07:00
Wayne Davison
ce854cf021 Add "syslog tag" to rsync daemon config. 2017-04-29 13:49:14 -07:00
Wayne Davison
9e7b8ab7cf Don't allow --daemon or --server alias via popt.
Fixes bug 12576.
2017-02-20 11:09:16 -08:00
Wayne Davison
87bc224011 Add a way to specify xattr name filtering. 2017-01-22 16:01:45 -08:00
Wayne Davison
a4e8b552d6 Join some lines. 2017-01-22 15:55:54 -08:00
Wayne Davison
62652202c4 Get rid of some superfluous double-quotes in error messages. 2017-01-22 15:42:36 -08:00
Wayne Davison
001adf5096 Fix extern of preallocated_len w/o SUPPORT_PREALLOCATION. 2016-10-31 09:06:50 -07:00
Wayne Davison
ff66fd4bb6 More fixes for --progress quirks.
This patch avoids inconsistent evaluation of options in the
show_filelist_p() function by turning it into a var.  We
also avoid setting "output_needs_newline" if --quiet was
specified.
2016-10-29 15:26:10 -07:00
Wayne Davison
e02b89d0d3 We need a LF after filelist-progress with a CR.
Fixes bug 12367.
2016-10-29 14:33:44 -07:00
Wayne Davison
d1a1fec134 Use S_BLKSIZE when multiplying st_blocks. 2016-10-15 11:33:07 -07:00
Wayne Davison
f3873b3d88 Support --sparse combined with --preallocate or --inplace.
The new code tries to punch holes in the destination file using newer
Linux fallocate features. It also supports a --whole-file + --sparse +
--inplace copy on any filesystem by truncating the destination file.
2016-10-10 11:53:03 -07:00
Stefan Metzmacher
6e3b2102bc xattrs: maintain a hashtable in order to speed up find_matching_xattr()
As a testcase I've used one directory on gpfs with 1000000 files,
each with an xattr called 'name$i' having a value of 'value$i'.
So we also have 1000000 unique xattrs. The source and dest directories
are already in sync before. So the rsync command is basically a noop,
just verifying that everything is already in sync.

The results before this patchset are:

  [gpfs]# time rsync -a -P -X -q source-xattr/ dest-with-xattr/

  real    8m46.191s
  user    6m29.016s
  sys     0m24.883s

  [gpfs]# time rsync -a -P -q source-xattr/ dest-without-xattr/

  real    1m58.462s
  user    0m0.957s
  sys     0m11.801s

With the patchset I got:

  [gpfs]# time /gpfs/rsync.install/bin/rsync -a -P -X -q source-xattr/ dest-with-xattr/

  real    2m4.150s
  user    0m1.917s
  sys     0m17.077s

  [gpfs]# time /gpfs/rsync.install/bin/rsync -a -P -q source-xattr/ dest-without-xattr/
  real    1m59.534s
  user    0m0.924s
  sys     0m11.599s

It means the time in userspace dropped from 6m29.016s down to 0m1.917s!
Without -X we get ~ 0m0.9s with or without the patch.

Part of a patchset for bug 5324.
2016-08-14 14:37:49 -07:00
Stefan Metzmacher
cc29b94d0f hashtable: add hashlittle() from lookup3.c, by Bob Jenkins
Part of a patchset for bug 5324.
2016-08-14 14:20:19 -07:00
Stefan Metzmacher
6eb71beaff xattrs: introduce a rsync_xa_list struct as layer between two nested item_lists
We have the global 'item_list rsync_xal_l', this maintains an array
of rsync_xa_list structure, one per file.

Each rsync_xa_list structure maintains an array of rsync_xa structure,
while each represent a single xattr with name and value.

Part of a patchset for bug 5324.
2016-08-14 14:20:16 -07:00
Stefan Metzmacher
39d7e3ec25 xattrs: let rsync_xal_store() return ndx.
Part of a patchset for bug 5324.
2016-08-14 13:54:34 -07:00
Stefan Metzmacher
ac97bc14f6 xattrs: add const to empty_xattr
Part of a patchset for bug 5324.
2016-08-14 13:54:34 -07:00
Greg Whiteley
31e93c3228 Makefile: rounding.h generation requires proto.h via rsync.h
Bug 12029 - Makefile missing dep gives parallel race for rounding.h

Signed-off-by: Greg Whiteley <greg.whiteley@gmail.com>
2016-07-20 08:34:26 -07:00
Wayne Davison
a720d81d0a Fix "could not find xattr #1" errors.
The abbreviated-xattr code can get requests that are not in the same
order as the xattr list, so we need to support wrap-around scanning
of the available xattrs. Fixes bug 6590.
2016-06-26 12:06:09 -07:00
Wayne Davison
359758d611 Fix path check when prior_dir_file is NULL. 2016-06-04 11:53:33 -07:00
Wayne Davison
1f83b51d71 Improve the top-level section on include/exclude traversal.
This is my edit of some suggestions by Karl O. Pinc.
2016-05-07 15:55:26 -07:00
Wayne Davison
a5a7d3a297 Add --checksum-choice option to choose the checksum algorithms. 2016-05-01 17:06:54 -07:00
Wayne Davison
4fc78878e0 Tweak indentation only. 2016-05-01 16:29:34 -07:00
Wayne Davison
b973bffa94 If a backup fails (e.g. full disk) rsync should fail.
Fixes bug 11668.
2016-04-17 16:31:57 -07:00
Wayne Davison
d1c80404fe Output "UNKNOWN" if starttime or endtime is -1.
Fixes bug 11382.
2016-04-17 16:11:04 -07:00
Wayne Davison
9a12959ab6 Support only splitting users/groups on commas.
Fixes bug 11817.
2016-04-17 15:56:11 -07:00
Wayne Davison
070c810e2d Tweak non-fatal output when man pages cannot be created. 2016-04-17 11:43:46 -07:00
Wayne Davison
71ec4609eb Fix use of obsolete compile macro.
Fixes bug 11813.
2016-04-17 11:20:38 -07:00
Wayne Davison
0f7db203fb Only output about new backup dirs when requested.
Fixes bug 11812.
2016-04-17 11:06:58 -07:00
Wayne Davison
4e25abc9a9 Fix/improve the sort functions.
Fixes bug 11704.
2016-01-31 14:40:51 -08:00
Wayne Davison
839dbff2aa Add support for comparing nanoseconds on the receiver.
This patch adds the ability to specify --modify-window=-1 (aka -@-1) to
ask rsync to compare files with the full nanosecond timestamps.  The
default is still -@0 for the moment, which ignores nanoseconds in time
comparisons.  Changing the default to -1 would cause a copy from ext4 to
ext3 to constantly compare as different, or a copy there and back again
to do a full copy as it zeroed all the nanosecond times.  Such a change
might be too much of a functional difference for things like backup
solutions to handle without a warning period.  The current plan is to
support nanosecond comparisons for those that want them, and possibly
change the default window value from 0 to -1 at some point in the
future.
2016-01-24 11:16:10 -08:00
Wayne Davison
f6f5ea4173 Prepare the repository for more development. 2016-01-24 11:12:32 -08:00
Wayne Davison
9a37d9cb1e Fix a tweak that should have been untweaked. 2015-12-24 13:09:47 -08:00
Wayne Davison
16b49716d5 Preparing for release of 3.1.2 2015-12-21 12:00:49 -08:00
Wayne Davison
58faa1e8b9 Improve the "use chroot" & "numeric ids" info a bit more. 2015-12-21 11:56:33 -08:00
Wayne Davison
9250e9ac23 Improve the comment a bit more. 2015-12-21 10:54:02 -08:00
Wayne Davison
3623d94fe7 Fix rule for out-of-tree builds.
Fixes bug 11635.
2015-12-18 16:09:58 -08:00
Wayne Davison
cbc42b9c16 Don't allow an empty flag name to --info & --debug. 2015-12-18 14:46:28 -08:00
Wayne Davison
6ff5824c25 Document expand_item_list's args & make sure incr==0 works OK. 2015-12-18 14:41:22 -08:00
Wayne Davison
32de6b7cb4 Fix return of stat info from try_dests_reg().
The try_dests_reg() function could sometimes tweak the stat struct's
info when it should have been left unchanged.  This fixes bug 11545
(where an ACL check of a file that was mistakenly thought to be a
directory failed).
2015-12-05 11:10:24 -08:00
Wayne Davison
bb853b3205 Add -wo option for write-only rrsync mode. 2015-09-13 16:23:54 -07:00
Wayne Davison
cce44865c1 Fixed logging of %b & %c when using --log-file.
The %b and %c escapes were outputting cumulative values when logged via
--log-file only (the bug didn't affect daemon transfer logging or the
output of the client's --out-format info).  Also unified the %b & %c
switch case to make it easier to maintain.  Fixes bug 11496.
2015-09-07 10:07:17 -07:00
Wayne Davison
1983198097 Add support for netbsd in xattrs case.
Closes bug-suggestion 11484.
2015-09-02 12:20:52 -07:00
Wayne Davison
2a7355fb56 Change daemon's gid list to use an "item_list". 2015-08-24 11:54:00 -07:00
Wayne Davison
3da1dc4d18 Add configure option to set max daemon gid list.
Fixes bug 11456.
2015-08-24 10:09:57 -07:00
Wayne Davison
abfb41e63e Avoid creating even the top-level backup dir until needed.
Fixes bug 11423.
2015-08-23 21:58:18 -07:00
Wayne Davison
9d1cd2437c Improve make_path() error return for non-dir element. 2015-08-23 21:55:16 -07:00
Wayne Davison
f8d2ecd223 Preparing for release of 3.1.2pre1 2015-08-08 12:47:35 -07:00
Wayne Davison
453914e35b Update the copyright year. 2015-08-08 12:47:03 -07:00
Wayne Davison
3f26e38f86 Mention latest fixes. 2015-08-08 12:42:13 -07:00
Wayne Davison
81d1ca0683 Don't create so many empty backup dirs.
Fixes bug 10724.
2015-08-08 12:19:42 -07:00
Wayne Davison
289ccbd02f Allow samba.org hostname to be overridden. 2015-08-02 11:15:17 -07:00
Wayne Davison
85d3877be9 Improve mergedir filter handling internals.
Fixes bug 10995.
2015-07-13 10:56:13 -07:00
Wayne Davison
e203245d76 Make sure chk subdir can't diverge in time from its src subdir. 2015-07-12 14:00:45 -07:00
Wayne Davison
dfbcc4f7ec Avoid --remove-sent-file issue for non-regular files. 2015-07-12 13:26:01 -07:00
Wayne Davison
0bcb8b639a Mention local-only effect of --msgs2stderr. 2015-07-12 13:10:05 -07:00
Wayne Davison
77f750f167 Mention how we handle a module named "global". 2015-07-12 10:38:32 -07:00
Wayne Davison
23afe20780 Brant Gurganus's autoconf updates.
This improves some obsolete autoconf macros and increases the minimum
autoconf version from 2.60 to 2.69.  Fixes bug 11369.
2015-07-07 10:37:12 -07:00
Wayne Davison
e12a6c087c Add parent-dir validation for --no-inc-recurse too. 2015-07-04 16:25:23 -07:00
Wayne Davison
6feb7d37df Change "fail" to "test_fail".
Fixes bug 11322.
2015-06-10 15:20:01 -07:00
Wayne Davison
81ff413bb0 Make the checksum_seed a bit harder to predict. 2015-05-11 14:32:45 -07:00
Wayne Davison
eac858085e Add compat flag to allow proper seed checksum order.
Fixes the equivalent of librsync's CVE-2014-8242 issue.
2015-05-11 12:36:20 -07:00
Wayne Davison
2ac35b4507 Pass -I option to aclocal. 2015-05-01 15:17:41 -07:00
Tiziano Müller
3bc319766d Use AS_IF instead of plain if/then/fi 2015-05-01 14:26:21 -07:00
Tiziano Müller
a689fb1f5f Ignore .deps directories. 2015-05-01 14:26:21 -07:00
Tiziano Müller
b560a96b2c Check for perl and assign it to a var since it is needed for generating the protocol header. 2015-05-01 14:26:21 -07:00
Tiziano Müller
51e3c3da85 Remove dead targets from build system 2015-05-01 14:26:21 -07:00
Wayne Davison
461086bbe7 Handle configure's new version style. 2015-05-01 14:26:21 -07:00
Tiziano Müller
00694610a6 Specify package name and version in call to AC_INIT 2015-05-01 14:26:21 -07:00
Tiziano Müller
8e3a6db842 Properly quote arguments for AC_LIBOBJ. 2015-05-01 14:26:21 -07:00
Wayne Davison
8354cad53e Must define LIBOBJDIR in the Makefile. 2015-05-01 14:26:05 -07:00
Tiziano Müller
317a0e8ca5 Use AC_CONFIG_LIBOBJ_DIR and AC_REPLACE_FUNCS to adhere to autoconf standards 2015-04-26 17:54:08 -07:00
Tiziano Müller
066ad8c719 Modularize m4 macros
Split acinclude.m4 into one file per function in m4/
2015-04-26 17:54:06 -07:00
Tiziano Müller
ec4f644d2f Properly quote m4 macro 2015-04-26 16:50:41 -07:00
Wayne Davison
4bf342c60f Update generated-files logic. 2015-04-26 16:50:41 -07:00
Tiziano Müller
a2f733c664 Rename aclocal.m4 to acinclude.m4 and add make target
It is common practice to split up m4 files for easier maintenance and
generate the required aclocal.m4 using `aclocal` instead.
2015-04-26 16:50:16 -07:00
Stefan Behrens
3ea74eb388 rsync: fix of-by-one in check of snprintf() result.
Fixes bug 11229.
2015-04-22 10:31:04 -07:00
Wayne Davison
962f8b9004 Complain if an inc-recursive path is not right for its dir.
This ensures that a malicious sender can't use a just-sent
symlink as a trasnfer path.
2014-12-31 13:48:42 -08:00
Wayne Davison
ae189e18de Mention that --append can be dangerous. 2014-12-31 13:10:46 -08:00
Wayne Davison
5b34561cf7 Call set_modtime even if only NSEC is different. 2014-12-31 13:10:37 -08:00
Wayne Davison
5546dab329 Use usleep() for msleep() if it is available. 2014-11-27 12:02:56 -08:00
Wayne Davison
6128f56694 Add a missing closing paren. 2014-10-10 14:15:11 -07:00
Wayne Davison
743f5a30d5 Prepare the repository for more development. 2014-09-06 11:00:52 -07:00
Wayne Davison
a955e93316 Mention DRY RUN in --debug=exit output. 2014-09-06 10:47:13 -07:00
Wayne Davison
aca7dd3bff Adding the long options that BackupPC likes to use. 2014-09-04 13:44:50 -07:00
Wayne Davison
bc55aa04df Set GIT_MERGE_AUTOEDIT=no in the environment. 2014-07-31 15:59:32 -07:00
Wayne Davison
f438d5abe0 Match latest git's repo branch message. 2014-07-31 14:52:30 -07:00
Wayne Davison
6fe798392b Match latest git's repo status messages. 2014-07-31 14:47:09 -07:00
Wayne Davison
6ceb9ea012 Remove superfluous ${INSTALL_STRIP} uses. 2014-07-31 14:39:09 -07:00
Wayne Davison
6900d35cce Fix a typo. 2014-07-31 14:38:16 -07:00
Wayne Davison
7cb0de6326 Preparing for release of 3.1.1 2014-06-22 09:50:03 -07:00
Wayne Davison
61e74afc42 Add a clarification about shell wildcard expansion. 2014-06-22 09:41:17 -07:00
Wayne Davison
0466e46b9f Make sure the link() destination file doesn't exist. 2014-06-22 09:04:24 -07:00
Wayne Davison
aa4c6db043 Make sure cmp_time() doesn't mess up due to a time_t overflow.
Fixes bug 10643.
2014-06-15 17:53:34 -07:00
Wayne Davison
edb0d9c792 Updated NEWS & tweaked a comment. 2014-06-14 09:55:37 -07:00
Wayne Davison
6ffd8f2169 Put zlib and popt -I options early in the CFLAGS. 2014-06-14 09:48:56 -07:00
Wayne Davison
ba43e88527 Fix hard-link bugs when receiver isn't capable.
If the receiving side cannot hard-link symlinks and/or special files
(including devices) then we now properly handle incoming hard-linked
items (creating separate identical items).
2014-06-13 16:05:08 -07:00
Wayne Davison
ff08acd4f2 Added a flag to disable xattr hlink optimization.
I added a compatibility flag for protocol 31 that will let both sides
know if they should be using the xattr optimization that attempted to
avoid sending xattr info for hardlinked files.  Since this optimization
was causing some issues, this compatibility flag will ensure that both
sides know if they should be trying to use the optimization or not.
2014-06-08 10:42:14 -07:00
Wayne Davison
03bb593f81 I missed this tweak in the undo of a prior xattr optimization. 2014-06-08 10:21:27 -07:00
244 changed files with 36110 additions and 19666 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto eol=lf

56
.github/workflows/cygwin-build.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: Test rsync on Cygwin
on:
push:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/cygwin-build.yml'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/cygwin-build.yml'
schedule:
- cron: '42 8 * * *'
jobs:
test:
runs-on: windows-2022
name: Test rsync on Cygwin
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: cygwin
run: choco install -y --no-progress cygwin cyg-get
- name: prep
run: |
cyg-get make autoconf automake gcc-core attr libattr-devel python39 python39-pip libzstd-devel liblz4-devel libssl-devel libxxhash0 libxxhash-devel
echo "C:/tools/cygwin/bin" >>$Env:GITHUB_PATH
- name: commonmark
run: bash -c 'python3 -mpip install --user commonmark'
- name: configure
run: bash -c './configure --with-rrsync'
- name: make
run: bash -c 'make'
- name: install
run: bash -c 'make install'
- name: info
run: bash -c '/usr/local/bin/rsync --version'
- name: check
run: bash -c 'RSYNC_EXPECT_SKIPPED=acls-default,acls,chown,devices,dir-sgid,open-noatime,protected-regular,simd-checksum make check'
- name: ssl file list
run: bash -c 'PATH="/usr/local/bin:$PATH" rsync-ssl --no-motd download.samba.org::rsyncftp/ || true'
- name: save artifact
uses: actions/upload-artifact@v4
with:
name: cygwin-bin
path: |
rsync.exe
rsync-ssl
rsync.1
rsync-ssl.1
rsyncd.conf.5
rrsync.1
rrsync

49
.github/workflows/freebsd-build.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Test rsync on FreeBSD
on:
push:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/freebsd-build.yml'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/freebsd-build.yml'
schedule:
- cron: '42 8 * * *'
jobs:
test:
runs-on: ubuntu-latest
name: Test rsync on FreeBSD
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Test in FreeBSD VM
id: test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
prepare: |
pkg install -y bash autotools m4 devel/xxhash zstd liblz4 python3 archivers/liblz4 git
run: |
freebsd-version
./configure --with-rrsync -disable-zstd --disable-md2man --disable-xxhash --disable-lz4
make
./rsync --version
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
uses: actions/upload-artifact@v4
with:
name: freebsd-bin
path: |
rsync
rsync-ssl
rsync.1
rsync-ssl.1
rsyncd.conf.5
rrsync.1
rrsync

58
.github/workflows/macos-build.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Test rsync on macOS
on:
push:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/macos-build.yml'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/macos-build.yml'
schedule:
- cron: '42 8 * * *'
jobs:
test:
runs-on: macos-latest
name: Test rsync on macOS
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: prep
run: |
brew install automake openssl xxhash zstd lz4
pip3 install --user --break-system-packages commonmark
echo "$(brew --prefix)/bin" >>$GITHUB_PATH
- name: configure
run: |
BREW_PREFIX=$(brew --prefix)
OPENSSL_PREFIX=$(brew --prefix openssl)
CPPFLAGS="-I${BREW_PREFIX}/include -I${OPENSSL_PREFIX}/include" \
LDFLAGS="-L${BREW_PREFIX}/lib -L${OPENSSL_PREFIX}/lib" \
./configure --with-rrsync
- name: make
run: make
- name: install
run: sudo make install
- name: info
run: rsync --version
- name: check
run: sudo RSYNC_EXPECT_SKIPPED=acls-default,chmod-temp-dir,chown-fake,devices-fake,dir-sgid,open-noatime,protected-regular,simd-checksum,xattrs-hlink,xattrs make check
- name: ssl file list
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
uses: actions/upload-artifact@v4
with:
name: macos-bin
path: |
rsync
rsync-ssl
rsync.1
rsync-ssl.1
rsyncd.conf.5
rrsync.1
rrsync

49
.github/workflows/solaris-build.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Test rsync on Solaris
on:
push:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/solaris-build.yml'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/solaris-build.yml'
schedule:
- cron: '42 8 * * *'
jobs:
test:
runs-on: ubuntu-latest
name: Test rsync on Solaris
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Test in Solaris VM
id: test
uses: vmactions/solaris-vm@v1
with:
usesh: true
prepare: |
pkg install bash automake gnu-m4 pkg://solaris/runtime/python-35 autoconf gcc git
run: |
uname -a
./configure --with-rrsync -disable-zstd --disable-md2man --disable-xxhash --disable-lz4
make
./rsync --version
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
uses: actions/upload-artifact@v4
with:
name: solaris-bin
path: |
rsync
rsync-ssl
rsync.1
rsync-ssl.1
rsyncd.conf.5
rrsync.1
rrsync

56
.github/workflows/ubuntu-build.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: Test rsync on Ubuntu
on:
push:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/ubuntu-build.yml'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/ubuntu-build.yml'
schedule:
- cron: '42 8 * * *'
jobs:
test:
runs-on: ubuntu-latest
name: Test rsync on Ubuntu
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: prep
run: |
sudo apt-get install acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm openssl
echo "/usr/local/bin" >>$GITHUB_PATH
- name: configure
run: ./configure --with-rrsync
- name: make
run: make
- name: install
run: sudo make install
- name: info
run: rsync --version
- name: check
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check
- name: check30
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check30
- name: check29
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check29
- name: ssl file list
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
uses: actions/upload-artifact@v4
with:
name: ubuntu-bin
path: |
rsync
rsync-ssl
rsync.1
rsync-ssl.1
rsyncd.conf.5
rrsync.1
rrsync

23
.gitignore vendored
View File

@@ -12,21 +12,30 @@ config.h.in
config.h.in.old
config.log
config.status
aclocal.m4
/proto.h
/proto.h-tstamp
/rsync.1
/rsyncd.conf.5
/rsync*.[15]
/rrsync
/rrsync*.1
/rsync*.html
/rrsync*.html
/help-rsync*.h
/default-cvsignore.h
/default-dont-compress.h
/daemon-parm.h
/.md2man-works
/autom4te*.cache
/confdefs.h
/conftest*
/dox
/getgroups
/gists
/gmon.out
/rsync
/rsync-ssl
/stunnel-rsync
/stunnel-rsyncd.conf
/shconfig
/git-version.h
/testdir
/tests-dont-exist
/testtmp
@@ -44,3 +53,9 @@ config.status
/testsuite/devices-fake.test
/testsuite/xattrs-hlink.test
/patches
/patches.gen
/build
/auto-build-save
.deps
/*.exe
*.dSYM/

17
COPYING
View File

@@ -1,7 +1,16 @@
REGARDING OPENSSL AND XXHASH
In addition, as a special exception, the copyright holders give
permission to dynamically link rsync with the OpenSSL and xxhash
libraries when those libraries are being distributed in compliance
with their license terms, and to distribute a dynamically linked
combination of rsync and these libraries. This is also considered
to be covered under the GPL's System Libraries exception.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +654,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +673,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.

74
INSTALL
View File

@@ -1,74 +0,0 @@
To build and install rsync:
$ ./configure
$ make
# make install
You may set the installation directory and other parameters by options
to ./configure. To see them, use:
$ ./configure --help
Configure tries to figure out if the local system uses group "nobody" or
"nogroup" by looking in the /etc/group file. (This is only used for the
default group of an rsync daemon, which attempts to run with "nobody"
user and group permissions.) You can change the default user and group
for the daemon by editing the NOBODY_USER and NOBODY_GROUP defines in
config.h, or just override them in your /etc/rsyncd.conf file.
As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
cut-down copy of a recent release is included in the rsync distribution,
and will be used if there is no popt library on your build host, or if
the --with-included-popt option is passed to ./configure.
If you configure using --enable-maintainer-mode, then rsync will try
to pop up an xterm on DISPLAY=:0 if it crashes. You might find this
useful, but it should be turned off for production builds.
MAKE COMPATIBILITY
------------------
Note that Makefile.in has a rule that uses a wildcard in a prerequisite. If
your make has a problem with this rule, you will see an error like this:
Don't know how to make ./*.c
You can change the "proto.h-tstamp" target in Makefile.in to list all the *.c
filenames explicitly in order to avoid this issue.
RPM NOTES
---------
Under packaging you will find .spec files for several distributions.
The .spec file in packaging/lsb can be used for Linux systems that
adhere to the Linux Standards Base (e.g., RedHat and others).
HP-UX NOTES
-----------
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
ANSI C. You may see this error message in config.log if ./configure
fails:
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
Install gcc or HP's "ANSI/C Compiler".
MAC OSX NOTES
-------------
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
not completely implement the "New Sockets" API.
<http://www.ipv6.org/impl/mac.html> says that Apple started to support
IPv6 in 10.2 (Jaguar). If your build fails, try again after running
configure with --disable-ipv6.
IBM AIX NOTES
-------------
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
The workaround is to append the below to config.h
#ifdef _LARGE_FILES
#undef HAVE_SECURE_MKSTEMP
#endif

247
INSTALL.md Normal file
View File

@@ -0,0 +1,247 @@
# How to build and install rsync
When building rsync, you'll want to install various libraries in order to get
all the features enabled. The configure script will alert you when the
newest libraries are missing and tell you the appropriate `--disable-LIB`
option to use if you want to just skip that feature. What follows are various
support libraries that you may want to install to build rsync with the maximum
features (the impatient can skip down to the package summary):
## The basic setup
You need to have a C compiler installed and optionally a C++ compiler in order
to try to build some hardware-accelerated checksum routines. Rsync also needs
a modern awk, which might be provided via gawk or nawk on some OSes.
## Autoconf & manpages
If you're installing from the git repo (instead of a release tar file) you'll
also need the GNU autotools (autoconf & automake) and your choice of 2 python3
markdown libraries: cmarkgfm or commonmark (needed to generate the manpages).
If your OS doesn't provide a python3-cmarkgfm or python3-commonmark package,
you can run the following to install the commonmark python library for your
build user (after installing python3's pip package):
> python3 -mpip install --user commonmark
You can test if you've got it fixed by running (from the rsync checkout):
> ./md-convert --test rsync-ssl.1.md
Alternately, you can avoid generating the manpages by fetching the very latest
versions (that match the latest git source) from the [generated-files][6] dir.
One way to do that is to run:
> ./prepare-source fetchgen
[6]: https://download.samba.org/pub/rsync/generated-files/
## ACL support
To support copying ACL file information, make sure you have an acl
development library installed. It also helps to have the helper programs
installed to manipulate ACLs and to run the rsync testsuite.
## Xattr support
To support copying xattr file information, make sure you have an attr
development library installed. It also helps to have the helper programs
installed to manipulate xattrs and to run the rsync testsuite.
## xxhash
The [xxHash library][1] provides extremely fast checksum functions that can
make the "rsync algorithm" run much more quickly, especially when matching
blocks in large files. Installing this development library adds xxhash
checksums as the default checksum algorithm. You'll need at least v0.8.0
if you want rsync to include the full range of its checksum algorithms.
[1]: https://cyan4973.github.io/xxHash/
## zstd
The [zstd library][2] compression algorithm that uses less CPU than
the default zlib algorithm at the same compression level. Note that you
need at least version 1.4, so you might need to skip the zstd compression if
you can only install a 1.3 release. Installing this development library
adds zstd compression as the default compression algorithm.
[2]: http://facebook.github.io/zstd/
## lz4
The [lz4 library][3] compression algorithm that uses very little CPU, though
it also has the smallest compression ratio of other algorithms. Installing
this development library adds lz4 compression as an available compression
algorithm.
[3]: https://lz4.github.io/lz4/
## openssl crypto
The [openssl crypto library][4] provides some hardware accelerated checksum
algorithms for MD4 and MD5. Installing this development library makes rsync
use the (potentially) faster checksum routines when computing MD4 & MD5
checksums.
[4]: https://www.openssl.org/docs/man1.0.2/man3/crypto.html
## Package summary
To help you get the libraries installed, here are some package install commands
for various OSes. The commands are split up to correspond with the above
items, but feel free to combine the package names into a single install, if you
like.
- For Debian and Ubuntu (Debian Buster users may want to briefly(?) enable
buster-backports to update zstd from 1.3 to 1.4):
> sudo apt install -y gcc g++ gawk autoconf automake python3-cmarkgfm
> sudo apt install -y acl libacl1-dev
> sudo apt install -y attr libattr1-dev
> sudo apt install -y libxxhash-dev
> sudo apt install -y libzstd-dev
> sudo apt install -y liblz4-dev
> sudo apt install -y libssl-dev
Or run support/install_deps_ubuntu.sh
- For CentOS (use EPEL for python3-pip):
> sudo yum -y install epel-release
> sudo yum -y install gcc g++ gawk autoconf automake python3-pip
> sudo yum -y install acl libacl-devel
> sudo yum -y install attr libattr-devel
> sudo yum -y install xxhash-devel
> sudo yum -y install libzstd-devel
> sudo yum -y install lz4-devel
> sudo yum -y install openssl-devel
> python3 -mpip install --user commonmark
- For Fedora 33:
> sudo dnf -y install acl libacl-devel
> sudo dnf -y install attr libattr-devel
> sudo dnf -y install xxhash-devel
> sudo dnf -y install libzstd-devel
> sudo dnf -y install lz4-devel
> sudo dnf -y install openssl-devel
- For FreeBSD (this assumes that the python3 version is 3.7):
> sudo pkg install -y autotools python3 py37-CommonMark
> sudo pkg install -y xxhash
> sudo pkg install -y zstd
> sudo pkg install -y liblz4
- For macOS:
> brew install automake
> brew install xxhash
> brew install zstd
> brew install lz4
> brew install openssl
- For Cygwin (with all cygwin programs stopped, run the appropriate setup program from a cmd shell):
> setup-x86_64 --quiet-mode -P make,gawk,autoconf,automake,gcc-core,python38,python38-pip
> setup-x86_64 --quiet-mode -P attr,libattr-devel
> setup-x86_64 --quiet-mode -P libzstd-devel
> setup-x86_64 --quiet-mode -P liblz4-devel
> setup-x86_64 --quiet-mode -P libssl-devel
Sometimes cygwin has commonmark packaged and sometimes it doesn't. Now that
its python38 has stabilized, you could install python38-commonmark. Or just
avoid the issue by running this from a bash shell as your build user:
> python3 -mpip install --user commonmark
## Build and install
After installing the various libraries, you need to configure, build, and
install the source:
> ./configure
> make
> sudo make install
The default install path is /usr/local/bin, but you can set the installation
directory and other parameters using options to ./configure. To see them, use:
> ./configure --help
Configure tries to figure out if the local system uses group "nobody" or
"nogroup" by looking in the /etc/group file. (This is only used for the
default group of an rsync daemon, which attempts to run with "nobody"
user and group permissions.) You can change the default user and group
for the daemon by editing the NOBODY_USER and NOBODY_GROUP defines in
config.h, or just override them in your /etc/rsyncd.conf file.
As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
cut-down copy of a recent release is included in the rsync distribution,
and will be used if there is no popt library on your build host, or if
the `--with-included-popt` option is passed to ./configure.
If you configure using `--enable-maintainer-mode`, then rsync will try
to pop up an xterm on DISPLAY=:0 if it crashes. You might find this
useful, but it should be turned off for production builds.
If you want to automatically use a separate "build" directory based on
the current git branch name, start with a pristine git checkout and run
"mkdir auto-build-save" before you run the first ./configure command.
That will cause a fresh build dir to spring into existence along with a
special Makefile symlink that allows you to run "make" and "./configure"
from the source dir (the "build" dir gets auto switched based on branch).
This is helpful when using the branch-from-patch and patch-update scripts
to maintain the official rsync patches. If you ever need to build from
a "detached head" git position then you'll need to manually chdir into
the build dir to run make. I also like to create 2 more symlinks in the
source dir: `ln -s build/rsync . ; ln -s build/testtmp .`
## Make compatibility
Note that Makefile.in has a rule that uses a wildcard in a prerequisite. If
your make has a problem with this rule, you will see an error like this:
Don't know how to make ./*.c
You can change the "proto.h-tstamp" target in Makefile.in to list all the \*.c
filenames explicitly in order to avoid this issue.
## RPM notes
Under packaging you will find .spec files for several distributions.
The .spec file in packaging/lsb can be used for Linux systems that
adhere to the Linux Standards Base (e.g., RedHat and others).
## HP-UX notes
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
ANSI C. You may see this error message in config.log if ./configure
fails:
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
Install gcc or HP's "ANSI/C Compiler".
## Mac OS X notes
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
not completely implement the "New Sockets" API.
[This site][5] says that Apple started to support IPv6 in 10.2 (Jaguar). If
your build fails, try again after running configure with `--disable-ipv6`.
Apple Silicon macs may install packages in a slightly different location and require flags.
CFLAGS="-I /opt/homebrew/include" LDFLAGS="-L /opt/homebrew/lib"
[5]: http://www.ipv6.org/impl/mac.html
## IBM AIX notes
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
The workaround is to append the following to config.h:
> #ifdef _LARGE_FILES
> #undef HAVE_SECURE_MKSTEMP
> #endif

View File

@@ -1,19 +1,23 @@
# Makefile for rsync. This is processed by configure to produce the final
# Makefile
# The Makefile for rsync (configure creates it from Makefile.in).
prefix=@prefix@
datarootdir=@datarootdir@
exec_prefix=@exec_prefix@
stunnel4=@STUNNEL4@
bindir=@bindir@
libdir=@libdir@/rsync
mandir=@mandir@
with_rrsync=@with_rrsync@
LIBS=@LIBS@
CC=@CC@
AWK=@AWK@
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@
EXEEXT=@EXEEXT@
LDFLAGS=@LDFLAGS@
LIBOBJDIR=lib/
INSTALLCMD=@INSTALL@
INSTALLMAN=@INSTALL@
@@ -23,33 +27,38 @@ MKDIR_P=@MKDIR_P@
VPATH=$(srcdir)
SHELL=/bin/sh
VERSION=@RSYNC_VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
GENFILES=configure.sh config.h.in proto.h proto.h-tstamp rsync.1 rsyncd.conf.5
ROLL_SIMD_x86_64=simd-checksum-x86_64.o
ROLL_ASM_x86_64=simd-checksum-avx2.o
MD5_ASM_x86_64=lib/md5-asm-x86_64.o
GENFILES=configure.sh aclocal.m4 config.h.in rsync.1 rsync.1.html \
rsync-ssl.1 rsync-ssl.1.html rsyncd.conf.5 rsyncd.conf.5.html \
@GEN_RRSYNC@
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
lib/pool_alloc.h
lib/pool_alloc.h lib/mdigest.h lib/md-defines.h
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
util.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
util1.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
OBJS3=progress.o pipe.o
usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
OBJS3=progress.o pipe.o @MD5_ASM@ @ROLL_SIMD@ @ROLL_ASM@
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
popt_OBJS= popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o popt/poptint.o
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
# Programs we must have to run the test cases
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT) \
simdtest$(EXEEXT)
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
@@ -62,29 +71,34 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: Makefile rsync$(EXEEXT) rsync-ssl stunnel-rsync stunnel-rsyncd.conf @MAKE_MAN@
# NOTE: consider running "packaging/smart-make" instead of "make" to auto-handle
# any changes to configure.sh and the main Makefile prior to a "make all".
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_RRSYNC@ @MAKE_MAN@
.PHONY: all
.PHONY: install
install: all
-${MKDIR_P} ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
-${MKDIR_P} ${DESTDIR}${mandir}/man1
-${MKDIR_P} ${DESTDIR}${mandir}/man5
if test -f rsync.1; then ${INSTALLMAN} -m 644 rsync.1 ${DESTDIR}${mandir}/man1; fi
if test -f rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
install-ssl-client: rsync-ssl stunnel-rsync
-${MKDIR_P} ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync-ssl ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 stunnel-rsync ${DESTDIR}${bindir}
-$(MKDIR_P) $(DESTDIR)$(bindir)
$(INSTALLCMD) $(INSTALL_STRIP) -m 755 rsync$(EXEEXT) $(DESTDIR)$(bindir)
$(INSTALLCMD) -m 755 $(srcdir)/rsync-ssl $(DESTDIR)$(bindir)
-$(MKDIR_P) $(DESTDIR)$(mandir)/man1
-$(MKDIR_P) $(DESTDIR)$(mandir)/man5
if test -f rsync.1; then $(INSTALLMAN) -m 644 rsync.1 $(DESTDIR)$(mandir)/man1; fi
if test -f rsync-ssl.1; then $(INSTALLMAN) -m 644 rsync-ssl.1 $(DESTDIR)$(mandir)/man1; fi
if test -f rsyncd.conf.5; then $(INSTALLMAN) -m 644 rsyncd.conf.5 $(DESTDIR)$(mandir)/man5; fi
if test "$(with_rrsync)" = yes; then \
$(INSTALLCMD) -m 755 rrsync $(DESTDIR)$(bindir); \
if test -f rrsync.1; then $(INSTALLMAN) -m 644 rrsync.1 $(DESTDIR)$(mandir)/man1; fi; \
fi
install-ssl-daemon: stunnel-rsyncd.conf
-${MKDIR_P} ${DESTDIR}/etc/stunnel
${INSTALLCMD} ${INSTALL_STRIP} -m 644 stunnel-rsyncd.conf ${DESTDIR}/etc/stunnel/rsyncd.conf
-$(MKDIR_P) $(DESTDIR)/etc/stunnel
$(INSTALLCMD) -m 644 stunnel-rsyncd.conf $(DESTDIR)/etc/stunnel/rsyncd.conf
@if ! ls /etc/rsync-ssl/certs/server.* >/dev/null 2>/dev/null; then \
echo "Note that you'll need to install the certificate used by /etc/stunnel/rsyncd.conf"; \
fi
install-all: install install-ssl-client install-ssl-daemon
install-all: install install-ssl-daemon
install-strip:
$(MAKE) INSTALL_STRIP='-s' install
@@ -92,12 +106,27 @@ install-strip:
rsync$(EXEEXT): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
rrsync: support/rrsync
cp -p $(srcdir)/support/rrsync rrsync
$(OBJS): $(HEADERS)
$(CHECK_OBJS): $(HEADERS)
tls.o xattrs.o: lib/sysxattrs.h
usage.o: version.h latest-year.h help-rsync.h help-rsyncd.h git-version.h default-cvsignore.h
loadparm.o: default-dont-compress.h daemon-parm.h
flist.o: rounding.h
rounding.h: rounding.c rsync.h
default-cvsignore.h default-dont-compress.h: rsync.1.md define-from-md.awk
$(AWK) -f $(srcdir)/define-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
help-rsync.h help-rsyncd.h: rsync.1.md help-from-md.awk
$(AWK) -f $(srcdir)/help-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
daemon-parm.h: daemon-parm.txt daemon-parm.awk
$(AWK) -f $(srcdir)/daemon-parm.awk $(srcdir)/daemon-parm.txt
rounding.h: rounding.c rsync.h proto.h
@for r in 0 1 3; do \
if $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o rounding -DEXTRA_ROUNDING=$$r -I. $(srcdir)/rounding.c >rounding.out 2>&1; then \
echo "#define EXTRA_ROUNDING $$r" >rounding.h; \
@@ -115,6 +144,21 @@ rounding.h: rounding.c rsync.h
fi
@rm -f rounding.out
git-version.h: ALWAYS_RUN
$(srcdir)/mkgitver
.PHONY: ALWAYS_RUN
ALWAYS_RUN:
simd-checksum-x86_64.o: simd-checksum-x86_64.cpp
@$(srcdir)/cmd-or-msg disable-roll-simd $(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $(srcdir)/simd-checksum-x86_64.cpp
simd-checksum-avx2.o: simd-checksum-avx2.S
@$(srcdir)/cmd-or-msg disable-roll-asm $(CC) $(CFLAGS) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/simd-checksum-avx2.S
lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.S lib/md-defines.h
@$(srcdir)/cmd-or-msg disable-md5-asm $(CC) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/lib/md5-asm-x86_64.S
tls$(EXEEXT): $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
@@ -127,21 +171,22 @@ getgroups$(EXEEXT): getgroups.o
getfsdev$(EXEEXT): getfsdev.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
TRIMSLASH_OBJ = trimslash.o syscall.o lib/compat.o lib/snprintf.o
TRIMSLASH_OBJ = trimslash.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
T_UNSAFE_OBJ = t_unsafe.o syscall.o util1.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
gen: conf proto.h man
.PHONY: conf
conf: configure.sh config.h.in
gensend: gen
rsync -aivzc $(GENFILES) samba.org:/home/ftp/pub/rsync/generated-files/
.PHONY: gen
gen: conf proto.h man git-version.h
conf:
cd $(srcdir) && $(MAKE) -f prepare-source.mak conf
aclocal.m4: $(srcdir)/m4/*.m4
aclocal -I $(srcdir)/m4
configure.sh config.h.in: configure.ac aclocal.m4
@if test -f configure.sh; then cp -p configure.sh configure.sh.old; else touch configure.sh.old; fi
@@ -160,7 +205,7 @@ configure.sh config.h.in: configure.ac aclocal.m4
else \
echo "config.h.in has CHANGED."; \
fi
@if test -f configure.sh.old -o -f config.h.in.old; then \
@if test -f configure.sh.old || test -f config.h.in.old; then \
if test "$(MAKECMDGOALS)" = reconfigure; then \
echo 'Continuing with "make reconfigure".'; \
else \
@@ -170,10 +215,15 @@ configure.sh config.h.in: configure.ac aclocal.m4
fi \
fi
.PHONY: reconfigure
reconfigure: configure.sh
./config.status --recheck
./config.status
.PHONY: restatus
restatus:
./config.status
Makefile: Makefile.in config.status configure.sh config.h.in
@if test -f Makefile; then cp -p Makefile Makefile.old; else touch Makefile.old; fi
@./config.status
@@ -189,72 +239,66 @@ Makefile: Makefile.in config.status configure.sh config.h.in
fi \
fi
rsync-ssl: $(srcdir)/rsync-ssl.in Makefile
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/rsync-ssl.in >rsync-ssl
@chmod +x rsync-ssl
stunnel-rsync: $(srcdir)/stunnel-rsync.in Makefile
sed 's;\@stunnel4\@;$(stunnel4);g' <$(srcdir)/stunnel-rsync.in >stunnel-rsync
@chmod +x stunnel-rsync
stunnel-rsyncd.conf: $(srcdir)/stunnel-rsyncd.conf.in Makefile
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/stunnel-rsyncd.conf.in >stunnel-rsyncd.conf
.PHONY: proto
proto: proto.h-tstamp
proto.h: proto.h-tstamp
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
$(AWK) -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
man: rsync.1 rsyncd.conf.5 man-copy
.PHONY: man
man: rsync.1 rsync-ssl.1 rsyncd.conf.5 @MAKE_RRSYNC_1@
man-copy:
@-if test -f rsync.1; then :; else echo 'Copying srcdir rsync.1'; cp -p $(srcdir)/rsync.1 .; fi
@-if test -f rsyncd.conf.5; then :; else echo 'Copying srcdir rsyncd.conf.5'; cp -p $(srcdir)/rsyncd.conf.5 .; fi
rsync.1: rsync.1.md md-convert version.h Makefile
@$(srcdir)/maybe-make-man rsync.1.md
rsync.1: rsync.yo
yodl2man -o rsync.1 $(srcdir)/rsync.yo
-$(srcdir)/tweak_manpage rsync.1
rsync-ssl.1: rsync-ssl.1.md md-convert version.h Makefile
@$(srcdir)/maybe-make-man rsync-ssl.1.md
rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
-$(srcdir)/tweak_manpage rsyncd.conf.5
rsyncd.conf.5: rsyncd.conf.5.md md-convert version.h Makefile
@$(srcdir)/maybe-make-man rsyncd.conf.5.md
rrsync.1: support/rrsync.1.md md-convert Makefile
@$(srcdir)/maybe-make-man support/rrsync.1.md
.PHONY: clean
clean: cleantests
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
rounding rounding.h *.old
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
*.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
.PHONY: cleantests
cleantests:
rm -rf ./testtmp*
# We try to delete built files from both the source and build
# directories, just in case somebody previously configured things in
# the source directory.
.PHONY: distclean
distclean: clean
rm -f Makefile config.h config.status
rm -f rsync-ssl stunnel-rsync stunnel-rsyncd.conf
rm -f lib/dummy popt/dummy zlib/dummy
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
rm -f $(srcdir)/lib/dummy $(srcdir)/popt/dummy $(srcdir)/zlib/dummy
rm -f config.cache config.log
rm -f $(srcdir)/config.cache $(srcdir)/config.log
rm -f shconfig $(srcdir)/shconfig
rm -f $(GENFILES)
rm -rf autom4te.cache
for dir in $(srcdir) . ; do \
(cd "$$dir" && rm -rf Makefile config.h config.status stunnel-rsyncd.conf \
lib/dummy popt/dummy zlib/dummy config.cache config.log shconfig \
$(GENFILES) autom4te.cache) ; \
done
# this target is really just for my use. It only works on a limited
# range of machines and is used to produce a list of potentially
# dead (ie. unused) functions in the code. (tridge)
.PHONY: finddead
finddead:
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
comm -13 nmused.txt nmfns.txt
@rm nmused.txt nmfns.txt
# 'check' is the GNU name, 'test' is the name for everybody else :-)
.PHONY: check test
.PHONY: test
test: check
# There seems to be no standard way to specify some variables as
@@ -267,19 +311,30 @@ test: check
# catch Bash-isms earlier even if we're running on GNU. Of course, we
# might lose in the future where POSIX diverges from old sh.
.PHONY: check
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT)
.PHONY: check29
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=29
.PHONY: check30
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=30
wildtest.o: wildtest.c lib/wildmatch.c rsync.h config.h
wildtest.o: wildtest.c t_stub.o lib/wildmatch.c rsync.h config.h
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)
simdtest$(EXEEXT): simd-checksum-x86_64.cpp $(HEADERS)
@if test x"@ROLL_SIMD@" != x; then \
$(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -DTEST_SIMD_CHECKSUM1 \
-o $@ $(srcdir)/simd-checksum-x86_64.cpp @ROLL_ASM@ $(LIBS); \
else \
touch $@; \
fi
testsuite/chown-fake.test:
ln -s chown.test $(srcdir)/testsuite/chown-fake.test
@@ -293,8 +348,9 @@ testsuite/xattrs-hlink.test:
# check a version installed from a binary or some other source tree,
# if you want.
.PHONY: installcheck
installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
$(srcdir)/runtests.py --rsync-bin="$(bindir)/rsync$(EXEEXT)" --srcdir="$(srcdir)" --tooldir=`pwd`
# TODO: Add 'dist' target; need to know which files will be included
@@ -303,21 +359,12 @@ installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
splint:
splint +unixlib +gnuextensions -weak rsync.c
rsync.dvi: doc/rsync.texinfo
texi2dvi -o $@ $<
rsync.ps: rsync.dvi
dvips -ta4 -o $@ $<
rsync.pdf: doc/rsync.texinfo
texi2dvi -o $@ --pdf $<
.PHONY: doxygen
doxygen:
cd $(srcdir) && rm dox/html/* && doxygen
# for maintainers only
.PHONY: doxygen-upload
doxygen-upload:
rsync -avzv $(srcdir)/dox/html/ --delete \
samba.org:/home/httpd/html/rsync/doxygen/head/
$${RSYNC_SAMBA_HOST-samba.org}:/home/httpd/html/rsync/doxygen/head/

105
NEWS
View File

@@ -1,105 +0,0 @@
NEWS for rsync 3.1.1 (UNRELEASED)
Protocol: 31 (unchanged)
Changes since 3.1.0:
BUG FIXES:
- If the receiver gets bogus filenames from the sender (an unexpected
leading slash or a ".." infix dir), exit with an error. This prevents a
malicious sender from trying to inject filenames that would affect an
area outside the destination directories.
- Fixed a failure to remove the partial-transfer temp file when interrupted
(and rsync is not saving the partial files).
- Changed the chown/group/xattr-set order to avoid losing some security-
related xattr info (that would get cleared by a chown).
- Fixed a bug in the xattr-finding code that could make a non-root-run
receiver not able to find some xattr numbers.
- Fixed a bug in the early daemon protocol where a timeout failed to be
honored (e.g. if the remote side fails to send us the initial protocol
greeting).
- Fixed unintended inclusion of commas in file numbers in the daemon log.
- We once again send the 'f' sub-flag (of -e) to the server side so it
knows that we can handle incremental-recursion directory errors properly
in older protocols.
- Fixed an issue with too-aggressive keep-alive messages causing a problem
for older rsync versions early in the transfer.
- Fixed an incorrect message about backup-directory-creation when using
--dry-run and the backup dir is not an absolute path.
- Fixed a bug where a failed deletion and/or a failed sender-side removal
would not affect the exit code.
- Fixed a bug that caused a failure when combining --delete-missing-args
with --xattrs and/or --acls.
- Fixed a strange dir_depth assertion error that was caused by empty-dir
removals and/or duplicate files in the transfer.
- Fixed a problem with --info=progress2's output stats where rsync would
only update the stats at the end of each file's transfer. It now uses
the data that is flowing for the current file, making the stats more
accurate and less jumpy.
- Fixed an itemize bug that affected the combo of --link-dest, -X, and -n.
- Fixed a problem with delete messages not appearing in the log file when
the user didn't use --verbose.
- Improve chunked xattr reading for OS X.
- Removed an attempted hard-link xattr optimization that was causing a
transfer failure. (If you need to interact with an rsync 3.1.0 using
--hard-links & --xattrs, you can specify --protocol=30.)
- We now generate a better error if the buffer overflows in do_mknod().
- Fixed a problem reading more than 16 ACLs on some OSes.
- Fixed the reading of the secrets file to avoid an infinite wait when
the username is missing.
- Fixed a parsing problem in the --usermap/--groupmap options when using
MIN-MAX numbers.
- Switched Cygwin back to using socketpair "pipes" to try to speed it up.
- Added knowledge of a few new options to rrsync.
ENHANCEMENTS:
- Tweaked the temp-file naming when --temp-dir=DIR is used: the temp-file
names will not get a '.' prepended.
- Added support for a new-compression idiom that does not compress all the
matching data in a transfer. This can help rsync to use less cpu when a
transfer has a lot of matching data, and also makes rsync compatible with
a non-bundled zlib. See the --new-compress and --old-compress options in
the manpage.
- Added the support/rsync-no-vanished wrapper script.
- Made configure more prominently mention when we failed to find yodl (in
case the user wants to be able to generate manpages from *.yo files).
- Have manpage mention how a daemon's max-verbosity setting affects info
and debug options. Also added more clarification on backslash removals
for excludes that contain wildcards.
- Have configure check if for the attr lib (for getxattr) for those systems
that need to link against it explicitly.
- Change the early dir-creation logic to only use that idiom in an
inc-recursive copy that is preserving directory times. e.g. using
--omit-dir-times will avoid these early directories being created.
DEVELOPER RELATED:
- We now include an example systemd file (in packaging/systemd).

5062
NEWS.md Normal file
View File

File diff suppressed because it is too large Load Diff

3599
OLDNEWS
View File

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,18 @@ options. To get a complete list of supported options type:
rsync --help
See the manpage for more detailed information.
See the [manpage][0] for more detailed information.
[0]: https://download.samba.org/pub/rsync/rsync.1
BUILDING AND INSTALLING
-----------------------
If you need to build rsync yourself, check out the [INSTALL][1] page for
information on what libraries and packages you can use to get the maximum
features in your build.
[1]: https://github.com/RsyncProject/rsync/blob/master/INSTALL.md
SETUP
-----
@@ -55,17 +65,17 @@ RSYNC DAEMONS
-------------
Rsync can also talk to "rsync daemons" which can provide anonymous or
authenticated rsync. See the rsyncd.conf(5) man page for details on how
to setup an rsync daemon. See the rsync(1) man page for info on how to
authenticated rsync. See the rsyncd.conf(5) manpage for details on how
to setup an rsync daemon. See the rsync(1) manpage for info on how to
connect to an rsync daemon.
WEB SITE
--------
The main rsync web site is here:
For more information, visit the [main rsync web site][2].
http://rsync.samba.org/
[2]: https://rsync.samba.org/
You'll find a FAQ list, downloads, resources, HTML versions of the
manpages, etc.
@@ -77,64 +87,58 @@ MAILING LISTS
There is a mailing list for the discussion of rsync and its applications
that is open to anyone to join. New releases are announced on this
list, and there is also an announcement-only mailing list for those that
want official announcements. See the mailing-list page for full
details:
want official announcements. See the [mailing-list page][3] for full
details.
http://rsync.samba.org/lists.html
[3]: https://rsync.samba.org/lists.html
BUG REPORTS
-----------
To visit this web page for full the details on bug reporting:
The [bug-tracking web page][4] has full details on bug reporting.
http://rsync.samba.org/bugzilla.html
[4]: https://rsync.samba.org/bug-tracking.html
That page contains links to the current bug list, and information on how
to report a bug well. You might also like to try searching the Internet
for the error message you've received, or looking in the mailing list
archives at:
That page contains links to the current bug list, and information on how to
do a good job when reporting a bug. You might also like to try searching
the Internet for the error message you've received, or looking in the
[mailing list archives][5].
http://mail-archive.com/rsync@lists.samba.org/
[5]: https://mail-archive.com/rsync@lists.samba.org/
To send a bug report, follow the instructions on the bug-tracking
page of the web site.
Alternately, email your bug report to rsync@lists.samba.org .
Alternately, email your bug report to <rsync@lists.samba.org>.
For security issues please email details of the issue to <rsync.project@gmail.com>.
GIT REPOSITORY
--------------
If you want to get the very latest version of rsync direct from the
source code repository then you can use git:
source code repository, then you will need to use git. The git repo
is hosted [on GitHub][6] and [on Samba's site][7].
git clone git://git.samba.org/rsync.git
[6]: https://github.com/RsyncProject/rsync
[7]: https://git.samba.org/?p=rsync.git;a=summary
See the download page for full details on all the ways to grab the
source, including nightly tar files, web-browsing of the git repository,
etc.:
See [the download page][8] for full details on all the ways to grab the
source.
http://rsync.samba.org/download.html
[8]: https://rsync.samba.org/download.html
COPYRIGHT
---------
Rsync was originally written by Andrew Tridgell and is currently
maintained by Wayne Davison. It has been improved by many developers
from around the world.
Rsync was originally written by Andrew Tridgell and Paul Mackerras. Many
people from around the world have helped to maintain and improve it.
Rsync may be used, modified and redistributed only under the terms of
the GNU General Public License, found in the file COPYING in this
distribution, or at:
the GNU General Public License, found in the file [COPYING][9] in this
distribution, or at [the Free Software Foundation][10].
http://www.fsf.org/licenses/gpl.html
AVAILABILITY
------------
The main web site for rsync is http://rsync.samba.org/
The main ftp site is ftp://rsync.samba.org/pub/rsync/
This is also available as rsync://rsync.samba.org/rsyncftp/
[9]: https://github.com/RsyncProject/rsync/blob/master/COPYING
[10]: https://www.fsf.org/licenses/gpl.html

13
SECURITY.md Normal file
View File

@@ -0,0 +1,13 @@
# Security Policy
## Supported Versions
Only the current release of the software is actively supported. If you need
help backporting fixes into an older release, feel free to ask.
## Reporting a Vulnerability
Email your vulnerability information to rsync's maintainer:
Rsync Project <rsync.project@gmail.com>

16
TODO
View File

@@ -49,7 +49,7 @@ Create test makefile target for some tests
RELATED PROJECTS -----------------------------------------------------
rsyncsh
http://rsync.samba.org/rsync-and-debian/
https://rsync.samba.org/rsync-and-debian/
rsyncable gzip patch
rsyncsplit as alternative to real integration with gzip?
reverse rsync over HTTP Range
@@ -66,8 +66,8 @@ Use chroot only if supported
If running as non-root, then don't fail, just give a warning.
(There was a thread about this a while ago?)
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
https://lists.samba.org/pipermail/rsync/2001-August/thread.html
https://lists.samba.org/pipermail/rsync/2001-September/thread.html
-- --
@@ -94,7 +94,7 @@ Handling IPv6 on old machines
platforms that have a half-working implementation, so redefining
these functions clashes with system headers, and leaving them out
breaks. This affects at least OSF/1, RedHat 5, and Cobalt, which
are moderately improtant.
are moderately important.
Perhaps the simplest solution would be to have two different files
implementing the same interface, and choose either the new or the
@@ -204,7 +204,7 @@ Create more granular verbosity 2003/05/15
fine grained selection of statistical reporting and what
actions are logged.
http://lists.samba.org/archive/rsync/2003-May/006059.html
https://lists.samba.org/archive/rsync/2003-May/006059.html
-- --
@@ -236,7 +236,7 @@ Memory accounting
At exit, show how much memory was used for the file list, etc.
Also we do a wierd exponential-growth allocation in flist.c. I'm
We also do a weird exponential-growth allocation in flist.c. I'm
not sure this makes sense with modern mallocs. At any rate it will
make us allocate a huge amount of memory for large file lists.
@@ -287,7 +287,7 @@ Perhaps flush stdout like syslog
Perhaps flush stdout after each filename, so that people trying to
monitor progress in a log file can do so more easily. See
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
-- --
@@ -495,7 +495,7 @@ rsyncsh
-- --
http://rsync.samba.org/rsync-and-debian/
https://rsync.samba.org/rsync-and-debian/
-- --

View File

@@ -2,7 +2,7 @@
* Routines to authenticate access to a daemon (hosts allow/deny).
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2004-2014 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
@@ -19,6 +19,10 @@
*/
#include "rsync.h"
#include "ifuncs.h"
#ifdef HAVE_NETGROUP_H
#include <netgroup.h>
#endif
static int allow_forward_dns;
@@ -33,6 +37,11 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
if (!host || !*host)
return 0;
#ifdef HAVE_INNETGR
if (*tok == '@' && tok[1])
return innetgr(tok + 1, host, NULL, NULL);
#endif
/* First check if the reverse-DNS-determined hostname matches. */
if (iwildmatch(tok, host))
return 1;
@@ -52,10 +61,8 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
/* If reverse lookups are off, we'll use the conf-specified
* hostname in preference to UNDETERMINED. */
if (host == undetermined_hostname) {
if (!(*host_ptr = strdup(tok)))
*host_ptr = undetermined_hostname;
}
if (host == undetermined_hostname)
*host_ptr = strdup(tok);
return 1;
}
}
@@ -92,7 +99,7 @@ static void make_mask(char *mask, int plen, int addrlen)
return;
}
static int match_address(const char *addr, const char *tok)
static int match_address(const char *addr, char *tok)
{
char *p;
struct addrinfo hints, *resa, *rest;
@@ -158,8 +165,7 @@ static int match_address(const char *addr, const char *tok)
break;
#ifdef INET6
case PF_INET6:
{
case PF_INET6: {
struct sockaddr_in6 *sin6a, *sin6t;
sin6a = (struct sockaddr_in6 *)resa->ai_addr;
@@ -171,20 +177,19 @@ static int match_address(const char *addr, const char *tok)
addrlen = 16;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
if (sin6t->sin6_scope_id &&
sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
if (sin6t->sin6_scope_id && sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
ret = 0;
goto out;
}
#endif
break;
}
}
#endif
default:
rprintf(FLOG, "unknown family %u\n", rest->ai_family);
ret = 0;
goto out;
rprintf(FLOG, "unknown family %u\n", rest->ai_family);
ret = 0;
goto out;
}
bits = -1;
@@ -243,9 +248,6 @@ static int access_match(const char *list, const char *addr, const char **host_pt
char *tok;
char *list2 = strdup(list);
if (!list2)
out_of_memory("access_match");
strlower(list2);
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {

92
aclocal.m4 vendored
View File

@@ -1,92 +0,0 @@
dnl AC_VALIDATE_CACHE_SYSTEM_TYPE[(cmd)]
dnl if the cache file is inconsistent with the current host,
dnl target and build system types, execute CMD or print a default
dnl error message.
AC_DEFUN(AC_VALIDATE_CACHE_SYSTEM_TYPE, [
AC_REQUIRE([AC_CANONICAL_SYSTEM])
AC_MSG_CHECKING([config.cache system type])
if { test x"${ac_cv_host_system_type+set}" = x"set" &&
test x"$ac_cv_host_system_type" != x"$host"; } ||
{ test x"${ac_cv_build_system_type+set}" = x"set" &&
test x"$ac_cv_build_system_type" != x"$build"; } ||
{ test x"${ac_cv_target_system_type+set}" = x"set" &&
test x"$ac_cv_target_system_type" != x"$target"; }; then
AC_MSG_RESULT([different])
ifelse($#, 1, [$1],
[AC_MSG_ERROR(["you must remove config.cache and restart configure"])])
else
AC_MSG_RESULT([same])
fi
ac_cv_host_system_type="$host"
ac_cv_build_system_type="$build"
ac_cv_target_system_type="$target"
])
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we
dnl have to test to find something that will work.
dnl This is no good, because passing the wrong pointer on C compilers is
dnl likely to only generate a warning, not an error. We don't call this at
dnl the moment.
AC_DEFUN([TYPE_SOCKLEN_T],
[
AC_CHECK_TYPE([socklen_t], ,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([rsync_cv_socklen_t_equiv],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
rsync_cv_socklen_t_equiv=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
int getpeername (int, $arg2 *, $t *);
],[
$t len;
getpeername(0,0,&len);
],[
rsync_cv_socklen_t_equiv="$t"
break
])
done
done
if test "x$rsync_cv_socklen_t_equiv" = x; then
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
fi
])
AC_MSG_RESULT($rsync_cv_socklen_t_equiv)
AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv,
[type to use in place of socklen_t if not defined])],
[#include <sys/types.h>
#include <sys/socket.h>])
])
dnl AC_HAVE_TYPE(TYPE,INCLUDES)
AC_DEFUN([AC_HAVE_TYPE], [
AC_REQUIRE([AC_HEADER_STDC])
cv=`echo "$1" | sed 'y%./+- %__p__%'`
AC_MSG_CHECKING(for $1)
AC_CACHE_VAL([ac_cv_type_$cv],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT
$2]],
[[$1 foo;]])],
[eval "ac_cv_type_$cv=yes"],
[eval "ac_cv_type_$cv=no"]))dnl
ac_foo=`eval echo \\$ac_cv_type_$cv`
AC_MSG_RESULT($ac_foo)
if test "$ac_foo" = yes; then
ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
if false; then
AC_CHECK_TYPES($1)
fi
AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1'])
fi
])

50
acls.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2006-2014 Wayne Davison
* Copyright (C) 2006-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
@@ -28,7 +28,7 @@ extern int dry_run;
extern int am_root;
extern int read_only;
extern int list_only;
extern int orig_umask;
extern mode_t orig_umask;
extern int numeric_ids;
extern int inc_recurse;
extern int preserve_devices;
@@ -48,7 +48,7 @@ extern int preserve_specials;
/* When we send the access bits over the wire, we shift them 2 bits to the
* left and use the lower 2 bits as flags (relevant only to a name entry).
* This makes the protocol more efficient than sending a value that would
* be likely to have its hightest bits set. */
* be likely to have its highest bits set. */
#define XFLAG_NAME_FOLLOWS 0x0001u
#define XFLAG_NAME_IS_USER 0x0002u
@@ -168,8 +168,6 @@ static rsync_acl *create_racl(void)
{
rsync_acl *racl = new(rsync_acl);
if (!racl)
out_of_memory("create_racl");
*racl = empty_rsync_acl;
return racl;
@@ -332,14 +330,11 @@ static BOOL unpack_smb_acl(SMB_ACL_T sacl, rsync_acl *racl)
if (temp_ida_list.count) {
#ifdef SMB_ACL_NEED_SORT
if (temp_ida_list.count > 1) {
qsort(temp_ida_list.items, temp_ida_list.count,
sizeof (id_access), id_access_sorter);
qsort(temp_ida_list.items, temp_ida_list.count, sizeof (id_access), id_access_sorter);
}
#endif
if (!(racl->names.idas = new_array(id_access, temp_ida_list.count)))
out_of_memory("unpack_smb_acl");
memcpy(racl->names.idas, temp_ida_list.items,
temp_ida_list.count * sizeof (id_access));
racl->names.idas = new_array(id_access, temp_ida_list.count);
memcpy(racl->names.idas, temp_ida_list.items, temp_ida_list.count * sizeof (id_access));
} else
racl->names.idas = NULL;
@@ -507,9 +502,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
if (cnt) {
char *bp = buf + 4*4;
id_access *ida;
if (!(ida = racl->names.idas = new_array(id_access, cnt)))
out_of_memory("get_rsync_acl");
id_access *ida = racl->names.idas = new_array(id_access, cnt);
racl->names.count = cnt;
for ( ; cnt--; ida++, bp += 4+4) {
ida->id = IVAL(bp, 0);
@@ -526,6 +519,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
sys_acl_free_acl(sacl);
if (!ok) {
rsyserr(FERROR_XFER, errno, "get_acl: unpack_smb_acl(%s)", fname);
return -1;
}
} else if (no_acl_syscall_error(errno)) {
@@ -705,12 +699,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
uchar computed_mask_bits = 0;
int i, count = read_varint(f);
if (count) {
if (!(ent->idas = new_array(id_access, count)))
out_of_memory("recv_ida_entries");
} else
ent->idas = NULL;
ent->idas = count ? new_array(id_access, count) : NULL;
ent->count = count;
for (i = 0; i < count; i++) {
@@ -724,7 +713,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
else
id = recv_group_name(f, id, NULL);
} else if (access & NAME_IS_USER) {
if (inc_recurse && am_root && !numeric_ids)
if (inc_recurse && !numeric_ids)
id = match_uid(id);
} else {
if (inc_recurse && (!am_root || !numeric_ids))
@@ -775,6 +764,8 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode
#ifdef HAVE_OSX_ACLS
/* If we received a superfluous mask, throw it away. */
duo_item->racl.mask_obj = NO_ENTRY;
(void)mode;
(void)computed_mask_bits;
#else
if (duo_item->racl.names.count && duo_item->racl.mask_obj == NO_ENTRY) {
/* Mask must be non-empty with lists. */
@@ -825,14 +816,12 @@ void cache_tmp_acl(struct file_struct *file, stat_x *sxp)
if (prior_access_count == (size_t)-1)
prior_access_count = access_acl_list.count;
F_ACL(file) = cache_rsync_acl(sxp->acc_acl,
SMB_ACL_TYPE_ACCESS, &access_acl_list);
F_ACL(file) = cache_rsync_acl(sxp->acc_acl, SMB_ACL_TYPE_ACCESS, &access_acl_list);
if (S_ISDIR(sxp->st.st_mode)) {
if (prior_default_count == (size_t)-1)
prior_default_count = default_acl_list.count;
F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl,
SMB_ACL_TYPE_DEFAULT, &default_acl_list);
F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl, SMB_ACL_TYPE_DEFAULT, &default_acl_list);
}
}
@@ -993,11 +982,10 @@ static int set_rsync_acl(const char *fname, acl_duo *duo_item,
&& !pack_smb_acl(&duo_item->sacl, &duo_item->racl))
return -1;
#ifdef HAVE_OSX_ACLS
mode = 0; /* eliminate compiler warning */
(void)mode; /* eliminate compiler warning */
#else
if (type == SMB_ACL_TYPE_ACCESS) {
cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl,
cur_mode, mode);
cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl, cur_mode, mode);
if (cur_mode == (mode_t)-1)
return 0;
}
@@ -1117,14 +1105,12 @@ int default_perms_for_dir(const char *dir)
case ENOSYS:
/* No ACLs are available. */
break;
case ENOENT:
if (dry_run) {
default:
if (dry_run && errno == ENOENT) {
/* We're doing a dry run, so the containing directory
* wasn't actually created. Don't worry about it. */
break;
}
/* Otherwise fall through. */
default:
rprintf(FWARNING,
"default_perms_for_dir: sys_acl_get_file(%s, %s): %s, falling back on umask\n",
dir, str_acl_type(SMB_ACL_TYPE_DEFAULT), strerror(errno));

View File

@@ -2,7 +2,7 @@
* Support rsync daemon authentication.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2002-2014 Wayne Davison
* Copyright (C) 2002-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
@@ -20,9 +20,11 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
extern int read_only;
extern char *password_file;
extern struct name_num_obj valid_auth_checksums;
/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
@@ -71,9 +73,9 @@ static void gen_challenge(const char *addr, char *challenge)
SIVAL(input, 20, tv.tv_usec);
SIVAL(input, 24, getpid());
sum_init(0);
len = sum_init(valid_auth_checksums.negotiated_nni, 0);
sum_update(input, sizeof input);
len = sum_end(digest);
sum_end(digest);
base64_encode(digest, len, challenge, 0);
}
@@ -85,10 +87,10 @@ static void generate_hash(const char *in, const char *challenge, char *out)
char buf[MAX_DIGEST_LEN];
int len;
sum_init(0);
len = sum_init(valid_auth_checksums.negotiated_nni, 0);
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
len = sum_end(buf);
sum_end(buf);
base64_encode(buf, len, out, 0);
}
@@ -118,7 +120,7 @@ static const char *check_secret(int module, const char *user, const char *group,
if ((st.st_mode & 06) != 0) {
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
ok = 0;
} else if (MY_UID() == 0 && st.st_uid != 0) {
} else if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
@@ -162,8 +164,8 @@ static const char *check_secret(int module, const char *user, const char *group,
fclose(fh);
memset(line, 0, sizeof line);
memset(pass2, 0, sizeof pass2);
force_memzero(line, sizeof line);
force_memzero(pass2, sizeof pass2);
return err;
}
@@ -195,7 +197,7 @@ static const char *getpassf(const char *filename)
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
exit_cleanup(RERR_SYNTAX);
}
if (MY_UID() == 0 && st.st_uid != 0) {
if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
exit_cleanup(RERR_SYNTAX);
}
@@ -226,7 +228,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
char *users = lp_auth_users(module);
char challenge[MAX_DIGEST_LEN*2];
char line[BIGPATHBUFLEN];
char **auth_uid_groups = NULL;
const char **auth_uid_groups = NULL;
int auth_uid_groups_cnt = -1;
const char *err = NULL;
int group_match = -1;
@@ -237,6 +239,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
if (!users || !*users)
return "";
negotiate_daemon_auth(f_out, 0);
gen_challenge(addr, challenge);
io_printf(f_out, "%s%s\n", leader, challenge);
@@ -250,8 +253,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
}
*pass++ = '\0';
if (!(users = strdup(users)))
out_of_memory("auth_server");
users = strdup(users);
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
char *opts;
@@ -279,17 +281,17 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
/* See if authorizing user is a real user, and if so, see
* if it is in a group that matches tok+1 wildmat. */
if (auth_uid_groups_cnt < 0) {
gid_t gid_list[64];
item_list gid_list = EMPTY_ITEM_LIST;
uid_t auth_uid;
auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
if (!user_to_uid(line, &auth_uid, False)
|| getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
|| getallgroups(auth_uid, &gid_list) != NULL)
auth_uid_groups_cnt = 0;
else {
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
out_of_memory("auth_server");
gid_t *gid_array = gid_list.items;
auth_uid_groups_cnt = gid_list.count;
auth_uid_groups = new_array(const char *, auth_uid_groups_cnt);
for (j = 0; j < auth_uid_groups_cnt; j++)
auth_uid_groups[j] = gid_to_group(gid_list[j]);
auth_uid_groups[j] = gid_to_group(gid_array[j]);
}
}
for (j = 0; j < auth_uid_groups_cnt; j++) {
@@ -313,18 +315,18 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
else if (opt_ch == 'd')
err = "denied by rule";
else {
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
const char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
err = check_secret(module, line, group, challenge, pass);
}
memset(challenge, 0, sizeof challenge);
memset(pass, 0, strlen(pass));
force_memzero(challenge, sizeof challenge);
force_memzero(pass, strlen(pass));
if (auth_uid_groups) {
int j;
for (j = 0; j < auth_uid_groups_cnt; j++) {
if (auth_uid_groups[j])
free(auth_uid_groups[j]);
free((char*)auth_uid_groups[j]);
}
free(auth_uid_groups);
}
@@ -350,18 +352,19 @@ void auth_client(int fd, const char *user, const char *challenge)
if (!user || !*user)
user = "nobody";
negotiate_daemon_auth(-1, 1);
if (!(pass = getpassf(password_file))
&& !(pass = getenv("RSYNC_PASSWORD"))) {
/* XXX: cyeoh says that getpass is deprecated, because
* it may return a truncated password on some systems,
* and it is not in the LSB.
*
* Andrew Klein says that getpassphrase() is present
* on Solaris and reads up to 256 characters.
*
* OpenBSD has a readpassphrase() that might be more suitable.
*/
*
* Andrew Klein says that getpassphrase() is present
* on Solaris and reads up to 256 characters.
*
* OpenBSD has a readpassphrase() that might be more suitable.
*/
pass = getpass("Password: ");
}

View File

@@ -2,7 +2,7 @@
* Backup handling code.
*
* Copyright (C) 1999 Andrew Tridgell
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-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
@@ -157,6 +157,18 @@ static BOOL copy_valid_path(const char *fname)
char *get_backup_name(const char *fname)
{
if (backup_dir) {
static int initialized = 0;
if (!initialized) {
int ret;
if (backup_dir_len > 1)
backup_dir_buf[backup_dir_len-1] = '\0';
ret = make_path(backup_dir_buf, 0);
if (backup_dir_len > 1)
backup_dir_buf[backup_dir_len-1] = '/';
if (ret < 0)
return NULL;
initialized = 1;
}
/* copy fname into backup_dir_buf while validating the dirs. */
if (copy_valid_path(fname))
return backup_dir_buf;
@@ -208,23 +220,24 @@ static inline int link_or_rename(const char *from, const char *to,
return 0;
}
/* Hard-link, rename, or copy an item to the backup name. Returns 2 if item
* was duplicated into backup area, 1 if item was moved, or 0 for failure.*/
/* Hard-link, rename, or copy an item to the backup name. Returns 0 for
* failure, 1 if item was moved, 2 if item was duplicated or hard linked
* into backup area, or 3 if item doesn't exist or isn't a regular file. */
int make_backup(const char *fname, BOOL prefer_rename)
{
stat_x sx;
struct file_struct *file;
int save_preserve_xattrs;
char *buf = get_backup_name(fname);
char *buf;
int ret = 0;
if (!buf)
return 0;
init_stat_x(&sx);
/* Return success if no file to keep. */
if (x_lstat(fname, &sx.st, NULL) < 0)
return 1;
return 3;
if (!(buf = get_backup_name(fname)))
return 0;
/* Try a hard-link or a rename first. Using rename is not atomic, but
* is more efficient than forcing a copy for larger files when no hard-
@@ -244,7 +257,7 @@ int make_backup(const char *fname, BOOL prefer_rename)
/* Fall back to making a copy. */
if (!(file = make_file(fname, NULL, &sx.st, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
return 3; /* the file could have disappeared */
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
@@ -291,7 +304,8 @@ int make_backup(const char *fname, BOOL prefer_rename)
#endif
if (!ret && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
if (INFO_GTE(NONREG, 1))
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
@@ -299,7 +313,7 @@ int make_backup(const char *fname, BOOL prefer_rename)
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 2;
return 3;
}
/* Copy to backup tree if a file. */
@@ -323,7 +337,7 @@ int make_backup(const char *fname, BOOL prefer_rename)
save_preserve_xattrs = preserve_xattrs;
preserve_xattrs = 0;
set_file_attrs(buf, file, NULL, fname, 0);
set_file_attrs(buf, file, NULL, fname, ATTRS_ACCURATE_TIME);
preserve_xattrs = save_preserve_xattrs;
unmake_file(file);

157
batch.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1999 Weiss
* Copyright (C) 2004 Chris Shoemaker
* Copyright (C) 2004-2014 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
@@ -37,7 +37,10 @@ extern int always_checksum;
extern int do_compression;
extern int inplace;
extern int append_mode;
extern int write_batch;
extern int protocol_version;
extern int raw_argc, cooked_argc;
extern char **raw_argv, **cooked_argv;
extern char *batch_name;
#ifdef ICONV_OPTION
extern char *iconv_opt;
@@ -45,6 +48,8 @@ extern char *iconv_opt;
extern filter_rule_list filter_list;
int batch_fd = -1;
int batch_sh_fd = -1;
int batch_stream_flags;
static int tweaked_append;
@@ -70,7 +75,7 @@ static int *flag_ptr[] = {
NULL
};
static char *flag_name[] = {
static const char *const flag_name[] = {
"--recurse (-r)",
"--owner (-o)",
"--group (-g)",
@@ -156,37 +161,45 @@ void check_batch_flags(void)
append_mode = 2;
}
static int write_arg(int fd, char *arg)
static int write_arg(const char *arg)
{
char *x, *s;
int len, ret = 0;
const char *x, *s;
int len, err = 0;
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
if (write(fd, arg, x - arg + 1) != x - arg + 1)
ret = -1;
err |= write(batch_sh_fd, arg, x - arg + 1) != x - arg + 1;
arg += x - arg + 1;
}
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
if (write(fd, "'", 1) != 1)
ret = -1;
err |= write(batch_sh_fd, "'", 1) != 1;
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
if (write(fd, s, x - s + 1) != x - s + 1
|| write(fd, "'", 1) != 1)
ret = -1;
err |= write(batch_sh_fd, s, x - s + 1) != x - s + 1;
err |= write(batch_sh_fd, "'", 1) != 1;
}
len = strlen(s);
if (write(fd, s, len) != len
|| write(fd, "'", 1) != 1)
ret = -1;
return ret;
err |= write(batch_sh_fd, s, len) != len;
err |= write(batch_sh_fd, "'", 1) != 1;
return err;
}
len = strlen(arg);
if (write(fd, arg, len) != len)
ret = -1;
err |= write(batch_sh_fd, arg, len) != len;
return ret;
return err;
}
/* Writes out a space and then an option (or other string) with an optional "=" + arg suffix. */
static int write_opt(const char *opt, const char *arg)
{
int len = strlen(opt);
int err = write(batch_sh_fd, " ", 1) != 1;
err = write(batch_sh_fd, opt, len) != len ? 1 : 0;
if (arg) {
err |= write(batch_sh_fd, "=", 1) != 1;
err |= write_arg(arg);
}
return err;
}
static void write_filter_rules(int fd)
@@ -208,41 +221,66 @@ static void write_filter_rules(int fd)
write_sbuf(fd, "#E#");
}
/* This sets batch_fd and (for --write-batch) batch_sh_fd. */
void open_batch_files(void)
{
if (write_batch) {
char filename[MAXPATHLEN];
stringjoin(filename, sizeof filename, batch_name, ".sh", NULL);
batch_sh_fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
if (batch_sh_fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(filename));
exit_cleanup(RERR_FILESELECT);
}
batch_fd = do_open(batch_name, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
} else if (strcmp(batch_name, "-") == 0)
batch_fd = STDIN_FILENO;
else
batch_fd = do_open(batch_name, O_RDONLY, S_IRUSR | S_IWUSR);
if (batch_fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(batch_name));
exit_cleanup(RERR_FILEIO);
}
}
/* This routine tries to write out an equivalent --read-batch command
* given the user's --write-batch args. However, it doesn't really
* understand most of the options, so it uses some overly simple
* heuristics to munge the command line into something that will
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
void write_batch_shell_file(void)
{
int fd, i, len, err = 0;
char *p, filename[MAXPATHLEN];
stringjoin(filename, sizeof filename,
batch_name, ".sh", NULL);
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IXUSR);
if (fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error",
filename);
exit_cleanup(RERR_FILESELECT);
}
int i, j, len, err = 0;
char *p, *p2;
/* Write argvs info to BATCH.sh file */
if (write_arg(fd, argv[0]) < 0)
err = 1;
err |= write_arg(raw_argv[0]);
if (filter_list.head) {
if (protocol_version >= 29)
write_sbuf(fd, " --filter=._-");
err |= write_opt("--filter", "._-");
else
write_sbuf(fd, " --exclude-from=-");
err |= write_opt("--exclude-from", "-");
}
for (i = 1; i < argc - file_arg_cnt; i++) {
p = argv[i];
/* 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) {
raw_argv[i] = NULL;
j--;
}
}
for (i = 1; i < raw_argc; i++) {
if (!(p = raw_argv[i]))
continue;
if (strncmp(p, "--files-from", 12) == 0
|| strncmp(p, "--filter", 8) == 0
|| strncmp(p, "--include", 9) == 0
|| strncmp(p, "--exclude", 9) == 0) {
|| strncmp(p, "--filter", 8) == 0
|| strncmp(p, "--include", 9) == 0
|| strncmp(p, "--exclude", 9) == 0) {
if (strchr(p, '=') == NULL)
i++;
continue;
@@ -251,33 +289,24 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
i++;
continue;
}
if (write(fd, " ", 1) != 1)
err = 1;
if (strncmp(p, "--write-batch", len = 13) == 0
|| strncmp(p, "--only-write-batch", len = 18) == 0) {
if (write(fd, "--read-batch", 12) != 12)
err = 1;
if (p[len] == '=') {
if (write(fd, "=", 1) != 1
|| write_arg(fd, p + len + 1) < 0)
err = 1;
}
} else {
if (write_arg(fd, p) < 0)
err = 1;
|| strncmp(p, "--only-write-batch", len = 18) == 0)
err |= write_opt("--read-batch", p[len] == '=' ? p + len + 1 : NULL);
else {
err |= write(batch_sh_fd, " ", 1) != 1;
err |= write_arg(p);
}
}
if (!(p = check_for_hostspec(argv[argc - 1], &p, &i)))
p = argv[argc - 1];
if (write(fd, " ${1:-", 6) != 6
|| write_arg(fd, p) < 0)
err = 1;
write_byte(fd, '}');
if (!(p = check_for_hostspec(cooked_argv[cooked_argc - 1], &p2, &i)))
p = cooked_argv[cooked_argc - 1];
err |= write_opt("${1:-", NULL);
err |= write_arg(p);
err |= write(batch_sh_fd, "}", 1) != 1;
if (filter_list.head)
write_filter_rules(fd);
if (write(fd, "\n", 1) != 1 || close(fd) < 0 || err) {
rsyserr(FERROR, errno, "Batch file %s write error",
filename);
write_filter_rules(batch_sh_fd);
if (write(batch_sh_fd, "\n", 1) != 1 || close(batch_sh_fd) < 0 || err) {
rsyserr(FERROR, errno, "Batch file %s.sh write error", batch_name);
exit_cleanup(RERR_FILEIO);
}
batch_sh_fd = -1;
}

View File

@@ -2,7 +2,7 @@
* Simple byteorder handling.
*
* Copyright (C) 1992-1995 Andrew Tridgell
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-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
@@ -19,7 +19,6 @@
*/
#undef CAREFUL_ALIGNMENT
#undef AVOID_BYTEORDER_INLINE
/* We know that the x86 can handle misalignment and has the same
* byte order (LSB-first) as the 32-bit numbers we transmit. */
@@ -36,16 +35,36 @@
#if CAREFUL_ALIGNMENT
#define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
#define IVAL64(buf,pos) (IVAL(buf,pos)|(int64)IVAL(buf,(pos)+4)<<32)
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
#define SIVAL(buf,pos,val) SIVALX(buf,pos,(uint32)(val))
#define SIVAL64(buf,pos,val) (SIVAL(buf,pos,val),SIVAL(buf,(pos)+4,(val)>>32))
static inline uint32
IVALu(const uchar *buf, int pos)
{
return UVAL(buf, pos)
| UVAL(buf, pos + 1) << 8
| UVAL(buf, pos + 2) << 16
| UVAL(buf, pos + 3) << 24;
}
#define IVALu(buf,pos) IVAL(buf,pos)
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
static inline void
SIVALu(uchar *buf, int pos, uint32 val)
{
CVAL(buf, pos) = val;
CVAL(buf, pos + 1) = val >> 8;
CVAL(buf, pos + 2) = val >> 16;
CVAL(buf, pos + 3) = val >> 24;
}
static inline int64
IVAL64(const char *buf, int pos)
{
return IVALu((uchar*)buf, pos) | (int64)IVALu((uchar*)buf, pos + 4) << 32;
}
static inline void
SIVAL64(char *buf, int pos, int64 val)
{
SIVALu((uchar*)buf, pos, val);
SIVALu((uchar*)buf, pos + 4, val >> 32);
}
#else /* !CAREFUL_ALIGNMENT */
@@ -53,16 +72,6 @@
* WARNING: This section is dependent on the length of an int32 (and thus a uint32)
* being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */
# ifdef AVOID_BYTEORDER_INLINE
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
#define IVALu(buf,pos) IVAL(buf,pos)
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
# else /* !AVOID_BYTEORDER_INLINE */
static inline uint32
IVALu(const uchar *buf, int pos)
{
@@ -85,18 +94,6 @@ SIVALu(uchar *buf, int pos, uint32 val)
*u.num = val;
}
static inline uint32
IVAL(const char *buf, int pos)
{
return IVALu((uchar*)buf, pos);
}
static inline void
SIVAL(char *buf, int pos, uint32 val)
{
SIVALu((uchar*)buf, pos, val);
}
static inline int64
IVAL64(const char *buf, int pos)
{
@@ -119,6 +116,16 @@ SIVAL64(char *buf, int pos, int64 val)
*u.num = val;
}
# endif /* !AVOID_BYTEORDER_INLINE */
#endif /* !CAREFUL_ALIGNMENT */
static inline uint32
IVAL(const char *buf, int pos)
{
return IVALu((uchar*)buf, pos);
}
static inline void
SIVAL(char *buf, int pos, uint32 val)
{
SIVALu((uchar*)buf, pos, val);
}

View File

@@ -1,7 +1,7 @@
/*
* Allow an arbitrary sequence of case labels.
*
* Copyright (C) 2006-2014 Wayne Davison
* Copyright (C) 2006-2020 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
@@ -17,7 +17,7 @@
* with this program; if not, visit the http://fsf.org website.
*/
/* This is included multiple times, once for every segement in a switch statement.
/* This is included multiple times, once for every segment in a switch statement.
* This produces the next "case N:" statement in sequence. */
#if !defined CASE_N_STATE_0
@@ -25,51 +25,67 @@
case 0:
#elif !defined CASE_N_STATE_1
#define CASE_N_STATE_1
/* FALLTHROUGH */
case 1:
#elif !defined CASE_N_STATE_2
#define CASE_N_STATE_2
/* FALLTHROUGH */
case 2:
#elif !defined CASE_N_STATE_3
#define CASE_N_STATE_3
/* FALLTHROUGH */
case 3:
#elif !defined CASE_N_STATE_4
#define CASE_N_STATE_4
/* FALLTHROUGH */
case 4:
#elif !defined CASE_N_STATE_5
#define CASE_N_STATE_5
/* FALLTHROUGH */
case 5:
#elif !defined CASE_N_STATE_6
#define CASE_N_STATE_6
/* FALLTHROUGH */
case 6:
#elif !defined CASE_N_STATE_7
#define CASE_N_STATE_7
/* FALLTHROUGH */
case 7:
#elif !defined CASE_N_STATE_8
#define CASE_N_STATE_8
/* FALLTHROUGH */
case 8:
#elif !defined CASE_N_STATE_9
#define CASE_N_STATE_9
/* FALLTHROUGH */
case 9:
#elif !defined CASE_N_STATE_10
#define CASE_N_STATE_10
/* FALLTHROUGH */
case 10:
#elif !defined CASE_N_STATE_11
#define CASE_N_STATE_11
/* FALLTHROUGH */
case 11:
#elif !defined CASE_N_STATE_12
#define CASE_N_STATE_12
/* FALLTHROUGH */
case 12:
#elif !defined CASE_N_STATE_13
#define CASE_N_STATE_13
/* FALLTHROUGH */
case 13:
#elif !defined CASE_N_STATE_14
#define CASE_N_STATE_14
/* FALLTHROUGH */
case 14:
#elif !defined CASE_N_STATE_15
#define CASE_N_STATE_15
/* FALLTHROUGH */
case 15:
#elif !defined CASE_N_STATE_16
#define CASE_N_STATE_16
/* FALLTHROUGH */
case 16:
#else
#error Need to add more case statements!

View File

@@ -3,13 +3,20 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2004-2014 Wayne Davison
* Copyright (C) 2004-2023 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to dynamically link rsync with the OpenSSL and xxhash
* libraries when those libraries are being distributed in compliance
* with their license terms, and to distribute a dynamically linked
* combination of rsync and these libraries. This is also considered
* to be covered under the GPL's System Libraries exception.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -21,59 +28,348 @@
#include "rsync.h"
#ifdef SUPPORT_XXHASH
#include <xxhash.h>
# if XXH_VERSION_NUMBER >= 800
# define SUPPORT_XXH3 1
# endif
#endif
extern int am_server;
extern int whole_file;
extern int checksum_seed;
extern int protocol_version;
extern int proper_seed_order;
extern const char *checksum_choice;
#define NNI_BUILTIN (1<<0)
#define NNI_EVP (1<<1)
#define NNI_EVP_OK (1<<2)
struct name_num_item valid_checksums_items[] = {
#ifdef SUPPORT_XXH3
{ CSUM_XXH3_128, 0, "xxh128", NULL },
{ CSUM_XXH3_64, 0, "xxh3", NULL },
#endif
#ifdef SUPPORT_XXHASH
{ CSUM_XXH64, 0, "xxh64", NULL },
{ CSUM_XXH64, 0, "xxhash", NULL },
#endif
{ CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
{ CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
#ifdef SHA_DIGEST_LENGTH
{ CSUM_SHA1, NNI_EVP, "sha1", NULL },
#endif
{ CSUM_NONE, 0, "none", NULL },
{ 0, 0, NULL, NULL }
};
struct name_num_obj valid_checksums = {
"checksum", NULL, 0, 0, valid_checksums_items
};
struct name_num_item valid_auth_checksums_items[] = {
#ifdef SHA512_DIGEST_LENGTH
{ CSUM_SHA512, NNI_EVP, "sha512", NULL },
#endif
#ifdef SHA256_DIGEST_LENGTH
{ CSUM_SHA256, NNI_EVP, "sha256", NULL },
#endif
#ifdef SHA_DIGEST_LENGTH
{ CSUM_SHA1, NNI_EVP, "sha1", NULL },
#endif
{ 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, valid_auth_checksums_items
};
/* These cannot make use of openssl, so they're marked just as built-in */
struct name_num_item implied_checksum_md4 =
{ 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 */
int xfer_sum_len;
struct name_num_item *file_sum_nni; /* used for the pre-transfer --checksum computations */
int file_sum_len, file_sum_extra_cnt;
#ifdef USE_OPENSSL
const EVP_MD *xfer_sum_evp_md;
const EVP_MD *file_sum_evp_md;
EVP_MD_CTX *ctx_evp = NULL;
#endif
static int initialized_choices = 0;
struct name_num_item *parse_csum_name(const char *name, int len)
{
struct name_num_item *nni;
if (len < 0 && name)
len = strlen(name);
init_checksum_choices();
if (!name || (len == 4 && strncasecmp(name, "auto", 4) == 0)) {
if (protocol_version >= 30) {
if (!proper_seed_order)
return &implied_checksum_md5;
name = "md5";
len = 3;
} else {
if (protocol_version >= 27)
implied_checksum_md4.num = CSUM_MD4_OLD;
else if (protocol_version >= 21)
implied_checksum_md4.num = CSUM_MD4_BUSTED;
else
implied_checksum_md4.num = CSUM_MD4_ARCHAIC;
return &implied_checksum_md4;
}
}
nni = get_nni_by_name(&valid_checksums, name, len);
if (!nni) {
rprintf(FERROR, "unknown checksum name: %s\n", name);
exit_cleanup(RERR_UNSUPPORTED);
}
return nni;
}
#ifdef USE_OPENSSL
static const EVP_MD *csum_evp_md(struct name_num_item *nni)
{
const EVP_MD *emd;
if (!(nni->flags & NNI_EVP))
return NULL;
#ifdef USE_MD5_ASM
if (nni->num == CSUM_MD5)
emd = NULL;
else
#endif
emd = EVP_get_digestbyname(nni->name);
if (emd && !(nni->flags & NNI_EVP_OK)) { /* Make sure it works before we advertise it */
if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
out_of_memory("csum_evp_md");
/* Some routines are marked as legacy and are not enabled in the openssl.cnf file.
* If we can't init the emd, we'll fall back to our built-in code. */
if (EVP_DigestInit_ex(ctx_evp, emd, NULL) == 0)
emd = NULL;
else
nni->flags = (nni->flags & ~NNI_BUILTIN) | NNI_EVP_OK;
}
if (!emd)
nni->flags &= ~NNI_EVP;
return emd;
}
#endif
void parse_checksum_choice(int final_call)
{
if (valid_checksums.negotiated_nni)
xfer_sum_nni = file_sum_nni = valid_checksums.negotiated_nni;
else {
const char *cp = checksum_choice ? strchr(checksum_choice, ',') : NULL;
if (cp) {
xfer_sum_nni = parse_csum_name(checksum_choice, cp - checksum_choice);
file_sum_nni = parse_csum_name(cp+1, -1);
} else
xfer_sum_nni = file_sum_nni = parse_csum_name(checksum_choice, -1);
if (am_server && checksum_choice)
validate_choice_vs_env(NSTR_CHECKSUM, xfer_sum_nni->num, file_sum_nni->num);
}
xfer_sum_len = csum_len_for_type(xfer_sum_nni->num, 0);
file_sum_len = csum_len_for_type(file_sum_nni->num, 0);
#ifdef USE_OPENSSL
xfer_sum_evp_md = csum_evp_md(xfer_sum_nni);
file_sum_evp_md = csum_evp_md(file_sum_nni);
#endif
file_sum_extra_cnt = (file_sum_len + EXTRA_LEN - 1) / EXTRA_LEN;
if (xfer_sum_nni->num == CSUM_NONE)
whole_file = 1;
/* Snag the checksum name for both write_batch's option output & the following debug output. */
if (valid_checksums.negotiated_nni)
checksum_choice = valid_checksums.negotiated_nni->name;
else if (checksum_choice == NULL)
checksum_choice = xfer_sum_nni->name;
if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)) {
rprintf(FINFO, "%s%s checksum: %s\n",
am_server ? "Server" : "Client",
valid_checksums.negotiated_nni ? " negotiated" : "",
checksum_choice);
}
}
int csum_len_for_type(int cst, BOOL flist_csum)
{
switch (cst) {
case CSUM_NONE:
return 1;
case CSUM_MD4_ARCHAIC:
/* The oldest checksum code is rather weird: the file-list code only sent
* 2-byte checksums, but all other checksums were full MD4 length. */
return flist_csum ? 2 : MD4_DIGEST_LEN;
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
return MD4_DIGEST_LEN;
case CSUM_MD5:
return MD5_DIGEST_LEN;
#ifdef SHA_DIGEST_LENGTH
case CSUM_SHA1:
return SHA_DIGEST_LENGTH;
#endif
#ifdef SHA256_DIGEST_LENGTH
case CSUM_SHA256:
return SHA256_DIGEST_LENGTH;
#endif
#ifdef SHA512_DIGEST_LENGTH
case CSUM_SHA512:
return SHA512_DIGEST_LENGTH;
#endif
case CSUM_XXH64:
case CSUM_XXH3_64:
return 64/8;
case CSUM_XXH3_128:
return 128/8;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
return 0;
}
/* Returns 0 if the checksum is not canonical (i.e. it includes a seed value).
* Returns 1 if the public sum order matches our internal sum order.
* Returns -1 if the public sum order is the reverse of our internal sum order.
*/
int canonical_checksum(int csum_type)
{
switch (csum_type) {
case CSUM_NONE:
case CSUM_MD4_ARCHAIC:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
break;
case CSUM_MD4:
case CSUM_MD5:
case CSUM_SHA1:
case CSUM_SHA256:
case CSUM_SHA512:
return -1;
case CSUM_XXH64:
case CSUM_XXH3_64:
case CSUM_XXH3_128:
return 1;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
return 0;
}
#ifndef USE_ROLL_SIMD /* See simd-checksum-*.cpp. */
/*
a simple 32 bit checksum that can be upadted from either end
a simple 32 bit checksum that can be updated from either end
(inspired by Mark Adler's Adler-32 checksum)
*/
uint32 get_checksum1(char *buf1, int32 len)
{
int32 i;
uint32 s1, s2;
schar *buf = (schar *)buf1;
int32 i;
uint32 s1, s2;
schar *buf = (schar *)buf1;
s1 = s2 = 0;
for (i = 0; i < (len-4); i+=4) {
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
10*CHAR_OFFSET;
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
}
for (; i < len; i++) {
s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
}
return (s1 & 0xffff) + (s2 << 16);
s1 = s2 = 0;
for (i = 0; i < (len-4); i+=4) {
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] + 10*CHAR_OFFSET;
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
}
for (; i < len; i++) {
s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
}
return (s1 & 0xffff) + (s2 << 16);
}
#endif
/* The "sum" buffer must be at least MAX_DIGEST_LEN bytes! */
void get_checksum2(char *buf, int32 len, char *sum)
{
md_context m;
if (protocol_version >= 30) {
#ifdef USE_OPENSSL
if (xfer_sum_evp_md) {
static EVP_MD_CTX *evp = NULL;
uchar seedbuf[4];
md5_begin(&m);
md5_update(&m, (uchar *)buf, len);
if (!evp && !(evp = EVP_MD_CTX_create()))
out_of_memory("get_checksum2");
EVP_DigestInit_ex(evp, xfer_sum_evp_md, NULL);
if (checksum_seed) {
SIVALu(seedbuf, 0, checksum_seed);
md5_update(&m, seedbuf, 4);
EVP_DigestUpdate(evp, seedbuf, 4);
}
md5_result(&m, (uchar *)sum);
} else {
EVP_DigestUpdate(evp, (uchar *)buf, len);
EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
} else
#endif
switch (xfer_sum_nni->num) {
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
SIVAL64(sum, 0, XXH3_64bits_withSeed(buf, len, checksum_seed));
break;
case CSUM_XXH3_128: {
XXH128_hash_t digest = XXH3_128bits_withSeed(buf, len, checksum_seed);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5: {
md_context m5;
uchar seedbuf[4];
md5_begin(&m5);
if (proper_seed_order) {
if (checksum_seed) {
SIVALu(seedbuf, 0, checksum_seed);
md5_update(&m5, seedbuf, 4);
}
md5_update(&m5, (uchar *)buf, len);
} else {
md5_update(&m5, (uchar *)buf, len);
if (checksum_seed) {
SIVALu(seedbuf, 0, checksum_seed);
md5_update(&m5, seedbuf, 4);
}
}
md5_result(&m5, (uchar *)sum);
break;
}
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC: {
md_context m;
int32 i;
static char *buf1;
static int32 len1;
mdfour_begin(&m);
if (len > len1) {
if (buf1)
free(buf1);
if (len > len1 || !buf1) {
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1)
out_of_memory("get_checksum2");
}
memcpy(buf1, buf, len);
@@ -91,10 +387,14 @@ 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.
*/
if (len - i > 0 || protocol_version >= 27)
if (len - i > 0 || xfer_sum_nni->num > CSUM_MD4_BUSTED)
mdfour_update(&m, (uchar *)(buf1+i), len-i);
mdfour_result(&m, (uchar *)sum);
break;
}
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
}
@@ -102,48 +402,135 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
{
struct map_struct *buf;
OFF_T i, len = st_p->st_size;
md_context m;
int32 remainder;
int fd;
memset(sum, 0, MAX_DIGEST_LEN);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1)
fd = do_open_checklinks(fname);
if (fd == -1) {
memset(sum, 0, file_sum_len);
return;
}
buf = map_file(fd, len, MAX_MAP_SIZE, CSUM_CHUNK);
buf = map_file(fd, len, MAX_MAP_SIZE, CHUNK_SIZE);
if (protocol_version >= 30) {
md5_begin(&m);
#ifdef USE_OPENSSL
if (file_sum_evp_md) {
static EVP_MD_CTX *evp = NULL;
if (!evp && !(evp = EVP_MD_CTX_create()))
out_of_memory("file_checksum");
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
md5_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
EVP_DigestInit_ex(evp, file_sum_evp_md, NULL);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
md5_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, remainder), remainder);
EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
} else
#endif
switch (file_sum_nni->num) {
#ifdef SUPPORT_XXHASH
case CSUM_XXH64: {
static XXH64_state_t* state = NULL;
if (!state && !(state = XXH64_createState()))
out_of_memory("file_checksum");
XXH64_reset(state, 0);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
XXH64_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
XXH64_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
SIVAL64(sum, 0, XXH64_digest(state));
break;
}
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64: {
static XXH3_state_t* state = NULL;
if (!state && !(state = XXH3_createState()))
out_of_memory("file_checksum");
XXH3_64bits_reset(state);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
SIVAL64(sum, 0, XXH3_64bits_digest(state));
break;
}
case CSUM_XXH3_128: {
XXH128_hash_t digest;
static XXH3_state_t* state = NULL;
if (!state && !(state = XXH3_createState()))
out_of_memory("file_checksum");
XXH3_128bits_reset(state);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
digest = XXH3_128bits_digest(state);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5: {
md_context m5;
md5_begin(&m5);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
md5_update(&m5, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
md5_update(&m5, (uchar *)map_ptr(buf, i, remainder), remainder);
md5_result(&m5, (uchar *)sum);
break;
}
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC: {
md_context m;
md5_result(&m, (uchar *)sum);
} else {
mdfour_begin(&m);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
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
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
if (remainder > 0 || protocol_version >= 27)
if (remainder > 0 || file_sum_nni->num > CSUM_MD4_BUSTED)
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
break;
}
default:
rprintf(FERROR, "Invalid checksum-choice for --checksum: %s (%d)\n",
file_sum_nni->name, file_sum_nni->num);
exit_cleanup(RERR_UNSUPPORTED);
}
close(fd);
@@ -151,73 +538,266 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
}
static int32 sumresidue;
static md_context md;
static md_context ctx_md;
#ifdef SUPPORT_XXHASH
static XXH64_state_t* xxh64_state;
#endif
#ifdef SUPPORT_XXH3
static XXH3_state_t* xxh3_state;
#endif
static struct name_num_item *cur_sum_nni;
int cur_sum_len;
void sum_init(int seed)
#ifdef USE_OPENSSL
static const EVP_MD *cur_sum_evp_md;
#endif
/* Initialize a hash digest accumulator. Data is supplied via
* sum_update() and the resulting binary digest is retrieved via
* sum_end(). This only supports one active sum at a time. */
int sum_init(struct name_num_item *nni, int seed)
{
char s[4];
if (protocol_version >= 30)
md5_begin(&md);
else {
mdfour_begin(&md);
if (!nni)
nni = parse_csum_name(NULL, 0);
cur_sum_nni = nni;
cur_sum_len = csum_len_for_type(nni->num, 0);
#ifdef USE_OPENSSL
cur_sum_evp_md = csum_evp_md(nni);
#endif
#ifdef USE_OPENSSL
if (cur_sum_evp_md) {
if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
out_of_memory("file_checksum");
EVP_DigestInit_ex(ctx_evp, cur_sum_evp_md, NULL);
} else
#endif
switch (cur_sum_nni->num) {
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
if (!xxh64_state && !(xxh64_state = XXH64_createState()))
out_of_memory("sum_init");
XXH64_reset(xxh64_state, 0);
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
out_of_memory("sum_init");
XXH3_64bits_reset(xxh3_state);
break;
case CSUM_XXH3_128:
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
out_of_memory("sum_init");
XXH3_128bits_reset(xxh3_state);
break;
#endif
case CSUM_MD5:
md5_begin(&ctx_md);
break;
case CSUM_MD4:
mdfour_begin(&ctx_md);
sumresidue = 0;
break;
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC:
mdfour_begin(&ctx_md);
sumresidue = 0;
SIVAL(s, 0, seed);
sum_update(s, 4);
break;
case CSUM_NONE:
break;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
return cur_sum_len;
}
/**
* Feed data into an MD4 accumulator, md. The results may be
* retrieved using sum_end(). md is used for different purposes at
* different points during execution.
*
* @todo Perhaps get rid of md and just pass in the address each time.
* Very slightly clearer and slower.
**/
/* Feed data into a hash digest accumulator. */
void sum_update(const char *p, int32 len)
{
if (protocol_version >= 30) {
md5_update(&md, (uchar *)p, len);
return;
}
#ifdef USE_OPENSSL
if (cur_sum_evp_md) {
EVP_DigestUpdate(ctx_evp, (uchar *)p, len);
} else
#endif
switch (cur_sum_nni->num) {
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
XXH64_update(xxh64_state, p, len);
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
XXH3_64bits_update(xxh3_state, p, len);
break;
case CSUM_XXH3_128:
XXH3_128bits_update(xxh3_state, p, len);
break;
#endif
case CSUM_MD5:
md5_update(&ctx_md, (uchar *)p, len);
break;
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC:
if (len + sumresidue < CSUM_CHUNK) {
memcpy(ctx_md.buffer + sumresidue, p, len);
sumresidue += len;
break;
}
if (len + sumresidue < CSUM_CHUNK) {
memcpy(md.buffer + sumresidue, p, len);
sumresidue += len;
return;
}
if (sumresidue) {
int32 i = CSUM_CHUNK - sumresidue;
memcpy(ctx_md.buffer + sumresidue, p, i);
mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, CSUM_CHUNK);
len -= i;
p += i;
}
if (sumresidue) {
int32 i = CSUM_CHUNK - sumresidue;
memcpy(md.buffer + sumresidue, p, i);
mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
len -= i;
p += i;
}
while (len >= CSUM_CHUNK) {
mdfour_update(&ctx_md, (uchar *)p, CSUM_CHUNK);
len -= CSUM_CHUNK;
p += CSUM_CHUNK;
}
while (len >= CSUM_CHUNK) {
mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
len -= CSUM_CHUNK;
p += CSUM_CHUNK;
sumresidue = len;
if (sumresidue)
memcpy(ctx_md.buffer, p, sumresidue);
break;
case CSUM_NONE:
break;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
sumresidue = len;
if (sumresidue)
memcpy(md.buffer, p, sumresidue);
}
int sum_end(char *sum)
/* The sum buffer only needs to be as long as the current checksum's digest
* len, not MAX_DIGEST_LEN. Note that for CSUM_MD4_ARCHAIC that is the full
* MD4_DIGEST_LEN even if the file-list code is going to ignore all but the
* first 2 bytes of it. */
void sum_end(char *sum)
{
if (protocol_version >= 30) {
md5_result(&md, (uchar *)sum);
return MD5_DIGEST_LEN;
#ifdef USE_OPENSSL
if (cur_sum_evp_md) {
EVP_DigestFinal_ex(ctx_evp, (uchar *)sum, NULL);
} else
#endif
switch (cur_sum_nni->num) {
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64_digest(xxh64_state));
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
SIVAL64(sum, 0, XXH3_64bits_digest(xxh3_state));
break;
case CSUM_XXH3_128: {
XXH128_hash_t digest = XXH3_128bits_digest(xxh3_state);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5:
md5_result(&ctx_md, (uchar *)sum);
break;
case CSUM_MD4:
case CSUM_MD4_OLD:
mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, sumresidue);
mdfour_result(&ctx_md, (uchar *)sum);
break;
case CSUM_MD4_BUSTED:
case CSUM_MD4_ARCHAIC:
if (sumresidue)
mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, sumresidue);
mdfour_result(&ctx_md, (uchar *)sum);
break;
case CSUM_NONE:
*sum = '\0';
break;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
if (sumresidue || protocol_version >= 27)
mdfour_update(&md, (uchar *)md.buffer, sumresidue);
mdfour_result(&md, (uchar *)sum);
return MD4_DIGEST_LEN;
}
#if defined SUPPORT_XXH3 || defined USE_OPENSSL
static void verify_digest(struct name_num_item *nni, BOOL check_auth_list)
{
#ifdef SUPPORT_XXH3
static int xxh3_result = 0;
#endif
#ifdef USE_OPENSSL
static int prior_num = 0, prior_flags = 0, prior_result = 0;
#endif
#ifdef SUPPORT_XXH3
if (nni->num == CSUM_XXH3_64 || nni->num == CSUM_XXH3_128) {
if (!xxh3_result) {
char buf[32816];
int j;
for (j = 0; j < (int)sizeof buf; j++)
buf[j] = ' ' + (j % 96);
sum_init(nni, 0);
sum_update(buf, 32816);
sum_update(buf, 31152);
sum_update(buf, 32474);
sum_update(buf, 9322);
xxh3_result = XXH3_64bits_digest(xxh3_state) != 0xadbcf16d4678d1de ? -1 : 1;
}
if (xxh3_result < 0)
nni->num = CSUM_gone;
return;
}
#endif
#ifdef USE_OPENSSL
if (BITS_SETnUNSET(nni->flags, NNI_EVP, NNI_BUILTIN|NNI_EVP_OK)) {
if (nni->num == prior_num && nni->flags == prior_flags) {
nni->flags = prior_result;
if (!(nni->flags & NNI_EVP))
nni->num = CSUM_gone;
} else {
prior_num = nni->num;
prior_flags = nni->flags;
if (!csum_evp_md(nni))
nni->num = CSUM_gone;
prior_result = nni->flags;
if (check_auth_list && (nni = get_nni_by_num(&valid_auth_checksums, prior_num)) != NULL)
verify_digest(nni, False);
}
}
#endif
}
#endif
void init_checksum_choices()
{
#if defined SUPPORT_XXH3 || defined USE_OPENSSL
struct name_num_item *nni;
#endif
if (initialized_choices)
return;
#if defined USE_OPENSSL && OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms();
#endif
#if defined SUPPORT_XXH3 || defined USE_OPENSSL
for (nni = valid_checksums.list; nni->name; nni++)
verify_digest(nni, True);
for (nni = valid_auth_checksums.list; nni->name; nni++)
verify_digest(nni, False);
#endif
initialized_choices = 1;
}

View File

@@ -2,7 +2,7 @@
* Implement the core of the --chmod option.
*
* Copyright (C) 2002 Scott Howard
* Copyright (C) 2005-2014 Wayne Davison
* Copyright (C) 2005-2020 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
@@ -44,7 +44,7 @@ struct chmod_mode_struct {
#define STATE_OCTAL_NUM 3
/* Parse a chmod-style argument, and break it down into one or more AND/OR
* pairs in a linked list. We return a pointer to new items on succcess
* pairs in a linked list. We return a pointer to new items on success
* (appending the items to the specified list), or NULL on error. */
struct chmod_mode_struct *parse_chmod(const char *modestr,
struct chmod_mode_struct **root_mode_ptr)

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2020 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
@@ -22,9 +22,11 @@
#include "rsync.h"
extern int dry_run;
extern int am_server;
extern int am_daemon;
extern int am_receiver;
extern int am_sender;
extern int io_error;
extern int keep_partial;
extern int got_xfer_error;
@@ -33,6 +35,7 @@ extern int output_needs_newline;
extern char *partial_dir;
extern char *logfile_name;
int called_from_signal_handler = 0;
BOOL shutting_down = False;
BOOL flush_ok_after_signal = False;
@@ -134,10 +137,9 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
if (DEBUG_GTE(EXIT, 2)) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
who_am_i(), code, file, line);
who_am_i(), code, src_file(file), line);
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
@@ -151,7 +153,6 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
}
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
@@ -171,18 +172,17 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
const char *fname = cleanup_fname;
cleanup_fname = NULL;
if (!partial_dir) {
/* We don't want to leave a partial file with a modern time or it
* could be skipped via --update. Setting the time to something
* really old also helps it to stand out as unfinished in an ls. */
tweak_modtime = 1;
cleanup_file->modtime = 0;
/* We don't want to leave a partial file with a modern time or it
* could be skipped via --update. Setting the time to something
* really old also helps it to stand out as unfinished in an ls. */
tweak_modtime = 1;
cleanup_file->modtime = 0;
}
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
cleanup_file, tweak_modtime, !partial_dir);
}
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
@@ -194,7 +194,6 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
if (!exit_code && !code)
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
@@ -222,37 +221,42 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
* we don't want to output a duplicate error. */
if ((exit_code && line > 0)
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) {
log_exit(exit_code, exit_file, exit_line);
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (DEBUG_GTE(EXIT, 1)) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
"about to call exit(%d)\n",
who_am_i(), first_code, exit_file, exit_line, exit_code);
"about to call exit(%d)%s\n",
who_am_i(), first_code, exit_file, exit_line, exit_code,
dry_run ? " (DRY RUN)" : "");
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1
&& exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) {
if (line > 0) {
if (DEBUG_GTE(EXIT, 3)) {
rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
who_am_i(), exit_code);
&& exit_code != RERR_TIMEOUT && !shutting_down) {
if (protocol_version >= 31 || am_receiver) {
if (line > 0) {
if (DEBUG_GTE(EXIT, 3)) {
rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
who_am_i(), exit_code);
}
send_msg_int(MSG_ERROR_EXIT, exit_code);
}
send_msg_int(MSG_ERROR_EXIT, exit_code);
if (!am_sender)
io_flush(MSG_FLUSH); /* Be sure to send all messages */
noop_io_until_death();
}
noop_io_until_death();
else if (!am_sender)
io_flush(MSG_FLUSH); /* Be sure to send all messages */
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
@@ -265,6 +269,8 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
break;
}
if (called_from_signal_handler)
_exit(exit_code);
exit(exit_code);
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2014 Wayne Davison
* Copyright (C) 2002-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
@@ -27,52 +27,60 @@
*/
#include "rsync.h"
#include "itypes.h"
extern int am_daemon;
static const char default_name[] = "UNKNOWN";
extern int am_server;
static const char proxyv2sig[] = "\r\n\r\n\0\r\nQUIT\n";
static char ipaddr_buf[100];
/**
* Return the IP addr of the client as a string
**/
#define PROXY_V2_SIG_SIZE ((int)sizeof proxyv2sig - 1)
#define PROXY_V2_HEADER_SIZE (PROXY_V2_SIG_SIZE + 1 + 1 + 2)
#define CMD_LOCAL 0
#define CMD_PROXY 1
#define PROXY_FAM_TCPv4 0x11
#define PROXY_FAM_TCPv6 0x21
#define GET_SOCKADDR_FAMILY(ss) ((struct sockaddr*)ss)->sa_family
static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len);
static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, char *name_buf, size_t name_buf_size);
static int valid_ipaddr(const char *s, int allow_scope);
/* Return the IP addr of the client as a string. */
char *client_addr(int fd)
{
static char addr_buf[100];
static int initialised;
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
if (initialised)
return addr_buf;
if (*ipaddr_buf)
return ipaddr_buf;
initialised = 1;
if (am_server) { /* daemon over --rsh mode */
if (am_daemon < 0) { /* daemon over --rsh mode */
char *env_str;
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
strlcpy(ipaddr_buf, "0.0.0.0", sizeof ipaddr_buf);
if ((env_str = getenv("REMOTE_HOST")) != NULL
|| (env_str = getenv("SSH_CONNECTION")) != NULL
|| (env_str = getenv("SSH_CLIENT")) != NULL
|| (env_str = getenv("SSH2_CLIENT")) != NULL) {
char *p;
strlcpy(addr_buf, env_str, sizeof addr_buf);
strlcpy(ipaddr_buf, env_str, sizeof ipaddr_buf);
/* Truncate the value to just the IP address. */
if ((p = strchr(addr_buf, ' ')) != NULL)
if ((p = strchr(ipaddr_buf, ' ')) != NULL)
*p = '\0';
}
} else {
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
if (valid_ipaddr(ipaddr_buf, True))
return ipaddr_buf;
}
return addr_buf;
}
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length, ipaddr_buf, sizeof ipaddr_buf, NULL, 0, NI_NUMERICHOST);
static int get_sockaddr_family(const struct sockaddr_storage *ss)
{
return ((struct sockaddr *) ss)->sa_family;
return ipaddr_buf;
}
@@ -89,71 +97,218 @@ static int get_sockaddr_family(const struct sockaddr_storage *ss)
* After translation from sockaddr to name we do a forward lookup to
* make sure nobody is spoofing PTR records.
**/
char *client_name(int fd)
char *client_name(const char *ipaddr)
{
static char name_buf[100];
static char port_buf[100];
static int initialised;
char port_buf[100];
struct sockaddr_storage ss;
socklen_t ss_len;
struct addrinfo hint, *answer;
int err;
if (initialised)
if (*name_buf)
return name_buf;
strlcpy(name_buf, default_name, sizeof name_buf);
initialised = 1;
if (strcmp(ipaddr, "0.0.0.0") == 0)
return name_buf;
memset(&ss, 0, sizeof ss);
if (am_server) { /* daemon over --rsh mode */
char *addr = client_addr(fd);
struct addrinfo hint, *answer;
int err;
if (strcmp(addr, "0.0.0.0") == 0)
return name_buf;
memset(&hint, 0, sizeof hint);
memset(&hint, 0, sizeof hint);
#ifdef AI_NUMERICHOST
hint.ai_flags = AI_NUMERICHOST;
hint.ai_flags = AI_NUMERICHOST;
#endif
hint.ai_socktype = SOCK_STREAM;
hint.ai_socktype = SOCK_STREAM;
if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
rprintf(FLOG, "malformed address %s: %s\n",
addr, gai_strerror(err));
return name_buf;
}
switch (answer->ai_family) {
case AF_INET:
ss_len = sizeof (struct sockaddr_in);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#ifdef INET6
case AF_INET6:
ss_len = sizeof (struct sockaddr_in6);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#endif
default:
exit_cleanup(RERR_SOCKETIO);
}
freeaddrinfo(answer);
} else {
ss_len = sizeof ss;
client_sockaddr(fd, &ss, &ss_len);
if ((err = getaddrinfo(ipaddr, NULL, &hint, &answer)) != 0) {
rprintf(FLOG, "malformed address %s: %s\n", ipaddr, gai_strerror(err));
return name_buf;
}
if (lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
port_buf, sizeof port_buf) == 0)
check_name(fd, &ss, name_buf, sizeof name_buf);
switch (answer->ai_family) {
case AF_INET:
ss_len = sizeof (struct sockaddr_in);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#ifdef INET6
case AF_INET6:
ss_len = sizeof (struct sockaddr_in6);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#endif
default:
NOISY_DEATH("Unknown ai_family value");
}
freeaddrinfo(answer);
/* reverse lookup */
err = getnameinfo((struct sockaddr*)&ss, ss_len, name_buf, sizeof name_buf,
port_buf, sizeof port_buf, NI_NAMEREQD | NI_NUMERICSERV);
if (err) {
strlcpy(name_buf, default_name, sizeof name_buf);
rprintf(FLOG, "name lookup failed for %s: %s\n", ipaddr, gai_strerror(err));
} else
check_name(ipaddr, &ss, name_buf, sizeof name_buf);
return name_buf;
}
/* Try to read a proxy protocol header (V1 or V2). Returns 1 on success or 0 on failure. */
int read_proxy_protocol_header(int fd)
{
union {
struct {
char line[108];
} v1;
struct {
char sig[PROXY_V2_SIG_SIZE];
char ver_cmd;
char fam;
unsigned char len[2];
union {
struct {
char src_addr[4];
char dst_addr[4];
char src_port[2];
char dst_port[2];
} ip4;
struct {
char src_addr[16];
char dst_addr[16];
char src_port[2];
char dst_port[2];
} ip6;
struct {
char src_addr[108];
char dst_addr[108];
} unx;
} addr;
} v2;
} hdr;
read_buf(fd, (char*)&hdr, PROXY_V2_SIG_SIZE);
if (memcmp(hdr.v2.sig, proxyv2sig, PROXY_V2_SIG_SIZE) == 0) { /* Proxy V2 */
int ver, cmd, size;
read_buf(fd, (char*)&hdr + PROXY_V2_SIG_SIZE, PROXY_V2_HEADER_SIZE - PROXY_V2_SIG_SIZE);
ver = (hdr.v2.ver_cmd & 0xf0) >> 4;
cmd = (hdr.v2.ver_cmd & 0x0f);
size = (hdr.v2.len[0] << 8) + hdr.v2.len[1];
if (ver != 2 || size + PROXY_V2_HEADER_SIZE > (int)sizeof hdr)
return 0;
/* Grab all the remaining data in the binary request. */
read_buf(fd, (char*)&hdr + PROXY_V2_HEADER_SIZE, size);
switch (cmd) {
case CMD_PROXY:
switch (hdr.v2.fam) {
case PROXY_FAM_TCPv4:
if (size != sizeof hdr.v2.addr.ip4)
return 0;
inet_ntop(AF_INET, hdr.v2.addr.ip4.src_addr, ipaddr_buf, sizeof ipaddr_buf);
return valid_ipaddr(ipaddr_buf, False);
#ifdef INET6
case PROXY_FAM_TCPv6:
if (size != sizeof hdr.v2.addr.ip6)
return 0;
inet_ntop(AF_INET6, hdr.v2.addr.ip6.src_addr, ipaddr_buf, sizeof ipaddr_buf);
return valid_ipaddr(ipaddr_buf, False);
#endif
default:
break;
}
/* For an unsupported protocol we'll ignore the proxy data (leaving ipaddr_buf unset)
* and accept the connection, which will get handled as a normal socket addr. */
return 1;
case CMD_LOCAL:
return 1;
default:
break;
}
return 0;
}
if (memcmp(hdr.v1.line, "PROXY", 5) == 0) { /* Proxy V1 */
char *endc, *sp, *p = hdr.v1.line + PROXY_V2_SIG_SIZE;
int port_chk;
*p = '\0';
if (!strchr(hdr.v1.line, '\n')) {
while (1) {
read_buf(fd, p, 1);
if (*p++ == '\n')
break;
if (p - hdr.v1.line >= (int)sizeof hdr.v1.line - 1)
return 0;
}
*p = '\0';
}
endc = strchr(hdr.v1.line, '\r');
if (!endc || endc[1] != '\n' || endc[2])
return 0;
*endc = '\0';
p = hdr.v1.line + 5;
if (!isSpace(p++))
return 0;
if (strncmp(p, "TCP4", 4) == 0)
p += 4;
else if (strncmp(p, "TCP6", 4) == 0)
p += 4;
else if (strncmp(p, "UNKNOWN", 7) == 0)
return 1;
else
return 0;
if (!isSpace(p++))
return 0;
if ((sp = strchr(p, ' ')) == NULL)
return 0;
*sp = '\0';
if (!valid_ipaddr(p, False))
return 0;
strlcpy(ipaddr_buf, p, sizeof ipaddr_buf); /* It will always fit when valid. */
p = sp + 1;
if ((sp = strchr(p, ' ')) == NULL)
return 0;
*sp = '\0';
if (!valid_ipaddr(p, False))
return 0;
/* Ignore destination address. */
p = sp + 1;
if ((sp = strchr(p, ' ')) == NULL)
return 0;
*sp = '\0';
port_chk = strtol(p, &endc, 10);
if (*endc || port_chk == 0)
return 0;
/* Ignore source port. */
p = sp + 1;
port_chk = strtol(p, &endc, 10);
if (*endc || port_chk == 0)
return 0;
/* Ignore destination port. */
return 1;
}
return 0;
}
/**
* Get the sockaddr for the client.
@@ -161,9 +316,7 @@ char *client_name(int fd)
* If it comes in as an ipv4 address mapped into IPv6 format then we
* convert it back to a regular IPv4.
**/
void client_sockaddr(int fd,
struct sockaddr_storage *ss,
socklen_t *ss_len)
static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len)
{
memset(ss, 0, sizeof *ss);
@@ -174,8 +327,8 @@ void client_sockaddr(int fd,
}
#ifdef INET6
if (get_sockaddr_family(ss) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
if (GET_SOCKADDR_FAMILY(ss) == AF_INET6
&& IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
/* OK, so ss is in the IPv6 family, but it is really
* an IPv4 address: something like
* "::ffff:10.130.1.2". If we use it as-is, then the
@@ -198,51 +351,20 @@ void client_sockaddr(int fd,
/* There is a macro to extract the mapped part
* (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
* to be present in the Linux headers. */
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof sin->sin_addr);
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12], sizeof sin->sin_addr);
}
#endif
}
/**
* Look up a name from @p ss into @p name_buf.
*
* @param fd file descriptor for client socket.
**/
int lookup_name(int fd, const struct sockaddr_storage *ss,
socklen_t ss_len,
char *name_buf, size_t name_buf_size,
char *port_buf, size_t port_buf_size)
{
int name_err;
/* reverse lookup */
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
name_buf, name_buf_size,
port_buf, port_buf_size,
NI_NAMEREQD | NI_NUMERICSERV);
if (name_err != 0) {
strlcpy(name_buf, default_name, name_buf_size);
rprintf(FLOG, "name lookup failed for %s: %s\n",
client_addr(fd), gai_strerror(name_err));
return name_err;
}
return 0;
}
/**
* Compare an addrinfo from the resolver to a sockinfo.
*
* Like strcmp, returns 0 for identical.
**/
int compare_addrinfo_sockaddr(const struct addrinfo *ai,
const struct sockaddr_storage *ss)
static int compare_addrinfo_sockaddr(const struct addrinfo *ai, const struct sockaddr_storage *ss)
{
int ss_family = get_sockaddr_family(ss);
int ss_family = GET_SOCKADDR_FAMILY(ss);
const char fn[] = "compare_addrinfo_sockaddr";
if (ai->ai_family != ss_family) {
@@ -258,8 +380,7 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
sin1 = (const struct sockaddr_in *) ss;
sin2 = (const struct sockaddr_in *) ai->ai_addr;
return memcmp(&sin1->sin_addr, &sin2->sin_addr,
sizeof sin1->sin_addr);
return memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof sin1->sin_addr);
}
#ifdef INET6
@@ -269,14 +390,13 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
sin1 = (const struct sockaddr_in6 *) ss;
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
if (ai->ai_addrlen < (int)sizeof (struct sockaddr_in6)) {
rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
fn, (int)ai->ai_addrlen);
return 1;
}
if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
sizeof sin1->sin6_addr))
if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof sin1->sin6_addr))
return 1;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
@@ -302,13 +422,11 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
* because it doesn't seem that it could be spoofed in any way, and
* getaddrinfo on random service names seems to cause problems on AIX.
**/
int check_name(int fd,
const struct sockaddr_storage *ss,
char *name_buf, size_t name_buf_size)
static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, char *name_buf, size_t name_buf_size)
{
struct addrinfo hints, *res, *res0;
int error;
int ss_family = get_sockaddr_family(ss);
int ss_family = GET_SOCKADDR_FAMILY(ss);
memset(&hints, 0, sizeof hints);
hints.ai_family = ss_family;
@@ -339,10 +457,82 @@ int check_name(int fd,
/* We hit the end of the list without finding an
* address that was the same as ss. */
rprintf(FLOG, "%s is not a known address for \"%s\": "
"spoofed address?\n", client_addr(fd), name_buf);
"spoofed address?\n", ipaddr, name_buf);
strlcpy(name_buf, default_name, name_buf_size);
}
freeaddrinfo(res0);
return 0;
}
/* Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */
static int valid_ipaddr(const char *s, int allow_scope)
{
int i;
if (strchr(s, ':') != NULL) { /* Only IPv6 has a colon. */
int count, saw_double_colon = 0;
int ipv4_at_end = 0;
if (*s == ':') { /* A colon at the start must be a :: */
if (*++s != ':')
return 0;
saw_double_colon = 1;
s++;
}
for (count = 0; count < 8; count++) {
if (!*s)
return saw_double_colon;
if (allow_scope && *s == '%') {
if (saw_double_colon)
break;
return 0;
}
if (strchr(s, ':') == NULL && strchr(s, '.') != NULL) {
if ((!saw_double_colon && count != 6) || (saw_double_colon && count > 6))
return 0;
ipv4_at_end = 1;
break;
}
if (!isHexDigit(s++)) /* Need 1-4 hex digits */
return 0;
if (isHexDigit(s) && isHexDigit(++s) && isHexDigit(++s) && isHexDigit(++s))
return 0;
if (*s == ':') {
if (!*++s)
return 0;
if (*s == ':') {
if (saw_double_colon)
return 0;
saw_double_colon = 1;
s++;
}
}
}
if (!ipv4_at_end) {
if (allow_scope && *s == '%')
for (s++; isAlNum(s); s++) { }
return !*s && s[-1] != '%';
}
}
/* IPv4 */
for (i = 0; i < 4; i++) {
long n;
char *end;
if (i && *s++ != '.')
return 0;
n = strtol(s, &end, 10);
if (n > 255 || n < 0 || end <= s || end > s+3)
return 0;
s = end;
}
return !*s;
}

View File

File diff suppressed because it is too large Load Diff

11
cmd-or-msg Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
srcdir=`dirname $0`
opt="$1"
shift
echo "$*"
if ! "${@}"; then
echo "If you can't fix the issue, re-run $srcdir/configure with --$opt."
exit 1
fi

657
compat.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) Andrew Tridgell 1996
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2004-2014 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
@@ -20,12 +20,8 @@
*/
#include "rsync.h"
int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0;
int compat_flags = 0;
int use_safe_inc_flist = 0;
#include "itypes.h"
#include "ifuncs.h"
extern int am_server;
extern int am_sender;
@@ -38,6 +34,7 @@ extern int preallocate_files;
extern int append_mode;
extern int fuzzy_basis;
extern int read_batch;
extern int write_batch;
extern int delay_updates;
extern int checksum_seed;
extern int basis_dir_cnt;
@@ -46,24 +43,51 @@ extern int protocol_version;
extern int protect_args;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_atimes;
extern int preserve_crtimes;
extern int preserve_acls;
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 do_compression;
extern int do_compression_level;
extern int do_compression_threads;
extern int saw_stderr_opt;
extern int msgs2stderr;
extern char *shell_cmd;
extern char *partial_dir;
extern char *dest_option;
extern char *files_from;
extern char *filesfrom_host;
extern const char *checksum_choice;
extern const char *compress_choice;
extern char *daemon_auth_choices;
extern filter_rule_list filter_list;
extern int need_unsorted_flist;
#ifdef ICONV_OPTION
extern iconv_t ic_send, ic_recv;
extern char *iconv_opt;
#endif
extern struct name_num_obj valid_checksums, valid_auth_checksums;
extern struct name_num_item *xfer_sum_nni;
int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0;
int compat_flags = 0;
int use_safe_inc_flist = 0;
int want_xattr_optim = 0;
int proper_seed_order = 0;
int inplace_partial = 0;
int do_negotiated_strings = 0;
int xmit_id0_names = 0;
struct name_num_item *xattr_sum_nni;
int xattr_sum_len = 0;
/* These index values are for the file-list's extra-attribute array. */
int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
int sender_symlink_iconv = 0; /* sender should convert symlink content */
@@ -72,10 +96,34 @@ int sender_symlink_iconv = 0; /* sender should convert symlink content */
int filesfrom_convert = 0;
#endif
#define MAX_NSTR_STRLEN 256
struct name_num_item valid_compressions_items[] = {
#ifdef SUPPORT_ZSTD
{ CPRES_ZSTD, 0, "zstd", NULL },
#endif
#ifdef SUPPORT_LZ4
{ CPRES_LZ4, 0, "lz4", NULL },
#endif
{ 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, 0, 0, valid_compressions_items
};
#define CF_INC_RECURSE (1<<0)
#define CF_SYMLINK_TIMES (1<<1)
#define CF_SYMLINK_ICONV (1<<2)
#define CF_SAFE_FLIST (1<<3)
#define CF_AVOID_XATTR_OPTIM (1<<4)
#define CF_CHKSUM_SEED_FIX (1<<5)
#define CF_INPLACE_PARTIAL_DIR (1<<6)
#define CF_VARINT_FLIST_FLAGS (1<<7)
#define CF_ID0_NAMES (1<<8)
static const char *client_info;
@@ -84,13 +132,9 @@ static const char *client_info;
* of that protocol for it to be advertised as available. */
static void check_sub_protocol(void)
{
char *dot;
const char *dot;
int their_protocol, their_sub;
#if SUBPROTOCOL_VERSION != 0
int our_sub = protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
#else
int our_sub = 0;
#endif
int our_sub = get_subprotocol_version();
/* client_info starts with VER.SUB string if client is a pre-release. */
if (!(their_protocol = atoi(client_info))
@@ -117,7 +161,13 @@ static void check_sub_protocol(void)
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;
@@ -125,17 +175,416 @@ void set_allow_inc_recurse(void)
&& (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;
}
void parse_compress_choice(int final_call)
{
if (valid_compressions.negotiated_nni)
do_compression = valid_compressions.negotiated_nni->num;
else if (compress_choice) {
struct name_num_item *nni = get_nni_by_name(&valid_compressions, compress_choice, -1);
if (!nni) {
rprintf(FERROR, "unknown compress name: %s\n", compress_choice);
exit_cleanup(RERR_UNSUPPORTED);
}
do_compression = nni->num;
if (am_server)
validate_choice_vs_env(NSTR_COMPRESS, do_compression, -1);
} else if (do_compression)
do_compression = CPRES_ZLIB;
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;
/* Snag the compression name for both write_batch's option output & the following debug output. */
if (valid_compressions.negotiated_nni)
compress_choice = valid_compressions.negotiated_nni->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_nni ? " negotiated" : "",
compress_choice, do_compression_level);
}
}
struct name_num_item *get_nni_by_name(struct name_num_obj *nno, const char *name, int len)
{
struct name_num_item *nni;
if (len < 0)
len = strlen(name);
for (nni = nno->list; nni->name; nni++) {
if (nni->num == CSUM_gone)
continue;
if (strncasecmp(name, nni->name, len) == 0 && nni->name[len] == '\0')
return nni;
}
return NULL;
}
struct name_num_item *get_nni_by_num(struct name_num_obj *nno, int num)
{
struct name_num_item *nni;
for (nni = nno->list; nni->name; nni++) {
if (num == nni->num)
return nni;
}
return NULL;
}
static void init_nno_saw(struct name_num_obj *nno, int val)
{
struct name_num_item *nni;
int cnt;
if (!nno->saw_len) {
for (nni = nno->list; nni->name; nni++) {
if (nni->num >= nno->saw_len)
nno->saw_len = nni->num + 1;
}
}
if (!nno->saw) {
nno->saw = new_array0(uchar, nno->saw_len);
/* We'll take this opportunity to set the main_nni values for duplicates. */
for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {
if (nni->num == CSUM_gone)
continue;
if (nno->saw[nni->num])
nni->main_nni = &nno->list[nno->saw[nni->num]-1];
else
nno->saw[nni->num] = cnt;
}
}
memset(nno->saw, val, nno->saw_len);
}
/* Simplify the user-provided string so that it contains valid names without any duplicates.
* It also sets the "saw" flags to a 1-relative count of which name was seen first. */
static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf, int tobuf_len)
{
char *to = tobuf, *tok = NULL;
int saw_tok = 0, cnt = 0;
while (1) {
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]) {
nno->saw[nni->num] = ++cnt;
if (nni->main_nni) {
to = tok + strlcpy(tok, nni->main_nni->name, tobuf_len - (tok - tobuf));
if (to - tobuf >= tobuf_len) {
to = tok - 1;
break;
}
}
} else
to = tok - (tok != tobuf);
saw_tok = 1;
tok = NULL;
}
if (!ch)
break;
continue;
}
if (!tok) {
if (to != tobuf)
*to++ = ' ';
tok = to;
}
if (to - tobuf >= tobuf_len - 1) {
to = tok - (tok != tobuf);
break;
}
*to++ = ch;
}
*to = '\0';
if (saw_tok && to == tobuf)
return strlcpy(tobuf, "INVALID", MAX_NSTR_STRLEN);
return to - tobuf;
}
static int parse_negotiate_str(struct name_num_obj *nno, char *tmpbuf)
{
struct name_num_item *nni, *ret = NULL;
int best = nno->saw_len; /* We want best == 1 from the client list, so start with a big number. */
char *space, *tok = tmpbuf;
while (tok) {
while (*tok == ' ') tok++; /* Should be unneeded... */
if (!*tok)
break;
if ((space = strchr(tok, ' ')) != NULL)
*space = '\0';
nni = get_nni_by_name(nno, tok, -1);
if (space) {
*space = ' ';
tok = space + 1;
} else
tok = NULL;
if (!nni || !nno->saw[nni->num] || best <= nno->saw[nni->num])
continue;
ret = nni;
best = nno->saw[nni->num];
if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
break;
}
if (ret) {
free(nno->saw);
nno->saw = NULL;
nno->negotiated_nni = ret->main_nni ? ret->main_nni : ret;
return 1;
}
return 0;
}
/* This routine is always called with a tmpbuf of MAX_NSTR_STRLEN length, but the
* buffer may be pre-populated with a "len" length string to use OR a len of -1
* to tell us to read a string from the fd. */
static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf, int len)
{
if (len < 0)
len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN);
if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
if (am_server)
rprintf(FINFO, "Client %s list (on server): %s\n", nno->type, tmpbuf);
else
rprintf(FINFO, "Server %s list (on client): %s\n", nno->type, tmpbuf);
}
if (len > 0 && parse_negotiate_str(nno, tmpbuf))
return;
if (!am_server || !do_negotiated_strings) {
char *cp = tmpbuf;
int j;
rprintf(FERROR, "Failed to negotiate a %s choice.\n", nno->type);
rprintf(FERROR, "%s list: %s\n", am_server ? "Client" : "Server", tmpbuf);
/* Recreate our original list from the saw values. This can't overflow our huge
* buffer because we don't have enough valid entries to get anywhere close. */
for (j = 1, *cp = '\0'; j <= nno->saw_len; j++) {
struct name_num_item *nni;
for (nni = nno->list; nni->name; nni++) {
if (nno->saw[nni->num] == j) {
*cp++ = ' ';
cp += strlcpy(cp, nni->name, MAX_NSTR_STRLEN - (cp - tmpbuf));
break;
}
}
}
if (!*tmpbuf)
strlcpy(cp, " INVALID", MAX_NSTR_STRLEN);
rprintf(FERROR, "%s list:%s\n", am_server ? "Server" : "Client", tmpbuf);
}
exit_cleanup(RERR_UNSUPPORTED);
}
static const char *getenv_nstr(int ntype)
{
const char *env_str = getenv(ntype == NSTR_COMPRESS ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
/* When writing a batch file, we always negotiate an old-style choice. */
if (write_batch)
env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
if (am_server && env_str) {
const char *cp = strchr(env_str, '&');
if (cp)
env_str = cp + 1;
}
return env_str;
}
void validate_choice_vs_env(int ntype, int num1, int num2)
{
struct name_num_obj *nno = ntype == NSTR_COMPRESS ? &valid_compressions : &valid_checksums;
const char *list_str = getenv_nstr(ntype);
char tmpbuf[MAX_NSTR_STRLEN];
if (!list_str)
return;
while (isSpace(list_str)) list_str++;
if (!*list_str)
return;
init_nno_saw(nno, 0);
parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
if (ntype == NSTR_CHECKSUM) /* If "md4" is in the env list, all the old MD4 choices are OK too. */
nno->saw[CSUM_MD4_ARCHAIC] = nno->saw[CSUM_MD4_BUSTED] = nno->saw[CSUM_MD4_OLD] = nno->saw[CSUM_MD4];
if (!nno->saw[num1] || (num2 >= 0 && !nno->saw[num2])) {
rprintf(FERROR, "Your --%s-choice value (%s) was refused by the server.\n",
ntype == NSTR_COMPRESS ? "compress" : "checksum",
ntype == NSTR_COMPRESS ? compress_choice : checksum_choice);
exit_cleanup(RERR_UNSUPPORTED);
}
free(nno->saw);
nno->saw = NULL;
}
/* 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.
* "none" is removed on the client side unless dup_markup != '\0'. */
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->num == CSUM_gone)
continue;
if (nni->main_nni) {
if (!dup_markup || nni->main_nni->num == CSUM_gone)
continue;
delim = dup_markup;
}
if (nni->num == 0 && !am_server && !dup_markup)
continue;
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, int ntype)
{
char tmpbuf[MAX_NSTR_STRLEN];
const char *list_str = getenv_nstr(ntype);
int len;
if (list_str && *list_str) {
init_nno_saw(nno, 0);
len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
list_str = tmpbuf;
} else
list_str = NULL;
if (!list_str || !*list_str)
len = get_default_nno_list(nno, tmpbuf, MAX_NSTR_STRLEN, '\0');
if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
if (am_server)
rprintf(FINFO, "Server %s list (on server): %s\n", nno->type, tmpbuf);
else
rprintf(FINFO, "Client %s list (on client): %s\n", nno->type, tmpbuf);
}
/* 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)
{
/* We send all the negotiation strings before we start to read them to help avoid a slow startup. */
init_checksum_choices();
if (!checksum_choice)
send_negotiate_str(f_out, &valid_checksums, NSTR_CHECKSUM);
if (do_compression && !compress_choice)
send_negotiate_str(f_out, &valid_compressions, NSTR_COMPRESS);
if (valid_checksums.saw) {
char tmpbuf[MAX_NSTR_STRLEN];
int len;
if (do_negotiated_strings)
len = -1;
else
len = strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, len);
}
if (valid_compressions.saw) {
char tmpbuf[MAX_NSTR_STRLEN];
int len;
if (do_negotiated_strings)
len = -1;
else
len = strlcpy(tmpbuf, "zlib", MAX_NSTR_STRLEN);
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, len);
}
/* 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)
valid_checksums.negotiated_nni = valid_compressions.negotiated_nni = NULL;
}
void setup_protocol(int f_out,int f_in)
{
if (am_sender)
file_extra_cnt += PTR_EXTRA_CNT;
assert(file_extra_cnt == 0);
assert(EXTRA64_CNT == 2 || EXTRA64_CNT == 1);
/* All int64 values must be set first so that they are guaranteed to be
* aligned for direct int64-pointer memory access. */
if (preserve_atimes)
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 file_extras64 union as well. */
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
else
file_extra_cnt++;
depth_ndx = ++file_extra_cnt;
if (preserve_uid)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
@@ -170,7 +619,7 @@ void setup_protocol(int f_out,int f_in)
if (remote_protocol < MIN_PROTOCOL_VERSION
|| remote_protocol > MAX_PROTOCOL_VERSION) {
rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
rprintf(FERROR,"(see the rsync manpage for an explanation)\n");
exit_cleanup(RERR_PROTOCOL);
}
if (remote_protocol < OLD_PROTOCOL_VERSION) {
@@ -190,6 +639,9 @@ void setup_protocol(int f_out,int f_in)
if (read_batch)
check_batch_flags();
if (!saw_stderr_opt && protocol_version <= 28 && am_server)
msgs2stderr = 0; /* The client side may not have stderr setup for us. */
#ifndef SUPPORT_PREALLOCATION
if (preallocate_files && !am_sender) {
rprintf(FERROR, "preallocation is not supported on this %s\n",
@@ -203,16 +655,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);
}
}
@@ -227,33 +679,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) {
@@ -265,13 +717,41 @@ void setup_protocol(int f_out,int f_in)
#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;
write_byte(f_out, compat_flags);
} else
compat_flags = read_byte(f_in);
if (strchr(client_info, 'x') != NULL)
compat_flags |= CF_AVOID_XATTR_OPTIM;
if (strchr(client_info, 'C') != NULL)
compat_flags |= CF_CHKSUM_SEED_FIX;
if (strchr(client_info, 'I') != NULL)
compat_flags |= CF_INPLACE_PARTIAL_DIR;
if (strchr(client_info, 'u') != NULL)
compat_flags |= CF_ID0_NAMES;
if (strchr(client_info, 'v') != NULL) {
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)
compat_flags |= CF_VARINT_FLIST_FLAGS;
write_byte(f_out, compat_flags);
} else
write_varint(f_out, compat_flags);
} else { /* read_varint() is compatible with the older write_byte() when the 0x80 bit isn't on. */
compat_flags = read_varint(f_in);
if (compat_flags & CF_VARINT_FLIST_FLAGS)
do_negotiated_strings = 1;
}
/* The inc_recurse var MUST be set to 0 or 1. */
inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
if (!xfer_flags_as_varint && preserve_crtimes) {
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
exit_cleanup(RERR_PROTOCOL);
}
if (am_sender) {
receiver_symlink_times = am_server
? strchr(client_info, 'L') != NULL
@@ -283,24 +763,29 @@ void setup_protocol(int f_out,int f_in)
#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) {
/* 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;
need_messages_from_generator = 1;
if (compat_flags & CF_INPLACE_PARTIAL_DIR)
inplace_partial = 1;
#ifdef CAN_SET_SYMLINK_TIMES
} else if (!am_sender) {
receiver_symlink_times = 1;
#endif
}
if (read_batch)
do_negotiated_strings = 0;
if (need_unsorted_flist && (!am_sender || inc_recurse))
unsort_ndx = ++file_extra_cnt;
@@ -321,11 +806,87 @@ void setup_protocol(int f_out,int f_in)
}
#endif
negotiate_the_strings(f_in, f_out);
if (am_server) {
if (!checksum_seed)
checksum_seed = time(NULL);
checksum_seed = time(NULL) ^ (getpid() << 6);
write_int(f_out, checksum_seed);
} else {
checksum_seed = read_int(f_in);
}
parse_checksum_choice(1); /* Sets file_sum_nni & xfer_sum_nni */
parse_compress_choice(1); /* Sets do_compression */
/* TODO in the future allow this algorithm to be chosen somehow, but it can't get too
* long or the size starts to cause a problem in the xattr abbrev/non-abbrev code. */
xattr_sum_nni = parse_csum_name(NULL, 0);
xattr_sum_len = csum_len_for_type(xattr_sum_nni->num, 0);
if (write_batch && !am_server)
write_batch_shell_file();
init_flist();
}
void output_daemon_greeting(int f_out, int am_client)
{
char tmpbuf[MAX_NSTR_STRLEN];
int our_sub = get_subprotocol_version();
init_checksum_choices();
get_default_nno_list(&valid_auth_checksums, tmpbuf, MAX_NSTR_STRLEN, '\0');
io_printf(f_out, "@RSYNCD: %d.%d %s\n", protocol_version, our_sub, tmpbuf);
if (am_client && DEBUG_GTE(NSTR, 2))
rprintf(FINFO, "Client %s list (on client): %s\n", valid_auth_checksums.type, tmpbuf);
}
void negotiate_daemon_auth(int f_out, int am_client)
{
char tmpbuf[MAX_NSTR_STRLEN];
int save_am_server = am_server;
int md4_is_old = 0;
if (!am_client)
am_server = 1;
if (daemon_auth_choices)
strlcpy(tmpbuf, daemon_auth_choices, MAX_NSTR_STRLEN);
else {
strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
md4_is_old = 1;
}
if (am_client) {
recv_negotiate_str(-1, &valid_auth_checksums, tmpbuf, strlen(tmpbuf));
if (DEBUG_GTE(NSTR, 1)) {
rprintf(FINFO, "Client negotiated %s: %s\n", valid_auth_checksums.type,
valid_auth_checksums.negotiated_nni->name);
}
} else {
if (!parse_negotiate_str(&valid_auth_checksums, tmpbuf)) {
get_default_nno_list(&valid_auth_checksums, tmpbuf, MAX_NSTR_STRLEN, '\0');
io_printf(f_out, "@ERROR: your client does not support one of our daemon-auth checksums: %s\n",
tmpbuf);
exit_cleanup(RERR_UNSUPPORTED);
}
}
am_server = save_am_server;
if (md4_is_old && valid_auth_checksums.negotiated_nni->num == CSUM_MD4) {
valid_auth_checksums.negotiated_nni->num = CSUM_MD4_OLD;
valid_auth_checksums.negotiated_nni->flags = 0;
}
}
int get_subprotocol_version()
{
#if SUBPROTOCOL_VERSION != 0
return protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
#else
return 0;
#endif
}

1694
config.guess vendored
View File

File diff suppressed because it is too large Load Diff

2963
config.sub vendored
View File

File diff suppressed because it is too large Load Diff

28
configure vendored
View File

@@ -4,24 +4,24 @@
# then transfer control to the configure.sh script to do the real work.
dir=`dirname $0`
realconfigure="$dir/configure.sh"
if test x"$dir" = x; then
dir=.
fi
if test ! -f "$realconfigure"; then
if test -f "$HOME/build_farm/build_test.fns"; then
# Test the included popt
set -- --with-included-popt "${@}"
# Allow the build farm to grab latest files via rsync.
actions='build fetch'
else
actions='build'
if test "$dir" = '.'; then
branch=`packaging/prep-auto-dir` || exit 1
if test x"$branch" != x; then
cd build || exit 1
dir=..
fi
if "$dir/prepare-source" $actions; then
:
else
fi
if test ! -f configure.sh; then
if ! "$dir/prepare-source" build; then
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
rm -f "$realconfigure"
rm -f configure.sh
exit 1
fi
fi
exec "$realconfigure" "${@}"
exec ./configure.sh --srcdir="$dir" "${@}"

View File

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
* Support the max connections option.
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2006-2020 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

View File

@@ -7,39 +7,54 @@ basically a summary of clientserver.c and authenticate.c.
This is the protocol used for rsync --daemon; i.e. connections to port
873 rather than invocations over a remote shell.
When the server accepts a connection, it prints a greeting
When the server accepts a connection, it prints a newline-terminated
greeting line:
@RSYNCD: <version>.<subprotocol>
@RSYNCD: <version>.<subprotocol> <digest1> <digestN>
where <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
'.' is a literal period, and <subprotocol> is the numeric subprotocol
version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases).
Protocols prior to 30 only output <version> alone. The daemon expects
to see a similar greeting back from the client. For protocols prior to
30, an absent ".<subprotocol>" value is assumed to be 0. For protocol
30, an absent value is a fatal error. The daemon then follows this line
with a free-format text message-of-the-day (if any is defined).
The <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
The <subprotocol> is the numeric subprotocol version (which is 0 for a
final protocol version, as the SUBPROTOCOL_VERSION define discusses).
The <digestN> names are the authentication digest algorithms that the
daemon supports, listed in order of preference.
An rsync prior to 3.2.7 omits the digest names. An rsync prior to 3.0.0
also omits the period and the <subprotocol> value. Since a final
protocol has a subprotocol value of 0, a missing subprotocol value is
assumed to be 0 for any protocol prior to 30. It is considered a fatal
error for protocol 30 and above to omit it. It is considered a fatal
error for protocol 32 and above to omit the digest name list (currently
31 is the newest protocol).
The daemon expects to see a similar greeting line back from the client.
Once received, the daemon follows the opening line with a free-format
text message-of-the-day (if any is defined).
The server is now in the connected state. The client can either send
the command
the command:
#list
to get a listing of modules, or the name of a module. After this, the
(to get a listing of modules) or the name of a module. After this, the
connection is now bound to a particular module. Access per host for
this module is now checked, as is per-module connection limits.
If authentication is required to use this module, the server will say
If authentication is required to use this module, the server will say:
@RSYNCD: AUTHREQD <challenge>
where <challenge> is a random string of base64 characters. The client
must respond with
must respond with:
<user> <response>
where <user> is the username they claim to be, and <response> is the
base64 form of the MD4 hash of challenge+password.
The <user> is the username they claim to be. The <response> is the
base64 form of the digest hash of the challenge+password string. The
chosen digest method is the most preferred client method that is also in
the server's list. If no digest list was explicitly provided, the side
expecting a list assumes the other side provided either the single name
"md5" (for a negotiated protocol 30 or 31), or the single name "md4"
(for an older protocol).
At this point the server applies all remaining constraints before
handing control to the client, including switching uid/gid, setting up
@@ -76,6 +91,13 @@ stay tuned (or write it yourself!).
------------
Protocol version changes
31 (2013-09-28, 3.1.0)
Initial release of protocol 31 had no changes. Rsync 3.2.7
introduced the suffixed list of digest names on the greeting
line. The presence of the list is allowed even if the greeting
indicates an older protocol version number.
30 (2007-10-04, 3.0.0pre1)
The use of a ".<subprotocol>" number was added to

114
daemon-parm.awk Executable file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/awk -f
# The caller must pass arg: daemon-parm.txt
# The resulting code is output into daemon-parm.h
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n"
sect = psect = defines = accessors = prior_ptype = ""
parms = "\nstatic const struct parm_struct parm_table[] = {"
comment_fmt = "\n/********** %s **********/\n"
tdstruct = "typedef struct {"
}
/^\s*$/ { next }
/^#/ { next }
/^Globals:/ {
if (defines != "") {
print "The Globals section must come first!"
defines = ""
exit
}
defines = tdstruct
values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "GLOBAL"
psect = ", P_GLOBAL, &Vars.g."
next
}
/^Locals:/ {
if (sect == "") {
print "The Locals section must come after the Globals!"
exit
}
defines = defines exps "} global_vars;\n\n" tdstruct
values = values exp_values "\n }, { /* Locals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "LOCAL"
psect = ", P_LOCAL, &Vars.l."
next
}
/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
ptype = $1
name = $2
$1 = $2 = ""
sub(/^[ \t]+/, "")
if (ptype != prior_ptype) {
comment = sprintf(comment_fmt, ptype)
defines = defines comment
values = values comment
parms = parms "\n"
accessors = accessors "\n"
prior_ptype = ptype
}
if (ptype == "STRING" || ptype == "PATH") {
atype = "STRING"
vtype = "char*"
} else if (ptype ~ /BOOL/) {
atype = vtype = "BOOL"
} else if (ptype == "CHAR") {
atype = "CHAR"
vtype = "char"
} else {
atype = "INTEGER"
vtype = "int"
}
# The name might be var_name|public_name
pubname = name
sub(/\|.*/, "", name)
sub(/.*\|/, "", pubname)
gsub(/_/, " ", pubname)
gsub(/-/, "", name)
if (ptype == "ENUM")
enum = "enum_" name
else
enum = "NULL"
defines = defines "\t" vtype " " name ";\n"
values = values "\t" $0 ", /* " name " */\n"
parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n"
accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n"
if (vtype == "char*") {
exps = exps "\tBOOL " name "_EXP;\n"
exp_values = exp_values "\tFalse, /* " name "_EXP */\n"
}
next
}
/./ {
print "Extraneous line:" $0
defines = ""
exit
}
END {
if (sect != "" && defines != "") {
defines = defines exps "} local_vars;\n\n"
defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n"
values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n"
parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n"
print heading defines values parms accessors > "daemon-parm.h"
} else {
print "Failed to parse the data in " ARGV[1]
exit 1
}
}

68
daemon-parm.txt Normal file
View File

@@ -0,0 +1,68 @@
Globals: ================================================================
STRING bind_address|address NULL
STRING daemon_chroot NULL
STRING daemon_gid NULL
STRING daemon_uid NULL
STRING motd_file NULL
STRING pid_file NULL
STRING socket_options NULL
INTEGER listen_backlog 5
INTEGER rsync_port|port 0
BOOL proxy_protocol False
Locals: =================================================================
STRING auth_users NULL
STRING charset NULL
STRING comment NULL
STRING dont_compress DEFAULT_DONT_COMPRESS
STRING early_exec NULL
STRING exclude NULL
STRING exclude_from NULL
STRING filter NULL
STRING gid NULL
STRING hosts_allow NULL
STRING hosts_deny NULL
STRING include NULL
STRING include_from NULL
STRING incoming_chmod NULL
STRING lock_file DEFAULT_LOCK_FILE
STRING log_file NULL
STRING log_format "%o %h [%a] %m (%u) %f %l"
STRING name NULL
STRING name_converter NULL
STRING outgoing_chmod NULL
STRING post-xfer_exec NULL
STRING pre-xfer_exec NULL
STRING refuse_options NULL
STRING secrets_file NULL
STRING syslog_tag "rsyncd"
STRING uid NULL
PATH path NULL
PATH temp_dir NULL
INTEGER max_connections 0
INTEGER max_verbosity 1
INTEGER timeout 0
ENUM syslog_facility LOG_DAEMON
BOOL fake_super False
BOOL forward_lookup True
BOOL ignore_errors False
BOOL ignore_nonreadable False
BOOL list True
BOOL read_only True
BOOL reverse_lookup True
BOOL strict_modes True
BOOL transfer_logging False
BOOL write_only False
BOOL3 munge_symlinks Unset
BOOL3 numeric_ids Unset
BOOL3 open_noatime Unset
BOOL3 use_chroot Unset

41
define-from-md.awk Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/awk -f
# The caller must pass args: -v hfile=NAME rsync.1.md
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */"
if (hfile ~ /compress/) {
define = "#define DEFAULT_DONT_COMPRESS"
prefix = "*."
} else {
define = "#define DEFAULT_CVSIGNORE"
prefix = ""
}
value_list = ""
}
/^ > [^ ]+$/ {
gsub(/`/, "")
if (value_list != "") value_list = value_list " "
value_list = value_list prefix $2
next
}
value_list ~ /\.gz / && hfile ~ /compress/ {
exit
}
value_list ~ /SCCS / && hfile ~ /cvsignore/ {
exit
}
value_list = ""
END {
if (value_list != "")
print heading "\n\n" define " \"" value_list "\"" > hfile
else {
print "Failed to find a value list in " ARGV[1] " for " hfile
exit 1
}
}

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2024 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
@@ -89,8 +89,8 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
if (DEBUG_GTE(DEL, 1)) {
rprintf(FINFO,
"mount point, %s, pins parent directory\n",
f_name(fp, NULL));
"mount point, %s, pins parent directory\n",
f_name(fp, NULL));
}
ret = DR_NOT_EMPTY;
continue;
@@ -188,7 +188,7 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
stats.deleted_symlinks++;
#endif
else if (IS_DEVICE(mode))
stats.deleted_symlinks++;
stats.deleted_devices++;
else
stats.deleted_specials++;
}

View File

@@ -126,7 +126,7 @@
<para><option>-P</option>
Display a progress indicator while files are transferred. This should
normally be ommitted if rsync is not run on a terminal.
normally be omitted if rsync is not run on a terminal.
</para>
</section>
@@ -348,4 +348,4 @@ running rsync giving the network directory.
<para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
</appendix>
</book>
</book>

View File

@@ -2,7 +2,7 @@
* Error codes returned by rsync.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2019 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

569
exclude.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2024 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
@@ -21,19 +21,25 @@
*/
#include "rsync.h"
#include "ifuncs.h"
extern int am_server;
extern int am_sender;
extern int am_generator;
extern int eol_nulls;
extern int io_error;
extern int xfer_dirs;
extern int recurse;
extern int local_server;
extern int prune_empty_dirs;
extern int ignore_perishable;
extern int relative_paths;
extern int delete_mode;
extern int delete_excluded;
extern int cvs_exclude;
extern int sanitize_paths;
extern int protocol_version;
extern int trust_sender_args;
extern int module_id;
extern char curr_dir[MAXPATHLEN];
@@ -43,6 +49,11 @@ extern unsigned int module_dirlen;
filter_rule_list filter_list = { .debug_type = "" };
filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" };
filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" };
filter_rule_list implied_filter_list = { .debug_type = " [implied]" };
int saw_xattr_filter = 0;
int trust_sender_args = 0;
int trust_sender_filter = 0;
/* Need room enough for ":MODS " prefix plus some room to grow. */
#define MAX_RULE_PREFIX (16)
@@ -67,6 +78,10 @@ static filter_rule **mergelist_parents;
static int mergelist_cnt = 0;
static int mergelist_size = 0;
#define LOCAL_RULE 1
#define REMOTE_RULE 2
static uchar cur_elide_value = REMOTE_RULE;
/* Each filter_list_struct describes a singly-linked list by keeping track
* of both the head and tail pointers. The list is slightly unusual in that
* a parent-dir's content can be appended to the end of the local list in a
@@ -100,52 +115,44 @@ static int mergelist_size = 0;
static void teardown_mergelist(filter_rule *ex)
{
int j;
if (!ex->u.mergelist)
return;
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] deactivating mergelist #%d%s\n",
who_am_i(), mergelist_cnt - 1,
ex->u.mergelist->debug_type);
}
/* We should deactivate mergelists in LIFO order. */
assert(mergelist_cnt > 0);
assert(ex == mergelist_parents[mergelist_cnt - 1]);
/* The parent_dirscan filters should have been freed. */
assert(ex->u.mergelist->parent_dirscan_head == NULL);
free(ex->u.mergelist->debug_type);
free(ex->u.mergelist);
mergelist_cnt--;
for (j = 0; j < mergelist_cnt; j++) {
if (mergelist_parents[j] == ex) {
mergelist_parents[j] = NULL;
break;
}
}
while (mergelist_cnt && mergelist_parents[mergelist_cnt-1] == NULL)
mergelist_cnt--;
}
static void free_filter(filter_rule *ex)
{
if (ex->rflags & FILTRULE_PERDIR_MERGE)
teardown_mergelist(ex);
free(ex->pattern);
free(ex);
}
static void free_filters(filter_rule *head)
static void free_filters(filter_rule *ent)
{
filter_rule *rev_head = NULL;
/* Reverse the list so we deactivate mergelists in the proper LIFO
* order. */
while (head) {
filter_rule *next = head->next;
head->next = rev_head;
rev_head = head;
head = next;
}
while (rev_head) {
filter_rule *prev = rev_head->next;
/* Tear down mergelists here, not in free_filter, so that we
* affect only real filter lists and not temporarily allocated
* filters. */
if (rev_head->rflags & FILTRULE_PERDIR_MERGE)
teardown_mergelist(rev_head);
free_filter(rev_head);
rev_head = prev;
while (ent) {
filter_rule *next = ent->next;
free_filter(ent);
ent = next;
}
}
@@ -157,13 +164,17 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
{
const char *cp;
unsigned int pre_len, suf_len, slash_cnt = 0;
char *mention_rule_suffix;
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s\n",
if (DEBUG_GTE(FILTER, 1) && pat_len && (pat[pat_len-1] == ' ' || pat[pat_len-1] == '\t'))
mention_rule_suffix = " -- CAUTION: trailing whitespace!";
else
mention_rule_suffix = DEBUG_GTE(FILTER, 2) ? "" : NULL;
if (mention_rule_suffix) {
rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s%s\n",
who_am_i(), get_rule_prefix(rule, pat, 0, NULL),
(int)pat_len, pat,
(rule->rflags & FILTRULE_DIRECTORY) ? "/" : "",
listp->debug_type);
(int)pat_len, pat, (rule->rflags & FILTRULE_DIRECTORY) ? "/" : "",
listp->debug_type, mention_rule_suffix);
}
/* These flags also indicate that we're reading a list that
@@ -205,8 +216,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
} else
suf_len = 0;
if (!(rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1)))
out_of_memory("add_rule");
rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1);
if (pre_len) {
memcpy(rule->pattern, dirbuf + module_dirlen, pre_len);
for (cp = rule->pattern; cp < rule->pattern + pre_len; cp++) {
@@ -214,6 +224,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
slash_cnt++;
}
}
rule->elide = 0;
strlcpy(rule->pattern + pre_len, pat, pat_len + 1);
pat_len += pre_len;
if (suf_len) {
@@ -252,7 +263,10 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
* add it again. */
for (i = 0; i < mergelist_cnt; i++) {
filter_rule *ex = mergelist_parents[i];
const char *s = strrchr(ex->pattern, '/');
const char *s;
if (!ex)
continue;
s = strrchr(ex->pattern, '/');
if (s)
s++;
else
@@ -264,20 +278,14 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
}
}
if (!(lp = new_array(filter_rule_list, 1)))
out_of_memory("add_rule");
lp->head = lp->tail = lp->parent_dirscan_head = NULL;
lp = new_array0(filter_rule_list, 1);
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
out_of_memory("add_rule");
rule->u.mergelist = lp;
if (mergelist_cnt == mergelist_size) {
mergelist_size += 5;
mergelist_parents = realloc_array(mergelist_parents,
filter_rule *,
mergelist_size);
if (!mergelist_parents)
out_of_memory("add_rule");
mergelist_parents = realloc_array(mergelist_parents, filter_rule *, mergelist_size);
}
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] activating mergelist #%d%s\n",
@@ -297,16 +305,288 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
}
}
static void clear_filter_list(filter_rule_list *listp)
/* If the wildcards failed, the remote shell might give us a file matching the literal
* wildcards. Since "*" & "?" already match themselves, this just needs to deal with
* failed "[foo]" idioms.
*/
static void maybe_add_literal_brackets_rule(filter_rule const *based_on, int arg_len)
{
if (listp->tail) {
/* Truncate any inherited items from the local list. */
listp->tail->next = NULL;
/* Now free everything that is left. */
free_filters(listp->head);
filter_rule *rule;
const char *arg = based_on->pattern, *cp;
char *p;
int cnt = 0;
if (arg_len < 0)
arg_len = strlen(arg);
for (cp = arg; *cp; cp++) {
if (*cp == '\\' && cp[1]) {
cp++;
} else if (*cp == '[')
cnt++;
}
if (!cnt)
return;
rule = new0(filter_rule);
rule->rflags = based_on->rflags;
rule->u.slash_cnt = based_on->u.slash_cnt;
p = rule->pattern = new_array(char, arg_len + cnt + 1);
for (cp = arg; *cp; ) {
if (*cp == '\\' && cp[1]) {
*p++ = *cp++;
} else if (*cp == '[')
*p++ = '\\';
*p++ = *cp++;
}
*p++ = '\0';
rule->next = implied_filter_list.head;
implied_filter_list.head = rule;
if (DEBUG_GTE(FILTER, 3)) {
rprintf(FINFO, "[%s] add_implied_include(%s%s)\n", who_am_i(), rule->pattern,
rule->rflags & FILTRULE_DIRECTORY ? "/" : "");
}
}
static char *partial_string_buf = NULL;
static int partial_string_len = 0;
void implied_include_partial_string(const char *s_start, const char *s_end)
{
partial_string_len = s_end - s_start;
if (partial_string_len <= 0 || partial_string_len >= MAXPATHLEN) { /* too-large should be impossible... */
partial_string_len = 0;
return;
}
if (!partial_string_buf)
partial_string_buf = new_array(char, MAXPATHLEN);
memcpy(partial_string_buf, s_start, partial_string_len);
}
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;
}
partial_string_len = 0; /* paranoia */
}
/* Each arg the client sends to the remote sender turns into an implied include
* that the receiver uses to validate the file list from the sender. */
void add_implied_include(const char *arg, int skip_daemon_module)
{
int arg_len, saw_wild = 0, saw_live_open_brkt = 0, backslash_cnt = 0;
int slash_cnt = 0;
const char *cp;
char *p;
if (trust_sender_args)
return;
if (partial_string_len) {
arg_len = strlen(arg);
if (partial_string_len + arg_len >= MAXPATHLEN) {
partial_string_len = 0;
return; /* Should be impossible... */
}
memcpy(partial_string_buf + partial_string_len, arg, arg_len + 1);
partial_string_len = 0;
arg = partial_string_buf;
}
if (skip_daemon_module) {
if ((cp = strchr(arg, '/')) != NULL)
arg = cp + 1;
else
arg = "";
}
if (relative_paths) {
if ((cp = strstr(arg, "/./")) != NULL)
arg = cp + 3;
} else if ((cp = strrchr(arg, '/')) != NULL) {
arg = cp + 1;
}
if (*arg == '.' && arg[1] == '\0')
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++)
arg_len++;
saw_wild = 1;
}
arg_len++; /* Leave room for the prefixed slash */
p = new_pat = new_array(char, arg_len + 1);
*p++ = '/';
slash_cnt++;
for (cp = arg; *cp; ) {
switch (*cp) {
case '\\':
if (cp[1] == ']') {
if (!saw_wild)
cp++; /* A \] in a non-wild filter causes a problem, so drop the \ . */
} else if (!strchr("*[?", cp[1])) {
backslash_cnt++;
if (saw_wild)
*p++ = '\\';
}
*p++ = *cp++;
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++;
} else {
slash_cnt++;
*p++ = *cp++;
}
break;
case '.':
if (p[-1] == '/') {
if (cp[1] == '/') {
cp += 2;
if (!*cp) {
slash_cnt--;
p--;
}
} else if (cp[1] == '\0') {
cp++;
slash_cnt--;
p--;
} else
*p++ = *cp++;
} else
*p++ = *cp++;
break;
case '[':
saw_live_open_brkt = 1;
*p++ = *cp++;
break;
default:
*p++ = *cp++;
break;
}
}
*p = '\0';
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) {
int sub_slash_cnt = slash_cnt;
while ((p = strrchr(new_pat, '/')) != NULL && p != new_pat) {
filter_rule const *ent;
filter_rule *R_rule;
int found = 0;
*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) {
*p = '/';
break; /* We added all parent dirs already */
}
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(new_pat, "*[?\\"))
R_rule->rflags |= FILTRULE_WILD;
R_rule->pattern = strdup(new_pat);
R_rule->u.slash_cnt = --sub_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);
}
for (p = new_pat; sub_slash_cnt < slash_cnt; sub_slash_cnt++) {
p += strlen(p);
*p = '/';
}
}
}
}
listp->head = listp->tail = NULL;
if (recurse || xfer_dirs) {
/* Now create a rule with an added "/" & "**" or "*" at the end */
filter_rule *rule = new0(filter_rule);
rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD;
if (recurse)
rule->rflags |= FILTRULE_WILD2;
/* We must leave enough room for / * * \0. */
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; ) { /* Note that arg_len != 0 because backslash_cnt > 0 */
if (*cp == '\\')
*p++ = '\\';
*p++ = *cp++;
}
} else {
p = rule->pattern = new_array(char, arg_len + 3 + 1);
if (arg_len) {
memcpy(p, arg, arg_len);
p += arg_len;
}
}
*p++ = '/';
*p++ = '*';
if (recurse)
*p++ = '*';
*p = '\0';
rule->u.slash_cnt = slash_cnt + 1;
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(), rule->pattern);
if (saw_live_open_brkt)
maybe_add_literal_brackets_rule(rule, p - rule->pattern);
}
}
/* This frees any non-inherited items, leaving just inherited items on the list. */
static void pop_filter_list(filter_rule_list *listp)
{
filter_rule *inherited;
if (!listp->tail)
return;
inherited = listp->tail->next;
/* Truncate any inherited items from the local list. */
listp->tail->next = NULL;
/* Now free everything that is left. */
free_filters(listp->head);
listp->head = inherited;
listp->tail = NULL;
}
/* This returns an expanded (absolute) filename for the merge-file name if
@@ -440,7 +720,8 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex,
parent_dirscan = True;
while (*y) {
char save[MAXPATHLEN];
strlcpy(save, y, MAXPATHLEN);
/* copylen is strlen(y) which is < MAXPATHLEN. +1 for \0 */
size_t copylen = strlcpy(save, y, MAXPATHLEN) + 1;
*y = '\0';
dirbuf_len = y - dirbuf;
strlcpy(x, ex->pattern, MAXPATHLEN - (x - buf));
@@ -454,11 +735,9 @@ static BOOL setup_merge_file(int mergelist_num, filter_rule *ex,
lp->head = NULL;
}
lp->tail = NULL;
strlcpy(y, save, MAXPATHLEN);
strlcpy(y, save, copylen);
while ((*x++ = *y++) != '/') {}
}
/* Save current head for freeing when the mergelist becomes inactive. */
lp->parent_dirscan_head = lp->head;
parent_dirscan = False;
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] completed parent_dirscan for mergelist #%d%s\n",
@@ -496,20 +775,23 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
push = (struct local_filter_state *)new_array(char,
sizeof (struct local_filter_state)
+ (mergelist_cnt-1) * sizeof (filter_rule_list));
if (!push)
out_of_memory("push_local_filters");
push->mergelist_cnt = mergelist_cnt;
for (i = 0; i < mergelist_cnt; i++) {
memcpy(&push->mergelists[i], mergelist_parents[i]->u.mergelist,
sizeof (filter_rule_list));
filter_rule *ex = mergelist_parents[i];
if (!ex)
continue;
memcpy(&push->mergelists[i], ex->u.mergelist, sizeof (filter_rule_list));
}
/* Note: parse_filter_file() might increase mergelist_cnt, so keep
* this loop separate from the above loop. */
for (i = 0; i < mergelist_cnt; i++) {
filter_rule *ex = mergelist_parents[i];
filter_rule_list *lp = ex->u.mergelist;
filter_rule_list *lp;
if (!ex)
continue;
lp = ex->u.mergelist;
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] pushing mergelist #%d%s\n",
@@ -553,44 +835,38 @@ void pop_local_filters(void *mem)
for (i = mergelist_cnt; i-- > 0; ) {
filter_rule *ex = mergelist_parents[i];
filter_rule_list *lp = ex->u.mergelist;
filter_rule_list *lp;
if (!ex)
continue;
lp = ex->u.mergelist;
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] popping mergelist #%d%s\n",
who_am_i(), i, lp->debug_type);
}
clear_filter_list(lp);
if (i >= old_mergelist_cnt) {
/* This mergelist does not exist in the state to be
* restored. Free its parent_dirscan list to clean up
* any per-dir mergelists defined there so we don't
* crash trying to restore nonexistent state for them
* below. (Counterpart to setup_merge_file call in
* push_local_filters. Must be done here, not in
* free_filter, for LIFO order.) */
pop_filter_list(lp);
if (i >= old_mergelist_cnt && lp->head) {
/* This mergelist does not exist in the state to be restored, but it
* still has inherited rules. This can sometimes happen if a per-dir
* merge file calls setup_merge_file() in push_local_filters() and that
* leaves some inherited rules that aren't in the pushed list state. */
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] freeing parent_dirscan filters of mergelist #%d%s\n",
who_am_i(), i, ex->u.mergelist->debug_type);
}
free_filters(lp->parent_dirscan_head);
lp->parent_dirscan_head = NULL;
pop_filter_list(lp);
}
}
/* If we cleaned things up properly, the only still-active mergelists
* should be those with a state to be restored. */
assert(mergelist_cnt == old_mergelist_cnt);
if (!pop)
return; /* No state to restore. */
if (!pop) {
/* No state to restore. */
return;
}
for (i = 0; i < mergelist_cnt; i++) {
memcpy(mergelist_parents[i]->u.mergelist, &pop->mergelists[i],
sizeof (filter_rule_list));
for (i = 0; i < old_mergelist_cnt; i++) {
filter_rule *ex = mergelist_parents[i];
if (!ex)
continue;
memcpy(ex->u.mergelist, &pop->mergelists[i], sizeof (filter_rule_list));
}
free(pop);
@@ -624,15 +900,18 @@ void change_local_filter_dir(const char *dname, int dlen, int dir_depth)
filt_array[cur_depth] = push_local_filters(dname, dlen);
}
static int rule_matches(const char *fname, filter_rule *ex, int name_is_dir)
static int rule_matches(const char *fname, filter_rule *ex, int name_flags)
{
int slash_handling, str_cnt = 0, anchored_match = 0;
int ret_match = ex->rflags & FILTRULE_NEGATE ? 0 : 1;
char *p, *pattern = ex->pattern;
const char *p, *pattern = ex->pattern;
const char *strings[16]; /* more than enough */
const char *name = fname + (*fname == '/');
if (!*name)
if (!*name || ex->elide == cur_elide_value)
return 0;
if (!(name_flags & NAME_IS_XATTR) ^ !(ex->rflags & FILTRULE_XATTR))
return 0;
if (!ex->u.slash_cnt && !(ex->rflags & FILTRULE_WILD2)) {
@@ -652,7 +931,7 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_is_dir)
strings[str_cnt++] = "/";
}
strings[str_cnt++] = name;
if (name_is_dir) {
if (name_flags & NAME_IS_DIR) {
/* Allow a trailing "/"+"***" to match the directory. */
if (ex->rflags & FILTRULE_WILD3_SUFFIX)
strings[str_cnt++] = "/";
@@ -704,27 +983,60 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_is_dir)
static void report_filter_result(enum logcode code, char const *name,
filter_rule const *ent,
int name_is_dir, const char *type)
int name_flags, const char *type)
{
int log_level = am_sender || am_generator ? 1 : 3;
/* If a trailing slash is present to match only directories,
* then it is stripped out by add_rule(). So as a special
* case we add it back in here. */
if (DEBUG_GTE(FILTER, 1)) {
* case we add it back in the log output. */
if (DEBUG_GTE(FILTER, log_level)) {
static char *actions[2][2]
= { {"show", "hid"}, {"risk", "protect"} };
const char *w = who_am_i();
const char *t = name_flags & NAME_IS_XATTR ? "xattr"
: name_flags & NAME_IS_DIR ? "directory"
: "file";
rprintf(code, "[%s] %sing %s %s because of pattern %s%s%s\n",
w, actions[*w!='s'][!(ent->rflags & FILTRULE_INCLUDE)],
name_is_dir ? "directory" : "file", name, ent->pattern,
w, actions[*w=='g'][!(ent->rflags & FILTRULE_INCLUDE)],
t, name, ent->pattern,
ent->rflags & FILTRULE_DIRECTORY ? "/" : "", type);
}
}
/* This function is used to check if a file should be included/excluded
* from the list of files based on its name and type etc. The value of
* filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
int name_is_excluded(const char *fname, int name_flags, int filter_level)
{
if (daemon_filter_list.head && check_filter(&daemon_filter_list, FLOG, fname, name_flags) < 0) {
if (!(name_flags & NAME_IS_XATTR))
errno = ENOENT;
return 1;
}
if (filter_level != ALL_FILTERS)
return 0;
if (filter_list.head && check_filter(&filter_list, FINFO, fname, name_flags) < 0)
return 1;
return 0;
}
int check_server_filter(filter_rule_list *listp, enum logcode code, const char *name, int name_flags)
{
int ret;
cur_elide_value = LOCAL_RULE;
ret = check_filter(listp, code, name, name_flags);
cur_elide_value = REMOTE_RULE;
return ret;
}
/* Return -1 if file "name" is defined to be excluded by the specified
* exclude list, 1 if it is included, and 0 if it was not matched. */
int check_filter(filter_rule_list *listp, enum logcode code,
const char *name, int name_is_dir)
const char *name, int name_flags)
{
filter_rule *ent;
@@ -732,22 +1044,19 @@ int check_filter(filter_rule_list *listp, enum logcode code,
if (ignore_perishable && ent->rflags & FILTRULE_PERISHABLE)
continue;
if (ent->rflags & FILTRULE_PERDIR_MERGE) {
int rc = check_filter(ent->u.mergelist, code, name,
name_is_dir);
int rc = check_filter(ent->u.mergelist, code, name, name_flags);
if (rc)
return rc;
continue;
}
if (ent->rflags & FILTRULE_CVS_IGNORE) {
int rc = check_filter(&cvs_filter_list, code, name,
name_is_dir);
int rc = check_filter(&cvs_filter_list, code, name, name_flags);
if (rc)
return rc;
continue;
}
if (rule_matches(name, ent, name_is_dir)) {
report_filter_result(code, name, ent, name_is_dir,
listp->debug_type);
if (rule_matches(name, ent, name_flags)) {
report_filter_result(code, name, ent, name_flags, listp->debug_type);
return ent->rflags & FILTRULE_INCLUDE ? 1 : -1;
}
}
@@ -798,8 +1107,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
if (!*s)
return NULL;
if (!(rule = new0(filter_rule)))
out_of_memory("parse_rule_tok");
rule = new0(filter_rule);
/* Inherit from the template. Don't inherit FILTRULES_SIDES; we check
* that later. */
@@ -871,8 +1179,9 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
}
switch (ch) {
case ':':
trust_sender_filter = 1;
rule->rflags |= FILTRULE_PERDIR_MERGE
| FILTRULE_FINISH_SETUP;
| FILTRULE_FINISH_SETUP;
/* FALL THROUGH */
case '.':
rule->rflags |= FILTRULE_MERGE_FILE;
@@ -972,6 +1281,10 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
goto invalid;
rule->rflags |= FILTRULE_WORD_SPLIT;
break;
case 'x':
rule->rflags |= FILTRULE_XATTR;
saw_xattr_filter = 1;
break;
}
}
if (*s)
@@ -1024,16 +1337,6 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
return rule;
}
static char default_cvsignore[] =
/* These default ignored items come from the CVS manual. */
"RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"
" .make.state .nse_depinfo *~ #* .#* ,* _$* *$"
" *.old *.bak *.BAK *.orig *.rej .del-*"
" *.a *.olb *.o *.obj *.so *.exe"
" *.Z *.elc *.ln core"
/* The rest we added to suit ourself. */
" .svn/ .git/ .hg/ .bzr/";
static void get_cvs_excludes(uint32 rflags)
{
static int initialized = 0;
@@ -1043,7 +1346,7 @@ static void get_cvs_excludes(uint32 rflags)
return;
initialized = 1;
parse_filter_str(&cvs_filter_list, default_cvsignore,
parse_filter_str(&cvs_filter_list, default_cvsignore(),
rule_template(rflags | (protocol_version >= 30 ? FILTRULE_PERISHABLE : 0)),
0);
@@ -1093,7 +1396,8 @@ void parse_filter_str(filter_rule_list *listp, const char *rulestr,
"[%s] clearing filter list%s\n",
who_am_i(), listp->debug_type);
}
clear_filter_list(listp);
pop_filter_list(listp);
listp->head = NULL;
goto free_continue;
}
@@ -1106,8 +1410,7 @@ void parse_filter_str(filter_rule_list *listp, const char *rulestr,
const char *name;
filter_rule *excl_self;
if (!(excl_self = new0(filter_rule)))
out_of_memory("parse_filter_str");
excl_self = new0(filter_rule);
/* Find the beginning of the basename and add an exclude for it. */
for (name = pat + pat_len; name > pat && name[-1] != '/'; name--) {}
add_rule(listp, name, (pat + pat_len) - name, excl_self, 0);
@@ -1258,6 +1561,8 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
}
if (rule->rflags & FILTRULE_EXCLUDE_SELF)
*op++ = 'e';
if (rule->rflags & FILTRULE_XATTR)
*op++ = 'x';
if (rule->rflags & FILTRULE_SENDER_SIDE
&& (!for_xfer || protocol_version >= 29))
*op++ = 's';
@@ -1283,7 +1588,7 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
static void send_rules(int f_out, filter_rule_list *flp)
{
filter_rule *ent, *prev = NULL;
filter_rule *ent;
for (ent = flp->head; ent; ent = ent->next) {
unsigned int len, plen, dlen;
@@ -1298,21 +1603,15 @@ static void send_rules(int f_out, filter_rule_list *flp)
* merge files as an optimization (since they can only have
* include/exclude rules). */
if (ent->rflags & FILTRULE_SENDER_SIDE)
elide = am_sender ? 1 : -1;
elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
if (ent->rflags & FILTRULE_RECEIVER_SIDE)
elide = elide ? 0 : am_sender ? -1 : 1;
elide = elide ? 0 : am_sender ? REMOTE_RULE : LOCAL_RULE;
else if (delete_excluded && !elide
&& (!(ent->rflags & FILTRULE_PERDIR_MERGE)
|| ent->rflags & FILTRULE_NO_PREFIXES))
elide = am_sender ? 1 : -1;
if (elide < 0) {
if (prev)
prev->next = ent->next;
else
flp->head = ent->next;
} else
prev = ent;
if (elide > 0)
elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
ent->elide = elide;
if (elide == LOCAL_RULE)
continue;
if (ent->rflags & FILTRULE_CVS_IGNORE
&& !(ent->rflags & FILTRULE_MERGE_FILE)) {
@@ -1340,7 +1639,6 @@ static void send_rules(int f_out, filter_rule_list *flp)
if (dlen)
write_byte(f_out, '/');
}
flp->tail = prev;
}
/* This is only called by the client. */
@@ -1376,8 +1674,7 @@ void recv_filter_list(int f_in)
char line[BIGPATHBUFLEN];
int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;
int receiver_wants_list = prune_empty_dirs
|| (delete_mode
&& (!delete_excluded || protocol_version >= 29));
|| (delete_mode && (!delete_excluded || protocol_version >= 29));
unsigned int len;
if (!local_server && (am_sender || receiver_wants_list)) {

130
fileio.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004-2014 Wayne Davison
* Copyright (C) 2004-2023 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
@@ -26,45 +26,56 @@
#define ENODATA EAGAIN
#endif
/* We want all reads to be aligned on 1K boundries. */
#define ALIGN_BOUNDRY 1024
/* We want all reads to be aligned on 1K boundaries. */
#define ALIGN_BOUNDARY 1024
/* How far past the boundary is an offset? */
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDRY-1))
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDARY-1))
/* Round up a length to the next boundary */
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDRY-1)) + 1)
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDARY-1)) + 1)
extern int sparse_files;
OFF_T preallocated_len = 0;
static OFF_T sparse_seek = 0;
static OFF_T sparse_past_write = 0;
int sparse_end(int f, OFF_T size)
int sparse_end(int f, OFF_T size, int updating_basis_or_equiv)
{
int ret;
int ret = 0;
if (!sparse_seek)
return 0;
#ifdef HAVE_FTRUNCATE
ret = do_ftruncate(f, size);
#else
if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
ret = -1;
else {
do {
ret = write(f, "", 1);
} while (ret < 0 && errno == EINTR);
ret = ret <= 0 ? -1 : 0;
}
if (updating_basis_or_equiv) {
if (sparse_seek && do_punch_hole(f, sparse_past_write, sparse_seek) < 0)
ret = -1;
#ifdef HAVE_FTRUNCATE /* A compilation formality -- in-place requires ftruncate() */
else /* Just in case the original file was longer */
ret = do_ftruncate(f, size);
#endif
} else if (sparse_seek) {
#ifdef HAVE_FTRUNCATE
ret = do_ftruncate(f, size);
#else
if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
ret = -1;
else {
do {
ret = write(f, "", 1);
} while (ret < 0 && errno == EINTR);
sparse_seek = 0;
ret = ret <= 0 ? -1 : 0;
}
#endif
}
sparse_past_write = sparse_seek = 0;
return ret;
}
static int write_sparse(int f, char *buf, int len)
/* Note that the offset is just the caller letting us know where
* the current file position is in the file. The use_seek arg tells
* us that we should seek over matching data instead of writing it. */
static int write_sparse(int f, int use_seek, OFF_T offset, const char *buf, int len)
{
int l1 = 0, l2 = 0;
int ret;
@@ -77,9 +88,24 @@ static int write_sparse(int f, char *buf, int len)
if (l1 == len)
return len;
if (sparse_seek)
do_lseek(f, sparse_seek, SEEK_CUR);
if (sparse_seek) {
if (sparse_past_write >= preallocated_len) {
if (do_lseek(f, sparse_seek, SEEK_CUR) < 0)
return -1;
} else if (do_punch_hole(f, sparse_past_write, sparse_seek) < 0) {
sparse_seek = 0;
return -1;
}
}
sparse_seek = l2;
sparse_past_write = offset + len - l2;
if (use_seek) {
/* The in-place data already matches. */
if (do_lseek(f, len - (l1+l2), SEEK_CUR) < 0)
return -1;
return len;
}
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
if (ret < 0 && errno == EINTR)
@@ -96,7 +122,6 @@ static int write_sparse(int f, char *buf, int len)
return len;
}
static char *wf_writeBuf;
static size_t wf_writeBufSize;
static size_t wf_writeBufCnt;
@@ -118,12 +143,10 @@ int flush_write_file(int f)
return ret;
}
/*
* write_file does not allow incomplete writes. It loops internally
* until len bytes are written or errno is set.
*/
int write_file(int f, char *buf, int len)
/* write_file does not allow incomplete writes. It loops internally
* until len bytes are written or errno is set. Note that use_seek and
* offset are only used in sparse processing (see write_sparse()). */
int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
{
int ret = 0;
@@ -131,14 +154,13 @@ int write_file(int f, char *buf, int len)
int r1;
if (sparse_files > 0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
r1 = write_sparse(f, buf, len1);
r1 = write_sparse(f, use_seek, offset, buf, len1);
offset += r1;
} else {
if (!wf_writeBuf) {
wf_writeBufSize = WRITE_SIZE * 8;
wf_writeBufCnt = 0;
wf_writeBuf = new_array(char, wf_writeBufSize);
if (!wf_writeBuf)
out_of_memory("write_file");
}
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
if (r1) {
@@ -164,6 +186,30 @@ int write_file(int f, char *buf, int len)
return ret;
}
/* An in-place update found identical data at an identical location. We either
* just seek past it, or (for an in-place sparse update), we give the data to
* the sparse processor with the use_seek flag set. */
int skip_matched(int fd, OFF_T offset, const char *buf, int len)
{
OFF_T pos;
if (sparse_files > 0) {
if (write_file(fd, 1, offset, buf, len) != len)
return -1;
return 0;
}
if (flush_write_file(fd) < 0)
return -1;
if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset + len) {
rsyserr(FERROR_XFER, errno, "lseek returned %s, not %s",
big_num(pos), big_num(offset));
return -1;
}
return 0;
}
/* This provides functionality somewhat similar to mmap() but using read().
* It gives sliding window access to a file. mmap() is not used because of
@@ -173,8 +219,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
{
struct map_struct *map;
if (!(map = new0(struct map_struct)))
out_of_memory("map_file");
map = new0(struct map_struct);
if (blk_size && (read_size % blk_size))
read_size += blk_size - (read_size % blk_size);
@@ -217,8 +262,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
map->p = realloc_array(map->p, char, window_size);
if (!map->p)
out_of_memory("map_ptr");
map->p_size = window_size;
}
@@ -271,7 +314,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
return map->p + align_fudge;
}
int unmap_file(struct map_struct *map)
{
int ret;
@@ -281,7 +323,9 @@ int unmap_file(struct map_struct *map)
map->p = NULL;
}
ret = map->status;
memset(map, 0, sizeof map[0]);
#if 0 /* I don't think we really need this. */
force_memzero(map, sizeof map[0]);
#endif
free(map);
return ret;

499
flist.c
View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,7 @@
fprintf(stderr, "Unable to stat `%s'\n", *argv);
exit(1);
}
printf("%ld/%ld\n", (long)major(st.st_dev),
(long)minor(st.st_dev));
printf("%ld/%ld\n", (long)major(st.st_dev), (long)minor(st.st_dev));
}
return 0;

View File

@@ -3,7 +3,7 @@
* `id -G` on Linux, but it's too hard to find a portable equivalent.
*
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2020 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
@@ -20,8 +20,7 @@
#include "rsync.h"
int
main(UNUSED(int argc), UNUSED(char *argv[]))
int main(UNUSED(int argc), UNUSED(char *argv[]))
{
int n, i;
gid_t *list;

View File

@@ -1,7 +1,7 @@
/*
* Routines to provide a memory-efficient hashtable.
*
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-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
@@ -35,9 +35,8 @@ struct hashtable *hashtable_create(int size, int key64)
size *= 2;
}
if (!(tbl = new(struct hashtable))
|| !(tbl->nodes = new_array0(char, size * node_size)))
out_of_memory("hashtable_create");
tbl = new(struct hashtable);
tbl->nodes = new_array0(char, size * node_size);
tbl->size = size;
tbl->entries = 0;
tbl->node_size = node_size;
@@ -66,9 +65,19 @@ void hashtable_destroy(struct hashtable *tbl)
free(tbl);
}
/* This returns the node for the indicated key, either newly created or
* already existing. Returns NULL if not allocating and not found. */
void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
/* Returns the node that holds the indicated key if it exists. When it does not
* exist, it returns either NULL (when data_when_new is NULL), or it returns a
* new node with its node->data set to the indicated value.
*
* If your code doesn't know the data value for a new node in advance (usually
* because it doesn't know if a node is new or not) you should pass in a unique
* (non-0) value that you can use to check if the returned node is new. You can
* then overwrite the data with any value you want (even 0) since it only needs
* to be different than whatever data_when_new value you use later on.
*
* This return is a void* just because it might be pointing at a ht_int32_node
* or a ht_int64_node, and that makes the caller's assignment a little easier. */
void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
{
int key64 = tbl->key64;
struct ht_int32_node *node;
@@ -79,13 +88,12 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
exit_cleanup(RERR_MESSAGEIO);
}
if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
if (data_when_new && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
void *old_nodes = tbl->nodes;
int size = tbl->size * 2;
int i;
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
out_of_memory("hashtable_node");
tbl->nodes = new_array0(char, size * tbl->node_size);
tbl->size = size;
tbl->entries = 0;
@@ -99,8 +107,12 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
int64 move_key = HT_KEY(move_node, key64);
if (move_key == 0)
continue;
node = hashtable_find(tbl, move_key, 1);
node->data = move_node->data;
if (move_node->data)
hashtable_find(tbl, move_key, move_node->data);
else {
node = hashtable_find(tbl, move_key, "");
node->data = 0;
}
}
free(old_nodes);
@@ -155,7 +167,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
if (nkey == key)
return node;
if (nkey == 0) {
if (!allocate_if_missing)
if (!data_when_new)
return NULL;
break;
}
@@ -167,6 +179,484 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
((struct ht_int64_node*)node)->key = key;
else
node->key = (int32)key;
node->data = data_when_new;
tbl->entries++;
return node;
}
#ifndef WORDS_BIGENDIAN
# define HASH_LITTLE_ENDIAN 1
# define HASH_BIG_ENDIAN 0
#else
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 1
#endif
/*
-------------------------------------------------------------------------------
lookup3.c, by Bob Jenkins, May 2006, Public Domain.
These are functions for producing 32-bit hashes for hash table lookup.
hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
are externally useful functions. Routines to test the hash are included
if SELF_TEST is defined. You can use this free for any purpose. It's in
the public domain. It has no warranty.
You probably want to use hashlittle(). hashlittle() and hashbig()
hash byte arrays. hashlittle() is is faster than hashbig() on
little-endian machines. Intel and AMD are little-endian machines.
On second thought, you probably want hashlittle2(), which is identical to
hashlittle() except it returns two 32-bit hashes for the price of one.
You could implement hashbig2() if you wanted but I haven't bothered here.
If you want to find a hash of, say, exactly 7 integers, do
a = i1; b = i2; c = i3;
mix(a,b,c);
a += i4; b += i5; c += i6;
mix(a,b,c);
a += i7;
final(a,b,c);
then use c as the hash value. If you have a variable length array of
4-byte integers to hash, use hash_word(). If you have a byte array (like
a character string), use hashlittle(). If you have several byte arrays, or
a mix of things, see the comments above hashlittle().
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
then mix those integers. This is fast (you can do a lot more thorough
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
*/
#define hashsize(n) ((uint32_t)1<<(n))
#define hashmask(n) (hashsize(n)-1)
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/*
-------------------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
This is reversible, so any information in (a,b,c) before mix() is
still in (a,b,c) after mix().
If four pairs of (a,b,c) inputs are run through mix(), or through
mix() in reverse, there are at least 32 bits of the output that
are sometimes the same for one pair and different for another pair.
This was tested for:
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
satisfy this are
4 6 8 16 19 4
9 15 3 18 27 15
14 9 3 7 17 3
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
for "differ" defined as + with a one-bit base and a two-bit delta. I
used http://burtleburtle.net/bob/hash/avalanche.html to choose
the operations, constants, and arrangements of the variables.
This does not achieve avalanche. There are input bits of (a,b,c)
that fail to affect some output bits of (a,b,c), especially of a. The
most thoroughly mixed value is c, but it doesn't really even achieve
avalanche in c.
This allows some parallelism. Read-after-writes are good at doubling
the number of bits affected, so the goal of mixing pulls in the opposite
direction as the goal of parallelism. I did what I could. Rotates
seem to cost as much as shifts on every machine I could lay my hands
on, and rotates are much kinder to the top and bottom bits, so I used
rotates.
-------------------------------------------------------------------------------
*/
#define mix(a,b,c) \
{ \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c,16); c += b; \
b -= a; b ^= rot(a,19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
}
/*
-------------------------------------------------------------------------------
final -- final mixing of 3 32-bit values (a,b,c) into c
Pairs of (a,b,c) values differing in only a few bits will usually
produce values of c that look totally different. This was tested for
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
These constants passed:
14 11 25 16 4 14 24
12 14 25 16 4 14 24
and these came close:
4 8 15 26 3 22 24
10 8 15 26 3 22 24
11 8 15 26 3 22 24
-------------------------------------------------------------------------------
*/
#define final(a,b,c) \
{ \
c ^= b; c -= rot(b,14); \
a ^= c; a -= rot(c,11); \
b ^= a; b -= rot(a,25); \
c ^= b; c -= rot(b,16); \
a ^= c; a -= rot(c,4); \
b ^= a; b -= rot(a,14); \
c ^= b; c -= rot(b,24); \
}
/*
-------------------------------------------------------------------------------
hashlittle() -- hash a variable-length key into a 32-bit value
k : the key (the unaligned variable-length array of bytes)
length : the length of the key, counting by bytes
val2 : IN: can be any 4-byte value OUT: second 32 bit hash.
Returns a 32-bit value. Every bit of the key affects every bit of
the return value. Two keys differing by one or two bits will have
totally different hash values. Note that the return value is better
mixed than val2, so use that first.
The best hash table sizes are powers of 2. There is no need to do
mod a prime (mod is sooo slow!). If you need less than 32 bits,
use a bitmask. For example, if you need only 10 bits, do
h = (h & hashmask(10));
In which case, the hash table should have hashsize(10) elements.
If you are hashing n strings (uint8_t **)k, do it like this:
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. It's free.
Use for hash table lookup, or anything where one collision in 2^^32 is
acceptable. Do NOT use for cryptographic purposes.
-------------------------------------------------------------------------------
*/
#define NON_ZERO_32(x) ((x) ? (x) : (uint32_t)1)
#define NON_ZERO_64(x, y) ((x) || (y) ? (y) | (int64)(x) << 32 | (y) : (int64)1)
uint32_t hashlittle(const void *key, size_t length)
{
uint32_t a,b,c; /* internal state */
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length);
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
const uint8_t *k8;
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
b += k[1];
c += k[2];
mix(a,b,c);
length -= 12;
k += 3;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]; break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
case 1 : a+=k8[0]; break;
case 0 : return NON_ZERO_32(c);
}
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
const uint8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12)
{
a += k[0] + (((uint32_t)k[1])<<16);
b += k[2] + (((uint32_t)k[3])<<16);
c += k[4] + (((uint32_t)k[5])<<16);
mix(a,b,c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=k[4];
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=k[2];
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=k[0];
break;
case 1 : a+=k8[0];
break;
case 0 : return NON_ZERO_32(c); /* zero length requires no mixing */
}
} else { /* need to read the key one byte at a time */
const uint8_t *k = (const uint8_t *)key;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
a += ((uint32_t)k[1])<<8;
a += ((uint32_t)k[2])<<16;
a += ((uint32_t)k[3])<<24;
b += k[4];
b += ((uint32_t)k[5])<<8;
b += ((uint32_t)k[6])<<16;
b += ((uint32_t)k[7])<<24;
c += k[8];
c += ((uint32_t)k[9])<<8;
c += ((uint32_t)k[10])<<16;
c += ((uint32_t)k[11])<<24;
mix(a,b,c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch(length) /* all the case statements fall through */
{
case 12: c+=((uint32_t)k[11])<<24;
/* FALLTHROUGH */
case 11: c+=((uint32_t)k[10])<<16;
/* FALLTHROUGH */
case 10: c+=((uint32_t)k[9])<<8;
/* FALLTHROUGH */
case 9 : c+=k[8];
/* FALLTHROUGH */
case 8 : b+=((uint32_t)k[7])<<24;
/* FALLTHROUGH */
case 7 : b+=((uint32_t)k[6])<<16;
/* FALLTHROUGH */
case 6 : b+=((uint32_t)k[5])<<8;
/* FALLTHROUGH */
case 5 : b+=k[4];
/* FALLTHROUGH */
case 4 : a+=((uint32_t)k[3])<<24;
/* FALLTHROUGH */
case 3 : a+=((uint32_t)k[2])<<16;
/* FALLTHROUGH */
case 2 : a+=((uint32_t)k[1])<<8;
/* FALLTHROUGH */
case 1 : a+=k[0];
break;
case 0 : return NON_ZERO_32(c);
}
}
final(a,b,c);
return NON_ZERO_32(c);
}
#if SIZEOF_INT64 >= 8
/*
* hashlittle2: return 2 32-bit hash values joined into an int64.
*
* This is identical to hashlittle(), except it returns two 32-bit hash
* values instead of just one. This is good enough for hash table
* lookup with 2^^64 buckets, or if you want a second hash if you're not
* happy with the first, or if you want a probably-unique 64-bit ID for
* the key. *pc is better mixed than *pb, so use *pc first. If you want
* a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
*/
int64 hashlittle2(const void *key, size_t length)
{
uint32_t a,b,c; /* internal state */
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length);
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
const uint8_t *k8;
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
b += k[1];
c += k[2];
mix(a,b,c);
length -= 12;
k += 3;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]; break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
case 1 : a+=k8[0]; break;
case 0 : return NON_ZERO_64(b, c);
}
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
const uint8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12)
{
a += k[0] + (((uint32_t)k[1])<<16);
b += k[2] + (((uint32_t)k[3])<<16);
c += k[4] + (((uint32_t)k[5])<<16);
mix(a,b,c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=k[4];
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=k[2];
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=k[0];
break;
case 1 : a+=k8[0];
break;
case 0 : return NON_ZERO_64(b, c); /* zero length strings require no mixing */
}
} else { /* need to read the key one byte at a time */
const uint8_t *k = (const uint8_t *)key;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
a += ((uint32_t)k[1])<<8;
a += ((uint32_t)k[2])<<16;
a += ((uint32_t)k[3])<<24;
b += k[4];
b += ((uint32_t)k[5])<<8;
b += ((uint32_t)k[6])<<16;
b += ((uint32_t)k[7])<<24;
c += k[8];
c += ((uint32_t)k[9])<<8;
c += ((uint32_t)k[10])<<16;
c += ((uint32_t)k[11])<<24;
mix(a,b,c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch(length) /* all the case statements fall through */
{
case 12: c+=((uint32_t)k[11])<<24;
/* FALLTHROUGH */
case 11: c+=((uint32_t)k[10])<<16;
/* FALLTHROUGH */
case 10: c+=((uint32_t)k[9])<<8;
/* FALLTHROUGH */
case 9 : c+=k[8];
/* FALLTHROUGH */
case 8 : b+=((uint32_t)k[7])<<24;
/* FALLTHROUGH */
case 7 : b+=((uint32_t)k[6])<<16;
/* FALLTHROUGH */
case 6 : b+=((uint32_t)k[5])<<8;
/* FALLTHROUGH */
case 5 : b+=k[4];
/* FALLTHROUGH */
case 4 : a+=((uint32_t)k[3])<<24;
/* FALLTHROUGH */
case 3 : a+=((uint32_t)k[2])<<16;
/* FALLTHROUGH */
case 2 : a+=((uint32_t)k[1])<<8;
/* FALLTHROUGH */
case 1 : a+=k[0];
break;
case 0 : return NON_ZERO_64(b, c);
}
}
final(a,b,c);
return NON_ZERO_64(b, c);
}
#else
#define hashlittle2(key, len) hashlittle(key, len)
#endif

40
help-from-md.awk Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/awk -f
# The caller must pass args: -v hfile=help-NAME.h NAME.NUM.md
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from the option list in " ARGV[1] "! */"
findcomment = hfile
sub("\\.", "\\.", findcomment)
findcomment = "\\[comment\\].*" findcomment
backtick_cnt = 0
prints = ""
}
/^```/ {
backtick_cnt++
next
}
foundcomment {
if (backtick_cnt > 1) exit
if (backtick_cnt == 1) {
gsub(/"/, "\\\"")
prints = prints "\n rprintf(F,\"" $0 "\\n\");"
}
next
}
$0 ~ findcomment {
foundcomment = 1
backtick_cnt = 0
}
END {
if (foundcomment && backtick_cnt > 1)
print heading "\n" prints > hfile
else {
print "Failed to find " hfile " section in " ARGV[1]
exit 1
}
}

57
hlink.c
View File

@@ -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-2014 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
@@ -29,7 +29,7 @@ extern int list_only;
extern int am_sender;
extern int inc_recurse;
extern int do_xfers;
extern int link_dest;
extern int alt_dest_type;
extern int preserve_acls;
extern int preserve_xattrs;
extern int protocol_version;
@@ -48,6 +48,8 @@ extern struct file_list *cur_flist;
* we can avoid the pool of dev+inode data. For incremental recursion mode,
* the receiver will use a ndx hash to remember old pathnames. */
static void *data_when_new = "";
static struct hashtable *dev_tbl;
static struct hashtable *prior_hlinks;
@@ -57,32 +59,29 @@ static struct file_list *hlink_flist;
void init_hard_links(void)
{
if (am_sender || protocol_version < 30)
dev_tbl = hashtable_create(16, 1);
dev_tbl = hashtable_create(16, HT_KEY64);
else if (inc_recurse)
prior_hlinks = hashtable_create(1024, 0);
prior_hlinks = hashtable_create(1024, HT_KEY32);
}
struct ht_int64_node *idev_find(int64 dev, int64 ino)
{
static struct ht_int64_node *dev_node = NULL;
struct hashtable *tbl;
/* Note that some OSes have a dev == 0, so increment to avoid storing a 0. */
if (!dev_node || dev_node->key != dev+1) {
/* We keep a separate hash table of inodes for every device. */
dev_node = hashtable_find(dev_tbl, dev+1, 1);
if (!(tbl = dev_node->data)) {
tbl = dev_node->data = hashtable_create(512, 1);
dev_node = hashtable_find(dev_tbl, dev+1, data_when_new);
if (dev_node->data == data_when_new) {
dev_node->data = hashtable_create(512, HT_KEY64);
if (DEBUG_GTE(HLINK, 3)) {
rprintf(FINFO,
"[%s] created hashtable for dev %s\n",
who_am_i(), big_num(dev));
rprintf(FINFO, "[%s] created hashtable for dev %s\n",
who_am_i(), big_num(dev));
}
}
} else
tbl = dev_node->data;
}
return hashtable_find(tbl, ino, 1);
return hashtable_find(dev_node->data, ino, (void*)-1L);
}
void idev_destroy(void)
@@ -118,17 +117,15 @@ static void match_gnums(int32 *ndx_list, int ndx_count)
struct ht_int32_node *node = NULL;
int32 gnum, gnum_next;
qsort(ndx_list, ndx_count, sizeof ndx_list[0],
(int (*)()) hlink_compare_gnum);
qsort(ndx_list, ndx_count, sizeof ndx_list[0], (int (*)(const void*, const void*))hlink_compare_gnum);
for (from = 0; from < ndx_count; from++) {
file = hlink_flist->sorted[ndx_list[from]];
gnum = F_HL_GNUM(file);
if (inc_recurse) {
node = hashtable_find(prior_hlinks, gnum, 1);
if (!node->data) {
if (!(node->data = new_array0(char, 5)))
out_of_memory("match_gnums");
node = hashtable_find(prior_hlinks, gnum, data_when_new);
if (node->data == data_when_new) {
node->data = new_array0(char, 5);
assert(gnum >= hlink_flist->ndx_start);
file->flags |= FLAG_HLINK_FIRST;
prev = -1;
@@ -192,8 +189,7 @@ void match_hard_links(struct file_list *flist)
int i, ndx_count = 0;
int32 *ndx_list;
if (!(ndx_list = new_array(int32, flist->used)))
out_of_memory("match_hard_links");
ndx_list = new_array(int32, flist->used);
for (i = 0; i < flist->used; i++) {
if (F_IS_HLINKED(flist->sorted[i]))
@@ -231,7 +227,7 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
}
}
if (atomic_create(file, fname, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
if (atomic_create(file, fname, NULL, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
if (itemizing) {
itemize(fname, file, ndx, statret, sxp,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
@@ -269,7 +265,7 @@ static char *check_prior(struct file_struct *file, int gnum,
}
if (inc_recurse
&& (node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
&& (node = hashtable_find(prior_hlinks, gnum, NULL)) != NULL) {
assert(node->data != NULL);
if (CVAL(node->data, 0) != 0) {
*prev_ndx_p = -1;
@@ -396,7 +392,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
continue;
if (link_dest) {
if (alt_dest_type == LINK_DEST) {
if (prev_st.st_dev != alt_sx.st.st_dev
|| prev_st.st_ino != alt_sx.st.st_ino)
continue;
@@ -410,7 +406,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
}
break;
}
if (!unchanged_file(cmpbuf, file, &alt_sx.st))
if (!quick_check_ok(FT_REG, cmpbuf, file, &alt_sx.st))
continue;
statret = 1;
if (unchanged_attrs(cmpbuf, file, &alt_sx))
@@ -450,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;
}
@@ -523,12 +519,12 @@ 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) {
int gnum = F_HL_GNUM(file);
struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, 0);
struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, NULL);
if (node == NULL) {
rprintf(FERROR, "Unable to find a hlink node for %d (%s)\n", gnum, f_name(file, prev_name));
exit_cleanup(RERR_MESSAGEIO);
@@ -543,8 +539,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
exit_cleanup(RERR_MESSAGEIO);
}
free(node->data);
if (!(node->data = strdup(our_name)))
out_of_memory("finish_hard_link");
node->data = strdup(our_name);
}
}

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-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
@@ -19,8 +19,7 @@
static inline void
alloc_xbuf(xbuf *xb, size_t sz)
{
if (!(xb->buf = new_array(char, sz)))
out_of_memory("alloc_xbuf");
xb->buf = new_array(char, sz);
xb->size = sz;
xb->len = xb->pos = 0;
}
@@ -29,8 +28,6 @@ static inline void
realloc_xbuf(xbuf *xb, size_t sz)
{
char *bf = realloc_array(xb->buf, char, sz);
if (!bf)
out_of_memory("realloc_xbuf");
xb->buf = bf;
xb->size = sz;
}
@@ -78,6 +75,7 @@ d_name(struct dirent *di)
static inline void
init_stat_x(stat_x *sx_p)
{
sx_p->crtime = 0;
#ifdef SUPPORT_ACLS
sx_p->acc_acl = sx_p->def_acl = NULL;
#endif
@@ -104,3 +102,11 @@ free_stat_x(stat_x *sx_p)
}
#endif
}
static inline char *my_strdup(const char *str, const char *file, int line)
{
int len = strlen(str)+1;
char *buf = my_alloc(NULL, len, 1, file, line);
memcpy(buf, str, len);
return buf;
}

View File

@@ -115,7 +115,7 @@ else
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
if [ -f $src ] || [ -d $src ]
then
true
else

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2008-2014 Wayne Davison
* Copyright (C) 2008-2019 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

273
io.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-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
@@ -41,9 +41,11 @@ 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;
extern int batch_fd;
extern int eol_nulls;
extern int flist_eof;
extern int file_total;
@@ -53,12 +55,15 @@ extern int read_batch;
extern int compat_flags;
extern int protect_args;
extern int checksum_seed;
extern int xfer_sum_len;
extern int daemon_connection;
extern int protocol_version;
extern int remove_source_files;
extern int preserve_hard_links;
extern BOOL extra_flist_sending_enabled;
extern BOOL flush_ok_after_signal;
extern struct stats stats;
extern time_t stop_at_utime;
extern struct file_list *cur_flist;
#ifdef ICONV_OPTION
extern int filesfrom_convert;
@@ -67,7 +72,6 @@ extern iconv_t ic_send, ic_recv;
int csum_length = SHORT_SUM_LENGTH; /* initial value */
int allowed_lull = 0;
int batch_fd = -1;
int msgdone_cnt = 0;
int forward_flist_data = 0;
BOOL flist_receiving_enabled = False;
@@ -82,6 +86,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;
@@ -111,7 +117,7 @@ static int active_filecnt = 0;
static OFF_T active_bytecnt = 0;
static int first_message = 1;
static char int_byte_extra[64] = {
static const char int_byte_extra[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* (00 - 3F)/4 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* (40 - 7F)/4 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* (80 - BF)/4 */
@@ -251,8 +257,7 @@ static size_t safe_read(int fd, char *buf, size_t len)
cnt = select(fd+1, &r_fds, NULL, &e_fds, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
rsyserr(FERROR, errno, "safe_read select failed [%s]",
who_am_i());
rsyserr(FERROR, errno, "safe_read select failed");
exit_cleanup(RERR_FILEIO);
}
check_timeout(1, MSK_ALLOW_FLUSH);
@@ -263,16 +268,18 @@ static size_t safe_read(int fd, char *buf, size_t len)
rprintf(FINFO, "select exception on fd %d\n", fd); */
if (FD_ISSET(fd, &r_fds)) {
int n = read(fd, buf + got, len - got);
if (DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] safe_read(%d)=%ld\n", who_am_i(), fd, (long)n);
ssize_t n = read(fd, buf + got, len - got);
if (DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] safe_read(%d)=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), fd, (SIZE_T_FMT_CAST)n);
}
if (n == 0)
break;
if (n < 0) {
if (errno == EINTR)
continue;
rsyserr(FERROR, errno, "safe_read failed to read %ld bytes [%s]",
(long)len, who_am_i());
rsyserr(FERROR, errno, "safe_read failed to read %" SIZE_T_FMT_MOD "d bytes",
(SIZE_T_FMT_CAST)len);
exit_cleanup(RERR_STREAMIO);
}
if ((got += (size_t)n) == len)
@@ -304,7 +311,7 @@ static const char *what_fd_is(int fd)
* is not used on the socket except very early in the transfer. */
static void safe_write(int fd, const char *buf, size_t len)
{
int n;
ssize_t n;
assert(fd != iobuf.out_fd);
@@ -315,8 +322,8 @@ static void safe_write(int fd, const char *buf, size_t len)
if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
write_failed:
rsyserr(FERROR, errno,
"safe_write failed to write %ld bytes to %s [%s]",
(long)len, what_fd_is(fd), who_am_i());
"safe_write failed to write %" SIZE_T_FMT_MOD "d bytes to %s",
(SIZE_T_FMT_CAST)len, what_fd_is(fd));
exit_cleanup(RERR_STREAMIO);
}
} else {
@@ -337,8 +344,7 @@ static void safe_write(int fd, const char *buf, size_t len)
cnt = select(fd + 1, NULL, &w_fds, NULL, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
rsyserr(FERROR, errno, "safe_write select failed on %s [%s]",
what_fd_is(fd), who_am_i());
rsyserr(FERROR, errno, "safe_write select failed on %s", what_fd_is(fd));
exit_cleanup(RERR_FILEIO);
}
if (io_timeout)
@@ -363,7 +369,7 @@ static void safe_write(int fd, const char *buf, size_t len)
* a chunk of data and put it into the output buffer. */
static void forward_filesfrom_data(void)
{
int len;
ssize_t len;
len = read(ff_forward_fd, ff_xb.buf + ff_xb.len, ff_xb.size - ff_xb.len);
if (len <= 0) {
@@ -374,12 +380,15 @@ static void forward_filesfrom_data(void)
free_xbuf(&ff_xb);
if (ff_reenable_multiplex >= 0)
io_start_multiplex_out(ff_reenable_multiplex);
free_implied_include_partial_string();
}
return;
}
if (DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] files-from read=%ld\n", who_am_i(), (long)len);
if (DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] files-from read=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), (SIZE_T_FMT_CAST)len);
}
#ifdef ICONV_OPTION
len += ff_xb.len;
@@ -415,6 +424,7 @@ static void forward_filesfrom_data(void)
while (s != eob) {
if (*s++ == '\0') {
ff_xb.len = s - sob - 1;
add_implied_include(sob, 0);
if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0)
exit_cleanup(RERR_PROTOCOL); /* impossible? */
write_buf(iobuf.out_fd, s-1, 1); /* Send the '\0'. */
@@ -430,6 +440,7 @@ static void forward_filesfrom_data(void)
ff_lastchar = '\0';
else {
/* Handle a partial string specially, saving any incomplete chars. */
implied_include_partial_string(sob, s);
flags &= ~ICB_INCLUDE_INCOMPLETE;
if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0) {
if (errno == E2BIG)
@@ -446,13 +457,17 @@ static void forward_filesfrom_data(void)
char *f = ff_xb.buf + ff_xb.pos;
char *t = ff_xb.buf;
char *eob = f + len;
char *cur = t;
/* Eliminate any multi-'\0' runs. */
while (f != eob) {
if (!(*t++ = *f++)) {
add_implied_include(cur, 0);
cur = t;
while (f != eob && *f == '\0')
f++;
}
}
implied_include_partial_string(cur, t);
ff_lastchar = f[-1];
if ((len = t - ff_xb.buf) != 0) {
/* This will not circle back to perform_io() because we only get
@@ -466,7 +481,7 @@ void reduce_iobuf_size(xbuf *out, size_t new_size)
{
if (new_size < out->size) {
/* Avoid weird buffer interactions by only outputting this to stderr. */
if (msgs2stderr && DEBUG_GTE(IO, 4)) {
if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
@@ -484,7 +499,7 @@ void restore_iobuf_size(xbuf *out)
if (IOBUF_WAS_REDUCED(out->size)) {
size_t new_size = IOBUF_RESTORE_SIZE(out->size);
/* Avoid weird buffer interactions by only outputting this to stderr. */
if (msgs2stderr && DEBUG_GTE(IO, 4)) {
if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
@@ -563,52 +578,59 @@ static char *perform_io(size_t needed, int flags)
case PIO_NEED_INPUT:
/* We never resize the circular input buffer. */
if (iobuf.in.size < needed) {
rprintf(FERROR, "need to read %ld bytes, iobuf.in.buf is only %ld bytes.\n",
(long)needed, (long)iobuf.in.size);
rprintf(FERROR, "need to read %" SIZE_T_FMT_MOD "d bytes,"
" iobuf.in.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
(SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.in.size);
exit_cleanup(RERR_PROTOCOL);
}
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, %sinput)\n",
who_am_i(), (long)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %sinput)\n",
who_am_i(), (SIZE_T_FMT_CAST)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
}
break;
case PIO_NEED_OUTROOM:
/* We never resize the circular output buffer. */
if (iobuf.out.size - iobuf.out_empty_len < needed) {
fprintf(stderr, "need to write %ld bytes, iobuf.out.buf is only %ld bytes.\n",
(long)needed, (long)(iobuf.out.size - iobuf.out_empty_len));
fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
" iobuf.out.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
(SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)(iobuf.out.size - iobuf.out_empty_len));
exit_cleanup(RERR_PROTOCOL);
}
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
who_am_i(), (long)needed,
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
" outroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
who_am_i(), (SIZE_T_FMT_CAST)needed,
iobuf.out.len + needed > iobuf.out.size
? (long)(iobuf.out.len + needed - iobuf.out.size) : 0L);
? (SIZE_T_FMT_CAST)(iobuf.out.len + needed - iobuf.out.size) : (SIZE_T_FMT_CAST)0);
}
break;
case PIO_NEED_MSGROOM:
/* We never resize the circular message buffer. */
if (iobuf.msg.size < needed) {
fprintf(stderr, "need to write %ld bytes, iobuf.msg.buf is only %ld bytes.\n",
(long)needed, (long)iobuf.msg.size);
fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
" iobuf.msg.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
(SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.msg.size);
exit_cleanup(RERR_PROTOCOL);
}
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
who_am_i(), (long)needed,
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
" msgroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
who_am_i(), (SIZE_T_FMT_CAST)needed,
iobuf.msg.len + needed > iobuf.msg.size
? (long)(iobuf.msg.len + needed - iobuf.msg.size) : 0L);
? (SIZE_T_FMT_CAST)(iobuf.msg.len + needed - iobuf.msg.size) : (SIZE_T_FMT_CAST)0);
}
break;
case 0:
if (msgs2stderr && DEBUG_GTE(IO, 3))
rprintf(FINFO, "[%s] perform_io(%ld, %d)\n", who_am_i(), (long)needed, flags);
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %d)\n",
who_am_i(), (SIZE_T_FMT_CAST)needed, flags);
}
break;
default:
@@ -665,9 +687,9 @@ static char *perform_io(size_t needed, int flags)
SIVAL(iobuf.out.buf + iobuf.raw_data_header_pos, 0,
((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
if (msgs2stderr && DEBUG_GTE(IO, 1)) {
rprintf(FINFO, "[%s] send_msg(%d, %ld)\n",
who_am_i(), (int)MSG_DATA, (long)iobuf.out.len - 4);
if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
who_am_i(), (int)MSG_DATA, (SIZE_T_FMT_CAST)iobuf.out.len - 4);
}
/* reserve room for the next MSG_DATA header */
@@ -758,7 +780,7 @@ static char *perform_io(size_t needed, int flags)
if (iobuf.in_fd >= 0 && FD_ISSET(iobuf.in_fd, &r_fds)) {
size_t len, pos = iobuf.in.pos + iobuf.in.len;
int n;
ssize_t n;
if (pos >= iobuf.in.size) {
pos -= iobuf.in.size;
len = iobuf.in.size - iobuf.in.len;
@@ -785,12 +807,14 @@ static char *perform_io(size_t needed, int flags)
exit_cleanup(RERR_SOCKETIO);
}
}
if (msgs2stderr && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] recv=%ld\n", who_am_i(), (long)n);
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] recv=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), (SIZE_T_FMT_CAST)n);
}
if (io_timeout) {
last_io_in = time(NULL);
if (flags & PIO_NEED_INPUT)
if (io_timeout && flags & PIO_NEED_INPUT)
maybe_send_keepalive(last_io_in, 0);
}
stats.total_read += n;
@@ -798,9 +822,14 @@ static char *perform_io(size_t needed, int flags)
iobuf.in.len += n;
}
if (stop_at_utime && time(NULL) >= stop_at_utime) {
rprintf(FERROR, "stopping at requested limit\n");
exit_cleanup(RERR_TIMEOUT);
}
if (out && FD_ISSET(iobuf.out_fd, &w_fds)) {
size_t len = iobuf.raw_flushing_ends_before ? iobuf.raw_flushing_ends_before - out->pos : out->len;
int n;
ssize_t n;
if (bwlimit_writemax && len > bwlimit_writemax)
len = bwlimit_writemax;
@@ -815,14 +844,14 @@ static char *perform_io(size_t needed, int flags)
msgs2stderr = 1;
iobuf.out_fd = -2;
iobuf.out.len = iobuf.msg.len = iobuf.raw_flushing_ends_before = 0;
rsyserr(FERROR_SOCKET, errno, "[%s] write error", who_am_i());
rsyserr(FERROR_SOCKET, errno, "write error");
drain_multiplex_messages();
exit_cleanup(RERR_SOCKETIO);
}
}
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] %s sent=%ld\n",
who_am_i(), out == &iobuf.out ? "out" : "msg", (long)n);
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] %s sent=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), out == &iobuf.out ? "out" : "msg", (SIZE_T_FMT_CAST)n);
}
if (io_timeout)
@@ -918,6 +947,10 @@ void noop_io_until_death(void)
if (!iobuf.in.buf || !iobuf.out.buf || iobuf.in_fd < 0 || iobuf.out_fd < 0 || kluge_around_eof)
return;
/* If we're talking to a daemon over a socket, don't short-circuit this logic */
if (msgs2stderr && daemon_connection >= 0)
return;
kluge_around_eof = 2;
/* Setting an I/O timeout ensures that if something inexplicably weird
* happens, we won't hang around forever. */
@@ -933,13 +966,15 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
{
char *hdr;
size_t needed, pos;
BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr || code != MSG_INFO);
BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr == 1 || code != MSG_INFO);
if (!OUT_MULTIPLEXED)
return 0;
if (want_debug)
rprintf(FINFO, "[%s] send_msg(%d, %ld)\n", who_am_i(), (int)code, (long)len);
if (want_debug) {
rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
who_am_i(), (int)code, (SIZE_T_FMT_CAST)len);
}
/* When checking for enough free space for this message, we need to
* make sure that there is space for the 4-byte header, plus we'll
@@ -954,8 +989,17 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
} else
#endif
needed = len + 4 + 3;
if (iobuf.msg.len + needed > iobuf.msg.size)
perform_io(needed, PIO_NEED_MSGROOM);
if (iobuf.msg.len + needed > iobuf.msg.size) {
if (am_sender)
perform_io(needed, PIO_NEED_MSGROOM);
else { /* We sometimes allow the iobuf.msg size to increase to avoid a deadlock. */
size_t old_size = iobuf.msg.size;
restore_iobuf_size(&iobuf.msg);
realloc_xbuf(&iobuf.msg, iobuf.msg.size * 2);
if (iobuf.msg.pos + iobuf.msg.len > old_size)
memcpy(iobuf.msg.buf + old_size, iobuf.msg.buf, iobuf.msg.pos + iobuf.msg.len - old_size);
}
}
pos = iobuf.msg.pos + iobuf.msg.len; /* Must be set after any flushing. */
if (pos >= iobuf.msg.size)
@@ -1005,8 +1049,10 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
SIVAL(hdr, 0, ((MPLEX_BASE + (int)code)<<24) + len);
if (want_debug && convert > 0)
rprintf(FINFO, "[%s] converted msg len=%ld\n", who_am_i(), (long)len);
if (want_debug && convert > 0) {
rprintf(FINFO, "[%s] converted msg len=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), (SIZE_T_FMT_CAST)len);
}
return 1;
}
@@ -1022,6 +1068,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");
@@ -1036,8 +1100,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
@@ -1090,8 +1158,8 @@ void set_io_timeout(int secs)
static void check_for_d_option_error(const char *msg)
{
static char rsync263_opts[] = "BCDHIKLPRSTWabceghlnopqrtuvxz";
char *colon;
static const char rsync263_opts[] = "BCDHIKLPRSTWabceghlnopqrtuvxz";
const char *colon;
int saw_d = 0;
if (*msg != 'r'
@@ -1113,8 +1181,7 @@ static void check_for_d_option_error(const char *msg)
}
if (saw_d) {
rprintf(FWARNING,
"*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n");
rprintf(FWARNING, "*** Try using \"--old-d\" if remote rsync is <= 2.6.3 ***\n");
}
}
@@ -1176,7 +1243,7 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags)
#ifdef ICONV_OPTION
if (flags & RL_CONVERT && iconv_buf.size < bufsiz)
realloc_xbuf(&iconv_buf, bufsiz + 1024);
realloc_xbuf(&iconv_buf, ROUND_UP_1024(bufsiz) + 1024);
#endif
start:
@@ -1234,8 +1301,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
rl_flags |= (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
#endif
if (!(argv = new_array(char *, maxargs)))
out_of_memory("read_args");
argv = new_array(char *, maxargs);
if (mod_name && !protect_args)
argv[argc++] = "rsyncd";
@@ -1248,8 +1314,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
if (argc == maxargs-1) {
maxargs += MAX_ARGS;
if (!(argv = realloc_array(argv, char *, maxargs)))
out_of_memory("read_args");
argv = realloc_array(argv, char *, maxargs);
}
if (dot_pos) {
@@ -1257,8 +1322,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
int len = strlen(buf);
if (request_len)
request_p[0][request_len++] = ' ';
if (!(*request_p = realloc_array(*request_p, char, request_len + len + 1)))
out_of_memory("read_args");
*request_p = realloc_array(*request_p, char, request_len + len + 1);
memcpy(*request_p + request_len, buf, len + 1);
request_len += len;
}
@@ -1267,8 +1331,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
else
glob_expand(buf, &argv, &argc, &maxargs);
} else {
if (!(p = strdup(buf)))
out_of_memory("read_args");
p = strdup(buf);
argv[argc++] = p;
if (*p == '.' && p[1] == '\0')
dot_pos = argc;
@@ -1284,7 +1347,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
BOOL io_start_buffering_out(int f_out)
{
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_out(%d)\n", who_am_i(), f_out);
if (iobuf.out.buf) {
@@ -1303,7 +1366,7 @@ BOOL io_start_buffering_out(int f_out)
BOOL io_start_buffering_in(int f_in)
{
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_in(%d)\n", who_am_i(), f_in);
if (iobuf.in.buf) {
@@ -1322,7 +1385,7 @@ BOOL io_start_buffering_in(int f_in)
void io_end_buffering_in(BOOL free_buffers)
{
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_in(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
@@ -1337,7 +1400,7 @@ void io_end_buffering_in(BOOL free_buffers)
void io_end_buffering_out(BOOL free_buffers)
{
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_out(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
@@ -1425,8 +1488,10 @@ static void read_a_msg(void)
msg_bytes = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE;
if (DEBUG_GTE(IO, 1) && msgs2stderr)
rprintf(FINFO, "[%s] got msg=%d, len=%ld\n", who_am_i(), (int)tag, (long)msg_bytes);
if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
rprintf(FINFO, "[%s] got msg=%d, len=%" SIZE_T_FMT_MOD "d\n",
who_am_i(), (int)tag, (SIZE_T_FMT_CAST)msg_bytes);
}
switch (tag) {
case MSG_DATA:
@@ -1535,14 +1600,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);
@@ -1602,8 +1668,10 @@ static void read_a_msg(void)
else
goto invalid_msg;
iobuf.in_multiplexed = 1;
if (DEBUG_GTE(EXIT, 3))
rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %ld bytes\n", who_am_i(), (long)msg_bytes);
if (DEBUG_GTE(EXIT, 3)) {
rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %" SIZE_T_FMT_MOD "d bytes\n",
who_am_i(), (SIZE_T_FMT_CAST)msg_bytes);
}
if (msg_bytes == 0) {
if (!am_sender && !am_generator) {
if (DEBUG_GTE(EXIT, 3)) {
@@ -1685,7 +1753,7 @@ void wait_for_receiver(void)
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
flist = recv_file_list(iobuf.in_fd);
flist = recv_file_list(iobuf.in_fd, ndx);
flist->parent_ndx = ndx;
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links)
@@ -1717,6 +1785,13 @@ int32 read_int(int f)
return num;
}
uint32 read_uint(int f)
{
char b[4];
read_buf(f, b, 4);
return IVAL(b, 0);
}
int32 read_varint(int f)
{
union {
@@ -1809,6 +1884,7 @@ int64 read_longint(int f)
#endif
}
/* Debugging note: this will be named read_buf_() when using an external zlib. */
void read_buf(int f, char *buf, size_t len)
{
if (f != iobuf.in_fd) {
@@ -1902,7 +1978,7 @@ void read_sum_head(int f, struct sum_struct *sum)
exit_cleanup(RERR_PROTOCOL);
}
sum->s2length = protocol_version < 27 ? csum_length : (int)read_int(f);
if (sum->s2length < 0 || sum->s2length > MAX_DIGEST_LEN) {
if (sum->s2length < 0 || sum->s2length > xfer_sum_len) {
rprintf(FERROR, "Invalid checksum length %d [%s]\n",
sum->s2length, who_am_i());
exit_cleanup(RERR_PROTOCOL);
@@ -1982,13 +2058,14 @@ static void sleep_for_bwlimit(int bytes_written)
total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
}
void io_flush(int flush_it_all)
void io_flush(int flush_type)
{
if (iobuf.out.len > iobuf.out_empty_len) {
if (flush_it_all) /* FULL_FLUSH: flush everything in the output buffers */
if (flush_type == FULL_FLUSH) /* flush everything in the output buffers */
perform_io(iobuf.out.size - iobuf.out_empty_len, PIO_NEED_OUTROOM);
else /* NORMAL_FLUSH: flush at least 1 byte */
else if (flush_type == NORMAL_FLUSH) /* flush at least 1 byte */
perform_io(iobuf.out.size - iobuf.out.len + 1, PIO_NEED_OUTROOM);
/* MSG_FLUSH: flush iobuf.msg only */
}
if (iobuf.msg.len)
perform_io(iobuf.msg.size, PIO_NEED_MSGROOM);
@@ -2013,20 +2090,20 @@ void write_varint(int f, int32 x)
{
char b[5];
uchar bit;
int cnt = 4;
int cnt;
SIVAL(b, 1, x);
while (cnt > 1 && b[cnt] == 0)
cnt--;
for (cnt = 4; cnt > 1 && b[cnt] == 0; cnt--) {}
bit = ((uchar)1<<(7-cnt+1));
if (CVAL(b, cnt) >= bit) {
cnt++;
*b = ~(bit-1);
} else if (cnt > 1)
*b = b[cnt] | ~(bit*2-1);
else
*b = b[cnt];
*b = b[1];
write_buf(f, b, cnt);
}
@@ -2283,7 +2360,7 @@ void io_printf(int fd, const char *format, ...)
if (len < 0)
exit_cleanup(RERR_PROTOCOL);
if (len > (int)sizeof buf) {
if (len >= (int)sizeof buf) {
rprintf(FERROR, "io_printf() was too long for the buffer.\n");
exit_cleanup(RERR_PROTOCOL);
}
@@ -2296,7 +2373,7 @@ void io_start_multiplex_out(int fd)
{
io_flush(FULL_FLUSH);
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_out(%d)\n", who_am_i(), fd);
if (!iobuf.msg.buf)
@@ -2313,7 +2390,7 @@ void io_start_multiplex_out(int fd)
/* Setup for multiplexing a MSG_* stream with the data stream. */
void io_start_multiplex_in(int fd)
{
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_in(%d)\n", who_am_i(), fd);
iobuf.in_multiplexed = 1; /* See also IN_MULTIPLEXED */
@@ -2324,7 +2401,7 @@ int io_end_multiplex_in(int mode)
{
int ret = iobuf.in_multiplexed ? iobuf.in_fd : -1;
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_in(mode=%d)\n", who_am_i(), mode);
iobuf.in_multiplexed = 0;
@@ -2342,7 +2419,7 @@ int io_end_multiplex_out(int mode)
{
int ret = iobuf.out_empty_len ? iobuf.out_fd : -1;
if (msgs2stderr && DEBUG_GTE(IO, 2))
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_out(mode=%d)\n", who_am_i(), mode);
if (mode != MPLX_TO_BUFFERED)
@@ -2368,7 +2445,7 @@ void start_write_batch(int fd)
* is involved. */
write_int(batch_fd, protocol_version);
if (protocol_version >= 30)
write_byte(batch_fd, compat_flags);
write_varint(batch_fd, compat_flags);
write_int(batch_fd, checksum_seed);
if (am_sender)

2
io.h
View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-2019 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

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-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
@@ -22,6 +22,12 @@ isDigit(const char *ptr)
return isdigit(*(unsigned char *)ptr);
}
static inline int
isHexDigit(const char *ptr)
{
return isxdigit(*(unsigned char *)ptr);
}
static inline int
isPrint(const char *ptr)
{
@@ -34,6 +40,12 @@ isSpace(const char *ptr)
return isspace(*(unsigned char *)ptr);
}
static inline int
isAlNum(const char *ptr)
{
return isalnum(*(unsigned char *)ptr);
}
static inline int
isLower(const char *ptr)
{

1
latest-year.h Normal file
View File

@@ -0,0 +1 @@
#define LATEST_YEAR "2026"

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004-2014 Wayne Davison
* Copyright (C) 2004-2020 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
@@ -24,16 +24,24 @@
static char number_separator;
#ifndef HAVE_STRDUP
char *strdup(char *s)
char get_number_separator(void)
{
int len = strlen(s) + 1;
char *ret = (char *)malloc(len);
if (ret)
memcpy(ret, s, len);
return ret;
if (!number_separator) {
char buf[32];
snprintf(buf, sizeof buf, "%f", 3.14);
if (strchr(buf, '.') != NULL)
number_separator = ',';
else
number_separator = '.';
}
return number_separator;
}
char get_decimal_point(void)
{
return get_number_separator() == ',' ? '.' : ',';
}
#endif
#ifndef HAVE_GETCWD
char *getcwd(char *buf, int size)
@@ -79,7 +87,7 @@ static char number_separator;
#ifndef HAVE_STRPBRK
/**
* Find the first ocurrence in @p s of any character in @p accept.
* Find the first occurrence in @p s of any character in @p accept.
*
* Derived from glibc
**/
@@ -155,30 +163,6 @@ int sys_gettimeofday(struct timeval *tv)
#endif
}
#define HUMANIFY(mult) \
do { \
if (num >= mult || num <= -mult) { \
double dnum = (double)num / mult; \
char units; \
if (num < 0) \
dnum = -dnum; \
if (dnum < mult) \
units = 'K'; \
else if ((dnum /= mult) < mult) \
units = 'M'; \
else if ((dnum /= mult) < mult) \
units = 'G'; \
else { \
dnum /= mult; \
units = 'T'; \
} \
if (num < 0) \
dnum = -dnum; \
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
return bufs[n]; \
} \
} while (0)
/* Return the int64 number as a string. If the human_flag arg is non-zero,
* we may output the number in K, M, G, or T units. If we don't add a unit
* suffix, we will append the fract string, if it is non-NULL. We can
@@ -190,22 +174,35 @@ char *do_big_num(int64 num, int human_flag, const char *fract)
char *s;
int len, negated;
if (human_flag && !number_separator) {
char buf[32];
snprintf(buf, sizeof buf, "%f", 3.14);
if (strchr(buf, '.') != NULL)
number_separator = ',';
else
number_separator = '.';
}
if (human_flag && !number_separator)
(void)get_number_separator();
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
if (human_flag > 1) {
if (human_flag == 2)
HUMANIFY(1000);
else
HUMANIFY(1024);
int mult = human_flag == 2 ? 1000 : 1024;
if (num >= mult || num <= -mult) {
double dnum = (double)num / mult;
char units;
if (num < 0)
dnum = -dnum;
if (dnum < mult)
units = 'K';
else if ((dnum /= mult) < mult)
units = 'M';
else if ((dnum /= mult) < mult)
units = 'G';
else if ((dnum /= mult) < mult)
units = 'T';
else {
dnum /= mult;
units = 'P';
}
if (num < 0)
dnum = -dnum;
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units);
return bufs[n];
}
}
s = bufs[n] + sizeof bufs[0] - 1;

37
lib/md-defines.h Normal file
View File

@@ -0,0 +1,37 @@
/* Keep this simple so both C and ASM can use it */
/* These allow something like CFLAGS=-DDISABLE_SHA512_DIGEST */
#ifdef DISABLE_SHA256_DIGEST
#undef SHA256_DIGEST_LENGTH
#endif
#ifdef DISABLE_SHA512_DIGEST
#undef SHA512_DIGEST_LENGTH
#endif
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#if defined SHA512_DIGEST_LENGTH
#define MAX_DIGEST_LEN SHA512_DIGEST_LENGTH
#elif defined SHA256_DIGEST_LENGTH
#define MAX_DIGEST_LEN SHA256_DIGEST_LENGTH
#elif defined SHA_DIGEST_LENGTH
#define MAX_DIGEST_LEN SHA_DIGEST_LENGTH
#else
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#endif
#define CSUM_CHUNK 64
#define CSUM_gone -1
#define CSUM_NONE 0
#define CSUM_MD4_ARCHAIC 1
#define CSUM_MD4_BUSTED 2
#define CSUM_MD4_OLD 3
#define CSUM_MD4 4
#define CSUM_MD5 5
#define CSUM_XXH64 6
#define CSUM_XXH3_64 7
#define CSUM_XXH3_128 8
#define CSUM_SHA1 9
#define CSUM_SHA256 10
#define CSUM_SHA512 11

701
lib/md5-asm-x86_64.S Normal file
View File

@@ -0,0 +1,701 @@
/*
* x86-64 optimized assembler MD5 implementation
*
* Author: Marc Bevand, 2004
*
* This code was placed in the public domain by the author. The original
* publication can be found at:
*
* https://www.zorinaq.com/papers/md5-amd64.html
*/
/*
* No modifications were made aside from changing the function and file names.
* The MD5_CTX structure as expected here (from OpenSSL) is binary compatible
* with the md_context used by rsync, for the fields accessed.
*
* Benchmarks (in MB/s) C ASM
* - Intel Atom D2700 302 334
* - Intel i7-7700hq 351 376
* - AMD ThreadRipper 2950x 728 784
*
* The original code was also incorporated into OpenSSL. It has since been
* modified there. Those changes have not been made here due to licensing
* incompatibilities. Benchmarks of those changes on the above CPUs did not
* show any significant difference in performance, though.
*/
#include "config.h"
#include "md-defines.h"
#ifdef USE_MD5_ASM /* { */
#ifdef __APPLE__
#define md5_process_asm _md5_process_asm
#endif
.text
.align 16
.globl md5_process_asm
md5_process_asm:
push %rbp
push %rbx
push %r12
push %r13 # not really useful (r13 is unused)
push %r14
push %r15
# rdi = arg #1 (ctx, MD5_CTX pointer)
# rsi = arg #2 (ptr, data pointer)
# rdx = arg #3 (nbr, number of 16-word blocks to process)
mov %rdi, %rbp # rbp = ctx
shl $6, %rdx # rdx = nbr in bytes
lea (%rsi,%rdx), %rdi # rdi = end
mov 0*4(%rbp), %eax # eax = ctx->A
mov 1*4(%rbp), %ebx # ebx = ctx->B
mov 2*4(%rbp), %ecx # ecx = ctx->C
mov 3*4(%rbp), %edx # edx = ctx->D
# end is 'rdi'
# ptr is 'rsi'
# A is 'eax'
# B is 'ebx'
# C is 'ecx'
# D is 'edx'
cmp %rdi, %rsi # cmp end with ptr
je 1f # jmp if ptr == end
# BEGIN of loop over 16-word blocks
2: # save old values of A, B, C, D
mov %eax, %r8d
mov %ebx, %r9d
mov %ecx, %r14d
mov %edx, %r15d
mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
xor %ecx, %r11d /* y ^ ... */
lea -680876936(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r11d /* x & ... */
xor %edx, %r11d /* z ^ ... */
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
add %r11d, %eax /* dst += ... */
rol $7, %eax /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %ebx, %eax /* dst += x */
xor %ebx, %r11d /* y ^ ... */
lea -389564586(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r11d /* x & ... */
xor %ecx, %r11d /* z ^ ... */
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
add %r11d, %edx /* dst += ... */
rol $12, %edx /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %eax, %edx /* dst += x */
xor %eax, %r11d /* y ^ ... */
lea 606105819(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r11d /* x & ... */
xor %ebx, %r11d /* z ^ ... */
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
add %r11d, %ecx /* dst += ... */
rol $17, %ecx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %edx, %ecx /* dst += x */
xor %edx, %r11d /* y ^ ... */
lea -1044525330(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r11d /* x & ... */
xor %eax, %r11d /* z ^ ... */
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
add %r11d, %ebx /* dst += ... */
rol $22, %ebx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %ecx, %ebx /* dst += x */
xor %ecx, %r11d /* y ^ ... */
lea -176418897(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r11d /* x & ... */
xor %edx, %r11d /* z ^ ... */
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
add %r11d, %eax /* dst += ... */
rol $7, %eax /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %ebx, %eax /* dst += x */
xor %ebx, %r11d /* y ^ ... */
lea 1200080426(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r11d /* x & ... */
xor %ecx, %r11d /* z ^ ... */
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
add %r11d, %edx /* dst += ... */
rol $12, %edx /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %eax, %edx /* dst += x */
xor %eax, %r11d /* y ^ ... */
lea -1473231341(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r11d /* x & ... */
xor %ebx, %r11d /* z ^ ... */
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
add %r11d, %ecx /* dst += ... */
rol $17, %ecx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %edx, %ecx /* dst += x */
xor %edx, %r11d /* y ^ ... */
lea -45705983(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r11d /* x & ... */
xor %eax, %r11d /* z ^ ... */
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
add %r11d, %ebx /* dst += ... */
rol $22, %ebx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %ecx, %ebx /* dst += x */
xor %ecx, %r11d /* y ^ ... */
lea 1770035416(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r11d /* x & ... */
xor %edx, %r11d /* z ^ ... */
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
add %r11d, %eax /* dst += ... */
rol $7, %eax /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %ebx, %eax /* dst += x */
xor %ebx, %r11d /* y ^ ... */
lea -1958414417(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r11d /* x & ... */
xor %ecx, %r11d /* z ^ ... */
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
add %r11d, %edx /* dst += ... */
rol $12, %edx /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %eax, %edx /* dst += x */
xor %eax, %r11d /* y ^ ... */
lea -42063(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r11d /* x & ... */
xor %ebx, %r11d /* z ^ ... */
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
add %r11d, %ecx /* dst += ... */
rol $17, %ecx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %edx, %ecx /* dst += x */
xor %edx, %r11d /* y ^ ... */
lea -1990404162(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r11d /* x & ... */
xor %eax, %r11d /* z ^ ... */
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
add %r11d, %ebx /* dst += ... */
rol $22, %ebx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %ecx, %ebx /* dst += x */
xor %ecx, %r11d /* y ^ ... */
lea 1804603682(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r11d /* x & ... */
xor %edx, %r11d /* z ^ ... */
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
add %r11d, %eax /* dst += ... */
rol $7, %eax /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %ebx, %eax /* dst += x */
xor %ebx, %r11d /* y ^ ... */
lea -40341101(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r11d /* x & ... */
xor %ecx, %r11d /* z ^ ... */
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
add %r11d, %edx /* dst += ... */
rol $12, %edx /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %eax, %edx /* dst += x */
xor %eax, %r11d /* y ^ ... */
lea -1502002290(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r11d /* x & ... */
xor %ebx, %r11d /* z ^ ... */
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
add %r11d, %ecx /* dst += ... */
rol $17, %ecx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %edx, %ecx /* dst += x */
xor %edx, %r11d /* y ^ ... */
lea 1236535329(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r11d /* x & ... */
xor %eax, %r11d /* z ^ ... */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
add %r11d, %ebx /* dst += ... */
rol $22, %ebx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %ecx, %ebx /* dst += x */
mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
not %r11d /* not z */
lea -165796510(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r12d /* x & z */
and %ecx, %r11d /* y & (not z) */
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %r12d, %eax /* dst += ... */
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
rol $5, %eax /* dst <<< s */
add %ebx, %eax /* dst += x */
not %r11d /* not z */
lea -1069501632(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r12d /* x & z */
and %ebx, %r11d /* y & (not z) */
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %r12d, %edx /* dst += ... */
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
rol $9, %edx /* dst <<< s */
add %eax, %edx /* dst += x */
not %r11d /* not z */
lea 643717713(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r12d /* x & z */
and %eax, %r11d /* y & (not z) */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %r12d, %ecx /* dst += ... */
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
rol $14, %ecx /* dst <<< s */
add %edx, %ecx /* dst += x */
not %r11d /* not z */
lea -373897302(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r12d /* x & z */
and %edx, %r11d /* y & (not z) */
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %r12d, %ebx /* dst += ... */
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
rol $20, %ebx /* dst <<< s */
add %ecx, %ebx /* dst += x */
not %r11d /* not z */
lea -701558691(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r12d /* x & z */
and %ecx, %r11d /* y & (not z) */
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %r12d, %eax /* dst += ... */
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
rol $5, %eax /* dst <<< s */
add %ebx, %eax /* dst += x */
not %r11d /* not z */
lea 38016083(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r12d /* x & z */
and %ebx, %r11d /* y & (not z) */
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %r12d, %edx /* dst += ... */
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
rol $9, %edx /* dst <<< s */
add %eax, %edx /* dst += x */
not %r11d /* not z */
lea -660478335(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r12d /* x & z */
and %eax, %r11d /* y & (not z) */
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %r12d, %ecx /* dst += ... */
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
rol $14, %ecx /* dst <<< s */
add %edx, %ecx /* dst += x */
not %r11d /* not z */
lea -405537848(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r12d /* x & z */
and %edx, %r11d /* y & (not z) */
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %r12d, %ebx /* dst += ... */
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
rol $20, %ebx /* dst <<< s */
add %ecx, %ebx /* dst += x */
not %r11d /* not z */
lea 568446438(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r12d /* x & z */
and %ecx, %r11d /* y & (not z) */
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %r12d, %eax /* dst += ... */
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
rol $5, %eax /* dst <<< s */
add %ebx, %eax /* dst += x */
not %r11d /* not z */
lea -1019803690(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r12d /* x & z */
and %ebx, %r11d /* y & (not z) */
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %r12d, %edx /* dst += ... */
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
rol $9, %edx /* dst <<< s */
add %eax, %edx /* dst += x */
not %r11d /* not z */
lea -187363961(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r12d /* x & z */
and %eax, %r11d /* y & (not z) */
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %r12d, %ecx /* dst += ... */
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
rol $14, %ecx /* dst <<< s */
add %edx, %ecx /* dst += x */
not %r11d /* not z */
lea 1163531501(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r12d /* x & z */
and %edx, %r11d /* y & (not z) */
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %r12d, %ebx /* dst += ... */
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
rol $20, %ebx /* dst <<< s */
add %ecx, %ebx /* dst += x */
not %r11d /* not z */
lea -1444681467(%eax,%r10d),%eax /* Const + dst + ... */
and %ebx, %r12d /* x & z */
and %ecx, %r11d /* y & (not z) */
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
add %r12d, %eax /* dst += ... */
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
rol $5, %eax /* dst <<< s */
add %ebx, %eax /* dst += x */
not %r11d /* not z */
lea -51403784(%edx,%r10d),%edx /* Const + dst + ... */
and %eax, %r12d /* x & z */
and %ebx, %r11d /* y & (not z) */
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
add %r12d, %edx /* dst += ... */
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
rol $9, %edx /* dst <<< s */
add %eax, %edx /* dst += x */
not %r11d /* not z */
lea 1735328473(%ecx,%r10d),%ecx /* Const + dst + ... */
and %edx, %r12d /* x & z */
and %eax, %r11d /* y & (not z) */
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
add %r12d, %ecx /* dst += ... */
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
rol $14, %ecx /* dst <<< s */
add %edx, %ecx /* dst += x */
not %r11d /* not z */
lea -1926607734(%ebx,%r10d),%ebx /* Const + dst + ... */
and %ecx, %r12d /* x & z */
and %edx, %r11d /* y & (not z) */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
add %r12d, %ebx /* dst += ... */
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
rol $20, %ebx /* dst <<< s */
add %ecx, %ebx /* dst += x */
mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
lea -378558(%eax,%r10d),%eax /* Const + dst + ... */
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
xor %edx, %r11d /* z ^ ... */
xor %ebx, %r11d /* x ^ ... */
add %r11d, %eax /* dst += ... */
rol $4, %eax /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
add %ebx, %eax /* dst += x */
lea -2022574463(%edx,%r10d),%edx /* Const + dst + ... */
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
xor %ecx, %r11d /* z ^ ... */
xor %eax, %r11d /* x ^ ... */
add %r11d, %edx /* dst += ... */
rol $11, %edx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
add %eax, %edx /* dst += x */
lea 1839030562(%ecx,%r10d),%ecx /* Const + dst + ... */
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
xor %ebx, %r11d /* z ^ ... */
xor %edx, %r11d /* x ^ ... */
add %r11d, %ecx /* dst += ... */
rol $16, %ecx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
add %edx, %ecx /* dst += x */
lea -35309556(%ebx,%r10d),%ebx /* Const + dst + ... */
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
xor %eax, %r11d /* z ^ ... */
xor %ecx, %r11d /* x ^ ... */
add %r11d, %ebx /* dst += ... */
rol $23, %ebx /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
add %ecx, %ebx /* dst += x */
lea -1530992060(%eax,%r10d),%eax /* Const + dst + ... */
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
xor %edx, %r11d /* z ^ ... */
xor %ebx, %r11d /* x ^ ... */
add %r11d, %eax /* dst += ... */
rol $4, %eax /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
add %ebx, %eax /* dst += x */
lea 1272893353(%edx,%r10d),%edx /* Const + dst + ... */
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
xor %ecx, %r11d /* z ^ ... */
xor %eax, %r11d /* x ^ ... */
add %r11d, %edx /* dst += ... */
rol $11, %edx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
add %eax, %edx /* dst += x */
lea -155497632(%ecx,%r10d),%ecx /* Const + dst + ... */
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
xor %ebx, %r11d /* z ^ ... */
xor %edx, %r11d /* x ^ ... */
add %r11d, %ecx /* dst += ... */
rol $16, %ecx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
add %edx, %ecx /* dst += x */
lea -1094730640(%ebx,%r10d),%ebx /* Const + dst + ... */
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
xor %eax, %r11d /* z ^ ... */
xor %ecx, %r11d /* x ^ ... */
add %r11d, %ebx /* dst += ... */
rol $23, %ebx /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
add %ecx, %ebx /* dst += x */
lea 681279174(%eax,%r10d),%eax /* Const + dst + ... */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
xor %edx, %r11d /* z ^ ... */
xor %ebx, %r11d /* x ^ ... */
add %r11d, %eax /* dst += ... */
rol $4, %eax /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
add %ebx, %eax /* dst += x */
lea -358537222(%edx,%r10d),%edx /* Const + dst + ... */
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
xor %ecx, %r11d /* z ^ ... */
xor %eax, %r11d /* x ^ ... */
add %r11d, %edx /* dst += ... */
rol $11, %edx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
add %eax, %edx /* dst += x */
lea -722521979(%ecx,%r10d),%ecx /* Const + dst + ... */
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
xor %ebx, %r11d /* z ^ ... */
xor %edx, %r11d /* x ^ ... */
add %r11d, %ecx /* dst += ... */
rol $16, %ecx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
add %edx, %ecx /* dst += x */
lea 76029189(%ebx,%r10d),%ebx /* Const + dst + ... */
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
xor %eax, %r11d /* z ^ ... */
xor %ecx, %r11d /* x ^ ... */
add %r11d, %ebx /* dst += ... */
rol $23, %ebx /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
add %ecx, %ebx /* dst += x */
lea -640364487(%eax,%r10d),%eax /* Const + dst + ... */
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
xor %edx, %r11d /* z ^ ... */
xor %ebx, %r11d /* x ^ ... */
add %r11d, %eax /* dst += ... */
rol $4, %eax /* dst <<< s */
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
add %ebx, %eax /* dst += x */
lea -421815835(%edx,%r10d),%edx /* Const + dst + ... */
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
xor %ecx, %r11d /* z ^ ... */
xor %eax, %r11d /* x ^ ... */
add %r11d, %edx /* dst += ... */
rol $11, %edx /* dst <<< s */
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
add %eax, %edx /* dst += x */
lea 530742520(%ecx,%r10d),%ecx /* Const + dst + ... */
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
xor %ebx, %r11d /* z ^ ... */
xor %edx, %r11d /* x ^ ... */
add %r11d, %ecx /* dst += ... */
rol $16, %ecx /* dst <<< s */
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
add %edx, %ecx /* dst += x */
lea -995338651(%ebx,%r10d),%ebx /* Const + dst + ... */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
xor %eax, %r11d /* z ^ ... */
xor %ecx, %r11d /* x ^ ... */
add %r11d, %ebx /* dst += ... */
rol $23, %ebx /* dst <<< s */
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
add %ecx, %ebx /* dst += x */
mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */
mov $0xffffffff, %r11d
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/
lea -198630844(%eax,%r10d),%eax /* Const + dst + ... */
or %ebx, %r11d /* x | ... */
xor %ecx, %r11d /* y ^ ... */
add %r11d, %eax /* dst += ... */
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
mov $0xffffffff, %r11d
rol $6, %eax /* dst <<< s */
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
add %ebx, %eax /* dst += x */
lea 1126891415(%edx,%r10d),%edx /* Const + dst + ... */
or %eax, %r11d /* x | ... */
xor %ebx, %r11d /* y ^ ... */
add %r11d, %edx /* dst += ... */
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
mov $0xffffffff, %r11d
rol $10, %edx /* dst <<< s */
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
add %eax, %edx /* dst += x */
lea -1416354905(%ecx,%r10d),%ecx /* Const + dst + ... */
or %edx, %r11d /* x | ... */
xor %eax, %r11d /* y ^ ... */
add %r11d, %ecx /* dst += ... */
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
mov $0xffffffff, %r11d
rol $15, %ecx /* dst <<< s */
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
add %edx, %ecx /* dst += x */
lea -57434055(%ebx,%r10d),%ebx /* Const + dst + ... */
or %ecx, %r11d /* x | ... */
xor %edx, %r11d /* y ^ ... */
add %r11d, %ebx /* dst += ... */
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
mov $0xffffffff, %r11d
rol $21, %ebx /* dst <<< s */
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
add %ecx, %ebx /* dst += x */
lea 1700485571(%eax,%r10d),%eax /* Const + dst + ... */
or %ebx, %r11d /* x | ... */
xor %ecx, %r11d /* y ^ ... */
add %r11d, %eax /* dst += ... */
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
mov $0xffffffff, %r11d
rol $6, %eax /* dst <<< s */
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
add %ebx, %eax /* dst += x */
lea -1894986606(%edx,%r10d),%edx /* Const + dst + ... */
or %eax, %r11d /* x | ... */
xor %ebx, %r11d /* y ^ ... */
add %r11d, %edx /* dst += ... */
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
mov $0xffffffff, %r11d
rol $10, %edx /* dst <<< s */
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
add %eax, %edx /* dst += x */
lea -1051523(%ecx,%r10d),%ecx /* Const + dst + ... */
or %edx, %r11d /* x | ... */
xor %eax, %r11d /* y ^ ... */
add %r11d, %ecx /* dst += ... */
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
mov $0xffffffff, %r11d
rol $15, %ecx /* dst <<< s */
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
add %edx, %ecx /* dst += x */
lea -2054922799(%ebx,%r10d),%ebx /* Const + dst + ... */
or %ecx, %r11d /* x | ... */
xor %edx, %r11d /* y ^ ... */
add %r11d, %ebx /* dst += ... */
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
mov $0xffffffff, %r11d
rol $21, %ebx /* dst <<< s */
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
add %ecx, %ebx /* dst += x */
lea 1873313359(%eax,%r10d),%eax /* Const + dst + ... */
or %ebx, %r11d /* x | ... */
xor %ecx, %r11d /* y ^ ... */
add %r11d, %eax /* dst += ... */
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
mov $0xffffffff, %r11d
rol $6, %eax /* dst <<< s */
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
add %ebx, %eax /* dst += x */
lea -30611744(%edx,%r10d),%edx /* Const + dst + ... */
or %eax, %r11d /* x | ... */
xor %ebx, %r11d /* y ^ ... */
add %r11d, %edx /* dst += ... */
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
mov $0xffffffff, %r11d
rol $10, %edx /* dst <<< s */
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
add %eax, %edx /* dst += x */
lea -1560198380(%ecx,%r10d),%ecx /* Const + dst + ... */
or %edx, %r11d /* x | ... */
xor %eax, %r11d /* y ^ ... */
add %r11d, %ecx /* dst += ... */
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
mov $0xffffffff, %r11d
rol $15, %ecx /* dst <<< s */
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
add %edx, %ecx /* dst += x */
lea 1309151649(%ebx,%r10d),%ebx /* Const + dst + ... */
or %ecx, %r11d /* x | ... */
xor %edx, %r11d /* y ^ ... */
add %r11d, %ebx /* dst += ... */
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
mov $0xffffffff, %r11d
rol $21, %ebx /* dst <<< s */
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
add %ecx, %ebx /* dst += x */
lea -145523070(%eax,%r10d),%eax /* Const + dst + ... */
or %ebx, %r11d /* x | ... */
xor %ecx, %r11d /* y ^ ... */
add %r11d, %eax /* dst += ... */
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
mov $0xffffffff, %r11d
rol $6, %eax /* dst <<< s */
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
add %ebx, %eax /* dst += x */
lea -1120210379(%edx,%r10d),%edx /* Const + dst + ... */
or %eax, %r11d /* x | ... */
xor %ebx, %r11d /* y ^ ... */
add %r11d, %edx /* dst += ... */
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
mov $0xffffffff, %r11d
rol $10, %edx /* dst <<< s */
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
add %eax, %edx /* dst += x */
lea 718787259(%ecx,%r10d),%ecx /* Const + dst + ... */
or %edx, %r11d /* x | ... */
xor %eax, %r11d /* y ^ ... */
add %r11d, %ecx /* dst += ... */
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
mov $0xffffffff, %r11d
rol $15, %ecx /* dst <<< s */
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
add %edx, %ecx /* dst += x */
lea -343485551(%ebx,%r10d),%ebx /* Const + dst + ... */
or %ecx, %r11d /* x | ... */
xor %edx, %r11d /* y ^ ... */
add %r11d, %ebx /* dst += ... */
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
mov $0xffffffff, %r11d
rol $21, %ebx /* dst <<< s */
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
add %ecx, %ebx /* dst += x */
# add old values of A, B, C, D
add %r8d, %eax
add %r9d, %ebx
add %r14d, %ecx
add %r15d, %edx
# loop control
add $64, %rsi # ptr += 64
cmp %rdi, %rsi # cmp end with ptr
jb 2b # jmp if ptr < end
# END of loop over 16-word blocks
1:
mov %eax, 0*4(%rbp) # ctx->A = A
mov %ebx, 1*4(%rbp) # ctx->B = B
mov %ecx, 2*4(%rbp) # ctx->C = C
mov %edx, 3*4(%rbp) # ctx->D = D
pop %r15
pop %r14
pop %r13 # not really useful (r13 is unused)
pop %r12
pop %rbx
pop %rbp
ret
#endif /* } USE_MD5_ASM */

View File

@@ -2,6 +2,7 @@
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2001-2003 Christophe Devine
* Copyright (C) 2007-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
@@ -146,6 +147,13 @@ static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
ctx->D += D;
}
#ifdef USE_MD5_ASM
#if CSUM_CHUNK != 64
#error The MD5 ASM code does not support CSUM_CHUNK != 64
#endif
extern void md5_process_asm(md_context *ctx, const void *data, size_t num);
#endif
void md5_update(md_context *ctx, const uchar *input, uint32 length)
{
uint32 left, fill;
@@ -170,17 +178,26 @@ void md5_update(md_context *ctx, const uchar *input, uint32 length)
left = 0;
}
#ifdef USE_MD5_ASM /* { */
if (length >= CSUM_CHUNK) {
uint32 chunks = length / CSUM_CHUNK;
md5_process_asm(ctx, input, chunks);
length -= chunks * CSUM_CHUNK;
input += chunks * CSUM_CHUNK;
}
#else /* } { */
while (length >= CSUM_CHUNK) {
md5_process(ctx, input);
length -= CSUM_CHUNK;
input += CSUM_CHUNK;
}
#endif /* } */
if (length)
memcpy(ctx->buffer + left, input, length);
}
static uchar md5_padding[CSUM_CHUNK] = { 0x80 };
static const uchar md5_padding[CSUM_CHUNK] = { 0x80 };
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
{
@@ -207,6 +224,8 @@ void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
SIVALu(digest, 12, ctx->D);
}
#ifdef TEST_MD5 /* { */
void get_md5(uchar *out, const uchar *input, int n)
{
md_context ctx;
@@ -215,8 +234,6 @@ void get_md5(uchar *out, const uchar *input, int n)
md5_result(&ctx, out);
}
#ifdef TEST_MD5
#include <stdlib.h>
#include <stdio.h>
@@ -301,4 +318,4 @@ int main(int argc, char *argv[])
return 0;
}
#endif
#endif /* } */

View File

@@ -4,7 +4,7 @@
* An implementation of MD4 designed for use in the SMB authentication protocol.
*
* Copyright (C) 1997-1998 Andrew Tridgell
* Copyright (C) 2005-2014 Wayne Davison
* Copyright (C) 2005-2020 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
@@ -193,6 +193,8 @@ void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN])
copy4(digest+12, m->D);
}
#ifdef TEST_MDFOUR
void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
{
md_context md;
@@ -201,7 +203,6 @@ void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
mdfour_result(&md, digest);
}
#ifdef TEST_MDFOUR
int protocol_version = 28;
static void file_checksum1(char *fname)

View File

@@ -1,10 +1,10 @@
/* The include file for both the MD4 and MD5 routines. */
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
#ifdef USE_OPENSSL
#include <openssl/sha.h>
#include <openssl/evp.h>
#endif
#include "md-defines.h"
typedef struct {
uint32 A, B, C, D;
@@ -17,10 +17,6 @@ void mdfour_begin(md_context *md);
void mdfour_update(md_context *md, const uchar *in, uint32 length);
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]);
void get_mdfour(uchar digest[MD4_DIGEST_LEN], const uchar *in, int length);
void md5_begin(md_context *ctx);
void md5_update(md_context *ctx, const uchar *input, uint32 length);
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]);
void get_md5(uchar digest[MD5_DIGEST_LEN], const uchar *input, int n);

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2019 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

View File

@@ -33,7 +33,7 @@ pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool
.SH SYNOPSIS
.B #include "pool_alloc.h"
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char*,char*,int), int \fIflags\fB);
\fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);

View File

@@ -9,8 +9,7 @@ struct alloc_pool
size_t size; /* extent size */
size_t quantum; /* allocation quantum */
struct pool_extent *extents; /* top extent is "live" */
void (*bomb)(); /* function to call if
* malloc fails */
void (*bomb)(const char*, const char*, int); /* called if malloc fails */
int flags;
/* statistical data */
@@ -43,21 +42,22 @@ struct align_test {
/* Temporarily cast a void* var into a char* var when adding an offset (to
* keep some compilers from complaining about the pointer arithmetic). */
#define PTR_ADD(b,o) ( (void*) ((char*)(b) + (o)) )
#define PTR_SUB(b,o) ( (void*) ((char*)(b) - (o)) )
alloc_pool_t
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags)
{
struct alloc_pool *pool;
if (!(pool = new0(struct alloc_pool)))
return NULL;
if ((MINALIGN & (MINALIGN - 1)) != 0) {
if ((MINALIGN & (MINALIGN - 1)) != (0)) {
if (bomb)
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
(*bomb)("Compiler error: MINALIGN is not a power of 2", __FILE__, __LINE__);
return NULL;
}
if (!(pool = new0(struct alloc_pool)))
return NULL;
if (!size)
size = POOL_DEF_EXTENT;
if (!quantum)
@@ -101,7 +101,7 @@ pool_destroy(alloc_pool_t p)
for (cur = pool->extents; cur; cur = next) {
next = cur->next;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
free(PTR_SUB(cur->start, sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);
@@ -169,7 +169,7 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
bomb_out:
if (pool->bomb)
(*pool->bomb)(bomb_msg);
(*pool->bomb)(bomb_msg, __FILE__, __LINE__);
return NULL;
}
@@ -236,7 +236,7 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (cur->free + cur->bound >= pool->size) {
prev->next = cur->next;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
free(PTR_SUB(cur->start, sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);
@@ -293,7 +293,7 @@ pool_free_old(alloc_pool_t p, void *addr)
while ((cur = next) != NULL) {
next = cur->next;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
free(PTR_SUB(cur->start, sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);

View File

@@ -7,7 +7,7 @@
typedef void *alloc_pool_t;
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags);
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags);
void pool_destroy(alloc_pool_t pool);
void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg);
void pool_free(alloc_pool_t pool, size_t size, void *addr);

View File

@@ -20,7 +20,7 @@
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
* causing nasty effects.
*
* More Recently:
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
@@ -34,7 +34,7 @@
* probably requires libm on most operating systems. Don't yet
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
* was pretty badly broken, it just wasn't being exercised in ways
* which showed it, so that's been fixed. Also, formated the code
* which showed it, so that's been fixed. Also, formatted the code
* to mutt conventions, and removed dead code left over from the
* original. Also, there is now a builtin-test, just compile with:
* gcc -I.. -DTEST_SNPRINTF -o snprintf snprintf.c -lm
@@ -77,7 +77,7 @@
* Fix incorrect zpadlen handling in fmtfp.
* Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it.
* few mods to make it easier to compile the tests.
* addedd the "Ollie" test to the floating point ones.
* added the "Ollie" test to the floating point ones.
*
* Martin Pool (mbp@samba.org) April 2003
* Remove NO_CONFIG_H so that the test case can be built within a source

View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
* Version 2.2.x
* Portable SMB ACL interface
* Copyright (C) Jeremy Allison 2000
* Copyright (C) 2007-2014 Wayne Davison
* Copyright (C) 2007-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
@@ -139,7 +139,9 @@ typedef struct acl *SMB_ACL_ENTRY_T;
/* Based on the Solaris & UnixWare code. */
#ifndef __TANDEM
#undef GROUP
#endif
#include <sys/aclv.h>
/* SVR4.2 ES/MP ACLs */
@@ -230,7 +232,7 @@ struct new_acl_entry{
#define SMB_ACL_ENTRY_T struct new_acl_entry*
#define SMB_ACL_T struct acl_entry_link*
#define SMB_ACL_TAG_T unsigned short
#define SMB_ACL_TYPE_T int

View File

@@ -2,7 +2,7 @@
* Extended attribute support for rsync.
*
* Copyright (C) 2004 Red Hat, Inc.
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2022 Wayne Davison
* Written by Jay Fenlason.
*
* This program is free software; you can redistribute it and/or modify
@@ -67,7 +67,7 @@ ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t si
u_int32_t offset = len;
size_t data_retrieved = len;
while (data_retrieved < size) {
len = getxattr(path, name, value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW);
len = getxattr(path, name, (char*)value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW);
if (len <= 0)
break;
data_retrieved += len;
@@ -126,9 +126,18 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
unsigned char keylen;
ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
if (len <= 0 || (size_t)len > size)
if (len <= 0 || size == 0)
return len;
if ((size_t)len >= size) {
/* FreeBSD extattr_list_xx() returns 'size' as 'len' in case there are
more data available, truncating the output, we solve this by signalling
ERANGE in case len == size so that the code in xattrs.c will retry with
a bigger buffer */
errno = ERANGE;
return -1;
}
/* FreeBSD puts a single-byte length before each string, with no '\0'
* terminator. We need to change this into a series of null-terminted
* strings. Since the size is the same, we can simply transform the
@@ -136,7 +145,7 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
for (off = 0; off < len; off += keylen + 1) {
keylen = ((unsigned char*)list)[off];
if (off + keylen >= len) {
/* Should be impossible, but kernel bugs happen! */
/* Should be impossible, but bugs happen! */
errno = EINVAL;
return -1;
}
@@ -167,7 +176,7 @@ static ssize_t read_xattr(int attrfd, void *buf, size_t buflen)
} else {
size_t bufpos;
for (bufpos = 0; bufpos < sb.st_size; ) {
ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - bufpos);
ssize_t cnt = read(attrfd, (char*)buf + bufpos, sb.st_size - bufpos);
if (cnt <= 0) {
if (cnt < 0 && errno == EINTR)
continue;
@@ -218,7 +227,7 @@ int sys_lsetxattr(const char *path, const char *name, const void *value, size_t
return -1;
for (bufpos = 0; bufpos < size; ) {
ssize_t cnt = write(attrfd, value+bufpos, size);
ssize_t cnt = write(attrfd, (char*)value + bufpos, size);
if (cnt <= 0) {
if (cnt < 0 && errno == EINTR)
continue;
@@ -274,7 +283,8 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
&& (dp->d_name[10] == 'o' || dp->d_name[10] == 'w'))
continue;
if ((ret += len+1) > size) {
ret += len + 1;
if ((size_t)ret > size) {
if (size == 0)
continue;
ret = -1;

View File

@@ -1,9 +1,9 @@
#ifdef SUPPORT_XATTRS
#if defined HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#elif defined HAVE_SYS_XATTR_H
#if defined HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#elif defined HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#elif defined HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif

View File

@@ -11,13 +11,12 @@
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
*
* This is based on loadparm.c from Samba, written by Andrew Tridgell
* and Karl Auer. Some of the changes are:
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2014 Wayne Davison <wayned@samba.org>
* Copyright (C) 2003-2020 Wayne Davison
*/
/* Load parameters.
@@ -31,7 +30,7 @@
* 1) add it to the global_vars or local_vars structure definition
* 2) add it to the parm_table
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
* 4) initialise it in the Defaults static stucture
* 4) initialise it in the Defaults static structure
*
* Notes:
* The configuration file is processed sequentially for speed. For this
@@ -43,23 +42,20 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
#include "default-dont-compress.h"
extern item_list dparam_list;
#define strequal(a, b) (strcasecmp(a, b)==0)
#define BOOLSTR(b) ((b) ? "Yes" : "No")
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
#define DEFAULT_DONT_COMPRESS "*.gz *.zip *.z *.rpm *.deb *.iso *.bz2" \
" *.t[gb]z *.7z *.mp[34] *.mov *.avi *.ogg *.jpg *.jpeg *.png" \
" *.lzo *.rzip *.lzma *.rar *.ace *.gpg *.xz *.txz *.lz *.tlz"
/* the following are used by loadparm for option lists */
typedef enum {
P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER,
P_BOOL, P_BOOLREV, P_BOOL3, P_CHAR, P_INTEGER,
P_OCTAL, P_PATH, P_STRING, P_ENUM
} parm_type;
@@ -69,7 +65,7 @@ typedef enum {
struct enum_list {
int value;
char *name;
const char *name;
};
struct parm_struct {
@@ -77,7 +73,7 @@ struct parm_struct {
parm_type type;
parm_class class;
void *ptr;
struct enum_list *enum_list;
const struct enum_list *enum_list;
unsigned flags;
};
@@ -90,148 +86,6 @@ struct parm_struct {
#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count)
#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char*)(p))-(char*)&Vars.l))
/* This structure describes global (ie., server-wide) parameters. */
typedef struct {
char *bind_address;
char *motd_file;
char *pid_file;
char *socket_options;
int listen_backlog;
int rsync_port;
} global_vars;
/* This structure describes a single section. Their order must match the
* initializers below, which you can accomplish by keeping each sub-section
* sorted. (e.g. in vim, just visually select each subsection and use !sort.)
* NOTE: the char* variables MUST all remain at the start of the stuct! */
typedef struct {
char *auth_users;
char *charset;
char *comment;
char *dont_compress;
char *exclude;
char *exclude_from;
char *filter;
char *gid;
char *hosts_allow;
char *hosts_deny;
char *include;
char *include_from;
char *incoming_chmod;
char *lock_file;
char *log_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
char *prexfer_exec;
char *refuse_options;
char *secrets_file;
char *temp_dir;
char *uid;
/* NOTE: update this macro if the last char* variable changes! */
#define LOCAL_STRING_COUNT() (offsetof(local_vars, uid) / sizeof (char*) + 1)
int max_connections;
int max_verbosity;
int syslog_facility;
int timeout;
BOOL fake_super;
BOOL forward_lookup;
BOOL ignore_errors;
BOOL ignore_nonreadable;
BOOL list;
BOOL munge_symlinks;
BOOL numeric_ids;
BOOL read_only;
BOOL reverse_lookup;
BOOL strict_modes;
BOOL transfer_logging;
BOOL use_chroot;
BOOL write_only;
} local_vars;
/* This structure describes the global variables (g) as well as the globally
* specified values of the local variables (l), which are used when modules
* don't specify their own values. */
typedef struct {
global_vars g;
local_vars l;
} all_vars;
/* The application defaults for all the variables. "Defaults" is
* used to re-initialize "Vars" before each config-file read.
*
* In order to keep these sorted in the same way as the structure
* above, use the variable name in the leading comment, including a
* trailing ';' (to avoid a sorting problem with trailing digits). */
static const all_vars Defaults = {
/* ==== global_vars ==== */
{
/* bind_address; */ NULL,
/* motd_file; */ NULL,
/* pid_file; */ NULL,
/* socket_options; */ NULL,
/* listen_backlog; */ 5,
/* rsync_port; */ 0,
},
/* ==== local_vars ==== */
{
/* auth_users; */ NULL,
/* charset; */ NULL,
/* comment; */ NULL,
/* dont_compress; */ DEFAULT_DONT_COMPRESS,
/* exclude; */ NULL,
/* exclude_from; */ NULL,
/* filter; */ NULL,
/* gid; */ NULL,
/* hosts_allow; */ NULL,
/* hosts_deny; */ NULL,
/* include; */ NULL,
/* include_from; */ NULL,
/* incoming_chmod; */ NULL,
/* lock_file; */ DEFAULT_LOCK_FILE,
/* log_file; */ NULL,
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
/* name; */ NULL,
/* outgoing_chmod; */ NULL,
/* path; */ NULL,
/* postxfer_exec; */ NULL,
/* prexfer_exec; */ NULL,
/* refuse_options; */ NULL,
/* secrets_file; */ NULL,
/* temp_dir; */ NULL,
/* uid; */ NULL,
/* max_connections; */ 0,
/* max_verbosity; */ 1,
/* syslog_facility; */ LOG_DAEMON,
/* timeout; */ 0,
/* fake_super; */ False,
/* forward_lookup; */ True,
/* ignore_errors; */ False,
/* ignore_nonreadable; */ False,
/* list; */ True,
/* munge_symlinks; */ (BOOL)-1,
/* numeric_ids; */ (BOOL)-1,
/* read_only; */ True,
/* reverse_lookup; */ True,
/* strict_modes; */ True,
/* transfer_logging; */ False,
/* use_chroot; */ True,
/* write_only; */ False,
}
};
/* The currently configured values for all the variables. */
static all_vars Vars;
/* Stack of "Vars" values used by the &include directive. */
static item_list Vars_stack = EMPTY_ITEM_LIST;
@@ -241,9 +95,7 @@ static item_list section_list = EMPTY_ITEM_LIST;
static int iSectionIndex = -1;
static BOOL bInGlobalSection = True;
#define NUMPARAMETERS (sizeof (parm_table) / sizeof (struct parm_struct))
static struct enum_list enum_facilities[] = {
static const struct enum_list enum_syslog_facility[] = {
#ifdef LOG_AUTH
{ LOG_AUTH, "auth" },
#endif
@@ -310,90 +162,27 @@ static struct enum_list enum_facilities[] = {
{ -1, NULL }
};
static struct parm_struct parm_table[] =
{
{"address", P_STRING, P_GLOBAL,&Vars.g.bind_address, NULL,0},
{"listen backlog", P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog, NULL,0},
{"motd file", P_STRING, P_GLOBAL,&Vars.g.motd_file, NULL,0},
{"pid file", P_STRING, P_GLOBAL,&Vars.g.pid_file, NULL,0},
{"port", P_INTEGER,P_GLOBAL,&Vars.g.rsync_port, NULL,0},
{"socket options", P_STRING, P_GLOBAL,&Vars.g.socket_options, NULL,0},
{"auth users", P_STRING, P_LOCAL, &Vars.l.auth_users, NULL,0},
{"charset", P_STRING, P_LOCAL, &Vars.l.charset, NULL,0},
{"comment", P_STRING, P_LOCAL, &Vars.l.comment, NULL,0},
{"dont compress", P_STRING, P_LOCAL, &Vars.l.dont_compress, NULL,0},
{"exclude from", P_STRING, P_LOCAL, &Vars.l.exclude_from, NULL,0},
{"exclude", P_STRING, P_LOCAL, &Vars.l.exclude, NULL,0},
{"fake super", P_BOOL, P_LOCAL, &Vars.l.fake_super, NULL,0},
{"filter", P_STRING, P_LOCAL, &Vars.l.filter, NULL,0},
{"forward lookup", P_BOOL, P_LOCAL, &Vars.l.forward_lookup, NULL,0},
{"gid", P_STRING, P_LOCAL, &Vars.l.gid, NULL,0},
{"hosts allow", P_STRING, P_LOCAL, &Vars.l.hosts_allow, NULL,0},
{"hosts deny", P_STRING, P_LOCAL, &Vars.l.hosts_deny, NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &Vars.l.ignore_errors, NULL,0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &Vars.l.ignore_nonreadable, NULL,0},
{"include from", P_STRING, P_LOCAL, &Vars.l.include_from, NULL,0},
{"include", P_STRING, P_LOCAL, &Vars.l.include, NULL,0},
{"incoming chmod", P_STRING, P_LOCAL, &Vars.l.incoming_chmod, NULL,0},
{"list", P_BOOL, P_LOCAL, &Vars.l.list, NULL,0},
{"lock file", P_STRING, P_LOCAL, &Vars.l.lock_file, NULL,0},
{"log file", P_STRING, P_LOCAL, &Vars.l.log_file, NULL,0},
{"log format", P_STRING, P_LOCAL, &Vars.l.log_format, NULL,0},
{"max connections", P_INTEGER,P_LOCAL, &Vars.l.max_connections, NULL,0},
{"max verbosity", P_INTEGER,P_LOCAL, &Vars.l.max_verbosity, NULL,0},
{"munge symlinks", P_BOOL, P_LOCAL, &Vars.l.munge_symlinks, NULL,0},
{"name", P_STRING, P_LOCAL, &Vars.l.name, NULL,0},
{"numeric ids", P_BOOL, P_LOCAL, &Vars.l.numeric_ids, NULL,0},
{"outgoing chmod", P_STRING, P_LOCAL, &Vars.l.outgoing_chmod, NULL,0},
{"path", P_PATH, P_LOCAL, &Vars.l.path, NULL,0},
#ifdef HAVE_PUTENV
{"post-xfer exec", P_STRING, P_LOCAL, &Vars.l.postxfer_exec, NULL,0},
{"pre-xfer exec", P_STRING, P_LOCAL, &Vars.l.prexfer_exec, NULL,0},
#endif
{"read only", P_BOOL, P_LOCAL, &Vars.l.read_only, NULL,0},
{"refuse options", P_STRING, P_LOCAL, &Vars.l.refuse_options, NULL,0},
{"reverse lookup", P_BOOL, P_LOCAL, &Vars.l.reverse_lookup, NULL,0},
{"secrets file", P_STRING, P_LOCAL, &Vars.l.secrets_file, NULL,0},
{"strict modes", P_BOOL, P_LOCAL, &Vars.l.strict_modes, NULL,0},
{"syslog facility", P_ENUM, P_LOCAL, &Vars.l.syslog_facility, enum_facilities,0},
{"temp dir", P_PATH, P_LOCAL, &Vars.l.temp_dir, NULL,0},
{"timeout", P_INTEGER,P_LOCAL, &Vars.l.timeout, NULL,0},
{"transfer logging", P_BOOL, P_LOCAL, &Vars.l.transfer_logging, NULL,0},
{"uid", P_STRING, P_LOCAL, &Vars.l.uid, NULL,0},
{"use chroot", P_BOOL, P_LOCAL, &Vars.l.use_chroot, NULL,0},
{"write only", P_BOOL, P_LOCAL, &Vars.l.write_only, NULL,0},
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
};
/* Initialise the Default all_vars structure. */
static void reset_all_vars(void)
{
memcpy(&Vars, &Defaults, sizeof Vars);
}
/* Expand %VAR% references. Any unknown vars or unrecognized
* syntax leaves the raw chars unchanged. */
static char *expand_vars(char *str)
static char *expand_vars(const char *str)
{
char *buf, *t, *f;
char *buf, *t;
const char *f;
int bufsize;
if (strchr(str, '%') == NULL)
return str;
if (!str || !strchr(str, '%'))
return (char *)str; /* TODO change return value to const char* at some point. */
bufsize = strlen(str) + 2048;
if ((buf = new_array(char, bufsize+1)) == NULL) /* +1 for trailing '\0' */
out_of_memory("expand_vars");
buf = new_array(char, bufsize+1); /* +1 for trailing '\0' */
for (t = buf, f = str; bufsize && *f; ) {
if (*f == '%' && *++f != '%') {
char *percent = strchr(f, '%');
if (percent) {
if (*f == '%' && isUpper(f+1)) {
const char *percent = strchr(f+1, '%');
if (percent && percent - f < bufsize) {
char *val;
*percent = '\0';
val = getenv(f);
*percent = '%';
strlcpy(t, f+1, percent - f);
val = getenv(t);
if (val) {
int len = strlcpy(t, val, bufsize+1);
if (len > bufsize)
@@ -404,7 +193,6 @@ static char *expand_vars(char *str)
continue;
}
}
f--;
}
*t++ = *f++;
bufsize--;
@@ -422,20 +210,25 @@ static char *expand_vars(char *str)
return buf;
}
/* Each "char* foo" has an associated "BOOL foo_EXP" that tracks if the string has been expanded yet or not. */
/* NOTE: use this function and all the FN_{GLOBAL,LOCAL} ones WITHOUT a trailing semicolon! */
#define RETURN_EXPANDED(val) {if (!val ## _EXP) {val = expand_vars(val); val ## _EXP = True;} return val ? val : "";}
/* In this section all the functions that are used to access the
* parameters from the rest of the program are defined. */
#define FN_GLOBAL_STRING(fn_name, ptr) \
char *fn_name(void) {return expand_vars(*(char **)(ptr) ? *(char **)(ptr) : "");}
#define FN_GLOBAL_BOOL(fn_name, ptr) \
BOOL fn_name(void) {return *(BOOL *)(ptr);}
#define FN_GLOBAL_CHAR(fn_name, ptr) \
char fn_name(void) {return *(char *)(ptr);}
#define FN_GLOBAL_INTEGER(fn_name, ptr) \
int fn_name(void) {return *(int *)(ptr);}
#define FN_GLOBAL_STRING(fn_name, val) \
char *fn_name(void) RETURN_EXPANDED(Vars.g.val)
#define FN_GLOBAL_BOOL(fn_name, val) \
BOOL fn_name(void) {return Vars.g.val;}
#define FN_GLOBAL_CHAR(fn_name, val) \
char fn_name(void) {return Vars.g.val;}
#define FN_GLOBAL_INTEGER(fn_name, val) \
int fn_name(void) {return Vars.g.val;}
#define FN_LOCAL_STRING(fn_name, val) \
char *fn_name(int i) {return expand_vars(LP_SNUM_OK(i) && iSECTION(i).val ? iSECTION(i).val : Vars.l.val ? Vars.l.val : "");}
char *fn_name(int i) {if (LP_SNUM_OK(i) && iSECTION(i).val) RETURN_EXPANDED(iSECTION(i).val) else RETURN_EXPANDED(Vars.l.val)}
#define FN_LOCAL_BOOL(fn_name, val) \
BOOL fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
#define FN_LOCAL_CHAR(fn_name, val) \
@@ -443,58 +236,24 @@ static char *expand_vars(char *str)
#define FN_LOCAL_INTEGER(fn_name, val) \
int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
FN_GLOBAL_STRING(lp_bind_address, &Vars.g.bind_address)
FN_GLOBAL_STRING(lp_motd_file, &Vars.g.motd_file)
FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file)
FN_GLOBAL_STRING(lp_socket_options, &Vars.g.socket_options)
/* The following include file contains:
*
* typedef global_vars - describes global (ie., server-wide) parameters.
* typedef local_vars - describes a single section.
* typedef all_vars - a combination of global_vars & local_vars.
* all_vars Defaults - the default values for all the variables.
* all_vars Vars - the currently configured values for all the variables.
* struct parm_struct parm_table - the strings & variables for the parser.
* FN_{LOCAL,GLOBAL}_{TYPE}() definition for all the lp_var_name() accessors.
*/
FN_GLOBAL_INTEGER(lp_listen_backlog, &Vars.g.listen_backlog)
FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port)
#include "daemon-parm.h"
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_charset, charset)
FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_filter, filter)
FN_LOCAL_STRING(lp_gid, gid)
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
FN_LOCAL_STRING(lp_include, include)
FN_LOCAL_STRING(lp_include_from, include_from)
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
FN_LOCAL_STRING(lp_lock_file, lock_file)
FN_LOCAL_STRING(lp_log_file, log_file)
FN_LOCAL_STRING(lp_log_format, log_format)
FN_LOCAL_STRING(lp_name, name)
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
FN_LOCAL_STRING(lp_path, path)
FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
FN_LOCAL_STRING(lp_uid, uid)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_BOOL(lp_fake_super, fake_super)
FN_LOCAL_BOOL(lp_forward_lookup, forward_lookup)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
FN_LOCAL_BOOL(lp_list, list)
FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
FN_LOCAL_BOOL(lp_read_only, read_only)
FN_LOCAL_BOOL(lp_reverse_lookup, reverse_lookup)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_write_only, write_only)
/* Initialise the Default all_vars structure. */
void reset_daemon_vars(void)
{
memcpy(&Vars, &Defaults, sizeof Vars);
}
/* Assign a copy of v to *s. Handles NULL strings. We don't worry
* about overwriting a malloc'd string because the long-running
@@ -503,25 +262,13 @@ FN_LOCAL_BOOL(lp_write_only, write_only)
* the start, so any lost memory is inconsequential. */
static inline void string_set(char **s, const char *v)
{
if (!v)
*s = NULL;
else if (!(*s = strdup(v)))
out_of_memory("string_set");
*s = v ? strdup(v) : NULL;
}
/* Copy the local_vars, strdup'ing any strings. NOTE: this depends on
* the structure starting with a contiguous list of the char* variables,
* and having an accurate count in the LOCAL_STRING_COUNT() macro. */
/* Copy local_vars into a new section. No need to strdup since we don't free. */
static void copy_section(local_vars *psectionDest, local_vars *psectionSource)
{
int count = LOCAL_STRING_COUNT();
char **strings = (char**)psectionDest;
memcpy(psectionDest, psectionSource, sizeof psectionDest[0]);
while (count--) {
if (strings[count] && !(strings[count] = strdup(strings[count])))
out_of_memory("copy_section");
}
}
/* Initialise a section to the defaults. */
@@ -531,19 +278,14 @@ static void init_section(local_vars *psection)
copy_section(psection, &Vars.l);
}
/* Do a case-insensitive, whitespace-ignoring string compare. */
static int strwicmp(char *psz1, char *psz2)
/* Do a case-insensitive, whitespace-ignoring string equality check. */
static int strwiEQ(char *psz1, char *psz2)
{
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
/* appropriate value. */
/* If one or both strings are NULL, we return equality right away. */
if (psz1 == psz2)
return 0;
if (psz1 == NULL)
return -1;
if (psz2 == NULL)
return 1;
if (psz1 == NULL || psz2 == NULL)
return 0;
/* sync the strings on first non-whitespace */
while (1) {
@@ -551,12 +293,14 @@ static int strwicmp(char *psz1, char *psz2)
psz1++;
while (isSpace(psz2))
psz2++;
if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
if (*psz1 == '\0' || *psz2 == '\0')
break;
if (toUpper(psz1) != toUpper(psz2))
break;
psz1++;
psz2++;
}
return *psz1 - *psz2;
return *psz1 == *psz2;
}
/* Find a section by name. Otherwise works like get_section. */
@@ -565,7 +309,7 @@ static int getsectionbyname(char *name)
int i;
for (i = section_list.count - 1; i >= 0; i--) {
if (strwicmp(iSECTION(i).name, name) == 0)
if (strwiEQ(iSECTION(i).name, name))
break;
}
@@ -605,7 +349,7 @@ static int map_parameter(char *parmname)
return -1;
for (iIndex = 0; parm_table[iIndex].label; iIndex++) {
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
if (strwiEQ(parm_table[iIndex].label, parmname))
return iIndex;
}
@@ -616,16 +360,14 @@ static int map_parameter(char *parmname)
/* Set a boolean variable from the text value stored in the passed string.
* Returns True in success, False if the passed string does not correctly
* represent a boolean. */
static BOOL set_boolean(BOOL *pb, char *parmvalue)
static BOOL set_boolean(BOOL *pb, char *parmvalue, int allow_unset)
{
if (strwicmp(parmvalue, "yes") == 0
|| strwicmp(parmvalue, "true") == 0
|| strwicmp(parmvalue, "1") == 0)
if (strwiEQ(parmvalue, "yes") || strwiEQ(parmvalue, "true") || strwiEQ(parmvalue, "1"))
*pb = True;
else if (strwicmp(parmvalue, "no") == 0
|| strwicmp(parmvalue, "False") == 0
|| strwicmp(parmvalue, "0") == 0)
else if (strwiEQ(parmvalue, "no") || strwiEQ(parmvalue, "false") || strwiEQ(parmvalue, "0"))
*pb = False;
else if (allow_unset && (strwiEQ(parmvalue, "unset") || strwiEQ(parmvalue, "-1")))
*pb = Unset;
else {
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue);
return False;
@@ -664,21 +406,25 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
switch (parm_table[parmnum].type) {
case P_PATH:
case P_STRING:
/* delay expansion of vars */
/* delay expansion of %VAR% strings */
break;
default:
/* expand any %VARS% now */
/* expand any %VAR% strings now */
parmvalue = expand_vars(parmvalue);
break;
}
switch (parm_table[parmnum].type) {
case P_BOOL:
set_boolean(parm_ptr, parmvalue);
set_boolean(parm_ptr, parmvalue, False);
break;
case P_BOOL3:
set_boolean(parm_ptr, parmvalue, True);
break;
case P_BOOLREV:
set_boolean(parm_ptr, parmvalue);
set_boolean(parm_ptr, parmvalue, False);
*(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
break;
@@ -691,7 +437,7 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
break;
case P_OCTAL:
sscanf(parmvalue, "%o", (int *)parm_ptr);
sscanf(parmvalue, "%o", (unsigned int *)parm_ptr);
break;
case P_PATH:
@@ -748,7 +494,7 @@ static BOOL do_section(char *sectionname)
return True;
}
isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
isglobal = strwiEQ(sectionname, GLOBAL_NAME);
/* At the end of the global section, add any --dparam items. */
if (bInGlobalSection && !isglobal) {
@@ -792,7 +538,7 @@ int lp_load(char *pszFname, int globals_only)
{
bInGlobalSection = True;
reset_all_vars();
reset_daemon_vars();
/* We get sections first, so have to start 'behind' to make up. */
iSectionIndex = -1;

246
log.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-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
@@ -31,11 +31,10 @@ extern int am_generator;
extern int local_server;
extern int quiet;
extern int module_id;
extern int checksum_len;
extern int allow_8bit_chars;
extern int protocol_version;
extern int always_checksum;
extern int preserve_times;
extern int preserve_mtimes;
extern int msgs2stderr;
extern int stdout_format_has_i;
extern int stdout_format_has_o_or_i;
@@ -61,6 +60,8 @@ extern unsigned int module_dirlen;
extern char sender_file_sum[MAX_DIGEST_LEN];
extern const char undetermined_hostname[];
extern struct name_num_item *xfer_sum_nni, *file_sum_nni;
static int log_initialised;
static int logfile_was_closed;
static FILE *logfile_fp;
@@ -74,8 +75,8 @@ static int64 initial_data_written;
static int64 initial_data_read;
struct {
int code;
char const *name;
int code;
char const *name;
} const rerr_names[] = {
{ RERR_SYNTAX , "syntax or usage error" },
{ RERR_PROTOCOL , "protocol incompatibility" },
@@ -132,21 +133,16 @@ static void logit(int priority, const char *buf)
static void syslog_init()
{
static int been_here = 0;
int options = LOG_PID;
if (been_here)
return;
been_here = 1;
#ifdef LOG_NDELAY
options |= LOG_NDELAY;
#endif
#ifdef LOG_DAEMON
openlog("rsyncd", options, lp_syslog_facility(module_id));
openlog(lp_syslog_tag(module_id), options, lp_syslog_facility(module_id));
#else
openlog("rsyncd", options);
openlog(lp_syslog_tag(module_id), options);
#endif
#ifndef LOG_NDELAY
@@ -166,14 +162,16 @@ static void logfile_open(void)
rsyserr(FERROR, fopen_errno,
"failed to open log-file %s", logfile_name);
rprintf(FINFO, "Ignoring \"log file\" setting.\n");
logfile_name = "";
}
}
void log_init(int restart)
{
if (log_initialised) {
if (!restart)
if (!restart) /* Note: a restart only happens with am_daemon */
return;
assert(logfile_name); /* all am_daemon procs got at least an empty string */
if (strcmp(logfile_name, lp_log_file(module_id)) != 0) {
if (logfile_fp) {
fclose(logfile_fp);
@@ -183,7 +181,8 @@ void log_init(int restart)
logfile_name = NULL;
} else if (*logfile_name)
return; /* unchanged, non-empty "log file" names */
else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id))
else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id)
|| strcmp(lp_syslog_tag(-1), lp_syslog_tag(module_id)) != 0)
closelog();
else
return; /* unchanged syslog settings */
@@ -205,6 +204,7 @@ void log_init(int restart)
syslog_init();
}
/* Note that this close & reopen idiom intentionally ignores syslog logging. */
void logfile_close(void)
{
if (logfile_fp) {
@@ -222,25 +222,26 @@ void logfile_reopen(void)
}
}
static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
static void filtered_fwrite(FILE *f, const char *in_buf, int in_len, int use_isprint, char end_char)
{
const char *s, *end = buf + len;
for (s = buf; s < end; s++) {
if ((s < end - 4
&& *s == '\\' && s[1] == '#'
&& isDigit(s + 2)
&& isDigit(s + 3)
&& isDigit(s + 4))
|| (*s != '\t'
&& ((use_isprint && !isPrint(s))
|| *(uchar*)s < ' '))) {
if (s != buf && fwrite(buf, s - buf, 1, f) != 1)
char outbuf[1024], *ob = outbuf;
const char *end = in_buf + in_len;
while (in_buf < end) {
if (ob - outbuf >= (int)sizeof outbuf - 10) {
if (fwrite(outbuf, ob - outbuf, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
fprintf(f, "\\#%03o", *(uchar*)s);
buf = s + 1;
ob = outbuf;
}
if ((in_buf < end - 4 && *in_buf == '\\' && in_buf[1] == '#'
&& isDigit(in_buf + 2) && isDigit(in_buf + 3) && isDigit(in_buf + 4))
|| (*in_buf != '\t' && ((use_isprint && !isPrint(in_buf)) || *(uchar*)in_buf < ' ')))
ob += snprintf(ob, 6, "\\#%03o", *(uchar*)in_buf++);
else
*ob++ = *in_buf++;
}
if (buf != end && fwrite(buf, end - buf, 1, f) != 1)
if (end_char) /* The "- 10" above means that there is always room for one more char here. */
*ob++ = end_char;
if (ob != outbuf && fwrite(outbuf, ob - outbuf, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
}
@@ -249,8 +250,8 @@ static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
* can happen with certain fatal conditions. */
void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
{
int trailing_CR_or_NL;
FILE *f = msgs2stderr ? stderr : stdout;
char trailing_CR_or_NL;
FILE *f = msgs2stderr == 1 ? stderr : stdout;
#ifdef ICONV_OPTION
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
#else
@@ -262,15 +263,14 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
if (len < 0)
exit_cleanup(RERR_MESSAGEIO);
if (msgs2stderr) {
if (!am_daemon) {
if (code == FLOG)
return;
goto output_msg;
}
if (code == FCLIENT)
return;
code = FLOG;
if (msgs2stderr == 1) {
/* A normal daemon can get msgs2stderr set if the socket is busted, so we
* change the message destination into an FLOG message in order to try to
* get some info about an abnormal-exit into the log file. An rsh daemon
* can have this set via user request, so we'll leave the code alone so
* that the msg gets logged and then sent to stderr after that. */
if (am_daemon > 0 && code != FCLIENT)
code = FLOG;
} else if (send_msgs_to_gen) {
assert(!is_utf8);
/* Pass the message to our sibling in native charset. */
@@ -306,10 +306,28 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
} else if (code == FLOG)
return;
if (quiet && code == FINFO)
return;
switch (code) {
case FERROR_XFER:
got_xfer_error = 1;
/* FALL THROUGH */
case FERROR:
case FWARNING:
f = stderr;
break;
case FINFO:
if (quiet)
return;
break;
/*case FLOG:*/
/*case FCLIENT:*/
/*case FERROR_UTF8:*/
/*case FERROR_SOCKET:*/
default:
fprintf(stderr, "Bad logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
exit_cleanup(RERR_MESSAGEIO);
}
if (am_server) {
if (am_server && msgs2stderr != 1 && (msgs2stderr != 2 || f != stderr)) {
enum msgcode msg = (enum msgcode)code;
if (protocol_version < 30) {
if (msg == MSG_ERROR)
@@ -320,40 +338,19 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
/* Pass the message to the non-server side. */
if (send_msg(msg, buf, len, !is_utf8))
return;
if (am_daemon) {
if (am_daemon > 0) {
/* TODO: can we send the error to the user somehow? */
return;
}
f = stderr;
}
output_msg:
switch (code) {
case FERROR_XFER:
got_xfer_error = 1;
/* FALL THROUGH */
case FERROR:
case FERROR_UTF8:
case FERROR_SOCKET:
case FWARNING:
f = stderr;
break;
case FLOG:
case FINFO:
case FCLIENT:
break;
default:
fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
exit_cleanup(RERR_MESSAGEIO);
}
if (output_needs_newline) {
fputc('\n', f);
output_needs_newline = 0;
}
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
? buf[--len] : 0;
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') ? buf[--len] : '\0';
if (len && buf[0] == '\r') {
fputc('\r', f);
@@ -374,21 +371,33 @@ output_msg:
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
char trailing = inbuf.len ? '\0' : trailing_CR_or_NL;
filtered_fwrite(f, convbuf, outbuf.len, 0, trailing);
if (trailing) {
trailing_CR_or_NL = '\0';
fflush(f);
}
outbuf.len = 0;
}
if (!ierrno || ierrno == E2BIG)
continue;
fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++));
inbuf.len--;
/* Log one byte of illegal/incomplete sequence and continue with
* the next character. Check that the buffer is non-empty for the
* sake of robustness. */
if ((ierrno == EILSEQ || ierrno == EINVAL) && inbuf.len) {
fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++));
inbuf.len--;
}
}
if (trailing_CR_or_NL) {
fputc(trailing_CR_or_NL, f);
fflush(f);
}
} else
#endif
filtered_fwrite(f, buf, len, !allow_8bit_chars);
if (trailing_CR_or_NL) {
fputc(trailing_CR_or_NL, f);
fflush(f);
{
filtered_fwrite(f, buf, len, !allow_8bit_chars, trailing_CR_or_NL);
if (trailing_CR_or_NL)
fflush(f);
}
}
@@ -447,8 +456,7 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
char buf[BIGPATHBUFLEN];
size_t len;
strlcpy(buf, RSYNC_NAME ": ", sizeof buf);
len = (sizeof RSYNC_NAME ": ") - 1;
len = snprintf(buf, sizeof buf, RSYNC_NAME ": [%s] ", who_am_i());
va_start(ap, format);
len += vsnprintf(buf + len, sizeof buf - len, format, ap);
@@ -656,21 +664,10 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
n = auth_user;
break;
case 'b':
if (!(iflags & ITEM_TRANSFER))
b = 0;
else if (am_sender)
b = total_data_written - initial_data_written;
else
b = total_data_read - initial_data_read;
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
do_big_num(b, humanize, NULL));
n = buf2;
break;
case 'c':
if (!(iflags & ITEM_TRANSFER))
b = 0;
else if (!am_sender)
else if ((!!am_sender) ^ (*p == 'c'))
b = total_data_written - initial_data_written;
else
b = total_data_read - initial_data_read;
@@ -680,15 +677,18 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
n = buf2;
break;
case 'C':
if (protocol_version >= 30
&& (iflags & ITEM_TRANSFER
|| (always_checksum && S_ISREG(file->mode)))) {
const char *sum = iflags & ITEM_TRANSFER
? sender_file_sum : F_SUM(file);
n = sum_as_hex(sum);
} else {
memset(buf2, ' ', checksum_len*2);
buf2[checksum_len*2] = '\0';
n = NULL;
if (S_ISREG(file->mode)) {
if (always_checksum)
n = sum_as_hex(file_sum_nni->num, F_SUM(file), 1);
else if (iflags & ITEM_TRANSFER)
n = sum_as_hex(xfer_sum_nni->num, sender_file_sum, 0);
}
if (!n) {
int sum_len = csum_len_for_type(always_checksum ? file_sum_nni->num : xfer_sum_nni->num,
always_checksum);
memset(buf2, ' ', sum_len*2);
buf2[sum_len*2] = '\0';
n = buf2;
}
break;
@@ -699,14 +699,14 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
}
n = c = buf2 + MAXPATHLEN - 32;
c[0] = iflags & ITEM_LOCAL_CHANGE
? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c'
? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c'
: !(iflags & ITEM_TRANSFER) ? '.'
: !local_server && *op == 's' ? '<' : '>';
if (S_ISLNK(file->mode)) {
c[1] = 'L';
c[3] = '.';
c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times || !receiver_symlink_times
: !preserve_mtimes || !receiver_symlink_times
|| (iflags & ITEM_REPORT_TIMEFAIL) ? 'T' : 't';
} else {
c[1] = S_ISDIR(file->mode) ? 'd'
@@ -714,13 +714,15 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
: IS_DEVICE(file->mode) ? 'D' : 'f';
c[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times ? 'T' : 't';
: !preserve_mtimes ? 'T' : 't';
}
c[2] = !(iflags & ITEM_REPORT_CHANGE) ? '.' : 'c';
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.' : 'u';
c[8] = !(iflags & (ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME)) ? '.'
: BITS_SET(iflags, ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME) ? 'b'
: iflags & ITEM_REPORT_ATIME ? 'u' : 'n';
c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
c[11] = '\0';
@@ -817,8 +819,7 @@ void log_item(enum logcode code, struct file_struct *file, int iflags, const cha
log_formatted(FLOG, logfile_format, s_or_r, file, NULL, iflags, hlink);
}
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
const char *buf)
void maybe_log_item(struct file_struct *file, int iflags, int itemizing, const char *buf)
{
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS;
int see_item = itemizing && (significant_flags || *buf
@@ -837,14 +838,24 @@ void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
void log_delete(const char *fname, int mode)
{
static struct {
union file_extras ex[4]; /* just in case... */
struct file_struct file;
} x; /* Zero-initialized due to static declaration. */
static struct file_struct *file = NULL;
int len = strlen(fname);
const char *fmt;
x.file.mode = mode;
if (!file) {
int extra_len = (file_extra_cnt + 2) * EXTRA_LEN;
char *bp;
#if EXTRA_ROUNDING > 0
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
#endif
bp = new_array0(char, FILE_STRUCT_LEN + extra_len + 1);
bp += extra_len;
file = (struct file_struct *)bp;
}
file->mode = mode;
if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
if (S_ISDIR(mode))
@@ -854,14 +865,14 @@ void log_delete(const char *fname, int mode)
;
else {
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
log_formatted(FCLIENT, fmt, "del.", file, fname, ITEM_DELETED, NULL);
}
if (!logfile_name || dry_run || !logfile_format)
return;
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
log_formatted(FLOG, fmt, "del.", file, fname, ITEM_DELETED, NULL);
}
/*
@@ -872,12 +883,15 @@ void log_delete(const char *fname, int mode)
*/
void log_exit(int code, const char *file, int line)
{
if (code == 0) {
/* The receiving side's stats are split between 2 procs until the
* end of the run, so only the sender can output non-final info. */
if (code == 0 || am_sender) {
rprintf(FLOG,"sent %s bytes received %s bytes total size %s\n",
big_num(stats.total_written),
big_num(stats.total_read),
big_num(stats.total_size));
} else if (am_server != 2) {
}
if (code != 0 && am_server != 2) {
const char *name;
name = rerr_name(code);
@@ -887,10 +901,10 @@ void log_exit(int code, const char *file, int line)
/* VANISHED is not an error, only a warning */
if (code == RERR_VANISHED) {
rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n",
name, code, file, line, who_am_i(), RSYNC_VERSION);
name, code, src_file(file), line, who_am_i(), rsync_version());
} else {
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
name, code, file, line, who_am_i(), RSYNC_VERSION);
name, code, src_file(file), line, who_am_i(), rsync_version());
}
}
}

21
m4/have_type.m4 Normal file
View File

@@ -0,0 +1,21 @@
dnl AC_HAVE_TYPE(TYPE,INCLUDES)
AC_DEFUN([AC_HAVE_TYPE], [
cv=`echo "$1" | sed 'y%./+- %__p__%'`
AC_MSG_CHECKING(for $1)
AC_CACHE_VAL([ac_cv_type_$cv],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT
$2]],
[[$1 foo;]])],
[eval "ac_cv_type_$cv=yes"],
[eval "ac_cv_type_$cv=no"]))dnl
ac_foo=`eval echo \\$ac_cv_type_$cv`
AC_MSG_RESULT($ac_foo)
if test "$ac_foo" = yes; then
ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
if false; then
AC_CHECK_TYPES($1)
fi
AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1'])
fi
])

27
m4/header_major_fixed.m4 Normal file
View File

@@ -0,0 +1,27 @@
AC_DEFUN([AC_HEADER_MAJOR_FIXED],
[AC_CACHE_CHECK(whether sys/types.h defines makedev,
ac_cv_header_sys_types_h_makedev,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/types.h>]],
[[return makedev(0, 0);]])],
[if grep sys/sysmacros.h conftest.err >/dev/null; then
ac_cv_header_sys_types_h_makedev=no
else
ac_cv_header_sys_types_h_makedev=yes
fi],
[ac_cv_header_sys_types_h_makedev=no])
])
if test $ac_cv_header_sys_types_h_makedev = no; then
AC_CHECK_HEADER(sys/mkdev.h,
[AC_DEFINE(MAJOR_IN_MKDEV, 1,
[Define to 1 if `major', `minor', and `makedev' are
declared in <mkdev.h>.])])
if test $ac_cv_header_sys_mkdev_h = no; then
AC_CHECK_HEADER(sys/sysmacros.h,
[AC_DEFINE(MAJOR_IN_SYSMACROS, 1,
[Define to 1 if `major', `minor', and `makedev'
are declared in <sysmacros.h>.])])
fi
fi
])

45
m4/socklen_t.m4 Normal file
View File

@@ -0,0 +1,45 @@
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we
dnl have to test to find something that will work.
dnl This is no good, because passing the wrong pointer on C compilers is
dnl likely to only generate a warning, not an error. We don't call this at
dnl the moment.
AC_DEFUN([TYPE_SOCKLEN_T],
[
AC_CHECK_TYPE([socklen_t], ,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([rsync_cv_socklen_t_equiv],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
rsync_cv_socklen_t_equiv=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
int getpeername (int, $arg2 *, $t *);
]],[[
$t len;
getpeername(0,0,&len);
]])],[
rsync_cv_socklen_t_equiv="$t"
break
])
done
done
if test "x$rsync_cv_socklen_t_equiv" = x; then
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
fi
])
AC_MSG_RESULT($rsync_cv_socklen_t_equiv)
AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv,
[type to use in place of socklen_t if not defined])],
[#include <sys/types.h>
#include <sys/socket.h>])
])

View File

@@ -0,0 +1,23 @@
dnl AC_VALIDATE_CACHE_SYSTEM_TYPE[(cmd)]
dnl if the cache file is inconsistent with the current host,
dnl target and build system types, execute CMD or print a default
dnl error message.
AC_DEFUN([AC_VALIDATE_CACHE_SYSTEM_TYPE], [
AC_REQUIRE([AC_CANONICAL_SYSTEM])
AC_MSG_CHECKING([config.cache system type])
if { test x"${ac_cv_host_system_type+set}" = x"set" &&
test x"$ac_cv_host_system_type" != x"$host"; } ||
{ test x"${ac_cv_build_system_type+set}" = x"set" &&
test x"$ac_cv_build_system_type" != x"$build"; } ||
{ test x"${ac_cv_target_system_type+set}" = x"set" &&
test x"$ac_cv_target_system_type" != x"$target"; }; then
AC_MSG_RESULT([different])
ifelse($#, 1, [$1],
[AC_MSG_ERROR(["you must remove config.cache and restart configure"])])
else
AC_MSG_RESULT([same])
fi
ac_cv_host_system_type="$host"
ac_cv_build_system_type="$build"
ac_cv_target_system_type="$target"
])

555
main.c
View File

File diff suppressed because it is too large Load Diff

48
match.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2014 Wayne Davison
* Copyright (C) 2003-2023 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
@@ -24,7 +24,9 @@
extern int checksum_seed;
extern int append_mode;
extern int checksum_len;
extern struct name_num_item *xfer_sum_nni;
extern int xfer_sum_len;
int updating_basis_file;
char sender_file_sum[MAX_DIGEST_LEN];
@@ -65,8 +67,6 @@ static void build_hash_table(struct sum_struct *s)
if (hash_table)
free(hash_table);
hash_table = new_array(int32, tablesize);
if (!hash_table)
out_of_memory("build_hash_table");
alloc_size = tablesize;
}
@@ -102,8 +102,7 @@ static OFF_T last_match;
* If i >= 0, the number of a matched token. If < 0, indicates we have
* only literal data. A -1 will send a 0-token-int too, and a -2 sends
* only literal data, w/o any token-int. */
static void matched(int f, struct sum_struct *s, struct map_struct *buf,
OFF_T offset, int32 i)
static void matched(int f, struct sum_struct *s, struct map_struct *buf, OFF_T offset, int32 i)
{
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
int32 j;
@@ -143,11 +142,14 @@ static void hash_search(int f,struct sum_struct *s,
{
OFF_T offset, aligned_offset, end;
int32 k, want_i, aligned_i, backup;
char sum2[SUM_LENGTH];
char sum2[MAX_DIGEST_LEN];
uint32 s1, s2, sum;
int more;
schar *map;
// prevent possible memory leaks
memset(sum2, 0, sizeof sum2);
/* want_i is used to encourage adjacent matches, allowing the RLL
* coding of the output to work more efficiently. */
want_i = 0;
@@ -207,7 +209,7 @@ static void hash_search(int f,struct sum_struct *s,
* either >= our offset or identical data at that offset.
* Remove any bypassed entries that we can never use. */
if (updating_basis_file && s->sums[i].offset < offset
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) {
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) {
*prev = s->sums[i].chain;
continue;
}
@@ -233,7 +235,7 @@ static void hash_search(int f,struct sum_struct *s,
done_csum2 = 1;
}
if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) {
if (memcmp(sum2, sum2_at(s, i), s->s2length) != 0) {
false_alarms++;
continue;
}
@@ -253,7 +255,7 @@ static void hash_search(int f,struct sum_struct *s,
if (i != aligned_i) {
if (sum != s->sums[aligned_i].sum1
|| l != s->sums[aligned_i].len
|| memcmp(sum2, s->sums[aligned_i].sum2, s->s2length) != 0)
|| memcmp(sum2, sum2_at(s, aligned_i), s->s2length) != 0)
goto check_want_i;
i = aligned_i;
}
@@ -272,7 +274,7 @@ static void hash_search(int f,struct sum_struct *s,
if (sum != s->sums[i].sum1)
goto check_want_i;
get_checksum2((char *)map, l, sum2);
if (memcmp(sum2, s->sums[i].sum2, s->s2length) != 0)
if (memcmp(sum2, sum2_at(s, i), s->s2length) != 0)
goto check_want_i;
/* OK, we have a re-alignment match. Bump the offset
* forward to the new match point. */
@@ -288,10 +290,10 @@ static void hash_search(int f,struct sum_struct *s,
/* we've found a match, but now check to see
* if want_i can hint at a better match. */
if (i != want_i && want_i < s->count
&& (!updating_basis_file || s->sums[want_i].offset >= offset
|| s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
&& sum == s->sums[want_i].sum1
&& memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) {
&& (!updating_basis_file || s->sums[want_i].offset >= offset
|| s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
&& sum == s->sums[want_i].sum1
&& memcmp(sum2, sum2_at(s, want_i), s->s2length) == 0) {
/* we've found an adjacent match - the RLL coder
* will be happy */
i = want_i;
@@ -317,8 +319,7 @@ static void hash_search(int f,struct sum_struct *s,
/* Trim off the first byte from the checksum */
more = offset + k < len;
map = (schar *)map_ptr(buf, offset - backup, k + more + backup)
+ backup;
map = (schar *)map_ptr(buf, offset - backup, k + more + backup) + backup;
s1 -= map[0] + CHAR_OFFSET;
s2 -= k * (map[0]+CHAR_OFFSET);
@@ -366,7 +367,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
matches = 0;
data_transfer = 0;
sum_init(checksum_seed);
sum_init(xfer_sum_nni, checksum_seed);
if (append_mode > 0) {
if (append_mode == 2) {
@@ -407,23 +408,22 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
matched(f, s, buf, len, -1);
}
if (sum_end(sender_file_sum) != checksum_len)
overflow_exit("checksum_len"); /* Impossible... */
sum_end(sender_file_sum);
/* If we had a read error, send a bad checksum. We use all bits
* off as long as the checksum doesn't happen to be that, in
* which case we turn the last 0 bit into a 1. */
if (buf && buf->status != 0) {
int i;
for (i = 0; i < checksum_len && sender_file_sum[i] == 0; i++) {}
memset(sender_file_sum, 0, checksum_len);
if (i == checksum_len)
for (i = 0; i < xfer_sum_len && sender_file_sum[i] == 0; i++) {}
memset(sender_file_sum, 0, xfer_sum_len);
if (i == xfer_sum_len)
sender_file_sum[i-1]++;
}
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO,"sending file_sum\n");
write_buf(f, sender_file_sum, checksum_len);
write_buf(f, sender_file_sum, xfer_sum_len);
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",

42
maybe-make-man Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
if [ $# != 1 ]; then
echo "Usage: $0 NAME.NUM.md" 1>&2
exit 1
fi
inname="$1"
srcdir=`dirname "$0"`
flagfile="$srcdir/.md2man-works"
force_flagfile="$srcdir/.md2man-force"
if [ ! -f "$flagfile" ]; then
# We test our smallest manpage just to see if the python setup works.
if "$srcdir/md-convert" --test "$srcdir/rsync-ssl.1.md" >/dev/null 2>&1; then
touch $flagfile
else
outname=`echo "$inname" | sed 's/\.md$//'`
if [ -f "$outname" ]; then
exit 0
elif [ -f "$srcdir/$outname" ]; then
echo "Copying $srcdir/$outname"
cp -p "$srcdir/$outname" .
exit 0
else
echo "ERROR: $outname cannot be created."
if [ -f "$HOME/build_farm/build_test.fns" ]; then
exit 0 # No exit errorno to avoid a build failure in the samba build farm
else
exit 1
fi
fi
fi
fi
if [ -f "$force_flagfile" ]; then
opt='--force-link-text'
else
opt=''
fi
"$srcdir/md-convert" $opt "$srcdir/$inname"

667
md-convert Executable file
View File

@@ -0,0 +1,667 @@
#!/usr/bin/env python3
# This script transforms markdown files into html and (optionally) nroff. The
# output files are written into the current directory named for the input file
# without the .md suffix and either the .html suffix or no suffix.
#
# If the input .md file has a section number at the end of the name (e.g.,
# rsync.1.md) a nroff file is also output (PROJ.NUM.md -> PROJ.NUM).
#
# The markdown input format has one extra extension: if a numbered list starts
# at 0, it is turned into a description list. The dl's dt tag is taken from the
# contents of the first tag inside the li, which is usually a p, code, or
# strong tag.
#
# The cmarkgfm or commonmark lib is used to transforms the input file into
# html. Then, the html.parser is used as a state machine that lets us tweak
# the html and (optionally) output nroff data based on the html tags.
#
# If the string @USE_GFM_PARSER@ exists in the file, the string is removed and
# a github-flavored-markup parser is used to parse the file.
#
# The man-page .md files also get the vars @VERSION@, @BINDIR@, and @LIBDIR@
# substituted. Some of these values depend on the Makefile $(prefix) (see the
# generated Makefile). If the maintainer wants to build files for /usr/local
# while creating release-ready man-page files for /usr, use the environment to
# set RSYNC_OVERRIDE_PREFIX=/usr.
# Copyright (C) 2020 - 2021 Wayne Davison
#
# This program is freely redistributable.
import os, sys, re, argparse, subprocess, time
from html.parser import HTMLParser
VALID_PAGES = 'README INSTALL COPYING rsync.1 rrsync.1 rsync-ssl.1 rsyncd.conf.5'.split()
CONSUMES_TXT = set('h1 h2 h3 p li pre'.split())
HTML_START = """\
<html><head>
<title>%TITLE%</title>
<meta charset="UTF-8"/>
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
<style>
body {
max-width: 50em;
margin: auto;
}
body, b, strong, u {
font-family: 'Roboto', sans-serif;
}
a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
a.tgt:after { content: '🔗'; }
a.tgt:hover { color: #444; background-color: #eaeaea; }
h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
code {
font-family: 'Roboto Mono', monospace;
font-weight: bold;
white-space: pre;
}
pre code {
display: block;
font-weight: normal;
}
blockquote pre code {
background: #f1f1f1;
}
dd p:first-of-type {
margin-block-start: 0em;
}
</style>
</head><body>
"""
TABLE_STYLE = """\
table {
border-color: grey;
border-spacing: 0;
}
tr {
border-top: 1px solid grey;
}
tr:nth-child(2n) {
background-color: #f6f8fa;
}
th, td {
border: 1px solid #dfe2e5;
text-align: center;
padding-left: 1em;
padding-right: 1em;
}
"""
MAN_HTML_END = """\
<div style="float: right"><p><i>%s</i></p></div>
"""
HTML_END = """\
</body></html>
"""
MAN_START = r"""
.TH "%s" "%s" "%s" "%s" "User Commands"
.\" prefix=%s
""".lstrip()
MAN_END = """\
"""
NORM_FONT = ('\1', r"\fP")
BOLD_FONT = ('\2', r"\fB")
UNDR_FONT = ('\3', r"\fI")
NBR_DASH = ('\4', r"\-")
NBR_SPACE = ('\xa0', r"\ ")
FILENAME_RE = re.compile(r'^(?P<fn>(?P<srcdir>.+/)?(?P<name>(?P<prog>[^/]+?)(\.(?P<sect>\d+))?)\.md)$')
ASSIGNMENT_RE = re.compile(r'^(\w+)=(.+)')
VER_RE = re.compile(r'^#define\s+RSYNC_VERSION\s+"(\d.+?)"', re.M)
TZ_RE = re.compile(r'^#define\s+MAINTAINER_TZ_OFFSET\s+(-?\d+(\.\d+)?)', re.M)
VAR_REF_RE = re.compile(r'\$\{(\w+)\}')
VERSION_RE = re.compile(r' (\d[.\d]+)[, ]')
BIN_CHARS_RE = re.compile(r'[\1-\7]+')
LONG_OPT_DASH_RE = re.compile(r'(--\w[-\w]+)')
SPACE_DOUBLE_DASH_RE = re.compile(r'\s--(\s)')
NON_SPACE_SINGLE_DASH_RE = re.compile(r'(^|\W)-')
WHITESPACE_RE = re.compile(r'\s')
CODE_BLOCK_RE = re.compile(r'[%s]([^=%s]+)[=%s]' % (BOLD_FONT[0], NORM_FONT[0], NORM_FONT[0]))
NBR_DASH_RE = re.compile(r'[%s]' % NBR_DASH[0])
INVALID_TARGET_CHARS_RE = re.compile(r'[^-A-Za-z0-9._]')
INVALID_START_CHAR_RE = re.compile(r'^([^A-Za-z0-9])')
MANIFY_LINESTART_RE = re.compile(r"^(['.])", flags=re.M)
md_parser = None
env_subs = { }
warning_count = 0
def main():
for mdfn in args.mdfiles:
parse_md_file(mdfn)
if args.test:
print("The test was successful.")
def parse_md_file(mdfn):
fi = FILENAME_RE.match(mdfn)
if not fi:
die('Failed to parse a md input file name:', mdfn)
fi = argparse.Namespace(**fi.groupdict())
fi.want_manpage = not not fi.sect
if fi.want_manpage:
fi.title = fi.prog + '(' + fi.sect + ') manpage'
else:
fi.title = fi.prog + ' for rsync'
if fi.want_manpage:
if not env_subs:
find_man_substitutions()
prog_ver = 'rsync ' + env_subs['VERSION']
if fi.prog != 'rsync':
prog_ver = fi.prog + ' from ' + prog_ver
fi.man_headings = (fi.prog, fi.sect, env_subs['date'], prog_ver, env_subs['prefix'])
with open(mdfn, 'r', encoding='utf-8') as fh:
txt = fh.read()
use_gfm_parser = '@USE_GFM_PARSER@' in txt
if use_gfm_parser:
txt = txt.replace('@USE_GFM_PARSER@', '')
if fi.want_manpage:
txt = (txt.replace('@VERSION@', env_subs['VERSION'])
.replace('@BINDIR@', env_subs['bindir'])
.replace('@LIBDIR@', env_subs['libdir']))
if use_gfm_parser:
if not gfm_parser:
die('Input file requires cmarkgfm parser:', mdfn)
fi.html_in = gfm_parser(txt)
else:
fi.html_in = md_parser(txt)
txt = None
TransformHtml(fi)
if args.test:
return
output_list = [ (fi.name + '.html', fi.html_out) ]
if fi.want_manpage:
output_list += [ (fi.name, fi.man_out) ]
for fn, txt in output_list:
if args.dest and args.dest != '.':
fn = os.path.join(args.dest, fn)
if os.path.lexists(fn):
os.unlink(fn)
print("Wrote:", fn)
with open(fn, 'w', encoding='utf-8') as fh:
fh.write(txt)
def find_man_substitutions():
srcdir = os.path.dirname(sys.argv[0]) + '/'
mtime = 0
git_dir = srcdir + '.git'
if os.path.lexists(git_dir):
mtime = int(subprocess.check_output(['git', '--git-dir', git_dir, 'log', '-1', '--format=%at']))
# Allow "prefix" to be overridden via the environment:
env_subs['prefix'] = os.environ.get('RSYNC_OVERRIDE_PREFIX', None)
if args.test:
env_subs['VERSION'] = '1.0.0'
env_subs['bindir'] = '/usr/bin'
env_subs['libdir'] = '/usr/lib/rsync'
tz_offset = 0
else:
for fn in (srcdir + 'version.h', 'Makefile'):
try:
st = os.lstat(fn)
except OSError:
die('Failed to find', srcdir + fn)
if not mtime:
mtime = st.st_mtime
with open(srcdir + 'version.h', 'r', encoding='utf-8') as fh:
txt = fh.read()
m = VER_RE.search(txt)
env_subs['VERSION'] = m.group(1)
m = TZ_RE.search(txt) # the tzdata lib may not be installed, so we use a simple hour offset
tz_offset = float(m.group(1)) * 60 * 60
with open('Makefile', 'r', encoding='utf-8') as fh:
for line in fh:
m = ASSIGNMENT_RE.match(line)
if not m:
continue
var, val = (m.group(1), m.group(2))
if var == 'prefix' and env_subs[var] is not None:
continue
while VAR_REF_RE.search(val):
val = VAR_REF_RE.sub(lambda m: env_subs[m.group(1)], val)
env_subs[var] = val
if var == 'srcdir':
break
env_subs['date'] = time.strftime('%d %b %Y', time.gmtime(mtime + tz_offset)).lstrip('0')
if 'SOURCE_DATE_EPOCH' in os.environ:
env_subs['date'] = time.strftime('%d %b %Y', time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
def html_via_commonmark(txt):
return commonmark.HtmlRenderer().render(commonmark.Parser().parse(txt))
class TransformHtml(HTMLParser):
def __init__(self, fi):
HTMLParser.__init__(self, convert_charrefs=True)
self.fn = fi.fn
st = self.state = argparse.Namespace(
list_state = [ ],
p_macro = ".P\n",
at_first_tag_in_li = False,
at_first_tag_in_dd = False,
dt_from = None,
in_pre = False,
in_code = False,
html_out = [ HTML_START.replace('%TITLE%', fi.title) ],
man_out = [ ],
txt = '',
want_manpage = fi.want_manpage,
created_hashtags = set(),
derived_hashtags = set(),
referenced_hashtags = set(),
bad_hashtags = set(),
latest_targets = [ ],
opt_prefix = 'opt',
a_href = None,
a_href_external = False,
a_txt_start = None,
after_a_tag = False,
target_suf = '',
)
if st.want_manpage:
st.man_out.append(MAN_START % fi.man_headings)
if '</table>' in fi.html_in:
st.html_out[0] = st.html_out[0].replace('</style>', TABLE_STYLE + '</style>')
self.feed(fi.html_in)
fi.html_in = None
if st.want_manpage:
st.html_out.append(MAN_HTML_END % env_subs['date'])
st.html_out.append(HTML_END)
st.man_out.append(MAN_END)
fi.html_out = ''.join(st.html_out)
st.html_out = None
fi.man_out = ''.join(st.man_out)
st.man_out = None
for tgt, txt in st.derived_hashtags:
derived = txt2target(txt, tgt)
if derived not in st.created_hashtags:
txt = BIN_CHARS_RE.sub('', txt.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' '))
warn('Unknown derived hashtag link in', self.fn, 'based on:', (tgt, txt))
for bad in st.bad_hashtags:
if bad in st.created_hashtags:
warn('Missing "#" in hashtag link in', self.fn + ':', bad)
else:
warn('Unknown non-hashtag link in', self.fn + ':', bad)
for bad in st.referenced_hashtags - st.created_hashtags:
warn('Unknown hashtag link in', self.fn + ':', '#' + bad)
def handle_UE(self):
st = self.state
if st.txt.startswith(('.', ',', '!', '?', ';', ':')):
st.man_out[-1] = ".UE " + st.txt[0] + "\n"
st.txt = st.txt[1:]
st.after_a_tag = False
def handle_starttag(self, tag, attrs_list):
st = self.state
if args.debug:
self.output_debug('START', (tag, attrs_list))
if st.at_first_tag_in_li:
if st.list_state[-1] == 'dl':
st.dt_from = tag
if tag == 'p':
tag = 'dt'
else:
st.html_out.append('<dt>')
elif tag == 'p':
st.at_first_tag_in_dd = True # Kluge to suppress a .P at the start of an li.
st.at_first_tag_in_li = False
if tag == 'p':
if not st.at_first_tag_in_dd:
st.man_out.append(st.p_macro)
elif tag == 'li':
st.at_first_tag_in_li = True
lstate = st.list_state[-1]
if lstate == 'dl':
return
if lstate == 'o':
st.man_out.append(".IP o\n")
else:
st.man_out.append(".IP " + str(lstate) + ".\n")
st.list_state[-1] += 1
elif tag == 'blockquote':
st.man_out.append(".RS 4\n")
elif tag == 'pre':
st.in_pre = True
st.man_out.append(st.p_macro + ".nf\n")
elif tag == 'code' and not st.in_pre:
st.in_code = True
st.txt += BOLD_FONT[0]
elif tag == 'strong' or tag == 'b':
st.txt += BOLD_FONT[0]
elif tag == 'em' or tag == 'i':
if st.want_manpage:
tag = 'u' # Change it into underline to be more like the manpage
st.txt += UNDR_FONT[0]
elif tag == 'ol':
start = 1
for var, val in attrs_list:
if var == 'start':
start = int(val) # We only support integers.
break
if st.list_state:
st.man_out.append(".RS\n")
if start == 0:
tag = 'dl'
attrs_list = [ ]
st.list_state.append('dl')
else:
st.list_state.append(start)
st.man_out.append(st.p_macro)
st.p_macro = ".IP\n"
elif tag == 'ul':
st.man_out.append(st.p_macro)
if st.list_state:
st.man_out.append(".RS\n")
st.p_macro = ".IP\n"
st.list_state.append('o')
elif tag == 'hr':
st.man_out.append(".l\n")
st.html_out.append("<hr />")
return
elif tag == 'a':
st.a_href = None
for var, val in attrs_list:
if var == 'href':
if val.startswith(('https://', 'http://', 'mailto:', 'ftp:')):
if st.after_a_tag:
self.handle_UE()
st.man_out.append(manify(st.txt.strip()) + "\n")
st.man_out.append(".UR " + val + "\n")
st.txt = ''
st.a_href = val
st.a_href_external = True
elif '#' in val:
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'):
st.a_href = val
st.a_href_external = False
elif pg == '':
st.referenced_hashtags.add(tgt)
if tgt in st.latest_targets:
warn('Found link to the current section in', self.fn + ':', val)
elif val not in VALID_PAGES:
st.bad_hashtags.add(val)
st.a_txt_start = len(st.txt)
st.html_out.append('<' + tag + ''.join(' ' + var + '="' + htmlify(val) + '"' for var, val in attrs_list) + '>')
st.at_first_tag_in_dd = False
def handle_endtag(self, tag):
st = self.state
if args.debug:
self.output_debug('END', (tag,))
if st.after_a_tag:
self.handle_UE()
if tag in CONSUMES_TXT or st.dt_from == tag:
txt = st.txt.strip()
st.txt = ''
else:
txt = None
add_to_txt = None
if tag == 'h1':
tgt = txt
target_suf = ''
if tgt.startswith('NEWS for '):
m = VERSION_RE.search(tgt)
if m:
tgt = m.group(1)
st.target_suf = '-' + tgt
self.add_targets(tag, tgt)
elif tag == 'h2':
st.man_out.append(st.p_macro + '.SH "' + manify(txt) + '"\n')
self.add_targets(tag, txt, st.target_suf)
st.opt_prefix = 'dopt' if txt == 'DAEMON OPTIONS' else 'opt'
elif tag == 'h3':
st.man_out.append(st.p_macro + '.SS "' + manify(txt) + '"\n')
self.add_targets(tag, txt, st.target_suf)
elif tag == 'p':
if st.dt_from == 'p':
tag = 'dt'
st.man_out.append('.IP "' + manify(txt) + '"\n')
if txt.startswith(BOLD_FONT[0]):
self.add_targets(tag, txt)
st.dt_from = None
elif txt != '':
st.man_out.append(manify(txt) + "\n")
elif tag == 'li':
if st.list_state[-1] == 'dl':
if st.at_first_tag_in_li:
die("Invalid 0. -> td translation")
tag = 'dd'
if txt != '':
st.man_out.append(manify(txt) + "\n")
st.at_first_tag_in_li = False
elif tag == 'blockquote':
st.man_out.append(".RE\n")
elif tag == 'pre':
st.in_pre = False
st.man_out.append(manify(txt) + "\n.fi\n")
elif (tag == 'code' and not st.in_pre):
st.in_code = False
add_to_txt = NORM_FONT[0]
elif tag == 'strong' or tag == 'b':
add_to_txt = NORM_FONT[0]
elif tag == 'em' or tag == 'i':
if st.want_manpage:
tag = 'u' # Change it into underline to be more like the manpage
add_to_txt = NORM_FONT[0]
elif tag == 'ol' or tag == 'ul':
if st.list_state.pop() == 'dl':
tag = 'dl'
if st.list_state:
st.man_out.append(".RE\n")
else:
st.p_macro = ".P\n"
st.at_first_tag_in_dd = False
elif tag == 'hr':
return
elif tag == 'a':
if st.a_href_external:
st.txt = st.txt.strip()
if args.force_link_text or st.a_href != st.txt:
st.man_out.append(manify(st.txt) + "\n")
st.man_out.append(".UE\n") # This might get replaced with a punctuation version in handle_UE()
st.after_a_tag = True
st.a_href_external = False
st.txt = ''
elif st.a_href:
atxt = st.txt[st.a_txt_start:]
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('#', 1)
derived = txt2target(atxt, tgt)
if pg == '':
if derived in st.latest_targets:
warn('Found link to the current section in', self.fn + ':', st.a_href)
st.derived_hashtags.add((tgt, atxt))
st.html_out[j] = st.html_out[j].replace(find, 'href="' + pg + '#' + derived + '"')
break
else:
die('INTERNAL ERROR: failed to find href in html data:', find)
st.html_out.append('</' + tag + '>')
if add_to_txt:
if txt is None:
st.txt += add_to_txt
else:
txt += add_to_txt
if st.dt_from == tag:
st.man_out.append('.IP "' + manify(txt) + '"\n')
st.html_out.append('</dt><dd>')
st.at_first_tag_in_dd = True
st.dt_from = None
elif tag == 'dt':
st.html_out.append('<dd>')
st.at_first_tag_in_dd = True
def handle_data(self, txt):
st = self.state
if '](' in txt:
warn('Malformed link in', self.fn + ':', txt)
if args.debug:
self.output_debug('DATA', (txt,))
if st.in_pre:
html = htmlify(txt)
else:
txt = LONG_OPT_DASH_RE.sub(lambda x: x.group(1).replace('-', NBR_DASH[0]), txt)
txt = SPACE_DOUBLE_DASH_RE.sub(NBR_SPACE[0] + r'--\1', txt).replace('--', NBR_DASH[0]*2)
txt = NON_SPACE_SINGLE_DASH_RE.sub(r'\1' + NBR_DASH[0], txt)
html = htmlify(txt)
if st.in_code:
txt = WHITESPACE_RE.sub(NBR_SPACE[0], txt)
html = html.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' ') # <code> is non-breaking in CSS
st.html_out.append(html.replace(NBR_SPACE[0], '&nbsp;').replace(NBR_DASH[0], '-&#8288;'))
st.txt += txt
def add_targets(self, tag, txt, suf=None):
st = self.state
tag = '<' + tag + '>'
targets = CODE_BLOCK_RE.findall(txt)
if not targets:
targets = [ txt ]
tag_pos = 0
for txt in targets:
txt = txt2target(txt, st.opt_prefix)
if not txt:
continue
if suf:
txt += suf
if txt in st.created_hashtags:
for j in range(2, 1000):
chk = txt + '-' + str(j)
if chk not in st.created_hashtags:
print('Made link target unique:', chk)
txt = chk
break
if tag_pos == 0:
tag_pos -= 1
while st.html_out[tag_pos] != tag:
tag_pos -= 1
st.html_out[tag_pos] = tag[:-1] + ' id="' + txt + '">'
st.html_out.append('<a href="#' + txt + '" class="tgt"></a>')
tag_pos -= 1 # take into account the append
else:
st.html_out[tag_pos] = '<span id="' + txt + '"></span>' + st.html_out[tag_pos]
st.created_hashtags.add(txt)
st.latest_targets = targets
def output_debug(self, event, extra):
import pprint
st = self.state
if args.debug < 2:
st = argparse.Namespace(**vars(st))
if len(st.html_out) > 2:
st.html_out = ['...'] + st.html_out[-2:]
if len(st.man_out) > 2:
st.man_out = ['...'] + st.man_out[-2:]
print(event, extra)
pprint.PrettyPrinter(indent=2).pprint(vars(st))
def txt2target(txt, opt_prefix):
txt = txt.strip().rstrip(':')
m = CODE_BLOCK_RE.search(txt)
if m:
txt = m.group(1)
txt = NBR_DASH_RE.sub('-', txt)
txt = BIN_CHARS_RE.sub('', txt)
txt = INVALID_TARGET_CHARS_RE.sub('_', txt)
if opt_prefix and txt.startswith('-'):
txt = opt_prefix + txt
else:
txt = INVALID_START_CHAR_RE.sub(r't\1', txt)
return txt
def manify(txt):
return MANIFY_LINESTART_RE.sub(r'\&\1', txt.replace('\\', '\\\\')
.replace(NBR_SPACE[0], NBR_SPACE[1])
.replace(NBR_DASH[0], NBR_DASH[1])
.replace(NORM_FONT[0], NORM_FONT[1])
.replace(BOLD_FONT[0], BOLD_FONT[1])
.replace(UNDR_FONT[0], UNDR_FONT[1]))
def htmlify(txt):
return txt.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
def warn(*msg):
print(*msg, file=sys.stderr)
global warning_count
warning_count += 1
def die(*msg):
warn(*msg)
sys.exit(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Convert markdown into html and (optionally) nroff. Each input filename must have a .md suffix, which is changed to .html for the output filename. If the input filename ends with .num.md (e.g. foo.1.md) then a nroff file is also output with the input filename's .md suffix removed (e.g. foo.1).", add_help=False)
parser.add_argument('--test', action='store_true', help="Just test the parsing without outputting any files.")
parser.add_argument('--dest', metavar='DIR', help="Create files in DIR instead of the current directory.")
parser.add_argument('--force-link-text', action='store_true', help="Don't remove the link text if it matches the link href. Useful when nroff doesn't understand .UR and .UE.")
parser.add_argument('--debug', '-D', action='count', default=0, help='Output copious info on the html parsing. Repeat for even more.')
parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
parser.add_argument("mdfiles", metavar='FILE.md', nargs='+', help="One or more .md files to convert.")
args = parser.parse_args()
try:
import cmarkgfm
md_parser = cmarkgfm.markdown_to_html
gfm_parser = cmarkgfm.github_flavored_markdown_to_html
except:
try:
import commonmark
md_parser = html_via_commonmark
except:
die("Failed to find cmarkgfm or commonmark for python3.")
gfm_parser = None
main()
if warning_count:
sys.exit(1)

1
md2man Symbolic link
View File

@@ -0,0 +1 @@
md-convert

22
mkgitver Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/sh
srcdir=`dirname $0`
if [ ! -f git-version.h ]; then
touch git-version.h
fi
if test -d "$srcdir/.git" || test -f "$srcdir/.git"; then
gitver=`git describe --abbrev=8 2>/dev/null`
# NOTE: I'm avoiding "|" in sed since I'm not sure if sed -r is portable and "\|" fails on some OSes.
verchk=`echo "$gitver-" | sed -n '/^v3\.[0-9][0-9]*\.[0-9][0-9]*\(pre[0-9]*\)*-/p'`
if [ -n "$verchk" ]; 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"
mv git-version.h.new git-version.h
else
rm git-version.h.new
fi
fi
fi

40
mkproto.awk Normal file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/awk -f
BEGIN {
while ((getline i < "proto.h") > 0) old_protos = old_protos ? old_protos "\n" i : i
close("proto.h")
protos = "/* This file is automatically generated with \"make proto\". DO NOT EDIT */\n"
}
inheader {
protos = protos "\n" ((inheader = /\)[ \t]*$/ ? 0 : 1) ? $0 : $0 ";")
next
}
/^FN_(LOCAL|GLOBAL)_[^(]+\([^,()]+/ {
local = /^FN_LOCAL/
gsub(/^FN_(LOC|GLOB)AL_|,.*$/, "")
sub(/^BOOL\(/, "BOOL ")
sub(/^CHAR\(/, "char ")
sub(/^INTEGER\(/, "int ")
sub(/^STRING\(/, "char *")
protos = protos "\n" $0 (local ? "(int module_id);" : "(void);")
next
}
/^static|^extern|;/||!/^[A-Za-z][A-Za-z0-9_]* / { next }
/\(.*\)[ \t]*$/ {
protos = protos "\n" $0 ";"
next
}
/\(/ {
inheader = 1
protos = protos "\n" $0
}
END {
if (old_protos != protos) print protos > "proto.h"
system("touch proto.h-tstamp")
}

View File

@@ -1,48 +0,0 @@
# generate prototypes for rsync
$old_protos = '';
if (open(IN, 'proto.h')) {
$old_protos = join('', <IN>);
close IN;
}
%FN_MAP = (
BOOL => 'BOOL ',
CHAR => 'char ',
INTEGER => 'int ',
STRING => 'char *',
);
$inheader = 0;
$protos = qq|/* This file is automatically generated with "make proto". DO NOT EDIT */\n\n|;
while (<>) {
if ($inheader) {
if (/[)][ \t]*$/) {
$inheader = 0;
s/$/;/;
}
$protos .= $_;
} elsif (/^FN_(LOCAL|GLOBAL)_([^(]+)\(([^,()]+)/) {
$ret = $FN_MAP{$2};
$func = $3;
$arg = $1 eq 'LOCAL' ? 'int module_id' : 'void';
$protos .= "$ret$func($arg);\n";
} elsif (/^static|^extern/ || /[;]/ || !/^[A-Za-z][A-Za-z0-9_]* /) {
;
} elsif (/[(].*[)][ \t]*$/) {
s/$/;/;
$protos .= $_;
} elsif (/[(]/) {
$inheader = 1;
$protos .= $_;
}
}
if ($old_protos ne $protos) {
open(OUT, '>proto.h') or die $!;
print OUT $protos;
close OUT;
}
open(OUT, '>proto.h-tstamp') and close OUT;

1732
options.c
View File

File diff suppressed because it is too large Load Diff

12
packaging/auto-Makefile Normal file
View File

@@ -0,0 +1,12 @@
TARGETS := all install install-ssl-daemon install-all install-strip conf gen reconfigure restatus \
proto man clean cleantests distclean test check check29 check30 installcheck splint \
doxygen doxygen-upload finddead rrsync
.PHONY: $(TARGETS) auto-prep
$(TARGETS): auto-prep
make -C build $@
auto-prep:
@if test x`packaging/prep-auto-dir` = x; then echo "auto-build-save is not setup"; exit 1; fi
@echo 'Build branch: '`readlink build/.branch | tr % /`

View File

@@ -1,6 +0,0 @@
#!/bin/sh -e
# This script gets git to run gpg with a --passphrase-file option.
PATH=`echo $PATH | sed 's/^[^:]*://'`
gpg --batch --passphrase-file=$GPG_PASSFILE "${@}"

View File

@@ -1,180 +1,174 @@
#!/usr/bin/perl
#!/usr/bin/env -S python3 -B
use strict;
use warnings;
use Getopt::Long;
# This script turns one or more diff files in the patches dir (which is
# expected to be a checkout of the rsync-patches git repo) into a branch
# in the main rsync git checkout. This allows the applied patch to be
# merged with the latest rsync changes and tested. To update the diff
# with the resulting changes, see the patch-update script.
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'branch|b=s' => \( my $master_branch = 'master' ),
'skip-check' => \( my $skip_branch_check ),
'delete' => \( my $delete_local_branches ),
'help|h' => \( my $help_opt ),
);
&usage if $help_opt;
import os, sys, re, argparse, glob
require 'packaging/git-status.pl';
check_git_state($master_branch, !$skip_branch_check, 1);
sys.path = ['packaging'] + sys.path
my %local_branch;
open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n";
while (<PIPE>) {
if (m# patch/\Q$master_branch\E/(.*)#o) {
$local_branch{$1} = 1;
}
}
close PIPE;
from pkglib import *
if ($delete_local_branches) {
foreach my $name (sort keys %local_branch) {
my $branch = "patch/$master_branch/$name";
system 'git', 'branch', '-D', $branch and exit 1;
}
%local_branch = ( );
}
def main():
global created, info, local_branch
my @patch_list;
foreach (@ARGV) {
if (!-f $_) {
die "File not found: $_\n";
}
die "Filename is not a .diff file: $_\n" unless /\.diff$/;
push @patch_list, $_;
}
cur_branch, args.base_branch = check_git_state(args.base_branch, not args.skip_check, args.patches_dir)
exit unless @patch_list;
local_branch = get_patch_branches(args.base_branch)
my(%scanned, %created, %info);
if args.delete_local_branches:
for name in sorted(local_branch):
branch = f"patch/{args.base_branch}/{name}"
cmd_chk(['git', 'branch', '-D', branch])
local_branch = set()
foreach my $patch (@patch_list) {
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
next if $scanned{$name}++;
if args.add_missing:
for fn in sorted(glob.glob(f"{args.patches_dir}/*.diff")):
name = re.sub(r'\.diff$', '', re.sub(r'.+/', '', fn))
if name not in local_branch and fn not in args.patch_files:
args.patch_files.append(fn)
open IN, '<', $patch or die "Unable to open $patch: $!\n";
if not args.patch_files:
return
my $info = '';
my $commit;
while (<IN>) {
if (m#^based-on: (\S+)#) {
$commit = $1;
last;
}
last if m#^index .*\.\..* \d#;
last if m#^diff --git #;
last if m#^--- (old|a)/#;
$info .= $_;
}
close IN;
for fn in args.patch_files:
if not fn.endswith('.diff'):
die(f"Filename is not a .diff file: {fn}")
if not os.path.isfile(fn):
die(f"File not found: {fn}")
$info =~ s/\s+\Z/\n/;
scanned = set()
info = { }
my $parent = $master_branch;
my @patches = $info =~ m#patch -p1 <patches/(\S+)\.diff#g;
if (@patches) {
if ($patches[-1] eq $name) {
pop @patches;
} else {
warn "No identity patch line in $patch\n";
}
if (@patches) {
$parent = pop @patches;
if (!$scanned{$parent}) {
unless (-f "$where$parent.diff") {
die "Unknown parent of $patch: $parent\n";
}
# Add parent to @patch_list so that we will look for the
# parent's parent. Any duplicates will just be ignored.
push @patch_list, "$where$parent.diff";
}
}
} else {
warn "No patch lines found in $patch\n";
}
patch_list = [ ]
for fn in args.patch_files:
m = re.match(r'^(?P<dir>.*?)(?P<name>[^/]+)\.diff$', fn)
patch = argparse.Namespace(**m.groupdict())
if patch.name in scanned:
continue
patch.fn = fn
$info{$name} = [ $parent, $info, $commit ];
}
lines = [ ]
commit_hash = None
with open(patch.fn, 'r', encoding='utf-8') as fh:
for line in fh:
m = re.match(r'^based-on: (\S+)', line)
if m:
commit_hash = m[1]
break
if (re.match(r'^index .*\.\..* \d', line)
or re.match(r'^diff --git ', line)
or re.match(r'^--- (old|a)/', line)):
break
lines.append(re.sub(r'\s*\Z', "\n", line, 1))
info_txt = ''.join(lines).strip() + "\n"
lines = None
foreach my $patch (@patch_list) {
create_branch($patch);
}
parent = args.base_branch
patches = re.findall(r'patch -p1 <%s/(\S+)\.diff' % args.patches_dir, info_txt)
if patches:
last = patches.pop()
if last != patch.name:
warn(f"No identity patch line in {patch.fn}")
patches.append(last)
if patches:
parent = patches.pop()
if parent not in scanned:
diff_fn = patch.dir + parent + '.diff'
if not os.path.isfile(diff_fn):
die(f"Failed to find parent of {patch.fn}: {parent}")
# Add parent to args.patch_files so that we will look for the
# parent's parent. Any duplicates will be ignored.
args.patch_files.append(diff_fn)
else:
warn(f"No patch lines found in {patch.fn}")
system 'git', 'checkout', $master_branch and exit 1;
info[patch.name] = [ parent, info_txt, commit_hash ]
exit;
patch_list.append(patch)
sub create_branch
{
my($patch) = @_;
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
created = set()
for patch in patch_list:
create_branch(patch)
return if $created{$name}++;
cmd_chk(['git', 'checkout', args.base_branch])
my $ref = $info{$name};
my($parent, $info, $commit) = @$ref;
my $parent_branch;
if ($parent eq $master_branch) {
$parent_branch = $master_branch;
$parent_branch = $commit if defined $commit;
} else {
create_branch("$where/$parent.diff");
$parent_branch = "patch/$master_branch/$parent";
}
def create_branch(patch):
if patch.name in created:
return
created.add(patch.name)
my $branch = "patch/$master_branch/$name";
print "\n", '=' x 64, "\nProcessing $branch ($parent_branch)\n";
parent, info_txt, commit_hash = info[patch.name]
parent = argparse.Namespace(dir=patch.dir, name=parent, fn=patch.dir + parent + '.diff')
if ($local_branch{$name}) {
system 'git', 'branch', '-D', $branch and exit 1;
}
if parent.name == args.base_branch:
parent_branch = commit_hash if commit_hash else args.base_branch
else:
create_branch(parent)
parent_branch = '/'.join(['patch', args.base_branch, parent.name])
system 'git', 'checkout', '-b', $branch, $parent_branch and exit 1;
branch = '/'.join(['patch', args.base_branch, patch.name])
print("\n" + '=' * 64)
print(f"Processing {branch} ({parent_branch})")
open OUT, '>', "PATCH.$name" or die $!;
print OUT $info;
close OUT;
system 'git', 'add', "PATCH.$name" and exit 1;
if patch.name in local_branch:
cmd_chk(['git', 'branch', '-D', branch])
open IN, '<', $patch or die "Unable to open $patch: $!\n";
$_ = join('', <IN>);
close IN;
cmd_chk(['git', 'checkout', '-b', branch, parent_branch])
open PIPE, '|-', 'patch -p1' or die $!;
print PIPE $_;
close PIPE;
info_fn = 'PATCH.' + patch.name
with open(info_fn, 'w', encoding='utf-8') as fh:
fh.write(info_txt)
cmd_chk(['git', 'add', info_fn])
system 'rm -f *.orig */*.orig';
with open(patch.fn, 'r', encoding='utf-8') as fh:
patch_txt = fh.read()
while (m#\nnew file mode (\d+)\s+--- /dev/null\s+\Q+++\E b/(.*)#g) {
chmod oct($1), $2;
system 'git', 'add', $2;
}
cmd_run('patch -p1'.split(), input=patch_txt)
while (1) {
system 'git status';
print 'Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: ';
$_ = <STDIN>;
last if /^$/;
chomp;
system "git add $_";
}
for fn in glob.glob('*.orig') + glob.glob('*/*.orig'):
os.unlink(fn)
while (system 'git', 'commit', '-a', '-m', "Creating branch from $name.diff.") {
exit 1 if system '/bin/zsh';
}
}
pos = 0
new_file_re = re.compile(r'\nnew file mode (?P<mode>\d+)\s+--- /dev/null\s+\+\+\+ b/(?P<fn>.+)')
while True:
m = new_file_re.search(patch_txt, pos)
if not m:
break
os.chmod(m['fn'], int(m['mode'], 8))
cmd_chk(['git', 'add', m['fn']])
pos = m.end()
sub usage
{
die <<EOT;
Usage branch-from-patch [OPTIONS] patches/DIFF...
while True:
cmd_chk('git status'.split())
ans = input('Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: ')
if ans == '':
break
cmd_chk("git add " + ans, shell=True)
Options:
-b, --branch=BRANCH Create branches relative to BRANCH if no "based-on"
header was found in the patch file.
--skip-check Skip the check that ensures starting with a clean branch.
--delete Delete all the local patch/BASE/* branches, not just the ones
that are being recreated.
-h, --help Output this help message.
EOT
}
while True:
s = cmd_run(['git', 'commit', '-a', '-m', f"Creating branch from {patch.name}.diff."])
if not s.returncode:
break
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
if s.returncode:
die('Aborting due to shell error code')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Create a git patch branch from an rsync patch file.", add_help=False)
parser.add_argument('--branch', '-b', dest='base_branch', metavar='BASE_BRANCH', default='master', help="The branch the patch is based on. Default: master.")
parser.add_argument('--add-missing', '-a', action='store_true', help="Add a branch for every patches/*.diff that doesn't have a branch.")
parser.add_argument('--skip-check', action='store_true', help="Skip the check that ensures starting with a clean branch.")
parser.add_argument('--delete', dest='delete_local_branches', action='store_true', help="Delete all the local patch/BASE/* branches, not just the ones that are being recreated.")
parser.add_argument('--patches-dir', '-p', metavar='DIR', default='patches', help="Override the location of the rsync-patches dir. Default: patches.")
parser.add_argument('patch_files', metavar='patches/DIFF_FILE', nargs='*', help="Specify what patch diff files to process. Default: all of them.")
parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
args = parser.parse_args()
main()
# vim: sw=4 et ft=python

148
packaging/cull-options Executable file
View File

@@ -0,0 +1,148 @@
#!/usr/bin/env python3
# This script outputs either perl or python code that parses all possible options
# that the code in options.c might send to the server. The resulting code is then
# included in the rrsync script.
import re, argparse
short_no_arg = { }
short_with_num = { '@': 1 }
long_opts = { # These include some extra long-args that BackupPC uses:
'block-size': 1,
'daemon': -1,
'debug': 1,
'fake-super': 0,
'fuzzy': 0,
'group': 0,
'hard-links': 0,
'ignore-times': 0,
'info': 1,
'links': 0,
'log-file': 3,
'munge-links': 0,
'no-munge-links': -1,
'one-file-system': 0,
'owner': 0,
'perms': 0,
'recursive': 0,
'stderr': 1,
'times': 0,
'copy-devices': -1,
'write-devices': -1,
}
def main():
last_long_opt = None
with open('../options.c') as fh:
for line in fh:
m = re.search(r"argstr\[x\+\+\] = '([^.ie])'", line)
if m:
short_no_arg[m.group(1)] = 1
last_long_opt = None
continue
m = re.search(r'asprintf\([^,]+, "-([a-zA-Z0-9])\%l?[ud]"', line)
if m:
short_with_num[m.group(1)] = 1
last_long_opt = None
continue
m = re.search(r'args\[ac\+\+\] = "--([^"=]+)"', line)
if m:
last_long_opt = m.group(1)
if last_long_opt not in long_opts:
long_opts[last_long_opt] = 0
else:
last_long_opt = None
continue
if last_long_opt:
m = re.search(r'args\[ac\+\+\] = safe_arg\("", ([^[("\s]+)\);', line)
if m:
long_opts[last_long_opt] = 2
last_long_opt = None
continue
if 'args[ac++] = ' in line:
last_long_opt = None
m = re.search(r'return "--([^"]+-dest)";', line)
if m:
long_opts[m.group(1)] = 2
last_long_opt = None
continue
m = re.search(r'asprintf\([^,]+, "--([^"=]+)=', line)
if not m:
m = re.search(r'args\[ac\+\+\] = "--([^"=]+)=', line)
if not m:
m = re.search(r'args\[ac\+\+\] = safe_arg\("--([^"=]+)"', line)
if not m:
m = re.search(r'fmt = .*: "--([^"=]+)=', line)
if m:
long_opts[m.group(1)] = 1
last_long_opt = None
long_opts['files-from'] = 3
txt = """\
### START of options data produced by the cull-options script. ###
# To disable a short-named option, add its letter to this string:
"""
txt += str_assign('short_disabled', 's') + "\n"
txt += '# These are also disabled when the restricted dir is not "/":\n'
txt += str_assign('short_disabled_subdir', 'KLk') + "\n"
txt += '# These are all possible short options that we will accept (when not disabled above):\n'
txt += str_assign('short_no_arg', ''.join(sorted(short_no_arg)), 'DO NOT REMOVE ANY')
txt += str_assign('short_with_num', ''.join(sorted(short_with_num)), 'DO NOT REMOVE ANY')
txt += """
# To disable a long-named option, change its value to a -1. The values mean:
# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
# check the arg when receiving; and 3 = always check the arg.
"""
print(txt, end='')
if args.python:
print("long_opts = {")
sep = ':'
else:
print("our %long_opt = (")
sep = ' =>'
for opt in sorted(long_opts):
if opt.startswith(('min-', 'max-')):
val = 1
else:
val = long_opts[opt]
print(' ', repr(opt) + sep, str(val) + ',')
if args.python:
print("}")
else:
print(");")
print("\n### END of options data produced by the cull-options script. ###")
def str_assign(name, val, comment=None):
comment = ' # ' + comment if comment else ''
if args.python:
return name + ' = ' + repr(val) + comment + "\n"
return 'our $' + name + ' = ' + repr(val) + ';' + comment + "\n"
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Output culled rsync options for rrsync.", add_help=False)
out_group = parser.add_mutually_exclusive_group()
out_group.add_argument('--perl', action='store_true', help="Output perl code.")
out_group.add_argument('--python', action='store_true', help="Output python code (the default).")
parser.add_argument('--help', '-h', action='help', help="Output this help message and exit.")
args = parser.parse_args()
if not args.perl:
args.python = True
main()
# vim: sw=4 et

View File

@@ -1,72 +0,0 @@
#!/usr/bin/perl
# This script outputs some perl code that parses all possible options
# that the code in options.c might send to the server. This perl code
# is included in the rrsync script.
use strict;
our %short_no_arg;
our %short_with_num;
our %long_opt = (
'daemon' => -1,
'debug' => 1,
'fake-super' => 0,
'info' => 1,
'log-file' => 3,
);
our $last_long_opt;
open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
while (<IN>) {
if (/\Qargstr[x++]\E = '([^.ie])'/) {
$short_no_arg{$1} = 1;
undef $last_long_opt;
} elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) {
$short_with_num{$1} = 1;
undef $last_long_opt;
} elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) {
$last_long_opt = $1;
$long_opt{$1} = 0 unless exists $long_opt{$1};
} elsif (defined($last_long_opt)
&& /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') {
$long_opt{$last_long_opt} = 2;
undef $last_long_opt;
} elsif (/dest_option = "--([^"]+)"/) {
$long_opt{$1} = 2;
undef $last_long_opt;
} elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/) {
$long_opt{$1} = 1;
undef $last_long_opt;
}
}
close IN;
my $short_no_arg = join('', sort keys %short_no_arg);
my $short_with_num = join('', sort keys %short_with_num);
print <<EOT;
# These options are the only options that rsync might send to the server,
# and only in the option format that the stock rsync produces.
# To disable a short-named option, add its letter to this string:
our \$short_disabled = 's';
our \$short_no_arg = '$short_no_arg'; # DO NOT REMOVE ANY
our \$short_with_num = '$short_with_num'; # DO NOT REMOVE ANY
# To disable a long-named option, change its value to a -1. The values mean:
# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
# check the arg when receiving; and 3 = always check the arg.
our \%long_opt = (
EOT
foreach my $opt (sort keys %long_opt) {
my $val = $long_opt{$opt};
$val = 1 if $opt =~ /^(max-|min-)/;
$val = 3 if $opt eq 'files-from';
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
print " '$opt' => $val,\n";
}
print ");\n\n";

View File

@@ -1,51 +0,0 @@
# Do some git-status checking for the current dir and (optionally)
# the patches dir.
sub check_git_state
{
my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_;
my($cur_branch) = check_git_status($fatal_unless_clean);
(my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH
if ($branch ne $master_branch) {
print "The checkout is not on the $master_branch branch.\n";
exit 1 if $master_branch ne 'master';
print "Do you want me to continue with --branch=$branch? [n] ";
$_ = <STDIN>;
exit 1 unless /^y/i;
$_[0] = $master_branch = $branch; # Updates caller's $master_branch too.
}
if ($check_patches_dir && -d 'patches/.git') {
($branch) = check_git_status($fatal_unless_clean, 'patches');
if ($branch ne $master_branch) {
print "The *patches* checkout is on branch $branch, not branch $master_branch.\n";
print "Do you want to change it to branch $master_branch? [n] ";
$_ = <STDIN>;
exit 1 unless /^y/i;
system "cd patches && git checkout '$master_branch'";
}
}
return $cur_branch;
}
sub check_git_status
{
my($fatal_unless_clean, $subdir) = @_;
$subdir = '.' unless defined $subdir;
my $status = `cd '$subdir' && git status`;
my $is_clean = $status =~ /\nnothing to commit \(working directory clean\)/;
my($cur_branch) = $status =~ /^# On branch (.+)\n/;
if ($fatal_unless_clean && !$is_clean) {
if ($subdir eq '.') {
$subdir = '';
} else {
$subdir = " *$subdir*";
}
die "The$subdir checkout is not clean:\n", $status;
}
($cur_branch, $is_clean, $status);
}
1;

View File

@@ -1,23 +1,18 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Name: rsync
Version: 3.1.1
%define fullversion %{version}pre2
Release: 0.1.pre2
%define srcdir src-previews
Version: 3.4.2
%define fullversion %{version}
Release: 1
%define srcdir src
Group: Applications/Internet
License: GPL
Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
#Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
URL: http://rsync.samba.org/
Source0: https://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
#Source1: https://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
URL: https://rsync.samba.org/
Prefix: %{_prefix}
BuildRoot: /var/tmp/%{name}-root
%package ssl-client
Summary: Provides rsync-ssl
Group: Applications/Internet
Requires: rsync, stunnel >= 4
%package ssl-daemon
Summary: An stunnel config file to support ssl rsync daemon connections.
Group: Applications/Internet
@@ -34,11 +29,6 @@ differences between the source files and the existing files in the
destination. Rsync is widely used for backups and mirroring and as an
improved copy command for everyday use.
%description ssl-client
Provides the rsync-ssl script that makes use of stunnel 4 to open an ssl
connection to an rsync daemon (on port 874). This setup does NOT require
any local stunnel daemon to be running to connect to the remote ssl rsyncd.
%description ssl-daemon
Provides a config file for stunnel that will (if you start your stunnel
service) cause stunnel to listen for ssl rsync-daemon connections and run
@@ -66,7 +56,7 @@ make
%install
rm -rf $RPM_BUILD_ROOT
make install install-ssl-client install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
make install install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d $RPM_BUILD_ROOT/etc/rsync-ssl/certs
install -m 644 packaging/lsb/rsync.xinetd $RPM_BUILD_ROOT/etc/xinetd.d/rsync
@@ -76,24 +66,18 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc COPYING NEWS OLDNEWS README support/ tech_report.tex
%doc COPYING NEWS.md README.md support/ tech_report.tex
%config(noreplace) /etc/xinetd.d/rsync
%{_prefix}/bin/rsync
%{_mandir}/man1/rsync.1*
%{_mandir}/man5/rsyncd.conf.5*
%files ssl-client
%{_prefix}/bin/rsync-ssl
%{_prefix}/bin/stunnel-rsync
%{_mandir}/man1/rsync.1*
%{_mandir}/man1/rsync-ssl.1*
%{_mandir}/man5/rsyncd.conf.5*
%files ssl-daemon
%config(noreplace) /etc/stunnel/rsyncd.conf
%dir /etc/rsync-ssl/certs
%changelog
* Mon May 26 2014 Wayne Davison <wayned@samba.org>
Released 3.1.1pre2.
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
Added installation of /etc/xinetd.d/rsync file and some commented-out
lines that demonstrate how to use the rsync-patches tar file.
* Tue Apr 28 2026 Rsync Project <rsync.project@gmail.com>
Released 3.4.2.

View File

@@ -1,173 +0,0 @@
#!/usr/bin/perl
use strict;
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
# copy of the /home/ftp/pub/rsync dir on samba.org. It also requires a
# git checkout of rsync (feel free to use your normal rsync build dir as
# long as it doesn't have any uncommitted changes).
#
# If this is run with -ctu, it will make an updated "nightly" tar file in
# the nightly dir. It will also remove any old tar files, regenerate the
# HTML man pages in the nightly dir, and then rsync the changes to the
# samba.org server.
use Getopt::Long;
use Date::Format;
# Where the local copy of /home/ftp/pub/rsync/dev/nightly should be updated.
our $dest = $ENV{HOME} . '/samba-rsync-ftp/dev/nightly';
our $nightly_symlink = "$dest/rsync-HEAD.tar.gz";
our($make_tar, $upload, $help_opt);
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'make-tar|t' => \$make_tar,
'upload|u' => \$upload,
'help|h' => \$help_opt,
) || $help_opt;
our $name = time2str('rsync-HEAD-%Y%m%d-%H%M%Z', time, 'GMT');
our $ztoday = time2str('%d %b %Y', time);
our $today = $ztoday;
our $gen_target = $upload ? 'gensend' : 'gen';
die "$dest does not exist\n" unless -d $dest;
die "There is no .git dir in the current directory.\n" unless -d '.git';
die "There is no rsync checkout in the current directory.\n" unless -f 'rsyncd.conf.yo';
if ($make_tar) {
open(IN, '-|', 'git status') or die $!;
my $status = join('', <IN>);
close IN;
die "The checkout is not clean:\n", $status unless $status =~ /\nnothing to commit \(working directory clean\)/;
die "The checkout is not on the master branch.\n" unless $status =~ /^# On branch master\n/;
system "make $gen_target" and die "make $gen_target failed!\n";
my @extra_files;
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
while (<IN>) {
if (s/^GENFILES=//) {
while (s/\\$//) {
$_ .= <IN>;
}
@extra_files = split(' ', $_);
last;
}
}
close IN;
my $confversion;
open(IN, '<', 'configure.ac') or die "Unable to open configure.ac: $!\n";
while (<IN>) {
if (/^RSYNC_VERSION=(.*)/) {
$confversion = $1;
last;
}
}
close IN;
die "Unable to find RSYNC_VERSION in configure.ac\n" unless defined $confversion;
open(IN, '<', 'OLDNEWS') or die "Unable to open OLDNEWS: $!\n";
$_ = <IN>;
my($lastversion) = /(\d+\.\d+\.\d+)/;
my $last_protocol_version;
while (<IN>) {
if (my($ver,$pdate,$pver) = /^\s+\S\S\s\S\S\S\s\d\d\d\d\s+(\d+\.\d+\.\d+)\s+(\d\d \w\w\w \d\d\d\d\s+)?(\d+)$/) {
$last_protocol_version = $pver if $ver eq $lastversion;
}
}
close IN;
die "Unable to determine protocol_version for $lastversion.\n" unless defined $last_protocol_version;
my($protocol_version,$subprotocol_version);
open(IN, '<', 'rsync.h') or die "Unable to open rsync.h: $!\n";
while (<IN>) {
if (/^#define\s+PROTOCOL_VERSION\s+(\d+)/) {
$protocol_version = $1;
} elsif (/^#define\s+SUBPROTOCOL_VERSION\s+(\d+)/) {
$subprotocol_version = $1;
}
}
close IN;
die "Unable to determine the current PROTOCOL_VERSION.\n" unless defined $protocol_version;
die "Unable to determine the current SUBPROTOCOL_VERSION.\n" unless defined $subprotocol_version;
if ($confversion =~ /dev|pre/) {
if ($last_protocol_version ne $protocol_version) {
if ($subprotocol_version == 0) {
die "SUBPROTOCOL_VERSION must not be 0 for a non-final release with a changed PROTOCOL_VERSION.\n";
}
} else {
if ($subprotocol_version != 0) {
die "SUBPROTOCOL_VERSION must be 0 when the PROTOCOL_VERSION hasn't changed from the last release.\n";
}
}
} else {
if ($subprotocol_version != 0) {
die "SUBPROTOCOL_VERSION must be 0 for a final release.\n";
}
}
print "Creating $name.tar.gz\n";
system "rsync -a @extra_files $name/";
system "git archive --format=tar --prefix=$name/ HEAD | tar xf -";
system "support/git-set-file-times --prefix=$name/";
system "fakeroot tar czf $dest/$name.tar.gz $name; rm -rf $name";
unlink($nightly_symlink);
symlink("$name.tar.gz", $nightly_symlink);
}
foreach my $fn (qw( rsync.yo rsyncd.conf.yo )) {
my $yo_tmp = "$dest/$fn";
(my $html_fn = "$dest/$fn") =~ s/\.yo/.html/;
open(IN, '<', $fn) or die $!;
undef $/; $_ = <IN>; $/ = "\n";
close IN;
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m;
#s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m;
open(OUT, '>', $yo_tmp) or die $!;
print OUT $_;
close OUT;
system 'yodl2html', '-o', $html_fn, $yo_tmp;
unlink($yo_tmp);
}
chdir($dest) or die $!;
my $cnt = 0;
open(PIPE, '-|', 'ls -1t rsync-HEAD-*') or die $!;
while (<PIPE>) {
chomp;
next if $cnt++ < 10;
unlink($_);
}
close PIPE;
system 'ls -ltr';
if ($upload) {
my $opt = '';
if (defined $ENV{RSYNC_PARTIAL_DIR}) {
$opt = " -f 'R $ENV{RSYNC_PARTIAL_DIR}'";
}
system "rsync$opt -aviHP --delete-after . samba.org:/home/ftp/pub/rsync/dev/nightly";
}
exit;
sub usage
{
die <<EOT;
Usage: nightly-rsync [OPTIONS]
-t, --make-tar create a new tar file in $dest
-u, --upload upload the revised nightly dir to samba.org
-h, --help display this help
EOT
}

View File

@@ -0,0 +1,18 @@
# This config file can be used with rsync to enable legacy digests
# (such as MD4) by using the OPENSSL_CONF environment variable.
# See rsync's configure --with-openssl-conf=/path/name option.
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1

View File

@@ -1,240 +1,244 @@
#!/usr/bin/perl
#!/usr/bin/env -S python3 -B
# This script is used to turn one or more of the "patch/BASE/*" branches
# into one or more diffs in the "patches" directory. Pass the option
# --gen if you want generated files in the diffs. Pass the name of
# one or more diffs if you want to just update a subset of all the
# diffs.
use strict;
use warnings;
use Getopt::Long;
import os, sys, re, argparse, time, shutil
my $patches_dir = 'patches';
my $tmp_dir = "patches.$$";
my $make_gen_cmd = 'make -f prepare-source.mak conf && ./config.status && make gen';
sys.path = ['packaging'] + sys.path
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'branch|b=s' => \( my $master_branch = 'master' ),
'skip-check' => \( my $skip_branch_check ),
'shell|s' => \( my $launch_shell ),
'gen:s' => \( my $incl_generated_files ),
'help|h' => \( my $help_opt ),
);
&usage if $help_opt;
from pkglib import *
if (defined $incl_generated_files) {
$patches_dir = $incl_generated_files if $incl_generated_files ne '';
$incl_generated_files = 1;
}
MAKE_GEN_CMDS = [
'./prepare-source'.split(),
'cd build && if test -f config.status ; then ./config.status ; else ../configure ; fi',
'make -C build gen'.split(),
]
TMP_DIR = "patches.gen"
die "No '$patches_dir' directory was found.\n" unless -d $patches_dir;
die "No '.git' directory present in the current dir.\n" unless -d '.git';
os.environ['GIT_MERGE_AUTOEDIT'] = 'no'
require 'packaging/git-status.pl';
my $starting_branch = check_git_state($master_branch, !$skip_branch_check, 1);
def main():
global master_commit, parent_patch, description, completed, last_touch
my $master_commit;
open PIPE, '-|', "git log -1 --no-color $master_branch" or die $!;
while (<PIPE>) {
if (/^commit (\S+)/) {
$master_commit = $1;
last;
}
}
close PIPE;
die "Unable to determine commit hash for master branch: $master_branch\n" unless defined $master_commit;
if not os.path.isdir(args.patches_dir):
die(f'No "{args.patches_dir}" directory was found.')
if not os.path.isdir('.git'):
die('No ".git" directory present in the current dir.')
if ($incl_generated_files) {
my @extra_files = get_extra_files();
die "'$tmp_dir' must not exist in the current directory.\n" if -e $tmp_dir;
mkdir($tmp_dir, 0700) or die "Unable to mkdir($tmp_dir): $!\n";
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/master/" and exit 1;
}
our $last_touch = time;
starting_branch, args.base_branch = check_git_state(args.base_branch, not args.skip_check, args.patches_dir)
my %patches;
master_commit = latest_git_hash(args.base_branch)
# Start by finding all patches so that we can load all possible parents.
open(PIPE, '-|', 'git', 'branch', '-l') or die $!;
while (<PIPE>) {
if (m# patch/\Q$master_branch\E/(.*)#o) {
$patches{$1} = 1;
}
}
close PIPE;
if cmd_txt_chk(['packaging/prep-auto-dir']).out == '':
die('You must setup an auto-build-save dir to use this script.')
my @patches = sort keys %patches;
if args.gen:
if os.path.lexists(TMP_DIR):
die(f'"{TMP_DIR}" must not exist in the current directory.')
gen_files = get_gen_files()
os.mkdir(TMP_DIR, 0o700)
for cmd in MAKE_GEN_CMDS:
cmd_chk(cmd)
cmd_chk(['rsync', '-a', *gen_files, f'{TMP_DIR}/master/'])
my(%parent, %description);
foreach my $patch (@patches) {
my $branch = "patch/$master_branch/$patch";
my $desc = '';
open(PIPE, '-|', 'git', 'diff', '-U1000', "$master_branch...$branch", '--', "PATCH.$patch") or die $!;
while (<PIPE>) {
last if /^@@ /;
}
while (<PIPE>) {
next unless s/^[ +]//;
if (m#patch -p1 <patches/(\S+)\.diff# && $1 ne $patch) {
my $parent = $parent{$patch} = $1;
if (!$patches{$parent}) {
die "Parent of $patch is not a local branch: $parent\n";
}
}
$desc .= $_;
}
close PIPE;
$description{$patch} = $desc;
}
last_touch = int(time.time())
if (@ARGV) {
# Limit the list of patches to actually process based on @ARGV.
@patches = ( );
foreach (@ARGV) {
s{^patch(es)?/} {};
s{\.diff$} {};
if (!$patches{$_}) {
die "Local branch not available for patch: $_\n";
}
push(@patches, $_);
}
}
# Start by finding all patches so that we can load all possible parents.
patches = sorted(list(get_patch_branches(args.base_branch)))
my %completed;
foreach my $patch (@patches) {
next if $completed{$patch}++;
last unless update_patch($patch);
}
parent_patch = { }
description = { }
if ($incl_generated_files) {
system "rm -rf $tmp_dir";
}
for patch in patches:
branch = f"patch/{args.base_branch}/{patch}"
desc = ''
proc = cmd_pipe(['git', 'diff', '-U1000', f"{args.base_branch}...{branch}", '--', f"PATCH.{patch}"])
in_diff = False
for line in proc.stdout:
if in_diff:
if not re.match(r'^[ +]', line):
continue
line = line[1:]
m = re.search(r'patch -p1 <patches/(\S+)\.diff', line)
if m and m[1] != patch:
parpat = parent_patch[patch] = m[1]
if not parpat in patches:
die(f"Parent of {patch} is not a local branch: {parpat}")
desc += line
elif re.match(r'^@@ ', line):
in_diff = True
description[patch] = desc
proc.communicate()
sleep 1 while $last_touch >= time;
system "git checkout $starting_branch" and exit 1;
if args.patch_files: # Limit the list of patches to actually process
valid_patches = patches
patches = [ ]
for fn in args.patch_files:
name = re.sub(r'\.diff$', '', re.sub(r'.+/', '', fn))
if name not in valid_patches:
die(f"Local branch not available for patch: {name}")
patches.append(name)
exit;
completed = set()
for patch in patches:
if patch in completed:
continue
if not update_patch(patch):
break
if args.gen:
shutil.rmtree(TMP_DIR)
while last_touch >= int(time.time()):
time.sleep(1)
cmd_chk(['git', 'checkout', starting_branch])
cmd_chk(['packaging/prep-auto-dir'], discard='output')
sub update_patch
{
my($patch) = @_;
def update_patch(patch):
global last_touch
my $parent = $parent{$patch};
my $based_on;
if (defined $parent) {
unless ($completed{$parent}++) {
update_patch($parent);
}
$based_on = $parent = "patch/$master_branch/$parent";
} else {
$parent = $master_branch;
$based_on = $master_commit;
}
completed.add(patch) # Mark it as completed early to short-circuit any (bogus) dependency loops.
print "======== $patch ========\n";
parent = parent_patch.get(patch, None)
if parent:
if parent not in completed:
if not update_patch(parent):
return 0
based_on = parent = f"patch/{args.base_branch}/{parent}"
else:
parent = args.base_branch
based_on = master_commit
sleep 1 while $incl_generated_files && $last_touch >= time;
system "git checkout patch/$master_branch/$patch" and return 0;
print(f"======== {patch} ========")
my $ok = system("git merge $based_on") == 0;
if (!$ok || $launch_shell) {
my($parent_dir) = $parent =~ m{([^/]+)$};
print qq|"git merge $based_on" incomplete -- please fix.\n| if !$ok;
$ENV{PS1} = "[$parent_dir] $patch: ";
while (1) {
if (system($ENV{SHELL}) != 0) {
print "Abort? [n/y] ";
$_ = <STDIN>;
next unless /^y/i;
return 0;
}
my($cur_branch, $is_clean, $status) = check_git_status(0);
last if $is_clean;
print $status;
}
}
while args.gen and last_touch >= int(time.time()):
time.sleep(1)
open(OUT, '>', "$patches_dir/$patch.diff") or die $!;
print OUT $description{$patch}, "\nbased-on: $based_on\n";
branch = f"patch/{args.base_branch}/{patch}"
s = cmd_run(['git', 'checkout', branch])
if s.returncode != 0:
return 0
my @extra_files;
if ($incl_generated_files) {
@extra_files = get_extra_files();
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/$patch/" and exit 1;
}
$last_touch = time;
s = cmd_run(['git', 'merge', based_on])
ok = s.returncode == 0
skip_shell = False
if not ok or args.cmd or args.make or args.shell:
cmd_chk(['packaging/prep-auto-dir'], discard='output')
if not ok:
print(f'"git merge {based_on}" incomplete -- please fix.')
if not run_a_shell(parent, patch):
return 0
if not args.make and not args.cmd:
skip_shell = True
if args.make:
if cmd_run(['packaging/smart-make']).returncode != 0:
if not run_a_shell(parent, patch):
return 0
if not args.cmd:
skip_shell = True
if args.cmd:
if cmd_run(args.cmd).returncode != 0:
if not run_a_shell(parent, patch):
return 0
skip_shell = True
if args.shell and not skip_shell:
if not run_a_shell(parent, patch):
return 0
open(PIPE, '-|', 'git', 'diff', $based_on) or die $!;
DIFF: while (<PIPE>) {
while (m{^diff --git a/PATCH}) {
while (<PIPE>) {
last if m{^diff --git a/};
}
last DIFF if !defined $_;
}
next if /^index /;
print OUT $_;
}
close PIPE;
with open(f"{args.patches_dir}/{patch}.diff", 'w', encoding='utf-8') as fh:
fh.write(description[patch])
fh.write(f"\nbased-on: {based_on}\n")
if ($incl_generated_files) {
my $parent_dir;
if ($parent eq $master_branch) {
$parent_dir = 'master';
} else {
($parent_dir) = $parent =~ m{([^/]+)$};
}
open(PIPE, '-|', 'diff', '-Nurp', "$tmp_dir/$parent_dir", "$tmp_dir/$patch") or die $!;
while (<PIPE>) {
s#^(diff -Nurp) $tmp_dir/[^/]+/(.*?) $tmp_dir/[^/]+/(.*)#$1 a/$2 b/$3#o;
s#^\Q---\E $tmp_dir/[^/]+/([^\t]+)\t.*#--- a/$1#o;
s#^\Q+++\E $tmp_dir/[^/]+/([^\t]+)\t.*#+++ b/$1#o;
print OUT $_;
}
close PIPE;
unlink @extra_files;
}
if args.gen:
gen_files = get_gen_files()
for cmd in MAKE_GEN_CMDS:
cmd_chk(cmd)
cmd_chk(['rsync', '-a', *gen_files, f"{TMP_DIR}/{patch}/"])
else:
gen_files = [ ]
last_touch = int(time.time())
close OUT;
proc = cmd_pipe(['git', 'diff', based_on])
skipping = False
for line in proc.stdout:
if skipping:
if not re.match(r'^diff --git a/', line):
continue
skipping = False
elif re.match(r'^diff --git a/PATCH', line):
skipping = True
continue
if not re.match(r'^index ', line):
fh.write(line)
proc.communicate()
1;
}
if args.gen:
e_tmp_dir = re.escape(TMP_DIR)
diff_re = re.compile(r'^(diff -Nurp) %s/[^/]+/(.*?) %s/[^/]+/(.*)' % (e_tmp_dir, e_tmp_dir))
minus_re = re.compile(r'^\-\-\- %s/[^/]+/([^\t]+)\t.*' % e_tmp_dir)
plus_re = re.compile(r'^\+\+\+ %s/[^/]+/([^\t]+)\t.*' % e_tmp_dir)
exit;
if parent == args.base_branch:
parent_dir = 'master'
else:
m = re.search(r'([^/]+)$', parent)
parent_dir = m[1]
sub get_extra_files
{
my @extras;
proc = cmd_pipe(['diff', '-Nurp', f"{TMP_DIR}/{parent_dir}", f"{TMP_DIR}/{patch}"])
for line in proc.stdout:
line = diff_re.sub(r'\1 a/\2 b/\3', line)
line = minus_re.sub(r'--- a/\1', line)
line = plus_re.sub(r'+++ b/\1', line)
fh.write(line)
proc.communicate()
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
while (<IN>) {
if (s/^GENFILES=//) {
while (s/\\$//) {
$_ .= <IN>;
}
@extras = split(' ', $_);
last;
}
}
close IN;
return 1
return @extras;
}
sub usage
{
die <<EOT;
Usage: patch-update [OPTIONS] [patches/DIFF...]
def run_a_shell(parent, patch):
m = re.search(r'([^/]+)$', parent)
parent_dir = m[1]
os.environ['PS1'] = f"[{parent_dir}] {patch}: "
Options:
-b, --branch=BRANCH The master branch to merge into the patch/BASE/* branches.
--gen[=DIR] Include generated files. Optional destination DIR
arg overrides the default of using the "patches" dir.
--skip-check Skip the check that ensures starting with a clean branch.
-s, --shell Launch a shell for every patch/BASE/* branch updated, not
just when a conflict occurs.
-h, --help Output this help message.
EOT
}
while True:
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
if s.returncode != 0:
ans = input("Abort? [n/y] ")
if re.match(r'^y', ans, flags=re.I):
return False
continue
cur_branch, is_clean, status_txt = check_git_status(0)
if is_clean:
break
print(status_txt, end='')
cmd_run('rm -f build/*.o build/*/*.o')
return True
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Turn a git branch back into a diff files in the patches dir.", add_help=False)
parser.add_argument('--branch', '-b', dest='base_branch', metavar='BASE_BRANCH', default='master', help="The branch the patch is based on. Default: master.")
parser.add_argument('--skip-check', action='store_true', help="Skip the check that ensures starting with a clean branch.")
parser.add_argument('--make', '-m', action='store_true', help="Run the smart-make script in every patch branch.")
parser.add_argument('--cmd', '-c', help="Run a command in every patch branch.")
parser.add_argument('--shell', '-s', action='store_true', help="Launch a shell for every patch/BASE/* branch updated, not just when a conflict occurs.")
parser.add_argument('--gen', metavar='DIR', nargs='?', const='', help='Include generated files. Optional DIR value overrides the default of using the "patches" dir.')
parser.add_argument('--patches-dir', '-p', metavar='DIR', default='patches', help="Override the location of the rsync-patches dir. Default: patches.")
parser.add_argument('patch_files', metavar='patches/DIFF_FILE', nargs='*', help="Specify what patch diff files to process. Default: all of them.")
parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
args = parser.parse_args()
if args.gen == '':
args.gen = args.patches_dir
elif args.gen is not None:
args.patches_dir = args.gen
main()
# vim: sw=4 et ft=python

Some files were not shown because too many files have changed in this diff Show More